Skip to content

[clang] Improve nested name specifier AST representation #147835

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Open
wants to merge 1 commit into
base: main
Choose a base branch
from

Conversation

mizvekov
Copy link
Contributor

@mizvekov mizvekov commented Jul 9, 2025

This is a major change on how we represent nested name qualifications in the AST.

  • The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy.
  • The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present.
  • TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for stdexec. For one datapoint, for test_on2.cpp in that project, which is the slowest compiling test, this patch improves -c compilation time by about 7.2%, with the -fsyntax-only improvement being at ~12%.

This has great results on compile-time-tracker as well:
image

This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in clang/include/clang/AST and clang/lib/AST, with also important changes in clang/lib/Sema/TreeTransform.h.

The rest and bulk of the changes are mostly consequences of the changes in API.

PS: TagType::getDecl is renamed to getOriginalDecl in this patch, just for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes #147000

This is a major change on how we represent nested name qualifications in the AST.

* The nested name specifier itself and how it's stored is changed. The prefixes
  for types are handled within the type hierarchy, which makes canonicalization
  for them super cheap, no memory allocation required. Also translating a type
  into nested name specifier form becomes a no-op. An identifier is stored as a
  DependentNameType. The nested name specifier gains a lightweight handle class,
  to be used instead of passing around pointers, which is similar to what is implemented
  for TemplateName. There is still one free bit available, and this handle can
  be used within a PointerUnion and PointerIntPair, which should keep bit-packing
  aficionados happy.
* The ElaboratedType node is removed, all type nodes in which it could previously apply
  to can now store the elaborated keyword and name qualifier, tail allocating
  when present.
* TagTypes can now point to the exact declaration found when producing these, as
  opposed to the previous situation of there only existing one TagType per entity.
  This increases the amount of type sugar retained, and can have several
  applications, for example in tracking module ownership, and other tools
  which care about source file origins, such as IWYU. These TagTypes are lazily
  allocated, in order to limit the increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for [stdexec](https://github.com/NVIDIA/stdexec).
For one datapoint, for `test_on2.cpp` in that project, which is the slowest
compiling test, this patch improves `-c` compilation time by about 7.2%, with
the `-fsyntax-only` improvement being at ~12%.

This has great results on compile-time-tracker as well:

This patch also further enables other optimziations in the future, and
will reduce the performance impact of template specialization resugaring
when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that.
Part of the reason is that I started by the nested name specifier
part, before the ElaboratedType part, but that had a huge performance
downside, as ElaboratedType is a big performance hog. I didn't have
the steam to go back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to
remove ElaboratedType in one go, versus removing it from one type
at a time, as that would present much more churn to the users.
Also, the nested name specifier having a different API avoids
missing changes related to how prefixes work now, which could
make existing code compile but not work.

How to review: The important changes are all in `clang/include/clang/AST` and
`clang/lib/AST`, with also import changes in `clang/lib/Sema/TreeTransform.h`.

The rest and bulk of the changes are mostly consequences of the changes in API.

Fixes #136624
Fixes #147000
@llvmbot llvmbot added clang:as-a-library libclang and C++ API clang:static analyzer debuginfo backend:CSKY HLSL HLSL Language Support coroutines C++20 coroutines clang:dataflow Clang Dataflow Analysis framework - https://clang.llvm.org/docs/DataFlowAnalysisIntro.html backend:ARC backend:loongarch clang:analysis clang:openmp OpenMP related changes to Clang clang:bytecode Issues for the clang bytecode constexpr interpreter backend:Lanai labels Jul 9, 2025
@llvmbot
Copy link
Member

llvmbot commented Jul 9, 2025

@llvm/pr-subscribers-backend-systemz
@llvm/pr-subscribers-clang-codegen
@llvm/pr-subscribers-backend-hexagon
@llvm/pr-subscribers-coroutines
@llvm/pr-subscribers-backend-arm

@llvm/pr-subscribers-backend-sparc

Author: Matheus Izvekov (mizvekov)

Changes

This is a major change on how we represent nested name qualifications in the AST.

  • The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy.
  • The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present.
  • TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for stdexec. For one datapoint, for test_on2.cpp in that project, which is the slowest compiling test, this patch improves -c compilation time by about 7.2%, with the -fsyntax-only improvement being at ~12%.

This has great results on compile-time-tracker as well:
image

This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in clang/include/clang/AST and clang/lib/AST, with also import changes in clang/lib/Sema/TreeTransform.h.

The rest and bulk of the changes are mostly consequences of the changes in API.

PS: TagType::getDecl is renamed to getOriginalDecl in this patch, just for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes #147000


Patch is 2.13 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/147835.diff

513 Files Affected:

  • (modified) clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp (+17-36)
  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-2)
  • (modified) clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp (+4-2)
  • (modified) clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp (+8-6)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp (+7-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp (+8-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp (+12-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp (+6-4)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+5-3)
  • (modified) clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp (+25-6)
  • (modified) clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp (+7-2)
  • (modified) clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp (+7-7)
  • (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp (+2-11)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp (+5-4)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp (+2-6)
  • (modified) clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp (+7-8)
  • (modified) clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp (+23-40)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp (+8-10)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp (+3-4)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp (+25-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp (+15-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp (+46-47)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp (+7-9)
  • (modified) clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp (+4-4)
  • (modified) clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp (+7-4)
  • (modified) clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp (+16-10)
  • (modified) clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp (+1-5)
  • (modified) clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp (+3-2)
  • (modified) clang-tools-extra/clang-tidy/utils/Matchers.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp (+12-24)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-1)
  • (modified) clang-tools-extra/clangd/AST.cpp (+57-35)
  • (modified) clang-tools-extra/clangd/AST.h (+2-1)
  • (modified) clang-tools-extra/clangd/CodeComplete.cpp (+7-12)
  • (modified) clang-tools-extra/clangd/DumpAST.cpp (+18-24)
  • (modified) clang-tools-extra/clangd/FindTarget.cpp (+48-78)
  • (modified) clang-tools-extra/clangd/Hover.cpp (+11-9)
  • (modified) clang-tools-extra/clangd/IncludeFixer.cpp (+13-10)
  • (modified) clang-tools-extra/clangd/InlayHints.cpp (+16-12)
  • (modified) clang-tools-extra/clangd/Quality.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/Selection.cpp (+10-7)
  • (modified) clang-tools-extra/clangd/SemanticHighlighting.cpp (+1-16)
  • (modified) clang-tools-extra/clangd/XRefs.cpp (+9-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp (+80-43)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp (+3-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/unittests/ASTTests.cpp (+4-3)
  • (modified) clang-tools-extra/clangd/unittests/DumpASTTests.cpp (+6-9)
  • (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+2-2)
  • (modified) clang-tools-extra/clangd/unittests/HoverTests.cpp (+5-5)
  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+1-8)
  • (modified) clang-tools-extra/clangd/unittests/QualityTests.cpp (+9-5)
  • (modified) clang-tools-extra/clangd/unittests/SelectionTests.cpp (+2-2)
  • (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (+11-18)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp (-1)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp (+3-3)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp (+11-11)
  • (modified) clang/include/clang/AST/ASTConcept.h (+2-7)
  • (modified) clang/include/clang/AST/ASTContext.h (+94-107)
  • (modified) clang/include/clang/AST/ASTImporter.h (+1-1)
  • (modified) clang/include/clang/AST/ASTNodeTraverser.h (+12-11)
  • (modified) clang/include/clang/AST/ASTTypeTraits.h (+8-7)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+17-27)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+18-20)
  • (modified) clang/include/clang/AST/CanonicalType.h (+4-7)
  • (modified) clang/include/clang/AST/Decl.h (+60-37)
  • (modified) clang/include/clang/AST/DeclBase.h (-10)
  • (modified) clang/include/clang/AST/DeclCXX.h (+54-39)
  • (modified) clang/include/clang/AST/DeclObjC.h (+3)
  • (modified) clang/include/clang/AST/DeclTemplate.h (+19-25)
  • (modified) clang/include/clang/AST/DependenceFlags.h (+1-1)
  • (modified) clang/include/clang/AST/DynamicRecursiveASTVisitor.h (+7-6)
  • (modified) clang/include/clang/AST/Expr.h (+2-2)
  • (modified) clang/include/clang/AST/ExprCXX.h (+4-4)
  • (modified) clang/include/clang/AST/JSONNodeDumper.h (-1)
  • (modified) clang/include/clang/AST/NestedNameSpecifier.h (+212-480)
  • (added) clang/include/clang/AST/NestedNameSpecifierBase.h (+585)
  • (modified) clang/include/clang/AST/ODRHash.h (+1-1)
  • (modified) clang/include/clang/AST/PrettyPrinter.h (+3-8)
  • (modified) clang/include/clang/AST/PropertiesBase.td (+3-3)
  • (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+177-105)
  • (modified) clang/include/clang/AST/TemplateBase.h (+17-23)
  • (modified) clang/include/clang/AST/TemplateName.h (+19-11)
  • (modified) clang/include/clang/AST/TextNodeDumper.h (+1-1)
  • (modified) clang/include/clang/AST/Type.h (+412-358)
  • (modified) clang/include/clang/AST/TypeLoc.h (+246-162)
  • (modified) clang/include/clang/AST/TypeProperties.td (+56-84)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+66-91)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchersInternal.h (+7-13)
  • (modified) clang/include/clang/Analysis/FlowSensitive/ASTOps.h (+8-2)
  • (modified) clang/include/clang/Basic/DeclNodes.td (+74-75)
  • (modified) clang/include/clang/Basic/TypeNodes.td (+1-2)
  • (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+2-3)
  • (modified) clang/include/clang/Sema/CodeCompleteConsumer.h (+4-3)
  • (modified) clang/include/clang/Sema/DeclSpec.h (+9-39)
  • (modified) clang/include/clang/Sema/HeuristicResolver.h (+1-2)
  • (modified) clang/include/clang/Sema/ParsedTemplate.h (+16-10)
  • (modified) clang/include/clang/Sema/Sema.h (+17-21)
  • (modified) clang/include/clang/Sema/SemaInternal.h (+4-4)
  • (modified) clang/include/clang/Sema/TypoCorrection.h (+15-14)
  • (modified) clang/include/clang/Serialization/ASTRecordReader.h (+1-1)
  • (modified) clang/include/clang/Serialization/ASTRecordWriter.h (+2-3)
  • (modified) clang/include/clang/Serialization/TypeBitCodes.def (-1)
  • (modified) clang/include/clang/Tooling/Refactoring/Lookup.h (+1-2)
  • (modified) clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h (+9-6)
  • (modified) clang/lib/AST/APValue.cpp (+2-1)
  • (modified) clang/lib/AST/ASTConcept.cpp (+9-2)
  • (modified) clang/lib/AST/ASTContext.cpp (+574-538)
  • (modified) clang/lib/AST/ASTDiagnostic.cpp (+15-34)
  • (modified) clang/lib/AST/ASTDumper.cpp (+3-1)
  • (modified) clang/lib/AST/ASTImporter.cpp (+102-206)
  • (modified) clang/lib/AST/ASTImporterLookupTable.cpp (+8-8)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+81-100)
  • (modified) clang/lib/AST/ASTTypeTraits.cpp (+31-5)
  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-4)
  • (modified) clang/lib/AST/ByteCode/Context.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+5-3)
  • (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-4)
  • (modified) clang/lib/AST/ByteCode/Interp.h (+1-4)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/InterpFrame.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Pointer.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-1)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+10-6)
  • (modified) clang/lib/AST/Comment.cpp (-2)
  • (modified) clang/lib/AST/CommentSema.cpp (+3-11)
  • (modified) clang/lib/AST/ComparisonCategories.cpp (+1-1)
  • (modified) clang/lib/AST/ComputeDependence.cpp (+10-16)
  • (modified) clang/lib/AST/Decl.cpp (+44-71)
  • (modified) clang/lib/AST/DeclBase.cpp (+12-28)
  • (modified) clang/lib/AST/DeclCXX.cpp (+78-56)
  • (modified) clang/lib/AST/DeclPrinter.cpp (+16-44)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+35-37)
  • (modified) clang/lib/AST/DeclarationName.cpp (+3-3)
  • (modified) clang/lib/AST/DynamicRecursiveASTVisitor.cpp (+41-12)
  • (modified) clang/lib/AST/Expr.cpp (+16-9)
  • (modified) clang/lib/AST/ExprCXX.cpp (+4-5)
  • (modified) clang/lib/AST/ExprConcepts.cpp (+2-2)
  • (modified) clang/lib/AST/ExprConstant.cpp (+43-26)
  • (modified) clang/lib/AST/FormatString.cpp (+6-4)
  • (modified) clang/lib/AST/InheritViz.cpp (+3-3)
  • (modified) clang/lib/AST/ItaniumCXXABI.cpp (+4-4)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+76-129)
  • (modified) clang/lib/AST/JSONNodeDumper.cpp (+16-20)
  • (modified) clang/lib/AST/MicrosoftMangle.cpp (+10-11)
  • (modified) clang/lib/AST/NestedNameSpecifier.cpp (+94-429)
  • (modified) clang/lib/AST/ODRHash.cpp (+47-80)
  • (modified) clang/lib/AST/OpenMPClause.cpp (+11-15)
  • (modified) clang/lib/AST/ParentMapContext.cpp (+4-2)
  • (modified) clang/lib/AST/PrintfFormatString.cpp (+1-1)
  • (modified) clang/lib/AST/QualTypeNames.cpp (+183-187)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+13-14)
  • (modified) clang/lib/AST/ScanfFormatString.cpp (+3-2)
  • (modified) clang/lib/AST/StmtPrinter.cpp (+10-23)
  • (modified) clang/lib/AST/StmtProfile.cpp (+7-8)
  • (modified) clang/lib/AST/TemplateBase.cpp (+28-4)
  • (modified) clang/lib/AST/TemplateName.cpp (+31-18)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+50-32)
  • (modified) clang/lib/AST/Type.cpp (+317-154)
  • (modified) clang/lib/AST/TypeLoc.cpp (+206-30)
  • (modified) clang/lib/AST/TypePrinter.cpp (+143-118)
  • (modified) clang/lib/AST/VTTBuilder.cpp (+9-3)
  • (modified) clang/lib/AST/VTableBuilder.cpp (+5-3)
  • (modified) clang/lib/ASTMatchers/ASTMatchFinder.cpp (+63-52)
  • (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+2-3)
  • (modified) clang/lib/ASTMatchers/Dynamic/Registry.cpp (+1-4)
  • (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+4-2)
  • (modified) clang/lib/Analysis/ThreadSafety.cpp (+3-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+2-2)
  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+8-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-1)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+18-18)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCUDANV.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCXX.cpp (+10-9)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+16-11)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+56-39)
  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+65-62)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+9-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+29-16)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+17-8)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+20-17)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+21-8)
  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+7-4)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGNonTrivialStruct.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+6-5)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+21-14)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+1-1)
  • (modified) clang/lib/CodeGen/CGStmt.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGVTables.cpp (+4-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-5)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+3-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+17-11)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+7-6)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+20-13)
  • (modified) clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp (+2-1)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+40-28)
  • (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+13-12)
  • (modified) clang/lib/CodeGen/SwiftCallingConv.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/ARC.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/BPF.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/Hexagon.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/Lanai.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/LoongArch.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/Mips.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/PNaCl.cpp (+2-2)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+5-3)
  • (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/WebAssembly.cpp (+2-1)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+35-24)
  • (modified) clang/lib/CodeGen/Targets/XCore.cpp (+2-2)
  • (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+57-60)
  • (modified) clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp (+1-1)
  • (modified) clang/lib/Frontend/ASTConsumers.cpp (+5-2)
  • (modified) clang/lib/Frontend/ASTUnit.cpp (+1-1)
  • (modified) clang/lib/Index/IndexTypeSourceInfo.cpp (+20-32)
  • (modified) clang/lib/Index/USRGeneration.cpp (+9-9)
  • (modified) clang/lib/InstallAPI/Visitor.cpp (+4-4)
  • (modified) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+1-1)
  • (modified) clang/lib/Interpreter/Value.cpp (+3-3)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+1-2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+8-5)
  • (modified) clang/lib/Parse/ParseTemplate.cpp (+17-12)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+1-1)
  • (modified) clang/lib/Parse/Parser.cpp (+5-4)
  • (modified) clang/lib/Sema/AnalysisBasedWarnings.cpp (+4-7)
  • (modified) clang/lib/Sema/DeclSpec.cpp (+5-31)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+4-19)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+1-1)
  • (modified) clang/lib/Sema/HeuristicResolver.cpp (+23-27)
  • (modified) clang/lib/Sema/Sema.cpp (+12-9)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+21-22)
  • (modified) clang/lib/Sema/SemaAvailability.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaBPF.cpp (+3-3)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-2)
  • (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+184-147)
  • (modified) clang/lib/Sema/SemaCast.cpp (+25-26)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+62-35)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+102-79)
  • (modified) clang/lib/Sema/SemaCoroutine.cpp (+16-19)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+337-254)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+15-8)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+246-238)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+20-12)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+70-55)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+85-77)
  • (modified) clang/lib/Sema/SemaExprMember.cpp (+4-3)
  • (modified) clang/lib/Sema/SemaExprObjC.cpp (+8-7)
  • (modified) clang/lib/Sema/SemaFunctionEffects.cpp (+6-2)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+11-9)
  • (modified) clang/lib/Sema/SemaInit.cpp (+78-67)
  • (modified) clang/lib/Sema/SemaLambda.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+152-88)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+3-1)
  • (modified) clang/lib/Sema/SemaOpenMP.cpp (+8-5)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+96-85)
  • (modified) clang/lib/Sema/SemaPPC.cpp (+4-2)
  • (modified) clang/lib/Sema/SemaSYCL.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaStmt.cpp (+23-17)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+6-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+258-286)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+71-91)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+32-26)
  • (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+75-109)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+37-47)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+21-18)
  • (modified) clang/lib/Sema/SemaType.cpp (+110-74)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+16-19)
  • (modified) clang/lib/Sema/TreeTransform.h (+420-563)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-3)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+58-68)
  • (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+8-20)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+58-55)
  • (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+3-4)
  • (modified) clang/lib/Serialization/TemplateArgumentHasher.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp (+2-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+2-5)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp (+3-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp (+1-4)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp (+5-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+7-9)
  • (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+10-23)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Core/CallEvent.cpp (+7-4)
  • (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Core/RegionStore.cpp (+3-2)
  • (modified) clang/lib/StaticAnalyzer/Core/SValBuilder.cpp (+2-2)
diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
index 3e367ab1a5558..471ca45fb5a53 100644
--- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
+++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
@@ -31,24 +31,9 @@ llvm::SmallVector<llvm::StringRef, 4> splitSymbolName(llvm::StringRef Name) {
   return Splitted;
 }
 
-SourceLocation startLocationForType(TypeLoc TLoc) {
-  // For elaborated types (e.g. `struct a::A`) we want the portion after the
-  // `struct` but including the namespace qualifier, `a::`.
-  if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) {
-    NestedNameSpecifierLoc NestedNameSpecifier =
-        TLoc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-    if (NestedNameSpecifier.getNestedNameSpecifier())
-      return NestedNameSpecifier.getBeginLoc();
-    TLoc = TLoc.getNextTypeLoc();
-  }
-  return TLoc.getBeginLoc();
-}
-
 SourceLocation endLocationForType(TypeLoc TLoc) {
-  // Dig past any namespace or keyword qualifications.
-  while (TLoc.getTypeLocClass() == TypeLoc::Elaborated ||
-         TLoc.getTypeLocClass() == TypeLoc::Qualified)
-    TLoc = TLoc.getNextTypeLoc();
+  if (auto QTL = TLoc.getAs<QualifiedTypeLoc>())
+    TLoc = QTL.getUnqualifiedLoc();
 
   // The location for template specializations (e.g. Foo<int>) includes the
   // templated types in its location range.  We want to restrict this to just
@@ -550,8 +535,8 @@ void ChangeNamespaceTool::run(
                  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
                      "nested_specifier_loc")) {
     SourceLocation Start = Specifier->getBeginLoc();
-    SourceLocation End = endLocationForType(Specifier->getTypeLoc());
-    fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
+    SourceLocation End = endLocationForType(Specifier->castAsTypeLoc());
+    fixTypeLoc(Result, Start, End, Specifier->castAsTypeLoc());
   } else if (const auto *BaseInitializer =
                  Result.Nodes.getNodeAs<CXXCtorInitializer>(
                      "base_initializer")) {
@@ -562,19 +547,16 @@ void ChangeNamespaceTool::run(
     // filtered by matchers in some cases, e.g. the type is templated. We should
     // handle the record type qualifier instead.
     TypeLoc Loc = *TLoc;
-    while (Loc.getTypeLocClass() == TypeLoc::Qualified)
-      Loc = Loc.getNextTypeLoc();
-    if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
-      NestedNameSpecifierLoc NestedNameSpecifier =
-          Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-      // FIXME: avoid changing injected class names.
-      if (auto *NNS = NestedNameSpecifier.getNestedNameSpecifier()) {
-        const Type *SpecifierType = NNS->getAsType();
-        if (SpecifierType && SpecifierType->isRecordType())
-          return;
-      }
-    }
-    fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
+    if (auto QTL = Loc.getAs<QualifiedTypeLoc>())
+      Loc = QTL.getUnqualifiedLoc();
+    // FIXME: avoid changing injected class names.
+    if (NestedNameSpecifier NestedNameSpecifier =
+            Loc.getPrefix().getNestedNameSpecifier();
+        NestedNameSpecifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        NestedNameSpecifier.getAsType()->isRecordType())
+      return;
+    fixTypeLoc(Result, Loc.getNonElaboratedBeginLoc(), endLocationForType(Loc),
+               Loc);
   } else if (const auto *VarRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
     const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
@@ -588,10 +570,9 @@ void ChangeNamespaceTool::run(
   } else if (const auto *EnumConstRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("enum_const_ref")) {
     // Do not rename the reference if it is already scoped by the EnumDecl name.
-    if (EnumConstRef->hasQualifier() &&
-        EnumConstRef->getQualifier()->getKind() ==
-            NestedNameSpecifier::SpecifierKind::TypeSpec &&
-        EnumConstRef->getQualifier()->getAsType()->isEnumeralType())
+    if (NestedNameSpecifier Qualifier = EnumConstRef->getQualifier();
+        Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        Qualifier.getAsType()->isEnumeralType())
       return;
     const auto *EnumConstDecl =
         Result.Nodes.getNodeAs<EnumConstantDecl>("enum_const_decl");
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 6cc372ce98a6d..8ac807b935a04 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -883,8 +883,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
     if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base =
-              cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition())) {
+      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
+              Ty->getOriginalDecl()->getDefinition())) {
         // Initialized without USR and name, this will be set in the following
         // if-else stmt.
         BaseRecordInfo BI(
diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
index bb48883f88815..1f30d27c0a54f 100644
--- a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
@@ -216,8 +216,7 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {
   // Uses of most types: just look at what the typeLoc refers to.
   MatchFinder->addMatcher(
       typeLoc(isExpansionInMainFile(),
-              loc(qualType(allOf(unless(elaboratedType()),
-                                 hasDeclaration(Types.bind("use")))))),
+              loc(qualType(hasDeclaration(Types.bind("use"))))),
       this);
   // Uses of typedefs: these are often transparent to hasDeclaration, so we need
   // to handle them explicitly.
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index f9d75978d0ea8..fac6e0418d163 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -533,7 +533,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
       Builder << reinterpret_cast<const NamedDecl *>(Info.getRawArg(Index));
       break;
     case clang::DiagnosticsEngine::ak_nestednamespec:
-      Builder << reinterpret_cast<NestedNameSpecifier *>(Info.getRawArg(Index));
+      Builder << NestedNameSpecifier::getFromVoidPointer(
+          reinterpret_cast<void *>(Info.getRawArg(Index)));
       break;
     case clang::DiagnosticsEngine::ak_declcontext:
       Builder << reinterpret_cast<DeclContext *>(Info.getRawArg(Index));
diff --git a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
index 28e8fe002d575..5bce285bea7b9 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
@@ -43,7 +43,8 @@ static bool isDerivedClassBefriended(const CXXRecordDecl *CRTP,
       return false;
     }
 
-    return FriendType->getType()->getAsCXXRecordDecl() == Derived;
+    return declaresSameEntity(FriendType->getType()->getAsCXXRecordDecl(),
+                              Derived);
   });
 }
 
@@ -55,7 +56,8 @@ getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP,
       CRTP->getTemplateArgs().asArray(), [&](const TemplateArgument &Arg) {
         ++Idx;
         return Arg.getKind() == TemplateArgument::Type &&
-               Arg.getAsType()->getAsCXXRecordDecl() == Derived;
+               declaresSameEntity(Arg.getAsType()->getAsCXXRecordDecl(),
+                                  Derived);
       });
 
   return AnyOf ? CRTP->getSpecializedTemplate()
diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
index a179d4bf66b4d..3cacb90cace52 100644
--- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
@@ -577,7 +577,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType,
                               ImplicitConversionModellingMode ImplicitMode);
 
 static inline bool isUselessSugar(const Type *T) {
-  return isa<AttributedType, DecayedType, ElaboratedType, ParenType>(T);
+  return isa<AttributedType, DecayedType, ParenType>(T);
 }
 
 namespace {
@@ -1040,7 +1040,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
   const auto *ToRecord = To->getAsCXXRecordDecl();
   if (isDerivedToBase(FromRecord, ToRecord)) {
     LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n");
-    WorkType = QualType{ToRecord->getTypeForDecl(), FastQualifiersToApply};
+    WorkType = QualType{
+        ToRecord->getASTContext().getCanonicalTagType(ToRecord)->getTypePtr(),
+        FastQualifiersToApply};
   }
 
   if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) {
@@ -1072,9 +1074,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
     WorkType = To;
   }
 
-  if (WorkType == To) {
+  if (Ctx.hasSameType(WorkType, To)) {
     LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Reached 'To' type.\n");
-    return {WorkType};
+    return {Ctx.getCommonSugaredType(WorkType, To)};
   }
 
   LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Did not reach 'To'.\n");
@@ -1219,7 +1221,7 @@ tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{RecordType, ToType};
     // The conversion from the operator call's return type to ToType was
@@ -1270,7 +1272,7 @@ tryConvertingConstructors(const TheCheck &Check, QualType FromType,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{FromType, RecordType};
     Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard;
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
index 75ef628436738..070ed04efffc4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
@@ -69,10 +69,9 @@ void ForwardDeclarationNamespaceCheck::check(
     //      struct B { friend A; };
     //    \endcode
     // `A` will not be marked as "referenced" in the AST.
-    if (const TypeSourceInfo *Tsi = Decl->getFriendType()) {
-      QualType Desugared = Tsi->getType().getDesugaredType(*Result.Context);
-      FriendTypes.insert(Desugared.getTypePtr());
-    }
+    if (const TypeSourceInfo *Tsi = Decl->getFriendType())
+      FriendTypes.insert(
+          Tsi->getType()->getCanonicalTypeUnqualified().getTypePtr());
   }
 }
 
@@ -119,7 +118,9 @@ void ForwardDeclarationNamespaceCheck::onEndOfTranslationUnit() {
       if (CurDecl->hasDefinition() || CurDecl->isReferenced()) {
         continue; // Skip forward declarations that are used/referenced.
       }
-      if (FriendTypes.contains(CurDecl->getTypeForDecl())) {
+      if (FriendTypes.contains(CurDecl->getASTContext()
+                                   .getCanonicalTagType(CurDecl)
+                                   ->getTypePtr())) {
         continue; // Skip forward declarations referenced as friend.
       }
       if (CurDecl->getLocation().isMacroID() ||
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
index 00e8f7e514368..10b747e17e2ad 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
@@ -33,21 +33,17 @@ AST_MATCHER(QualType, isEnableIf) {
     BaseType = BaseType->getPointeeType().getTypePtr();
   }
   // Case: type parameter dependent (enable_if<is_integral<T>>).
-  if (const auto *Dependent = BaseType->getAs<DependentNameType>()) {
-    BaseType = Dependent->getQualifier()->getAsType();
-  }
+  if (const auto *Dependent = BaseType->getAs<DependentNameType>())
+    BaseType = Dependent->getQualifier().getAsType();
   if (!BaseType)
     return false;
   if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>()))
     return true; // Case: enable_if_t< >.
-  if (const auto *Elaborated = BaseType->getAs<ElaboratedType>()) {
-    if (const auto *Q = Elaborated->getQualifier())
-      if (const auto *Qualifier = Q->getAsType()) {
-        if (CheckTemplate(Qualifier->getAs<TemplateSpecializationType>())) {
-          return true; // Case: enable_if< >::type.
-        }
-      }
-  }
+  if (const auto *TT = BaseType->getAs<TypedefType>())
+    if (NestedNameSpecifier Q = TT->getQualifier();
+        Q.getKind() == NestedNameSpecifier::Kind::Type)
+      if (CheckTemplate(Q.getAsType()->getAs<TemplateSpecializationType>()))
+        return true; // Case: enable_if< >::type.
   return false;
 }
 AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument,
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
index 75f1107904fce..07cd90d64c2a4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
@@ -32,13 +32,10 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument,
 void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       templateTypeParmDecl(
-          hasUnnamedDefaultArgument(
-              elaboratedTypeLoc(
-                  hasNamedTypeLoc(templateSpecializationTypeLoc(
-                                      loc(qualType(hasDeclaration(namedDecl(
-                                          hasName("::std::enable_if"))))))
-                                      .bind("enable_if_specialization")))
-                  .bind("elaborated")))
+          hasUnnamedDefaultArgument(templateSpecializationTypeLoc(
+                                        loc(qualType(hasDeclaration(namedDecl(
+                                            hasName("::std::enable_if"))))))
+                                        .bind("enable_if_specialization")))
           .bind("enable_if"),
       this);
 }
@@ -46,13 +43,11 @@ void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
 void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *EnableIf =
       Result.Nodes.getNodeAs<TemplateTypeParmDecl>("enable_if");
-  const auto *ElaboratedLoc =
-      Result.Nodes.getNodeAs<ElaboratedTypeLoc>("elaborated");
   const auto *EnableIfSpecializationLoc =
       Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
           "enable_if_specialization");
 
-  if (!EnableIf || !ElaboratedLoc || !EnableIfSpecializationLoc)
+  if (!EnableIf || !EnableIfSpecializationLoc)
     return;
 
   const SourceManager &SM = *Result.SourceManager;
@@ -62,8 +57,10 @@ void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   auto Diag = diag(EnableIf->getBeginLoc(),
                    "incorrect std::enable_if usage detected; use "
                    "'typename std::enable_if<...>::type'");
+  // FIXME: This should handle the enable_if specialization already having an
+  // elaborated keyword.
   if (!getLangOpts().CPlusPlus20) {
-    Diag << FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(),
+    Diag << FixItHint::CreateInsertion(EnableIfSpecializationLoc->getBeginLoc(),
                                        "typename ");
   }
   Diag << FixItHint::CreateInsertion(RAngleLoc.getLocWithOffset(1), "::type");
diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
index 33642c407a3a9..5dc988d6662df 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
@@ -39,24 +39,31 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
     // std::move(). This will hopefully prevent erroneous replacements if the
     // code does unusual things (e.g. create an alias for std::move() in
     // another namespace).
-    NestedNameSpecifier *NNS = Callee->getQualifier();
-    if (!NNS) {
+    NestedNameSpecifier NNS = Callee->getQualifier();
+    switch (NNS.getKind()) {
+    case NestedNameSpecifier::Kind::Null:
       // Called as "move" (i.e. presumably the code had a "using std::move;").
       // We still conservatively put a "std::" in front of the forward because
       // we don't know whether the code also had a "using std::forward;".
       Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
-    } else if (const NamespaceDecl *Namespace = NNS->getAsNamespace()) {
+      break;
+    case NestedNameSpecifier::Kind::Namespace: {
+      auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
       if (Namespace->getName() == "std") {
-        if (!NNS->getPrefix()) {
+        if (!Prefix) {
           // Called as "std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "std::" + ForwardName);
-        } else if (NNS->getPrefix()->getKind() == NestedNameSpecifier::Global) {
+        } else if (Prefix.getKind() == NestedNameSpecifier::Kind::Global) {
           // Called as "::std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "::std::" + ForwardName);
         }
       }
+      break;
+    }
+    default:
+      return;
     }
   }
 }
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index 88d2f2c388d07..c29eec2d2abe8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -425,7 +425,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
            "suspicious usage of 'sizeof(array)/sizeof(...)';"
            " denominator differs from the size of array elements")
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-    } else if (NumTy && DenomTy && NumTy == DenomTy &&
+    } else if (NumTy && DenomTy && Ctx.hasSameType(NumTy, DenomTy) &&
                !NumTy->isDependentType()) {
       // Dependent type should not be compared.
       diag(E->getOperatorLoc(),
@@ -434,7 +434,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
     } else if (!WarnOnSizeOfPointer) {
       // When 'WarnOnSizeOfPointer' is enabled, these messages become redundant:
-      if (PointedTy && DenomTy && PointedTy == DenomTy) {
+      if (PointedTy && DenomTy && Ctx.hasSameType(PointedTy, DenomTy)) {
         diag(E->getOperatorLoc(),
              "suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer "
              "is divided by size of pointed type")
@@ -463,7 +463,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
     const auto *SizeOfExpr =
         Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-mul-expr");
 
-    if ((LP...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jul 9, 2025

@llvm/pr-subscribers-backend-amdgpu

Author: Matheus Izvekov (mizvekov)

Changes

This is a major change on how we represent nested name qualifications in the AST.

  • The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy.
  • The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present.
  • TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for stdexec. For one datapoint, for test_on2.cpp in that project, which is the slowest compiling test, this patch improves -c compilation time by about 7.2%, with the -fsyntax-only improvement being at ~12%.

This has great results on compile-time-tracker as well:
image

This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in clang/include/clang/AST and clang/lib/AST, with also import changes in clang/lib/Sema/TreeTransform.h.

The rest and bulk of the changes are mostly consequences of the changes in API.

PS: TagType::getDecl is renamed to getOriginalDecl in this patch, just for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes #147000


Patch is 2.13 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/147835.diff

513 Files Affected:

  • (modified) clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp (+17-36)
  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-2)
  • (modified) clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp (+4-2)
  • (modified) clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp (+8-6)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp (+7-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp (+8-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp (+12-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp (+6-4)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+5-3)
  • (modified) clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp (+25-6)
  • (modified) clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp (+7-2)
  • (modified) clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp (+7-7)
  • (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp (+2-11)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp (+5-4)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp (+2-6)
  • (modified) clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp (+7-8)
  • (modified) clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp (+23-40)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp (+8-10)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp (+3-4)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp (+25-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp (+15-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp (+46-47)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp (+7-9)
  • (modified) clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp (+4-4)
  • (modified) clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp (+7-4)
  • (modified) clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp (+16-10)
  • (modified) clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp (+1-5)
  • (modified) clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp (+3-2)
  • (modified) clang-tools-extra/clang-tidy/utils/Matchers.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp (+12-24)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-1)
  • (modified) clang-tools-extra/clangd/AST.cpp (+57-35)
  • (modified) clang-tools-extra/clangd/AST.h (+2-1)
  • (modified) clang-tools-extra/clangd/CodeComplete.cpp (+7-12)
  • (modified) clang-tools-extra/clangd/DumpAST.cpp (+18-24)
  • (modified) clang-tools-extra/clangd/FindTarget.cpp (+48-78)
  • (modified) clang-tools-extra/clangd/Hover.cpp (+11-9)
  • (modified) clang-tools-extra/clangd/IncludeFixer.cpp (+13-10)
  • (modified) clang-tools-extra/clangd/InlayHints.cpp (+16-12)
  • (modified) clang-tools-extra/clangd/Quality.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/Selection.cpp (+10-7)
  • (modified) clang-tools-extra/clangd/SemanticHighlighting.cpp (+1-16)
  • (modified) clang-tools-extra/clangd/XRefs.cpp (+9-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp (+80-43)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp (+3-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/unittests/ASTTests.cpp (+4-3)
  • (modified) clang-tools-extra/clangd/unittests/DumpASTTests.cpp (+6-9)
  • (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+2-2)
  • (modified) clang-tools-extra/clangd/unittests/HoverTests.cpp (+5-5)
  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+1-8)
  • (modified) clang-tools-extra/clangd/unittests/QualityTests.cpp (+9-5)
  • (modified) clang-tools-extra/clangd/unittests/SelectionTests.cpp (+2-2)
  • (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (+11-18)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp (-1)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp (+3-3)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp (+11-11)
  • (modified) clang/include/clang/AST/ASTConcept.h (+2-7)
  • (modified) clang/include/clang/AST/ASTContext.h (+94-107)
  • (modified) clang/include/clang/AST/ASTImporter.h (+1-1)
  • (modified) clang/include/clang/AST/ASTNodeTraverser.h (+12-11)
  • (modified) clang/include/clang/AST/ASTTypeTraits.h (+8-7)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+17-27)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+18-20)
  • (modified) clang/include/clang/AST/CanonicalType.h (+4-7)
  • (modified) clang/include/clang/AST/Decl.h (+60-37)
  • (modified) clang/include/clang/AST/DeclBase.h (-10)
  • (modified) clang/include/clang/AST/DeclCXX.h (+54-39)
  • (modified) clang/include/clang/AST/DeclObjC.h (+3)
  • (modified) clang/include/clang/AST/DeclTemplate.h (+19-25)
  • (modified) clang/include/clang/AST/DependenceFlags.h (+1-1)
  • (modified) clang/include/clang/AST/DynamicRecursiveASTVisitor.h (+7-6)
  • (modified) clang/include/clang/AST/Expr.h (+2-2)
  • (modified) clang/include/clang/AST/ExprCXX.h (+4-4)
  • (modified) clang/include/clang/AST/JSONNodeDumper.h (-1)
  • (modified) clang/include/clang/AST/NestedNameSpecifier.h (+212-480)
  • (added) clang/include/clang/AST/NestedNameSpecifierBase.h (+585)
  • (modified) clang/include/clang/AST/ODRHash.h (+1-1)
  • (modified) clang/include/clang/AST/PrettyPrinter.h (+3-8)
  • (modified) clang/include/clang/AST/PropertiesBase.td (+3-3)
  • (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+177-105)
  • (modified) clang/include/clang/AST/TemplateBase.h (+17-23)
  • (modified) clang/include/clang/AST/TemplateName.h (+19-11)
  • (modified) clang/include/clang/AST/TextNodeDumper.h (+1-1)
  • (modified) clang/include/clang/AST/Type.h (+412-358)
  • (modified) clang/include/clang/AST/TypeLoc.h (+246-162)
  • (modified) clang/include/clang/AST/TypeProperties.td (+56-84)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+66-91)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchersInternal.h (+7-13)
  • (modified) clang/include/clang/Analysis/FlowSensitive/ASTOps.h (+8-2)
  • (modified) clang/include/clang/Basic/DeclNodes.td (+74-75)
  • (modified) clang/include/clang/Basic/TypeNodes.td (+1-2)
  • (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+2-3)
  • (modified) clang/include/clang/Sema/CodeCompleteConsumer.h (+4-3)
  • (modified) clang/include/clang/Sema/DeclSpec.h (+9-39)
  • (modified) clang/include/clang/Sema/HeuristicResolver.h (+1-2)
  • (modified) clang/include/clang/Sema/ParsedTemplate.h (+16-10)
  • (modified) clang/include/clang/Sema/Sema.h (+17-21)
  • (modified) clang/include/clang/Sema/SemaInternal.h (+4-4)
  • (modified) clang/include/clang/Sema/TypoCorrection.h (+15-14)
  • (modified) clang/include/clang/Serialization/ASTRecordReader.h (+1-1)
  • (modified) clang/include/clang/Serialization/ASTRecordWriter.h (+2-3)
  • (modified) clang/include/clang/Serialization/TypeBitCodes.def (-1)
  • (modified) clang/include/clang/Tooling/Refactoring/Lookup.h (+1-2)
  • (modified) clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h (+9-6)
  • (modified) clang/lib/AST/APValue.cpp (+2-1)
  • (modified) clang/lib/AST/ASTConcept.cpp (+9-2)
  • (modified) clang/lib/AST/ASTContext.cpp (+574-538)
  • (modified) clang/lib/AST/ASTDiagnostic.cpp (+15-34)
  • (modified) clang/lib/AST/ASTDumper.cpp (+3-1)
  • (modified) clang/lib/AST/ASTImporter.cpp (+102-206)
  • (modified) clang/lib/AST/ASTImporterLookupTable.cpp (+8-8)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+81-100)
  • (modified) clang/lib/AST/ASTTypeTraits.cpp (+31-5)
  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-4)
  • (modified) clang/lib/AST/ByteCode/Context.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+5-3)
  • (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-4)
  • (modified) clang/lib/AST/ByteCode/Interp.h (+1-4)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/InterpFrame.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Pointer.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-1)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+10-6)
  • (modified) clang/lib/AST/Comment.cpp (-2)
  • (modified) clang/lib/AST/CommentSema.cpp (+3-11)
  • (modified) clang/lib/AST/ComparisonCategories.cpp (+1-1)
  • (modified) clang/lib/AST/ComputeDependence.cpp (+10-16)
  • (modified) clang/lib/AST/Decl.cpp (+44-71)
  • (modified) clang/lib/AST/DeclBase.cpp (+12-28)
  • (modified) clang/lib/AST/DeclCXX.cpp (+78-56)
  • (modified) clang/lib/AST/DeclPrinter.cpp (+16-44)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+35-37)
  • (modified) clang/lib/AST/DeclarationName.cpp (+3-3)
  • (modified) clang/lib/AST/DynamicRecursiveASTVisitor.cpp (+41-12)
  • (modified) clang/lib/AST/Expr.cpp (+16-9)
  • (modified) clang/lib/AST/ExprCXX.cpp (+4-5)
  • (modified) clang/lib/AST/ExprConcepts.cpp (+2-2)
  • (modified) clang/lib/AST/ExprConstant.cpp (+43-26)
  • (modified) clang/lib/AST/FormatString.cpp (+6-4)
  • (modified) clang/lib/AST/InheritViz.cpp (+3-3)
  • (modified) clang/lib/AST/ItaniumCXXABI.cpp (+4-4)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+76-129)
  • (modified) clang/lib/AST/JSONNodeDumper.cpp (+16-20)
  • (modified) clang/lib/AST/MicrosoftMangle.cpp (+10-11)
  • (modified) clang/lib/AST/NestedNameSpecifier.cpp (+94-429)
  • (modified) clang/lib/AST/ODRHash.cpp (+47-80)
  • (modified) clang/lib/AST/OpenMPClause.cpp (+11-15)
  • (modified) clang/lib/AST/ParentMapContext.cpp (+4-2)
  • (modified) clang/lib/AST/PrintfFormatString.cpp (+1-1)
  • (modified) clang/lib/AST/QualTypeNames.cpp (+183-187)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+13-14)
  • (modified) clang/lib/AST/ScanfFormatString.cpp (+3-2)
  • (modified) clang/lib/AST/StmtPrinter.cpp (+10-23)
  • (modified) clang/lib/AST/StmtProfile.cpp (+7-8)
  • (modified) clang/lib/AST/TemplateBase.cpp (+28-4)
  • (modified) clang/lib/AST/TemplateName.cpp (+31-18)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+50-32)
  • (modified) clang/lib/AST/Type.cpp (+317-154)
  • (modified) clang/lib/AST/TypeLoc.cpp (+206-30)
  • (modified) clang/lib/AST/TypePrinter.cpp (+143-118)
  • (modified) clang/lib/AST/VTTBuilder.cpp (+9-3)
  • (modified) clang/lib/AST/VTableBuilder.cpp (+5-3)
  • (modified) clang/lib/ASTMatchers/ASTMatchFinder.cpp (+63-52)
  • (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+2-3)
  • (modified) clang/lib/ASTMatchers/Dynamic/Registry.cpp (+1-4)
  • (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+4-2)
  • (modified) clang/lib/Analysis/ThreadSafety.cpp (+3-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+2-2)
  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+8-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-1)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+18-18)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCUDANV.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCXX.cpp (+10-9)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+16-11)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+56-39)
  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+65-62)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+9-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+29-16)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+17-8)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+20-17)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+21-8)
  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+7-4)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGNonTrivialStruct.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+6-5)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+21-14)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+1-1)
  • (modified) clang/lib/CodeGen/CGStmt.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGVTables.cpp (+4-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-5)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+3-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+17-11)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+7-6)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+20-13)
  • (modified) clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp (+2-1)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+40-28)
  • (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+13-12)
  • (modified) clang/lib/CodeGen/SwiftCallingConv.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/ARC.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/BPF.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/Hexagon.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/Lanai.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/LoongArch.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/Mips.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/PNaCl.cpp (+2-2)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+5-3)
  • (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/WebAssembly.cpp (+2-1)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+35-24)
  • (modified) clang/lib/CodeGen/Targets/XCore.cpp (+2-2)
  • (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+57-60)
  • (modified) clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp (+1-1)
  • (modified) clang/lib/Frontend/ASTConsumers.cpp (+5-2)
  • (modified) clang/lib/Frontend/ASTUnit.cpp (+1-1)
  • (modified) clang/lib/Index/IndexTypeSourceInfo.cpp (+20-32)
  • (modified) clang/lib/Index/USRGeneration.cpp (+9-9)
  • (modified) clang/lib/InstallAPI/Visitor.cpp (+4-4)
  • (modified) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+1-1)
  • (modified) clang/lib/Interpreter/Value.cpp (+3-3)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+1-2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+8-5)
  • (modified) clang/lib/Parse/ParseTemplate.cpp (+17-12)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+1-1)
  • (modified) clang/lib/Parse/Parser.cpp (+5-4)
  • (modified) clang/lib/Sema/AnalysisBasedWarnings.cpp (+4-7)
  • (modified) clang/lib/Sema/DeclSpec.cpp (+5-31)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+4-19)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+1-1)
  • (modified) clang/lib/Sema/HeuristicResolver.cpp (+23-27)
  • (modified) clang/lib/Sema/Sema.cpp (+12-9)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+21-22)
  • (modified) clang/lib/Sema/SemaAvailability.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaBPF.cpp (+3-3)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-2)
  • (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+184-147)
  • (modified) clang/lib/Sema/SemaCast.cpp (+25-26)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+62-35)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+102-79)
  • (modified) clang/lib/Sema/SemaCoroutine.cpp (+16-19)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+337-254)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+15-8)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+246-238)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+20-12)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+70-55)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+85-77)
  • (modified) clang/lib/Sema/SemaExprMember.cpp (+4-3)
  • (modified) clang/lib/Sema/SemaExprObjC.cpp (+8-7)
  • (modified) clang/lib/Sema/SemaFunctionEffects.cpp (+6-2)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+11-9)
  • (modified) clang/lib/Sema/SemaInit.cpp (+78-67)
  • (modified) clang/lib/Sema/SemaLambda.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+152-88)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+3-1)
  • (modified) clang/lib/Sema/SemaOpenMP.cpp (+8-5)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+96-85)
  • (modified) clang/lib/Sema/SemaPPC.cpp (+4-2)
  • (modified) clang/lib/Sema/SemaSYCL.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaStmt.cpp (+23-17)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+6-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+258-286)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+71-91)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+32-26)
  • (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+75-109)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+37-47)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+21-18)
  • (modified) clang/lib/Sema/SemaType.cpp (+110-74)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+16-19)
  • (modified) clang/lib/Sema/TreeTransform.h (+420-563)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-3)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+58-68)
  • (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+8-20)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+58-55)
  • (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+3-4)
  • (modified) clang/lib/Serialization/TemplateArgumentHasher.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp (+2-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+2-5)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp (+3-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp (+1-4)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp (+5-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+7-9)
  • (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+10-23)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Core/CallEvent.cpp (+7-4)
  • (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Core/RegionStore.cpp (+3-2)
  • (modified) clang/lib/StaticAnalyzer/Core/SValBuilder.cpp (+2-2)
diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
index 3e367ab1a5558..471ca45fb5a53 100644
--- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
+++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
@@ -31,24 +31,9 @@ llvm::SmallVector<llvm::StringRef, 4> splitSymbolName(llvm::StringRef Name) {
   return Splitted;
 }
 
-SourceLocation startLocationForType(TypeLoc TLoc) {
-  // For elaborated types (e.g. `struct a::A`) we want the portion after the
-  // `struct` but including the namespace qualifier, `a::`.
-  if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) {
-    NestedNameSpecifierLoc NestedNameSpecifier =
-        TLoc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-    if (NestedNameSpecifier.getNestedNameSpecifier())
-      return NestedNameSpecifier.getBeginLoc();
-    TLoc = TLoc.getNextTypeLoc();
-  }
-  return TLoc.getBeginLoc();
-}
-
 SourceLocation endLocationForType(TypeLoc TLoc) {
-  // Dig past any namespace or keyword qualifications.
-  while (TLoc.getTypeLocClass() == TypeLoc::Elaborated ||
-         TLoc.getTypeLocClass() == TypeLoc::Qualified)
-    TLoc = TLoc.getNextTypeLoc();
+  if (auto QTL = TLoc.getAs<QualifiedTypeLoc>())
+    TLoc = QTL.getUnqualifiedLoc();
 
   // The location for template specializations (e.g. Foo<int>) includes the
   // templated types in its location range.  We want to restrict this to just
@@ -550,8 +535,8 @@ void ChangeNamespaceTool::run(
                  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
                      "nested_specifier_loc")) {
     SourceLocation Start = Specifier->getBeginLoc();
-    SourceLocation End = endLocationForType(Specifier->getTypeLoc());
-    fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
+    SourceLocation End = endLocationForType(Specifier->castAsTypeLoc());
+    fixTypeLoc(Result, Start, End, Specifier->castAsTypeLoc());
   } else if (const auto *BaseInitializer =
                  Result.Nodes.getNodeAs<CXXCtorInitializer>(
                      "base_initializer")) {
@@ -562,19 +547,16 @@ void ChangeNamespaceTool::run(
     // filtered by matchers in some cases, e.g. the type is templated. We should
     // handle the record type qualifier instead.
     TypeLoc Loc = *TLoc;
-    while (Loc.getTypeLocClass() == TypeLoc::Qualified)
-      Loc = Loc.getNextTypeLoc();
-    if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
-      NestedNameSpecifierLoc NestedNameSpecifier =
-          Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-      // FIXME: avoid changing injected class names.
-      if (auto *NNS = NestedNameSpecifier.getNestedNameSpecifier()) {
-        const Type *SpecifierType = NNS->getAsType();
-        if (SpecifierType && SpecifierType->isRecordType())
-          return;
-      }
-    }
-    fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
+    if (auto QTL = Loc.getAs<QualifiedTypeLoc>())
+      Loc = QTL.getUnqualifiedLoc();
+    // FIXME: avoid changing injected class names.
+    if (NestedNameSpecifier NestedNameSpecifier =
+            Loc.getPrefix().getNestedNameSpecifier();
+        NestedNameSpecifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        NestedNameSpecifier.getAsType()->isRecordType())
+      return;
+    fixTypeLoc(Result, Loc.getNonElaboratedBeginLoc(), endLocationForType(Loc),
+               Loc);
   } else if (const auto *VarRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
     const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
@@ -588,10 +570,9 @@ void ChangeNamespaceTool::run(
   } else if (const auto *EnumConstRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("enum_const_ref")) {
     // Do not rename the reference if it is already scoped by the EnumDecl name.
-    if (EnumConstRef->hasQualifier() &&
-        EnumConstRef->getQualifier()->getKind() ==
-            NestedNameSpecifier::SpecifierKind::TypeSpec &&
-        EnumConstRef->getQualifier()->getAsType()->isEnumeralType())
+    if (NestedNameSpecifier Qualifier = EnumConstRef->getQualifier();
+        Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        Qualifier.getAsType()->isEnumeralType())
       return;
     const auto *EnumConstDecl =
         Result.Nodes.getNodeAs<EnumConstantDecl>("enum_const_decl");
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 6cc372ce98a6d..8ac807b935a04 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -883,8 +883,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
     if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base =
-              cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition())) {
+      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
+              Ty->getOriginalDecl()->getDefinition())) {
         // Initialized without USR and name, this will be set in the following
         // if-else stmt.
         BaseRecordInfo BI(
diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
index bb48883f88815..1f30d27c0a54f 100644
--- a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
@@ -216,8 +216,7 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {
   // Uses of most types: just look at what the typeLoc refers to.
   MatchFinder->addMatcher(
       typeLoc(isExpansionInMainFile(),
-              loc(qualType(allOf(unless(elaboratedType()),
-                                 hasDeclaration(Types.bind("use")))))),
+              loc(qualType(hasDeclaration(Types.bind("use"))))),
       this);
   // Uses of typedefs: these are often transparent to hasDeclaration, so we need
   // to handle them explicitly.
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index f9d75978d0ea8..fac6e0418d163 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -533,7 +533,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
       Builder << reinterpret_cast<const NamedDecl *>(Info.getRawArg(Index));
       break;
     case clang::DiagnosticsEngine::ak_nestednamespec:
-      Builder << reinterpret_cast<NestedNameSpecifier *>(Info.getRawArg(Index));
+      Builder << NestedNameSpecifier::getFromVoidPointer(
+          reinterpret_cast<void *>(Info.getRawArg(Index)));
       break;
     case clang::DiagnosticsEngine::ak_declcontext:
       Builder << reinterpret_cast<DeclContext *>(Info.getRawArg(Index));
diff --git a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
index 28e8fe002d575..5bce285bea7b9 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
@@ -43,7 +43,8 @@ static bool isDerivedClassBefriended(const CXXRecordDecl *CRTP,
       return false;
     }
 
-    return FriendType->getType()->getAsCXXRecordDecl() == Derived;
+    return declaresSameEntity(FriendType->getType()->getAsCXXRecordDecl(),
+                              Derived);
   });
 }
 
@@ -55,7 +56,8 @@ getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP,
       CRTP->getTemplateArgs().asArray(), [&](const TemplateArgument &Arg) {
         ++Idx;
         return Arg.getKind() == TemplateArgument::Type &&
-               Arg.getAsType()->getAsCXXRecordDecl() == Derived;
+               declaresSameEntity(Arg.getAsType()->getAsCXXRecordDecl(),
+                                  Derived);
       });
 
   return AnyOf ? CRTP->getSpecializedTemplate()
diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
index a179d4bf66b4d..3cacb90cace52 100644
--- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
@@ -577,7 +577,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType,
                               ImplicitConversionModellingMode ImplicitMode);
 
 static inline bool isUselessSugar(const Type *T) {
-  return isa<AttributedType, DecayedType, ElaboratedType, ParenType>(T);
+  return isa<AttributedType, DecayedType, ParenType>(T);
 }
 
 namespace {
@@ -1040,7 +1040,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
   const auto *ToRecord = To->getAsCXXRecordDecl();
   if (isDerivedToBase(FromRecord, ToRecord)) {
     LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n");
-    WorkType = QualType{ToRecord->getTypeForDecl(), FastQualifiersToApply};
+    WorkType = QualType{
+        ToRecord->getASTContext().getCanonicalTagType(ToRecord)->getTypePtr(),
+        FastQualifiersToApply};
   }
 
   if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) {
@@ -1072,9 +1074,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
     WorkType = To;
   }
 
-  if (WorkType == To) {
+  if (Ctx.hasSameType(WorkType, To)) {
     LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Reached 'To' type.\n");
-    return {WorkType};
+    return {Ctx.getCommonSugaredType(WorkType, To)};
   }
 
   LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Did not reach 'To'.\n");
@@ -1219,7 +1221,7 @@ tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{RecordType, ToType};
     // The conversion from the operator call's return type to ToType was
@@ -1270,7 +1272,7 @@ tryConvertingConstructors(const TheCheck &Check, QualType FromType,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{FromType, RecordType};
     Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard;
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
index 75ef628436738..070ed04efffc4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
@@ -69,10 +69,9 @@ void ForwardDeclarationNamespaceCheck::check(
     //      struct B { friend A; };
     //    \endcode
     // `A` will not be marked as "referenced" in the AST.
-    if (const TypeSourceInfo *Tsi = Decl->getFriendType()) {
-      QualType Desugared = Tsi->getType().getDesugaredType(*Result.Context);
-      FriendTypes.insert(Desugared.getTypePtr());
-    }
+    if (const TypeSourceInfo *Tsi = Decl->getFriendType())
+      FriendTypes.insert(
+          Tsi->getType()->getCanonicalTypeUnqualified().getTypePtr());
   }
 }
 
@@ -119,7 +118,9 @@ void ForwardDeclarationNamespaceCheck::onEndOfTranslationUnit() {
       if (CurDecl->hasDefinition() || CurDecl->isReferenced()) {
         continue; // Skip forward declarations that are used/referenced.
       }
-      if (FriendTypes.contains(CurDecl->getTypeForDecl())) {
+      if (FriendTypes.contains(CurDecl->getASTContext()
+                                   .getCanonicalTagType(CurDecl)
+                                   ->getTypePtr())) {
         continue; // Skip forward declarations referenced as friend.
       }
       if (CurDecl->getLocation().isMacroID() ||
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
index 00e8f7e514368..10b747e17e2ad 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
@@ -33,21 +33,17 @@ AST_MATCHER(QualType, isEnableIf) {
     BaseType = BaseType->getPointeeType().getTypePtr();
   }
   // Case: type parameter dependent (enable_if<is_integral<T>>).
-  if (const auto *Dependent = BaseType->getAs<DependentNameType>()) {
-    BaseType = Dependent->getQualifier()->getAsType();
-  }
+  if (const auto *Dependent = BaseType->getAs<DependentNameType>())
+    BaseType = Dependent->getQualifier().getAsType();
   if (!BaseType)
     return false;
   if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>()))
     return true; // Case: enable_if_t< >.
-  if (const auto *Elaborated = BaseType->getAs<ElaboratedType>()) {
-    if (const auto *Q = Elaborated->getQualifier())
-      if (const auto *Qualifier = Q->getAsType()) {
-        if (CheckTemplate(Qualifier->getAs<TemplateSpecializationType>())) {
-          return true; // Case: enable_if< >::type.
-        }
-      }
-  }
+  if (const auto *TT = BaseType->getAs<TypedefType>())
+    if (NestedNameSpecifier Q = TT->getQualifier();
+        Q.getKind() == NestedNameSpecifier::Kind::Type)
+      if (CheckTemplate(Q.getAsType()->getAs<TemplateSpecializationType>()))
+        return true; // Case: enable_if< >::type.
   return false;
 }
 AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument,
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
index 75f1107904fce..07cd90d64c2a4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
@@ -32,13 +32,10 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument,
 void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       templateTypeParmDecl(
-          hasUnnamedDefaultArgument(
-              elaboratedTypeLoc(
-                  hasNamedTypeLoc(templateSpecializationTypeLoc(
-                                      loc(qualType(hasDeclaration(namedDecl(
-                                          hasName("::std::enable_if"))))))
-                                      .bind("enable_if_specialization")))
-                  .bind("elaborated")))
+          hasUnnamedDefaultArgument(templateSpecializationTypeLoc(
+                                        loc(qualType(hasDeclaration(namedDecl(
+                                            hasName("::std::enable_if"))))))
+                                        .bind("enable_if_specialization")))
           .bind("enable_if"),
       this);
 }
@@ -46,13 +43,11 @@ void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
 void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *EnableIf =
       Result.Nodes.getNodeAs<TemplateTypeParmDecl>("enable_if");
-  const auto *ElaboratedLoc =
-      Result.Nodes.getNodeAs<ElaboratedTypeLoc>("elaborated");
   const auto *EnableIfSpecializationLoc =
       Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
           "enable_if_specialization");
 
-  if (!EnableIf || !ElaboratedLoc || !EnableIfSpecializationLoc)
+  if (!EnableIf || !EnableIfSpecializationLoc)
     return;
 
   const SourceManager &SM = *Result.SourceManager;
@@ -62,8 +57,10 @@ void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   auto Diag = diag(EnableIf->getBeginLoc(),
                    "incorrect std::enable_if usage detected; use "
                    "'typename std::enable_if<...>::type'");
+  // FIXME: This should handle the enable_if specialization already having an
+  // elaborated keyword.
   if (!getLangOpts().CPlusPlus20) {
-    Diag << FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(),
+    Diag << FixItHint::CreateInsertion(EnableIfSpecializationLoc->getBeginLoc(),
                                        "typename ");
   }
   Diag << FixItHint::CreateInsertion(RAngleLoc.getLocWithOffset(1), "::type");
diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
index 33642c407a3a9..5dc988d6662df 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
@@ -39,24 +39,31 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
     // std::move(). This will hopefully prevent erroneous replacements if the
     // code does unusual things (e.g. create an alias for std::move() in
     // another namespace).
-    NestedNameSpecifier *NNS = Callee->getQualifier();
-    if (!NNS) {
+    NestedNameSpecifier NNS = Callee->getQualifier();
+    switch (NNS.getKind()) {
+    case NestedNameSpecifier::Kind::Null:
       // Called as "move" (i.e. presumably the code had a "using std::move;").
       // We still conservatively put a "std::" in front of the forward because
       // we don't know whether the code also had a "using std::forward;".
       Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
-    } else if (const NamespaceDecl *Namespace = NNS->getAsNamespace()) {
+      break;
+    case NestedNameSpecifier::Kind::Namespace: {
+      auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
       if (Namespace->getName() == "std") {
-        if (!NNS->getPrefix()) {
+        if (!Prefix) {
           // Called as "std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "std::" + ForwardName);
-        } else if (NNS->getPrefix()->getKind() == NestedNameSpecifier::Global) {
+        } else if (Prefix.getKind() == NestedNameSpecifier::Kind::Global) {
           // Called as "::std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "::std::" + ForwardName);
         }
       }
+      break;
+    }
+    default:
+      return;
     }
   }
 }
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index 88d2f2c388d07..c29eec2d2abe8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -425,7 +425,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
            "suspicious usage of 'sizeof(array)/sizeof(...)';"
            " denominator differs from the size of array elements")
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-    } else if (NumTy && DenomTy && NumTy == DenomTy &&
+    } else if (NumTy && DenomTy && Ctx.hasSameType(NumTy, DenomTy) &&
                !NumTy->isDependentType()) {
       // Dependent type should not be compared.
       diag(E->getOperatorLoc(),
@@ -434,7 +434,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
     } else if (!WarnOnSizeOfPointer) {
       // When 'WarnOnSizeOfPointer' is enabled, these messages become redundant:
-      if (PointedTy && DenomTy && PointedTy == DenomTy) {
+      if (PointedTy && DenomTy && Ctx.hasSameType(PointedTy, DenomTy)) {
         diag(E->getOperatorLoc(),
              "suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer "
              "is divided by size of pointed type")
@@ -463,7 +463,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
     const auto *SizeOfExpr =
         Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-mul-expr");
 
-    if ((LP...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jul 9, 2025

@llvm/pr-subscribers-clang-static-analyzer-1

Author: Matheus Izvekov (mizvekov)

Changes

This is a major change on how we represent nested name qualifications in the AST.

  • The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy.
  • The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present.
  • TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for stdexec. For one datapoint, for test_on2.cpp in that project, which is the slowest compiling test, this patch improves -c compilation time by about 7.2%, with the -fsyntax-only improvement being at ~12%.

This has great results on compile-time-tracker as well:
image

This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in clang/include/clang/AST and clang/lib/AST, with also import changes in clang/lib/Sema/TreeTransform.h.

The rest and bulk of the changes are mostly consequences of the changes in API.

PS: TagType::getDecl is renamed to getOriginalDecl in this patch, just for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes #147000


Patch is 2.13 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/147835.diff

513 Files Affected:

  • (modified) clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp (+17-36)
  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-2)
  • (modified) clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp (+4-2)
  • (modified) clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp (+8-6)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp (+7-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp (+8-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp (+12-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp (+6-4)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+5-3)
  • (modified) clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp (+25-6)
  • (modified) clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp (+7-2)
  • (modified) clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp (+7-7)
  • (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp (+2-11)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp (+5-4)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp (+2-6)
  • (modified) clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp (+7-8)
  • (modified) clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp (+23-40)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp (+8-10)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp (+3-4)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp (+25-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp (+15-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp (+46-47)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp (+7-9)
  • (modified) clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp (+4-4)
  • (modified) clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp (+7-4)
  • (modified) clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp (+16-10)
  • (modified) clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp (+1-5)
  • (modified) clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp (+3-2)
  • (modified) clang-tools-extra/clang-tidy/utils/Matchers.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp (+12-24)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-1)
  • (modified) clang-tools-extra/clangd/AST.cpp (+57-35)
  • (modified) clang-tools-extra/clangd/AST.h (+2-1)
  • (modified) clang-tools-extra/clangd/CodeComplete.cpp (+7-12)
  • (modified) clang-tools-extra/clangd/DumpAST.cpp (+18-24)
  • (modified) clang-tools-extra/clangd/FindTarget.cpp (+48-78)
  • (modified) clang-tools-extra/clangd/Hover.cpp (+11-9)
  • (modified) clang-tools-extra/clangd/IncludeFixer.cpp (+13-10)
  • (modified) clang-tools-extra/clangd/InlayHints.cpp (+16-12)
  • (modified) clang-tools-extra/clangd/Quality.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/Selection.cpp (+10-7)
  • (modified) clang-tools-extra/clangd/SemanticHighlighting.cpp (+1-16)
  • (modified) clang-tools-extra/clangd/XRefs.cpp (+9-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp (+80-43)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp (+3-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/unittests/ASTTests.cpp (+4-3)
  • (modified) clang-tools-extra/clangd/unittests/DumpASTTests.cpp (+6-9)
  • (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+2-2)
  • (modified) clang-tools-extra/clangd/unittests/HoverTests.cpp (+5-5)
  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+1-8)
  • (modified) clang-tools-extra/clangd/unittests/QualityTests.cpp (+9-5)
  • (modified) clang-tools-extra/clangd/unittests/SelectionTests.cpp (+2-2)
  • (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (+11-18)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp (-1)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp (+3-3)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp (+11-11)
  • (modified) clang/include/clang/AST/ASTConcept.h (+2-7)
  • (modified) clang/include/clang/AST/ASTContext.h (+94-107)
  • (modified) clang/include/clang/AST/ASTImporter.h (+1-1)
  • (modified) clang/include/clang/AST/ASTNodeTraverser.h (+12-11)
  • (modified) clang/include/clang/AST/ASTTypeTraits.h (+8-7)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+17-27)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+18-20)
  • (modified) clang/include/clang/AST/CanonicalType.h (+4-7)
  • (modified) clang/include/clang/AST/Decl.h (+60-37)
  • (modified) clang/include/clang/AST/DeclBase.h (-10)
  • (modified) clang/include/clang/AST/DeclCXX.h (+54-39)
  • (modified) clang/include/clang/AST/DeclObjC.h (+3)
  • (modified) clang/include/clang/AST/DeclTemplate.h (+19-25)
  • (modified) clang/include/clang/AST/DependenceFlags.h (+1-1)
  • (modified) clang/include/clang/AST/DynamicRecursiveASTVisitor.h (+7-6)
  • (modified) clang/include/clang/AST/Expr.h (+2-2)
  • (modified) clang/include/clang/AST/ExprCXX.h (+4-4)
  • (modified) clang/include/clang/AST/JSONNodeDumper.h (-1)
  • (modified) clang/include/clang/AST/NestedNameSpecifier.h (+212-480)
  • (added) clang/include/clang/AST/NestedNameSpecifierBase.h (+585)
  • (modified) clang/include/clang/AST/ODRHash.h (+1-1)
  • (modified) clang/include/clang/AST/PrettyPrinter.h (+3-8)
  • (modified) clang/include/clang/AST/PropertiesBase.td (+3-3)
  • (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+177-105)
  • (modified) clang/include/clang/AST/TemplateBase.h (+17-23)
  • (modified) clang/include/clang/AST/TemplateName.h (+19-11)
  • (modified) clang/include/clang/AST/TextNodeDumper.h (+1-1)
  • (modified) clang/include/clang/AST/Type.h (+412-358)
  • (modified) clang/include/clang/AST/TypeLoc.h (+246-162)
  • (modified) clang/include/clang/AST/TypeProperties.td (+56-84)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+66-91)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchersInternal.h (+7-13)
  • (modified) clang/include/clang/Analysis/FlowSensitive/ASTOps.h (+8-2)
  • (modified) clang/include/clang/Basic/DeclNodes.td (+74-75)
  • (modified) clang/include/clang/Basic/TypeNodes.td (+1-2)
  • (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+2-3)
  • (modified) clang/include/clang/Sema/CodeCompleteConsumer.h (+4-3)
  • (modified) clang/include/clang/Sema/DeclSpec.h (+9-39)
  • (modified) clang/include/clang/Sema/HeuristicResolver.h (+1-2)
  • (modified) clang/include/clang/Sema/ParsedTemplate.h (+16-10)
  • (modified) clang/include/clang/Sema/Sema.h (+17-21)
  • (modified) clang/include/clang/Sema/SemaInternal.h (+4-4)
  • (modified) clang/include/clang/Sema/TypoCorrection.h (+15-14)
  • (modified) clang/include/clang/Serialization/ASTRecordReader.h (+1-1)
  • (modified) clang/include/clang/Serialization/ASTRecordWriter.h (+2-3)
  • (modified) clang/include/clang/Serialization/TypeBitCodes.def (-1)
  • (modified) clang/include/clang/Tooling/Refactoring/Lookup.h (+1-2)
  • (modified) clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h (+9-6)
  • (modified) clang/lib/AST/APValue.cpp (+2-1)
  • (modified) clang/lib/AST/ASTConcept.cpp (+9-2)
  • (modified) clang/lib/AST/ASTContext.cpp (+574-538)
  • (modified) clang/lib/AST/ASTDiagnostic.cpp (+15-34)
  • (modified) clang/lib/AST/ASTDumper.cpp (+3-1)
  • (modified) clang/lib/AST/ASTImporter.cpp (+102-206)
  • (modified) clang/lib/AST/ASTImporterLookupTable.cpp (+8-8)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+81-100)
  • (modified) clang/lib/AST/ASTTypeTraits.cpp (+31-5)
  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-4)
  • (modified) clang/lib/AST/ByteCode/Context.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+5-3)
  • (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-4)
  • (modified) clang/lib/AST/ByteCode/Interp.h (+1-4)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/InterpFrame.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Pointer.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-1)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+10-6)
  • (modified) clang/lib/AST/Comment.cpp (-2)
  • (modified) clang/lib/AST/CommentSema.cpp (+3-11)
  • (modified) clang/lib/AST/ComparisonCategories.cpp (+1-1)
  • (modified) clang/lib/AST/ComputeDependence.cpp (+10-16)
  • (modified) clang/lib/AST/Decl.cpp (+44-71)
  • (modified) clang/lib/AST/DeclBase.cpp (+12-28)
  • (modified) clang/lib/AST/DeclCXX.cpp (+78-56)
  • (modified) clang/lib/AST/DeclPrinter.cpp (+16-44)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+35-37)
  • (modified) clang/lib/AST/DeclarationName.cpp (+3-3)
  • (modified) clang/lib/AST/DynamicRecursiveASTVisitor.cpp (+41-12)
  • (modified) clang/lib/AST/Expr.cpp (+16-9)
  • (modified) clang/lib/AST/ExprCXX.cpp (+4-5)
  • (modified) clang/lib/AST/ExprConcepts.cpp (+2-2)
  • (modified) clang/lib/AST/ExprConstant.cpp (+43-26)
  • (modified) clang/lib/AST/FormatString.cpp (+6-4)
  • (modified) clang/lib/AST/InheritViz.cpp (+3-3)
  • (modified) clang/lib/AST/ItaniumCXXABI.cpp (+4-4)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+76-129)
  • (modified) clang/lib/AST/JSONNodeDumper.cpp (+16-20)
  • (modified) clang/lib/AST/MicrosoftMangle.cpp (+10-11)
  • (modified) clang/lib/AST/NestedNameSpecifier.cpp (+94-429)
  • (modified) clang/lib/AST/ODRHash.cpp (+47-80)
  • (modified) clang/lib/AST/OpenMPClause.cpp (+11-15)
  • (modified) clang/lib/AST/ParentMapContext.cpp (+4-2)
  • (modified) clang/lib/AST/PrintfFormatString.cpp (+1-1)
  • (modified) clang/lib/AST/QualTypeNames.cpp (+183-187)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+13-14)
  • (modified) clang/lib/AST/ScanfFormatString.cpp (+3-2)
  • (modified) clang/lib/AST/StmtPrinter.cpp (+10-23)
  • (modified) clang/lib/AST/StmtProfile.cpp (+7-8)
  • (modified) clang/lib/AST/TemplateBase.cpp (+28-4)
  • (modified) clang/lib/AST/TemplateName.cpp (+31-18)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+50-32)
  • (modified) clang/lib/AST/Type.cpp (+317-154)
  • (modified) clang/lib/AST/TypeLoc.cpp (+206-30)
  • (modified) clang/lib/AST/TypePrinter.cpp (+143-118)
  • (modified) clang/lib/AST/VTTBuilder.cpp (+9-3)
  • (modified) clang/lib/AST/VTableBuilder.cpp (+5-3)
  • (modified) clang/lib/ASTMatchers/ASTMatchFinder.cpp (+63-52)
  • (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+2-3)
  • (modified) clang/lib/ASTMatchers/Dynamic/Registry.cpp (+1-4)
  • (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+4-2)
  • (modified) clang/lib/Analysis/ThreadSafety.cpp (+3-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+2-2)
  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+8-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-1)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+18-18)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCUDANV.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCXX.cpp (+10-9)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+16-11)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+56-39)
  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+65-62)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+9-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+29-16)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+17-8)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+20-17)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+21-8)
  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+7-4)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGNonTrivialStruct.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+6-5)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+21-14)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+1-1)
  • (modified) clang/lib/CodeGen/CGStmt.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGVTables.cpp (+4-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-5)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+3-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+17-11)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+7-6)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+20-13)
  • (modified) clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp (+2-1)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+40-28)
  • (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+13-12)
  • (modified) clang/lib/CodeGen/SwiftCallingConv.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/ARC.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/BPF.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/Hexagon.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/Lanai.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/LoongArch.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/Mips.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/PNaCl.cpp (+2-2)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+5-3)
  • (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/WebAssembly.cpp (+2-1)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+35-24)
  • (modified) clang/lib/CodeGen/Targets/XCore.cpp (+2-2)
  • (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+57-60)
  • (modified) clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp (+1-1)
  • (modified) clang/lib/Frontend/ASTConsumers.cpp (+5-2)
  • (modified) clang/lib/Frontend/ASTUnit.cpp (+1-1)
  • (modified) clang/lib/Index/IndexTypeSourceInfo.cpp (+20-32)
  • (modified) clang/lib/Index/USRGeneration.cpp (+9-9)
  • (modified) clang/lib/InstallAPI/Visitor.cpp (+4-4)
  • (modified) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+1-1)
  • (modified) clang/lib/Interpreter/Value.cpp (+3-3)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+1-2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+8-5)
  • (modified) clang/lib/Parse/ParseTemplate.cpp (+17-12)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+1-1)
  • (modified) clang/lib/Parse/Parser.cpp (+5-4)
  • (modified) clang/lib/Sema/AnalysisBasedWarnings.cpp (+4-7)
  • (modified) clang/lib/Sema/DeclSpec.cpp (+5-31)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+4-19)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+1-1)
  • (modified) clang/lib/Sema/HeuristicResolver.cpp (+23-27)
  • (modified) clang/lib/Sema/Sema.cpp (+12-9)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+21-22)
  • (modified) clang/lib/Sema/SemaAvailability.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaBPF.cpp (+3-3)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-2)
  • (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+184-147)
  • (modified) clang/lib/Sema/SemaCast.cpp (+25-26)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+62-35)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+102-79)
  • (modified) clang/lib/Sema/SemaCoroutine.cpp (+16-19)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+337-254)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+15-8)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+246-238)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+20-12)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+70-55)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+85-77)
  • (modified) clang/lib/Sema/SemaExprMember.cpp (+4-3)
  • (modified) clang/lib/Sema/SemaExprObjC.cpp (+8-7)
  • (modified) clang/lib/Sema/SemaFunctionEffects.cpp (+6-2)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+11-9)
  • (modified) clang/lib/Sema/SemaInit.cpp (+78-67)
  • (modified) clang/lib/Sema/SemaLambda.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+152-88)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+3-1)
  • (modified) clang/lib/Sema/SemaOpenMP.cpp (+8-5)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+96-85)
  • (modified) clang/lib/Sema/SemaPPC.cpp (+4-2)
  • (modified) clang/lib/Sema/SemaSYCL.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaStmt.cpp (+23-17)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+6-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+258-286)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+71-91)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+32-26)
  • (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+75-109)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+37-47)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+21-18)
  • (modified) clang/lib/Sema/SemaType.cpp (+110-74)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+16-19)
  • (modified) clang/lib/Sema/TreeTransform.h (+420-563)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-3)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+58-68)
  • (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+8-20)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+58-55)
  • (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+3-4)
  • (modified) clang/lib/Serialization/TemplateArgumentHasher.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp (+2-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+2-5)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp (+3-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp (+1-4)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp (+5-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+7-9)
  • (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+10-23)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Core/CallEvent.cpp (+7-4)
  • (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Core/RegionStore.cpp (+3-2)
  • (modified) clang/lib/StaticAnalyzer/Core/SValBuilder.cpp (+2-2)
diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
index 3e367ab1a5558..471ca45fb5a53 100644
--- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
+++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
@@ -31,24 +31,9 @@ llvm::SmallVector<llvm::StringRef, 4> splitSymbolName(llvm::StringRef Name) {
   return Splitted;
 }
 
-SourceLocation startLocationForType(TypeLoc TLoc) {
-  // For elaborated types (e.g. `struct a::A`) we want the portion after the
-  // `struct` but including the namespace qualifier, `a::`.
-  if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) {
-    NestedNameSpecifierLoc NestedNameSpecifier =
-        TLoc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-    if (NestedNameSpecifier.getNestedNameSpecifier())
-      return NestedNameSpecifier.getBeginLoc();
-    TLoc = TLoc.getNextTypeLoc();
-  }
-  return TLoc.getBeginLoc();
-}
-
 SourceLocation endLocationForType(TypeLoc TLoc) {
-  // Dig past any namespace or keyword qualifications.
-  while (TLoc.getTypeLocClass() == TypeLoc::Elaborated ||
-         TLoc.getTypeLocClass() == TypeLoc::Qualified)
-    TLoc = TLoc.getNextTypeLoc();
+  if (auto QTL = TLoc.getAs<QualifiedTypeLoc>())
+    TLoc = QTL.getUnqualifiedLoc();
 
   // The location for template specializations (e.g. Foo<int>) includes the
   // templated types in its location range.  We want to restrict this to just
@@ -550,8 +535,8 @@ void ChangeNamespaceTool::run(
                  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
                      "nested_specifier_loc")) {
     SourceLocation Start = Specifier->getBeginLoc();
-    SourceLocation End = endLocationForType(Specifier->getTypeLoc());
-    fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
+    SourceLocation End = endLocationForType(Specifier->castAsTypeLoc());
+    fixTypeLoc(Result, Start, End, Specifier->castAsTypeLoc());
   } else if (const auto *BaseInitializer =
                  Result.Nodes.getNodeAs<CXXCtorInitializer>(
                      "base_initializer")) {
@@ -562,19 +547,16 @@ void ChangeNamespaceTool::run(
     // filtered by matchers in some cases, e.g. the type is templated. We should
     // handle the record type qualifier instead.
     TypeLoc Loc = *TLoc;
-    while (Loc.getTypeLocClass() == TypeLoc::Qualified)
-      Loc = Loc.getNextTypeLoc();
-    if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
-      NestedNameSpecifierLoc NestedNameSpecifier =
-          Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-      // FIXME: avoid changing injected class names.
-      if (auto *NNS = NestedNameSpecifier.getNestedNameSpecifier()) {
-        const Type *SpecifierType = NNS->getAsType();
-        if (SpecifierType && SpecifierType->isRecordType())
-          return;
-      }
-    }
-    fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
+    if (auto QTL = Loc.getAs<QualifiedTypeLoc>())
+      Loc = QTL.getUnqualifiedLoc();
+    // FIXME: avoid changing injected class names.
+    if (NestedNameSpecifier NestedNameSpecifier =
+            Loc.getPrefix().getNestedNameSpecifier();
+        NestedNameSpecifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        NestedNameSpecifier.getAsType()->isRecordType())
+      return;
+    fixTypeLoc(Result, Loc.getNonElaboratedBeginLoc(), endLocationForType(Loc),
+               Loc);
   } else if (const auto *VarRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
     const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
@@ -588,10 +570,9 @@ void ChangeNamespaceTool::run(
   } else if (const auto *EnumConstRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("enum_const_ref")) {
     // Do not rename the reference if it is already scoped by the EnumDecl name.
-    if (EnumConstRef->hasQualifier() &&
-        EnumConstRef->getQualifier()->getKind() ==
-            NestedNameSpecifier::SpecifierKind::TypeSpec &&
-        EnumConstRef->getQualifier()->getAsType()->isEnumeralType())
+    if (NestedNameSpecifier Qualifier = EnumConstRef->getQualifier();
+        Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        Qualifier.getAsType()->isEnumeralType())
       return;
     const auto *EnumConstDecl =
         Result.Nodes.getNodeAs<EnumConstantDecl>("enum_const_decl");
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 6cc372ce98a6d..8ac807b935a04 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -883,8 +883,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
     if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base =
-              cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition())) {
+      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
+              Ty->getOriginalDecl()->getDefinition())) {
         // Initialized without USR and name, this will be set in the following
         // if-else stmt.
         BaseRecordInfo BI(
diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
index bb48883f88815..1f30d27c0a54f 100644
--- a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
@@ -216,8 +216,7 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {
   // Uses of most types: just look at what the typeLoc refers to.
   MatchFinder->addMatcher(
       typeLoc(isExpansionInMainFile(),
-              loc(qualType(allOf(unless(elaboratedType()),
-                                 hasDeclaration(Types.bind("use")))))),
+              loc(qualType(hasDeclaration(Types.bind("use"))))),
       this);
   // Uses of typedefs: these are often transparent to hasDeclaration, so we need
   // to handle them explicitly.
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index f9d75978d0ea8..fac6e0418d163 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -533,7 +533,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
       Builder << reinterpret_cast<const NamedDecl *>(Info.getRawArg(Index));
       break;
     case clang::DiagnosticsEngine::ak_nestednamespec:
-      Builder << reinterpret_cast<NestedNameSpecifier *>(Info.getRawArg(Index));
+      Builder << NestedNameSpecifier::getFromVoidPointer(
+          reinterpret_cast<void *>(Info.getRawArg(Index)));
       break;
     case clang::DiagnosticsEngine::ak_declcontext:
       Builder << reinterpret_cast<DeclContext *>(Info.getRawArg(Index));
diff --git a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
index 28e8fe002d575..5bce285bea7b9 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
@@ -43,7 +43,8 @@ static bool isDerivedClassBefriended(const CXXRecordDecl *CRTP,
       return false;
     }
 
-    return FriendType->getType()->getAsCXXRecordDecl() == Derived;
+    return declaresSameEntity(FriendType->getType()->getAsCXXRecordDecl(),
+                              Derived);
   });
 }
 
@@ -55,7 +56,8 @@ getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP,
       CRTP->getTemplateArgs().asArray(), [&](const TemplateArgument &Arg) {
         ++Idx;
         return Arg.getKind() == TemplateArgument::Type &&
-               Arg.getAsType()->getAsCXXRecordDecl() == Derived;
+               declaresSameEntity(Arg.getAsType()->getAsCXXRecordDecl(),
+                                  Derived);
       });
 
   return AnyOf ? CRTP->getSpecializedTemplate()
diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
index a179d4bf66b4d..3cacb90cace52 100644
--- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
@@ -577,7 +577,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType,
                               ImplicitConversionModellingMode ImplicitMode);
 
 static inline bool isUselessSugar(const Type *T) {
-  return isa<AttributedType, DecayedType, ElaboratedType, ParenType>(T);
+  return isa<AttributedType, DecayedType, ParenType>(T);
 }
 
 namespace {
@@ -1040,7 +1040,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
   const auto *ToRecord = To->getAsCXXRecordDecl();
   if (isDerivedToBase(FromRecord, ToRecord)) {
     LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n");
-    WorkType = QualType{ToRecord->getTypeForDecl(), FastQualifiersToApply};
+    WorkType = QualType{
+        ToRecord->getASTContext().getCanonicalTagType(ToRecord)->getTypePtr(),
+        FastQualifiersToApply};
   }
 
   if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) {
@@ -1072,9 +1074,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
     WorkType = To;
   }
 
-  if (WorkType == To) {
+  if (Ctx.hasSameType(WorkType, To)) {
     LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Reached 'To' type.\n");
-    return {WorkType};
+    return {Ctx.getCommonSugaredType(WorkType, To)};
   }
 
   LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Did not reach 'To'.\n");
@@ -1219,7 +1221,7 @@ tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{RecordType, ToType};
     // The conversion from the operator call's return type to ToType was
@@ -1270,7 +1272,7 @@ tryConvertingConstructors(const TheCheck &Check, QualType FromType,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{FromType, RecordType};
     Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard;
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
index 75ef628436738..070ed04efffc4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
@@ -69,10 +69,9 @@ void ForwardDeclarationNamespaceCheck::check(
     //      struct B { friend A; };
     //    \endcode
     // `A` will not be marked as "referenced" in the AST.
-    if (const TypeSourceInfo *Tsi = Decl->getFriendType()) {
-      QualType Desugared = Tsi->getType().getDesugaredType(*Result.Context);
-      FriendTypes.insert(Desugared.getTypePtr());
-    }
+    if (const TypeSourceInfo *Tsi = Decl->getFriendType())
+      FriendTypes.insert(
+          Tsi->getType()->getCanonicalTypeUnqualified().getTypePtr());
   }
 }
 
@@ -119,7 +118,9 @@ void ForwardDeclarationNamespaceCheck::onEndOfTranslationUnit() {
       if (CurDecl->hasDefinition() || CurDecl->isReferenced()) {
         continue; // Skip forward declarations that are used/referenced.
       }
-      if (FriendTypes.contains(CurDecl->getTypeForDecl())) {
+      if (FriendTypes.contains(CurDecl->getASTContext()
+                                   .getCanonicalTagType(CurDecl)
+                                   ->getTypePtr())) {
         continue; // Skip forward declarations referenced as friend.
       }
       if (CurDecl->getLocation().isMacroID() ||
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
index 00e8f7e514368..10b747e17e2ad 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
@@ -33,21 +33,17 @@ AST_MATCHER(QualType, isEnableIf) {
     BaseType = BaseType->getPointeeType().getTypePtr();
   }
   // Case: type parameter dependent (enable_if<is_integral<T>>).
-  if (const auto *Dependent = BaseType->getAs<DependentNameType>()) {
-    BaseType = Dependent->getQualifier()->getAsType();
-  }
+  if (const auto *Dependent = BaseType->getAs<DependentNameType>())
+    BaseType = Dependent->getQualifier().getAsType();
   if (!BaseType)
     return false;
   if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>()))
     return true; // Case: enable_if_t< >.
-  if (const auto *Elaborated = BaseType->getAs<ElaboratedType>()) {
-    if (const auto *Q = Elaborated->getQualifier())
-      if (const auto *Qualifier = Q->getAsType()) {
-        if (CheckTemplate(Qualifier->getAs<TemplateSpecializationType>())) {
-          return true; // Case: enable_if< >::type.
-        }
-      }
-  }
+  if (const auto *TT = BaseType->getAs<TypedefType>())
+    if (NestedNameSpecifier Q = TT->getQualifier();
+        Q.getKind() == NestedNameSpecifier::Kind::Type)
+      if (CheckTemplate(Q.getAsType()->getAs<TemplateSpecializationType>()))
+        return true; // Case: enable_if< >::type.
   return false;
 }
 AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument,
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
index 75f1107904fce..07cd90d64c2a4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
@@ -32,13 +32,10 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument,
 void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       templateTypeParmDecl(
-          hasUnnamedDefaultArgument(
-              elaboratedTypeLoc(
-                  hasNamedTypeLoc(templateSpecializationTypeLoc(
-                                      loc(qualType(hasDeclaration(namedDecl(
-                                          hasName("::std::enable_if"))))))
-                                      .bind("enable_if_specialization")))
-                  .bind("elaborated")))
+          hasUnnamedDefaultArgument(templateSpecializationTypeLoc(
+                                        loc(qualType(hasDeclaration(namedDecl(
+                                            hasName("::std::enable_if"))))))
+                                        .bind("enable_if_specialization")))
           .bind("enable_if"),
       this);
 }
@@ -46,13 +43,11 @@ void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
 void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *EnableIf =
       Result.Nodes.getNodeAs<TemplateTypeParmDecl>("enable_if");
-  const auto *ElaboratedLoc =
-      Result.Nodes.getNodeAs<ElaboratedTypeLoc>("elaborated");
   const auto *EnableIfSpecializationLoc =
       Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
           "enable_if_specialization");
 
-  if (!EnableIf || !ElaboratedLoc || !EnableIfSpecializationLoc)
+  if (!EnableIf || !EnableIfSpecializationLoc)
     return;
 
   const SourceManager &SM = *Result.SourceManager;
@@ -62,8 +57,10 @@ void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   auto Diag = diag(EnableIf->getBeginLoc(),
                    "incorrect std::enable_if usage detected; use "
                    "'typename std::enable_if<...>::type'");
+  // FIXME: This should handle the enable_if specialization already having an
+  // elaborated keyword.
   if (!getLangOpts().CPlusPlus20) {
-    Diag << FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(),
+    Diag << FixItHint::CreateInsertion(EnableIfSpecializationLoc->getBeginLoc(),
                                        "typename ");
   }
   Diag << FixItHint::CreateInsertion(RAngleLoc.getLocWithOffset(1), "::type");
diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
index 33642c407a3a9..5dc988d6662df 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
@@ -39,24 +39,31 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
     // std::move(). This will hopefully prevent erroneous replacements if the
     // code does unusual things (e.g. create an alias for std::move() in
     // another namespace).
-    NestedNameSpecifier *NNS = Callee->getQualifier();
-    if (!NNS) {
+    NestedNameSpecifier NNS = Callee->getQualifier();
+    switch (NNS.getKind()) {
+    case NestedNameSpecifier::Kind::Null:
       // Called as "move" (i.e. presumably the code had a "using std::move;").
       // We still conservatively put a "std::" in front of the forward because
       // we don't know whether the code also had a "using std::forward;".
       Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
-    } else if (const NamespaceDecl *Namespace = NNS->getAsNamespace()) {
+      break;
+    case NestedNameSpecifier::Kind::Namespace: {
+      auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
       if (Namespace->getName() == "std") {
-        if (!NNS->getPrefix()) {
+        if (!Prefix) {
           // Called as "std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "std::" + ForwardName);
-        } else if (NNS->getPrefix()->getKind() == NestedNameSpecifier::Global) {
+        } else if (Prefix.getKind() == NestedNameSpecifier::Kind::Global) {
           // Called as "::std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "::std::" + ForwardName);
         }
       }
+      break;
+    }
+    default:
+      return;
     }
   }
 }
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index 88d2f2c388d07..c29eec2d2abe8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -425,7 +425,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
            "suspicious usage of 'sizeof(array)/sizeof(...)';"
            " denominator differs from the size of array elements")
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-    } else if (NumTy && DenomTy && NumTy == DenomTy &&
+    } else if (NumTy && DenomTy && Ctx.hasSameType(NumTy, DenomTy) &&
                !NumTy->isDependentType()) {
       // Dependent type should not be compared.
       diag(E->getOperatorLoc(),
@@ -434,7 +434,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
     } else if (!WarnOnSizeOfPointer) {
       // When 'WarnOnSizeOfPointer' is enabled, these messages become redundant:
-      if (PointedTy && DenomTy && PointedTy == DenomTy) {
+      if (PointedTy && DenomTy && Ctx.hasSameType(PointedTy, DenomTy)) {
         diag(E->getOperatorLoc(),
              "suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer "
              "is divided by size of pointed type")
@@ -463,7 +463,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
     const auto *SizeOfExpr =
         Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-mul-expr");
 
-    if ((LP...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jul 9, 2025

@llvm/pr-subscribers-backend-mips

Author: Matheus Izvekov (mizvekov)

Changes

This is a major change on how we represent nested name qualifications in the AST.

  • The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy.
  • The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present.
  • TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for stdexec. For one datapoint, for test_on2.cpp in that project, which is the slowest compiling test, this patch improves -c compilation time by about 7.2%, with the -fsyntax-only improvement being at ~12%.

This has great results on compile-time-tracker as well:
image

This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in clang/include/clang/AST and clang/lib/AST, with also import changes in clang/lib/Sema/TreeTransform.h.

The rest and bulk of the changes are mostly consequences of the changes in API.

PS: TagType::getDecl is renamed to getOriginalDecl in this patch, just for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes #147000


Patch is 2.13 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/147835.diff

513 Files Affected:

  • (modified) clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp (+17-36)
  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-2)
  • (modified) clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp (+4-2)
  • (modified) clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp (+8-6)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp (+7-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp (+8-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp (+12-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp (+6-4)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+5-3)
  • (modified) clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp (+25-6)
  • (modified) clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp (+7-2)
  • (modified) clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp (+7-7)
  • (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp (+2-11)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp (+5-4)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp (+2-6)
  • (modified) clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp (+7-8)
  • (modified) clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp (+23-40)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp (+8-10)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp (+3-4)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp (+25-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp (+15-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp (+46-47)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp (+7-9)
  • (modified) clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp (+4-4)
  • (modified) clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp (+7-4)
  • (modified) clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp (+16-10)
  • (modified) clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp (+1-5)
  • (modified) clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp (+3-2)
  • (modified) clang-tools-extra/clang-tidy/utils/Matchers.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp (+12-24)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-1)
  • (modified) clang-tools-extra/clangd/AST.cpp (+57-35)
  • (modified) clang-tools-extra/clangd/AST.h (+2-1)
  • (modified) clang-tools-extra/clangd/CodeComplete.cpp (+7-12)
  • (modified) clang-tools-extra/clangd/DumpAST.cpp (+18-24)
  • (modified) clang-tools-extra/clangd/FindTarget.cpp (+48-78)
  • (modified) clang-tools-extra/clangd/Hover.cpp (+11-9)
  • (modified) clang-tools-extra/clangd/IncludeFixer.cpp (+13-10)
  • (modified) clang-tools-extra/clangd/InlayHints.cpp (+16-12)
  • (modified) clang-tools-extra/clangd/Quality.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/Selection.cpp (+10-7)
  • (modified) clang-tools-extra/clangd/SemanticHighlighting.cpp (+1-16)
  • (modified) clang-tools-extra/clangd/XRefs.cpp (+9-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp (+80-43)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp (+3-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/unittests/ASTTests.cpp (+4-3)
  • (modified) clang-tools-extra/clangd/unittests/DumpASTTests.cpp (+6-9)
  • (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+2-2)
  • (modified) clang-tools-extra/clangd/unittests/HoverTests.cpp (+5-5)
  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+1-8)
  • (modified) clang-tools-extra/clangd/unittests/QualityTests.cpp (+9-5)
  • (modified) clang-tools-extra/clangd/unittests/SelectionTests.cpp (+2-2)
  • (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (+11-18)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp (-1)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp (+3-3)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp (+11-11)
  • (modified) clang/include/clang/AST/ASTConcept.h (+2-7)
  • (modified) clang/include/clang/AST/ASTContext.h (+94-107)
  • (modified) clang/include/clang/AST/ASTImporter.h (+1-1)
  • (modified) clang/include/clang/AST/ASTNodeTraverser.h (+12-11)
  • (modified) clang/include/clang/AST/ASTTypeTraits.h (+8-7)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+17-27)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+18-20)
  • (modified) clang/include/clang/AST/CanonicalType.h (+4-7)
  • (modified) clang/include/clang/AST/Decl.h (+60-37)
  • (modified) clang/include/clang/AST/DeclBase.h (-10)
  • (modified) clang/include/clang/AST/DeclCXX.h (+54-39)
  • (modified) clang/include/clang/AST/DeclObjC.h (+3)
  • (modified) clang/include/clang/AST/DeclTemplate.h (+19-25)
  • (modified) clang/include/clang/AST/DependenceFlags.h (+1-1)
  • (modified) clang/include/clang/AST/DynamicRecursiveASTVisitor.h (+7-6)
  • (modified) clang/include/clang/AST/Expr.h (+2-2)
  • (modified) clang/include/clang/AST/ExprCXX.h (+4-4)
  • (modified) clang/include/clang/AST/JSONNodeDumper.h (-1)
  • (modified) clang/include/clang/AST/NestedNameSpecifier.h (+212-480)
  • (added) clang/include/clang/AST/NestedNameSpecifierBase.h (+585)
  • (modified) clang/include/clang/AST/ODRHash.h (+1-1)
  • (modified) clang/include/clang/AST/PrettyPrinter.h (+3-8)
  • (modified) clang/include/clang/AST/PropertiesBase.td (+3-3)
  • (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+177-105)
  • (modified) clang/include/clang/AST/TemplateBase.h (+17-23)
  • (modified) clang/include/clang/AST/TemplateName.h (+19-11)
  • (modified) clang/include/clang/AST/TextNodeDumper.h (+1-1)
  • (modified) clang/include/clang/AST/Type.h (+412-358)
  • (modified) clang/include/clang/AST/TypeLoc.h (+246-162)
  • (modified) clang/include/clang/AST/TypeProperties.td (+56-84)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+66-91)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchersInternal.h (+7-13)
  • (modified) clang/include/clang/Analysis/FlowSensitive/ASTOps.h (+8-2)
  • (modified) clang/include/clang/Basic/DeclNodes.td (+74-75)
  • (modified) clang/include/clang/Basic/TypeNodes.td (+1-2)
  • (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+2-3)
  • (modified) clang/include/clang/Sema/CodeCompleteConsumer.h (+4-3)
  • (modified) clang/include/clang/Sema/DeclSpec.h (+9-39)
  • (modified) clang/include/clang/Sema/HeuristicResolver.h (+1-2)
  • (modified) clang/include/clang/Sema/ParsedTemplate.h (+16-10)
  • (modified) clang/include/clang/Sema/Sema.h (+17-21)
  • (modified) clang/include/clang/Sema/SemaInternal.h (+4-4)
  • (modified) clang/include/clang/Sema/TypoCorrection.h (+15-14)
  • (modified) clang/include/clang/Serialization/ASTRecordReader.h (+1-1)
  • (modified) clang/include/clang/Serialization/ASTRecordWriter.h (+2-3)
  • (modified) clang/include/clang/Serialization/TypeBitCodes.def (-1)
  • (modified) clang/include/clang/Tooling/Refactoring/Lookup.h (+1-2)
  • (modified) clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h (+9-6)
  • (modified) clang/lib/AST/APValue.cpp (+2-1)
  • (modified) clang/lib/AST/ASTConcept.cpp (+9-2)
  • (modified) clang/lib/AST/ASTContext.cpp (+574-538)
  • (modified) clang/lib/AST/ASTDiagnostic.cpp (+15-34)
  • (modified) clang/lib/AST/ASTDumper.cpp (+3-1)
  • (modified) clang/lib/AST/ASTImporter.cpp (+102-206)
  • (modified) clang/lib/AST/ASTImporterLookupTable.cpp (+8-8)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+81-100)
  • (modified) clang/lib/AST/ASTTypeTraits.cpp (+31-5)
  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-4)
  • (modified) clang/lib/AST/ByteCode/Context.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+5-3)
  • (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-4)
  • (modified) clang/lib/AST/ByteCode/Interp.h (+1-4)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/InterpFrame.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Pointer.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-1)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+10-6)
  • (modified) clang/lib/AST/Comment.cpp (-2)
  • (modified) clang/lib/AST/CommentSema.cpp (+3-11)
  • (modified) clang/lib/AST/ComparisonCategories.cpp (+1-1)
  • (modified) clang/lib/AST/ComputeDependence.cpp (+10-16)
  • (modified) clang/lib/AST/Decl.cpp (+44-71)
  • (modified) clang/lib/AST/DeclBase.cpp (+12-28)
  • (modified) clang/lib/AST/DeclCXX.cpp (+78-56)
  • (modified) clang/lib/AST/DeclPrinter.cpp (+16-44)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+35-37)
  • (modified) clang/lib/AST/DeclarationName.cpp (+3-3)
  • (modified) clang/lib/AST/DynamicRecursiveASTVisitor.cpp (+41-12)
  • (modified) clang/lib/AST/Expr.cpp (+16-9)
  • (modified) clang/lib/AST/ExprCXX.cpp (+4-5)
  • (modified) clang/lib/AST/ExprConcepts.cpp (+2-2)
  • (modified) clang/lib/AST/ExprConstant.cpp (+43-26)
  • (modified) clang/lib/AST/FormatString.cpp (+6-4)
  • (modified) clang/lib/AST/InheritViz.cpp (+3-3)
  • (modified) clang/lib/AST/ItaniumCXXABI.cpp (+4-4)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+76-129)
  • (modified) clang/lib/AST/JSONNodeDumper.cpp (+16-20)
  • (modified) clang/lib/AST/MicrosoftMangle.cpp (+10-11)
  • (modified) clang/lib/AST/NestedNameSpecifier.cpp (+94-429)
  • (modified) clang/lib/AST/ODRHash.cpp (+47-80)
  • (modified) clang/lib/AST/OpenMPClause.cpp (+11-15)
  • (modified) clang/lib/AST/ParentMapContext.cpp (+4-2)
  • (modified) clang/lib/AST/PrintfFormatString.cpp (+1-1)
  • (modified) clang/lib/AST/QualTypeNames.cpp (+183-187)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+13-14)
  • (modified) clang/lib/AST/ScanfFormatString.cpp (+3-2)
  • (modified) clang/lib/AST/StmtPrinter.cpp (+10-23)
  • (modified) clang/lib/AST/StmtProfile.cpp (+7-8)
  • (modified) clang/lib/AST/TemplateBase.cpp (+28-4)
  • (modified) clang/lib/AST/TemplateName.cpp (+31-18)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+50-32)
  • (modified) clang/lib/AST/Type.cpp (+317-154)
  • (modified) clang/lib/AST/TypeLoc.cpp (+206-30)
  • (modified) clang/lib/AST/TypePrinter.cpp (+143-118)
  • (modified) clang/lib/AST/VTTBuilder.cpp (+9-3)
  • (modified) clang/lib/AST/VTableBuilder.cpp (+5-3)
  • (modified) clang/lib/ASTMatchers/ASTMatchFinder.cpp (+63-52)
  • (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+2-3)
  • (modified) clang/lib/ASTMatchers/Dynamic/Registry.cpp (+1-4)
  • (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+4-2)
  • (modified) clang/lib/Analysis/ThreadSafety.cpp (+3-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+2-2)
  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+8-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-1)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+18-18)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCUDANV.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCXX.cpp (+10-9)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+16-11)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+56-39)
  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+65-62)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+9-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+29-16)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+17-8)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+20-17)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+21-8)
  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+7-4)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGNonTrivialStruct.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+6-5)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+21-14)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+1-1)
  • (modified) clang/lib/CodeGen/CGStmt.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGVTables.cpp (+4-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-5)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+3-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+17-11)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+7-6)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+20-13)
  • (modified) clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp (+2-1)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+40-28)
  • (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+13-12)
  • (modified) clang/lib/CodeGen/SwiftCallingConv.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/ARC.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/BPF.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/Hexagon.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/Lanai.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/LoongArch.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/Mips.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/PNaCl.cpp (+2-2)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+5-3)
  • (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/WebAssembly.cpp (+2-1)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+35-24)
  • (modified) clang/lib/CodeGen/Targets/XCore.cpp (+2-2)
  • (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+57-60)
  • (modified) clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp (+1-1)
  • (modified) clang/lib/Frontend/ASTConsumers.cpp (+5-2)
  • (modified) clang/lib/Frontend/ASTUnit.cpp (+1-1)
  • (modified) clang/lib/Index/IndexTypeSourceInfo.cpp (+20-32)
  • (modified) clang/lib/Index/USRGeneration.cpp (+9-9)
  • (modified) clang/lib/InstallAPI/Visitor.cpp (+4-4)
  • (modified) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+1-1)
  • (modified) clang/lib/Interpreter/Value.cpp (+3-3)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+1-2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+8-5)
  • (modified) clang/lib/Parse/ParseTemplate.cpp (+17-12)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+1-1)
  • (modified) clang/lib/Parse/Parser.cpp (+5-4)
  • (modified) clang/lib/Sema/AnalysisBasedWarnings.cpp (+4-7)
  • (modified) clang/lib/Sema/DeclSpec.cpp (+5-31)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+4-19)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+1-1)
  • (modified) clang/lib/Sema/HeuristicResolver.cpp (+23-27)
  • (modified) clang/lib/Sema/Sema.cpp (+12-9)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+21-22)
  • (modified) clang/lib/Sema/SemaAvailability.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaBPF.cpp (+3-3)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-2)
  • (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+184-147)
  • (modified) clang/lib/Sema/SemaCast.cpp (+25-26)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+62-35)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+102-79)
  • (modified) clang/lib/Sema/SemaCoroutine.cpp (+16-19)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+337-254)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+15-8)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+246-238)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+20-12)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+70-55)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+85-77)
  • (modified) clang/lib/Sema/SemaExprMember.cpp (+4-3)
  • (modified) clang/lib/Sema/SemaExprObjC.cpp (+8-7)
  • (modified) clang/lib/Sema/SemaFunctionEffects.cpp (+6-2)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+11-9)
  • (modified) clang/lib/Sema/SemaInit.cpp (+78-67)
  • (modified) clang/lib/Sema/SemaLambda.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+152-88)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+3-1)
  • (modified) clang/lib/Sema/SemaOpenMP.cpp (+8-5)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+96-85)
  • (modified) clang/lib/Sema/SemaPPC.cpp (+4-2)
  • (modified) clang/lib/Sema/SemaSYCL.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaStmt.cpp (+23-17)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+6-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+258-286)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+71-91)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+32-26)
  • (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+75-109)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+37-47)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+21-18)
  • (modified) clang/lib/Sema/SemaType.cpp (+110-74)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+16-19)
  • (modified) clang/lib/Sema/TreeTransform.h (+420-563)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-3)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+58-68)
  • (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+8-20)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+58-55)
  • (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+3-4)
  • (modified) clang/lib/Serialization/TemplateArgumentHasher.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp (+2-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+2-5)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp (+3-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp (+1-4)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp (+5-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+7-9)
  • (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+10-23)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Core/CallEvent.cpp (+7-4)
  • (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Core/RegionStore.cpp (+3-2)
  • (modified) clang/lib/StaticAnalyzer/Core/SValBuilder.cpp (+2-2)
diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
index 3e367ab1a5558..471ca45fb5a53 100644
--- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
+++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
@@ -31,24 +31,9 @@ llvm::SmallVector<llvm::StringRef, 4> splitSymbolName(llvm::StringRef Name) {
   return Splitted;
 }
 
-SourceLocation startLocationForType(TypeLoc TLoc) {
-  // For elaborated types (e.g. `struct a::A`) we want the portion after the
-  // `struct` but including the namespace qualifier, `a::`.
-  if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) {
-    NestedNameSpecifierLoc NestedNameSpecifier =
-        TLoc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-    if (NestedNameSpecifier.getNestedNameSpecifier())
-      return NestedNameSpecifier.getBeginLoc();
-    TLoc = TLoc.getNextTypeLoc();
-  }
-  return TLoc.getBeginLoc();
-}
-
 SourceLocation endLocationForType(TypeLoc TLoc) {
-  // Dig past any namespace or keyword qualifications.
-  while (TLoc.getTypeLocClass() == TypeLoc::Elaborated ||
-         TLoc.getTypeLocClass() == TypeLoc::Qualified)
-    TLoc = TLoc.getNextTypeLoc();
+  if (auto QTL = TLoc.getAs<QualifiedTypeLoc>())
+    TLoc = QTL.getUnqualifiedLoc();
 
   // The location for template specializations (e.g. Foo<int>) includes the
   // templated types in its location range.  We want to restrict this to just
@@ -550,8 +535,8 @@ void ChangeNamespaceTool::run(
                  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
                      "nested_specifier_loc")) {
     SourceLocation Start = Specifier->getBeginLoc();
-    SourceLocation End = endLocationForType(Specifier->getTypeLoc());
-    fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
+    SourceLocation End = endLocationForType(Specifier->castAsTypeLoc());
+    fixTypeLoc(Result, Start, End, Specifier->castAsTypeLoc());
   } else if (const auto *BaseInitializer =
                  Result.Nodes.getNodeAs<CXXCtorInitializer>(
                      "base_initializer")) {
@@ -562,19 +547,16 @@ void ChangeNamespaceTool::run(
     // filtered by matchers in some cases, e.g. the type is templated. We should
     // handle the record type qualifier instead.
     TypeLoc Loc = *TLoc;
-    while (Loc.getTypeLocClass() == TypeLoc::Qualified)
-      Loc = Loc.getNextTypeLoc();
-    if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
-      NestedNameSpecifierLoc NestedNameSpecifier =
-          Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-      // FIXME: avoid changing injected class names.
-      if (auto *NNS = NestedNameSpecifier.getNestedNameSpecifier()) {
-        const Type *SpecifierType = NNS->getAsType();
-        if (SpecifierType && SpecifierType->isRecordType())
-          return;
-      }
-    }
-    fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
+    if (auto QTL = Loc.getAs<QualifiedTypeLoc>())
+      Loc = QTL.getUnqualifiedLoc();
+    // FIXME: avoid changing injected class names.
+    if (NestedNameSpecifier NestedNameSpecifier =
+            Loc.getPrefix().getNestedNameSpecifier();
+        NestedNameSpecifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        NestedNameSpecifier.getAsType()->isRecordType())
+      return;
+    fixTypeLoc(Result, Loc.getNonElaboratedBeginLoc(), endLocationForType(Loc),
+               Loc);
   } else if (const auto *VarRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
     const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
@@ -588,10 +570,9 @@ void ChangeNamespaceTool::run(
   } else if (const auto *EnumConstRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("enum_const_ref")) {
     // Do not rename the reference if it is already scoped by the EnumDecl name.
-    if (EnumConstRef->hasQualifier() &&
-        EnumConstRef->getQualifier()->getKind() ==
-            NestedNameSpecifier::SpecifierKind::TypeSpec &&
-        EnumConstRef->getQualifier()->getAsType()->isEnumeralType())
+    if (NestedNameSpecifier Qualifier = EnumConstRef->getQualifier();
+        Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        Qualifier.getAsType()->isEnumeralType())
       return;
     const auto *EnumConstDecl =
         Result.Nodes.getNodeAs<EnumConstantDecl>("enum_const_decl");
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 6cc372ce98a6d..8ac807b935a04 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -883,8 +883,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
     if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base =
-              cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition())) {
+      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
+              Ty->getOriginalDecl()->getDefinition())) {
         // Initialized without USR and name, this will be set in the following
         // if-else stmt.
         BaseRecordInfo BI(
diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
index bb48883f88815..1f30d27c0a54f 100644
--- a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
@@ -216,8 +216,7 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {
   // Uses of most types: just look at what the typeLoc refers to.
   MatchFinder->addMatcher(
       typeLoc(isExpansionInMainFile(),
-              loc(qualType(allOf(unless(elaboratedType()),
-                                 hasDeclaration(Types.bind("use")))))),
+              loc(qualType(hasDeclaration(Types.bind("use"))))),
       this);
   // Uses of typedefs: these are often transparent to hasDeclaration, so we need
   // to handle them explicitly.
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index f9d75978d0ea8..fac6e0418d163 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -533,7 +533,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
       Builder << reinterpret_cast<const NamedDecl *>(Info.getRawArg(Index));
       break;
     case clang::DiagnosticsEngine::ak_nestednamespec:
-      Builder << reinterpret_cast<NestedNameSpecifier *>(Info.getRawArg(Index));
+      Builder << NestedNameSpecifier::getFromVoidPointer(
+          reinterpret_cast<void *>(Info.getRawArg(Index)));
       break;
     case clang::DiagnosticsEngine::ak_declcontext:
       Builder << reinterpret_cast<DeclContext *>(Info.getRawArg(Index));
diff --git a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
index 28e8fe002d575..5bce285bea7b9 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
@@ -43,7 +43,8 @@ static bool isDerivedClassBefriended(const CXXRecordDecl *CRTP,
       return false;
     }
 
-    return FriendType->getType()->getAsCXXRecordDecl() == Derived;
+    return declaresSameEntity(FriendType->getType()->getAsCXXRecordDecl(),
+                              Derived);
   });
 }
 
@@ -55,7 +56,8 @@ getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP,
       CRTP->getTemplateArgs().asArray(), [&](const TemplateArgument &Arg) {
         ++Idx;
         return Arg.getKind() == TemplateArgument::Type &&
-               Arg.getAsType()->getAsCXXRecordDecl() == Derived;
+               declaresSameEntity(Arg.getAsType()->getAsCXXRecordDecl(),
+                                  Derived);
       });
 
   return AnyOf ? CRTP->getSpecializedTemplate()
diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
index a179d4bf66b4d..3cacb90cace52 100644
--- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
@@ -577,7 +577,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType,
                               ImplicitConversionModellingMode ImplicitMode);
 
 static inline bool isUselessSugar(const Type *T) {
-  return isa<AttributedType, DecayedType, ElaboratedType, ParenType>(T);
+  return isa<AttributedType, DecayedType, ParenType>(T);
 }
 
 namespace {
@@ -1040,7 +1040,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
   const auto *ToRecord = To->getAsCXXRecordDecl();
   if (isDerivedToBase(FromRecord, ToRecord)) {
     LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n");
-    WorkType = QualType{ToRecord->getTypeForDecl(), FastQualifiersToApply};
+    WorkType = QualType{
+        ToRecord->getASTContext().getCanonicalTagType(ToRecord)->getTypePtr(),
+        FastQualifiersToApply};
   }
 
   if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) {
@@ -1072,9 +1074,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
     WorkType = To;
   }
 
-  if (WorkType == To) {
+  if (Ctx.hasSameType(WorkType, To)) {
     LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Reached 'To' type.\n");
-    return {WorkType};
+    return {Ctx.getCommonSugaredType(WorkType, To)};
   }
 
   LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Did not reach 'To'.\n");
@@ -1219,7 +1221,7 @@ tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{RecordType, ToType};
     // The conversion from the operator call's return type to ToType was
@@ -1270,7 +1272,7 @@ tryConvertingConstructors(const TheCheck &Check, QualType FromType,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{FromType, RecordType};
     Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard;
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
index 75ef628436738..070ed04efffc4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
@@ -69,10 +69,9 @@ void ForwardDeclarationNamespaceCheck::check(
     //      struct B { friend A; };
     //    \endcode
     // `A` will not be marked as "referenced" in the AST.
-    if (const TypeSourceInfo *Tsi = Decl->getFriendType()) {
-      QualType Desugared = Tsi->getType().getDesugaredType(*Result.Context);
-      FriendTypes.insert(Desugared.getTypePtr());
-    }
+    if (const TypeSourceInfo *Tsi = Decl->getFriendType())
+      FriendTypes.insert(
+          Tsi->getType()->getCanonicalTypeUnqualified().getTypePtr());
   }
 }
 
@@ -119,7 +118,9 @@ void ForwardDeclarationNamespaceCheck::onEndOfTranslationUnit() {
       if (CurDecl->hasDefinition() || CurDecl->isReferenced()) {
         continue; // Skip forward declarations that are used/referenced.
       }
-      if (FriendTypes.contains(CurDecl->getTypeForDecl())) {
+      if (FriendTypes.contains(CurDecl->getASTContext()
+                                   .getCanonicalTagType(CurDecl)
+                                   ->getTypePtr())) {
         continue; // Skip forward declarations referenced as friend.
       }
       if (CurDecl->getLocation().isMacroID() ||
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
index 00e8f7e514368..10b747e17e2ad 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
@@ -33,21 +33,17 @@ AST_MATCHER(QualType, isEnableIf) {
     BaseType = BaseType->getPointeeType().getTypePtr();
   }
   // Case: type parameter dependent (enable_if<is_integral<T>>).
-  if (const auto *Dependent = BaseType->getAs<DependentNameType>()) {
-    BaseType = Dependent->getQualifier()->getAsType();
-  }
+  if (const auto *Dependent = BaseType->getAs<DependentNameType>())
+    BaseType = Dependent->getQualifier().getAsType();
   if (!BaseType)
     return false;
   if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>()))
     return true; // Case: enable_if_t< >.
-  if (const auto *Elaborated = BaseType->getAs<ElaboratedType>()) {
-    if (const auto *Q = Elaborated->getQualifier())
-      if (const auto *Qualifier = Q->getAsType()) {
-        if (CheckTemplate(Qualifier->getAs<TemplateSpecializationType>())) {
-          return true; // Case: enable_if< >::type.
-        }
-      }
-  }
+  if (const auto *TT = BaseType->getAs<TypedefType>())
+    if (NestedNameSpecifier Q = TT->getQualifier();
+        Q.getKind() == NestedNameSpecifier::Kind::Type)
+      if (CheckTemplate(Q.getAsType()->getAs<TemplateSpecializationType>()))
+        return true; // Case: enable_if< >::type.
   return false;
 }
 AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument,
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
index 75f1107904fce..07cd90d64c2a4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
@@ -32,13 +32,10 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument,
 void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       templateTypeParmDecl(
-          hasUnnamedDefaultArgument(
-              elaboratedTypeLoc(
-                  hasNamedTypeLoc(templateSpecializationTypeLoc(
-                                      loc(qualType(hasDeclaration(namedDecl(
-                                          hasName("::std::enable_if"))))))
-                                      .bind("enable_if_specialization")))
-                  .bind("elaborated")))
+          hasUnnamedDefaultArgument(templateSpecializationTypeLoc(
+                                        loc(qualType(hasDeclaration(namedDecl(
+                                            hasName("::std::enable_if"))))))
+                                        .bind("enable_if_specialization")))
           .bind("enable_if"),
       this);
 }
@@ -46,13 +43,11 @@ void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
 void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *EnableIf =
       Result.Nodes.getNodeAs<TemplateTypeParmDecl>("enable_if");
-  const auto *ElaboratedLoc =
-      Result.Nodes.getNodeAs<ElaboratedTypeLoc>("elaborated");
   const auto *EnableIfSpecializationLoc =
       Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
           "enable_if_specialization");
 
-  if (!EnableIf || !ElaboratedLoc || !EnableIfSpecializationLoc)
+  if (!EnableIf || !EnableIfSpecializationLoc)
     return;
 
   const SourceManager &SM = *Result.SourceManager;
@@ -62,8 +57,10 @@ void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   auto Diag = diag(EnableIf->getBeginLoc(),
                    "incorrect std::enable_if usage detected; use "
                    "'typename std::enable_if<...>::type'");
+  // FIXME: This should handle the enable_if specialization already having an
+  // elaborated keyword.
   if (!getLangOpts().CPlusPlus20) {
-    Diag << FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(),
+    Diag << FixItHint::CreateInsertion(EnableIfSpecializationLoc->getBeginLoc(),
                                        "typename ");
   }
   Diag << FixItHint::CreateInsertion(RAngleLoc.getLocWithOffset(1), "::type");
diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
index 33642c407a3a9..5dc988d6662df 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
@@ -39,24 +39,31 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
     // std::move(). This will hopefully prevent erroneous replacements if the
     // code does unusual things (e.g. create an alias for std::move() in
     // another namespace).
-    NestedNameSpecifier *NNS = Callee->getQualifier();
-    if (!NNS) {
+    NestedNameSpecifier NNS = Callee->getQualifier();
+    switch (NNS.getKind()) {
+    case NestedNameSpecifier::Kind::Null:
       // Called as "move" (i.e. presumably the code had a "using std::move;").
       // We still conservatively put a "std::" in front of the forward because
       // we don't know whether the code also had a "using std::forward;".
       Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
-    } else if (const NamespaceDecl *Namespace = NNS->getAsNamespace()) {
+      break;
+    case NestedNameSpecifier::Kind::Namespace: {
+      auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
       if (Namespace->getName() == "std") {
-        if (!NNS->getPrefix()) {
+        if (!Prefix) {
           // Called as "std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "std::" + ForwardName);
-        } else if (NNS->getPrefix()->getKind() == NestedNameSpecifier::Global) {
+        } else if (Prefix.getKind() == NestedNameSpecifier::Kind::Global) {
           // Called as "::std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "::std::" + ForwardName);
         }
       }
+      break;
+    }
+    default:
+      return;
     }
   }
 }
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index 88d2f2c388d07..c29eec2d2abe8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -425,7 +425,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
            "suspicious usage of 'sizeof(array)/sizeof(...)';"
            " denominator differs from the size of array elements")
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-    } else if (NumTy && DenomTy && NumTy == DenomTy &&
+    } else if (NumTy && DenomTy && Ctx.hasSameType(NumTy, DenomTy) &&
                !NumTy->isDependentType()) {
       // Dependent type should not be compared.
       diag(E->getOperatorLoc(),
@@ -434,7 +434,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
     } else if (!WarnOnSizeOfPointer) {
       // When 'WarnOnSizeOfPointer' is enabled, these messages become redundant:
-      if (PointedTy && DenomTy && PointedTy == DenomTy) {
+      if (PointedTy && DenomTy && Ctx.hasSameType(PointedTy, DenomTy)) {
         diag(E->getOperatorLoc(),
              "suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer "
              "is divided by size of pointed type")
@@ -463,7 +463,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
     const auto *SizeOfExpr =
         Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-mul-expr");
 
-    if ((LP...
[truncated]

@llvmbot
Copy link
Member

llvmbot commented Jul 9, 2025

@llvm/pr-subscribers-backend-x86

Author: Matheus Izvekov (mizvekov)

Changes

This is a major change on how we represent nested name qualifications in the AST.

  • The nested name specifier itself and how it's stored is changed. The prefixes for types are handled within the type hierarchy, which makes canonicalization for them super cheap, no memory allocation required. Also translating a type into nested name specifier form becomes a no-op. An identifier is stored as a DependentNameType. The nested name specifier gains a lightweight handle class, to be used instead of passing around pointers, which is similar to what is implemented for TemplateName. There is still one free bit available, and this handle can be used within a PointerUnion and PointerIntPair, which should keep bit-packing aficionados happy.
  • The ElaboratedType node is removed, all type nodes in which it could previously apply to can now store the elaborated keyword and name qualifier, tail allocating when present.
  • TagTypes can now point to the exact declaration found when producing these, as opposed to the previous situation of there only existing one TagType per entity. This increases the amount of type sugar retained, and can have several applications, for example in tracking module ownership, and other tools which care about source file origins, such as IWYU. These TagTypes are lazily allocated, in order to limit the increase in AST size.

This patch offers a great performance benefit.

It greatly improves compilation time for stdexec. For one datapoint, for test_on2.cpp in that project, which is the slowest compiling test, this patch improves -c compilation time by about 7.2%, with the -fsyntax-only improvement being at ~12%.

This has great results on compile-time-tracker as well:
image

This patch also further enables other optimziations in the future, and will reduce the performance impact of template specialization resugaring when that lands.

It has some other miscelaneous drive-by fixes.

About the review: Yes the patch is huge, sorry about that. Part of the reason is that I started by the nested name specifier part, before the ElaboratedType part, but that had a huge performance downside, as ElaboratedType is a big performance hog. I didn't have the steam to go back and change the patch after the fact.

There is also a lot of internal API changes, and it made sense to remove ElaboratedType in one go, versus removing it from one type at a time, as that would present much more churn to the users. Also, the nested name specifier having a different API avoids missing changes related to how prefixes work now, which could make existing code compile but not work.

How to review: The important changes are all in clang/include/clang/AST and clang/lib/AST, with also import changes in clang/lib/Sema/TreeTransform.h.

The rest and bulk of the changes are mostly consequences of the changes in API.

PS: TagType::getDecl is renamed to getOriginalDecl in this patch, just for easier to rebasing. I plan to rename it back after this lands.

Fixes #136624
Fixes #147000


Patch is 2.13 MiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/147835.diff

513 Files Affected:

  • (modified) clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp (+17-36)
  • (modified) clang-tools-extra/clang-doc/Serialize.cpp (+2-2)
  • (modified) clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp (+4-2)
  • (modified) clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp (+8-6)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp (+7-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp (+8-11)
  • (modified) clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp (+12-5)
  • (modified) clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp (+6-4)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp (+5-3)
  • (modified) clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp (+25-6)
  • (modified) clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp (+7-2)
  • (modified) clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp (+7-7)
  • (modified) clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp (+2-11)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp (+5-4)
  • (modified) clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp (+2-6)
  • (modified) clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp (+6-5)
  • (modified) clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp (+1-2)
  • (modified) clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp (+7-8)
  • (modified) clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp (+23-40)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp (+8-10)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp (+3-4)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp (+25-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp (+15-28)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp (+46-47)
  • (modified) clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp (+7-9)
  • (modified) clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp (+4-4)
  • (modified) clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp (+7-4)
  • (modified) clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp (+16-10)
  • (modified) clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp (+2-2)
  • (modified) clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp (+1-5)
  • (modified) clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp (+2-1)
  • (modified) clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp (+3-2)
  • (modified) clang-tools-extra/clang-tidy/utils/Matchers.cpp (+1-1)
  • (modified) clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp (+12-24)
  • (modified) clang-tools-extra/clang-tidy/utils/TypeTraits.cpp (+2-1)
  • (modified) clang-tools-extra/clangd/AST.cpp (+57-35)
  • (modified) clang-tools-extra/clangd/AST.h (+2-1)
  • (modified) clang-tools-extra/clangd/CodeComplete.cpp (+7-12)
  • (modified) clang-tools-extra/clangd/DumpAST.cpp (+18-24)
  • (modified) clang-tools-extra/clangd/FindTarget.cpp (+48-78)
  • (modified) clang-tools-extra/clangd/Hover.cpp (+11-9)
  • (modified) clang-tools-extra/clangd/IncludeFixer.cpp (+13-10)
  • (modified) clang-tools-extra/clangd/InlayHints.cpp (+16-12)
  • (modified) clang-tools-extra/clangd/Quality.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/Selection.cpp (+10-7)
  • (modified) clang-tools-extra/clangd/SemanticHighlighting.cpp (+1-16)
  • (modified) clang-tools-extra/clangd/XRefs.cpp (+9-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp (+80-43)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp (+3-4)
  • (modified) clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp (+1-1)
  • (modified) clang-tools-extra/clangd/unittests/ASTTests.cpp (+4-3)
  • (modified) clang-tools-extra/clangd/unittests/DumpASTTests.cpp (+6-9)
  • (modified) clang-tools-extra/clangd/unittests/FindTargetTests.cpp (+2-2)
  • (modified) clang-tools-extra/clangd/unittests/HoverTests.cpp (+5-5)
  • (modified) clang-tools-extra/clangd/unittests/InlayHintTests.cpp (+1-8)
  • (modified) clang-tools-extra/clangd/unittests/QualityTests.cpp (+9-5)
  • (modified) clang-tools-extra/clangd/unittests/SelectionTests.cpp (+2-2)
  • (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (+11-18)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp (-1)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp (+3-3)
  • (modified) clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp (+11-11)
  • (modified) clang/include/clang/AST/ASTConcept.h (+2-7)
  • (modified) clang/include/clang/AST/ASTContext.h (+94-107)
  • (modified) clang/include/clang/AST/ASTImporter.h (+1-1)
  • (modified) clang/include/clang/AST/ASTNodeTraverser.h (+12-11)
  • (modified) clang/include/clang/AST/ASTTypeTraits.h (+8-7)
  • (modified) clang/include/clang/AST/AbstractBasicReader.h (+17-27)
  • (modified) clang/include/clang/AST/AbstractBasicWriter.h (+18-20)
  • (modified) clang/include/clang/AST/CanonicalType.h (+4-7)
  • (modified) clang/include/clang/AST/Decl.h (+60-37)
  • (modified) clang/include/clang/AST/DeclBase.h (-10)
  • (modified) clang/include/clang/AST/DeclCXX.h (+54-39)
  • (modified) clang/include/clang/AST/DeclObjC.h (+3)
  • (modified) clang/include/clang/AST/DeclTemplate.h (+19-25)
  • (modified) clang/include/clang/AST/DependenceFlags.h (+1-1)
  • (modified) clang/include/clang/AST/DynamicRecursiveASTVisitor.h (+7-6)
  • (modified) clang/include/clang/AST/Expr.h (+2-2)
  • (modified) clang/include/clang/AST/ExprCXX.h (+4-4)
  • (modified) clang/include/clang/AST/JSONNodeDumper.h (-1)
  • (modified) clang/include/clang/AST/NestedNameSpecifier.h (+212-480)
  • (added) clang/include/clang/AST/NestedNameSpecifierBase.h (+585)
  • (modified) clang/include/clang/AST/ODRHash.h (+1-1)
  • (modified) clang/include/clang/AST/PrettyPrinter.h (+3-8)
  • (modified) clang/include/clang/AST/PropertiesBase.td (+3-3)
  • (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+177-105)
  • (modified) clang/include/clang/AST/TemplateBase.h (+17-23)
  • (modified) clang/include/clang/AST/TemplateName.h (+19-11)
  • (modified) clang/include/clang/AST/TextNodeDumper.h (+1-1)
  • (modified) clang/include/clang/AST/Type.h (+412-358)
  • (modified) clang/include/clang/AST/TypeLoc.h (+246-162)
  • (modified) clang/include/clang/AST/TypeProperties.td (+56-84)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchers.h (+66-91)
  • (modified) clang/include/clang/ASTMatchers/ASTMatchersInternal.h (+7-13)
  • (modified) clang/include/clang/Analysis/FlowSensitive/ASTOps.h (+8-2)
  • (modified) clang/include/clang/Basic/DeclNodes.td (+74-75)
  • (modified) clang/include/clang/Basic/TypeNodes.td (+1-2)
  • (modified) clang/include/clang/ExtractAPI/DeclarationFragments.h (+2-3)
  • (modified) clang/include/clang/Sema/CodeCompleteConsumer.h (+4-3)
  • (modified) clang/include/clang/Sema/DeclSpec.h (+9-39)
  • (modified) clang/include/clang/Sema/HeuristicResolver.h (+1-2)
  • (modified) clang/include/clang/Sema/ParsedTemplate.h (+16-10)
  • (modified) clang/include/clang/Sema/Sema.h (+17-21)
  • (modified) clang/include/clang/Sema/SemaInternal.h (+4-4)
  • (modified) clang/include/clang/Sema/TypoCorrection.h (+15-14)
  • (modified) clang/include/clang/Serialization/ASTRecordReader.h (+1-1)
  • (modified) clang/include/clang/Serialization/ASTRecordWriter.h (+2-3)
  • (modified) clang/include/clang/Serialization/TypeBitCodes.def (-1)
  • (modified) clang/include/clang/Tooling/Refactoring/Lookup.h (+1-2)
  • (modified) clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h (+9-6)
  • (modified) clang/lib/AST/APValue.cpp (+2-1)
  • (modified) clang/lib/AST/ASTConcept.cpp (+9-2)
  • (modified) clang/lib/AST/ASTContext.cpp (+574-538)
  • (modified) clang/lib/AST/ASTDiagnostic.cpp (+15-34)
  • (modified) clang/lib/AST/ASTDumper.cpp (+3-1)
  • (modified) clang/lib/AST/ASTImporter.cpp (+102-206)
  • (modified) clang/lib/AST/ASTImporterLookupTable.cpp (+8-8)
  • (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+81-100)
  • (modified) clang/lib/AST/ASTTypeTraits.cpp (+31-5)
  • (modified) clang/lib/AST/ByteCode/Compiler.cpp (+5-4)
  • (modified) clang/lib/AST/ByteCode/Context.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Descriptor.cpp (+5-3)
  • (modified) clang/lib/AST/ByteCode/Interp.cpp (+4-4)
  • (modified) clang/lib/AST/ByteCode/Interp.h (+1-4)
  • (modified) clang/lib/AST/ByteCode/InterpBuiltin.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/InterpFrame.cpp (+1-1)
  • (modified) clang/lib/AST/ByteCode/Pointer.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Program.cpp (+4-3)
  • (modified) clang/lib/AST/ByteCode/Record.cpp (+1-1)
  • (modified) clang/lib/AST/CXXInheritance.cpp (+10-6)
  • (modified) clang/lib/AST/Comment.cpp (-2)
  • (modified) clang/lib/AST/CommentSema.cpp (+3-11)
  • (modified) clang/lib/AST/ComparisonCategories.cpp (+1-1)
  • (modified) clang/lib/AST/ComputeDependence.cpp (+10-16)
  • (modified) clang/lib/AST/Decl.cpp (+44-71)
  • (modified) clang/lib/AST/DeclBase.cpp (+12-28)
  • (modified) clang/lib/AST/DeclCXX.cpp (+78-56)
  • (modified) clang/lib/AST/DeclPrinter.cpp (+16-44)
  • (modified) clang/lib/AST/DeclTemplate.cpp (+35-37)
  • (modified) clang/lib/AST/DeclarationName.cpp (+3-3)
  • (modified) clang/lib/AST/DynamicRecursiveASTVisitor.cpp (+41-12)
  • (modified) clang/lib/AST/Expr.cpp (+16-9)
  • (modified) clang/lib/AST/ExprCXX.cpp (+4-5)
  • (modified) clang/lib/AST/ExprConcepts.cpp (+2-2)
  • (modified) clang/lib/AST/ExprConstant.cpp (+43-26)
  • (modified) clang/lib/AST/FormatString.cpp (+6-4)
  • (modified) clang/lib/AST/InheritViz.cpp (+3-3)
  • (modified) clang/lib/AST/ItaniumCXXABI.cpp (+4-4)
  • (modified) clang/lib/AST/ItaniumMangle.cpp (+76-129)
  • (modified) clang/lib/AST/JSONNodeDumper.cpp (+16-20)
  • (modified) clang/lib/AST/MicrosoftMangle.cpp (+10-11)
  • (modified) clang/lib/AST/NestedNameSpecifier.cpp (+94-429)
  • (modified) clang/lib/AST/ODRHash.cpp (+47-80)
  • (modified) clang/lib/AST/OpenMPClause.cpp (+11-15)
  • (modified) clang/lib/AST/ParentMapContext.cpp (+4-2)
  • (modified) clang/lib/AST/PrintfFormatString.cpp (+1-1)
  • (modified) clang/lib/AST/QualTypeNames.cpp (+183-187)
  • (modified) clang/lib/AST/RecordLayoutBuilder.cpp (+13-14)
  • (modified) clang/lib/AST/ScanfFormatString.cpp (+3-2)
  • (modified) clang/lib/AST/StmtPrinter.cpp (+10-23)
  • (modified) clang/lib/AST/StmtProfile.cpp (+7-8)
  • (modified) clang/lib/AST/TemplateBase.cpp (+28-4)
  • (modified) clang/lib/AST/TemplateName.cpp (+31-18)
  • (modified) clang/lib/AST/TextNodeDumper.cpp (+50-32)
  • (modified) clang/lib/AST/Type.cpp (+317-154)
  • (modified) clang/lib/AST/TypeLoc.cpp (+206-30)
  • (modified) clang/lib/AST/TypePrinter.cpp (+143-118)
  • (modified) clang/lib/AST/VTTBuilder.cpp (+9-3)
  • (modified) clang/lib/AST/VTableBuilder.cpp (+5-3)
  • (modified) clang/lib/ASTMatchers/ASTMatchFinder.cpp (+63-52)
  • (modified) clang/lib/ASTMatchers/ASTMatchersInternal.cpp (+2-3)
  • (modified) clang/lib/ASTMatchers/Dynamic/Registry.cpp (+1-4)
  • (modified) clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp (+4-2)
  • (modified) clang/lib/Analysis/ThreadSafety.cpp (+3-1)
  • (modified) clang/lib/Analysis/ThreadSafetyCommon.cpp (+2-2)
  • (modified) clang/lib/Analysis/UnsafeBufferUsage.cpp (+8-4)
  • (modified) clang/lib/CodeGen/ABIInfo.cpp (+1-1)
  • (modified) clang/lib/CodeGen/ABIInfoImpl.cpp (+18-18)
  • (modified) clang/lib/CodeGen/CGBlocks.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCUDANV.cpp (+2-1)
  • (modified) clang/lib/CodeGen/CGCXX.cpp (+10-9)
  • (modified) clang/lib/CodeGen/CGCXXABI.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGCall.cpp (+16-11)
  • (modified) clang/lib/CodeGen/CGClass.cpp (+56-39)
  • (modified) clang/lib/CodeGen/CGDebugInfo.cpp (+65-62)
  • (modified) clang/lib/CodeGen/CGDecl.cpp (+9-4)
  • (modified) clang/lib/CodeGen/CGExpr.cpp (+29-16)
  • (modified) clang/lib/CodeGen/CGExprAgg.cpp (+17-8)
  • (modified) clang/lib/CodeGen/CGExprCXX.cpp (+20-17)
  • (modified) clang/lib/CodeGen/CGExprConstant.cpp (+21-8)
  • (modified) clang/lib/CodeGen/CGExprScalar.cpp (+7-4)
  • (modified) clang/lib/CodeGen/CGHLSLRuntime.cpp (+1-2)
  • (modified) clang/lib/CodeGen/CGNonTrivialStruct.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGObjC.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGObjCMac.cpp (+6-5)
  • (modified) clang/lib/CodeGen/CGObjCRuntime.cpp (+3-1)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntime.cpp (+21-14)
  • (modified) clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGPointerAuth.cpp (+1-1)
  • (modified) clang/lib/CodeGen/CGStmt.cpp (+2-2)
  • (modified) clang/lib/CodeGen/CGStmtOpenMP.cpp (+6-3)
  • (modified) clang/lib/CodeGen/CGVTables.cpp (+4-4)
  • (modified) clang/lib/CodeGen/CodeGenFunction.cpp (+3-5)
  • (modified) clang/lib/CodeGen/CodeGenFunction.h (+3-3)
  • (modified) clang/lib/CodeGen/CodeGenModule.cpp (+17-11)
  • (modified) clang/lib/CodeGen/CodeGenTBAA.cpp (+7-6)
  • (modified) clang/lib/CodeGen/CodeGenTypes.cpp (+20-13)
  • (modified) clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp (+2-1)
  • (modified) clang/lib/CodeGen/ItaniumCXXABI.cpp (+40-28)
  • (modified) clang/lib/CodeGen/MicrosoftCXXABI.cpp (+13-12)
  • (modified) clang/lib/CodeGen/SwiftCallingConv.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AArch64.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/AMDGPU.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/ARC.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/ARM.cpp (+5-4)
  • (modified) clang/lib/CodeGen/Targets/BPF.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/CSKY.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/Hexagon.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/Lanai.cpp (+3-2)
  • (modified) clang/lib/CodeGen/Targets/LoongArch.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/Mips.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/NVPTX.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/PNaCl.cpp (+2-2)
  • (modified) clang/lib/CodeGen/Targets/PPC.cpp (+5-3)
  • (modified) clang/lib/CodeGen/Targets/RISCV.cpp (+6-4)
  • (modified) clang/lib/CodeGen/Targets/SPIR.cpp (+3-3)
  • (modified) clang/lib/CodeGen/Targets/Sparc.cpp (+1-1)
  • (modified) clang/lib/CodeGen/Targets/SystemZ.cpp (+4-4)
  • (modified) clang/lib/CodeGen/Targets/WebAssembly.cpp (+2-1)
  • (modified) clang/lib/CodeGen/Targets/X86.cpp (+35-24)
  • (modified) clang/lib/CodeGen/Targets/XCore.cpp (+2-2)
  • (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+57-60)
  • (modified) clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp (+1-1)
  • (modified) clang/lib/Frontend/ASTConsumers.cpp (+5-2)
  • (modified) clang/lib/Frontend/ASTUnit.cpp (+1-1)
  • (modified) clang/lib/Index/IndexTypeSourceInfo.cpp (+20-32)
  • (modified) clang/lib/Index/USRGeneration.cpp (+9-9)
  • (modified) clang/lib/InstallAPI/Visitor.cpp (+4-4)
  • (modified) clang/lib/Interpreter/InterpreterValuePrinter.cpp (+1-1)
  • (modified) clang/lib/Interpreter/Value.cpp (+3-3)
  • (modified) clang/lib/Parse/ParseDeclCXX.cpp (+1-2)
  • (modified) clang/lib/Parse/ParseExprCXX.cpp (+8-5)
  • (modified) clang/lib/Parse/ParseTemplate.cpp (+17-12)
  • (modified) clang/lib/Parse/ParseTentative.cpp (+1-1)
  • (modified) clang/lib/Parse/Parser.cpp (+5-4)
  • (modified) clang/lib/Sema/AnalysisBasedWarnings.cpp (+4-7)
  • (modified) clang/lib/Sema/DeclSpec.cpp (+5-31)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp (+4-19)
  • (modified) clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h (+1-1)
  • (modified) clang/lib/Sema/HeuristicResolver.cpp (+23-27)
  • (modified) clang/lib/Sema/Sema.cpp (+12-9)
  • (modified) clang/lib/Sema/SemaAccess.cpp (+21-22)
  • (modified) clang/lib/Sema/SemaAvailability.cpp (+2-2)
  • (modified) clang/lib/Sema/SemaBPF.cpp (+3-3)
  • (modified) clang/lib/Sema/SemaCUDA.cpp (+5-2)
  • (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+184-147)
  • (modified) clang/lib/Sema/SemaCast.cpp (+25-26)
  • (modified) clang/lib/Sema/SemaChecking.cpp (+62-35)
  • (modified) clang/lib/Sema/SemaCodeComplete.cpp (+102-79)
  • (modified) clang/lib/Sema/SemaCoroutine.cpp (+16-19)
  • (modified) clang/lib/Sema/SemaDecl.cpp (+337-254)
  • (modified) clang/lib/Sema/SemaDeclAttr.cpp (+15-8)
  • (modified) clang/lib/Sema/SemaDeclCXX.cpp (+246-238)
  • (modified) clang/lib/Sema/SemaDeclObjC.cpp (+20-12)
  • (modified) clang/lib/Sema/SemaExceptionSpec.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaExpr.cpp (+70-55)
  • (modified) clang/lib/Sema/SemaExprCXX.cpp (+85-77)
  • (modified) clang/lib/Sema/SemaExprMember.cpp (+4-3)
  • (modified) clang/lib/Sema/SemaExprObjC.cpp (+8-7)
  • (modified) clang/lib/Sema/SemaFunctionEffects.cpp (+6-2)
  • (modified) clang/lib/Sema/SemaHLSL.cpp (+11-9)
  • (modified) clang/lib/Sema/SemaInit.cpp (+78-67)
  • (modified) clang/lib/Sema/SemaLambda.cpp (+4-4)
  • (modified) clang/lib/Sema/SemaLookup.cpp (+152-88)
  • (modified) clang/lib/Sema/SemaObjC.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaObjCProperty.cpp (+3-1)
  • (modified) clang/lib/Sema/SemaOpenMP.cpp (+8-5)
  • (modified) clang/lib/Sema/SemaOverload.cpp (+96-85)
  • (modified) clang/lib/Sema/SemaPPC.cpp (+4-2)
  • (modified) clang/lib/Sema/SemaSYCL.cpp (+1-1)
  • (modified) clang/lib/Sema/SemaStmt.cpp (+23-17)
  • (modified) clang/lib/Sema/SemaStmtAsm.cpp (+6-4)
  • (modified) clang/lib/Sema/SemaSwift.cpp (+3-2)
  • (modified) clang/lib/Sema/SemaTemplate.cpp (+258-286)
  • (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+71-91)
  • (modified) clang/lib/Sema/SemaTemplateDeductionGuide.cpp (+32-26)
  • (modified) clang/lib/Sema/SemaTemplateInstantiate.cpp (+75-109)
  • (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+37-47)
  • (modified) clang/lib/Sema/SemaTemplateVariadic.cpp (+21-18)
  • (modified) clang/lib/Sema/SemaType.cpp (+110-74)
  • (modified) clang/lib/Sema/SemaTypeTraits.cpp (+16-19)
  • (modified) clang/lib/Sema/TreeTransform.h (+420-563)
  • (modified) clang/lib/Sema/UsedDeclVisitor.h (+4-3)
  • (modified) clang/lib/Serialization/ASTReader.cpp (+58-68)
  • (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+8-20)
  • (modified) clang/lib/Serialization/ASTWriter.cpp (+58-55)
  • (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+3-4)
  • (modified) clang/lib/Serialization/TemplateArgumentHasher.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp (+1-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp (+2-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp (+2-5)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp (+3-1)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp (+1-4)
  • (modified) clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp (+5-6)
  • (modified) clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp (+7-9)
  • (modified) clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp (+10-23)
  • (modified) clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp (+2-6)
  • (modified) clang/lib/StaticAnalyzer/Core/CallEvent.cpp (+7-4)
  • (modified) clang/lib/StaticAnalyzer/Core/MemRegion.cpp (+2-2)
  • (modified) clang/lib/StaticAnalyzer/Core/RegionStore.cpp (+3-2)
  • (modified) clang/lib/StaticAnalyzer/Core/SValBuilder.cpp (+2-2)
diff --git a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
index 3e367ab1a5558..471ca45fb5a53 100644
--- a/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
+++ b/clang-tools-extra/clang-change-namespace/ChangeNamespace.cpp
@@ -31,24 +31,9 @@ llvm::SmallVector<llvm::StringRef, 4> splitSymbolName(llvm::StringRef Name) {
   return Splitted;
 }
 
-SourceLocation startLocationForType(TypeLoc TLoc) {
-  // For elaborated types (e.g. `struct a::A`) we want the portion after the
-  // `struct` but including the namespace qualifier, `a::`.
-  if (TLoc.getTypeLocClass() == TypeLoc::Elaborated) {
-    NestedNameSpecifierLoc NestedNameSpecifier =
-        TLoc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-    if (NestedNameSpecifier.getNestedNameSpecifier())
-      return NestedNameSpecifier.getBeginLoc();
-    TLoc = TLoc.getNextTypeLoc();
-  }
-  return TLoc.getBeginLoc();
-}
-
 SourceLocation endLocationForType(TypeLoc TLoc) {
-  // Dig past any namespace or keyword qualifications.
-  while (TLoc.getTypeLocClass() == TypeLoc::Elaborated ||
-         TLoc.getTypeLocClass() == TypeLoc::Qualified)
-    TLoc = TLoc.getNextTypeLoc();
+  if (auto QTL = TLoc.getAs<QualifiedTypeLoc>())
+    TLoc = QTL.getUnqualifiedLoc();
 
   // The location for template specializations (e.g. Foo<int>) includes the
   // templated types in its location range.  We want to restrict this to just
@@ -550,8 +535,8 @@ void ChangeNamespaceTool::run(
                  Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
                      "nested_specifier_loc")) {
     SourceLocation Start = Specifier->getBeginLoc();
-    SourceLocation End = endLocationForType(Specifier->getTypeLoc());
-    fixTypeLoc(Result, Start, End, Specifier->getTypeLoc());
+    SourceLocation End = endLocationForType(Specifier->castAsTypeLoc());
+    fixTypeLoc(Result, Start, End, Specifier->castAsTypeLoc());
   } else if (const auto *BaseInitializer =
                  Result.Nodes.getNodeAs<CXXCtorInitializer>(
                      "base_initializer")) {
@@ -562,19 +547,16 @@ void ChangeNamespaceTool::run(
     // filtered by matchers in some cases, e.g. the type is templated. We should
     // handle the record type qualifier instead.
     TypeLoc Loc = *TLoc;
-    while (Loc.getTypeLocClass() == TypeLoc::Qualified)
-      Loc = Loc.getNextTypeLoc();
-    if (Loc.getTypeLocClass() == TypeLoc::Elaborated) {
-      NestedNameSpecifierLoc NestedNameSpecifier =
-          Loc.castAs<ElaboratedTypeLoc>().getQualifierLoc();
-      // FIXME: avoid changing injected class names.
-      if (auto *NNS = NestedNameSpecifier.getNestedNameSpecifier()) {
-        const Type *SpecifierType = NNS->getAsType();
-        if (SpecifierType && SpecifierType->isRecordType())
-          return;
-      }
-    }
-    fixTypeLoc(Result, startLocationForType(Loc), endLocationForType(Loc), Loc);
+    if (auto QTL = Loc.getAs<QualifiedTypeLoc>())
+      Loc = QTL.getUnqualifiedLoc();
+    // FIXME: avoid changing injected class names.
+    if (NestedNameSpecifier NestedNameSpecifier =
+            Loc.getPrefix().getNestedNameSpecifier();
+        NestedNameSpecifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        NestedNameSpecifier.getAsType()->isRecordType())
+      return;
+    fixTypeLoc(Result, Loc.getNonElaboratedBeginLoc(), endLocationForType(Loc),
+               Loc);
   } else if (const auto *VarRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("var_ref")) {
     const auto *Var = Result.Nodes.getNodeAs<VarDecl>("var_decl");
@@ -588,10 +570,9 @@ void ChangeNamespaceTool::run(
   } else if (const auto *EnumConstRef =
                  Result.Nodes.getNodeAs<DeclRefExpr>("enum_const_ref")) {
     // Do not rename the reference if it is already scoped by the EnumDecl name.
-    if (EnumConstRef->hasQualifier() &&
-        EnumConstRef->getQualifier()->getKind() ==
-            NestedNameSpecifier::SpecifierKind::TypeSpec &&
-        EnumConstRef->getQualifier()->getAsType()->isEnumeralType())
+    if (NestedNameSpecifier Qualifier = EnumConstRef->getQualifier();
+        Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
+        Qualifier.getAsType()->isEnumeralType())
       return;
     const auto *EnumConstDecl =
         Result.Nodes.getNodeAs<EnumConstantDecl>("enum_const_decl");
diff --git a/clang-tools-extra/clang-doc/Serialize.cpp b/clang-tools-extra/clang-doc/Serialize.cpp
index 6cc372ce98a6d..8ac807b935a04 100644
--- a/clang-tools-extra/clang-doc/Serialize.cpp
+++ b/clang-tools-extra/clang-doc/Serialize.cpp
@@ -883,8 +883,8 @@ parseBases(RecordInfo &I, const CXXRecordDecl *D, bool IsFileInRootDir,
     return;
   for (const CXXBaseSpecifier &B : D->bases()) {
     if (const RecordType *Ty = B.getType()->getAs<RecordType>()) {
-      if (const CXXRecordDecl *Base =
-              cast_or_null<CXXRecordDecl>(Ty->getDecl()->getDefinition())) {
+      if (const CXXRecordDecl *Base = cast_or_null<CXXRecordDecl>(
+              Ty->getOriginalDecl()->getDefinition())) {
         // Initialized without USR and name, this will be set in the following
         // if-else stmt.
         BaseRecordInfo BI(
diff --git a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
index bb48883f88815..1f30d27c0a54f 100644
--- a/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
+++ b/clang-tools-extra/clang-include-fixer/find-all-symbols/FindAllSymbols.cpp
@@ -216,8 +216,7 @@ void FindAllSymbols::registerMatchers(MatchFinder *MatchFinder) {
   // Uses of most types: just look at what the typeLoc refers to.
   MatchFinder->addMatcher(
       typeLoc(isExpansionInMainFile(),
-              loc(qualType(allOf(unless(elaboratedType()),
-                                 hasDeclaration(Types.bind("use")))))),
+              loc(qualType(hasDeclaration(Types.bind("use"))))),
       this);
   // Uses of typedefs: these are often transparent to hasDeclaration, so we need
   // to handle them explicitly.
diff --git a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
index f9d75978d0ea8..fac6e0418d163 100644
--- a/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
+++ b/clang-tools-extra/clang-tidy/ClangTidyDiagnosticConsumer.cpp
@@ -533,7 +533,8 @@ void ClangTidyDiagnosticConsumer::forwardDiagnostic(const Diagnostic &Info) {
       Builder << reinterpret_cast<const NamedDecl *>(Info.getRawArg(Index));
       break;
     case clang::DiagnosticsEngine::ak_nestednamespec:
-      Builder << reinterpret_cast<NestedNameSpecifier *>(Info.getRawArg(Index));
+      Builder << NestedNameSpecifier::getFromVoidPointer(
+          reinterpret_cast<void *>(Info.getRawArg(Index)));
       break;
     case clang::DiagnosticsEngine::ak_declcontext:
       Builder << reinterpret_cast<DeclContext *>(Info.getRawArg(Index));
diff --git a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
index 28e8fe002d575..5bce285bea7b9 100644
--- a/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/CrtpConstructorAccessibilityCheck.cpp
@@ -43,7 +43,8 @@ static bool isDerivedClassBefriended(const CXXRecordDecl *CRTP,
       return false;
     }
 
-    return FriendType->getType()->getAsCXXRecordDecl() == Derived;
+    return declaresSameEntity(FriendType->getType()->getAsCXXRecordDecl(),
+                              Derived);
   });
 }
 
@@ -55,7 +56,8 @@ getDerivedParameter(const ClassTemplateSpecializationDecl *CRTP,
       CRTP->getTemplateArgs().asArray(), [&](const TemplateArgument &Arg) {
         ++Idx;
         return Arg.getKind() == TemplateArgument::Type &&
-               Arg.getAsType()->getAsCXXRecordDecl() == Derived;
+               declaresSameEntity(Arg.getAsType()->getAsCXXRecordDecl(),
+                                  Derived);
       });
 
   return AnyOf ? CRTP->getSpecializedTemplate()
diff --git a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
index a179d4bf66b4d..3cacb90cace52 100644
--- a/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/EasilySwappableParametersCheck.cpp
@@ -577,7 +577,7 @@ approximateImplicitConversion(const TheCheck &Check, QualType LType,
                               ImplicitConversionModellingMode ImplicitMode);
 
 static inline bool isUselessSugar(const Type *T) {
-  return isa<AttributedType, DecayedType, ElaboratedType, ParenType>(T);
+  return isa<AttributedType, DecayedType, ParenType>(T);
 }
 
 namespace {
@@ -1040,7 +1040,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
   const auto *ToRecord = To->getAsCXXRecordDecl();
   if (isDerivedToBase(FromRecord, ToRecord)) {
     LLVM_DEBUG(llvm::dbgs() << "--- approximateStdConv. Derived To Base.\n");
-    WorkType = QualType{ToRecord->getTypeForDecl(), FastQualifiersToApply};
+    WorkType = QualType{
+        ToRecord->getASTContext().getCanonicalTagType(ToRecord)->getTypePtr(),
+        FastQualifiersToApply};
   }
 
   if (Ctx.getLangOpts().CPlusPlus17 && FromPtr && ToPtr) {
@@ -1072,9 +1074,9 @@ approximateStandardConversionSequence(const TheCheck &Check, QualType From,
     WorkType = To;
   }
 
-  if (WorkType == To) {
+  if (Ctx.hasSameType(WorkType, To)) {
     LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Reached 'To' type.\n");
-    return {WorkType};
+    return {Ctx.getCommonSugaredType(WorkType, To)};
   }
 
   LLVM_DEBUG(llvm::dbgs() << "<<< approximateStdConv. Did not reach 'To'.\n");
@@ -1219,7 +1221,7 @@ tryConversionOperators(const TheCheck &Check, const CXXRecordDecl *RD,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{RecordType, ToType};
     // The conversion from the operator call's return type to ToType was
@@ -1270,7 +1272,7 @@ tryConvertingConstructors(const TheCheck &Check, QualType FromType,
 
   if (std::optional<UserDefinedConversionSelector::PreparedConversion>
           SelectedConversion = ConversionSet()) {
-    QualType RecordType{RD->getTypeForDecl(), 0};
+    CanQualType RecordType = RD->getASTContext().getCanonicalTagType(RD);
 
     ConversionSequence Result{FromType, RecordType};
     Result.AfterFirstStandard = SelectedConversion->Seq.AfterFirstStandard;
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
index 75ef628436738..070ed04efffc4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardDeclarationNamespaceCheck.cpp
@@ -69,10 +69,9 @@ void ForwardDeclarationNamespaceCheck::check(
     //      struct B { friend A; };
     //    \endcode
     // `A` will not be marked as "referenced" in the AST.
-    if (const TypeSourceInfo *Tsi = Decl->getFriendType()) {
-      QualType Desugared = Tsi->getType().getDesugaredType(*Result.Context);
-      FriendTypes.insert(Desugared.getTypePtr());
-    }
+    if (const TypeSourceInfo *Tsi = Decl->getFriendType())
+      FriendTypes.insert(
+          Tsi->getType()->getCanonicalTypeUnqualified().getTypePtr());
   }
 }
 
@@ -119,7 +118,9 @@ void ForwardDeclarationNamespaceCheck::onEndOfTranslationUnit() {
       if (CurDecl->hasDefinition() || CurDecl->isReferenced()) {
         continue; // Skip forward declarations that are used/referenced.
       }
-      if (FriendTypes.contains(CurDecl->getTypeForDecl())) {
+      if (FriendTypes.contains(CurDecl->getASTContext()
+                                   .getCanonicalTagType(CurDecl)
+                                   ->getTypePtr())) {
         continue; // Skip forward declarations referenced as friend.
       }
       if (CurDecl->getLocation().isMacroID() ||
diff --git a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
index 00e8f7e514368..10b747e17e2ad 100644
--- a/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/ForwardingReferenceOverloadCheck.cpp
@@ -33,21 +33,17 @@ AST_MATCHER(QualType, isEnableIf) {
     BaseType = BaseType->getPointeeType().getTypePtr();
   }
   // Case: type parameter dependent (enable_if<is_integral<T>>).
-  if (const auto *Dependent = BaseType->getAs<DependentNameType>()) {
-    BaseType = Dependent->getQualifier()->getAsType();
-  }
+  if (const auto *Dependent = BaseType->getAs<DependentNameType>())
+    BaseType = Dependent->getQualifier().getAsType();
   if (!BaseType)
     return false;
   if (CheckTemplate(BaseType->getAs<TemplateSpecializationType>()))
     return true; // Case: enable_if_t< >.
-  if (const auto *Elaborated = BaseType->getAs<ElaboratedType>()) {
-    if (const auto *Q = Elaborated->getQualifier())
-      if (const auto *Qualifier = Q->getAsType()) {
-        if (CheckTemplate(Qualifier->getAs<TemplateSpecializationType>())) {
-          return true; // Case: enable_if< >::type.
-        }
-      }
-  }
+  if (const auto *TT = BaseType->getAs<TypedefType>())
+    if (NestedNameSpecifier Q = TT->getQualifier();
+        Q.getKind() == NestedNameSpecifier::Kind::Type)
+      if (CheckTemplate(Q.getAsType()->getAs<TemplateSpecializationType>()))
+        return true; // Case: enable_if< >::type.
   return false;
 }
 AST_MATCHER_P(TemplateTypeParmDecl, hasDefaultArgument,
diff --git a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
index 75f1107904fce..07cd90d64c2a4 100644
--- a/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/IncorrectEnableIfCheck.cpp
@@ -32,13 +32,10 @@ AST_MATCHER_P(TemplateTypeParmDecl, hasUnnamedDefaultArgument,
 void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
   Finder->addMatcher(
       templateTypeParmDecl(
-          hasUnnamedDefaultArgument(
-              elaboratedTypeLoc(
-                  hasNamedTypeLoc(templateSpecializationTypeLoc(
-                                      loc(qualType(hasDeclaration(namedDecl(
-                                          hasName("::std::enable_if"))))))
-                                      .bind("enable_if_specialization")))
-                  .bind("elaborated")))
+          hasUnnamedDefaultArgument(templateSpecializationTypeLoc(
+                                        loc(qualType(hasDeclaration(namedDecl(
+                                            hasName("::std::enable_if"))))))
+                                        .bind("enable_if_specialization")))
           .bind("enable_if"),
       this);
 }
@@ -46,13 +43,11 @@ void IncorrectEnableIfCheck::registerMatchers(MatchFinder *Finder) {
 void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   const auto *EnableIf =
       Result.Nodes.getNodeAs<TemplateTypeParmDecl>("enable_if");
-  const auto *ElaboratedLoc =
-      Result.Nodes.getNodeAs<ElaboratedTypeLoc>("elaborated");
   const auto *EnableIfSpecializationLoc =
       Result.Nodes.getNodeAs<TemplateSpecializationTypeLoc>(
           "enable_if_specialization");
 
-  if (!EnableIf || !ElaboratedLoc || !EnableIfSpecializationLoc)
+  if (!EnableIf || !EnableIfSpecializationLoc)
     return;
 
   const SourceManager &SM = *Result.SourceManager;
@@ -62,8 +57,10 @@ void IncorrectEnableIfCheck::check(const MatchFinder::MatchResult &Result) {
   auto Diag = diag(EnableIf->getBeginLoc(),
                    "incorrect std::enable_if usage detected; use "
                    "'typename std::enable_if<...>::type'");
+  // FIXME: This should handle the enable_if specialization already having an
+  // elaborated keyword.
   if (!getLangOpts().CPlusPlus20) {
-    Diag << FixItHint::CreateInsertion(ElaboratedLoc->getBeginLoc(),
+    Diag << FixItHint::CreateInsertion(EnableIfSpecializationLoc->getBeginLoc(),
                                        "typename ");
   }
   Diag << FixItHint::CreateInsertion(RAngleLoc.getLocWithOffset(1), "::type");
diff --git a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
index 33642c407a3a9..5dc988d6662df 100644
--- a/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/MoveForwardingReferenceCheck.cpp
@@ -39,24 +39,31 @@ static void replaceMoveWithForward(const UnresolvedLookupExpr *Callee,
     // std::move(). This will hopefully prevent erroneous replacements if the
     // code does unusual things (e.g. create an alias for std::move() in
     // another namespace).
-    NestedNameSpecifier *NNS = Callee->getQualifier();
-    if (!NNS) {
+    NestedNameSpecifier NNS = Callee->getQualifier();
+    switch (NNS.getKind()) {
+    case NestedNameSpecifier::Kind::Null:
       // Called as "move" (i.e. presumably the code had a "using std::move;").
       // We still conservatively put a "std::" in front of the forward because
       // we don't know whether the code also had a "using std::forward;".
       Diag << FixItHint::CreateReplacement(CallRange, "std::" + ForwardName);
-    } else if (const NamespaceDecl *Namespace = NNS->getAsNamespace()) {
+      break;
+    case NestedNameSpecifier::Kind::Namespace: {
+      auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
       if (Namespace->getName() == "std") {
-        if (!NNS->getPrefix()) {
+        if (!Prefix) {
           // Called as "std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "std::" + ForwardName);
-        } else if (NNS->getPrefix()->getKind() == NestedNameSpecifier::Global) {
+        } else if (Prefix.getKind() == NestedNameSpecifier::Kind::Global) {
           // Called as "::std::move".
           Diag << FixItHint::CreateReplacement(CallRange,
                                                "::std::" + ForwardName);
         }
       }
+      break;
+    }
+    default:
+      return;
     }
   }
 }
diff --git a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
index 88d2f2c388d07..c29eec2d2abe8 100644
--- a/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/bugprone/SizeofExpressionCheck.cpp
@@ -425,7 +425,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
            "suspicious usage of 'sizeof(array)/sizeof(...)';"
            " denominator differs from the size of array elements")
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
-    } else if (NumTy && DenomTy && NumTy == DenomTy &&
+    } else if (NumTy && DenomTy && Ctx.hasSameType(NumTy, DenomTy) &&
                !NumTy->isDependentType()) {
       // Dependent type should not be compared.
       diag(E->getOperatorLoc(),
@@ -434,7 +434,7 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
           << E->getLHS()->getSourceRange() << E->getRHS()->getSourceRange();
     } else if (!WarnOnSizeOfPointer) {
       // When 'WarnOnSizeOfPointer' is enabled, these messages become redundant:
-      if (PointedTy && DenomTy && PointedTy == DenomTy) {
+      if (PointedTy && DenomTy && Ctx.hasSameType(PointedTy, DenomTy)) {
         diag(E->getOperatorLoc(),
              "suspicious usage of 'sizeof(...)/sizeof(...)'; size of pointer "
              "is divided by size of pointed type")
@@ -463,7 +463,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
     const auto *SizeOfExpr =
         Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-mul-expr");
 
-    if ((LP...
[truncated]

@QuietMisdreavus
Copy link
Contributor

ExtractAPI changes look good.

@cor3ntin cor3ntin requested review from shafik and Sirraide July 10, 2025 06:36
Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
backend:AArch64 backend:AMDGPU backend:ARC backend:ARM backend:CSKY backend:Hexagon backend:Lanai backend:loongarch backend:MIPS backend:PowerPC backend:RISC-V backend:Sparc backend:SystemZ backend:WebAssembly backend:X86 clang:analysis clang:as-a-library libclang and C++ API clang:bytecode Issues for the clang bytecode constexpr interpreter clang:codegen IR generation bugs: mangling, exceptions, etc. clang:dataflow Clang Dataflow Analysis framework - https://clang.llvm.org/docs/DataFlowAnalysisIntro.html clang:frontend Language frontend issues, e.g. anything involving "Sema" clang:modules C++20 modules and Clang Header Modules clang:openmp OpenMP related changes to Clang clang:static analyzer clang Clang issues not falling into any other category clang-tidy clang-tools-extra clangd coroutines C++20 coroutines debuginfo HLSL HLSL Language Support
Projects
None yet
3 participants