[clang] [clang-tools-extra] [clang] Improve nested name specifier AST representation (PR #147835)
Matheus Izvekov via cfe-commits
cfe-commits at lists.llvm.org
Thu Jul 10 10:13:09 PDT 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/147835
>From c33b81a0769706da3df039345001652dc28e809e Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Thu, 10 Jul 2025 14:03:40 -0300
Subject: [PATCH 1/4] [clang] Improve nested name specifier AST representation
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 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
---
clang/include/clang/AST/ASTConcept.h | 9 +-
clang/include/clang/AST/ASTContext.h | 201 ++-
clang/include/clang/AST/ASTImporter.h | 2 +-
clang/include/clang/AST/ASTNodeTraverser.h | 23 +-
clang/include/clang/AST/ASTTypeTraits.h | 15 +-
clang/include/clang/AST/AbstractBasicReader.h | 44 +-
clang/include/clang/AST/AbstractBasicWriter.h | 38 +-
clang/include/clang/AST/CanonicalType.h | 11 +-
clang/include/clang/AST/Decl.h | 97 +-
clang/include/clang/AST/DeclBase.h | 10 -
clang/include/clang/AST/DeclCXX.h | 93 +-
clang/include/clang/AST/DeclObjC.h | 3 +
clang/include/clang/AST/DeclTemplate.h | 44 +-
clang/include/clang/AST/DependenceFlags.h | 2 +-
.../clang/AST/DynamicRecursiveASTVisitor.h | 13 +-
clang/include/clang/AST/Expr.h | 4 +-
clang/include/clang/AST/ExprCXX.h | 8 +-
clang/include/clang/AST/JSONNodeDumper.h | 1 -
clang/include/clang/AST/NestedNameSpecifier.h | 692 ++++------
.../clang/AST/NestedNameSpecifierBase.h | 585 +++++++++
clang/include/clang/AST/ODRHash.h | 2 +-
clang/include/clang/AST/PrettyPrinter.h | 11 +-
clang/include/clang/AST/PropertiesBase.td | 6 +-
clang/include/clang/AST/RecursiveASTVisitor.h | 282 +++--
clang/include/clang/AST/TemplateBase.h | 40 +-
clang/include/clang/AST/TemplateName.h | 30 +-
clang/include/clang/AST/TextNodeDumper.h | 2 +-
clang/include/clang/AST/Type.h | 770 ++++++------
clang/include/clang/AST/TypeLoc.h | 408 +++---
clang/include/clang/AST/TypeProperties.td | 140 +--
clang/lib/AST/APValue.cpp | 3 +-
clang/lib/AST/ASTConcept.cpp | 11 +-
clang/lib/AST/ASTContext.cpp | 1112 +++++++++--------
clang/lib/AST/ASTDiagnostic.cpp | 49 +-
clang/lib/AST/ASTDumper.cpp | 4 +-
clang/lib/AST/ASTImporter.cpp | 308 ++---
clang/lib/AST/ASTImporterLookupTable.cpp | 16 +-
clang/lib/AST/ASTStructuralEquivalence.cpp | 181 ++-
clang/lib/AST/ASTTypeTraits.cpp | 36 +-
clang/lib/AST/ByteCode/Compiler.cpp | 9 +-
clang/lib/AST/ByteCode/Context.cpp | 2 +-
clang/lib/AST/ByteCode/Descriptor.cpp | 8 +-
clang/lib/AST/ByteCode/Interp.cpp | 8 +-
clang/lib/AST/ByteCode/Interp.h | 5 +-
clang/lib/AST/ByteCode/InterpBuiltin.cpp | 7 +-
clang/lib/AST/ByteCode/InterpFrame.cpp | 2 +-
clang/lib/AST/ByteCode/Pointer.cpp | 7 +-
clang/lib/AST/ByteCode/Program.cpp | 7 +-
clang/lib/AST/ByteCode/Record.cpp | 2 +-
clang/lib/AST/CXXInheritance.cpp | 16 +-
clang/lib/AST/Comment.cpp | 2 -
clang/lib/AST/CommentSema.cpp | 14 +-
clang/lib/AST/ComparisonCategories.cpp | 2 +-
clang/lib/AST/ComputeDependence.cpp | 26 +-
clang/lib/AST/Decl.cpp | 115 +-
clang/lib/AST/DeclBase.cpp | 40 +-
clang/lib/AST/DeclCXX.cpp | 134 +-
clang/lib/AST/DeclPrinter.cpp | 60 +-
clang/lib/AST/DeclTemplate.cpp | 72 +-
clang/lib/AST/DeclarationName.cpp | 6 +-
clang/lib/AST/DynamicRecursiveASTVisitor.cpp | 53 +-
clang/lib/AST/Expr.cpp | 25 +-
clang/lib/AST/ExprCXX.cpp | 9 +-
clang/lib/AST/ExprConcepts.cpp | 4 +-
clang/lib/AST/ExprConstant.cpp | 69 +-
clang/lib/AST/FormatString.cpp | 10 +-
clang/lib/AST/InheritViz.cpp | 6 +-
clang/lib/AST/ItaniumCXXABI.cpp | 8 +-
clang/lib/AST/ItaniumMangle.cpp | 205 ++-
clang/lib/AST/JSONNodeDumper.cpp | 36 +-
clang/lib/AST/MicrosoftMangle.cpp | 21 +-
clang/lib/AST/NestedNameSpecifier.cpp | 523 ++------
clang/lib/AST/ODRHash.cpp | 127 +-
clang/lib/AST/OpenMPClause.cpp | 26 +-
clang/lib/AST/ParentMapContext.cpp | 6 +-
clang/lib/AST/PrintfFormatString.cpp | 2 +-
clang/lib/AST/QualTypeNames.cpp | 370 +++---
clang/lib/AST/RecordLayoutBuilder.cpp | 27 +-
clang/lib/AST/ScanfFormatString.cpp | 5 +-
clang/lib/AST/StmtPrinter.cpp | 33 +-
clang/lib/AST/StmtProfile.cpp | 15 +-
clang/lib/AST/TemplateBase.cpp | 32 +-
clang/lib/AST/TemplateName.cpp | 49 +-
clang/lib/AST/TextNodeDumper.cpp | 82 +-
clang/lib/AST/Type.cpp | 471 ++++---
clang/lib/AST/TypeLoc.cpp | 236 +++-
clang/lib/AST/TypePrinter.cpp | 261 ++--
clang/lib/AST/VTTBuilder.cpp | 12 +-
clang/lib/AST/VTableBuilder.cpp | 8 +-
clang/lib/Sema/TreeTransform.h | 983 +++++++--------
90 files changed, 4908 insertions(+), 4656 deletions(-)
create mode 100644 clang/include/clang/AST/NestedNameSpecifierBase.h
diff --git a/clang/include/clang/AST/ASTConcept.h b/clang/include/clang/AST/ASTConcept.h
index c8f6330a73bb1..6ab82824458ab 100644
--- a/clang/include/clang/AST/ASTConcept.h
+++ b/clang/include/clang/AST/ASTConcept.h
@@ -15,7 +15,7 @@
#define LLVM_CLANG_AST_ASTCONCEPT_H
#include "clang/AST/DeclarationName.h"
-#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
#include "clang/AST/TemplateBase.h"
#include "clang/Basic/SourceLocation.h"
#include "clang/Basic/UnsignedOrNone.h"
@@ -175,12 +175,7 @@ class ConceptReference {
SourceLocation getLocation() const { return getConceptNameLoc(); }
- SourceLocation getBeginLoc() const LLVM_READONLY {
- // Note that if the qualifier is null the template KW must also be null.
- if (auto QualifierLoc = getNestedNameSpecifierLoc())
- return QualifierLoc.getBeginLoc();
- return getConceptNameInfo().getBeginLoc();
- }
+ SourceLocation getBeginLoc() const LLVM_READONLY;
SourceLocation getEndLoc() const LLVM_READONLY {
return getTemplateArgsAsWritten() &&
diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h
index 2b9cd035623cc..bb2e0c5bc630e 100644
--- a/clang/include/clang/AST/ASTContext.h
+++ b/clang/include/clang/AST/ASTContext.h
@@ -233,10 +233,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<TemplateSpecializationType, ASTContext&>
TemplateSpecializationTypes;
mutable llvm::FoldingSet<ParenType> ParenTypes{GeneralTypesLog2InitSize};
+ mutable llvm::FoldingSet<TagTypeFoldingSetPlaceholder> TagTypes;
+ mutable llvm::FoldingSet<FoldingSetPlaceholder<UnresolvedUsingType>>
+ UnresolvedUsingTypes;
mutable llvm::FoldingSet<UsingType> UsingTypes;
- mutable llvm::FoldingSet<TypedefType> TypedefTypes;
- mutable llvm::FoldingSet<ElaboratedType> ElaboratedTypes{
- GeneralTypesLog2InitSize};
+ mutable llvm::FoldingSet<FoldingSetPlaceholder<TypedefType>> TypedefTypes;
mutable llvm::FoldingSet<DependentNameType> DependentNameTypes;
mutable llvm::ContextualFoldingSet<DependentTemplateSpecializationType,
ASTContext&>
@@ -277,11 +278,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
mutable llvm::ContextualFoldingSet<ArrayParameterType, ASTContext &>
ArrayParameterTypes;
- /// The set of nested name specifiers.
+ /// Internal storage for NestedNameSpecifiers.
///
/// This set is managed by the NestedNameSpecifier class.
- mutable llvm::FoldingSet<NestedNameSpecifier> NestedNameSpecifiers;
- mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr;
+ mutable llvm::FoldingSet<NamespaceAndPrefixStorage>
+ NamespaceAndPrefixStorages;
/// A cache mapping from RecordDecls to ASTRecordLayouts.
///
@@ -1370,8 +1371,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Return a type with extended qualifiers.
QualType getExtQualType(const Type *Base, Qualifiers Quals) const;
- QualType getTypeDeclTypeSlow(const TypeDecl *Decl) const;
-
QualType getPipeType(QualType T, bool ReadOnly) const;
public:
@@ -1612,7 +1611,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Return the uniqued reference to the type for a member pointer to
/// the specified type in the specified nested name.
- QualType getMemberPointerType(QualType T, NestedNameSpecifier *Qualifier,
+ QualType getMemberPointerType(QualType T, NestedNameSpecifier Qualifier,
const CXXRecordDecl *Cls) const;
/// Return a non-unique reference to the type for a variable array of
@@ -1749,34 +1748,51 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool IsCanon = false) const;
public:
+ QualType getTypeDeclType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TypeDecl *Decl) const;
+
/// Return the unique reference to the type for the specified type
/// declaration.
- QualType getTypeDeclType(const TypeDecl *Decl,
- const TypeDecl *PrevDecl = nullptr) const {
- assert(Decl && "Passed null for Decl param");
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
-
- if (PrevDecl) {
- assert(PrevDecl->TypeForDecl && "previous decl has no TypeForDecl");
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- return QualType(PrevDecl->TypeForDecl, 0);
- }
+ QualType getTypeDeclType(const TypeDecl *Decl) const;
+ QualType getTypeDeclType(const TagDecl *) const = delete;
+ QualType getTypeDeclType(const TypedefDecl *) const = delete;
+ QualType getTypeDeclType(const TypeAliasDecl *) const = delete;
+ QualType getTypeDeclType(const UnresolvedUsingTypenameDecl *) const = delete;
- return getTypeDeclTypeSlow(Decl);
- }
+ CanQualType getCanonicalTypeDeclType(const TypeDecl *TD) const;
- QualType getUsingType(const UsingShadowDecl *Found,
- QualType Underlying) const;
+ QualType getUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const UsingShadowDecl *D,
+ QualType UnderlyingType = QualType()) const;
/// Return the unique reference to the type for the specified
/// typedef-name decl.
- QualType getTypedefType(const TypedefNameDecl *Decl,
- QualType Underlying = QualType()) const;
+ /// FIXME: TypeMatchesDeclOrNone is a workaround for a serialization issue:
+ /// The decl underlying type might still not be available.
+ QualType getTypedefType(
+ ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
+ const TypedefNameDecl *Decl, QualType UnderlyingType = QualType(),
+ std::optional<bool> TypeMatchesDeclOrNone = std::nullopt) const;
+
+ CanQualType getCanonicalTagType(const TagDecl *TD) const;
+ QualType getTagType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const TagDecl *TD,
+ bool OwnsTag) const;
- QualType getRecordType(const RecordDecl *Decl) const;
+private:
+ UnresolvedUsingType *getUnresolvedUsingTypeInternal(
+ ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
+ const UnresolvedUsingTypenameDecl *D, void *InsertPos,
+ const Type *CanonicalType) const;
- QualType getEnumType(const EnumDecl *Decl) const;
+ TagType *getTagTypeInternal(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const TagDecl *Tag,
+ bool OwnsTag, bool IsInjected,
+ const Type *CanonicalType,
+ bool WithFoldingSetNode) const;
+public:
/// Compute BestType and BestPromotionType for an enum based on the highest
/// number of negative and positive bits of its elements.
/// Returns true if enum width is too large.
@@ -1825,10 +1841,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
return MembersRepresentableByInt;
}
- QualType
- getUnresolvedUsingType(const UnresolvedUsingTypenameDecl *Decl) const;
-
- QualType getInjectedClassNameType(CXXRecordDecl *Decl, QualType TST) const;
+ CanQualType
+ getCanonicalUnresolvedUsingType(const UnresolvedUsingTypenameDecl *D) const;
+ QualType getUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const UnresolvedUsingTypenameDecl *D) const;
QualType getAttributedType(attr::Kind attrKind, QualType modifiedType,
QualType equivalentType,
@@ -1868,18 +1885,20 @@ class ASTContext : public RefCountedBase<ASTContext> {
TemplateName T, ArrayRef<TemplateArgument> CanonicalArgs) const;
QualType
- getTemplateSpecializationType(TemplateName T,
+ getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T,
ArrayRef<TemplateArgument> SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs,
QualType Underlying = QualType()) const;
QualType
- getTemplateSpecializationType(TemplateName T,
+ getTemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T,
ArrayRef<TemplateArgumentLoc> SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs,
QualType Canon = QualType()) const;
TypeSourceInfo *getTemplateSpecializationTypeInfo(
+ ElaboratedTypeKeyword Keyword, SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKeywordLoc,
TemplateName T, SourceLocation TLoc,
const TemplateArgumentListInfo &SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs,
@@ -1890,11 +1909,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getMacroQualifiedType(QualType UnderlyingTy,
const IdentifierInfo *MacroII) const;
- QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType NamedType,
- TagDecl *OwnedTagDecl = nullptr) const;
QualType getDependentNameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
+ NestedNameSpecifier NNS,
const IdentifierInfo *Name) const;
QualType getDependentTemplateSpecializationType(
@@ -1980,21 +1996,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
QualType getUnconstrainedType(QualType T) const;
/// C++17 deduced class template specialization type.
- QualType getDeducedTemplateSpecializationType(TemplateName Template,
+ QualType getDeducedTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ TemplateName Template,
QualType DeducedType,
bool IsDependent) const;
private:
- QualType getDeducedTemplateSpecializationTypeInternal(TemplateName Template,
- QualType DeducedType,
- bool IsDependent,
- QualType Canon) const;
+ QualType getDeducedTemplateSpecializationTypeInternal(
+ ElaboratedTypeKeyword Keyword, TemplateName Template,
+ QualType DeducedType, bool IsDependent, QualType Canon) const;
public:
- /// Return the unique reference to the type for the specified TagDecl
- /// (struct/union/class/enum) decl.
- QualType getTagDeclType(const TagDecl *Decl) const;
-
/// Return the unique type for "size_t" (C99 7.17), defined in
/// <stddef.h>.
///
@@ -2068,7 +2080,9 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// if it hasn't yet been built.
QualType getRawCFConstantStringType() const {
if (CFConstantStringTypeDecl)
- return getTypedefType(CFConstantStringTypeDecl);
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt,
+ CFConstantStringTypeDecl);
return QualType();
}
void setCFConstantStringType(QualType T);
@@ -2165,10 +2179,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
}
#include "clang/Basic/BuiltinTemplates.inc"
- /// Retrieve the Objective-C "instancetype" type, if already known;
- /// otherwise, returns a NULL type;
+ /// Retrieve the Objective-C "instancetype" type.
QualType getObjCInstanceType() {
- return getTypeDeclType(getObjCInstanceTypeDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt,
+ getObjCInstanceTypeDecl());
}
/// Retrieve the typedef declaration corresponding to the Objective-C
@@ -2181,7 +2196,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Retrieve the C FILE type.
QualType getFILEType() const {
if (FILEDecl)
- return getTypeDeclType(FILEDecl);
+ return getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, FILEDecl);
return QualType();
}
@@ -2193,7 +2209,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Retrieve the C jmp_buf type.
QualType getjmp_bufType() const {
if (jmp_bufDecl)
- return getTypeDeclType(jmp_bufDecl);
+ return getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, jmp_bufDecl);
return QualType();
}
@@ -2205,7 +2222,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Retrieve the C sigjmp_buf type.
QualType getsigjmp_bufType() const {
if (sigjmp_bufDecl)
- return getTypeDeclType(sigjmp_bufDecl);
+ return getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, sigjmp_bufDecl);
return QualType();
}
@@ -2217,12 +2235,13 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Retrieve the C ucontext_t type.
QualType getucontext_tType() const {
if (ucontext_tDecl)
- return getTypeDeclType(ucontext_tDecl);
+ return getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, ucontext_tDecl);
return QualType();
}
/// The result type of logical operations, '<', '>', '!=', etc.
- QualType getLogicalOperationType() const {
+ CanQualType getLogicalOperationType() const {
return getLangOpts().CPlusPlus ? BoolTy : IntTy;
}
@@ -2287,7 +2306,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// This is set up lazily, by Sema. \c id is always a (typedef for a)
/// pointer type, a pointer to a struct.
QualType getObjCIdType() const {
- return getTypeDeclType(getObjCIdDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, getObjCIdDecl());
}
/// Retrieve the typedef corresponding to the predefined 'SEL' type
@@ -2297,7 +2317,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Retrieve the type that corresponds to the predefined Objective-C
/// 'SEL' type.
QualType getObjCSelType() const {
- return getTypeDeclType(getObjCSelDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, getObjCSelDecl());
}
/// Retrieve the typedef declaration corresponding to the predefined
@@ -2309,7 +2330,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// This is set up lazily, by Sema. \c Class is always a (typedef for a)
/// pointer type, a pointer to a struct.
QualType getObjCClassType() const {
- return getTypeDeclType(getObjCClassDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, getObjCClassDecl());
}
/// Retrieve the Objective-C class declaration corresponding to
@@ -2328,7 +2350,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// type of 'BOOL' type.
QualType getBOOLType() const {
- return getTypeDeclType(getBOOLDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, getBOOLDecl());
}
/// Retrieve the type of the Objective-C \c Protocol class.
@@ -2342,7 +2365,8 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Retrieve the type of the \c __builtin_va_list type.
QualType getBuiltinVaListType() const {
- return getTypeDeclType(getBuiltinVaListDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, getBuiltinVaListDecl());
}
/// Retrieve the C type declaration corresponding to the predefined
@@ -2356,16 +2380,17 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Retrieve the type of the \c __builtin_ms_va_list type.
QualType getBuiltinMSVaListType() const {
- return getTypeDeclType(getBuiltinMSVaListDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, getBuiltinMSVaListDecl());
}
/// Retrieve the implicitly-predeclared 'struct _GUID' declaration.
TagDecl *getMSGuidTagDecl() const { return MSGuidTagDecl; }
/// Retrieve the implicitly-predeclared 'struct _GUID' type.
- QualType getMSGuidType() const {
+ CanQualType getMSGuidType() const {
assert(MSGuidTagDecl && "asked for GUID type but MS extensions disabled");
- return getTagDeclType(MSGuidTagDecl);
+ return getCanonicalTagType(MSGuidTagDecl);
}
/// Return whether a declaration to a builtin is allowed to be
@@ -2446,7 +2471,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
UnresolvedSetIterator End) const;
TemplateName getAssumedTemplateName(DeclarationName Name) const;
- TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS,
+ TemplateName getQualifiedTemplateName(NestedNameSpecifier Qualifier,
bool TemplateKeyword,
TemplateName Template) const;
TemplateName
@@ -2888,32 +2913,6 @@ class ASTContext : public RefCountedBase<ASTContext> {
/// Determine if two types are similar, ignoring only CVR qualifiers.
bool hasCvrSimilarType(QualType T1, QualType T2);
- /// Retrieves the "canonical" nested name specifier for a
- /// given nested name specifier.
- ///
- /// The canonical nested name specifier is a nested name specifier
- /// that uniquely identifies a type or namespace within the type
- /// system. For example, given:
- ///
- /// \code
- /// namespace N {
- /// struct S {
- /// template<typename T> struct X { typename T* type; };
- /// };
- /// }
- ///
- /// template<typename T> struct Y {
- /// typename N::S::X<T>::type member;
- /// };
- /// \endcode
- ///
- /// Here, the nested-name-specifier for N::S::X<T>:: will be
- /// S::X<template-param-0-0>, since 'S' and 'X' are uniquely defined
- /// by declarations in the type system and the canonical type for
- /// the template type parameter 'T' is template-param-0-0.
- NestedNameSpecifier *
- getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
-
/// Retrieves the default calling convention for the current target.
CallingConv getDefaultCallingConvention(bool IsVariadic,
bool IsCXXMethod,
@@ -3123,7 +3122,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
mergeExceptionSpecs(FunctionProtoType::ExceptionSpecInfo ESI1,
FunctionProtoType::ExceptionSpecInfo ESI2,
SmallVectorImpl<QualType> &ExceptionTypeStorage,
- bool AcceptDependent);
+ bool AcceptDependent) const;
// For two "same" types, return a type which has
// the common sugar between them. If Unqualified is true,
@@ -3131,7 +3130,7 @@ class ASTContext : public RefCountedBase<ASTContext> {
// The result will drop the qualifiers which do not occur
// in both types.
QualType getCommonSugaredType(QualType X, QualType Y,
- bool Unqualified = false);
+ bool Unqualified = false) const;
private:
// Helper for integer ordering
@@ -3149,23 +3148,11 @@ class ASTContext : public RefCountedBase<ASTContext> {
bool propertyTypesAreCompatible(QualType, QualType);
bool typesAreBlockPointerCompatible(QualType, QualType);
- bool isObjCIdType(QualType T) const {
- if (const auto *ET = dyn_cast<ElaboratedType>(T))
- T = ET->getNamedType();
- return T == getObjCIdType();
- }
+ bool isObjCIdType(QualType T) const { return T == getObjCIdType(); }
- bool isObjCClassType(QualType T) const {
- if (const auto *ET = dyn_cast<ElaboratedType>(T))
- T = ET->getNamedType();
- return T == getObjCClassType();
- }
+ bool isObjCClassType(QualType T) const { return T == getObjCClassType(); }
- bool isObjCSelType(QualType T) const {
- if (const auto *ET = dyn_cast<ElaboratedType>(T))
- T = ET->getNamedType();
- return T == getObjCSelType();
- }
+ bool isObjCSelType(QualType T) const { return T == getObjCSelType(); }
bool ObjCQualifiedIdTypesAreCompatible(const ObjCObjectPointerType *LHS,
const ObjCObjectPointerType *RHS,
diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h
index c40b92666a2ff..4a0ca45b785a9 100644
--- a/clang/include/clang/AST/ASTImporter.h
+++ b/clang/include/clang/AST/ASTImporter.h
@@ -404,7 +404,7 @@ class TypeSourceInfo;
///
/// \returns The equivalent nested-name-specifier in the "to"
/// context, or the import error.
- llvm::Expected<NestedNameSpecifier *> Import(NestedNameSpecifier *FromNNS);
+ llvm::Expected<NestedNameSpecifier> Import(NestedNameSpecifier FromNNS);
/// Import the given nested-name-specifier-loc from the "from"
/// context into the "to" context.
diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h
index 8ebabb2bde10d..d9dc8290b0e49 100644
--- a/clang/include/clang/AST/ASTNodeTraverser.h
+++ b/clang/include/clang/AST/ASTNodeTraverser.h
@@ -394,12 +394,14 @@ class ASTNodeTraverser
}
void VisitMemberPointerType(const MemberPointerType *T) {
// FIXME: Provide a NestedNameSpecifier visitor.
- NestedNameSpecifier *Qualifier = T->getQualifier();
- if (NestedNameSpecifier::SpecifierKind K = Qualifier->getKind();
- K == NestedNameSpecifier::TypeSpec)
- Visit(Qualifier->getAsType());
+ NestedNameSpecifier Qualifier = T->getQualifier();
+ if (NestedNameSpecifier::Kind K = Qualifier.getKind();
+ K == NestedNameSpecifier::Kind::Type)
+ Visit(Qualifier.getAsType());
if (T->isSugared())
- Visit(T->getMostRecentCXXRecordDecl()->getTypeForDecl());
+ Visit(cast<MemberPointerType>(T->getCanonicalTypeUnqualified())
+ ->getQualifier()
+ .getAsType());
Visit(T->getPointeeType());
}
void VisitArrayType(const ArrayType *T) { Visit(T->getElementType()); }
@@ -510,7 +512,7 @@ class ASTNodeTraverser
}
void VisitMemberPointerTypeLoc(MemberPointerTypeLoc TL) {
// FIXME: Provide NestedNamespecifierLoc visitor.
- Visit(TL.getQualifierLoc().getTypeLoc());
+ Visit(TL.getQualifierLoc().castAsTypeLoc());
}
void VisitVariableArrayTypeLoc(VariableArrayTypeLoc TL) {
Visit(TL.getSizeExpr());
@@ -772,17 +774,16 @@ class ASTNodeTraverser
}
void VisitUsingShadowDecl(const UsingShadowDecl *D) {
- if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
- Visit(TD->getTypeForDecl());
+ Visit(D->getTargetDecl());
}
void VisitFriendDecl(const FriendDecl *D) {
if (D->getFriendType()) {
// Traverse any CXXRecordDecl owned by this type, since
// it will not be in the parent context:
- if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
- if (auto *TD = ET->getOwnedTagDecl())
- Visit(TD);
+ if (auto *TT = D->getFriendType()->getType()->getAs<TagType>())
+ if (TT->isTagOwned())
+ Visit(TT->getOriginalDecl());
} else {
Visit(D->getFriendDecl());
}
diff --git a/clang/include/clang/AST/ASTTypeTraits.h b/clang/include/clang/AST/ASTTypeTraits.h
index 3988a15971db5..6f40705fb7436 100644
--- a/clang/include/clang/AST/ASTTypeTraits.h
+++ b/clang/include/clang/AST/ASTTypeTraits.h
@@ -307,7 +307,7 @@ class DynTypedNode {
/// For nodes which represent textual entities in the source code,
/// return their SourceRange. For all other nodes, return SourceRange().
- SourceRange getSourceRange() const;
+ SourceRange getSourceRange(bool IncludeQualifier = false) const;
/// @{
/// Imposes an order on \c DynTypedNode.
@@ -336,9 +336,9 @@ class DynTypedNode {
NodeKind)) {
auto NNSLA = getUnchecked<NestedNameSpecifierLoc>();
auto NNSLB = Other.getUnchecked<NestedNameSpecifierLoc>();
- return std::make_pair(NNSLA.getNestedNameSpecifier(),
+ return std::make_pair(NNSLA.getNestedNameSpecifier().getAsVoidPointer(),
NNSLA.getOpaqueData()) <
- std::make_pair(NNSLB.getNestedNameSpecifier(),
+ std::make_pair(NNSLB.getNestedNameSpecifier().getAsVoidPointer(),
NNSLB.getOpaqueData());
}
@@ -393,8 +393,9 @@ class DynTypedNode {
if (ASTNodeKind::getFromNodeKind<NestedNameSpecifierLoc>().isSame(
Val.NodeKind)) {
auto NNSL = Val.getUnchecked<NestedNameSpecifierLoc>();
- return llvm::hash_combine(NNSL.getNestedNameSpecifier(),
- NNSL.getOpaqueData());
+ return llvm::hash_combine(
+ NNSL.getNestedNameSpecifier().getAsVoidPointer(),
+ NNSL.getOpaqueData());
}
assert(Val.getMemoizationData());
@@ -539,8 +540,8 @@ struct DynTypedNode::BaseConverter<
: public DynCastPtrConverter<T, Attr> {};
template <>
-struct DynTypedNode::BaseConverter<
- NestedNameSpecifier, void> : public PtrConverter<NestedNameSpecifier> {};
+struct DynTypedNode::BaseConverter<NestedNameSpecifier, void>
+ : public ValueConverter<NestedNameSpecifier> {};
template <>
struct DynTypedNode::BaseConverter<
diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h
index 514f4cef3a694..f01232d044e18 100644
--- a/clang/include/clang/AST/AbstractBasicReader.h
+++ b/clang/include/clang/AST/AbstractBasicReader.h
@@ -197,7 +197,7 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
unsigned int_ = asImpl().readUInt32();
Decl *decl = asImpl().template readDeclAs<Decl>();
if (auto *recordDecl = dyn_cast<CXXRecordDecl>(decl))
- elemTy = getASTContext().getRecordType(recordDecl);
+ elemTy = getASTContext().getCanonicalTagType(recordDecl);
else
elemTy = cast<ValueDecl>(decl)->getType();
path.push_back(
@@ -252,44 +252,34 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> {
return EffectConditionExpr{asImpl().readExprRef()};
}
- NestedNameSpecifier *readNestedNameSpecifier() {
+ NestedNameSpecifier readNestedNameSpecifier() {
auto &ctx = getASTContext();
// We build this up iteratively.
- NestedNameSpecifier *cur = nullptr;
+ NestedNameSpecifier cur = std::nullopt;
uint32_t depth = asImpl().readUInt32();
for (uint32_t i = 0; i != depth; ++i) {
auto kind = asImpl().readNestedNameSpecifierKind();
switch (kind) {
- case NestedNameSpecifier::Identifier:
- cur = NestedNameSpecifier::Create(ctx, cur,
- asImpl().readIdentifier());
+ case NestedNameSpecifier::Kind::Namespace:
+ cur =
+ NestedNameSpecifier(ctx, asImpl().readNamespaceBaseDeclRef(), cur);
continue;
-
- case NestedNameSpecifier::Namespace:
- cur = NestedNameSpecifier::Create(ctx, cur,
- asImpl().readNamespaceDeclRef());
- continue;
-
- case NestedNameSpecifier::NamespaceAlias:
- cur = NestedNameSpecifier::Create(ctx, cur,
- asImpl().readNamespaceAliasDeclRef());
+ case NestedNameSpecifier::Kind::Type:
+ assert(!cur);
+ cur = NestedNameSpecifier(asImpl().readQualType().getTypePtr());
continue;
-
- case NestedNameSpecifier::TypeSpec:
- cur = NestedNameSpecifier::Create(ctx, cur,
- asImpl().readQualType().getTypePtr());
+ case NestedNameSpecifier::Kind::Global:
+ assert(!cur);
+ cur = NestedNameSpecifier::getGlobal();
continue;
-
- case NestedNameSpecifier::Global:
- cur = NestedNameSpecifier::GlobalSpecifier(ctx);
- continue;
-
- case NestedNameSpecifier::Super:
- cur = NestedNameSpecifier::SuperSpecifier(ctx,
- asImpl().readCXXRecordDeclRef());
+ case NestedNameSpecifier::Kind::Super:
+ assert(!cur);
+ cur = NestedNameSpecifier(asImpl().readCXXRecordDeclRef());
continue;
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
llvm_unreachable("bad nested name specifier kind");
}
diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h
index fedde8a2e46c5..214964188e962 100644
--- a/clang/include/clang/AST/AbstractBasicWriter.h
+++ b/clang/include/clang/AST/AbstractBasicWriter.h
@@ -181,7 +181,7 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
const Decl *baseOrMember = elem.getAsBaseOrMember().getPointer();
if (const auto *recordDecl = dyn_cast<CXXRecordDecl>(baseOrMember)) {
asImpl().writeDeclRef(recordDecl);
- elemTy = ctx.getRecordType(recordDecl);
+ elemTy = ctx.getCanonicalTagType(recordDecl);
} else {
const auto *valueDecl = cast<ValueDecl>(baseOrMember);
asImpl().writeDeclRef(valueDecl);
@@ -229,46 +229,44 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> {
asImpl().writeExprRef(CE.getCondition());
}
- void writeNestedNameSpecifier(NestedNameSpecifier *NNS) {
+ void writeNestedNameSpecifier(NestedNameSpecifier NNS) {
// Nested name specifiers usually aren't too long. I think that 8 would
// typically accommodate the vast majority.
- SmallVector<NestedNameSpecifier *, 8> nestedNames;
+ SmallVector<NestedNameSpecifier, 8> nestedNames;
// Push each of the NNS's onto a stack for serialization in reverse order.
while (NNS) {
nestedNames.push_back(NNS);
- NNS = NNS->getPrefix();
+ NNS = NNS.getKind() == NestedNameSpecifier::Kind::Namespace
+ ? NNS.getAsNamespaceAndPrefix().Prefix
+ : std::nullopt;
}
asImpl().writeUInt32(nestedNames.size());
while (!nestedNames.empty()) {
NNS = nestedNames.pop_back_val();
- NestedNameSpecifier::SpecifierKind kind = NNS->getKind();
+ NestedNameSpecifier::Kind kind = NNS.getKind();
asImpl().writeNestedNameSpecifierKind(kind);
switch (kind) {
- case NestedNameSpecifier::Identifier:
- asImpl().writeIdentifier(NNS->getAsIdentifier());
+ case NestedNameSpecifier::Kind::Namespace:
+ asImpl().writeNamespaceBaseDeclRef(
+ NNS.getAsNamespaceAndPrefix().Namespace);
continue;
- case NestedNameSpecifier::Namespace:
- asImpl().writeNamespaceDeclRef(NNS->getAsNamespace());
+ case NestedNameSpecifier::Kind::Type:
+ asImpl().writeQualType(QualType(NNS.getAsType(), 0));
continue;
- case NestedNameSpecifier::NamespaceAlias:
- asImpl().writeNamespaceAliasDeclRef(NNS->getAsNamespaceAlias());
- continue;
-
- case NestedNameSpecifier::TypeSpec:
- asImpl().writeQualType(QualType(NNS->getAsType(), 0));
- continue;
-
- case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Kind::Global:
// Don't need to write an associated value.
continue;
- case NestedNameSpecifier::Super:
- asImpl().writeDeclRef(NNS->getAsRecordDecl());
+ case NestedNameSpecifier::Kind::Super:
+ asImpl().writeDeclRef(NNS.getAsSuper());
continue;
+
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
llvm_unreachable("bad nested name specifier kind");
}
diff --git a/clang/include/clang/AST/CanonicalType.h b/clang/include/clang/AST/CanonicalType.h
index 35db68971e029..b5a4e94e1330a 100644
--- a/clang/include/clang/AST/CanonicalType.h
+++ b/clang/include/clang/AST/CanonicalType.h
@@ -453,7 +453,7 @@ template<>
struct CanProxyAdaptor<MemberPointerType>
: public CanProxyBase<MemberPointerType> {
LLVM_CLANG_CANPROXY_TYPE_ACCESSOR(getPointeeType)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(NestedNameSpecifier *, getQualifier)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(NestedNameSpecifier, getQualifier)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(const CXXRecordDecl *,
getMostRecentCXXRecordDecl)
};
@@ -551,21 +551,18 @@ struct CanProxyAdaptor<UnaryTransformType>
template<>
struct CanProxyAdaptor<TagType> : public CanProxyBase<TagType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(TagDecl *, getOriginalDecl)
};
template<>
struct CanProxyAdaptor<RecordType> : public CanProxyBase<RecordType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(RecordDecl *, getOriginalDecl)
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasConstFields)
};
template<>
struct CanProxyAdaptor<EnumType> : public CanProxyBase<EnumType> {
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getDecl)
- LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isBeingDefined)
+ LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(EnumDecl *, getOriginalDecl)
};
template<>
diff --git a/clang/include/clang/AST/Decl.h b/clang/include/clang/AST/Decl.h
index f70a039bf3517..80d20a23b3753 100644
--- a/clang/include/clang/AST/Decl.h
+++ b/clang/include/clang/AST/Decl.h
@@ -20,7 +20,7 @@
#include "clang/AST/DeclBase.h"
#include "clang/AST/DeclarationName.h"
#include "clang/AST/ExternalASTSource.h"
-#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
#include "clang/AST/Redeclarable.h"
#include "clang/AST/Type.h"
#include "clang/Basic/AddressSpaces.h"
@@ -565,8 +565,25 @@ class LabelDecl : public NamedDecl {
static bool classofKind(Kind K) { return K == Label; }
};
+/// Represents C++ namespaces and their aliases.
+class NamespaceBaseDecl : public NamedDecl {
+protected:
+ using NamedDecl::NamedDecl;
+
+public:
+ NamespaceDecl *getNamespace();
+ const NamespaceDecl *getNamespace() const {
+ return const_cast<NamespaceBaseDecl *>(this)->getNamespace();
+ }
+
+ static bool classof(const Decl *D) { return classofKind(D->getKind()); }
+ static bool classofKind(Kind K) {
+ return K >= firstNamespaceBase && K <= lastNamespaceBase;
+ }
+};
+
/// Represent a C++ namespace.
-class NamespaceDecl : public NamedDecl,
+class NamespaceDecl : public NamespaceBaseDecl,
public DeclContext,
public Redeclarable<NamespaceDecl> {
/// The starting location of the source range, pointing
@@ -813,9 +830,9 @@ class DeclaratorDecl : public ValueDecl {
/// Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : nullptr;
+ : std::nullopt;
}
/// Retrieve the nested-name-specifier (with source-location
@@ -3485,8 +3502,14 @@ class TypeDecl : public NamedDecl {
// check out ASTContext::getTypeDeclType or one of
// ASTContext::getTypedefType, ASTContext::getRecordType, etc. if you
// already know the specific kind of node this is.
- const Type *getTypeForDecl() const { return TypeForDecl; }
- void setTypeForDecl(const Type *TD) { TypeForDecl = TD; }
+ const Type *getTypeForDecl() const {
+ assert(!isa<TagDecl>(this));
+ return TypeForDecl;
+ }
+ void setTypeForDecl(const Type *TD) {
+ assert(!isa<TagDecl>(this));
+ TypeForDecl = TD;
+ }
SourceLocation getBeginLoc() const LLVM_READONLY { return LocStart; }
void setLocStart(SourceLocation L) { LocStart = L; }
@@ -3592,6 +3615,9 @@ class TypedefNameDecl : public TypeDecl, public Redeclarable<TypedefNameDecl> {
return isTransparentTagSlow();
}
+ const Type *getTypeForDecl() const = delete;
+ void setTypeForDecl(const Type *TD) = delete;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) {
@@ -3711,14 +3737,6 @@ class TagDecl : public TypeDecl,
/// True if this decl is currently being defined.
void setBeingDefined(bool V = true) { TagDeclBits.IsBeingDefined = V; }
- /// Indicates whether it is possible for declarations of this kind
- /// to have an out-of-date definition.
- ///
- /// This option is only enabled when modules are enabled.
- void setMayHaveOutOfDateDef(bool V = true) {
- TagDeclBits.MayHaveOutOfDateDef = V;
- }
-
public:
friend class ASTDeclReader;
friend class ASTDeclWriter;
@@ -3799,12 +3817,6 @@ class TagDecl : public TypeDecl,
TagDeclBits.IsFreeStanding = isFreeStanding;
}
- /// Indicates whether it is possible for declarations of this kind
- /// to have an out-of-date definition.
- ///
- /// This option is only enabled when modules are enabled.
- bool mayHaveOutOfDateDef() const { return TagDeclBits.MayHaveOutOfDateDef; }
-
/// Whether this declaration declares a type that is
/// dependent, i.e., a type that somehow depends on template
/// parameters.
@@ -3845,6 +3857,19 @@ class TagDecl : public TypeDecl,
/// the struct/union/class/enum.
TagDecl *getDefinition() const;
+ TagDecl *getDefinitionOrSelf() const {
+ if (TagDecl *Def = getDefinition())
+ return Def;
+ return const_cast<TagDecl *>(this);
+ }
+
+ /// Determines whether this entity is in the process of being defined.
+ bool isEntityBeingDefined() const {
+ if (const TagDecl *Def = getDefinition())
+ return Def->isBeingDefined();
+ return false;
+ }
+
StringRef getKindName() const {
return TypeWithKeyword::getTagTypeKindName(getTagKind());
}
@@ -3891,9 +3916,9 @@ class TagDecl : public TypeDecl,
/// Retrieve the nested-name-specifier that qualifies the name of this
/// declaration, if it was present in the source.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return hasExtInfo() ? getExtInfo()->QualifierLoc.getNestedNameSpecifier()
- : nullptr;
+ : std::nullopt;
}
/// Retrieve the nested-name-specifier (with source-location
@@ -3915,6 +3940,9 @@ class TagDecl : public TypeDecl,
return getExtInfo()->TemplParamLists[i];
}
+ const Type *getTypeForDecl() const = delete;
+ void setTypeForDecl(const Type *TD) = delete;
+
using TypeDecl::printName;
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;
@@ -4044,6 +4072,10 @@ class EnumDecl : public TagDecl {
return cast_or_null<EnumDecl>(TagDecl::getDefinition());
}
+ EnumDecl *getDefinitionOrSelf() const {
+ return cast_or_null<EnumDecl>(TagDecl::getDefinitionOrSelf());
+ }
+
static EnumDecl *Create(ASTContext &C, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, EnumDecl *PrevDecl,
@@ -4402,21 +4434,6 @@ class RecordDecl : public TagDecl {
void reorderDecls(const SmallVectorImpl<Decl *> &Decls);
- /// Determines whether this declaration represents the
- /// injected class name.
- ///
- /// The injected class name in C++ is the name of the class that
- /// appears inside the class itself. For example:
- ///
- /// \code
- /// struct C {
- /// // C is implicitly declared here as a synonym for the class name.
- /// };
- ///
- /// C::C c; // same as "C c;"
- /// \endcode
- bool isInjectedClassName() const;
-
/// Determine whether this record is a class describing a lambda
/// function object.
bool isLambda() const;
@@ -4441,6 +4458,10 @@ class RecordDecl : public TagDecl {
return cast_or_null<RecordDecl>(TagDecl::getDefinition());
}
+ RecordDecl *getDefinitionOrSelf() const {
+ return cast_or_null<RecordDecl>(TagDecl::getDefinitionOrSelf());
+ }
+
/// Returns whether this record is a union, or contains (at any nesting level)
/// a union member. This is used by CMSE to warn about possible information
/// leaks.
@@ -5271,6 +5292,8 @@ void Redeclarable<decl_type>::setPreviousDecl(decl_type *PrevDecl) {
/// We use this function to break a cycle between the inline definitions in
/// Type.h and Decl.h.
inline bool IsEnumDeclComplete(EnumDecl *ED) {
+ if (const auto *Def = ED->getDefinition())
+ return Def->isComplete();
return ED->isComplete();
}
diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h
index dd67ebc9873ff..5ac664202db6d 100644
--- a/clang/include/clang/AST/DeclBase.h
+++ b/clang/include/clang/AST/DeclBase.h
@@ -410,9 +410,6 @@ class alignas(8) Decl {
virtual ~Decl();
- /// Update a potentially out-of-date declaration.
- void updateOutOfDate(IdentifierInfo &II) const;
-
Linkage getCachedLinkage() const {
return static_cast<Linkage>(CacheValidAndLinkage);
}
@@ -1564,13 +1561,6 @@ class DeclContext {
LLVM_PREFERRED_TYPE(bool)
uint64_t IsFreeStanding : 1;
- /// Indicates whether it is possible for declarations of this kind
- /// to have an out-of-date definition.
- ///
- /// This option is only enabled when modules are enabled.
- LLVM_PREFERRED_TYPE(bool)
- uint64_t MayHaveOutOfDateDef : 1;
-
/// Has the full definition of this type been required by a use somewhere in
/// the TU.
LLVM_PREFERRED_TYPE(bool)
diff --git a/clang/include/clang/AST/DeclCXX.h b/clang/include/clang/AST/DeclCXX.h
index 05cddd024d7cf..1d2ef0f4f2319 100644
--- a/clang/include/clang/AST/DeclCXX.h
+++ b/clang/include/clang/AST/DeclCXX.h
@@ -545,21 +545,6 @@ class CXXRecordDecl : public RecordDecl {
return const_cast<CXXRecordDecl*>(this)->getMostRecentDecl();
}
- CXXRecordDecl *getMostRecentNonInjectedDecl() {
- CXXRecordDecl *Recent =
- static_cast<CXXRecordDecl *>(this)->getMostRecentDecl();
- while (Recent->isInjectedClassName()) {
- // FIXME: Does injected class name need to be in the redeclarations chain?
- assert(Recent->getPreviousDecl());
- Recent = Recent->getPreviousDecl();
- }
- return Recent;
- }
-
- const CXXRecordDecl *getMostRecentNonInjectedDecl() const {
- return const_cast<CXXRecordDecl*>(this)->getMostRecentNonInjectedDecl();
- }
-
CXXRecordDecl *getDefinition() const {
// We only need an update if we don't already know which
// declaration is the definition.
@@ -567,13 +552,18 @@ class CXXRecordDecl : public RecordDecl {
return DD ? DD->Definition : nullptr;
}
+ CXXRecordDecl *getDefinitionOrSelf() const {
+ if (auto *Def = getDefinition())
+ return Def;
+ return const_cast<CXXRecordDecl *>(this);
+ }
+
bool hasDefinition() const { return DefinitionData || dataPtr(); }
static CXXRecordDecl *Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id,
- CXXRecordDecl *PrevDecl = nullptr,
- bool DelayTypeCreation = false);
+ CXXRecordDecl *PrevDecl = nullptr);
static CXXRecordDecl *CreateLambda(const ASTContext &C, DeclContext *DC,
TypeSourceInfo *Info, SourceLocation Loc,
unsigned DependencyKind, bool IsGeneric,
@@ -1889,6 +1879,35 @@ class CXXRecordDecl : public RecordDecl {
DL.IsGenericLambda = IsGeneric;
}
+ /// Determines whether this declaration represents the
+ /// injected class name.
+ ///
+ /// The injected class name in C++ is the name of the class that
+ /// appears inside the class itself. For example:
+ ///
+ /// \code
+ /// struct C {
+ /// // C is implicitly declared here as a synonym for the class name.
+ /// };
+ ///
+ /// C::C c; // same as "C c;"
+ /// \endcode
+ bool isInjectedClassName() const;
+
+ /// Determines whether this declaration has is canonically of an injected
+ /// class type. These are non-instantiated class template patterns, which can
+ /// be used from within the class template itself. For example:
+ ///
+ /// \code
+ /// template<class T> struct C {
+ /// C *t; // Here `C *` is a pointer to an injected class type.
+ /// };
+ /// \endcode
+ bool hasInjectedClassType() const;
+
+ CanQualType
+ getCanonicalTemplateSpecializationType(const ASTContext &Ctx) const;
+
// Determine whether this type is an Interface Like type for
// __interface inheritance purposes.
bool isInterfaceLike() const;
@@ -3117,7 +3136,7 @@ class UsingDirectiveDecl : public NamedDecl {
/// Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3172,7 +3191,7 @@ class UsingDirectiveDecl : public NamedDecl {
/// \code
/// namespace Foo = Bar;
/// \endcode
-class NamespaceAliasDecl : public NamedDecl,
+class NamespaceAliasDecl : public NamespaceBaseDecl,
public Redeclarable<NamespaceAliasDecl> {
friend class ASTDeclReader;
@@ -3189,14 +3208,14 @@ class NamespaceAliasDecl : public NamedDecl,
/// The Decl that this alias points to, either a NamespaceDecl or
/// a NamespaceAliasDecl.
- NamedDecl *Namespace;
+ NamespaceBaseDecl *Namespace;
NamespaceAliasDecl(ASTContext &C, DeclContext *DC,
SourceLocation NamespaceLoc, SourceLocation AliasLoc,
IdentifierInfo *Alias, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc, NamedDecl *Namespace)
- : NamedDecl(NamespaceAlias, DC, AliasLoc, Alias), redeclarable_base(C),
- NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
+ SourceLocation IdentLoc, NamespaceBaseDecl *Namespace)
+ : NamespaceBaseDecl(NamespaceAlias, DC, AliasLoc, Alias),
+ redeclarable_base(C), NamespaceLoc(NamespaceLoc), IdentLoc(IdentLoc),
QualifierLoc(QualifierLoc), Namespace(Namespace) {}
void anchor() override;
@@ -3208,13 +3227,11 @@ class NamespaceAliasDecl : public NamedDecl,
NamespaceAliasDecl *getMostRecentDeclImpl() override;
public:
- static NamespaceAliasDecl *Create(ASTContext &C, DeclContext *DC,
- SourceLocation NamespaceLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace);
+ static NamespaceAliasDecl *
+ Create(ASTContext &C, DeclContext *DC, SourceLocation NamespaceLoc,
+ SourceLocation AliasLoc, IdentifierInfo *Alias,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc,
+ NamespaceBaseDecl *Namespace);
static NamespaceAliasDecl *CreateDeserialized(ASTContext &C, GlobalDeclID ID);
@@ -3240,7 +3257,7 @@ class NamespaceAliasDecl : public NamedDecl,
/// Retrieve the nested-name-specifier that qualifies the
/// name of the namespace.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3268,7 +3285,7 @@ class NamespaceAliasDecl : public NamedDecl,
/// Retrieve the namespace that this alias refers to, which
/// may either be a NamespaceDecl or a NamespaceAliasDecl.
- NamedDecl *getAliasedNamespace() const { return Namespace; }
+ NamespaceBaseDecl *getAliasedNamespace() const { return Namespace; }
SourceRange getSourceRange() const override LLVM_READONLY {
return SourceRange(NamespaceLoc, IdentLoc);
@@ -3602,7 +3619,7 @@ class UsingDecl : public BaseUsingDecl, public Mergeable<UsingDecl> {
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// Retrieve the nested-name-specifier that qualifies the name.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3792,13 +3809,11 @@ class UsingEnumDecl : public BaseUsingDecl, public Mergeable<UsingEnumDecl> {
/// The source location of the 'enum' keyword.
SourceLocation getEnumLoc() const { return EnumLocation; }
void setEnumLoc(SourceLocation L) { EnumLocation = L; }
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return getQualifierLoc().getNestedNameSpecifier();
}
NestedNameSpecifierLoc getQualifierLoc() const {
- if (auto ETL = EnumType->getTypeLoc().getAs<ElaboratedTypeLoc>())
- return ETL.getQualifierLoc();
- return NestedNameSpecifierLoc();
+ return getEnumTypeLoc().getPrefix();
}
// Returns the "qualifier::Name" part as a TypeLoc.
TypeLoc getEnumTypeLoc() const {
@@ -3958,7 +3973,7 @@ class UnresolvedUsingValueDecl : public ValueDecl,
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// Retrieve the nested-name-specifier that qualifies the name.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -4048,7 +4063,7 @@ class UnresolvedUsingTypenameDecl
NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
/// Retrieve the nested-name-specifier that qualifies the name.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
diff --git a/clang/include/clang/AST/DeclObjC.h b/clang/include/clang/AST/DeclObjC.h
index 9014d76f8433b..2541edba83855 100644
--- a/clang/include/clang/AST/DeclObjC.h
+++ b/clang/include/clang/AST/DeclObjC.h
@@ -643,6 +643,9 @@ class ObjCTypeParamDecl : public TypedefNameDecl {
/// from the explicitly-specified bound.
SourceLocation getColonLoc() const { return ColonLoc; }
+ using TypeDecl::getTypeForDecl;
+ using TypeDecl::setTypeForDecl;
+
// Implement isa/cast/dyncast/etc.
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCTypeParam; }
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 1ff6cc6fcb7d1..e657463a24c36 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1880,14 +1880,14 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
void getNameForDiagnostic(raw_ostream &OS, const PrintingPolicy &Policy,
bool Qualified) const override;
- // FIXME: This is broken. CXXRecordDecl::getMostRecentDecl() returns a
- // different "most recent" declaration from this function for the same
- // declaration, because we don't override getMostRecentDeclImpl(). But
- // it's not clear that we should override that, because the most recent
- // declaration as a CXXRecordDecl sometimes is the injected-class-name.
ClassTemplateSpecializationDecl *getMostRecentDecl() {
return cast<ClassTemplateSpecializationDecl>(
- getMostRecentNonInjectedDecl());
+ CXXRecordDecl::getMostRecentDecl());
+ }
+
+ ClassTemplateSpecializationDecl *getDefinitionOrSelf() const {
+ return cast<ClassTemplateSpecializationDecl>(
+ CXXRecordDecl::getDefinitionOrSelf());
}
/// Retrieve the template that this specialization specializes.
@@ -2105,10 +2105,13 @@ class ClassTemplatePartialSpecializationDecl
llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
InstantiatedFromMember;
+ mutable CanQualType CanonInjectedTST;
+
ClassTemplatePartialSpecializationDecl(
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
+ CanQualType CanonInjectedTST,
ClassTemplatePartialSpecializationDecl *PrevDecl);
ClassTemplatePartialSpecializationDecl(ASTContext &C)
@@ -2125,7 +2128,7 @@ class ClassTemplatePartialSpecializationDecl
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
- ArrayRef<TemplateArgument> Args, QualType CanonInjectedType,
+ ArrayRef<TemplateArgument> Args, CanQualType CanonInjectedTST,
ClassTemplatePartialSpecializationDecl *PrevDecl);
static ClassTemplatePartialSpecializationDecl *
@@ -2142,12 +2145,6 @@ class ClassTemplatePartialSpecializationDecl
return TemplateParams;
}
- /// Get the template argument list of the template parameter list.
- ArrayRef<TemplateArgument>
- getInjectedTemplateArgs(const ASTContext &Context) const {
- return getTemplateParameters()->getInjectedTemplateArgs(Context);
- }
-
/// \brief All associated constraints of this partial specialization,
/// including the requires clause and any constraints derived from
/// constrained-parameters.
@@ -2229,14 +2226,10 @@ class ClassTemplatePartialSpecializationDecl
return First->InstantiatedFromMember.setInt(true);
}
- /// Retrieves the injected specialization type for this partial
- /// specialization. This is not the same as the type-decl-type for
- /// this partial specialization, which is an InjectedClassNameType.
- QualType getInjectedSpecializationType() const {
- assert(getTypeForDecl() && "partial specialization has no type set!");
- return cast<InjectedClassNameType>(getTypeForDecl())
- ->getInjectedSpecializationType();
- }
+ /// Retrieves the canonical injected specialization type for this partial
+ /// specialization.
+ CanQualType
+ getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const;
SourceRange getSourceRange() const override LLVM_READONLY;
@@ -2271,8 +2264,8 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
llvm::FoldingSetVector<ClassTemplatePartialSpecializationDecl>
PartialSpecializations;
- /// The injected-class-name type for this class template.
- QualType InjectedClassNameType;
+ /// The Injected Template Specialization Type for this declaration.
+ CanQualType CanonInjectedTST;
Common() = default;
};
@@ -2409,7 +2402,7 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
findPartialSpecInstantiatedFromMember(
ClassTemplatePartialSpecializationDecl *D);
- /// Retrieve the template specialization type of the
+ /// Retrieve the canonical template specialization type of the
/// injected-class-name for this class template.
///
/// The injected-class-name for a class template \c X is \c
@@ -2423,7 +2416,8 @@ class ClassTemplateDecl : public RedeclarableTemplateDecl {
/// typedef array this_type; // "array" is equivalent to "array<T, N>"
/// };
/// \endcode
- QualType getInjectedClassNameSpecialization();
+ CanQualType
+ getCanonicalInjectedSpecializationType(const ASTContext &Ctx) const;
using spec_iterator = SpecIterator<ClassTemplateSpecializationDecl>;
using spec_range = llvm::iterator_range<spec_iterator>;
diff --git a/clang/include/clang/AST/DependenceFlags.h b/clang/include/clang/AST/DependenceFlags.h
index bdcaabc143cc4..c4395259f0758 100644
--- a/clang/include/clang/AST/DependenceFlags.h
+++ b/clang/include/clang/AST/DependenceFlags.h
@@ -293,7 +293,7 @@ inline TypeDependence toSemanticDependence(TypeDependence D) {
}
inline NestedNameSpecifierDependence
-toNestedNameSpecifierDependendence(TypeDependence D) {
+toNestedNameSpecifierDependence(TypeDependence D) {
return Dependence(D).nestedNameSpecifier();
}
diff --git a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
index 703cca22777ad..7b5bdca318348 100644
--- a/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
+++ b/clang/include/clang/AST/DynamicRecursiveASTVisitor.h
@@ -134,8 +134,7 @@ template <bool IsConst> class DynamicRecursiveASTVisitorBase {
/// Recursively visit a C++ nested-name-specifier.
///
/// \returns false if the visitation was terminated early, true otherwise.
- virtual bool
- TraverseNestedNameSpecifier(MaybeConst<NestedNameSpecifier> *NNS);
+ virtual bool TraverseNestedNameSpecifier(NestedNameSpecifier NNS);
/// Recursively visit a C++ nested-name-specifier with location
/// information.
@@ -181,14 +180,14 @@ template <bool IsConst> class DynamicRecursiveASTVisitorBase {
///
/// \returns false if the visitation was terminated early, true
/// otherwise (including when the argument is a Null type).
- virtual bool TraverseType(QualType T);
+ virtual bool TraverseType(QualType T, bool TraverseQualifier = true);
/// Recursively visit a type with location, by dispatching to
/// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
///
/// \returns false if the visitation was terminated early, true
/// otherwise (including when the argument is a Null type location).
- virtual bool TraverseTypeLoc(TypeLoc TL);
+ virtual bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true);
/// Recursively visit an Objective-C protocol reference with location
/// information.
@@ -273,7 +272,8 @@ template <bool IsConst> class DynamicRecursiveASTVisitorBase {
#define ABSTRACT_TYPE(CLASS, BASE)
#define TYPE(CLASS, BASE) \
bool WalkUpFrom##CLASS##Type(MaybeConst<CLASS##Type> *T); \
- virtual bool Traverse##CLASS##Type(MaybeConst<CLASS##Type> *T);
+ virtual bool Traverse##CLASS##Type(MaybeConst<CLASS##Type> *T, \
+ bool TraverseQualifier = true);
#include "clang/AST/TypeNodes.inc"
#define TYPE(CLASS, BASE) \
@@ -283,7 +283,8 @@ template <bool IsConst> class DynamicRecursiveASTVisitorBase {
// TypeLocs.
#define ABSTRACT_TYPELOC(CLASS, BASE)
#define TYPELOC(CLASS, BASE) \
- virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+ virtual bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL, \
+ bool TraverseQualifier);
#include "clang/AST/TypeLocNodes.def"
#define TYPELOC(CLASS, BASE) \
diff --git a/clang/include/clang/AST/Expr.h b/clang/include/clang/AST/Expr.h
index 523c0326d47ef..d973e2cb822bd 100644
--- a/clang/include/clang/AST/Expr.h
+++ b/clang/include/clang/AST/Expr.h
@@ -1366,7 +1366,7 @@ class DeclRefExpr final
/// If the name was qualified, retrieves the nested-name-specifier
/// that precedes the name. Otherwise, returns NULL.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return getQualifierLoc().getNestedNameSpecifier();
}
@@ -3393,7 +3393,7 @@ class MemberExpr final
/// If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// NULL.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return getQualifierLoc().getNestedNameSpecifier();
}
diff --git a/clang/include/clang/AST/ExprCXX.h b/clang/include/clang/AST/ExprCXX.h
index a22c32241ac61..f8fa782f3fb68 100644
--- a/clang/include/clang/AST/ExprCXX.h
+++ b/clang/include/clang/AST/ExprCXX.h
@@ -2780,7 +2780,7 @@ class CXXPseudoDestructorExpr : public Expr {
/// If the member name was qualified, retrieves the
/// nested-name-specifier that precedes the member name. Otherwise, returns
/// null.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3221,7 +3221,7 @@ class OverloadExpr : public Expr {
SourceLocation getNameLoc() const { return NameInfo.getLoc(); }
/// Fetches the nested-name qualifier, if one was given.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3497,7 +3497,7 @@ class DependentScopeDeclRefExpr final
/// Retrieve the nested-name-specifier that qualifies this
/// declaration.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
@@ -3912,7 +3912,7 @@ class CXXDependentScopeMemberExpr final
}
/// Retrieve the nested-name-specifier that qualifies the member name.
- NestedNameSpecifier *getQualifier() const {
+ NestedNameSpecifier getQualifier() const {
return QualifierLoc.getNestedNameSpecifier();
}
diff --git a/clang/include/clang/AST/JSONNodeDumper.h b/clang/include/clang/AST/JSONNodeDumper.h
index 570662b58ccf0..8640780206dba 100644
--- a/clang/include/clang/AST/JSONNodeDumper.h
+++ b/clang/include/clang/AST/JSONNodeDumper.h
@@ -240,7 +240,6 @@ class JSONNodeDumper
void VisitInjectedClassNameType(const InjectedClassNameType *ICNT);
void VisitObjCInterfaceType(const ObjCInterfaceType *OIT);
void VisitPackExpansionType(const PackExpansionType *PET);
- void VisitElaboratedType(const ElaboratedType *ET);
void VisitMacroQualifiedType(const MacroQualifiedType *MQT);
void VisitMemberPointerType(const MemberPointerType *MPT);
diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h
index 952c79753d10a..fba57369f5131 100644
--- a/clang/include/clang/AST/NestedNameSpecifier.h
+++ b/clang/include/clang/AST/NestedNameSpecifier.h
@@ -6,534 +6,266 @@
//
//===----------------------------------------------------------------------===//
//
-// This file defines the NestedNameSpecifier class, which represents
-// a C++ nested-name-specifier.
+// This file completes the definition of the NestedNameSpecifier class.
//
//===----------------------------------------------------------------------===//
#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
#define LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
-#include "clang/AST/DependenceFlags.h"
-#include "clang/Basic/Diagnostic.h"
-#include "clang/Basic/SourceLocation.h"
+#include "clang/AST/Decl.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
+#include "clang/AST/Type.h"
+#include "clang/AST/TypeLoc.h"
#include "llvm/ADT/DenseMapInfo.h"
-#include "llvm/ADT/FoldingSet.h"
-#include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/Compiler.h"
-#include <cstdint>
-#include <cstdlib>
-#include <utility>
namespace clang {
-class ASTContext;
-class CXXRecordDecl;
-class IdentifierInfo;
-class LangOptions;
-class NamespaceAliasDecl;
-class NamespaceDecl;
-struct PrintingPolicy;
-class Type;
-class TypeLoc;
-
-/// Represents a C++ nested name specifier, such as
-/// "\::std::vector<int>::".
-///
-/// C++ nested name specifiers are the prefixes to qualified
-/// names. For example, "foo::" in "foo::x" is a nested name
-/// specifier. Nested name specifiers are made up of a sequence of
-/// specifiers, each of which can be a namespace, type, identifier
-/// (for dependent names), decltype specifier, or the global specifier ('::').
-/// The last two specifiers can only appear at the start of a
-/// nested-namespace-specifier.
-class NestedNameSpecifier : public llvm::FoldingSetNode {
- /// Enumeration describing
- enum StoredSpecifierKind {
- StoredIdentifier = 0,
- StoredDecl = 1,
- StoredTypeSpec = 2
- };
-
- /// The nested name specifier that precedes this nested name
- /// specifier.
- ///
- /// The pointer is the nested-name-specifier that precedes this
- /// one. The integer stores one of the first four values of type
- /// SpecifierKind.
- llvm::PointerIntPair<NestedNameSpecifier *, 2, StoredSpecifierKind> Prefix;
-
- /// The last component in the nested name specifier, which
- /// can be an identifier, a declaration, or a type.
- ///
- /// When the pointer is NULL, this specifier represents the global
- /// specifier '::'. Otherwise, the pointer is one of
- /// IdentifierInfo*, Namespace*, or Type*, depending on the kind of
- /// specifier as encoded within the prefix.
- void* Specifier = nullptr;
-
-public:
- /// The kind of specifier that completes this nested name
- /// specifier.
- enum SpecifierKind {
- /// An identifier, stored as an IdentifierInfo*.
- Identifier,
-
- /// A namespace, stored as a NamespaceDecl*.
- Namespace,
-
- /// A namespace alias, stored as a NamespaceAliasDecl*.
- NamespaceAlias,
-
- /// A type, stored as a Type*.
- TypeSpec,
-
- /// The global specifier '::'. There is no stored value.
- Global,
-
- /// Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
- /// the class it appeared in.
- Super
- };
-
-private:
- /// Builds the global specifier.
- NestedNameSpecifier() : Prefix(nullptr, StoredIdentifier) {}
-
- /// Copy constructor used internally to clone nested name
- /// specifiers.
- NestedNameSpecifier(const NestedNameSpecifier &Other) = default;
-
- /// Either find or insert the given nested name specifier
- /// mockup in the given context.
- static NestedNameSpecifier *FindOrInsert(const ASTContext &Context,
- const NestedNameSpecifier &Mockup);
-
-public:
- NestedNameSpecifier &operator=(const NestedNameSpecifier &) = delete;
-
- /// Builds a specifier combining a prefix and an identifier.
- ///
- /// The prefix must be dependent, since nested name specifiers
- /// referencing an identifier are only permitted when the identifier
- /// cannot be resolved.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const IdentifierInfo *II);
-
- /// Builds a nested name specifier that names a namespace.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceDecl *NS);
-
- /// Builds a nested name specifier that names a namespace alias.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceAliasDecl *Alias);
-
- /// Builds a nested name specifier that names a type.
- static NestedNameSpecifier *
- Create(const ASTContext &Context, NestedNameSpecifier *Prefix, const Type *T);
-
- /// Builds a specifier that consists of just an identifier.
- ///
- /// The nested-name-specifier is assumed to be dependent, but has no
- /// prefix because the prefix is implied by something outside of the
- /// nested name specifier, e.g., in "x->Base::f", the "x" has a dependent
- /// type.
- static NestedNameSpecifier *Create(const ASTContext &Context,
- const IdentifierInfo *II);
-
- /// Returns the nested name specifier representing the global
- /// scope.
- static NestedNameSpecifier *GlobalSpecifier(const ASTContext &Context);
-
- /// Returns the nested name specifier representing the __super scope
- /// for the given CXXRecordDecl.
- static NestedNameSpecifier *SuperSpecifier(const ASTContext &Context,
- CXXRecordDecl *RD);
-
- /// Return the prefix of this nested name specifier.
- ///
- /// The prefix contains all of the parts of the nested name
- /// specifier that precede this current specifier. For example, for a
- /// nested name specifier that represents "foo::bar::", the current
- /// specifier will contain "bar::" and the prefix will contain
- /// "foo::".
- NestedNameSpecifier *getPrefix() const { return Prefix.getPointer(); }
-
- /// Determine what kind of nested name specifier is stored.
- SpecifierKind getKind() const;
-
- /// Retrieve the identifier stored in this nested name
- /// specifier.
- IdentifierInfo *getAsIdentifier() const {
- if (Prefix.getInt() == StoredIdentifier)
- return (IdentifierInfo *)Specifier;
-
- return nullptr;
+auto NestedNameSpecifier::getKind() const -> Kind {
+ if (!isStoredKind()) {
+ switch (getFlagKind()) {
+ case FlagKind::Null:
+ return Kind::Null;
+ case FlagKind::Global:
+ return Kind::Global;
+ case FlagKind::Invalid:
+ llvm_unreachable("use of invalid NestedNameSpecifier");
+ }
+ llvm_unreachable("unhandled FlagKind");
}
+ switch (auto [K, Ptr] = getStored(); K) {
+ case StoredKind::Type:
+ return Kind::Type;
+ case StoredKind::NamespaceWithGlobal:
+ case StoredKind::NamespaceWithNamespace:
+ return Kind::Namespace;
+ case StoredKind::NamespaceOrSuper:
+ switch (static_cast<const Decl *>(Ptr)->getKind()) {
+ case Decl::Namespace:
+ case Decl::NamespaceAlias:
+ return Kind::Namespace;
+ case Decl::CXXRecord:
+ case Decl::ClassTemplateSpecialization:
+ case Decl::ClassTemplatePartialSpecialization:
+ return Kind::Super;
+ default:
+ llvm_unreachable("unexpected decl kind");
+ }
+ }
+ llvm_unreachable("unknown StoredKind");
+}
- /// Retrieve the namespace stored in this nested name
- /// specifier.
- NamespaceDecl *getAsNamespace() const;
+NestedNameSpecifier::NestedNameSpecifier(const Type *T)
+ : NestedNameSpecifier({StoredKind::Type, T}) {
+ assert(getKind() == Kind::Type);
+}
- /// Retrieve the namespace alias stored in this nested name
- /// specifier.
- NamespaceAliasDecl *getAsNamespaceAlias() const;
+auto NestedNameSpecifier::MakeNamespacePtrKind(
+ const ASTContext &Ctx, const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix) -> PtrKind {
+ switch (Prefix.getKind()) {
+ case Kind::Null:
+ return {StoredKind::NamespaceOrSuper, Namespace};
+ case Kind::Global:
+ return {StoredKind::NamespaceWithGlobal, Namespace};
+ case Kind::Namespace:
+ return {StoredKind::NamespaceWithNamespace,
+ MakeNamespaceAndPrefixStorage(Ctx, Namespace, Prefix)};
+ case Kind::Super:
+ case Kind::Type:
+ llvm_unreachable("invalid prefix for namespace");
+ }
+ llvm_unreachable("unhandled kind");
+}
- /// Retrieve the record declaration stored in this nested name
- /// specifier.
- CXXRecordDecl *getAsRecordDecl() const;
+/// Builds a nested name specifier that names a namespace.
+NestedNameSpecifier::NestedNameSpecifier(const ASTContext &Ctx,
+ const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix)
+ : NestedNameSpecifier(MakeNamespacePtrKind(Ctx, Namespace, Prefix)) {
+ assert(getKind() == Kind::Namespace);
+}
- /// Retrieve the type stored in this nested name specifier.
- const Type *getAsType() const {
- if (Prefix.getInt() == StoredTypeSpec)
- return (const Type *)Specifier;
+/// Builds a nested name specifier that names a class through microsoft's
+/// __super specifier.
+NestedNameSpecifier::NestedNameSpecifier(CXXRecordDecl *RD)
+ : NestedNameSpecifier({StoredKind::NamespaceOrSuper, RD}) {
+ assert(getKind() == Kind::Super);
+}
+CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
+ switch (getKind()) {
+ case Kind::Super:
+ return getAsSuper();
+ case Kind::Type:
+ return getAsType()->getAsCXXRecordDecl();
+ case Kind::Global:
+ case Kind::Namespace:
+ case Kind::Null:
return nullptr;
}
+ llvm_unreachable("Invalid NNS Kind!");
+}
- /// Fully translate this nested name specifier to a type.
- /// Unlike getAsType, this will convert this entire nested
- /// name specifier chain into its equivalent type.
- const Type *translateToType(const ASTContext &Context) const;
-
- NestedNameSpecifierDependence getDependence() const;
-
- /// Whether this nested name specifier refers to a dependent
- /// type or not.
- bool isDependent() const;
-
- /// Whether this nested name specifier involves a template
- /// parameter.
- bool isInstantiationDependent() const;
+NestedNameSpecifier NestedNameSpecifier::getCanonical() const {
+ switch (getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
+ // These are canonical and unique.
+ return *this;
+ case NestedNameSpecifier::Kind::Namespace: {
+ // A namespace is canonical; build a nested-name-specifier with
+ // this namespace and no prefix.
+ const NamespaceBaseDecl *ND = getAsNamespaceAndPrefix().Namespace;
+ return NestedNameSpecifier(
+ {StoredKind::NamespaceOrSuper, ND->getNamespace()->getCanonicalDecl()});
+ }
+ case NestedNameSpecifier::Kind::Type:
+ return NestedNameSpecifier(
+ getAsType()->getCanonicalTypeInternal().getTypePtr());
+ }
+ llvm_unreachable("unhandled kind");
+}
- /// Whether this nested-name-specifier contains an unexpanded
- /// parameter pack (for C++11 variadic templates).
- bool containsUnexpandedParameterPack() const;
+bool NestedNameSpecifier::isCanonical() const {
+ return *this == getCanonical();
+}
- /// Whether this nested name specifier contains an error.
- bool containsErrors() const;
+TypeLoc NestedNameSpecifierLoc::castAsTypeLoc() const {
+ return TypeLoc(Qualifier.getAsType(), LoadPointer(/*Offset=*/0));
+}
- /// Print this nested name specifier to the given output stream. If
- /// `ResolveTemplateArguments` is true, we'll print actual types, e.g.
- /// `ns::SomeTemplate<int, MyClass>` instead of
- /// `ns::SomeTemplate<Container::value_type, T>`.
- void print(raw_ostream &OS, const PrintingPolicy &Policy,
- bool ResolveTemplateArguments = false,
- bool PrintFinalScopeResOp = true) const;
+TypeLoc NestedNameSpecifierLoc::getAsTypeLoc() const {
+ if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
+ return TypeLoc();
+ return castAsTypeLoc();
+}
- void Profile(llvm::FoldingSetNodeID &ID) const {
- ID.AddPointer(Prefix.getOpaqueValue());
- ID.AddPointer(Specifier);
+unsigned
+NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier Qualifier) {
+ // Location of the trailing '::'.
+ unsigned Length = sizeof(SourceLocation::UIntTy);
+
+ switch (Qualifier.getKind()) {
+ case NestedNameSpecifier::Kind::Global:
+ // Nothing more to add.
+ break;
+
+ case NestedNameSpecifier::Kind::Namespace:
+ case NestedNameSpecifier::Kind::Super:
+ // The location of the identifier or namespace name.
+ Length += sizeof(SourceLocation::UIntTy);
+ break;
+
+ case NestedNameSpecifier::Kind::Type:
+ // The "void*" that points at the TypeLoc data.
+ // Note: the 'template' keyword is part of the TypeLoc.
+ Length += sizeof(void *);
+ break;
+
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("Expected a non-NULL qualifier");
}
- /// Dump the nested name specifier to standard output to aid
- /// in debugging.
- void dump(const LangOptions &LO) const;
- void dump() const;
- void dump(llvm::raw_ostream &OS) const;
- void dump(llvm::raw_ostream &OS, const LangOptions &LO) const;
-};
+ return Length;
+}
-/// A C++ nested-name-specifier augmented with source location
-/// information.
-class NestedNameSpecifierLoc {
- NestedNameSpecifier *Qualifier = nullptr;
- void *Data = nullptr;
-
- /// Determines the data length for the last component in the
- /// given nested-name-specifier.
- static unsigned getLocalDataLength(NestedNameSpecifier *Qualifier);
-
- /// Determines the data length for the entire
- /// nested-name-specifier.
- static unsigned getDataLength(NestedNameSpecifier *Qualifier);
-
-public:
- /// Construct an empty nested-name-specifier.
- NestedNameSpecifierLoc() = default;
-
- /// Construct a nested-name-specifier with source location information
- /// from
- NestedNameSpecifierLoc(NestedNameSpecifier *Qualifier, void *Data)
- : Qualifier(Qualifier), Data(Data) {}
-
- /// Evaluates true when this nested-name-specifier location is
- /// non-empty.
- explicit operator bool() const { return Qualifier; }
-
- /// Evaluates true when this nested-name-specifier location is
- /// non-empty.
- bool hasQualifier() const { return Qualifier; }
-
- /// Retrieve the nested-name-specifier to which this instance
- /// refers.
- NestedNameSpecifier *getNestedNameSpecifier() const {
- return Qualifier;
- }
+NamespaceAndPrefixLoc NestedNameSpecifierLoc::castAsNamespaceAndPrefix() const {
+ auto [Namespace, Prefix] = Qualifier.getAsNamespaceAndPrefix();
+ return {Namespace, NestedNameSpecifierLoc(Prefix, Data)};
+}
- /// Retrieve the opaque pointer that refers to source-location data.
- void *getOpaqueData() const { return Data; }
-
- /// Retrieve the source range covering the entirety of this
- /// nested-name-specifier.
- ///
- /// For example, if this instance refers to a nested-name-specifier
- /// \c \::std::vector<int>::, the returned source range would cover
- /// from the initial '::' to the last '::'.
- SourceRange getSourceRange() const LLVM_READONLY {
- return SourceRange(getBeginLoc(), getEndLoc());
- }
+NamespaceAndPrefixLoc NestedNameSpecifierLoc::getAsNamespaceAndPrefix() const {
+ if (Qualifier.getKind() != NestedNameSpecifier::Kind::Namespace)
+ return {};
+ return castAsNamespaceAndPrefix();
+}
- /// Retrieve the source range covering just the last part of
- /// this nested-name-specifier, not including the prefix.
- ///
- /// For example, if this instance refers to a nested-name-specifier
- /// \c \::std::vector<int>::, the returned source range would cover
- /// from "vector" to the last '::'.
- SourceRange getLocalSourceRange() const;
-
- /// Retrieve the location of the beginning of this
- /// nested-name-specifier.
- SourceLocation getBeginLoc() const {
- if (!Qualifier)
- return SourceLocation();
-
- NestedNameSpecifierLoc First = *this;
- while (NestedNameSpecifierLoc Prefix = First.getPrefix())
- First = Prefix;
- return First.getLocalSourceRange().getBegin();
+unsigned NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier Qualifier) {
+ unsigned Length = 0;
+ for (; Qualifier; Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix) {
+ Length += getLocalDataLength(Qualifier);
+ if (Qualifier.getKind() != NestedNameSpecifier::Kind::Namespace)
+ break;
}
+ return Length;
+}
- /// Retrieve the location of the end of this
- /// nested-name-specifier.
- SourceLocation getEndLoc() const { return getLocalSourceRange().getEnd(); }
+unsigned NestedNameSpecifierLoc::getDataLength() const {
+ return getDataLength(Qualifier);
+}
- /// Retrieve the location of the beginning of this
- /// component of the nested-name-specifier.
- SourceLocation getLocalBeginLoc() const {
- return getLocalSourceRange().getBegin();
+SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
+ switch (auto Kind = Qualifier.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ return SourceRange();
+ case NestedNameSpecifier::Kind::Global:
+ return LoadSourceLocation(/*Offset=*/0);
+ case NestedNameSpecifier::Kind::Namespace:
+ case NestedNameSpecifier::Kind::Super: {
+ unsigned Offset =
+ Kind == NestedNameSpecifier::Kind::Namespace
+ ? getDataLength(Qualifier.getAsNamespaceAndPrefix().Prefix)
+ : 0;
+ return SourceRange(
+ LoadSourceLocation(Offset),
+ LoadSourceLocation(Offset + sizeof(SourceLocation::UIntTy)));
}
-
- /// Retrieve the location of the end of this component of the
- /// nested-name-specifier.
- SourceLocation getLocalEndLoc() const {
- return getLocalSourceRange().getEnd();
+ case NestedNameSpecifier::Kind::Type: {
+ // The "void*" that points at the TypeLoc data.
+ // Note: the 'template' keyword is part of the TypeLoc.
+ void *TypeData = LoadPointer(/*Offset=*/0);
+ TypeLoc TL(Qualifier.getAsType(), TypeData);
+ return SourceRange(TL.getBeginLoc(), LoadSourceLocation(sizeof(void *)));
}
-
- /// Return the prefix of this nested-name-specifier.
- ///
- /// For example, if this instance refers to a nested-name-specifier
- /// \c \::std::vector<int>::, the prefix is \c \::std::. Note that the
- /// returned prefix may be empty, if this is the first component of
- /// the nested-name-specifier.
- NestedNameSpecifierLoc getPrefix() const {
- if (!Qualifier)
- return *this;
-
- return NestedNameSpecifierLoc(Qualifier->getPrefix(), Data);
}
- /// For a nested-name-specifier that refers to a type,
- /// retrieve the type with source-location information.
- TypeLoc getTypeLoc() const;
+ llvm_unreachable("Invalid NNS Kind!");
+}
- /// Determines the data length for the entire
- /// nested-name-specifier.
- unsigned getDataLength() const { return getDataLength(Qualifier); }
+SourceRange NestedNameSpecifierLoc::getSourceRange() const {
+ return SourceRange(getBeginLoc(), getEndLoc());
+}
- friend bool operator==(NestedNameSpecifierLoc X,
- NestedNameSpecifierLoc Y) {
- return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
- }
+SourceLocation NestedNameSpecifierLoc::getEndLoc() const {
+ return getLocalSourceRange().getEnd();
+}
- friend bool operator!=(NestedNameSpecifierLoc X,
- NestedNameSpecifierLoc Y) {
- return !(X == Y);
- }
-};
+/// Retrieve the location of the beginning of this
+/// component of the nested-name-specifier.
+SourceLocation NestedNameSpecifierLoc::getLocalBeginLoc() const {
+ return getLocalSourceRange().getBegin();
+}
-/// Class that aids in the construction of nested-name-specifiers along
-/// with source-location information for all of the components of the
+/// Retrieve the location of the end of this component of the
/// nested-name-specifier.
-class NestedNameSpecifierLocBuilder {
- /// The current representation of the nested-name-specifier we're
- /// building.
- NestedNameSpecifier *Representation = nullptr;
-
- /// Buffer used to store source-location information for the
- /// nested-name-specifier.
- ///
- /// Note that we explicitly manage the buffer (rather than using a
- /// SmallVector) because \c Declarator expects it to be possible to memcpy()
- /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
- char *Buffer = nullptr;
-
- /// The size of the buffer used to store source-location information
- /// for the nested-name-specifier.
- unsigned BufferSize = 0;
-
- /// The capacity of the buffer used to store source-location
- /// information for the nested-name-specifier.
- unsigned BufferCapacity = 0;
-
-public:
- NestedNameSpecifierLocBuilder() = default;
- NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
-
- NestedNameSpecifierLocBuilder &
- operator=(const NestedNameSpecifierLocBuilder &Other);
-
- ~NestedNameSpecifierLocBuilder() {
- if (BufferCapacity)
- free(Buffer);
- }
+SourceLocation NestedNameSpecifierLoc::getLocalEndLoc() const {
+ return getLocalSourceRange().getEnd();
+}
- /// Retrieve the representation of the nested-name-specifier.
- NestedNameSpecifier *getRepresentation() const { return Representation; }
-
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'type::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param TL The TypeLoc that describes the type preceding the '::'.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc);
-
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'identifier::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Identifier The identifier.
- ///
- /// \param IdentifierLoc The location of the identifier.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, IdentifierInfo *Identifier,
- SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
-
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'namespace::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Namespace The namespace.
- ///
- /// \param NamespaceLoc The location of the namespace name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceDecl *Namespace,
- SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
-
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'namespace-alias::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Alias The namespace alias.
- ///
- /// \param AliasLoc The location of the namespace alias
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc, SourceLocation ColonColonLoc);
-
- /// Turn this (empty) nested-name-specifier into the global
- /// nested-name-specifier '::'.
- void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
-
- /// Turns this (empty) nested-name-specifier into '__super'
- /// nested-name-specifier.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param RD The declaration of the class in which nested-name-specifier
- /// appeared.
- ///
- /// \param SuperLoc The location of the '__super' keyword.
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
- SourceLocation SuperLoc, SourceLocation ColonColonLoc);
-
- /// Make a new nested-name-specifier from incomplete source-location
- /// information.
- ///
- /// This routine should be used very, very rarely, in cases where we
- /// need to synthesize a nested-name-specifier. Most code should instead use
- /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
- void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
- SourceRange R);
-
- /// Adopt an existing nested-name-specifier (with source-range
- /// information).
- void Adopt(NestedNameSpecifierLoc Other);
-
- /// Retrieve the source range covered by this nested-name-specifier.
- SourceRange getSourceRange() const LLVM_READONLY {
- return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
- }
+SourceRange NestedNameSpecifierLocBuilder::getSourceRange() const {
+ return NestedNameSpecifierLoc(Representation, Buffer).getSourceRange();
+}
- /// Retrieve a nested-name-specifier with location information,
- /// copied into the given AST context.
- ///
- /// \param Context The context into which this nested-name-specifier will be
- /// copied.
- NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
-
- /// Retrieve a nested-name-specifier with location
- /// information based on the information in this builder.
- ///
- /// This loc will contain references to the builder's internal data and may
- /// be invalidated by any change to the builder.
- NestedNameSpecifierLoc getTemporary() const {
- return NestedNameSpecifierLoc(Representation, Buffer);
- }
+} // namespace clang
+
+namespace llvm {
+
+template <> struct DenseMapInfo<clang::NestedNameSpecifier> {
+ static clang::NestedNameSpecifier getEmptyKey() { return std::nullopt; }
- /// Clear out this builder, and prepare it to build another
- /// nested-name-specifier with source-location information.
- void Clear() {
- Representation = nullptr;
- BufferSize = 0;
+ static clang::NestedNameSpecifier getTombstoneKey() {
+ return clang::NestedNameSpecifier::getInvalid();
}
- /// Retrieve the underlying buffer.
- ///
- /// \returns A pair containing a pointer to the buffer of source-location
- /// data and the size of the source-location data that resides in that
- /// buffer.
- std::pair<char *, unsigned> getBuffer() const {
- return std::make_pair(Buffer, BufferSize);
+ static unsigned getHashValue(const clang::NestedNameSpecifier &V) {
+ return hash_combine(V.getAsVoidPointer());
}
};
-/// Insertion operator for diagnostics. This allows sending
-/// NestedNameSpecifiers into a diagnostic with <<.
-inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
- NestedNameSpecifier *NNS) {
- DB.AddTaggedVal(reinterpret_cast<uint64_t>(NNS),
- DiagnosticsEngine::ak_nestednamespec);
- return DB;
-}
-
-} // namespace clang
-
-namespace llvm {
-
template <> struct DenseMapInfo<clang::NestedNameSpecifierLoc> {
- using FirstInfo = DenseMapInfo<clang::NestedNameSpecifier *>;
+ using FirstInfo = DenseMapInfo<clang::NestedNameSpecifier>;
using SecondInfo = DenseMapInfo<void *>;
static clang::NestedNameSpecifierLoc getEmptyKey() {
@@ -559,4 +291,4 @@ template <> struct DenseMapInfo<clang::NestedNameSpecifierLoc> {
};
} // namespace llvm
-#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIER_H
+#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIERBASE_H
\ No newline at end of file
diff --git a/clang/include/clang/AST/NestedNameSpecifierBase.h b/clang/include/clang/AST/NestedNameSpecifierBase.h
new file mode 100644
index 0000000000000..b7ce157051faf
--- /dev/null
+++ b/clang/include/clang/AST/NestedNameSpecifierBase.h
@@ -0,0 +1,585 @@
+//===- NestedNameSpecifier.h - C++ nested name specifiers -------*- C++ -*-===//
+//
+// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
+// See https://llvm.org/LICENSE.txt for license information.
+// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
+//
+//===----------------------------------------------------------------------===//
+//
+// This file defines the NestedNameSpecifier class, which represents
+// a C++ nested-name-specifier.
+//
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_AST_NESTEDNAMESPECIFIERBASE_H
+#define LLVM_CLANG_AST_NESTEDNAMESPECIFIERBASE_H
+
+#include "clang/AST/DependenceFlags.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/FoldingSet.h"
+#include "llvm/Support/Compiler.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include <cstdint>
+#include <cstdlib>
+#include <utility>
+
+namespace clang {
+
+class ASTContext;
+class CXXRecordDecl;
+class NamedDecl;
+class IdentifierInfo;
+class LangOptions;
+class NamespaceBaseDecl;
+struct PrintingPolicy;
+class Type;
+class TypeLoc;
+
+struct NamespaceAndPrefix;
+struct alignas(16) NamespaceAndPrefixStorage;
+
+/// Represents a C++ nested name specifier, such as
+/// "\::std::vector<int>::".
+///
+/// C++ nested name specifiers are the prefixes to qualified
+/// names. For example, "foo::" in "foo::x" is a nested name
+/// specifier. Nested name specifiers are made up of a sequence of
+/// specifiers, each of which can be a namespace, type, decltype specifier, or
+/// the global specifier ('::'). The last two specifiers can only appear at the
+/// start of a nested-namespace-specifier.
+class NestedNameSpecifier {
+ enum class FlagKind { Null, Global, Invalid };
+ enum class StoredKind {
+ Type,
+ NamespaceOrSuper,
+ NamespaceWithGlobal,
+ NamespaceWithNamespace
+ };
+ static constexpr uintptr_t FlagBits = 2, FlagMask = (1u << FlagBits) - 1u,
+ FlagOffset = 1, PtrOffset = FlagBits + FlagOffset,
+ PtrMask = (1u << PtrOffset) - 1u;
+
+ uintptr_t StoredOrFlag;
+
+ explicit NestedNameSpecifier(uintptr_t StoredOrFlag)
+ : StoredOrFlag(StoredOrFlag) {}
+ struct PtrKind {
+ StoredKind SK;
+ const void *Ptr;
+ };
+ explicit NestedNameSpecifier(PtrKind PK)
+ : StoredOrFlag(uintptr_t(PK.Ptr) | (uintptr_t(PK.SK) << FlagOffset)) {
+ assert(PK.Ptr != nullptr);
+ assert((uintptr_t(PK.Ptr) & ((1u << PtrOffset) - 1u)) == 0);
+ assert((uintptr_t(PK.Ptr) >> PtrOffset) != 0);
+ }
+
+ explicit constexpr NestedNameSpecifier(FlagKind K)
+ : StoredOrFlag(uintptr_t(K) << FlagOffset) {}
+
+ bool isStoredKind() const { return (StoredOrFlag >> PtrOffset) != 0; }
+
+ std::pair<StoredKind, const void *> getStored() const {
+ assert(isStoredKind());
+ return {StoredKind(StoredOrFlag >> FlagOffset & FlagMask),
+ reinterpret_cast<const void *>(StoredOrFlag & ~PtrMask)};
+ }
+
+ FlagKind getFlagKind() const {
+ assert(!isStoredKind());
+ return FlagKind(StoredOrFlag >> FlagOffset);
+ }
+
+ static const NamespaceAndPrefixStorage *
+ MakeNamespaceAndPrefixStorage(const ASTContext &Ctx,
+ const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix);
+ static inline PtrKind MakeNamespacePtrKind(const ASTContext &Ctx,
+ const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix);
+
+public:
+ static constexpr NestedNameSpecifier getInvalid() {
+ return NestedNameSpecifier(FlagKind::Invalid);
+ }
+
+ static constexpr NestedNameSpecifier getGlobal() {
+ return NestedNameSpecifier(FlagKind::Global);
+ }
+
+ NestedNameSpecifier() : NestedNameSpecifier(FlagKind::Invalid) {}
+
+ /// The kind of specifier that completes this nested name
+ /// specifier.
+ enum class Kind {
+ /// Empty.
+ Null,
+
+ /// The global specifier '::'. There is no stored value.
+ Global,
+
+ /// A type, stored as a Type*.
+ Type,
+
+ /// A namespace-like entity, stored as a NamespaceBaseDecl*.
+ Namespace,
+
+ /// Microsoft's '__super' specifier, stored as a CXXRecordDecl* of
+ /// the class it appeared in.
+ Super,
+ };
+
+ inline Kind getKind() const;
+
+ NestedNameSpecifier(std::nullopt_t) : StoredOrFlag(0) {}
+
+ explicit inline NestedNameSpecifier(const Type *T);
+
+ /// Builds a nested name specifier that names a namespace.
+ inline NestedNameSpecifier(const ASTContext &Ctx,
+ const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix);
+
+ /// Builds a nested name specifier that names a class through microsoft's
+ /// __super specifier.
+ explicit inline NestedNameSpecifier(CXXRecordDecl *RD);
+
+ explicit operator bool() const { return StoredOrFlag != 0; }
+
+ void *getAsVoidPointer() const {
+ return reinterpret_cast<void *>(StoredOrFlag);
+ }
+ static NestedNameSpecifier getFromVoidPointer(const void *Ptr) {
+ return NestedNameSpecifier(reinterpret_cast<uintptr_t>(Ptr));
+ }
+
+ const Type *getAsType() const {
+ auto [Kind, Ptr] = getStored();
+ assert(Kind == StoredKind::Type);
+ assert(Ptr != nullptr);
+ return static_cast<const Type *>(Ptr);
+ }
+
+ inline NamespaceAndPrefix getAsNamespaceAndPrefix() const;
+
+ CXXRecordDecl *getAsSuper() const {
+ auto [Kind, Ptr] = getStored();
+ assert(Kind == StoredKind::NamespaceOrSuper);
+ assert(Ptr != nullptr);
+ return static_cast<CXXRecordDecl *>(const_cast<void *>(Ptr));
+ }
+
+ /// Retrieve the record declaration stored in this nested name
+ /// specifier, or null.
+ inline CXXRecordDecl *getAsRecordDecl() const;
+
+ friend bool operator==(NestedNameSpecifier LHS, NestedNameSpecifier RHS) {
+ return LHS.StoredOrFlag == RHS.StoredOrFlag;
+ }
+ friend bool operator!=(NestedNameSpecifier LHS, NestedNameSpecifier RHS) {
+ return LHS.StoredOrFlag != RHS.StoredOrFlag;
+ }
+
+ /// Retrieves the "canonical" nested name specifier for a
+ /// given nested name specifier.
+ ///
+ /// The canonical nested name specifier is a nested name specifier
+ /// that uniquely identifies a type or namespace within the type
+ /// system. For example, given:
+ ///
+ /// \code
+ /// namespace N {
+ /// struct S {
+ /// template<typename T> struct X { typename T* type; };
+ /// };
+ /// }
+ ///
+ /// template<typename T> struct Y {
+ /// typename N::S::X<T>::type member;
+ /// };
+ /// \endcode
+ ///
+ /// Here, the nested-name-specifier for N::S::X<T>:: will be
+ /// S::X<template-param-0-0>, since 'S' and 'X' are uniquely defined
+ /// by declarations in the type system and the canonical type for
+ /// the template type parameter 'T' is template-param-0-0.
+ inline NestedNameSpecifier getCanonical() const;
+
+ /// Whether this nested name specifier is canonical.
+ inline bool isCanonical() const;
+
+ /// Whether this nested name specifier starts with a '::'.
+ bool isFullyQualified() const;
+
+ NestedNameSpecifierDependence getDependence() const;
+
+ /// Whether this nested name specifier refers to a dependent
+ /// type or not.
+ bool isDependent() const {
+ return getDependence() & NestedNameSpecifierDependence::Dependent;
+ }
+
+ /// Whether this nested name specifier involves a template
+ /// parameter.
+ bool isInstantiationDependent() const {
+ return getDependence() & NestedNameSpecifierDependence::Instantiation;
+ }
+
+ /// Whether this nested-name-specifier contains an unexpanded
+ /// parameter pack (for C++11 variadic templates).
+ bool containsUnexpandedParameterPack() const {
+ return getDependence() & NestedNameSpecifierDependence::UnexpandedPack;
+ }
+
+ /// Whether this nested name specifier contains an error.
+ bool containsErrors() const {
+ return getDependence() & NestedNameSpecifierDependence::Error;
+ }
+
+ /// Print this nested name specifier to the given output stream. If
+ /// `ResolveTemplateArguments` is true, we'll print actual types, e.g.
+ /// `ns::SomeTemplate<int, MyClass>` instead of
+ /// `ns::SomeTemplate<Container::value_type, T>`.
+ void print(raw_ostream &OS, const PrintingPolicy &Policy,
+ bool ResolveTemplateArguments = false,
+ bool PrintFinalScopeResOp = true) const;
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ ID.AddInteger(StoredOrFlag);
+ }
+
+ /// Dump the nested name specifier to aid in debugging.
+ void dump(llvm::raw_ostream *OS = nullptr,
+ const LangOptions *LO = nullptr) const;
+ void dump(const LangOptions &LO) const;
+ void dump(llvm::raw_ostream &OS) const;
+ void dump(llvm::raw_ostream &OS, const LangOptions &LO) const;
+
+ static constexpr auto NumLowBitsAvailable = FlagOffset;
+};
+
+struct NamespaceAndPrefix {
+ const NamespaceBaseDecl *Namespace;
+ NestedNameSpecifier Prefix;
+};
+
+struct alignas(16) NamespaceAndPrefixStorage : NamespaceAndPrefix,
+ llvm::FoldingSetNode {
+ NamespaceAndPrefixStorage(const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix)
+ : NamespaceAndPrefix{Namespace, Prefix} {}
+ void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, Namespace, Prefix); }
+ static void Profile(llvm::FoldingSetNodeID &ID,
+ const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix) {
+ ID.AddPointer(Namespace);
+ Prefix.Profile(ID);
+ }
+};
+
+NamespaceAndPrefix NestedNameSpecifier::getAsNamespaceAndPrefix() const {
+ auto [Kind, Ptr] = getStored();
+ switch (Kind) {
+ case StoredKind::NamespaceOrSuper:
+ case StoredKind::NamespaceWithGlobal:
+ return {static_cast<const NamespaceBaseDecl *>(Ptr),
+ Kind == StoredKind::NamespaceWithGlobal
+ ? NestedNameSpecifier::getGlobal()
+ : std::nullopt};
+ case StoredKind::NamespaceWithNamespace:
+ return *static_cast<const NamespaceAndPrefixStorage *>(Ptr);
+ case StoredKind::Type:;
+ }
+ llvm_unreachable("unexpected stored kind");
+}
+
+struct NamespaceAndPrefixLoc;
+
+/// A C++ nested-name-specifier augmented with source location
+/// information.
+class NestedNameSpecifierLoc {
+ NestedNameSpecifier Qualifier = std::nullopt;
+ void *Data = nullptr;
+
+ /// Load a (possibly unaligned) source location from a given address
+ /// and offset.
+ SourceLocation LoadSourceLocation(unsigned Offset) const {
+ SourceLocation::UIntTy Raw;
+ memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(Raw));
+ return SourceLocation::getFromRawEncoding(Raw);
+ }
+
+ /// Load a (possibly unaligned) pointer from a given address and
+ /// offset.
+ void *LoadPointer(unsigned Offset) const {
+ void *Result;
+ memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void *));
+ return Result;
+ }
+
+ /// Determines the data length for the last component in the
+ /// given nested-name-specifier.
+ static inline unsigned getLocalDataLength(NestedNameSpecifier Qualifier);
+
+ /// Determines the data length for the entire
+ /// nested-name-specifier.
+ static inline unsigned getDataLength(NestedNameSpecifier Qualifier);
+
+public:
+ /// Construct an empty nested-name-specifier.
+ NestedNameSpecifierLoc() = default;
+
+ /// Construct a nested-name-specifier with source location information
+ /// from
+ NestedNameSpecifierLoc(NestedNameSpecifier Qualifier, void *Data)
+ : Qualifier(Qualifier), Data(Data) {}
+
+ /// Evaluates true when this nested-name-specifier location is
+ /// non-empty.
+ explicit operator bool() const { return bool(Qualifier); }
+
+ /// Evaluates true when this nested-name-specifier location is
+ /// non-empty.
+ bool hasQualifier() const { return bool(Qualifier); }
+
+ /// Retrieve the nested-name-specifier to which this instance
+ /// refers.
+ NestedNameSpecifier getNestedNameSpecifier() const { return Qualifier; }
+
+ /// Retrieve the opaque pointer that refers to source-location data.
+ void *getOpaqueData() const { return Data; }
+
+ /// Retrieve the source range covering the entirety of this
+ /// nested-name-specifier.
+ ///
+ /// For example, if this instance refers to a nested-name-specifier
+ /// \c \::std::vector<int>::, the returned source range would cover
+ /// from the initial '::' to the last '::'.
+ inline SourceRange getSourceRange() const LLVM_READONLY;
+
+ /// Retrieve the source range covering just the last part of
+ /// this nested-name-specifier, not including the prefix.
+ ///
+ /// For example, if this instance refers to a nested-name-specifier
+ /// \c \::std::vector<int>::, the returned source range would cover
+ /// from "vector" to the last '::'.
+ inline SourceRange getLocalSourceRange() const;
+
+ /// Retrieve the location of the beginning of this
+ /// nested-name-specifier.
+ SourceLocation getBeginLoc() const;
+
+ /// Retrieve the location of the end of this
+ /// nested-name-specifier.
+ inline SourceLocation getEndLoc() const;
+
+ /// Retrieve the location of the beginning of this
+ /// component of the nested-name-specifier.
+ inline SourceLocation getLocalBeginLoc() const;
+
+ /// Retrieve the location of the end of this component of the
+ /// nested-name-specifier.
+ inline SourceLocation getLocalEndLoc() const;
+
+ /// For a nested-name-specifier that refers to a namespace,
+ /// retrieve the namespace and its prefix.
+ ///
+ /// For example, if this instance refers to a nested-name-specifier
+ /// \c \::std::chrono::, the prefix is \c \::std::. Note that the
+ /// returned prefix may be empty, if this is the first component of
+ /// the nested-name-specifier.
+ inline NamespaceAndPrefixLoc castAsNamespaceAndPrefix() const;
+ inline NamespaceAndPrefixLoc getAsNamespaceAndPrefix() const;
+
+ /// For a nested-name-specifier that refers to a type,
+ /// retrieve the type with source-location information.
+ inline TypeLoc castAsTypeLoc() const;
+ inline TypeLoc getAsTypeLoc() const;
+
+ /// Determines the data length for the entire
+ /// nested-name-specifier.
+ inline unsigned getDataLength() const;
+
+ friend bool operator==(NestedNameSpecifierLoc X, NestedNameSpecifierLoc Y) {
+ return X.Qualifier == Y.Qualifier && X.Data == Y.Data;
+ }
+
+ friend bool operator!=(NestedNameSpecifierLoc X, NestedNameSpecifierLoc Y) {
+ return !(X == Y);
+ }
+};
+
+struct NamespaceAndPrefixLoc {
+ const NamespaceBaseDecl *Namespace = nullptr;
+ NestedNameSpecifierLoc Prefix;
+
+ explicit operator bool() const { return Namespace != nullptr; }
+};
+
+/// Class that aids in the construction of nested-name-specifiers along
+/// with source-location information for all of the components of the
+/// nested-name-specifier.
+class NestedNameSpecifierLocBuilder {
+ /// The current representation of the nested-name-specifier we're
+ /// building.
+ NestedNameSpecifier Representation = std::nullopt;
+
+ /// Buffer used to store source-location information for the
+ /// nested-name-specifier.
+ ///
+ /// Note that we explicitly manage the buffer (rather than using a
+ /// SmallVector) because \c Declarator expects it to be possible to memcpy()
+ /// a \c CXXScopeSpec, and CXXScopeSpec uses a NestedNameSpecifierLocBuilder.
+ char *Buffer = nullptr;
+
+ /// The size of the buffer used to store source-location information
+ /// for the nested-name-specifier.
+ unsigned BufferSize = 0;
+
+ /// The capacity of the buffer used to store source-location
+ /// information for the nested-name-specifier.
+ unsigned BufferCapacity = 0;
+
+ void PushTrivial(ASTContext &Context, NestedNameSpecifier Qualifier,
+ SourceRange R);
+
+public:
+ NestedNameSpecifierLocBuilder() = default;
+ NestedNameSpecifierLocBuilder(const NestedNameSpecifierLocBuilder &Other);
+
+ NestedNameSpecifierLocBuilder &
+ operator=(const NestedNameSpecifierLocBuilder &Other);
+
+ ~NestedNameSpecifierLocBuilder() {
+ if (BufferCapacity)
+ free(Buffer);
+ }
+
+ /// Retrieve the representation of the nested-name-specifier.
+ NestedNameSpecifier getRepresentation() const { return Representation; }
+
+ /// Make a nested-name-specifier of the form 'type::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param TL The TypeLoc that describes the type preceding the '::'.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Make(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc);
+
+ /// Extend the current nested-name-specifier by another
+ /// nested-name-specifier component of the form 'namespace::'.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param Namespace The namespace.
+ ///
+ /// \param NamespaceLoc The location of the namespace name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void Extend(ASTContext &Context, const NamespaceBaseDecl *Namespace,
+ SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
+
+ /// Turn this (empty) nested-name-specifier into the global
+ /// nested-name-specifier '::'.
+ void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
+
+ /// Turns this (empty) nested-name-specifier into '__super'
+ /// nested-name-specifier.
+ ///
+ /// \param Context The AST context in which this nested-name-specifier
+ /// resides.
+ ///
+ /// \param RD The declaration of the class in which nested-name-specifier
+ /// appeared.
+ ///
+ /// \param SuperLoc The location of the '__super' keyword.
+ /// name.
+ ///
+ /// \param ColonColonLoc The location of the trailing '::'.
+ void MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
+ SourceLocation SuperLoc, SourceLocation ColonColonLoc);
+
+ /// Make a new nested-name-specifier from incomplete source-location
+ /// information.
+ ///
+ /// This routine should be used very, very rarely, in cases where we
+ /// need to synthesize a nested-name-specifier. Most code should instead use
+ /// \c Adopt() with a proper \c NestedNameSpecifierLoc.
+ void MakeTrivial(ASTContext &Context, NestedNameSpecifier Qualifier,
+ SourceRange R) {
+ Representation = Qualifier;
+ BufferSize = 0;
+ PushTrivial(Context, Qualifier, R);
+ }
+
+ /// Adopt an existing nested-name-specifier (with source-range
+ /// information).
+ void Adopt(NestedNameSpecifierLoc Other);
+
+ /// Retrieve the source range covered by this nested-name-specifier.
+ inline SourceRange getSourceRange() const LLVM_READONLY;
+
+ /// Retrieve a nested-name-specifier with location information,
+ /// copied into the given AST context.
+ ///
+ /// \param Context The context into which this nested-name-specifier will be
+ /// copied.
+ NestedNameSpecifierLoc getWithLocInContext(ASTContext &Context) const;
+
+ /// Retrieve a nested-name-specifier with location
+ /// information based on the information in this builder.
+ ///
+ /// This loc will contain references to the builder's internal data and may
+ /// be invalidated by any change to the builder.
+ NestedNameSpecifierLoc getTemporary() const {
+ return NestedNameSpecifierLoc(Representation, Buffer);
+ }
+
+ /// Clear out this builder, and prepare it to build another
+ /// nested-name-specifier with source-location information.
+ void Clear() {
+ Representation = std::nullopt;
+ BufferSize = 0;
+ }
+
+ /// Retrieve the underlying buffer.
+ ///
+ /// \returns A pair containing a pointer to the buffer of source-location
+ /// data and the size of the source-location data that resides in that
+ /// buffer.
+ std::pair<char *, unsigned> getBuffer() const {
+ return std::make_pair(Buffer, BufferSize);
+ }
+};
+
+/// Insertion operator for diagnostics. This allows sending
+/// NestedNameSpecifiers into a diagnostic with <<.
+inline const StreamingDiagnostic &operator<<(const StreamingDiagnostic &DB,
+ NestedNameSpecifier NNS) {
+ DB.AddTaggedVal(reinterpret_cast<uintptr_t>(NNS.getAsVoidPointer()),
+ DiagnosticsEngine::ak_nestednamespec);
+ return DB;
+}
+
+} // namespace clang
+
+namespace llvm {
+
+template <> struct PointerLikeTypeTraits<clang::NestedNameSpecifier> {
+ static void *getAsVoidPointer(clang::NestedNameSpecifier P) {
+ return P.getAsVoidPointer();
+ }
+ static clang::NestedNameSpecifier getFromVoidPointer(const void *P) {
+ return clang::NestedNameSpecifier::getFromVoidPointer(P);
+ }
+ static constexpr int NumLowBitsAvailable =
+ clang::NestedNameSpecifier::NumLowBitsAvailable;
+};
+
+} // namespace llvm
+
+#endif // LLVM_CLANG_AST_NESTEDNAMESPECIFIERBASE_H
\ No newline at end of file
diff --git a/clang/include/clang/AST/ODRHash.h b/clang/include/clang/AST/ODRHash.h
index 11f917a1a4634..ae3fab697786a 100644
--- a/clang/include/clang/AST/ODRHash.h
+++ b/clang/include/clang/AST/ODRHash.h
@@ -93,7 +93,7 @@ class ODRHash {
void AddQualType(QualType T);
void AddStmt(const Stmt *S);
void AddIdentifierInfo(const IdentifierInfo *II);
- void AddNestedNameSpecifier(const NestedNameSpecifier *NNS);
+ void AddNestedNameSpecifier(NestedNameSpecifier NNS);
void AddDependentTemplateName(const DependentTemplateStorage &Name);
void AddTemplateName(TemplateName Name);
void AddDeclarationNameInfo(DeclarationNameInfo NameInfo,
diff --git a/clang/include/clang/AST/PrettyPrinter.h b/clang/include/clang/AST/PrettyPrinter.h
index 875769cd02bc0..fd995a653d167 100644
--- a/clang/include/clang/AST/PrettyPrinter.h
+++ b/clang/include/clang/AST/PrettyPrinter.h
@@ -63,9 +63,9 @@ struct PrintingPolicy {
SuppressTagKeyword(LO.CPlusPlus), IncludeTagDefinition(false),
SuppressScope(false), SuppressUnwrittenScope(false),
SuppressInlineNamespace(SuppressInlineNamespaceMode::Redundant),
- SuppressElaboration(false), SuppressInitializers(false),
- ConstantArraySizeAsWritten(false), AnonymousTagLocations(true),
- SuppressStrongLifetime(false), SuppressLifetimeQualifiers(false),
+ SuppressInitializers(false), ConstantArraySizeAsWritten(false),
+ AnonymousTagLocations(true), SuppressStrongLifetime(false),
+ SuppressLifetimeQualifiers(false),
SuppressTemplateArgsInCXXConstructors(false),
SuppressDefaultTemplateArgs(true), Bool(LO.Bool),
Nullptr(LO.CPlusPlus11 || LO.C23), NullptrTypeInNamespace(LO.CPlusPlus),
@@ -150,11 +150,6 @@ struct PrintingPolicy {
LLVM_PREFERRED_TYPE(SuppressInlineNamespaceMode)
unsigned SuppressInlineNamespace : 2;
- /// Ignore qualifiers and tag keywords as specified by elaborated type sugar,
- /// instead letting the underlying type print as normal.
- LLVM_PREFERRED_TYPE(bool)
- unsigned SuppressElaboration : 1;
-
/// Suppress printing of variable initializers.
///
/// This flag is used when printing the loop variable in a for-range
diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td
index 1215056ffde1b..5b10127526e4e 100644
--- a/clang/include/clang/AST/PropertiesBase.td
+++ b/clang/include/clang/AST/PropertiesBase.td
@@ -91,6 +91,7 @@ def DeclRef : RefPropertyType<"Decl"> { let ConstWhenWriting = 1; }
SubclassPropertyType<"FunctionDecl", DeclRef>;
def NamedDeclRef :
SubclassPropertyType<"NamedDecl", DeclRef>;
+ def NamespaceBaseDeclRef : SubclassPropertyType<"NamespaceBaseDecl", DeclRef>;
def NamespaceDeclRef :
SubclassPropertyType<"NamespaceDecl", DeclRef>;
def NamespaceAliasDeclRef :
@@ -126,9 +127,8 @@ def LValuePathSerializationHelper :
PropertyType<"APValue::LValuePathSerializationHelper"> {
let BufferElementTypes = [ LValuePathEntry ];
}
-def NestedNameSpecifier : PropertyType<"NestedNameSpecifier *">;
-def NestedNameSpecifierKind :
- EnumPropertyType<"NestedNameSpecifier::SpecifierKind">;
+def NestedNameSpecifier : PropertyType<"NestedNameSpecifier">;
+def NestedNameSpecifierKind : EnumPropertyType<"NestedNameSpecifier::Kind">;
def OverloadedOperatorKind : EnumPropertyType;
def Qualifiers : PropertyType;
def QualType : DefaultValuePropertyType;
diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h
index 5cb2f57edffe4..65e015ac88ef7 100644
--- a/clang/include/clang/AST/RecursiveASTVisitor.h
+++ b/clang/include/clang/AST/RecursiveASTVisitor.h
@@ -216,14 +216,14 @@ template <typename Derived> class RecursiveASTVisitor {
///
/// \returns false if the visitation was terminated early, true
/// otherwise (including when the argument is a Null type).
- bool TraverseType(QualType T);
+ bool TraverseType(QualType T, bool TraverseQualifier = true);
/// Recursively visit a type with location, by dispatching to
/// Traverse*TypeLoc() based on the argument type's getTypeClass() property.
///
/// \returns false if the visitation was terminated early, true
/// otherwise (including when the argument is a Null type location).
- bool TraverseTypeLoc(TypeLoc TL);
+ bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true);
/// Recursively visit an attribute, by dispatching to
/// Traverse*Attr() based on the argument's dynamic type.
@@ -242,7 +242,7 @@ template <typename Derived> class RecursiveASTVisitor {
/// Recursively visit a C++ nested-name-specifier.
///
/// \returns false if the visitation was terminated early, true otherwise.
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier NNS);
/// Recursively visit a C++ nested-name-specifier with location
/// information.
@@ -389,7 +389,8 @@ template <typename Derived> class RecursiveASTVisitor {
// Declare Traverse*() for all concrete Type classes.
#define ABSTRACT_TYPE(CLASS, BASE)
-#define TYPE(CLASS, BASE) bool Traverse##CLASS##Type(CLASS##Type *T);
+#define TYPE(CLASS, BASE) \
+ bool Traverse##CLASS##Type(CLASS##Type *T, bool TraverseQualifier);
#include "clang/AST/TypeNodes.inc"
// The above header #undefs ABSTRACT_TYPE and TYPE upon exit.
@@ -410,7 +411,8 @@ template <typename Derived> class RecursiveASTVisitor {
// Declare Traverse*() for all concrete TypeLoc classes.
#define ABSTRACT_TYPELOC(CLASS, BASE)
-#define TYPELOC(CLASS, BASE) bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL);
+#define TYPELOC(CLASS, BASE) \
+ bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL, bool TraverseQualifier);
#include "clang/AST/TypeLocNodes.def"
// The above header #undefs ABSTRACT_TYPELOC and TYPELOC upon exit.
@@ -499,6 +501,8 @@ template <typename Derived> class RecursiveASTVisitor {
bool TraverseOMPExecutableDirective(OMPExecutableDirective *S);
bool TraverseOMPLoopDirective(OMPLoopDirective *S);
bool TraverseOMPClause(OMPClause *C);
+ bool TraverseTagType(TagType *T, bool TraverseQualifier);
+ bool TraverseTagTypeLoc(TagTypeLoc TL, bool TraverseQualifier);
#define GEN_CLANG_CLAUSE_CLASS
#define CLAUSE_CLASS(Enum, Str, Class) bool Visit##Class(Class *C);
#include "llvm/Frontend/OpenMP/OMP.inc"
@@ -698,7 +702,8 @@ RecursiveASTVisitor<Derived>::TraverseStmt(Stmt *S, DataRecursionQueue *Queue) {
}
template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
+bool RecursiveASTVisitor<Derived>::TraverseType(QualType T,
+ bool TraverseQualifier) {
if (T.isNull())
return true;
@@ -707,7 +712,8 @@ bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
#define TYPE(CLASS, BASE) \
case Type::CLASS: \
return getDerived().Traverse##CLASS##Type( \
- static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())));
+ static_cast<CLASS##Type *>(const_cast<Type *>(T.getTypePtr())), \
+ TraverseQualifier);
#include "clang/AST/TypeNodes.inc"
}
@@ -715,7 +721,8 @@ bool RecursiveASTVisitor<Derived>::TraverseType(QualType T) {
}
template <typename Derived>
-bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
+bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL,
+ bool TraverseQualifier) {
if (TL.isNull())
return true;
@@ -723,7 +730,8 @@ bool RecursiveASTVisitor<Derived>::TraverseTypeLoc(TypeLoc TL) {
#define ABSTRACT_TYPELOC(CLASS, BASE)
#define TYPELOC(CLASS, BASE) \
case TypeLoc::CLASS: \
- return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>());
+ return getDerived().Traverse##CLASS##TypeLoc(TL.castAs<CLASS##TypeLoc>(), \
+ TraverseQualifier);
#include "clang/AST/TypeLocNodes.def"
}
@@ -779,48 +787,43 @@ bool RecursiveASTVisitor<Derived>::TraverseDecl(Decl *D) {
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
- if (!NNS)
+ NestedNameSpecifier NNS) {
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
return true;
-
- if (NNS->getPrefix())
- TRY_TO(TraverseNestedNameSpecifier(NNS->getPrefix()));
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Namespace:
+ TRY_TO(TraverseNestedNameSpecifier(NNS.getAsNamespaceAndPrefix().Prefix));
+ return true;
+ case NestedNameSpecifier::Kind::Type: {
+ auto *T = const_cast<Type *>(NNS.getAsType());
+ TRY_TO(TraverseNestedNameSpecifier(T->getPrefix()));
+ TRY_TO(TraverseType(QualType(T, 0), /*TraverseQualifier=*/false));
return true;
-
- case NestedNameSpecifier::TypeSpec:
- TRY_TO(TraverseType(QualType(NNS->getAsType(), 0)));
}
-
- return true;
+ }
+ llvm_unreachable("unhandled kind");
}
template <typename Derived>
bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc(
NestedNameSpecifierLoc NNS) {
- if (!NNS)
+ switch (NNS.getNestedNameSpecifier().getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
return true;
-
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- TRY_TO(TraverseNestedNameSpecifierLoc(Prefix));
-
- switch (NNS.getNestedNameSpecifier()->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Namespace:
+ TRY_TO(
+ TraverseNestedNameSpecifierLoc(NNS.castAsNamespaceAndPrefix().Prefix));
return true;
-
- case NestedNameSpecifier::TypeSpec:
- TRY_TO(TraverseTypeLoc(NNS.getTypeLoc()));
- break;
+ case NestedNameSpecifier::Kind::Type: {
+ TypeLoc TL = NNS.castAsTypeLoc();
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getPrefix()));
+ TRY_TO(TraverseTypeLoc(TL, /*TraverseQualifier=*/false));
+ return true;
+ }
}
return true;
@@ -977,10 +980,13 @@ RecursiveASTVisitor<Derived>::TraverseLambdaCapture(LambdaExpr *LE,
// This macro makes available a variable T, the passed-in type.
#define DEF_TRAVERSE_TYPE(TYPE, CODE) \
template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T) { \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE(TYPE *T, \
+ bool TraverseQualifier) { \
if (!getDerived().shouldTraversePostOrder()) \
TRY_TO(WalkUpFrom##TYPE(T)); \
- { CODE; } \
+ { \
+ CODE; \
+ } \
if (getDerived().shouldTraversePostOrder()) \
TRY_TO(WalkUpFrom##TYPE(T)); \
return true; \
@@ -1002,10 +1008,11 @@ DEF_TRAVERSE_TYPE(RValueReferenceType,
{ TRY_TO(TraverseType(T->getPointeeType())); })
DEF_TRAVERSE_TYPE(MemberPointerType, {
- TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- if (T->isSugared())
- TRY_TO(TraverseType(
- QualType(T->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0)));
+ NestedNameSpecifier Qualifier =
+ T->isSugared() ? cast<MemberPointerType>(T->getCanonicalTypeUnqualified())
+ ->getQualifier()
+ : T->getQualifier();
+ TRY_TO(TraverseNestedNameSpecifier(Qualifier));
TRY_TO(TraverseType(T->getPointeeType()));
})
@@ -1089,9 +1096,18 @@ DEF_TRAVERSE_TYPE(FunctionProtoType, {
TRY_TO(TraverseStmt(NE));
})
-DEF_TRAVERSE_TYPE(UsingType, {})
-DEF_TRAVERSE_TYPE(UnresolvedUsingType, {})
-DEF_TRAVERSE_TYPE(TypedefType, {})
+DEF_TRAVERSE_TYPE(UsingType, {
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+})
+DEF_TRAVERSE_TYPE(UnresolvedUsingType, {
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+})
+DEF_TRAVERSE_TYPE(TypedefType, {
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+})
DEF_TRAVERSE_TYPE(TypeOfExprType,
{ TRY_TO(TraverseStmt(T->getUnderlyingExpr())); })
@@ -1117,13 +1133,7 @@ DEF_TRAVERSE_TYPE(AutoType, {
TRY_TO(TraverseTemplateArguments(T->getTypeConstraintArguments()));
}
})
-DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseType(T->getDeducedType()));
-})
-DEF_TRAVERSE_TYPE(RecordType, {})
-DEF_TRAVERSE_TYPE(EnumType, {})
DEF_TRAVERSE_TYPE(TemplateTypeParmType, {})
DEF_TRAVERSE_TYPE(SubstTemplateTypeParmType, {
TRY_TO(TraverseType(T->getReplacementType()));
@@ -1132,13 +1142,6 @@ DEF_TRAVERSE_TYPE(SubstTemplateTypeParmPackType, {
TRY_TO(TraverseTemplateArgument(T->getArgumentPack()));
})
-DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(T->getTemplateName()));
- TRY_TO(TraverseTemplateArguments(T->template_arguments()));
-})
-
-DEF_TRAVERSE_TYPE(InjectedClassNameType, {})
-
DEF_TRAVERSE_TYPE(AttributedType,
{ TRY_TO(TraverseType(T->getModifiedType())); })
@@ -1167,22 +1170,54 @@ DEF_TRAVERSE_TYPE(ParenType, { TRY_TO(TraverseType(T->getInnerType())); })
DEF_TRAVERSE_TYPE(MacroQualifiedType,
{ TRY_TO(TraverseType(T->getUnderlyingType())); })
-DEF_TRAVERSE_TYPE(ElaboratedType, {
- if (T->getQualifier()) {
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTagType(TagType *T,
+ bool TraverseQualifier) {
+ if (TraverseQualifier)
TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
- }
- TRY_TO(TraverseType(T->getNamedType()));
-})
+ return true;
+}
+
+DEF_TRAVERSE_TYPE(EnumType, { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
+DEF_TRAVERSE_TYPE(RecordType,
+ { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
+DEF_TRAVERSE_TYPE(InjectedClassNameType,
+ { TRY_TO(TraverseTagType(T, TraverseQualifier)); })
-DEF_TRAVERSE_TYPE(DependentNameType,
- { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); })
+DEF_TRAVERSE_TYPE(DependentNameType, {
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifier(T->getQualifier()));
+})
DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, {
const DependentTemplateStorage &S = T->getDependentTemplateName();
- TRY_TO(TraverseNestedNameSpecifier(S.getQualifier()));
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifier(S.getQualifier()));
TRY_TO(TraverseTemplateArguments(T->template_arguments()));
})
+DEF_TRAVERSE_TYPE(TemplateSpecializationType, {
+ if (TraverseQualifier) {
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ } else {
+ // FIXME: Try to preserve the rest of the template name.
+ TRY_TO(TraverseTemplateName(TemplateName(
+ T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
+ }
+ TRY_TO(TraverseTemplateArguments(T->template_arguments()));
+})
+
+DEF_TRAVERSE_TYPE(DeducedTemplateSpecializationType, {
+ if (TraverseQualifier) {
+ TRY_TO(TraverseTemplateName(T->getTemplateName()));
+ } else {
+ // FIXME: Try to preserve the rest of the template name.
+ TRY_TO(TraverseTemplateName(TemplateName(
+ T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true))));
+ }
+ TRY_TO(TraverseType(T->getDeducedType()));
+})
+
DEF_TRAVERSE_TYPE(PackExpansionType, { TRY_TO(TraverseType(T->getPattern())); })
DEF_TRAVERSE_TYPE(ObjCTypeParamType, {})
@@ -1221,13 +1256,16 @@ DEF_TRAVERSE_TYPE(DependentBitIntType,
// continue to work.
#define DEF_TRAVERSE_TYPELOC(TYPE, CODE) \
template <typename Derived> \
- bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc(TYPE##Loc TL) { \
+ bool RecursiveASTVisitor<Derived>::Traverse##TYPE##Loc( \
+ TYPE##Loc TL, bool TraverseQualifier) { \
if (!getDerived().shouldTraversePostOrder()) { \
TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
if (getDerived().shouldWalkTypesOfTypeLocs()) \
TRY_TO(WalkUpFrom##TYPE(const_cast<TYPE *>(TL.getTypePtr()))); \
} \
- { CODE; } \
+ { \
+ CODE; \
+ } \
if (getDerived().shouldTraversePostOrder()) { \
TRY_TO(WalkUpFrom##TYPE##Loc(TL)); \
if (getDerived().shouldWalkTypesOfTypeLocs()) \
@@ -1237,8 +1275,10 @@ DEF_TRAVERSE_TYPE(DependentBitIntType,
}
template <typename Derived>
-bool
-RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
+bool RecursiveASTVisitor<Derived>::TraverseQualifiedTypeLoc(
+ QualifiedTypeLoc TL, bool TraverseQualifier) {
+ assert(TraverseQualifier &&
+ "Qualifiers should never occur within NestedNameSpecifiers");
// Move this over to the 'main' typeloc tree. Note that this is a
// move -- we pretend that we were really looking at the unqualified
// typeloc all along -- rather than a recursion, so we don't follow
@@ -1391,9 +1431,21 @@ DEF_TRAVERSE_TYPELOC(FunctionProtoType, {
TRY_TO(TraverseStmt(NE));
})
-DEF_TRAVERSE_TYPELOC(UsingType, {})
-DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {})
-DEF_TRAVERSE_TYPELOC(TypedefType, {})
+DEF_TRAVERSE_TYPELOC(UsingType, {
+ if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ TraverseQualifier && QualifierLoc)
+ TRY_TO(TraverseNestedNameSpecifierLoc(QualifierLoc));
+})
+DEF_TRAVERSE_TYPELOC(UnresolvedUsingType, {
+ if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ TraverseQualifier && QualifierLoc)
+ TRY_TO(TraverseNestedNameSpecifierLoc(QualifierLoc));
+})
+DEF_TRAVERSE_TYPELOC(TypedefType, {
+ if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ TraverseQualifier && QualifierLoc)
+ TRY_TO(TraverseNestedNameSpecifierLoc(QualifierLoc));
+})
DEF_TRAVERSE_TYPELOC(TypeOfExprType,
{ TRY_TO(TraverseStmt(TL.getUnderlyingExpr())); })
@@ -1423,13 +1475,6 @@ DEF_TRAVERSE_TYPELOC(AutoType, {
}
})
-DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- TRY_TO(TraverseType(TL.getTypePtr()->getDeducedType()));
-})
-
-DEF_TRAVERSE_TYPELOC(RecordType, {})
-DEF_TRAVERSE_TYPELOC(EnumType, {})
DEF_TRAVERSE_TYPELOC(TemplateTypeParmType, {})
DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmType, {
TRY_TO(TraverseType(TL.getTypePtr()->getReplacementType()));
@@ -1438,16 +1483,6 @@ DEF_TRAVERSE_TYPELOC(SubstTemplateTypeParmPackType, {
TRY_TO(TraverseTemplateArgument(TL.getTypePtr()->getArgumentPack()));
})
-// FIXME: use the loc for the template name?
-DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
- TRY_TO(TraverseTemplateName(TL.getTypePtr()->getTemplateName()));
- for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
- TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
- }
-})
-
-DEF_TRAVERSE_TYPELOC(InjectedClassNameType, {})
-
DEF_TRAVERSE_TYPELOC(ParenType, { TRY_TO(TraverseTypeLoc(TL.getInnerLoc())); })
DEF_TRAVERSE_TYPELOC(MacroQualifiedType,
@@ -1468,27 +1503,63 @@ DEF_TRAVERSE_TYPELOC(HLSLAttributedResourceType,
DEF_TRAVERSE_TYPELOC(HLSLInlineSpirvType,
{ TRY_TO(TraverseType(TL.getType())); })
-DEF_TRAVERSE_TYPELOC(ElaboratedType, {
- if (TL.getQualifierLoc()) {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
- }
- TRY_TO(TraverseTypeLoc(TL.getNamedTypeLoc()));
-})
+template <typename Derived>
+bool RecursiveASTVisitor<Derived>::TraverseTagTypeLoc(TagTypeLoc TL,
+ bool TraverseQualifier) {
+ if (NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ TraverseQualifier && QualifierLoc)
+ TRY_TO(TraverseNestedNameSpecifierLoc(QualifierLoc));
+ return true;
+}
+
+DEF_TRAVERSE_TYPELOC(EnumType,
+ { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
+DEF_TRAVERSE_TYPELOC(RecordType,
+ { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
+DEF_TRAVERSE_TYPELOC(InjectedClassNameType,
+ { TRY_TO(TraverseTagTypeLoc(TL, TraverseQualifier)); })
DEF_TRAVERSE_TYPELOC(DependentNameType, {
- TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
})
DEF_TRAVERSE_TYPELOC(DependentTemplateSpecializationType, {
- if (TL.getQualifierLoc()) {
+ if (TraverseQualifier)
TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
+ TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
}
+})
+
+DEF_TRAVERSE_TYPELOC(TemplateSpecializationType, {
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+
+ // FIXME: Try to preserve the rest of the template name.
+ TRY_TO(TraverseTemplateName(
+ TemplateName(TL.getTypePtr()->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true))));
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I) {
TRY_TO(TraverseTemplateArgumentLoc(TL.getArgLoc(I)));
}
})
+DEF_TRAVERSE_TYPELOC(DeducedTemplateSpecializationType, {
+ if (TraverseQualifier)
+ TRY_TO(TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()));
+
+ const auto *T = TL.getTypePtr();
+ // FIXME: Try to preserve the rest of the template name.
+ TRY_TO(
+ TraverseTemplateName(TemplateName(T->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true))));
+
+ TRY_TO(TraverseType(T->getDeducedType()));
+})
+
DEF_TRAVERSE_TYPELOC(PackExpansionType,
{ TRY_TO(TraverseTypeLoc(TL.getPatternLoc())); })
@@ -1629,8 +1700,9 @@ DEF_TRAVERSE_DECL(FriendDecl, {
TRY_TO(TraverseTypeLoc(D->getFriendType()->getTypeLoc()));
// Traverse any CXXRecordDecl owned by this type, since
// it will not be in the parent context:
- if (auto *ET = D->getFriendType()->getType()->getAs<ElaboratedType>())
- TRY_TO(TraverseDecl(ET->getOwnedTagDecl()));
+ if (auto *TT = D->getFriendType()->getType()->getAs<TagType>();
+ TT && TT->isTagOwned())
+ TRY_TO(TraverseDecl(TT->getOriginalDecl()));
} else {
TRY_TO(TraverseDecl(D->getFriendDecl()));
}
diff --git a/clang/include/clang/AST/TemplateBase.h b/clang/include/clang/AST/TemplateBase.h
index b67036cae4261..ac0c0cc7e0286 100644
--- a/clang/include/clang/AST/TemplateBase.h
+++ b/clang/include/clang/AST/TemplateBase.h
@@ -15,7 +15,7 @@
#define LLVM_CLANG_AST_TEMPLATEBASE_H
#include "clang/AST/DependenceFlags.h"
-#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
@@ -476,31 +476,25 @@ class TemplateArgument {
/// Location information for a TemplateArgument.
struct TemplateArgumentLocInfo {
-private:
struct TemplateTemplateArgLocInfo {
- // FIXME: We'd like to just use the qualifier in the TemplateName,
- // but template arguments get canonicalized too quickly.
- NestedNameSpecifier *Qualifier;
void *QualifierLocData;
+ SourceLocation TemplateKwLoc;
SourceLocation TemplateNameLoc;
SourceLocation EllipsisLoc;
};
- llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
- Pointer;
-
TemplateTemplateArgLocInfo *getTemplate() const {
return cast<TemplateTemplateArgLocInfo *>(Pointer);
}
-public:
TemplateArgumentLocInfo() {}
TemplateArgumentLocInfo(TypeSourceInfo *Declarator) { Pointer = Declarator; }
TemplateArgumentLocInfo(Expr *E) { Pointer = E; }
// Ctx is used for allocation -- this case is unusually large and also rare,
// so we store the payload out-of-line.
- TemplateArgumentLocInfo(ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
+ TemplateArgumentLocInfo(ASTContext &Ctx, SourceLocation TemplateKwLoc,
+ NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
SourceLocation EllipsisLoc);
@@ -510,10 +504,8 @@ struct TemplateArgumentLocInfo {
Expr *getAsExpr() const { return cast<Expr *>(Pointer); }
- NestedNameSpecifierLoc getTemplateQualifierLoc() const {
- const auto *Template = getTemplate();
- return NestedNameSpecifierLoc(Template->Qualifier,
- Template->QualifierLocData);
+ SourceLocation getTemplateKwLoc() const {
+ return getTemplate()->TemplateKwLoc;
}
SourceLocation getTemplateNameLoc() const {
@@ -523,6 +515,10 @@ struct TemplateArgumentLocInfo {
SourceLocation getTemplateEllipsisLoc() const {
return getTemplate()->EllipsisLoc;
}
+
+private:
+ llvm::PointerUnion<TemplateTemplateArgLocInfo *, Expr *, TypeSourceInfo *>
+ Pointer;
};
/// Location wrapper for a TemplateArgument. TemplateArgument is to
@@ -556,14 +552,10 @@ class TemplateArgumentLoc {
}
TemplateArgumentLoc(ASTContext &Ctx, const TemplateArgument &Argument,
+ SourceLocation TemplateKWLoc,
NestedNameSpecifierLoc QualifierLoc,
SourceLocation TemplateNameLoc,
- SourceLocation EllipsisLoc = SourceLocation())
- : Argument(Argument),
- LocInfo(Ctx, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
- assert(Argument.getKind() == TemplateArgument::Template ||
- Argument.getKind() == TemplateArgument::TemplateExpansion);
- }
+ SourceLocation EllipsisLoc = SourceLocation());
/// - Fetches the primary location of the argument.
SourceLocation getLocation() const {
@@ -612,13 +604,15 @@ class TemplateArgumentLoc {
return LocInfo.getAsExpr();
}
- NestedNameSpecifierLoc getTemplateQualifierLoc() const {
+ SourceLocation getTemplateKWLoc() const {
if (Argument.getKind() != TemplateArgument::Template &&
Argument.getKind() != TemplateArgument::TemplateExpansion)
- return NestedNameSpecifierLoc();
- return LocInfo.getTemplateQualifierLoc();
+ return SourceLocation();
+ return LocInfo.getTemplateKwLoc();
}
+ NestedNameSpecifierLoc getTemplateQualifierLoc() const;
+
SourceLocation getTemplateNameLoc() const {
if (Argument.getKind() != TemplateArgument::Template &&
Argument.getKind() != TemplateArgument::TemplateExpansion)
diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h
index 63949f898f6a2..37ea401a0045a 100644
--- a/clang/include/clang/AST/TemplateName.h
+++ b/clang/include/clang/AST/TemplateName.h
@@ -14,7 +14,7 @@
#define LLVM_CLANG_AST_TEMPLATENAME_H
#include "clang/AST/DependenceFlags.h"
-#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
#include "clang/Basic/LLVM.h"
#include "clang/Basic/OperatorKinds.h"
#include "clang/Basic/UnsignedOrNone.h"
@@ -335,10 +335,18 @@ class TemplateName {
/// structure, if any.
QualifiedTemplateName *getAsQualifiedTemplateName() const;
+ /// Retrieve the underlying qualified template name,
+ /// looking through underlying nodes.
+ QualifiedTemplateName *getAsAdjustedQualifiedTemplateName() const;
+
/// Retrieve the underlying dependent template name
/// structure, if any.
DependentTemplateName *getAsDependentTemplateName() const;
+ // Retrieve the qualifier stored in either a underlying DependentTemplateName
+ // or QualifiedTemplateName.
+ NestedNameSpecifier getQualifier() const;
+
/// Retrieve the using shadow declaration through which the underlying
/// template declaration is introduced, if any.
UsingShadowDecl *getAsUsingShadowDecl() const;
@@ -503,7 +511,7 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
/// "template" keyword is always redundant in this case (otherwise,
/// the template name would be a dependent name and we would express
/// this name with DependentTemplateName).
- llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier;
+ llvm::PointerIntPair<NestedNameSpecifier, 1, bool> Qualifier;
/// The underlying template name, it is either
/// 1) a Template -- a template declaration that this qualified name refers
@@ -512,7 +520,7 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
/// using-shadow declaration.
TemplateName UnderlyingTemplate;
- QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword,
+ QualifiedTemplateName(NestedNameSpecifier NNS, bool TemplateKeyword,
TemplateName Template)
: Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) {
assert(UnderlyingTemplate.getKind() == TemplateName::Template ||
@@ -521,7 +529,7 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
public:
/// Return the nested name specifier that qualifies this name.
- NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+ NestedNameSpecifier getQualifier() const { return Qualifier.getPointer(); }
/// Whether the template name was prefixed by the "template"
/// keyword.
@@ -534,9 +542,9 @@ class QualifiedTemplateName : public llvm::FoldingSetNode {
Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate);
}
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+ static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier NNS,
bool TemplateKeyword, TemplateName TN) {
- ID.AddPointer(NNS);
+ NNS.Profile(ID);
ID.AddBoolean(TemplateKeyword);
ID.AddPointer(TN.getAsVoidPointer());
}
@@ -585,18 +593,18 @@ class DependentTemplateStorage {
///
/// The bit stored in this qualifier describes whether the \c Name field
/// was preceeded by a template keyword.
- llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier;
+ llvm::PointerIntPair<NestedNameSpecifier, 1, bool> Qualifier;
/// The dependent template name.
IdentifierOrOverloadedOperator Name;
public:
- DependentTemplateStorage(NestedNameSpecifier *Qualifier,
+ DependentTemplateStorage(NestedNameSpecifier Qualifier,
IdentifierOrOverloadedOperator Name,
bool HasTemplateKeyword);
/// Return the nested name specifier that qualifies this name.
- NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); }
+ NestedNameSpecifier getQualifier() const { return Qualifier.getPointer(); }
IdentifierOrOverloadedOperator getName() const { return Name; }
@@ -609,10 +617,10 @@ class DependentTemplateStorage {
Profile(ID, getQualifier(), getName(), hasTemplateKeyword());
}
- static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS,
+ static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier NNS,
IdentifierOrOverloadedOperator Name,
bool HasTemplateKeyword) {
- ID.AddPointer(NNS);
+ NNS.Profile(ID);
ID.AddBoolean(HasTemplateKeyword);
Name.Profile(ID);
}
diff --git a/clang/include/clang/AST/TextNodeDumper.h b/clang/include/clang/AST/TextNodeDumper.h
index 1917a8ac29f05..6d2795111685a 100644
--- a/clang/include/clang/AST/TextNodeDumper.h
+++ b/clang/include/clang/AST/TextNodeDumper.h
@@ -211,7 +211,7 @@ class TextNodeDumper
void dumpAccessSpecifier(AccessSpecifier AS);
void dumpCleanupObject(const ExprWithCleanups::CleanupObject &C);
void dumpTemplateSpecializationKind(TemplateSpecializationKind TSK);
- void dumpNestedNameSpecifier(const NestedNameSpecifier *NNS);
+ void dumpNestedNameSpecifier(NestedNameSpecifier NNS);
void dumpConceptReference(const ConceptReference *R);
void dumpTemplateArgument(const TemplateArgument &TA);
void dumpBareTemplateName(TemplateName TN);
diff --git a/clang/include/clang/AST/Type.h b/clang/include/clang/AST/Type.h
index 21b97102db95a..db0b159d6b0cd 100644
--- a/clang/include/clang/AST/Type.h
+++ b/clang/include/clang/AST/Type.h
@@ -18,7 +18,7 @@
#define LLVM_CLANG_AST_TYPE_H
#include "clang/AST/DependenceFlags.h"
-#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
#include "clang/AST/TemplateName.h"
#include "clang/Basic/AddressSpaces.h"
#include "clang/Basic/AttrKinds.h"
@@ -133,6 +133,7 @@ struct PrintingPolicy;
class RecordDecl;
class Stmt;
class TagDecl;
+class ClassTemplateDecl;
class TemplateArgument;
class TemplateArgumentListInfo;
class TemplateArgumentLoc;
@@ -2044,8 +2045,8 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
unsigned InnerRef : 1;
};
- class TypeWithKeywordBitfields {
- friend class TypeWithKeyword;
+ class KeywordWrapperBitfields {
+ template <class> friend class KeywordWrapper;
LLVM_PREFERRED_TYPE(TypeBitfields)
unsigned : NumTypeBits;
@@ -2057,15 +2058,23 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
enum { NumTypeWithKeywordBits = NumTypeBits + 8 };
- class ElaboratedTypeBitfields {
- friend class ElaboratedType;
+ class TagTypeBitfields {
+ friend class TagType;
- LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
+ LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
unsigned : NumTypeWithKeywordBits;
- /// Whether the ElaboratedType has a trailing OwnedTagDecl.
+ /// Whether the TagType has a trailing Qualifier.
LLVM_PREFERRED_TYPE(bool)
- unsigned HasOwnedTagDecl : 1;
+ unsigned HasQualifier : 1;
+
+ /// Whether the TagType owns the Tag.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned OwnsTag : 1;
+
+ /// Whether the TagType was created from an injected name.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned IsInjected : 1;
};
class VectorTypeBitfields {
@@ -2124,22 +2133,37 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
unsigned Kind : 1;
};
+ class UnresolvedUsingBitfields {
+ friend class UnresolvedUsingType;
+
+ LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
+ unsigned : NumTypeWithKeywordBits;
+
+ /// True if there is a non-null qualifier.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned hasQualifier : 1;
+ };
+
class UsingBitfields {
friend class UsingType;
- LLVM_PREFERRED_TYPE(TypeBitfields)
- unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
+ unsigned : NumTypeWithKeywordBits;
- /// True if the underlying type is different from the declared one.
+ /// True if there is a non-null qualifier.
LLVM_PREFERRED_TYPE(bool)
- unsigned hasTypeDifferentFromDecl : 1;
+ unsigned hasQualifier : 1;
};
class TypedefBitfields {
friend class TypedefType;
- LLVM_PREFERRED_TYPE(TypeBitfields)
- unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
+ unsigned : NumTypeWithKeywordBits;
+
+ /// True if there is a non-null qualifier.
+ LLVM_PREFERRED_TYPE(bool)
+ unsigned hasQualifier : 1;
/// True if the underlying type is different from the declared one.
LLVM_PREFERRED_TYPE(bool)
@@ -2205,8 +2229,8 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
class TemplateSpecializationTypeBitfields {
friend class TemplateSpecializationType;
- LLVM_PREFERRED_TYPE(TypeBitfields)
- unsigned : NumTypeBits;
+ LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
+ unsigned : NumTypeWithKeywordBits;
/// Whether this template specialization type is a substituted type alias.
LLVM_PREFERRED_TYPE(bool)
@@ -2225,7 +2249,7 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
class DependentTemplateSpecializationTypeBitfields {
friend class DependentTemplateSpecializationType;
- LLVM_PREFERRED_TYPE(TypeWithKeywordBitfields)
+ LLVM_PREFERRED_TYPE(KeywordWrapperBitfields)
unsigned : NumTypeWithKeywordBits;
/// The number of template arguments named in this class template
@@ -2281,13 +2305,14 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
AutoTypeBitfields AutoTypeBits;
TypeOfBitfields TypeOfBits;
TypedefBitfields TypedefBits;
+ UnresolvedUsingBitfields UnresolvedUsingBits;
UsingBitfields UsingBits;
BuiltinTypeBitfields BuiltinTypeBits;
FunctionTypeBitfields FunctionTypeBits;
ObjCObjectTypeBitfields ObjCObjectTypeBits;
ReferenceTypeBitfields ReferenceTypeBits;
- TypeWithKeywordBitfields TypeWithKeywordBits;
- ElaboratedTypeBitfields ElaboratedTypeBits;
+ KeywordWrapperBitfields KeywordWrapperBits;
+ TagTypeBitfields TagTypeBits;
VectorTypeBitfields VectorTypeBits;
TemplateTypeParmTypeBitfields TemplateTypeParmTypeBits;
SubstTemplateTypeParmTypeBitfields SubstTemplateTypeParmTypeBits;
@@ -2906,6 +2931,11 @@ class alignas(TypeAlignment) Type : public ExtQualsTypeCommonBase {
/// qualifiers from the outermost type.
const ArrayType *castAsArrayTypeUnsafe() const;
+ /// If this type represents a qualified-id, this returns its nested name
+ /// specifier. For example, for the qualified-id "foo::bar::baz", this returns
+ /// "foo::bar". Returns null if this type represents an unqualified-id.
+ NestedNameSpecifier getPrefix() const;
+
/// Determine whether this type had the specified attribute applied to it
/// (looking through top-level type sugar).
bool hasAttr(attr::Kind AK) const;
@@ -3583,12 +3613,12 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
/// The class of which the pointee is a member. Must ultimately be a
/// CXXRecordType, but could be a typedef or a template parameter too.
- NestedNameSpecifier *Qualifier;
+ NestedNameSpecifier Qualifier;
- MemberPointerType(QualType Pointee, NestedNameSpecifier *Qualifier,
+ MemberPointerType(QualType Pointee, NestedNameSpecifier Qualifier,
QualType CanonicalPtr)
: Type(MemberPointer, CanonicalPtr,
- (toTypeDependence(Qualifier->getDependence()) &
+ (toTypeDependence(Qualifier.getDependence()) &
~TypeDependence::VariablyModified) |
Pointee->getDependence()),
PointeeType(Pointee), Qualifier(Qualifier) {}
@@ -3608,7 +3638,7 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
return !PointeeType->isFunctionProtoType();
}
- NestedNameSpecifier *getQualifier() const { return Qualifier; }
+ NestedNameSpecifier getQualifier() const { return Qualifier; }
/// Note: this can trigger extra deserialization when external AST sources are
/// used. Prefer `getCXXRecordDecl()` unless you really need the most recent
/// decl.
@@ -3627,7 +3657,7 @@ class MemberPointerType : public Type, public llvm::FoldingSetNode {
}
static void Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const NestedNameSpecifier *Qualifier,
+ const NestedNameSpecifier Qualifier,
const CXXRecordDecl *Cls);
static bool classof(const Type *T) {
@@ -5742,84 +5772,254 @@ class FunctionProtoType final
bool Canonical);
};
+/// The elaboration keyword that precedes a qualified type name or
+/// introduces an elaborated-type-specifier.
+enum class ElaboratedTypeKeyword {
+ /// The "struct" keyword introduces the elaborated-type-specifier.
+ Struct,
+
+ /// The "__interface" keyword introduces the elaborated-type-specifier.
+ Interface,
+
+ /// The "union" keyword introduces the elaborated-type-specifier.
+ Union,
+
+ /// The "class" keyword introduces the elaborated-type-specifier.
+ Class,
+
+ /// The "enum" keyword introduces the elaborated-type-specifier.
+ Enum,
+
+ /// The "typename" keyword precedes the qualified type name, e.g.,
+ /// \c typename T::type.
+ Typename,
+
+ /// No keyword precedes the qualified type name.
+ None
+};
+
+/// The kind of a tag type.
+enum class TagTypeKind {
+ /// The "struct" keyword.
+ Struct,
+
+ /// The "__interface" keyword.
+ Interface,
+
+ /// The "union" keyword.
+ Union,
+
+ /// The "class" keyword.
+ Class,
+
+ /// The "enum" keyword.
+ Enum
+};
+
+/// Provides a few static helpers for converting and printing
+/// elaborated type keyword and tag type kind enumerations.
+struct KeywordHelpers {
+ /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword.
+ static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
+
+ /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
+ /// It is an error to provide a type specifier which *isn't* a tag kind here.
+ static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
+
+ /// Converts a TagTypeKind into an elaborated type keyword.
+ static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
+
+ /// Converts an elaborated type keyword into a TagTypeKind.
+ /// It is an error to provide an elaborated type keyword
+ /// which *isn't* a tag kind here.
+ static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
+
+ static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
+
+ static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
+
+ static StringRef getTagTypeKindName(TagTypeKind Kind) {
+ return getKeywordName(getKeywordForTagTypeKind(Kind));
+ }
+};
+
+template <class T> class KeywordWrapper : public T, public KeywordHelpers {
+protected:
+ template <class... As>
+ KeywordWrapper(ElaboratedTypeKeyword Keyword, As &&...as)
+ : T(std::forward<As>(as)...) {
+ this->KeywordWrapperBits.Keyword = llvm::to_underlying(Keyword);
+ }
+
+public:
+ ElaboratedTypeKeyword getKeyword() const {
+ return static_cast<ElaboratedTypeKeyword>(this->KeywordWrapperBits.Keyword);
+ }
+
+ class CannotCastToThisType {};
+ static CannotCastToThisType classof(const T *);
+};
+
+/// A helper class for Type nodes having an ElaboratedTypeKeyword.
+/// The keyword in stored in the free bits of the base class.
+class TypeWithKeyword : public KeywordWrapper<Type> {
+protected:
+ TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
+ QualType Canonical, TypeDependence Dependence)
+ : KeywordWrapper(Keyword, tc, Canonical, Dependence) {}
+};
+
+template <class T> struct FoldingSetPlaceholder : llvm::FoldingSetNode {
+ void Profile(llvm::FoldingSetNodeID &ID) { getType()->Profile(ID); }
+
+ inline const T *getType() const {
+ constexpr unsigned long Offset =
+ llvm::alignTo(sizeof(T), alignof(FoldingSetPlaceholder));
+ const auto *Addr = reinterpret_cast<const T *>(
+ reinterpret_cast<const char *>(this) - Offset);
+ assert(llvm::isAddrAligned(llvm::Align(alignof(T)), Addr));
+ return Addr;
+ }
+};
+
/// Represents the dependent type named by a dependently-scoped
/// typename using declaration, e.g.
/// using typename Base<T>::foo;
///
/// Template instantiation turns these into the underlying type.
-class UnresolvedUsingType : public Type {
+class UnresolvedUsingType final
+ : public TypeWithKeyword,
+ private llvm::TrailingObjects<UnresolvedUsingType,
+ FoldingSetPlaceholder<UnresolvedUsingType>,
+ NestedNameSpecifier> {
friend class ASTContext; // ASTContext creates these.
+ friend TrailingObjects;
UnresolvedUsingTypenameDecl *Decl;
- UnresolvedUsingType(const UnresolvedUsingTypenameDecl *D)
- : Type(UnresolvedUsing, QualType(),
- TypeDependence::DependentInstantiation),
- Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {}
+ unsigned numTrailingObjects(
+ OverloadToken<FoldingSetPlaceholder<UnresolvedUsingType>>) const {
+ assert(UnresolvedUsingBits.hasQualifier ||
+ getKeyword() != ElaboratedTypeKeyword::None);
+ return 1;
+ }
+
+ FoldingSetPlaceholder<UnresolvedUsingType> *getFoldingSetPlaceholder() {
+ assert(numTrailingObjects(
+ OverloadToken<FoldingSetPlaceholder<UnresolvedUsingType>>{}) ==
+ 1);
+ return getTrailingObjects<FoldingSetPlaceholder<UnresolvedUsingType>>();
+ }
+
+ UnresolvedUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const UnresolvedUsingTypenameDecl *D,
+ const Type *CanonicalType);
public:
+ NestedNameSpecifier getQualifier() const {
+ return UnresolvedUsingBits.hasQualifier
+ ? *getTrailingObjects<NestedNameSpecifier>()
+ : std::nullopt;
+ }
+
UnresolvedUsingTypenameDecl *getDecl() const { return Decl; }
bool isSugared() const { return false; }
QualType desugar() const { return QualType(this, 0); }
- static bool classof(const Type *T) {
- return T->getTypeClass() == UnresolvedUsing;
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const UnresolvedUsingTypenameDecl *D) {
+ static_assert(llvm::to_underlying(ElaboratedTypeKeyword::None) <= 7);
+ ID.AddInteger(uintptr_t(D) | llvm::to_underlying(Keyword));
+ if (Qualifier)
+ Qualifier.Profile(ID);
}
- void Profile(llvm::FoldingSetNodeID &ID) {
- return Profile(ID, Decl);
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ Profile(ID, getKeyword(), getQualifier(), getDecl());
}
- static void Profile(llvm::FoldingSetNodeID &ID,
- UnresolvedUsingTypenameDecl *D) {
- ID.AddPointer(D);
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == UnresolvedUsing;
}
};
-class UsingType final : public Type,
+class UsingType final : public TypeWithKeyword,
public llvm::FoldingSetNode,
- private llvm::TrailingObjects<UsingType, QualType> {
- UsingShadowDecl *Found;
+ llvm::TrailingObjects<UsingType, NestedNameSpecifier> {
+ UsingShadowDecl *D;
+ QualType UnderlyingType;
+
friend class ASTContext; // ASTContext creates these.
friend TrailingObjects;
- UsingType(const UsingShadowDecl *Found, QualType Underlying, QualType Canon);
+ UsingType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
+ const UsingShadowDecl *D, QualType UnderlyingType);
public:
- UsingShadowDecl *getFoundDecl() const { return Found; }
- QualType getUnderlyingType() const;
-
- bool isSugared() const { return true; }
+ NestedNameSpecifier getQualifier() const {
+ return UsingBits.hasQualifier ? *getTrailingObjects() : std::nullopt;
+ }
- // This always has the 'same' type as declared, but not necessarily identical.
- QualType desugar() const { return getUnderlyingType(); }
+ UsingShadowDecl *getDecl() const { return D; }
- // Internal helper, for debugging purposes.
- bool typeMatchesDecl() const { return !UsingBits.hasTypeDifferentFromDecl; }
+ QualType desugar() const { return UnderlyingType; }
+ bool isSugared() const { return true; }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Found, getUnderlyingType());
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const UsingShadowDecl *D,
+ QualType UnderlyingType) {
+ static_assert(llvm::to_underlying(ElaboratedTypeKeyword::None) <= 7);
+ ID.AddInteger(uintptr_t(D) | llvm::to_underlying(Keyword));
+ UnderlyingType.Profile(ID);
+ if (Qualifier)
+ Qualifier.Profile(ID);
}
- static void Profile(llvm::FoldingSetNodeID &ID, const UsingShadowDecl *Found,
- QualType Underlying) {
- ID.AddPointer(Found);
- Underlying.Profile(ID);
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ Profile(ID, getKeyword(), getQualifier(), D, desugar());
}
static bool classof(const Type *T) { return T->getTypeClass() == Using; }
};
-class TypedefType final : public Type,
- public llvm::FoldingSetNode,
- private llvm::TrailingObjects<TypedefType, QualType> {
+class TypedefType final
+ : public TypeWithKeyword,
+ private llvm::TrailingObjects<TypedefType,
+ FoldingSetPlaceholder<TypedefType>,
+ NestedNameSpecifier, QualType> {
TypedefNameDecl *Decl;
friend class ASTContext; // ASTContext creates these.
friend TrailingObjects;
- TypedefType(TypeClass tc, const TypedefNameDecl *D, QualType UnderlyingType,
- bool HasTypeDifferentFromDecl);
+ unsigned
+ numTrailingObjects(OverloadToken<FoldingSetPlaceholder<TypedefType>>) const {
+ assert(TypedefBits.hasQualifier || TypedefBits.hasTypeDifferentFromDecl ||
+ getKeyword() != ElaboratedTypeKeyword::None);
+ return 1;
+ }
+
+ unsigned numTrailingObjects(OverloadToken<NestedNameSpecifier>) const {
+ return TypedefBits.hasQualifier;
+ }
+
+ TypedefType(TypeClass TC, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const TypedefNameDecl *D,
+ QualType UnderlyingType, bool HasTypeDifferentFromDecl);
+
+ FoldingSetPlaceholder<TypedefType> *getFoldingSetPlaceholder() {
+ assert(numTrailingObjects(
+ OverloadToken<FoldingSetPlaceholder<TypedefType>>{}) == 1);
+ return getTrailingObjects<FoldingSetPlaceholder<TypedefType>>();
+ }
public:
+ NestedNameSpecifier getQualifier() const {
+ return TypedefBits.hasQualifier ? *getTrailingObjects<NestedNameSpecifier>()
+ : std::nullopt;
+ }
+
TypedefNameDecl *getDecl() const { return Decl; }
bool isSugared() const { return true; }
@@ -5830,16 +6030,25 @@ class TypedefType final : public Type,
// Internal helper, for debugging purposes.
bool typeMatchesDecl() const { return !TypedefBits.hasTypeDifferentFromDecl; }
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, Decl, typeMatchesDecl() ? QualType() : desugar());
- }
- static void Profile(llvm::FoldingSetNodeID &ID, const TypedefNameDecl *Decl,
- QualType Underlying) {
- ID.AddPointer(Decl);
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TypedefNameDecl *Decl, QualType Underlying) {
+
+ ID.AddInteger(uintptr_t(Decl) | (Keyword != ElaboratedTypeKeyword::None) |
+ (!Qualifier << 1));
+ if (Keyword != ElaboratedTypeKeyword::None)
+ ID.AddInteger(llvm::to_underlying(Keyword));
+ if (Qualifier)
+ Qualifier.Profile(ID);
if (!Underlying.isNull())
Underlying.Profile(ID);
}
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ Profile(ID, getKeyword(), getQualifier(), getDecl(),
+ typeMatchesDecl() ? QualType() : desugar());
+ }
+
static bool classof(const Type *T) { return T->getTypeClass() == Typedef; }
};
@@ -6106,71 +6315,148 @@ class UnaryTransformType : public Type, public llvm::FoldingSetNode {
}
};
-class TagType : public Type {
- friend class ASTReader;
- template <class T> friend class serialization::AbstractTypeReader;
+class TagType : public TypeWithKeyword {
+ friend class ASTContext; // ASTContext creates these.
/// Stores the TagDecl associated with this type. The decl may point to any
/// TagDecl that declares the entity.
TagDecl *decl;
+ void *getTrailingPointer() const;
+ NestedNameSpecifier &getTrailingQualifier() const;
+
protected:
- TagType(TypeClass TC, const TagDecl *D, QualType can);
+ TagType(TypeClass TC, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const TagDecl *TD, bool OwnsTag,
+ bool IsInjected, const Type *CanonicalType);
public:
- TagDecl *getDecl() const;
+ TagDecl *getOriginalDecl() const { return decl; }
+
+ NestedNameSpecifier getQualifier() const;
+
+ /// Does the TagType own this declaration of the Tag?
+ bool isTagOwned() const { return TagTypeBits.OwnsTag; }
- /// Determines whether this type is in the process of being defined.
- bool isBeingDefined() const;
+ bool isInjected() const { return TagTypeBits.IsInjected; }
+
+ ClassTemplateDecl *getTemplateDecl() const;
+ TemplateName getTemplateName(const ASTContext &Ctx) const;
+ ArrayRef<TemplateArgument> getTemplateArgs(const ASTContext &Ctx) const;
+
+ bool isSugared() const { return false; }
+ QualType desugar() const { return getCanonicalTypeInternal(); }
static bool classof(const Type *T) {
- return T->getTypeClass() == Enum || T->getTypeClass() == Record;
+ return T->getTypeClass() == Enum || T->getTypeClass() == Record ||
+ T->getTypeClass() == InjectedClassName;
+ }
+};
+
+struct TagTypeFoldingSetPlaceholder : public llvm::FoldingSetNode {
+ static constexpr size_t getOffset() {
+ return alignof(TagType) -
+ (sizeof(TagTypeFoldingSetPlaceholder) % alignof(TagType));
+ }
+
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const TagDecl *Tag,
+ bool OwnsTag, bool IsInjected) {
+ ID.AddInteger(uintptr_t(Tag) | OwnsTag | (IsInjected << 1) |
+ ((Keyword != ElaboratedTypeKeyword::None) << 2));
+ if (Keyword != ElaboratedTypeKeyword::None)
+ ID.AddInteger(llvm::to_underlying(Keyword));
+ if (Qualifier)
+ Qualifier.Profile(ID);
+ }
+
+ void Profile(llvm::FoldingSetNodeID &ID) const {
+ const TagType *T = getTagType();
+ Profile(ID, T->getKeyword(), T->getQualifier(), T->getOriginalDecl(),
+ T->isTagOwned(), T->isInjected());
+ }
+
+ TagType *getTagType() {
+ return reinterpret_cast<TagType *>(reinterpret_cast<char *>(this + 1) +
+ getOffset());
+ }
+ const TagType *getTagType() const {
+ return const_cast<TagTypeFoldingSetPlaceholder *>(this)->getTagType();
+ }
+ static TagTypeFoldingSetPlaceholder *fromTagType(TagType *T) {
+ return reinterpret_cast<TagTypeFoldingSetPlaceholder *>(
+ reinterpret_cast<char *>(T) - getOffset()) -
+ 1;
}
};
/// A helper class that allows the use of isa/cast/dyncast
/// to detect TagType objects of structs/unions/classes.
-class RecordType : public TagType {
-protected:
- friend class ASTContext; // ASTContext creates these.
-
- explicit RecordType(const RecordDecl *D)
- : TagType(Record, reinterpret_cast<const TagDecl*>(D), QualType()) {}
- explicit RecordType(TypeClass TC, RecordDecl *D)
- : TagType(TC, reinterpret_cast<const TagDecl*>(D), QualType()) {}
+class RecordType final : public TagType {
+ using TagType::TagType;
public:
- RecordDecl *getDecl() const {
- return reinterpret_cast<RecordDecl*>(TagType::getDecl());
+ RecordDecl *getOriginalDecl() const {
+ return reinterpret_cast<RecordDecl *>(TagType::getOriginalDecl());
}
/// Recursively check all fields in the record for const-ness. If any field
/// is declared const, return true. Otherwise, return false.
bool hasConstFields() const;
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
static bool classof(const Type *T) { return T->getTypeClass() == Record; }
};
/// A helper class that allows the use of isa/cast/dyncast
/// to detect TagType objects of enums.
-class EnumType : public TagType {
+class EnumType final : public TagType {
+ using TagType::TagType;
+
+public:
+ EnumDecl *getOriginalDecl() const {
+ return reinterpret_cast<EnumDecl *>(TagType::getOriginalDecl());
+ }
+
+ static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
+};
+
+/// The injected class name of a C++ class template or class
+/// template partial specialization. Used to record that a type was
+/// spelled with a bare identifier rather than as a template-id; the
+/// equivalent for non-templated classes is just RecordType.
+///
+/// Injected class name types are always dependent. Template
+/// instantiation turns these into RecordTypes.
+///
+/// Injected class name types are always canonical. This works
+/// because it is impossible to compare an injected class name type
+/// with the corresponding non-injected template type, for the same
+/// reason that it is impossible to directly compare template
+/// parameters from different dependent contexts: injected class name
+/// types can only occur within the scope of a particular templated
+/// declaration, and within that scope every template specialization
+/// will canonicalize to the injected class name (when appropriate
+/// according to the rules of the language).
+class InjectedClassNameType final : public TagType {
friend class ASTContext; // ASTContext creates these.
- explicit EnumType(const EnumDecl *D)
- : TagType(Enum, reinterpret_cast<const TagDecl*>(D), QualType()) {}
+ InjectedClassNameType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const TagDecl *TD,
+ bool IsInjected, CanQualType CanonicalInjectedTST,
+ const Type *CanonicalType);
+
+ QualType CanonicalInjectedTST;
public:
- EnumDecl *getDecl() const {
- return reinterpret_cast<EnumDecl*>(TagType::getDecl());
- }
+ CanQualType getCanonicalInjectedTST() const;
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
+ CXXRecordDecl *getOriginalDecl() const {
+ return reinterpret_cast<CXXRecordDecl *>(TagType::getOriginalDecl());
+ }
- static bool classof(const Type *T) { return T->getTypeClass() == Enum; }
+ static bool classof(const Type *T) {
+ return T->getTypeClass() == InjectedClassName;
+ }
};
/// An attributed type is a type to which a type attribute has been applied.
@@ -6781,34 +7067,38 @@ class AutoType : public DeducedType {
};
/// Represents a C++17 deduced template specialization type.
-class DeducedTemplateSpecializationType : public DeducedType,
+class DeducedTemplateSpecializationType : public KeywordWrapper<DeducedType>,
public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
/// The name of the template whose arguments will be deduced.
TemplateName Template;
- DeducedTemplateSpecializationType(TemplateName Template,
+ DeducedTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ TemplateName Template,
QualType DeducedAsType,
bool IsDeducedAsDependent, QualType Canon)
- : DeducedType(DeducedTemplateSpecialization, DeducedAsType,
- toTypeDependence(Template.getDependence()) |
- (IsDeducedAsDependent
- ? TypeDependence::DependentInstantiation
- : TypeDependence::None),
- Canon),
+ : KeywordWrapper(Keyword, DeducedTemplateSpecialization, DeducedAsType,
+ toTypeDependence(Template.getDependence()) |
+ (IsDeducedAsDependent
+ ? TypeDependence::DependentInstantiation
+ : TypeDependence::None),
+ Canon),
Template(Template) {}
public:
/// Retrieve the name of the template that we are deducing.
- TemplateName getTemplateName() const { return Template;}
+ TemplateName getTemplateName() const { return Template; }
void Profile(llvm::FoldingSetNodeID &ID) const {
- Profile(ID, getTemplateName(), getDeducedType(), isDependentType());
+ Profile(ID, getKeyword(), getTemplateName(), getDeducedType(),
+ isDependentType());
}
- static void Profile(llvm::FoldingSetNodeID &ID, TemplateName Template,
- QualType Deduced, bool IsDependent) {
+ static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
+ TemplateName Template, QualType Deduced,
+ bool IsDependent) {
+ ID.AddInteger(llvm::to_underlying(Keyword));
Template.Profile(ID);
Deduced.Profile(ID);
ID.AddBoolean(IsDependent || Template.isDependent());
@@ -6839,7 +7129,8 @@ class DeducedTemplateSpecializationType : public DeducedType,
/// TemplateArguments, followed by a QualType representing the
/// non-canonical aliased type when the template is a type alias
/// template.
-class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
+class TemplateSpecializationType : public TypeWithKeyword,
+ public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
/// The name of the template being specialized. This is
@@ -6851,8 +7142,8 @@ class TemplateSpecializationType : public Type, public llvm::FoldingSetNode {
/// replacement must, recursively, be one of these).
TemplateName Template;
- TemplateSpecializationType(TemplateName T, bool IsAlias,
- ArrayRef<TemplateArgument> Args,
+ TemplateSpecializationType(ElaboratedTypeKeyword Keyword, TemplateName T,
+ bool IsAlias, ArrayRef<TemplateArgument> Args,
QualType Underlying);
public:
@@ -6953,241 +7244,6 @@ bool isSubstitutedDefaultArgument(ASTContext &Ctx, TemplateArgument Arg,
ArrayRef<TemplateArgument> Args,
unsigned Depth);
-/// The injected class name of a C++ class template or class
-/// template partial specialization. Used to record that a type was
-/// spelled with a bare identifier rather than as a template-id; the
-/// equivalent for non-templated classes is just RecordType.
-///
-/// Injected class name types are always dependent. Template
-/// instantiation turns these into RecordTypes.
-///
-/// Injected class name types are always canonical. This works
-/// because it is impossible to compare an injected class name type
-/// with the corresponding non-injected template type, for the same
-/// reason that it is impossible to directly compare template
-/// parameters from different dependent contexts: injected class name
-/// types can only occur within the scope of a particular templated
-/// declaration, and within that scope every template specialization
-/// will canonicalize to the injected class name (when appropriate
-/// according to the rules of the language).
-class InjectedClassNameType : public Type {
- friend class ASTContext; // ASTContext creates these.
- friend class ASTNodeImporter;
- friend class ASTReader; // FIXME: ASTContext::getInjectedClassNameType is not
- // currently suitable for AST reading, too much
- // interdependencies.
- template <class T> friend class serialization::AbstractTypeReader;
-
- CXXRecordDecl *Decl;
-
- /// The template specialization which this type represents.
- /// For example, in
- /// template <class T> class A { ... };
- /// this is A<T>, whereas in
- /// template <class X, class Y> class A<B<X,Y> > { ... };
- /// this is A<B<X,Y> >.
- ///
- /// It is always unqualified, always a template specialization type,
- /// and always dependent.
- QualType InjectedType;
-
- InjectedClassNameType(CXXRecordDecl *D, QualType TST)
- : Type(InjectedClassName, QualType(),
- TypeDependence::DependentInstantiation),
- Decl(D), InjectedType(TST) {
- assert(isa<TemplateSpecializationType>(TST));
- assert(!TST.hasQualifiers());
- assert(TST->isDependentType());
- }
-
-public:
- QualType getInjectedSpecializationType() const { return InjectedType; }
-
- const TemplateSpecializationType *getInjectedTST() const {
- return cast<TemplateSpecializationType>(InjectedType.getTypePtr());
- }
-
- TemplateName getTemplateName() const {
- return getInjectedTST()->getTemplateName();
- }
-
- CXXRecordDecl *getDecl() const;
-
- bool isSugared() const { return false; }
- QualType desugar() const { return QualType(this, 0); }
-
- static bool classof(const Type *T) {
- return T->getTypeClass() == InjectedClassName;
- }
-};
-
-/// The elaboration keyword that precedes a qualified type name or
-/// introduces an elaborated-type-specifier.
-enum class ElaboratedTypeKeyword {
- /// The "struct" keyword introduces the elaborated-type-specifier.
- Struct,
-
- /// The "__interface" keyword introduces the elaborated-type-specifier.
- Interface,
-
- /// The "union" keyword introduces the elaborated-type-specifier.
- Union,
-
- /// The "class" keyword introduces the elaborated-type-specifier.
- Class,
-
- /// The "enum" keyword introduces the elaborated-type-specifier.
- Enum,
-
- /// The "typename" keyword precedes the qualified type name, e.g.,
- /// \c typename T::type.
- Typename,
-
- /// No keyword precedes the qualified type name.
- None
-};
-
-/// The kind of a tag type.
-enum class TagTypeKind {
- /// The "struct" keyword.
- Struct,
-
- /// The "__interface" keyword.
- Interface,
-
- /// The "union" keyword.
- Union,
-
- /// The "class" keyword.
- Class,
-
- /// The "enum" keyword.
- Enum
-};
-
-/// A helper class for Type nodes having an ElaboratedTypeKeyword.
-/// The keyword in stored in the free bits of the base class.
-/// Also provides a few static helpers for converting and printing
-/// elaborated type keyword and tag type kind enumerations.
-class TypeWithKeyword : public Type {
-protected:
- TypeWithKeyword(ElaboratedTypeKeyword Keyword, TypeClass tc,
- QualType Canonical, TypeDependence Dependence)
- : Type(tc, Canonical, Dependence) {
- TypeWithKeywordBits.Keyword = llvm::to_underlying(Keyword);
- }
-
-public:
- ElaboratedTypeKeyword getKeyword() const {
- return static_cast<ElaboratedTypeKeyword>(TypeWithKeywordBits.Keyword);
- }
-
- /// Converts a type specifier (DeclSpec::TST) into an elaborated type keyword.
- static ElaboratedTypeKeyword getKeywordForTypeSpec(unsigned TypeSpec);
-
- /// Converts a type specifier (DeclSpec::TST) into a tag type kind.
- /// It is an error to provide a type specifier which *isn't* a tag kind here.
- static TagTypeKind getTagTypeKindForTypeSpec(unsigned TypeSpec);
-
- /// Converts a TagTypeKind into an elaborated type keyword.
- static ElaboratedTypeKeyword getKeywordForTagTypeKind(TagTypeKind Tag);
-
- /// Converts an elaborated type keyword into a TagTypeKind.
- /// It is an error to provide an elaborated type keyword
- /// which *isn't* a tag kind here.
- static TagTypeKind getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword);
-
- static bool KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword);
-
- static StringRef getKeywordName(ElaboratedTypeKeyword Keyword);
-
- static StringRef getTagTypeKindName(TagTypeKind Kind) {
- return getKeywordName(getKeywordForTagTypeKind(Kind));
- }
-
- class CannotCastToThisType {};
- static CannotCastToThisType classof(const Type *);
-};
-
-/// Represents a type that was referred to using an elaborated type
-/// keyword, e.g., struct S, or via a qualified name, e.g., N::M::type,
-/// or both.
-///
-/// This type is used to keep track of a type name as written in the
-/// source code, including tag keywords and any nested-name-specifiers.
-/// The type itself is always "sugar", used to express what was written
-/// in the source code but containing no additional semantic information.
-class ElaboratedType final
- : public TypeWithKeyword,
- public llvm::FoldingSetNode,
- private llvm::TrailingObjects<ElaboratedType, TagDecl *> {
- friend class ASTContext; // ASTContext creates these
- friend TrailingObjects;
-
- /// The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
-
- /// The type that this qualified name refers to.
- QualType NamedType;
-
- /// The (re)declaration of this tag type owned by this occurrence is stored
- /// as a trailing object if there is one. Use getOwnedTagDecl to obtain
- /// it, or obtain a null pointer if there is none.
-
- ElaboratedType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- QualType NamedType, QualType CanonType, TagDecl *OwnedTagDecl)
- : TypeWithKeyword(Keyword, Elaborated, CanonType,
- // Any semantic dependence on the qualifier will have
- // been incorporated into NamedType. We still need to
- // track syntactic (instantiation / error / pack)
- // dependence on the qualifier.
- NamedType->getDependence() |
- (NNS ? toSyntacticDependence(
- toTypeDependence(NNS->getDependence()))
- : TypeDependence::None)),
- NNS(NNS), NamedType(NamedType) {
- ElaboratedTypeBits.HasOwnedTagDecl = false;
- if (OwnedTagDecl) {
- ElaboratedTypeBits.HasOwnedTagDecl = true;
- *getTrailingObjects() = OwnedTagDecl;
- }
- }
-
-public:
- /// Retrieve the qualification on this type.
- NestedNameSpecifier *getQualifier() const { return NNS; }
-
- /// Retrieve the type named by the qualified-id.
- QualType getNamedType() const { return NamedType; }
-
- /// Remove a single level of sugar.
- QualType desugar() const { return getNamedType(); }
-
- /// Returns whether this type directly provides sugar.
- bool isSugared() const { return true; }
-
- /// Return the (re)declaration of this type owned by this occurrence of this
- /// type, or nullptr if there is none.
- TagDecl *getOwnedTagDecl() const {
- return ElaboratedTypeBits.HasOwnedTagDecl ? *getTrailingObjects() : nullptr;
- }
-
- void Profile(llvm::FoldingSetNodeID &ID) {
- Profile(ID, getKeyword(), NNS, NamedType, getOwnedTagDecl());
- }
-
- static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, QualType NamedType,
- TagDecl *OwnedTagDecl) {
- ID.AddInteger(llvm::to_underlying(Keyword));
- ID.AddPointer(NNS);
- NamedType.Profile(ID);
- ID.AddPointer(OwnedTagDecl);
- }
-
- static bool classof(const Type *T) { return T->getTypeClass() == Elaborated; }
-};
-
/// Represents a qualified type name for which the type name is
/// dependent.
///
@@ -7204,24 +7260,24 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
friend class ASTContext; // ASTContext creates these
/// The nested name specifier containing the qualifier.
- NestedNameSpecifier *NNS;
+ NestedNameSpecifier NNS;
/// The type that this typename specifier refers to.
const IdentifierInfo *Name;
- DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
+ DependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier NNS,
const IdentifierInfo *Name, QualType CanonType)
: TypeWithKeyword(Keyword, DependentName, CanonType,
TypeDependence::DependentInstantiation |
- toTypeDependence(NNS->getDependence())),
+ (NNS ? toTypeDependence(NNS.getDependence())
+ : TypeDependence::Dependent)),
NNS(NNS), Name(Name) {
- assert(NNS);
assert(Name);
}
public:
/// Retrieve the qualification on this type.
- NestedNameSpecifier *getQualifier() const { return NNS; }
+ NestedNameSpecifier getQualifier() const { return NNS; }
/// Retrieve the identifier that terminates this type name.
/// For example, "type" in "typename T::type".
@@ -7237,9 +7293,9 @@ class DependentNameType : public TypeWithKeyword, public llvm::FoldingSetNode {
}
static void Profile(llvm::FoldingSetNodeID &ID, ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS, const IdentifierInfo *Name) {
+ NestedNameSpecifier NNS, const IdentifierInfo *Name) {
ID.AddInteger(llvm::to_underlying(Keyword));
- ID.AddPointer(NNS);
+ NNS.Profile(ID);
ID.AddPointer(Name);
}
@@ -8760,8 +8816,8 @@ inline bool Type::isIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
- return IsEnumDeclComplete(ET->getDecl()) &&
- !IsEnumDeclScoped(ET->getDecl());
+ return IsEnumDeclComplete(ET->getOriginalDecl()) &&
+ !IsEnumDeclScoped(ET->getOriginalDecl());
}
return isBitIntType();
}
@@ -8819,7 +8875,7 @@ inline bool Type::isScalarType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType))
// Enums are scalar types, but only if they are defined. Incomplete enums
// are not treated as scalar types.
- return IsEnumDeclComplete(ET->getDecl());
+ return IsEnumDeclComplete(ET->getOriginalDecl());
return isa<PointerType>(CanonicalType) ||
isa<BlockPointerType>(CanonicalType) ||
isa<MemberPointerType>(CanonicalType) ||
@@ -8835,7 +8891,7 @@ inline bool Type::isIntegralOrEnumerationType() const {
// Check for a complete enum type; incomplete enum types are not properly an
// enumeration type in the sense required here.
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
- return IsEnumDeclComplete(ET->getDecl());
+ return IsEnumDeclComplete(ET->getOriginalDecl());
return isBitIntType();
}
@@ -8971,8 +9027,6 @@ template <typename T> const T *Type::getAsAdjusted() const {
Ty = A->getWrappedType().getTypePtr();
else if (const auto *A = dyn_cast<HLSLAttributedResourceType>(Ty))
Ty = A->getWrappedType().getTypePtr();
- else if (const auto *E = dyn_cast<ElaboratedType>(Ty))
- Ty = E->desugar().getTypePtr();
else if (const auto *P = dyn_cast<ParenType>(Ty))
Ty = P->desugar().getTypePtr();
else if (const auto *A = dyn_cast<AdjustedType>(Ty))
diff --git a/clang/include/clang/AST/TypeLoc.h b/clang/include/clang/AST/TypeLoc.h
index cf06e27758996..478a7670f7abd 100644
--- a/clang/include/clang/AST/TypeLoc.h
+++ b/clang/include/clang/AST/TypeLoc.h
@@ -16,7 +16,7 @@
#include "clang/AST/ASTConcept.h"
#include "clang/AST/DeclarationName.h"
-#include "clang/AST/NestedNameSpecifier.h"
+#include "clang/AST/NestedNameSpecifierBase.h"
#include "clang/AST/TemplateBase.h"
#include "clang/AST/Type.h"
#include "clang/Basic/LLVM.h"
@@ -193,6 +193,21 @@ class TypeLoc {
/// Get the SourceLocation of the template keyword (if any).
SourceLocation getTemplateKeywordLoc() const;
+ /// If this type represents a qualified-id, this returns it's nested name
+ /// specifier. For example, for the qualified-id "foo::bar::baz", this returns
+ /// "foo::bar". Returns null if this type represents an unqualified-id.
+ NestedNameSpecifierLoc getPrefix() const;
+
+ /// This returns the position of the type after any elaboration, such as the
+ /// 'struct' keyword, and name qualifiers. This will the 'template' keyword if
+ /// present, or the name location otherwise.
+ SourceLocation getNonPrefixBeginLoc() const;
+
+ /// This returns the position of the type after any elaboration, such as the
+ /// 'struct' keyword. This may be the position of the name qualifiers,
+ /// 'template' keyword, or the name location otherwise.
+ SourceLocation getNonElaboratedBeginLoc() const;
+
/// Initializes this to state that every location in this
/// type is the given location.
///
@@ -679,62 +694,164 @@ class BuiltinTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
}
};
-/// Wrapper for source info for types used via transparent aliases.
-class UsingTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- UsingTypeLoc, UsingType> {
-public:
- QualType getUnderlyingType() const {
- return getTypePtr()->getUnderlyingType();
+struct ElaboratedNameLocInfo {
+ SourceLocation NameLoc;
+ SourceLocation ElaboratedKeywordLoc;
+
+ ElaboratedNameLocInfo() = default;
+ ElaboratedNameLocInfo(SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation NameLoc)
+ : NameLoc(NameLoc), ElaboratedKeywordLoc(ElaboratedKeywordLoc),
+ QualifierData(QualifierLoc.getOpaqueData()) {}
+ ElaboratedNameLocInfo(ASTContext &Context, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, SourceLocation Loc)
+ : NameLoc(Loc),
+ ElaboratedKeywordLoc(
+ Keyword != ElaboratedTypeKeyword::None ? Loc : SourceLocation()),
+ QualifierData(getTrivialQualifierData(Context, Qualifier, Loc)) {}
+
+ NestedNameSpecifierLoc getQualifierLoc(NestedNameSpecifier Qualifier) const {
+ assert(!Qualifier == !QualifierData);
+ return NestedNameSpecifierLoc(Qualifier, QualifierData);
+ }
+
+ SourceRange getLocalSourceRange(NestedNameSpecifier Qualifier) const {
+ SourceLocation BeginLoc = ElaboratedKeywordLoc;
+ if (NestedNameSpecifierLoc QualifierLoc = getQualifierLoc(Qualifier);
+ BeginLoc.isInvalid() && Qualifier)
+ BeginLoc = QualifierLoc.getBeginLoc();
+ if (BeginLoc.isInvalid())
+ BeginLoc = NameLoc;
+ return SourceRange(BeginLoc, NameLoc);
}
- UsingShadowDecl *getFoundDecl() const { return getTypePtr()->getFoundDecl(); }
-};
-/// Wrapper for source info for typedefs.
-class TypedefTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TypedefTypeLoc,
- TypedefType> {
-public:
- TypedefNameDecl *getTypedefNameDecl() const {
- return getTypePtr()->getDecl();
+private:
+ void *QualifierData;
+
+ static void *getTrivialQualifierData(ASTContext &Context,
+ NestedNameSpecifier Qualifier,
+ SourceLocation Loc) {
+ if (!Qualifier)
+ return nullptr;
+ NestedNameSpecifierLocBuilder Builder;
+ Builder.MakeTrivial(Context, Qualifier, Loc);
+ return Builder.getWithLocInContext(Context).getOpaqueData();
}
};
-/// Wrapper for source info for injected class names of class
-/// templates.
-class InjectedClassNameTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- InjectedClassNameTypeLoc,
- InjectedClassNameType> {
+template <class TL, class T>
+class ElaboratedNameTypeLoc
+ : public ConcreteTypeLoc<UnqualTypeLoc, TL, T, ElaboratedNameLocInfo> {
public:
- CXXRecordDecl *getDecl() const {
- return getTypePtr()->getDecl();
+ auto *getDecl() const { return this->getTypePtr()->getDecl(); }
+
+ void set(SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation NameLoc) {
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ this->getTypePtr()->getQualifier());
+ *this->getLocalData() =
+ ElaboratedNameLocInfo(ElaboratedKeywordLoc, QualifierLoc, NameLoc);
+ }
+
+ SourceLocation getElaboratedKeywordLoc() const {
+ return this->getLocalData()->ElaboratedKeywordLoc;
+ }
+
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ return this->getLocalData()->getQualifierLoc(
+ this->getTypePtr()->getQualifier());
+ }
+
+ SourceLocation getNameLoc() const { return this->getLocalData()->NameLoc; }
+
+ SourceRange getLocalSourceRange() const {
+ return this->getLocalData()->getLocalSourceRange(
+ this->getTypePtr()->getQualifier());
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+ const auto *Ptr = this->getTypePtr();
+ *this->getLocalData() = ElaboratedNameLocInfo(Context, Ptr->getKeyword(),
+ Ptr->getQualifier(), Loc);
}
};
+/// Wrapper for source info for typedefs.
+class TypedefTypeLoc
+ : public ElaboratedNameTypeLoc<TypedefTypeLoc, TypedefType> {};
+
/// Wrapper for source info for unresolved typename using decls.
-class UnresolvedUsingTypeLoc :
- public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- UnresolvedUsingTypeLoc,
- UnresolvedUsingType> {
-public:
- UnresolvedUsingTypenameDecl *getDecl() const {
- return getTypePtr()->getDecl();
- }
+class UnresolvedUsingTypeLoc
+ : public ElaboratedNameTypeLoc<UnresolvedUsingTypeLoc,
+ UnresolvedUsingType> {};
+
+/// Wrapper for source info for types used via transparent aliases.
+class UsingTypeLoc : public ElaboratedNameTypeLoc<UsingTypeLoc, UsingType> {};
+
+struct TagTypeLocInfo {
+ SourceLocation NameLoc;
+ SourceLocation ElaboratedKWLoc;
+ void *QualifierData;
};
-/// Wrapper for source info for tag types. Note that this only
-/// records source info for the name itself; a type written 'struct foo'
-/// should be represented as an ElaboratedTypeLoc. We currently
-/// only do that when C++ is enabled because of the expense of
-/// creating an ElaboratedType node for so many type references in C.
-class TagTypeLoc : public InheritingConcreteTypeLoc<TypeSpecTypeLoc,
- TagTypeLoc,
- TagType> {
+class TagTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc, TagTypeLoc, TagType,
+ TagTypeLocInfo> {
public:
- TagDecl *getDecl() const { return getTypePtr()->getDecl(); }
+ TagDecl *getOriginalDecl() const { return getTypePtr()->getOriginalDecl(); }
/// True if the tag was defined in this type specifier.
bool isDefinition() const;
+
+ SourceLocation getElaboratedKeywordLoc() const {
+ return getLocalData()->ElaboratedKWLoc;
+ }
+
+ void setElaboratedKeywordLoc(SourceLocation Loc) {
+ getLocalData()->ElaboratedKWLoc = Loc;
+ }
+
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ NestedNameSpecifier Qualifier = getTypePtr()->getQualifier();
+ void *QualifierData = getLocalData()->QualifierData;
+ assert(!Qualifier == !QualifierData);
+ return NestedNameSpecifierLoc(Qualifier, QualifierData);
+ }
+
+ void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ getTypePtr()->getQualifier());
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+ }
+
+ SourceLocation getNameLoc() const { return getLocalData()->NameLoc; }
+
+ void setNameLoc(SourceLocation Loc) { getLocalData()->NameLoc = Loc; }
+
+ SourceRange getLocalSourceRange() const {
+ SourceLocation BeginLoc = getElaboratedKeywordLoc();
+ if (NestedNameSpecifierLoc Qualifier = getQualifierLoc();
+ BeginLoc.isInvalid() && Qualifier)
+ BeginLoc = Qualifier.getBeginLoc();
+ if (BeginLoc.isInvalid())
+ BeginLoc = getNameLoc();
+ return SourceRange(BeginLoc, getNameLoc());
+ }
+
+ void initializeLocal(ASTContext &Context, SourceLocation Loc) {
+ setElaboratedKeywordLoc(getTypePtr()->getKeyword() !=
+ ElaboratedTypeKeyword::None
+ ? Loc
+ : SourceLocation());
+ if (NestedNameSpecifier Qualifier = getTypePtr()->getQualifier()) {
+ NestedNameSpecifierLocBuilder Builder;
+ Builder.MakeTrivial(Context, Qualifier, Loc);
+ setQualifierLoc(Builder.getWithLocInContext(Context));
+ } else {
+ getLocalData()->QualifierData = nullptr;
+ }
+ setNameLoc(Loc);
+ }
};
/// Wrapper for source info for record types.
@@ -742,7 +859,9 @@ class RecordTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
RecordTypeLoc,
RecordType> {
public:
- RecordDecl *getDecl() const { return getTypePtr()->getDecl(); }
+ RecordDecl *getOriginalDecl() const {
+ return getTypePtr()->getOriginalDecl();
+ }
};
/// Wrapper for source info for enum types.
@@ -750,7 +869,18 @@ class EnumTypeLoc : public InheritingConcreteTypeLoc<TagTypeLoc,
EnumTypeLoc,
EnumType> {
public:
- EnumDecl *getDecl() const { return getTypePtr()->getDecl(); }
+ EnumDecl *getOriginalDecl() const { return getTypePtr()->getOriginalDecl(); }
+};
+
+/// Wrapper for source info for injected class names of class
+/// templates.
+class InjectedClassNameTypeLoc
+ : public InheritingConcreteTypeLoc<TagTypeLoc, InjectedClassNameTypeLoc,
+ InjectedClassNameType> {
+public:
+ CXXRecordDecl *getOriginalDecl() const {
+ return getTypePtr()->getOriginalDecl();
+ }
};
/// Wrapper for template type parameters.
@@ -1405,7 +1535,7 @@ class MemberPointerTypeLoc : public PointerLikeTypeLoc<MemberPointerTypeLoc,
void initializeLocal(ASTContext &Context, SourceLocation Loc) {
setSigilLoc(Loc);
- if (auto *Qualifier = getTypePtr()->getQualifier()) {
+ if (NestedNameSpecifier Qualifier = getTypePtr()->getQualifier()) {
NestedNameSpecifierLocBuilder Builder;
Builder.MakeTrivial(Context, Qualifier, Loc);
setQualifierLoc(Builder.getWithLocInContext(Context));
@@ -1701,9 +1831,11 @@ struct TemplateNameLocInfo {
};
struct TemplateSpecializationLocInfo : TemplateNameLocInfo {
+ SourceRange SR;
+ SourceLocation ElaboratedKWLoc;
SourceLocation TemplateKWLoc;
SourceLocation LAngleLoc;
- SourceLocation RAngleLoc;
+ void *QualifierData;
};
class TemplateSpecializationTypeLoc :
@@ -1712,54 +1844,53 @@ class TemplateSpecializationTypeLoc :
TemplateSpecializationType,
TemplateSpecializationLocInfo> {
public:
- SourceLocation getTemplateKeywordLoc() const {
- return getLocalData()->TemplateKWLoc;
- }
+ void set(SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKeywordLoc, SourceLocation NameLoc,
+ SourceLocation LAngleLoc, SourceLocation RAngleLoc);
- void setTemplateKeywordLoc(SourceLocation Loc) {
- getLocalData()->TemplateKWLoc = Loc;
- }
+ void set(SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKeywordLoc, SourceLocation NameLoc,
+ const TemplateArgumentListInfo &TAL);
- SourceLocation getLAngleLoc() const {
- return getLocalData()->LAngleLoc;
+ SourceLocation getElaboratedKeywordLoc() const {
+ return getLocalData()->ElaboratedKWLoc;
}
- void setLAngleLoc(SourceLocation Loc) {
- getLocalData()->LAngleLoc = Loc;
- }
+ NestedNameSpecifierLoc getQualifierLoc() const {
+ if (!getLocalData()->QualifierData)
+ return NestedNameSpecifierLoc();
- SourceLocation getRAngleLoc() const {
- return getLocalData()->RAngleLoc;
+ auto *QTN =
+ getTypePtr()->getTemplateName().getAsAdjustedQualifiedTemplateName();
+ assert(QTN && "missing qualification");
+ return NestedNameSpecifierLoc(QTN->getQualifier(),
+ getLocalData()->QualifierData);
}
- void setRAngleLoc(SourceLocation Loc) {
- getLocalData()->RAngleLoc = Loc;
+ SourceLocation getTemplateKeywordLoc() const {
+ return getLocalData()->TemplateKWLoc;
}
+ SourceLocation getTemplateNameLoc() const { return getLocalData()->NameLoc; }
+
+ SourceLocation getLAngleLoc() const { return getLocalData()->LAngleLoc; }
+
unsigned getNumArgs() const {
return getTypePtr()->template_arguments().size();
}
- void setArgLocInfo(unsigned i, TemplateArgumentLocInfo AI) {
- getArgInfos()[i] = AI;
- }
-
- TemplateArgumentLocInfo getArgLocInfo(unsigned i) const {
- return getArgInfos()[i];
+ MutableArrayRef<TemplateArgumentLocInfo> getArgLocInfos() {
+ return {getArgInfos(), getNumArgs()};
}
TemplateArgumentLoc getArgLoc(unsigned i) const {
return TemplateArgumentLoc(getTypePtr()->template_arguments()[i],
- getArgLocInfo(i));
- }
-
- SourceLocation getTemplateNameLoc() const {
- return getLocalData()->NameLoc;
+ getArgInfos()[i]);
}
- void setTemplateNameLoc(SourceLocation Loc) {
- getLocalData()->NameLoc = Loc;
- }
+ SourceLocation getRAngleLoc() const { return getLocalData()->SR.getEnd(); }
/// - Copy the location information from the given info.
void copy(TemplateSpecializationTypeLoc Loc) {
@@ -1773,21 +1904,9 @@ class TemplateSpecializationTypeLoc :
memcpy(Data, Loc.Data, size);
}
- SourceRange getLocalSourceRange() const {
- if (getTemplateKeywordLoc().isValid())
- return SourceRange(getTemplateKeywordLoc(), getRAngleLoc());
- else
- return SourceRange(getTemplateNameLoc(), getRAngleLoc());
- }
+ SourceRange getLocalSourceRange() const { return getLocalData()->SR; }
- void initializeLocal(ASTContext &Context, SourceLocation Loc) {
- setTemplateKeywordLoc(SourceLocation());
- setTemplateNameLoc(Loc);
- setLAngleLoc(Loc);
- setRAngleLoc(Loc);
- initializeArgLocs(Context, getTypePtr()->template_arguments(),
- getArgInfos(), Loc);
- }
+ void initializeLocal(ASTContext &Context, SourceLocation Loc);
static void initializeArgLocs(ASTContext &Context,
ArrayRef<TemplateArgument> Args,
@@ -2346,99 +2465,66 @@ class AutoTypeLoc
void initializeLocal(ASTContext &Context, SourceLocation Loc);
};
-class DeducedTemplateSpecializationTypeLoc
- : public InheritingConcreteTypeLoc<DeducedTypeLoc,
- DeducedTemplateSpecializationTypeLoc,
- DeducedTemplateSpecializationType> {
-public:
- SourceLocation getTemplateNameLoc() const {
- return getNameLoc();
- }
-
- void setTemplateNameLoc(SourceLocation Loc) {
- setNameLoc(Loc);
- }
-};
-
-struct ElaboratedLocInfo {
+struct DeducedTemplateSpecializationLocInfo : TypeSpecLocInfo {
SourceLocation ElaboratedKWLoc;
-
/// Data associated with the nested-name-specifier location.
void *QualifierData;
};
-class ElaboratedTypeLoc : public ConcreteTypeLoc<UnqualTypeLoc,
- ElaboratedTypeLoc,
- ElaboratedType,
- ElaboratedLocInfo> {
+class DeducedTemplateSpecializationTypeLoc
+ : public ConcreteTypeLoc<DeducedTypeLoc,
+ DeducedTemplateSpecializationTypeLoc,
+ DeducedTemplateSpecializationType,
+ DeducedTemplateSpecializationLocInfo> {
public:
- SourceLocation getElaboratedKeywordLoc() const {
- return !isEmpty() ? getLocalData()->ElaboratedKWLoc : SourceLocation();
+ SourceLocation getElaboratedKWLoc() const {
+ return getLocalData()->ElaboratedKWLoc;
}
- void setElaboratedKeywordLoc(SourceLocation Loc) {
- if (isEmpty()) {
- assert(Loc.isInvalid());
- return;
- }
+ void setElaboratedKWLoc(SourceLocation Loc) {
getLocalData()->ElaboratedKWLoc = Loc;
}
+ SourceLocation getTemplateNameLoc() const { return getNameLoc(); }
+
+ void setTemplateNameLoc(SourceLocation Loc) { setNameLoc(Loc); }
+
NestedNameSpecifierLoc getQualifierLoc() const {
- return !isEmpty() ? NestedNameSpecifierLoc(getTypePtr()->getQualifier(),
- getLocalData()->QualifierData)
- : NestedNameSpecifierLoc();
+ void *Data = getLocalData()->QualifierData;
+ if (!Data)
+ return NestedNameSpecifierLoc();
+ NestedNameSpecifier Qualifier = getTypePtr()
+ ->getTemplateName()
+ .getAsAdjustedQualifiedTemplateName()
+ ->getQualifier();
+ return NestedNameSpecifierLoc(Qualifier, Data);
}
void setQualifierLoc(NestedNameSpecifierLoc QualifierLoc) {
- assert(QualifierLoc.getNestedNameSpecifier() ==
- getTypePtr()->getQualifier() &&
- "Inconsistent nested-name-specifier pointer");
- if (isEmpty()) {
- assert(!QualifierLoc.hasQualifier());
+ if (!QualifierLoc) {
+ // Even if we have a nested-name-specifier in the dependent
+ // template specialization type, we won't record the nested-name-specifier
+ // location information when this type-source location information is
+ // part of a nested-name-specifier.
+ getLocalData()->QualifierData = nullptr;
return;
}
- getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
- }
-
- SourceRange getLocalSourceRange() const {
- if (getElaboratedKeywordLoc().isValid())
- if (getQualifierLoc())
- return SourceRange(getElaboratedKeywordLoc(),
- getQualifierLoc().getEndLoc());
- else
- return SourceRange(getElaboratedKeywordLoc());
- else
- return getQualifierLoc().getSourceRange();
- }
-
- void initializeLocal(ASTContext &Context, SourceLocation Loc);
-
- TypeLoc getNamedTypeLoc() const { return getInnerTypeLoc(); }
-
- QualType getInnerType() const { return getTypePtr()->getNamedType(); }
- bool isEmpty() const {
- return getTypePtr()->getKeyword() == ElaboratedTypeKeyword::None &&
- !getTypePtr()->getQualifier();
- }
-
- unsigned getLocalDataAlignment() const {
- // FIXME: We want to return 1 here in the empty case, but
- // there are bugs in how alignment is handled in TypeLocs
- // that prevent this from working.
- return ConcreteTypeLoc::getLocalDataAlignment();
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ getTypePtr()
+ ->getTemplateName()
+ .getAsAdjustedQualifiedTemplateName()
+ ->getQualifier() &&
+ "Inconsistent nested-name-specifier pointer");
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
}
+};
- unsigned getLocalDataSize() const {
- return !isEmpty() ? ConcreteTypeLoc::getLocalDataSize() : 0;
- }
+struct ElaboratedLocInfo {
+ SourceLocation ElaboratedKWLoc;
- void copy(ElaboratedTypeLoc Loc) {
- unsigned size = getFullDataSize();
- assert(size == Loc.getFullDataSize());
- memcpy(Data, Loc.Data, size);
- }
+ /// Data associated with the nested-name-specifier location.
+ void *QualifierData;
};
// This is exactly the structure of an ElaboratedTypeLoc whose inner
@@ -2749,8 +2835,6 @@ inline T TypeLoc::getAsAdjusted() const {
Cur = ATL.getWrappedLoc();
else if (auto ATL = Cur.getAs<HLSLAttributedResourceTypeLoc>())
Cur = ATL.getWrappedLoc();
- else if (auto ETL = Cur.getAs<ElaboratedTypeLoc>())
- Cur = ETL.getNamedTypeLoc();
else if (auto ATL = Cur.getAs<AdjustedTypeLoc>())
Cur = ATL.getOriginalLoc();
else if (auto MQL = Cur.getAs<MacroQualifiedTypeLoc>())
diff --git a/clang/include/clang/AST/TypeProperties.td b/clang/include/clang/AST/TypeProperties.td
index a6157649060b1..8fbeeb38c51c9 100644
--- a/clang/include/clang/AST/TypeProperties.td
+++ b/clang/include/clang/AST/TypeProperties.td
@@ -379,38 +379,59 @@ let Class = AtomicType in {
}
let Class = UnresolvedUsingType in {
- def : Property<"declaration", DeclRef> {
- let Read = [{ node->getDecl() }];
+ def : Property<"IsCanonical", Bool> {
+ let Read = [{ node->isCanonicalUnqualified() }];
}
-
+ def : Property<"Keyword", ElaboratedTypeKeyword> {
+ let Conditional = [{ !IsCanonical }];
+ let Read = [{ node->getKeyword() }];
+ }
+ def : Property<"Qualifier", NestedNameSpecifier> {
+ let Conditional = [{ !IsCanonical }];
+ let Read = [{ node->getQualifier() }];
+ }
+ def : Property<"D", DeclRef> { let Read = [{ node->getDecl() }]; }
def : Creator<[{
- return ctx.getUnresolvedUsingType(cast<UnresolvedUsingTypenameDecl>(declaration));
+ auto *UD = cast<UnresolvedUsingTypenameDecl>(D);
+ return IsCanonical ? ctx.getCanonicalUnresolvedUsingType(UD) : ctx.getUnresolvedUsingType(*Keyword, *Qualifier, UD);
}]>;
}
let Class = UsingType in {
- def : Property<"foundDeclaration", UsingShadowDeclRef> {
- let Read = [{ node->getFoundDecl() }];
+ def : Property<"Keyword", ElaboratedTypeKeyword> {
+ let Read = [{ node->getKeyword() }];
}
- def : Property<"underlyingType", QualType> {
- let Read = [{ node->getUnderlyingType() }];
+ def : Property<"Qualifier", NestedNameSpecifier> {
+ let Read = [{ node->getQualifier() }];
+ }
+ def : Property<"D", UsingShadowDeclRef> { let Read = [{ node->getDecl() }]; }
+ def : Property<"UnderlyingType", QualType> {
+ let Read = [{ node->desugar() }];
}
-
def : Creator<[{
- return ctx.getUsingType(foundDeclaration, underlyingType);
+ return ctx.getUsingType(Keyword, Qualifier, D, UnderlyingType);
}]>;
}
let Class = TypedefType in {
+ def : Property<"Keyword", ElaboratedTypeKeyword> {
+ let Read = [{ node->getKeyword() }];
+ }
+ def : Property<"Qualifier", NestedNameSpecifier> {
+ let Read = [{ node->getQualifier() }];
+ }
def : Property<"declaration", DeclRef> {
let Read = [{ node->getDecl() }];
}
- def : Property<"underlyingType", QualType> {
+ def : Property<"UnderlyingType", QualType> {
let Read = [{ node->desugar() }];
}
+ def : Property<"TypeMatchesDecl", Bool> {
+ let Read = [{ node->typeMatchesDecl() }];
+ }
def : Creator<[{
- return ctx.getTypedefType(cast<TypedefNameDecl>(declaration), underlyingType);
+ return ctx.getTypedefType(Keyword, Qualifier, cast<TypedefNameDecl>(declaration), UnderlyingType, TypeMatchesDecl);
}]>;
}
@@ -520,6 +541,9 @@ let Class = AutoType in {
}
let Class = DeducedTemplateSpecializationType in {
+ def : Property<"keyword", ElaboratedTypeKeyword> {
+ let Read = [{ node->getKeyword() }];
+ }
def : Property<"templateName", Optional<TemplateName>> {
let Read = [{ makeOptionalFromNullable(node->getTemplateName()) }];
}
@@ -533,97 +557,42 @@ let Class = DeducedTemplateSpecializationType in {
}
def : Creator<[{
- return ctx.getDeducedTemplateSpecializationType(
+ return ctx.getDeducedTemplateSpecializationType(keyword,
makeNullableFromOptional(templateName),
deducedType, dependent);
}]>;
}
let Class = TagType in {
- def : Property<"dependent", Bool> {
- let Read = [{ node->isDependentType() }];
+ def : Property<"IsCanonical", Bool> {
+ let Read = [{ node->isCanonicalUnqualified() }];
}
- def : Property<"declaration", DeclRef> {
- // We don't know which declaration was originally referenced here, and we
- // cannot reference a declaration that follows the use (because that can
- // introduce deserialization cycles), so conservatively generate a
- // reference to the first declaration.
- // FIXME: If this is a reference to a class template specialization, that
- // can still introduce a deserialization cycle.
- let Read = [{ node->getDecl()->getCanonicalDecl() }];
+ def : Property<"Keyword", ElaboratedTypeKeyword> {
+ let Conditional = [{ !IsCanonical }];
+ let Read = [{ node->getKeyword() }];
+ }
+ def : Property<"Qualifier", NestedNameSpecifier> {
+ let Conditional = [{ !IsCanonical }];
+ let Read = [{ node->getQualifier() }];
}
+ def : Property<"TD", TagDeclRef> { let Read = [{ node->getOriginalDecl() }]; }
}
let Class = EnumType in {
+ def : Property<"OwnsTag", Bool> { let Read = [{ node->isTagOwned() }]; }
def : Creator<[{
- QualType result = ctx.getEnumType(cast<EnumDecl>(declaration));
- if (dependent)
- const_cast<Type *>(result.getTypePtr())
- ->addDependence(TypeDependence::DependentInstantiation);
- return result;
+ return IsCanonical ? ctx.getCanonicalTagType(TD) : ctx.getTagType(*Keyword, *Qualifier, TD, OwnsTag);
}]>;
}
-
let Class = RecordType in {
+ def : Property<"OwnsTag", Bool> { let Read = [{ node->isTagOwned() }]; }
def : Creator<[{
- auto record = cast<RecordDecl>(declaration);
- QualType result = ctx.getRecordType(record);
- if (dependent)
- const_cast<Type *>(result.getTypePtr())
- ->addDependence(TypeDependence::DependentInstantiation);
- return result;
+ return IsCanonical ? ctx.getCanonicalTagType(TD) : ctx.getTagType(*Keyword, *Qualifier, TD, OwnsTag);
}]>;
}
-
-let Class = ElaboratedType in {
- def : Property<"keyword", ElaboratedTypeKeyword> {
- let Read = [{ node->getKeyword() }];
- }
- def : Property<"qualifier", NestedNameSpecifier> {
- let Read = [{ node->getQualifier() }];
- }
- def : Property<"namedType", QualType> {
- let Read = [{ node->getNamedType() }];
- }
- def : Property<"ownedTag", Optional<TagDeclRef>> {
- let Read = [{ makeOptionalFromPointer(
- const_cast<const TagDecl *>(node->getOwnedTagDecl())) }];
- }
-
- def : Creator<[{
- return ctx.getElaboratedType(keyword, qualifier, namedType,
- makePointerFromOptional(ownedTag));
- }]>;
-}
-
let Class = InjectedClassNameType in {
- def : Property<"declaration", DeclRef> {
- // FIXME: drilling down to the canonical declaration is what the
- // existing serialization code was doing, but it's not clear why.
- let Read = [{ node->getDecl()->getCanonicalDecl() }];
- }
- def : Property<"injectedSpecializationType", QualType> {
- let Read = [{ node->getInjectedSpecializationType() }];
- }
-
def : Creator<[{
- // FIXME: ASTContext::getInjectedClassNameType is not currently suitable
- // for AST reading, too much interdependencies.
- const Type *T = nullptr;
- auto typeDecl = cast<CXXRecordDecl>(declaration);
- for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl()) {
- if (const Type *existing = DI->getTypeForDecl()) {
- T = existing;
- break;
- }
- }
- if (!T) {
- T = new (ctx, TypeAlignment)
- InjectedClassNameType(typeDecl, injectedSpecializationType);
- for (auto *DI = typeDecl; DI; DI = DI->getPreviousDecl())
- DI->setTypeForDecl(T);
- }
- return QualType(T, 0);
+ return IsCanonical ? ctx.getCanonicalTagType(TD) : ctx.getTagType(*Keyword, *Qualifier, TD, /*OwnsTag=*/false);
}]>;
}
@@ -741,6 +710,9 @@ let Class = DependentAddressSpaceType in {
}
let Class = TemplateSpecializationType in {
+ def : Property<"keyword", ElaboratedTypeKeyword> {
+ let Read = [{ node->getKeyword() }];
+ }
def : Property<"templateName", TemplateName> {
let Read = [{ node->getTemplateName() }];
}
@@ -753,7 +725,7 @@ let Class = TemplateSpecializationType in {
}
def : Creator<[{
- return ctx.getTemplateSpecializationType(templateName, args, {}, UnderlyingType);
+ return ctx.getTemplateSpecializationType(keyword, templateName, args, {}, UnderlyingType);
}]>;
}
diff --git a/clang/lib/AST/APValue.cpp b/clang/lib/AST/APValue.cpp
index ee3dc84479fd9..2d62209bbc28c 100644
--- a/clang/lib/AST/APValue.cpp
+++ b/clang/lib/AST/APValue.cpp
@@ -902,8 +902,9 @@ void APValue::printPretty(raw_ostream &Out, const PrintingPolicy &Policy,
}
case APValue::Struct: {
Out << '{';
- const RecordDecl *RD = Ty->castAs<RecordType>()->getDecl();
bool First = true;
+ const RecordDecl *RD =
+ Ty->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
if (unsigned N = getStructNumBases()) {
const CXXRecordDecl *CD = cast<CXXRecordDecl>(RD);
CXXRecordDecl::base_class_const_iterator BI = CD->bases_begin();
diff --git a/clang/lib/AST/ASTConcept.cpp b/clang/lib/AST/ASTConcept.cpp
index c9cfec6bd64b5..bdf0d9d8bdde1 100644
--- a/clang/lib/AST/ASTConcept.cpp
+++ b/clang/lib/AST/ASTConcept.cpp
@@ -14,6 +14,7 @@
#include "clang/AST/ASTConcept.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ExprConcepts.h"
+#include "clang/AST/NestedNameSpecifier.h"
#include "clang/AST/PrettyPrinter.h"
#include "llvm/ADT/StringExtras.h"
@@ -92,10 +93,16 @@ ConceptReference::Create(const ASTContext &C, NestedNameSpecifierLoc NNS,
FoundDecl, NamedConcept, ArgsAsWritten);
}
+SourceLocation ConceptReference::getBeginLoc() const {
+ // Note that if the qualifier is null the template KW must also be null.
+ if (auto QualifierLoc = getNestedNameSpecifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return getConceptNameInfo().getBeginLoc();
+}
+
void ConceptReference::print(llvm::raw_ostream &OS,
const PrintingPolicy &Policy) const {
- if (NestedNameSpec)
- NestedNameSpec.getNestedNameSpecifier()->print(OS, Policy);
+ NestedNameSpec.getNestedNameSpecifier().print(OS, Policy);
ConceptName.printName(OS, Policy);
if (hasExplicitTemplateArgs()) {
OS << "<";
diff --git a/clang/lib/AST/ASTContext.cpp b/clang/lib/AST/ASTContext.cpp
index 679812adcdf12..96e097858a49b 100644
--- a/clang/lib/AST/ASTContext.cpp
+++ b/clang/lib/AST/ASTContext.cpp
@@ -653,7 +653,7 @@ comments::FullComment *ASTContext::getCommentForDecl(
// does not have one of its own.
QualType QT = TD->getUnderlyingType();
if (const auto *TT = QT->getAs<TagType>())
- if (const Decl *TD = TT->getDecl())
+ if (const Decl *TD = TT->getOriginalDecl())
if (comments::FullComment *FC = getCommentForDecl(TD, PP))
return cloneFullComment(FC, D);
}
@@ -1931,10 +1931,12 @@ TypeInfoChars ASTContext::getTypeInfoDataSizeInChars(QualType T) const {
// of a base-class subobject. We decide whether that's possible
// during class layout, so here we can just trust the layout results.
if (getLangOpts().CPlusPlus) {
- if (const auto *RT = T->getAs<RecordType>();
- RT && !RT->getDecl()->isInvalidDecl()) {
- const ASTRecordLayout &layout = getASTRecordLayout(RT->getDecl());
- Info.Width = layout.getDataSize();
+ if (const auto *RT = T->getAs<RecordType>()) {
+ const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ if (!RD->isInvalidDecl()) {
+ const ASTRecordLayout &layout = getASTRecordLayout(RD);
+ Info.Width = layout.getDataSize();
+ }
}
}
@@ -2001,8 +2003,9 @@ bool ASTContext::isPromotableIntegerType(QualType T) const {
// Enumerated types are promotable to their compatible integer types
// (C99 6.3.1.1) a.k.a. its underlying type (C++ [conv.prom]p2).
if (const auto *ET = T->getAs<EnumType>()) {
- if (T->isDependentType() || ET->getDecl()->getPromotionType().isNull() ||
- ET->getDecl()->isScoped())
+ const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (T->isDependentType() || ED->getPromotionType().isNull() ||
+ ED->isScoped())
return false;
return true;
@@ -2038,8 +2041,8 @@ unsigned ASTContext::getTypeAlignIfKnown(QualType T,
return Align;
// Otherwise, see if the declaration of the type had an attribute.
- if (const auto *TT = T->getAs<TagType>())
- return TT->getDecl()->getMaxAlignment();
+ if (const auto *TD = T->getAsTagDecl())
+ return TD->getMaxAlignment();
return 0;
}
@@ -2470,15 +2473,16 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
case Type::Record:
case Type::Enum: {
const auto *TT = cast<TagType>(T);
+ const TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf();
- if (TT->getDecl()->isInvalidDecl()) {
+ if (TD->isInvalidDecl()) {
Width = 8;
Align = 8;
break;
}
- if (const auto *ET = dyn_cast<EnumType>(TT)) {
- const EnumDecl *ED = ET->getDecl();
+ if (isa<EnumType>(TT)) {
+ const EnumDecl *ED = cast<EnumDecl>(TD);
TypeInfo Info =
getTypeInfo(ED->getIntegerType()->getUnqualifiedDesugaredType());
if (unsigned AttrAlign = ED->getMaxAlignment()) {
@@ -2488,8 +2492,7 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
return Info;
}
- const auto *RT = cast<RecordType>(TT);
- const RecordDecl *RD = RT->getDecl();
+ const auto *RD = cast<RecordDecl>(TD);
const ASTRecordLayout &Layout = getASTRecordLayout(RD);
Width = toBits(Layout.getSize());
Align = toBits(Layout.getAlignment());
@@ -2541,9 +2544,6 @@ TypeInfo ASTContext::getTypeInfoImpl(const Type *T) const {
break;
}
- case Type::Elaborated:
- return getTypeInfo(cast<ElaboratedType>(T)->getNamedType().getTypePtr());
-
case Type::Attributed:
return getTypeInfo(
cast<AttributedType>(T)->getEquivalentType().getTypePtr());
@@ -2614,8 +2614,7 @@ unsigned ASTContext::getTypeUnadjustedAlign(const Type *T) const {
unsigned UnadjustedAlign;
if (const auto *RT = T->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
- const ASTRecordLayout &Layout = getASTRecordLayout(RD);
+ const ASTRecordLayout &Layout = getASTRecordLayout(RT->getOriginalDecl());
UnadjustedAlign = toBits(Layout.getUnadjustedAlignment());
} else if (const auto *ObjCI = T->getAs<ObjCInterfaceType>()) {
const ASTRecordLayout &Layout = getASTObjCInterfaceLayout(ObjCI->getDecl());
@@ -2691,7 +2690,7 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
return ABIAlign;
if (const auto *RT = T->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
// When used as part of a typedef, or together with a 'packed' attribute,
// the 'aligned' attribute can be used to decrease alignment. Note that the
@@ -2714,7 +2713,10 @@ unsigned ASTContext::getPreferredTypeAlign(const Type *T) const {
if (const auto *CT = T->getAs<ComplexType>())
T = CT->getElementType().getTypePtr();
if (const auto *ET = T->getAs<EnumType>())
- T = ET->getDecl()->getIntegerType().getTypePtr();
+ T = ET->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->getIntegerType()
+ .getTypePtr();
if (T->isSpecificBuiltinType(BuiltinType::Double) ||
T->isSpecificBuiltinType(BuiltinType::LongLong) ||
T->isSpecificBuiltinType(BuiltinType::ULongLong) ||
@@ -2846,7 +2848,8 @@ static bool unionHasUniqueObjectRepresentations(const ASTContext &Context,
const RecordDecl *RD,
bool CheckIfTriviallyCopyable) {
assert(RD->isUnion() && "Must be union type");
- CharUnits UnionSize = Context.getTypeSizeInChars(RD->getTypeForDecl());
+ CharUnits UnionSize =
+ Context.getTypeSizeInChars(Context.getCanonicalTagType(RD));
for (const auto *Field : RD->fields()) {
if (!Context.hasUniqueObjectRepresentations(Field->getType(),
@@ -3040,7 +3043,8 @@ bool ASTContext::hasUniqueObjectRepresentations(
return !ABI->getMemberPointerInfo(MPT).HasPadding;
if (Ty->isRecordType()) {
- const RecordDecl *Record = Ty->castAs<RecordType>()->getDecl();
+ const RecordDecl *Record =
+ Ty->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
if (Record->isInvalidDecl())
return false;
@@ -3413,7 +3417,10 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
// type, or an unsigned integer type.
//
// So we have to treat enum types as integers.
- QualType UnderlyingType = cast<EnumType>(T)->getDecl()->getIntegerType();
+ QualType UnderlyingType = cast<EnumType>(T)
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->getIntegerType();
return encodeTypeForFunctionPointerAuth(
Ctx, OS, UnderlyingType.isNull() ? Ctx.IntTy : UnderlyingType);
}
@@ -3451,7 +3458,7 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
OS << "M";
const auto *MPT = T->castAs<MemberPointerType>();
encodeTypeForFunctionPointerAuth(
- Ctx, OS, QualType(MPT->getQualifier()->getAsType(), 0));
+ Ctx, OS, QualType(MPT->getQualifier().getAsType(), 0));
encodeTypeForFunctionPointerAuth(Ctx, OS, MPT->getPointeeType());
return;
}
@@ -3557,7 +3564,8 @@ static void encodeTypeForFunctionPointerAuth(const ASTContext &Ctx,
llvm_unreachable("should never get here");
}
case Type::Record: {
- const RecordDecl *RD = T->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ T->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
const IdentifierInfo *II = RD->getIdentifier();
// In C++, an immediate typedef of an anonymous struct or union
@@ -3735,12 +3743,6 @@ ASTContext::adjustType(QualType Orig,
adjustType(BTFT->getWrappedType(), Adjust));
}
- case Type::Elaborated: {
- const auto *ET = cast<ElaboratedType>(Orig);
- return getElaboratedType(ET->getKeyword(), ET->getQualifier(),
- adjustType(ET->getNamedType(), Adjust));
- }
-
case Type::Paren:
return getParenType(
adjustType(cast<ParenType>(Orig)->getInnerType(), Adjust));
@@ -4158,14 +4160,13 @@ QualType ASTContext::getRValueReferenceType(QualType T) const {
}
QualType ASTContext::getMemberPointerType(QualType T,
- NestedNameSpecifier *Qualifier,
+ NestedNameSpecifier Qualifier,
const CXXRecordDecl *Cls) const {
if (!Qualifier) {
assert(Cls && "At least one of Qualifier or Cls must be provided");
- Qualifier = NestedNameSpecifier::Create(*this, /*Prefix=*/nullptr,
- getTypeDeclType(Cls).getTypePtr());
+ Qualifier = NestedNameSpecifier(getCanonicalTagType(Cls).getTypePtr());
} else if (!Cls) {
- Cls = Qualifier->getAsRecordDecl();
+ Cls = Qualifier.getAsRecordDecl();
}
// Unique pointers, to guarantee there is only one pointer of a particular
// structure.
@@ -4177,12 +4178,11 @@ QualType ASTContext::getMemberPointerType(QualType T,
MemberPointerTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(PT, 0);
- NestedNameSpecifier *CanonicalQualifier = [&] {
+ NestedNameSpecifier CanonicalQualifier = [&] {
if (!Cls)
- return getCanonicalNestedNameSpecifier(Qualifier);
- NestedNameSpecifier *R = NestedNameSpecifier::Create(
- *this, /*Prefix=*/nullptr, Cls->getCanonicalDecl()->getTypeForDecl());
- assert(R == getCanonicalNestedNameSpecifier(R));
+ return Qualifier.getCanonical();
+ NestedNameSpecifier R(getCanonicalTagType(Cls).getTypePtr());
+ assert(R.isCanonical());
return R;
}();
// If the pointee or class type isn't canonical, this won't be a canonical
@@ -5216,153 +5216,301 @@ QualType ASTContext::getDependentBitIntType(bool IsUnsigned,
return QualType(New, 0);
}
-#ifndef NDEBUG
-static bool NeedsInjectedClassNameType(const RecordDecl *D) {
- if (!isa<CXXRecordDecl>(D)) return false;
- const auto *RD = cast<CXXRecordDecl>(D);
- if (isa<ClassTemplatePartialSpecializationDecl>(RD))
- return true;
- if (RD->getDescribedClassTemplate() &&
- !isa<ClassTemplateSpecializationDecl>(RD))
- return true;
- return false;
-}
-#endif
+QualType ASTContext::getTypeDeclType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TypeDecl *Decl) const {
+ if (auto *Tag = dyn_cast<TagDecl>(Decl))
+ return getTagType(Keyword, Qualifier, Tag,
+ /*OwnsTag=*/false);
+ if (auto *Typedef = dyn_cast<TypedefNameDecl>(Decl))
+ return getTypedefType(Keyword, Qualifier, Typedef);
+ if (auto *UD = dyn_cast<UnresolvedUsingTypenameDecl>(Decl))
+ return getUnresolvedUsingType(Keyword, Qualifier, UD);
-/// getInjectedClassNameType - Return the unique reference to the
-/// injected class name type for the specified templated declaration.
-QualType ASTContext::getInjectedClassNameType(CXXRecordDecl *Decl,
- QualType TST) const {
- assert(NeedsInjectedClassNameType(Decl));
- if (Decl->TypeForDecl) {
- assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
- } else if (CXXRecordDecl *PrevDecl = Decl->getPreviousDecl()) {
- assert(PrevDecl->TypeForDecl && "previous declaration has no type");
- Decl->TypeForDecl = PrevDecl->TypeForDecl;
- assert(isa<InjectedClassNameType>(Decl->TypeForDecl));
- } else {
- Type *newType = new (*this, alignof(InjectedClassNameType))
- InjectedClassNameType(Decl, TST);
- Decl->TypeForDecl = newType;
- Types.push_back(newType);
- }
+ assert(Keyword == ElaboratedTypeKeyword::None);
+ assert(!Qualifier);
return QualType(Decl->TypeForDecl, 0);
}
-/// getTypeDeclType - Return the unique reference to the type for the
-/// specified type declaration.
-QualType ASTContext::getTypeDeclTypeSlow(const TypeDecl *Decl) const {
- assert(Decl && "Passed null for Decl param");
- assert(!Decl->TypeForDecl && "TypeForDecl present in slow case");
-
- if (const auto *Typedef = dyn_cast<TypedefNameDecl>(Decl))
- return getTypedefType(Typedef);
-
- assert(!isa<TemplateTypeParmDecl>(Decl) &&
- "Template type parameter types are always available.");
-
- if (const auto *Record = dyn_cast<RecordDecl>(Decl)) {
- assert(Record->isFirstDecl() && "struct/union has previous declaration");
- assert(!NeedsInjectedClassNameType(Record));
- return getRecordType(Record);
- } else if (const auto *Enum = dyn_cast<EnumDecl>(Decl)) {
- assert(Enum->isFirstDecl() && "enum has previous declaration");
- return getEnumType(Enum);
- } else if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl)) {
- return getUnresolvedUsingType(Using);
- } else
- llvm_unreachable("TypeDecl without a type?");
-
+CanQualType ASTContext::getCanonicalTypeDeclType(const TypeDecl *TD) const {
+ if (auto *Tag = dyn_cast<TagDecl>(TD))
+ return getCanonicalTagType(Tag);
+ if (auto *TN = dyn_cast<TypedefNameDecl>(TD))
+ return getCanonicalType(TN->getUnderlyingType());
+ if (const auto *UD = dyn_cast<UnresolvedUsingTypenameDecl>(TD))
+ return getCanonicalUnresolvedUsingType(UD);
+ assert(TD->TypeForDecl);
+ return TD->TypeForDecl->getCanonicalTypeUnqualified();
+}
+
+QualType ASTContext::getTypeDeclType(const TypeDecl *Decl) const {
+ if (const auto *TD = dyn_cast<TagDecl>(Decl))
+ return getCanonicalTagType(TD);
+ if (const auto *TD = dyn_cast<TypedefNameDecl>(Decl);
+ isa_and_nonnull<TypedefDecl, TypeAliasDecl>(TD))
+ return getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD);
+ if (const auto *Using = dyn_cast<UnresolvedUsingTypenameDecl>(Decl))
+ return getCanonicalUnresolvedUsingType(Using);
+
+ assert(Decl->TypeForDecl);
return QualType(Decl->TypeForDecl, 0);
}
/// getTypedefType - Return the unique reference to the type for the
/// specified typedef name decl.
-QualType ASTContext::getTypedefType(const TypedefNameDecl *Decl,
- QualType Underlying) const {
- if (!Decl->TypeForDecl) {
- if (Underlying.isNull())
- Underlying = Decl->getUnderlyingType();
- auto *NewType = new (*this, alignof(TypedefType)) TypedefType(
- Type::Typedef, Decl, Underlying, /*HasTypeDifferentFromDecl=*/false);
- Decl->TypeForDecl = NewType;
+QualType
+ASTContext::getTypedefType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TypedefNameDecl *Decl, QualType UnderlyingType,
+ std::optional<bool> TypeMatchesDeclOrNone) const {
+ if (!TypeMatchesDeclOrNone) {
+ QualType DeclUnderlyingType = Decl->getUnderlyingType();
+ assert(!DeclUnderlyingType.isNull());
+ if (UnderlyingType.isNull())
+ UnderlyingType = DeclUnderlyingType;
+ else
+ assert(hasSameType(UnderlyingType, DeclUnderlyingType));
+ TypeMatchesDeclOrNone = UnderlyingType == DeclUnderlyingType;
+ } else {
+ // FIXME: This is a workaround for a serialization cycle: assume the decl
+ // underlying type is not available; don't touch it.
+ assert(!UnderlyingType.isNull());
+ }
+
+ if (Keyword == ElaboratedTypeKeyword::None && !Qualifier &&
+ *TypeMatchesDeclOrNone) {
+ if (Decl->TypeForDecl)
+ return QualType(Decl->TypeForDecl, 0);
+
+ auto *NewType = new (*this, alignof(TypedefType))
+ TypedefType(Type::Typedef, Keyword, Qualifier, Decl, UnderlyingType,
+ !*TypeMatchesDeclOrNone);
+
Types.push_back(NewType);
+ Decl->TypeForDecl = NewType;
return QualType(NewType, 0);
}
- if (Underlying.isNull() || Decl->getUnderlyingType() == Underlying)
- return QualType(Decl->TypeForDecl, 0);
- assert(hasSameType(Decl->getUnderlyingType(), Underlying));
llvm::FoldingSetNodeID ID;
- TypedefType::Profile(ID, Decl, Underlying);
+ TypedefType::Profile(ID, Keyword, Qualifier, Decl, UnderlyingType);
void *InsertPos = nullptr;
- if (TypedefType *T = TypedefTypes.FindNodeOrInsertPos(ID, InsertPos)) {
- assert(!T->typeMatchesDecl() &&
- "non-divergent case should be handled with TypeDecl");
- return QualType(T, 0);
- }
+ if (FoldingSetPlaceholder<TypedefType> *Placeholder =
+ TypedefTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(Placeholder->getType(), 0);
- void *Mem = Allocate(TypedefType::totalSizeToAlloc<QualType>(true),
- alignof(TypedefType));
- auto *NewType = new (Mem) TypedefType(Type::Typedef, Decl, Underlying,
- /*HasTypeDifferentFromDecl=*/true);
- TypedefTypes.InsertNode(NewType, InsertPos);
+ void *Mem =
+ Allocate(TypedefType::totalSizeToAlloc<FoldingSetPlaceholder<TypedefType>,
+ NestedNameSpecifier, QualType>(
+ 1, !!Qualifier, !*TypeMatchesDeclOrNone),
+ alignof(TypedefType));
+ auto *NewType =
+ new (Mem) TypedefType(Type::Typedef, Keyword, Qualifier, Decl,
+ UnderlyingType, !*TypeMatchesDeclOrNone);
+ auto *Placeholder = new (NewType->getFoldingSetPlaceholder())
+ FoldingSetPlaceholder<TypedefType>();
+ TypedefTypes.InsertNode(Placeholder, InsertPos);
Types.push_back(NewType);
return QualType(NewType, 0);
}
-QualType ASTContext::getUsingType(const UsingShadowDecl *Found,
- QualType Underlying) const {
+QualType ASTContext::getUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const UsingShadowDecl *D,
+ QualType UnderlyingType) const {
+ // FIXME: This is expensive to compute every time!
+ if (UnderlyingType.isNull()) {
+ const auto *UD = cast<UsingDecl>(D->getIntroducer());
+ UnderlyingType =
+ getTypeDeclType(UD->hasTypename() ? ElaboratedTypeKeyword::Typename
+ : ElaboratedTypeKeyword::None,
+ UD->getQualifier(), cast<TypeDecl>(D->getTargetDecl()));
+ }
+
llvm::FoldingSetNodeID ID;
- UsingType::Profile(ID, Found, Underlying);
+ UsingType::Profile(ID, Keyword, Qualifier, D, UnderlyingType);
void *InsertPos = nullptr;
- if (UsingType *T = UsingTypes.FindNodeOrInsertPos(ID, InsertPos))
+ if (const UsingType *T = UsingTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(T, 0);
- const Type *TypeForDecl =
- cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl();
+ assert(!UnderlyingType.hasLocalQualifiers());
- assert(!Underlying.hasLocalQualifiers());
- QualType Canon = Underlying->getCanonicalTypeInternal();
- assert(TypeForDecl->getCanonicalTypeInternal() == Canon);
+ assert(
+ hasSameType(getCanonicalTypeDeclType(cast<TypeDecl>(D->getTargetDecl())),
+ UnderlyingType));
- if (Underlying.getTypePtr() == TypeForDecl)
- Underlying = QualType();
void *Mem =
- Allocate(UsingType::totalSizeToAlloc<QualType>(!Underlying.isNull()),
+ Allocate(UsingType::totalSizeToAlloc<NestedNameSpecifier>(!!Qualifier),
alignof(UsingType));
- UsingType *NewType = new (Mem) UsingType(Found, Underlying, Canon);
- Types.push_back(NewType);
- UsingTypes.InsertNode(NewType, InsertPos);
- return QualType(NewType, 0);
+ UsingType *T = new (Mem) UsingType(Keyword, Qualifier, D, UnderlyingType);
+ Types.push_back(T);
+ UsingTypes.InsertNode(T, InsertPos);
+ return QualType(T, 0);
}
-QualType ASTContext::getRecordType(const RecordDecl *Decl) const {
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+TagType *ASTContext::getTagTypeInternal(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TagDecl *TD, bool OwnsTag,
+ bool IsInjected,
+ const Type *CanonicalType,
+ bool WithFoldingSetNode) const {
+ auto [TC, Size] = [&] {
+ switch (TD->getDeclKind()) {
+ case Decl::Enum:
+ static_assert(alignof(EnumType) == alignof(TagType));
+ return std::make_tuple(Type::Enum, sizeof(EnumType));
+ case Decl::ClassTemplatePartialSpecialization:
+ case Decl::ClassTemplateSpecialization:
+ case Decl::CXXRecord:
+ static_assert(alignof(RecordType) == alignof(TagType));
+ static_assert(alignof(InjectedClassNameType) == alignof(TagType));
+ if (cast<CXXRecordDecl>(TD)->hasInjectedClassType())
+ return std::make_tuple(Type::InjectedClassName,
+ sizeof(InjectedClassNameType));
+ [[fallthrough]];
+ case Decl::Record:
+ return std::make_tuple(Type::Record, sizeof(RecordType));
+ default:
+ llvm_unreachable("unexpected decl kind");
+ }
+ }();
- if (const RecordDecl *PrevDecl = Decl->getPreviousDecl())
- if (PrevDecl->TypeForDecl)
- return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
+ if (Qualifier) {
+ static_assert(alignof(NestedNameSpecifier) <= alignof(TagType));
+ Size = llvm::alignTo(Size, alignof(NestedNameSpecifier)) +
+ sizeof(NestedNameSpecifier);
+ }
+ void *Mem;
+ if (WithFoldingSetNode) {
+ // FIXME: It would be more profitable to tail allocate the folding set node
+ // from the type, instead of the other way around, due to the greater
+ // alignment requirements of the type. But this makes it harder to deal with
+ // the different type node sizes. This would require either uniquing from
+ // different folding set nodes, or having the folding set node accept a
+ // contextual parameter which is not fixed at construction.
+ Mem = Allocate(
+ sizeof(TagTypeFoldingSetPlaceholder) +
+ TagTypeFoldingSetPlaceholder::getOffset() + Size,
+ std::max(alignof(TagTypeFoldingSetPlaceholder), alignof(TagType)));
+ auto *T = new (Mem) TagTypeFoldingSetPlaceholder();
+ Mem = T->getTagType();
+ } else {
+ Mem = Allocate(Size, alignof(TagType));
+ }
+
+ auto *T = [&, TC = TC]() -> TagType * {
+ switch (TC) {
+ case Type::Enum: {
+ assert(isa<EnumDecl>(TD));
+ auto *T = new (Mem) EnumType(TC, Keyword, Qualifier, TD, OwnsTag,
+ IsInjected, CanonicalType);
+ assert(reinterpret_cast<void *>(T) ==
+ reinterpret_cast<void *>(static_cast<TagType *>(T)) &&
+ "TagType must be the first base of EnumType");
+ return T;
+ }
+ case Type::Record: {
+ assert(isa<RecordDecl>(TD));
+ auto *T = new (Mem) RecordType(TC, Keyword, Qualifier, TD, OwnsTag,
+ IsInjected, CanonicalType);
+ assert(reinterpret_cast<void *>(T) ==
+ reinterpret_cast<void *>(static_cast<TagType *>(T)) &&
+ "TagType must be the first base of RecordType");
+ return T;
+ }
+ case Type::InjectedClassName: {
+ CanQualType CanonicalInjectedTST =
+ cast<CXXRecordDecl>(TD)->getCanonicalTemplateSpecializationType(
+ *this);
+ auto *T =
+ new (Mem) InjectedClassNameType(Keyword, Qualifier, TD, IsInjected,
+ CanonicalInjectedTST, CanonicalType);
+ assert(reinterpret_cast<void *>(T) ==
+ reinterpret_cast<void *>(static_cast<TagType *>(T)) &&
+ "TagType must be the first base of InjectedClassNameType");
+ return T;
+ }
+ default:
+ llvm_unreachable("unexpected type class");
+ }
+ }();
+ assert(T->getKeyword() == Keyword);
+ assert(T->getQualifier() == Qualifier);
+ assert(T->getOriginalDecl() == TD);
+ assert(T->isInjected() == IsInjected);
+ assert(T->isTagOwned() == OwnsTag);
+ assert((T->isCanonicalUnqualified()
+ ? QualType()
+ : T->getCanonicalTypeInternal()) == QualType(CanonicalType, 0));
+ Types.push_back(T);
+ return T;
+}
- auto *newType = new (*this, alignof(RecordType)) RecordType(Decl);
- Decl->TypeForDecl = newType;
- Types.push_back(newType);
- return QualType(newType, 0);
+static bool getNonInjectedClassName(const TagDecl *&TD) {
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(TD);
+ RD && RD->isInjectedClassName()) {
+ TD = cast<TagDecl>(RD->getDeclContext());
+ return true;
+ }
+ return false;
}
-QualType ASTContext::getEnumType(const EnumDecl *Decl) const {
- if (Decl->TypeForDecl) return QualType(Decl->TypeForDecl, 0);
+CanQualType ASTContext::getCanonicalTagType(const TagDecl *TD) const {
+ ::getNonInjectedClassName(TD);
+ TD = TD->getCanonicalDecl();
+ if (TD->TypeForDecl)
+ return TD->TypeForDecl->getCanonicalTypeUnqualified();
+
+ const Type *CanonicalType = getTagTypeInternal(
+ ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD,
+ /*OwnsTag=*/false, /*IsInjected=*/false, /*CanonicalType=*/nullptr,
+ /*WithFoldingSetNode=*/false);
+ TD->TypeForDecl = CanonicalType;
+ return CanQualType::CreateUnsafe(QualType(CanonicalType, 0));
+}
+
+QualType ASTContext::getTagType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TagDecl *TD, bool OwnsTag) const {
+ ElaboratedTypeKeyword PreferredKeyword =
+ getLangOpts().CPlusPlus
+ ? ElaboratedTypeKeyword::None
+ : KeywordHelpers::getKeywordForTagTypeKind(TD->getTagKind());
+
+ if (Keyword == PreferredKeyword && !Qualifier && !OwnsTag) {
+ if (const Type *T = TD->TypeForDecl; T && !T->isCanonicalUnqualified())
+ return QualType(T, 0);
+
+ bool IsInjected = ::getNonInjectedClassName(TD);
+ const Type *CanonicalType = getCanonicalTagType(TD).getTypePtr();
+ const Type *T =
+ getTagTypeInternal(Keyword,
+ /*Qualifier=*/std::nullopt, TD,
+ /*OwnsTag=*/false, IsInjected, CanonicalType,
+ /*WithFoldingSetNode=*/false);
+ TD->TypeForDecl = T;
+ return QualType(T, 0);
+ }
- if (const EnumDecl *PrevDecl = Decl->getPreviousDecl())
- if (PrevDecl->TypeForDecl)
- return QualType(Decl->TypeForDecl = PrevDecl->TypeForDecl, 0);
+ bool IsInjected = ::getNonInjectedClassName(TD);
- auto *newType = new (*this, alignof(EnumType)) EnumType(Decl);
- Decl->TypeForDecl = newType;
- Types.push_back(newType);
- return QualType(newType, 0);
+ llvm::FoldingSetNodeID ID;
+ TagTypeFoldingSetPlaceholder::Profile(ID, Keyword, Qualifier, TD, OwnsTag,
+ IsInjected);
+
+ void *InsertPos = nullptr;
+ if (TagTypeFoldingSetPlaceholder *T =
+ TagTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(T->getTagType(), 0);
+
+ const Type *CanonicalType = getCanonicalTagType(TD).getTypePtr();
+ TagType *T = getTagTypeInternal(Keyword, Qualifier, TD, OwnsTag, IsInjected,
+ CanonicalType, /*WithFoldingSetNode=*/true);
+ TagTypes.InsertNode(TagTypeFoldingSetPlaceholder::fromTagType(T), InsertPos);
+ return QualType(T, 0);
}
bool ASTContext::computeBestEnumTypes(bool IsPacked, unsigned NumNegativeBits,
@@ -5457,21 +5605,69 @@ bool ASTContext::isRepresentableIntegerValue(llvm::APSInt &Value, QualType T) {
return Value.getSignificantBits() <= BitWidth;
}
-QualType ASTContext::getUnresolvedUsingType(
- const UnresolvedUsingTypenameDecl *Decl) const {
- if (Decl->TypeForDecl)
- return QualType(Decl->TypeForDecl, 0);
+UnresolvedUsingType *ASTContext::getUnresolvedUsingTypeInternal(
+ ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
+ const UnresolvedUsingTypenameDecl *D, void *InsertPos,
+ const Type *CanonicalType) const {
+ void *Mem = Allocate(
+ UnresolvedUsingType::totalSizeToAlloc<
+ FoldingSetPlaceholder<UnresolvedUsingType>, NestedNameSpecifier>(
+ !!InsertPos, !!Qualifier),
+ alignof(UnresolvedUsingType));
+ auto *T = new (Mem) UnresolvedUsingType(Keyword, Qualifier, D, CanonicalType);
+ if (InsertPos) {
+ auto *Placeholder = new (T->getFoldingSetPlaceholder())
+ FoldingSetPlaceholder<TypedefType>();
+ TypedefTypes.InsertNode(Placeholder, InsertPos);
+ }
+ Types.push_back(T);
+ return T;
+}
- if (const UnresolvedUsingTypenameDecl *CanonicalDecl =
- Decl->getCanonicalDecl())
- if (CanonicalDecl->TypeForDecl)
- return QualType(Decl->TypeForDecl = CanonicalDecl->TypeForDecl, 0);
+CanQualType ASTContext::getCanonicalUnresolvedUsingType(
+ const UnresolvedUsingTypenameDecl *D) const {
+ D = D->getCanonicalDecl();
+ if (D->TypeForDecl)
+ return D->TypeForDecl->getCanonicalTypeUnqualified();
- Type *newType =
- new (*this, alignof(UnresolvedUsingType)) UnresolvedUsingType(Decl);
- Decl->TypeForDecl = newType;
- Types.push_back(newType);
- return QualType(newType, 0);
+ const Type *CanonicalType = getUnresolvedUsingTypeInternal(
+ ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, D,
+ /*InsertPos=*/nullptr, /*CanonicalType=*/nullptr);
+ D->TypeForDecl = CanonicalType;
+ return CanQualType::CreateUnsafe(QualType(CanonicalType, 0));
+}
+
+QualType
+ASTContext::getUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const UnresolvedUsingTypenameDecl *D) const {
+ if (Keyword == ElaboratedTypeKeyword::None && !Qualifier) {
+ if (const Type *T = D->TypeForDecl; T && !T->isCanonicalUnqualified())
+ return QualType(T, 0);
+
+ const Type *CanonicalType = getCanonicalUnresolvedUsingType(D).getTypePtr();
+ const Type *T =
+ getUnresolvedUsingTypeInternal(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, D,
+ /*InsertPos=*/nullptr, CanonicalType);
+ D->TypeForDecl = T;
+ return QualType(T, 0);
+ }
+
+ llvm::FoldingSetNodeID ID;
+ UnresolvedUsingType::Profile(ID, Keyword, Qualifier, D);
+
+ void *InsertPos = nullptr;
+ if (FoldingSetPlaceholder<UnresolvedUsingType> *Placeholder =
+ UnresolvedUsingTypes.FindNodeOrInsertPos(ID, InsertPos))
+ return QualType(Placeholder->getType(), 0);
+ assert(InsertPos);
+
+ const Type *CanonicalType = getCanonicalUnresolvedUsingType(D).getTypePtr();
+ const Type *T = getUnresolvedUsingTypeInternal(Keyword, Qualifier, D,
+ InsertPos, CanonicalType);
+ return QualType(T, 0);
}
QualType ASTContext::getAttributedType(attr::Kind attrKind,
@@ -5691,34 +5887,32 @@ QualType ASTContext::getTemplateTypeParmType(unsigned Depth, unsigned Index,
}
TypeSourceInfo *ASTContext::getTemplateSpecializationTypeInfo(
+ ElaboratedTypeKeyword Keyword, SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateKeywordLoc,
TemplateName Name, SourceLocation NameLoc,
const TemplateArgumentListInfo &SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const {
- QualType TST = getTemplateSpecializationType(Name, SpecifiedArgs.arguments(),
- CanonicalArgs, Underlying);
+ QualType TST = getTemplateSpecializationType(
+ Keyword, Name, SpecifiedArgs.arguments(), CanonicalArgs, Underlying);
TypeSourceInfo *DI = CreateTypeSourceInfo(TST);
- TemplateSpecializationTypeLoc TL =
- DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>();
- TL.setTemplateKeywordLoc(SourceLocation());
- TL.setTemplateNameLoc(NameLoc);
- TL.setLAngleLoc(SpecifiedArgs.getLAngleLoc());
- TL.setRAngleLoc(SpecifiedArgs.getRAngleLoc());
- for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
- TL.setArgLocInfo(i, SpecifiedArgs[i].getLocInfo());
+ DI->getTypeLoc().castAs<TemplateSpecializationTypeLoc>().set(
+ ElaboratedKeywordLoc, QualifierLoc, TemplateKeywordLoc, NameLoc,
+ SpecifiedArgs);
return DI;
}
QualType ASTContext::getTemplateSpecializationType(
- TemplateName Template, ArrayRef<TemplateArgumentLoc> SpecifiedArgs,
+ ElaboratedTypeKeyword Keyword, TemplateName Template,
+ ArrayRef<TemplateArgumentLoc> SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const {
SmallVector<TemplateArgument, 4> SpecifiedArgVec;
SpecifiedArgVec.reserve(SpecifiedArgs.size());
for (const TemplateArgumentLoc &Arg : SpecifiedArgs)
SpecifiedArgVec.push_back(Arg.getArgument());
- return getTemplateSpecializationType(Template, SpecifiedArgVec, CanonicalArgs,
- Underlying);
+ return getTemplateSpecializationType(Keyword, Template, SpecifiedArgVec,
+ CanonicalArgs, Underlying);
}
[[maybe_unused]] static bool
@@ -5749,7 +5943,8 @@ QualType ASTContext::getCanonicalTemplateSpecializationType(
sizeof(TemplateArgument) * Args.size(),
alignof(TemplateSpecializationType));
auto *Spec = new (Mem)
- TemplateSpecializationType(Template, /*IsAlias=*/false, Args, QualType());
+ TemplateSpecializationType(ElaboratedTypeKeyword::None, Template,
+ /*IsAlias=*/false, Args, QualType());
assert(Spec->isDependentType() &&
"canonical template specialization must be dependent");
Types.push_back(Spec);
@@ -5758,7 +5953,8 @@ QualType ASTContext::getCanonicalTemplateSpecializationType(
}
QualType ASTContext::getTemplateSpecializationType(
- TemplateName Template, ArrayRef<TemplateArgument> SpecifiedArgs,
+ ElaboratedTypeKeyword Keyword, TemplateName Template,
+ ArrayRef<TemplateArgument> SpecifiedArgs,
ArrayRef<TemplateArgument> CanonicalArgs, QualType Underlying) const {
assert(!Template.getUnderlying().getAsDependentTemplateName() &&
"No dependent template names here!");
@@ -5768,7 +5964,8 @@ QualType ASTContext::getTemplateSpecializationType(
if (Underlying.isNull()) {
TemplateName CanonTemplate =
getCanonicalTemplateName(Template, /*IgnoreDeduced=*/true);
- bool NonCanonical = Template != CanonTemplate;
+ bool NonCanonical =
+ Template != CanonTemplate || Keyword != ElaboratedTypeKeyword::None;
SmallVector<TemplateArgument, 4> CanonArgsVec;
if (CanonicalArgs.empty()) {
CanonArgsVec = SmallVector<TemplateArgument, 4>(SpecifiedArgs);
@@ -5799,42 +5996,12 @@ QualType ASTContext::getTemplateSpecializationType(
sizeof(TemplateArgument) * SpecifiedArgs.size() +
(IsTypeAlias ? sizeof(QualType) : 0),
alignof(TemplateSpecializationType));
- auto *Spec = new (Mem) TemplateSpecializationType(Template, IsTypeAlias,
- SpecifiedArgs, Underlying);
+ auto *Spec = new (Mem) TemplateSpecializationType(
+ Keyword, Template, IsTypeAlias, SpecifiedArgs, Underlying);
Types.push_back(Spec);
return QualType(Spec, 0);
}
-QualType ASTContext::getElaboratedType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
- QualType NamedType,
- TagDecl *OwnedTagDecl) const {
- llvm::FoldingSetNodeID ID;
- ElaboratedType::Profile(ID, Keyword, NNS, NamedType, OwnedTagDecl);
-
- void *InsertPos = nullptr;
- ElaboratedType *T = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
- if (T)
- return QualType(T, 0);
-
- QualType Canon = NamedType;
- if (!Canon.isCanonical()) {
- Canon = getCanonicalType(NamedType);
- ElaboratedType *CheckT = ElaboratedTypes.FindNodeOrInsertPos(ID, InsertPos);
- assert(!CheckT && "Elaborated canonical type broken");
- (void)CheckT;
- }
-
- void *Mem =
- Allocate(ElaboratedType::totalSizeToAlloc<TagDecl *>(!!OwnedTagDecl),
- alignof(ElaboratedType));
- T = new (Mem) ElaboratedType(Keyword, NNS, NamedType, Canon, OwnedTagDecl);
-
- Types.push_back(T);
- ElaboratedTypes.InsertNode(T, InsertPos);
- return QualType(T, 0);
-}
-
QualType
ASTContext::getParenType(QualType InnerType) const {
llvm::FoldingSetNodeID ID;
@@ -5897,7 +6064,7 @@ getCanonicalElaboratedTypeKeyword(ElaboratedTypeKeyword Keyword) {
}
QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
- NestedNameSpecifier *NNS,
+ NestedNameSpecifier NNS,
const IdentifierInfo *Name) const {
llvm::FoldingSetNodeID ID;
DependentNameType::Profile(ID, Keyword, NNS, Name);
@@ -5909,7 +6076,7 @@ QualType ASTContext::getDependentNameType(ElaboratedTypeKeyword Keyword,
ElaboratedTypeKeyword CanonKeyword =
getCanonicalElaboratedTypeKeyword(Keyword);
- NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+ NestedNameSpecifier CanonNNS = NNS.getCanonical();
QualType Canon;
if (CanonKeyword != Keyword || CanonNNS != NNS) {
@@ -5948,13 +6115,13 @@ QualType ASTContext::getDependentTemplateSpecializationType(
ID, InsertPos))
return QualType(T, 0);
- NestedNameSpecifier *NNS = Name.getQualifier();
+ NestedNameSpecifier NNS = Name.getQualifier();
QualType Canon;
if (!IsCanonical) {
ElaboratedTypeKeyword CanonKeyword =
getCanonicalElaboratedTypeKeyword(Keyword);
- NestedNameSpecifier *CanonNNS = getCanonicalNestedNameSpecifier(NNS);
+ NestedNameSpecifier CanonNNS = NNS.getCanonical();
bool AnyNonCanonArgs = false;
auto CanonArgs =
::getCanonicalTemplateArguments(*this, Args, AnyNonCanonArgs);
@@ -5974,7 +6141,7 @@ QualType ASTContext::getDependentTemplateSpecializationType(
} else {
assert(Keyword == getCanonicalElaboratedTypeKeyword(Keyword));
assert(Name.hasTemplateKeyword());
- assert(NNS == getCanonicalNestedNameSpecifier(NNS));
+ assert(NNS.isCanonical());
#ifndef NDEBUG
for (const auto &Arg : Args)
assert(Arg.structurallyEquals(getCanonicalTemplateArgument(Arg)));
@@ -6025,7 +6192,8 @@ TemplateArgument ASTContext::getInjectedTemplateArg(NamedDecl *Param) const {
} else {
auto *TTP = cast<TemplateTemplateParmDecl>(Param);
TemplateName Name = getQualifiedTemplateName(
- nullptr, /*TemplateKeyword=*/false, TemplateName(TTP));
+ /*Qualifier=*/std::nullopt, /*TemplateKeyword=*/false,
+ TemplateName(TTP));
if (TTP->isParameterPack())
Arg = TemplateArgument(Name, /*NumExpansions=*/std::nullopt);
else
@@ -6297,11 +6465,11 @@ void ASTContext::adjustObjCTypeParamBoundType(const ObjCTypeParamDecl *Orig,
ObjCTypeParamDecl *New) const {
New->setTypeSourceInfo(getTrivialTypeSourceInfo(Orig->getUnderlyingType()));
// Update TypeForDecl after updating TypeSourceInfo.
- auto NewTypeParamTy = cast<ObjCTypeParamType>(New->getTypeForDecl());
+ auto *NewTypeParamTy = cast<ObjCTypeParamType>(New->TypeForDecl);
SmallVector<ObjCProtocolDecl *, 8> protocols;
protocols.append(NewTypeParamTy->qual_begin(), NewTypeParamTy->qual_end());
QualType UpdatedTy = getObjCTypeParamType(New, protocols);
- New->setTypeForDecl(UpdatedTy.getTypePtr());
+ New->TypeForDecl = UpdatedTy.getTypePtr();
}
/// ObjCObjectAdoptsQTypeProtocols - Checks that protocols in IC's
@@ -6698,20 +6866,20 @@ QualType ASTContext::getUnconstrainedType(QualType T) const {
}
QualType ASTContext::getDeducedTemplateSpecializationTypeInternal(
- TemplateName Template, QualType DeducedType, bool IsDependent,
- QualType Canon) const {
+ ElaboratedTypeKeyword Keyword, TemplateName Template, QualType DeducedType,
+ bool IsDependent, QualType Canon) const {
// Look in the folding set for an existing type.
void *InsertPos = nullptr;
llvm::FoldingSetNodeID ID;
- DeducedTemplateSpecializationType::Profile(ID, Template, DeducedType,
+ DeducedTemplateSpecializationType::Profile(ID, Keyword, Template, DeducedType,
IsDependent);
if (DeducedTemplateSpecializationType *DTST =
DeducedTemplateSpecializationTypes.FindNodeOrInsertPos(ID, InsertPos))
return QualType(DTST, 0);
auto *DTST = new (*this, alignof(DeducedTemplateSpecializationType))
- DeducedTemplateSpecializationType(Template, DeducedType, IsDependent,
- Canon);
+ DeducedTemplateSpecializationType(Keyword, Template, DeducedType,
+ IsDependent, Canon);
#ifndef NDEBUG
llvm::FoldingSetNodeID TempID;
@@ -6727,14 +6895,20 @@ QualType ASTContext::getDeducedTemplateSpecializationTypeInternal(
/// which has been deduced to the given type, or to the canonical undeduced
/// such type, or the canonical deduced-but-dependent such type.
QualType ASTContext::getDeducedTemplateSpecializationType(
- TemplateName Template, QualType DeducedType, bool IsDependent) const {
- QualType Canon = DeducedType.isNull()
- ? getDeducedTemplateSpecializationTypeInternal(
- getCanonicalTemplateName(Template), QualType(),
- IsDependent, QualType())
- : DeducedType.getCanonicalType();
- return getDeducedTemplateSpecializationTypeInternal(Template, DeducedType,
- IsDependent, Canon);
+ ElaboratedTypeKeyword Keyword, TemplateName Template, QualType DeducedType,
+ bool IsDependent) const {
+ // FIXME: This could save an extra hash table lookup if it handled all the
+ // parameters already being canonical.
+ // FIXME: Can this be formed from a DependentTemplateName, such that the
+ // keyword should be part of the canonical type?
+ QualType Canon =
+ DeducedType.isNull()
+ ? getDeducedTemplateSpecializationTypeInternal(
+ ElaboratedTypeKeyword::None, getCanonicalTemplateName(Template),
+ QualType(), IsDependent, QualType())
+ : DeducedType.getCanonicalType();
+ return getDeducedTemplateSpecializationTypeInternal(
+ Keyword, Template, DeducedType, IsDependent, Canon);
}
/// getAtomicType - Return the uniqued reference to the atomic type for
@@ -6784,15 +6958,6 @@ QualType ASTContext::getAutoRRefDeductType() const {
return AutoRRefDeductTy;
}
-/// getTagDeclType - Return the unique reference to the type for the
-/// specified TagDecl (struct/union/class/enum) decl.
-QualType ASTContext::getTagDeclType(const TagDecl *Decl) const {
- assert(Decl);
- // FIXME: What is the design on getTagDeclType when it requires casting
- // away const? mutable?
- return getTypeDeclType(const_cast<TagDecl*>(Decl));
-}
-
/// getSizeType - Return the unique type for "size_t" (C99 7.17), the result
/// of the sizeof operator (C99 6.5.3.4p4). The value is target dependent and
/// needs to agree with the definition in <stddef.h>.
@@ -7010,8 +7175,8 @@ bool ASTContext::UnwrapSimilarTypes(QualType &T1, QualType &T2,
*RD2 = T2MPType->getMostRecentCXXRecordDecl();
RD1 != RD2 && RD1->getCanonicalDecl() != RD2->getCanonicalDecl())
return false;
- if (getCanonicalNestedNameSpecifier(T1MPType->getQualifier()) !=
- getCanonicalNestedNameSpecifier(T2MPType->getQualifier()))
+ if (T1MPType->getQualifier().getCanonical() !=
+ T2MPType->getQualifier().getCanonical())
return false;
T1 = T1MPType->getPointeeType();
T2 = T2MPType->getPointeeType();
@@ -7168,9 +7333,8 @@ TemplateName ASTContext::getCanonicalTemplateName(TemplateName Name,
case TemplateName::DependentTemplate: {
DependentTemplateName *DTN = Name.getAsDependentTemplateName();
assert(DTN && "Non-dependent template names must refer to template decls.");
- NestedNameSpecifier *Qualifier = DTN->getQualifier();
- NestedNameSpecifier *CanonQualifier =
- getCanonicalNestedNameSpecifier(Qualifier);
+ NestedNameSpecifier Qualifier = DTN->getQualifier();
+ NestedNameSpecifier CanonQualifier = Qualifier.getCanonical();
if (Qualifier != CanonQualifier || !DTN->hasTemplateKeyword())
return getDependentTemplateName({CanonQualifier, DTN->getName(),
/*HasTemplateKeyword=*/true});
@@ -7387,50 +7551,40 @@ bool ASTContext::isSameDefaultTemplateArgument(const NamedDecl *X,
return hasSameTemplateName(TAX.getAsTemplate(), TAY.getAsTemplate());
}
-static NamespaceDecl *getNamespace(const NestedNameSpecifier *X) {
- if (auto *NS = X->getAsNamespace())
- return NS;
- if (auto *NAS = X->getAsNamespaceAlias())
- return NAS->getNamespace();
- return nullptr;
-}
+static bool isSameQualifier(const NestedNameSpecifier X,
+ const NestedNameSpecifier Y) {
+ if (X == Y)
+ return true;
+ if (!X || !Y)
+ return false;
-static bool isSameQualifier(const NestedNameSpecifier *X,
- const NestedNameSpecifier *Y) {
- if (auto *NSX = getNamespace(X)) {
- auto *NSY = getNamespace(Y);
- if (!NSY || NSX->getCanonicalDecl() != NSY->getCanonicalDecl())
- return false;
- } else if (X->getKind() != Y->getKind())
+ auto Kind = X.getKind();
+ if (Kind != Y.getKind())
return false;
// FIXME: For namespaces and types, we're permitted to check that the entity
// is named via the same tokens. We should probably do so.
- switch (X->getKind()) {
- case NestedNameSpecifier::Identifier:
- if (X->getAsIdentifier() != Y->getAsIdentifier())
+ switch (Kind) {
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [NamespaceX, PrefixX] = X.getAsNamespaceAndPrefix();
+ auto [NamespaceY, PrefixY] = Y.getAsNamespaceAndPrefix();
+ if (!declaresSameEntity(NamespaceX->getNamespace(),
+ NamespaceY->getNamespace()))
return false;
- break;
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- // We've already checked that we named the same namespace.
- break;
- case NestedNameSpecifier::TypeSpec:
- if (X->getAsType()->getCanonicalTypeInternal() !=
- Y->getAsType()->getCanonicalTypeInternal())
+ return isSameQualifier(PrefixX, PrefixY);
+ }
+ case NestedNameSpecifier::Kind::Type: {
+ const auto *TX = X.getAsType(), *TY = Y.getAsType();
+ if (TX->getCanonicalTypeInternal() != TY->getCanonicalTypeInternal())
return false;
- break;
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
+ return isSameQualifier(TX->getPrefix(), TY->getPrefix());
+ }
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
return true;
}
-
- // Recurse into earlier portion of NNS, if any.
- auto *PX = X->getPrefix();
- auto *PY = Y->getPrefix();
- if (PX && PY)
- return isSameQualifier(PX, PY);
- return !PX && !PY;
+ llvm_unreachable("unhandled qualifier kind");
}
static bool hasSameCudaAttrs(const FunctionDecl *A, const FunctionDecl *B) {
@@ -7823,70 +7977,6 @@ bool ASTContext::isSameTemplateArgument(const TemplateArgument &Arg1,
llvm_unreachable("Unhandled template argument kind");
}
-NestedNameSpecifier *
-ASTContext::getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const {
- if (!NNS)
- return nullptr;
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- // Canonicalize the prefix but keep the identifier the same.
- return NestedNameSpecifier::Create(*this,
- getCanonicalNestedNameSpecifier(NNS->getPrefix()),
- NNS->getAsIdentifier());
-
- case NestedNameSpecifier::Namespace:
- // A namespace is canonical; build a nested-name-specifier with
- // this namespace and no prefix.
- return NestedNameSpecifier::Create(*this, nullptr,
- NNS->getAsNamespace()->getFirstDecl());
-
- case NestedNameSpecifier::NamespaceAlias:
- // A namespace is canonical; build a nested-name-specifier with
- // this namespace and no prefix.
- return NestedNameSpecifier::Create(
- *this, nullptr,
- NNS->getAsNamespaceAlias()->getNamespace()->getFirstDecl());
-
- // The difference between TypeSpec and TypeSpecWithTemplate is that the
- // latter will have the 'template' keyword when printed.
- case NestedNameSpecifier::TypeSpec: {
- const Type *T = getCanonicalType(NNS->getAsType());
-
- // If we have some kind of dependent-named type (e.g., "typename T::type"),
- // break it apart into its prefix and identifier, then reconsititute those
- // as the canonical nested-name-specifier. This is required to canonicalize
- // a dependent nested-name-specifier involving typedefs of dependent-name
- // types, e.g.,
- // typedef typename T::type T1;
- // typedef typename T1::type T2;
- if (const auto *DNT = T->getAs<DependentNameType>())
- return NestedNameSpecifier::Create(*this, DNT->getQualifier(),
- DNT->getIdentifier());
- if (const auto *DTST = T->getAs<DependentTemplateSpecializationType>()) {
- const DependentTemplateStorage &DTN = DTST->getDependentTemplateName();
- QualType NewT = getDependentTemplateSpecializationType(
- ElaboratedTypeKeyword::None,
- {/*NNS=*/nullptr, DTN.getName(), /*HasTemplateKeyword=*/true},
- DTST->template_arguments(), /*IsCanonical=*/true);
- assert(NewT.isCanonical());
- NestedNameSpecifier *Prefix = DTN.getQualifier();
- if (!Prefix)
- Prefix = getCanonicalNestedNameSpecifier(NNS->getPrefix());
- return NestedNameSpecifier::Create(*this, Prefix, NewT.getTypePtr());
- }
- return NestedNameSpecifier::Create(*this, nullptr, T);
- }
-
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- // The global specifier and __super specifer are canonical and unique.
- return NNS;
- }
-
- llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
-}
-
const ArrayType *ASTContext::getAsArrayType(QualType T) const {
// Handle the non-qualified case efficiently.
if (!T.hasLocalQualifiers()) {
@@ -8205,7 +8295,7 @@ QualType ASTContext::getPromotedIntegerType(QualType Promotable) const {
assert(!Promotable.isNull());
assert(isPromotableIntegerType(Promotable));
if (const auto *ET = Promotable->getAs<EnumType>())
- return ET->getDecl()->getPromotionType();
+ return ET->getOriginalDecl()->getDefinitionOrSelf()->getPromotionType();
if (const auto *BT = Promotable->getAs<BuiltinType>()) {
// C++ [conv.prom]: A prvalue of type char16_t, char32_t, or wchar_t
@@ -8264,8 +8354,9 @@ Qualifiers::ObjCLifetime ASTContext::getInnerObjCOwnership(QualType T) const {
static const Type *getIntegerTypeForEnum(const EnumType *ET) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
- if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
- return ET->getDecl()->getIntegerType().getTypePtr();
+ const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (ED->isComplete() && !ED->isScoped())
+ return ED->getIntegerType().getTypePtr();
return nullptr;
}
@@ -8394,7 +8485,7 @@ TypedefDecl *ASTContext::getCFConstantStringDecl() const {
CFConstantStringTagDecl->completeDefinition();
// This type is designed to be compatible with NSConstantString, but cannot
// use the same name, since NSConstantString is an interface.
- auto tagType = getTagDeclType(CFConstantStringTagDecl);
+ CanQualType tagType = getCanonicalTagType(CFConstantStringTagDecl);
CFConstantStringTypeDecl =
buildImplicitTypedef(tagType, "__NSConstantString");
@@ -8409,14 +8500,15 @@ RecordDecl *ASTContext::getCFConstantStringTagDecl() const {
// getCFConstantStringType - Return the type used for constant CFStrings.
QualType ASTContext::getCFConstantStringType() const {
- return getTypedefType(getCFConstantStringDecl());
+ return getTypedefType(ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt,
+ getCFConstantStringDecl());
}
QualType ASTContext::getObjCSuperType() const {
if (ObjCSuperType.isNull()) {
RecordDecl *ObjCSuperTypeDecl = buildImplicitRecord("objc_super");
getTranslationUnitDecl()->addDecl(ObjCSuperTypeDecl);
- ObjCSuperType = getTagDeclType(ObjCSuperTypeDecl);
+ ObjCSuperType = getCanonicalTagType(ObjCSuperTypeDecl);
}
return ObjCSuperType;
}
@@ -8425,12 +8517,12 @@ void ASTContext::setCFConstantStringType(QualType T) {
const auto *TD = T->castAs<TypedefType>();
CFConstantStringTypeDecl = cast<TypedefDecl>(TD->getDecl());
const auto *TagType = TD->castAs<RecordType>();
- CFConstantStringTagDecl = TagType->getDecl();
+ CFConstantStringTagDecl = TagType->getOriginalDecl()->getDefinitionOrSelf();
}
QualType ASTContext::getBlockDescriptorType() const {
if (BlockDescriptorType)
- return getTagDeclType(BlockDescriptorType);
+ return getCanonicalTagType(BlockDescriptorType);
RecordDecl *RD;
// FIXME: Needs the FlagAppleBlock bit.
@@ -8460,12 +8552,12 @@ QualType ASTContext::getBlockDescriptorType() const {
BlockDescriptorType = RD;
- return getTagDeclType(BlockDescriptorType);
+ return getCanonicalTagType(BlockDescriptorType);
}
QualType ASTContext::getBlockDescriptorExtendedType() const {
if (BlockDescriptorExtendedType)
- return getTagDeclType(BlockDescriptorExtendedType);
+ return getCanonicalTagType(BlockDescriptorExtendedType);
RecordDecl *RD;
// FIXME: Needs the FlagAppleBlock bit.
@@ -8499,7 +8591,7 @@ QualType ASTContext::getBlockDescriptorExtendedType() const {
RD->completeDefinition();
BlockDescriptorExtendedType = RD;
- return getTagDeclType(BlockDescriptorExtendedType);
+ return getCanonicalTagType(BlockDescriptorExtendedType);
}
OpenCLTypeKind ASTContext::getOpenCLTypeKind(const Type *T) const {
@@ -9137,7 +9229,7 @@ static char getObjCEncodingForPrimitiveType(const ASTContext *C,
}
static char ObjCEncodingForEnumType(const ASTContext *C, const EnumType *ET) {
- EnumDecl *Enum = ET->getDecl();
+ EnumDecl *Enum = ET->getOriginalDecl()->getDefinitionOrSelf();
// The encoding of an non-fixed enum type is always 'i', regardless of size.
if (!Enum->isFixed())
@@ -9306,13 +9398,14 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
return;
}
} else if (const auto *RTy = PointeeTy->getAs<RecordType>()) {
+ const IdentifierInfo *II = RTy->getOriginalDecl()->getIdentifier();
// GCC binary compat: Need to convert "struct objc_class *" to "#".
- if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_class")) {
+ if (II == &Idents.get("objc_class")) {
S += '#';
return;
}
// GCC binary compat: Need to convert "struct objc_object *" to "@".
- if (RTy->getDecl()->getIdentifier() == &Idents.get("objc_object")) {
+ if (II == &Idents.get("objc_object")) {
S += '@';
return;
}
@@ -9377,7 +9470,7 @@ void ASTContext::getObjCEncodingForTypeImpl(QualType T, std::string &S,
return;
case Type::Record: {
- RecordDecl *RDecl = cast<RecordType>(CT)->getDecl();
+ RecordDecl *RDecl = cast<RecordType>(CT)->getOriginalDecl();
S += RDecl->isUnion() ? '(' : '{';
// Anonymous structures print as '?'
if (const IdentifierInfo *II = RDecl->getIdentifier()) {
@@ -9865,7 +9958,7 @@ CreateAArch64ABIBuiltinVaListDecl(const ASTContext *Context) {
}
VaListTagDecl->completeDefinition();
Context->VaListTagDecl = VaListTagDecl;
- QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+ CanQualType VaListTagType = Context->getCanonicalTagType(VaListTagDecl);
// } __builtin_va_list;
return Context->buildImplicitTypedef(VaListTagType, "__builtin_va_list");
@@ -9917,14 +10010,15 @@ static TypedefDecl *CreatePowerABIBuiltinVaListDecl(const ASTContext *Context) {
}
VaListTagDecl->completeDefinition();
Context->VaListTagDecl = VaListTagDecl;
- QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+ CanQualType VaListTagType = Context->getCanonicalTagType(VaListTagDecl);
// } __va_list_tag;
TypedefDecl *VaListTagTypedefDecl =
Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
QualType VaListTagTypedefType =
- Context->getTypedefType(VaListTagTypedefDecl);
+ Context->getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, VaListTagTypedefDecl);
// typedef __va_list_tag __builtin_va_list[1];
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
@@ -9976,7 +10070,7 @@ CreateX86_64ABIBuiltinVaListDecl(const ASTContext *Context) {
}
VaListTagDecl->completeDefinition();
Context->VaListTagDecl = VaListTagDecl;
- QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+ CanQualType VaListTagType = Context->getCanonicalTagType(VaListTagDecl);
// };
@@ -10032,7 +10126,7 @@ CreateAAPCSABIBuiltinVaListDecl(const ASTContext *Context) {
Context->VaListTagDecl = VaListDecl;
// typedef struct __va_list __builtin_va_list;
- QualType T = Context->getRecordType(VaListDecl);
+ CanQualType T = Context->getCanonicalTagType(VaListDecl);
return Context->buildImplicitTypedef(T, "__builtin_va_list");
}
@@ -10079,7 +10173,7 @@ CreateSystemZBuiltinVaListDecl(const ASTContext *Context) {
}
VaListTagDecl->completeDefinition();
Context->VaListTagDecl = VaListTagDecl;
- QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+ CanQualType VaListTagType = Context->getCanonicalTagType(VaListTagDecl);
// };
@@ -10126,13 +10220,15 @@ static TypedefDecl *CreateHexagonBuiltinVaListDecl(const ASTContext *Context) {
}
VaListTagDecl->completeDefinition();
Context->VaListTagDecl = VaListTagDecl;
- QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+ CanQualType VaListTagType = Context->getCanonicalTagType(VaListTagDecl);
// } __va_list_tag;
TypedefDecl *VaListTagTypedefDecl =
Context->buildImplicitTypedef(VaListTagType, "__va_list_tag");
- QualType VaListTagTypedefType = Context->getTypedefType(VaListTagTypedefDecl);
+ QualType VaListTagTypedefType =
+ Context->getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, VaListTagTypedefDecl);
// typedef __va_list_tag __builtin_va_list[1];
llvm::APInt Size(Context->getTypeSize(Context->getSizeType()), 1);
@@ -10170,7 +10266,7 @@ CreateXtensaABIBuiltinVaListDecl(const ASTContext *Context) {
}
VaListTagDecl->completeDefinition();
Context->VaListTagDecl = VaListTagDecl;
- QualType VaListTagType = Context->getRecordType(VaListTagDecl);
+ CanQualType VaListTagType = Context->getCanonicalTagType(VaListTagDecl);
// } __va_list_tag;
TypedefDecl *VaListTagTypedefDecl =
@@ -10286,7 +10382,7 @@ TemplateName ASTContext::getAssumedTemplateName(DeclarationName Name) const {
/// Retrieve the template name that represents a qualified
/// template name such as \c std::vector.
-TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
+TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier Qualifier,
bool TemplateKeyword,
TemplateName Template) const {
assert(Template.getKind() == TemplateName::Template ||
@@ -10294,14 +10390,14 @@ TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS,
// FIXME: Canonicalization?
llvm::FoldingSetNodeID ID;
- QualifiedTemplateName::Profile(ID, NNS, TemplateKeyword, Template);
+ QualifiedTemplateName::Profile(ID, Qualifier, TemplateKeyword, Template);
void *InsertPos = nullptr;
QualifiedTemplateName *QTN =
- QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
+ QualifiedTemplateNames.FindNodeOrInsertPos(ID, InsertPos);
if (!QTN) {
QTN = new (*this, alignof(QualifiedTemplateName))
- QualifiedTemplateName(NNS, TemplateKeyword, Template);
+ QualifiedTemplateName(Qualifier, TemplateKeyword, Template);
QualifiedTemplateNames.InsertNode(QTN, InsertPos);
}
@@ -11271,7 +11367,7 @@ QualType ASTContext::mergeTransparentUnionType(QualType T, QualType SubType,
bool OfBlockPointer,
bool Unqualified) {
if (const RecordType *UT = T->getAsUnionType()) {
- RecordDecl *UD = UT->getDecl();
+ RecordDecl *UD = UT->getOriginalDecl()->getMostRecentDecl();
if (UD->hasAttr<TransparentUnionAttr>()) {
for (const auto *I : UD->fields()) {
QualType ET = I->getType().getUnqualifiedType();
@@ -11503,7 +11599,8 @@ QualType ASTContext::mergeFunctionTypes(QualType lhs, QualType rhs,
// Look at the converted type of enum types, since that is the type used
// to pass enum values.
if (const auto *Enum = paramTy->getAs<EnumType>()) {
- paramTy = Enum->getDecl()->getIntegerType();
+ paramTy =
+ Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (paramTy.isNull())
return {};
}
@@ -11535,7 +11632,8 @@ static QualType mergeEnumWithInteger(ASTContext &Context, const EnumType *ET,
// a signed integer type, or an unsigned integer type.
// Compatibility is based on the underlying type, not the promotion
// type.
- QualType underlyingType = ET->getDecl()->getIntegerType();
+ QualType underlyingType =
+ ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (underlyingType.isNull())
return {};
if (Context.hasSameType(underlyingType, other))
@@ -12094,7 +12192,7 @@ QualType ASTContext::mergeObjCGCQualifiers(QualType LHS, QualType RHS) {
unsigned ASTContext::getIntWidth(QualType T) const {
if (const auto *ET = T->getAs<EnumType>())
- T = ET->getDecl()->getIntegerType();
+ T = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (T->isBooleanType())
return 1;
if (const auto *EIT = T->getAs<BitIntType>())
@@ -12120,7 +12218,7 @@ QualType ASTContext::getCorrespondingUnsignedType(QualType T) const {
// For enums, get the underlying integer type of the enum, and let the general
// integer type signchanging code handle it.
if (const auto *ETy = T->getAs<EnumType>())
- T = ETy->getDecl()->getIntegerType();
+ T = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
switch (T->castAs<BuiltinType>()->getKind()) {
case BuiltinType::Char_U:
@@ -12194,7 +12292,7 @@ QualType ASTContext::getCorrespondingSignedType(QualType T) const {
// For enums, get the underlying integer type of the enum, and let the general
// integer type signchanging code handle it.
if (const auto *ETy = T->getAs<EnumType>())
- T = ETy->getDecl()->getIntegerType();
+ T = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
switch (T->castAs<BuiltinType>()->getKind()) {
case BuiltinType::Char_S:
@@ -13554,7 +13652,7 @@ static T *getCommonDeclChecked(T *X, T *Y) {
const_cast<Decl *>(cast<Decl>(Y))));
}
-static TemplateName getCommonTemplateName(ASTContext &Ctx, TemplateName X,
+static TemplateName getCommonTemplateName(const ASTContext &Ctx, TemplateName X,
TemplateName Y,
bool IgnoreDeduced = false) {
if (X.getAsVoidPointer() == Y.getAsVoidPointer())
@@ -13569,7 +13667,7 @@ static TemplateName getCommonTemplateName(ASTContext &Ctx, TemplateName X,
return CX;
}
-static TemplateName getCommonTemplateNameChecked(ASTContext &Ctx,
+static TemplateName getCommonTemplateNameChecked(const ASTContext &Ctx,
TemplateName X, TemplateName Y,
bool IgnoreDeduced) {
TemplateName R = getCommonTemplateName(Ctx, X, Y, IgnoreDeduced);
@@ -13577,7 +13675,7 @@ static TemplateName getCommonTemplateNameChecked(ASTContext &Ctx,
return R;
}
-static auto getCommonTypes(ASTContext &Ctx, ArrayRef<QualType> Xs,
+static auto getCommonTypes(const ASTContext &Ctx, ArrayRef<QualType> Xs,
ArrayRef<QualType> Ys, bool Unqualified = false) {
assert(Xs.size() == Ys.size());
SmallVector<QualType, 8> Rs(Xs.size());
@@ -13592,7 +13690,7 @@ static SourceLocation getCommonAttrLoc(const T *X, const T *Y) {
: SourceLocation();
}
-static TemplateArgument getCommonTemplateArgument(ASTContext &Ctx,
+static TemplateArgument getCommonTemplateArgument(const ASTContext &Ctx,
const TemplateArgument &X,
const TemplateArgument &Y) {
if (X.getKind() != Y.getKind())
@@ -13638,7 +13736,7 @@ static TemplateArgument getCommonTemplateArgument(ASTContext &Ctx,
}
}
-static bool getCommonTemplateArguments(ASTContext &Ctx,
+static bool getCommonTemplateArguments(const ASTContext &Ctx,
SmallVectorImpl<TemplateArgument> &R,
ArrayRef<TemplateArgument> Xs,
ArrayRef<TemplateArgument> Ys) {
@@ -13653,7 +13751,7 @@ static bool getCommonTemplateArguments(ASTContext &Ctx,
return false;
}
-static auto getCommonTemplateArguments(ASTContext &Ctx,
+static auto getCommonTemplateArguments(const ASTContext &Ctx,
ArrayRef<TemplateArgument> Xs,
ArrayRef<TemplateArgument> Ys) {
SmallVector<TemplateArgument, 8> R;
@@ -13664,162 +13762,101 @@ static auto getCommonTemplateArguments(ASTContext &Ctx,
}
template <class T>
-static ElaboratedTypeKeyword getCommonTypeKeyword(const T *X, const T *Y) {
- return X->getKeyword() == Y->getKeyword() ? X->getKeyword()
- : ElaboratedTypeKeyword::None;
+static ElaboratedTypeKeyword getCommonTypeKeyword(const T *X, const T *Y,
+ bool IsSame) {
+ ElaboratedTypeKeyword KX = X->getKeyword(), KY = Y->getKeyword();
+ if (KX == KY)
+ return KX;
+ KX = getCanonicalElaboratedTypeKeyword(KX);
+ assert(!IsSame || KX == getCanonicalElaboratedTypeKeyword(KY));
+ return KX;
}
/// Returns a NestedNameSpecifier which has only the common sugar
/// present in both NNS1 and NNS2.
-static NestedNameSpecifier *getCommonNNS(ASTContext &Ctx,
- NestedNameSpecifier *NNS1,
- NestedNameSpecifier *NNS2,
- bool IsSame) {
+static NestedNameSpecifier getCommonNNS(const ASTContext &Ctx,
+ NestedNameSpecifier NNS1,
+ NestedNameSpecifier NNS2, bool IsSame) {
// If they are identical, all sugar is common.
if (NNS1 == NNS2)
return NNS1;
- // IsSame implies both NNSes are equivalent.
- NestedNameSpecifier *Canon = Ctx.getCanonicalNestedNameSpecifier(NNS1);
- if (Canon != Ctx.getCanonicalNestedNameSpecifier(NNS2)) {
+ // IsSame implies both Qualifiers are equivalent.
+ NestedNameSpecifier Canon = NNS1.getCanonical();
+ if (Canon != NNS2.getCanonical()) {
assert(!IsSame && "Should be the same NestedNameSpecifier");
// If they are not the same, there is nothing to unify.
- // FIXME: It would be useful here if we could represent a canonically
- // empty NNS, which is not identical to an empty-as-written NNS.
- return nullptr;
+ return std::nullopt;
}
- NestedNameSpecifier *R = nullptr;
- NestedNameSpecifier::SpecifierKind K1 = NNS1->getKind(), K2 = NNS2->getKind();
- switch (K1) {
- case NestedNameSpecifier::SpecifierKind::Identifier: {
- assert(K2 == NestedNameSpecifier::SpecifierKind::Identifier);
- IdentifierInfo *II = NNS1->getAsIdentifier();
- assert(II == NNS2->getAsIdentifier());
- // For an identifier, the prefixes are significant, so they must be the
- // same.
- NestedNameSpecifier *P = ::getCommonNNS(Ctx, NNS1->getPrefix(),
- NNS2->getPrefix(), /*IsSame=*/true);
- R = NestedNameSpecifier::Create(Ctx, P, II);
- break;
- }
- case NestedNameSpecifier::SpecifierKind::Namespace:
- case NestedNameSpecifier::SpecifierKind::NamespaceAlias: {
- assert(K2 == NestedNameSpecifier::SpecifierKind::Namespace ||
- K2 == NestedNameSpecifier::SpecifierKind::NamespaceAlias);
- // The prefixes for namespaces are not significant, its declaration
- // identifies it uniquely.
- NestedNameSpecifier *P =
- ::getCommonNNS(Ctx, NNS1->getPrefix(), NNS2->getPrefix(),
- /*IsSame=*/false);
- NamespaceAliasDecl *A1 = NNS1->getAsNamespaceAlias(),
- *A2 = NNS2->getAsNamespaceAlias();
- // Are they the same namespace alias?
- if (declaresSameEntity(A1, A2)) {
- R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(A1, A2));
+ NestedNameSpecifier R = std::nullopt;
+ NestedNameSpecifier::Kind Kind = NNS1.getKind();
+ assert(Kind == NNS2.getKind());
+ switch (Kind) {
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace1, Prefix1] = NNS1.getAsNamespaceAndPrefix();
+ auto [Namespace2, Prefix2] = NNS2.getAsNamespaceAndPrefix();
+ auto Kind = Namespace1->getKind();
+ if (Kind != Namespace2->getKind() ||
+ (Kind == Decl::NamespaceAlias &&
+ !declaresSameEntity(Namespace1, Namespace2))) {
+ R = NestedNameSpecifier(
+ Ctx,
+ ::getCommonDeclChecked(Namespace1->getNamespace(),
+ Namespace2->getNamespace()),
+ /*Prefix=*/std::nullopt);
break;
}
- // Otherwise, look at the namespaces only.
- NamespaceDecl *N1 = A1 ? A1->getNamespace() : NNS1->getAsNamespace(),
- *N2 = A2 ? A2->getNamespace() : NNS2->getAsNamespace();
- R = NestedNameSpecifier::Create(Ctx, P, ::getCommonDeclChecked(N1, N2));
+ // The prefixes for namespaces are not significant, its declaration
+ // identifies it uniquely.
+ NestedNameSpecifier Prefix = ::getCommonNNS(Ctx, Prefix1, Prefix2,
+ /*IsSame=*/false);
+ R = NestedNameSpecifier(Ctx, ::getCommonDeclChecked(Namespace1, Namespace2),
+ Prefix);
break;
}
- case NestedNameSpecifier::SpecifierKind::TypeSpec: {
- // FIXME: See comment below, on Super case.
- if (K2 == NestedNameSpecifier::SpecifierKind::Super)
- return Ctx.getCanonicalNestedNameSpecifier(NNS1);
-
- assert(K2 == NestedNameSpecifier::SpecifierKind::TypeSpec);
-
- const Type *T1 = NNS1->getAsType(), *T2 = NNS2->getAsType();
- if (T1 == T2) {
- // If the types are indentical, then only the prefixes differ.
- // A well-formed NNS never has these types, as they have
- // special normalized forms.
- assert((!isa<DependentNameType, ElaboratedType>(T1)));
- // Only for a DependentTemplateSpecializationType the prefix
- // is actually significant. A DependentName, which would be another
- // plausible case, cannot occur here, as explained above.
- bool IsSame = isa<DependentTemplateSpecializationType>(T1);
- NestedNameSpecifier *P =
- ::getCommonNNS(Ctx, NNS1->getPrefix(), NNS2->getPrefix(), IsSame);
- R = NestedNameSpecifier::Create(Ctx, P, T1);
- break;
- }
- // TODO: Try to salvage the original prefix.
- // If getCommonSugaredType removed any top level sugar, the original prefix
- // is not applicable anymore.
+ case NestedNameSpecifier::Kind::Type: {
+ const Type *T1 = NNS1.getAsType(), *T2 = NNS2.getAsType();
const Type *T = Ctx.getCommonSugaredType(QualType(T1, 0), QualType(T2, 0),
/*Unqualified=*/true)
.getTypePtr();
-
- // A NestedNameSpecifier has special normalization rules for certain types.
- switch (T->getTypeClass()) {
- case Type::Elaborated: {
- // An ElaboratedType is stripped off, it's Qualifier becomes the prefix.
- auto *ET = cast<ElaboratedType>(T);
- R = NestedNameSpecifier::Create(Ctx, ET->getQualifier(),
- ET->getNamedType().getTypePtr());
- break;
- }
- case Type::DependentName: {
- // A DependentName is turned into an Identifier NNS.
- auto *DN = cast<DependentNameType>(T);
- R = NestedNameSpecifier::Create(Ctx, DN->getQualifier(),
- DN->getIdentifier());
- break;
- }
- case Type::DependentTemplateSpecialization: {
- // A DependentTemplateSpecializationType loses it's Qualifier, which
- // is turned into the prefix.
- auto *DTST = cast<DependentTemplateSpecializationType>(T);
- const DependentTemplateStorage &DTN = DTST->getDependentTemplateName();
- DependentTemplateStorage NewDTN(/*Qualifier=*/nullptr, DTN.getName(),
- DTN.hasTemplateKeyword());
- T = Ctx.getDependentTemplateSpecializationType(DTST->getKeyword(), NewDTN,
- DTST->template_arguments())
- .getTypePtr();
- R = NestedNameSpecifier::Create(Ctx, DTN.getQualifier(), T);
- break;
- }
- default:
- R = NestedNameSpecifier::Create(Ctx, /*Prefix=*/nullptr, T);
- break;
- }
+ R = NestedNameSpecifier(T);
break;
}
- case NestedNameSpecifier::SpecifierKind::Super:
+ case NestedNameSpecifier::Kind::Super: {
// FIXME: Can __super even be used with data members?
// If it's only usable in functions, we will never see it here,
// unless we save the qualifiers used in function types.
// In that case, it might be possible NNS2 is a type,
// in which case we should degrade the result to
// a CXXRecordType.
- return Ctx.getCanonicalNestedNameSpecifier(NNS1);
- case NestedNameSpecifier::SpecifierKind::Global:
- // The global NNS is a singleton.
- assert(K2 == NestedNameSpecifier::SpecifierKind::Global &&
- "Global NNS cannot be equivalent to any other kind");
- llvm_unreachable("Global NestedNameSpecifiers did not compare equal");
- }
- assert(Ctx.getCanonicalNestedNameSpecifier(R) == Canon);
+ R = NestedNameSpecifier(
+ getCommonDeclChecked(NNS1.getAsSuper(), NNS2.getAsSuper()));
+ break;
+ }
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ // These are singletons.
+ llvm_unreachable("singletons did not compare equal");
+ }
+ assert(R.getCanonical() == Canon);
return R;
}
template <class T>
-static NestedNameSpecifier *getCommonQualifier(ASTContext &Ctx, const T *X,
- const T *Y, bool IsSame) {
+static NestedNameSpecifier getCommonQualifier(const ASTContext &Ctx, const T *X,
+ const T *Y, bool IsSame) {
return ::getCommonNNS(Ctx, X->getQualifier(), Y->getQualifier(), IsSame);
}
template <class T>
-static QualType getCommonElementType(ASTContext &Ctx, const T *X, const T *Y) {
+static QualType getCommonElementType(const ASTContext &Ctx, const T *X,
+ const T *Y) {
return Ctx.getCommonSugaredType(X->getElementType(), Y->getElementType());
}
template <class T>
-static QualType getCommonArrayElementType(ASTContext &Ctx, const T *X,
+static QualType getCommonArrayElementType(const ASTContext &Ctx, const T *X,
Qualifiers &QX, const T *Y,
Qualifiers &QY) {
QualType EX = X->getElementType(), EY = Y->getElementType();
@@ -13836,11 +13873,13 @@ static QualType getCommonArrayElementType(ASTContext &Ctx, const T *X,
}
template <class T>
-static QualType getCommonPointeeType(ASTContext &Ctx, const T *X, const T *Y) {
+static QualType getCommonPointeeType(const ASTContext &Ctx, const T *X,
+ const T *Y) {
return Ctx.getCommonSugaredType(X->getPointeeType(), Y->getPointeeType());
}
-template <class T> static auto *getCommonSizeExpr(ASTContext &Ctx, T *X, T *Y) {
+template <class T>
+static auto *getCommonSizeExpr(const ASTContext &Ctx, T *X, T *Y) {
assert(Ctx.hasSameExpr(X->getSizeExpr(), Y->getSizeExpr()));
return X->getSizeExpr();
}
@@ -13860,8 +13899,9 @@ static auto getCommonIndexTypeCVRQualifiers(const ArrayType *X,
// each type (in a canonical sense) only once, in the order they appear
// from X to Y. If they occur in both X and Y, the result will contain
// the common sugared type between them.
-static void mergeTypeLists(ASTContext &Ctx, SmallVectorImpl<QualType> &Out,
- ArrayRef<QualType> X, ArrayRef<QualType> Y) {
+static void mergeTypeLists(const ASTContext &Ctx,
+ SmallVectorImpl<QualType> &Out, ArrayRef<QualType> X,
+ ArrayRef<QualType> Y) {
llvm::DenseMap<QualType, unsigned> Found;
for (auto Ts : {X, Y}) {
for (QualType T : Ts) {
@@ -13880,7 +13920,7 @@ FunctionProtoType::ExceptionSpecInfo
ASTContext::mergeExceptionSpecs(FunctionProtoType::ExceptionSpecInfo ESI1,
FunctionProtoType::ExceptionSpecInfo ESI2,
SmallVectorImpl<QualType> &ExceptionTypeStorage,
- bool AcceptDependent) {
+ bool AcceptDependent) const {
ExceptionSpecificationType EST1 = ESI1.Type, EST2 = ESI2.Type;
// If either of them can throw anything, that is the result.
@@ -13944,7 +13984,7 @@ ASTContext::mergeExceptionSpecs(FunctionProtoType::ExceptionSpecInfo ESI1,
llvm_unreachable("invalid ExceptionSpecificationType");
}
-static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
+static QualType getCommonNonSugarTypeNode(const ASTContext &Ctx, const Type *X,
Qualifiers &QX, const Type *Y,
Qualifiers &QY) {
Type::TypeClass TC = X->getTypeClass();
@@ -13962,10 +14002,8 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
SUGAR_FREE_TYPE(Builtin)
SUGAR_FREE_TYPE(DeducedTemplateSpecialization)
SUGAR_FREE_TYPE(DependentBitInt)
- SUGAR_FREE_TYPE(Enum)
SUGAR_FREE_TYPE(BitInt)
SUGAR_FREE_TYPE(ObjCInterface)
- SUGAR_FREE_TYPE(Record)
SUGAR_FREE_TYPE(SubstTemplateTypeParmPack)
SUGAR_FREE_TYPE(UnresolvedUsing)
SUGAR_FREE_TYPE(HLSLAttributedResource)
@@ -14183,13 +14221,15 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
getCommonElementType(Ctx, VX, VY), getCommonSizeExpr(Ctx, VX, VY),
getCommonAttrLoc(VX, VY), VX->getVectorKind());
}
+ case Type::Enum:
+ case Type::Record:
case Type::InjectedClassName: {
- const auto *IX = cast<InjectedClassNameType>(X),
- *IY = cast<InjectedClassNameType>(Y);
- return Ctx.getInjectedClassNameType(
- getCommonDeclChecked(IX->getDecl(), IY->getDecl()),
- Ctx.getCommonSugaredType(IX->getInjectedSpecializationType(),
- IY->getInjectedSpecializationType()));
+ const auto *TX = cast<TagType>(X), *TY = cast<TagType>(Y);
+ return Ctx.getTagType(
+ ::getCommonTypeKeyword(TX, TY, /*IsSame=*/false),
+ ::getCommonQualifier(Ctx, TX, TY, /*IsSame=*/false),
+ ::getCommonDeclChecked(TX->getOriginalDecl(), TY->getOriginalDecl()),
+ /*OwnedTag=*/false);
}
case Type::TemplateSpecialization: {
const auto *TX = cast<TemplateSpecializationType>(X),
@@ -14197,6 +14237,7 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
auto As = getCommonTemplateArguments(Ctx, TX->template_arguments(),
TY->template_arguments());
return Ctx.getTemplateSpecializationType(
+ getCommonTypeKeyword(TX, TY, /*IsSame=*/false),
::getCommonTemplateNameChecked(Ctx, TX->getTemplateName(),
TY->getTemplateName(),
/*IgnoreDeduced=*/true),
@@ -14224,7 +14265,7 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
*NY = cast<DependentNameType>(Y);
assert(NX->getIdentifier() == NY->getIdentifier());
return Ctx.getDependentNameType(
- getCommonTypeKeyword(NX, NY),
+ getCommonTypeKeyword(NX, NY, /*IsSame=*/true),
getCommonQualifier(Ctx, NX, NY, /*IsSame=*/true), NX->getIdentifier());
}
case Type::DependentTemplateSpecialization: {
@@ -14240,7 +14281,7 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
/*IsSame=*/true),
SX.getName(), SX.hasTemplateKeyword() || SY.hasTemplateKeyword());
return Ctx.getDependentTemplateSpecializationType(
- getCommonTypeKeyword(TX, TY), Name, As);
+ getCommonTypeKeyword(TX, TY, /*IsSame=*/true), Name, As);
}
case Type::UnaryTransform: {
const auto *TX = cast<UnaryTransformType>(X),
@@ -14281,7 +14322,7 @@ static QualType getCommonNonSugarTypeNode(ASTContext &Ctx, const Type *X,
llvm_unreachable("Unknown Type Class");
}
-static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
+static QualType getCommonSugarTypeNode(const ASTContext &Ctx, const Type *X,
const Type *Y,
SplitQualType Underlying) {
Type::TypeClass TC = X->getTypeClass();
@@ -14296,6 +14337,8 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
#include "clang/AST/TypeNodes.inc"
#define CANONICAL_TYPE(Class) UNEXPECTED_TYPE(Class, "canonical")
+ CANONICAL_TYPE(Record)
+ CANONICAL_TYPE(Enum)
CANONICAL_TYPE(Atomic)
CANONICAL_TYPE(BitInt)
CANONICAL_TYPE(BlockPointer)
@@ -14304,7 +14347,6 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
CANONICAL_TYPE(ConstantArray)
CANONICAL_TYPE(ArrayParameter)
CANONICAL_TYPE(ConstantMatrix)
- CANONICAL_TYPE(Enum)
CANONICAL_TYPE(ExtVector)
CANONICAL_TYPE(FunctionNoProto)
CANONICAL_TYPE(FunctionProto)
@@ -14317,7 +14359,6 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
CANONICAL_TYPE(ObjCObjectPointer)
CANONICAL_TYPE(Pipe)
CANONICAL_TYPE(Pointer)
- CANONICAL_TYPE(Record)
CANONICAL_TYPE(RValueReference)
CANONICAL_TYPE(VariableArray)
CANONICAL_TYPE(Vector)
@@ -14393,15 +14434,6 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
case Type::DeducedTemplateSpecialization:
// FIXME: Try to merge these.
return QualType();
-
- case Type::Elaborated: {
- const auto *EX = cast<ElaboratedType>(X), *EY = cast<ElaboratedType>(Y);
- return Ctx.getElaboratedType(
- ::getCommonTypeKeyword(EX, EY),
- ::getCommonQualifier(Ctx, EX, EY, /*IsSame=*/false),
- Ctx.getQualifiedType(Underlying),
- ::getCommonDecl(EX->getOwnedTagDecl(), EY->getOwnedTagDecl()));
- }
case Type::MacroQualified: {
const auto *MX = cast<MacroQualifiedType>(X),
*MY = cast<MacroQualifiedType>(Y);
@@ -14445,16 +14477,19 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
if (getCommonTemplateArguments(Ctx, As, TX->template_arguments(),
TY->template_arguments()))
return QualType();
- return Ctx.getTemplateSpecializationType(CTN, As,
- /*CanonicalArgs=*/{},
- Ctx.getQualifiedType(Underlying));
+ return Ctx.getTemplateSpecializationType(
+ getCommonTypeKeyword(TX, TY, /*IsSame=*/false), CTN, As,
+ /*CanonicalArgs=*/{}, Ctx.getQualifiedType(Underlying));
}
case Type::Typedef: {
const auto *TX = cast<TypedefType>(X), *TY = cast<TypedefType>(Y);
const TypedefNameDecl *CD = ::getCommonDecl(TX->getDecl(), TY->getDecl());
if (!CD)
return QualType();
- return Ctx.getTypedefType(CD, Ctx.getQualifiedType(Underlying));
+ return Ctx.getTypedefType(
+ ::getCommonTypeKeyword(TX, TY, /*IsSame=*/false),
+ ::getCommonQualifier(Ctx, TX, TY, /*IsSame=*/false), CD,
+ Ctx.getQualifiedType(Underlying));
}
case Type::TypeOf: {
// The common sugar between two typeof expressions, where one is
@@ -14485,11 +14520,12 @@ static QualType getCommonSugarTypeNode(ASTContext &Ctx, const Type *X,
}
case Type::Using: {
const auto *UX = cast<UsingType>(X), *UY = cast<UsingType>(Y);
- const UsingShadowDecl *CD =
- ::getCommonDecl(UX->getFoundDecl(), UY->getFoundDecl());
+ const UsingShadowDecl *CD = ::getCommonDecl(UX->getDecl(), UY->getDecl());
if (!CD)
return QualType();
- return Ctx.getUsingType(CD, Ctx.getQualifiedType(Underlying));
+ return Ctx.getUsingType(::getCommonTypeKeyword(UX, UY, /*IsSame=*/false),
+ ::getCommonQualifier(Ctx, UX, UY, /*IsSame=*/false),
+ CD, Ctx.getQualifiedType(Underlying));
}
case Type::MemberPointer: {
const auto *PX = cast<MemberPointerType>(X),
@@ -14544,7 +14580,7 @@ static auto unwrapSugar(SplitQualType &T, Qualifiers &QTotal) {
}
QualType ASTContext::getCommonSugaredType(QualType X, QualType Y,
- bool Unqualified) {
+ bool Unqualified) const {
assert(Unqualified ? hasSameUnqualifiedType(X, Y) : hasSameType(X, Y));
if (X == Y)
return X;
diff --git a/clang/lib/AST/ASTDiagnostic.cpp b/clang/lib/AST/ASTDiagnostic.cpp
index 0fa9234159f22..830e34b00d88e 100644
--- a/clang/lib/AST/ASTDiagnostic.cpp
+++ b/clang/lib/AST/ASTDiagnostic.cpp
@@ -36,11 +36,6 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
while (true) {
const Type *Ty = QC.strip(QT);
- // Don't aka just because we saw an elaborated type...
- if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Ty)) {
- QT = ET->desugar();
- continue;
- }
// ... or a using type ...
if (const UsingType *UT = dyn_cast<UsingType>(Ty)) {
QT = UT->desugar();
@@ -130,7 +125,8 @@ QualType clang::desugarForDiagnostic(ASTContext &Context, QualType QT,
if (DesugarArgument) {
ShouldAKA = true;
QT = Context.getTemplateSpecializationType(
- TST->getTemplateName(), Args, /*CanonicalArgs=*/{}, QT);
+ TST->getKeyword(), TST->getTemplateName(), Args,
+ /*CanonicalArgs=*/{}, QT);
}
break;
}
@@ -200,7 +196,8 @@ break; \
// Don't desugar through the primary typedef of an anonymous type.
if (const TagType *UTT = Underlying->getAs<TagType>())
if (const TypedefType *QTT = dyn_cast<TypedefType>(QT))
- if (UTT->getDecl()->getTypedefNameForAnonDecl() == QTT->getDecl())
+ if (UTT->getOriginalDecl()->getTypedefNameForAnonDecl() ==
+ QTT->getDecl())
break;
// Record that we actually looked through an opaque type here.
@@ -461,13 +458,12 @@ void clang::FormatASTNodeDiagnosticArgument(
ND->getNameForDiagnostic(OS, Context.getPrintingPolicy(), Qualified);
break;
}
- case DiagnosticsEngine::ak_nestednamespec: {
- NestedNameSpecifier *NNS = reinterpret_cast<NestedNameSpecifier*>(Val);
- NNS->print(OS, Context.getPrintingPolicy(),
+ case DiagnosticsEngine::ak_nestednamespec:
+ NestedNameSpecifier::getFromVoidPointer(reinterpret_cast<void *>(Val))
+ .print(OS, Context.getPrintingPolicy(),
/*ResolveTemplateArguments=*/false,
/*PrintFinalScopeResOp=*/false);
break;
- }
case DiagnosticsEngine::ak_declcontext: {
DeclContext *DC = reinterpret_cast<DeclContext *> (Val);
assert(DC && "Should never have a null declaration context");
@@ -484,9 +480,8 @@ void clang::FormatASTNodeDiagnosticArgument(
} else if (isLambdaCallOperator(DC)) {
OS << "lambda expression";
} else if (TypeDecl *Type = dyn_cast<TypeDecl>(DC)) {
- OS << ConvertTypeToDiagnosticString(Context,
- Context.getTypeDeclType(Type),
- PrevArgs, QualTypeVals);
+ OS << ConvertTypeToDiagnosticString(
+ Context, Context.getTypeDeclType(Type), PrevArgs, QualTypeVals);
} else {
assert(isa<NamedDecl>(DC) && "Expected a NamedDecl");
NamedDecl *ND = cast<NamedDecl>(DC);
@@ -1158,12 +1153,13 @@ class TemplateDiff {
return nullptr;
const ClassTemplateSpecializationDecl *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
if (!CTSD)
return nullptr;
Ty = Context.getTemplateSpecializationType(
+ ElaboratedTypeKeyword::None,
TemplateName(CTSD->getSpecializedTemplate()),
CTSD->getTemplateArgs().asArray(), /*CanonicalArgs=*/{},
Ty.getLocalUnqualifiedType().getCanonicalType());
@@ -1743,25 +1739,10 @@ class TemplateDiff {
std::string FromTypeStr = FromType.isNull() ? "(no argument)"
: FromType.getAsString(Policy);
- std::string ToTypeStr = ToType.isNull() ? "(no argument)"
- : ToType.getAsString(Policy);
- // Print without ElaboratedType sugar if it is better.
+ std::string ToTypeStr =
+ ToType.isNull() ? "(no argument)" : ToType.getAsString(Policy);
// TODO: merge this with other aka printing above.
if (FromTypeStr == ToTypeStr) {
- const auto *FromElTy = dyn_cast<ElaboratedType>(FromType),
- *ToElTy = dyn_cast<ElaboratedType>(ToType);
- if (FromElTy || ToElTy) {
- std::string FromNamedTypeStr =
- FromElTy ? FromElTy->getNamedType().getAsString(Policy)
- : FromTypeStr;
- std::string ToNamedTypeStr =
- ToElTy ? ToElTy->getNamedType().getAsString(Policy) : ToTypeStr;
- if (FromNamedTypeStr != ToNamedTypeStr) {
- FromTypeStr = FromNamedTypeStr;
- ToTypeStr = ToNamedTypeStr;
- goto PrintTypes;
- }
- }
// Switch to canonical typename if it is better.
std::string FromCanTypeStr =
FromType.getCanonicalType().getAsString(Policy);
@@ -1772,8 +1753,8 @@ class TemplateDiff {
}
}
- PrintTypes:
- if (PrintTree) OS << '[';
+ if (PrintTree)
+ OS << '[';
OS << (FromDefault ? "(default) " : "");
Bold();
OS << FromTypeStr;
diff --git a/clang/lib/AST/ASTDumper.cpp b/clang/lib/AST/ASTDumper.cpp
index 5e4487e0687d3..8e651a0a68629 100644
--- a/clang/lib/AST/ASTDumper.cpp
+++ b/clang/lib/AST/ASTDumper.cpp
@@ -117,7 +117,9 @@ void ASTDumper::dumpTemplateDeclSpecialization(const SpecializationDecl *D,
// FIXME: The redecls() range sometimes has elements of a less-specific
// type. (In particular, ClassTemplateSpecializationDecl::redecls() gives
// us TagDecls, and should give CXXRecordDecls).
- auto *Redecl = cast<SpecializationDecl>(RedeclWithBadType);
+ auto *Redecl = dyn_cast<SpecializationDecl>(RedeclWithBadType);
+ if (!Redecl)
+ continue;
switch (Redecl->getTemplateSpecializationKind()) {
case TSK_ExplicitInstantiationDeclaration:
case TSK_ExplicitInstantiationDefinition:
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 90d309e49b264..cd9af82358960 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -933,8 +933,10 @@ ASTNodeImporter::import(const TemplateArgumentLoc &TALoc) {
else
return TSIOrErr.takeError();
} else {
- auto ToTemplateQualifierLocOrErr =
- import(FromInfo.getTemplateQualifierLoc());
+ auto ToTemplateKWLocOrErr = import(FromInfo.getTemplateKwLoc());
+ if (!ToTemplateKWLocOrErr)
+ return ToTemplateKWLocOrErr.takeError();
+ auto ToTemplateQualifierLocOrErr = import(TALoc.getTemplateQualifierLoc());
if (!ToTemplateQualifierLocOrErr)
return ToTemplateQualifierLocOrErr.takeError();
auto ToTemplateNameLocOrErr = import(FromInfo.getTemplateNameLoc());
@@ -945,8 +947,9 @@ ASTNodeImporter::import(const TemplateArgumentLoc &TALoc) {
if (!ToTemplateEllipsisLocOrErr)
return ToTemplateEllipsisLocOrErr.takeError();
ToInfo = TemplateArgumentLocInfo(
- Importer.getToContext(), *ToTemplateQualifierLocOrErr,
- *ToTemplateNameLocOrErr, *ToTemplateEllipsisLocOrErr);
+ Importer.getToContext(), *ToTemplateKWLocOrErr,
+ *ToTemplateQualifierLocOrErr, *ToTemplateNameLocOrErr,
+ *ToTemplateEllipsisLocOrErr);
}
return TemplateArgumentLoc(Arg, ToInfo);
@@ -1410,13 +1413,15 @@ ASTNodeImporter::VisitFunctionProtoType(const FunctionProtoType *T) {
ExpectedType ASTNodeImporter::VisitUnresolvedUsingType(
const UnresolvedUsingType *T) {
Error Err = Error::success();
- auto ToD = importChecked(Err, T->getDecl());
- auto ToPrevD = importChecked(Err, T->getDecl()->getPreviousDecl());
+ auto ToQualifier = importChecked(Err, T->getQualifier());
+ auto *ToD = importChecked(Err, T->getDecl());
if (Err)
return std::move(Err);
- return Importer.getToContext().getTypeDeclType(
- ToD, cast_or_null<TypeDecl>(ToPrevD));
+ if (T->isCanonicalUnqualified())
+ return Importer.getToContext().getCanonicalUnresolvedUsingType(ToD);
+ return Importer.getToContext().getUnresolvedUsingType(T->getKeyword(),
+ ToQualifier, ToD);
}
ExpectedType ASTNodeImporter::VisitParenType(const ParenType *T) {
@@ -1444,15 +1449,17 @@ ExpectedType ASTNodeImporter::VisitTypedefType(const TypedefType *T) {
if (!ToDeclOrErr)
return ToDeclOrErr.takeError();
- TypedefNameDecl *ToDecl = *ToDeclOrErr;
- if (ToDecl->getTypeForDecl())
- return QualType(ToDecl->getTypeForDecl(), 0);
+ auto ToQualifierOrErr = import(T->getQualifier());
+ if (!ToQualifierOrErr)
+ return ToQualifierOrErr.takeError();
- ExpectedType ToUnderlyingTypeOrErr = import(T->desugar());
+ ExpectedType ToUnderlyingTypeOrErr =
+ T->typeMatchesDecl() ? QualType() : import(T->desugar());
if (!ToUnderlyingTypeOrErr)
return ToUnderlyingTypeOrErr.takeError();
- return Importer.getToContext().getTypedefType(ToDecl, *ToUnderlyingTypeOrErr);
+ return Importer.getToContext().getTypedefType(
+ T->getKeyword(), *ToQualifierOrErr, *ToDeclOrErr, *ToUnderlyingTypeOrErr);
}
ExpectedType ASTNodeImporter::VisitTypeOfExprType(const TypeOfExprType *T) {
@@ -1471,14 +1478,14 @@ ExpectedType ASTNodeImporter::VisitTypeOfType(const TypeOfType *T) {
}
ExpectedType ASTNodeImporter::VisitUsingType(const UsingType *T) {
- Expected<UsingShadowDecl *> FoundOrErr = import(T->getFoundDecl());
- if (!FoundOrErr)
- return FoundOrErr.takeError();
- Expected<QualType> UnderlyingOrErr = import(T->getUnderlyingType());
- if (!UnderlyingOrErr)
- return UnderlyingOrErr.takeError();
-
- return Importer.getToContext().getUsingType(*FoundOrErr, *UnderlyingOrErr);
+ Error Err = Error::success();
+ auto ToQualifier = importChecked(Err, T->getQualifier());
+ auto *ToD = importChecked(Err, T->getDecl());
+ QualType ToT = importChecked(Err, T->desugar());
+ if (Err)
+ return std::move(Err);
+ return Importer.getToContext().getUsingType(T->getKeyword(), ToQualifier, ToD,
+ ToT);
}
ExpectedType ASTNodeImporter::VisitDecltypeType(const DecltypeType *T) {
@@ -1541,36 +1548,37 @@ ExpectedType ASTNodeImporter::VisitDeducedTemplateSpecializationType(
return ToDeducedTypeOrErr.takeError();
return Importer.getToContext().getDeducedTemplateSpecializationType(
- *ToTemplateNameOrErr, *ToDeducedTypeOrErr, T->isDependentType());
+ T->getKeyword(), *ToTemplateNameOrErr, *ToDeducedTypeOrErr,
+ T->isDependentType());
}
-ExpectedType ASTNodeImporter::VisitInjectedClassNameType(
- const InjectedClassNameType *T) {
- Expected<CXXRecordDecl *> ToDeclOrErr = import(T->getDecl());
+ExpectedType ASTNodeImporter::VisitTagType(const TagType *T) {
+ Expected<TagDecl *> ToDeclOrErr = import(T->getOriginalDecl());
if (!ToDeclOrErr)
return ToDeclOrErr.takeError();
- // The InjectedClassNameType is created in VisitRecordDecl when the
- // T->getDecl() is imported. Here we can return the existing type.
- const Type *Ty = (*ToDeclOrErr)->getTypeForDecl();
- assert(isa_and_nonnull<InjectedClassNameType>(Ty));
- return QualType(Ty, 0);
-}
+ if (T->isCanonicalUnqualified())
+ return Importer.getToContext().getCanonicalTagType(*ToDeclOrErr);
-ExpectedType ASTNodeImporter::VisitRecordType(const RecordType *T) {
- Expected<RecordDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
+ auto ToQualifierOrErr = import(T->getQualifier());
+ if (!ToQualifierOrErr)
+ return ToQualifierOrErr.takeError();
- return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
+ return Importer.getToContext().getTagType(T->getKeyword(), *ToQualifierOrErr,
+ *ToDeclOrErr, T->isTagOwned());
}
ExpectedType ASTNodeImporter::VisitEnumType(const EnumType *T) {
- Expected<EnumDecl *> ToDeclOrErr = import(T->getDecl());
- if (!ToDeclOrErr)
- return ToDeclOrErr.takeError();
+ return VisitTagType(T);
+}
- return Importer.getToContext().getTagDeclType(*ToDeclOrErr);
+ExpectedType ASTNodeImporter::VisitRecordType(const RecordType *T) {
+ return VisitTagType(T);
+}
+
+ExpectedType
+ASTNodeImporter::VisitInjectedClassNameType(const InjectedClassNameType *T) {
+ return VisitTagType(T);
}
ExpectedType ASTNodeImporter::VisitAttributedType(const AttributedType *T) {
@@ -1663,27 +1671,8 @@ ExpectedType ASTNodeImporter::VisitTemplateSpecializationType(
if (!ToUnderlyingOrErr)
return ToUnderlyingOrErr.takeError();
return Importer.getToContext().getTemplateSpecializationType(
- *ToTemplateOrErr, ToTemplateArgs, {}, *ToUnderlyingOrErr);
-}
-
-ExpectedType ASTNodeImporter::VisitElaboratedType(const ElaboratedType *T) {
- // Note: the qualifier in an ElaboratedType is optional.
- auto ToQualifierOrErr = import(T->getQualifier());
- if (!ToQualifierOrErr)
- return ToQualifierOrErr.takeError();
-
- ExpectedType ToNamedTypeOrErr = import(T->getNamedType());
- if (!ToNamedTypeOrErr)
- return ToNamedTypeOrErr.takeError();
-
- Expected<TagDecl *> ToOwnedTagDeclOrErr = import(T->getOwnedTagDecl());
- if (!ToOwnedTagDeclOrErr)
- return ToOwnedTagDeclOrErr.takeError();
-
- return Importer.getToContext().getElaboratedType(T->getKeyword(),
- *ToQualifierOrErr,
- *ToNamedTypeOrErr,
- *ToOwnedTagDeclOrErr);
+ T->getKeyword(), *ToTemplateOrErr, ToTemplateArgs, {},
+ *ToUnderlyingOrErr);
}
ExpectedType
@@ -1976,7 +1965,7 @@ Error ASTNodeImporter::ImportDeclParts(
const Type *LeafT =
getLeafPointeeType(P->getType().getCanonicalType().getTypePtr());
auto *RT = dyn_cast<RecordType>(LeafT);
- if (RT && RT->getDecl() == D) {
+ if (RT && RT->getOriginalDecl() == D) {
Importer.FromDiag(D->getLocation(), diag::err_unsupported_ast_node)
<< D->getDeclKindName();
return make_error<ASTImportError>(ASTImportError::UnsupportedConstruct);
@@ -2229,8 +2218,8 @@ Error ASTNodeImporter::ImportFieldDeclDefinition(const FieldDecl *From,
const RecordType *RecordTo = ToType->getAs<RecordType>();
if (RecordFrom && RecordTo) {
- FromRecordDecl = RecordFrom->getDecl();
- ToRecordDecl = RecordTo->getDecl();
+ FromRecordDecl = RecordFrom->getOriginalDecl();
+ ToRecordDecl = RecordTo->getOriginalDecl();
}
}
@@ -2451,7 +2440,7 @@ Error ASTNodeImporter::ImportDefinition(
return Err;
ExpectedType ToTypeOrErr =
- import(Importer.getFromContext().getTypeDeclType(From));
+ import(QualType(Importer.getFromContext().getCanonicalTagType(From)));
if (!ToTypeOrErr)
return ToTypeOrErr.takeError();
@@ -3026,7 +3015,7 @@ ExpectedDecl ASTNodeImporter::VisitEnumDecl(EnumDecl *D) {
if (auto *Typedef = dyn_cast<TypedefNameDecl>(FoundDecl)) {
if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
- FoundDecl = Tag->getDecl();
+ FoundDecl = Tag->getOriginalDecl();
}
if (auto *FoundEnum = dyn_cast<EnumDecl>(FoundDecl)) {
@@ -3157,7 +3146,7 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
Decl *Found = FoundDecl;
if (auto *Typedef = dyn_cast<TypedefNameDecl>(Found)) {
if (const auto *Tag = Typedef->getUnderlyingType()->getAs<TagType>())
- Found = Tag->getDecl();
+ Found = Tag->getOriginalDecl();
}
if (auto *FoundRecord = dyn_cast<RecordDecl>(Found)) {
@@ -3236,17 +3225,6 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
return CDeclOrErr.takeError();
Numbering.ContextDecl = *CDeclOrErr;
D2CXX->setLambdaNumbering(Numbering);
- } else if (DCXX->isInjectedClassName()) {
- // We have to be careful to do a similar dance to the one in
- // Sema::ActOnStartCXXMemberDeclarations
- const bool DelayTypeCreation = true;
- if (GetImportedOrCreateDecl(
- D2CXX, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, Loc, Name.getAsIdentifierInfo(),
- cast_or_null<CXXRecordDecl>(PrevDecl), DelayTypeCreation))
- return D2CXX;
- Importer.getToContext().getTypeDeclType(
- D2CXX, dyn_cast<CXXRecordDecl>(DC));
} else {
if (GetImportedOrCreateDecl(D2CXX, D, Importer.getToContext(),
D->getTagKind(), DC, *BeginLocOrErr, Loc,
@@ -3266,51 +3244,6 @@ ExpectedDecl ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
if (Error Err = importInto(ToDescribed, FromDescribed))
return std::move(Err);
D2CXX->setDescribedClassTemplate(ToDescribed);
- if (!DCXX->isInjectedClassName() && !IsFriendTemplate) {
- // In a record describing a template the type should be an
- // InjectedClassNameType (see Sema::CheckClassTemplate). Update the
- // previously set type to the correct value here (ToDescribed is not
- // available at record create).
- CXXRecordDecl *Injected = nullptr;
- for (NamedDecl *Found : D2CXX->noload_lookup(Name)) {
- auto *Record = dyn_cast<CXXRecordDecl>(Found);
- if (Record && Record->isInjectedClassName()) {
- Injected = Record;
- break;
- }
- }
- // Create an injected type for the whole redecl chain.
- // The chain may contain an already existing injected type at the start,
- // if yes this should be reused. We must ensure that only one type
- // object exists for the injected type (including the injected record
- // declaration), ASTContext does not check it.
- SmallVector<Decl *, 2> Redecls =
- getCanonicalForwardRedeclChain(D2CXX);
- const Type *FrontTy =
- cast<CXXRecordDecl>(Redecls.front())->getTypeForDecl();
- QualType InjSpec;
- if (auto *InjTy = FrontTy->getAs<InjectedClassNameType>())
- InjSpec = InjTy->getInjectedSpecializationType();
- else
- InjSpec = ToDescribed->getInjectedClassNameSpecialization();
- for (auto *R : Redecls) {
- auto *RI = cast<CXXRecordDecl>(R);
- if (R != Redecls.front() ||
- !isa<InjectedClassNameType>(RI->getTypeForDecl()))
- RI->setTypeForDecl(nullptr);
- // This function tries to get the injected type from getTypeForDecl,
- // then from the previous declaration if possible. If not, it creates
- // a new type.
- Importer.getToContext().getInjectedClassNameType(RI, InjSpec);
- }
- // Set the new type for the injected decl too.
- if (Injected) {
- Injected->setTypeForDecl(nullptr);
- // This function will copy the injected type from D2CXX into Injected.
- // The injected decl does not have a previous decl to copy from.
- Importer.getToContext().getTypeDeclType(Injected, D2CXX);
- }
- }
} else if (MemberSpecializationInfo *MemberInfo =
DCXX->getMemberSpecializationInfo()) {
TemplateSpecializationKind SK =
@@ -3634,11 +3567,12 @@ class IsTypeDeclaredInsideVisitor
}
std::optional<bool> VisitTagType(const TagType *T) {
- if (auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(T->getDecl()))
+ if (auto *Spec =
+ dyn_cast<ClassTemplateSpecializationDecl>(T->getOriginalDecl()))
for (const auto &Arg : Spec->getTemplateArgs().asArray())
if (checkTemplateArgument(Arg))
return true;
- return isAncestorDeclContextOf(ParentDC, T->getDecl());
+ return isAncestorDeclContextOf(ParentDC, T->getOriginalDecl());
}
std::optional<bool> VisitPointerType(const PointerType *T) {
@@ -3650,17 +3584,11 @@ class IsTypeDeclaredInsideVisitor
}
std::optional<bool> VisitTypedefType(const TypedefType *T) {
- const TypedefNameDecl *TD = T->getDecl();
- assert(TD);
- return isAncestorDeclContextOf(ParentDC, TD);
+ return isAncestorDeclContextOf(ParentDC, T->getDecl());
}
std::optional<bool> VisitUsingType(const UsingType *T) {
- if (T->getFoundDecl() &&
- isAncestorDeclContextOf(ParentDC, T->getFoundDecl()))
- return true;
-
- return {};
+ return isAncestorDeclContextOf(ParentDC, T->getDecl());
}
std::optional<bool>
@@ -6329,16 +6257,10 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
// Create the specialization.
ClassTemplateSpecializationDecl *D2 = nullptr;
if (PartialSpec) {
- QualType CanonInjType;
- if (Error Err = importInto(
- CanonInjType, PartialSpec->getInjectedSpecializationType()))
- return std::move(Err);
- CanonInjType = CanonInjType.getCanonicalType();
-
if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
D2, D, Importer.getToContext(), D->getTagKind(), DC, *BeginLocOrErr,
*IdLocOrErr, ToTPList, ClassTemplate, ArrayRef(TemplateArgs),
- CanonInjType,
+ /*CanonInjectedTST=*/CanQualType(),
cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
return D2;
@@ -9758,53 +9680,34 @@ Expected<Stmt *> ASTImporter::Import(Stmt *FromS) {
return ToSOrErr;
}
-Expected<NestedNameSpecifier *>
-ASTImporter::Import(NestedNameSpecifier *FromNNS) {
- if (!FromNNS)
- return nullptr;
-
- NestedNameSpecifier *Prefix = nullptr;
- if (Error Err = importInto(Prefix, FromNNS->getPrefix()))
- return std::move(Err);
-
- switch (FromNNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- assert(FromNNS->getAsIdentifier() && "NNS should contain identifier.");
- return NestedNameSpecifier::Create(ToContext, Prefix,
- Import(FromNNS->getAsIdentifier()));
-
- case NestedNameSpecifier::Namespace:
- if (ExpectedDecl NSOrErr = Import(FromNNS->getAsNamespace())) {
- return NestedNameSpecifier::Create(ToContext, Prefix,
- cast<NamespaceDecl>(*NSOrErr));
- } else
+Expected<NestedNameSpecifier> ASTImporter::Import(NestedNameSpecifier FromNNS) {
+ switch (FromNNS.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ return FromNNS;
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = FromNNS.getAsNamespaceAndPrefix();
+ auto NSOrErr = Import(Namespace);
+ if (!NSOrErr)
return NSOrErr.takeError();
-
- case NestedNameSpecifier::NamespaceAlias:
- if (ExpectedDecl NSADOrErr = Import(FromNNS->getAsNamespaceAlias()))
- return NestedNameSpecifier::Create(ToContext, Prefix,
- cast<NamespaceAliasDecl>(*NSADOrErr));
- else
- return NSADOrErr.takeError();
-
- case NestedNameSpecifier::Global:
- return NestedNameSpecifier::GlobalSpecifier(ToContext);
-
- case NestedNameSpecifier::Super:
- if (ExpectedDecl RDOrErr = Import(FromNNS->getAsRecordDecl()))
- return NestedNameSpecifier::SuperSpecifier(ToContext,
- cast<CXXRecordDecl>(*RDOrErr));
+ auto PrefixOrErr = Import(Prefix);
+ if (!PrefixOrErr)
+ return PrefixOrErr.takeError();
+ return NestedNameSpecifier(ToContext, cast<NamespaceBaseDecl>(*NSOrErr),
+ Prefix);
+ }
+ case NestedNameSpecifier::Kind::Super:
+ if (ExpectedDecl RDOrErr = Import(FromNNS.getAsSuper()))
+ return NestedNameSpecifier(cast<CXXRecordDecl>(*RDOrErr));
else
return RDOrErr.takeError();
-
- case NestedNameSpecifier::TypeSpec:
- if (ExpectedTypePtr TyOrErr = Import(FromNNS->getAsType())) {
- return NestedNameSpecifier::Create(ToContext, Prefix, *TyOrErr);
+ case NestedNameSpecifier::Kind::Type:
+ if (ExpectedTypePtr TyOrErr = Import(FromNNS.getAsType())) {
+ return NestedNameSpecifier(*TyOrErr);
} else {
return TyOrErr.takeError();
}
}
-
llvm_unreachable("Invalid nested name specifier kind");
}
@@ -9818,69 +9721,62 @@ ASTImporter::Import(NestedNameSpecifierLoc FromNNS) {
// serialization in reverse order.
while (NNS) {
NestedNames.push_back(NNS);
- NNS = NNS.getPrefix();
+ NNS = NNS.getAsNamespaceAndPrefix().Prefix;
}
NestedNameSpecifierLocBuilder Builder;
while (!NestedNames.empty()) {
NNS = NestedNames.pop_back_val();
- NestedNameSpecifier *Spec = nullptr;
+ NestedNameSpecifier Spec = std::nullopt;
if (Error Err = importInto(Spec, NNS.getNestedNameSpecifier()))
return std::move(Err);
- NestedNameSpecifier::SpecifierKind Kind = Spec->getKind();
+ NestedNameSpecifier::Kind Kind = Spec.getKind();
SourceLocation ToLocalBeginLoc, ToLocalEndLoc;
- if (Kind != NestedNameSpecifier::Super) {
+ if (Kind != NestedNameSpecifier::Kind::Super) {
if (Error Err = importInto(ToLocalBeginLoc, NNS.getLocalBeginLoc()))
return std::move(Err);
- if (Kind != NestedNameSpecifier::Global)
+ if (Kind != NestedNameSpecifier::Kind::Global)
if (Error Err = importInto(ToLocalEndLoc, NNS.getLocalEndLoc()))
return std::move(Err);
}
switch (Kind) {
- case NestedNameSpecifier::Identifier:
- Builder.Extend(getToContext(), Spec->getAsIdentifier(), ToLocalBeginLoc,
- ToLocalEndLoc);
- break;
-
- case NestedNameSpecifier::Namespace:
- Builder.Extend(getToContext(), Spec->getAsNamespace(), ToLocalBeginLoc,
- ToLocalEndLoc);
- break;
-
- case NestedNameSpecifier::NamespaceAlias:
- Builder.Extend(getToContext(), Spec->getAsNamespaceAlias(),
+ case NestedNameSpecifier::Kind::Namespace:
+ Builder.Extend(getToContext(), Spec.getAsNamespaceAndPrefix().Namespace,
ToLocalBeginLoc, ToLocalEndLoc);
break;
- case NestedNameSpecifier::TypeSpec: {
+ case NestedNameSpecifier::Kind::Type: {
SourceLocation ToTLoc;
- if (Error Err = importInto(ToTLoc, NNS.getTypeLoc().getBeginLoc()))
+ if (Error Err = importInto(ToTLoc, NNS.castAsTypeLoc().getBeginLoc()))
return std::move(Err);
TypeSourceInfo *TSI = getToContext().getTrivialTypeSourceInfo(
- QualType(Spec->getAsType(), 0), ToTLoc);
- Builder.Extend(getToContext(), TSI->getTypeLoc(), ToLocalEndLoc);
+ QualType(Spec.getAsType(), 0), ToTLoc);
+ Builder.Make(getToContext(), TSI->getTypeLoc(), ToLocalEndLoc);
break;
}
- case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Kind::Global:
Builder.MakeGlobal(getToContext(), ToLocalBeginLoc);
break;
- case NestedNameSpecifier::Super: {
+ case NestedNameSpecifier::Kind::Super: {
auto ToSourceRangeOrErr = Import(NNS.getSourceRange());
if (!ToSourceRangeOrErr)
return ToSourceRangeOrErr.takeError();
- Builder.MakeSuper(getToContext(), Spec->getAsRecordDecl(),
+ Builder.MakeSuper(getToContext(), Spec.getAsSuper(),
ToSourceRangeOrErr->getBegin(),
ToSourceRangeOrErr->getEnd());
+ break;
+ }
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
- }
}
return Builder.getWithLocInContext(getToContext());
@@ -10460,7 +10356,7 @@ ASTNodeImporter::ImportAPValue(const APValue &FromValue) {
if (Err)
return std::move(Err);
if (auto *RD = dyn_cast<CXXRecordDecl>(FromDecl))
- FromElemTy = Importer.FromContext.getRecordType(RD);
+ FromElemTy = Importer.FromContext.getCanonicalTagType(RD);
else
FromElemTy = cast<ValueDecl>(FromDecl)->getType();
ToPath[LoopIdx] = APValue::LValuePathEntry(APValue::BaseOrMemberType(
diff --git a/clang/lib/AST/ASTImporterLookupTable.cpp b/clang/lib/AST/ASTImporterLookupTable.cpp
index 4ed3198d7ea62..29c3af1703b4f 100644
--- a/clang/lib/AST/ASTImporterLookupTable.cpp
+++ b/clang/lib/AST/ASTImporterLookupTable.cpp
@@ -49,8 +49,6 @@ struct Builder : RecursiveASTVisitor<Builder> {
bool VisitFriendDecl(FriendDecl *D) {
if (D->getFriendType()) {
QualType Ty = D->getFriendType()->getType();
- if (isa<ElaboratedType>(Ty))
- Ty = cast<ElaboratedType>(Ty)->getNamedType();
// A FriendDecl with a dependent type (e.g. ClassTemplateSpecialization)
// always has that decl as child node.
// However, there are non-dependent cases which does not have the
@@ -64,13 +62,15 @@ struct Builder : RecursiveASTVisitor<Builder> {
dyn_cast<SubstTemplateTypeParmType>(Ty)) {
if (SubstTy->getAsCXXRecordDecl())
LT.add(SubstTy->getAsCXXRecordDecl());
- } else if (isa<TypedefType>(Ty)) {
- // We do not put friend typedefs to the lookup table because
- // ASTImporter does not organize typedefs into redecl chains.
- } else if (isa<UsingType>(Ty)) {
- // Similar to TypedefType, not putting into lookup table.
} else {
- llvm_unreachable("Unhandled type of friend class");
+ if (isa<TypedefType>(Ty)) {
+ // We do not put friend typedefs to the lookup table because
+ // ASTImporter does not organize typedefs into redecl chains.
+ } else if (isa<UsingType>(Ty)) {
+ // Similar to TypedefType, not putting into lookup table.
+ } else {
+ llvm_unreachable("Unhandled type of friend class");
+ }
}
}
}
diff --git a/clang/lib/AST/ASTStructuralEquivalence.cpp b/clang/lib/AST/ASTStructuralEquivalence.cpp
index 704de8156132c..8ed7bae3dc0da 100644
--- a/clang/lib/AST/ASTStructuralEquivalence.cpp
+++ b/clang/lib/AST/ASTStructuralEquivalence.cpp
@@ -110,8 +110,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
const TemplateArgumentLoc &Arg1,
const TemplateArgumentLoc &Arg2);
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
- NestedNameSpecifier *NNS1,
- NestedNameSpecifier *NNS2);
+ NestedNameSpecifier NNS1,
+ NestedNameSpecifier NNS2);
static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
const IdentifierInfo *Name2);
@@ -577,38 +577,30 @@ static bool IsStructurallyEquivalent(const IdentifierInfo *Name1,
/// Determine whether two nested-name-specifiers are equivalent.
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
- NestedNameSpecifier *NNS1,
- NestedNameSpecifier *NNS2) {
- if (NNS1->getKind() != NNS2->getKind())
- return false;
-
- NestedNameSpecifier *Prefix1 = NNS1->getPrefix(),
- *Prefix2 = NNS2->getPrefix();
- if ((bool)Prefix1 != (bool)Prefix2)
- return false;
-
- if (Prefix1)
- if (!IsStructurallyEquivalent(Context, Prefix1, Prefix2))
- return false;
-
- switch (NNS1->getKind()) {
- case NestedNameSpecifier::Identifier:
- return IsStructurallyEquivalent(NNS1->getAsIdentifier(),
- NNS2->getAsIdentifier());
- case NestedNameSpecifier::Namespace:
- return IsStructurallyEquivalent(Context, NNS1->getAsNamespace(),
- NNS2->getAsNamespace());
- case NestedNameSpecifier::NamespaceAlias:
- return IsStructurallyEquivalent(Context, NNS1->getAsNamespaceAlias(),
- NNS2->getAsNamespaceAlias());
- case NestedNameSpecifier::TypeSpec:
- return IsStructurallyEquivalent(Context, QualType(NNS1->getAsType(), 0),
- QualType(NNS2->getAsType(), 0));
- case NestedNameSpecifier::Global:
+ NestedNameSpecifier NNS1,
+ NestedNameSpecifier NNS2) {
+ auto Kind = NNS1.getKind();
+ if (Kind != NNS2.getKind())
+ return false;
+ switch (Kind) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
return true;
- case NestedNameSpecifier::Super:
- return IsStructurallyEquivalent(Context, NNS1->getAsRecordDecl(),
- NNS2->getAsRecordDecl());
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace1, Prefix1] = NNS1.getAsNamespaceAndPrefix();
+ auto [Namespace2, Prefix2] = NNS2.getAsNamespaceAndPrefix();
+ if (!IsStructurallyEquivalent(Context,
+ const_cast<NamespaceBaseDecl *>(Namespace1),
+ const_cast<NamespaceBaseDecl *>(Namespace2)))
+ return false;
+ return IsStructurallyEquivalent(Context, Prefix1, Prefix2);
+ }
+ case NestedNameSpecifier::Kind::Type:
+ return IsStructurallyEquivalent(Context, QualType(NNS1.getAsType(), 0),
+ QualType(NNS2.getAsType(), 0));
+ case NestedNameSpecifier::Kind::Super:
+ return IsStructurallyEquivalent(Context, NNS1.getAsSuper(),
+ NNS2.getAsSuper());
}
return false;
}
@@ -616,9 +608,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
const DependentTemplateStorage &S1,
const DependentTemplateStorage &S2) {
- if (NestedNameSpecifier *NNS1 = S1.getQualifier(), *NNS2 = S2.getQualifier();
- !NNS1 != !NNS2 ||
- (NNS1 && !IsStructurallyEquivalent(Context, NNS1, NNS2)))
+ if (!IsStructurallyEquivalent(Context, S1.getQualifier(), S2.getQualifier()))
return false;
IdentifierOrOverloadedOperator IO1 = S1.getName(), IO2 = S2.getName();
@@ -1187,23 +1177,35 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
return false;
break;
- case Type::Using:
- if (!IsStructurallyEquivalent(Context, cast<UsingType>(T1)->getFoundDecl(),
- cast<UsingType>(T2)->getFoundDecl()))
+ case Type::Using: {
+ auto *U1 = cast<UsingType>(T1), *U2 = cast<UsingType>(T2);
+ if (U1->getKeyword() != U2->getKeyword())
return false;
- if (!IsStructurallyEquivalent(Context,
- cast<UsingType>(T1)->getUnderlyingType(),
- cast<UsingType>(T2)->getUnderlyingType()))
+ if (!IsStructurallyEquivalent(Context, U1->getQualifier(),
+ U2->getQualifier()))
+ return false;
+ if (!IsStructurallyEquivalent(Context, U1->getDecl(), U2->getDecl()))
+ return false;
+ if (!IsStructurallyEquivalent(Context, U1->desugar(), U2->desugar()))
return false;
break;
-
- case Type::Typedef:
- if (!IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->getDecl(),
- cast<TypedefType>(T2)->getDecl()) ||
- !IsStructurallyEquivalent(Context, cast<TypedefType>(T1)->desugar(),
- cast<TypedefType>(T2)->desugar()))
+ }
+ case Type::Typedef: {
+ auto *U1 = cast<TypedefType>(T1), *U2 = cast<TypedefType>(T2);
+ if (U1->getKeyword() != U2->getKeyword())
+ return false;
+ if (!IsStructurallyEquivalent(Context, U1->getQualifier(),
+ U2->getQualifier()))
+ return false;
+ if (!IsStructurallyEquivalent(Context, U1->getDecl(), U2->getDecl()))
+ return false;
+ if (U1->typeMatchesDecl() != U2->typeMatchesDecl())
+ return false;
+ if (!U1->typeMatchesDecl() &&
+ !IsStructurallyEquivalent(Context, U1->desugar(), U2->desugar()))
return false;
break;
+ }
case Type::TypeOfExpr:
if (!IsStructurallyEquivalent(
@@ -1267,10 +1269,20 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
case Type::Record:
case Type::Enum:
- if (!IsStructurallyEquivalent(Context, cast<TagType>(T1)->getDecl(),
- cast<TagType>(T2)->getDecl()))
+ case Type::InjectedClassName: {
+ const auto *TT1 = cast<TagType>(T1), *TT2 = cast<TagType>(T2);
+ if (TT1->getKeyword() != TT2->getKeyword())
+ return false;
+ if (TT1->isTagOwned() != TT2->isTagOwned())
+ return false;
+ if (!IsStructurallyEquivalent(Context, TT1->getQualifier(),
+ TT2->getQualifier()))
+ return false;
+ if (!IsStructurallyEquivalent(Context, TT1->getOriginalDecl(),
+ TT2->getOriginalDecl()))
return false;
break;
+ }
case Type::TemplateTypeParm: {
const auto *Parm1 = cast<TemplateTypeParmType>(T1);
@@ -1329,33 +1341,6 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
break;
}
- case Type::Elaborated: {
- const auto *Elab1 = cast<ElaboratedType>(T1);
- const auto *Elab2 = cast<ElaboratedType>(T2);
- // CHECKME: what if a keyword is ElaboratedTypeKeyword::None or
- // ElaboratedTypeKeyword::Typename
- // ?
- if (Elab1->getKeyword() != Elab2->getKeyword())
- return false;
- if (!IsStructurallyEquivalent(Context, Elab1->getQualifier(),
- Elab2->getQualifier()))
- return false;
- if (!IsStructurallyEquivalent(Context, Elab1->getNamedType(),
- Elab2->getNamedType()))
- return false;
- break;
- }
-
- case Type::InjectedClassName: {
- const auto *Inj1 = cast<InjectedClassNameType>(T1);
- const auto *Inj2 = cast<InjectedClassNameType>(T2);
- if (!IsStructurallyEquivalent(Context,
- Inj1->getInjectedSpecializationType(),
- Inj2->getInjectedSpecializationType()))
- return false;
- break;
- }
-
case Type::DependentName: {
const auto *Typename1 = cast<DependentNameType>(T1);
const auto *Typename2 = cast<DependentNameType>(T2);
@@ -1523,8 +1508,8 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
// types
if (Field1->isAnonymousStructOrUnion() &&
Field2->isAnonymousStructOrUnion()) {
- RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getDecl();
- RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *D1 = Field1->getType()->castAs<RecordType>()->getOriginalDecl();
+ RecordDecl *D2 = Field2->getType()->castAs<RecordType>()->getOriginalDecl();
return IsStructurallyEquivalent(Context, D1, D2);
}
@@ -1602,7 +1587,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
FieldDecl *Field1, FieldDecl *Field2) {
const auto *Owner2 = cast<RecordDecl>(Field2->getDeclContext());
return IsStructurallyEquivalent(Context, Field1, Field2,
- Context.ToCtx.getTypeDeclType(Owner2));
+ Context.ToCtx.getCanonicalTagType(Owner2));
}
/// Determine structural equivalence of two methods.
@@ -1770,7 +1755,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Context.Complain) {
Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag1(D1->getLocation(), diag::note_odr_tag_kind_here)
<< D1->getDeclName() << (unsigned)D1->getTagKind();
@@ -1872,7 +1857,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag2(D2->getLocation(), diag::note_odr_number_of_bases)
<< D2CXX->getNumBases();
@@ -1893,7 +1878,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag2(Base2->getBeginLoc(), diag::note_odr_base)
<< Base2->getType() << Base2->getSourceRange();
@@ -1909,7 +1894,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag2(Base2->getBeginLoc(), diag::note_odr_virtual_base)
<< Base2->isVirtual() << Base2->getSourceRange();
@@ -1931,7 +1916,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2CXX)
+ << Context.ToCtx.getCanonicalTagType(D2CXX)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
Context.Diag2(D2->getLocation(), diag::note_odr_missing_friend);
@@ -1944,7 +1929,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2CXX)
+ << Context.ToCtx.getCanonicalTagType(D2CXX)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag1((*Friend1)->getFriendLoc(), diag::note_odr_friend);
Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
@@ -1958,7 +1943,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag2((*Friend2)->getFriendLoc(), diag::note_odr_friend);
Context.Diag1(D1->getLocation(), diag::note_odr_missing_friend);
@@ -1970,7 +1955,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
const CXXBaseSpecifier *Base1 = D1CXX->bases_begin();
Context.Diag1(Base1->getBeginLoc(), diag::note_odr_base)
@@ -1982,7 +1967,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
}
// Check the fields for consistency.
- QualType D2Type = Context.ToCtx.getTypeDeclType(D2);
+ CanQualType D2Type = Context.ToCtx.getCanonicalTagType(D2);
RecordDecl::field_iterator Field2 = D2->field_begin(),
Field2End = D2->field_end();
for (RecordDecl::field_iterator Field1 = D1->field_begin(),
@@ -1993,7 +1978,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag1(Field1->getLocation(), diag::note_odr_field)
<< Field1->getDeclName() << Field1->getType();
@@ -2010,7 +1995,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Context.Complain) {
Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag2(Field2->getLocation(), diag::note_odr_field)
<< Field2->getDeclName() << Field2->getType();
@@ -2089,7 +2074,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag1((*EC1)->getLocation(), diag::note_odr_enumerator)
<< (*EC1)->getDeclName() << toString((*EC1)->getInitVal(), 10);
@@ -2107,7 +2092,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
Context.Diag2(D2->getLocation(),
Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag2((*EC2)->getLocation(), diag::note_odr_enumerator)
<< (*EC2)->getDeclName() << toString((*EC2)->getInitVal(), 10);
@@ -2125,7 +2110,7 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (Context.Complain) {
Context.Diag2(D2->getLocation(), Context.getApplicableDiagnostic(
diag::err_odr_tag_type_inconsistent))
- << Context.ToCtx.getTypeDeclType(D2)
+ << Context.ToCtx.getCanonicalTagType(D2)
<< (&Context.FromCtx != &Context.ToCtx);
Context.Diag2((*EC2)->getLocation(), diag::note_odr_enumerator)
<< (*EC2)->getDeclName() << toString((*EC2)->getInitVal(), 10);
@@ -2521,7 +2506,7 @@ DiagnosticBuilder StructuralEquivalenceContext::Diag2(SourceLocation Loc,
UnsignedOrNone
StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
ASTContext &Context = Anon->getASTContext();
- QualType AnonTy = Context.getRecordType(Anon);
+ CanQualType AnonTy = Context.getCanonicalTagType(Anon);
const auto *Owner = dyn_cast<RecordDecl>(Anon->getDeclContext());
if (!Owner)
@@ -2543,12 +2528,8 @@ StructuralEquivalenceContext::findUntaggedStructOrUnionIndex(RecordDecl *Anon) {
// If the field looks like this:
// struct { ... } A;
QualType FieldType = F->getType();
- // In case of nested structs.
- while (const auto *ElabType = dyn_cast<ElaboratedType>(FieldType))
- FieldType = ElabType->getNamedType();
-
if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {
- const RecordDecl *RecDecl = RecType->getDecl();
+ const RecordDecl *RecDecl = RecType->getOriginalDecl();
if (RecDecl->getDeclContext() == Owner && !RecDecl->getIdentifier()) {
if (Context.hasSameType(FieldType, AnonTy))
break;
diff --git a/clang/lib/AST/ASTTypeTraits.cpp b/clang/lib/AST/ASTTypeTraits.cpp
index 99916f523aa95..d2f7fdbbad04d 100644
--- a/clang/lib/AST/ASTTypeTraits.cpp
+++ b/clang/lib/AST/ASTTypeTraits.cpp
@@ -194,8 +194,8 @@ void DynTypedNode::print(llvm::raw_ostream &OS,
else if (const NestedNameSpecifier *NNS = get<NestedNameSpecifier>())
NNS->print(OS, PP);
else if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>()) {
- if (const NestedNameSpecifier *NNS = NNSL->getNestedNameSpecifier())
- NNS->print(OS, PP);
+ if (NestedNameSpecifier NNS = NNSL->getNestedNameSpecifier())
+ NNS.print(OS, PP);
else
OS << "(empty NestedNameSpecifierLoc)";
} else if (const QualType *QT = get<QualType>())
@@ -234,13 +234,39 @@ void DynTypedNode::dump(llvm::raw_ostream &OS,
OS << "Unable to dump values of type " << NodeKind.asStringRef() << "\n";
}
-SourceRange DynTypedNode::getSourceRange() const {
+SourceRange DynTypedNode::getSourceRange(bool IncludeQualifier) const {
if (const CXXCtorInitializer *CCI = get<CXXCtorInitializer>())
return CCI->getSourceRange();
if (const NestedNameSpecifierLoc *NNSL = get<NestedNameSpecifierLoc>())
return NNSL->getSourceRange();
- if (const TypeLoc *TL = get<TypeLoc>())
- return TL->getSourceRange();
+ if (const TypeLoc *TL = get<TypeLoc>()) {
+ if (IncludeQualifier)
+ return TL->getSourceRange();
+ switch (TL->getTypeLocClass()) {
+ case TypeLoc::DependentName:
+ return TL->castAs<DependentNameTypeLoc>().getNameLoc();
+ case TypeLoc::TemplateSpecialization: {
+ auto T = TL->castAs<TemplateSpecializationTypeLoc>();
+ return SourceRange(T.getTemplateNameLoc(), T.getEndLoc());
+ }
+ case TypeLoc::DependentTemplateSpecialization: {
+ auto T = TL->castAs<DependentTemplateSpecializationTypeLoc>();
+ return SourceRange(T.getTemplateNameLoc(), T.getEndLoc());
+ }
+ case TypeLoc::Enum:
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName:
+ return TL->castAs<TagTypeLoc>().getNameLoc();
+ case TypeLoc::Typedef:
+ return TL->castAs<TypedefTypeLoc>().getNameLoc();
+ case TypeLoc::UnresolvedUsing:
+ return TL->castAs<UnresolvedUsingTypeLoc>().getNameLoc();
+ case TypeLoc::Using:
+ return TL->castAs<UsingTypeLoc>().getNameLoc();
+ default:
+ return TL->getSourceRange();
+ }
+ }
if (const Decl *D = get<Decl>())
return D->getSourceRange();
if (const Stmt *S = get<Stmt>())
diff --git a/clang/lib/AST/ByteCode/Compiler.cpp b/clang/lib/AST/ByteCode/Compiler.cpp
index ee9c3890794af..10cd8a7e6c73a 100644
--- a/clang/lib/AST/ByteCode/Compiler.cpp
+++ b/clang/lib/AST/ByteCode/Compiler.cpp
@@ -509,9 +509,10 @@ bool Compiler<Emitter>::VisitCastExpr(const CastExpr *CE) {
// Possibly diagnose casts to enum types if the target type does not
// have a fixed size.
if (Ctx.getLangOpts().CPlusPlus && CE->getType()->isEnumeralType()) {
- if (const auto *ET = CE->getType().getCanonicalType()->castAs<EnumType>();
- !ET->getDecl()->isFixed()) {
- if (!this->emitCheckEnumValue(*FromT, ET->getDecl(), CE))
+ const auto *ET = CE->getType().getCanonicalType()->castAs<EnumType>();
+ const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isFixed()) {
+ if (!this->emitCheckEnumValue(*FromT, ED, CE))
return false;
}
}
@@ -4488,7 +4489,7 @@ const RecordType *Compiler<Emitter>::getRecordTy(QualType Ty) {
template <class Emitter> Record *Compiler<Emitter>::getRecord(QualType Ty) {
if (const auto *RecordTy = getRecordTy(Ty))
- return getRecord(RecordTy->getDecl());
+ return getRecord(RecordTy->getOriginalDecl()->getDefinitionOrSelf());
return nullptr;
}
diff --git a/clang/lib/AST/ByteCode/Context.cpp b/clang/lib/AST/ByteCode/Context.cpp
index a629ff9569428..f9b2e0b400525 100644
--- a/clang/lib/AST/ByteCode/Context.cpp
+++ b/clang/lib/AST/ByteCode/Context.cpp
@@ -314,7 +314,7 @@ std::optional<PrimType> Context::classify(QualType T) const {
}
if (const auto *ET = T->getAs<EnumType>()) {
- const auto *D = ET->getDecl();
+ const auto *D = ET->getOriginalDecl()->getDefinitionOrSelf();
if (!D->isComplete())
return std::nullopt;
return classify(D->getIntegerType());
diff --git a/clang/lib/AST/ByteCode/Descriptor.cpp b/clang/lib/AST/ByteCode/Descriptor.cpp
index c89eca9bef440..1f8072fbf27f6 100644
--- a/clang/lib/AST/ByteCode/Descriptor.cpp
+++ b/clang/lib/AST/ByteCode/Descriptor.cpp
@@ -427,12 +427,14 @@ QualType Descriptor::getType() const {
if (const auto *D = asValueDecl())
return D->getType();
if (const auto *T = dyn_cast_if_present<TypeDecl>(asDecl()))
- return QualType(T->getTypeForDecl(), 0);
+ return T->getASTContext().getTypeDeclType(T);
// The Source sometimes has a different type than the once
// we really save. Try to consult the Record first.
- if (isRecord())
- return QualType(ElemRecord->getDecl()->getTypeForDecl(), 0);
+ if (isRecord()) {
+ const RecordDecl *RD = ElemRecord->getDecl();
+ return RD->getASTContext().getCanonicalTagType(RD);
+ }
if (const auto *E = asExpr())
return E->getType();
llvm_unreachable("Invalid descriptor type");
diff --git a/clang/lib/AST/ByteCode/Interp.cpp b/clang/lib/AST/ByteCode/Interp.cpp
index 51cf0c59f0b50..83bee1b0f778d 100644
--- a/clang/lib/AST/ByteCode/Interp.cpp
+++ b/clang/lib/AST/ByteCode/Interp.cpp
@@ -1985,7 +1985,7 @@ bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType) {
return false;
// Pick the most-derived type.
- const Type *T = P.getDeclPtr().getType().getTypePtr();
+ CanQualType T = P.getDeclPtr().getType()->getCanonicalTypeUnqualified();
// ... unless we're currently constructing this object.
// FIXME: We have a similar check to this in more places.
if (S.Current->getFunction()) {
@@ -1993,14 +1993,14 @@ bool GetTypeidPtr(InterpState &S, CodePtr OpPC, const Type *TypeInfoType) {
if (const Function *Func = Frame->getFunction();
Func && (Func->isConstructor() || Func->isDestructor()) &&
P.block() == Frame->getThis().block()) {
- T = Func->getParentDecl()->getTypeForDecl();
+ T = S.getContext().getASTContext().getCanonicalTagType(
+ Func->getParentDecl());
break;
}
}
}
- S.Stk.push<Pointer>(T->getCanonicalTypeUnqualified().getTypePtr(),
- TypeInfoType);
+ S.Stk.push<Pointer>(T->getTypePtr(), TypeInfoType);
return true;
}
diff --git a/clang/lib/AST/ByteCode/Interp.h b/clang/lib/AST/ByteCode/Interp.h
index 85a07abb5ed01..48a5d35bcbaea 100644
--- a/clang/lib/AST/ByteCode/Interp.h
+++ b/clang/lib/AST/ByteCode/Interp.h
@@ -1743,10 +1743,7 @@ inline bool GetPtrDerivedPop(InterpState &S, CodePtr OpPC, uint32_t Off,
const Record *TargetRecord = Ptr.atFieldSub(Off).getRecord();
assert(TargetRecord);
- if (TargetRecord->getDecl()
- ->getTypeForDecl()
- ->getAsCXXRecordDecl()
- ->getCanonicalDecl() !=
+ if (TargetRecord->getDecl()->getCanonicalDecl() !=
TargetType->getAsCXXRecordDecl()->getCanonicalDecl()) {
QualType MostDerivedType = Ptr.getDeclDesc()->getType();
S.CCEDiag(S.Current->getSource(OpPC), diag::note_constexpr_invalid_downcast)
diff --git a/clang/lib/AST/ByteCode/InterpBuiltin.cpp b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
index 1fe6d146b511d..19afbf3772ab7 100644
--- a/clang/lib/AST/ByteCode/InterpBuiltin.cpp
+++ b/clang/lib/AST/ByteCode/InterpBuiltin.cpp
@@ -2660,7 +2660,7 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
const RecordType *RT = CurrentType->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isInvalidDecl())
return false;
const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
@@ -2693,7 +2693,7 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
const RecordType *RT = CurrentType->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isInvalidDecl())
return false;
const ASTRecordLayout &RL = S.getASTContext().getASTRecordLayout(RD);
@@ -2705,7 +2705,8 @@ bool InterpretOffsetOf(InterpState &S, CodePtr OpPC, const OffsetOfExpr *E,
return false;
// Add the offset to the base.
- Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl()));
+ Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(
+ BaseRT->getOriginalDecl()->getDefinitionOrSelf()));
break;
}
case OffsetOfNode::Identifier:
diff --git a/clang/lib/AST/ByteCode/InterpFrame.cpp b/clang/lib/AST/ByteCode/InterpFrame.cpp
index a5a4bd25fe712..9fde953cfab8e 100644
--- a/clang/lib/AST/ByteCode/InterpFrame.cpp
+++ b/clang/lib/AST/ByteCode/InterpFrame.cpp
@@ -159,7 +159,7 @@ void InterpFrame::describe(llvm::raw_ostream &OS) const {
} else if (const auto *M = dyn_cast<CXXMethodDecl>(F)) {
print(OS, This, S.getASTContext(),
S.getASTContext().getLValueReferenceType(
- S.getASTContext().getRecordType(M->getParent())));
+ S.getASTContext().getCanonicalTagType(M->getParent())));
OS << ".";
}
}
diff --git a/clang/lib/AST/ByteCode/Pointer.cpp b/clang/lib/AST/ByteCode/Pointer.cpp
index 6769e51a8ad00..fca52a2f382ea 100644
--- a/clang/lib/AST/ByteCode/Pointer.cpp
+++ b/clang/lib/AST/ByteCode/Pointer.cpp
@@ -666,7 +666,7 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
assert(Record && "Missing record descriptor");
bool Ok = true;
- if (RT->getDecl()->isUnion()) {
+ if (RT->getOriginalDecl()->isUnion()) {
const FieldDecl *ActiveField = nullptr;
APValue Value;
for (const auto &F : Record->fields()) {
@@ -705,14 +705,15 @@ std::optional<APValue> Pointer::toRValue(const Context &Ctx,
for (unsigned I = 0; I < NB; ++I) {
const Record::Base *BD = Record->getBase(I);
- QualType BaseTy = Ctx.getASTContext().getRecordType(BD->Decl);
+ QualType BaseTy = Ctx.getASTContext().getCanonicalTagType(BD->Decl);
const Pointer &BP = Ptr.atField(BD->Offset);
Ok &= Composite(BaseTy, BP, R.getStructBase(I));
}
for (unsigned I = 0; I < NV; ++I) {
const Record::Base *VD = Record->getVirtualBase(I);
- QualType VirtBaseTy = Ctx.getASTContext().getRecordType(VD->Decl);
+ QualType VirtBaseTy =
+ Ctx.getASTContext().getCanonicalTagType(VD->Decl);
const Pointer &VP = Ptr.atField(VD->Offset);
Ok &= Composite(VirtBaseTy, VP, R.getStructBase(NB + I));
}
diff --git a/clang/lib/AST/ByteCode/Program.cpp b/clang/lib/AST/ByteCode/Program.cpp
index 5ac0f59f32d4e..47dd6f082bc48 100644
--- a/clang/lib/AST/ByteCode/Program.cpp
+++ b/clang/lib/AST/ByteCode/Program.cpp
@@ -326,7 +326,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
const auto *RT = Spec.getType()->getAs<RecordType>();
if (!RT)
return nullptr;
- const RecordDecl *BD = RT->getDecl();
+ const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf();
const Record *BR = getOrCreateRecord(BD);
const Descriptor *Desc = GetBaseDesc(BD, BR);
@@ -343,7 +343,7 @@ Record *Program::getOrCreateRecord(const RecordDecl *RD) {
if (!RT)
return nullptr;
- const RecordDecl *BD = RT->getDecl();
+ const RecordDecl *BD = RT->getOriginalDecl()->getDefinitionOrSelf();
const Record *BR = getOrCreateRecord(BD);
const Descriptor *Desc = GetBaseDesc(BD, BR);
@@ -400,7 +400,8 @@ Descriptor *Program::createDescriptor(const DeclTy &D, const Type *Ty,
// Classes and structures.
if (const auto *RT = Ty->getAs<RecordType>()) {
- if (const auto *Record = getOrCreateRecord(RT->getDecl()))
+ if (const auto *Record =
+ getOrCreateRecord(RT->getOriginalDecl()->getDefinitionOrSelf()))
return allocateDescriptor(D, Record, MDSize, IsConst, IsTemporary,
IsMutable, IsVolatile);
return allocateDescriptor(D, MDSize);
diff --git a/clang/lib/AST/ByteCode/Record.cpp b/clang/lib/AST/ByteCode/Record.cpp
index 1d4ac7103cb76..a7934ccb4e55e 100644
--- a/clang/lib/AST/ByteCode/Record.cpp
+++ b/clang/lib/AST/ByteCode/Record.cpp
@@ -51,7 +51,7 @@ const Record::Base *Record::getBase(const RecordDecl *FD) const {
const Record::Base *Record::getBase(QualType T) const {
if (auto *RT = T->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
return BaseMap.lookup(RD);
}
return nullptr;
diff --git a/clang/lib/AST/CXXInheritance.cpp b/clang/lib/AST/CXXInheritance.cpp
index f0376168e43a2..e4b77edc063dc 100644
--- a/clang/lib/AST/CXXInheritance.cpp
+++ b/clang/lib/AST/CXXInheritance.cpp
@@ -132,8 +132,8 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches) const {
if (!Ty)
return false;
- CXXRecordDecl *Base =
- cast_if_present<CXXRecordDecl>(Ty->getDecl()->getDefinition());
+ CXXRecordDecl *Base = cast_if_present<CXXRecordDecl>(
+ Ty->getOriginalDecl()->getDefinition());
if (!Base ||
(Base->isDependentContext() &&
!Base->isCurrentInstantiation(Record))) {
@@ -256,7 +256,8 @@ bool CXXBasePaths::lookupInBases(ASTContext &Context,
BaseSpec.getType()->getAs<TemplateSpecializationType>();
if (!TST) {
if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
- BaseRecord = cast<CXXRecordDecl>(RT->getDecl());
+ BaseRecord = cast<CXXRecordDecl>(RT->getOriginalDecl())
+ ->getDefinitionOrSelf();
} else {
TemplateName TN = TST->getTemplateName();
if (auto *TD =
@@ -336,7 +337,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
CXXRecordDecl *VBase = nullptr;
if (const RecordType *Record = PE.Base->getType()->getAs<RecordType>())
- VBase = cast<CXXRecordDecl>(Record->getDecl());
+ VBase = cast<CXXRecordDecl>(Record->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!VBase)
break;
@@ -348,7 +350,8 @@ bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
CXXRecordDecl *HidingClass = nullptr;
if (const RecordType *Record =
HidingP.back().Base->getType()->getAs<RecordType>())
- HidingClass = cast<CXXRecordDecl>(Record->getDecl());
+ HidingClass = cast<CXXRecordDecl>(Record->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!HidingClass)
break;
@@ -468,7 +471,8 @@ void FinalOverriderCollector::Collect(const CXXRecordDecl *RD,
for (const auto &Base : RD->bases()) {
if (const RecordType *RT = Base.getType()->getAs<RecordType>()) {
- const CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(RT->getDecl());
+ const CXXRecordDecl *BaseDecl =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if (!BaseDecl->isPolymorphic())
continue;
diff --git a/clang/lib/AST/Comment.cpp b/clang/lib/AST/Comment.cpp
index cd73d2709dc65..37e21c340c316 100644
--- a/clang/lib/AST/Comment.cpp
+++ b/clang/lib/AST/Comment.cpp
@@ -147,8 +147,6 @@ static TypeLoc lookThroughTypedefOrTypeAliasLocs(TypeLoc &SrcTL) {
return BlockPointerTL.getPointeeLoc().getUnqualifiedLoc();
if (MemberPointerTypeLoc MemberPointerTL = TL.getAs<MemberPointerTypeLoc>())
return MemberPointerTL.getPointeeLoc().getUnqualifiedLoc();
- if (ElaboratedTypeLoc ETL = TL.getAs<ElaboratedTypeLoc>())
- return ETL.getNamedTypeLoc();
return TL;
}
diff --git a/clang/lib/AST/CommentSema.cpp b/clang/lib/AST/CommentSema.cpp
index 95f6bf79d118c..5a16621578a3e 100644
--- a/clang/lib/AST/CommentSema.cpp
+++ b/clang/lib/AST/CommentSema.cpp
@@ -902,17 +902,9 @@ bool Sema::isClassOrStructOrTagTypedefDecl() {
if (isClassOrStructDeclImpl(ThisDeclInfo->CurrentDecl))
return true;
- if (auto *ThisTypedefDecl = dyn_cast<TypedefDecl>(ThisDeclInfo->CurrentDecl)) {
- auto UnderlyingType = ThisTypedefDecl->getUnderlyingType();
- if (auto ThisElaboratedType = dyn_cast<ElaboratedType>(UnderlyingType)) {
- auto DesugaredType = ThisElaboratedType->desugar();
- if (auto *DesugaredTypePtr = DesugaredType.getTypePtrOrNull()) {
- if (auto *ThisRecordType = dyn_cast<RecordType>(DesugaredTypePtr)) {
- return isClassOrStructDeclImpl(ThisRecordType->getAsRecordDecl());
- }
- }
- }
- }
+ if (auto *ThisTypedefDecl = dyn_cast<TypedefDecl>(ThisDeclInfo->CurrentDecl))
+ if (auto *D = ThisTypedefDecl->getUnderlyingType()->getAsRecordDecl())
+ return isClassOrStructDeclImpl(D);
return false;
}
diff --git a/clang/lib/AST/ComparisonCategories.cpp b/clang/lib/AST/ComparisonCategories.cpp
index 28244104d6636..0c7a7f4eacbbf 100644
--- a/clang/lib/AST/ComparisonCategories.cpp
+++ b/clang/lib/AST/ComparisonCategories.cpp
@@ -166,7 +166,7 @@ const ComparisonCategoryInfo &ComparisonCategories::getInfoForType(QualType Ty)
QualType ComparisonCategoryInfo::getType() const {
assert(Record);
- return QualType(Record->getTypeForDecl(), 0);
+ return Record->getASTContext().getCanonicalTagType(Record);
}
StringRef ComparisonCategories::getCategoryString(ComparisonCategoryType Kind) {
diff --git a/clang/lib/AST/ComputeDependence.cpp b/clang/lib/AST/ComputeDependence.cpp
index 14ec93eb1d166..e95bcd75634fa 100644
--- a/clang/lib/AST/ComputeDependence.cpp
+++ b/clang/lib/AST/ComputeDependence.cpp
@@ -500,9 +500,8 @@ ExprDependence clang::computeDependence(OMPIteratorExpr *E) {
ExprDependence clang::computeDependence(DeclRefExpr *E, const ASTContext &Ctx) {
auto Deps = ExprDependence::None;
- if (auto *NNS = E->getQualifier())
- Deps |= toExprDependence(NNS->getDependence() &
- ~NestedNameSpecifierDependence::Dependent);
+ Deps |= toExprDependence(E->getQualifier().getDependence() &
+ ~NestedNameSpecifierDependence::Dependent);
if (auto *FirstArg = E->getTemplateArgs()) {
unsigned NumArgs = E->getNumTemplateArgs();
@@ -673,9 +672,8 @@ ExprDependence clang::computeDependence(MemberExpr *E) {
auto D = E->getBase()->getDependence();
D |= getDependenceInExpr(E->getMemberNameInfo());
- if (auto *NNS = E->getQualifier())
- D |= toExprDependence(NNS->getDependence() &
- ~NestedNameSpecifierDependence::Dependent);
+ D |= toExprDependence(E->getQualifier().getDependence() &
+ ~NestedNameSpecifierDependence::Dependent);
for (const auto &A : E->template_arguments())
D |= toExprDependence(A.getArgument().getDependence());
@@ -783,9 +781,8 @@ ExprDependence clang::computeDependence(CXXPseudoDestructorExpr *E) {
if (auto *ST = E->getScopeTypeInfo())
D |= turnTypeToValueDependence(
toExprDependenceAsWritten(ST->getType()->getDependence()));
- if (auto *Q = E->getQualifier())
- D |= toExprDependence(Q->getDependence() &
- ~NestedNameSpecifierDependence::Dependent);
+ D |= toExprDependence(E->getQualifier().getDependence() &
+ ~NestedNameSpecifierDependence::Dependent);
return D;
}
@@ -801,9 +798,8 @@ clang::computeDependence(OverloadExpr *E, bool KnownDependent,
if (KnownContainsUnexpandedParameterPack)
Deps |= ExprDependence::UnexpandedPack;
Deps |= getDependenceInExpr(E->getNameInfo());
- if (auto *Q = E->getQualifier())
- Deps |= toExprDependence(Q->getDependence() &
- ~NestedNameSpecifierDependence::Dependent);
+ Deps |= toExprDependence(E->getQualifier().getDependence() &
+ ~NestedNameSpecifierDependence::Dependent);
for (auto *D : E->decls()) {
if (D->getDeclContext()->isDependentContext() ||
isa<UnresolvedUsingValueDecl>(D))
@@ -820,8 +816,7 @@ clang::computeDependence(OverloadExpr *E, bool KnownDependent,
ExprDependence clang::computeDependence(DependentScopeDeclRefExpr *E) {
auto D = ExprDependence::TypeValue;
D |= getDependenceInExpr(E->getNameInfo());
- if (auto *Q = E->getQualifier())
- D |= toExprDependence(Q->getDependence());
+ D |= toExprDependence(E->getQualifier().getDependence());
for (const auto &A : E->template_arguments())
D |= toExprDependence(A.getArgument().getDependence());
return D;
@@ -872,8 +867,7 @@ ExprDependence clang::computeDependence(CXXDependentScopeMemberExpr *E) {
auto D = ExprDependence::TypeValueInstantiation;
if (!E->isImplicitAccess())
D |= E->getBase()->getDependence();
- if (auto *Q = E->getQualifier())
- D |= toExprDependence(Q->getDependence());
+ D |= toExprDependence(E->getQualifier().getDependence());
D |= getDependenceInExpr(E->getMemberNameInfo());
for (const auto &A : E->template_arguments())
D |= toExprDependence(A.getArgument().getDependence());
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index 8855d0107daca..dc0ce6e66bac7 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -1690,9 +1690,9 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
return;
}
printNestedNameSpecifier(OS, P);
- if (getDeclName())
- OS << *this;
- else {
+ if (getDeclName()) {
+ printName(OS, P);
+ } else {
// Give the printName override a chance to pick a different name before we
// fall back to "(anonymous)".
SmallString<64> NameBuffer;
@@ -1880,18 +1880,13 @@ bool NamedDecl::declarationReplaces(const NamedDecl *OldD,
// Using declarations can be replaced if they import the same name from the
// same context.
- if (const auto *UD = dyn_cast<UsingDecl>(this)) {
- ASTContext &Context = getASTContext();
- return Context.getCanonicalNestedNameSpecifier(UD->getQualifier()) ==
- Context.getCanonicalNestedNameSpecifier(
- cast<UsingDecl>(OldD)->getQualifier());
- }
- if (const auto *UUVD = dyn_cast<UnresolvedUsingValueDecl>(this)) {
- ASTContext &Context = getASTContext();
- return Context.getCanonicalNestedNameSpecifier(UUVD->getQualifier()) ==
- Context.getCanonicalNestedNameSpecifier(
- cast<UnresolvedUsingValueDecl>(OldD)->getQualifier());
- }
+ if (const auto *UD = dyn_cast<UsingDecl>(this))
+ return UD->getQualifier().getCanonical() ==
+
+ cast<UsingDecl>(OldD)->getQualifier().getCanonical();
+ if (const auto *UUVD = dyn_cast<UnresolvedUsingValueDecl>(this))
+ return UUVD->getQualifier().getCanonical() ==
+ cast<UnresolvedUsingValueDecl>(OldD)->getQualifier().getCanonical();
if (isRedeclarable(getKind())) {
if (getCanonicalDecl() != OldD->getCanonicalDecl())
@@ -2861,7 +2856,8 @@ VarDecl::needsDestruction(const ASTContext &Ctx) const {
bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
assert(hasInit() && "Expect initializer to check for flexible array init");
auto *Ty = getType()->getAs<RecordType>();
- if (!Ty || !Ty->getDecl()->hasFlexibleArrayMember())
+ if (!Ty ||
+ !Ty->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return false;
auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
if (!List)
@@ -2876,7 +2872,10 @@ bool VarDecl::hasFlexibleArrayInit(const ASTContext &Ctx) const {
CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
assert(hasInit() && "Expect initializer to check for flexible array init");
auto *Ty = getType()->getAs<RecordType>();
- if (!Ty || !Ty->getDecl()->hasFlexibleArrayMember())
+ if (!Ty)
+ return CharUnits::Zero();
+ const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ if (!Ty || !RD->hasFlexibleArrayMember())
return CharUnits::Zero();
auto *List = dyn_cast<InitListExpr>(getInit()->IgnoreParens());
if (!List || List->getNumInits() == 0)
@@ -2886,7 +2885,7 @@ CharUnits VarDecl::getFlexibleArrayInitChars(const ASTContext &Ctx) const {
if (!InitTy)
return CharUnits::Zero();
CharUnits FlexibleArraySize = Ctx.getTypeSizeInChars(InitTy);
- const ASTRecordLayout &RL = Ctx.getASTRecordLayout(Ty->getDecl());
+ const ASTRecordLayout &RL = Ctx.getASTRecordLayout(RD);
CharUnits FlexibleArrayOffset =
Ctx.toCharUnitsFromBits(RL.getFieldOffset(RL.getFieldCount() - 1));
if (FlexibleArrayOffset + FlexibleArraySize < RL.getSize())
@@ -2988,7 +2987,10 @@ bool ParmVarDecl::isDestroyedInCallee() const {
// FIXME: isParamDestroyedInCallee() should probably imply
// isDestructedType()
const auto *RT = getType()->getAs<RecordType>();
- if (RT && RT->getDecl()->isParamDestroyedInCallee() &&
+ if (RT &&
+ RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isParamDestroyedInCallee() &&
getType().isDestructedType())
return true;
@@ -3499,7 +3501,7 @@ bool FunctionDecl::isUsableAsGlobalAllocationFunctionInConstantEvaluation(
while (const auto *TD = T->getAs<TypedefType>())
T = TD->getDecl()->getUnderlyingType();
const IdentifierInfo *II =
- T->castAs<EnumType>()->getDecl()->getIdentifier();
+ T->castAs<EnumType>()->getOriginalDecl()->getIdentifier();
if (II && II->isStr("__hot_cold_t"))
Consume();
}
@@ -4650,7 +4652,7 @@ bool FieldDecl::isAnonymousStructOrUnion() const {
return false;
if (const auto *Record = getType()->getAs<RecordType>())
- return Record->getDecl()->isAnonymousStructOrUnion();
+ return Record->getOriginalDecl()->isAnonymousStructOrUnion();
return false;
}
@@ -4707,7 +4709,7 @@ bool FieldDecl::isZeroSize(const ASTContext &Ctx) const {
const auto *RT = getType()->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl()->getDefinition();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
if (!RD) {
assert(isInvalidDecl() && "valid field has incomplete type");
return false;
@@ -4830,10 +4832,6 @@ TagDecl *TagDecl::getCanonicalDecl() { return getFirstDecl(); }
void TagDecl::setTypedefNameForAnonDecl(TypedefNameDecl *TDD) {
TypedefNameDeclOrQualifier = TDD;
- if (const Type *T = getTypeForDecl()) {
- (void)T;
- assert(T->isLinkageValid());
- }
assert(isLinkageValid());
}
@@ -4861,25 +4859,16 @@ void TagDecl::completeDefinition() {
}
TagDecl *TagDecl::getDefinition() const {
- if (isCompleteDefinition())
+ if (isCompleteDefinition() || isBeingDefined())
return const_cast<TagDecl *>(this);
- // If it's possible for us to have an out-of-date definition, check now.
- if (mayHaveOutOfDateDef()) {
- if (IdentifierInfo *II = getIdentifier()) {
- if (II->isOutOfDate()) {
- updateOutOfDate(*II);
- }
- }
- }
-
if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(this))
return CXXRD->getDefinition();
- for (auto *R : redecls())
- if (R->isCompleteDefinition())
+ for (TagDecl *R :
+ redecl_range(redecl_iterator(getNextRedeclaration()), redecl_iterator()))
+ if (R->isCompleteDefinition() || R->isBeingDefined())
return R;
-
return nullptr;
}
@@ -4913,7 +4902,7 @@ void TagDecl::printName(raw_ostream &OS, const PrintingPolicy &Policy) const {
// is already printed as part of the type.
PrintingPolicy Copy(Policy);
Copy.SuppressScope = true;
- getASTContext().getTagDeclType(this).print(OS, Copy);
+ QualType(getASTContext().getCanonicalTagType(this)).print(OS, Copy);
return;
}
// Otherwise, do the normal printing.
@@ -4957,19 +4946,13 @@ EnumDecl *EnumDecl::Create(ASTContext &C, DeclContext *DC,
IdentifierInfo *Id,
EnumDecl *PrevDecl, bool IsScoped,
bool IsScopedUsingClassTag, bool IsFixed) {
- auto *Enum = new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl,
- IsScoped, IsScopedUsingClassTag, IsFixed);
- Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
- C.getTypeDeclType(Enum, PrevDecl);
- return Enum;
+ return new (C, DC) EnumDecl(C, DC, StartLoc, IdLoc, Id, PrevDecl, IsScoped,
+ IsScopedUsingClassTag, IsFixed);
}
EnumDecl *EnumDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
- EnumDecl *Enum =
- new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
- nullptr, nullptr, false, false, false);
- Enum->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
- return Enum;
+ return new (C, ID) EnumDecl(C, nullptr, SourceLocation(), SourceLocation(),
+ nullptr, nullptr, false, false, false);
}
SourceRange EnumDecl::getIntegerTypeRange() const {
@@ -5029,7 +5012,7 @@ EnumDecl *EnumDecl::getTemplateInstantiationPattern() const {
EnumDecl *ED = getInstantiatedFromMemberEnum();
while (auto *NewED = ED->getInstantiatedFromMemberEnum())
ED = NewED;
- return getDefinitionOrSelf(ED);
+ return ::getDefinitionOrSelf(ED);
}
}
@@ -5119,26 +5102,15 @@ RecordDecl::RecordDecl(Kind DK, TagKind TK, const ASTContext &C,
RecordDecl *RecordDecl::Create(const ASTContext &C, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, RecordDecl* PrevDecl) {
- RecordDecl *R = new (C, DC) RecordDecl(Record, TK, C, DC,
- StartLoc, IdLoc, Id, PrevDecl);
- R->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
-
- C.getTypeDeclType(R, PrevDecl);
- return R;
+ return new (C, DC)
+ RecordDecl(Record, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl);
}
RecordDecl *RecordDecl::CreateDeserialized(const ASTContext &C,
GlobalDeclID ID) {
- RecordDecl *R = new (C, ID)
+ return new (C, ID)
RecordDecl(Record, TagTypeKind::Struct, C, nullptr, SourceLocation(),
SourceLocation(), nullptr, nullptr);
- R->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
- return R;
-}
-
-bool RecordDecl::isInjectedClassName() const {
- return isImplicit() && getDeclName() && getDeclContext()->isRecord() &&
- cast<RecordDecl>(getDeclContext())->getDeclName() == getDeclName();
}
bool RecordDecl::isLambda() const {
@@ -5162,7 +5134,7 @@ bool RecordDecl::isOrContainsUnion() const {
if (const RecordDecl *Def = getDefinition()) {
for (const FieldDecl *FD : Def->fields()) {
const RecordType *RT = FD->getType()->getAs<RecordType>();
- if (RT && RT->getDecl()->isOrContainsUnion())
+ if (RT && RT->getOriginalDecl()->isOrContainsUnion())
return true;
}
}
@@ -5294,8 +5266,9 @@ const FieldDecl *RecordDecl::findFirstNamedDataMember() const {
return I;
if (const auto *RT = I->getType()->getAs<RecordType>())
- if (const FieldDecl *NamedDataMember =
- RT->getDecl()->findFirstNamedDataMember())
+ if (const FieldDecl *NamedDataMember = RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->findFirstNamedDataMember())
return NamedDataMember;
}
@@ -5657,14 +5630,14 @@ void TypedefNameDecl::anchor() {}
TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const {
if (auto *TT = getTypeSourceInfo()->getType()->getAs<TagType>()) {
- auto *OwningTypedef = TT->getDecl()->getTypedefNameForAnonDecl();
+ auto *OwningTypedef = TT->getOriginalDecl()->getTypedefNameForAnonDecl();
auto *ThisTypedef = this;
if (AnyRedecl && OwningTypedef) {
OwningTypedef = OwningTypedef->getCanonicalDecl();
ThisTypedef = ThisTypedef->getCanonicalDecl();
}
if (OwningTypedef == ThisTypedef)
- return TT->getDecl();
+ return TT->getOriginalDecl()->getDefinitionOrSelf();
}
return nullptr;
@@ -5673,7 +5646,7 @@ TagDecl *TypedefNameDecl::getAnonDeclWithTypedefName(bool AnyRedecl) const {
bool TypedefNameDecl::isTransparentTagSlow() const {
auto determineIsTransparent = [&]() {
if (auto *TT = getUnderlyingType()->getAs<TagType>()) {
- if (auto *TD = TT->getDecl()) {
+ if (auto *TD = TT->getOriginalDecl()) {
if (TD->getName() != getName())
return false;
SourceLocation TTLoc = getLocation();
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 13c46fdbff96a..680a4d74171a9 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -58,10 +58,6 @@ using namespace clang;
#define ABSTRACT_DECL(DECL)
#include "clang/AST/DeclNodes.inc"
-void Decl::updateOutOfDate(IdentifierInfo &II) const {
- getASTContext().getExternalSource()->updateOutOfDateIdentifier(II);
-}
-
#define DECL(DERIVED, BASE) \
static_assert(alignof(Decl) >= alignof(DERIVED##Decl), \
"Alignment sufficient after objects prepended to " #DERIVED);
@@ -489,8 +485,7 @@ bool Decl::isFlexibleArrayMemberLike(
// Look through typedefs.
if (TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
- const TypedefNameDecl *TDL = TTL.getTypedefNameDecl();
- TInfo = TDL->getTypeSourceInfo();
+ TInfo = TTL.getDecl()->getTypeSourceInfo();
continue;
}
@@ -1512,30 +1507,19 @@ DeclContext *DeclContext::getPrimaryContext() {
case Decl::ObjCCategoryImpl:
return this;
- default:
- if (getDeclKind() >= Decl::firstTag && getDeclKind() <= Decl::lastTag) {
- // If this is a tag type that has a definition or is currently
- // being defined, that definition is our primary context.
- auto *Tag = cast<TagDecl>(this);
-
- if (TagDecl *Def = Tag->getDefinition())
- return Def;
-
- if (const auto *TagTy = dyn_cast<TagType>(Tag->getTypeForDecl())) {
- // Note, TagType::getDecl returns the (partial) definition one exists.
- TagDecl *PossiblePartialDef = TagTy->getDecl();
- if (PossiblePartialDef->isBeingDefined())
- return PossiblePartialDef;
- } else {
- assert(isa<InjectedClassNameType>(Tag->getTypeForDecl()));
- }
-
- return Tag;
- }
+ // If this is a tag type that has a definition or is currently
+ // being defined, that definition is our primary context.
+ case Decl::ClassTemplatePartialSpecialization:
+ case Decl::ClassTemplateSpecialization:
+ case Decl::CXXRecord:
+ return cast<CXXRecordDecl>(this)->getDefinitionOrSelf();
+ case Decl::Record:
+ case Decl::Enum:
+ return cast<TagDecl>(this)->getDefinitionOrSelf();
+ default:
assert(getDeclKind() >= Decl::firstFunction &&
- getDeclKind() <= Decl::lastFunction &&
- "Unknown DeclContext kind");
+ getDeclKind() <= Decl::lastFunction && "Unknown DeclContext kind");
return this;
}
}
diff --git a/clang/lib/AST/DeclCXX.cpp b/clang/lib/AST/DeclCXX.cpp
index ccb308e103253..6ab0650171301 100644
--- a/clang/lib/AST/DeclCXX.cpp
+++ b/clang/lib/AST/DeclCXX.cpp
@@ -132,16 +132,9 @@ CXXRecordDecl::CXXRecordDecl(Kind K, TagKind TK, const ASTContext &C,
CXXRecordDecl *CXXRecordDecl::Create(const ASTContext &C, TagKind TK,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, IdentifierInfo *Id,
- CXXRecordDecl *PrevDecl,
- bool DelayTypeCreation) {
- auto *R = new (C, DC) CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc, IdLoc, Id,
- PrevDecl);
- R->setMayHaveOutOfDateDef(C.getLangOpts().Modules);
-
- // FIXME: DelayTypeCreation seems like such a hack
- if (!DelayTypeCreation)
- C.getTypeDeclType(R, PrevDecl);
- return R;
+ CXXRecordDecl *PrevDecl) {
+ return new (C, DC)
+ CXXRecordDecl(CXXRecord, TK, C, DC, StartLoc, IdLoc, Id, PrevDecl);
}
CXXRecordDecl *
@@ -154,10 +147,7 @@ CXXRecordDecl::CreateLambda(const ASTContext &C, DeclContext *DC,
R->setBeingDefined(true);
R->DefinitionData = new (C) struct LambdaDefinitionData(
R, Info, DependencyKind, IsGeneric, CaptureDefault);
- R->setMayHaveOutOfDateDef(false);
R->setImplicit(true);
-
- C.getTypeDeclType(R, /*PrevDecl=*/nullptr);
return R;
}
@@ -166,7 +156,6 @@ CXXRecordDecl *CXXRecordDecl::CreateDeserialized(const ASTContext &C,
auto *R = new (C, ID)
CXXRecordDecl(CXXRecord, TagTypeKind::Struct, C, nullptr,
SourceLocation(), SourceLocation(), nullptr, nullptr);
- R->setMayHaveOutOfDateDef(false);
return R;
}
@@ -178,7 +167,7 @@ static bool hasRepeatedBaseClass(const CXXRecordDecl *StartRD) {
SmallVector<const CXXRecordDecl*, 8> WorkList = {StartRD};
while (!WorkList.empty()) {
const CXXRecordDecl *RD = WorkList.pop_back_val();
- if (RD->getTypeForDecl()->isDependentType())
+ if (RD->isDependentType())
continue;
for (const CXXBaseSpecifier &BaseSpec : RD->bases()) {
if (const CXXRecordDecl *B = BaseSpec.getType()->getAsCXXRecordDecl()) {
@@ -228,7 +217,8 @@ CXXRecordDecl::setBases(CXXBaseSpecifier const * const *Bases,
if (BaseType->isDependentType())
continue;
auto *BaseClassDecl =
- cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// C++2a [class]p7:
// A standard-layout class is a class that:
@@ -1218,7 +1208,7 @@ void CXXRecordDecl::addedMember(Decl *D) {
bool IsZeroSize = Field->isZeroSize(Context);
if (const auto *RecordTy = T->getAs<RecordType>()) {
- auto *FieldRec = cast<CXXRecordDecl>(RecordTy->getDecl());
+ auto *FieldRec = cast<CXXRecordDecl>(RecordTy->getOriginalDecl());
if (FieldRec->getDefinition()) {
addedClassSubobject(FieldRec);
@@ -1925,7 +1915,8 @@ static void CollectVisibleConversions(
= CXXRecordDecl::MergeAccess(Access, I.getAccessSpecifier());
bool BaseInVirtual = InVirtual || I.isVirtual();
- auto *Base = cast<CXXRecordDecl>(RT->getDecl());
+ auto *Base =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
CollectVisibleConversions(Context, Base, BaseInVirtual, BaseAccess,
*HiddenTypes, Output, VOutput, HiddenVBaseCs);
}
@@ -1963,9 +1954,11 @@ static void CollectVisibleConversions(ASTContext &Context,
const auto *RT = I.getType()->getAs<RecordType>();
if (!RT) continue;
- CollectVisibleConversions(Context, cast<CXXRecordDecl>(RT->getDecl()),
- I.isVirtual(), I.getAccessSpecifier(),
- HiddenTypes, Output, VBaseCs, HiddenVBaseCs);
+ CollectVisibleConversions(
+ Context,
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf(),
+ I.isVirtual(), I.getAccessSpecifier(), HiddenTypes, Output, VBaseCs,
+ HiddenVBaseCs);
}
// Add any unhidden conversions provided by virtual bases.
@@ -2125,11 +2118,10 @@ const CXXRecordDecl *CXXRecordDecl::getTemplateInstantiationPattern() const {
CXXDestructorDecl *CXXRecordDecl::getDestructor() const {
ASTContext &Context = getASTContext();
- QualType ClassType = Context.getTypeDeclType(this);
+ CanQualType ClassType = Context.getCanonicalTagType(this);
- DeclarationName Name
- = Context.DeclarationNames.getCXXDestructorName(
- Context.getCanonicalType(ClassType));
+ DeclarationName Name =
+ Context.DeclarationNames.getCXXDestructorName(ClassType);
DeclContext::lookup_result R = lookup(Name);
@@ -2149,6 +2141,39 @@ bool CXXRecordDecl::hasDeletedDestructor() const {
return false;
}
+bool CXXRecordDecl::isInjectedClassName() const {
+ if (!isImplicit() || !getDeclName())
+ return false;
+
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(getDeclContext()))
+ return RD->getDeclName() == getDeclName();
+
+ return false;
+}
+
+bool CXXRecordDecl::hasInjectedClassType() const {
+ switch (getDeclKind()) {
+ case Decl::ClassTemplatePartialSpecialization:
+ return true;
+ case Decl::ClassTemplateSpecialization:
+ return false;
+ case Decl::CXXRecord:
+ return getDescribedClassTemplate() != nullptr;
+ default:
+ llvm_unreachable("unexpected decl kind");
+ }
+}
+
+CanQualType CXXRecordDecl::getCanonicalTemplateSpecializationType(
+ const ASTContext &Ctx) const {
+ if (auto *RD = dyn_cast<ClassTemplatePartialSpecializationDecl>(this))
+ return RD->getCanonicalInjectedSpecializationType(Ctx);
+ if (const ClassTemplateDecl *TD = getDescribedClassTemplate();
+ TD && !isa<ClassTemplateSpecializationDecl>(this))
+ return TD->getCanonicalInjectedSpecializationType(Ctx);
+ return CanQualType();
+}
+
static bool isDeclContextInNamespace(const DeclContext *DC) {
while (!DC->isTranslationUnit()) {
if (DC->isNamespace())
@@ -2262,7 +2287,7 @@ void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
Context.getDiagnostics().Report(
AT->getLocation(),
diag::warn_cxx20_compat_requires_explicit_init_non_aggregate)
- << AT << FD << Context.getRecordType(this);
+ << AT << FD << Context.getCanonicalTagType(this);
}
}
@@ -2274,7 +2299,7 @@ void CXXRecordDecl::completeDefinition(CXXFinalOverriderMap *FinalOverriders) {
if (const auto *AT = FD->getAttr<ExplicitInitAttr>())
Context.getDiagnostics().Report(AT->getLocation(),
diag::warn_attribute_needs_aggregate)
- << AT << Context.getRecordType(this);
+ << AT << Context.getCanonicalTagType(this);
}
setHasUninitializedExplicitInitFields(false);
}
@@ -2286,8 +2311,8 @@ bool CXXRecordDecl::mayBeAbstract() const {
return false;
for (const auto &B : bases()) {
- const auto *BaseDecl =
- cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl());
+ const auto *BaseDecl = cast<CXXRecordDecl>(
+ B.getType()->castAs<RecordType>()->getOriginalDecl());
if (BaseDecl->isAbstract())
return true;
}
@@ -2450,7 +2475,8 @@ CXXMethodDecl::getCorrespondingMethodInClass(const CXXRecordDecl *RD,
const RecordType *RT = I.getType()->getAs<RecordType>();
if (!RT)
continue;
- const auto *Base = cast<CXXRecordDecl>(RT->getDecl());
+ const auto *Base =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if (CXXMethodDecl *D = this->getCorrespondingMethodInClass(Base))
AddFinalOverrider(D);
}
@@ -2702,8 +2728,7 @@ bool CXXMethodDecl::isCopyAssignmentOperator() const {
ParamType = Ref->getPointeeType();
ASTContext &Context = getASTContext();
- QualType ClassType
- = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
+ CanQualType ClassType = Context.getCanonicalTagType(getParent());
return Context.hasSameUnqualifiedType(ClassType, ParamType);
}
@@ -2723,8 +2748,7 @@ bool CXXMethodDecl::isMoveAssignmentOperator() const {
ParamType = ParamType->getPointeeType();
ASTContext &Context = getASTContext();
- QualType ClassType
- = Context.getCanonicalType(Context.getTypeDeclType(getParent()));
+ CanQualType ClassType = Context.getCanonicalTagType(getParent());
return Context.hasSameUnqualifiedType(ClassType, ParamType);
}
@@ -2759,7 +2783,7 @@ CXXMethodDecl::overridden_methods() const {
static QualType getThisObjectType(ASTContext &C, const FunctionProtoType *FPT,
const CXXRecordDecl *Decl) {
- QualType ClassTy = C.getTypeDeclType(Decl);
+ CanQualType ClassTy = C.getCanonicalTagType(Decl);
return C.getQualifiedType(ClassTy, FPT->getMethodQuals());
}
@@ -3017,11 +3041,9 @@ bool CXXConstructorDecl::isCopyOrMoveConstructor(unsigned &TypeQuals) const {
// Is it a reference to our class type?
ASTContext &Context = getASTContext();
- CanQualType PointeeType
- = Context.getCanonicalType(ParamRefType->getPointeeType());
- CanQualType ClassTy
- = Context.getCanonicalType(Context.getTagDeclType(getParent()));
- if (PointeeType.getUnqualifiedType() != ClassTy)
+ QualType PointeeType = ParamRefType->getPointeeType();
+ CanQualType ClassTy = Context.getCanonicalTagType(getParent());
+ if (!Context.hasSameUnqualifiedType(PointeeType, ClassTy))
return false;
// FIXME: other qualifiers?
@@ -3056,15 +3078,11 @@ bool CXXConstructorDecl::isSpecializationCopyingObject() const {
const ParmVarDecl *Param = getParamDecl(0);
ASTContext &Context = getASTContext();
- CanQualType ParamType = Context.getCanonicalType(Param->getType());
+ CanQualType ParamType = Param->getType()->getCanonicalTypeUnqualified();
// Is it the same as our class type?
- CanQualType ClassTy
- = Context.getCanonicalType(Context.getTagDeclType(getParent()));
- if (ParamType.getUnqualifiedType() != ClassTy)
- return false;
-
- return true;
+ CanQualType ClassTy = Context.getCanonicalTagType(getParent());
+ return ParamType == ClassTy;
}
void CXXDestructorDecl::anchor() {}
@@ -3201,6 +3219,12 @@ UsingDirectiveDecl *UsingDirectiveDecl::CreateDeserialized(ASTContext &C,
SourceLocation(), nullptr, nullptr);
}
+NamespaceDecl *NamespaceBaseDecl::getNamespace() {
+ if (auto *Alias = dyn_cast<NamespaceAliasDecl>(this))
+ return Alias->getNamespace();
+ return cast<NamespaceDecl>(this);
+}
+
NamespaceDecl *UsingDirectiveDecl::getNominatedNamespace() {
if (auto *NA = dyn_cast_or_null<NamespaceAliasDecl>(NominatedNamespace))
return NA->getNamespace();
@@ -3211,7 +3235,7 @@ NamespaceDecl::NamespaceDecl(ASTContext &C, DeclContext *DC, bool Inline,
SourceLocation StartLoc, SourceLocation IdLoc,
IdentifierInfo *Id, NamespaceDecl *PrevDecl,
bool Nested)
- : NamedDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
+ : NamespaceBaseDecl(Namespace, DC, IdLoc, Id), DeclContext(Namespace),
redeclarable_base(C), LocStart(StartLoc) {
setInline(Inline);
setNested(Nested);
@@ -3258,13 +3282,11 @@ NamespaceAliasDecl *NamespaceAliasDecl::getMostRecentDeclImpl() {
return getMostRecentDecl();
}
-NamespaceAliasDecl *NamespaceAliasDecl::Create(ASTContext &C, DeclContext *DC,
- SourceLocation UsingLoc,
- SourceLocation AliasLoc,
- IdentifierInfo *Alias,
- NestedNameSpecifierLoc QualifierLoc,
- SourceLocation IdentLoc,
- NamedDecl *Namespace) {
+NamespaceAliasDecl *NamespaceAliasDecl::Create(
+ ASTContext &C, DeclContext *DC, SourceLocation UsingLoc,
+ SourceLocation AliasLoc, IdentifierInfo *Alias,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation IdentLoc,
+ NamespaceBaseDecl *Namespace) {
// FIXME: Preserve the aliased namespace as written.
if (auto *NS = dyn_cast_or_null<NamespaceDecl>(Namespace))
Namespace = NS->getFirstDecl();
@@ -3357,7 +3379,7 @@ ConstructorUsingShadowDecl::CreateDeserialized(ASTContext &C, GlobalDeclID ID) {
}
CXXRecordDecl *ConstructorUsingShadowDecl::getNominatedBaseClass() const {
- return getIntroducer()->getQualifier()->getAsRecordDecl();
+ return getIntroducer()->getQualifier().getAsRecordDecl();
}
void BaseUsingDecl::anchor() {}
diff --git a/clang/lib/AST/DeclPrinter.cpp b/clang/lib/AST/DeclPrinter.cpp
index 9273f5816d5ac..ca1d601370f23 100644
--- a/clang/lib/AST/DeclPrinter.cpp
+++ b/clang/lib/AST/DeclPrinter.cpp
@@ -202,8 +202,7 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
}
Decl** End = Begin + NumDecls;
- TagDecl* TD = dyn_cast<TagDecl>(*Begin);
- if (TD)
+ if (isa<TagDecl>(*Begin))
++Begin;
PrintingPolicy SubPolicy(Policy);
@@ -211,13 +210,9 @@ void Decl::printGroup(Decl** Begin, unsigned NumDecls,
bool isFirst = true;
for ( ; Begin != End; ++Begin) {
if (isFirst) {
- if(TD)
- SubPolicy.IncludeTagDefinition = true;
- SubPolicy.SuppressSpecifiers = false;
isFirst = false;
} else {
- if (!isFirst) Out << ", ";
- SubPolicy.IncludeTagDefinition = false;
+ Out << ", ";
SubPolicy.SuppressSpecifiers = true;
}
@@ -487,10 +482,12 @@ void DeclPrinter::VisitDeclContext(DeclContext *DC, bool Indent) {
QualType CurDeclType = getDeclType(*D);
if (!Decls.empty() && !CurDeclType.isNull()) {
QualType BaseType = GetBaseType(CurDeclType);
- if (!BaseType.isNull() && isa<ElaboratedType>(BaseType) &&
- cast<ElaboratedType>(BaseType)->getOwnedTagDecl() == Decls[0]) {
- Decls.push_back(*D);
- continue;
+ if (const auto *TT = dyn_cast_or_null<TagType>(BaseType);
+ TT && TT->isTagOwned()) {
+ if (TT->getOriginalDecl() == Decls[0]) {
+ Decls.push_back(*D);
+ continue;
+ }
}
}
@@ -662,16 +659,6 @@ static void printExplicitSpecifier(ExplicitSpecifier ES, llvm::raw_ostream &Out,
Out << Proto;
}
-static void MaybePrintTagKeywordIfSupressingScopes(PrintingPolicy &Policy,
- QualType T,
- llvm::raw_ostream &Out) {
- StringRef prefix = T->isClassType() ? "class "
- : T->isStructureType() ? "struct "
- : T->isUnionType() ? "union "
- : "";
- Out << prefix;
-}
-
void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
if (!D->getDescribedFunctionTemplate() &&
!D->isFunctionTemplateSpecialization()) {
@@ -721,11 +708,8 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Proto += D->getQualifiedNameAsString();
} else {
llvm::raw_string_ostream OS(Proto);
- if (!Policy.SuppressScope) {
- if (const NestedNameSpecifier *NS = D->getQualifier()) {
- NS->print(OS, Policy);
- }
- }
+ if (!Policy.SuppressScope)
+ D->getQualifier().print(OS, Policy);
D->getNameInfo().printName(OS, Policy);
}
@@ -833,10 +817,6 @@ void DeclPrinter::VisitFunctionDecl(FunctionDecl *D) {
Out << Proto << " -> ";
Proto.clear();
}
- if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
- !Policy.SuppressUnwrittenScope)
- MaybePrintTagKeywordIfSupressingScopes(Policy, AFT->getReturnType(),
- Out);
AFT->getReturnType().print(Out, Policy, Proto);
Proto.clear();
}
@@ -995,10 +975,6 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) {
}
}
- if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
- !Policy.SuppressUnwrittenScope)
- MaybePrintTagKeywordIfSupressingScopes(Policy, T, Out);
-
printDeclType(T, (isa<ParmVarDecl>(D) && Policy.CleanUglifiedParameters &&
D->getIdentifier())
? D->getIdentifier()->deuglifiedName()
@@ -1028,7 +1004,6 @@ void DeclPrinter::VisitVarDecl(VarDecl *D) {
}
PrintingPolicy SubPolicy(Policy);
SubPolicy.SuppressSpecifiers = false;
- SubPolicy.IncludeTagDefinition = false;
Init->printPretty(Out, nullptr, SubPolicy, Indentation, "\n", &Context);
if ((D->getInitStyle() == VarDecl::CallInit) && !isa<ParenListExpr>(Init))
Out << ")";
@@ -1086,15 +1061,13 @@ void DeclPrinter::VisitNamespaceDecl(NamespaceDecl *D) {
void DeclPrinter::VisitUsingDirectiveDecl(UsingDirectiveDecl *D) {
Out << "using namespace ";
- if (D->getQualifier())
- D->getQualifier()->print(Out, Policy);
+ D->getQualifier().print(Out, Policy);
Out << *D->getNominatedNamespaceAsWritten();
}
void DeclPrinter::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
Out << "namespace " << *D << " = ";
- if (D->getQualifier())
- D->getQualifier()->print(Out, Policy);
+ D->getQualifier().print(Out, Policy);
Out << *D->getAliasedNamespace();
}
@@ -1115,8 +1088,7 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
Out << ' ';
if (D->getIdentifier()) {
- if (auto *NNS = D->getQualifier())
- NNS->print(Out, Policy);
+ D->getQualifier().print(Out, Policy);
Out << *D;
if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
@@ -1748,7 +1720,7 @@ void DeclPrinter::VisitUsingDecl(UsingDecl *D) {
Out << "using ";
if (D->hasTypename())
Out << "typename ";
- D->getQualifier()->print(Out, Policy);
+ D->getQualifier().print(Out, Policy);
// Use the correct record name when the using declaration is used for
// inheriting constructors.
@@ -1770,14 +1742,14 @@ void DeclPrinter::VisitUsingEnumDecl(UsingEnumDecl *D) {
void
DeclPrinter::VisitUnresolvedUsingTypenameDecl(UnresolvedUsingTypenameDecl *D) {
Out << "using typename ";
- D->getQualifier()->print(Out, Policy);
+ D->getQualifier().print(Out, Policy);
Out << D->getDeclName();
}
void DeclPrinter::VisitUnresolvedUsingValueDecl(UnresolvedUsingValueDecl *D) {
if (!D->isAccessDeclaration())
Out << "using ";
- D->getQualifier()->print(Out, Policy);
+ D->getQualifier().print(Out, Policy);
Out << D->getDeclName();
}
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 5035f2d33b0a1..7786e17cfca3d 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -630,7 +630,8 @@ ClassTemplateDecl::findPartialSpecialization(QualType T) {
ASTContext &Context = getASTContext();
for (ClassTemplatePartialSpecializationDecl &P :
getPartialSpecializations()) {
- if (Context.hasSameType(P.getInjectedSpecializationType(), T))
+ if (Context.hasSameType(P.getCanonicalInjectedSpecializationType(Context),
+ T))
return P.getMostRecentDecl();
}
@@ -649,28 +650,20 @@ ClassTemplateDecl::findPartialSpecInstantiatedFromMember(
return nullptr;
}
-QualType
-ClassTemplateDecl::getInjectedClassNameSpecialization() {
+CanQualType ClassTemplateDecl::getCanonicalInjectedSpecializationType(
+ const ASTContext &Ctx) const {
Common *CommonPtr = getCommonPtr();
- if (!CommonPtr->InjectedClassNameType.isNull())
- return CommonPtr->InjectedClassNameType;
-
- // C++0x [temp.dep.type]p2:
- // The template argument list of a primary template is a template argument
- // list in which the nth template argument has the value of the nth template
- // parameter of the class template. If the nth template parameter is a
- // template parameter pack (14.5.3), the nth template argument is a pack
- // expansion (14.5.3) whose pattern is the name of the template parameter
- // pack.
- ASTContext &Context = getASTContext();
- TemplateName Name = Context.getQualifiedTemplateName(
- /*NNS=*/nullptr, /*TemplateKeyword=*/false, TemplateName(this));
- auto TemplateArgs = getTemplateParameters()->getInjectedTemplateArgs(Context);
- CommonPtr->InjectedClassNameType =
- Context.getTemplateSpecializationType(Name,
- /*SpecifiedArgs=*/TemplateArgs,
- /*CanonicalArgs=*/{});
- return CommonPtr->InjectedClassNameType;
+
+ if (CommonPtr->CanonInjectedTST.isNull()) {
+ SmallVector<TemplateArgument> CanonicalArgs(
+ getTemplateParameters()->getInjectedTemplateArgs(Ctx));
+ Ctx.canonicalizeTemplateArguments(CanonicalArgs);
+ CommonPtr->CanonInjectedTST =
+ CanQualType::CreateUnsafe(Ctx.getCanonicalTemplateSpecializationType(
+ TemplateName(const_cast<ClassTemplateDecl *>(getCanonicalDecl())),
+ CanonicalArgs));
+ }
+ return CommonPtr->CanonInjectedTST;
}
//===----------------------------------------------------------------------===//
@@ -993,7 +986,6 @@ ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create(
auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
SpecializedTemplate, Args, StrictPackMatch, PrevDecl);
- Result->setMayHaveOutOfDateDef(false);
// If the template decl is incomplete, copy the external lexical storage from
// the base template. This allows instantiations of incomplete types to
@@ -1003,17 +995,14 @@ ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create(
Result->setHasExternalLexicalStorage(
SpecializedTemplate->getTemplatedDecl()->hasExternalLexicalStorage());
- Context.getTypeDeclType(Result, PrevDecl);
return Result;
}
ClassTemplateSpecializationDecl *
ClassTemplateSpecializationDecl::CreateDeserialized(ASTContext &C,
GlobalDeclID ID) {
- auto *Result =
- new (C, ID) ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
- Result->setMayHaveOutOfDateDef(false);
- return Result;
+ return new (C, ID)
+ ClassTemplateSpecializationDecl(C, ClassTemplateSpecialization);
}
void ClassTemplateSpecializationDecl::getNameForDiagnostic(
@@ -1175,13 +1164,15 @@ ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
+ CanQualType CanonInjectedTST,
ClassTemplatePartialSpecializationDecl *PrevDecl)
: ClassTemplateSpecializationDecl(
Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
// Tracking StrictPackMatch for Partial
// Specializations is not needed.
SpecializedTemplate, Args, /*StrictPackMatch=*/false, PrevDecl),
- TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
+ TemplateParams(Params), InstantiatedFromMember(nullptr, false),
+ CanonInjectedTST(CanonInjectedTST) {
if (AdoptTemplateParameterList(Params, this))
setInvalidDecl();
}
@@ -1191,24 +1182,31 @@ ClassTemplatePartialSpecializationDecl::Create(
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc, TemplateParameterList *Params,
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
- QualType CanonInjectedType,
+ CanQualType CanonInjectedTST,
ClassTemplatePartialSpecializationDecl *PrevDecl) {
auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
- PrevDecl);
+ CanonInjectedTST, PrevDecl);
Result->setSpecializationKind(TSK_ExplicitSpecialization);
- Result->setMayHaveOutOfDateDef(false);
-
- Context.getInjectedClassNameType(Result, CanonInjectedType);
return Result;
}
ClassTemplatePartialSpecializationDecl *
ClassTemplatePartialSpecializationDecl::CreateDeserialized(ASTContext &C,
GlobalDeclID ID) {
- auto *Result = new (C, ID) ClassTemplatePartialSpecializationDecl(C);
- Result->setMayHaveOutOfDateDef(false);
- return Result;
+ return new (C, ID) ClassTemplatePartialSpecializationDecl(C);
+}
+
+CanQualType
+ClassTemplatePartialSpecializationDecl::getCanonicalInjectedSpecializationType(
+ const ASTContext &Ctx) const {
+ if (CanonInjectedTST.isNull()) {
+ CanonInjectedTST =
+ CanQualType::CreateUnsafe(Ctx.getCanonicalTemplateSpecializationType(
+ TemplateName(getSpecializedTemplate()->getCanonicalDecl()),
+ getTemplateArgs().asArray()));
+ }
+ return CanonInjectedTST;
}
SourceRange ClassTemplatePartialSpecializationDecl::getSourceRange() const {
diff --git a/clang/lib/AST/DeclarationName.cpp b/clang/lib/AST/DeclarationName.cpp
index ae5fcf6e86adf..6c7b995d57567 100644
--- a/clang/lib/AST/DeclarationName.cpp
+++ b/clang/lib/AST/DeclarationName.cpp
@@ -115,12 +115,12 @@ static void printCXXConstructorDestructorName(QualType ClassType,
Policy.adjustForCPlusPlus();
if (const RecordType *ClassRec = ClassType->getAs<RecordType>()) {
- ClassRec->getDecl()->printName(OS, Policy);
+ ClassRec->getOriginalDecl()->printName(OS, Policy);
return;
}
if (Policy.SuppressTemplateArgsInCXXConstructors) {
if (auto *InjTy = ClassType->getAs<InjectedClassNameType>()) {
- InjTy->getDecl()->printName(OS, Policy);
+ InjTy->getOriginalDecl()->printName(OS, Policy);
return;
}
}
@@ -184,7 +184,7 @@ void DeclarationName::print(raw_ostream &OS,
OS << "operator ";
QualType Type = getCXXNameType();
if (const RecordType *Rec = Type->getAs<RecordType>()) {
- OS << *Rec->getDecl();
+ OS << *Rec->getOriginalDecl();
return;
}
// We know we're printing C++ here, ensure we print 'bool' properly.
diff --git a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
index b478e7a39ea18..8821cd332e918 100644
--- a/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
+++ b/clang/lib/AST/DynamicRecursiveASTVisitor.cpp
@@ -115,8 +115,12 @@ template <bool Const> struct Impl : RecursiveASTVisitor<Impl<Const>> {
bool TraverseAST(ASTContext &AST) { return Visitor.TraverseAST(AST); }
bool TraverseAttr(Attr *At) { return Visitor.TraverseAttr(At); }
bool TraverseDecl(Decl *D) { return Visitor.TraverseDecl(D); }
- bool TraverseType(QualType T) { return Visitor.TraverseType(T); }
- bool TraverseTypeLoc(TypeLoc TL) { return Visitor.TraverseTypeLoc(TL); }
+ bool TraverseType(QualType T, bool TraverseQualifier = true) {
+ return Visitor.TraverseType(T, TraverseQualifier);
+ }
+ bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) {
+ return Visitor.TraverseTypeLoc(TL, TraverseQualifier);
+ }
bool TraverseStmt(Stmt *S) { return Visitor.TraverseStmt(S); }
bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
@@ -172,7 +176,7 @@ template <bool Const> struct Impl : RecursiveASTVisitor<Impl<Const>> {
return Visitor.TraverseLambdaCapture(LE, C, Init);
}
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier NNS) {
return Visitor.TraverseNestedNameSpecifier(NNS);
}
@@ -241,8 +245,8 @@ template <bool Const> struct Impl : RecursiveASTVisitor<Impl<Const>> {
// Types.
#define ABSTRACT_TYPE(CLASS, BASE)
#define TYPE(CLASS, BASE) \
- bool Traverse##CLASS##Type(CLASS##Type *T) { \
- return Visitor.Traverse##CLASS##Type(T); \
+ bool Traverse##CLASS##Type(CLASS##Type *T, bool TraverseQualifier) { \
+ return Visitor.Traverse##CLASS##Type(T, TraverseQualifier); \
}
#include "clang/AST/TypeNodes.inc"
@@ -255,8 +259,8 @@ template <bool Const> struct Impl : RecursiveASTVisitor<Impl<Const>> {
// TypeLocs.
#define ABSTRACT_TYPELOC(CLASS, BASE)
#define TYPELOC(CLASS, BASE) \
- bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL) { \
- return Visitor.Traverse##CLASS##TypeLoc(TL); \
+ bool Traverse##CLASS##TypeLoc(CLASS##TypeLoc TL, bool TraverseQualifier) { \
+ return Visitor.Traverse##CLASS##TypeLoc(TL, TraverseQualifier); \
}
#include "clang/AST/TypeLocNodes.def"
@@ -297,7 +301,6 @@ FORWARD_TO_BASE(TraverseAttr, Attr, *)
FORWARD_TO_BASE(TraverseConstructorInitializer, CXXCtorInitializer, *)
FORWARD_TO_BASE(TraverseDecl, Decl, *)
FORWARD_TO_BASE(TraverseStmt, Stmt, *)
-FORWARD_TO_BASE(TraverseNestedNameSpecifier, NestedNameSpecifier, *)
FORWARD_TO_BASE(TraverseTemplateInstantiations, ClassTemplateDecl, *)
FORWARD_TO_BASE(TraverseTemplateInstantiations, VarTemplateDecl, *)
FORWARD_TO_BASE(TraverseTemplateInstantiations, FunctionTemplateDecl, *)
@@ -314,8 +317,22 @@ FORWARD_TO_BASE_EXACT(TraverseTemplateArgument, const TemplateArgument &)
FORWARD_TO_BASE_EXACT(TraverseTemplateArguments, ArrayRef<TemplateArgument>)
FORWARD_TO_BASE_EXACT(TraverseTemplateArgumentLoc, const TemplateArgumentLoc &)
FORWARD_TO_BASE_EXACT(TraverseTemplateName, TemplateName)
-FORWARD_TO_BASE_EXACT(TraverseType, QualType)
-FORWARD_TO_BASE_EXACT(TraverseTypeLoc, TypeLoc)
+FORWARD_TO_BASE_EXACT(TraverseNestedNameSpecifier, NestedNameSpecifier)
+
+template <bool Const>
+bool DynamicRecursiveASTVisitorBase<Const>::TraverseType(
+ QualType T, bool TraverseQualifier) {
+ return Impl<Const>(*this).RecursiveASTVisitor<Impl<Const>>::TraverseType(
+ T, TraverseQualifier);
+}
+
+template <bool Const>
+bool DynamicRecursiveASTVisitorBase<Const>::TraverseTypeLoc(
+ TypeLoc TL, bool TraverseQualifier) {
+ return Impl<Const>(*this).RecursiveASTVisitor<Impl<Const>>::TraverseTypeLoc(
+ TL, TraverseQualifier);
+}
+
FORWARD_TO_BASE_EXACT(TraverseTypeConstraint, const TypeConstraint *)
FORWARD_TO_BASE_EXACT(TraverseObjCProtocolLoc, ObjCProtocolLoc)
FORWARD_TO_BASE_EXACT(TraverseNestedNameSpecifierLoc, NestedNameSpecifierLoc)
@@ -354,13 +371,25 @@ bool DynamicRecursiveASTVisitorBase<Const>::dataTraverseNode(
// Declare Traverse*() and friends for all concrete Type classes.
#define ABSTRACT_TYPE(CLASS, BASE)
#define TYPE(CLASS, BASE) \
- FORWARD_TO_BASE(Traverse##CLASS##Type, CLASS##Type, *) \
+ template <bool Const> \
+ bool DynamicRecursiveASTVisitorBase<Const>::Traverse##CLASS##Type( \
+ MaybeConst<CLASS##Type> *T, bool TraverseQualifier) { \
+ return Impl<Const>(*this) \
+ .RecursiveASTVisitor<Impl<Const>>::Traverse##CLASS##Type( \
+ const_cast<CLASS##Type *>(T), TraverseQualifier); \
+ } \
FORWARD_TO_BASE(WalkUpFrom##CLASS##Type, CLASS##Type, *)
#include "clang/AST/TypeNodes.inc"
#define ABSTRACT_TYPELOC(CLASS, BASE)
#define TYPELOC(CLASS, BASE) \
- FORWARD_TO_BASE_EXACT(Traverse##CLASS##TypeLoc, CLASS##TypeLoc)
+ template <bool Const> \
+ bool DynamicRecursiveASTVisitorBase<Const>::Traverse##CLASS##TypeLoc( \
+ CLASS##TypeLoc TL, bool TraverseQualifier) { \
+ return Impl<Const>(*this) \
+ .RecursiveASTVisitor<Impl<Const>>::Traverse##CLASS##TypeLoc( \
+ TL, TraverseQualifier); \
+ }
#include "clang/AST/TypeLocNodes.def"
#define TYPELOC(CLASS, BASE) \
diff --git a/clang/lib/AST/Expr.cpp b/clang/lib/AST/Expr.cpp
index 36fd5ee271e03..ca312c35508f5 100644
--- a/clang/lib/AST/Expr.cpp
+++ b/clang/lib/AST/Expr.cpp
@@ -75,8 +75,7 @@ const CXXRecordDecl *Expr::getBestDynamicClassType() const {
return nullptr;
const RecordType *Ty = DerivedType->castAs<RecordType>();
- Decl *D = Ty->getDecl();
- return cast<CXXRecordDecl>(D);
+ return cast<CXXRecordDecl>(Ty->getOriginalDecl())->getDefinitionOrSelf();
}
const Expr *Expr::skipRValueSubobjectAdjustments(
@@ -92,7 +91,9 @@ const Expr *Expr::skipRValueSubobjectAdjustments(
E->getType()->isRecordType()) {
E = CE->getSubExpr();
const auto *Derived =
- cast<CXXRecordDecl>(E->getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ E->getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
Adjustments.push_back(SubobjectAdjustment(CE, Derived));
continue;
}
@@ -268,7 +269,7 @@ QualType Expr::getEnumCoercedType(const ASTContext &Ctx) const {
if (const auto *ECD = getEnumConstantDecl()) {
const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
if (ED->isCompleteDefinition())
- return Ctx.getTypeDeclType(ED);
+ return Ctx.getCanonicalTagType(ED);
}
return getType();
}
@@ -2031,7 +2032,8 @@ CXXBaseSpecifier **CastExpr::path_buffer() {
const FieldDecl *CastExpr::getTargetFieldForToUnionCast(QualType unionType,
QualType opType) {
- auto RD = unionType->castAs<RecordType>()->getDecl();
+ auto RD =
+ unionType->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
return getTargetFieldForToUnionCast(RD, opType);
}
@@ -3222,7 +3224,7 @@ static const Expr *skipTemporaryBindingsNoOpCastsAndParens(const Expr *E) {
/// isTemporaryObject - Determines if this expression produces a
/// temporary of the given class type.
bool Expr::isTemporaryObject(ASTContext &C, const CXXRecordDecl *TempTy) const {
- if (!C.hasSameUnqualifiedType(getType(), C.getTypeDeclType(TempTy)))
+ if (!C.hasSameUnqualifiedType(getType(), C.getCanonicalTagType(TempTy)))
return false;
const Expr *E = skipTemporaryBindingsNoOpCastsAndParens(this);
@@ -3404,7 +3406,10 @@ bool Expr::isConstantInitializer(ASTContext &Ctx, bool IsForRef,
if (ILE->getType()->isRecordType()) {
unsigned ElementNo = 0;
- RecordDecl *RD = ILE->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *RD = ILE->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
// In C++17, bases were added to the list of members used by aggregate
// initialization.
@@ -4047,8 +4052,10 @@ Expr::isNullPointerConstant(ASTContext &Ctx,
return NPCK_CXX11_nullptr;
if (const RecordType *UT = getType()->getAsUnionType())
- if (!Ctx.getLangOpts().CPlusPlus11 &&
- UT && UT->getDecl()->hasAttr<TransparentUnionAttr>())
+ if (!Ctx.getLangOpts().CPlusPlus11 && UT &&
+ UT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<TransparentUnionAttr>())
if (const CompoundLiteralExpr *CLE = dyn_cast<CompoundLiteralExpr>(this)){
const Expr *InitExpr = CLE->getInitializer();
if (const InitListExpr *ILE = dyn_cast<InitListExpr>(InitExpr))
diff --git a/clang/lib/AST/ExprCXX.cpp b/clang/lib/AST/ExprCXX.cpp
index 5833a6405125d..21640c87ab424 100644
--- a/clang/lib/AST/ExprCXX.cpp
+++ b/clang/lib/AST/ExprCXX.cpp
@@ -1307,7 +1307,7 @@ LambdaExpr *LambdaExpr::Create(const ASTContext &Context, CXXRecordDecl *Class,
bool ContainsUnexpandedParameterPack) {
// Determine the type of the expression (i.e., the type of the
// function object we're creating).
- QualType T = Context.getTypeDeclType(Class);
+ CanQualType T = Context.getCanonicalTagType(Class);
unsigned Size = totalSizeToAlloc<Stmt *>(CaptureInits.size() + 1);
void *Mem = Context.Allocate(Size);
@@ -1675,10 +1675,9 @@ CXXRecordDecl *UnresolvedMemberExpr::getNamingClass() {
// It can't be dependent: after all, we were actually able to do the
// lookup.
CXXRecordDecl *Record = nullptr;
- auto *NNS = getQualifier();
- if (NNS && NNS->getKind() != NestedNameSpecifier::Super) {
- const Type *T = getQualifier()->getAsType();
- assert(T && "qualifier in member expression does not name type");
+ if (NestedNameSpecifier Qualifier = getQualifier();
+ Qualifier.getKind() == NestedNameSpecifier::Kind::Type) {
+ const Type *T = getQualifier().getAsType();
Record = T->getAsCXXRecordDecl();
assert(Record && "qualifier in member expression does not name record");
}
diff --git a/clang/lib/AST/ExprConcepts.cpp b/clang/lib/AST/ExprConcepts.cpp
index ac0e566fe6e72..36f910da49bfb 100644
--- a/clang/lib/AST/ExprConcepts.cpp
+++ b/clang/lib/AST/ExprConcepts.cpp
@@ -41,10 +41,10 @@ ConceptSpecializationExpr::ConceptSpecializationExpr(
assert(!Loc->getNestedNameSpecifierLoc() ||
(!Loc->getNestedNameSpecifierLoc()
.getNestedNameSpecifier()
- ->isInstantiationDependent() &&
+ .isInstantiationDependent() &&
!Loc->getNestedNameSpecifierLoc()
.getNestedNameSpecifier()
- ->containsUnexpandedParameterPack()));
+ .containsUnexpandedParameterPack()));
assert((!isValueDependent() || isInstantiationDependent()) &&
"should not be value-dependent");
}
diff --git a/clang/lib/AST/ExprConstant.cpp b/clang/lib/AST/ExprConstant.cpp
index 60c658a8d8f99..fb8b89c355ed9 100644
--- a/clang/lib/AST/ExprConstant.cpp
+++ b/clang/lib/AST/ExprConstant.cpp
@@ -400,7 +400,7 @@ namespace {
assert(!Invalid && "invalid designator has no subobject type");
return MostDerivedPathLength == Entries.size()
? MostDerivedType
- : Ctx.getRecordType(getAsBaseClass(Entries.back()));
+ : Ctx.getCanonicalTagType(getAsBaseClass(Entries.back()));
}
/// Update this designator to refer to the first element within this array.
@@ -2617,7 +2617,8 @@ static bool CheckEvaluationResult(CheckEvaluationResultKind CERK,
Value.getUnionValue(), Kind, Value.getUnionField(), CheckedTemps);
}
if (Value.isStruct()) {
- RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
+ RecordDecl *RD =
+ Type->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
if (const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD)) {
unsigned BaseIndex = 0;
for (const CXXBaseSpecifier &BS : CD->bases()) {
@@ -4103,7 +4104,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
}
// Next subobject is a class, struct or union field.
- RecordDecl *RD = ObjType->castAs<RecordType>()->getDecl();
+ RecordDecl *RD = ObjType->castAs<RecordType>()->getOriginalDecl();
if (RD->isUnion()) {
const FieldDecl *UnionField = O->getUnionField();
if (!UnionField ||
@@ -4138,7 +4139,7 @@ findSubobject(EvalInfo &Info, const Expr *E, const CompleteObject &Obj,
const CXXRecordDecl *Base = getAsBaseClass(Sub.Entries[I]);
O = &O->getStructBase(getBaseIndex(Derived, Base));
- ObjType = getSubobjectType(ObjType, Info.Ctx.getRecordType(Base));
+ ObjType = getSubobjectType(ObjType, Info.Ctx.getCanonicalTagType(Base));
}
}
}
@@ -6295,7 +6296,7 @@ static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E,
const CXXRecordDecl *C = E->getTypeAsWritten()->getPointeeCXXRecordDecl();
assert(C && "dynamic_cast target is not void pointer nor class");
- CanQualType CQT = Info.Ctx.getCanonicalType(Info.Ctx.getRecordType(C));
+ CanQualType CQT = Info.Ctx.getCanonicalTagType(C);
auto RuntimeCheckFailed = [&] (CXXBasePaths *Paths) {
// C++ [expr.dynamic.cast]p9:
@@ -6321,7 +6322,7 @@ static bool HandleDynamicCast(EvalInfo &Info, const ExplicitCastExpr *E,
}
Info.FFDiag(E, diag::note_constexpr_dynamic_cast_to_reference_failed)
<< DiagKind << Ptr.Designator.getType(Info.Ctx)
- << Info.Ctx.getRecordType(DynType->Type)
+ << Info.Ctx.getCanonicalTagType(DynType->Type)
<< E->getType().getUnqualifiedType();
return false;
};
@@ -6818,8 +6819,8 @@ static bool HandleConstructorCall(const Expr *E, const LValue &This,
// FIXME: This immediately starts the lifetime of all members of
// an anonymous struct. It would be preferable to strictly start
// member lifetime in initialization order.
- Success &=
- handleDefaultInitValue(Info.Ctx.getRecordType(CD), *Value);
+ Success &= handleDefaultInitValue(Info.Ctx.getCanonicalTagType(CD),
+ *Value);
}
// Store Subobject as its parent before updating it for the last element
// in the chain.
@@ -7717,7 +7718,8 @@ class BufferToAPValueConverter {
}
std::optional<APValue> visit(const EnumType *Ty, CharUnits Offset) {
- QualType RepresentationType = Ty->getDecl()->getIntegerType();
+ QualType RepresentationType =
+ Ty->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
assert(!RepresentationType.isNull() &&
"enum forward decl should be caught by Sema");
const auto *AsBuiltin =
@@ -8451,7 +8453,7 @@ class ExprEvaluatorBase
if (auto *DD = dyn_cast<CXXDestructorDecl>(FD)) {
assert(This && "no 'this' pointer for destructor call");
return HandleDestruction(Info, E, *This,
- Info.Ctx.getRecordType(DD->getParent())) &&
+ Info.Ctx.getCanonicalTagType(DD->getParent())) &&
CallScope.destroy();
}
@@ -8512,8 +8514,10 @@ class ExprEvaluatorBase
const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl());
if (!FD) return Error(E);
assert(!FD->getType()->isReferenceType() && "prvalue reference?");
- assert(BaseTy->castAs<RecordType>()->getDecl()->getCanonicalDecl() ==
- FD->getParent()->getCanonicalDecl() && "record / field mismatch");
+ assert(
+ BaseTy->castAs<RecordType>()->getOriginalDecl()->getCanonicalDecl() ==
+ FD->getParent()->getCanonicalDecl() &&
+ "record / field mismatch");
// Note: there is no lvalue base here. But this case should only ever
// happen in C or in C++98, where we cannot be evaluating a constexpr
@@ -8740,8 +8744,10 @@ class LValueExprEvaluatorBase
const ValueDecl *MD = E->getMemberDecl();
if (const FieldDecl *FD = dyn_cast<FieldDecl>(E->getMemberDecl())) {
- assert(BaseTy->castAs<RecordType>()->getDecl()->getCanonicalDecl() ==
- FD->getParent()->getCanonicalDecl() && "record / field mismatch");
+ assert(
+ BaseTy->castAs<RecordType>()->getOriginalDecl()->getCanonicalDecl() ==
+ FD->getParent()->getCanonicalDecl() &&
+ "record / field mismatch");
(void)BaseTy;
if (!HandleLValueMember(this->Info, E, Result, FD))
return false;
@@ -9180,8 +9186,8 @@ bool LValueExprEvaluator::VisitCXXTypeidExpr(const CXXTypeidExpr *E) {
if (!DynType)
return false;
- TypeInfo =
- TypeInfoLValue(Info.Ctx.getRecordType(DynType->Type).getTypePtr());
+ TypeInfo = TypeInfoLValue(
+ Info.Ctx.getCanonicalTagType(DynType->Type).getTypePtr());
}
return Success(APValue::LValueBase::getTypeInfo(TypeInfo, E->getType()));
@@ -10718,7 +10724,8 @@ static bool HandleClassZeroInitialization(EvalInfo &Info, const Expr *E,
}
bool RecordExprEvaluator::ZeroInitialization(const Expr *E, QualType T) {
- const RecordDecl *RD = T->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ T->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isInvalidDecl()) return false;
if (RD->isUnion()) {
// C++11 [dcl.init]p5: If T is a (possibly cv-qualified) union type, the
@@ -10787,8 +10794,10 @@ bool RecordExprEvaluator::VisitInitListExpr(const InitListExpr *E) {
bool RecordExprEvaluator::VisitCXXParenListOrInitListExpr(
const Expr *ExprToVisit, ArrayRef<Expr *> Args) {
- const RecordDecl *RD =
- ExprToVisit->getType()->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD = ExprToVisit->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &Layout = Info.Ctx.getASTRecordLayout(RD);
auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
@@ -11008,7 +11017,10 @@ bool RecordExprEvaluator::VisitCXXStdInitializerListExpr(
Result = APValue(APValue::UninitStruct(), 0, 2);
Array.moveInto(Result.getStructField(0));
- RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *Record = E->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
RecordDecl::field_iterator Field = Record->field_begin();
assert(Field != Record->field_end() &&
Info.Ctx.hasSameType(Field->getType()->getPointeeType(),
@@ -12781,7 +12793,10 @@ static bool convertUnsignedAPIntToCharUnits(const llvm::APInt &Int,
static void addFlexibleArrayMemberInitSize(EvalInfo &Info, const QualType &T,
const LValue &LV, CharUnits &Size) {
if (!T.isNull() && T->isStructureType() &&
- T->getAsStructureType()->getDecl()->hasFlexibleArrayMember())
+ T->getAsStructureType()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember())
if (const auto *V = LV.getLValueBase().dyn_cast<const ValueDecl *>())
if (const auto *VD = dyn_cast<VarDecl>(V))
if (VD->hasInit())
@@ -15028,7 +15043,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
const RecordType *RT = CurrentType->getAs<RecordType>();
if (!RT)
return Error(OOE);
- RecordDecl *RD = RT->getDecl();
+ RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
unsigned i = MemberDecl->getFieldIndex();
@@ -15050,7 +15065,7 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
const RecordType *RT = CurrentType->getAs<RecordType>();
if (!RT)
return Error(OOE);
- RecordDecl *RD = RT->getDecl();
+ RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isInvalidDecl()) return false;
const ASTRecordLayout &RL = Info.Ctx.getASTRecordLayout(RD);
@@ -15061,7 +15076,8 @@ bool IntExprEvaluator::VisitOffsetOfExpr(const OffsetOfExpr *OOE) {
return Error(OOE);
// Add the offset to the base.
- Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(BaseRT->getDecl()));
+ Result += RL.getBaseClassOffset(cast<CXXRecordDecl>(
+ BaseRT->getOriginalDecl()->getDefinitionOrSelf()));
break;
}
}
@@ -15240,7 +15256,7 @@ bool IntExprEvaluator::VisitCastExpr(const CastExpr *E) {
if (Info.Ctx.getLangOpts().CPlusPlus && DestType->isEnumeralType()) {
const EnumType *ET = dyn_cast<EnumType>(DestType.getCanonicalType());
- const EnumDecl *ED = ET->getDecl();
+ const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
// Check that the value is within the range of the enumeration values.
//
// This corressponds to [expr.static.cast]p10 which says:
@@ -17913,7 +17929,8 @@ bool Expr::isPotentialConstantExpr(const FunctionDecl *FD,
// Fabricate an arbitrary expression on the stack and pretend that it
// is a temporary being used as the 'this' pointer.
LValue This;
- ImplicitValueInitExpr VIE(RD ? Info.Ctx.getRecordType(RD) : Info.Ctx.IntTy);
+ ImplicitValueInitExpr VIE(RD ? Info.Ctx.getCanonicalTagType(RD)
+ : Info.Ctx.IntTy);
This.set({&VIE, Info.CurrentCall->Index});
ArrayRef<const Expr*> Args;
diff --git a/clang/lib/AST/FormatString.cpp b/clang/lib/AST/FormatString.cpp
index 5d3b56fc4e713..ffeca9190fc7e 100644
--- a/clang/lib/AST/FormatString.cpp
+++ b/clang/lib/AST/FormatString.cpp
@@ -353,10 +353,11 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
// If the enum is incomplete we know nothing about the underlying type.
// Assume that it's 'int'. Do not use the underlying type for a scoped
// enumeration.
- if (!ETy->getDecl()->isComplete())
+ const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete())
return NoMatch;
if (ETy->isUnscopedEnumerationType())
- argTy = ETy->getDecl()->getIntegerType();
+ argTy = ED->getIntegerType();
}
if (const auto *BT = argTy->getAs<BuiltinType>()) {
@@ -398,10 +399,11 @@ ArgType::matchesType(ASTContext &C, QualType argTy) const {
// If the enum is incomplete we know nothing about the underlying type.
// Assume that it's 'int'. Do not use the underlying type for a scoped
// enumeration as that needs an exact match.
- if (!ETy->getDecl()->isComplete())
+ const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete())
argTy = C.IntTy;
else if (ETy->isUnscopedEnumerationType())
- argTy = ETy->getDecl()->getIntegerType();
+ argTy = ED->getIntegerType();
}
if (argTy->isSaturatedFixedPointType())
diff --git a/clang/lib/AST/InheritViz.cpp b/clang/lib/AST/InheritViz.cpp
index 1dafed837a356..c03492c64b161 100644
--- a/clang/lib/AST/InheritViz.cpp
+++ b/clang/lib/AST/InheritViz.cpp
@@ -89,8 +89,8 @@ void InheritanceHierarchyWriter::WriteNode(QualType Type, bool FromVirtual) {
Out << " \"];\n";
// Display the base classes.
- const auto *Decl =
- static_cast<const CXXRecordDecl *>(Type->castAs<RecordType>()->getDecl());
+ const auto *Decl = static_cast<const CXXRecordDecl *>(
+ Type->castAs<RecordType>()->getOriginalDecl());
for (const auto &Base : Decl->bases()) {
QualType CanonBaseType = Context.getCanonicalType(Base.getType());
@@ -133,7 +133,7 @@ InheritanceHierarchyWriter::WriteNodeReference(QualType Type,
/// viewInheritance - Display the inheritance hierarchy of this C++
/// class using GraphViz.
void CXXRecordDecl::viewInheritance(ASTContext& Context) const {
- QualType Self = Context.getTypeDeclType(this);
+ QualType Self = Context.getCanonicalTagType(this);
int FD;
SmallString<128> Filename;
diff --git a/clang/lib/AST/ItaniumCXXABI.cpp b/clang/lib/AST/ItaniumCXXABI.cpp
index 6ceedd657fe7e..43a8bcd9443ff 100644
--- a/clang/lib/AST/ItaniumCXXABI.cpp
+++ b/clang/lib/AST/ItaniumCXXABI.cpp
@@ -42,10 +42,10 @@ namespace {
///
/// Returns the name of anonymous union VarDecl or nullptr if it is not found.
static const IdentifierInfo *findAnonymousUnionVarDeclName(const VarDecl& VD) {
- const RecordType *RT = VD.getType()->getAs<RecordType>();
- assert(RT && "type of VarDecl is expected to be RecordType.");
- assert(RT->getDecl()->isUnion() && "RecordType is expected to be a union.");
- if (const FieldDecl *FD = RT->getDecl()->findFirstNamedDataMember()) {
+ const auto *RT = VD.getType()->castAs<RecordType>();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ assert(RD->isUnion() && "RecordType is expected to be a union.");
+ if (const FieldDecl *FD = RD->findFirstNamedDataMember()) {
return FD->getIdentifier();
}
diff --git a/clang/lib/AST/ItaniumMangle.cpp b/clang/lib/AST/ItaniumMangle.cpp
index 8a1d4e8313e28..a2f964a71b90c 100644
--- a/clang/lib/AST/ItaniumMangle.cpp
+++ b/clang/lib/AST/ItaniumMangle.cpp
@@ -463,9 +463,7 @@ class CXXNameMangler {
void mangleVendorType(StringRef Name);
private:
-
bool mangleSubstitution(const NamedDecl *ND);
- bool mangleSubstitution(NestedNameSpecifier *NNS);
bool mangleSubstitution(QualType T);
bool mangleSubstitution(TemplateName Template);
bool mangleSubstitution(uintptr_t Ptr);
@@ -479,21 +477,15 @@ class CXXNameMangler {
addSubstitution(reinterpret_cast<uintptr_t>(ND));
}
- void addSubstitution(NestedNameSpecifier *NNS) {
- NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
-
- addSubstitution(reinterpret_cast<uintptr_t>(NNS));
- }
void addSubstitution(QualType T);
void addSubstitution(TemplateName Template);
void addSubstitution(uintptr_t Ptr);
// Destructive copy substitutions from other mangler.
void extendSubstitutions(CXXNameMangler* Other);
- void mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
+ void mangleUnresolvedPrefix(NestedNameSpecifier Qualifier,
bool recursive = false);
- void mangleUnresolvedName(NestedNameSpecifier *qualifier,
- DeclarationName name,
+ void mangleUnresolvedName(NestedNameSpecifier Qualifier, DeclarationName name,
const TemplateArgumentLoc *TemplateArgs,
unsigned NumTemplateArgs,
unsigned KnownArity = UnknownArity);
@@ -542,7 +534,7 @@ class CXXNameMangler {
void mangleNestedNameWithClosurePrefix(GlobalDecl GD,
const NamedDecl *PrefixND,
const AbiTagList *AdditionalAbiTags);
- void manglePrefix(NestedNameSpecifier *qualifier);
+ void manglePrefix(NestedNameSpecifier Qualifier);
void manglePrefix(const DeclContext *DC, bool NoFunction=false);
void manglePrefix(QualType type);
void mangleTemplatePrefix(GlobalDecl GD, bool NoFunction=false);
@@ -588,12 +580,10 @@ class CXXNameMangler {
void mangleMemberExprBase(const Expr *base, bool isArrow);
void mangleMemberExpr(const Expr *base, bool isArrow,
- NestedNameSpecifier *qualifier,
- NamedDecl *firstQualifierLookup,
- DeclarationName name,
+ NestedNameSpecifier Qualifier,
+ NamedDecl *firstQualifierLookup, DeclarationName name,
const TemplateArgumentLoc *TemplateArgs,
- unsigned NumTemplateArgs,
- unsigned knownArity);
+ unsigned NumTemplateArgs, unsigned knownArity);
void mangleCastExpression(const Expr *E, StringRef CastEncoding);
void mangleInitListElements(const InitListExpr *InitList);
void mangleRequirement(SourceLocation RequiresExprLoc,
@@ -1331,6 +1321,21 @@ void CXXNameMangler::manglePrefix(QualType type) {
mangleTemplateArgs(Template, DTST->template_arguments());
addSubstitution(QualType(DTST, 0));
}
+ } else if (const auto *DNT = type->getAs<DependentNameType>()) {
+ // Clang 14 and before did not consider this substitutable.
+ bool Clang14Compat = isCompatibleWith(LangOptions::ClangABI::Ver14);
+ if (!Clang14Compat && mangleSubstitution(QualType(DNT, 0)))
+ return;
+
+ // Member expressions can have these without prefixes, but that
+ // should end up in mangleUnresolvedPrefix instead.
+ assert(DNT->getQualifier());
+ manglePrefix(DNT->getQualifier());
+
+ mangleSourceName(DNT->getIdentifier());
+
+ if (!Clang14Compat)
+ addSubstitution(QualType(DNT, 0));
} else {
// We use the QualType mangle type variant here because it handles
// substitutions.
@@ -1342,7 +1347,7 @@ void CXXNameMangler::manglePrefix(QualType type) {
///
/// \param recursive - true if this is being called recursively,
/// i.e. if there is more prefix "to the right".
-void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
+void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier Qualifier,
bool recursive) {
// x, ::x
@@ -1359,8 +1364,11 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
// <unresolved-name> ::= [gs] sr <unresolved-qualifier-level>+ E
// <base-unresolved-name>
- switch (qualifier->getKind()) {
- case NestedNameSpecifier::Global:
+ switch (Qualifier.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
+
+ case NestedNameSpecifier::Kind::Global:
Out << "gs";
// We want an 'sr' unless this is the entire NNS.
@@ -1370,35 +1378,29 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
// We never want an 'E' here.
return;
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Super:
llvm_unreachable("Can't mangle __super specifier");
- case NestedNameSpecifier::Namespace:
- if (qualifier->getPrefix())
- mangleUnresolvedPrefix(qualifier->getPrefix(),
- /*recursive*/ true);
- else
- Out << "sr";
- mangleSourceNameWithAbiTags(qualifier->getAsNamespace());
- break;
- case NestedNameSpecifier::NamespaceAlias:
- if (qualifier->getPrefix())
- mangleUnresolvedPrefix(qualifier->getPrefix(),
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = Qualifier.getAsNamespaceAndPrefix();
+ if (Prefix)
+ mangleUnresolvedPrefix(Prefix,
/*recursive*/ true);
else
Out << "sr";
- mangleSourceNameWithAbiTags(qualifier->getAsNamespaceAlias());
+ mangleSourceNameWithAbiTags(Namespace);
break;
+ }
- case NestedNameSpecifier::TypeSpec: {
- const Type *type = qualifier->getAsType();
+ case NestedNameSpecifier::Kind::Type: {
+ const Type *type = Qualifier.getAsType();
// We only want to use an unresolved-type encoding if this is one of:
// - a decltype
// - a template type parameter
// - a template template parameter with arguments
// In all of these cases, we should have no prefix.
- if (NestedNameSpecifier *Prefix = qualifier->getPrefix()) {
+ if (NestedNameSpecifier Prefix = type->getPrefix()) {
mangleUnresolvedPrefix(Prefix,
/*recursive=*/true);
} else {
@@ -1411,18 +1413,6 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
break;
}
-
- case NestedNameSpecifier::Identifier:
- // Member expressions can have these without prefixes.
- if (qualifier->getPrefix())
- mangleUnresolvedPrefix(qualifier->getPrefix(),
- /*recursive*/ true);
- else
- Out << "sr";
-
- mangleSourceName(qualifier->getAsIdentifier());
- // An Identifier has no type information, so we can't emit abi tags for it.
- break;
}
// If this was the innermost part of the NNS, and we fell out to
@@ -1434,10 +1424,11 @@ void CXXNameMangler::mangleUnresolvedPrefix(NestedNameSpecifier *qualifier,
/// Mangle an unresolved-name, which is generally used for names which
/// weren't resolved to specific entities.
void CXXNameMangler::mangleUnresolvedName(
- NestedNameSpecifier *qualifier, DeclarationName name,
+ NestedNameSpecifier Qualifier, DeclarationName name,
const TemplateArgumentLoc *TemplateArgs, unsigned NumTemplateArgs,
unsigned knownArity) {
- if (qualifier) mangleUnresolvedPrefix(qualifier);
+ if (Qualifier)
+ mangleUnresolvedPrefix(Qualifier);
switch (name.getNameKind()) {
// <base-unresolved-name> ::= <simple-id>
case DeclarationName::Identifier:
@@ -1586,7 +1577,10 @@ void CXXNameMangler::mangleUnqualifiedName(
if (const VarDecl *VD = dyn_cast<VarDecl>(ND)) {
// We must have an anonymous union or struct declaration.
- const RecordDecl *RD = VD->getType()->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD = VD->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
// Itanium C++ ABI 5.1.2:
//
@@ -2172,53 +2166,22 @@ void CXXNameMangler::mangleLambdaSig(const CXXRecordDecl *Lambda) {
Lambda->getLambdaStaticInvoker());
}
-void CXXNameMangler::manglePrefix(NestedNameSpecifier *qualifier) {
- switch (qualifier->getKind()) {
- case NestedNameSpecifier::Global:
+void CXXNameMangler::manglePrefix(NestedNameSpecifier Qualifier) {
+ switch (Qualifier.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
// nothing
return;
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Super:
llvm_unreachable("Can't mangle __super specifier");
- case NestedNameSpecifier::Namespace:
- mangleName(qualifier->getAsNamespace());
+ case NestedNameSpecifier::Kind::Namespace:
+ mangleName(Qualifier.getAsNamespaceAndPrefix().Namespace->getNamespace());
return;
- case NestedNameSpecifier::NamespaceAlias:
- mangleName(qualifier->getAsNamespaceAlias()->getNamespace());
- return;
-
- case NestedNameSpecifier::TypeSpec:
- if (NestedNameSpecifier *Prefix = qualifier->getPrefix()) {
- const auto *DTST =
- cast<DependentTemplateSpecializationType>(qualifier->getAsType());
- QualType NewT = getASTContext().getDependentTemplateSpecializationType(
- DTST->getKeyword(),
- {Prefix, DTST->getDependentTemplateName().getName(),
- /*HasTemplateKeyword=*/true},
- DTST->template_arguments(), /*IsCanonical=*/true);
- manglePrefix(NewT);
- return;
- }
- manglePrefix(QualType(qualifier->getAsType(), 0));
- return;
-
- case NestedNameSpecifier::Identifier:
- // Clang 14 and before did not consider this substitutable.
- bool Clang14Compat = isCompatibleWith(LangOptions::ClangABI::Ver14);
- if (!Clang14Compat && mangleSubstitution(qualifier))
- return;
-
- // Member expressions can have these without prefixes, but that
- // should end up in mangleUnresolvedPrefix instead.
- assert(qualifier->getPrefix());
- manglePrefix(qualifier->getPrefix());
-
- mangleSourceName(qualifier->getAsIdentifier());
-
- if (!Clang14Compat)
- addSubstitution(qualifier);
+ case NestedNameSpecifier::Kind::Type:
+ manglePrefix(QualType(Qualifier.getAsType(), 0));
return;
}
@@ -2278,8 +2241,7 @@ void CXXNameMangler::mangleTemplatePrefix(TemplateName Template) {
if (!Clang11Compat && mangleSubstitution(Template))
return;
- if (NestedNameSpecifier *Qualifier = Dependent->getQualifier())
- manglePrefix(Qualifier);
+ manglePrefix(Dependent->getQualifier());
if (Clang11Compat && mangleSubstitution(Template))
return;
@@ -2530,7 +2492,8 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::Enum:
case Type::Record:
- mangleSourceNameWithAbiTags(cast<TagType>(Ty)->getDecl());
+ mangleSourceNameWithAbiTags(
+ cast<TagType>(Ty)->getOriginalDecl()->getDefinitionOrSelf());
break;
case Type::TemplateSpecialization: {
@@ -2591,8 +2554,9 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
}
case Type::InjectedClassName:
- mangleSourceNameWithAbiTags(
- cast<InjectedClassNameType>(Ty)->getDecl());
+ mangleSourceNameWithAbiTags(cast<InjectedClassNameType>(Ty)
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf());
break;
case Type::DependentName:
@@ -2613,9 +2577,6 @@ bool CXXNameMangler::mangleUnresolvedTypeOrSimpleId(QualType Ty,
case Type::Using:
return mangleUnresolvedTypeOrSimpleId(cast<UsingType>(Ty)->desugar(),
Prefix);
- case Type::Elaborated:
- return mangleUnresolvedTypeOrSimpleId(
- cast<ElaboratedType>(Ty)->getNamedType(), Prefix);
}
return false;
@@ -3843,7 +3804,7 @@ void CXXNameMangler::mangleType(const RecordType *T) {
mangleType(static_cast<const TagType*>(T));
}
void CXXNameMangler::mangleType(const TagType *T) {
- mangleName(T->getDecl());
+ mangleName(T->getOriginalDecl()->getDefinitionOrSelf());
}
// <type> ::= <array-type>
@@ -3880,16 +3841,10 @@ void CXXNameMangler::mangleType(const IncompleteArrayType *T) {
// <pointer-to-member-type> ::= M <class type> <member type>
void CXXNameMangler::mangleType(const MemberPointerType *T) {
Out << 'M';
- if (auto *RD = T->getMostRecentCXXRecordDecl()) {
+ if (auto *RD = T->getMostRecentCXXRecordDecl())
mangleCXXRecordDecl(RD);
- } else {
- NestedNameSpecifier *NNS = T->getQualifier();
- if (auto *II = NNS->getAsIdentifier())
- mangleType(getASTContext().getDependentNameType(
- ElaboratedTypeKeyword::None, NNS->getPrefix(), II));
- else
- manglePrefix(NNS);
- }
+ else
+ mangleType(QualType(T->getQualifier().getAsType(), 0));
QualType PointeeType = T->getPointeeType();
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(PointeeType)) {
mangleType(FPT);
@@ -4476,7 +4431,7 @@ void CXXNameMangler::mangleType(const InjectedClassNameType *T) {
// Mangle injected class name types as if the user had written the
// specialization out fully. It may not actually be possible to see
// this mangling, though.
- mangleType(T->getInjectedSpecializationType());
+ mangleType(T->getCanonicalInjectedTST());
}
void CXXNameMangler::mangleType(const TemplateSpecializationType *T) {
@@ -4752,7 +4707,7 @@ void CXXNameMangler::mangleIntegerLiteral(QualType T,
void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) {
// Ignore member expressions involving anonymous unions.
while (const auto *RT = Base->getType()->getAs<RecordType>()) {
- if (!RT->getDecl()->isAnonymousStructOrUnion())
+ if (!RT->getOriginalDecl()->isAnonymousStructOrUnion())
break;
const auto *ME = dyn_cast<MemberExpr>(Base);
if (!ME)
@@ -4773,9 +4728,8 @@ void CXXNameMangler::mangleMemberExprBase(const Expr *Base, bool IsArrow) {
}
/// Mangles a member expression.
-void CXXNameMangler::mangleMemberExpr(const Expr *base,
- bool isArrow,
- NestedNameSpecifier *qualifier,
+void CXXNameMangler::mangleMemberExpr(const Expr *base, bool isArrow,
+ NestedNameSpecifier Qualifier,
NamedDecl *firstQualifierLookup,
DeclarationName member,
const TemplateArgumentLoc *TemplateArgs,
@@ -4785,7 +4739,7 @@ void CXXNameMangler::mangleMemberExpr(const Expr *base,
// ::= pt <expression> <unresolved-name>
if (base)
mangleMemberExprBase(base, isArrow);
- mangleUnresolvedName(qualifier, member, TemplateArgs, NumTemplateArgs, arity);
+ mangleUnresolvedName(Qualifier, member, TemplateArgs, NumTemplateArgs, arity);
}
/// Look at the callee of the given call expression and determine if
@@ -5235,7 +5189,7 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
const auto *PDE = cast<CXXPseudoDestructorExpr>(E);
if (const Expr *Base = PDE->getBase())
mangleMemberExprBase(Base, PDE->isArrow());
- NestedNameSpecifier *Qualifier = PDE->getQualifier();
+ NestedNameSpecifier Qualifier = PDE->getQualifier();
if (TypeSourceInfo *ScopeInfo = PDE->getScopeTypeInfo()) {
if (Qualifier) {
mangleUnresolvedPrefix(Qualifier,
@@ -5860,7 +5814,8 @@ void CXXNameMangler::mangleExpression(const Expr *E, unsigned Arity,
// externally-visible declaration, so there's no standard mangling for
// this, but mangling as a literal of the closure type seems reasonable.
Out << "L";
- mangleType(Context.getASTContext().getRecordType(cast<LambdaExpr>(E)->getLambdaClass()));
+ mangleType(Context.getASTContext().getCanonicalTagType(
+ cast<LambdaExpr>(E)->getLambdaClass()));
Out << "E";
break;
}
@@ -6533,7 +6488,7 @@ static QualType getLValueType(ASTContext &Ctx, const APValue &LV) {
dyn_cast<FieldDecl>(E.getAsBaseOrMember().getPointer()))
T = FD->getType();
else
- T = Ctx.getRecordType(
+ T = Ctx.getCanonicalTagType(
cast<CXXRecordDecl>(E.getAsBaseOrMember().getPointer()));
}
return T;
@@ -6900,7 +6855,7 @@ void CXXNameMangler::mangleValueInTemplateArg(QualType T, const APValue &V,
}
TypeSoFar = FD->getType();
} else {
- TypeSoFar = Ctx.getRecordType(cast<CXXRecordDecl>(D));
+ TypeSoFar = Ctx.getCanonicalTagType(cast<CXXRecordDecl>(D));
}
}
}
@@ -7010,14 +6965,6 @@ bool CXXNameMangler::mangleSubstitution(const NamedDecl *ND) {
return mangleSubstitution(reinterpret_cast<uintptr_t>(ND));
}
-bool CXXNameMangler::mangleSubstitution(NestedNameSpecifier *NNS) {
- assert(NNS->getKind() == NestedNameSpecifier::Identifier &&
- "mangleSubstitution(NestedNameSpecifier *) is only used for "
- "identifier nested name specifiers.");
- NNS = Context.getASTContext().getCanonicalNestedNameSpecifier(NNS);
- return mangleSubstitution(reinterpret_cast<uintptr_t>(NNS));
-}
-
/// Determine whether the given type has any qualifiers that are relevant for
/// substitutions.
static bool hasMangledSubstitutionQualifiers(QualType T) {
@@ -7028,7 +6975,7 @@ static bool hasMangledSubstitutionQualifiers(QualType T) {
bool CXXNameMangler::mangleSubstitution(QualType T) {
if (!hasMangledSubstitutionQualifiers(T)) {
if (const RecordType *RT = T->getAs<RecordType>())
- return mangleSubstitution(RT->getDecl());
+ return mangleSubstitution(RT->getOriginalDecl()->getDefinitionOrSelf());
}
uintptr_t TypePtr = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr());
@@ -7069,7 +7016,7 @@ bool CXXNameMangler::isSpecializedAs(QualType S, llvm::StringRef Name,
return false;
const ClassTemplateSpecializationDecl *SD =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
if (!SD || !SD->getIdentifier()->isStr(Name))
return false;
@@ -7199,7 +7146,7 @@ bool CXXNameMangler::mangleStandardSubstitution(const NamedDecl *ND) {
void CXXNameMangler::addSubstitution(QualType T) {
if (!hasMangledSubstitutionQualifiers(T)) {
if (const RecordType *RT = T->getAs<RecordType>()) {
- addSubstitution(RT->getDecl());
+ addSubstitution(RT->getOriginalDecl()->getDefinitionOrSelf());
return;
}
}
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index 64ddb1e739347..b3f12a1cce2ec 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -395,8 +395,8 @@ llvm::json::Array JSONNodeDumper::createCastPath(const CastExpr *C) {
for (auto I = C->path_begin(), E = C->path_end(); I != E; ++I) {
const CXXBaseSpecifier *Base = *I;
- const auto *RD =
- cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
+ const auto *RD = cast<CXXRecordDecl>(
+ Base->getType()->castAs<RecordType>()->getOriginalDecl());
llvm::json::Object Val{{"name", RD->getName()}};
if (Base->isVirtual())
@@ -606,9 +606,8 @@ void JSONNodeDumper::VisitTypedefType(const TypedefType *TT) {
}
void JSONNodeDumper::VisitUsingType(const UsingType *TT) {
- JOS.attribute("decl", createBareDeclRef(TT->getFoundDecl()));
- if (!TT->typeMatchesDecl())
- JOS.attribute("type", createQualType(TT->desugar()));
+ JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
+ JOS.attribute("type", createQualType(TT->desugar()));
}
void JSONNodeDumper::VisitFunctionType(const FunctionType *T) {
@@ -759,7 +758,15 @@ void JSONNodeDumper::VisitUnaryTransformType(const UnaryTransformType *UTT) {
}
void JSONNodeDumper::VisitTagType(const TagType *TT) {
- JOS.attribute("decl", createBareDeclRef(TT->getDecl()));
+ if (NestedNameSpecifier Qualifier = TT->getQualifier()) {
+ std::string Str;
+ llvm::raw_string_ostream OS(Str);
+ Qualifier.print(OS, PrintPolicy, /*ResolveTemplateArguments=*/true);
+ JOS.attribute("qualifier", Str);
+ }
+ JOS.attribute("decl", createBareDeclRef(TT->getOriginalDecl()));
+ if (TT->isTagOwned())
+ JOS.attribute("isTagOwned", true);
}
void JSONNodeDumper::VisitTemplateTypeParmType(
@@ -809,7 +816,7 @@ void JSONNodeDumper::VisitTemplateSpecializationType(
void JSONNodeDumper::VisitInjectedClassNameType(
const InjectedClassNameType *ICNT) {
- JOS.attribute("decl", createBareDeclRef(ICNT->getDecl()));
+ JOS.attribute("decl", createBareDeclRef(ICNT->getOriginalDecl()));
}
void JSONNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *OIT) {
@@ -821,17 +828,6 @@ void JSONNodeDumper::VisitPackExpansionType(const PackExpansionType *PET) {
JOS.attribute("numExpansions", *N);
}
-void JSONNodeDumper::VisitElaboratedType(const ElaboratedType *ET) {
- if (const NestedNameSpecifier *NNS = ET->getQualifier()) {
- std::string Str;
- llvm::raw_string_ostream OS(Str);
- NNS->print(OS, PrintPolicy, /*ResolveTemplateArgs*/ true);
- JOS.attribute("qualifier", Str);
- }
- if (const TagDecl *TD = ET->getOwnedTagDecl())
- JOS.attribute("ownedTagDecl", createBareDeclRef(TD));
-}
-
void JSONNodeDumper::VisitMacroQualifiedType(const MacroQualifiedType *MQT) {
JOS.attribute("macroName", MQT->getMacroIdentifier()->getName());
}
@@ -902,9 +898,9 @@ void JSONNodeDumper::VisitNamespaceAliasDecl(const NamespaceAliasDecl *NAD) {
void JSONNodeDumper::VisitUsingDecl(const UsingDecl *UD) {
std::string Name;
- if (const NestedNameSpecifier *NNS = UD->getQualifier()) {
+ if (NestedNameSpecifier Qualifier = UD->getQualifier()) {
llvm::raw_string_ostream SOS(Name);
- NNS->print(SOS, UD->getASTContext().getPrintingPolicy());
+ Qualifier.print(SOS, UD->getASTContext().getPrintingPolicy());
}
Name += UD->getNameAsString();
JOS.attribute("name", Name);
diff --git a/clang/lib/AST/MicrosoftMangle.cpp b/clang/lib/AST/MicrosoftMangle.cpp
index bc47e0506add0..1d17f75b8c53a 100644
--- a/clang/lib/AST/MicrosoftMangle.cpp
+++ b/clang/lib/AST/MicrosoftMangle.cpp
@@ -1806,17 +1806,16 @@ void MicrosoftCXXNameMangler::mangleTemplateArg(const TemplateDecl *TD,
case TemplateArgument::Declaration: {
const NamedDecl *ND = TA.getAsDecl();
if (isa<FieldDecl>(ND) || isa<IndirectFieldDecl>(ND)) {
- mangleMemberDataPointer(cast<CXXRecordDecl>(ND->getDeclContext())
- ->getMostRecentNonInjectedDecl(),
- cast<ValueDecl>(ND),
- cast<NonTypeTemplateParmDecl>(Parm),
- TA.getParamTypeForDecl());
+ mangleMemberDataPointer(
+ cast<CXXRecordDecl>(ND->getDeclContext())->getMostRecentDecl(),
+ cast<ValueDecl>(ND), cast<NonTypeTemplateParmDecl>(Parm),
+ TA.getParamTypeForDecl());
} else if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(ND)) {
const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD);
if (MD && MD->isInstance()) {
- mangleMemberFunctionPointer(
- MD->getParent()->getMostRecentNonInjectedDecl(), MD,
- cast<NonTypeTemplateParmDecl>(Parm), TA.getParamTypeForDecl());
+ mangleMemberFunctionPointer(MD->getParent()->getMostRecentDecl(), MD,
+ cast<NonTypeTemplateParmDecl>(Parm),
+ TA.getParamTypeForDecl());
} else {
mangleFunctionPointer(FD, cast<NonTypeTemplateParmDecl>(Parm),
TA.getParamTypeForDecl());
@@ -2022,7 +2021,7 @@ void MicrosoftCXXNameMangler::mangleTemplateArgValue(QualType T,
if (RD->isAnonymousStructOrUnion())
continue;
} else {
- ET = getASTContext().getRecordType(cast<CXXRecordDecl>(D));
+ ET = getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));
// Bug in MSVC: fully qualified name of base class should be used for
// mangling to prevent collisions e.g. on base classes with same names
// in different namespaces.
@@ -3248,11 +3247,11 @@ void MicrosoftCXXNameMangler::mangleTagTypeKind(TagTypeKind TTK) {
}
void MicrosoftCXXNameMangler::mangleType(const EnumType *T, Qualifiers,
SourceRange) {
- mangleType(cast<TagType>(T)->getDecl());
+ mangleType(cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf());
}
void MicrosoftCXXNameMangler::mangleType(const RecordType *T, Qualifiers,
SourceRange) {
- mangleType(cast<TagType>(T)->getDecl());
+ mangleType(cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf());
}
void MicrosoftCXXNameMangler::mangleType(const TagDecl *TD) {
mangleTagTypeKind(TD->getTagKind());
diff --git a/clang/lib/AST/NestedNameSpecifier.cpp b/clang/lib/AST/NestedNameSpecifier.cpp
index db1ad89565189..b91aa011dd024 100644
--- a/clang/lib/AST/NestedNameSpecifier.cpp
+++ b/clang/lib/AST/NestedNameSpecifier.cpp
@@ -15,7 +15,6 @@
#include "clang/AST/ASTContext.h"
#include "clang/AST/Decl.h"
#include "clang/AST/DeclCXX.h"
-#include "clang/AST/DeclTemplate.h"
#include "clang/AST/DependenceFlags.h"
#include "clang/AST/PrettyPrinter.h"
#include "clang/AST/TemplateName.h"
@@ -35,416 +34,118 @@
using namespace clang;
-NestedNameSpecifier *
-NestedNameSpecifier::FindOrInsert(const ASTContext &Context,
- const NestedNameSpecifier &Mockup) {
+const NamespaceAndPrefixStorage *
+NestedNameSpecifier::MakeNamespaceAndPrefixStorage(
+ const ASTContext &Ctx, const NamespaceBaseDecl *Namespace,
+ NestedNameSpecifier Prefix) {
llvm::FoldingSetNodeID ID;
- Mockup.Profile(ID);
+ NamespaceAndPrefixStorage::Profile(ID, Namespace, Prefix);
void *InsertPos = nullptr;
- NestedNameSpecifier *NNS
- = Context.NestedNameSpecifiers.FindNodeOrInsertPos(ID, InsertPos);
- if (!NNS) {
- NNS =
- new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier(Mockup);
- Context.NestedNameSpecifiers.InsertNode(NNS, InsertPos);
+ NamespaceAndPrefixStorage *S =
+ Ctx.NamespaceAndPrefixStorages.FindNodeOrInsertPos(ID, InsertPos);
+ if (!S) {
+ S = new (Ctx, alignof(NamespaceAndPrefixStorage))
+ NamespaceAndPrefixStorage(Namespace, Prefix);
+ Ctx.NamespaceAndPrefixStorages.InsertNode(S, InsertPos);
}
-
- return NNS;
-}
-
-NestedNameSpecifier *NestedNameSpecifier::Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const IdentifierInfo *II) {
- assert(II && "Identifier cannot be NULL");
- assert((!Prefix || Prefix->isDependent()) && "Prefix must be dependent");
-
- NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(StoredIdentifier);
- Mockup.Specifier = const_cast<IdentifierInfo *>(II);
- return FindOrInsert(Context, Mockup);
-}
-
-NestedNameSpecifier *
-NestedNameSpecifier::Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceDecl *NS) {
- assert(NS && "Namespace cannot be NULL");
- assert((!Prefix ||
- (Prefix->getAsType() == nullptr &&
- Prefix->getAsIdentifier() == nullptr)) &&
- "Broken nested name specifier");
- NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(StoredDecl);
- Mockup.Specifier = const_cast<NamespaceDecl *>(NS);
- return FindOrInsert(Context, Mockup);
-}
-
-NestedNameSpecifier *
-NestedNameSpecifier::Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const NamespaceAliasDecl *Alias) {
- assert(Alias && "Namespace alias cannot be NULL");
- assert((!Prefix ||
- (Prefix->getAsType() == nullptr &&
- Prefix->getAsIdentifier() == nullptr)) &&
- "Broken nested name specifier");
- NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(StoredDecl);
- Mockup.Specifier = const_cast<NamespaceAliasDecl *>(Alias);
- return FindOrInsert(Context, Mockup);
-}
-
-NestedNameSpecifier *NestedNameSpecifier::Create(const ASTContext &Context,
- NestedNameSpecifier *Prefix,
- const Type *T) {
- assert(T && "Type cannot be NULL");
- NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(Prefix);
- Mockup.Prefix.setInt(StoredTypeSpec);
- Mockup.Specifier = const_cast<Type*>(T);
- return FindOrInsert(Context, Mockup);
-}
-
-NestedNameSpecifier *NestedNameSpecifier::Create(const ASTContext &Context,
- const IdentifierInfo *II) {
- assert(II && "Identifier cannot be NULL");
- NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(nullptr);
- Mockup.Prefix.setInt(StoredIdentifier);
- Mockup.Specifier = const_cast<IdentifierInfo *>(II);
- return FindOrInsert(Context, Mockup);
-}
-
-NestedNameSpecifier *
-NestedNameSpecifier::GlobalSpecifier(const ASTContext &Context) {
- if (!Context.GlobalNestedNameSpecifier)
- Context.GlobalNestedNameSpecifier =
- new (Context, alignof(NestedNameSpecifier)) NestedNameSpecifier();
- return Context.GlobalNestedNameSpecifier;
-}
-
-NestedNameSpecifier *
-NestedNameSpecifier::SuperSpecifier(const ASTContext &Context,
- CXXRecordDecl *RD) {
- NestedNameSpecifier Mockup;
- Mockup.Prefix.setPointer(nullptr);
- Mockup.Prefix.setInt(StoredDecl);
- Mockup.Specifier = RD;
- return FindOrInsert(Context, Mockup);
+ return S;
}
-NestedNameSpecifier::SpecifierKind NestedNameSpecifier::getKind() const {
- if (!Specifier)
- return Global;
-
- switch (Prefix.getInt()) {
- case StoredIdentifier:
- return Identifier;
-
- case StoredDecl: {
- NamedDecl *ND = static_cast<NamedDecl *>(Specifier);
- if (isa<CXXRecordDecl>(ND))
- return Super;
- return isa<NamespaceDecl>(ND) ? Namespace : NamespaceAlias;
- }
-
- case StoredTypeSpec:
- return TypeSpec;
- }
-
- llvm_unreachable("Invalid NNS Kind!");
-}
-
-/// Retrieve the namespace stored in this nested name specifier.
-NamespaceDecl *NestedNameSpecifier::getAsNamespace() const {
- if (Prefix.getInt() == StoredDecl)
- return dyn_cast<NamespaceDecl>(static_cast<NamedDecl *>(Specifier));
-
- return nullptr;
-}
-
-/// Retrieve the namespace alias stored in this nested name specifier.
-NamespaceAliasDecl *NestedNameSpecifier::getAsNamespaceAlias() const {
- if (Prefix.getInt() == StoredDecl)
- return dyn_cast<NamespaceAliasDecl>(static_cast<NamedDecl *>(Specifier));
-
- return nullptr;
-}
-
-/// Retrieve the record declaration stored in this nested name specifier.
-CXXRecordDecl *NestedNameSpecifier::getAsRecordDecl() const {
- switch (Prefix.getInt()) {
- case StoredIdentifier:
- return nullptr;
-
- case StoredDecl:
- return dyn_cast<CXXRecordDecl>(static_cast<NamedDecl *>(Specifier));
-
- case StoredTypeSpec:
- return getAsType()->getAsCXXRecordDecl();
+bool NestedNameSpecifier::isFullyQualified() const {
+ switch (getKind()) {
+ case NestedNameSpecifier::Kind::Global:
+ return true;
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Super:
+ return false;
+ case NestedNameSpecifier::Kind::Namespace:
+ return getAsNamespaceAndPrefix().Prefix.isFullyQualified();
+ case NestedNameSpecifier::Kind::Type:
+ return getAsType()->getPrefix().isFullyQualified();
}
-
llvm_unreachable("Invalid NNS Kind!");
}
NestedNameSpecifierDependence NestedNameSpecifier::getDependence() const {
switch (getKind()) {
- case Identifier: {
- // Identifier specifiers always represent dependent types
- auto F = NestedNameSpecifierDependence::Dependent |
- NestedNameSpecifierDependence::Instantiation;
- // Prefix can contain unexpanded template parameters.
- if (getPrefix())
- return F | getPrefix()->getDependence();
- return F;
- }
-
- case Namespace:
- case NamespaceAlias:
- case Global:
- return NestedNameSpecifierDependence::None;
-
- case Super: {
- CXXRecordDecl *RD = static_cast<CXXRecordDecl *>(Specifier);
- for (const auto &Base : RD->bases())
- if (Base.getType()->isDependentType())
- // FIXME: must also be instantiation-dependent.
- return NestedNameSpecifierDependence::Dependent;
+ case Kind::Null:
+ case Kind::Global:
+ case Kind::Namespace:
return NestedNameSpecifierDependence::None;
+ case Kind::Super: {
+ CXXRecordDecl *RD = getAsSuper();
+ return RD->isDependentContext()
+ ? NestedNameSpecifierDependence::DependentInstantiation |
+ NestedNameSpecifierDependence::Dependent
+ : NestedNameSpecifierDependence::None;
}
-
- case TypeSpec: {
- NestedNameSpecifierDependence Dep =
- toNestedNameSpecifierDependendence(getAsType()->getDependence());
- if (NestedNameSpecifier *Prefix = getPrefix())
- Dep |=
- Prefix->getDependence() & ~NestedNameSpecifierDependence::Dependent;
- return Dep;
- }
+ case Kind::Type:
+ return toNestedNameSpecifierDependence(getAsType()->getDependence());
}
llvm_unreachable("Invalid NNS Kind!");
}
-bool NestedNameSpecifier::isDependent() const {
- return getDependence() & NestedNameSpecifierDependence::Dependent;
-}
-
-bool NestedNameSpecifier::isInstantiationDependent() const {
- return getDependence() & NestedNameSpecifierDependence::Instantiation;
-}
-
-bool NestedNameSpecifier::containsUnexpandedParameterPack() const {
- return getDependence() & NestedNameSpecifierDependence::UnexpandedPack;
-}
-
-bool NestedNameSpecifier::containsErrors() const {
- return getDependence() & NestedNameSpecifierDependence::Error;
-}
-
-const Type *
-NestedNameSpecifier::translateToType(const ASTContext &Context) const {
- NestedNameSpecifier *Prefix = getPrefix();
- switch (getKind()) {
- case SpecifierKind::Identifier:
- return Context
- .getDependentNameType(ElaboratedTypeKeyword::None, Prefix,
- getAsIdentifier())
- .getTypePtr();
- case SpecifierKind::TypeSpec: {
- const Type *T = getAsType();
- switch (T->getTypeClass()) {
- case Type::DependentTemplateSpecialization: {
- const auto *DT = cast<DependentTemplateSpecializationType>(T);
- const DependentTemplateStorage &DTN = DT->getDependentTemplateName();
- return Context
- .getDependentTemplateSpecializationType(
- ElaboratedTypeKeyword::None,
- {Prefix, DTN.getName(), DTN.hasTemplateKeyword()},
- DT->template_arguments())
- .getTypePtr();
- }
- case Type::Record:
- case Type::TemplateSpecialization:
- case Type::Using:
- case Type::Enum:
- case Type::Typedef:
- case Type::UnresolvedUsing:
- return Context
- .getElaboratedType(ElaboratedTypeKeyword::None, Prefix,
- QualType(T, 0))
- .getTypePtr();
- default:
- assert(Prefix == nullptr && "unexpected type with elaboration");
- return T;
- }
- }
- case SpecifierKind::Global:
- case SpecifierKind::Namespace:
- case SpecifierKind::NamespaceAlias:
- case SpecifierKind::Super:
- // These are not representable as types.
- return nullptr;
- }
- llvm_unreachable("Unhandled SpecifierKind enum");
-}
-
/// Print this nested name specifier to the given output
/// stream.
void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
bool ResolveTemplateArguments,
bool PrintFinalScopeResOp) const {
- if (getPrefix())
- getPrefix()->print(OS, Policy);
-
switch (getKind()) {
- case Identifier:
- OS << getAsIdentifier()->getName();
- break;
-
- case Namespace:
- if (getAsNamespace()->isAnonymousNamespace())
- return;
-
- OS << getAsNamespace()->getName();
- break;
-
- case NamespaceAlias:
- OS << getAsNamespaceAlias()->getName();
+ case Kind::Namespace: {
+ auto [Namespace, Prefix] = getAsNamespaceAndPrefix();
+ Prefix.print(OS, Policy);
+ if (const auto *NS = dyn_cast<NamespaceDecl>(Namespace)) {
+ assert(!NS->isAnonymousNamespace());
+ OS << NS->getName();
+ } else {
+ OS << cast<NamespaceAliasDecl>(Namespace)->getName();
+ }
break;
-
- case Global:
+ }
+ case Kind::Global:
OS << "::";
return;
-
- case Super:
+ case Kind::Super:
OS << "__super";
break;
-
- case TypeSpec: {
+ case Kind::Type: {
PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.SuppressScope = true;
InnerPolicy.SuppressTagKeyword = true;
QualType(getAsType(), 0).print(OS, InnerPolicy);
break;
}
+ case Kind::Null:
+ return;
}
-
if (PrintFinalScopeResOp)
OS << "::";
}
-LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const {
- dump(llvm::errs(), LO);
+LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream *OS,
+ const LangOptions *LO) const {
+ print(OS ? *OS : llvm::errs(), LO ? *LO : LangOptions());
}
-LLVM_DUMP_METHOD void NestedNameSpecifier::dump() const { dump(llvm::errs()); }
-
+LLVM_DUMP_METHOD void NestedNameSpecifier::dump(const LangOptions &LO) const {
+ dump(/*OS=*/nullptr, &LO);
+}
LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS) const {
- LangOptions LO;
- dump(OS, LO);
+ dump(&OS);
}
-
LLVM_DUMP_METHOD void NestedNameSpecifier::dump(llvm::raw_ostream &OS,
const LangOptions &LO) const {
- print(OS, PrintingPolicy(LO));
+ dump(&OS, &LO);
}
-unsigned
-NestedNameSpecifierLoc::getLocalDataLength(NestedNameSpecifier *Qualifier) {
- assert(Qualifier && "Expected a non-NULL qualifier");
-
- // Location of the trailing '::'.
- unsigned Length = sizeof(SourceLocation::UIntTy);
-
- switch (Qualifier->getKind()) {
- case NestedNameSpecifier::Global:
- // Nothing more to add.
- break;
-
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Super:
- // The location of the identifier or namespace name.
- Length += sizeof(SourceLocation::UIntTy);
- break;
-
- case NestedNameSpecifier::TypeSpec:
- // The "void*" that points at the TypeLoc data.
- // Note: the 'template' keyword is part of the TypeLoc.
- Length += sizeof(void *);
- break;
- }
-
- return Length;
-}
-
-unsigned
-NestedNameSpecifierLoc::getDataLength(NestedNameSpecifier *Qualifier) {
- unsigned Length = 0;
- for (; Qualifier; Qualifier = Qualifier->getPrefix())
- Length += getLocalDataLength(Qualifier);
- return Length;
-}
-
-/// Load a (possibly unaligned) source location from a given address
-/// and offset.
-static SourceLocation LoadSourceLocation(void *Data, unsigned Offset) {
- SourceLocation::UIntTy Raw;
- memcpy(&Raw, static_cast<char *>(Data) + Offset, sizeof(Raw));
- return SourceLocation::getFromRawEncoding(Raw);
-}
-
-/// Load a (possibly unaligned) pointer from a given address and
-/// offset.
-static void *LoadPointer(void *Data, unsigned Offset) {
- void *Result;
- memcpy(&Result, static_cast<char *>(Data) + Offset, sizeof(void*));
- return Result;
-}
-
-SourceRange NestedNameSpecifierLoc::getLocalSourceRange() const {
+SourceLocation NestedNameSpecifierLoc::getBeginLoc() const {
if (!Qualifier)
- return SourceRange();
-
- unsigned Offset = getDataLength(Qualifier->getPrefix());
- switch (Qualifier->getKind()) {
- case NestedNameSpecifier::Global:
- return LoadSourceLocation(Data, Offset);
-
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Super:
- return SourceRange(
- LoadSourceLocation(Data, Offset),
- LoadSourceLocation(Data, Offset + sizeof(SourceLocation::UIntTy)));
-
- case NestedNameSpecifier::TypeSpec: {
- // The "void*" that points at the TypeLoc data.
- // Note: the 'template' keyword is part of the TypeLoc.
- void *TypeData = LoadPointer(Data, Offset);
- TypeLoc TL(Qualifier->getAsType(), TypeData);
- return SourceRange(TL.getBeginLoc(),
- LoadSourceLocation(Data, Offset + sizeof(void*)));
- }
- }
-
- llvm_unreachable("Invalid NNS Kind!");
-}
+ return SourceLocation();
-TypeLoc NestedNameSpecifierLoc::getTypeLoc() const {
- if (Qualifier->getKind() != NestedNameSpecifier::TypeSpec)
- return TypeLoc();
-
- // The "void*" that points at the TypeLoc data.
- unsigned Offset = getDataLength(Qualifier->getPrefix());
- void *TypeData = LoadPointer(Data, Offset);
- return TypeLoc(Qualifier->getAsType(), TypeData);
+ NestedNameSpecifierLoc First = *this;
+ while (NestedNameSpecifierLoc Prefix = First.getAsNamespaceAndPrefix().Prefix)
+ First = Prefix;
+ return First.getLocalSourceRange().getBegin();
}
static void Append(char *Start, char *End, char *&Buffer, unsigned &BufferSize,
@@ -546,10 +247,10 @@ operator=(const NestedNameSpecifierLocBuilder &Other) {
return *this;
}
-void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, TypeLoc TL,
- SourceLocation ColonColonLoc) {
- Representation =
- NestedNameSpecifier::Create(Context, Representation, TL.getTypePtr());
+void NestedNameSpecifierLocBuilder::Make(ASTContext &Context, TypeLoc TL,
+ SourceLocation ColonColonLoc) {
+ assert(!Representation);
+ Representation = NestedNameSpecifier(TL.getTypePtr());
// Push source-location info into the buffer.
SavePointer(TL.getOpaqueData(), Buffer, BufferSize, BufferCapacity);
@@ -557,44 +258,20 @@ void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context, TypeLoc TL,
}
void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
- IdentifierInfo *Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation ColonColonLoc) {
- Representation = NestedNameSpecifier::Create(Context, Representation,
- Identifier);
-
- // Push source-location info into the buffer.
- SaveSourceLocation(IdentifierLoc, Buffer, BufferSize, BufferCapacity);
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
-}
-
-void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
- NamespaceDecl *Namespace,
+ const NamespaceBaseDecl *Namespace,
SourceLocation NamespaceLoc,
SourceLocation ColonColonLoc) {
- Representation = NestedNameSpecifier::Create(Context, Representation,
- Namespace);
+ Representation = NestedNameSpecifier(Context, Namespace, Representation);
// Push source-location info into the buffer.
SaveSourceLocation(NamespaceLoc, Buffer, BufferSize, BufferCapacity);
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}
-void NestedNameSpecifierLocBuilder::Extend(ASTContext &Context,
- NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc,
- SourceLocation ColonColonLoc) {
- Representation = NestedNameSpecifier::Create(Context, Representation, Alias);
-
- // Push source-location info into the buffer.
- SaveSourceLocation(AliasLoc, Buffer, BufferSize, BufferCapacity);
- SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
-}
-
void NestedNameSpecifierLocBuilder::MakeGlobal(ASTContext &Context,
SourceLocation ColonColonLoc) {
assert(!Representation && "Already have a nested-name-specifier!?");
- Representation = NestedNameSpecifier::GlobalSpecifier(Context);
+ Representation = NestedNameSpecifier::getGlobal();
// Push source-location info into the buffer.
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
@@ -604,51 +281,39 @@ void NestedNameSpecifierLocBuilder::MakeSuper(ASTContext &Context,
CXXRecordDecl *RD,
SourceLocation SuperLoc,
SourceLocation ColonColonLoc) {
- Representation = NestedNameSpecifier::SuperSpecifier(Context, RD);
+ Representation = NestedNameSpecifier(RD);
// Push source-location info into the buffer.
SaveSourceLocation(SuperLoc, Buffer, BufferSize, BufferCapacity);
SaveSourceLocation(ColonColonLoc, Buffer, BufferSize, BufferCapacity);
}
-void NestedNameSpecifierLocBuilder::MakeTrivial(ASTContext &Context,
- NestedNameSpecifier *Qualifier,
+void NestedNameSpecifierLocBuilder::PushTrivial(ASTContext &Context,
+ NestedNameSpecifier Qualifier,
SourceRange R) {
- Representation = Qualifier;
-
// Construct bogus (but well-formed) source information for the
// nested-name-specifier.
- BufferSize = 0;
- SmallVector<NestedNameSpecifier *, 4> Stack;
- for (NestedNameSpecifier *NNS = Qualifier; NNS; NNS = NNS->getPrefix())
- Stack.push_back(NNS);
- while (!Stack.empty()) {
- NestedNameSpecifier *NNS = Stack.pop_back_val();
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
- break;
-
- case NestedNameSpecifier::TypeSpec: {
- TypeSourceInfo *TSInfo
- = Context.getTrivialTypeSourceInfo(QualType(NNS->getAsType(), 0),
- R.getBegin());
- SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
- BufferCapacity);
- break;
- }
-
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- break;
- }
-
- // Save the location of the '::'.
- SaveSourceLocation(Stack.empty()? R.getEnd() : R.getBegin(),
- Buffer, BufferSize, BufferCapacity);
+ switch (Qualifier.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ return;
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [_1, Prefix] = Qualifier.getAsNamespaceAndPrefix();
+ PushTrivial(Context, Prefix, R.getBegin());
+ SaveSourceLocation(R.getBegin(), Buffer, BufferSize, BufferCapacity);
+ break;
+ }
+ case NestedNameSpecifier::Kind::Type: {
+ TypeSourceInfo *TSInfo = Context.getTrivialTypeSourceInfo(
+ QualType(Qualifier.getAsType(), 0), R.getBegin());
+ SavePointer(TSInfo->getTypeLoc().getOpaqueData(), Buffer, BufferSize,
+ BufferCapacity);
+ break;
+ }
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
+ break;
}
+ SaveSourceLocation(R.getEnd(), Buffer, BufferSize, BufferCapacity);
}
void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
@@ -656,7 +321,7 @@ void NestedNameSpecifierLocBuilder::Adopt(NestedNameSpecifierLoc Other) {
free(Buffer);
if (!Other) {
- Representation = nullptr;
+ Representation = std::nullopt;
BufferSize = 0;
return;
}
diff --git a/clang/lib/AST/ODRHash.cpp b/clang/lib/AST/ODRHash.cpp
index 7fdfcfa3014f3..2f64d76af02cf 100644
--- a/clang/lib/AST/ODRHash.cpp
+++ b/clang/lib/AST/ODRHash.cpp
@@ -111,37 +111,28 @@ void ODRHash::AddDeclarationNameInfoImpl(DeclarationNameInfo NameInfo) {
}
}
-void ODRHash::AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
- assert(NNS && "Expecting non-null pointer.");
- const auto *Prefix = NNS->getPrefix();
- AddBoolean(Prefix);
- if (Prefix) {
- AddNestedNameSpecifier(Prefix);
- }
- auto Kind = NNS->getKind();
- ID.AddInteger(Kind);
+void ODRHash::AddNestedNameSpecifier(NestedNameSpecifier NNS) {
+ auto Kind = NNS.getKind();
+ ID.AddInteger(llvm::to_underlying(Kind));
switch (Kind) {
- case NestedNameSpecifier::Identifier:
- AddIdentifierInfo(NNS->getAsIdentifier());
- break;
- case NestedNameSpecifier::Namespace:
- AddDecl(NNS->getAsNamespace());
- break;
- case NestedNameSpecifier::NamespaceAlias:
- AddDecl(NNS->getAsNamespaceAlias());
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
+ AddDecl(Namespace);
+ AddNestedNameSpecifier(Prefix);
break;
- case NestedNameSpecifier::TypeSpec:
- AddType(NNS->getAsType());
+ }
+ case NestedNameSpecifier::Kind::Type:
+ AddType(NNS.getAsType());
break;
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
break;
}
}
void ODRHash::AddDependentTemplateName(const DependentTemplateStorage &Name) {
- if (NestedNameSpecifier *NNS = Name.getQualifier())
- AddNestedNameSpecifier(NNS);
+ AddNestedNameSpecifier(Name.getQualifier());
if (IdentifierOrOverloadedOperator IO = Name.getName();
const IdentifierInfo *II = IO.getIdentifier())
AddIdentifierInfo(II);
@@ -159,8 +150,7 @@ void ODRHash::AddTemplateName(TemplateName Name) {
break;
case TemplateName::QualifiedTemplate: {
QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
- if (NestedNameSpecifier *NNS = QTN->getQualifier())
- AddNestedNameSpecifier(NNS);
+ AddNestedNameSpecifier(QTN->getQualifier());
AddBoolean(QTN->hasTemplateKeyword());
AddTemplateName(QTN->getUnderlyingTemplate());
break;
@@ -892,11 +882,8 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
}
}
- void AddNestedNameSpecifier(const NestedNameSpecifier *NNS) {
- Hash.AddBoolean(NNS);
- if (NNS) {
- Hash.AddNestedNameSpecifier(NNS);
- }
+ void AddNestedNameSpecifier(NestedNameSpecifier NNS) {
+ Hash.AddNestedNameSpecifier(NNS);
}
void AddIdentifierInfo(const IdentifierInfo *II) {
@@ -910,52 +897,33 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
ID.AddInteger(Quals.getAsOpaqueValue());
}
- // Return the RecordType if the typedef only strips away a keyword.
- // Otherwise, return the original type.
- static const Type *RemoveTypedef(const Type *T) {
+ // Handle typedefs which only strip away a keyword.
+ bool handleTypedef(const Type *T) {
const auto *TypedefT = dyn_cast<TypedefType>(T);
- if (!TypedefT) {
- return T;
- }
-
- const TypedefNameDecl *D = TypedefT->getDecl();
- QualType UnderlyingType = D->getUnderlyingType();
-
- if (UnderlyingType.hasLocalQualifiers()) {
- return T;
- }
-
- const auto *ElaboratedT = dyn_cast<ElaboratedType>(UnderlyingType);
- if (!ElaboratedT) {
- return T;
- }
+ if (!TypedefT)
+ return false;
- if (ElaboratedT->getQualifier() != nullptr) {
- return T;
- }
+ QualType UnderlyingType = TypedefT->desugar();
- QualType NamedType = ElaboratedT->getNamedType();
- if (NamedType.hasLocalQualifiers()) {
- return T;
- }
+ if (UnderlyingType.hasLocalQualifiers())
+ return false;
- const auto *RecordT = dyn_cast<RecordType>(NamedType);
- if (!RecordT) {
- return T;
- }
+ const auto *TagT = dyn_cast<TagType>(UnderlyingType);
+ if (!TagT || TagT->getQualifier())
+ return false;
- const IdentifierInfo *TypedefII = TypedefT->getDecl()->getIdentifier();
- const IdentifierInfo *RecordII = RecordT->getDecl()->getIdentifier();
- if (!TypedefII || !RecordII ||
- TypedefII->getName() != RecordII->getName()) {
- return T;
- }
+ if (TypedefT->getDecl()->getIdentifier() !=
+ TagT->getOriginalDecl()->getIdentifier())
+ return false;
- return RecordT;
+ ID.AddInteger(TagT->getTypeClass());
+ VisitTagType(TagT, /*ElaboratedOverride=*/TypedefT);
+ return true;
}
void Visit(const Type *T) {
- T = RemoveTypedef(T);
+ if (handleTypedef(T))
+ return;
ID.AddInteger(T->getTypeClass());
Inherited::Visit(T);
}
@@ -1091,7 +1059,7 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
}
void VisitInjectedClassNameType(const InjectedClassNameType *T) {
- AddDecl(T->getDecl());
+ AddDecl(T->getOriginalDecl()->getDefinitionOrSelf());
VisitType(T);
}
@@ -1189,14 +1157,17 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
VisitType(T);
}
- void VisitTagType(const TagType *T) {
- AddDecl(T->getDecl());
+ void VisitTagType(const TagType *T,
+ const TypedefType *ElaboratedOverride = nullptr) {
+ ID.AddInteger(llvm::to_underlying(
+ ElaboratedOverride ? ElaboratedTypeKeyword::None : T->getKeyword()));
+ AddNestedNameSpecifier(ElaboratedOverride
+ ? ElaboratedOverride->getQualifier()
+ : T->getQualifier());
+ AddDecl(T->getOriginalDecl()->getDefinitionOrSelf());
VisitType(T);
}
- void VisitRecordType(const RecordType *T) { VisitTagType(T); }
- void VisitEnumType(const EnumType *T) { VisitTagType(T); }
-
void VisitTemplateSpecializationType(const TemplateSpecializationType *T) {
ID.AddInteger(T->template_arguments().size());
for (const auto &TA : T->template_arguments()) {
@@ -1214,6 +1185,8 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
}
void VisitTypedefType(const TypedefType *T) {
+ ID.AddInteger(llvm::to_underlying(T->getKeyword()));
+ AddNestedNameSpecifier(T->getQualifier());
AddDecl(T->getDecl());
VisitType(T);
}
@@ -1250,12 +1223,6 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
VisitTypeWithKeyword(T);
}
- void VisitElaboratedType(const ElaboratedType *T) {
- AddNestedNameSpecifier(T->getQualifier());
- AddQualType(T->getNamedType());
- VisitTypeWithKeyword(T);
- }
-
void VisitUnaryTransformType(const UnaryTransformType *T) {
AddQualType(T->getUnderlyingType());
AddQualType(T->getBaseType());
@@ -1333,7 +1300,7 @@ void ODRHash::AddStructuralValue(const APValue &Value) {
TypeSoFar = FD->getType();
} else {
TypeSoFar =
- D->getASTContext().getRecordType(cast<CXXRecordDecl>(D));
+ D->getASTContext().getCanonicalTagType(cast<CXXRecordDecl>(D));
}
}
}
diff --git a/clang/lib/AST/OpenMPClause.cpp b/clang/lib/AST/OpenMPClause.cpp
index de8b5996818de..588b0dcc6d7b8 100644
--- a/clang/lib/AST/OpenMPClause.cpp
+++ b/clang/lib/AST/OpenMPClause.cpp
@@ -2350,17 +2350,16 @@ void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
if (Node->getModifierLoc().isValid())
OS << getOpenMPSimpleClauseTypeName(OMPC_reduction, Node->getModifier())
<< ", ";
- NestedNameSpecifier *QualifierLoc =
+ NestedNameSpecifier Qualifier =
Node->getQualifierLoc().getNestedNameSpecifier();
OverloadedOperatorKind OOK =
Node->getNameInfo().getName().getCXXOverloadedOperator();
- if (QualifierLoc == nullptr && OOK != OO_None) {
+ if (!Qualifier && OOK != OO_None) {
// Print reduction identifier in C format
OS << getOperatorSpelling(OOK);
} else {
// Use C++ format
- if (QualifierLoc != nullptr)
- QualifierLoc->print(OS, Policy);
+ Qualifier.print(OS, Policy);
OS << Node->getNameInfo();
}
OS << ":";
@@ -2373,17 +2372,16 @@ void OMPClausePrinter::VisitOMPTaskReductionClause(
OMPTaskReductionClause *Node) {
if (!Node->varlist_empty()) {
OS << "task_reduction(";
- NestedNameSpecifier *QualifierLoc =
+ NestedNameSpecifier Qualifier =
Node->getQualifierLoc().getNestedNameSpecifier();
OverloadedOperatorKind OOK =
Node->getNameInfo().getName().getCXXOverloadedOperator();
- if (QualifierLoc == nullptr && OOK != OO_None) {
+ if (!Qualifier && OOK != OO_None) {
// Print reduction identifier in C format
OS << getOperatorSpelling(OOK);
} else {
// Use C++ format
- if (QualifierLoc != nullptr)
- QualifierLoc->print(OS, Policy);
+ Qualifier.print(OS, Policy);
OS << Node->getNameInfo();
}
OS << ":";
@@ -2395,17 +2393,16 @@ void OMPClausePrinter::VisitOMPTaskReductionClause(
void OMPClausePrinter::VisitOMPInReductionClause(OMPInReductionClause *Node) {
if (!Node->varlist_empty()) {
OS << "in_reduction(";
- NestedNameSpecifier *QualifierLoc =
+ NestedNameSpecifier Qualifier =
Node->getQualifierLoc().getNestedNameSpecifier();
OverloadedOperatorKind OOK =
Node->getNameInfo().getName().getCXXOverloadedOperator();
- if (QualifierLoc == nullptr && OOK != OO_None) {
+ if (!Qualifier && OOK != OO_None) {
// Print reduction identifier in C format
OS << getOperatorSpelling(OOK);
} else {
// Use C++ format
- if (QualifierLoc != nullptr)
- QualifierLoc->print(OS, Policy);
+ Qualifier.print(OS, Policy);
OS << Node->getNameInfo();
}
OS << ":";
@@ -2508,10 +2505,9 @@ template <typename T>
static void PrintMapper(raw_ostream &OS, T *Node,
const PrintingPolicy &Policy) {
OS << '(';
- NestedNameSpecifier *MapperNNS =
+ NestedNameSpecifier MapperNNS =
Node->getMapperQualifierLoc().getNestedNameSpecifier();
- if (MapperNNS)
- MapperNNS->print(OS, Policy);
+ MapperNNS.print(OS, Policy);
OS << Node->getMapperIdInfo() << ')';
}
diff --git a/clang/lib/AST/ParentMapContext.cpp b/clang/lib/AST/ParentMapContext.cpp
index 68dfe4d5d22cb..acc011cb2faa4 100644
--- a/clang/lib/AST/ParentMapContext.cpp
+++ b/clang/lib/AST/ParentMapContext.cpp
@@ -438,10 +438,12 @@ class ParentMapContext::ParentMap::ASTVisitor
DeclNode, DeclNode, [&] { return VisitorBase::TraverseDecl(DeclNode); },
&Map.PointerParents);
}
- bool TraverseTypeLoc(TypeLoc TypeLocNode) {
+ bool TraverseTypeLoc(TypeLoc TypeLocNode, bool TraverseQualifier = true) {
return TraverseNode(
TypeLocNode, DynTypedNode::create(TypeLocNode),
- [&] { return VisitorBase::TraverseTypeLoc(TypeLocNode); },
+ [&] {
+ return VisitorBase::TraverseTypeLoc(TypeLocNode, TraverseQualifier);
+ },
&Map.OtherParents);
}
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLocNode) {
diff --git a/clang/lib/AST/PrintfFormatString.cpp b/clang/lib/AST/PrintfFormatString.cpp
index 293164ddac8f8..4aece07ef9613 100644
--- a/clang/lib/AST/PrintfFormatString.cpp
+++ b/clang/lib/AST/PrintfFormatString.cpp
@@ -791,7 +791,7 @@ bool PrintfSpecifier::fixType(QualType QT, const LangOptions &LangOpt,
// If it's an enum, get its underlying type.
if (const EnumType *ETy = QT->getAs<EnumType>())
- QT = ETy->getDecl()->getIntegerType();
+ QT = ETy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
const BuiltinType *BT = QT->getAs<BuiltinType>();
if (!BT) {
diff --git a/clang/lib/AST/QualTypeNames.cpp b/clang/lib/AST/QualTypeNames.cpp
index 39703d6d7b882..9e31a8ca5d085 100644
--- a/clang/lib/AST/QualTypeNames.cpp
+++ b/clang/lib/AST/QualTypeNames.cpp
@@ -24,10 +24,9 @@ namespace TypeName {
/// is requested.
/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
/// specifier "::" should be prepended or not.
-static NestedNameSpecifier *createNestedNameSpecifier(
- const ASTContext &Ctx,
- const NamespaceDecl *Namesp,
- bool WithGlobalNsPrefix);
+static NestedNameSpecifier
+createNestedNameSpecifier(const ASTContext &Ctx, const NamespaceDecl *Namesp,
+ bool WithGlobalNsPrefix);
/// Create a NestedNameSpecifier for TagDecl and its enclosing
/// scopes.
@@ -39,22 +38,24 @@ static NestedNameSpecifier *createNestedNameSpecifier(
/// qualified names.
/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace
/// specifier "::" should be prepended or not.
-static NestedNameSpecifier *createNestedNameSpecifier(
- const ASTContext &Ctx, const TypeDecl *TD,
- bool FullyQualify, bool WithGlobalNsPrefix);
+static NestedNameSpecifier createNestedNameSpecifier(const ASTContext &Ctx,
+ const TypeDecl *TD,
+ bool FullyQualify,
+ bool WithGlobalNsPrefix);
-static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
- const ASTContext &Ctx, const Decl *decl,
- bool FullyQualified, bool WithGlobalNsPrefix);
+static NestedNameSpecifier
+createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Decl *decl,
+ bool FullyQualified,
+ bool WithGlobalNsPrefix);
-static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
- const ASTContext &Ctx, NestedNameSpecifier *scope, bool WithGlobalNsPrefix);
+static NestedNameSpecifier getFullyQualifiedNestedNameSpecifier(
+ const ASTContext &Ctx, NestedNameSpecifier NNS, bool WithGlobalNsPrefix);
static bool getFullyQualifiedTemplateName(const ASTContext &Ctx,
TemplateName &TName,
bool WithGlobalNsPrefix) {
bool Changed = false;
- NestedNameSpecifier *NNS = nullptr;
+ NestedNameSpecifier NNS = std::nullopt;
TemplateDecl *ArgTDecl = TName.getAsTemplateDecl();
// ArgTDecl won't be NULL because we asserted that this isn't a
@@ -65,13 +66,13 @@ static bool getFullyQualifiedTemplateName(const ASTContext &Ctx,
if (QTName &&
!QTName->hasTemplateKeyword() &&
(NNS = QTName->getQualifier())) {
- NestedNameSpecifier *QNNS = getFullyQualifiedNestedNameSpecifier(
- Ctx, NNS, WithGlobalNsPrefix);
+ NestedNameSpecifier QNNS =
+ getFullyQualifiedNestedNameSpecifier(Ctx, NNS, WithGlobalNsPrefix);
if (QNNS != NNS) {
Changed = true;
NNS = QNNS;
} else {
- NNS = nullptr;
+ NNS = std::nullopt;
}
} else {
NNS = createNestedNameSpecifierForScopeOf(
@@ -116,76 +117,81 @@ static bool getFullyQualifiedTemplateArgument(const ASTContext &Ctx,
}
static const Type *getFullyQualifiedTemplateType(const ASTContext &Ctx,
- const Type *TypePtr,
+ const TagType *TSTRecord,
+ ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
bool WithGlobalNsPrefix) {
- // DependentTemplateTypes exist within template declarations and
- // definitions. Therefore we shouldn't encounter them at the end of
- // a translation unit. If we do, the caller has made an error.
- assert(!isa<DependentTemplateSpecializationType>(TypePtr));
- // In case of template specializations, iterate over the arguments
- // and fully qualify them as well.
- if (const auto *TST = dyn_cast<const TemplateSpecializationType>(TypePtr)) {
- bool MightHaveChanged = false;
- SmallVector<TemplateArgument, 4> FQArgs;
- // Cheap to copy and potentially modified by
- // getFullyQualifedTemplateArgument.
- for (TemplateArgument Arg : TST->template_arguments()) {
- MightHaveChanged |= getFullyQualifiedTemplateArgument(
- Ctx, Arg, WithGlobalNsPrefix);
- FQArgs.push_back(Arg);
- }
+ // We are asked to fully qualify and we have a Record Type,
+ // which can point to a template instantiation with no sugar in any of
+ // its template argument, however we still need to fully qualify them.
+
+ const auto *TD = TSTRecord->getOriginalDecl();
+ const auto *TSTDecl = dyn_cast<ClassTemplateSpecializationDecl>(TD);
+ if (!TSTDecl)
+ return Ctx.getTagType(Keyword, Qualifier, TD, /*OwnsTag=*/false)
+ .getTypePtr();
+
+ const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
+
+ bool MightHaveChanged = false;
+ SmallVector<TemplateArgument, 4> FQArgs;
+ for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
+ // cheap to copy and potentially modified by
+ // getFullyQualifedTemplateArgument
+ TemplateArgument Arg(TemplateArgs[I]);
+ MightHaveChanged |=
+ getFullyQualifiedTemplateArgument(Ctx, Arg, WithGlobalNsPrefix);
+ FQArgs.push_back(Arg);
+ }
- // If a fully qualified arg is different from the unqualified arg,
- // allocate new type in the AST.
- if (MightHaveChanged) {
- QualType QT = Ctx.getTemplateSpecializationType(
- TST->getTemplateName(), FQArgs,
- /*CanonicalArgs=*/{}, TST->desugar());
- // getTemplateSpecializationType returns a fully qualified
- // version of the specialization itself, so no need to qualify
- // it.
- return QT.getTypePtr();
- }
- } else if (const auto *TSTRecord = dyn_cast<const RecordType>(TypePtr)) {
- // We are asked to fully qualify and we have a Record Type,
- // which can point to a template instantiation with no sugar in any of
- // its template argument, however we still need to fully qualify them.
-
- if (const auto *TSTDecl =
- dyn_cast<ClassTemplateSpecializationDecl>(TSTRecord->getDecl())) {
- const TemplateArgumentList &TemplateArgs = TSTDecl->getTemplateArgs();
-
- bool MightHaveChanged = false;
- SmallVector<TemplateArgument, 4> FQArgs;
- for (unsigned int I = 0, E = TemplateArgs.size(); I != E; ++I) {
- // cheap to copy and potentially modified by
- // getFullyQualifedTemplateArgument
- TemplateArgument Arg(TemplateArgs[I]);
- MightHaveChanged |= getFullyQualifiedTemplateArgument(
- Ctx, Arg, WithGlobalNsPrefix);
- FQArgs.push_back(Arg);
- }
+ if (!MightHaveChanged)
+ return Ctx.getTagType(Keyword, Qualifier, TD, /*OwnsTag=*/false)
+ .getTypePtr();
+ // If a fully qualified arg is different from the unqualified arg,
+ // allocate new type in the AST.
+ TemplateName TN = Ctx.getQualifiedTemplateName(
+ Qualifier, /*TemplateKeyword=*/false,
+ TemplateName(TSTDecl->getSpecializedTemplate()));
+ QualType QT = Ctx.getTemplateSpecializationType(
+ Keyword, TN, FQArgs,
+ /*CanonicalArgs=*/{}, TSTRecord->getCanonicalTypeInternal());
+ // getTemplateSpecializationType returns a fully qualified
+ // version of the specialization itself, so no need to qualify
+ // it.
+ return QT.getTypePtr();
+}
- // If a fully qualified arg is different from the unqualified arg,
- // allocate new type in the AST.
- if (MightHaveChanged) {
- TemplateName TN(TSTDecl->getSpecializedTemplate());
- QualType QT = Ctx.getTemplateSpecializationType(
- TN, FQArgs,
- /*CanonicalArgs=*/{}, TSTRecord->getCanonicalTypeInternal());
- // getTemplateSpecializationType returns a fully qualified
- // version of the specialization itself, so no need to qualify
- // it.
- return QT.getTypePtr();
- }
- }
+static const Type *
+getFullyQualifiedTemplateType(const ASTContext &Ctx,
+ const TemplateSpecializationType *TST,
+ bool WithGlobalNsPrefix) {
+ TemplateName TName = TST->getTemplateName();
+ bool MightHaveChanged =
+ getFullyQualifiedTemplateName(Ctx, TName, WithGlobalNsPrefix);
+ SmallVector<TemplateArgument, 4> FQArgs;
+ // Cheap to copy and potentially modified by
+ // getFullyQualifedTemplateArgument.
+ for (TemplateArgument Arg : TST->template_arguments()) {
+ MightHaveChanged |=
+ getFullyQualifiedTemplateArgument(Ctx, Arg, WithGlobalNsPrefix);
+ FQArgs.push_back(Arg);
}
- return TypePtr;
+
+ if (!MightHaveChanged)
+ return TST;
+
+ QualType NewQT =
+ Ctx.getTemplateSpecializationType(TST->getKeyword(), TName, FQArgs,
+ /*CanonicalArgs=*/{}, TST->desugar());
+ // getTemplateSpecializationType returns a fully qualified
+ // version of the specialization itself, so no need to qualify
+ // it.
+ return NewQT.getTypePtr();
}
-static NestedNameSpecifier *createOuterNNS(const ASTContext &Ctx, const Decl *D,
- bool FullyQualify,
- bool WithGlobalNsPrefix) {
+static NestedNameSpecifier createOuterNNS(const ASTContext &Ctx, const Decl *D,
+ bool FullyQualify,
+ bool WithGlobalNsPrefix) {
const DeclContext *DC = D->getDeclContext();
if (const auto *NS = dyn_cast<NamespaceDecl>(DC)) {
while (NS && NS->isInline()) {
@@ -195,80 +201,63 @@ static NestedNameSpecifier *createOuterNNS(const ASTContext &Ctx, const Decl *D,
if (NS && NS->getDeclName()) {
return createNestedNameSpecifier(Ctx, NS, WithGlobalNsPrefix);
}
- return nullptr; // no starting '::', no anonymous
- } else if (const auto *TD = dyn_cast<TagDecl>(DC)) {
- return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
- } else if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC)) {
- return createNestedNameSpecifier(
- Ctx, TDD, FullyQualify, WithGlobalNsPrefix);
- } else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
- return NestedNameSpecifier::GlobalSpecifier(Ctx);
+ return std::nullopt; // no starting '::', no anonymous
}
- return nullptr; // no starting '::' if |WithGlobalNsPrefix| is false
+ if (const auto *TD = dyn_cast<TagDecl>(DC))
+ return createNestedNameSpecifier(Ctx, TD, FullyQualify, WithGlobalNsPrefix);
+ if (const auto *TDD = dyn_cast<TypedefNameDecl>(DC))
+ return createNestedNameSpecifier(Ctx, TDD, FullyQualify,
+ WithGlobalNsPrefix);
+ if (WithGlobalNsPrefix && DC->isTranslationUnit())
+ return NestedNameSpecifier::getGlobal();
+ return std::nullopt; // no starting '::' if |WithGlobalNsPrefix| is false
}
/// Return a fully qualified version of this name specifier.
-static NestedNameSpecifier *getFullyQualifiedNestedNameSpecifier(
- const ASTContext &Ctx, NestedNameSpecifier *Scope,
- bool WithGlobalNsPrefix) {
- switch (Scope->getKind()) {
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- // Already fully qualified
- return Scope;
- case NestedNameSpecifier::Namespace:
- return TypeName::createNestedNameSpecifier(
- Ctx, Scope->getAsNamespace(), WithGlobalNsPrefix);
- case NestedNameSpecifier::NamespaceAlias:
- // Namespace aliases are only valid for the duration of the
- // scope where they were introduced, and therefore are often
- // invalid at the end of the TU. So use the namespace name more
- // likely to be valid at the end of the TU.
- return TypeName::createNestedNameSpecifier(
- Ctx,
- Scope->getAsNamespaceAlias()->getNamespace()->getCanonicalDecl(),
- WithGlobalNsPrefix);
- case NestedNameSpecifier::Identifier:
- // A function or some other construct that makes it un-namable
- // at the end of the TU. Skip the current component of the name,
- // but use the name of it's prefix.
- return getFullyQualifiedNestedNameSpecifier(
- Ctx, Scope->getPrefix(), WithGlobalNsPrefix);
- case NestedNameSpecifier::TypeSpec: {
- const Type *Type = Scope->getAsType();
- // Find decl context.
- const TagDecl *TD = nullptr;
- if (const TagType *TagDeclType = Type->getAs<TagType>()) {
- TD = TagDeclType->getDecl();
- } else {
- TD = Type->getAsCXXRecordDecl();
- }
- if (TD) {
- return TypeName::createNestedNameSpecifier(Ctx, TD,
- true /*FullyQualified*/,
- WithGlobalNsPrefix);
- } else if (const auto *TDD = dyn_cast<TypedefType>(Type)) {
- return TypeName::createNestedNameSpecifier(Ctx, TDD->getDecl(),
- true /*FullyQualified*/,
- WithGlobalNsPrefix);
- }
+static NestedNameSpecifier getFullyQualifiedNestedNameSpecifier(
+ const ASTContext &Ctx, NestedNameSpecifier Scope, bool WithGlobalNsPrefix) {
+ switch (Scope.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("can't fully qualify the empty nested name specifier");
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
+ // Already fully qualified
+ return Scope;
+ case NestedNameSpecifier::Kind::Namespace:
+ return TypeName::createNestedNameSpecifier(
+ Ctx, Scope.getAsNamespaceAndPrefix().Namespace->getNamespace(),
+ WithGlobalNsPrefix);
+ case NestedNameSpecifier::Kind::Type: {
+ const Type *Type = Scope.getAsType();
+ // Find decl context.
+ const TypeDecl *TD;
+ if (const TagType *TagDeclType = Type->getAs<TagType>())
+ TD = TagDeclType->getOriginalDecl();
+ else if (const auto *D = dyn_cast<TypedefType>(Type))
+ TD = D->getDecl();
+ else
return Scope;
- }
+ return TypeName::createNestedNameSpecifier(Ctx, TD, /*FullyQualify=*/true,
+ WithGlobalNsPrefix);
+ }
}
llvm_unreachable("bad NNS kind");
}
/// Create a nested name specifier for the declaring context of
/// the type.
-static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
- const ASTContext &Ctx, const Decl *Decl,
- bool FullyQualified, bool WithGlobalNsPrefix) {
+static NestedNameSpecifier
+createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Decl *Decl,
+ bool FullyQualified,
+ bool WithGlobalNsPrefix) {
assert(Decl);
const DeclContext *DC = Decl->getDeclContext()->getRedeclContext();
const auto *Outer = dyn_cast<NamedDecl>(DC);
const auto *OuterNS = dyn_cast<NamespaceDecl>(DC);
- if (Outer && !(OuterNS && OuterNS->isAnonymousNamespace())) {
+ if (OuterNS && OuterNS->isAnonymousNamespace())
+ OuterNS = dyn_cast<NamespaceDecl>(OuterNS->getParent());
+ if (Outer) {
if (const auto *CxxDecl = dyn_cast<CXXRecordDecl>(DC)) {
if (ClassTemplateDecl *ClassTempl =
CxxDecl->getDescribedClassTemplate()) {
@@ -297,76 +286,80 @@ static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
Ctx, TD, FullyQualified, WithGlobalNsPrefix);
} else if (isa<TranslationUnitDecl>(Outer)) {
// Context is the TU. Nothing needs to be done.
- return nullptr;
+ return std::nullopt;
} else {
// Decl's context was neither the TU, a namespace, nor a
// TagDecl, which means it is a type local to a scope, and not
// accessible at the end of the TU.
- return nullptr;
+ return std::nullopt;
}
} else if (WithGlobalNsPrefix && DC->isTranslationUnit()) {
- return NestedNameSpecifier::GlobalSpecifier(Ctx);
+ return NestedNameSpecifier::getGlobal();
}
- return nullptr;
+ return std::nullopt;
}
/// Create a nested name specifier for the declaring context of
/// the type.
-static NestedNameSpecifier *createNestedNameSpecifierForScopeOf(
- const ASTContext &Ctx, const Type *TypePtr,
- bool FullyQualified, bool WithGlobalNsPrefix) {
- if (!TypePtr) return nullptr;
+static NestedNameSpecifier
+createNestedNameSpecifierForScopeOf(const ASTContext &Ctx, const Type *TypePtr,
+ bool FullyQualified,
+ bool WithGlobalNsPrefix) {
+ if (!TypePtr)
+ return std::nullopt;
Decl *Decl = nullptr;
// There are probably other cases ...
if (const auto *TDT = dyn_cast<TypedefType>(TypePtr)) {
Decl = TDT->getDecl();
} else if (const auto *TagDeclType = dyn_cast<TagType>(TypePtr)) {
- Decl = TagDeclType->getDecl();
+ Decl = TagDeclType->getOriginalDecl();
} else if (const auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
Decl = TST->getTemplateName().getAsTemplateDecl();
} else {
Decl = TypePtr->getAsCXXRecordDecl();
}
- if (!Decl) return nullptr;
+ if (!Decl)
+ return std::nullopt;
return createNestedNameSpecifierForScopeOf(
Ctx, Decl, FullyQualified, WithGlobalNsPrefix);
}
-NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
- const NamespaceDecl *Namespace,
- bool WithGlobalNsPrefix) {
+static NestedNameSpecifier
+createNestedNameSpecifier(const ASTContext &Ctx, const NamespaceDecl *Namespace,
+ bool WithGlobalNsPrefix) {
while (Namespace && Namespace->isInline()) {
// Ignore inline namespace;
Namespace = dyn_cast<NamespaceDecl>(Namespace->getDeclContext());
}
- if (!Namespace) return nullptr;
+ if (!Namespace)
+ return std::nullopt;
- bool FullyQualified = true; // doesn't matter, DeclContexts are namespaces
- return NestedNameSpecifier::Create(
- Ctx,
- createOuterNNS(Ctx, Namespace, FullyQualified, WithGlobalNsPrefix),
- Namespace);
+ bool FullyQualify = true; // doesn't matter, DeclContexts are namespaces
+ return NestedNameSpecifier(
+ Ctx, Namespace,
+ createOuterNNS(Ctx, Namespace, FullyQualify, WithGlobalNsPrefix));
}
-NestedNameSpecifier *createNestedNameSpecifier(const ASTContext &Ctx,
- const TypeDecl *TD,
- bool FullyQualify,
- bool WithGlobalNsPrefix) {
- const Type *TypePtr = TD->getTypeForDecl();
- if (isa<const TemplateSpecializationType>(TypePtr) ||
- isa<const RecordType>(TypePtr)) {
+NestedNameSpecifier createNestedNameSpecifier(const ASTContext &Ctx,
+ const TypeDecl *TD,
+ bool FullyQualify,
+ bool WithGlobalNsPrefix) {
+ const Type *TypePtr = Ctx.getTypeDeclType(TD).getTypePtr();
+ if (auto *RD = dyn_cast<TagType>(TypePtr)) {
// We are asked to fully qualify and we have a Record Type (which
// may point to a template specialization) or Template
// Specialization Type. We need to fully qualify their arguments.
-
- TypePtr = getFullyQualifiedTemplateType(Ctx, TypePtr, WithGlobalNsPrefix);
+ TypePtr = getFullyQualifiedTemplateType(
+ Ctx, RD, ElaboratedTypeKeyword::None,
+ createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix),
+ WithGlobalNsPrefix);
+ } else if (auto *TST = dyn_cast<TemplateSpecializationType>(TypePtr)) {
+ TypePtr = getFullyQualifiedTemplateType(Ctx, TST, WithGlobalNsPrefix);
}
-
- return NestedNameSpecifier::Create(
- Ctx, createOuterNNS(Ctx, TD, FullyQualify, WithGlobalNsPrefix), TypePtr);
+ return NestedNameSpecifier(TypePtr);
}
/// Return the fully qualified type, including fully-qualified
@@ -390,7 +383,7 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
Qualifiers Quals = QT.getQualifiers();
// Fully qualify the pointee and class types.
QT = getFullyQualifiedType(QT->getPointeeType(), Ctx, WithGlobalNsPrefix);
- NestedNameSpecifier *Qualifier = getFullyQualifiedNestedNameSpecifier(
+ NestedNameSpecifier Qualifier = getFullyQualifiedNestedNameSpecifier(
Ctx, MPT->getQualifier(), WithGlobalNsPrefix);
QT = Ctx.getMemberPointerType(QT, Qualifier,
MPT->getMostRecentCXXRecordDecl());
@@ -443,45 +436,48 @@ QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx,
QT = Ctx.getQualifiedType(QT, Quals);
}
- NestedNameSpecifier *Prefix = nullptr;
+ if (const auto *TST =
+ dyn_cast<const TemplateSpecializationType>(QT.getTypePtr())) {
+
+ const Type *T = getFullyQualifiedTemplateType(Ctx, TST, WithGlobalNsPrefix);
+ if (T == TST)
+ return QT;
+ return Ctx.getQualifiedType(T, QT.getQualifiers());
+ }
+
// Local qualifiers are attached to the QualType outside of the
// elaborated type. Retrieve them before descending into the
// elaborated type.
Qualifiers PrefixQualifiers = QT.getLocalQualifiers();
QT = QualType(QT.getTypePtr(), 0);
- ElaboratedTypeKeyword Keyword = ElaboratedTypeKeyword::None;
- if (const auto *ETypeInput = dyn_cast<ElaboratedType>(QT.getTypePtr())) {
- QT = ETypeInput->getNamedType();
- assert(!QT.hasLocalQualifiers());
- Keyword = ETypeInput->getKeyword();
- }
// We don't consider the alias introduced by `using a::X` as a new type.
// The qualified name is still a::X.
if (const auto *UT = QT->getAs<UsingType>()) {
- QT = Ctx.getQualifiedType(UT->getUnderlyingType(), PrefixQualifiers);
+ QT = Ctx.getQualifiedType(UT->desugar(), PrefixQualifiers);
return getFullyQualifiedType(QT, Ctx, WithGlobalNsPrefix);
}
// Create a nested name specifier if needed.
- Prefix = createNestedNameSpecifierForScopeOf(Ctx, QT.getTypePtr(),
- true /*FullyQualified*/,
- WithGlobalNsPrefix);
+ NestedNameSpecifier Prefix = createNestedNameSpecifierForScopeOf(
+ Ctx, QT.getTypePtr(), true /*FullyQualified*/, WithGlobalNsPrefix);
// In case of template specializations iterate over the arguments and
// fully qualify them as well.
- if (isa<const TemplateSpecializationType>(QT.getTypePtr()) ||
- isa<const RecordType>(QT.getTypePtr())) {
+ if (const auto *TT = dyn_cast<TagType>(QT.getTypePtr())) {
// We are asked to fully qualify and we have a Record Type (which
// may point to a template specialization) or Template
// Specialization Type. We need to fully qualify their arguments.
const Type *TypePtr = getFullyQualifiedTemplateType(
- Ctx, QT.getTypePtr(), WithGlobalNsPrefix);
+ Ctx, TT, TT->getKeyword(), Prefix, WithGlobalNsPrefix);
QT = QualType(TypePtr, 0);
- }
- if (Prefix || Keyword != ElaboratedTypeKeyword::None) {
- QT = Ctx.getElaboratedType(Keyword, Prefix, QT);
+ } else if (const auto *TT = dyn_cast<TypedefType>(QT.getTypePtr())) {
+ QT = Ctx.getTypedefType(
+ TT->getKeyword(), Prefix, TT->getDecl(),
+ getFullyQualifiedType(TT->desugar(), Ctx, WithGlobalNsPrefix));
+ } else {
+ assert(!Prefix && "Unhandled type node");
}
QT = Ctx.getQualifiedType(QT, PrefixQualifiers);
return QT;
diff --git a/clang/lib/AST/RecordLayoutBuilder.cpp b/clang/lib/AST/RecordLayoutBuilder.cpp
index 6d819031cbef4..8ea4e660c08bb 100644
--- a/clang/lib/AST/RecordLayoutBuilder.cpp
+++ b/clang/lib/AST/RecordLayoutBuilder.cpp
@@ -2012,8 +2012,7 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
} else if (const BuiltinType *BTy = BaseTy->getAs<BuiltinType>()) {
performBuiltinTypeAlignmentUpgrade(BTy);
} else if (const RecordType *RT = BaseTy->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
- assert(RD && "Expected non-null RecordDecl.");
+ const RecordDecl *RD = RT->getOriginalDecl();
const ASTRecordLayout &FieldRecord = Context.getASTRecordLayout(RD);
PreferredAlign = FieldRecord.getPreferredAlignment();
}
@@ -2128,7 +2127,8 @@ void ItaniumRecordLayoutBuilder::LayoutField(const FieldDecl *D,
// TODO: Takes no account the alignment of the outer struct
if (FieldOffset % OriginalFieldAlign != 0)
Diag(D->getLocation(), diag::warn_unaligned_access)
- << Context.getTypeDeclType(RD) << D->getName() << D->getType();
+ << Context.getCanonicalTagType(RD) << D->getName()
+ << D->getType();
}
}
@@ -2193,8 +2193,7 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
InBits = false;
}
Diag(RD->getLocation(), diag::warn_padded_struct_size)
- << Context.getTypeDeclType(RD)
- << PadSize
+ << Context.getCanonicalTagType(RD) << PadSize
<< (InBits ? 1 : 0); // (byte|bit)
}
@@ -2212,7 +2211,7 @@ void ItaniumRecordLayoutBuilder::FinishLayout(const NamedDecl *D) {
Context.getLangOpts().getClangABICompat() <=
LangOptions::ClangABI::Ver15))
Diag(D->getLocation(), diag::warn_unnecessary_packed)
- << Context.getTypeDeclType(RD);
+ << Context.getCanonicalTagType(RD);
}
}
@@ -2306,7 +2305,7 @@ static void CheckFieldPadding(const ASTContext &Context, bool IsUnion,
Context.getDiagnostics().Report(D->getLocation(),
Diagnostic)
<< getPaddingDiagFromTagKind(D->getParent()->getTagKind())
- << Context.getTypeDeclType(D->getParent()) << PadSize
+ << Context.getCanonicalTagType(D->getParent()) << PadSize
<< (InBits ? 1 : 0) // (byte|bit)
<< D->getIdentifier();
} else {
@@ -2315,7 +2314,7 @@ static void CheckFieldPadding(const ASTContext &Context, bool IsUnion,
Context.getDiagnostics().Report(D->getLocation(),
Diagnostic)
<< getPaddingDiagFromTagKind(D->getParent()->getTagKind())
- << Context.getTypeDeclType(D->getParent()) << PadSize
+ << Context.getCanonicalTagType(D->getParent()) << PadSize
<< (InBits ? 1 : 0); // (byte|bit)
}
}
@@ -2723,7 +2722,7 @@ MicrosoftRecordLayoutBuilder::getAdjustedElementInfo(
else {
if (auto RT =
FD->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
- auto const &Layout = Context.getASTRecordLayout(RT->getDecl());
+ auto const &Layout = Context.getASTRecordLayout(RT->getOriginalDecl());
EndsWithZeroSizedObject = Layout.endsWithZeroSizedObject();
FieldRequiredAlignment = std::max(FieldRequiredAlignment,
Layout.getRequiredAlignment());
@@ -3282,7 +3281,7 @@ void MicrosoftRecordLayoutBuilder::finalizeLayout(const RecordDecl *RD) {
Context.getDiagnostics().Report(RD->getLocation(),
diag::warn_padded_struct_size)
- << Context.getTypeDeclType(RD) << PadSize
+ << Context.getCanonicalTagType(RD) << PadSize
<< (InBits ? 1 : 0); // (byte|bit)
}
}
@@ -3640,7 +3639,7 @@ static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD,
auto CXXRD = dyn_cast<CXXRecordDecl>(RD);
PrintOffset(OS, Offset, IndentLevel);
- OS << C.getTypeDeclType(const_cast<RecordDecl *>(RD));
+ OS << C.getCanonicalTagType(const_cast<RecordDecl *>(RD));
if (Description)
OS << ' ' << Description;
if (CXXRD && CXXRD->isEmpty())
@@ -3705,8 +3704,8 @@ static void DumpRecordLayout(raw_ostream &OS, const RecordDecl *RD,
// Recursively dump fields of record type.
if (auto RT = Field->getType()->getAs<RecordType>()) {
- DumpRecordLayout(OS, RT->getDecl(), C, FieldOffset, IndentLevel,
- Field->getName().data(),
+ DumpRecordLayout(OS, RT->getOriginalDecl()->getDefinitionOrSelf(), C,
+ FieldOffset, IndentLevel, Field->getName().data(),
/*PrintSizeInfo=*/false,
/*IncludeVirtualBases=*/true);
continue;
@@ -3789,7 +3788,7 @@ void ASTContext::DumpRecordLayout(const RecordDecl *RD, raw_ostream &OS,
// in libFrontend.
const ASTRecordLayout &Info = getASTRecordLayout(RD);
- OS << "Type: " << getTypeDeclType(RD) << "\n";
+ OS << "Type: " << getCanonicalTagType(RD) << "\n";
OS << "\nLayout: ";
OS << "<ASTRecordLayout\n";
OS << " Size:" << toBits(Info.getSize()) << "\n";
diff --git a/clang/lib/AST/ScanfFormatString.cpp b/clang/lib/AST/ScanfFormatString.cpp
index 7ee21c8c61954..7835b1f52ccd5 100644
--- a/clang/lib/AST/ScanfFormatString.cpp
+++ b/clang/lib/AST/ScanfFormatString.cpp
@@ -427,9 +427,10 @@ bool ScanfSpecifier::fixType(QualType QT, QualType RawQT,
// If it's an enum, get its underlying type.
if (const EnumType *ETy = PT->getAs<EnumType>()) {
// Don't try to fix incomplete enums.
- if (!ETy->getDecl()->isComplete())
+ const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete())
return false;
- PT = ETy->getDecl()->getIntegerType();
+ PT = ED->getIntegerType();
}
const BuiltinType *BT = PT->getAs<BuiltinType>();
diff --git a/clang/lib/AST/StmtPrinter.cpp b/clang/lib/AST/StmtPrinter.cpp
index be02bdde38a3d..698c864c77c83 100644
--- a/clang/lib/AST/StmtPrinter.cpp
+++ b/clang/lib/AST/StmtPrinter.cpp
@@ -454,10 +454,7 @@ void StmtPrinter::VisitMSDependentExistsStmt(MSDependentExistsStmt *Node) {
else
OS << "__if_not_exists (";
- if (NestedNameSpecifier *Qualifier
- = Node->getQualifierLoc().getNestedNameSpecifier())
- Qualifier->print(OS, Policy);
-
+ Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);
OS << Node->getNameInfo() << ") ";
PrintRawCompoundStmt(Node->getSubStmt());
@@ -1309,8 +1306,7 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
TPOD->printAsExpr(OS, Policy);
return;
}
- if (NestedNameSpecifier *Qualifier = Node->getQualifier())
- Qualifier->print(OS, Policy);
+ Node->getQualifier().print(OS, Policy);
if (Node->hasTemplateKeyword())
OS << "template ";
@@ -1359,8 +1355,7 @@ void StmtPrinter::VisitDeclRefExpr(DeclRefExpr *Node) {
void StmtPrinter::VisitDependentScopeDeclRefExpr(
DependentScopeDeclRefExpr *Node) {
- if (NestedNameSpecifier *Qualifier = Node->getQualifier())
- Qualifier->print(OS, Policy);
+ Node->getQualifier().print(OS, Policy);
if (Node->hasTemplateKeyword())
OS << "template ";
OS << Node->getNameInfo();
@@ -1369,8 +1364,7 @@ void StmtPrinter::VisitDependentScopeDeclRefExpr(
}
void StmtPrinter::VisitUnresolvedLookupExpr(UnresolvedLookupExpr *Node) {
- if (Node->getQualifier())
- Node->getQualifier()->print(OS, Policy);
+ Node->getQualifier().print(OS, Policy);
if (Node->hasTemplateKeyword())
OS << "template ";
OS << Node->getNameInfo();
@@ -1778,8 +1772,7 @@ void StmtPrinter::VisitMemberExpr(MemberExpr *Node) {
if (FD->isAnonymousStructOrUnion())
return;
- if (NestedNameSpecifier *Qualifier = Node->getQualifier())
- Qualifier->print(OS, Policy);
+ Node->getQualifier().print(OS, Policy);
if (Node->hasTemplateKeyword())
OS << "template ";
OS << Node->getMemberNameInfo();
@@ -2177,9 +2170,7 @@ void StmtPrinter::VisitMSPropertyRefExpr(MSPropertyRefExpr *Node) {
OS << "->";
else
OS << ".";
- if (NestedNameSpecifier *Qualifier =
- Node->getQualifierLoc().getNestedNameSpecifier())
- Qualifier->print(OS, Policy);
+ Node->getQualifierLoc().getNestedNameSpecifier().print(OS, Policy);
OS << Node->getPropertyDecl()->getDeclName();
}
@@ -2509,8 +2500,7 @@ void StmtPrinter::VisitCXXPseudoDestructorExpr(CXXPseudoDestructorExpr *E) {
OS << "->";
else
OS << '.';
- if (E->getQualifier())
- E->getQualifier()->print(OS, Policy);
+ E->getQualifier().print(OS, Policy);
OS << "~";
if (const IdentifierInfo *II = E->getDestroyedTypeIdentifier())
@@ -2572,8 +2562,7 @@ void StmtPrinter::VisitCXXDependentScopeMemberExpr(
PrintExpr(Node->getBase());
OS << (Node->isArrow() ? "->" : ".");
}
- if (NestedNameSpecifier *Qualifier = Node->getQualifier())
- Qualifier->print(OS, Policy);
+ Node->getQualifier().print(OS, Policy);
if (Node->hasTemplateKeyword())
OS << "template ";
OS << Node->getMemberNameInfo();
@@ -2586,8 +2575,7 @@ void StmtPrinter::VisitUnresolvedMemberExpr(UnresolvedMemberExpr *Node) {
PrintExpr(Node->getBase());
OS << (Node->isArrow() ? "->" : ".");
}
- if (NestedNameSpecifier *Qualifier = Node->getQualifier())
- Qualifier->print(OS, Policy);
+ Node->getQualifier().print(OS, Policy);
if (Node->hasTemplateKeyword())
OS << "template ";
OS << Node->getMemberNameInfo();
@@ -2678,8 +2666,7 @@ void StmtPrinter::VisitCXXParenListInitExpr(CXXParenListInitExpr *Node) {
void StmtPrinter::VisitConceptSpecializationExpr(ConceptSpecializationExpr *E) {
NestedNameSpecifierLoc NNS = E->getNestedNameSpecifierLoc();
- if (NNS)
- NNS.getNestedNameSpecifier()->print(OS, Policy);
+ NNS.getNestedNameSpecifier().print(OS, Policy);
if (E->getTemplateKWLoc().isValid())
OS << "template ";
OS << E->getFoundDecl()->getName();
diff --git a/clang/lib/AST/StmtProfile.cpp b/clang/lib/AST/StmtProfile.cpp
index c61450e19f1b6..59a18395d109c 100644
--- a/clang/lib/AST/StmtProfile.cpp
+++ b/clang/lib/AST/StmtProfile.cpp
@@ -65,7 +65,7 @@ namespace {
/// Visit a nested-name-specifier that occurs within an expression
/// or statement.
- virtual void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) = 0;
+ virtual void VisitNestedNameSpecifier(NestedNameSpecifier NNS) = 0;
/// Visit a template name that occurs within an expression or
/// statement.
@@ -167,10 +167,10 @@ namespace {
ID.AddPointer(II);
}
- void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
+ void VisitNestedNameSpecifier(NestedNameSpecifier NNS) override {
if (Canonical)
- NNS = Context.getCanonicalNestedNameSpecifier(NNS);
- ID.AddPointer(NNS);
+ NNS = NNS.getCanonical();
+ NNS.Profile(ID);
}
void VisitTemplateName(TemplateName Name) override {
@@ -226,11 +226,10 @@ namespace {
void VisitTemplateName(TemplateName Name) override {
Hash.AddTemplateName(Name);
}
- void VisitNestedNameSpecifier(NestedNameSpecifier *NNS) override {
- ID.AddBoolean(NNS);
- if (NNS) {
+ void VisitNestedNameSpecifier(NestedNameSpecifier NNS) override {
+ ID.AddBoolean(bool(NNS));
+ if (NNS)
Hash.AddNestedNameSpecifier(NNS);
- }
}
};
}
diff --git a/clang/lib/AST/TemplateBase.cpp b/clang/lib/AST/TemplateBase.cpp
index 7c89dea4629cc..700675840fd96 100644
--- a/clang/lib/AST/TemplateBase.cpp
+++ b/clang/lib/AST/TemplateBase.cpp
@@ -57,7 +57,7 @@ static void printIntegral(const TemplateArgument &TemplArg, raw_ostream &Out,
if (Policy.UseEnumerators) {
if (const EnumType *ET = T->getAs<EnumType>()) {
- for (const EnumConstantDecl *ECD : ET->getDecl()->enumerators()) {
+ for (const EnumConstantDecl *ECD : ET->getOriginalDecl()->enumerators()) {
// In Sema::CheckTemplateArugment, enum template arguments value are
// extended to the size of the integer underlying the enum type. This
// may create a size difference between the enum value and template
@@ -585,6 +585,29 @@ void TemplateArgument::print(const PrintingPolicy &Policy, raw_ostream &Out,
// TemplateArgumentLoc Implementation
//===----------------------------------------------------------------------===//
+TemplateArgumentLoc::TemplateArgumentLoc(ASTContext &Ctx,
+ const TemplateArgument &Argument,
+ SourceLocation TemplateKWLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateNameLoc,
+ SourceLocation EllipsisLoc)
+ : Argument(Argument),
+ LocInfo(Ctx, TemplateKWLoc, QualifierLoc, TemplateNameLoc, EllipsisLoc) {
+ assert(Argument.getKind() == TemplateArgument::Template ||
+ Argument.getKind() == TemplateArgument::TemplateExpansion);
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ Argument.getAsTemplateOrTemplatePattern().getQualifier());
+}
+
+NestedNameSpecifierLoc TemplateArgumentLoc::getTemplateQualifierLoc() const {
+ if (Argument.getKind() != TemplateArgument::Template &&
+ Argument.getKind() != TemplateArgument::TemplateExpansion)
+ return NestedNameSpecifierLoc();
+ return NestedNameSpecifierLoc(
+ Argument.getAsTemplateOrTemplatePattern().getQualifier(),
+ LocInfo.getTemplate()->QualifierLocData);
+}
+
SourceRange TemplateArgumentLoc::getSourceRange() const {
switch (Argument.getKind()) {
case TemplateArgument::Expression:
@@ -691,10 +714,11 @@ const StreamingDiagnostic &clang::operator<<(const StreamingDiagnostic &DB,
}
clang::TemplateArgumentLocInfo::TemplateArgumentLocInfo(
- ASTContext &Ctx, NestedNameSpecifierLoc QualifierLoc,
- SourceLocation TemplateNameLoc, SourceLocation EllipsisLoc) {
+ ASTContext &Ctx, SourceLocation TemplateKWLoc,
+ NestedNameSpecifierLoc QualifierLoc, SourceLocation TemplateNameLoc,
+ SourceLocation EllipsisLoc) {
TemplateTemplateArgLocInfo *Template = new (Ctx) TemplateTemplateArgLocInfo;
- Template->Qualifier = QualifierLoc.getNestedNameSpecifier();
+ Template->TemplateKwLoc = TemplateKWLoc;
Template->QualifierLocData = QualifierLoc.getOpaqueData();
Template->TemplateNameLoc = TemplateNameLoc;
Template->EllipsisLoc = EllipsisLoc;
diff --git a/clang/lib/AST/TemplateName.cpp b/clang/lib/AST/TemplateName.cpp
index 5b7abc4d038a9..28d54760a1f4a 100644
--- a/clang/lib/AST/TemplateName.cpp
+++ b/clang/lib/AST/TemplateName.cpp
@@ -289,10 +289,30 @@ QualifiedTemplateName *TemplateName::getAsQualifiedTemplateName() const {
return dyn_cast_if_present<QualifiedTemplateName *>(Storage);
}
+QualifiedTemplateName *
+TemplateName::getAsAdjustedQualifiedTemplateName() const {
+ for (std::optional<TemplateName> Cur = *this; Cur;
+ Cur = Cur->desugar(/*IgnoreDeduced=*/true))
+ if (QualifiedTemplateName *N = Cur->getAsQualifiedTemplateName())
+ return N;
+ return nullptr;
+}
+
DependentTemplateName *TemplateName::getAsDependentTemplateName() const {
return Storage.dyn_cast<DependentTemplateName *>();
}
+NestedNameSpecifier TemplateName::getQualifier() const {
+ for (std::optional<TemplateName> Cur = *this; Cur;
+ Cur = Cur->desugar(/*IgnoreDeduced=*/true)) {
+ if (DependentTemplateName *N = Cur->getAsDependentTemplateName())
+ return N->getQualifier();
+ if (QualifiedTemplateName *N = Cur->getAsQualifiedTemplateName())
+ return N->getQualifier();
+ }
+ return std::nullopt;
+}
+
UsingShadowDecl *TemplateName::getAsUsingShadowDecl() const {
if (Decl *D = Storage.dyn_cast<Decl *>())
if (UsingShadowDecl *USD = dyn_cast<UsingShadowDecl>(D))
@@ -303,24 +323,21 @@ UsingShadowDecl *TemplateName::getAsUsingShadowDecl() const {
}
DependentTemplateStorage::DependentTemplateStorage(
- NestedNameSpecifier *Qualifier, IdentifierOrOverloadedOperator Name,
+ NestedNameSpecifier Qualifier, IdentifierOrOverloadedOperator Name,
bool HasTemplateKeyword)
: Qualifier(Qualifier, HasTemplateKeyword), Name(Name) {
- assert((!Qualifier || Qualifier->isDependent()) &&
+ assert((!Qualifier || Qualifier.isDependent()) &&
"Qualifier must be dependent");
}
TemplateNameDependence DependentTemplateStorage::getDependence() const {
- auto D = TemplateNameDependence::DependentInstantiation;
- if (NestedNameSpecifier *Qualifier = getQualifier())
- D |= toTemplateNameDependence(Qualifier->getDependence());
- return D;
+ return toTemplateNameDependence(getQualifier().getDependence()) |
+ TemplateNameDependence::DependentInstantiation;
}
void DependentTemplateStorage::print(raw_ostream &OS,
const PrintingPolicy &Policy) const {
- if (NestedNameSpecifier *NNS = getQualifier())
- NNS->print(OS, Policy);
+ getQualifier().print(OS, Policy);
if (hasTemplateKeyword())
OS << "template ";
@@ -363,16 +380,13 @@ TemplateNameDependence TemplateName::getDependence() const {
case NameKind::QualifiedTemplate: {
QualifiedTemplateName *S = getAsQualifiedTemplateName();
TemplateNameDependence D = S->getUnderlyingTemplate().getDependence();
- if (NestedNameSpecifier *NNS = S->getQualifier())
- D |= toTemplateNameDependence(NNS->getDependence());
+ D |= toTemplateNameDependence(S->getQualifier().getDependence());
return D;
}
case NameKind::DependentTemplate: {
DependentTemplateName *S = getAsDependentTemplateName();
- auto D = TemplateNameDependence::DependentInstantiation;
- if (NestedNameSpecifier *Qualifier = S->getQualifier())
- D |= toTemplateNameDependence(Qualifier->getDependence());
- return D;
+ return toTemplateNameDependence(S->getQualifier().getDependence()) |
+ TemplateNameDependence::DependentInstantiation;
}
case NameKind::SubstTemplateTemplateParm: {
auto *S = getAsSubstTemplateTemplateParm();
@@ -434,7 +448,7 @@ void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
Template = cast<TemplateDecl>(Template->getCanonicalDecl());
if (handleAnonymousTTP(Template, OS))
return;
- if (Qual == Qualified::None)
+ if (Qual == Qualified::None || Policy.SuppressScope)
OS << *Template;
else
Template->printQualifiedName(OS, Policy);
@@ -443,9 +457,8 @@ void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
QTN->getUnderlyingTemplate().print(OS, Policy, Qual);
return;
}
- if (NestedNameSpecifier *NNS = QTN->getQualifier();
- Qual != Qualified::None && NNS)
- NNS->print(OS, Policy);
+ if (Qual != Qualified::None)
+ QTN->getQualifier().print(OS, Policy);
if (QTN->hasTemplateKeyword())
OS << "template ";
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index 9d7c2757d6ee4..bd4f3cacc481d 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -1034,39 +1034,34 @@ void clang::TextNodeDumper::dumpTemplateSpecializationKind(
}
}
-void clang::TextNodeDumper::dumpNestedNameSpecifier(const NestedNameSpecifier *NNS) {
+void clang::TextNodeDumper::dumpNestedNameSpecifier(NestedNameSpecifier NNS) {
if (!NNS)
return;
AddChild([=] {
OS << "NestedNameSpecifier";
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- OS << " Identifier";
- OS << " '" << NNS->getAsIdentifier()->getName() << "'";
- break;
- case NestedNameSpecifier::Namespace:
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
OS << " "; // "Namespace" is printed as the decl kind.
- dumpBareDeclRef(NNS->getAsNamespace());
- break;
- case NestedNameSpecifier::NamespaceAlias:
- OS << " "; // "NamespaceAlias" is printed as the decl kind.
- dumpBareDeclRef(NNS->getAsNamespaceAlias());
+ dumpBareDeclRef(Namespace);
+ dumpNestedNameSpecifier(Prefix);
break;
- case NestedNameSpecifier::TypeSpec:
+ }
+ case NestedNameSpecifier::Kind::Type:
OS << " TypeSpec";
- dumpType(QualType(NNS->getAsType(), 0));
+ dumpType(QualType(NNS.getAsType(), 0));
break;
- case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Kind::Global:
OS << " Global";
break;
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Super:
OS << " Super";
break;
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
-
- dumpNestedNameSpecifier(NNS->getPrefix());
});
}
@@ -1402,8 +1397,8 @@ static void dumpBasePath(raw_ostream &OS, const CastExpr *Node) {
if (!First)
OS << " -> ";
- const auto *RD =
- cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
+ const auto *RD = cast<CXXRecordDecl>(
+ Base->getType()->castAs<RecordType>()->getOriginalDecl());
if (Base->isVirtual())
OS << "virtual ";
@@ -2113,19 +2108,32 @@ void TextNodeDumper::VisitFunctionProtoType(const FunctionProtoType *T) {
}
void TextNodeDumper::VisitUnresolvedUsingType(const UnresolvedUsingType *T) {
+ if (ElaboratedTypeKeyword K = T->getKeyword();
+ K != ElaboratedTypeKeyword::None)
+ OS << ' ' << TypeWithKeyword::getKeywordName(K);
+ dumpNestedNameSpecifier(T->getQualifier());
dumpDeclRef(T->getDecl());
}
void TextNodeDumper::VisitUsingType(const UsingType *T) {
- dumpDeclRef(T->getFoundDecl());
- if (!T->typeMatchesDecl())
- OS << " divergent";
+ if (ElaboratedTypeKeyword K = T->getKeyword();
+ K != ElaboratedTypeKeyword::None)
+ OS << ' ' << TypeWithKeyword::getKeywordName(K);
+ dumpNestedNameSpecifier(T->getQualifier());
+ dumpDeclRef(T->getDecl());
+ dumpType(T->desugar());
}
void TextNodeDumper::VisitTypedefType(const TypedefType *T) {
+ if (ElaboratedTypeKeyword K = T->getKeyword();
+ K != ElaboratedTypeKeyword::None)
+ OS << ' ' << TypeWithKeyword::getKeywordName(K);
+ dumpNestedNameSpecifier(T->getQualifier());
dumpDeclRef(T->getDecl());
- if (!T->typeMatchesDecl())
+ if (!T->typeMatchesDecl()) {
OS << " divergent";
+ dumpType(T->desugar());
+ }
}
void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
@@ -2139,7 +2147,17 @@ void TextNodeDumper::VisitUnaryTransformType(const UnaryTransformType *T) {
}
void TextNodeDumper::VisitTagType(const TagType *T) {
- dumpDeclRef(T->getDecl());
+ if (T->isCanonicalUnqualified())
+ OS << " canonical";
+ if (T->isTagOwned())
+ OS << " owns_tag";
+ if (T->isInjected())
+ OS << " injected";
+ if (ElaboratedTypeKeyword K = T->getKeyword();
+ K != ElaboratedTypeKeyword::None)
+ OS << ' ' << TypeWithKeyword::getKeywordName(K);
+ dumpNestedNameSpecifier(T->getQualifier());
+ dumpDeclRef(T->getOriginalDecl());
}
void TextNodeDumper::VisitTemplateTypeParmType(const TemplateTypeParmType *T) {
@@ -2183,12 +2201,15 @@ void TextNodeDumper::VisitTemplateSpecializationType(
const TemplateSpecializationType *T) {
if (T->isTypeAlias())
OS << " alias";
+ if (ElaboratedTypeKeyword K = T->getKeyword();
+ K != ElaboratedTypeKeyword::None)
+ OS << ' ' << TypeWithKeyword::getKeywordName(K);
dumpTemplateName(T->getTemplateName(), "name");
}
void TextNodeDumper::VisitInjectedClassNameType(
const InjectedClassNameType *T) {
- dumpDeclRef(T->getDecl());
+ dumpDeclRef(T->getOriginalDecl());
}
void TextNodeDumper::VisitObjCInterfaceType(const ObjCInterfaceType *T) {
@@ -2779,8 +2800,7 @@ void TextNodeDumper::VisitTemplateTemplateParmDecl(
void TextNodeDumper::VisitUsingDecl(const UsingDecl *D) {
OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ D->getQualifier().print(OS, D->getASTContext().getPrintingPolicy());
OS << D->getDeclName();
dumpNestedNameSpecifier(D->getQualifier());
}
@@ -2793,16 +2813,14 @@ void TextNodeDumper::VisitUsingEnumDecl(const UsingEnumDecl *D) {
void TextNodeDumper::VisitUnresolvedUsingTypenameDecl(
const UnresolvedUsingTypenameDecl *D) {
OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ D->getQualifier().print(OS, D->getASTContext().getPrintingPolicy());
OS << D->getDeclName();
}
void TextNodeDumper::VisitUnresolvedUsingValueDecl(
const UnresolvedUsingValueDecl *D) {
OS << ' ';
- if (D->getQualifier())
- D->getQualifier()->print(OS, D->getASTContext().getPrintingPolicy());
+ D->getQualifier().print(OS, D->getASTContext().getPrintingPolicy());
OS << D->getDeclName();
dumpType(D->getType());
}
diff --git a/clang/lib/AST/Type.cpp b/clang/lib/AST/Type.cpp
index e5a1ab2ff8906..1ad42c2a3836e 100644
--- a/clang/lib/AST/Type.cpp
+++ b/clang/lib/AST/Type.cpp
@@ -109,12 +109,14 @@ bool Qualifiers::isTargetAddressSpaceSupersetOf(LangAS A, LangAS B,
const IdentifierInfo *QualType::getBaseTypeIdentifier() const {
const Type *ty = getTypePtr();
NamedDecl *ND = nullptr;
+ if (const auto *DNT = ty->getAs<DependentNameType>())
+ return DNT->getIdentifier();
if (ty->isPointerOrReferenceType())
return ty->getPointeeType().getBaseTypeIdentifier();
- else if (ty->isRecordType())
- ND = ty->castAs<RecordType>()->getDecl();
+ if (ty->isRecordType())
+ ND = ty->castAs<RecordType>()->getOriginalDecl();
else if (ty->isEnumeralType())
- ND = ty->castAs<EnumType>()->getDecl();
+ ND = ty->castAs<EnumType>()->getOriginalDecl();
else if (ty->getTypeClass() == Type::Typedef)
ND = ty->castAs<TypedefType>()->getDecl();
else if (ty->isArrayType())
@@ -671,13 +673,13 @@ const Type *Type::getUnqualifiedDesugaredType() const {
bool Type::isClassType() const {
if (const auto *RT = getAs<RecordType>())
- return RT->getDecl()->isClass();
+ return RT->getOriginalDecl()->isClass();
return false;
}
bool Type::isStructureType() const {
if (const auto *RT = getAs<RecordType>())
- return RT->getDecl()->isStruct();
+ return RT->getOriginalDecl()->isStruct();
return false;
}
@@ -685,7 +687,7 @@ bool Type::isStructureTypeWithFlexibleArrayMember() const {
const auto *RT = getAs<RecordType>();
if (!RT)
return false;
- const auto *Decl = RT->getDecl();
+ const auto *Decl = RT->getOriginalDecl()->getDefinitionOrSelf();
if (!Decl->isStruct())
return false;
return Decl->hasFlexibleArrayMember();
@@ -693,19 +695,21 @@ bool Type::isStructureTypeWithFlexibleArrayMember() const {
bool Type::isObjCBoxableRecordType() const {
if (const auto *RT = getAs<RecordType>())
- return RT->getDecl()->hasAttr<ObjCBoxableAttr>();
+ return RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasAttr<ObjCBoxableAttr>();
return false;
}
bool Type::isInterfaceType() const {
if (const auto *RT = getAs<RecordType>())
- return RT->getDecl()->isInterface();
+ return RT->getOriginalDecl()->isInterface();
return false;
}
bool Type::isStructureOrClassType() const {
if (const auto *RT = getAs<RecordType>()) {
- RecordDecl *RD = RT->getDecl();
+ RecordDecl *RD = RT->getOriginalDecl();
return RD->isStruct() || RD->isClass() || RD->isInterface();
}
return false;
@@ -719,7 +723,7 @@ bool Type::isVoidPointerType() const {
bool Type::isUnionType() const {
if (const auto *RT = getAs<RecordType>())
- return RT->getDecl()->isUnion();
+ return RT->getOriginalDecl()->isUnion();
return false;
}
@@ -736,7 +740,7 @@ bool Type::isComplexIntegerType() const {
bool Type::isScopedEnumeralType() const {
if (const auto *ET = getAs<EnumType>())
- return ET->getDecl()->isScoped();
+ return ET->getOriginalDecl()->isScoped();
return false;
}
@@ -770,13 +774,13 @@ QualType Type::getPointeeType() const {
const RecordType *Type::getAsStructureType() const {
// If this is directly a structure type, return it.
if (const auto *RT = dyn_cast<RecordType>(this)) {
- if (RT->getDecl()->isStruct())
+ if (RT->getOriginalDecl()->isStruct())
return RT;
}
// If the canonical form of this type isn't the right kind, reject it.
if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) {
- if (!RT->getDecl()->isStruct())
+ if (!RT->getOriginalDecl()->isStruct())
return nullptr;
// If this is a typedef for a structure type, strip the typedef off without
@@ -789,13 +793,13 @@ const RecordType *Type::getAsStructureType() const {
const RecordType *Type::getAsUnionType() const {
// If this is directly a union type, return it.
if (const auto *RT = dyn_cast<RecordType>(this)) {
- if (RT->getDecl()->isUnion())
+ if (RT->getOriginalDecl()->isUnion())
return RT;
}
// If the canonical form of this type isn't the right kind, reject it.
if (const auto *RT = dyn_cast<RecordType>(CanonicalType)) {
- if (!RT->getDecl()->isUnion())
+ if (!RT->getOriginalDecl()->isUnion())
return nullptr;
// If this is a typedef for a union type, strip the typedef off without
@@ -1272,9 +1276,6 @@ struct SimpleTransformVisitor : public TypeVisitor<Derived, QualType> {
TRIVIAL_TYPE_CLASS(Record)
TRIVIAL_TYPE_CLASS(Enum)
- // FIXME: Non-trivial to implement, but important for C++
- SUGARED_TYPE_CLASS(Elaborated)
-
QualType VisitAttributedType(const AttributedType *T) {
QualType modifiedType = recurse(T->getModifiedType());
if (modifiedType.isNull())
@@ -1921,25 +1922,32 @@ const CXXRecordDecl *Type::getPointeeCXXRecordDecl() const {
return nullptr;
if (const auto *RT = PointeeType->getAs<RecordType>())
- return dyn_cast<CXXRecordDecl>(RT->getDecl());
+ return dyn_cast<CXXRecordDecl>(
+ RT->getOriginalDecl()->getDefinitionOrSelf());
return nullptr;
}
CXXRecordDecl *Type::getAsCXXRecordDecl() const {
- return dyn_cast_or_null<CXXRecordDecl>(getAsTagDecl());
+ const auto *TT = dyn_cast<TagType>(CanonicalType);
+ if (!isa_and_present<RecordType, InjectedClassNameType>(TT))
+ return nullptr;
+ auto *TD = TT->getOriginalDecl();
+ if (!isa<InjectedClassNameType>(TT) && !isa<CXXRecordDecl>(TD))
+ return nullptr;
+ return cast<CXXRecordDecl>(TD)->getDefinitionOrSelf();
}
RecordDecl *Type::getAsRecordDecl() const {
- return dyn_cast_or_null<RecordDecl>(getAsTagDecl());
+ const auto *TT = dyn_cast<TagType>(CanonicalType);
+ if (!isa_and_present<RecordType, InjectedClassNameType>(TT))
+ return nullptr;
+ return cast<RecordDecl>(TT->getOriginalDecl())->getDefinitionOrSelf();
}
TagDecl *Type::getAsTagDecl() const {
- if (const auto *TT = getAs<TagType>())
- return TT->getDecl();
- if (const auto *Injected = getAs<InjectedClassNameType>())
- return Injected->getDecl();
-
+ if (const auto *TT = dyn_cast<TagType>(CanonicalType))
+ return TT->getOriginalDecl()->getDefinitionOrSelf();
return nullptr;
}
@@ -1951,6 +1959,35 @@ Type::getAsNonAliasTemplateSpecializationType() const {
return TST;
}
+NestedNameSpecifier Type::getPrefix() const {
+ switch (getTypeClass()) {
+ case Type::DependentName:
+ return cast<DependentNameType>(this)->getQualifier();
+ case Type::TemplateSpecialization: {
+ QualifiedTemplateName *S = cast<TemplateSpecializationType>(this)
+ ->getTemplateName()
+ .getAsAdjustedQualifiedTemplateName();
+ return S ? S->getQualifier() : std::nullopt;
+ }
+ case Type::DependentTemplateSpecialization:
+ return cast<DependentTemplateSpecializationType>(this)
+ ->getDependentTemplateName()
+ .getQualifier();
+ case Type::Enum:
+ case Type::Record:
+ case Type::InjectedClassName:
+ return cast<TagType>(this)->getQualifier();
+ case Type::Typedef:
+ return cast<TypedefType>(this)->getQualifier();
+ case Type::UnresolvedUsing:
+ return cast<UnresolvedUsingType>(this)->getQualifier();
+ case Type::Using:
+ return cast<UsingType>(this)->getQualifier();
+ default:
+ return std::nullopt;
+ }
+}
+
bool Type::hasAttr(attr::Kind AK) const {
const Type *Cur = this;
while (const auto *AT = Cur->getAs<AttributedType>()) {
@@ -1989,10 +2026,6 @@ class GetContainedDeducedTypeVisitor
return Visit(T->getReplacementType());
}
- Type *VisitElaboratedType(const ElaboratedType *T) {
- return Visit(T->getNamedType());
- }
-
Type *VisitPointerType(const PointerType *T) {
return Visit(T->getPointeeType());
}
@@ -2114,7 +2147,7 @@ bool Type::isIntegralType(const ASTContext &Ctx) const {
// Complete enum types are integral in C.
if (!Ctx.getLangOpts().CPlusPlus)
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
- return ET->getDecl()->isComplete();
+ return IsEnumDeclComplete(ET->getOriginalDecl());
return isBitIntType();
}
@@ -2131,7 +2164,7 @@ bool Type::isIntegralOrUnscopedEnumerationType() const {
bool Type::isUnscopedEnumerationType() const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
- return !ET->getDecl()->isScoped();
+ return !ET->getOriginalDecl()->isScoped();
return false;
}
@@ -2216,8 +2249,10 @@ bool Type::isSignedIntegerType() const {
if (const EnumType *ET = dyn_cast<EnumType>(CanonicalType)) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
- if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
- return ET->getDecl()->getIntegerType()->isSignedIntegerType();
+ const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete() || ED->isScoped())
+ return false;
+ return ED->getIntegerType()->isSignedIntegerType();
}
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
@@ -2232,9 +2267,12 @@ bool Type::isSignedIntegerOrEnumerationType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->isSignedInteger();
- if (const auto *ET = dyn_cast<EnumType>(CanonicalType);
- ET && ET->getDecl()->isComplete())
- return ET->getDecl()->getIntegerType()->isSignedIntegerType();
+ if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
+ const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete())
+ return false;
+ return ED->getIntegerType()->isSignedIntegerType();
+ }
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
return IT->isSigned();
@@ -2261,8 +2299,10 @@ bool Type::isUnsignedIntegerType() const {
if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
// Incomplete enum types are not treated as integer types.
// FIXME: In C++, enum types are never integer types.
- if (ET->getDecl()->isComplete() && !ET->getDecl()->isScoped())
- return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
+ const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete() || ED->isScoped())
+ return false;
+ return ED->getIntegerType()->isUnsignedIntegerType();
}
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
@@ -2277,9 +2317,12 @@ bool Type::isUnsignedIntegerOrEnumerationType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->isUnsignedInteger();
- if (const auto *ET = dyn_cast<EnumType>(CanonicalType);
- ET && ET->getDecl()->isComplete())
- return ET->getDecl()->getIntegerType()->isUnsignedIntegerType();
+ if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
+ const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete())
+ return false;
+ return ED->getIntegerType()->isUnsignedIntegerType();
+ }
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
return IT->isUnsigned();
@@ -2328,8 +2371,10 @@ bool Type::isRealType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Ibm128;
- if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
- return ET->getDecl()->isComplete() && !ET->getDecl()->isScoped();
+ if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
+ const auto *ED = ET->getOriginalDecl();
+ return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete();
+ }
return isBitIntType();
}
@@ -2337,14 +2382,16 @@ bool Type::isArithmeticType() const {
if (const auto *BT = dyn_cast<BuiltinType>(CanonicalType))
return BT->getKind() >= BuiltinType::Bool &&
BT->getKind() <= BuiltinType::Ibm128;
- if (const auto *ET = dyn_cast<EnumType>(CanonicalType))
+ if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
// GCC allows forward declaration of enum types (forbid by C99 6.7.2.3p2).
// If a body isn't seen by the time we get here, return false.
//
// C++0x: Enumerations are not arithmetic types. For now, just return
// false for scoped enumerations since that will disable any
// unwanted implicit conversions.
- return !ET->getDecl()->isScoped() && ET->getDecl()->isComplete();
+ const auto *ED = ET->getOriginalDecl();
+ return !ED->isScoped() && ED->getDefinitionOrSelf()->isComplete();
+ }
return isa<ComplexType>(CanonicalType) || isBitIntType();
}
@@ -2352,8 +2399,8 @@ bool Type::hasBooleanRepresentation() const {
if (const auto *VT = dyn_cast<VectorType>(CanonicalType))
return VT->getElementType()->isBooleanType();
if (const auto *ET = dyn_cast<EnumType>(CanonicalType)) {
- return ET->getDecl()->isComplete() &&
- ET->getDecl()->getIntegerType()->isBooleanType();
+ const auto *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ return ED->isComplete() && ED->getIntegerType()->isBooleanType();
}
if (const auto *IT = dyn_cast<BitIntType>(CanonicalType))
return IT->getNumBits() == 1;
@@ -2385,7 +2432,10 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
} else if (isa<MemberPointerType>(T)) {
return STK_MemberPointer;
} else if (isa<EnumType>(T)) {
- assert(cast<EnumType>(T)->getDecl()->isComplete());
+ assert(cast<EnumType>(T)
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isComplete());
return STK_Integral;
} else if (const auto *CT = dyn_cast<ComplexType>(T)) {
if (CT->getElementType()->isRealFloatingType())
@@ -2409,7 +2459,8 @@ Type::ScalarTypeKind Type::getScalarTypeKind() const {
/// includes union types.
bool Type::isAggregateType() const {
if (const auto *Record = dyn_cast<RecordType>(CanonicalType)) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(Record->getDecl()))
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(
+ Record->getOriginalDecl()->getDefinitionOrSelf()))
return ClassDecl->isAggregate();
return true;
@@ -2443,7 +2494,8 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
// be completed.
return isVoidType();
case Enum: {
- EnumDecl *EnumD = cast<EnumType>(CanonicalType)->getDecl();
+ EnumDecl *EnumD =
+ cast<EnumType>(CanonicalType)->getOriginalDecl()->getDefinitionOrSelf();
if (Def)
*Def = EnumD;
return !EnumD->isComplete();
@@ -2451,13 +2503,17 @@ bool Type::isIncompleteType(NamedDecl **Def) const {
case Record: {
// A tagged type (struct/union/enum/class) is incomplete if the decl is a
// forward declaration, but not a full definition (C99 6.2.5p22).
- RecordDecl *Rec = cast<RecordType>(CanonicalType)->getDecl();
+ RecordDecl *Rec = cast<RecordType>(CanonicalType)
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
if (Def)
*Def = Rec;
return !Rec->isCompleteDefinition();
}
case InjectedClassName: {
- CXXRecordDecl *Rec = cast<InjectedClassNameType>(CanonicalType)->getDecl();
+ CXXRecordDecl *Rec = cast<InjectedClassNameType>(CanonicalType)
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
if (!Rec->isBeingDefined())
return false;
if (Def)
@@ -2739,9 +2795,9 @@ bool QualType::isCXX98PODType(const ASTContext &Context) const {
return true;
case Type::Record:
- if (const auto *ClassDecl =
- dyn_cast<CXXRecordDecl>(cast<RecordType>(CanonicalType)->getDecl()))
- return ClassDecl->isPOD();
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(
+ cast<RecordType>(CanonicalType)->getOriginalDecl()))
+ return ClassDecl->getDefinitionOrSelf()->isPOD();
// C struct/union is POD.
return true;
@@ -2782,7 +2838,8 @@ bool QualType::isTrivialType(const ASTContext &Context) const {
if (CanonicalType->isScalarType() || CanonicalType->isVectorType())
return true;
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (const auto *ClassDecl =
+ dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
// C++20 [class]p6:
// A trivial class is a class that is trivially copyable, and
// has one or more eligible default constructors such that each is
@@ -2841,14 +2898,17 @@ static bool isTriviallyCopyableTypeImpl(const QualType &type,
return true;
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (const auto *ClassDecl =
+ dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
if (IsCopyConstructible) {
return ClassDecl->isTriviallyCopyConstructible();
} else {
return ClassDecl->isTriviallyCopyable();
}
}
- return !RT->getDecl()->isNonTrivialToPrimitiveCopy();
+ return !RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isNonTrivialToPrimitiveCopy();
}
// No other types can match.
return false;
@@ -2938,7 +2998,9 @@ QualType::PrimitiveDefaultInitializeKind
QualType::isNonTrivialToPrimitiveDefaultInitialize() const {
if (const auto *RT =
getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>())
- if (RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize())
+ if (RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isNonTrivialToPrimitiveDefaultInitialize())
return PDIK_Struct;
switch (getQualifiers().getObjCLifetime()) {
@@ -2954,7 +3016,9 @@ QualType::isNonTrivialToPrimitiveDefaultInitialize() const {
QualType::PrimitiveCopyKind QualType::isNonTrivialToPrimitiveCopy() const {
if (const auto *RT =
getTypePtr()->getBaseElementTypeUnsafe()->getAs<RecordType>())
- if (RT->getDecl()->isNonTrivialToPrimitiveCopy())
+ if (RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isNonTrivialToPrimitiveCopy())
return PCK_Struct;
Qualifiers Qs = getQualifiers();
@@ -3022,8 +3086,8 @@ bool Type::isLiteralType(const ASTContext &Ctx) const {
// -- all non-static data members and base classes of literal types
//
// We resolve DR1361 by ignoring the second bullet.
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
- return ClassDecl->isLiteral();
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
+ return ClassDecl->getDefinitionOrSelf()->isLiteral();
return true;
}
@@ -3076,8 +3140,8 @@ bool Type::isStandardLayoutType() const {
if (BaseTy->isScalarType() || BaseTy->isVectorType())
return true;
if (const auto *RT = BaseTy->getAs<RecordType>()) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
- if (!ClassDecl->isStandardLayout())
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
+ if (!ClassDecl->getDefinitionOrSelf()->isStandardLayout())
return false;
// Default to 'true' for non-C++ class types.
@@ -3119,7 +3183,9 @@ bool QualType::isCXX11PODType(const ASTContext &Context) const {
if (BaseTy->isScalarType() || BaseTy->isVectorType())
return true;
if (const auto *RT = BaseTy->getAs<RecordType>()) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (const auto *ClassDecl =
+ dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
+ ClassDecl = ClassDecl->getDefinitionOrSelf();
// C++11 [class]p10:
// A POD struct is a non-union class that is both a trivial class [...]
if (!ClassDecl->isTrivial())
@@ -3159,8 +3225,9 @@ bool Type::isNothrowT() const {
bool Type::isAlignValT() const {
if (const auto *ET = getAs<EnumType>()) {
- IdentifierInfo *II = ET->getDecl()->getIdentifier();
- if (II && II->isStr("align_val_t") && ET->getDecl()->isInStdNamespace())
+ const auto *ED = ET->getOriginalDecl();
+ IdentifierInfo *II = ED->getIdentifier();
+ if (II && II->isStr("align_val_t") && ED->isInStdNamespace())
return true;
}
return false;
@@ -3168,8 +3235,9 @@ bool Type::isAlignValT() const {
bool Type::isStdByteType() const {
if (const auto *ET = getAs<EnumType>()) {
- IdentifierInfo *II = ET->getDecl()->getIdentifier();
- if (II && II->isStr("byte") && ET->getDecl()->isInStdNamespace())
+ const auto *ED = ET->getOriginalDecl();
+ IdentifierInfo *II = ED->getIdentifier();
+ if (II && II->isStr("byte") && ED->isInStdNamespace())
return true;
}
return false;
@@ -3188,7 +3256,6 @@ bool Type::isSpecifierType() const {
case TemplateTypeParm:
case SubstTemplateTypeParm:
case TemplateSpecialization:
- case Elaborated:
case DependentName:
case DependentTemplateSpecialization:
case ObjCInterface:
@@ -3199,8 +3266,7 @@ bool Type::isSpecifierType() const {
}
}
-ElaboratedTypeKeyword
-TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
+ElaboratedTypeKeyword KeywordHelpers::getKeywordForTypeSpec(unsigned TypeSpec) {
switch (TypeSpec) {
default:
return ElaboratedTypeKeyword::None;
@@ -3219,7 +3285,7 @@ TypeWithKeyword::getKeywordForTypeSpec(unsigned TypeSpec) {
}
}
-TagTypeKind TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
+TagTypeKind KeywordHelpers::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
switch (TypeSpec) {
case TST_class:
return TagTypeKind::Class;
@@ -3237,7 +3303,7 @@ TagTypeKind TypeWithKeyword::getTagTypeKindForTypeSpec(unsigned TypeSpec) {
}
ElaboratedTypeKeyword
-TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
+KeywordHelpers::getKeywordForTagTypeKind(TagTypeKind Kind) {
switch (Kind) {
case TagTypeKind::Class:
return ElaboratedTypeKeyword::Class;
@@ -3254,7 +3320,7 @@ TypeWithKeyword::getKeywordForTagTypeKind(TagTypeKind Kind) {
}
TagTypeKind
-TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
+KeywordHelpers::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
case ElaboratedTypeKeyword::Class:
return TagTypeKind::Class;
@@ -3273,7 +3339,7 @@ TypeWithKeyword::getTagTypeKindForKeyword(ElaboratedTypeKeyword Keyword) {
llvm_unreachable("Unknown elaborated type keyword.");
}
-bool TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
+bool KeywordHelpers::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
case ElaboratedTypeKeyword::None:
case ElaboratedTypeKeyword::Typename:
@@ -3288,7 +3354,7 @@ bool TypeWithKeyword::KeywordIsTagTypeKind(ElaboratedTypeKeyword Keyword) {
llvm_unreachable("Unknown elaborated type keyword.");
}
-StringRef TypeWithKeyword::getKeywordName(ElaboratedTypeKeyword Keyword) {
+StringRef KeywordHelpers::getKeywordName(ElaboratedTypeKeyword Keyword) {
switch (Keyword) {
case ElaboratedTypeKeyword::None:
return {};
@@ -3338,13 +3404,21 @@ void DependentTemplateSpecializationType::Profile(
bool Type::isElaboratedTypeSpecifier() const {
ElaboratedTypeKeyword Keyword;
- if (const auto *Elab = dyn_cast<ElaboratedType>(this))
- Keyword = Elab->getKeyword();
+ if (const auto *TST = dyn_cast<TemplateSpecializationType>(this))
+ Keyword = TST->getKeyword();
else if (const auto *DepName = dyn_cast<DependentNameType>(this))
Keyword = DepName->getKeyword();
else if (const auto *DepTST =
dyn_cast<DependentTemplateSpecializationType>(this))
Keyword = DepTST->getKeyword();
+ else if (const auto *T = dyn_cast<TagType>(this))
+ Keyword = T->getKeyword();
+ else if (const auto *T = dyn_cast<TypedefType>(this))
+ Keyword = T->getKeyword();
+ else if (const auto *T = dyn_cast<UnresolvedUsingType>(this))
+ Keyword = T->getKeyword();
+ else if (const auto *T = dyn_cast<UsingType>(this))
+ Keyword = T->getKeyword();
else
return false;
@@ -4011,34 +4085,53 @@ StringRef CountAttributedType::getAttributeName(bool WithMacroPrefix) const {
#undef ENUMERATE_ATTRS
}
-TypedefType::TypedefType(TypeClass tc, const TypedefNameDecl *D,
- QualType UnderlyingType, bool HasTypeDifferentFromDecl)
- : Type(tc, UnderlyingType.getCanonicalType(),
- toSemanticDependence(UnderlyingType->getDependence())),
+TypedefType::TypedefType(TypeClass TC, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TypedefNameDecl *D, QualType UnderlyingType,
+ bool HasTypeDifferentFromDecl)
+ : TypeWithKeyword(
+ Keyword, TC, UnderlyingType.getCanonicalType(),
+ toSemanticDependence(UnderlyingType->getDependence()) |
+ (Qualifier
+ ? toTypeDependence(Qualifier.getDependence() &
+ ~NestedNameSpecifierDependence::Dependent)
+ : TypeDependence{})),
Decl(const_cast<TypedefNameDecl *>(D)) {
- TypedefBits.hasTypeDifferentFromDecl = HasTypeDifferentFromDecl;
- if (!typeMatchesDecl())
- *getTrailingObjects() = UnderlyingType;
+ if ((TypedefBits.hasQualifier = !!Qualifier))
+ *getTrailingObjects<NestedNameSpecifier>() = Qualifier;
+ if ((TypedefBits.hasTypeDifferentFromDecl = HasTypeDifferentFromDecl))
+ *getTrailingObjects<QualType>() = UnderlyingType;
}
QualType TypedefType::desugar() const {
- return typeMatchesDecl() ? Decl->getUnderlyingType() : *getTrailingObjects();
-}
-
-UsingType::UsingType(const UsingShadowDecl *Found, QualType Underlying,
- QualType Canon)
- : Type(Using, Canon, toSemanticDependence(Canon->getDependence())),
- Found(const_cast<UsingShadowDecl *>(Found)) {
- UsingBits.hasTypeDifferentFromDecl = !Underlying.isNull();
- if (!typeMatchesDecl())
- *getTrailingObjects() = Underlying;
-}
-
-QualType UsingType::getUnderlyingType() const {
- return typeMatchesDecl()
- ? QualType(
- cast<TypeDecl>(Found->getTargetDecl())->getTypeForDecl(), 0)
- : *getTrailingObjects();
+ return typeMatchesDecl() ? Decl->getUnderlyingType()
+ : *getTrailingObjects<QualType>();
+}
+
+UnresolvedUsingType::UnresolvedUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const UnresolvedUsingTypenameDecl *D,
+ const Type *CanonicalType)
+ : TypeWithKeyword(
+ Keyword, UnresolvedUsing, QualType(CanonicalType, 0),
+ TypeDependence::DependentInstantiation |
+ (Qualifier
+ ? toTypeDependence(Qualifier.getDependence() &
+ ~NestedNameSpecifierDependence::Dependent)
+ : TypeDependence{})),
+ Decl(const_cast<UnresolvedUsingTypenameDecl *>(D)) {
+ if ((UnresolvedUsingBits.hasQualifier = !!Qualifier))
+ *getTrailingObjects<NestedNameSpecifier>() = Qualifier;
+}
+
+UsingType::UsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const UsingShadowDecl *D,
+ QualType UnderlyingType)
+ : TypeWithKeyword(Keyword, Using, UnderlyingType.getCanonicalType(),
+ toSemanticDependence(UnderlyingType->getDependence())),
+ D(const_cast<UsingShadowDecl *>(D)), UnderlyingType(UnderlyingType) {
+ if ((UsingBits.hasQualifier = !!Qualifier))
+ *getTrailingObjects() = Qualifier;
}
QualType MacroQualifiedType::desugar() const { return getUnderlyingType(); }
@@ -4212,24 +4305,79 @@ UnaryTransformType::UnaryTransformType(QualType BaseType,
: Type(UnaryTransform, CanonicalType, BaseType->getDependence()),
BaseType(BaseType), UnderlyingType(UnderlyingType), UKind(UKind) {}
-TagType::TagType(TypeClass TC, const TagDecl *D, QualType can)
- : Type(TC, can,
- D->isDependentType() ? TypeDependence::DependentInstantiation
- : TypeDependence::None),
- decl(const_cast<TagDecl *>(D)) {}
-
-static TagDecl *getInterestingTagDecl(TagDecl *decl) {
- for (auto *I : decl->redecls()) {
- if (I->isCompleteDefinition() || I->isBeingDefined())
- return I;
+TagType::TagType(TypeClass TC, ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, const TagDecl *Tag,
+ bool OwnsTag, bool ISInjected, const Type *CanonicalType)
+ : TypeWithKeyword(
+ Keyword, TC, QualType(CanonicalType, 0),
+ (Tag->isDependentType() ? TypeDependence::DependentInstantiation
+ : TypeDependence::None) |
+ (Qualifier
+ ? toTypeDependence(Qualifier.getDependence() &
+ ~NestedNameSpecifierDependence::Dependent)
+ : TypeDependence{})),
+ decl(const_cast<TagDecl *>(Tag)) {
+ if ((TagTypeBits.HasQualifier = !!Qualifier))
+ getTrailingQualifier() = Qualifier;
+ TagTypeBits.OwnsTag = !!OwnsTag;
+ TagTypeBits.IsInjected = ISInjected;
+}
+
+void *TagType::getTrailingPointer() const {
+ switch (getTypeClass()) {
+ case Type::Enum:
+ return const_cast<EnumType *>(cast<EnumType>(this) + 1);
+ case Type::Record:
+ return const_cast<RecordType *>(cast<RecordType>(this) + 1);
+ case Type::InjectedClassName:
+ return const_cast<InjectedClassNameType *>(
+ cast<InjectedClassNameType>(this) + 1);
+ default:
+ llvm_unreachable("unexpected type class");
}
- // If there's no definition (not even in progress), return what we have.
- return decl;
}
-TagDecl *TagType::getDecl() const { return getInterestingTagDecl(decl); }
+NestedNameSpecifier &TagType::getTrailingQualifier() const {
+ assert(TagTypeBits.HasQualifier);
+ return *reinterpret_cast<NestedNameSpecifier *>(llvm::alignAddr(
+ getTrailingPointer(), llvm::Align::Of<NestedNameSpecifier *>()));
+}
+
+NestedNameSpecifier TagType::getQualifier() const {
+ return TagTypeBits.HasQualifier ? getTrailingQualifier() : std::nullopt;
+}
-bool TagType::isBeingDefined() const { return getDecl()->isBeingDefined(); }
+ClassTemplateDecl *TagType::getTemplateDecl() const {
+ auto *Decl = dyn_cast<CXXRecordDecl>(decl);
+ if (!Decl)
+ return nullptr;
+ if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl))
+ return RD->getSpecializedTemplate();
+ return Decl->getDescribedClassTemplate();
+}
+
+TemplateName TagType::getTemplateName(const ASTContext &Ctx) const {
+ auto *TD = getTemplateDecl();
+ if (!TD)
+ return TemplateName();
+ if (isCanonicalUnqualified())
+ return TemplateName(TD);
+ return Ctx.getQualifiedTemplateName(getQualifier(), /*TemplateKeyword=*/false,
+ TemplateName(TD));
+}
+
+ArrayRef<TemplateArgument>
+TagType::getTemplateArgs(const ASTContext &Ctx) const {
+ auto *Decl = dyn_cast<CXXRecordDecl>(decl);
+ if (!Decl)
+ return {};
+
+ if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl))
+ return RD->getTemplateArgs().asArray();
+ if (ClassTemplateDecl *TD = Decl->getDescribedClassTemplate())
+ return TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx);
+ return {};
+}
bool RecordType::hasConstFields() const {
std::vector<const RecordType *> RecordTypeList;
@@ -4237,8 +4385,10 @@ bool RecordType::hasConstFields() const {
unsigned NextToCheckIndex = 0;
while (RecordTypeList.size() > NextToCheckIndex) {
- for (FieldDecl *FD :
- RecordTypeList[NextToCheckIndex]->getDecl()->fields()) {
+ for (FieldDecl *FD : RecordTypeList[NextToCheckIndex]
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->fields()) {
QualType FieldTy = FD->getType();
if (FieldTy.isConstQualified())
return true;
@@ -4253,6 +4403,19 @@ bool RecordType::hasConstFields() const {
return false;
}
+InjectedClassNameType::InjectedClassNameType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ const TagDecl *TD, bool IsInjected,
+ CanQualType CanonicalInjectedTST,
+ const Type *CanonicalType)
+ : TagType(TypeClass::InjectedClassName, Keyword, Qualifier, TD,
+ /*OwnsTag=*/false, IsInjected, CanonicalType),
+ CanonicalInjectedTST(CanonicalInjectedTST) {}
+
+CanQualType InjectedClassNameType::getCanonicalInjectedTST() const {
+ return CanQualType::CreateUnsafe(CanonicalInjectedTST);
+}
+
AttributedType::AttributedType(QualType canon, const Attr *attr,
QualType modified, QualType equivalent)
: AttributedType(canon, attr->getKind(), attr, modified, equivalent) {}
@@ -4340,10 +4503,6 @@ bool AttributedType::isCallingConv() const {
llvm_unreachable("invalid attr kind");
}
-CXXRecordDecl *InjectedClassNameType::getDecl() const {
- return cast<CXXRecordDecl>(getInterestingTagDecl(Decl));
-}
-
IdentifierInfo *TemplateTypeParmType::getIdentifier() const {
return isCanonicalUnqualified() ? nullptr : getDecl()->getIdentifier();
}
@@ -4467,16 +4626,17 @@ bool TemplateSpecializationType::anyInstantiationDependentTemplateArguments(
}
TemplateSpecializationType::TemplateSpecializationType(
- TemplateName T, bool IsAlias, ArrayRef<TemplateArgument> Args,
- QualType Underlying)
- : Type(TemplateSpecialization,
- Underlying.isNull() ? QualType(this, 0)
- : Underlying.getCanonicalType(),
- (Underlying.isNull()
- ? TypeDependence::DependentInstantiation
- : toSemanticDependence(Underlying->getDependence())) |
- (toTypeDependence(T.getDependence()) &
- TypeDependence::UnexpandedPack)),
+ ElaboratedTypeKeyword Keyword, TemplateName T, bool IsAlias,
+ ArrayRef<TemplateArgument> Args, QualType Underlying)
+ : TypeWithKeyword(
+ Keyword, TemplateSpecialization,
+ Underlying.isNull() ? QualType(this, 0)
+ : Underlying.getCanonicalType(),
+ (Underlying.isNull()
+ ? TypeDependence::DependentInstantiation
+ : toSemanticDependence(Underlying->getDependence())) |
+ (toTypeDependence(T.getDependence()) &
+ TypeDependence::UnexpandedPack)),
Template(T) {
TemplateSpecializationTypeBits.NumArgs = Args.size();
TemplateSpecializationTypeBits.TypeAlias = IsAlias;
@@ -4699,7 +4859,8 @@ static CachedProperties computeCachedProperties(const Type *T) {
case Type::Record:
case Type::Enum: {
- const TagDecl *Tag = cast<TagType>(T)->getDecl();
+ const TagDecl *Tag =
+ cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf();
// C++ [basic.link]p8:
// - it is a class or enumeration type that is named (or has a name
@@ -4726,12 +4887,9 @@ static CachedProperties computeCachedProperties(const Type *T) {
case Type::MemberPointer: {
const auto *MPT = cast<MemberPointerType>(T);
CachedProperties Cls = [&] {
- if (auto *RD = MPT->getMostRecentCXXRecordDecl())
- return Cache::get(QualType(RD->getTypeForDecl(), 0));
- if (const Type *T = MPT->getQualifier()->getAsType())
- return Cache::get(T);
- // Treat as a dependent type.
- return CachedProperties(Linkage::External, false);
+ if (MPT->isSugared())
+ MPT = cast<MemberPointerType>(MPT->getCanonicalTypeInternal());
+ return Cache::get(MPT->getQualifier().getAsType());
}();
return merge(Cls, Cache::get(MPT->getPointeeType()));
}
@@ -4811,7 +4969,8 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
case Type::Record:
case Type::Enum:
- return getDeclLinkageAndVisibility(cast<TagType>(T)->getDecl());
+ return getDeclLinkageAndVisibility(
+ cast<TagType>(T)->getOriginalDecl()->getDefinitionOrSelf());
case Type::Complex:
return computeTypeLinkageInfo(cast<ComplexType>(T)->getElementType());
@@ -4827,8 +4986,8 @@ LinkageInfo LinkageComputer::computeTypeLinkageInfo(const Type *T) {
LinkageInfo LV;
if (auto *D = MPT->getMostRecentCXXRecordDecl()) {
LV.merge(getDeclLinkageAndVisibility(D));
- } else if (auto *Ty = MPT->getQualifier()->getAsType()) {
- LV.merge(computeTypeLinkageInfo(Ty));
+ } else {
+ LV.merge(computeTypeLinkageInfo(MPT->getQualifier().getAsType()));
}
LV.merge(computeTypeLinkageInfo(MPT->getPointeeType()));
return LV;
@@ -5014,7 +5173,7 @@ bool Type::canHaveNullability(bool ResultIfUnknown) const {
llvm_unreachable("unknown builtin type");
case Type::Record: {
- const RecordDecl *RD = cast<RecordType>(type)->getDecl();
+ const RecordDecl *RD = cast<RecordType>(type)->getOriginalDecl();
// For template specializations, look only at primary template attributes.
// This is a consistent regardless of whether the instantiation is known.
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
@@ -5212,14 +5371,18 @@ bool Type::isCARCBridgableType() const {
/// Check if the specified type is the CUDA device builtin surface type.
bool Type::isCUDADeviceBuiltinSurfaceType() const {
if (const auto *RT = getAs<RecordType>())
- return RT->getDecl()->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>();
+ return RT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>();
return false;
}
/// Check if the specified type is the CUDA device builtin texture type.
bool Type::isCUDADeviceBuiltinTextureType() const {
if (const auto *RT = getAs<RecordType>())
- return RT->getDecl()->hasAttr<CUDADeviceBuiltinTextureTypeAttr>();
+ return RT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<CUDADeviceBuiltinTextureTypeAttr>();
return false;
}
@@ -5283,7 +5446,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
}
if (const auto *RT = type->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl();
if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
/// Check if this is a C++ object with a non-trivial destructor.
if (CXXRD->hasDefinition() && !CXXRD->hasTrivialDestructor())
@@ -5291,7 +5454,7 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
} else {
/// Check if this is a C struct that is non-trivial to destroy or an array
/// that contains such a struct.
- if (RD->isNonTrivialToPrimitiveDestroy())
+ if (RD->getDefinitionOrSelf()->isNonTrivialToPrimitiveDestroy())
return DK_nontrivial_c_struct;
}
}
@@ -5301,16 +5464,16 @@ QualType::DestructionKind QualType::isDestructedTypeImpl(QualType type) {
bool MemberPointerType::isSugared() const {
CXXRecordDecl *D1 = getMostRecentCXXRecordDecl(),
- *D2 = getQualifier()->getAsRecordDecl();
+ *D2 = getQualifier().getAsRecordDecl();
assert(!D1 == !D2);
return D1 != D2 && D1->getCanonicalDecl() != D2->getCanonicalDecl();
}
void MemberPointerType::Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
- const NestedNameSpecifier *Qualifier,
+ const NestedNameSpecifier Qualifier,
const CXXRecordDecl *Cls) {
ID.AddPointer(Pointee.getAsOpaquePtr());
- ID.AddPointer(Qualifier);
+ Qualifier.Profile(ID);
if (Cls)
ID.AddPointer(Cls->getCanonicalDecl());
}
@@ -5318,14 +5481,14 @@ void MemberPointerType::Profile(llvm::FoldingSetNodeID &ID, QualType Pointee,
CXXRecordDecl *MemberPointerType::getCXXRecordDecl() const {
return dyn_cast<MemberPointerType>(getCanonicalTypeInternal())
->getQualifier()
- ->getAsRecordDecl();
+ .getAsRecordDecl();
}
CXXRecordDecl *MemberPointerType::getMostRecentCXXRecordDecl() const {
auto *RD = getCXXRecordDecl();
if (!RD)
return nullptr;
- return RD->getMostRecentNonInjectedDecl();
+ return RD->getMostRecentDecl();
}
void clang::FixedPointValueToString(SmallVectorImpl<char> &Str,
diff --git a/clang/lib/AST/TypeLoc.cpp b/clang/lib/AST/TypeLoc.cpp
index 5c45c596538f8..83099a74aa7b5 100644
--- a/clang/lib/AST/TypeLoc.cpp
+++ b/clang/lib/AST/TypeLoc.cpp
@@ -195,15 +195,6 @@ SourceLocation TypeLoc::getBeginLoc() const {
TypeLoc LeftMost = Cur;
while (true) {
switch (Cur.getTypeLocClass()) {
- case Elaborated:
- if (Cur.getLocalSourceRange().getBegin().isValid()) {
- LeftMost = Cur;
- break;
- }
- Cur = Cur.getNextTypeLoc();
- if (Cur.isNull())
- break;
- continue;
case FunctionProto:
if (Cur.castAs<FunctionProtoTypeLoc>().getTypePtr()
->hasTrailingReturn()) {
@@ -275,7 +266,6 @@ SourceLocation TypeLoc::getEndLoc() const {
Last = Cur;
break;
case Qualified:
- case Elaborated:
break;
}
Cur = Cur.getNextTypeLoc();
@@ -313,9 +303,8 @@ bool TypeSpecTypeLoc::isKind(const TypeLoc &TL) {
}
bool TagTypeLoc::isDefinition() const {
- TagDecl *D = getDecl();
- return D->isCompleteDefinition() &&
- (D->getIdentifier() == nullptr || D->getLocation() == getNameLoc());
+ return getTypePtr()->isTagOwned() &&
+ getOriginalDecl()->isCompleteDefinition();
}
// Reimplemented to account for GNU/C++ extension
@@ -482,6 +471,134 @@ TypeLoc TypeLoc::findExplicitQualifierLoc() const {
return {};
}
+NestedNameSpecifierLoc TypeLoc::getPrefix() const {
+ switch (getTypeLocClass()) {
+ case TypeLoc::DependentName:
+ return castAs<DependentNameTypeLoc>().getQualifierLoc();
+ case TypeLoc::TemplateSpecialization:
+ return castAs<TemplateSpecializationTypeLoc>().getQualifierLoc();
+ case TypeLoc::DependentTemplateSpecialization:
+ return castAs<DependentTemplateSpecializationTypeLoc>().getQualifierLoc();
+ case TypeLoc::DeducedTemplateSpecialization:
+ return castAs<DeducedTemplateSpecializationTypeLoc>().getQualifierLoc();
+ case TypeLoc::Enum:
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName:
+ return castAs<TagTypeLoc>().getQualifierLoc();
+ case TypeLoc::Typedef:
+ return castAs<TypedefTypeLoc>().getQualifierLoc();
+ case TypeLoc::UnresolvedUsing:
+ return castAs<UnresolvedUsingTypeLoc>().getQualifierLoc();
+ case TypeLoc::Using:
+ return castAs<UsingTypeLoc>().getQualifierLoc();
+ default:
+ return NestedNameSpecifierLoc();
+ }
+}
+
+SourceLocation TypeLoc::getNonPrefixBeginLoc() const {
+ switch (getTypeLocClass()) {
+ case TypeLoc::TemplateSpecialization: {
+ auto TL = castAs<TemplateSpecializationTypeLoc>();
+ SourceLocation Loc = TL.getTemplateKeywordLoc();
+ if (!Loc.isValid())
+ Loc = TL.getTemplateNameLoc();
+ return Loc;
+ }
+ case TypeLoc::DependentTemplateSpecialization: {
+ auto TL = castAs<DependentTemplateSpecializationTypeLoc>();
+ SourceLocation Loc = TL.getTemplateKeywordLoc();
+ if (!Loc.isValid())
+ Loc = TL.getTemplateNameLoc();
+ return Loc;
+ }
+ case TypeLoc::DeducedTemplateSpecialization: {
+ auto TL = castAs<DeducedTemplateSpecializationTypeLoc>();
+ SourceLocation Loc = TL.getTemplateKeywordLoc();
+ if (!Loc.isValid())
+ Loc = TL.getTemplateNameLoc();
+ return Loc;
+ }
+ case TypeLoc::DependentName:
+ return castAs<DependentNameTypeLoc>().getNameLoc();
+ case TypeLoc::Enum:
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName:
+ return castAs<TagTypeLoc>().getNameLoc();
+ case TypeLoc::Typedef:
+ return castAs<TypedefTypeLoc>().getNameLoc();
+ case TypeLoc::UnresolvedUsing:
+ return castAs<UnresolvedUsingTypeLoc>().getNameLoc();
+ case TypeLoc::Using:
+ return castAs<UsingTypeLoc>().getNameLoc();
+ default:
+ return getBeginLoc();
+ }
+}
+
+SourceLocation TypeLoc::getNonElaboratedBeginLoc() const {
+ // For elaborated types (e.g. `struct a::A`) we want the portion after the
+ // `struct` but including the namespace qualifier, `a::`.
+ switch (getTypeLocClass()) {
+ case TypeLoc::Qualified:
+ return castAs<QualifiedTypeLoc>()
+ .getUnqualifiedLoc()
+ .getNonElaboratedBeginLoc();
+ case TypeLoc::TemplateSpecialization: {
+ auto T = castAs<TemplateSpecializationTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getTemplateNameLoc();
+ }
+ case TypeLoc::DependentTemplateSpecialization: {
+ auto T = castAs<DependentTemplateSpecializationTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getTemplateNameLoc();
+ }
+ case TypeLoc::DeducedTemplateSpecialization: {
+ auto T = castAs<DeducedTemplateSpecializationTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getTemplateNameLoc();
+ }
+ case TypeLoc::DependentName: {
+ auto T = castAs<DependentNameTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getNameLoc();
+ }
+ case TypeLoc::Enum:
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName: {
+ auto T = castAs<TagTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getNameLoc();
+ }
+ case TypeLoc::Typedef: {
+ auto T = castAs<TypedefTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getNameLoc();
+ }
+ case TypeLoc::UnresolvedUsing: {
+ auto T = castAs<UnresolvedUsingTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getNameLoc();
+ }
+ case TypeLoc::Using: {
+ auto T = castAs<UsingTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = T.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return T.getNameLoc();
+ }
+ default:
+ return getBeginLoc();
+ }
+}
+
void ObjCTypeParamTypeLoc::initializeLocal(ASTContext &Context,
SourceLocation Loc) {
setNameLoc(Loc);
@@ -555,9 +672,9 @@ static void initializeElaboratedKeyword(TL T, SourceLocation Loc) {
: SourceLocation());
}
-static NestedNameSpecifierLoc
-initializeQualifier(ASTContext &Context, NestedNameSpecifier *Qualifier,
- SourceLocation Loc) {
+static NestedNameSpecifierLoc initializeQualifier(ASTContext &Context,
+ NestedNameSpecifier Qualifier,
+ SourceLocation Loc) {
if (!Qualifier)
return NestedNameSpecifierLoc();
NestedNameSpecifierLocBuilder Builder;
@@ -565,15 +682,6 @@ initializeQualifier(ASTContext &Context, NestedNameSpecifier *Qualifier,
return Builder.getWithLocInContext(Context);
}
-void ElaboratedTypeLoc::initializeLocal(ASTContext &Context,
- SourceLocation Loc) {
- if (isEmpty())
- return;
- initializeElaboratedKeyword(*this, Loc);
- setQualifierLoc(
- initializeQualifier(Context, getTypePtr()->getQualifier(), Loc));
-}
-
void DependentNameTypeLoc::initializeLocal(ASTContext &Context,
SourceLocation Loc) {
initializeElaboratedKeyword(*this, Loc);
@@ -596,6 +704,78 @@ DependentTemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
Context, getTypePtr()->template_arguments(), getArgInfos(), Loc);
}
+void TemplateSpecializationTypeLoc::set(SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKeywordLoc,
+ SourceLocation NameLoc,
+ SourceLocation LAngleLoc,
+ SourceLocation RAngleLoc) {
+ TemplateSpecializationLocInfo &Data = *getLocalData();
+
+ Data.ElaboratedKWLoc = ElaboratedKeywordLoc;
+ SourceLocation BeginLoc = ElaboratedKeywordLoc;
+
+ getLocalData()->QualifierData = QualifierLoc.getOpaqueData();
+
+ assert(QualifierLoc.getNestedNameSpecifier() ==
+ getTypePtr()->getTemplateName().getQualifier());
+ Data.QualifierData = QualifierLoc ? QualifierLoc.getOpaqueData() : nullptr;
+ if (QualifierLoc && !BeginLoc.isValid())
+ BeginLoc = QualifierLoc.getBeginLoc();
+
+ Data.TemplateKWLoc = TemplateKeywordLoc;
+ if (!BeginLoc.isValid())
+ BeginLoc = TemplateKeywordLoc;
+
+ Data.NameLoc = NameLoc;
+ if (!BeginLoc.isValid())
+ BeginLoc = NameLoc;
+
+ Data.LAngleLoc = LAngleLoc;
+ Data.SR = SourceRange(BeginLoc, RAngleLoc);
+}
+
+void TemplateSpecializationTypeLoc::set(SourceLocation ElaboratedKeywordLoc,
+ NestedNameSpecifierLoc QualifierLoc,
+ SourceLocation TemplateKeywordLoc,
+ SourceLocation NameLoc,
+ const TemplateArgumentListInfo &TAL) {
+ set(ElaboratedKeywordLoc, QualifierLoc, TemplateKeywordLoc, NameLoc,
+ TAL.getLAngleLoc(), TAL.getRAngleLoc());
+ MutableArrayRef<TemplateArgumentLocInfo> ArgInfos = getArgLocInfos();
+ assert(TAL.size() == ArgInfos.size());
+ for (unsigned I = 0, N = TAL.size(); I != N; ++I)
+ ArgInfos[I] = TAL[I].getLocInfo();
+}
+
+void TemplateSpecializationTypeLoc::initializeLocal(ASTContext &Context,
+ SourceLocation Loc) {
+ QualifiedTemplateName *Name =
+ getTypePtr()->getTemplateName().getAsAdjustedQualifiedTemplateName();
+
+ SourceLocation ElaboratedKeywordLoc =
+ getTypePtr()->getKeyword() != ElaboratedTypeKeyword::None
+ ? Loc
+ : SourceLocation();
+
+ NestedNameSpecifierLoc QualifierLoc;
+ if (NestedNameSpecifier Qualifier =
+ Name ? Name->getQualifier() : std::nullopt) {
+ NestedNameSpecifierLocBuilder Builder;
+ Builder.MakeTrivial(Context, Qualifier, Loc);
+ QualifierLoc = Builder.getWithLocInContext(Context);
+ }
+
+ TemplateArgumentListInfo TAL(Loc, Loc);
+ set(ElaboratedKeywordLoc, QualifierLoc,
+ /*TemplateKeywordLoc=*/Name && Name->hasTemplateKeyword()
+ ? Loc
+ : SourceLocation(),
+ /*NameLoc=*/Loc, /*LAngleLoc=*/Loc, /*RAngleLoc=*/Loc);
+ initializeArgLocs(Context, getTypePtr()->template_arguments(), getArgInfos(),
+ Loc);
+}
+
void TemplateSpecializationTypeLoc::initializeArgLocs(
ASTContext &Context, ArrayRef<TemplateArgument> Args,
TemplateArgumentLocInfo *ArgInfos, SourceLocation Loc) {
@@ -631,7 +811,7 @@ void TemplateSpecializationTypeLoc::initializeArgLocs(
Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
ArgInfos[i] = TemplateArgumentLocInfo(
- Context, Builder.getWithLocInContext(Context), Loc,
+ Context, Loc, Builder.getWithLocInContext(Context), Loc,
Args[i].getKind() == TemplateArgument::Template ? SourceLocation()
: Loc);
break;
@@ -693,10 +873,6 @@ namespace {
// Only these types can contain the desired 'auto' type.
- TypeLoc VisitElaboratedTypeLoc(ElaboratedTypeLoc T) {
- return Visit(T.getNamedTypeLoc());
- }
-
TypeLoc VisitQualifiedTypeLoc(QualifiedTypeLoc T) {
return Visit(T.getUnqualifiedLoc());
}
diff --git a/clang/lib/AST/TypePrinter.cpp b/clang/lib/AST/TypePrinter.cpp
index d18723d807c6a..adaeeb59e8133 100644
--- a/clang/lib/AST/TypePrinter.cpp
+++ b/clang/lib/AST/TypePrinter.cpp
@@ -133,7 +133,7 @@ class TypePrinter {
void printAfter(QualType T, raw_ostream &OS);
void AppendScope(DeclContext *DC, raw_ostream &OS,
DeclarationName NameInScope);
- void printTag(TagDecl *T, raw_ostream &OS);
+ void printTagType(const TagType *T, raw_ostream &OS);
void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
#define ABSTRACT_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) \
@@ -230,7 +230,6 @@ bool TypePrinter::canPrefixQualifiers(const Type *T,
case Type::UnaryTransform:
case Type::Record:
case Type::Enum:
- case Type::Elaborated:
case Type::TemplateTypeParm:
case Type::SubstTemplateTypeParmPack:
case Type::DeducedTemplateSpecialization:
@@ -503,11 +502,7 @@ void TypePrinter::printMemberPointerBefore(const MemberPointerType *T,
// FIXME: this should include vectors, but vectors use attributes I guess.
if (isa<ArrayType>(T->getPointeeType()))
OS << '(';
-
- PrintingPolicy InnerPolicy(Policy);
- InnerPolicy.IncludeTagDefinition = false;
- T->getQualifier()->print(OS, InnerPolicy);
-
+ T->getQualifier().print(OS, Policy);
OS << "*";
}
@@ -1210,29 +1205,50 @@ void TypePrinter::printTypeSpec(NamedDecl *D, raw_ostream &OS) {
void TypePrinter::printUnresolvedUsingBefore(const UnresolvedUsingType *T,
raw_ostream &OS) {
- printTypeSpec(T->getDecl(), OS);
+ OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+ if (T->getKeyword() != ElaboratedTypeKeyword::None)
+ OS << ' ';
+ auto *D = T->getDecl();
+ if (Policy.FullyQualifiedName || T->isCanonicalUnqualified()) {
+ AppendScope(D->getDeclContext(), OS, D->getDeclName());
+ } else {
+ T->getQualifier().print(OS, Policy);
+ }
+ OS << D->getIdentifier()->getName();
+ spaceBeforePlaceHolder(OS);
}
void TypePrinter::printUnresolvedUsingAfter(const UnresolvedUsingType *T,
raw_ostream &OS) {}
void TypePrinter::printUsingBefore(const UsingType *T, raw_ostream &OS) {
- // After `namespace b { using a::X }`, is the type X within B a::X or b::X?
- //
- // - b::X is more formally correct given the UsingType model
- // - b::X makes sense if "re-exporting" a symbol in a new namespace
- // - a::X makes sense if "importing" a symbol for convenience
- //
- // The "importing" use seems much more common, so we print a::X.
- // This could be a policy option, but the right choice seems to rest more
- // with the intent of the code than the caller.
- printTypeSpec(T->getFoundDecl()->getUnderlyingDecl(), OS);
+ OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+ if (T->getKeyword() != ElaboratedTypeKeyword::None)
+ OS << ' ';
+ auto *D = T->getDecl();
+ if (Policy.FullyQualifiedName) {
+ AppendScope(D->getDeclContext(), OS, D->getDeclName());
+ } else {
+ T->getQualifier().print(OS, Policy);
+ }
+ OS << D->getIdentifier()->getName();
+ spaceBeforePlaceHolder(OS);
}
void TypePrinter::printUsingAfter(const UsingType *T, raw_ostream &OS) {}
void TypePrinter::printTypedefBefore(const TypedefType *T, raw_ostream &OS) {
- printTypeSpec(T->getDecl(), OS);
+ OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+ if (T->getKeyword() != ElaboratedTypeKeyword::None)
+ OS << ' ';
+ auto *D = T->getDecl();
+ if (Policy.FullyQualifiedName) {
+ AppendScope(D->getDeclContext(), OS, D->getDeclName());
+ } else {
+ T->getQualifier().print(OS, Policy);
+ }
+ OS << D->getIdentifier()->getName();
+ spaceBeforePlaceHolder(OS);
}
void TypePrinter::printMacroQualifiedBefore(const MacroQualifiedType *T,
@@ -1353,14 +1369,53 @@ void TypePrinter::printAutoAfter(const AutoType *T, raw_ostream &OS) {
void TypePrinter::printDeducedTemplateSpecializationBefore(
const DeducedTemplateSpecializationType *T, raw_ostream &OS) {
- // If the type has been deduced, print the deduced type.
+ if (ElaboratedTypeKeyword Keyword = T->getKeyword();
+ T->getKeyword() != ElaboratedTypeKeyword::None)
+ OS << KeywordHelpers::getKeywordName(Keyword) << ' ';
+
+ TemplateName Name = T->getTemplateName();
+
+ // If the type has been deduced, print the template arguments, as if this was
+ // printing the deduced type, but including elaboration and template name
+ // qualification.
+ // FIXME: There should probably be a policy which controls this.
+ // We would probably want to do this on diagnostics, but not on -ast-print.
+ ArrayRef<TemplateArgument> Args;
+ TemplateDecl *DeducedTD = nullptr;
if (!T->getDeducedType().isNull()) {
- printBefore(T->getDeducedType(), OS);
- } else {
+ if (const auto *TST =
+ dyn_cast<TemplateSpecializationType>(T->getDeducedType())) {
+ DeducedTD = TST->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true);
+ Args = TST->template_arguments();
+ } else {
+ // Should only get here for canonical types.
+ const auto *CD = cast<ClassTemplateSpecializationDecl>(
+ cast<RecordType>(T->getDeducedType())->getOriginalDecl());
+ DeducedTD = CD->getSpecializedTemplate();
+ Args = CD->getTemplateArgs().asArray();
+ }
+
+ // FIXME: Workaround for alias template CTAD not producing guides which
+ // include the alias template specialization type.
+ // Purposefully disregard qualification when building this TemplateName;
+ // any qualification we might have, might not make sense in the
+ // context this was deduced.
+ if (!declaresSameEntity(DeducedTD, Name.getAsTemplateDecl(
+ /*IgnoreDeduced=*/true)))
+ Name = TemplateName(DeducedTD);
+ }
+
+ {
IncludeStrongLifetimeRAII Strong(Policy);
- T->getTemplateName().print(OS, Policy);
- spaceBeforePlaceHolder(OS);
+ Name.print(OS, Policy);
+ }
+ if (DeducedTD) {
+ printTemplateArgumentList(OS, Args, Policy,
+ DeducedTD->getTemplateParameters());
}
+
+ spaceBeforePlaceHolder(OS);
}
void TypePrinter::printDeducedTemplateSpecializationAfter(
@@ -1470,30 +1525,37 @@ void TypePrinter::AppendScope(DeclContext *DC, raw_ostream &OS,
}
}
-void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
- if (Policy.IncludeTagDefinition) {
- PrintingPolicy SubPolicy = Policy;
- SubPolicy.IncludeTagDefinition = false;
- D->print(OS, SubPolicy, Indentation);
+void TypePrinter::printTagType(const TagType *T, raw_ostream &OS) {
+ TagDecl *D = T->getOriginalDecl();
+
+ if (Policy.IncludeTagDefinition && T->isTagOwned()) {
+ D->print(OS, Policy, Indentation);
spaceBeforePlaceHolder(OS);
return;
}
bool HasKindDecoration = false;
- // We don't print tags unless this is an elaborated type.
- // In C, we just assume every RecordType is an elaborated type.
- if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
- HasKindDecoration = true;
- OS << D->getKindName();
- OS << ' ';
+ if (T->isCanonicalUnqualified()) {
+ if (!Policy.SuppressTagKeyword && !D->getTypedefNameForAnonDecl()) {
+ HasKindDecoration = true;
+ OS << D->getKindName();
+ OS << ' ';
+ }
+ } else {
+ OS << TypeWithKeyword::getKeywordName(T->getKeyword());
+ if (T->getKeyword() != ElaboratedTypeKeyword::None)
+ OS << ' ';
}
- // Compute the full nested-name-specifier for this type.
- // In C, this will always be empty except when the type
- // being printed is anonymous within other Record.
- if (!Policy.SuppressScope)
+ if (!Policy.FullyQualifiedName && !T->isCanonicalUnqualified()) {
+ T->getQualifier().print(OS, Policy);
+ } else if (!Policy.SuppressScope) {
+ // Compute the full nested-name-specifier for this type.
+ // In C, this will always be empty except when the type
+ // being printed is anonymous within other Record.
AppendScope(D->getDeclContext(), OS, D->getDeclName());
+ }
if (const IdentifierInfo *II = D->getIdentifier())
OS << II->getName();
@@ -1568,9 +1630,11 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
// Print the preferred name if we have one for this type.
if (Policy.UsePreferredNames) {
- for (const auto *PNA : T->getDecl()->specific_attrs<PreferredNameAttr>()) {
+ for (const auto *PNA : T->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->specific_attrs<PreferredNameAttr>()) {
if (!declaresSameEntity(PNA->getTypedefType()->getAsCXXRecordDecl(),
- T->getDecl()))
+ T->getOriginalDecl()))
continue;
// Find the outermost typedef or alias template.
QualType T = PNA->getTypedefType();
@@ -1584,17 +1648,44 @@ void TypePrinter::printRecordBefore(const RecordType *T, raw_ostream &OS) {
}
}
- printTag(T->getDecl(), OS);
+ printTagType(T, OS);
}
void TypePrinter::printRecordAfter(const RecordType *T, raw_ostream &OS) {}
void TypePrinter::printEnumBefore(const EnumType *T, raw_ostream &OS) {
- printTag(T->getDecl(), OS);
+ printTagType(T, OS);
}
void TypePrinter::printEnumAfter(const EnumType *T, raw_ostream &OS) {}
+void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
+ raw_ostream &OS) {
+ const ASTContext &Ctx = T->getOriginalDecl()->getASTContext();
+ IncludeStrongLifetimeRAII Strong(Policy);
+ T->getTemplateName(Ctx).print(OS, Policy);
+ if (Policy.PrintInjectedClassNameWithArguments) {
+ auto *Decl = T->getOriginalDecl();
+ // FIXME: Use T->getTemplateArgs(Ctx) when that supports as-written
+ // arguments.
+ if (auto *RD = dyn_cast<ClassTemplateSpecializationDecl>(Decl)) {
+ printTemplateArgumentList(OS, RD->getTemplateArgsAsWritten()->arguments(),
+ Policy,
+ T->getTemplateDecl()->getTemplateParameters());
+ } else {
+ ClassTemplateDecl *TD = Decl->getDescribedClassTemplate();
+ assert(TD);
+ printTemplateArgumentList(
+ OS, TD->getTemplateParameters()->getInjectedTemplateArgs(Ctx), Policy,
+ T->getTemplateDecl()->getTemplateParameters());
+ }
+ }
+ spaceBeforePlaceHolder(OS);
+}
+
+void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
+ raw_ostream &OS) {}
+
void TypePrinter::printTemplateTypeParmBefore(const TemplateTypeParmType *T,
raw_ostream &OS) {
TemplateTypeParmDecl *D = T->getDecl();
@@ -1661,6 +1752,10 @@ void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
raw_ostream &OS, bool FullyQualify) {
IncludeStrongLifetimeRAII Strong(Policy);
+ if (ElaboratedTypeKeyword K = T->getKeyword();
+ K != ElaboratedTypeKeyword::None)
+ OS << TypeWithKeyword::getKeywordName(K) << ' ';
+
TemplateDecl *TD =
T->getTemplateName().getAsTemplateDecl(/*IgnoreDeduced=*/true);
// FIXME: Null TD never exercised in test suite.
@@ -1670,7 +1765,10 @@ void TypePrinter::printTemplateId(const TemplateSpecializationType *T,
OS << TD->getName();
} else {
- T->getTemplateName().print(OS, Policy, TemplateName::Qualified::None);
+ T->getTemplateName().print(OS, Policy,
+ !Policy.SuppressScope
+ ? TemplateName::Qualified::AsWritten
+ : TemplateName::Qualified::None);
}
DefaultTemplateArgsPolicyRAII TemplateArgs(Policy);
@@ -1689,77 +1787,6 @@ void TypePrinter::printTemplateSpecializationAfter(
const TemplateSpecializationType *T,
raw_ostream &OS) {}
-void TypePrinter::printInjectedClassNameBefore(const InjectedClassNameType *T,
- raw_ostream &OS) {
- if (Policy.PrintInjectedClassNameWithArguments)
- return printTemplateSpecializationBefore(T->getInjectedTST(), OS);
-
- IncludeStrongLifetimeRAII Strong(Policy);
- T->getTemplateName().print(OS, Policy);
- spaceBeforePlaceHolder(OS);
-}
-
-void TypePrinter::printInjectedClassNameAfter(const InjectedClassNameType *T,
- raw_ostream &OS) {}
-
-void TypePrinter::printElaboratedBefore(const ElaboratedType *T,
- raw_ostream &OS) {
- if (Policy.IncludeTagDefinition && T->getOwnedTagDecl()) {
- TagDecl *OwnedTagDecl = T->getOwnedTagDecl();
- assert(OwnedTagDecl->getTypeForDecl() == T->getNamedType().getTypePtr() &&
- "OwnedTagDecl expected to be a declaration for the type");
- PrintingPolicy SubPolicy = Policy;
- SubPolicy.IncludeTagDefinition = false;
- OwnedTagDecl->print(OS, SubPolicy, Indentation);
- spaceBeforePlaceHolder(OS);
- return;
- }
-
- if (Policy.SuppressElaboration) {
- printBefore(T->getNamedType(), OS);
- return;
- }
-
- // The tag definition will take care of these.
- if (!Policy.IncludeTagDefinition)
- {
- OS << TypeWithKeyword::getKeywordName(T->getKeyword());
- if (T->getKeyword() != ElaboratedTypeKeyword::None)
- OS << " ";
- NestedNameSpecifier *Qualifier = T->getQualifier();
- if (!Policy.SuppressTagKeyword && Policy.SuppressScope &&
- !Policy.SuppressUnwrittenScope) {
- bool OldTagKeyword = Policy.SuppressTagKeyword;
- bool OldSupressScope = Policy.SuppressScope;
- Policy.SuppressTagKeyword = true;
- Policy.SuppressScope = false;
- printBefore(T->getNamedType(), OS);
- Policy.SuppressTagKeyword = OldTagKeyword;
- Policy.SuppressScope = OldSupressScope;
- return;
- }
- if (Qualifier)
- Qualifier->print(OS, Policy);
- }
-
- ElaboratedTypePolicyRAII PolicyRAII(Policy);
- printBefore(T->getNamedType(), OS);
-}
-
-void TypePrinter::printElaboratedAfter(const ElaboratedType *T,
- raw_ostream &OS) {
- if (Policy.IncludeTagDefinition && T->getOwnedTagDecl())
- return;
-
- if (Policy.SuppressElaboration) {
- printAfter(T->getNamedType(), OS);
- return;
- }
-
- ElaboratedTypePolicyRAII PolicyRAII(Policy);
- printAfter(T->getNamedType(), OS);
-}
-
void TypePrinter::printParenBefore(const ParenType *T, raw_ostream &OS) {
if (!HasEmptyPlaceHolder && !isa<FunctionType>(T->getInnerType())) {
printBefore(T->getInnerType(), OS);
@@ -1781,9 +1808,7 @@ void TypePrinter::printDependentNameBefore(const DependentNameType *T,
OS << TypeWithKeyword::getKeywordName(T->getKeyword());
if (T->getKeyword() != ElaboratedTypeKeyword::None)
OS << " ";
-
- T->getQualifier()->print(OS, Policy);
-
+ T->getQualifier().print(OS, Policy);
OS << T->getIdentifier()->getName();
spaceBeforePlaceHolder(OS);
}
diff --git a/clang/lib/AST/VTTBuilder.cpp b/clang/lib/AST/VTTBuilder.cpp
index de011848a721e..85101aee97e66 100644
--- a/clang/lib/AST/VTTBuilder.cpp
+++ b/clang/lib/AST/VTTBuilder.cpp
@@ -64,7 +64,9 @@ void VTTBuilder::LayoutSecondaryVTTs(BaseSubobject Base) {
continue;
const auto *BaseDecl =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
const ASTRecordLayout &Layout = Ctx.getASTRecordLayout(RD);
CharUnits BaseOffset = Base.getBaseOffset() +
@@ -90,7 +92,9 @@ VTTBuilder::LayoutSecondaryVirtualPointers(BaseSubobject Base,
for (const auto &I : RD->bases()) {
const auto *BaseDecl =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Itanium C++ ABI 2.6.2:
// Secondary virtual pointers are present for all bases with either
@@ -154,7 +158,9 @@ void VTTBuilder::LayoutVirtualVTTs(const CXXRecordDecl *RD,
VisitedVirtualBasesSetTy &VBases) {
for (const auto &I : RD->bases()) {
const auto *BaseDecl =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Check if this is a virtual base.
if (I.isVirtual()) {
diff --git a/clang/lib/AST/VTableBuilder.cpp b/clang/lib/AST/VTableBuilder.cpp
index 0001745a6ff22..6cec526ba8443 100644
--- a/clang/lib/AST/VTableBuilder.cpp
+++ b/clang/lib/AST/VTableBuilder.cpp
@@ -313,10 +313,12 @@ ComputeReturnAdjustmentBaseOffset(ASTContext &Context,
}
const CXXRecordDecl *DerivedRD =
- cast<CXXRecordDecl>(cast<RecordType>(CanDerivedReturnType)->getDecl());
+ cast<CXXRecordDecl>(
+ cast<RecordType>(CanDerivedReturnType)->getOriginalDecl())
+ ->getDefinitionOrSelf();
- const CXXRecordDecl *BaseRD =
- cast<CXXRecordDecl>(cast<RecordType>(CanBaseReturnType)->getDecl());
+ const CXXRecordDecl *BaseRD = cast<CXXRecordDecl>(
+ cast<RecordType>(CanBaseReturnType)->getOriginalDecl());
return ComputeBaseOffset(Context, BaseRD, DerivedRD);
}
diff --git a/clang/lib/Sema/TreeTransform.h b/clang/lib/Sema/TreeTransform.h
index 758012f894a41..ce12e1e8fccad 100644
--- a/clang/lib/Sema/TreeTransform.h
+++ b/clang/lib/Sema/TreeTransform.h
@@ -591,12 +591,12 @@ class TreeTransform {
/// By default, transforms the template name by transforming the declarations
/// and nested-name-specifiers that occur within the template name.
/// Subclasses may override this function to provide alternate behavior.
- TemplateName
- TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
- SourceLocation NameLoc,
- QualType ObjectType = QualType(),
- NamedDecl *FirstQualifierInScope = nullptr,
- bool AllowInjectedClassName = false);
+ TemplateName TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
+ SourceLocation TemplateKWLoc,
+ TemplateName Name, SourceLocation NameLoc,
+ QualType ObjectType = QualType(),
+ NamedDecl *FirstQualifierInScope = nullptr,
+ bool AllowInjectedClassName = false);
/// Transform the given template argument.
///
@@ -693,20 +693,17 @@ class TreeTransform {
StmtResult TransformSEHHandler(Stmt *Handler);
- QualType
- TransformTemplateSpecializationType(TypeLocBuilder &TLB,
- TemplateSpecializationTypeLoc TL,
- TemplateName Template);
-
- QualType
- TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
- DependentTemplateSpecializationTypeLoc TL,
+ QualType TransformTemplateSpecializationType(TypeLocBuilder &TLB,
+ TemplateSpecializationTypeLoc TL,
TemplateName Template,
CXXScopeSpec &SS);
QualType TransformDependentTemplateSpecializationType(
TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
- CXXScopeSpec &SS);
+ QualType ObjectType, NamedDecl *UnqualLookup,
+ bool AllowInjectedClassName);
+
+ QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL);
/// Transforms the parameters of a function type into the
/// given vectors.
@@ -1016,16 +1013,22 @@ class TreeTransform {
/// Rebuild an unresolved typename type, given the decl that
/// the UnresolvedUsingTypenameDecl was transformed to.
- QualType RebuildUnresolvedUsingType(SourceLocation NameLoc, Decl *D);
+ QualType RebuildUnresolvedUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ SourceLocation NameLoc, Decl *D);
/// Build a new type found via an alias.
- QualType RebuildUsingType(UsingShadowDecl *Found, QualType Underlying) {
- return SemaRef.Context.getUsingType(Found, Underlying);
+ QualType RebuildUsingType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, UsingShadowDecl *D,
+ QualType UnderlyingType) {
+ return SemaRef.Context.getUsingType(Keyword, Qualifier, D, UnderlyingType);
}
/// Build a new typedef type.
- QualType RebuildTypedefType(TypedefNameDecl *Typedef) {
- return SemaRef.Context.getTypeDeclType(Typedef);
+ QualType RebuildTypedefType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier,
+ TypedefNameDecl *Typedef) {
+ return SemaRef.Context.getTypedefType(Keyword, Qualifier, Typedef);
}
/// Build a new MacroDefined type.
@@ -1034,14 +1037,14 @@ class TreeTransform {
return SemaRef.Context.getMacroQualifiedType(T, MacroII);
}
- /// Build a new class/struct/union type.
- QualType RebuildRecordType(RecordDecl *Record) {
- return SemaRef.Context.getTypeDeclType(Record);
+ /// Build a new class/struct/union/enum type.
+ QualType RebuildTagType(ElaboratedTypeKeyword Keyword,
+ NestedNameSpecifier Qualifier, TagDecl *Tag) {
+ return SemaRef.Context.getTagType(Keyword, Qualifier, Tag,
+ /*OwnsTag=*/false);
}
-
- /// Build a new Enum type.
- QualType RebuildEnumType(EnumDecl *Enum) {
- return SemaRef.Context.getTypeDeclType(Enum);
+ QualType RebuildCanonicalTagType(TagDecl *Tag) {
+ return SemaRef.Context.getCanonicalTagType(Tag);
}
/// Build a new typeof(expr) type.
@@ -1090,10 +1093,10 @@ class TreeTransform {
/// By default, builds a new DeducedTemplateSpecializationType with the given
/// deduced type.
- QualType RebuildDeducedTemplateSpecializationType(TemplateName Template,
- QualType Deduced) {
+ QualType RebuildDeducedTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword, TemplateName Template, QualType Deduced) {
return SemaRef.Context.getDeducedTemplateSpecializationType(
- Template, Deduced, /*IsDependent*/ false);
+ Keyword, Template, Deduced, /*IsDependent*/ false);
}
/// Build a new template specialization type.
@@ -1101,7 +1104,8 @@ class TreeTransform {
/// By default, performs semantic analysis when building the template
/// specialization type. Subclasses may override this routine to provide
/// different behavior.
- QualType RebuildTemplateSpecializationType(TemplateName Template,
+ QualType RebuildTemplateSpecializationType(ElaboratedTypeKeyword Keyword,
+ TemplateName Template,
SourceLocation TemplateLoc,
TemplateArgumentListInfo &Args);
@@ -1113,41 +1117,22 @@ class TreeTransform {
return SemaRef.BuildParenType(InnerType);
}
- /// Build a new qualified name type.
- ///
- /// By default, builds a new ElaboratedType type from the keyword,
- /// the nested-name-specifier and the named type.
- /// Subclasses may override this routine to provide different behavior.
- QualType RebuildElaboratedType(SourceLocation KeywordLoc,
- ElaboratedTypeKeyword Keyword,
- NestedNameSpecifierLoc QualifierLoc,
- QualType Named) {
- return SemaRef.Context.getElaboratedType(Keyword,
- QualifierLoc.getNestedNameSpecifier(),
- Named);
- }
-
/// Build a new typename type that refers to a template-id.
///
/// By default, builds a new DependentNameType type from the
/// nested-name-specifier and the given type. Subclasses may override
/// this routine to provide different behavior.
QualType RebuildDependentTemplateSpecializationType(
- ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS,
- SourceLocation TemplateKWLoc, TemplateName Name, SourceLocation NameLoc,
- TemplateArgumentListInfo &Args, bool AllowInjectedClassName) {
+ ElaboratedTypeKeyword Keyword, SourceLocation TemplateKWLoc,
+ TemplateName Name, SourceLocation NameLoc, TemplateArgumentListInfo &Args,
+ bool AllowInjectedClassName) {
// If it's still dependent, make a dependent specialization.
if (const DependentTemplateStorage *S = Name.getAsDependentTemplateName())
return SemaRef.Context.getDependentTemplateSpecializationType(
Keyword, *S, Args.arguments());
- // Otherwise, make an elaborated type wrapping a non-dependent
- // specialization.
- QualType T =
- getDerived().RebuildTemplateSpecializationType(Name, NameLoc, Args);
- if (T.isNull())
- return QualType();
- return SemaRef.Context.getElaboratedType(Keyword, NNS, T);
+ return getDerived().RebuildTemplateSpecializationType(Keyword, Name,
+ NameLoc, Args);
}
/// Build a new typename type that refers to an identifier.
@@ -1164,7 +1149,7 @@ class TreeTransform {
CXXScopeSpec SS;
SS.Adopt(QualifierLoc);
- if (QualifierLoc.getNestedNameSpecifier()->isDependent()) {
+ if (QualifierLoc.getNestedNameSpecifier().isDependent()) {
// If the name is still dependent, just build a new dependent name type.
if (!SemaRef.computeDeclContext(SS))
return SemaRef.Context.getDependentNameType(Keyword,
@@ -1234,19 +1219,14 @@ class TreeTransform {
}
return QualType();
}
-
if (!SemaRef.isAcceptableTagRedeclaration(Tag, Kind, /*isDefinition*/false,
IdLoc, Id)) {
SemaRef.Diag(KeywordLoc, diag::err_use_with_wrong_tag) << Id;
SemaRef.Diag(Tag->getLocation(), diag::note_previous_use);
return QualType();
}
-
- // Build the elaborated-type-specifier type.
- QualType T = SemaRef.Context.getTypeDeclType(Tag);
- return SemaRef.Context.getElaboratedType(Keyword,
- QualifierLoc.getNestedNameSpecifier(),
- T);
+ return getDerived().RebuildTagType(
+ Keyword, QualifierLoc.getNestedNameSpecifier(), Tag);
}
/// Build a new pack expansion type.
@@ -1299,7 +1279,6 @@ class TreeTransform {
SourceLocation TemplateKWLoc,
const IdentifierInfo &Name,
SourceLocation NameLoc, QualType ObjectType,
- NamedDecl *FirstQualifierInScope,
bool AllowInjectedClassName);
/// Build a new template name given a nested name specifier and the
@@ -1319,7 +1298,6 @@ class TreeTransform {
SourceLocation TemplateKWLoc,
IdentifierOrOverloadedOperator IO,
SourceLocation NameLoc, QualType ObjectType,
- NamedDecl *FirstQualifierInScope,
bool AllowInjectedClassName);
/// Build a new template name given a template template parameter pack
@@ -4008,8 +3986,8 @@ class TreeTransform {
SemaRef.Context,
TemplateArgument(Pattern.getArgument().getAsTemplate(),
NumExpansions),
- Pattern.getTemplateQualifierLoc(), Pattern.getTemplateNameLoc(),
- EllipsisLoc);
+ Pattern.getTemplateKWLoc(), Pattern.getTemplateQualifierLoc(),
+ Pattern.getTemplateNameLoc(), EllipsisLoc);
case TemplateArgument::Null:
case TemplateArgument::Integral:
@@ -4254,23 +4232,29 @@ class TreeTransform {
}
private:
- TypeLoc TransformTypeInObjectScope(TypeLoc TL,
- QualType ObjectType,
- NamedDecl *FirstQualifierInScope,
- CXXScopeSpec &SS);
+ QualType TransformTypeInObjectScope(TypeLocBuilder &TLB, TypeLoc TL,
+ QualType ObjectType,
+ NamedDecl *FirstQualifierInScope);
TypeSourceInfo *TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
QualType ObjectType,
- NamedDecl *FirstQualifierInScope,
- CXXScopeSpec &SS);
+ NamedDecl *FirstQualifierInScope) {
+ if (getDerived().AlreadyTransformed(TSInfo->getType()))
+ return TSInfo;
- TypeSourceInfo *TransformTSIInObjectScope(TypeLoc TL, QualType ObjectType,
- NamedDecl *FirstQualifierInScope,
- CXXScopeSpec &SS);
+ TypeLocBuilder TLB;
+ QualType T = TransformTypeInObjectScope(TLB, TSInfo->getTypeLoc(),
+ ObjectType, FirstQualifierInScope);
+ if (T.isNull())
+ return nullptr;
+ return TLB.getTypeSourceInfo(SemaRef.Context, T);
+ }
QualType TransformDependentNameType(TypeLocBuilder &TLB,
DependentNameTypeLoc TL,
- bool DeducibleTSTContext);
+ bool DeducibleTSTContext,
+ QualType ObjectType = QualType(),
+ NamedDecl *UnqualLookup = nullptr);
llvm::SmallVector<OpenACCClause *>
TransformOpenACCClauseList(OpenACCDirectiveKind DirKind,
@@ -4599,7 +4583,7 @@ NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
auto insertNNS = [&Qualifiers](NestedNameSpecifierLoc NNS) {
for (NestedNameSpecifierLoc Qualifier = NNS; Qualifier;
- Qualifier = Qualifier.getPrefix())
+ Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix)
Qualifiers.push_back(Qualifier);
};
insertNNS(NNS);
@@ -4607,86 +4591,86 @@ NestedNameSpecifierLoc TreeTransform<Derived>::TransformNestedNameSpecifierLoc(
CXXScopeSpec SS;
while (!Qualifiers.empty()) {
NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
- NestedNameSpecifier *QNNS = Q.getNestedNameSpecifier();
-
- switch (QNNS->getKind()) {
- case NestedNameSpecifier::Identifier: {
- Sema::NestedNameSpecInfo IdInfo(QNNS->getAsIdentifier(),
- Q.getLocalBeginLoc(), Q.getLocalEndLoc(),
- ObjectType);
- if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo, false,
- SS, FirstQualifierInScope, false))
- return NestedNameSpecifierLoc();
- break;
- }
+ NestedNameSpecifier QNNS = Q.getNestedNameSpecifier();
- case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS =
- cast_or_null<NamespaceDecl>(getDerived().TransformDecl(
- Q.getLocalBeginLoc(), QNNS->getAsNamespace()));
- SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
- break;
- }
+ switch (QNNS.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
- case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias =
- cast_or_null<NamespaceAliasDecl>(getDerived().TransformDecl(
- Q.getLocalBeginLoc(), QNNS->getAsNamespaceAlias()));
- SS.Extend(SemaRef.Context, Alias, Q.getLocalBeginLoc(),
- Q.getLocalEndLoc());
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto *NS = cast<NamespaceBaseDecl>(getDerived().TransformDecl(
+ Q.getLocalBeginLoc(), const_cast<NamespaceBaseDecl *>(
+ QNNS.getAsNamespaceAndPrefix().Namespace)));
+ SS.Extend(SemaRef.Context, NS, Q.getLocalBeginLoc(), Q.getLocalEndLoc());
break;
}
- case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Kind::Global:
// There is no meaningful transformation that one could perform on the
// global scope.
SS.MakeGlobal(SemaRef.Context, Q.getBeginLoc());
break;
- case NestedNameSpecifier::Super: {
- CXXRecordDecl *RD =
- cast_or_null<CXXRecordDecl>(getDerived().TransformDecl(
- SourceLocation(), QNNS->getAsRecordDecl()));
+ case NestedNameSpecifier::Kind::Super: {
+ CXXRecordDecl *RD = cast_or_null<CXXRecordDecl>(
+ getDerived().TransformDecl(SourceLocation(), QNNS.getAsRecordDecl()));
SS.MakeSuper(SemaRef.Context, RD, Q.getBeginLoc(), Q.getEndLoc());
break;
}
- case NestedNameSpecifier::TypeSpec: {
- TypeLoc TL = TransformTypeInObjectScope(Q.getTypeLoc(), ObjectType,
- FirstQualifierInScope, SS);
-
- if (!TL)
- return NestedNameSpecifierLoc();
+ case NestedNameSpecifier::Kind::Type: {
+ assert(SS.isEmpty());
+ TypeLoc TL = Q.castAsTypeLoc();
+
+ if (auto DNT = TL.getAs<DependentNameTypeLoc>()) {
+ NestedNameSpecifierLoc QualifierLoc = DNT.getQualifierLoc();
+ if (QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
+ QualifierLoc, ObjectType, FirstQualifierInScope);
+ if (!QualifierLoc)
+ return NestedNameSpecifierLoc();
+ ObjectType = QualType();
+ FirstQualifierInScope = nullptr;
+ }
+ SS.Adopt(QualifierLoc);
+ Sema::NestedNameSpecInfo IdInfo(
+ const_cast<IdentifierInfo *>(DNT.getTypePtr()->getIdentifier()),
+ DNT.getNameLoc(), Q.getLocalEndLoc(), ObjectType);
+ if (SemaRef.BuildCXXNestedNameSpecifier(/*Scope=*/nullptr, IdInfo,
+ false, SS,
+ FirstQualifierInScope, false))
+ return NestedNameSpecifierLoc();
+ return SS.getWithLocInContext(SemaRef.Context);
+ }
QualType T = TL.getType();
+ TypeLocBuilder TLB;
+ if (!getDerived().AlreadyTransformed(T)) {
+ T = TransformTypeInObjectScope(TLB, TL, ObjectType,
+ FirstQualifierInScope);
+ if (T.isNull())
+ return NestedNameSpecifierLoc();
+ TL = TLB.getTypeLocInContext(SemaRef.Context, T);
+ }
+
if (T->isDependentType() || T->isRecordType() ||
(SemaRef.getLangOpts().CPlusPlus11 && T->isEnumeralType())) {
if (T->isEnumeralType())
SemaRef.Diag(TL.getBeginLoc(),
diag::warn_cxx98_compat_enum_nested_name_spec);
-
- if (const auto ETL = TL.getAs<ElaboratedTypeLoc>()) {
- SS.Adopt(ETL.getQualifierLoc());
- TL = ETL.getNamedTypeLoc();
- }
-
- SS.Extend(SemaRef.Context, TL, Q.getLocalEndLoc());
+ SS.Make(SemaRef.Context, TL, Q.getLocalEndLoc());
break;
}
// If the nested-name-specifier is an invalid type def, don't emit an
// error because a previous error should have already been emitted.
TypedefTypeLoc TTL = TL.getAsAdjusted<TypedefTypeLoc>();
- if (!TTL || !TTL.getTypedefNameDecl()->isInvalidDecl()) {
+ if (!TTL || !TTL.getDecl()->isInvalidDecl()) {
SemaRef.Diag(TL.getBeginLoc(), diag::err_nested_name_spec_non_tag)
<< T << SS.getRange();
}
return NestedNameSpecifierLoc();
}
}
-
- // The qualifier-in-scope and object type only apply to the leftmost entity.
- FirstQualifierInScope = nullptr;
- ObjectType = QualType();
}
// Don't rebuild the nested-name-specifier if we don't have to.
@@ -4772,30 +4756,32 @@ template <typename Derived>
TemplateName TreeTransform<Derived>::RebuildTemplateName(
CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
IdentifierOrOverloadedOperator IO, SourceLocation NameLoc,
- QualType ObjectType, NamedDecl *FirstQualifierInScope,
- bool AllowInjectedClassName) {
- if (const IdentifierInfo *II = IO.getIdentifier()) {
+ QualType ObjectType, bool AllowInjectedClassName) {
+ if (const IdentifierInfo *II = IO.getIdentifier())
return getDerived().RebuildTemplateName(SS, TemplateKWLoc, *II, NameLoc,
- ObjectType, FirstQualifierInScope,
- AllowInjectedClassName);
- }
+ ObjectType, AllowInjectedClassName);
return getDerived().RebuildTemplateName(SS, TemplateKWLoc, IO.getOperator(),
NameLoc, ObjectType,
AllowInjectedClassName);
}
-template<typename Derived>
-TemplateName
-TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
- TemplateName Name,
- SourceLocation NameLoc,
- QualType ObjectType,
- NamedDecl *FirstQualifierInScope,
- bool AllowInjectedClassName) {
+template <typename Derived>
+TemplateName TreeTransform<Derived>::TransformTemplateName(
+ NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
+ TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
+ NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
if (QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName()) {
+ // FIXME: Preserve UsingTemplateName.
TemplateDecl *Template = QTN->getUnderlyingTemplate().getAsTemplateDecl();
assert(Template && "qualified template name must refer to a template");
+ if (QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
+ QualifierLoc, ObjectType, FirstQualifierInScope);
+ if (!QualifierLoc)
+ return TemplateName();
+ }
+
TemplateDecl *TransTemplate
= cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
Template));
@@ -4803,41 +4789,67 @@ TreeTransform<Derived>::TransformTemplateName(CXXScopeSpec &SS,
return TemplateName();
if (!getDerived().AlwaysRebuild() &&
- SS.getScopeRep() == QTN->getQualifier() &&
+ QualifierLoc.getNestedNameSpecifier() == QTN->getQualifier() &&
TransTemplate == Template)
return Name;
-
+ CXXScopeSpec SS;
+ SS.Adopt(QualifierLoc);
return getDerived().RebuildTemplateName(SS, QTN->hasTemplateKeyword(),
TransTemplate);
}
if (DependentTemplateName *DTN = Name.getAsDependentTemplateName()) {
- if (SS.getScopeRep()) {
- // These apply to the scope specifier, not the template.
+ if (QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
+ QualifierLoc, ObjectType, FirstQualifierInScope);
+ if (!QualifierLoc)
+ return TemplateName();
+ // The qualifier-in-scope and object type only apply to the leftmost
+ // entity.
ObjectType = QualType();
- FirstQualifierInScope = nullptr;
}
if (!getDerived().AlwaysRebuild() &&
- SS.getScopeRep() == DTN->getQualifier() &&
+ QualifierLoc.getNestedNameSpecifier() == DTN->getQualifier() &&
ObjectType.isNull())
return Name;
- // FIXME: Preserve the location of the "template" keyword.
- SourceLocation TemplateKWLoc = NameLoc;
- return getDerived().RebuildTemplateName(
- SS, TemplateKWLoc, DTN->getName(), NameLoc, ObjectType,
+ CXXScopeSpec SS;
+ SS.Adopt(QualifierLoc);
+ return getDerived().RebuildTemplateName(SS, TemplateKWLoc, DTN->getName(),
+ NameLoc, ObjectType,
+ AllowInjectedClassName);
+ }
+
+ if (SubstTemplateTemplateParmStorage *S =
+ Name.getAsSubstTemplateTemplateParm()) {
+ TemplateName NewName = getDerived().TransformTemplateName(
+ QualifierLoc, TemplateKWLoc, S->getReplacement(), NameLoc, ObjectType,
FirstQualifierInScope, AllowInjectedClassName);
+ if (NewName.isNull())
+ return TemplateName();
+ Decl *AssociatedDecl =
+ getDerived().TransformDecl(NameLoc, S->getAssociatedDecl());
+ if (!getDerived().AlwaysRebuild() && NewName == S->getReplacement() &&
+ AssociatedDecl == S->getAssociatedDecl())
+ return Name;
+ return SemaRef.Context.getSubstTemplateTemplateParm(
+ NewName, AssociatedDecl, S->getIndex(), S->getPackIndex(),
+ S->getFinal());
}
- // FIXME: Try to preserve more of the TemplateName.
+ assert(!Name.getAsDeducedTemplateName() &&
+ "DeducedTemplateName should not escape partial ordering");
+
if (TemplateDecl *Template = Name.getAsTemplateDecl()) {
+ assert(!QualifierLoc && "missed a Qualified Template");
TemplateDecl *TransTemplate
= cast_or_null<TemplateDecl>(getDerived().TransformDecl(NameLoc,
Template));
if (!TransTemplate)
return TemplateName();
+ CXXScopeSpec SS;
return getDerived().RebuildTemplateName(SS, /*TemplateKeyword=*/false,
TransTemplate);
}
@@ -4929,21 +4941,16 @@ bool TreeTransform<Derived>::TransformTemplateArgument(
case TemplateArgument::Template: {
NestedNameSpecifierLoc QualifierLoc = Input.getTemplateQualifierLoc();
- if (QualifierLoc) {
- QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
- if (!QualifierLoc)
- return true;
- }
- CXXScopeSpec SS;
- SS.Adopt(QualifierLoc);
TemplateName Template = getDerived().TransformTemplateName(
- SS, Arg.getAsTemplate(), Input.getTemplateNameLoc());
+ QualifierLoc, Input.getTemplateKWLoc(), Arg.getAsTemplate(),
+ Input.getTemplateNameLoc());
if (Template.isNull())
return true;
Output = TemplateArgumentLoc(SemaRef.Context, TemplateArgument(Template),
- QualifierLoc, Input.getTemplateNameLoc());
+ Input.getTemplateKWLoc(), QualifierLoc,
+ Input.getTemplateNameLoc());
return false;
}
@@ -5380,85 +5387,35 @@ QualType TreeTransform<Derived>::RebuildQualifiedType(QualType T,
return SemaRef.BuildQualifiedType(T, Loc, Quals);
}
-template<typename Derived>
-TypeLoc
-TreeTransform<Derived>::TransformTypeInObjectScope(TypeLoc TL,
- QualType ObjectType,
- NamedDecl *UnqualLookup,
- CXXScopeSpec &SS) {
- if (getDerived().AlreadyTransformed(TL.getType()))
- return TL;
-
- TypeSourceInfo *TSI =
- TransformTSIInObjectScope(TL, ObjectType, UnqualLookup, SS);
- if (TSI)
- return TSI->getTypeLoc();
- return TypeLoc();
-}
-
-template<typename Derived>
-TypeSourceInfo *
-TreeTransform<Derived>::TransformTypeInObjectScope(TypeSourceInfo *TSInfo,
- QualType ObjectType,
- NamedDecl *UnqualLookup,
- CXXScopeSpec &SS) {
- if (getDerived().AlreadyTransformed(TSInfo->getType()))
- return TSInfo;
-
- return TransformTSIInObjectScope(TSInfo->getTypeLoc(), ObjectType,
- UnqualLookup, SS);
-}
-
template <typename Derived>
-TypeSourceInfo *TreeTransform<Derived>::TransformTSIInObjectScope(
- TypeLoc TL, QualType ObjectType, NamedDecl *UnqualLookup,
- CXXScopeSpec &SS) {
- QualType T = TL.getType();
- assert(!getDerived().AlreadyTransformed(T));
-
- TypeLocBuilder TLB;
- QualType Result;
-
- if (isa<TemplateSpecializationType>(T)) {
- TemplateSpecializationTypeLoc SpecTL =
- TL.castAs<TemplateSpecializationTypeLoc>();
-
- TemplateName Template = getDerived().TransformTemplateName(
- SS, SpecTL.getTypePtr()->getTemplateName(), SpecTL.getTemplateNameLoc(),
- ObjectType, UnqualLookup, /*AllowInjectedClassName*/true);
- if (Template.isNull())
- return nullptr;
+QualType TreeTransform<Derived>::TransformTypeInObjectScope(
+ TypeLocBuilder &TLB, TypeLoc TL, QualType ObjectType,
+ NamedDecl *UnqualLookup) {
+ assert(!getDerived().AlreadyTransformed(TL.getType()));
- Result = getDerived().TransformTemplateSpecializationType(TLB, SpecTL,
- Template);
- } else if (isa<DependentTemplateSpecializationType>(T)) {
- DependentTemplateSpecializationTypeLoc SpecTL =
- TL.castAs<DependentTemplateSpecializationTypeLoc>();
-
- const IdentifierInfo *II = SpecTL.getTypePtr()
- ->getDependentTemplateName()
- .getName()
- .getIdentifier();
- TemplateName Template = getDerived().RebuildTemplateName(
- SS, SpecTL.getTemplateKeywordLoc(), *II, SpecTL.getTemplateNameLoc(),
- ObjectType, UnqualLookup,
- /*AllowInjectedClassName*/ true);
- if (Template.isNull())
- return nullptr;
-
- Result = getDerived().TransformDependentTemplateSpecializationType(TLB,
- SpecTL,
- Template,
- SS);
- } else {
- // Nothing special needs to be done for these.
- Result = getDerived().TransformType(TLB, TL);
+ switch (TL.getTypeLocClass()) {
+ case TypeLoc::DependentTemplateSpecialization:
+ return getDerived().TransformDependentTemplateSpecializationType(
+ TLB, TL.castAs<DependentTemplateSpecializationTypeLoc>(), ObjectType,
+ UnqualLookup, /*AllowInjectedClassName=*/true);
+ case TypeLoc::DependentName: {
+ return getDerived().TransformDependentNameType(
+ TLB, TL.castAs<DependentNameTypeLoc>(), /*DeducedTSTContext=*/false,
+ ObjectType, UnqualLookup);
+ }
+ case TypeLoc::Typedef:
+ case TypeLoc::TemplateSpecialization:
+ case TypeLoc::SubstTemplateTypeParm:
+ case TypeLoc::PackIndexing:
+ case TypeLoc::Enum:
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName:
+ case TypeLoc::TemplateTypeParm:
+ case TypeLoc::Decltype:
+ return getDerived().TransformType(TLB, TL);
+ default:
+ llvm_unreachable("unexpected type class");
}
-
- if (Result.isNull())
- return nullptr;
-
- return TLB.getTypeSourceInfo(SemaRef.Context, Result);
}
template <class TyLoc> static inline
@@ -6694,23 +6651,38 @@ QualType TreeTransform<Derived>::TransformFunctionNoProtoType(
template <typename Derived>
QualType TreeTransform<Derived>::TransformUnresolvedUsingType(
TypeLocBuilder &TLB, UnresolvedUsingTypeLoc TL) {
+
const UnresolvedUsingType *T = TL.getTypePtr();
- Decl *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
+ bool Changed = false;
+
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+ if (!QualifierLoc)
+ return QualType();
+ Changed |= QualifierLoc != OldQualifierLoc;
+ }
+
+ auto *D = getDerived().TransformDecl(TL.getNameLoc(), T->getDecl());
if (!D)
return QualType();
+ Changed |= D != T->getDecl();
QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() || D != T->getDecl()) {
- Result = getDerived().RebuildUnresolvedUsingType(TL.getNameLoc(), D);
+ if (getDerived().AlwaysRebuild() || Changed) {
+ Result = getDerived().RebuildUnresolvedUsingType(
+ T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TL.getNameLoc(),
+ D);
if (Result.isNull())
return QualType();
}
- // We might get an arbitrary type spec type back. We should at
- // least always get a type spec type, though.
- TypeSpecTypeLoc NewTL = TLB.pushTypeSpec(Result);
- NewTL.setNameLoc(TL.getNameLoc());
-
+ if (isa<UsingType>(Result))
+ TLB.push<UsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),
+ QualifierLoc, TL.getNameLoc());
+ else
+ TLB.push<UnresolvedUsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),
+ QualifierLoc, TL.getNameLoc());
return Result;
}
@@ -6718,25 +6690,37 @@ template <typename Derived>
QualType TreeTransform<Derived>::TransformUsingType(TypeLocBuilder &TLB,
UsingTypeLoc TL) {
const UsingType *T = TL.getTypePtr();
+ bool Changed = false;
- auto *Found = cast_or_null<UsingShadowDecl>(getDerived().TransformDecl(
- TL.getLocalSourceRange().getBegin(), T->getFoundDecl()));
- if (!Found)
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+ if (!QualifierLoc)
+ return QualType();
+ Changed |= QualifierLoc != OldQualifierLoc;
+ }
+
+ auto *D = cast_or_null<UsingShadowDecl>(
+ getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
+ if (!D)
return QualType();
+ Changed |= D != T->getDecl();
- QualType Underlying = getDerived().TransformType(T->desugar());
- if (Underlying.isNull())
+ QualType UnderlyingType = getDerived().TransformType(T->desugar());
+ if (UnderlyingType.isNull())
return QualType();
+ Changed |= UnderlyingType != T->desugar();
QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() || Found != T->getFoundDecl() ||
- Underlying != T->getUnderlyingType()) {
- Result = getDerived().RebuildUsingType(Found, Underlying);
+ if (getDerived().AlwaysRebuild() || Changed) {
+ Result = getDerived().RebuildUsingType(
+ T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), D,
+ UnderlyingType);
if (Result.isNull())
return QualType();
}
-
- TLB.pushTypeSpec(Result).setNameLoc(TL.getNameLoc());
+ TLB.push<UsingTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(), QualifierLoc,
+ TL.getNameLoc());
return Result;
}
@@ -6744,23 +6728,34 @@ template<typename Derived>
QualType TreeTransform<Derived>::TransformTypedefType(TypeLocBuilder &TLB,
TypedefTypeLoc TL) {
const TypedefType *T = TL.getTypePtr();
- TypedefNameDecl *Typedef
- = cast_or_null<TypedefNameDecl>(getDerived().TransformDecl(TL.getNameLoc(),
- T->getDecl()));
+ bool Changed = false;
+
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ if (NestedNameSpecifierLoc OldQualifierLoc = QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+ if (!QualifierLoc)
+ return QualType();
+ Changed |= QualifierLoc != OldQualifierLoc;
+ }
+
+ auto *Typedef = cast_or_null<TypedefNameDecl>(
+ getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
if (!Typedef)
return QualType();
+ Changed |= Typedef != T->getDecl();
+
+ // FIXME: Transform the UnderlyingType if different from decl.
QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() ||
- Typedef != T->getDecl()) {
- Result = getDerived().RebuildTypedefType(Typedef);
+ if (getDerived().AlwaysRebuild() || Changed) {
+ Result = getDerived().RebuildTypedefType(
+ T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Typedef);
if (Result.isNull())
return QualType();
}
- TypedefTypeLoc NewTL = TLB.push<TypedefTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
-
+ TLB.push<TypedefTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),
+ QualifierLoc, TL.getNameLoc());
return Result;
}
@@ -6996,9 +6991,10 @@ QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
TypeLocBuilder &TLB, DeducedTemplateSpecializationTypeLoc TL) {
const DeducedTemplateSpecializationType *T = TL.getTypePtr();
- CXXScopeSpec SS;
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
TemplateName TemplateName = getDerived().TransformTemplateName(
- SS, T->getTemplateName(), TL.getTemplateNameLoc());
+ QualifierLoc, /*TemplateKELoc=*/SourceLocation(), T->getTemplateName(),
+ TL.getTemplateNameLoc());
if (TemplateName.isNull())
return QualType();
@@ -7011,76 +7007,71 @@ QualType TreeTransform<Derived>::TransformDeducedTemplateSpecializationType(
}
QualType Result = getDerived().RebuildDeducedTemplateSpecializationType(
- TemplateName, NewDeduced);
+ T->getKeyword(), TemplateName, NewDeduced);
if (Result.isNull())
return QualType();
- DeducedTemplateSpecializationTypeLoc NewTL =
- TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
+ auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
+ NewTL.setElaboratedKWLoc(TL.getElaboratedKWLoc());
NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
-
+ NewTL.setQualifierLoc(QualifierLoc);
return Result;
}
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
- RecordTypeLoc TL) {
- const RecordType *T = TL.getTypePtr();
- RecordDecl *Record
- = cast_or_null<RecordDecl>(getDerived().TransformDecl(TL.getNameLoc(),
- T->getDecl()));
- if (!Record)
+template <typename Derived>
+QualType TreeTransform<Derived>::TransformTagType(TypeLocBuilder &TLB,
+ TagTypeLoc TL) {
+ const TagType *T = TL.getTypePtr();
+
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ if (QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+ if (!QualifierLoc)
+ return QualType();
+ }
+
+ auto *TD = cast_or_null<TagDecl>(
+ getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl()));
+ if (!TD)
return QualType();
QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() ||
- Record != T->getDecl()) {
- Result = getDerived().RebuildRecordType(Record);
+ if (getDerived().AlwaysRebuild() || QualifierLoc != TL.getQualifierLoc() ||
+ TD != T->getOriginalDecl()) {
+ if (T->isCanonicalUnqualified())
+ Result = getDerived().RebuildCanonicalTagType(TD);
+ else
+ Result = getDerived().RebuildTagType(
+ T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), TD);
if (Result.isNull())
return QualType();
}
- RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
+ TagTypeLoc NewTL = TLB.push<TagTypeLoc>(Result);
+ NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
+ NewTL.setQualifierLoc(QualifierLoc);
NewTL.setNameLoc(TL.getNameLoc());
return Result;
}
-template<typename Derived>
+template <typename Derived>
QualType TreeTransform<Derived>::TransformEnumType(TypeLocBuilder &TLB,
EnumTypeLoc TL) {
- const EnumType *T = TL.getTypePtr();
- EnumDecl *Enum
- = cast_or_null<EnumDecl>(getDerived().TransformDecl(TL.getNameLoc(),
- T->getDecl()));
- if (!Enum)
- return QualType();
-
- QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() ||
- Enum != T->getDecl()) {
- Result = getDerived().RebuildEnumType(Enum);
- if (Result.isNull())
- return QualType();
- }
-
- EnumTypeLoc NewTL = TLB.push<EnumTypeLoc>(Result);
- NewTL.setNameLoc(TL.getNameLoc());
+ return getDerived().TransformTagType(TLB, TL);
+}
- return Result;
+template <typename Derived>
+QualType TreeTransform<Derived>::TransformRecordType(TypeLocBuilder &TLB,
+ RecordTypeLoc TL) {
+ return getDerived().TransformTagType(TLB, TL);
}
template<typename Derived>
QualType TreeTransform<Derived>::TransformInjectedClassNameType(
TypeLocBuilder &TLB,
InjectedClassNameTypeLoc TL) {
- Decl *D = getDerived().TransformDecl(TL.getNameLoc(),
- TL.getTypePtr()->getDecl());
- if (!D) return QualType();
-
- QualType T = SemaRef.Context.getTypeDeclType(cast<TypeDecl>(D));
- TLB.pushTypeSpec(T).setNameLoc(TL.getNameLoc());
- return T;
+ return getDerived().TransformTagType(TLB, TL);
}
template<typename Derived>
@@ -7141,24 +7132,6 @@ QualType TreeTransform<Derived>::TransformSubstTemplateTypeParmPackType(
return TransformTypeSpecType(TLB, TL);
}
-template<typename Derived>
-QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
- TypeLocBuilder &TLB,
- TemplateSpecializationTypeLoc TL) {
- const TemplateSpecializationType *T = TL.getTypePtr();
-
- // The nested-name-specifier never matters in a TemplateSpecializationType,
- // because we can't have a dependent nested-name-specifier anyway.
- CXXScopeSpec SS;
- TemplateName Template
- = getDerived().TransformTemplateName(SS, T->getTemplateName(),
- TL.getTemplateNameLoc());
- if (Template.isNull())
- return QualType();
-
- return getDerived().TransformTemplateSpecializationType(TLB, TL, Template);
-}
-
template<typename Derived>
QualType TreeTransform<Derived>::TransformAtomicType(TypeLocBuilder &TLB,
AtomicTypeLoc TL) {
@@ -7392,9 +7365,16 @@ QualType TreeTransform<Derived>::TransformAutoType(TypeLocBuilder &TLB,
template <typename Derived>
QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
- TypeLocBuilder &TLB,
- TemplateSpecializationTypeLoc TL,
- TemplateName Template) {
+ TypeLocBuilder &TLB, TemplateSpecializationTypeLoc TL) {
+ const TemplateSpecializationType *T = TL.getTypePtr();
+
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ TemplateName Template = getDerived().TransformTemplateName(
+ QualifierLoc, TL.getTemplateKeywordLoc(), T->getTemplateName(),
+ TL.getTemplateNameLoc());
+ if (Template.isNull())
+ return QualType();
+
TemplateArgumentListInfo NewTemplateArgs;
NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
@@ -7409,10 +7389,9 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
// original template changed. If the template changed, and even if the
// arguments didn't change, these arguments might not correspond to their
// respective parameters, therefore needing conversions.
- QualType Result =
- getDerived().RebuildTemplateSpecializationType(Template,
- TL.getTemplateNameLoc(),
- NewTemplateArgs);
+ QualType Result = getDerived().RebuildTemplateSpecializationType(
+ TL.getTypePtr()->getKeyword(), Template, TL.getTemplateNameLoc(),
+ NewTemplateArgs);
if (!Result.isNull()) {
// Specializations of template template parameters are represented as
@@ -7422,8 +7401,8 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
if (isa<DependentTemplateSpecializationType>(Result)) {
DependentTemplateSpecializationTypeLoc NewTL
= TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
- NewTL.setElaboratedKeywordLoc(SourceLocation());
- NewTL.setQualifierLoc(NestedNameSpecifierLoc());
+ NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
+ NewTL.setQualifierLoc(QualifierLoc);
NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
NewTL.setLAngleLoc(TL.getLAngleLoc());
@@ -7432,132 +7411,14 @@ QualType TreeTransform<Derived>::TransformTemplateSpecializationType(
NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
return Result;
}
-
- TemplateSpecializationTypeLoc NewTL
- = TLB.push<TemplateSpecializationTypeLoc>(Result);
- NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
- NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
- NewTL.setLAngleLoc(TL.getLAngleLoc());
- NewTL.setRAngleLoc(TL.getRAngleLoc());
- for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
- NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
+ TLB.push<TemplateSpecializationTypeLoc>(Result).set(
+ TL.getElaboratedKeywordLoc(), QualifierLoc, TL.getTemplateKeywordLoc(),
+ TL.getTemplateNameLoc(), NewTemplateArgs);
}
return Result;
}
-template <typename Derived>
-QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
- TypeLocBuilder &TLB,
- DependentTemplateSpecializationTypeLoc TL,
- TemplateName Template,
- CXXScopeSpec &SS) {
- TemplateArgumentListInfo NewTemplateArgs;
- NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
- NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
- typedef TemplateArgumentLocContainerIterator<
- DependentTemplateSpecializationTypeLoc> ArgIterator;
- if (getDerived().TransformTemplateArguments(ArgIterator(TL, 0),
- ArgIterator(TL, TL.getNumArgs()),
- NewTemplateArgs))
- return QualType();
-
- // FIXME: maybe don't rebuild if all the template arguments are the same.
-
- if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
- assert(DTN->getQualifier() == SS.getScopeRep());
- QualType Result = getSema().Context.getDependentTemplateSpecializationType(
- TL.getTypePtr()->getKeyword(), *DTN, NewTemplateArgs.arguments());
-
- DependentTemplateSpecializationTypeLoc NewTL
- = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
- NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
- NewTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
- NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
- NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
- NewTL.setLAngleLoc(TL.getLAngleLoc());
- NewTL.setRAngleLoc(TL.getRAngleLoc());
- for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
- NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
- return Result;
- }
-
- QualType Result
- = getDerived().RebuildTemplateSpecializationType(Template,
- TL.getTemplateNameLoc(),
- NewTemplateArgs);
-
- if (!Result.isNull()) {
- /// FIXME: Wrap this in an elaborated-type-specifier?
- TemplateSpecializationTypeLoc NewTL
- = TLB.push<TemplateSpecializationTypeLoc>(Result);
- NewTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
- NewTL.setTemplateNameLoc(TL.getTemplateNameLoc());
- NewTL.setLAngleLoc(TL.getLAngleLoc());
- NewTL.setRAngleLoc(TL.getRAngleLoc());
- for (unsigned i = 0, e = NewTemplateArgs.size(); i != e; ++i)
- NewTL.setArgLocInfo(i, NewTemplateArgs[i].getLocInfo());
- }
-
- return Result;
-}
-
-template<typename Derived>
-QualType
-TreeTransform<Derived>::TransformElaboratedType(TypeLocBuilder &TLB,
- ElaboratedTypeLoc TL) {
- const ElaboratedType *T = TL.getTypePtr();
-
- NestedNameSpecifierLoc QualifierLoc;
- // NOTE: the qualifier in an ElaboratedType is optional.
- if (TL.getQualifierLoc()) {
- QualifierLoc
- = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
- if (!QualifierLoc)
- return QualType();
- }
-
- QualType NamedT = getDerived().TransformType(TLB, TL.getNamedTypeLoc());
- if (NamedT.isNull())
- return QualType();
-
- // C++0x [dcl.type.elab]p2:
- // If the identifier resolves to a typedef-name or the simple-template-id
- // resolves to an alias template specialization, the
- // elaborated-type-specifier is ill-formed.
- if (T->getKeyword() != ElaboratedTypeKeyword::None &&
- T->getKeyword() != ElaboratedTypeKeyword::Typename) {
- if (const TemplateSpecializationType *TST =
- NamedT->getAs<TemplateSpecializationType>()) {
- TemplateName Template = TST->getTemplateName();
- if (TypeAliasTemplateDecl *TAT = dyn_cast_or_null<TypeAliasTemplateDecl>(
- Template.getAsTemplateDecl())) {
- SemaRef.Diag(TL.getNamedTypeLoc().getBeginLoc(),
- diag::err_tag_reference_non_tag)
- << TAT << NonTagKind::TypeAliasTemplate
- << ElaboratedType::getTagTypeKindForKeyword(T->getKeyword());
- SemaRef.Diag(TAT->getLocation(), diag::note_declared_at);
- }
- }
- }
-
- QualType Result = TL.getType();
- if (getDerived().AlwaysRebuild() ||
- QualifierLoc != TL.getQualifierLoc() ||
- NamedT != T->getNamedType()) {
- Result = getDerived().RebuildElaboratedType(TL.getElaboratedKeywordLoc(),
- T->getKeyword(),
- QualifierLoc, NamedT);
- if (Result.isNull())
- return QualType();
- }
-
- ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
- NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
- NewTL.setQualifierLoc(QualifierLoc);
- return Result;
-}
-
template <typename Derived>
QualType TreeTransform<Derived>::TransformAttributedType(TypeLocBuilder &TLB,
AttributedTypeLoc TL) {
@@ -7748,15 +7609,22 @@ QualType TreeTransform<Derived>::TransformDependentNameType(
return TransformDependentNameType(TLB, TL, false);
}
-template<typename Derived>
+template <typename Derived>
QualType TreeTransform<Derived>::TransformDependentNameType(
- TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext) {
+ TypeLocBuilder &TLB, DependentNameTypeLoc TL, bool DeducedTSTContext,
+ QualType ObjectType, NamedDecl *UnqualLookup) {
const DependentNameType *T = TL.getTypePtr();
- NestedNameSpecifierLoc QualifierLoc
- = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
- if (!QualifierLoc)
- return QualType();
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ if (QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
+ QualifierLoc, ObjectType, UnqualLookup);
+ if (!QualifierLoc)
+ return QualType();
+ } else {
+ assert((ObjectType.isNull() && !UnqualLookup) &&
+ "must be transformed by TransformNestedNameSpecifierLoc");
+ }
QualType Result
= getDerived().RebuildDependentNameType(T->getKeyword(),
@@ -7768,13 +7636,19 @@ QualType TreeTransform<Derived>::TransformDependentNameType(
if (Result.isNull())
return QualType();
- if (const ElaboratedType* ElabT = Result->getAs<ElaboratedType>()) {
- QualType NamedT = ElabT->getNamedType();
- TLB.pushTypeSpec(NamedT).setNameLoc(TL.getNameLoc());
-
- ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
+ if (isa<TagType>(Result)) {
+ auto NewTL = TLB.push<TagTypeLoc>(Result);
NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
NewTL.setQualifierLoc(QualifierLoc);
+ NewTL.setNameLoc(TL.getNameLoc());
+ } else if (isa<DeducedTemplateSpecializationType>(Result)) {
+ auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
+ NewTL.setElaboratedKWLoc(TL.getElaboratedKeywordLoc());
+ NewTL.setTemplateNameLoc(TL.getNameLoc());
+ NewTL.setQualifierLoc(QualifierLoc);
+ } else if (isa<TypedefType>(Result)) {
+ TLB.push<TypedefTypeLoc>(Result).set(TL.getElaboratedKeywordLoc(),
+ QualifierLoc, TL.getNameLoc());
} else {
DependentNameTypeLoc NewTL = TLB.push<DependentNameTypeLoc>(Result);
NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
@@ -7784,33 +7658,34 @@ QualType TreeTransform<Derived>::TransformDependentNameType(
return Result;
}
-template<typename Derived>
-QualType TreeTransform<Derived>::
- TransformDependentTemplateSpecializationType(TypeLocBuilder &TLB,
- DependentTemplateSpecializationTypeLoc TL) {
- NestedNameSpecifierLoc QualifierLoc;
- if (TL.getQualifierLoc()) {
- QualifierLoc
- = getDerived().TransformNestedNameSpecifierLoc(TL.getQualifierLoc());
- if (!QualifierLoc)
- return QualType();
- }
-
- CXXScopeSpec SS;
- SS.Adopt(QualifierLoc);
- return getDerived().TransformDependentTemplateSpecializationType(TLB, TL, SS);
+template <typename Derived>
+QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
+ TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL) {
+ return getDerived().TransformDependentTemplateSpecializationType(
+ TLB, TL, QualType(), nullptr, false);
}
template <typename Derived>
QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
TypeLocBuilder &TLB, DependentTemplateSpecializationTypeLoc TL,
- CXXScopeSpec &SS) {
+ QualType ObjectType, NamedDecl *UnqualLookup, bool AllowInjectedClassName) {
const DependentTemplateSpecializationType *T = TL.getTypePtr();
- TemplateArgumentListInfo NewTemplateArgs;
- NewTemplateArgs.setLAngleLoc(TL.getLAngleLoc());
- NewTemplateArgs.setRAngleLoc(TL.getRAngleLoc());
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ if (QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(
+ QualifierLoc, ObjectType, UnqualLookup);
+ if (!QualifierLoc)
+ return QualType();
+ // These only apply to the leftmost prefix.
+ ObjectType = QualType();
+ UnqualLookup = nullptr;
+ }
+ CXXScopeSpec SS;
+ SS.Adopt(QualifierLoc);
+ TemplateArgumentListInfo NewTemplateArgs(TL.getLAngleLoc(),
+ TL.getRAngleLoc());
auto ArgsRange = llvm::make_range<TemplateArgumentLocContainerIterator<
DependentTemplateSpecializationTypeLoc>>({TL, 0}, {TL, TL.getNumArgs()});
@@ -7827,43 +7702,27 @@ QualType TreeTransform<Derived>::TransformDependentTemplateSpecializationType(
QualType Result = TL.getType();
if (getDerived().AlwaysRebuild() || SS.getScopeRep() != DTN.getQualifier() ||
- TemplateArgumentsChanged) {
+ TemplateArgumentsChanged || !ObjectType.isNull()) {
TemplateName Name = getDerived().RebuildTemplateName(
SS, TL.getTemplateKeywordLoc(), DTN.getName(), TL.getTemplateNameLoc(),
- /*ObjectType=*/QualType(), /*FirstQualifierInScope=*/nullptr,
- /*AllowInjectedClassName=*/false);
+ ObjectType, AllowInjectedClassName);
if (Name.isNull())
return QualType();
Result = getDerived().RebuildDependentTemplateSpecializationType(
- T->getKeyword(), SS.getScopeRep(), TL.getTemplateKeywordLoc(), Name,
+ T->getKeyword(), TL.getTemplateKeywordLoc(), Name,
TL.getTemplateNameLoc(), NewTemplateArgs,
/*AllowInjectedClassName=*/false);
if (Result.isNull())
return QualType();
}
- NestedNameSpecifierLoc QualifierLoc = SS.getWithLocInContext(SemaRef.Context);
- if (const ElaboratedType *ElabT = dyn_cast<ElaboratedType>(Result)) {
- QualType NamedT = ElabT->getNamedType();
-
- // Copy information relevant to the template specialization.
- TemplateSpecializationTypeLoc NamedTL
- = TLB.push<TemplateSpecializationTypeLoc>(NamedT);
- NamedTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
- NamedTL.setTemplateNameLoc(TL.getTemplateNameLoc());
- NamedTL.setLAngleLoc(TL.getLAngleLoc());
- NamedTL.setRAngleLoc(TL.getRAngleLoc());
- for (unsigned I = 0, E = NewTemplateArgs.size(); I != E; ++I)
- NamedTL.setArgLocInfo(I, NewTemplateArgs[I].getLocInfo());
-
- // Copy information relevant to the elaborated type.
- ElaboratedTypeLoc NewTL = TLB.push<ElaboratedTypeLoc>(Result);
- NewTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
- NewTL.setQualifierLoc(QualifierLoc);
+ QualifierLoc = SS.getWithLocInContext(SemaRef.Context);
+ if (isa<TemplateSpecializationType>(Result)) {
+ TLB.push<TemplateSpecializationTypeLoc>(Result).set(
+ TL.getElaboratedKeywordLoc(), QualifierLoc, TL.getTemplateKeywordLoc(),
+ TL.getTemplateNameLoc(), NewTemplateArgs);
} else {
- assert(isa<DependentTemplateSpecializationType>(Result));
- DependentTemplateSpecializationTypeLoc SpecTL
- = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
+ auto SpecTL = TLB.push<DependentTemplateSpecializationTypeLoc>(Result);
SpecTL.setElaboratedKeywordLoc(TL.getElaboratedKeywordLoc());
SpecTL.setQualifierLoc(QualifierLoc);
SpecTL.setTemplateKeywordLoc(TL.getTemplateKeywordLoc());
@@ -8584,14 +8443,18 @@ TreeTransform<Derived>::TransformDeclStmt(DeclStmt *S) {
DeclChanged = true;
if (LSI) {
- if (auto *TD = dyn_cast<TypeDecl>(Transformed))
- LSI->ContainsUnexpandedParameterPack |=
- getSema()
- .getASTContext()
- .getTypeDeclType(TD)
- .getSingleStepDesugaredType(getSema().getASTContext())
- ->containsUnexpandedParameterPack();
-
+ if (auto *TD = dyn_cast<TypeDecl>(Transformed)) {
+ if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) {
+ LSI->ContainsUnexpandedParameterPack |=
+ TN->getUnderlyingType()->containsUnexpandedParameterPack();
+ } else {
+ LSI->ContainsUnexpandedParameterPack |=
+ getSema()
+ .getASTContext()
+ .getTypeDeclType(TD)
+ ->containsUnexpandedParameterPack();
+ }
+ }
if (auto *VD = dyn_cast<VarDecl>(Transformed))
LSI->ContainsUnexpandedParameterPack |=
VD->getType()->containsUnexpandedParameterPack();
@@ -14295,7 +14158,7 @@ TreeTransform<Derived>::TransformCXXTypeidExpr(CXXTypeidExpr *E) {
auto EvalCtx = Sema::ExpressionEvaluationContext::Unevaluated;
if (E->isGLValue())
if (auto *RecordT = Op->getType()->getAs<RecordType>())
- if (cast<CXXRecordDecl>(RecordT->getDecl())->isPolymorphic())
+ if (cast<CXXRecordDecl>(RecordT->getOriginalDecl())->isPolymorphic())
EvalCtx = SemaRef.ExprEvalContexts.back().Context;
EnterExpressionEvaluationContext Unevaluated(SemaRef, EvalCtx,
@@ -14535,7 +14398,8 @@ TreeTransform<Derived>::TransformCXXNewExpr(CXXNewExpr *E) {
QualType ElementType
= SemaRef.Context.getBaseElementType(E->getAllocatedType());
if (const RecordType *RecordT = ElementType->getAs<RecordType>()) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getDecl());
+ CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordT->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(Record)) {
SemaRef.MarkFunctionReferenced(E->getBeginLoc(), Destructor);
}
@@ -14605,7 +14469,9 @@ TreeTransform<Derived>::TransformCXXDeleteExpr(CXXDeleteExpr *E) {
QualType Destroyed = SemaRef.Context.getBaseElementType(
E->getDestroyedType());
if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
+ CXXRecordDecl *Record =
+ cast<CXXRecordDecl>(DestroyedRec->getOriginalDecl())
+ ->getDefinitionOrSelf();
SemaRef.MarkFunctionReferenced(E->getBeginLoc(),
SemaRef.LookupDestructor(Record));
}
@@ -14649,9 +14515,9 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
PseudoDestructorTypeStorage Destroyed;
if (E->getDestroyedTypeInfo()) {
- TypeSourceInfo *DestroyedTypeInfo
- = getDerived().TransformTypeInObjectScope(E->getDestroyedTypeInfo(),
- ObjectType, nullptr, SS);
+ TypeSourceInfo *DestroyedTypeInfo = getDerived().TransformTypeInObjectScope(
+ E->getDestroyedTypeInfo(), ObjectType,
+ /*FirstQualifierInScope=*/nullptr);
if (!DestroyedTypeInfo)
return ExprError();
Destroyed = DestroyedTypeInfo;
@@ -14675,9 +14541,8 @@ TreeTransform<Derived>::TransformCXXPseudoDestructorExpr(
TypeSourceInfo *ScopeTypeInfo = nullptr;
if (E->getScopeTypeInfo()) {
- CXXScopeSpec EmptySS;
ScopeTypeInfo = getDerived().TransformTypeInObjectScope(
- E->getScopeTypeInfo(), ObjectType, nullptr, EmptySS);
+ E->getScopeTypeInfo(), ObjectType, nullptr);
if (!ScopeTypeInfo)
return ExprError();
}
@@ -15798,10 +15663,6 @@ TreeTransform<Derived>::TransformLambdaExpr(LambdaExpr *E) {
// parameters are dependent.
DependencyKind = getDerived().ComputeLambdaDependency(&LSICopy);
Class->setLambdaDependencyKind(DependencyKind);
- // Clean up the type cache created previously. Then, we re-create a type for
- // such Decl with the new DependencyKind.
- Class->setTypeForDecl(nullptr);
- getSema().Context.getTypeDeclType(Class);
return getDerived().RebuildLambdaExpr(E->getBeginLoc(),
Body.get()->getEndLoc(), &LSICopy);
@@ -17304,9 +17165,10 @@ QualType TreeTransform<Derived>::RebuildFunctionNoProtoType(QualType T) {
return SemaRef.Context.getFunctionNoProtoType(T);
}
-template<typename Derived>
-QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
- Decl *D) {
+template <typename Derived>
+QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(
+ ElaboratedTypeKeyword Keyword, NestedNameSpecifier Qualifier,
+ SourceLocation NameLoc, Decl *D) {
assert(D && "no decl found");
if (D->isInvalidDecl()) return QualType();
@@ -17316,7 +17178,7 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
// UsingDecls, but they must each have exactly one type, and it must be
// the same type in every case. But we must have at least one expansion!
if (UPD->expansions().empty()) {
- getSema().Diag(Loc, diag::err_using_pack_expansion_empty)
+ getSema().Diag(NameLoc, diag::err_using_pack_expansion_empty)
<< UPD->isCXXClassMember() << UPD;
return QualType();
}
@@ -17327,10 +17189,11 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
QualType FallbackT;
QualType T;
for (auto *E : UPD->expansions()) {
- QualType ThisT = RebuildUnresolvedUsingType(Loc, E);
+ QualType ThisT =
+ RebuildUnresolvedUsingType(Keyword, Qualifier, NameLoc, E);
if (ThisT.isNull())
continue;
- else if (ThisT->getAs<UnresolvedUsingType>())
+ if (ThisT->getAs<UnresolvedUsingType>())
FallbackT = ThisT;
else if (T.isNull())
T = ThisT;
@@ -17339,7 +17202,8 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
"mismatched resolved types in using pack expansion");
}
return T.isNull() ? FallbackT : T;
- } else if (auto *Using = dyn_cast<UsingDecl>(D)) {
+ }
+ if (auto *Using = dyn_cast<UsingDecl>(D)) {
assert(Using->hasTypename() &&
"UnresolvedUsingTypenameDecl transformed to non-typename using");
@@ -17347,17 +17211,14 @@ QualType TreeTransform<Derived>::RebuildUnresolvedUsingType(SourceLocation Loc,
assert(++Using->shadow_begin() == Using->shadow_end());
UsingShadowDecl *Shadow = *Using->shadow_begin();
- if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), Loc))
+ if (SemaRef.DiagnoseUseOfDecl(Shadow->getTargetDecl(), NameLoc))
return QualType();
- return SemaRef.Context.getUsingType(
- Shadow, SemaRef.Context.getTypeDeclType(
- cast<TypeDecl>(Shadow->getTargetDecl())));
- } else {
- assert(isa<UnresolvedUsingTypenameDecl>(D) &&
- "UnresolvedUsingTypenameDecl transformed to non-using decl");
- return SemaRef.Context.getTypeDeclType(
- cast<UnresolvedUsingTypenameDecl>(D));
+ return SemaRef.Context.getUsingType(Keyword, Qualifier, Shadow);
}
+ assert(isa<UnresolvedUsingTypenameDecl>(D) &&
+ "UnresolvedUsingTypenameDecl transformed to non-using decl");
+ return SemaRef.Context.getUnresolvedUsingType(
+ Keyword, Qualifier, cast<UnresolvedUsingTypenameDecl>(D));
}
template <typename Derived>
@@ -17393,12 +17254,12 @@ QualType TreeTransform<Derived>::RebuildUnaryTransformType(QualType BaseType,
return SemaRef.BuildUnaryTransformType(BaseType, UKind, Loc);
}
-template<typename Derived>
+template <typename Derived>
QualType TreeTransform<Derived>::RebuildTemplateSpecializationType(
- TemplateName Template,
- SourceLocation TemplateNameLoc,
- TemplateArgumentListInfo &TemplateArgs) {
- return SemaRef.CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
+ ElaboratedTypeKeyword Keyword, TemplateName Template,
+ SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
+ return SemaRef.CheckTemplateIdType(Keyword, Template, TemplateNameLoc,
+ TemplateArgs);
}
template<typename Derived>
@@ -17441,15 +17302,10 @@ TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
TemplateName(Template));
}
-template<typename Derived>
-TemplateName
-TreeTransform<Derived>::RebuildTemplateName(CXXScopeSpec &SS,
- SourceLocation TemplateKWLoc,
- const IdentifierInfo &Name,
- SourceLocation NameLoc,
- QualType ObjectType,
- NamedDecl *FirstQualifierInScope,
- bool AllowInjectedClassName) {
+template <typename Derived>
+TemplateName TreeTransform<Derived>::RebuildTemplateName(
+ CXXScopeSpec &SS, SourceLocation TemplateKWLoc, const IdentifierInfo &Name,
+ SourceLocation NameLoc, QualType ObjectType, bool AllowInjectedClassName) {
UnqualifiedId TemplateName;
TemplateName.setIdentifier(&Name, NameLoc);
Sema::TemplateTy Template;
@@ -17591,15 +17447,16 @@ TreeTransform<Derived>::RebuildCXXPseudoDestructorExpr(Expr *Base,
NameInfo.setNamedTypeInfo(DestroyedType);
// The scope type is now known to be a valid nested name specifier
- // component. Tack it on to the end of the nested name specifier.
+ // component. Tack it on to the nested name specifier.
if (ScopeType) {
- if (!ScopeType->getType()->getAs<TagType>()) {
+ if (!isa<TagType>(ScopeType->getType().getCanonicalType())) {
getSema().Diag(ScopeType->getTypeLoc().getBeginLoc(),
diag::err_expected_class_or_namespace)
<< ScopeType->getType() << getSema().getLangOpts().CPlusPlus;
return ExprError();
}
- SS.Extend(SemaRef.Context, ScopeType->getTypeLoc(), CCLoc);
+ SS.clear();
+ SS.Make(SemaRef.Context, ScopeType->getTypeLoc(), CCLoc);
}
SourceLocation TemplateKWLoc; // FIXME: retrieve it from caller.
>From 5255a9d0afb42a2e73dbed3e2e5ab489064cc84e Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Sat, 12 Apr 2025 23:01:12 -0300
Subject: [PATCH 2/4] Other changes
---
clang/include/clang/ASTMatchers/ASTMatchers.h | 157 ++---
.../clang/ASTMatchers/ASTMatchersInternal.h | 20 +-
.../clang/Analysis/FlowSensitive/ASTOps.h | 10 +-
clang/include/clang/Basic/DeclNodes.td | 149 +++--
clang/include/clang/Basic/TypeNodes.td | 3 +-
.../clang/ExtractAPI/DeclarationFragments.h | 5 +-
.../include/clang/Sema/CodeCompleteConsumer.h | 7 +-
clang/include/clang/Sema/DeclSpec.h | 48 +-
clang/include/clang/Sema/HeuristicResolver.h | 3 +-
clang/include/clang/Sema/ParsedTemplate.h | 26 +-
clang/include/clang/Sema/Sema.h | 38 +-
clang/include/clang/Sema/SemaInternal.h | 8 +-
clang/include/clang/Sema/TypoCorrection.h | 29 +-
.../clang/Serialization/ASTRecordReader.h | 2 +-
.../clang/Serialization/ASTRecordWriter.h | 5 +-
.../clang/Serialization/TypeBitCodes.def | 1 -
.../clang/Tooling/Refactoring/Lookup.h | 3 +-
.../Refactoring/RecursiveSymbolVisitor.h | 15 +-
clang/lib/ASTMatchers/ASTMatchFinder.cpp | 115 ++--
clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 5 +-
clang/lib/ASTMatchers/Dynamic/Registry.cpp | 5 +-
.../FlowSensitive/DataflowEnvironment.cpp | 6 +-
clang/lib/Analysis/ThreadSafety.cpp | 4 +-
clang/lib/Analysis/ThreadSafetyCommon.cpp | 4 +-
clang/lib/Analysis/UnsafeBufferUsage.cpp | 12 +-
clang/lib/CodeGen/ABIInfo.cpp | 2 +-
clang/lib/CodeGen/ABIInfoImpl.cpp | 36 +-
clang/lib/CodeGen/CGBlocks.cpp | 3 +-
clang/lib/CodeGen/CGCUDANV.cpp | 3 +-
clang/lib/CodeGen/CGCXX.cpp | 19 +-
clang/lib/CodeGen/CGCXXABI.cpp | 4 +-
clang/lib/CodeGen/CGCall.cpp | 27 +-
clang/lib/CodeGen/CGClass.cpp | 95 +--
clang/lib/CodeGen/CGDebugInfo.cpp | 127 ++--
clang/lib/CodeGen/CGDecl.cpp | 13 +-
clang/lib/CodeGen/CGExpr.cpp | 45 +-
clang/lib/CodeGen/CGExprAgg.cpp | 25 +-
clang/lib/CodeGen/CGExprCXX.cpp | 37 +-
clang/lib/CodeGen/CGExprConstant.cpp | 29 +-
clang/lib/CodeGen/CGExprScalar.cpp | 11 +-
clang/lib/CodeGen/CGHLSLRuntime.cpp | 3 +-
clang/lib/CodeGen/CGNonTrivialStruct.cpp | 9 +-
clang/lib/CodeGen/CGObjC.cpp | 4 +-
clang/lib/CodeGen/CGObjCMac.cpp | 11 +-
clang/lib/CodeGen/CGObjCRuntime.cpp | 4 +-
clang/lib/CodeGen/CGOpenMPRuntime.cpp | 35 +-
clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp | 4 +-
clang/lib/CodeGen/CGPointerAuth.cpp | 2 +-
clang/lib/CodeGen/CGStmt.cpp | 4 +-
clang/lib/CodeGen/CGStmtOpenMP.cpp | 9 +-
clang/lib/CodeGen/CGVTables.cpp | 8 +-
clang/lib/CodeGen/CodeGenFunction.cpp | 8 +-
clang/lib/CodeGen/CodeGenFunction.h | 6 +-
clang/lib/CodeGen/CodeGenModule.cpp | 28 +-
clang/lib/CodeGen/CodeGenTBAA.cpp | 13 +-
clang/lib/CodeGen/CodeGenTypes.cpp | 33 +-
clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp | 3 +-
clang/lib/CodeGen/ItaniumCXXABI.cpp | 68 +-
clang/lib/CodeGen/MicrosoftCXXABI.cpp | 25 +-
clang/lib/CodeGen/SwiftCallingConv.cpp | 9 +-
clang/lib/CodeGen/Targets/AArch64.cpp | 9 +-
clang/lib/CodeGen/Targets/AMDGPU.cpp | 6 +-
clang/lib/CodeGen/Targets/ARC.cpp | 5 +-
clang/lib/CodeGen/Targets/ARM.cpp | 9 +-
clang/lib/CodeGen/Targets/BPF.cpp | 5 +-
clang/lib/CodeGen/Targets/CSKY.cpp | 2 +-
clang/lib/CodeGen/Targets/Hexagon.cpp | 5 +-
clang/lib/CodeGen/Targets/Lanai.cpp | 5 +-
clang/lib/CodeGen/Targets/LoongArch.cpp | 10 +-
clang/lib/CodeGen/Targets/Mips.cpp | 8 +-
clang/lib/CodeGen/Targets/NVPTX.cpp | 6 +-
clang/lib/CodeGen/Targets/PNaCl.cpp | 4 +-
clang/lib/CodeGen/Targets/PPC.cpp | 8 +-
clang/lib/CodeGen/Targets/RISCV.cpp | 10 +-
clang/lib/CodeGen/Targets/SPIR.cpp | 6 +-
clang/lib/CodeGen/Targets/Sparc.cpp | 2 +-
clang/lib/CodeGen/Targets/SystemZ.cpp | 8 +-
clang/lib/CodeGen/Targets/WebAssembly.cpp | 3 +-
clang/lib/CodeGen/Targets/X86.cpp | 59 +-
clang/lib/CodeGen/Targets/XCore.cpp | 4 +-
clang/lib/ExtractAPI/DeclarationFragments.cpp | 117 ++--
.../TypedefUnderlyingTypeResolver.cpp | 2 +-
clang/lib/Frontend/ASTConsumers.cpp | 7 +-
clang/lib/Frontend/ASTUnit.cpp | 2 +-
clang/lib/Index/IndexTypeSourceInfo.cpp | 52 +-
clang/lib/Index/USRGeneration.cpp | 18 +-
clang/lib/InstallAPI/Visitor.cpp | 8 +-
.../Interpreter/InterpreterValuePrinter.cpp | 2 +-
clang/lib/Interpreter/Value.cpp | 6 +-
clang/lib/Parse/ParseDeclCXX.cpp | 3 +-
clang/lib/Parse/ParseExprCXX.cpp | 13 +-
clang/lib/Parse/ParseTemplate.cpp | 29 +-
clang/lib/Parse/ParseTentative.cpp | 2 +-
clang/lib/Parse/Parser.cpp | 9 +-
clang/lib/Sema/AnalysisBasedWarnings.cpp | 11 +-
clang/lib/Sema/DeclSpec.cpp | 36 +-
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 23 +-
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 2 +-
clang/lib/Sema/HeuristicResolver.cpp | 50 +-
clang/lib/Sema/Sema.cpp | 21 +-
clang/lib/Sema/SemaAccess.cpp | 43 +-
clang/lib/Sema/SemaAvailability.cpp | 4 +-
clang/lib/Sema/SemaBPF.cpp | 6 +-
clang/lib/Sema/SemaCUDA.cpp | 7 +-
clang/lib/Sema/SemaCXXScopeSpec.cpp | 331 +++++-----
clang/lib/Sema/SemaCast.cpp | 51 +-
clang/lib/Sema/SemaChecking.cpp | 97 +--
clang/lib/Sema/SemaCodeComplete.cpp | 181 +++---
clang/lib/Sema/SemaCoroutine.cpp | 35 +-
clang/lib/Sema/SemaDecl.cpp | 591 ++++++++++--------
clang/lib/Sema/SemaDeclAttr.cpp | 23 +-
clang/lib/Sema/SemaDeclCXX.cpp | 484 +++++++-------
clang/lib/Sema/SemaDeclObjC.cpp | 32 +-
clang/lib/Sema/SemaExceptionSpec.cpp | 5 +-
clang/lib/Sema/SemaExpr.cpp | 125 ++--
clang/lib/Sema/SemaExprCXX.cpp | 162 ++---
clang/lib/Sema/SemaExprMember.cpp | 7 +-
clang/lib/Sema/SemaExprObjC.cpp | 15 +-
clang/lib/Sema/SemaFunctionEffects.cpp | 8 +-
clang/lib/Sema/SemaHLSL.cpp | 20 +-
clang/lib/Sema/SemaInit.cpp | 145 +++--
clang/lib/Sema/SemaLambda.cpp | 8 +-
clang/lib/Sema/SemaLookup.cpp | 240 ++++---
clang/lib/Sema/SemaObjC.cpp | 5 +-
clang/lib/Sema/SemaObjCProperty.cpp | 4 +-
clang/lib/Sema/SemaOpenMP.cpp | 13 +-
clang/lib/Sema/SemaOverload.cpp | 181 +++---
clang/lib/Sema/SemaPPC.cpp | 6 +-
clang/lib/Sema/SemaSYCL.cpp | 2 +-
clang/lib/Sema/SemaStmt.cpp | 40 +-
clang/lib/Sema/SemaStmtAsm.cpp | 10 +-
clang/lib/Sema/SemaSwift.cpp | 5 +-
clang/lib/Sema/SemaTemplate.cpp | 544 ++++++++--------
clang/lib/Sema/SemaTemplateDeduction.cpp | 162 +++--
clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 58 +-
clang/lib/Sema/SemaTemplateInstantiate.cpp | 184 +++---
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 84 ++-
clang/lib/Sema/SemaTemplateVariadic.cpp | 39 +-
clang/lib/Sema/SemaType.cpp | 184 +++---
clang/lib/Sema/SemaTypeTraits.cpp | 35 +-
clang/lib/Sema/UsedDeclVisitor.h | 7 +-
clang/lib/Serialization/ASTReader.cpp | 126 ++--
clang/lib/Serialization/ASTReaderDecl.cpp | 28 +-
clang/lib/Serialization/ASTWriter.cpp | 113 ++--
clang/lib/Serialization/ASTWriterDecl.cpp | 7 +-
.../Serialization/TemplateArgumentHasher.cpp | 8 +-
.../Checkers/CallAndMessageChecker.cpp | 2 +-
.../Checkers/CastSizeChecker.cpp | 2 +-
.../Checkers/DynamicTypePropagation.cpp | 2 +-
.../Checkers/EnumCastOutOfRangeChecker.cpp | 3 +-
.../Checkers/LLVMConventionsChecker.cpp | 7 +-
.../Checkers/NonNullParamChecker.cpp | 4 +-
.../NonnullGlobalConstantsChecker.cpp | 5 +-
.../NumberObjectConversionChecker.cpp | 11 +-
.../Checkers/PaddingChecker.cpp | 16 +-
.../Checkers/StdLibraryFunctionsChecker.cpp | 4 +-
.../Checkers/WebKit/PtrTypesSemantics.cpp | 33 +-
.../WebKit/RefCntblBaseVirtualDtorChecker.cpp | 8 +-
clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 11 +-
clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 4 +-
clang/lib/StaticAnalyzer/Core/RegionStore.cpp | 5 +-
clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 4 +-
clang/lib/Tooling/ASTDiff/ASTDiff.cpp | 13 +-
clang/lib/Tooling/Refactoring/Lookup.cpp | 14 +-
.../Refactoring/Rename/USRLocFinder.cpp | 167 ++---
clang/lib/Tooling/Syntax/BuildTree.cpp | 172 +++--
.../lib/Tooling/Transformer/RangeSelector.cpp | 8 +-
clang/tools/libclang/CIndex.cpp | 179 ++----
clang/tools/libclang/CIndexCodeCompletion.cpp | 4 +-
clang/tools/libclang/CXCursor.cpp | 8 +-
clang/tools/libclang/CXIndexDataConsumer.cpp | 25 +-
clang/tools/libclang/CXType.cpp | 36 +-
clang/tools/libclang/CursorVisitor.h | 4 +-
173 files changed, 3741 insertions(+), 3504 deletions(-)
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index bae004896c11f..599155c5c9950 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -221,6 +221,19 @@ extern const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
extern const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl>
typeAliasDecl;
+/// \brief Matches shadow declarations introduced into a scope by a
+/// (resolved) using declaration.
+///
+/// Given
+/// \code
+/// namespace n { int f; }
+/// namespace declToImport { using n::f; }
+/// \endcode
+/// usingShadowDecl()
+/// matches \code f \endcode
+extern const internal::VariadicDynCastAllOfMatcher<Decl, UsingShadowDecl>
+ usingShadowDecl;
+
/// Matches type alias template declarations.
///
/// typeAliasTemplateDecl() matches
@@ -3718,7 +3731,7 @@ extern const internal::VariadicOperatorMatcherFunc<1, 1> unless;
/// Matcher<MemberExpr>, Matcher<QualType>, Matcher<RecordType>,
/// Matcher<TagType>, Matcher<TemplateSpecializationType>,
/// Matcher<TemplateTypeParmType>, Matcher<TypedefType>,
-/// Matcher<UnresolvedUsingType>
+/// Matcher<UnresolvedUsingType>, Matcher<UsingType>
inline internal::PolymorphicMatcher<
internal::HasDeclarationMatcher,
void(internal::HasDeclarationSupportedTypes), internal::Matcher<Decl>>
@@ -4353,7 +4366,13 @@ AST_POLYMORPHIC_MATCHER_P(throughUsingDecl,
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr,
UsingType),
internal::Matcher<UsingShadowDecl>, Inner) {
- const NamedDecl *FoundDecl = Node.getFoundDecl();
+ const NamedDecl *FoundDecl;
+ if constexpr (std::is_same_v<NodeType, UsingType>) {
+ FoundDecl = Node.getDecl();
+ } else {
+ static_assert(std::is_same_v<NodeType, DeclRefExpr>);
+ FoundDecl = Node.getFoundDecl();
+ }
if (const UsingShadowDecl *UsingDecl = dyn_cast<UsingShadowDecl>(FoundDecl))
return Inner.matches(*UsingDecl, Finder, Builder);
return false;
@@ -6982,37 +7001,6 @@ AST_POLYMORPHIC_MATCHER_P2(
InnerMatcher.matches(Args[Index], Finder, Builder);
}
-/// Matches C or C++ elaborated `TypeLoc`s.
-///
-/// Given
-/// \code
-/// struct s {};
-/// struct s ss;
-/// \endcode
-/// elaboratedTypeLoc()
-/// matches the `TypeLoc` of the variable declaration of `ss`.
-extern const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
- elaboratedTypeLoc;
-
-/// Matches elaborated `TypeLoc`s that have a named `TypeLoc` matching
-/// `InnerMatcher`.
-///
-/// Given
-/// \code
-/// template <typename T>
-/// class C {};
-/// class C<int> c;
-///
-/// class D {};
-/// class D d;
-/// \endcode
-/// elaboratedTypeLoc(hasNamedTypeLoc(templateSpecializationTypeLoc()));
-/// matches the `TypeLoc` of the variable declaration of `c`, but not `d`.
-AST_MATCHER_P(ElaboratedTypeLoc, hasNamedTypeLoc, internal::Matcher<TypeLoc>,
- InnerMatcher) {
- return InnerMatcher.matches(Node.getNamedTypeLoc(), Finder, Builder);
-}
-
/// Matches type \c bool.
///
/// Given
@@ -7279,7 +7267,7 @@ extern const AstTypeMatcher<DecltypeType> decltypeType;
AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
AST_POLYMORPHIC_SUPPORTED_TYPES(AutoType));
-/// Matches \c DecltypeType or \c UsingType nodes to find the underlying type.
+/// Matches \c QualType nodes to find the underlying type.
///
/// Given
/// \code
@@ -7289,10 +7277,13 @@ AST_TYPE_TRAVERSE_MATCHER(hasDeducedType, getDeducedType,
/// decltypeType(hasUnderlyingType(isInteger()))
/// matches the type of "a"
///
-/// Usable as: Matcher<DecltypeType>, Matcher<UsingType>
-AST_TYPE_TRAVERSE_MATCHER(hasUnderlyingType, getUnderlyingType,
- AST_POLYMORPHIC_SUPPORTED_TYPES(DecltypeType,
- UsingType));
+/// Usable as: Matcher<QualType>
+AST_MATCHER_P(Type, hasUnderlyingType, internal::Matcher<QualType>, Inner) {
+ QualType QT = Node.getLocallyUnqualifiedSingleStepDesugaredType();
+ if (QT == QualType(&Node, 0))
+ return false;
+ return Inner.matches(QT, Finder, Builder);
+}
/// Matches \c FunctionType nodes.
///
@@ -7571,27 +7562,7 @@ extern const AstTypeMatcher<RecordType> recordType;
/// and \c c.
extern const AstTypeMatcher<TagType> tagType;
-/// Matches types specified with an elaborated type keyword or with a
-/// qualified name.
-///
-/// Given
-/// \code
-/// namespace N {
-/// namespace M {
-/// class D {};
-/// }
-/// }
-/// class C {};
-///
-/// class C c;
-/// N::M::D d;
-/// \endcode
-///
-/// \c elaboratedType() matches the type of the variable declarations of both
-/// \c c and \c d.
-extern const AstTypeMatcher<ElaboratedType> elaboratedType;
-
-/// Matches ElaboratedTypes whose qualifier, a NestedNameSpecifier,
+/// Matches Types whose qualifier, a NestedNameSpecifier,
/// matches \c InnerMatcher if the qualifier exists.
///
/// Given
@@ -7606,34 +7577,14 @@ extern const AstTypeMatcher<ElaboratedType> elaboratedType;
///
/// \c elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N"))))
/// matches the type of the variable declaration of \c d.
-AST_MATCHER_P(ElaboratedType, hasQualifier,
- internal::Matcher<NestedNameSpecifier>, InnerMatcher) {
- if (const NestedNameSpecifier *Qualifier = Node.getQualifier())
- return InnerMatcher.matches(*Qualifier, Finder, Builder);
+AST_MATCHER_P(Type, hasQualifier, internal::Matcher<NestedNameSpecifier>,
+ InnerMatcher) {
+ if (NestedNameSpecifier Qualifier = Node.getPrefix())
+ return InnerMatcher.matches(Qualifier, Finder, Builder);
return false;
}
-/// Matches ElaboratedTypes whose named type matches \c InnerMatcher.
-///
-/// Given
-/// \code
-/// namespace N {
-/// namespace M {
-/// class D {};
-/// }
-/// }
-/// N::M::D d;
-/// \endcode
-///
-/// \c elaboratedType(namesType(recordType(
-/// hasDeclaration(namedDecl(hasName("D")))))) matches the type of the variable
-/// declaration of \c d.
-AST_MATCHER_P(ElaboratedType, namesType, internal::Matcher<QualType>,
- InnerMatcher) {
- return InnerMatcher.matches(Node.getNamedType(), Finder, Builder);
-}
-
/// Matches types specified through a using declaration.
///
/// Given
@@ -7802,7 +7753,7 @@ AST_MATCHER_FUNCTION_P_OVERLOAD(
/// matches "A::"
AST_MATCHER_P(NestedNameSpecifier, specifiesType,
internal::Matcher<QualType>, InnerMatcher) {
- if (!Node.getAsType())
+ if (Node.getKind() != NestedNameSpecifier::Kind::Type)
return false;
return InnerMatcher.matches(QualType(Node.getAsType(), 0), Finder, Builder);
}
@@ -7820,8 +7771,12 @@ AST_MATCHER_P(NestedNameSpecifier, specifiesType,
/// matches "A::"
AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
internal::Matcher<TypeLoc>, InnerMatcher) {
- return Node && Node.getNestedNameSpecifier()->getAsType() &&
- InnerMatcher.matches(Node.getTypeLoc(), Finder, Builder);
+ if (!Node)
+ return false;
+ TypeLoc TL = Node.getAsTypeLoc();
+ if (!TL)
+ return false;
+ return InnerMatcher.matches(TL, Finder, Builder);
}
/// Matches on the prefix of a \c NestedNameSpecifier.
@@ -7836,10 +7791,21 @@ AST_MATCHER_P(NestedNameSpecifierLoc, specifiesTypeLoc,
AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
internal::Matcher<NestedNameSpecifier>, InnerMatcher,
0) {
- const NestedNameSpecifier *NextNode = Node.getPrefix();
+ NestedNameSpecifier NextNode = std::nullopt;
+ switch (Node.getKind()) {
+ case NestedNameSpecifier::Kind::Namespace:
+ NextNode = Node.getAsNamespaceAndPrefix().Prefix;
+ break;
+ case NestedNameSpecifier::Kind::Type:
+ NextNode = Node.getAsType()->getPrefix();
+ break;
+ default:
+ break;
+ }
+
if (!NextNode)
return false;
- return InnerMatcher.matches(*NextNode, Finder, Builder);
+ return InnerMatcher.matches(NextNode, Finder, Builder);
}
/// Matches on the prefix of a \c NestedNameSpecifierLoc.
@@ -7854,7 +7820,12 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifier, hasPrefix,
AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
internal::Matcher<NestedNameSpecifierLoc>, InnerMatcher,
1) {
- NestedNameSpecifierLoc NextNode = Node.getPrefix();
+ NestedNameSpecifierLoc NextNode;
+ if (TypeLoc TL = Node.getAsTypeLoc())
+ NextNode = TL.getPrefix();
+ else
+ NextNode = Node.getAsNamespaceAndPrefix().Prefix;
+
if (!NextNode)
return false;
return InnerMatcher.matches(NextNode, Finder, Builder);
@@ -7872,9 +7843,13 @@ AST_MATCHER_P_OVERLOAD(NestedNameSpecifierLoc, hasPrefix,
/// matches "ns::"
AST_MATCHER_P(NestedNameSpecifier, specifiesNamespace,
internal::Matcher<NamespaceDecl>, InnerMatcher) {
- if (!Node.getAsNamespace())
+ if (Node.getKind() != NestedNameSpecifier::Kind::Namespace)
+ return false;
+ const auto *Namespace =
+ dyn_cast<NamespaceDecl>(Node.getAsNamespaceAndPrefix().Namespace);
+ if (!Namespace)
return false;
- return InnerMatcher.matches(*Node.getAsNamespace(), Finder, Builder);
+ return InnerMatcher.matches(*Namespace, Finder, Builder);
}
/// Matches attributes.
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 667a044abcef1..399af3d888551 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1013,10 +1013,7 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
// First, for any types that have a declaration, extract the declaration and
// match on it.
if (const auto *S = dyn_cast<TagType>(&Node)) {
- return matchesDecl(S->getDecl(), Finder, Builder);
- }
- if (const auto *S = dyn_cast<InjectedClassNameType>(&Node)) {
- return matchesDecl(S->getDecl(), Finder, Builder);
+ return matchesDecl(S->getOriginalDecl(), Finder, Builder);
}
if (const auto *S = dyn_cast<TemplateTypeParmType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
@@ -1027,6 +1024,9 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
if (const auto *S = dyn_cast<UnresolvedUsingType>(&Node)) {
return matchesDecl(S->getDecl(), Finder, Builder);
}
+ if (const auto *S = dyn_cast<UsingType>(&Node)) {
+ return matchesDecl(S->getDecl(), Finder, Builder);
+ }
if (const auto *S = dyn_cast<ObjCObjectType>(&Node)) {
return matchesDecl(S->getInterface(), Finder, Builder);
}
@@ -1062,12 +1062,6 @@ class HasDeclarationMatcher : public MatcherInterface<T> {
Builder);
}
- // FIXME: We desugar elaborated types. This makes the assumption that users
- // do never want to match on whether a type is elaborated - there are
- // arguments for both sides; for now, continue desugaring.
- if (const auto *S = dyn_cast<ElaboratedType>(&Node)) {
- return matchesSpecialized(S->desugar(), Finder, Builder);
- }
// Similarly types found via using declarations.
// These are *usually* meaningless sugar, and this matches the historical
// behavior prior to the introduction of UsingType.
@@ -1207,8 +1201,8 @@ using AdaptativeDefaultToTypes =
/// All types that are supported by HasDeclarationMatcher above.
using HasDeclarationSupportedTypes =
TypeList<CallExpr, CXXConstructExpr, CXXNewExpr, DeclRefExpr, EnumType,
- ElaboratedType, InjectedClassNameType, LabelStmt, AddrLabelExpr,
- MemberExpr, QualType, RecordType, TagType,
+ InjectedClassNameType, LabelStmt, AddrLabelExpr, MemberExpr,
+ QualType, RecordType, TagType, UsingType,
TemplateSpecializationType, TemplateTypeParmType, TypedefType,
UnresolvedUsingType, ObjCIvarRefExpr, ObjCInterfaceDecl>;
@@ -1785,7 +1779,7 @@ class LocMatcher : public MatcherInterface<TLoc> {
private:
static DynTypedNode extract(const NestedNameSpecifierLoc &Loc) {
- return DynTypedNode::create(*Loc.getNestedNameSpecifier());
+ return DynTypedNode::create(Loc.getNestedNameSpecifier());
}
};
diff --git a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
index 8c7ee86d15c06..a404b06cd62ca 100644
--- a/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
+++ b/clang/include/clang/Analysis/FlowSensitive/ASTOps.h
@@ -112,8 +112,14 @@ class AnalysisASTVisitor : public DynamicRecursiveASTVisitor {
// fields that are only used in these.
// Note: The operand of the `noexcept` operator is an unevaluated operand, but
// nevertheless it appears in the Clang CFG, so we don't exclude it here.
- bool TraverseDecltypeTypeLoc(DecltypeTypeLoc) override { return true; }
- bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc) override { return true; }
+ bool TraverseDecltypeTypeLoc(DecltypeTypeLoc,
+ bool TraverseQualifier) override {
+ return true;
+ }
+ bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc,
+ bool TraverseQualifier) override {
+ return true;
+ }
bool TraverseCXXTypeidExpr(CXXTypeidExpr *TIE) override {
if (TIE->isPotentiallyEvaluated())
return DynamicRecursiveASTVisitor::TraverseCXXTypeidExpr(TIE);
diff --git a/clang/include/clang/Basic/DeclNodes.td b/clang/include/clang/Basic/DeclNodes.td
index f1ebaf1db3fc0..b4c02949426a1 100644
--- a/clang/include/clang/Basic/DeclNodes.td
+++ b/clang/include/clang/Basic/DeclNodes.td
@@ -15,81 +15,80 @@ def PragmaComment : DeclNode<Decl>;
def PragmaDetectMismatch : DeclNode<Decl>;
def ExternCContext : DeclNode<Decl>, DeclContext;
def Named : DeclNode<Decl, "named declarations", 1>;
- def Namespace : DeclNode<Named, "namespaces">, DeclContext;
- def UsingDirective : DeclNode<Named>;
- def NamespaceAlias : DeclNode<Named>;
- def Label : DeclNode<Named, "labels">;
- def Type : DeclNode<Named, "types", 1>;
- def TypedefName : DeclNode<Type, "typedefs", 1>;
- def Typedef : DeclNode<TypedefName>;
- def TypeAlias : DeclNode<TypedefName>;
- def ObjCTypeParam : DeclNode<TypedefName>;
- def UnresolvedUsingTypename : DeclNode<Type>;
- def Tag : DeclNode<Type, "tag types", 1>, DeclContext;
- def Enum : DeclNode<Tag, "enums">;
- def Record : DeclNode<Tag, "structs, unions, classes">;
- def CXXRecord : DeclNode<Record, "classes">;
- def ClassTemplateSpecialization : DeclNode<CXXRecord>;
- def ClassTemplatePartialSpecialization
- : DeclNode<ClassTemplateSpecialization>;
- def TemplateTypeParm : DeclNode<Type>;
- def Value : DeclNode<Named, "value declarations", 1>;
- def EnumConstant : DeclNode<Value, "enumerators">;
- def UnresolvedUsingValue : DeclNode<Value>;
- def IndirectField : DeclNode<Value>;
- def Binding : DeclNode<Value>;
- def OMPDeclareReduction : DeclNode<Value>, DeclContext;
- def OMPDeclareMapper : DeclNode<Value>, DeclContext;
- def MSGuid : DeclNode<Value>;
- def UnnamedGlobalConstant : DeclNode<Value>;
- def TemplateParamObject : DeclNode<Value>;
- def Declarator : DeclNode<Value, "declarators", 1>;
- def Field : DeclNode<Declarator, "non-static data members">;
- def ObjCIvar : DeclNode<Field>;
- def ObjCAtDefsField : DeclNode<Field>;
- def MSProperty : DeclNode<Declarator>;
- def Function : DeclNode<Declarator, "functions">, DeclContext;
- def CXXDeductionGuide : DeclNode<Function>;
- def CXXMethod : DeclNode<Function>;
- def CXXConstructor : DeclNode<CXXMethod>;
- def CXXDestructor : DeclNode<CXXMethod>;
- def CXXConversion : DeclNode<CXXMethod>;
- def Var : DeclNode<Declarator, "variables">;
- def VarTemplateSpecialization : DeclNode<Var>;
- def VarTemplatePartialSpecialization
- : DeclNode<VarTemplateSpecialization>;
- def ImplicitParam : DeclNode<Var>;
- def ParmVar : DeclNode<Var, "parameters">;
- def Decomposition : DeclNode<Var>;
- def OMPCapturedExpr : DeclNode<Var>;
- def NonTypeTemplateParm : DeclNode<Declarator>;
- def Template : DeclNode<Named, "templates", 1>;
- def RedeclarableTemplate : DeclNode<Template, "redeclarable templates", 1>;
- def FunctionTemplate : DeclNode<RedeclarableTemplate>;
- def ClassTemplate : DeclNode<RedeclarableTemplate>;
- def VarTemplate : DeclNode<RedeclarableTemplate>;
- def TypeAliasTemplate : DeclNode<RedeclarableTemplate>;
- def TemplateTemplateParm : DeclNode<Template>;
- def BuiltinTemplate : DeclNode<Template>;
- def Concept : DeclNode<Template>;
- def BaseUsing : DeclNode<Named, "", 1>;
- def Using : DeclNode<BaseUsing>;
- def UsingEnum : DeclNode<BaseUsing>;
- def UsingPack : DeclNode<Named>;
- def UsingShadow : DeclNode<Named>;
- def ConstructorUsingShadow : DeclNode<UsingShadow>;
- def UnresolvedUsingIfExists : DeclNode<Named>;
- def ObjCMethod : DeclNode<Named, "Objective-C methods">, DeclContext;
- def ObjCContainer : DeclNode<Named, "Objective-C containers", 1>, DeclContext;
- def ObjCCategory : DeclNode<ObjCContainer>;
- def ObjCProtocol : DeclNode<ObjCContainer, "Objective-C protocols">;
- def ObjCInterface : DeclNode<ObjCContainer, "Objective-C interfaces">;
- def ObjCImpl
- : DeclNode<ObjCContainer, "Objective-C implementation declarations", 1>;
- def ObjCCategoryImpl : DeclNode<ObjCImpl>;
- def ObjCImplementation : DeclNode<ObjCImpl>;
- def ObjCProperty : DeclNode<Named, "Objective-C properties">;
- def ObjCCompatibleAlias : DeclNode<Named>;
+def NamespaceBase : DeclNode<Named, "namespace declarations", 1>;
+def Namespace : DeclNode<NamespaceBase, "namespaces">, DeclContext;
+def NamespaceAlias : DeclNode<NamespaceBase>;
+def UsingDirective : DeclNode<Named>;
+def Label : DeclNode<Named, "labels">;
+def Type : DeclNode<Named, "types", 1>;
+def TypedefName : DeclNode<Type, "typedefs", 1>;
+def Typedef : DeclNode<TypedefName>;
+def TypeAlias : DeclNode<TypedefName>;
+def ObjCTypeParam : DeclNode<TypedefName>;
+def UnresolvedUsingTypename : DeclNode<Type>;
+def Tag : DeclNode<Type, "tag types", 1>, DeclContext;
+def Enum : DeclNode<Tag, "enums">;
+def Record : DeclNode<Tag, "structs, unions, classes">;
+def CXXRecord : DeclNode<Record, "classes">;
+def ClassTemplateSpecialization : DeclNode<CXXRecord>;
+def ClassTemplatePartialSpecialization : DeclNode<ClassTemplateSpecialization>;
+def TemplateTypeParm : DeclNode<Type>;
+def Value : DeclNode<Named, "value declarations", 1>;
+def EnumConstant : DeclNode<Value, "enumerators">;
+def UnresolvedUsingValue : DeclNode<Value>;
+def IndirectField : DeclNode<Value>;
+def Binding : DeclNode<Value>;
+def OMPDeclareReduction : DeclNode<Value>, DeclContext;
+def OMPDeclareMapper : DeclNode<Value>, DeclContext;
+def MSGuid : DeclNode<Value>;
+def UnnamedGlobalConstant : DeclNode<Value>;
+def TemplateParamObject : DeclNode<Value>;
+def Declarator : DeclNode<Value, "declarators", 1>;
+def Field : DeclNode<Declarator, "non-static data members">;
+def ObjCIvar : DeclNode<Field>;
+def ObjCAtDefsField : DeclNode<Field>;
+def MSProperty : DeclNode<Declarator>;
+def Function : DeclNode<Declarator, "functions">, DeclContext;
+def CXXDeductionGuide : DeclNode<Function>;
+def CXXMethod : DeclNode<Function>;
+def CXXConstructor : DeclNode<CXXMethod>;
+def CXXDestructor : DeclNode<CXXMethod>;
+def CXXConversion : DeclNode<CXXMethod>;
+def Var : DeclNode<Declarator, "variables">;
+def VarTemplateSpecialization : DeclNode<Var>;
+def VarTemplatePartialSpecialization : DeclNode<VarTemplateSpecialization>;
+def ImplicitParam : DeclNode<Var>;
+def ParmVar : DeclNode<Var, "parameters">;
+def Decomposition : DeclNode<Var>;
+def OMPCapturedExpr : DeclNode<Var>;
+def NonTypeTemplateParm : DeclNode<Declarator>;
+def Template : DeclNode<Named, "templates", 1>;
+def RedeclarableTemplate : DeclNode<Template, "redeclarable templates", 1>;
+def FunctionTemplate : DeclNode<RedeclarableTemplate>;
+def ClassTemplate : DeclNode<RedeclarableTemplate>;
+def VarTemplate : DeclNode<RedeclarableTemplate>;
+def TypeAliasTemplate : DeclNode<RedeclarableTemplate>;
+def TemplateTemplateParm : DeclNode<Template>;
+def BuiltinTemplate : DeclNode<Template>;
+def Concept : DeclNode<Template>;
+def BaseUsing : DeclNode<Named, "", 1>;
+def Using : DeclNode<BaseUsing>;
+def UsingEnum : DeclNode<BaseUsing>;
+def UsingPack : DeclNode<Named>;
+def UsingShadow : DeclNode<Named>;
+def ConstructorUsingShadow : DeclNode<UsingShadow>;
+def UnresolvedUsingIfExists : DeclNode<Named>;
+def ObjCMethod : DeclNode<Named, "Objective-C methods">, DeclContext;
+def ObjCContainer : DeclNode<Named, "Objective-C containers", 1>, DeclContext;
+def ObjCCategory : DeclNode<ObjCContainer>;
+def ObjCProtocol : DeclNode<ObjCContainer, "Objective-C protocols">;
+def ObjCInterface : DeclNode<ObjCContainer, "Objective-C interfaces">;
+def ObjCImpl
+ : DeclNode<ObjCContainer, "Objective-C implementation declarations", 1>;
+def ObjCCategoryImpl : DeclNode<ObjCImpl>;
+def ObjCImplementation : DeclNode<ObjCImpl>;
+def ObjCProperty : DeclNode<Named, "Objective-C properties">;
+def ObjCCompatibleAlias : DeclNode<Named>;
def ImplicitConceptSpecialization : DeclNode<Decl>;
def LinkageSpec : DeclNode<Decl>, DeclContext;
def Export : DeclNode<Decl>, DeclContext;
diff --git a/clang/include/clang/Basic/TypeNodes.td b/clang/include/clang/Basic/TypeNodes.td
index 567b8a5ca5a4d..5f3b20e4f3245 100644
--- a/clang/include/clang/Basic/TypeNodes.td
+++ b/clang/include/clang/Basic/TypeNodes.td
@@ -90,7 +90,7 @@ def UnaryTransformType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def TagType : TypeNode<Type, 1>;
def RecordType : TypeNode<TagType>, LeafType;
def EnumType : TypeNode<TagType>, LeafType;
-def ElaboratedType : TypeNode<Type>, NeverCanonical;
+def InjectedClassNameType : TypeNode<TagType>, AlwaysDependent, LeafType;
def AttributedType : TypeNode<Type>, NeverCanonical;
def BTFTagAttributedType : TypeNode<Type>, NeverCanonical;
def HLSLAttributedResourceType : TypeNode<Type>;
@@ -102,7 +102,6 @@ def TemplateSpecializationType : TypeNode<Type>, NeverCanonicalUnlessDependent;
def DeducedType : TypeNode<Type, 1>;
def AutoType : TypeNode<DeducedType>;
def DeducedTemplateSpecializationType : TypeNode<DeducedType>;
-def InjectedClassNameType : TypeNode<Type>, AlwaysDependent, LeafType;
def DependentNameType : TypeNode<Type>, AlwaysDependent;
def DependentTemplateSpecializationType : TypeNode<Type>, AlwaysDependent;
def PackExpansionType : TypeNode<Type>, AlwaysDependent;
diff --git a/clang/include/clang/ExtractAPI/DeclarationFragments.h b/clang/include/clang/ExtractAPI/DeclarationFragments.h
index 4ac744459031e..4859225ef4ced 100644
--- a/clang/include/clang/ExtractAPI/DeclarationFragments.h
+++ b/clang/include/clang/ExtractAPI/DeclarationFragments.h
@@ -440,9 +440,8 @@ class DeclarationFragmentsBuilder {
DeclarationFragments &);
/// Build DeclarationFragments for a NestedNameSpecifier.
- static DeclarationFragments getFragmentsForNNS(const NestedNameSpecifier *,
- ASTContext &,
- DeclarationFragments &);
+ static DeclarationFragments
+ getFragmentsForNNS(NestedNameSpecifier, ASTContext &, DeclarationFragments &);
/// Build DeclarationFragments for Qualifiers.
static DeclarationFragments getFragmentsForQualifiers(const Qualifiers quals);
diff --git a/clang/include/clang/Sema/CodeCompleteConsumer.h b/clang/include/clang/Sema/CodeCompleteConsumer.h
index 2dd27593778c7..c26f4e33d289c 100644
--- a/clang/include/clang/Sema/CodeCompleteConsumer.h
+++ b/clang/include/clang/Sema/CodeCompleteConsumer.h
@@ -162,7 +162,8 @@ SimplifiedTypeClass getSimplifiedTypeClass(CanQualType T);
/// Determine the type that this declaration will have if it is used
/// as a type or in an expression.
-QualType getDeclUsageType(ASTContext &C, const NamedDecl *ND);
+QualType getDeclUsageType(ASTContext &C, NestedNameSpecifier Qualifier,
+ const NamedDecl *ND);
/// Determine the priority to be given to a macro code completion result
/// with the given name.
@@ -867,7 +868,7 @@ class CodeCompletionResult {
/// If the result should have a nested-name-specifier, this is it.
/// When \c QualifierIsInformative, the nested-name-specifier is
/// informative rather than required.
- NestedNameSpecifier *Qualifier = nullptr;
+ NestedNameSpecifier Qualifier = std::nullopt;
/// If this Decl was unshadowed by using declaration, this can store a
/// pointer to the UsingShadowDecl which was used in the unshadowing process.
@@ -882,7 +883,7 @@ class CodeCompletionResult {
/// Build a result that refers to a declaration.
CodeCompletionResult(const NamedDecl *Declaration, unsigned Priority,
- NestedNameSpecifier *Qualifier = nullptr,
+ NestedNameSpecifier Qualifier = std::nullopt,
bool QualifierIsInformative = false,
bool Accessible = true,
std::vector<FixItHint> FixIts = std::vector<FixItHint>())
diff --git a/clang/include/clang/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index 567ad2d5934d4..f16d9b5680ee2 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -92,12 +92,11 @@ class CXXScopeSpec {
}
/// Retrieve the representation of the nested-name-specifier.
- NestedNameSpecifier *getScopeRep() const {
+ NestedNameSpecifier getScopeRep() const {
return Builder.getRepresentation();
}
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'type::'.
+ /// Make a nested-name-specifier of the form 'type::'.
///
/// \param Context The AST context in which this nested-name-specifier
/// resides.
@@ -107,21 +106,7 @@ class CXXScopeSpec {
/// \param TL The TypeLoc that describes the type preceding the '::'.
///
/// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc);
-
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'identifier::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Identifier The identifier.
- ///
- /// \param IdentifierLoc The location of the identifier.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, IdentifierInfo *Identifier,
- SourceLocation IdentifierLoc, SourceLocation ColonColonLoc);
+ void Make(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc);
/// Extend the current nested-name-specifier by another
/// nested-name-specifier component of the form 'namespace::'.
@@ -134,24 +119,9 @@ class CXXScopeSpec {
/// \param NamespaceLoc The location of the namespace name.
///
/// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceDecl *Namespace,
+ void Extend(ASTContext &Context, NamespaceBaseDecl *Namespace,
SourceLocation NamespaceLoc, SourceLocation ColonColonLoc);
- /// Extend the current nested-name-specifier by another
- /// nested-name-specifier component of the form 'namespace-alias::'.
- ///
- /// \param Context The AST context in which this nested-name-specifier
- /// resides.
- ///
- /// \param Alias The namespace alias.
- ///
- /// \param AliasLoc The location of the namespace alias
- /// name.
- ///
- /// \param ColonColonLoc The location of the trailing '::'.
- void Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc, SourceLocation ColonColonLoc);
-
/// Turn this (empty) nested-name-specifier into the global
/// nested-name-specifier '::'.
void MakeGlobal(ASTContext &Context, SourceLocation ColonColonLoc);
@@ -178,7 +148,7 @@ class CXXScopeSpec {
/// FIXME: This routine should be used very, very rarely, in cases where we
/// need to synthesize a nested-name-specifier. Most code should instead use
/// \c Adopt() with a proper \c NestedNameSpecifierLoc.
- void MakeTrivial(ASTContext &Context, NestedNameSpecifier *Qualifier,
+ void MakeTrivial(ASTContext &Context, NestedNameSpecifier Qualifier,
SourceRange R);
/// Adopt an existing nested-name-specifier (with source-range
@@ -204,14 +174,14 @@ class CXXScopeSpec {
SourceLocation getLastQualifierNameLoc() const;
/// No scope specifier.
- bool isEmpty() const { return Range.isInvalid() && getScopeRep() == nullptr; }
+ bool isEmpty() const { return Range.isInvalid() && !getScopeRep(); }
/// A scope specifier is present, but may be valid or invalid.
bool isNotEmpty() const { return !isEmpty(); }
/// An error occurred during parsing of the scope specifier.
- bool isInvalid() const { return Range.isValid() && getScopeRep() == nullptr; }
+ bool isInvalid() const { return Range.isValid() && !getScopeRep(); }
/// A scope specifier is present, and it refers to a real scope.
- bool isValid() const { return getScopeRep() != nullptr; }
+ bool isValid() const { return bool(getScopeRep()); }
/// Indicate that this nested-name-specifier is invalid.
void SetInvalid(SourceRange R) {
@@ -224,7 +194,7 @@ class CXXScopeSpec {
/// Deprecated. Some call sites intend isNotEmpty() while others intend
/// isValid().
- bool isSet() const { return getScopeRep() != nullptr; }
+ bool isSet() const { return bool(getScopeRep()); }
void clear() {
Range = SourceRange();
diff --git a/clang/include/clang/Sema/HeuristicResolver.h b/clang/include/clang/Sema/HeuristicResolver.h
index e193c0bc14cd9..71588bee92d16 100644
--- a/clang/include/clang/Sema/HeuristicResolver.h
+++ b/clang/include/clang/Sema/HeuristicResolver.h
@@ -67,8 +67,7 @@ class HeuristicResolver {
// Try to heuristically resolve a dependent nested name specifier
// to the type it likely denotes. Note that *dependent* name specifiers always
// denote types, not namespaces.
- QualType
- resolveNestedNameSpecifierToType(const NestedNameSpecifier *NNS) const;
+ QualType resolveNestedNameSpecifierToType(NestedNameSpecifier NNS) const;
// Perform an imprecise lookup of a dependent name in `RD`.
// This function does not follow strict semantic rules and should be used
diff --git a/clang/include/clang/Sema/ParsedTemplate.h b/clang/include/clang/Sema/ParsedTemplate.h
index 3a8050f9a0a3d..4a3df781b5a58 100644
--- a/clang/include/clang/Sema/ParsedTemplate.h
+++ b/clang/include/clang/Sema/ParsedTemplate.h
@@ -48,8 +48,8 @@ namespace clang {
///
/// \param Arg the template type argument or non-type template argument.
/// \param Loc the location of the type.
- ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation Loc)
- : Kind(Kind), Arg(Arg), Loc(Loc) { }
+ ParsedTemplateArgument(KindType Kind, void *Arg, SourceLocation NameLoc)
+ : Kind(Kind), Arg(Arg), NameLoc(NameLoc) {}
/// Create a template template argument.
///
@@ -60,11 +60,11 @@ namespace clang {
/// argument refers.
///
/// \param TemplateLoc the location of the template name.
- ParsedTemplateArgument(const CXXScopeSpec &SS,
- ParsedTemplateTy Template,
- SourceLocation TemplateLoc)
- : Kind(ParsedTemplateArgument::Template),
- Arg(Template.getAsOpaquePtr()), SS(SS), Loc(TemplateLoc) {}
+ ParsedTemplateArgument(SourceLocation TemplateKwLoc, const CXXScopeSpec &SS,
+ ParsedTemplateTy Template, SourceLocation NameLoc)
+ : Kind(ParsedTemplateArgument::Template),
+ Arg(Template.getAsOpaquePtr()), SS(SS), TemplateKwLoc(TemplateKwLoc),
+ NameLoc(NameLoc) {}
/// Determine whether the given template argument is invalid.
bool isInvalid() const { return Arg == nullptr; }
@@ -91,7 +91,10 @@ namespace clang {
}
/// Retrieve the location of the template argument.
- SourceLocation getLocation() const { return Loc; }
+ SourceLocation getTemplateKwLoc() const { return TemplateKwLoc; }
+
+ /// Retrieve the location of the template argument.
+ SourceLocation getNameLoc() const { return NameLoc; }
/// Retrieve the nested-name-specifier that precedes the template
/// name in a template template argument.
@@ -128,8 +131,11 @@ namespace clang {
/// argument.
CXXScopeSpec SS;
- /// the location of the template argument.
- SourceLocation Loc;
+ /// the location of the template keyword.
+ SourceLocation TemplateKwLoc;
+
+ /// the location of the template name.
+ SourceLocation NameLoc;
/// The ellipsis location that can accompany a template template
/// argument (turning it into a template template argument expansion).
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index b281b1cfef96a..c6319672ef823 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3208,7 +3208,7 @@ class Sema final : public SemaBase {
/// current instantiation (C++0x [temp.dep.type]p1).
///
/// \param NNS a dependent nested name specifier.
- CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier *NNS);
+ CXXRecordDecl *getCurrentInstantiationOf(NestedNameSpecifier NNS);
/// The parser has parsed a global nested-name-specifier '::'.
///
@@ -3245,7 +3245,7 @@ class Sema final : public SemaBase {
/// (e.g., Base::), perform name lookup for that identifier as a
/// nested-name-specifier within the given scope, and return the result of
/// that name lookup.
- NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS);
+ NamedDecl *FindFirstQualifierInScope(Scope *S, NestedNameSpecifier NNS);
/// Keeps information about an identifier in a nested-name-spec.
///
@@ -3564,8 +3564,8 @@ class Sema final : public SemaBase {
/// Returns the TypeDeclType for the given type declaration,
/// as ASTContext::getTypeDeclType would, but
/// performs the required semantic checks for name lookup of said entity.
- QualType getTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK,
- TypeDecl *TD, SourceLocation NameLoc);
+ void checkTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK, TypeDecl *TD,
+ SourceLocation NameLoc);
/// If the identifier refers to a type name within this scope,
/// return the declaration of that type.
@@ -7607,7 +7607,7 @@ class Sema final : public SemaBase {
/// "real" base class is checked as appropriate when checking the access of
/// the member name.
ExprResult PerformObjectMemberConversion(Expr *From,
- NestedNameSpecifier *Qualifier,
+ NestedNameSpecifier Qualifier,
NamedDecl *FoundDecl,
NamedDecl *Member);
@@ -10185,7 +10185,7 @@ class Sema final : public SemaBase {
ExprResult InitializeExplicitObjectArgument(Sema &S, Expr *Obj,
FunctionDecl *Fun);
ExprResult PerformImplicitObjectArgumentInitialization(
- Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl,
+ Expr *From, NestedNameSpecifier Qualifier, NamedDecl *FoundDecl,
CXXMethodDecl *Method);
/// PerformContextuallyConvertToBool - Perform a contextual conversion
@@ -11592,13 +11592,16 @@ class Sema final : public SemaBase {
void NoteAllFoundTemplates(TemplateName Name);
- QualType CheckTemplateIdType(TemplateName Template,
+ QualType CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
+ TemplateName Template,
SourceLocation TemplateLoc,
TemplateArgumentListInfo &TemplateArgs);
TypeResult
- ActOnTemplateIdType(Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
- TemplateTy Template, const IdentifierInfo *TemplateII,
+ ActOnTemplateIdType(Scope *S, ElaboratedTypeKeyword ElaboratedKeyword,
+ SourceLocation ElaboratedKeywordLoc, CXXScopeSpec &SS,
+ SourceLocation TemplateKWLoc, TemplateTy Template,
+ const IdentifierInfo *TemplateII,
SourceLocation TemplateIILoc, SourceLocation LAngleLoc,
ASTTemplateArgsPtr TemplateArgs, SourceLocation RAngleLoc,
bool IsCtorOrDtorName = false, bool IsClassName = false,
@@ -11827,8 +11830,8 @@ class Sema final : public SemaBase {
/// argument, substitute into that default template argument and
/// return the corresponding template argument.
TemplateArgumentLoc SubstDefaultTemplateArgumentIfAvailable(
- TemplateDecl *Template, SourceLocation TemplateLoc,
- SourceLocation RAngleLoc, Decl *Param,
+ TemplateDecl *Template, SourceLocation TemplateKWLoc,
+ SourceLocation TemplateNameLoc, SourceLocation RAngleLoc, Decl *Param,
ArrayRef<TemplateArgument> SugaredConverted,
ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg);
@@ -13738,8 +13741,9 @@ class Sema final : public SemaBase {
SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
const MultiLevelTemplateArgumentList &TemplateArgs);
TemplateName
- SubstTemplateName(NestedNameSpecifierLoc QualifierLoc, TemplateName Name,
- SourceLocation Loc,
+ SubstTemplateName(SourceLocation TemplateKWLoc,
+ NestedNameSpecifierLoc &QualifierLoc, TemplateName Name,
+ SourceLocation NameLoc,
const MultiLevelTemplateArgumentList &TemplateArgs);
bool SubstTypeConstraint(TemplateTypeParmDecl *Inst, const TypeConstraint *TC,
@@ -15155,14 +15159,6 @@ class Sema final : public SemaBase {
return RequireCompleteExprType(E, CompleteTypeKind::Default, Diagnoser);
}
- /// Retrieve a version of the type 'T' that is elaborated by Keyword,
- /// qualified by the nested-name-specifier contained in SS, and that is
- /// (re)declared by OwnedTagDecl, which is nullptr if this is not a
- /// (re)declaration.
- QualType getElaboratedType(ElaboratedTypeKeyword Keyword,
- const CXXScopeSpec &SS, QualType T,
- TagDecl *OwnedTagDecl = nullptr);
-
// Returns the underlying type of a decltype with the given expression.
QualType getDecltypeForExpr(Expr *E);
diff --git a/clang/include/clang/Sema/SemaInternal.h b/clang/include/clang/Sema/SemaInternal.h
index 4d0da1102bb59..c6287f4c76a11 100644
--- a/clang/include/clang/Sema/SemaInternal.h
+++ b/clang/include/clang/Sema/SemaInternal.h
@@ -208,7 +208,7 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer {
class NamespaceSpecifierSet {
struct SpecifierInfo {
DeclContext* DeclCtx;
- NestedNameSpecifier* NameSpecifier;
+ NestedNameSpecifier NameSpecifier;
unsigned EditDistance;
};
@@ -228,9 +228,9 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer {
static DeclContextList buildContextChain(DeclContext *Start);
unsigned buildNestedNameSpecifier(DeclContextList &DeclChain,
- NestedNameSpecifier *&NNS);
+ NestedNameSpecifier &NNS);
- public:
+ public:
NamespaceSpecifierSet(ASTContext &Context, DeclContext *CurContext,
CXXScopeSpec *CurScopeSpec);
@@ -275,7 +275,7 @@ class TypoCorrectionConsumer : public VisibleDeclConsumer {
};
void addName(StringRef Name, NamedDecl *ND,
- NestedNameSpecifier *NNS = nullptr, bool isKeyword = false);
+ NestedNameSpecifier NNS = std::nullopt, bool isKeyword = false);
/// Find any visible decls for the given typo correction candidate.
/// If none are found, it to the set of candidates for which qualified lookups
diff --git a/clang/include/clang/Sema/TypoCorrection.h b/clang/include/clang/Sema/TypoCorrection.h
index 09de164297e7b..1d780c45efd55 100644
--- a/clang/include/clang/Sema/TypoCorrection.h
+++ b/clang/include/clang/Sema/TypoCorrection.h
@@ -57,15 +57,15 @@ class TypoCorrection {
static const unsigned CallbackDistanceWeight = 150U;
TypoCorrection(const DeclarationName &Name, NamedDecl *NameDecl,
- NestedNameSpecifier *NNS = nullptr, unsigned CharDistance = 0,
- unsigned QualifierDistance = 0)
+ NestedNameSpecifier NNS = std::nullopt,
+ unsigned CharDistance = 0, unsigned QualifierDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
CharDistance(CharDistance), QualifierDistance(QualifierDistance) {
if (NameDecl)
CorrectionDecls.push_back(NameDecl);
}
- TypoCorrection(NamedDecl *Name, NestedNameSpecifier *NNS = nullptr,
+ TypoCorrection(NamedDecl *Name, NestedNameSpecifier NNS = std::nullopt,
unsigned CharDistance = 0)
: CorrectionName(Name->getDeclName()), CorrectionNameSpec(NNS),
CharDistance(CharDistance) {
@@ -73,7 +73,7 @@ class TypoCorrection {
CorrectionDecls.push_back(Name);
}
- TypoCorrection(DeclarationName Name, NestedNameSpecifier *NNS = nullptr,
+ TypoCorrection(DeclarationName Name, NestedNameSpecifier NNS = std::nullopt,
unsigned CharDistance = 0)
: CorrectionName(Name), CorrectionNameSpec(NNS),
CharDistance(CharDistance) {}
@@ -88,13 +88,13 @@ class TypoCorrection {
}
/// Gets the NestedNameSpecifier needed to use the typo correction
- NestedNameSpecifier *getCorrectionSpecifier() const {
+ NestedNameSpecifier getCorrectionSpecifier() const {
return CorrectionNameSpec;
}
- void setCorrectionSpecifier(NestedNameSpecifier *NNS) {
+ void setCorrectionSpecifier(NestedNameSpecifier NNS) {
CorrectionNameSpec = NNS;
- ForceSpecifierReplacement = (NNS != nullptr);
+ ForceSpecifierReplacement = !!NNS;
}
void WillReplaceSpecifier(bool ForceReplacement) {
@@ -264,7 +264,7 @@ class TypoCorrection {
// Results.
DeclarationName CorrectionName;
- NestedNameSpecifier *CorrectionNameSpec = nullptr;
+ NestedNameSpecifier CorrectionNameSpec = std::nullopt;
SmallVector<NamedDecl *, 1> CorrectionDecls;
unsigned CharDistance = 0;
unsigned QualifierDistance = 0;
@@ -282,8 +282,9 @@ class CorrectionCandidateCallback {
public:
static const unsigned InvalidDistance = TypoCorrection::InvalidDistance;
- explicit CorrectionCandidateCallback(const IdentifierInfo *Typo = nullptr,
- NestedNameSpecifier *TypoNNS = nullptr)
+ explicit CorrectionCandidateCallback(
+ const IdentifierInfo *Typo = nullptr,
+ NestedNameSpecifier TypoNNS = std::nullopt)
: Typo(Typo), TypoNNS(TypoNNS) {}
virtual ~CorrectionCandidateCallback() = default;
@@ -320,7 +321,7 @@ class CorrectionCandidateCallback {
virtual std::unique_ptr<CorrectionCandidateCallback> clone() = 0;
void setTypoName(const IdentifierInfo *II) { Typo = II; }
- void setTypoNNS(NestedNameSpecifier *NNS) { TypoNNS = NNS; }
+ void setTypoNNS(NestedNameSpecifier NNS) { TypoNNS = NNS; }
// Flags for context-dependent keywords. WantFunctionLikeCasts is only
// used/meaningful when WantCXXNamedCasts is false.
@@ -346,13 +347,13 @@ class CorrectionCandidateCallback {
}
const IdentifierInfo *Typo;
- NestedNameSpecifier *TypoNNS;
+ NestedNameSpecifier TypoNNS;
};
class DefaultFilterCCC final : public CorrectionCandidateCallback {
public:
explicit DefaultFilterCCC(const IdentifierInfo *Typo = nullptr,
- NestedNameSpecifier *TypoNNS = nullptr)
+ NestedNameSpecifier TypoNNS = std::nullopt)
: CorrectionCandidateCallback(Typo, TypoNNS) {}
std::unique_ptr<CorrectionCandidateCallback> clone() override {
@@ -366,7 +367,7 @@ template <class C>
class DeclFilterCCC final : public CorrectionCandidateCallback {
public:
explicit DeclFilterCCC(const IdentifierInfo *Typo = nullptr,
- NestedNameSpecifier *TypoNNS = nullptr)
+ NestedNameSpecifier TypoNNS = std::nullopt)
: CorrectionCandidateCallback(Typo, TypoNNS) {}
bool ValidateCandidate(const TypoCorrection &candidate) override {
diff --git a/clang/include/clang/Serialization/ASTRecordReader.h b/clang/include/clang/Serialization/ASTRecordReader.h
index 1472497ff5e7e..aed1b7d309001 100644
--- a/clang/include/clang/Serialization/ASTRecordReader.h
+++ b/clang/include/clang/Serialization/ASTRecordReader.h
@@ -223,7 +223,7 @@ class ASTRecordReader
void readQualifierInfo(QualifierInfo &Info);
/// Return a nested name specifier, advancing Idx.
- // NestedNameSpecifier *readNestedNameSpecifier(); (inherited)
+ // NestedNameSpecifier readNestedNameSpecifier(); (inherited)
NestedNameSpecifierLoc readNestedNameSpecifierLoc();
diff --git a/clang/include/clang/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h
index ee005ec287708..9849ea6b395ab 100644
--- a/clang/include/clang/Serialization/ASTRecordWriter.h
+++ b/clang/include/clang/Serialization/ASTRecordWriter.h
@@ -247,8 +247,7 @@ class ASTRecordWriter
void AddTypeLoc(TypeLoc TL);
/// Emits a template argument location info.
- void AddTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind,
- const TemplateArgumentLocInfo &Arg);
+ void AddTemplateArgumentLocInfo(const TemplateArgumentLoc &Arg);
/// Emits a template argument location.
void AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg);
@@ -280,7 +279,7 @@ class ASTRecordWriter
void AddQualifierInfo(const QualifierInfo &Info);
/// Emit a nested name specifier.
- void AddNestedNameSpecifier(NestedNameSpecifier *NNS) {
+ void AddNestedNameSpecifier(NestedNameSpecifier NNS) {
writeNestedNameSpecifier(NNS);
}
diff --git a/clang/include/clang/Serialization/TypeBitCodes.def b/clang/include/clang/Serialization/TypeBitCodes.def
index b8cde2e370960..8abdf5e842541 100644
--- a/clang/include/clang/Serialization/TypeBitCodes.def
+++ b/clang/include/clang/Serialization/TypeBitCodes.def
@@ -32,7 +32,6 @@ TYPE_BIT_CODE(Enum, ENUM, 20)
TYPE_BIT_CODE(ObjCInterface, OBJC_INTERFACE, 21)
TYPE_BIT_CODE(ObjCObjectPointer, OBJC_OBJECT_POINTER, 22)
TYPE_BIT_CODE(Decltype, DECLTYPE, 23)
-TYPE_BIT_CODE(Elaborated, ELABORATED, 24)
TYPE_BIT_CODE(SubstTemplateTypeParm, SUBST_TEMPLATE_TYPE_PARM, 25)
TYPE_BIT_CODE(UnresolvedUsing, UNRESOLVED_USING, 26)
TYPE_BIT_CODE(InjectedClassName, INJECTED_CLASS_NAME, 27)
diff --git a/clang/include/clang/Tooling/Refactoring/Lookup.h b/clang/include/clang/Tooling/Refactoring/Lookup.h
index dcb40b7eee66c..fe0df8656bce1 100644
--- a/clang/include/clang/Tooling/Refactoring/Lookup.h
+++ b/clang/include/clang/Tooling/Refactoring/Lookup.h
@@ -38,8 +38,7 @@ namespace tooling {
/// \param ReplacementString The replacement nested name. Must be fully
/// qualified including a leading "::".
/// \returns The new name to be inserted in place of the current nested name.
-std::string replaceNestedName(const NestedNameSpecifier *Use,
- SourceLocation UseLoc,
+std::string replaceNestedName(NestedNameSpecifier Use, SourceLocation UseLoc,
const DeclContext *UseContext,
const NamedDecl *FromDecl,
StringRef ReplacementString);
diff --git a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
index 015dbba26f688..319569fd5ab33 100644
--- a/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
+++ b/clang/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -108,18 +108,21 @@ class RecursiveSymbolVisitor
bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
const SourceLocation TypeEndLoc =
Lexer::getLocForEndOfToken(TL.getBeginLoc(), 0, SM, LangOpts);
- return visit(TL.getTypedefNameDecl(), TL.getBeginLoc(), TypeEndLoc);
+ return visit(TL.getDecl(), TL.getBeginLoc(), TypeEndLoc);
}
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) {
// The base visitor will visit NNSL prefixes, so we should only look at
// the current NNS.
- if (NNS) {
- const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
- if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
+ if (NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
+ Qualifier.getKind() == NestedNameSpecifier::Kind::Namespace) {
+ const auto *ND = dyn_cast<NamespaceDecl>(
+ Qualifier.getAsNamespaceAndPrefix().Namespace);
+ if (!visit(ND, QualifierLoc.getLocalBeginLoc(),
+ QualifierLoc.getLocalEndLoc()))
return false;
}
- return BaseType::TraverseNestedNameSpecifierLoc(NNS);
+ return BaseType::TraverseNestedNameSpecifierLoc(QualifierLoc);
}
bool VisitDesignatedInitExpr(const DesignatedInitExpr *E) {
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index 6d0ba0b7907a1..d43d1aec71b29 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -122,15 +122,15 @@ class MatchChildASTVisitor
else if (const Stmt *S = DynNode.get<Stmt>())
traverse(*S);
else if (const NestedNameSpecifier *NNS =
- DynNode.get<NestedNameSpecifier>())
+ DynNode.get<NestedNameSpecifier>())
traverse(*NNS);
else if (const NestedNameSpecifierLoc *NNSLoc =
DynNode.get<NestedNameSpecifierLoc>())
traverse(*NNSLoc);
else if (const QualType *Q = DynNode.get<QualType>())
- traverse(*Q);
+ traverse(*Q, /*TraverseQualifier=*/true);
else if (const TypeLoc *T = DynNode.get<TypeLoc>())
- traverse(*T);
+ traverse(*T, /*TraverseQualifier=*/true);
else if (const auto *C = DynNode.get<CXXCtorInitializer>())
traverse(*C);
else if (const TemplateArgumentLoc *TALoc =
@@ -194,7 +194,7 @@ class MatchChildASTVisitor
}
// We assume that the QualType and the contained type are on the same
// hierarchy level. Thus, we try to match either of them.
- bool TraverseType(QualType TypeNode) {
+ bool TraverseType(QualType TypeNode, bool TraverseQualifier = true) {
if (TypeNode.isNull())
return true;
ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -202,11 +202,11 @@ class MatchChildASTVisitor
if (!match(*TypeNode))
return false;
// The QualType is matched inside traverse.
- return traverse(TypeNode);
+ return traverse(TypeNode, TraverseQualifier);
}
// We assume that the TypeLoc, contained QualType and contained Type all are
// on the same hierarchy level. Thus, we try to match all of them.
- bool TraverseTypeLoc(TypeLoc TypeLocNode) {
+ bool TraverseTypeLoc(TypeLoc TypeLocNode, bool TraverseQualifier = true) {
if (TypeLocNode.isNull())
return true;
ScopedIncrement ScopedDepth(&CurrentDepth);
@@ -217,17 +217,17 @@ class MatchChildASTVisitor
if (!match(TypeLocNode.getType()))
return false;
// The TypeLoc is matched inside traverse.
- return traverse(TypeLocNode);
+ return traverse(TypeLocNode, TraverseQualifier);
}
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier NNS) {
ScopedIncrement ScopedDepth(&CurrentDepth);
- return (NNS == nullptr) || traverse(*NNS);
+ return !NNS || traverse(NNS);
}
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
if (!NNS)
return true;
ScopedIncrement ScopedDepth(&CurrentDepth);
- if (!match(*NNS.getNestedNameSpecifier()))
+ if (!match(NNS.getNestedNameSpecifier()))
return false;
return traverse(NNS);
}
@@ -340,15 +340,14 @@ class MatchChildASTVisitor
bool baseTraverse(const Stmt &StmtNode) {
return VisitorBase::TraverseStmt(const_cast<Stmt*>(&StmtNode));
}
- bool baseTraverse(QualType TypeNode) {
- return VisitorBase::TraverseType(TypeNode);
+ bool baseTraverse(QualType TypeNode, bool TraverseQualifier) {
+ return VisitorBase::TraverseType(TypeNode, TraverseQualifier);
}
- bool baseTraverse(TypeLoc TypeLocNode) {
- return VisitorBase::TraverseTypeLoc(TypeLocNode);
+ bool baseTraverse(TypeLoc TypeLocNode, bool TraverseQualifier) {
+ return VisitorBase::TraverseTypeLoc(TypeLocNode, TraverseQualifier);
}
- bool baseTraverse(const NestedNameSpecifier &NNS) {
- return VisitorBase::TraverseNestedNameSpecifier(
- const_cast<NestedNameSpecifier*>(&NNS));
+ bool baseTraverse(NestedNameSpecifier NNS) {
+ return VisitorBase::TraverseNestedNameSpecifier(NNS);
}
bool baseTraverse(NestedNameSpecifierLoc NNS) {
return VisitorBase::TraverseNestedNameSpecifierLoc(NNS);
@@ -396,13 +395,13 @@ class MatchChildASTVisitor
// Traverses the subtree rooted at 'Node'; returns true if the
// traversal should continue after this function returns.
- template <typename T>
- bool traverse(const T &Node) {
+ template <typename T, class... Args>
+ bool traverse(const T &Node, Args &&...args) {
static_assert(IsBaseType<T>::value,
"traverse can only be instantiated with base type");
if (!match(Node))
return false;
- return baseTraverse(Node);
+ return baseTraverse(Node, std::forward<Args>(args)...);
}
const DynTypedMatcher *const Matcher;
@@ -501,9 +500,9 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
bool TraverseDecl(Decl *DeclNode);
bool TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue = nullptr);
- bool TraverseType(QualType TypeNode);
- bool TraverseTypeLoc(TypeLoc TypeNode);
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *NNS);
+ bool TraverseType(QualType TypeNode, bool TraverseQualifier = true);
+ bool TraverseTypeLoc(TypeLoc TypeNode, bool TraverseQualifier = true);
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier NNS);
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
bool TraverseConstructorInitializer(CXXCtorInitializer *CtorInit);
bool TraverseTemplateArgumentLoc(TemplateArgumentLoc TAL);
@@ -577,13 +576,13 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
const auto *T = Proto.getTypePtr();
for (const auto &E : T->exceptions())
- TraverseType(E);
+ TraverseType(E, /*TraverseQualifier=*/true);
if (Expr *NE = T->getNoexceptExpr())
TraverseStmt(NE, Queue);
if (LE->hasExplicitResultType())
- TraverseTypeLoc(Proto.getReturnLoc());
+ TraverseTypeLoc(Proto.getReturnLoc(), /*TraverseQualifier=*/true);
TraverseStmt(
const_cast<Expr *>(LE->getTrailingRequiresClause().ConstraintExpr));
}
@@ -1289,33 +1288,42 @@ class MatchASTVisitor : public RecursiveASTVisitor<MatchASTVisitor>,
if (Aliases == TypeAliases.end())
return false;
- if (const auto *ElaboratedTypeNode =
- llvm::dyn_cast<ElaboratedType>(TypeNode)) {
- if (ElaboratedTypeNode->isSugared() && Aliases->second.size() > 1) {
- const auto &DesugaredTypeName =
- ElaboratedTypeNode->desugar().getAsString();
+ auto matches = [&](const TypedefNameDecl *Alias) {
+ BoundNodesTreeBuilder Result(*Builder);
+ if (Matcher.matches(*Alias, this, &Result)) {
+ *Builder = std::move(Result);
+ return true;
+ }
+ return false;
+ };
- for (const TypedefNameDecl *Alias : Aliases->second) {
- if (Alias->getName() != DesugaredTypeName) {
- continue;
- }
+ if (const auto *T = TypeNode->getAs<TypedefType>()) {
+ const auto *TD = T->getDecl()->getCanonicalDecl();
- BoundNodesTreeBuilder Result(*Builder);
- if (Matcher.matches(*Alias, this, &Result)) {
- *Builder = std::move(Result);
- return true;
- }
+ // Prioritize exact matches.
+ SmallVector<const TypedefNameDecl *, 8> NonExactMatches;
+ for (const TypedefNameDecl *Alias : Aliases->second) {
+ if (!declaresSameEntity(TD, Alias)) {
+ NonExactMatches.push_back(Alias);
+ continue;
}
+ if (matches(Alias))
+ return true;
}
- }
- for (const TypedefNameDecl *Alias : Aliases->second) {
- BoundNodesTreeBuilder Result(*Builder);
- if (Matcher.matches(*Alias, this, &Result)) {
- *Builder = std::move(Result);
- return true;
+ for (const TypedefNameDecl *Alias : NonExactMatches) {
+ BoundNodesTreeBuilder Result(*Builder);
+ if (Matcher.matches(*Alias, this, &Result)) {
+ *Builder = std::move(Result);
+ return true;
+ }
}
+ return false;
}
+
+ for (const TypedefNameDecl *Alias : Aliases->second)
+ if (matches(Alias))
+ return true;
return false;
}
@@ -1506,12 +1514,14 @@ bool MatchASTVisitor::TraverseStmt(Stmt *StmtNode, DataRecursionQueue *Queue) {
return RecursiveASTVisitor<MatchASTVisitor>::TraverseStmt(StmtNode, Queue);
}
-bool MatchASTVisitor::TraverseType(QualType TypeNode) {
+bool MatchASTVisitor::TraverseType(QualType TypeNode, bool TraverseQualifier) {
match(TypeNode);
- return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode);
+ return RecursiveASTVisitor<MatchASTVisitor>::TraverseType(TypeNode,
+ TraverseQualifier);
}
-bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
+bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode,
+ bool TraverseQualifier) {
// The RecursiveASTVisitor only visits types if they're not within TypeLocs.
// We still want to find those types via matchers, so we match them here. Note
// that the TypeLocs are structurally a shadow-hierarchy to the expressed
@@ -1519,11 +1529,12 @@ bool MatchASTVisitor::TraverseTypeLoc(TypeLoc TypeLocNode) {
// each TypeLoc.
match(TypeLocNode);
match(TypeLocNode.getType());
- return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(TypeLocNode);
+ return RecursiveASTVisitor<MatchASTVisitor>::TraverseTypeLoc(
+ TypeLocNode, TraverseQualifier);
}
-bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier *NNS) {
- match(*NNS);
+bool MatchASTVisitor::TraverseNestedNameSpecifier(NestedNameSpecifier NNS) {
+ match(NNS);
return RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifier(NNS);
}
@@ -1537,7 +1548,7 @@ bool MatchASTVisitor::TraverseNestedNameSpecifierLoc(
// We only match the nested name specifier here (as opposed to traversing it)
// because the traversal is already done in the parallel "Loc"-hierarchy.
if (NNS.hasQualifier())
- match(*NNS.getNestedNameSpecifier());
+ match(NNS.getNestedNameSpecifier());
return
RecursiveASTVisitor<MatchASTVisitor>::TraverseNestedNameSpecifierLoc(NNS);
}
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 9cc50a656d37f..cb6397d5ed8eb 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -754,6 +754,8 @@ const internal::VariadicDynCastAllOfMatcher<Decl, TypedefDecl> typedefDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, TypedefNameDecl>
typedefNameDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasDecl> typeAliasDecl;
+const internal::VariadicDynCastAllOfMatcher<Decl, UsingShadowDecl>
+ usingShadowDecl;
const internal::VariadicDynCastAllOfMatcher<Decl, TypeAliasTemplateDecl>
typeAliasTemplateDecl;
const internal::VariadicAllOfMatcher<Decl> decl;
@@ -807,8 +809,6 @@ const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
const internal::VariadicDynCastAllOfMatcher<TypeLoc,
TemplateSpecializationTypeLoc>
templateSpecializationTypeLoc;
-const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
- elaboratedTypeLoc;
const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
unaryExprOrTypeTraitExpr;
@@ -1099,7 +1099,6 @@ const AstTypeMatcher<TemplateSpecializationType> templateSpecializationType;
const AstTypeMatcher<UnaryTransformType> unaryTransformType;
const AstTypeMatcher<RecordType> recordType;
const AstTypeMatcher<TagType> tagType;
-const AstTypeMatcher<ElaboratedType> elaboratedType;
const AstTypeMatcher<UsingType> usingType;
const AstTypeMatcher<SubstTemplateTypeParmType> substTemplateTypeParmType;
const AstTypeMatcher<TemplateTypeParmType> templateTypeParmType;
diff --git a/clang/lib/ASTMatchers/Dynamic/Registry.cpp b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
index 562df715e08ae..7f6a6aaed1734 100644
--- a/clang/lib/ASTMatchers/Dynamic/Registry.cpp
+++ b/clang/lib/ASTMatchers/Dynamic/Registry.cpp
@@ -235,8 +235,6 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(designatorCountIs);
REGISTER_MATCHER(doStmt);
REGISTER_MATCHER(eachOf);
- REGISTER_MATCHER(elaboratedType);
- REGISTER_MATCHER(elaboratedTypeLoc);
REGISTER_MATCHER(usingType);
REGISTER_MATCHER(enumConstantDecl);
REGISTER_MATCHER(enumDecl);
@@ -341,7 +339,6 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(hasMemberName);
REGISTER_MATCHER(hasMethod);
REGISTER_MATCHER(hasName);
- REGISTER_MATCHER(hasNamedTypeLoc);
REGISTER_MATCHER(hasNullSelector);
REGISTER_MATCHER(hasObjectExpression);
REGISTER_MATCHER(hasOperands);
@@ -503,7 +500,6 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(memberHasSameNameAsBoundNode);
REGISTER_MATCHER(memberPointerType);
REGISTER_MATCHER(namedDecl);
- REGISTER_MATCHER(namesType);
REGISTER_MATCHER(namespaceAliasDecl);
REGISTER_MATCHER(namespaceDecl);
REGISTER_MATCHER(nestedNameSpecifier);
@@ -593,6 +589,7 @@ RegistryMaps::RegistryMaps() {
REGISTER_MATCHER(typeLoc);
REGISTER_MATCHER(typedefDecl);
REGISTER_MATCHER(typedefNameDecl);
+ REGISTER_MATCHER(usingShadowDecl);
REGISTER_MATCHER(typedefType);
REGISTER_MATCHER(unaryExprOrTypeTraitExpr);
REGISTER_MATCHER(unaryOperator);
diff --git a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
index 256ea18284189..f14cb43e47dd4 100644
--- a/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
+++ b/clang/lib/Analysis/FlowSensitive/DataflowEnvironment.cpp
@@ -532,9 +532,11 @@ void Environment::initialize() {
} else if (auto *FieldBeingInitialized =
dyn_cast<FieldDecl>(Parent->getLambdaContextDecl())) {
// This is in a field initializer, rather than a method.
+ const RecordDecl *RD = FieldBeingInitialized->getParent();
+ const ASTContext &Ctx = RD->getASTContext();
+ CanQualType T = Ctx.getCanonicalTagType(RD);
setThisPointeeStorageLocation(
- cast<RecordStorageLocation>(createObject(QualType(
- FieldBeingInitialized->getParent()->getTypeForDecl(), 0))));
+ cast<RecordStorageLocation>(createObject(T)));
} else {
assert(false && "Unexpected this-capturing lambda context.");
}
diff --git a/clang/lib/Analysis/ThreadSafety.cpp b/clang/lib/Analysis/ThreadSafety.cpp
index 80e7c8eff671a..5037b75542925 100644
--- a/clang/lib/Analysis/ThreadSafety.cpp
+++ b/clang/lib/Analysis/ThreadSafety.cpp
@@ -1875,7 +1875,9 @@ void BuildLockset::handleCall(const Expr *Exp, const NamedDecl *D,
assert(inserted.second && "Are we visiting the same expression again?");
if (isa<CXXConstructExpr>(Exp))
Self = Placeholder;
- if (TagT->getDecl()->hasAttr<ScopedLockableAttr>())
+ if (TagT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<ScopedLockableAttr>())
Scp = CapabilityExpr(Placeholder, Exp->getType(), /*Neg=*/false);
}
diff --git a/clang/lib/Analysis/ThreadSafetyCommon.cpp b/clang/lib/Analysis/ThreadSafetyCommon.cpp
index ddbd0a9ca904b..f560dd8ae1dd1 100644
--- a/clang/lib/Analysis/ThreadSafetyCommon.cpp
+++ b/clang/lib/Analysis/ThreadSafetyCommon.cpp
@@ -84,8 +84,8 @@ static std::pair<StringRef, bool> classifyCapability(QualType QT) {
// which it is. The type should either be a record or a typedef, or a pointer
// or reference thereof.
if (const auto *RT = QT->getAs<RecordType>()) {
- if (const auto *RD = RT->getDecl())
- return classifyCapability(*RD);
+ if (const auto *RD = RT->getOriginalDecl())
+ return classifyCapability(*RD->getDefinitionOrSelf());
} else if (const auto *TT = QT->getAs<TypedefType>()) {
if (const auto *TD = TT->getDecl())
return classifyCapability(*TD);
diff --git a/clang/lib/Analysis/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index 6048169b56640..dc865cbc335b0 100644
--- a/clang/lib/Analysis/UnsafeBufferUsage.cpp
+++ b/clang/lib/Analysis/UnsafeBufferUsage.cpp
@@ -181,18 +181,22 @@ class MatchDescendantVisitor : public DynamicRecursiveASTVisitor {
return DynamicRecursiveASTVisitor::TraverseUnaryExprOrTypeTraitExpr(Node);
}
- bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override {
+ bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node,
+ bool TraverseQualifier) override {
// Unevaluated context.
if (ignoreUnevaluatedContext)
return true;
- return DynamicRecursiveASTVisitor::TraverseTypeOfExprTypeLoc(Node);
+ return DynamicRecursiveASTVisitor::TraverseTypeOfExprTypeLoc(
+ Node, TraverseQualifier);
}
- bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override {
+ bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node,
+ bool TraverseQualifier) override {
// Unevaluated context.
if (ignoreUnevaluatedContext)
return true;
- return DynamicRecursiveASTVisitor::TraverseDecltypeTypeLoc(Node);
+ return DynamicRecursiveASTVisitor::TraverseDecltypeTypeLoc(
+ Node, TraverseQualifier);
}
bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
diff --git a/clang/lib/CodeGen/ABIInfo.cpp b/clang/lib/CodeGen/ABIInfo.cpp
index d981d69913632..b5d5f46dc5b5d 100644
--- a/clang/lib/CodeGen/ABIInfo.cpp
+++ b/clang/lib/CodeGen/ABIInfo.cpp
@@ -68,7 +68,7 @@ bool ABIInfo::isHomogeneousAggregate(QualType Ty, const Type *&Base,
return false;
Members *= NElements;
} else if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return false;
diff --git a/clang/lib/CodeGen/ABIInfoImpl.cpp b/clang/lib/CodeGen/ABIInfoImpl.cpp
index 0a612d3461dc2..79dbe70a0c8eb 100644
--- a/clang/lib/CodeGen/ABIInfoImpl.cpp
+++ b/clang/lib/CodeGen/ABIInfoImpl.cpp
@@ -29,7 +29,7 @@ ABIArgInfo DefaultABIInfo::classifyArgumentType(QualType Ty) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
ASTContext &Context = getContext();
if (const auto *EIT = Ty->getAs<BitIntType>())
@@ -53,7 +53,7 @@ ABIArgInfo DefaultABIInfo::classifyReturnType(QualType RetTy) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (const auto *EIT = RetTy->getAs<BitIntType>())
if (EIT->getNumBits() >
@@ -105,13 +105,12 @@ llvm::Type *CodeGen::getVAListElementType(CodeGenFunction &CGF) {
CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(const RecordType *RT,
CGCXXABI &CXXABI) {
- const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- if (!RD) {
- if (!RT->getDecl()->canPassInRegisters())
- return CGCXXABI::RAA_Indirect;
- return CGCXXABI::RAA_Default;
- }
- return CXXABI.getRecordArgABI(RD);
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
+ return CXXABI.getRecordArgABI(CXXRD);
+ if (!RD->canPassInRegisters())
+ return CGCXXABI::RAA_Indirect;
+ return CGCXXABI::RAA_Default;
}
CGCXXABI::RecordArgABI CodeGen::getRecordArgABI(QualType T, CGCXXABI &CXXABI) {
@@ -125,20 +124,21 @@ bool CodeGen::classifyReturnType(const CGCXXABI &CXXABI, CGFunctionInfo &FI,
const ABIInfo &Info) {
QualType Ty = FI.getReturnType();
- if (const auto *RT = Ty->getAs<RecordType>())
- if (!isa<CXXRecordDecl>(RT->getDecl()) &&
- !RT->getDecl()->canPassInRegisters()) {
+ if (const auto *RT = Ty->getAs<RecordType>()) {
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ if (!isa<CXXRecordDecl>(RD) && !RD->canPassInRegisters()) {
FI.getReturnInfo() = Info.getNaturalAlignIndirect(
Ty, Info.getDataLayout().getAllocaAddrSpace());
return true;
}
+ }
return CXXABI.classifyReturnType(FI);
}
QualType CodeGen::useFirstFieldIfTransparentUnion(QualType Ty) {
if (const RecordType *UT = Ty->getAsUnionType()) {
- const RecordDecl *UD = UT->getDecl();
+ const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
if (UD->hasAttr<TransparentUnionAttr>()) {
assert(!UD->field_empty() && "sema created an empty transparent union");
return UD->field_begin()->getType();
@@ -276,7 +276,7 @@ bool CodeGen::isEmptyField(ASTContext &Context, const FieldDecl *FD,
// according to the Itanium ABI. The exception applies only to records,
// not arrays of records, so we must also check whether we stripped off an
// array type above.
- if (isa<CXXRecordDecl>(RT->getDecl()) &&
+ if (isa<CXXRecordDecl>(RT->getOriginalDecl()) &&
(WasArray || (!AsIfNoUniqueAddr && !FD->hasAttr<NoUniqueAddressAttr>())))
return false;
@@ -288,7 +288,7 @@ bool CodeGen::isEmptyRecord(ASTContext &Context, QualType T, bool AllowArrays,
const RecordType *RT = T->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return false;
@@ -320,7 +320,7 @@ bool CodeGen::isEmptyRecordForLayout(const ASTContext &Context, QualType T) {
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
@@ -344,7 +344,7 @@ const Type *CodeGen::isSingleElementStruct(QualType T, ASTContext &Context) {
if (!RT)
return nullptr;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return nullptr;
@@ -463,7 +463,7 @@ bool CodeGen::isRecordWithSIMDVectorType(ASTContext &Context, QualType Ty) {
const RecordType *RT = Ty->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
diff --git a/clang/lib/CodeGen/CGBlocks.cpp b/clang/lib/CodeGen/CGBlocks.cpp
index f3ddf7bf9a463..7f2f82bc5e62a 100644
--- a/clang/lib/CodeGen/CGBlocks.cpp
+++ b/clang/lib/CodeGen/CGBlocks.cpp
@@ -425,7 +425,8 @@ static bool isSafeForCXXConstantCapture(QualType type) {
// Only records can be unsafe.
if (!recordType) return true;
- const auto *record = cast<CXXRecordDecl>(recordType->getDecl());
+ const auto *record =
+ cast<CXXRecordDecl>(recordType->getOriginalDecl())->getDefinitionOrSelf();
// Maintain semantics for classes with non-trivial dtors or copy ctors.
if (!record->hasTrivialDestructor()) return false;
diff --git a/clang/lib/CodeGen/CGCUDANV.cpp b/clang/lib/CodeGen/CGCUDANV.cpp
index dd26be74e561b..c7f4bf8a21354 100644
--- a/clang/lib/CodeGen/CGCUDANV.cpp
+++ b/clang/lib/CodeGen/CGCUDANV.cpp
@@ -1131,7 +1131,8 @@ void CGNVCUDARuntime::handleVarRegistration(const VarDecl *D,
// Builtin surfaces and textures and their template arguments are
// also registered with CUDA runtime.
const auto *TD = cast<ClassTemplateSpecializationDecl>(
- D->getType()->castAs<RecordType>()->getDecl());
+ D->getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
const TemplateArgumentList &Args = TD->getTemplateArgs();
if (TD->hasAttr<CUDADeviceBuiltinSurfaceTypeAttr>()) {
assert(Args.size() == 2 &&
diff --git a/clang/lib/CodeGen/CGCXX.cpp b/clang/lib/CodeGen/CGCXX.cpp
index 78a7b021855b7..f9aff893eb0f0 100644
--- a/clang/lib/CodeGen/CGCXX.cpp
+++ b/clang/lib/CodeGen/CGCXX.cpp
@@ -83,8 +83,9 @@ bool CodeGenModule::TryEmitBaseDestructorAsAlias(const CXXDestructorDecl *D) {
if (I.isVirtual()) continue;
// Skip base classes with trivial destructors.
- const auto *Base =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ const auto *Base = cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (Base->hasTrivialDestructor()) continue;
// If we've already found a base class with a non-trivial
@@ -277,18 +278,18 @@ static CGCallee BuildAppleKextVirtualCall(CodeGenFunction &CGF,
/// BuildAppleKextVirtualCall - This routine is to support gcc's kext ABI making
/// indirect call to virtual functions. It makes the call through indexing
/// into the vtable.
-CGCallee
-CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
- NestedNameSpecifier *Qual,
- llvm::Type *Ty) {
- assert((Qual->getKind() == NestedNameSpecifier::TypeSpec) &&
+CGCallee CodeGenFunction::BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
+ NestedNameSpecifier Qual,
+ llvm::Type *Ty) {
+ assert(Qual.getKind() == NestedNameSpecifier::Kind::Type &&
"BuildAppleKextVirtualCall - bad Qual kind");
- const Type *QTy = Qual->getAsType();
+ const Type *QTy = Qual.getAsType();
QualType T = QualType(QTy, 0);
const RecordType *RT = T->getAs<RecordType>();
assert(RT && "BuildAppleKextVirtualCall - Qual type must be record");
- const auto *RD = cast<CXXRecordDecl>(RT->getDecl());
+ const auto *RD =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if (const auto *DD = dyn_cast<CXXDestructorDecl>(MD))
return BuildAppleKextVirtualDestructorCall(DD, Dtor_Complete, RD);
diff --git a/clang/lib/CodeGen/CGCXXABI.cpp b/clang/lib/CodeGen/CGCXXABI.cpp
index d42e0bb814a88..cca675838644e 100644
--- a/clang/lib/CodeGen/CGCXXABI.cpp
+++ b/clang/lib/CodeGen/CGCXXABI.cpp
@@ -52,7 +52,7 @@ CGCallee CGCXXABI::EmitLoadOfMemberFunctionPointer(
const auto *RD = MPT->getMostRecentCXXRecordDecl();
ThisPtrForCall =
- CGF.getAsNaturalPointerTo(This, CGF.getContext().getRecordType(RD));
+ CGF.getAsNaturalPointerTo(This, CGF.getContext().getCanonicalTagType(RD));
const FunctionProtoType *FPT =
MPT->getPointeeType()->getAs<FunctionProtoType>();
llvm::Constant *FnPtr = llvm::Constant::getNullValue(
@@ -106,7 +106,7 @@ CGCXXABI::EmitNullMemberPointer(const MemberPointerType *MPT) {
llvm::Constant *CGCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
return GetBogusMemberPointer(CGM.getContext().getMemberPointerType(
- MD->getType(), /*Qualifier=*/nullptr, MD->getParent()));
+ MD->getType(), /*Qualifier=*/std::nullopt, MD->getParent()));
}
llvm::Constant *CGCXXABI::EmitMemberDataPointer(const MemberPointerType *MPT,
diff --git a/clang/lib/CodeGen/CGCall.cpp b/clang/lib/CodeGen/CGCall.cpp
index c8c3d6b20c496..6cf67be5206a3 100644
--- a/clang/lib/CodeGen/CGCall.cpp
+++ b/clang/lib/CodeGen/CGCall.cpp
@@ -125,16 +125,16 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
/// calling a method pointer.
CanQualType CodeGenTypes::DeriveThisType(const CXXRecordDecl *RD,
const CXXMethodDecl *MD) {
- QualType RecTy;
+ CanQualType RecTy;
if (RD)
- RecTy = Context.getTagDeclType(RD)->getCanonicalTypeInternal();
+ RecTy = Context.getCanonicalTagType(RD);
else
RecTy = Context.VoidTy;
if (MD)
- RecTy = Context.getAddrSpaceQualType(
- RecTy, MD->getMethodQualifiers().getAddressSpace());
- return Context.getPointerType(CanQualType::CreateUnsafe(RecTy));
+ RecTy = CanQualType::CreateUnsafe(Context.getAddrSpaceQualType(
+ RecTy, MD->getMethodQualifiers().getAddressSpace()));
+ return Context.getPointerType(RecTy);
}
/// Returns the canonical formal type of the given C++ method.
@@ -1008,7 +1008,7 @@ getTypeExpansion(QualType Ty, const ASTContext &Context) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
SmallVector<const CXXBaseSpecifier *, 1> Bases;
SmallVector<const FieldDecl *, 1> Fields;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
assert(!RD->hasFlexibleArrayMember() &&
"Cannot expand structure with flexible array.");
if (RD->isUnion()) {
@@ -1895,7 +1895,7 @@ bool CodeGenModule::MayDropFunctionReturn(const ASTContext &Context,
// complex destructor or a non-trivially copyable type.
if (const RecordType *RT =
ReturnType.getCanonicalType()->getAs<RecordType>()) {
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
return ClassDecl->hasTrivialDestructor();
}
return ReturnType.isTriviallyCopyableType(Context);
@@ -3807,7 +3807,7 @@ static void setUsedBits(CodeGenModule &CGM, const RecordType *RTy, int Offset,
SmallVectorImpl<uint64_t> &Bits) {
ASTContext &Context = CGM.getContext();
int CharWidth = Context.getCharWidth();
- const RecordDecl *RD = RTy->getDecl()->getDefinition();
+ const RecordDecl *RD = RTy->getOriginalDecl()->getDefinition();
const ASTRecordLayout &ASTLayout = Context.getASTRecordLayout(RD);
const CGRecordLayout &Layout = CGM.getTypes().getCGRecordLayout(RD);
@@ -4268,7 +4268,10 @@ void CodeGenFunction::EmitDelegateCallArg(CallArgList &args,
// Deactivate the cleanup for the callee-destructed param that was pushed.
if (type->isRecordType() && !CurFuncIsThunk &&
- type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee() &&
+ type->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isParamDestroyedInCallee() &&
param->needsDestruction(getContext())) {
EHScopeStack::stable_iterator cleanup =
CalleeDestructedParamCleanups.lookup(cast<ParmVarDecl>(param));
@@ -4864,8 +4867,10 @@ void CodeGenFunction::EmitCallArg(CallArgList &args, const Expr *E,
// In the Microsoft C++ ABI, aggregate arguments are destructed by the callee.
// However, we still have to push an EH-only cleanup in case we unwind before
// we make it to the call.
- if (type->isRecordType() &&
- type->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
+ if (type->isRecordType() && type->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isParamDestroyedInCallee()) {
// If we're using inalloca, use the argument memory. Otherwise, use a
// temporary.
AggValueSlot Slot = args.isUsingInAlloca()
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 4a465e6526da0..e9a92ae0f01cb 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -181,7 +181,9 @@ CharUnits CodeGenModule::computeNonVirtualBaseClassOffset(
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
const auto *BaseDecl =
- cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ Base->getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Add the offset.
Offset += Layout.getBaseClassOffset(BaseDecl);
@@ -301,7 +303,8 @@ Address CodeGenFunction::GetAddressOfBaseClass(
// and hence will not require any further steps.
if ((*Start)->isVirtual()) {
VBase = cast<CXXRecordDecl>(
- (*Start)->getType()->castAs<RecordType>()->getDecl());
+ (*Start)->getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
++Start;
}
@@ -326,7 +329,7 @@ Address CodeGenFunction::GetAddressOfBaseClass(
llvm::Type *PtrTy = llvm::PointerType::get(
CGM.getLLVMContext(), Value.getType()->getPointerAddressSpace());
- QualType DerivedTy = getContext().getRecordType(Derived);
+ CanQualType DerivedTy = getContext().getCanonicalTagType(Derived);
CharUnits DerivedAlign = CGM.getClassPointerAlignment(Derived);
// If the static offset is zero and we don't have a virtual step,
@@ -401,8 +404,7 @@ CodeGenFunction::GetAddressOfDerivedClass(Address BaseAddr,
bool NullCheckValue) {
assert(PathBegin != PathEnd && "Base path should not be empty!");
- QualType DerivedTy =
- getContext().getCanonicalType(getContext().getTagDeclType(Derived));
+ CanQualType DerivedTy = getContext().getCanonicalTagType(Derived);
llvm::Type *DerivedValueTy = ConvertType(DerivedTy);
llvm::Value *NonVirtualOffset =
@@ -559,7 +561,8 @@ static void EmitBaseInitializer(CodeGenFunction &CGF,
const Type *BaseType = BaseInit->getBaseClass();
const auto *BaseClassDecl =
- cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
bool isBaseVirtual = BaseInit->isBaseVirtual();
@@ -638,7 +641,7 @@ static void EmitMemberInitializer(CodeGenFunction &CGF,
QualType FieldType = Field->getType();
llvm::Value *ThisPtr = CGF.LoadCXXThis();
- QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
+ CanQualType RecordTy = CGF.getContext().getCanonicalTagType(ClassDecl);
LValue LHS;
// If a base constructor is being emitted, create an LValue that has the
@@ -974,7 +977,7 @@ namespace {
}
CharUnits MemcpySize = getMemcpySize(FirstByteOffset);
- QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
+ CanQualType RecordTy = CGF.getContext().getCanonicalTagType(ClassDecl);
Address ThisPtr = CGF.LoadCXXThisAddress();
LValue DestLV = CGF.MakeAddrLValue(ThisPtr, RecordTy);
LValue Dest = CGF.EmitLValueForFieldInitialization(DestLV, FirstField);
@@ -1122,7 +1125,7 @@ namespace {
void pushEHDestructors() {
Address ThisPtr = CGF.LoadCXXThisAddress();
- QualType RecordTy = CGF.getContext().getTypeDeclType(ClassDecl);
+ CanQualType RecordTy = CGF.getContext().getCanonicalTagType(ClassDecl);
LValue LHS = CGF.MakeAddrLValue(ThisPtr, RecordTy);
for (unsigned i = 0; i < AggregatedInits.size(); ++i) {
@@ -1265,7 +1268,8 @@ namespace {
static bool isInitializerOfDynamicClass(const CXXCtorInitializer *BaseInit) {
const Type *BaseType = BaseInit->getBaseClass();
const auto *BaseClassDecl =
- cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(BaseType->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
return BaseClassDecl->isDynamicClass();
}
@@ -1374,7 +1378,9 @@ HasTrivialDestructorBody(ASTContext &Context,
continue;
const CXXRecordDecl *NonVirtualBase =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!HasTrivialDestructorBody(Context, NonVirtualBase,
MostDerivedClassDecl))
return false;
@@ -1383,8 +1389,10 @@ HasTrivialDestructorBody(ASTContext &Context,
if (BaseClassDecl == MostDerivedClassDecl) {
// Check virtual bases.
for (const auto &I : BaseClassDecl->vbases()) {
- const CXXRecordDecl *VirtualBase =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ const auto *VirtualBase =
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!HasTrivialDestructorBody(Context, VirtualBase,
MostDerivedClassDecl))
return false;
@@ -1404,7 +1412,8 @@ FieldHasTrivialDestructorBody(ASTContext &Context,
if (!RT)
return true;
- CXXRecordDecl *FieldClassDecl = cast<CXXRecordDecl>(RT->getDecl());
+ auto *FieldClassDecl =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
// The destructor for an implicit anonymous union member is never invoked.
if (FieldClassDecl->isUnion() && FieldClassDecl->isAnonymousStructOrUnion())
@@ -1588,7 +1597,7 @@ namespace {
const CXXRecordDecl *ClassDecl = Dtor->getParent();
CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
LoadThisForDtorDelete(CGF, Dtor),
- CGF.getContext().getTagDeclType(ClassDecl));
+ CGF.getContext().getCanonicalTagType(ClassDecl));
}
};
@@ -1606,7 +1615,7 @@ namespace {
const CXXRecordDecl *ClassDecl = Dtor->getParent();
CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
LoadThisForDtorDelete(CGF, Dtor),
- CGF.getContext().getTagDeclType(ClassDecl));
+ CGF.getContext().getCanonicalTagType(ClassDecl));
assert(Dtor->getOperatorDelete()->isDestroyingOperatorDelete() ==
ReturnAfterDelete &&
"unexpected value for ReturnAfterDelete");
@@ -1647,7 +1656,8 @@ namespace {
void Emit(CodeGenFunction &CGF, Flags flags) override {
// Find the address of the field.
Address thisValue = CGF.LoadCXXThisAddress();
- QualType RecordTy = CGF.getContext().getTagDeclType(field->getParent());
+ CanQualType RecordTy =
+ CGF.getContext().getCanonicalTagType(field->getParent());
LValue ThisLV = CGF.MakeAddrLValue(thisValue, RecordTy);
LValue LV = CGF.EmitLValueForField(ThisLV, field);
assert(LV.isSimple());
@@ -1870,7 +1880,7 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
const CXXRecordDecl *ClassDecl = DD->getParent();
EmitDeleteCall(DD->getOperatorDelete(),
LoadThisForDtorDelete(*this, DD),
- getContext().getTagDeclType(ClassDecl));
+ getContext().getCanonicalTagType(ClassDecl));
EmitBranchThroughCleanup(ReturnBlock);
} else {
EHStack.pushCleanup<CallDtorDelete>(NormalAndEHCleanup);
@@ -1898,7 +1908,9 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
// the reverse order.
for (const auto &Base : ClassDecl->vbases()) {
auto *BaseClassDecl =
- cast<CXXRecordDecl>(Base.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ Base.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (BaseClassDecl->hasTrivialDestructor()) {
// Under SanitizeMemoryUseAfterDtor, poison the trivial base class
@@ -1964,7 +1976,7 @@ void CodeGenFunction::EnterDtorCleanups(const CXXDestructorDecl *DD,
// Anonymous union members do not have their destructors called.
const RecordType *RT = type->getAsUnionType();
- if (RT && RT->getDecl()->isAnonymousStructOrUnion())
+ if (RT && RT->getOriginalDecl()->isAnonymousStructOrUnion())
continue;
CleanupKind cleanupKind = getCleanupKind(dtorKind);
@@ -2057,7 +2069,7 @@ void CodeGenFunction::EmitCXXAggrConstructorCall(const CXXConstructorDecl *ctor,
//
// Note that these are complete objects and so we don't need to
// use the non-virtual size or alignment.
- QualType type = getContext().getTypeDeclType(ctor->getParent());
+ CanQualType type = getContext().getCanonicalTagType(ctor->getParent());
CharUnits eltAlignment =
arrayBase.getAlignment()
.alignmentOfArrayElement(getContext().getTypeSizeInChars(type));
@@ -2119,7 +2131,8 @@ void CodeGenFunction::destroyCXXObject(CodeGenFunction &CGF,
Address addr,
QualType type) {
const RecordType *rtype = type->castAs<RecordType>();
- const CXXRecordDecl *record = cast<CXXRecordDecl>(rtype->getDecl());
+ const auto *record =
+ cast<CXXRecordDecl>(rtype->getOriginalDecl())->getDefinitionOrSelf();
const CXXDestructorDecl *dtor = record->getDestructor();
assert(!dtor->isTrivial());
CGF.EmitCXXDestructorCall(dtor, Dtor_Complete, /*for vbase*/ false,
@@ -2158,7 +2171,7 @@ void CodeGenFunction::EmitCXXConstructorCall(const CXXConstructorDecl *D,
const Expr *Arg = E->getArg(0);
LValue Src = EmitLValue(Arg);
- QualType DestTy = getContext().getTypeDeclType(D->getParent());
+ CanQualType DestTy = getContext().getCanonicalTagType(D->getParent());
LValue Dest = MakeAddrLValue(This, DestTy);
EmitAggregateCopyCtor(Dest, Src, ThisAVS.mayOverlap());
return;
@@ -2210,7 +2223,8 @@ void CodeGenFunction::EmitCXXConstructorCall(
if (!NewPointerIsChecked)
EmitTypeCheck(CodeGenFunction::TCK_ConstructorCall, Loc, This,
- getContext().getRecordType(ClassDecl), CharUnits::Zero());
+ getContext().getCanonicalTagType(ClassDecl),
+ CharUnits::Zero());
if (D->isTrivial() && D->isDefaultConstructor()) {
assert(Args.size() == 1 && "trivial default ctor with args");
@@ -2226,7 +2240,7 @@ void CodeGenFunction::EmitCXXConstructorCall(
Address Src = makeNaturalAddressForPointer(
Args[1].getRValue(*this).getScalarVal(), SrcTy);
LValue SrcLVal = MakeAddrLValue(Src, SrcTy);
- QualType DestTy = getContext().getTypeDeclType(ClassDecl);
+ CanQualType DestTy = getContext().getCanonicalTagType(ClassDecl);
LValue DestLVal = MakeAddrLValue(This, DestTy);
EmitAggregateCopyCtor(DestLVal, SrcLVal, Overlap);
return;
@@ -2638,8 +2652,9 @@ void CodeGenFunction::getVTablePointers(BaseSubobject Base,
// Traverse bases.
for (const auto &I : RD->bases()) {
- auto *BaseDecl =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ auto *BaseDecl = cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Ignore classes without a vtable.
if (!BaseDecl->isDynamicClass())
@@ -2772,7 +2787,7 @@ void CodeGenFunction::EmitTypeMetadataCodeForVCall(const CXXRecordDecl *RD,
// Don't insert type test assumes if we are forcing public
// visibility.
!CGM.AlwaysHasLTOVisibilityPublic(RD)) {
- QualType Ty = QualType(RD->getTypeForDecl(), 0);
+ CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(Ty);
llvm::Value *TypeId =
llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
@@ -2839,7 +2854,8 @@ void CodeGenFunction::EmitVTablePtrCheckForCast(QualType T, Address Derived,
if (!ClassTy)
return;
- const CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(ClassTy->getDecl());
+ const auto *ClassDecl =
+ cast<CXXRecordDecl>(ClassTy->getOriginalDecl())->getDefinitionOrSelf();
if (!ClassDecl->isCompleteDefinition() || !ClassDecl->isDynamicClass())
return;
@@ -2896,8 +2912,8 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
EmitSanitizerStatReport(SSK);
- llvm::Metadata *MD =
- CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
+ CanQualType T = CGM.getContext().getCanonicalTagType(RD);
+ llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(T);
llvm::Value *TypeId = llvm::MetadataAsValue::get(getLLVMContext(), MD);
llvm::Value *TypeTest = Builder.CreateCall(
@@ -2906,7 +2922,7 @@ void CodeGenFunction::EmitVTablePtrCheck(const CXXRecordDecl *RD,
llvm::Constant *StaticData[] = {
llvm::ConstantInt::get(Int8Ty, TCK),
EmitCheckSourceLocation(Loc),
- EmitCheckTypeDescriptor(QualType(RD->getTypeForDecl(), 0)),
+ EmitCheckTypeDescriptor(T),
};
auto CrossDsoTypeId = CGM.CreateCrossDsoCfiTypeId(MD);
@@ -2956,8 +2972,8 @@ llvm::Value *CodeGenFunction::EmitVTableTypeCheckedLoad(
EmitSanitizerStatReport(llvm::SanStat_CFI_VCall);
- llvm::Metadata *MD =
- CGM.CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
+ CanQualType T = CGM.getContext().getCanonicalTagType(RD);
+ llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(T);
llvm::Value *TypeId = llvm::MetadataAsValue::get(CGM.getLLVMContext(), MD);
auto CheckedLoadIntrinsic = CGM.getVTables().useRelativeLayout()
@@ -3039,7 +3055,8 @@ void CodeGenFunction::EmitLambdaBlockInvokeBody() {
// Start building arguments for forwarding call
CallArgList CallArgs;
- QualType ThisType = getContext().getPointerType(getContext().getRecordType(Lambda));
+ CanQualType ThisType =
+ getContext().getPointerType(getContext().getCanonicalTagType(Lambda));
Address ThisPtr = GetAddrOfBlockDecl(variable);
CallArgs.add(RValue::get(getAsNaturalPointerTo(ThisPtr, ThisType)), ThisType);
@@ -3066,8 +3083,8 @@ void CodeGenFunction::EmitLambdaStaticInvokeBody(const CXXMethodDecl *MD) {
// Start building arguments for forwarding call
CallArgList CallArgs;
- QualType LambdaType = getContext().getRecordType(Lambda);
- QualType ThisType = getContext().getPointerType(LambdaType);
+ CanQualType LambdaType = getContext().getCanonicalTagType(Lambda);
+ CanQualType ThisType = getContext().getPointerType(LambdaType);
Address ThisPtr = CreateMemTemp(LambdaType, "unused.capture");
CallArgs.add(RValue::get(ThisPtr.emitRawPointer(*this)), ThisType);
@@ -3118,8 +3135,8 @@ void CodeGenFunction::EmitLambdaInAllocaCallOpBody(const CXXMethodDecl *MD) {
// Forward %this argument.
CallArgList CallArgs;
- QualType LambdaType = getContext().getRecordType(MD->getParent());
- QualType ThisType = getContext().getPointerType(LambdaType);
+ CanQualType LambdaType = getContext().getCanonicalTagType(MD->getParent());
+ CanQualType ThisType = getContext().getPointerType(LambdaType);
llvm::Value *ThisArg = CurFn->getArg(0);
CallArgs.add(RValue::get(ThisArg), ThisType);
diff --git a/clang/lib/CodeGen/CGDebugInfo.cpp b/clang/lib/CodeGen/CGDebugInfo.cpp
index 8bf7d24d8551d..2df95d59cc8cf 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -369,7 +369,7 @@ llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context,
if (const auto *RDecl = dyn_cast<RecordDecl>(Context))
if (!RDecl->isDependentType())
- return getOrCreateType(CGM.getContext().getTypeDeclType(RDecl),
+ return getOrCreateType(CGM.getContext().getCanonicalTagType(RDecl),
TheCU->getFile());
return Default;
}
@@ -1294,7 +1294,7 @@ static bool needsTypeIdentifier(const TagDecl *TD, CodeGenModule &CGM,
static SmallString<256> getTypeIdentifier(const TagType *Ty, CodeGenModule &CGM,
llvm::DICompileUnit *TheCU) {
SmallString<256> Identifier;
- const TagDecl *TD = Ty->getDecl();
+ const TagDecl *TD = Ty->getOriginalDecl()->getDefinitionOrSelf();
if (!needsTypeIdentifier(TD, CGM, TheCU))
return Identifier;
@@ -1330,8 +1330,8 @@ static llvm::dwarf::Tag getTagForRecord(const RecordDecl *RD) {
llvm::DICompositeType *
CGDebugInfo::getOrCreateRecordFwdDecl(const RecordType *Ty,
llvm::DIScope *Ctx) {
- const RecordDecl *RD = Ty->getDecl();
- if (llvm::DIType *T = getTypeOrNull(CGM.getContext().getRecordType(RD)))
+ const RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
+ if (llvm::DIType *T = getTypeOrNull(QualType(Ty, 0)))
return cast<llvm::DICompositeType>(T);
llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
const unsigned Line =
@@ -2024,6 +2024,8 @@ void CGDebugInfo::CollectRecordNestedType(
const TypeDecl *TD, SmallVectorImpl<llvm::Metadata *> &elements) {
QualType Ty = CGM.getContext().getTypeDeclType(TD);
// Injected class names are not considered nested records.
+ // FIXME: Is this supposed to be testing for injected class name declarations
+ // instead?
if (isa<InjectedClassNameType>(Ty))
return;
SourceLocation Loc = TD->getLocation();
@@ -2365,7 +2367,9 @@ void CGDebugInfo::CollectCXXBasesAux(
const ASTRecordLayout &RL = CGM.getContext().getASTRecordLayout(RD);
for (const auto &BI : Bases) {
const auto *Base =
- cast<CXXRecordDecl>(BI.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ BI.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinition();
if (!SeenTypes.insert(Base).second)
continue;
auto *BaseTy = getOrCreateType(BI.getType(), Unit);
@@ -2831,12 +2835,12 @@ void CGDebugInfo::addHeapAllocSiteMetadata(llvm::CallBase *CI,
void CGDebugInfo::completeType(const EnumDecl *ED) {
if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
return;
- QualType Ty = CGM.getContext().getEnumType(ED);
+ CanQualType Ty = CGM.getContext().getCanonicalTagType(ED);
void *TyPtr = Ty.getAsOpaquePtr();
auto I = TypeCache.find(TyPtr);
if (I == TypeCache.end() || !cast<llvm::DIType>(I->second)->isForwardDecl())
return;
- llvm::DIType *Res = CreateTypeDefinition(Ty->castAs<EnumType>());
+ llvm::DIType *Res = CreateTypeDefinition(dyn_cast<EnumType>(Ty));
assert(!Res->isForwardDecl());
TypeCache[TyPtr].reset(Res);
}
@@ -2906,7 +2910,7 @@ void CGDebugInfo::completeClassData(const RecordDecl *RD) {
void CGDebugInfo::completeClass(const RecordDecl *RD) {
if (DebugKind <= llvm::codegenoptions::DebugLineTablesOnly)
return;
- QualType Ty = CGM.getContext().getRecordType(RD);
+ CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
void *TyPtr = Ty.getAsOpaquePtr();
auto I = TypeCache.find(TyPtr);
if (I != TypeCache.end() && !cast<llvm::DIType>(I->second)->isForwardDecl())
@@ -2915,7 +2919,7 @@ void CGDebugInfo::completeClass(const RecordDecl *RD) {
// We want the canonical definition of the structure to not
// be the typedef. Since that would lead to circular typedef
// metadata.
- auto [Res, PrefRes] = CreateTypeDefinition(Ty->castAs<RecordType>());
+ auto [Res, PrefRes] = CreateTypeDefinition(dyn_cast<RecordType>(Ty));
assert(!Res->isForwardDecl());
TypeCache[TyPtr].reset(Res);
}
@@ -3019,14 +3023,14 @@ void CGDebugInfo::completeRequiredType(const RecordDecl *RD) {
if (shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD, CGM.getLangOpts()))
return;
- QualType Ty = CGM.getContext().getRecordType(RD);
+ CanQualType Ty = CGM.getContext().getCanonicalTagType(RD);
llvm::DIType *T = getTypeOrNull(Ty);
if (T && T->isForwardDecl())
completeClassData(RD);
}
llvm::DIType *CGDebugInfo::CreateType(const RecordType *Ty) {
- RecordDecl *RD = Ty->getDecl();
+ RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
llvm::DIType *T = cast_or_null<llvm::DIType>(getTypeOrNull(QualType(Ty, 0)));
if (T || shouldOmitDefinition(DebugKind, DebugTypeExtRefs, RD,
CGM.getLangOpts())) {
@@ -3054,7 +3058,7 @@ llvm::DIType *CGDebugInfo::GetPreferredNameType(const CXXRecordDecl *RD,
std::pair<llvm::DIType *, llvm::DIType *>
CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
- RecordDecl *RD = Ty->getDecl();
+ RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
// Get overall information about the record type for the debug info.
llvm::DIFile *DefUnit = getOrCreateFile(RD->getLocation());
@@ -3076,7 +3080,7 @@ CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
// Push the struct on region stack.
LexicalBlockStack.emplace_back(&*FwdDecl);
- RegionMap[Ty->getDecl()].reset(FwdDecl);
+ RegionMap[RD].reset(FwdDecl);
// Convert all the elements.
SmallVector<llvm::Metadata *, 16> EltTys;
@@ -3098,7 +3102,7 @@ CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
CollectCXXMemberFunctions(CXXDecl, DefUnit, EltTys, FwdDecl);
LexicalBlockStack.pop_back();
- RegionMap.erase(Ty->getDecl());
+ RegionMap.erase(RD);
llvm::DINodeArray Elements = DBuilder.getOrCreateArray(EltTys);
DBuilder.replaceArrays(FwdDecl, Elements);
@@ -3107,7 +3111,7 @@ CGDebugInfo::CreateTypeDefinition(const RecordType *Ty) {
FwdDecl =
llvm::MDNode::replaceWithPermanent(llvm::TempDICompositeType(FwdDecl));
- RegionMap[Ty->getDecl()].reset(FwdDecl);
+ RegionMap[RD].reset(FwdDecl);
if (CGM.getCodeGenOpts().getDebuggerTuning() == llvm::DebuggerKind::LLDB)
if (auto *PrefDI = GetPreferredNameType(CXXDecl, DefUnit))
@@ -3654,8 +3658,9 @@ llvm::DIType *CGDebugInfo::CreateType(const MemberPointerType *Ty,
}
}
- llvm::DIType *ClassType = getOrCreateType(
- QualType(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0), U);
+ CanQualType T =
+ CGM.getContext().getCanonicalTagType(Ty->getMostRecentCXXRecordDecl());
+ llvm::DIType *ClassType = getOrCreateType(T, U);
if (Ty->isMemberDataPointerType())
return DBuilder.createMemberPointerType(
getOrCreateType(Ty->getPointeeType(), U), ClassType, Size, /*Align=*/0,
@@ -3690,17 +3695,21 @@ llvm::DIType *CGDebugInfo::CreateType(const HLSLInlineSpirvType *Ty,
return nullptr;
}
-llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
- const EnumDecl *ED = Ty->getDecl();
+static auto getEnumInfo(CodeGenModule &CGM, llvm::DICompileUnit *TheCU,
+ const EnumType *Ty) {
+ const EnumDecl *ED = Ty->getOriginalDecl()->getDefinitionOrSelf();
uint64_t Size = 0;
uint32_t Align = 0;
- if (!ED->getTypeForDecl()->isIncompleteType()) {
- Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
+ if (ED->isComplete()) {
+ Size = CGM.getContext().getTypeSize(QualType(Ty, 0));
Align = getDeclAlignIfRequired(ED, CGM.getContext());
}
+ return std::make_tuple(ED, Size, Align, getTypeIdentifier(Ty, CGM, TheCU));
+}
- SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
+llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
+ auto [ED, Size, Align, Identifier] = getEnumInfo(CGM, TheCU, Ty);
bool isImportedFromModule =
DebugTypeExtRefs && ED->isFromASTFile() && ED->getDefinition();
@@ -3735,15 +3744,7 @@ llvm::DIType *CGDebugInfo::CreateEnumType(const EnumType *Ty) {
}
llvm::DIType *CGDebugInfo::CreateTypeDefinition(const EnumType *Ty) {
- const EnumDecl *ED = Ty->getDecl();
- uint64_t Size = 0;
- uint32_t Align = 0;
- if (!ED->getTypeForDecl()->isIncompleteType()) {
- Size = CGM.getContext().getTypeSize(ED->getTypeForDecl());
- Align = getDeclAlignIfRequired(ED, CGM.getContext());
- }
-
- SmallString<256> Identifier = getTypeIdentifier(Ty, CGM, TheCU);
+ auto [ED, Size, Align, Identifier] = getEnumInfo(CGM, TheCU, Ty);
SmallVector<llvm::Metadata *, 16> Enumerators;
ED = ED->getDefinition();
@@ -3818,6 +3819,11 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
switch (T->getTypeClass()) {
default:
return C.getQualifiedType(T.getTypePtr(), Quals);
+ case Type::Enum:
+ case Type::Record:
+ case Type::InjectedClassName:
+ return C.getQualifiedType(T->getCanonicalTypeUnqualified().getTypePtr(),
+ Quals);
case Type::TemplateSpecialization: {
const auto *Spec = cast<TemplateSpecializationType>(T);
if (Spec->isTypeAlias())
@@ -3846,11 +3852,8 @@ static QualType UnwrapTypeForDebugInfo(QualType T, const ASTContext &C) {
case Type::CountAttributed:
T = cast<CountAttributedType>(T)->desugar();
break;
- case Type::Elaborated:
- T = cast<ElaboratedType>(T)->getNamedType();
- break;
case Type::Using:
- T = cast<UsingType>(T)->getUnderlyingType();
+ T = cast<UsingType>(T)->desugar();
break;
case Type::Paren:
T = cast<ParenType>(T)->getInnerType();
@@ -3909,7 +3912,8 @@ void CGDebugInfo::completeUnusedClass(const CXXRecordDecl &D) {
completeClassData(&D);
// In case this type has no member function definitions being emitted, ensure
// it is retained
- RetainedTypes.push_back(CGM.getContext().getRecordType(&D).getAsOpaquePtr());
+ RetainedTypes.push_back(
+ CGM.getContext().getCanonicalTagType(&D).getAsOpaquePtr());
}
llvm::DIType *CGDebugInfo::getOrCreateType(QualType Ty, llvm::DIFile *Unit) {
@@ -4053,7 +4057,6 @@ llvm::DIType *CGDebugInfo::CreateTypeNode(QualType Ty, llvm::DIFile *Unit) {
case Type::Adjusted:
case Type::Decayed:
case Type::DeducedTemplateSpecialization:
- case Type::Elaborated:
case Type::Using:
case Type::Paren:
case Type::MacroQualified:
@@ -4096,7 +4099,7 @@ CGDebugInfo::getOrCreateLimitedType(const RecordType *Ty) {
// TODO: Currently used for context chains when limiting debug info.
llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
- RecordDecl *RD = Ty->getDecl();
+ RecordDecl *RD = Ty->getOriginalDecl()->getDefinitionOrSelf();
// Get overall information about the record type for the debug info.
StringRef RDName = getClassName(RD);
@@ -4113,7 +4116,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
// If we ended up creating the type during the context chain construction,
// just return that.
auto *T = cast_or_null<llvm::DICompositeType>(
- getTypeOrNull(CGM.getContext().getRecordType(RD)));
+ getTypeOrNull(CGM.getContext().getCanonicalTagType(RD)));
if (T && (!T->isForwardDecl() || !RD->getDefinition()))
return T;
@@ -4183,7 +4186,7 @@ llvm::DICompositeType *CGDebugInfo::CreateLimitedType(const RecordType *Ty) {
break;
}
- RegionMap[Ty->getDecl()].reset(RealDecl);
+ RegionMap[RD].reset(RealDecl);
TypeCache[QualType(Ty, 0).getAsOpaquePtr()].reset(RealDecl);
if (const auto *TSpecial = dyn_cast<ClassTemplateSpecializationDecl>(RD))
@@ -4207,8 +4210,8 @@ void CGDebugInfo::CollectContainingType(const CXXRecordDecl *RD,
else
break;
}
- ContainingType = getOrCreateType(QualType(PBase->getTypeForDecl(), 0),
- getOrCreateFile(RD->getLocation()));
+ CanQualType T = CGM.getContext().getCanonicalTagType(PBase);
+ ContainingType = getOrCreateType(T, getOrCreateFile(RD->getLocation()));
} else if (RD->isDynamicClass())
ContainingType = RealDecl;
@@ -4414,9 +4417,10 @@ llvm::DINode *CGDebugInfo::getDeclarationOrDefinition(const Decl *D) {
// we would otherwise do to get a type for a pointee. (forward declarations in
// limited debug info, full definitions (if the type definition is available)
// in unlimited debug info)
- if (const auto *TD = dyn_cast<TypeDecl>(D))
- return getOrCreateType(CGM.getContext().getTypeDeclType(TD),
- getOrCreateFile(TD->getLocation()));
+ if (const auto *TD = dyn_cast<TypeDecl>(D)) {
+ QualType Ty = CGM.getContext().getTypeDeclType(TD);
+ return getOrCreateType(Ty, getOrCreateFile(TD->getLocation()));
+ }
auto I = DeclCache.find(D->getCanonicalDecl());
if (I != DeclCache.end()) {
@@ -5074,7 +5078,7 @@ llvm::DILocalVariable *CGDebugInfo::EmitDeclare(const VarDecl *VD,
} else if (const auto *RT = dyn_cast<RecordType>(VD->getType())) {
// If VD is an anonymous union then Storage represents value for
// all union fields.
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion() && RD->isAnonymousStructOrUnion()) {
// GDB has trouble finding local variables in anonymous unions, so we emit
// artificial local variables for each of the members.
@@ -5531,7 +5535,7 @@ void CGDebugInfo::EmitDeclareOfBlockLiteralArgVariable(const CGBlockInfo &block,
cast_or_null<CXXMethodDecl>(blockDecl->getNonClosureContext()))
type = Method->getThisType();
else if (auto *RDecl = dyn_cast<CXXRecordDecl>(blockDecl->getParent()))
- type = QualType(RDecl->getTypeForDecl(), 0);
+ type = CGM.getContext().getCanonicalTagType(RDecl);
else
llvm_unreachable("unexpected block declcontext");
@@ -5620,8 +5624,9 @@ llvm::DIGlobalVariableExpression *CGDebugInfo::CollectAnonRecordDecls(
// Ignore unnamed fields, but recurse into anonymous records.
if (FieldName.empty()) {
if (const auto *RT = dyn_cast<RecordType>(Field->getType()))
- GVE = CollectAnonRecordDecls(RT->getDecl(), Unit, LineNo, LinkageName,
- Var, DContext);
+ GVE =
+ CollectAnonRecordDecls(RT->getOriginalDecl()->getDefinitionOrSelf(),
+ Unit, LineNo, LinkageName, Var, DContext);
continue;
}
// Use VarDecl's Tag, Scope and Line number.
@@ -5640,7 +5645,7 @@ static bool ReferencesAnonymousEntity(RecordType *RT) {
// But so long as it's not one of those, it doesn't matter if some sub-type
// of the record (a template parameter) can't be reconstituted - because the
// un-reconstitutable type itself will carry its own name.
- const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
+ const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
if (!RD)
return false;
if (!RD->getIdentifier())
@@ -5699,15 +5704,15 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
}
return true;
}
- bool TraverseEnumType(EnumType *ET) {
+ bool TraverseEnumType(EnumType *ET, bool = false) {
// Unnamed enums can't be reconstituted due to a lack of column info we
// produce in the DWARF, so we can't get Clang's full name back.
- if (const auto *ED = dyn_cast<EnumDecl>(ET->getDecl())) {
+ if (const auto *ED = dyn_cast<EnumDecl>(ET->getOriginalDecl())) {
if (!ED->getIdentifier()) {
Reconstitutable = false;
return false;
}
- if (!ED->isExternallyVisible()) {
+ if (!ED->getDefinitionOrSelf()->isExternallyVisible()) {
Reconstitutable = false;
return false;
}
@@ -5720,7 +5725,7 @@ struct ReconstitutableType : public RecursiveASTVisitor<ReconstitutableType> {
Reconstitutable &= !FT->getNoReturnAttr();
return Reconstitutable;
}
- bool VisitRecordType(RecordType *RT) {
+ bool VisitRecordType(RecordType *RT, bool = false) {
if (ReferencesAnonymousEntity(RT)) {
Reconstitutable = false;
return false;
@@ -5903,7 +5908,8 @@ void CGDebugInfo::EmitGlobalVariable(llvm::GlobalVariable *Var,
// variable for each member of the anonymous union so that it's possible
// to find the name of any field in the union.
if (T->isUnionType() && DeclName.empty()) {
- const RecordDecl *RD = T->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ T->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
assert(RD->isAnonymousStructOrUnion() &&
"unnamed non-anonymous struct or union?");
GVE = CollectAnonRecordDecls(RD, Unit, LineNo, LinkageName, Var, DContext);
@@ -5950,8 +5956,6 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
if (const auto *ECD = dyn_cast<EnumConstantDecl>(VD)) {
const auto *ED = cast<EnumDecl>(ECD->getDeclContext());
- assert(isa<EnumType>(ED->getTypeForDecl()) && "Enum without EnumType?");
-
if (CGM.getCodeGenOpts().EmitCodeView) {
// If CodeView, emit enums as global variables, unless they are defined
// inside a class. We do this because MSVC doesn't emit S_CONSTANTs for
@@ -5963,10 +5967,9 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
// If not CodeView, emit DW_TAG_enumeration_type if necessary. For
// example: for "enum { ZERO };", a DW_TAG_enumeration_type is created the
// first time `ZERO` is referenced in a function.
- llvm::DIType *EDTy =
- getOrCreateType(QualType(ED->getTypeForDecl(), 0), Unit);
- assert (EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
- (void)EDTy;
+ CanQualType T = CGM.getContext().getCanonicalTagType(ED);
+ [[maybe_unused]] llvm::DIType *EDTy = getOrCreateType(T, Unit);
+ assert(EDTy->getTag() == llvm::dwarf::DW_TAG_enumeration_type);
return;
}
}
@@ -5985,7 +5988,7 @@ void CGDebugInfo::EmitGlobalVariable(const ValueDecl *VD, const APValue &Init) {
// FIXME: This is probably unnecessary, since Ty should reference RD
// through its scope.
RetainedTypes.push_back(
- CGM.getContext().getRecordType(RD).getAsOpaquePtr());
+ CGM.getContext().getCanonicalTagType(RD).getAsOpaquePtr());
return;
}
diff --git a/clang/lib/CodeGen/CGDecl.cpp b/clang/lib/CodeGen/CGDecl.cpp
index 04f13c7d7a6a3..55155ada9b9c7 100644
--- a/clang/lib/CodeGen/CGDecl.cpp
+++ b/clang/lib/CodeGen/CGDecl.cpp
@@ -113,12 +113,14 @@ void CodeGenFunction::EmitDecl(const Decl &D, bool EvaluateConditionDecl) {
case Decl::CXXRecord: // struct/union/class X; [C++]
if (CGDebugInfo *DI = getDebugInfo())
if (cast<RecordDecl>(D).getDefinition())
- DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(&D)));
+ DI->EmitAndRetainType(
+ getContext().getCanonicalTagType(cast<RecordDecl>(&D)));
return;
case Decl::Enum: // enum X;
if (CGDebugInfo *DI = getDebugInfo())
if (cast<EnumDecl>(D).getDefinition())
- DI->EmitAndRetainType(getContext().getEnumType(cast<EnumDecl>(&D)));
+ DI->EmitAndRetainType(
+ getContext().getCanonicalTagType(cast<EnumDecl>(&D)));
return;
case Decl::Function: // void X();
case Decl::EnumConstant: // enum ? { X = ? }
@@ -1567,7 +1569,7 @@ CodeGenFunction::EmitAutoVarAlloca(const VarDecl &D) {
;
if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
- const auto *RD = RecordTy->getDecl();
+ const auto *RD = RecordTy->getOriginalDecl()->getDefinitionOrSelf();
const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD);
if ((CXXRD && !CXXRD->hasTrivialDestructor()) ||
RD->isNonTrivialToPrimitiveDestroy()) {
@@ -2727,7 +2729,10 @@ void CodeGenFunction::EmitParmDecl(const VarDecl &D, ParamValue Arg,
// Don't push a cleanup in a thunk for a method that will also emit a
// cleanup.
if (Ty->isRecordType() && !CurFuncIsThunk &&
- Ty->castAs<RecordType>()->getDecl()->isParamDestroyedInCallee()) {
+ Ty->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isParamDestroyedInCallee()) {
if (QualType::DestructionKind DtorKind =
D.needsDestruction(getContext())) {
assert((DtorKind == QualType::DK_cxx_destructor ||
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 85c768807572f..1b1f6a98988ef 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -397,9 +397,10 @@ pushTemporaryCleanup(CodeGenFunction &CGF, const MaterializeTemporaryExpr *M,
if (const RecordType *RT =
E->getType()->getBaseElementTypeUnsafe()->getAs<RecordType>()) {
// Get the destructor for the reference temporary.
- if (auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl());
+ if (auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
ClassDecl && !ClassDecl->hasTrivialDestructor())
- ReferenceTemporaryDtor = ClassDecl->getDestructor();
+ ReferenceTemporaryDtor =
+ ClassDecl->getDefinitionOrSelf()->getDestructor();
}
if (!ReferenceTemporaryDtor)
@@ -1198,9 +1199,10 @@ llvm::Value *CodeGenFunction::GetCountedByFieldExprGEP(
return nullptr;
Indices.push_back(Builder.getInt32(0));
- return Builder.CreateInBoundsGEP(
- ConvertType(QualType(RD->getTypeForDecl(), 0)), Res,
- RecIndicesTy(llvm::reverse(Indices)), "counted_by.gep");
+ CanQualType T = CGM.getContext().getCanonicalTagType(RD);
+ return Builder.CreateInBoundsGEP(ConvertType(T), Res,
+ RecIndicesTy(llvm::reverse(Indices)),
+ "counted_by.gep");
}
/// This method is typically called in contexts where we can't generate
@@ -1748,9 +1750,11 @@ static bool isConstantEmittableObjectType(QualType type) {
// Otherwise, all object types satisfy this except C++ classes with
// mutable subobjects or non-trivial copy/destroy behavior.
if (const auto *RT = dyn_cast<RecordType>(type))
- if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
+ RD = RD->getDefinitionOrSelf();
if (RD->hasMutableFields() || !RD->isTrivial())
return false;
+ }
return true;
}
@@ -1911,8 +1915,10 @@ static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
llvm::APInt &Min, llvm::APInt &End,
bool StrictEnums, bool IsBool) {
const EnumType *ET = Ty->getAs<EnumType>();
- bool IsRegularCPlusPlusEnum = CGF.getLangOpts().CPlusPlus && StrictEnums &&
- ET && !ET->getDecl()->isFixed();
+ const EnumDecl *ED =
+ ET ? ET->getOriginalDecl()->getDefinitionOrSelf() : nullptr;
+ bool IsRegularCPlusPlusEnum =
+ CGF.getLangOpts().CPlusPlus && StrictEnums && ET && !ED->isFixed();
if (!IsBool && !IsRegularCPlusPlusEnum)
return false;
@@ -1920,7 +1926,6 @@ static bool getRangeForType(CodeGenFunction &CGF, QualType Ty,
Min = llvm::APInt(CGF.getContext().getTypeSize(Ty), 0);
End = llvm::APInt(CGF.getContext().getTypeSize(Ty), 2);
} else {
- const EnumDecl *ED = ET->getDecl();
ED->getValueRange(End, Min);
}
return true;
@@ -4266,7 +4271,9 @@ static bool IsPreserveAIArrayBase(CodeGenFunction &CGF, const Expr *ArrayBase) {
const auto *PointeeT = PtrT->getPointeeType()
->getUnqualifiedDesugaredType();
if (const auto *RecT = dyn_cast<RecordType>(PointeeT))
- return RecT->getDecl()->hasAttr<BPFPreserveAccessIndexAttr>();
+ return RecT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<BPFPreserveAccessIndexAttr>();
return false;
}
@@ -5032,10 +5039,12 @@ LValue CodeGenFunction::EmitLValueForLambdaField(const FieldDecl *Field,
Address Base = GetAddressOfBaseClass(
LambdaLV.getAddress(), ThisTy, BasePathArray.begin(),
BasePathArray.end(), /*NullCheckValue=*/false, SourceLocation());
- LambdaLV = MakeAddrLValue(Base, QualType{LambdaTy->getTypeForDecl(), 0});
+ CanQualType T = getContext().getCanonicalTagType(LambdaTy);
+ LambdaLV = MakeAddrLValue(Base, T);
}
} else {
- QualType LambdaTagType = getContext().getTagDeclType(Field->getParent());
+ CanQualType LambdaTagType =
+ getContext().getCanonicalTagType(Field->getParent());
LambdaLV = MakeNaturalAlignAddrLValue(ThisValue, LambdaTagType);
}
return EmitLValueForField(LambdaLV, Field);
@@ -5160,7 +5169,7 @@ LValue CodeGenFunction::EmitLValueForField(LValue base, const FieldDecl *field,
}
} else {
llvm::DIType *DbgInfo = getDebugInfo()->getOrCreateRecordType(
- getContext().getRecordType(rec), rec->getLocation());
+ getContext().getCanonicalTagType(rec), rec->getLocation());
Addr = Builder.CreatePreserveStructAccessIndex(
Addr, Idx, getDebugInfoFIndex(rec, field->getFieldIndex()),
DbgInfo);
@@ -5622,7 +5631,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
case CK_DerivedToBase: {
const auto *DerivedClassTy =
E->getSubExpr()->getType()->castAs<RecordType>();
- auto *DerivedClassDecl = cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+ auto *DerivedClassDecl =
+ cast<CXXRecordDecl>(DerivedClassTy->getOriginalDecl())
+ ->getDefinitionOrSelf();
LValue LV = EmitLValue(E->getSubExpr());
Address This = LV.getAddress();
@@ -5642,7 +5653,9 @@ LValue CodeGenFunction::EmitCastLValue(const CastExpr *E) {
return EmitAggExprToLValue(E);
case CK_BaseToDerived: {
const auto *DerivedClassTy = E->getType()->castAs<RecordType>();
- auto *DerivedClassDecl = cast<CXXRecordDecl>(DerivedClassTy->getDecl());
+ auto *DerivedClassDecl =
+ cast<CXXRecordDecl>(DerivedClassTy->getOriginalDecl())
+ ->getDefinitionOrSelf();
LValue LV = EmitLValue(E->getSubExpr());
@@ -6700,7 +6713,7 @@ void CodeGenFunction::FlattenAccessAndType(
WorkList.emplace_back(CAT->getElementType(), IdxListCopy);
}
} else if (const auto *RT = dyn_cast<RecordType>(T)) {
- const RecordDecl *Record = RT->getDecl();
+ const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf();
assert(!Record->isUnion() && "Union types not supported in flat cast.");
const CXXRecordDecl *CXXD = dyn_cast<CXXRecordDecl>(Record);
diff --git a/clang/lib/CodeGen/CGExprAgg.cpp b/clang/lib/CodeGen/CGExprAgg.cpp
index cad6731173700..2c1081d665231 100644
--- a/clang/lib/CodeGen/CGExprAgg.cpp
+++ b/clang/lib/CodeGen/CGExprAgg.cpp
@@ -272,7 +272,7 @@ bool AggExprEmitter::TypeRequiresGCollection(QualType T) {
if (!RecordTy) return false;
// Don't mess with non-trivial C++ types.
- RecordDecl *Record = RecordTy->getDecl();
+ RecordDecl *Record = RecordTy->getOriginalDecl()->getDefinitionOrSelf();
if (isa<CXXRecordDecl>(Record) &&
(cast<CXXRecordDecl>(Record)->hasNonTrivialCopyConstructor() ||
!cast<CXXRecordDecl>(Record)->hasTrivialDestructor()))
@@ -428,7 +428,10 @@ AggExprEmitter::VisitCXXStdInitializerListExpr(CXXStdInitializerListExpr *E) {
Ctx.getAsConstantArrayType(E->getSubExpr()->getType());
assert(ArrayType && "std::initializer_list constructed from non-array");
- RecordDecl *Record = E->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *Record = E->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
RecordDecl::field_iterator Field = Record->field_begin();
assert(Field != Record->field_end() &&
Ctx.hasSameType(Field->getType()->getPointeeType(),
@@ -1810,7 +1813,10 @@ void AggExprEmitter::VisitCXXParenListOrInitListExpr(
// the disadvantage is that the generated code is more difficult for
// the optimizer, especially with bitfields.
unsigned NumInitElements = InitExprs.size();
- RecordDecl *record = ExprToVisit->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *record = ExprToVisit->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
// We'll need to enter cleanup scopes in case any of the element
// initializers throws an exception.
@@ -2120,7 +2126,7 @@ static CharUnits GetNumNonZeroBytesInInit(const Expr *E, CodeGenFunction &CGF) {
// referencee. InitListExprs for unions and arrays can't have references.
if (const RecordType *RT = E->getType()->getAs<RecordType>()) {
if (!RT->isUnionType()) {
- RecordDecl *SD = RT->getDecl();
+ RecordDecl *SD = RT->getOriginalDecl()->getDefinitionOrSelf();
CharUnits NumNonZeroBytes = CharUnits::Zero();
unsigned ILEElement = 0;
@@ -2172,7 +2178,7 @@ static void CheckAggExprForMemSetUse(AggValueSlot &Slot, const Expr *E,
if (CGF.getLangOpts().CPlusPlus)
if (const RecordType *RT = CGF.getContext()
.getBaseElementType(E->getType())->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getOriginalDecl());
if (RD->hasUserDeclaredConstructor())
return;
}
@@ -2293,7 +2299,8 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty,
if (getLangOpts().CPlusPlus) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(RT->getDecl());
+ auto *Record =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
assert((Record->hasTrivialCopyConstructor() ||
Record->hasTrivialCopyAssignment() ||
Record->hasTrivialMoveConstructor() ||
@@ -2377,7 +2384,7 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty,
if (CGM.getLangOpts().getGC() == LangOptions::NonGC) {
// fall through
} else if (const RecordType *RecordTy = Ty->getAs<RecordType>()) {
- RecordDecl *Record = RecordTy->getDecl();
+ RecordDecl *Record = RecordTy->getOriginalDecl()->getDefinitionOrSelf();
if (Record->hasObjectMember()) {
CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
SizeVal);
@@ -2386,7 +2393,9 @@ void CodeGenFunction::EmitAggregateCopy(LValue Dest, LValue Src, QualType Ty,
} else if (Ty->isArrayType()) {
QualType BaseType = getContext().getBaseElementType(Ty);
if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
- if (RecordTy->getDecl()->hasObjectMember()) {
+ if (RecordTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasObjectMember()) {
CGM.getObjCRuntime().EmitGCMemmoveCollectable(*this, DestPtr, SrcPtr,
SizeVal);
return;
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 359e30cb8f5cd..a92b89def6433 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -181,7 +181,7 @@ static CXXRecordDecl *getCXXRecord(const Expr *E) {
if (const PointerType *PTy = T->getAs<PointerType>())
T = PTy->getPointeeType();
const RecordType *Ty = T->castAs<RecordType>();
- return cast<CXXRecordDecl>(Ty->getDecl());
+ return cast<CXXRecordDecl>(Ty->getOriginalDecl())->getDefinitionOrSelf();
}
// Note: This function also emit constructor calls to support a MSVC
@@ -206,7 +206,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
}
bool HasQualifier = ME->hasQualifier();
- NestedNameSpecifier *Qualifier = HasQualifier ? ME->getQualifier() : nullptr;
+ NestedNameSpecifier Qualifier = ME->getQualifier();
bool IsArrow = ME->isArrow();
const Expr *Base = ME->getBase();
@@ -217,7 +217,7 @@ RValue CodeGenFunction::EmitCXXMemberCallExpr(const CXXMemberCallExpr *CE,
RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue,
- bool HasQualifier, NestedNameSpecifier *Qualifier, bool IsArrow,
+ bool HasQualifier, NestedNameSpecifier Qualifier, bool IsArrow,
const Expr *Base, llvm::CallBase **CallOrInvoke) {
assert(isa<CXXMemberCallExpr>(CE) || isa<CXXOperatorCallExpr>(CE));
@@ -361,7 +361,7 @@ RValue CodeGenFunction::EmitCXXMemberOrOperatorMemberCallExpr(
if (sanitizePerformTypeCheck())
EmitTypeCheck(CodeGenFunction::TCK_MemberCall, CallLoc,
This.emitRawPointer(*this),
- C.getRecordType(CalleeDecl->getParent()),
+ C.getCanonicalTagType(CalleeDecl->getParent()),
/*Alignment=*/CharUnits::Zero(), SkippedChecks);
// C++ [class.virtual]p12:
@@ -461,9 +461,9 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
else
This = EmitLValue(BaseExpr, KnownNonNull).getAddress();
- EmitTypeCheck(
- TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
- QualType(MPT->getMostRecentCXXRecordDecl()->getTypeForDecl(), 0));
+ CanQualType ClassType = CGM.getContext().getCanonicalTagType(RD);
+ EmitTypeCheck(TCK_MemberCall, E->getExprLoc(), This.emitRawPointer(*this),
+ ClassType);
// Get the member function pointer.
llvm::Value *MemFnPtr = EmitScalarExpr(MemFnExpr);
@@ -476,8 +476,7 @@ CodeGenFunction::EmitCXXMemberPointerCallExpr(const CXXMemberCallExpr *E,
CallArgList Args;
- QualType ThisType =
- getContext().getPointerType(getContext().getTagDeclType(RD));
+ QualType ThisType = getContext().getPointerType(ClassType);
// Push the this ptr.
Args.add(RValue::get(ThisPtrForCall), ThisType);
@@ -498,7 +497,7 @@ RValue CodeGenFunction::EmitCXXOperatorMemberCallExpr(
assert(MD->isImplicitObjectMemberFunction() &&
"Trying to emit a member call expr on a static method!");
return EmitCXXMemberOrOperatorMemberCallExpr(
- E, MD, ReturnValue, /*HasQualifier=*/false, /*Qualifier=*/nullptr,
+ E, MD, ReturnValue, /*HasQualifier=*/false, /*Qualifier=*/std::nullopt,
/*IsArrow=*/false, E->getArg(0), CallOrInvoke);
}
@@ -1237,11 +1236,12 @@ void CodeGenFunction::EmitNewArrayInitializer(
// usually use memset.
if (auto *ILE = dyn_cast<InitListExpr>(Init)) {
if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
- if (RType->getDecl()->isStruct()) {
+ const RecordDecl *RD = RType->getOriginalDecl()->getDefinitionOrSelf();
+ if (RD->isStruct()) {
unsigned NumElements = 0;
- if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RType->getDecl()))
+ if (auto *CXXRD = dyn_cast<CXXRecordDecl>(RD))
NumElements = CXXRD->getNumBases();
- for (auto *Field : RType->getDecl()->fields())
+ for (auto *Field : RD->fields())
if (!Field->isUnnamedBitField())
++NumElements;
// FIXME: Recurse into nested InitListExprs.
@@ -1687,9 +1687,11 @@ llvm::Value *CodeGenFunction::EmitCXXNewExpr(const CXXNewExpr *E) {
QualType AlignValT = sizeType;
if (allocatorType->getNumParams() > IndexOfAlignArg) {
AlignValT = allocatorType->getParamType(IndexOfAlignArg);
- assert(getContext().hasSameUnqualifiedType(
- AlignValT->castAs<EnumType>()->getDecl()->getIntegerType(),
- sizeType) &&
+ assert(getContext().hasSameUnqualifiedType(AlignValT->castAs<EnumType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->getIntegerType(),
+ sizeType) &&
"wrong type for alignment parameter");
++ParamsToSkip;
} else {
@@ -1972,7 +1974,8 @@ static bool EmitObjectDelete(CodeGenFunction &CGF,
// destructor is virtual, we'll just emit the vcall and return.
const CXXDestructorDecl *Dtor = nullptr;
if (const RecordType *RT = ElementType->getAs<RecordType>()) {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ auto *RD =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if (RD->hasDefinition() && !RD->hasTrivialDestructor()) {
Dtor = RD->getDestructor();
diff --git a/clang/lib/CodeGen/CGExprConstant.cpp b/clang/lib/CodeGen/CGExprConstant.cpp
index 715bd392f59f7..a96c1518d2a1d 100644
--- a/clang/lib/CodeGen/CGExprConstant.cpp
+++ b/clang/lib/CodeGen/CGExprConstant.cpp
@@ -714,7 +714,10 @@ static bool EmitDesignatedInitUpdater(ConstantEmitter &Emitter,
}
bool ConstStructBuilder::Build(const InitListExpr *ILE, bool AllowOverwrite) {
- RecordDecl *RD = ILE->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *RD = ILE->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
const ASTRecordLayout &Layout = CGM.getContext().getASTRecordLayout(RD);
unsigned FieldNo = -1;
@@ -977,7 +980,8 @@ bool ConstStructBuilder::DoZeroInitPadding(const ASTRecordLayout &Layout,
llvm::Constant *ConstStructBuilder::Finalize(QualType Type) {
Type = Type.getNonReferenceType();
- RecordDecl *RD = Type->castAs<RecordType>()->getDecl();
+ RecordDecl *RD =
+ Type->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
llvm::Type *ValTy = CGM.getTypes().ConvertType(Type);
return Builder.build(ValTy, RD->hasFlexibleArrayMember());
}
@@ -1000,7 +1004,8 @@ llvm::Constant *ConstStructBuilder::BuildStruct(ConstantEmitter &Emitter,
ConstantAggregateBuilder Const(Emitter.CGM);
ConstStructBuilder Builder(Emitter, Const, CharUnits::Zero());
- const RecordDecl *RD = ValTy->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ ValTy->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
const CXXRecordDecl *CD = dyn_cast<CXXRecordDecl>(RD);
if (!Builder.Build(Val, RD, false, CD, CharUnits::Zero()))
return nullptr;
@@ -1506,7 +1511,9 @@ class ConstExprEmitter
llvm::Type *ValTy = CGM.getTypes().ConvertType(destType);
bool HasFlexibleArray = false;
if (const auto *RT = destType->getAs<RecordType>())
- HasFlexibleArray = RT->getDecl()->hasFlexibleArrayMember();
+ HasFlexibleArray = RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember();
return Const.build(ValTy, HasFlexibleArray);
}
@@ -2640,7 +2647,9 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
}
const CXXRecordDecl *base =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Ignore empty bases.
if (isEmptyRecordForLayout(CGM.getContext(), I.getType()) ||
@@ -2679,8 +2688,10 @@ static llvm::Constant *EmitNullConstant(CodeGenModule &CGM,
// Fill in the virtual bases, if we're working with the complete object.
if (CXXR && asCompleteObject) {
for (const auto &I : CXXR->vbases()) {
- const CXXRecordDecl *base =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ const auto *base =
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Ignore empty bases.
if (isEmptyRecordForLayout(CGM.getContext(), I.getType()))
@@ -2746,7 +2757,9 @@ llvm::Constant *CodeGenModule::EmitNullConstant(QualType T) {
}
if (const RecordType *RT = T->getAs<RecordType>())
- return ::EmitNullConstant(*this, RT->getDecl(), /*complete object*/ true);
+ return ::EmitNullConstant(*this,
+ RT->getOriginalDecl()->getDefinitionOrSelf(),
+ /*complete object*/ true);
assert(T->isMemberDataPointerType() &&
"Should only see pointers to data members here!");
diff --git a/clang/lib/CodeGen/CGExprScalar.cpp b/clang/lib/CodeGen/CGExprScalar.cpp
index 44931d0481e26..0318f85a344d7 100644
--- a/clang/lib/CodeGen/CGExprScalar.cpp
+++ b/clang/lib/CodeGen/CGExprScalar.cpp
@@ -3515,7 +3515,9 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
case OffsetOfNode::Field: {
FieldDecl *MemberDecl = ON.getField();
- RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
+ RecordDecl *RD = CurrentType->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
// Compute the index of the field in its parent.
@@ -3548,15 +3550,16 @@ Value *ScalarExprEmitter::VisitOffsetOfExpr(OffsetOfExpr *E) {
continue;
}
- RecordDecl *RD = CurrentType->castAs<RecordType>()->getDecl();
- const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(RD);
+ const ASTRecordLayout &RL = CGF.getContext().getASTRecordLayout(
+ CurrentType->castAs<RecordType>()->getOriginalDecl());
// Save the element type.
CurrentType = ON.getBase()->getType();
// Compute the offset to the base.
auto *BaseRT = CurrentType->castAs<RecordType>();
- auto *BaseRD = cast<CXXRecordDecl>(BaseRT->getDecl());
+ auto *BaseRD =
+ cast<CXXRecordDecl>(BaseRT->getOriginalDecl())->getDefinitionOrSelf();
CharUnits OffsetInt = RL.getBaseClassOffset(BaseRD);
Offset = llvm::ConstantInt::get(ResultType, OffsetInt.getQuantity());
break;
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index c1fd6f22f693b..ad7048b61e727 100644
--- a/clang/lib/CodeGen/CGHLSLRuntime.cpp
+++ b/clang/lib/CodeGen/CGHLSLRuntime.cpp
@@ -186,8 +186,7 @@ static const clang::HLSLAttributedResourceType *
createBufferHandleType(const HLSLBufferDecl *BufDecl) {
ASTContext &AST = BufDecl->getASTContext();
QualType QT = AST.getHLSLAttributedResourceType(
- AST.HLSLResourceTy,
- QualType(BufDecl->getLayoutStruct()->getTypeForDecl(), 0),
+ AST.HLSLResourceTy, AST.getCanonicalTagType(BufDecl->getLayoutStruct()),
HLSLAttributedResourceType::Attributes(ResourceClass::CBuffer));
return cast<HLSLAttributedResourceType>(QT.getTypePtr());
}
diff --git a/clang/lib/CodeGen/CGNonTrivialStruct.cpp b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
index e0983ef256e71..1b941fff8b644 100644
--- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -39,7 +39,8 @@ template <class Derived> struct StructVisitor {
template <class... Ts>
void visitStructFields(QualType QT, CharUnits CurStructOffset, Ts... Args) {
- const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ QT->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
// Iterate over the fields of the struct.
for (const FieldDecl *FD : RD->fields()) {
@@ -464,7 +465,8 @@ template <class Derived> struct GenFuncBase {
if (WrongType) {
std::string FuncName = std::string(F->getName());
- SourceLocation Loc = QT->castAs<RecordType>()->getDecl()->getLocation();
+ SourceLocation Loc =
+ QT->castAs<RecordType>()->getOriginalDecl()->getLocation();
CGM.Error(Loc, "special function " + FuncName +
" for non-trivial C struct has incorrect type");
return nullptr;
@@ -560,7 +562,8 @@ struct GenBinaryFunc : CopyStructVisitor<Derived, IsMove>,
if (FD->isZeroLengthBitField())
return;
- QualType RT = QualType(FD->getParent()->getTypeForDecl(), 0);
+ CanQualType RT =
+ this->CGF->getContext().getCanonicalTagType(FD->getParent());
llvm::Type *Ty = this->CGF->ConvertType(RT);
Address DstAddr = this->getAddrWithOffset(Addrs[DstIdx], Offset);
LValue DstBase =
diff --git a/clang/lib/CodeGen/CGObjC.cpp b/clang/lib/CodeGen/CGObjC.cpp
index 6f87444d3f672..04b6d4fe29296 100644
--- a/clang/lib/CodeGen/CGObjC.cpp
+++ b/clang/lib/CodeGen/CGObjC.cpp
@@ -1000,7 +1000,9 @@ PropertyImplStrategy::PropertyImplStrategy(CodeGenModule &CGM,
// Compute whether the ivar has strong members.
if (CGM.getLangOpts().getGC())
if (const RecordType *recordType = ivarType->getAs<RecordType>())
- HasStrong = recordType->getDecl()->hasObjectMember();
+ HasStrong = recordType->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasObjectMember();
// We can never access structs with object members with a native
// access, because we need to use write barriers. This is what
diff --git a/clang/lib/CodeGen/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index a52c92cdbc83b..adb5639e7289c 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -2493,7 +2493,7 @@ void CGObjCCommonMac::BuildRCBlockVarRecordLayout(const RecordType *RT,
CharUnits BytePos,
bool &HasUnion,
bool ByrefLayout) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
SmallVector<const FieldDecl *, 16> Fields(RD->fields());
llvm::Type *Ty = CGM.getTypes().ConvertType(QualType(RT, 0));
const llvm::StructLayout *RecLayout =
@@ -3352,7 +3352,8 @@ static bool hasWeakMember(QualType type) {
}
if (auto recType = type->getAs<RecordType>()) {
- for (auto *field : recType->getDecl()->fields()) {
+ for (auto *field :
+ recType->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
if (hasWeakMember(field->getType()))
return true;
}
@@ -5174,7 +5175,7 @@ CGObjCCommonMac::GetIvarLayoutName(IdentifierInfo *Ident,
}
void IvarLayoutBuilder::visitRecord(const RecordType *RT, CharUnits offset) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
// If this is a union, remember that we had one, because it might mess
// up the ordering of layout entries.
@@ -5660,7 +5661,7 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
nullptr, false, ICIS_NoInit));
RD->completeDefinition();
- SuperCTy = Ctx.getTagDeclType(RD);
+ SuperCTy = Ctx.getCanonicalTagType(RD);
SuperPtrCTy = Ctx.getPointerType(SuperCTy);
SuperTy = cast<llvm::StructType>(Types.ConvertType(SuperCTy));
@@ -6006,7 +6007,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(
false, ICIS_NoInit));
RD->completeDefinition();
- MessageRefCTy = Ctx.getTagDeclType(RD);
+ MessageRefCTy = Ctx.getCanonicalTagType(RD);
MessageRefCPtrTy = Ctx.getPointerType(MessageRefCTy);
MessageRefTy = cast<llvm::StructType>(Types.ConvertType(MessageRefCTy));
diff --git a/clang/lib/CodeGen/CGObjCRuntime.cpp b/clang/lib/CodeGen/CGObjCRuntime.cpp
index 6e2f32022a01e..cbf99534d2ce6 100644
--- a/clang/lib/CodeGen/CGObjCRuntime.cpp
+++ b/clang/lib/CodeGen/CGObjCRuntime.cpp
@@ -440,7 +440,9 @@ void CGObjCRuntime::destroyCalleeDestroyedArguments(CodeGenFunction &CGF,
} else {
QualType QT = param->getType();
auto *RT = QT->getAs<RecordType>();
- if (RT && RT->getDecl()->isParamDestroyedInCallee()) {
+ if (RT && RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isParamDestroyedInCallee()) {
RValue RV = I->getRValue(CGF);
QualType::DestructionKind DtorKind = QT.isDestructedType();
switch (DtorKind) {
diff --git a/clang/lib/CodeGen/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index a5f2f0efa2c3b..503c02f02cc6c 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -2915,7 +2915,7 @@ createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
addFieldToRecordDecl(C, UD, KmpInt32Ty);
addFieldToRecordDecl(C, UD, KmpRoutineEntryPointerQTy);
UD->completeDefinition();
- QualType KmpCmplrdataTy = C.getRecordType(UD);
+ CanQualType KmpCmplrdataTy = C.getCanonicalTagType(UD);
RecordDecl *RD = C.buildImplicitRecord("kmp_task_t");
RD->startDefinition();
addFieldToRecordDecl(C, RD, C.VoidPtrTy);
@@ -2950,7 +2950,7 @@ createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
RD->startDefinition();
addFieldToRecordDecl(C, RD, KmpTaskTQTy);
if (const RecordDecl *PrivateRD = createPrivatesRecordDecl(CGM, Privates))
- addFieldToRecordDecl(C, RD, C.getRecordType(PrivateRD));
+ addFieldToRecordDecl(C, RD, C.getCanonicalTagType(PrivateRD));
RD->completeDefinition();
return RD;
}
@@ -3582,7 +3582,7 @@ static void getKmpAffinityType(ASTContext &C, QualType &KmpTaskAffinityInfoTy) {
addFieldToRecordDecl(C, KmpAffinityInfoRD, C.getSizeType());
addFieldToRecordDecl(C, KmpAffinityInfoRD, FlagsTy);
KmpAffinityInfoRD->completeDefinition();
- KmpTaskAffinityInfoTy = C.getRecordType(KmpAffinityInfoRD);
+ KmpTaskAffinityInfoTy = C.getCanonicalTagType(KmpAffinityInfoRD);
}
}
@@ -3640,7 +3640,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
// Build type kmp_task_t (if not built yet).
if (isOpenMPTaskLoopDirective(D.getDirectiveKind())) {
if (SavedKmpTaskloopTQTy.isNull()) {
- SavedKmpTaskloopTQTy = C.getRecordType(createKmpTaskTRecordDecl(
+ SavedKmpTaskloopTQTy = C.getCanonicalTagType(createKmpTaskTRecordDecl(
CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
}
KmpTaskTQTy = SavedKmpTaskloopTQTy;
@@ -3650,7 +3650,7 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
isOpenMPTargetDataManagementDirective(D.getDirectiveKind())) &&
"Expected taskloop, task or target directive");
if (SavedKmpTaskTQTy.isNull()) {
- SavedKmpTaskTQTy = C.getRecordType(createKmpTaskTRecordDecl(
+ SavedKmpTaskTQTy = C.getCanonicalTagType(createKmpTaskTRecordDecl(
CGM, D.getDirectiveKind(), KmpInt32Ty, KmpRoutineEntryPtrQTy));
}
KmpTaskTQTy = SavedKmpTaskTQTy;
@@ -3659,7 +3659,8 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
// Build particular struct kmp_task_t for the given task.
const RecordDecl *KmpTaskTWithPrivatesQTyRD =
createKmpTaskTWithPrivatesRecordDecl(CGM, KmpTaskTQTy, Privates);
- QualType KmpTaskTWithPrivatesQTy = C.getRecordType(KmpTaskTWithPrivatesQTyRD);
+ CanQualType KmpTaskTWithPrivatesQTy =
+ C.getCanonicalTagType(KmpTaskTWithPrivatesQTyRD);
QualType KmpTaskTWithPrivatesPtrQTy =
C.getPointerType(KmpTaskTWithPrivatesQTy);
llvm::Type *KmpTaskTWithPrivatesPtrTy = CGF.Builder.getPtrTy(0);
@@ -3914,7 +3915,10 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
// Fill the data in the resulting kmp_task_t record.
// Copy shareds if there are any.
Address KmpTaskSharedsPtr = Address::invalid();
- if (!SharedsTy->getAsStructureType()->getDecl()->field_empty()) {
+ if (!SharedsTy->getAsStructureType()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->field_empty()) {
KmpTaskSharedsPtr = Address(
CGF.EmitLoadOfScalar(
CGF.EmitLValueForField(
@@ -3944,8 +3948,11 @@ CGOpenMPRuntime::emitTaskInit(CodeGenFunction &CGF, SourceLocation Loc,
enum { Priority = 0, Destructors = 1 };
// Provide pointer to function with destructors for privates.
auto FI = std::next(KmpTaskTQTyRD->field_begin(), Data1);
- const RecordDecl *KmpCmplrdataUD =
- (*FI)->getType()->getAsUnionType()->getDecl();
+ const RecordDecl *KmpCmplrdataUD = (*FI)
+ ->getType()
+ ->getAsUnionType()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
if (NeedsCleanup) {
llvm::Value *DestructorFn = emitDestructorsFunction(
CGM, Loc, KmpInt32Ty, KmpTaskTWithPrivatesPtrQTy,
@@ -4015,7 +4022,7 @@ static void getDependTypes(ASTContext &C, QualType &KmpDependInfoTy,
addFieldToRecordDecl(C, KmpDependInfoRD, C.getSizeType());
addFieldToRecordDecl(C, KmpDependInfoRD, FlagsTy);
KmpDependInfoRD->completeDefinition();
- KmpDependInfoTy = C.getRecordType(KmpDependInfoRD);
+ KmpDependInfoTy = C.getCanonicalTagType(KmpDependInfoRD);
}
}
@@ -5714,7 +5721,7 @@ llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
const FieldDecl *FlagsFD = addFieldToRecordDecl(
C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/false));
RD->completeDefinition();
- QualType RDType = C.getRecordType(RD);
+ CanQualType RDType = C.getCanonicalTagType(RD);
unsigned Size = Data.ReductionVars.size();
llvm::APInt ArraySize(/*numBits=*/64, Size);
QualType ArrayRDType =
@@ -10640,7 +10647,7 @@ static unsigned evaluateCDTSize(const FunctionDecl *FD,
unsigned Offset = 0;
if (const auto *MD = dyn_cast<CXXMethodDecl>(FD)) {
if (ParamAttrs[Offset].Kind == Vector)
- CDT = C.getPointerType(C.getRecordType(MD->getParent()));
+ CDT = C.getPointerType(C.getCanonicalTagType(MD->getParent()));
++Offset;
}
if (CDT.isNull()) {
@@ -11222,7 +11229,7 @@ void CGOpenMPRuntime::emitDoacrossInit(CodeGenFunction &CGF,
addFieldToRecordDecl(C, RD, Int64Ty);
addFieldToRecordDecl(C, RD, Int64Ty);
RD->completeDefinition();
- KmpDimTy = C.getRecordType(RD);
+ KmpDimTy = C.getCanonicalTagType(RD);
} else {
RD = cast<RecordDecl>(KmpDimTy->getAsTagDecl());
}
@@ -11718,7 +11725,7 @@ Address CGOpenMPRuntime::emitLastprivateConditionalInit(CodeGenFunction &CGF,
VDField = addFieldToRecordDecl(C, RD, VD->getType().getNonReferenceType());
FiredField = addFieldToRecordDecl(C, RD, C.CharTy);
RD->completeDefinition();
- NewType = C.getRecordType(RD);
+ NewType = C.getCanonicalTagType(RD);
Address Addr = CGF.CreateMemTemp(NewType, C.getDeclAlign(VD), VD->getName());
BaseLVal = CGF.MakeAddrLValue(Addr, NewType, AlignmentSource::Decl);
I->getSecond().try_emplace(VD, NewType, VDField, FiredField, BaseLVal);
diff --git a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
index e25b6948d30f8..0e746ddfe13a2 100644
--- a/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
+++ b/clang/lib/CodeGen/CGOpenMPRuntimeGPU.cpp
@@ -769,7 +769,7 @@ void CGOpenMPRuntimeGPU::emitKernelDeinit(CodeGenFunction &CGF,
"_openmp_teams_reduction_type_$_", RecordDecl::TagKind::Union);
StaticRD->startDefinition();
for (const RecordDecl *TeamReductionRec : TeamsReductions) {
- QualType RecTy = C.getRecordType(TeamReductionRec);
+ CanQualType RecTy = C.getCanonicalTagType(TeamReductionRec);
auto *Field = FieldDecl::Create(
C, StaticRD, SourceLocation(), SourceLocation(), nullptr, RecTy,
C.getTrivialTypeSourceInfo(RecTy, SourceLocation()),
@@ -779,7 +779,7 @@ void CGOpenMPRuntimeGPU::emitKernelDeinit(CodeGenFunction &CGF,
StaticRD->addDecl(Field);
}
StaticRD->completeDefinition();
- QualType StaticTy = C.getRecordType(StaticRD);
+ CanQualType StaticTy = C.getCanonicalTagType(StaticRD);
llvm::Type *LLVMReductionsBufferTy =
CGM.getTypes().ConvertTypeForMem(StaticTy);
const auto &DL = CGM.getModule().getDataLayout();
diff --git a/clang/lib/CodeGen/CGPointerAuth.cpp b/clang/lib/CodeGen/CGPointerAuth.cpp
index dcef01a5eb6d3..1a5ffb5eb33f8 100644
--- a/clang/lib/CodeGen/CGPointerAuth.cpp
+++ b/clang/lib/CodeGen/CGPointerAuth.cpp
@@ -531,7 +531,7 @@ llvm::Constant *CodeGenModule::getMemberFunctionPointer(llvm::Constant *Pointer,
llvm::Constant *CodeGenModule::getMemberFunctionPointer(const FunctionDecl *FD,
llvm::Type *Ty) {
QualType FT = FD->getType();
- FT = getContext().getMemberPointerType(FT, /*Qualifier=*/nullptr,
+ FT = getContext().getMemberPointerType(FT, /*Qualifier=*/std::nullopt,
cast<CXXMethodDecl>(FD)->getParent());
return getMemberFunctionPointer(getRawFunctionPointer(FD, Ty), FT);
}
diff --git a/clang/lib/CodeGen/CGStmt.cpp b/clang/lib/CodeGen/CGStmt.cpp
index e0650067b9547..28d518a52cfe7 100644
--- a/clang/lib/CodeGen/CGStmt.cpp
+++ b/clang/lib/CodeGen/CGStmt.cpp
@@ -3270,7 +3270,7 @@ void CodeGenFunction::EmitAsmStmt(const AsmStmt &S) {
LValue CodeGenFunction::InitCapturedStruct(const CapturedStmt &S) {
const RecordDecl *RD = S.getCapturedRecordDecl();
- QualType RecordTy = getContext().getRecordType(RD);
+ CanQualType RecordTy = getContext().getCanonicalTagType(RD);
// Initialize the captured struct.
LValue SlotLV =
@@ -3350,7 +3350,7 @@ CodeGenFunction::GenerateCapturedStmtFunction(const CapturedStmt &S) {
// Initialize variable-length arrays.
LValue Base = MakeNaturalAlignRawAddrLValue(
- CapturedStmtInfo->getContextValue(), Ctx.getTagDeclType(RD));
+ CapturedStmtInfo->getContextValue(), Ctx.getCanonicalTagType(RD));
for (auto *FD : RD->fields()) {
if (FD->hasCapturedVLAType()) {
auto *ExprArg =
diff --git a/clang/lib/CodeGen/CGStmtOpenMP.cpp b/clang/lib/CodeGen/CGStmtOpenMP.cpp
index 5822e0f6db89a..f6a0ca574a191 100644
--- a/clang/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/clang/lib/CodeGen/CGStmtOpenMP.cpp
@@ -5273,7 +5273,8 @@ void CodeGenFunction::EmitOMPTargetTaskBasedDirective(
// Emit outlined function for task construct.
const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
- QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
+ CanQualType SharedsTy =
+ getContext().getCanonicalTagType(CS->getCapturedRecordDecl());
auto I = CS->getCapturedDecl()->param_begin();
auto PartId = std::next(I);
auto TaskT = std::next(I, 4);
@@ -5507,7 +5508,8 @@ void CodeGenFunction::EmitOMPTaskDirective(const OMPTaskDirective &S) {
// Emit outlined function for task construct.
const CapturedStmt *CS = S.getCapturedStmt(OMPD_task);
Address CapturedStruct = GenerateCapturedStmtArgument(*CS);
- QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
+ CanQualType SharedsTy =
+ getContext().getCanonicalTagType(CS->getCapturedRecordDecl());
const Expr *IfCond = nullptr;
for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
if (C->getNameModifier() == OMPD_unknown ||
@@ -7890,7 +7892,8 @@ void CodeGenFunction::EmitOMPTaskLoopBasedDirective(const OMPLoopDirective &S) {
OMPLexicalScope Scope(*this, S, OMPD_taskloop, /*EmitPreInitStmt=*/false);
CapturedStruct = GenerateCapturedStmtArgument(*CS);
}
- QualType SharedsTy = getContext().getRecordType(CS->getCapturedRecordDecl());
+ CanQualType SharedsTy =
+ getContext().getCanonicalTagType(CS->getCapturedRecordDecl());
const Expr *IfCond = nullptr;
for (const auto *C : S.getClausesOfKind<OMPIfClause>()) {
if (C->getNameModifier() == OMPD_unknown ||
diff --git a/clang/lib/CodeGen/CGVTables.cpp b/clang/lib/CodeGen/CGVTables.cpp
index 0b6e830e0d557..e14e883a55ac5 100644
--- a/clang/lib/CodeGen/CGVTables.cpp
+++ b/clang/lib/CodeGen/CGVTables.cpp
@@ -971,7 +971,7 @@ llvm::GlobalVariable *CodeGenVTables::GenerateConstructionVTable(
VTable->setUnnamedAddr(llvm::GlobalValue::UnnamedAddr::Global);
llvm::Constant *RTTI = CGM.GetAddrOfRTTIDescriptor(
- CGM.getContext().getTagDeclType(Base.getBase()));
+ CGM.getContext().getCanonicalTagType(Base.getBase()));
// Create and set the initializer.
ConstantInitBuilder builder(CGM);
@@ -1382,8 +1382,8 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
AP.second.AddressPointIndex,
{}};
llvm::raw_string_ostream Stream(N.TypeName);
- getCXXABI().getMangleContext().mangleCanonicalTypeName(
- QualType(N.Base->getTypeForDecl(), 0), Stream);
+ CanQualType T = getContext().getCanonicalTagType(N.Base);
+ getCXXABI().getMangleContext().mangleCanonicalTypeName(T, Stream);
AddressPoints.push_back(std::move(N));
}
@@ -1404,7 +1404,7 @@ void CodeGenModule::EmitVTableTypeMetadata(const CXXRecordDecl *RD,
continue;
llvm::Metadata *MD = CreateMetadataIdentifierForVirtualMemPtrType(
Context.getMemberPointerType(Comps[I].getFunctionDecl()->getType(),
- /*Qualifier=*/nullptr, AP.Base));
+ /*Qualifier=*/std::nullopt, AP.Base));
VTable->addTypeMetadata((ComponentWidth * I).getQuantity(), MD);
}
}
diff --git a/clang/lib/CodeGen/CodeGenFunction.cpp b/clang/lib/CodeGen/CodeGenFunction.cpp
index 776a646ceb32f..3307e3fbd2196 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2224,7 +2224,9 @@ CodeGenFunction::EmitNullInitialization(Address DestPtr, QualType Ty) {
// Ignore empty classes in C++.
if (getLangOpts().CPlusPlus) {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- if (cast<CXXRecordDecl>(RT->getDecl())->isEmpty())
+ if (cast<CXXRecordDecl>(RT->getOriginalDecl())
+ ->getDefinitionOrSelf()
+ ->isEmpty())
return;
}
}
@@ -2494,10 +2496,6 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::HLSLInlineSpirv:
llvm_unreachable("type class is never variably-modified!");
- case Type::Elaborated:
- type = cast<ElaboratedType>(ty)->getNamedType();
- break;
-
case Type::Adjusted:
type = cast<AdjustedType>(ty)->getAdjustedType();
break;
diff --git a/clang/lib/CodeGen/CodeGenFunction.h b/clang/lib/CodeGen/CodeGenFunction.h
index 6c32c98cec011..c33c215c03e01 100644
--- a/clang/lib/CodeGen/CodeGenFunction.h
+++ b/clang/lib/CodeGen/CodeGenFunction.h
@@ -2974,7 +2974,7 @@ class CodeGenFunction : public CodeGenTypeCache {
/// member.
bool hasVolatileMember(QualType T) {
if (const RecordType *RT = T->getAs<RecordType>()) {
- const RecordDecl *RD = cast<RecordDecl>(RT->getDecl());
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
return RD->hasVolatileMember();
}
return false;
@@ -4560,7 +4560,7 @@ class CodeGenFunction : public CodeGenTypeCache {
ArrayRef<llvm::Value *> args);
CGCallee BuildAppleKextVirtualCall(const CXXMethodDecl *MD,
- NestedNameSpecifier *Qual, llvm::Type *Ty);
+ NestedNameSpecifier Qual, llvm::Type *Ty);
CGCallee BuildAppleKextVirtualDestructorCall(const CXXDestructorDecl *DD,
CXXDtorType Type,
@@ -4665,7 +4665,7 @@ class CodeGenFunction : public CodeGenTypeCache {
llvm::CallBase **CallOrInvoke = nullptr);
RValue EmitCXXMemberOrOperatorMemberCallExpr(
const CallExpr *CE, const CXXMethodDecl *MD, ReturnValueSlot ReturnValue,
- bool HasQualifier, NestedNameSpecifier *Qualifier, bool IsArrow,
+ bool HasQualifier, NestedNameSpecifier Qualifier, bool IsArrow,
const Expr *Base, llvm::CallBase **CallOrInvoke);
// Compute the object pointer.
Address EmitCXXMemberDataPointerAddress(
diff --git a/clang/lib/CodeGen/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index c8866f15745c2..6fdb187b3a242 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2795,7 +2795,7 @@ void CodeGenModule::SetLLVMFunctionAttributesForDefinition(const Decl *D,
for (const CXXRecordDecl *Base : getMostBaseClasses(MD->getParent())) {
llvm::Metadata *Id =
CreateMetadataIdentifierForType(Context.getMemberPointerType(
- MD->getType(), /*Qualifier=*/nullptr, Base));
+ MD->getType(), /*Qualifier=*/std::nullopt, Base));
F->addTypeMetadata(0, Id);
}
}
@@ -4154,9 +4154,11 @@ void CodeGenModule::EmitGlobal(GlobalDecl GD) {
// Check if T is a class type with a destructor that's not dllimport.
static bool HasNonDllImportDtor(QualType T) {
if (const auto *RT = T->getBaseElementTypeUnsafe()->getAs<RecordType>())
- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl()))
+ if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
+ RD = RD->getDefinitionOrSelf();
if (RD->getDestructor() && !RD->getDestructor()->hasAttr<DLLImportAttr>())
return true;
+ }
return false;
}
@@ -6030,7 +6032,7 @@ static bool isVarDeclStrongDefinition(const ASTContext &Context,
return true;
if (const auto *RT = VarType->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
for (const FieldDecl *FD : RD->fields()) {
if (FD->isBitField())
continue;
@@ -6737,7 +6739,7 @@ QualType CodeGenModule::getObjCFastEnumerationStateType() {
}
D->completeDefinition();
- ObjCFastEnumerationStateType = Context.getTagDeclType(D);
+ ObjCFastEnumerationStateType = Context.getCanonicalTagType(D);
}
return ObjCFastEnumerationStateType;
@@ -7247,7 +7249,8 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
CXXRecordDecl *CRD = cast<CXXRecordDecl>(D);
if (CGDebugInfo *DI = getModuleDebugInfo()) {
if (CRD->hasDefinition())
- DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(D)));
+ DI->EmitAndRetainType(
+ getContext().getCanonicalTagType(cast<RecordDecl>(D)));
if (auto *ES = D->getASTContext().getExternalSource())
if (ES->hasExternalDefinitions(D) == ExternalASTSource::EK_Never)
DI->completeUnusedClass(*CRD);
@@ -7466,20 +7469,23 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) {
case Decl::Typedef:
case Decl::TypeAlias: // using foo = bar; [C++11]
if (CGDebugInfo *DI = getModuleDebugInfo())
- DI->EmitAndRetainType(
- getContext().getTypedefType(cast<TypedefNameDecl>(D)));
+ DI->EmitAndRetainType(getContext().getTypedefType(
+ ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt,
+ cast<TypedefNameDecl>(D)));
break;
case Decl::Record:
if (CGDebugInfo *DI = getModuleDebugInfo())
if (cast<RecordDecl>(D)->getDefinition())
- DI->EmitAndRetainType(getContext().getRecordType(cast<RecordDecl>(D)));
+ DI->EmitAndRetainType(
+ getContext().getCanonicalTagType(cast<RecordDecl>(D)));
break;
case Decl::Enum:
if (CGDebugInfo *DI = getModuleDebugInfo())
if (cast<EnumDecl>(D)->getDefinition())
- DI->EmitAndRetainType(getContext().getEnumType(cast<EnumDecl>(D)));
+ DI->EmitAndRetainType(
+ getContext().getCanonicalTagType(cast<EnumDecl>(D)));
break;
case Decl::HLSLBuffer:
@@ -7933,8 +7939,8 @@ bool CodeGenModule::NeedAllVtablesTypeId() const {
void CodeGenModule::AddVTableTypeMetadata(llvm::GlobalVariable *VTable,
CharUnits Offset,
const CXXRecordDecl *RD) {
- llvm::Metadata *MD =
- CreateMetadataIdentifierForType(QualType(RD->getTypeForDecl(), 0));
+ CanQualType T = getContext().getCanonicalTagType(RD);
+ llvm::Metadata *MD = CreateMetadataIdentifierForType(T);
VTable->addTypeMetadata(Offset.getQuantity(), MD);
if (CodeGenOpts.SanitizeCfiCrossDso)
diff --git a/clang/lib/CodeGen/CodeGenTBAA.cpp b/clang/lib/CodeGen/CodeGenTBAA.cpp
index a02a009158d12..3dc0859cc5d51 100644
--- a/clang/lib/CodeGen/CodeGenTBAA.cpp
+++ b/clang/lib/CodeGen/CodeGenTBAA.cpp
@@ -143,7 +143,7 @@ static bool TypeHasMayAlias(QualType QTy) {
/// Check if the given type is a valid base type to be used in access tags.
static bool isValidBaseType(QualType QTy) {
if (const RecordType *TTy = QTy->getAs<RecordType>()) {
- const RecordDecl *RD = TTy->getDecl()->getDefinition();
+ const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition();
// Incomplete types are not valid base access types.
if (!RD)
return false;
@@ -311,7 +311,7 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
// This also covers anonymous structs and unions, which have a different
// compatibility rule, but it doesn't matter because you can never have a
// pointer to an anonymous struct or union.
- if (!RT->getDecl()->getDeclName())
+ if (!RT->getOriginalDecl()->getDeclName())
return getAnyPtr(PtrDepth);
// For non-builtin types use the mangled name of the canonical type.
@@ -333,14 +333,15 @@ llvm::MDNode *CodeGenTBAA::getTypeInfoHelper(const Type *Ty) {
// Enum types are distinct types. In C++ they have "underlying types",
// however they aren't related for TBAA.
if (const EnumType *ETy = dyn_cast<EnumType>(Ty)) {
+ const EnumDecl *ED = ETy->getOriginalDecl()->getDefinitionOrSelf();
if (!Features.CPlusPlus)
- return getTypeInfo(ETy->getDecl()->getIntegerType());
+ return getTypeInfo(ED->getIntegerType());
// In C++ mode, types have linkage, so we can rely on the ODR and
// on their mangled names, if they're external.
// TODO: Is there a way to get a program-wide unique name for a
// decl with local linkage or no linkage?
- if (!ETy->getDecl()->isExternallyVisible())
+ if (!ED->isExternallyVisible())
return getChar();
SmallString<256> OutName;
@@ -433,7 +434,7 @@ CodeGenTBAA::CollectFields(uint64_t BaseOffset,
llvm::MDBuilder::TBAAStructField(BaseOffset, Size, TBAATag));
return true;
}
- const RecordDecl *RD = TTy->getDecl()->getDefinition();
+ const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition();
if (RD->hasFlexibleArrayMember())
return false;
@@ -514,7 +515,7 @@ CodeGenTBAA::getTBAAStructInfo(QualType QTy) {
llvm::MDNode *CodeGenTBAA::getBaseTypeInfoHelper(const Type *Ty) {
if (auto *TTy = dyn_cast<RecordType>(Ty)) {
- const RecordDecl *RD = TTy->getDecl()->getDefinition();
+ const RecordDecl *RD = TTy->getOriginalDecl()->getDefinition();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
using TBAAStructField = llvm::MDBuilder::TBAAStructField;
SmallVector<TBAAStructField, 4> Fields;
diff --git a/clang/lib/CodeGen/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index c98503e4bbd26..f2a0a649a88fd 100644
--- a/clang/lib/CodeGen/CodeGenTypes.cpp
+++ b/clang/lib/CodeGen/CodeGenTypes.cpp
@@ -229,12 +229,13 @@ bool CodeGenTypes::isFuncTypeConvertible(const FunctionType *FT) {
/// UpdateCompletedType - When we find the full definition for a TagDecl,
/// replace the 'opaque' type we previously made for it if applicable.
void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
+ CanQualType T = CGM.getContext().getCanonicalTagType(TD);
// If this is an enum being completed, then we flush all non-struct types from
// the cache. This allows function types and other things that may be derived
// from the enum to be recomputed.
if (const EnumDecl *ED = dyn_cast<EnumDecl>(TD)) {
// Only flush the cache if we've actually already converted this type.
- if (TypeCache.count(ED->getTypeForDecl())) {
+ if (TypeCache.count(T->getTypePtr())) {
// Okay, we formed some types based on this. We speculated that the enum
// would be lowered to i32, so we only need to flush the cache if this
// didn't happen.
@@ -255,7 +256,7 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
// Only complete it if we converted it already. If we haven't converted it
// yet, we'll just do it lazily.
- if (RecordDeclTypes.count(Context.getTagDeclType(RD).getTypePtr()))
+ if (RecordDeclTypes.count(T.getTypePtr()))
ConvertRecordDeclType(RD);
// If necessary, provide the full definition of a type only used with a
@@ -265,7 +266,7 @@ void CodeGenTypes::UpdateCompletedType(const TagDecl *TD) {
}
void CodeGenTypes::RefreshTypeCacheForClass(const CXXRecordDecl *RD) {
- QualType T = Context.getRecordType(RD);
+ CanQualType T = Context.getCanonicalTagType(RD);
T = Context.getCanonicalType(T);
const Type *Ty = T.getTypePtr();
@@ -311,11 +312,11 @@ llvm::Type *CodeGenTypes::ConvertFunctionTypeInternal(QualType QFT) {
// Force conversion of all the relevant record types, to make sure
// we re-convert the FunctionType when appropriate.
if (const RecordType *RT = FT->getReturnType()->getAs<RecordType>())
- ConvertRecordDeclType(RT->getDecl());
+ ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf());
if (const FunctionProtoType *FPT = dyn_cast<FunctionProtoType>(FT))
for (unsigned i = 0, e = FPT->getNumParams(); i != e; i++)
if (const RecordType *RT = FPT->getParamType(i)->getAs<RecordType>())
- ConvertRecordDeclType(RT->getDecl());
+ ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf());
SkippedLayout = true;
@@ -373,7 +374,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
// RecordTypes are cached and processed specially.
if (const RecordType *RT = dyn_cast<RecordType>(Ty))
- return ConvertRecordDeclType(RT->getDecl());
+ return ConvertRecordDeclType(RT->getOriginalDecl()->getDefinitionOrSelf());
llvm::Type *CachedType = nullptr;
auto TCI = TypeCache.find(Ty);
@@ -699,7 +700,8 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
break;
case Type::Enum: {
- const EnumDecl *ED = cast<EnumType>(Ty)->getDecl();
+ const EnumDecl *ED =
+ cast<EnumType>(Ty)->getOriginalDecl()->getDefinitionOrSelf();
if (ED->isCompleteDefinition() || ED->isFixed())
return ConvertType(ED->getIntegerType());
// Return a placeholder 'i32' type. This can be changed later when the
@@ -725,8 +727,10 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
case Type::MemberPointer: {
auto *MPTy = cast<MemberPointerType>(Ty);
if (!getCXXABI().isMemberPointerConvertible(MPTy)) {
- auto *C = MPTy->getMostRecentCXXRecordDecl()->getTypeForDecl();
- auto Insertion = RecordsWithOpaqueMemberPointers.try_emplace(C);
+ CanQualType T = CGM.getContext().getCanonicalTagType(
+ MPTy->getMostRecentCXXRecordDecl());
+ auto Insertion =
+ RecordsWithOpaqueMemberPointers.try_emplace(T.getTypePtr());
if (Insertion.second)
Insertion.first->second = llvm::StructType::create(getLLVMContext());
ResultType = Insertion.first->second;
@@ -789,7 +793,7 @@ bool CodeGenModule::isPaddedAtomicType(const AtomicType *type) {
llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {
// TagDecl's are not necessarily unique, instead use the (clang)
// type connected to the decl.
- const Type *Key = Context.getTagDeclType(RD).getTypePtr();
+ const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
llvm::StructType *&Entry = RecordDeclTypes[Key];
@@ -810,7 +814,10 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {
if (const CXXRecordDecl *CRD = dyn_cast<CXXRecordDecl>(RD)) {
for (const auto &I : CRD->bases()) {
if (I.isVirtual()) continue;
- ConvertRecordDeclType(I.getType()->castAs<RecordType>()->getDecl());
+ ConvertRecordDeclType(I.getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf());
}
}
@@ -830,7 +837,7 @@ llvm::StructType *CodeGenTypes::ConvertRecordDeclType(const RecordDecl *RD) {
/// getCGRecordLayout - Return record layout info for the given record decl.
const CGRecordLayout &
CodeGenTypes::getCGRecordLayout(const RecordDecl *RD) {
- const Type *Key = Context.getTagDeclType(RD).getTypePtr();
+ const Type *Key = Context.getCanonicalTagType(RD).getTypePtr();
auto I = CGRecordLayouts.find(Key);
if (I != CGRecordLayouts.end())
@@ -869,7 +876,7 @@ bool CodeGenTypes::isZeroInitializable(QualType T) {
// Records are non-zero-initializable if they contain any
// non-zero-initializable subobjects.
if (const RecordType *RT = T->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
return isZeroInitializable(RD);
}
diff --git a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
index 1ed33894b15aa..ac56dda74abb7 100644
--- a/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/HLSLBufferLayoutBuilder.cpp
@@ -101,7 +101,8 @@ llvm::TargetExtType *HLSLBufferLayoutBuilder::createLayoutType(
const RecordType *RT = RecordTypes.back();
RecordTypes.pop_back();
- for (const auto *FD : RT->getDecl()->fields()) {
+ for (const auto *FD :
+ RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
assert((!PackOffsets || Index < PackOffsets->size()) &&
"number of elements in layout struct does not match number of "
"packoffset annotations");
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index f4a99467010af..f0f7b97c624f7 100644
--- a/clang/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/clang/lib/CodeGen/ItaniumCXXABI.cpp
@@ -826,7 +826,7 @@ CGCallee ItaniumCXXABI::EmitLoadOfMemberFunctionPointer(
for (const CXXRecordDecl *Base : CGM.getMostBaseClasses(RD)) {
llvm::Metadata *MD = CGM.CreateMetadataIdentifierForType(
getContext().getMemberPointerType(MPT->getPointeeType(),
- /*Qualifier=*/nullptr,
+ /*Qualifier=*/std::nullopt,
Base->getCanonicalDecl()));
llvm::Value *TypeId =
llvm::MetadataAsValue::get(CGF.getLLVMContext(), MD);
@@ -1236,7 +1236,7 @@ llvm::Constant *ItaniumCXXABI::EmitMemberPointer(const APValue &MP,
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(MPD)) {
llvm::Constant *Src = BuildMemberPointer(MD, ThisAdjustment);
QualType SrcType = getContext().getMemberPointerType(
- MD->getType(), /*Qualifier=*/nullptr, MD->getParent());
+ MD->getType(), /*Qualifier=*/std::nullopt, MD->getParent());
return pointerAuthResignMemberFunctionPointer(Src, MPType, SrcType, CGM);
}
@@ -1392,8 +1392,9 @@ void ItaniumCXXABI::emitVirtualObjectDelete(CodeGenFunction &CGF,
// to pass to the deallocation function.
// Grab the vtable pointer as an intptr_t*.
- auto *ClassDecl =
- cast<CXXRecordDecl>(ElementType->castAs<RecordType>()->getDecl());
+ auto *ClassDecl = cast<CXXRecordDecl>(
+ ElementType->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
llvm::Value *VTable = CGF.GetVTablePtr(Ptr, CGF.UnqualPtrTy, ClassDecl);
// Track back to entry -2 and pull out the offset there.
@@ -1479,7 +1480,8 @@ void ItaniumCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
// trivial destructor (or isn't a record), we just pass null.
llvm::Constant *Dtor = nullptr;
if (const RecordType *RecordTy = ThrowType->getAs<RecordType>()) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
+ CXXRecordDecl *Record =
+ cast<CXXRecordDecl>(RecordTy->getOriginalDecl())->getDefinitionOrSelf();
if (!Record->hasTrivialDestructor()) {
// __cxa_throw is declared to take its destructor as void (*)(void *). We
// must match that if function pointers can be authenticated with a
@@ -1606,7 +1608,8 @@ llvm::Value *ItaniumCXXABI::EmitTypeid(CodeGenFunction &CGF,
Address ThisPtr,
llvm::Type *StdTypeInfoPtrTy) {
auto *ClassDecl =
- cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
llvm::Value *Value = CGF.GetVTablePtr(ThisPtr, CGM.GlobalsInt8PtrTy,
ClassDecl);
@@ -1763,7 +1766,8 @@ llvm::Value *ItaniumCXXABI::emitDynamicCastToVoid(CodeGenFunction &CGF,
Address ThisAddr,
QualType SrcRecordTy) {
auto *ClassDecl =
- cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(SrcRecordTy->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
llvm::Value *OffsetToTop;
if (CGM.getItaniumVTableContext().isRelativeLayout()) {
// Get the vtable pointer.
@@ -2016,7 +2020,7 @@ void ItaniumCXXABI::emitVTableDefinitions(CodeGenVTables &CGVT,
const VTableLayout &VTLayout = VTContext.getVTableLayout(RD);
llvm::GlobalVariable::LinkageTypes Linkage = CGM.getVTableLinkage(RD);
llvm::Constant *RTTI =
- CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getTagDeclType(RD));
+ CGM.GetAddrOfRTTIDescriptor(CGM.getContext().getCanonicalTagType(RD));
// Create and set the initializer.
ConstantInitBuilder builder(CGM);
@@ -3755,7 +3759,8 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
if (!Context.getLangOpts().RTTI) return false;
if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+ const CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(RecordTy->getOriginalDecl())->getDefinitionOrSelf();
if (!RD->hasDefinition())
return false;
@@ -3789,7 +3794,9 @@ static bool ShouldUseExternalRTTIDescriptor(CodeGenModule &CGM,
/// IsIncompleteClassType - Returns whether the given record type is incomplete.
static bool IsIncompleteClassType(const RecordType *RecordTy) {
- return !RecordTy->getDecl()->isCompleteDefinition();
+ return !RecordTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isCompleteDefinition();
}
/// ContainsIncompleteClassType - Returns whether the given type contains an
@@ -3815,9 +3822,7 @@ static bool ContainsIncompleteClassType(QualType Ty) {
if (const MemberPointerType *MemberPointerTy =
dyn_cast<MemberPointerType>(Ty)) {
// Check if the class type is incomplete.
- const auto *ClassType = cast<RecordType>(
- MemberPointerTy->getMostRecentCXXRecordDecl()->getTypeForDecl());
- if (IsIncompleteClassType(ClassType))
+ if (!MemberPointerTy->getMostRecentCXXRecordDecl()->hasDefinition())
return true;
return ContainsIncompleteClassType(MemberPointerTy->getPointeeType());
@@ -3846,8 +3851,9 @@ static bool CanUseSingleInheritance(const CXXRecordDecl *RD) {
return false;
// Check that the class is dynamic iff the base is.
- auto *BaseDecl =
- cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
+ auto *BaseDecl = cast<CXXRecordDecl>(
+ Base->getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!BaseDecl->isEmpty() &&
BaseDecl->isDynamicClass() != RD->isDynamicClass())
return false;
@@ -3926,7 +3932,8 @@ void ItaniumRTTIBuilder::BuildVTablePointer(const Type *Ty,
case Type::Record: {
const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+ cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!RD->hasDefinition() || !RD->getNumBases()) {
VTableName = ClassTypeInfo;
@@ -4048,7 +4055,8 @@ static llvm::GlobalVariable::LinkageTypes getTypeInfoLinkage(CodeGenModule &CGM,
return llvm::GlobalValue::LinkOnceODRLinkage;
if (const RecordType *Record = dyn_cast<RecordType>(Ty)) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+ const CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(Record->getOriginalDecl())->getDefinitionOrSelf();
if (RD->hasAttr<WeakAttr>())
return llvm::GlobalValue::WeakODRLinkage;
if (CGM.getTriple().isWindowsItaniumEnvironment())
@@ -4212,7 +4220,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
case Type::Record: {
const CXXRecordDecl *RD =
- cast<CXXRecordDecl>(cast<RecordType>(Ty)->getDecl());
+ cast<CXXRecordDecl>(cast<RecordType>(Ty)->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!RD->hasDefinition() || !RD->getNumBases()) {
// We don't need to emit any fields.
break;
@@ -4259,7 +4268,8 @@ llvm::Constant *ItaniumRTTIBuilder::BuildTypeInfo(
if (CGM.getTarget().hasPS4DLLImportExport() &&
GVDLLStorageClass != llvm::GlobalVariable::DLLExportStorageClass) {
if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (RD->hasAttr<DLLExportAttr>() ||
CXXRecordNonInlineHasAttr<DLLExportAttr>(RD))
GVDLLStorageClass = llvm::GlobalVariable::DLLExportStorageClass;
@@ -4363,8 +4373,9 @@ static unsigned ComputeVMIClassTypeInfoFlags(const CXXBaseSpecifier *Base,
unsigned Flags = 0;
- auto *BaseDecl =
- cast<CXXRecordDecl>(Base->getType()->castAs<RecordType>()->getDecl());
+ auto *BaseDecl = cast<CXXRecordDecl>(
+ Base->getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (Base->isVirtual()) {
// Mark the virtual base as seen.
@@ -4464,7 +4475,9 @@ void ItaniumRTTIBuilder::BuildVMIClassTypeInfo(const CXXRecordDecl *RD) {
Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(Base.getType()));
auto *BaseDecl =
- cast<CXXRecordDecl>(Base.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ Base.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
int64_t OffsetFlags = 0;
@@ -4554,9 +4567,8 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
// attributes of the type pointed to.
unsigned Flags = extractPBaseFlags(CGM.getContext(), PointeeTy);
- const auto *ClassType =
- cast<RecordType>(Ty->getMostRecentCXXRecordDecl()->getTypeForDecl());
- if (IsIncompleteClassType(ClassType))
+ const auto *RD = Ty->getMostRecentCXXRecordDecl();
+ if (!RD->hasDefinition())
Flags |= PTI_ContainingClassIncomplete;
llvm::Type *UnsignedIntLTy =
@@ -4574,8 +4586,8 @@ ItaniumRTTIBuilder::BuildPointerToMemberTypeInfo(const MemberPointerType *Ty) {
// __context is a pointer to an abi::__class_type_info corresponding to the
// class type containing the member pointed to
// (e.g., the "A" in "int A::*").
- Fields.push_back(
- ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(QualType(ClassType, 0)));
+ CanQualType T = CGM.getContext().getCanonicalTagType(RD);
+ Fields.push_back(ItaniumRTTIBuilder(CXXABI).BuildTypeInfo(T));
}
llvm::Constant *ItaniumCXXABI::getAddrOfRTTIDescriptor(QualType Ty) {
@@ -5155,7 +5167,7 @@ ItaniumCXXABI::getSignedVirtualMemberFunctionPointer(const CXXMethodDecl *MD) {
.getDecl());
llvm::Constant *thunk = getOrCreateVirtualFunctionPointerThunk(origMD);
QualType funcType = CGM.getContext().getMemberPointerType(
- MD->getType(), /*Qualifier=*/nullptr, MD->getParent());
+ MD->getType(), /*Qualifier=*/std::nullopt, MD->getParent());
return CGM.getMemberFunctionPointer(thunk, funcType);
}
diff --git a/clang/lib/CodeGen/MicrosoftCXXABI.cpp b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
index a181559834296..977c9a27a6ad6 100644
--- a/clang/lib/CodeGen/MicrosoftCXXABI.cpp
+++ b/clang/lib/CodeGen/MicrosoftCXXABI.cpp
@@ -870,7 +870,8 @@ MicrosoftCXXABI::getRecordArgABI(const CXXRecordDecl *RD) const {
// it indirectly. Prior to MSVC version 19.14, passing overaligned
// arguments was not supported and resulted in a compiler error. In 19.14
// and later versions, such arguments are now passed indirectly.
- TypeInfo Info = getContext().getTypeInfo(RD->getTypeForDecl());
+ TypeInfo Info =
+ getContext().getTypeInfo(getContext().getCanonicalTagType(RD));
if (Info.isAlignRequired() && Info.Align > 4)
return RAA_Indirect;
@@ -2918,15 +2919,15 @@ llvm::Constant *MicrosoftCXXABI::EmitMemberPointer(const APValue &MP,
if (!FD)
FD = cast<FieldDecl>(*cast<IndirectFieldDecl>(MPD)->chain_begin());
const CXXRecordDecl *RD = cast<CXXRecordDecl>(FD->getParent());
- RD = RD->getMostRecentNonInjectedDecl();
+ RD = RD->getMostRecentDecl();
C = EmitMemberDataPointer(RD, FieldOffset);
}
if (!MemberPointerPath.empty()) {
const CXXRecordDecl *SrcRD = cast<CXXRecordDecl>(MPD->getDeclContext());
const MemberPointerType *SrcTy =
- Ctx.getMemberPointerType(DstTy->getPointeeType(), /*Qualifier=*/nullptr,
- SrcRD)
+ Ctx.getMemberPointerType(DstTy->getPointeeType(),
+ /*Qualifier=*/std::nullopt, SrcRD)
->castAs<MemberPointerType>();
bool DerivedMember = MP.isMemberPointerToDerivedMember();
@@ -2963,7 +2964,7 @@ MicrosoftCXXABI::EmitMemberFunctionPointer(const CXXMethodDecl *MD) {
assert(MD->isInstance() && "Member function must not be static!");
CharUnits NonVirtualBaseAdjustment = CharUnits::Zero();
- const CXXRecordDecl *RD = MD->getParent()->getMostRecentNonInjectedDecl();
+ const CXXRecordDecl *RD = MD->getParent()->getMostRecentDecl();
CodeGenTypes &Types = CGM.getTypes();
unsigned VBTableIndex = 0;
@@ -3684,7 +3685,7 @@ struct MSRTTIBuilder {
MSRTTIBuilder(MicrosoftCXXABI &ABI, const CXXRecordDecl *RD)
: CGM(ABI.CGM), Context(CGM.getContext()),
VMContext(CGM.getLLVMContext()), Module(CGM.getModule()), RD(RD),
- Linkage(getLinkageForRTTI(CGM.getContext().getTagDeclType(RD))),
+ Linkage(getLinkageForRTTI(CGM.getContext().getCanonicalTagType(RD))),
ABI(ABI) {}
llvm::GlobalVariable *getBaseClassDescriptor(const MSRTTIClass &Classes);
@@ -3858,7 +3859,7 @@ MSRTTIBuilder::getBaseClassDescriptor(const MSRTTIClass &Class) {
// Initialize the BaseClassDescriptor.
llvm::Constant *Fields[] = {
ABI.getImageRelativeConstant(
- ABI.getAddrOfRTTIDescriptor(Context.getTypeDeclType(Class.RD))),
+ ABI.getAddrOfRTTIDescriptor(Context.getCanonicalTagType(Class.RD))),
llvm::ConstantInt::get(CGM.IntTy, Class.NumBases),
llvm::ConstantInt::get(CGM.IntTy, Class.OffsetInVBase),
llvm::ConstantInt::get(CGM.IntTy, VBPtrOffset),
@@ -3905,7 +3906,7 @@ MSRTTIBuilder::getCompleteObjectLocator(const VPtrInfo &Info) {
llvm::ConstantInt::get(CGM.IntTy, OffsetToTop),
llvm::ConstantInt::get(CGM.IntTy, VFPtrOffset),
ABI.getImageRelativeConstant(
- CGM.GetAddrOfRTTIDescriptor(Context.getTypeDeclType(RD))),
+ CGM.GetAddrOfRTTIDescriptor(Context.getCanonicalTagType(RD))),
ABI.getImageRelativeConstant(getClassHierarchyDescriptor()),
ABI.getImageRelativeConstant(COL),
};
@@ -4076,7 +4077,7 @@ MicrosoftCXXABI::getAddrOfCXXCtorClosure(const CXXConstructorDecl *CD,
const CGFunctionInfo &FnInfo = CGM.getTypes().arrangeMSCtorClosure(CD, CT);
llvm::FunctionType *ThunkTy = CGM.getTypes().GetFunctionType(FnInfo);
const CXXRecordDecl *RD = CD->getParent();
- QualType RecordTy = getContext().getRecordType(RD);
+ CanQualType RecordTy = getContext().getCanonicalTagType(RD);
llvm::Function *ThunkFn = llvm::Function::Create(
ThunkTy, getLinkageForRTTI(RecordTy), ThunkName.str(), &CGM.getModule());
ThunkFn->setCallingConv(static_cast<llvm::CallingConv::ID>(
@@ -4312,7 +4313,7 @@ llvm::GlobalVariable *MicrosoftCXXABI::getCatchableTypeArray(QualType T) {
// Turn our record back into a pointer if the exception object is a
// pointer.
- QualType RTTITy = QualType(Class.RD->getTypeForDecl(), 0);
+ CanQualType RTTITy = Context.getCanonicalTagType(Class.RD);
if (IsPointer)
RTTITy = Context.getPointerType(RTTITy);
CatchableTypes.insert(getCatchableType(RTTITy, Class.OffsetInVBase,
@@ -4463,8 +4464,8 @@ void MicrosoftCXXABI::emitThrow(CodeGenFunction &CGF, const CXXThrowExpr *E) {
std::pair<llvm::Value *, const CXXRecordDecl *>
MicrosoftCXXABI::LoadVTablePtr(CodeGenFunction &CGF, Address This,
const CXXRecordDecl *RD) {
- std::tie(This, std::ignore, RD) =
- performBaseAdjustment(CGF, This, QualType(RD->getTypeForDecl(), 0));
+ CanQualType T = CGF.getContext().getCanonicalTagType(RD);
+ std::tie(This, std::ignore, RD) = performBaseAdjustment(CGF, This, T);
return {CGF.GetVTablePtr(This, CGM.Int8PtrTy, RD), RD};
}
diff --git a/clang/lib/CodeGen/SwiftCallingConv.cpp b/clang/lib/CodeGen/SwiftCallingConv.cpp
index 10f9f20bca313..de58e0d95a866 100644
--- a/clang/lib/CodeGen/SwiftCallingConv.cpp
+++ b/clang/lib/CodeGen/SwiftCallingConv.cpp
@@ -66,9 +66,9 @@ void SwiftAggLowering::addTypedData(QualType type, CharUnits begin) {
// Record types.
if (auto recType = type->getAs<RecordType>()) {
- addTypedData(recType->getDecl(), begin);
+ addTypedData(recType->getOriginalDecl(), begin);
- // Array types.
+ // Array types.
} else if (type->isArrayType()) {
// Incomplete array types (flexible array members?) don't provide
// data to lay out, and the other cases shouldn't be possible.
@@ -814,7 +814,7 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type,
bool forReturn) {
unsigned IndirectAS = CGM.getDataLayout().getAllocaAddrSpace();
if (auto recordType = dyn_cast<RecordType>(type)) {
- auto record = recordType->getDecl();
+ auto record = recordType->getOriginalDecl();
auto &layout = CGM.getContext().getASTRecordLayout(record);
if (mustPassRecordIndirectly(CGM, record))
@@ -822,7 +822,8 @@ static ABIArgInfo classifyType(CodeGenModule &CGM, CanQualType type,
/*AddrSpace=*/IndirectAS, /*byval=*/false);
SwiftAggLowering lowering(CGM);
- lowering.addTypedData(recordType->getDecl(), CharUnits::Zero(), layout);
+ lowering.addTypedData(recordType->getOriginalDecl(), CharUnits::Zero(),
+ layout);
lowering.finish();
return classifyExpandedType(lowering, forReturn, layout.getAlignment(),
diff --git a/clang/lib/CodeGen/Targets/AArch64.cpp b/clang/lib/CodeGen/Targets/AArch64.cpp
index b82c46966cf0b..289f8a9dcf211 100644
--- a/clang/lib/CodeGen/Targets/AArch64.cpp
+++ b/clang/lib/CodeGen/Targets/AArch64.cpp
@@ -375,7 +375,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
if (!passAsAggregateType(Ty)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (const auto *EIT = Ty->getAs<BitIntType>())
if (EIT->getNumBits() > 128)
@@ -496,7 +496,7 @@ ABIArgInfo AArch64ABIInfo::classifyArgumentType(QualType Ty, bool IsVariadicFn,
const RecordType *RT = Ty->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
for (const auto &I : CXXRD->bases())
if (!Self(Self, I.getType()))
@@ -548,7 +548,8 @@ ABIArgInfo AArch64ABIInfo::classifyReturnType(QualType RetTy,
if (!passAsAggregateType(RetTy)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy =
+ EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (const auto *EIT = RetTy->getAs<BitIntType>())
if (EIT->getNumBits() > 128)
@@ -744,7 +745,7 @@ bool AArch64ABIInfo::passAsPureScalableType(
return false;
// Pure scalable types are never unions and never contain unions.
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion())
return false;
diff --git a/clang/lib/CodeGen/Targets/AMDGPU.cpp b/clang/lib/CodeGen/Targets/AMDGPU.cpp
index 47a552a7bf495..41bccbb5721b2 100644
--- a/clang/lib/CodeGen/Targets/AMDGPU.cpp
+++ b/clang/lib/CodeGen/Targets/AMDGPU.cpp
@@ -96,7 +96,7 @@ unsigned AMDGPUABIInfo::numRegsForType(QualType Ty) const {
}
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
assert(!RD->hasFlexibleArrayMember());
for (const FieldDecl *Field : RD->fields()) {
@@ -153,7 +153,7 @@ ABIArgInfo AMDGPUABIInfo::classifyReturnType(QualType RetTy) const {
return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0)));
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return DefaultABIInfo::classifyReturnType(RetTy);
}
@@ -246,7 +246,7 @@ ABIArgInfo AMDGPUABIInfo::classifyArgumentType(QualType Ty, bool Variadic,
return ABIArgInfo::getDirect(CGT.ConvertType(QualType(SeltTy, 0)));
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return DefaultABIInfo::classifyArgumentType(Ty);
}
diff --git a/clang/lib/CodeGen/Targets/ARC.cpp b/clang/lib/CodeGen/Targets/ARC.cpp
index c8db7e8f9706e..ace524e1976d9 100644
--- a/clang/lib/CodeGen/Targets/ARC.cpp
+++ b/clang/lib/CodeGen/Targets/ARC.cpp
@@ -106,13 +106,14 @@ ABIArgInfo ARCABIInfo::classifyArgumentType(QualType Ty,
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
auto SizeInRegs = llvm::alignTo(getContext().getTypeSize(Ty), 32) / 32;
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
- if (RT && RT->getDecl()->hasFlexibleArrayMember())
+ if (RT &&
+ RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getIndirectByValue(Ty);
// Ignore empty structs/unions.
diff --git a/clang/lib/CodeGen/Targets/ARM.cpp b/clang/lib/CodeGen/Targets/ARM.cpp
index 68f9e01856486..532ba4cead244 100644
--- a/clang/lib/CodeGen/Targets/ARM.cpp
+++ b/clang/lib/CodeGen/Targets/ARM.cpp
@@ -383,7 +383,7 @@ ABIArgInfo ARMABIInfo::classifyArgumentType(QualType Ty, bool isVariadic,
if (!isAggregateTypeForABI(Ty)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
}
if (const auto *EIT = Ty->getAs<BitIntType>())
@@ -516,7 +516,7 @@ static bool isIntegerLikeType(QualType Ty, ASTContext &Context,
if (!RT) return false;
// Ignore records with flexible arrays.
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return false;
@@ -593,7 +593,8 @@ ABIArgInfo ARMABIInfo::classifyReturnType(QualType RetTy, bool isVariadic,
if (!isAggregateTypeForABI(RetTy)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy =
+ EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (const auto *EIT = RetTy->getAs<BitIntType>())
if (EIT->getNumBits() > 64)
@@ -718,7 +719,7 @@ bool ARMABIInfo::containsAnyFP16Vectors(QualType Ty) const {
return false;
return containsAnyFP16Vectors(AT->getElementType());
} else if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
diff --git a/clang/lib/CodeGen/Targets/BPF.cpp b/clang/lib/CodeGen/Targets/BPF.cpp
index 880a891083c3a..87d50e671d251 100644
--- a/clang/lib/CodeGen/Targets/BPF.cpp
+++ b/clang/lib/CodeGen/Targets/BPF.cpp
@@ -48,7 +48,7 @@ class BPFABIInfo : public DefaultABIInfo {
}
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
ASTContext &Context = getContext();
if (const auto *EIT = Ty->getAs<BitIntType>())
@@ -70,7 +70,8 @@ class BPFABIInfo : public DefaultABIInfo {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy =
+ EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
ASTContext &Context = getContext();
if (const auto *EIT = RetTy->getAs<BitIntType>())
diff --git a/clang/lib/CodeGen/Targets/CSKY.cpp b/clang/lib/CodeGen/Targets/CSKY.cpp
index ef26d483a180a..7e5a16f30727f 100644
--- a/clang/lib/CodeGen/Targets/CSKY.cpp
+++ b/clang/lib/CodeGen/Targets/CSKY.cpp
@@ -116,7 +116,7 @@ ABIArgInfo CSKYABIInfo::classifyArgumentType(QualType Ty, int &ArgGPRsLeft,
if (!isAggregateTypeForABI(Ty)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// All integral types are promoted to XLen width, unless passed on the
// stack.
diff --git a/clang/lib/CodeGen/Targets/Hexagon.cpp b/clang/lib/CodeGen/Targets/Hexagon.cpp
index 2976657360650..0c423429eda4f 100644
--- a/clang/lib/CodeGen/Targets/Hexagon.cpp
+++ b/clang/lib/CodeGen/Targets/Hexagon.cpp
@@ -98,7 +98,7 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty,
if (!isAggregateTypeForABI(Ty)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
uint64_t Size = getContext().getTypeSize(Ty);
if (Size <= 64)
@@ -161,7 +161,8 @@ ABIArgInfo HexagonABIInfo::classifyReturnType(QualType RetTy) const {
if (!isAggregateTypeForABI(RetTy)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy =
+ EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (Size > 64 && RetTy->isBitIntType())
return getNaturalAlignIndirect(
diff --git a/clang/lib/CodeGen/Targets/Lanai.cpp b/clang/lib/CodeGen/Targets/Lanai.cpp
index 6f75bd54a8ef2..08cb36034f6fd 100644
--- a/clang/lib/CodeGen/Targets/Lanai.cpp
+++ b/clang/lib/CodeGen/Targets/Lanai.cpp
@@ -102,7 +102,8 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty,
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
- if (RT && RT->getDecl()->hasFlexibleArrayMember())
+ if (RT &&
+ RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getIndirectResult(Ty, /*ByVal=*/true, State);
// Ignore empty structs/unions.
@@ -125,7 +126,7 @@ ABIArgInfo LanaiABIInfo::classifyArgumentType(QualType Ty,
// Treat an enum type as its underlying type.
if (const auto *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
bool InReg = shouldUseInReg(Ty, State);
diff --git a/clang/lib/CodeGen/Targets/LoongArch.cpp b/clang/lib/CodeGen/Targets/LoongArch.cpp
index 7640f3779816a..af863e6101e2c 100644
--- a/clang/lib/CodeGen/Targets/LoongArch.cpp
+++ b/clang/lib/CodeGen/Targets/LoongArch.cpp
@@ -150,7 +150,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
// Non-zero-length arrays of empty records make the struct ineligible to be
// passed via FARs in C++.
if (const auto *RTy = EltTy->getAs<RecordType>()) {
- if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
+ if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getOriginalDecl()) &&
isEmptyRecord(getContext(), EltTy, true, true))
return false;
}
@@ -169,7 +169,7 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
// copy constructor are not eligible for the FP calling convention.
if (getRecordArgABI(Ty, CGT.getCXXABI()))
return false;
- const RecordDecl *RD = RTy->getDecl();
+ const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf();
if (isEmptyRecord(getContext(), Ty, true, true) &&
(!RD->isUnion() || !isa<CXXRecordDecl>(RD)))
return true;
@@ -181,7 +181,9 @@ bool LoongArchABIInfo::detectFARsEligibleStructHelper(
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
for (const CXXBaseSpecifier &B : CXXRD->bases()) {
const auto *BDecl =
- cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ B.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!detectFARsEligibleStructHelper(
B.getType(), CurOff + Layout.getBaseClassOffset(BDecl),
Field1Ty, Field1Off, Field2Ty, Field2Off))
@@ -369,7 +371,7 @@ ABIArgInfo LoongArchABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// All integral types are promoted to GRLen width.
if (Size < GRLen && Ty->isIntegralOrEnumerationType())
diff --git a/clang/lib/CodeGen/Targets/Mips.cpp b/clang/lib/CodeGen/Targets/Mips.cpp
index c025f7312959c..e12a34ce07bbe 100644
--- a/clang/lib/CodeGen/Targets/Mips.cpp
+++ b/clang/lib/CodeGen/Targets/Mips.cpp
@@ -161,7 +161,7 @@ llvm::Type* MipsABIInfo::HandleAggregates(QualType Ty, uint64_t TySize) const {
return llvm::StructType::get(getVMContext(), ArgList);
}
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
assert(!(TySize % 8) && "Size of structure must be multiple of 8.");
@@ -242,7 +242,7 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// Make sure we pass indirectly things that are too large.
if (const auto *EIT = Ty->getAs<BitIntType>())
@@ -265,7 +265,7 @@ MipsABIInfo::returnAggregateInRegs(QualType RetTy, uint64_t Size) const {
SmallVector<llvm::Type*, 8> RTList;
if (RT && RT->isStructureOrClassType()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
const ASTRecordLayout &Layout = getContext().getASTRecordLayout(RD);
unsigned FieldCnt = Layout.getFieldCount();
@@ -333,7 +333,7 @@ ABIArgInfo MipsABIInfo::classifyReturnType(QualType RetTy) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// Make sure we pass indirectly things that are too large.
if (const auto *EIT = RetTy->getAs<BitIntType>())
diff --git a/clang/lib/CodeGen/Targets/NVPTX.cpp b/clang/lib/CodeGen/Targets/NVPTX.cpp
index 82bdfe2666b52..e874617796f86 100644
--- a/clang/lib/CodeGen/Targets/NVPTX.cpp
+++ b/clang/lib/CodeGen/Targets/NVPTX.cpp
@@ -133,7 +133,7 @@ bool NVPTXABIInfo::isUnsupportedType(QualType T) const {
const auto *RT = T->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
// If this is a C++ record, check the bases first.
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
@@ -174,7 +174,7 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
: ABIArgInfo::getDirect());
@@ -183,7 +183,7 @@ ABIArgInfo NVPTXABIInfo::classifyReturnType(QualType RetTy) const {
ABIArgInfo NVPTXABIInfo::classifyArgumentType(QualType Ty) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// Return aggregates type as indirect by value
if (isAggregateTypeForABI(Ty)) {
diff --git a/clang/lib/CodeGen/Targets/PNaCl.cpp b/clang/lib/CodeGen/Targets/PNaCl.cpp
index 358010785850e..a2610950f24be 100644
--- a/clang/lib/CodeGen/Targets/PNaCl.cpp
+++ b/clang/lib/CodeGen/Targets/PNaCl.cpp
@@ -68,7 +68,7 @@ ABIArgInfo PNaClABIInfo::classifyArgumentType(QualType Ty) const {
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
} else if (const EnumType *EnumTy = Ty->getAs<EnumType>()) {
// Treat an enum type as its underlying type.
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
} else if (Ty->isFloatingType()) {
// Floating-point types don't go inreg.
return ABIArgInfo::getDirect();
@@ -102,7 +102,7 @@ ABIArgInfo PNaClABIInfo::classifyReturnType(QualType RetTy) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
return (isPromotableIntegerTypeForABI(RetTy) ? ABIArgInfo::getExtend(RetTy)
: ABIArgInfo::getDirect());
diff --git a/clang/lib/CodeGen/Targets/PPC.cpp b/clang/lib/CodeGen/Targets/PPC.cpp
index 4df4c9f3c3475..38e76399299ec 100644
--- a/clang/lib/CodeGen/Targets/PPC.cpp
+++ b/clang/lib/CodeGen/Targets/PPC.cpp
@@ -154,7 +154,7 @@ class AIXTargetCodeGenInfo : public TargetCodeGenInfo {
bool AIXABIInfo::isPromotableTypeForABI(QualType Ty) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// Promotable integer types are required to be promoted by the ABI.
if (getContext().isPromotableIntegerType(Ty))
@@ -295,7 +295,9 @@ void AIXTargetCodeGenInfo::setTargetAttributes(
unsigned Alignment = Context.toBits(Context.getDeclAlign(D)) / 8;
const auto *Ty = VarD->getType().getTypePtr();
const RecordDecl *RDecl =
- Ty->isRecordType() ? Ty->getAs<RecordType>()->getDecl() : nullptr;
+ Ty->isRecordType()
+ ? Ty->getAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf()
+ : nullptr;
bool EmitDiagnostic = UserSpecifiedTOC && GV->hasExternalLinkage();
auto reportUnsupportedWarning = [&](bool ShouldEmitWarning, StringRef Msg) {
@@ -707,7 +709,7 @@ bool
PPC64_SVR4_ABIInfo::isPromotableTypeForABI(QualType Ty) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// Promotable integer types are required to be promoted by the ABI.
if (isPromotableIntegerTypeForABI(Ty))
diff --git a/clang/lib/CodeGen/Targets/RISCV.cpp b/clang/lib/CodeGen/Targets/RISCV.cpp
index cc3d487da83b5..6600efad3657b 100644
--- a/clang/lib/CodeGen/Targets/RISCV.cpp
+++ b/clang/lib/CodeGen/Targets/RISCV.cpp
@@ -228,7 +228,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
// Non-zero-length arrays of empty records make the struct ineligible for
// the FP calling convention in C++.
if (const auto *RTy = EltTy->getAs<RecordType>()) {
- if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getDecl()) &&
+ if (ArraySize != 0 && isa<CXXRecordDecl>(RTy->getOriginalDecl()) &&
isEmptyRecord(getContext(), EltTy, true, true))
return false;
}
@@ -250,7 +250,7 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
return false;
if (isEmptyRecord(getContext(), Ty, true, true))
return true;
- const RecordDecl *RD = RTy->getDecl();
+ const RecordDecl *RD = RTy->getOriginalDecl()->getDefinitionOrSelf();
// Unions aren't eligible unless they're empty (which is caught above).
if (RD->isUnion())
return false;
@@ -259,7 +259,9 @@ bool RISCVABIInfo::detectFPCCEligibleStructHelper(QualType Ty, CharUnits CurOff,
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
for (const CXXBaseSpecifier &B : CXXRD->bases()) {
const auto *BDecl =
- cast<CXXRecordDecl>(B.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ B.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
CharUnits BaseOff = Layout.getBaseClassOffset(BDecl);
bool Ret = detectFPCCEligibleStructHelper(B.getType(), CurOff + BaseOff,
Field1Ty, Field1Off, Field2Ty,
@@ -697,7 +699,7 @@ ABIArgInfo RISCVABIInfo::classifyArgumentType(QualType Ty, bool IsFixed,
if (!isAggregateTypeForABI(Ty) && !Ty->isVectorType()) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// All integral types are promoted to XLen width
if (Size < XLen && Ty->isIntegralOrEnumerationType()) {
diff --git a/clang/lib/CodeGen/Targets/SPIR.cpp b/clang/lib/CodeGen/Targets/SPIR.cpp
index a66de79ed7cd1..8daabe48ad3be 100644
--- a/clang/lib/CodeGen/Targets/SPIR.cpp
+++ b/clang/lib/CodeGen/Targets/SPIR.cpp
@@ -119,7 +119,7 @@ ABIArgInfo SPIRVABIInfo::classifyReturnType(QualType RetTy) const {
return DefaultABIInfo::classifyReturnType(RetTy);
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return DefaultABIInfo::classifyReturnType(RetTy);
}
@@ -187,7 +187,7 @@ ABIArgInfo SPIRVABIInfo::classifyArgumentType(QualType Ty) const {
RAA == CGCXXABI::RAA_DirectInMemory);
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return DefaultABIInfo::classifyArgumentType(Ty);
}
@@ -432,7 +432,7 @@ static llvm::Type *getInlineSpirvType(CodeGenModule &CGM,
case SpirvOperandKind::TypeId: {
QualType TypeOperand = Operand.getResultType();
if (auto *RT = TypeOperand->getAs<RecordType>()) {
- auto *RD = RT->getDecl();
+ auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
assert(RD->isCompleteDefinition() &&
"Type completion should have been required in Sema");
diff --git a/clang/lib/CodeGen/Targets/Sparc.cpp b/clang/lib/CodeGen/Targets/Sparc.cpp
index 9642196b78c63..1547bed7ea8b2 100644
--- a/clang/lib/CodeGen/Targets/Sparc.cpp
+++ b/clang/lib/CodeGen/Targets/Sparc.cpp
@@ -238,7 +238,7 @@ SparcV9ABIInfo::classifyType(QualType Ty, unsigned SizeLimit) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// Integer types smaller than a register are extended.
if (Size < 64 && Ty->isIntegerType())
diff --git a/clang/lib/CodeGen/Targets/SystemZ.cpp b/clang/lib/CodeGen/Targets/SystemZ.cpp
index 6ea6c7a546436..38cc4d39126be 100644
--- a/clang/lib/CodeGen/Targets/SystemZ.cpp
+++ b/clang/lib/CodeGen/Targets/SystemZ.cpp
@@ -146,7 +146,7 @@ class SystemZTargetCodeGenInfo : public TargetCodeGenInfo {
bool SystemZABIInfo::isPromotableIntegerTypeForABI(QualType Ty) const {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
// Promotable integer types are required to be promoted by the ABI.
if (ABIInfo::isPromotableIntegerTypeForABI(Ty))
@@ -211,7 +211,7 @@ QualType SystemZABIInfo::GetSingleElementType(QualType Ty) const {
const RecordType *RT = Ty->getAs<RecordType>();
if (RT && RT->isStructureOrClassType()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
QualType Found;
// If this is a C++ record, check the bases first.
@@ -455,7 +455,7 @@ ABIArgInfo SystemZABIInfo::classifyArgumentType(QualType Ty) const {
if (const RecordType *RT = Ty->getAs<RecordType>()) {
// Structures with flexible arrays have variable length, so really
// fail the size test above.
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->hasFlexibleArrayMember())
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
/*ByVal=*/false);
@@ -526,7 +526,7 @@ bool SystemZTargetCodeGenInfo::isVectorTypeBased(const Type *Ty,
return true;
if (const auto *RecordTy = Ty->getAs<RecordType>()) {
- const RecordDecl *RD = RecordTy->getDecl();
+ const RecordDecl *RD = RecordTy->getOriginalDecl()->getDefinitionOrSelf();
if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD))
if (CXXRD->hasDefinition())
for (const auto &I : CXXRD->bases())
diff --git a/clang/lib/CodeGen/Targets/WebAssembly.cpp b/clang/lib/CodeGen/Targets/WebAssembly.cpp
index 9217c78a540a3..ac8dcd2a0540a 100644
--- a/clang/lib/CodeGen/Targets/WebAssembly.cpp
+++ b/clang/lib/CodeGen/Targets/WebAssembly.cpp
@@ -118,7 +118,8 @@ ABIArgInfo WebAssemblyABIInfo::classifyArgumentType(QualType Ty) const {
const RecordType *RT = Ty->getAs<RecordType>();
assert(RT);
bool HasBitField = false;
- for (auto *Field : RT->getDecl()->fields()) {
+ for (auto *Field :
+ RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
if (Field->isBitField()) {
HasBitField = true;
break;
diff --git a/clang/lib/CodeGen/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index 0f59caac2323e..51d144e2f223a 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -359,7 +359,8 @@ bool X86_32ABIInfo::shouldReturnTypeInRegister(QualType Ty,
// Structure types are passed in register if all fields would be
// passed in a register.
- for (const auto *FD : RT->getDecl()->fields()) {
+ for (const auto *FD :
+ RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
// Empty fields are ignored.
if (isEmptyField(Context, FD, true))
continue;
@@ -429,9 +430,9 @@ bool X86_32ABIInfo::canExpandIndirectArgument(QualType Ty) const {
const RecordType *RT = Ty->getAs<RecordType>();
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
uint64_t Size = 0;
- if (const CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ if (const auto *CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
if (!IsWin32StructABI) {
// On non-Windows, we have to conservatively match our old bitcode
// prototypes in order to be ABI-compatible at the bitcode level.
@@ -509,7 +510,9 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
if (isAggregateTypeForABI(RetTy)) {
if (const RecordType *RT = RetTy->getAs<RecordType>()) {
// Structures with flexible arrays are always indirect.
- if (RT->getDecl()->hasFlexibleArrayMember())
+ if (RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember())
return getIndirectReturnResult(RetTy, State);
}
@@ -554,7 +557,7 @@ ABIArgInfo X86_32ABIInfo::classifyReturnType(QualType RetTy,
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (const auto *EIT = RetTy->getAs<BitIntType>())
if (EIT->getNumBits() > 64)
@@ -796,7 +799,8 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
if (isAggregateTypeForABI(Ty)) {
// Structures with flexible arrays are always indirect.
// FIXME: This should not be byval!
- if (RT && RT->getDecl()->hasFlexibleArrayMember())
+ if (RT &&
+ RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getIndirectResult(Ty, true, State);
// Ignore empty structs/unions on non-Windows.
@@ -831,7 +835,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
unsigned AlignInBits = 0;
if (RT) {
const ASTRecordLayout &Layout =
- getContext().getASTRecordLayout(RT->getDecl());
+ getContext().getASTRecordLayout(RT->getOriginalDecl());
AlignInBits = getContext().toBits(Layout.getRequiredAlignment());
} else if (TI.isAlignRequired()) {
AlignInBits = TI.Align;
@@ -883,7 +887,7 @@ ABIArgInfo X86_32ABIInfo::classifyArgumentType(QualType Ty, CCState &State,
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
bool InReg = shouldPrimitiveUseInReg(Ty, State);
@@ -1847,7 +1851,8 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
if (const EnumType *ET = Ty->getAs<EnumType>()) {
// Classify the underlying integer type.
- classify(ET->getDecl()->getIntegerType(), OffsetBase, Lo, Hi, isNamedArg);
+ classify(ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType(),
+ OffsetBase, Lo, Hi, isNamedArg);
return;
}
@@ -2053,7 +2058,7 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
if (getRecordArgABI(RT, getCXXABI()))
return;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
// Assume variable sized types are passed in memory.
if (RD->hasFlexibleArrayMember())
@@ -2070,7 +2075,9 @@ void X86_64ABIInfo::classify(QualType Ty, uint64_t OffsetBase, Class &Lo,
assert(!I.isVirtual() && !I.getType()->isDependentType() &&
"Unexpected base class!");
const auto *Base =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Classify this field.
//
@@ -2184,7 +2191,7 @@ ABIArgInfo X86_64ABIInfo::getIndirectReturnResult(QualType Ty) const {
if (!isAggregateTypeForABI(Ty)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (Ty->isBitIntType())
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace());
@@ -2226,7 +2233,7 @@ ABIArgInfo X86_64ABIInfo::getIndirectResult(QualType Ty,
!Ty->isBitIntType()) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
return (isPromotableIntegerTypeForABI(Ty) ? ABIArgInfo::getExtend(Ty)
: ABIArgInfo::getDirect());
@@ -2347,7 +2354,7 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,
}
if (const RecordType *RT = Ty->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
const ASTRecordLayout &Layout = Context.getASTRecordLayout(RD);
// If this is a C++ record, check the bases first.
@@ -2356,7 +2363,9 @@ static bool BitsContainNoUserData(QualType Ty, unsigned StartBit,
assert(!I.isVirtual() && !I.getType()->isDependentType() &&
"Unexpected base class!");
const auto *Base =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// If the base is after the span we care about, ignore it.
unsigned BaseOffset = Context.toBits(Layout.getBaseClassOffset(Base));
@@ -2633,7 +2642,8 @@ classifyReturnType(QualType RetTy) const {
if (Hi == NoClass && isa<llvm::IntegerType>(ResType)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = RetTy->getAs<EnumType>())
- RetTy = EnumTy->getDecl()->getIntegerType();
+ RetTy =
+ EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (RetTy->isIntegralOrEnumerationType() &&
isPromotableIntegerTypeForABI(RetTy))
@@ -2777,7 +2787,7 @@ X86_64ABIInfo::classifyArgumentType(QualType Ty, unsigned freeIntRegs,
if (Hi == NoClass && isa<llvm::IntegerType>(ResType)) {
// Treat an enum type as its underlying type.
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (Ty->isIntegralOrEnumerationType() &&
isPromotableIntegerTypeForABI(Ty))
@@ -2851,14 +2861,15 @@ ABIArgInfo
X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
unsigned &NeededSSE,
unsigned &MaxVectorWidth) const {
- auto RT = Ty->getAs<RecordType>();
- assert(RT && "classifyRegCallStructType only valid with struct types");
+ auto *RD = cast<RecordType>(Ty.getCanonicalType())
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
- if (RT->getDecl()->hasFlexibleArrayMember())
+ if (RD->hasFlexibleArrayMember())
return getIndirectReturnResult(Ty);
// Sum up bases
- if (auto CXXRD = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (auto CXXRD = dyn_cast<CXXRecordDecl>(RD)) {
if (CXXRD->isDynamicClass()) {
NeededInt = NeededSSE = 0;
return getIndirectReturnResult(Ty);
@@ -2874,7 +2885,7 @@ X86_64ABIInfo::classifyRegCallStructTypeImpl(QualType Ty, unsigned &NeededInt,
}
// Sum up members
- for (const auto *FD : RT->getDecl()->fields()) {
+ for (const auto *FD : RD->fields()) {
QualType MTy = FD->getType();
if (MTy->isRecordType() && !MTy->isUnionType()) {
if (classifyRegCallStructTypeImpl(MTy, NeededInt, NeededSSE,
@@ -3298,7 +3309,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs,
return ABIArgInfo::getIgnore();
if (const EnumType *EnumTy = Ty->getAs<EnumType>())
- Ty = EnumTy->getDecl()->getIntegerType();
+ Ty = EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
TypeInfo Info = getContext().getTypeInfo(Ty);
uint64_t Width = Info.Width;
@@ -3312,7 +3323,7 @@ ABIArgInfo WinX86_64ABIInfo::classify(QualType Ty, unsigned &FreeSSERegs,
RAA == CGCXXABI::RAA_DirectInMemory);
}
- if (RT->getDecl()->hasFlexibleArrayMember())
+ if (RT->getOriginalDecl()->getDefinitionOrSelf()->hasFlexibleArrayMember())
return getNaturalAlignIndirect(Ty, getDataLayout().getAllocaAddrSpace(),
/*ByVal=*/false);
}
diff --git a/clang/lib/CodeGen/Targets/XCore.cpp b/clang/lib/CodeGen/Targets/XCore.cpp
index b7824bde5f55a..aa6947b1d956b 100644
--- a/clang/lib/CodeGen/Targets/XCore.cpp
+++ b/clang/lib/CodeGen/Targets/XCore.cpp
@@ -379,7 +379,7 @@ static bool appendRecordType(SmallStringEnc &Enc, const RecordType *RT,
// We collect all encoded fields and order as necessary.
bool IsRecursive = false;
- const RecordDecl *RD = RT->getDecl()->getDefinition();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
if (RD && !RD->field_empty()) {
// An incomplete TypeString stub is placed in the cache for this RecordType
// so that recursive calls to this RecordType will use it whilst building a
@@ -428,7 +428,7 @@ static bool appendEnumType(SmallStringEnc &Enc, const EnumType *ET,
Enc += "){";
// We collect all encoded enumerations and order them alphanumerically.
- if (const EnumDecl *ED = ET->getDecl()->getDefinition()) {
+ if (const EnumDecl *ED = ET->getOriginalDecl()->getDefinition()) {
SmallVector<FieldEncoding, 16> FE;
for (auto I = ED->enumerator_begin(), E = ED->enumerator_end(); I != E;
++I) {
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 791afc1a97575..d3d549c0127bf 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -205,54 +205,39 @@ DeclarationFragments::getStructureTypeFragment(const RecordDecl *Record) {
// Build declaration fragments for NNS recursively so that we have the USR for
// every part in a qualified name, and also leaves the actual underlying type
// cleaner for its own fragment.
-DeclarationFragments
-DeclarationFragmentsBuilder::getFragmentsForNNS(const NestedNameSpecifier *NNS,
- ASTContext &Context,
- DeclarationFragments &After) {
+DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForNNS(
+ NestedNameSpecifier NNS, ASTContext &Context, DeclarationFragments &After) {
DeclarationFragments Fragments;
- if (NNS->getPrefix())
- Fragments.append(getFragmentsForNNS(NNS->getPrefix(), Context, After));
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- Fragments.append(NNS->getAsIdentifier()->getName(),
- DeclarationFragments::FragmentKind::Identifier);
- break;
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ return Fragments;
- case NestedNameSpecifier::Namespace: {
- const NamespaceDecl *NS = NNS->getAsNamespace();
- if (NS->isAnonymousNamespace())
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
+ Fragments.append(getFragmentsForNNS(Prefix, Context, After));
+ if (const auto *NS = dyn_cast<NamespaceDecl>(Namespace);
+ NS && NS->isAnonymousNamespace())
return Fragments;
SmallString<128> USR;
- index::generateUSRForDecl(NS, USR);
- Fragments.append(NS->getName(),
- DeclarationFragments::FragmentKind::Identifier, USR, NS);
- break;
- }
-
- case NestedNameSpecifier::NamespaceAlias: {
- const NamespaceAliasDecl *Alias = NNS->getAsNamespaceAlias();
- SmallString<128> USR;
- index::generateUSRForDecl(Alias, USR);
- Fragments.append(Alias->getName(),
+ index::generateUSRForDecl(Namespace, USR);
+ Fragments.append(Namespace->getName(),
DeclarationFragments::FragmentKind::Identifier, USR,
- Alias);
+ Namespace);
break;
}
- case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Kind::Global:
// The global specifier `::` at the beginning. No stored value.
break;
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Super:
// Microsoft's `__super` specifier.
Fragments.append("__super", DeclarationFragments::FragmentKind::Keyword);
break;
- case NestedNameSpecifier::TypeSpec: {
- const Type *T = NNS->getAsType();
+ case NestedNameSpecifier::Kind::Type: {
// FIXME: Handle C++ template specialization type
- Fragments.append(getFragmentsForType(T, Context, After));
+ Fragments.append(getFragmentsForType(NNS.getAsType(), Context, After));
break;
}
}
@@ -282,26 +267,6 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
return Fragments;
}
- // An ElaboratedType is a sugar for types that are referred to using an
- // elaborated keyword, e.g., `struct S`, `enum E`, or (in C++) via a
- // qualified name, e.g., `N::M::type`, or both.
- if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(T)) {
- ElaboratedTypeKeyword Keyword = ET->getKeyword();
- if (Keyword != ElaboratedTypeKeyword::None) {
- Fragments
- .append(ElaboratedType::getKeywordName(Keyword),
- DeclarationFragments::FragmentKind::Keyword)
- .appendSpace();
- }
-
- if (const NestedNameSpecifier *NNS = ET->getQualifier())
- Fragments.append(getFragmentsForNNS(NNS, Context, After));
-
- // After handling the elaborated keyword or qualified name, build
- // declaration fragments for the desugared underlying type.
- return Fragments.append(getFragmentsForType(ET->desugar(), Context, After));
- }
-
// If the type is a typedefed type, get the underlying TypedefNameDecl for a
// direct reference to the typedef instead of the wrapped type.
@@ -312,7 +277,18 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
TypedefUnderlyingTypeResolver TypedefResolver(Context);
std::string USR = TypedefResolver.getUSRForType(QualType(T, 0));
- if (T->isObjCIdType()) {
+ if (ElaboratedTypeKeyword Keyword = TypedefTy->getKeyword();
+ Keyword != ElaboratedTypeKeyword::None) {
+ Fragments
+ .append(KeywordHelpers::getKeywordName(Keyword),
+ DeclarationFragments::FragmentKind::Keyword)
+ .appendSpace();
+ }
+
+ Fragments.append(
+ getFragmentsForNNS(TypedefTy->getQualifier(), Context, After));
+
+ if (TypedefTy->isObjCIdType()) {
return Fragments.append(Decl->getName(),
DeclarationFragments::FragmentKind::Keyword);
}
@@ -405,14 +381,26 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
if (const TemplateSpecializationType *TemplSpecTy =
dyn_cast<TemplateSpecializationType>(T)) {
- const auto TemplName = TemplSpecTy->getTemplateName();
+ if (ElaboratedTypeKeyword Keyword = TemplSpecTy->getKeyword();
+ Keyword != ElaboratedTypeKeyword::None)
+ Fragments
+ .append(KeywordHelpers::getKeywordName(Keyword),
+ DeclarationFragments::FragmentKind::Keyword)
+ .appendSpace();
+
+ auto TemplName = TemplSpecTy->getTemplateName();
std::string Str;
raw_string_ostream Stream(Str);
TemplName.print(Stream, Context.getPrintingPolicy(),
TemplateName::Qualified::AsWritten);
SmallString<64> USR("");
+ if (const auto *QTN = TemplName.getAsQualifiedTemplateName()) {
+ Fragments.append(getFragmentsForNNS(QTN->getQualifier(), Context, After));
+ TemplName = QTN->getUnderlyingTemplate();
+ }
if (const auto *TemplDecl = TemplName.getAsTemplateDecl())
index::generateUSRForDecl(TemplDecl, USR);
+ // FIXME: Handle other kinds of TemplateNames.
return Fragments
.append(Str, DeclarationFragments::FragmentKind::TypeIdentifier, USR)
@@ -422,14 +410,19 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
.append(">", DeclarationFragments::FragmentKind::Text);
}
- // Everything we care about has been handled now, reduce to the canonical
- // unqualified base type.
- QualType Base = T->getCanonicalTypeUnqualified();
-
// If the base type is a TagType (struct/interface/union/class/enum), let's
// get the underlying Decl for better names and USRs.
- if (const TagType *TagTy = dyn_cast<TagType>(Base)) {
- const TagDecl *Decl = TagTy->getDecl();
+ if (const TagType *TagTy = dyn_cast<TagType>(T)) {
+ if (ElaboratedTypeKeyword Keyword = TagTy->getKeyword();
+ Keyword != ElaboratedTypeKeyword::None)
+ Fragments
+ .append(KeywordHelpers::getKeywordName(Keyword),
+ DeclarationFragments::FragmentKind::Keyword)
+ .appendSpace();
+
+ Fragments.append(getFragmentsForNNS(TagTy->getQualifier(), Context, After));
+
+ const TagDecl *Decl = TagTy->getOriginalDecl();
// Anonymous decl, skip this fragment.
if (Decl->getName().empty())
return Fragments.append("{ ... }",
@@ -441,6 +434,10 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType(
TagUSR, Decl);
}
+ // Everything we care about has been handled now, reduce to the canonical
+ // unqualified base type.
+ QualType Base = T->getCanonicalTypeUnqualified();
+
// If the base type is an ObjCInterfaceType, use the underlying
// ObjCInterfaceDecl for the true USR.
if (const auto *ObjCIT = dyn_cast<ObjCInterfaceType>(Base)) {
diff --git a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp
index 41e4e0cf1795f..5adbbc6d1c34c 100644
--- a/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp
+++ b/clang/lib/ExtractAPI/TypedefUnderlyingTypeResolver.cpp
@@ -26,7 +26,7 @@ TypedefUnderlyingTypeResolver::getUnderlyingTypeDecl(QualType Type) const {
if (TypedefTy)
TypeDecl = TypedefTy->getDecl();
if (const TagType *TagTy = Type->getAs<TagType>()) {
- TypeDecl = TagTy->getDecl();
+ TypeDecl = TagTy->getOriginalDecl();
} else if (const ObjCInterfaceType *ObjCITy =
Type->getAs<ObjCInterfaceType>()) {
TypeDecl = ObjCITy->getDecl();
diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp
index ab8a35a189250..67c8761511e0c 100644
--- a/clang/lib/Frontend/ASTConsumers.cpp
+++ b/clang/lib/Frontend/ASTConsumers.cpp
@@ -97,6 +97,7 @@ namespace {
Out << "Not a DeclContext\n";
} else if (OutputKind == Print) {
PrintingPolicy Policy(D->getASTContext().getLangOpts());
+ Policy.IncludeTagDefinition = true;
D->print(Out, Policy, /*Indentation=*/0, /*PrintInstantiation=*/true);
} else if (OutputKind != None) {
D->dump(Out, OutputKind == DumpFull, OutputFormat);
@@ -112,8 +113,10 @@ namespace {
// FIXME: Support combining -ast-dump-decl-types with -ast-dump-lookups.
if (auto *VD = dyn_cast<ValueDecl>(InnerD))
VD->getType().dump(Out, VD->getASTContext());
- if (auto *TD = dyn_cast<TypeDecl>(InnerD))
- TD->getTypeForDecl()->dump(Out, TD->getASTContext());
+ if (auto *TD = dyn_cast<TypeDecl>(InnerD)) {
+ const ASTContext &Ctx = TD->getASTContext();
+ Ctx.getTypeDeclType(TD)->dump(Out, Ctx);
+ }
}
}
diff --git a/clang/lib/Frontend/ASTUnit.cpp b/clang/lib/Frontend/ASTUnit.cpp
index 4ebec8e074330..2f2cc12b3fe30 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -395,7 +395,7 @@ void ASTUnit::CacheCodeCompletionResults() {
// Keep track of the type of this completion in an ASTContext-agnostic
// way.
- QualType UsageType = getDeclUsageType(*Ctx, R.Declaration);
+ QualType UsageType = getDeclUsageType(*Ctx, R.Qualifier, R.Declaration);
if (UsageType.isNull()) {
CachedResult.TypeClass = STC_Void;
CachedResult.Type = 0;
diff --git a/clang/lib/Index/IndexTypeSourceInfo.cpp b/clang/lib/Index/IndexTypeSourceInfo.cpp
index 98b5513128fbe..8868aea53f10b 100644
--- a/clang/lib/Index/IndexTypeSourceInfo.cpp
+++ b/clang/lib/Index/IndexTypeSourceInfo.cpp
@@ -59,7 +59,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
bool VisitTypedefTypeLoc(TypedefTypeLoc TL) {
SourceLocation Loc = TL.getNameLoc();
- TypedefNameDecl *ND = TL.getTypedefNameDecl();
+ TypedefNameDecl *ND = TL.getDecl();
if (ND->isTransparentTag()) {
TagDecl *Underlying = ND->getUnderlyingType()->getAsTagDecl();
return IndexCtx.handleReference(Underlying, Loc, Parent,
@@ -117,7 +117,7 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
}
bool VisitTagTypeLoc(TagTypeLoc TL) {
- TagDecl *D = TL.getDecl();
+ TagDecl *D = TL.getOriginalDecl();
if (!IndexCtx.shouldIndexFunctionLocalSymbols() &&
D->getParentFunctionOrMethod())
return true;
@@ -172,7 +172,8 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
return true;
}
- bool TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL) {
+ bool TraverseTemplateSpecializationTypeLoc(TemplateSpecializationTypeLoc TL,
+ bool TraverseQualifier) {
if (!WalkUpFromTemplateSpecializationTypeLoc(TL))
return false;
if (!TraverseTemplateName(TL.getTypePtr()->getTemplateName()))
@@ -202,11 +203,6 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
return true;
}
- bool VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- return IndexCtx.handleReference(TL.getDecl(), TL.getNameLoc(), Parent,
- ParentDC, SymbolRoleSet(), Relations);
- }
-
bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
std::vector<const NamedDecl *> Symbols =
IndexCtx.getResolver()->resolveDependentNameType(TL.getTypePtr());
@@ -248,36 +244,28 @@ void IndexingContext::indexTypeLoc(TypeLoc TL,
TypeIndexer(*this, Parent, DC, isBase, isIBType).TraverseTypeLoc(TL);
}
-void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
- const NamedDecl *Parent,
- const DeclContext *DC) {
- if (!NNS)
- return;
-
- if (NestedNameSpecifierLoc Prefix = NNS.getPrefix())
- indexNestedNameSpecifierLoc(Prefix, Parent, DC);
-
+void IndexingContext::indexNestedNameSpecifierLoc(
+ NestedNameSpecifierLoc QualifierLoc, const NamedDecl *Parent,
+ const DeclContext *DC) {
if (!DC)
DC = Parent->getLexicalDeclContext();
- SourceLocation Loc = NNS.getLocalBeginLoc();
-
- switch (NNS.getNestedNameSpecifier()->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
+ switch (NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
+ Qualifier.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
break;
- case NestedNameSpecifier::Namespace:
- handleReference(NNS.getNestedNameSpecifier()->getAsNamespace(),
- Loc, Parent, DC, SymbolRoleSet());
- break;
- case NestedNameSpecifier::NamespaceAlias:
- handleReference(NNS.getNestedNameSpecifier()->getAsNamespaceAlias(),
- Loc, Parent, DC, SymbolRoleSet());
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = QualifierLoc.castAsNamespaceAndPrefix();
+ indexNestedNameSpecifierLoc(Prefix, Parent, DC);
+ handleReference(Namespace, QualifierLoc.getLocalBeginLoc(), Parent, DC,
+ SymbolRoleSet());
break;
+ }
- case NestedNameSpecifier::TypeSpec:
- indexTypeLoc(NNS.getTypeLoc(), Parent, DC);
+ case NestedNameSpecifier::Kind::Type:
+ indexTypeLoc(QualifierLoc.castAsTypeLoc(), Parent, DC);
break;
}
}
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 6a884f7be00e1..9e69ca567e80c 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -653,14 +653,14 @@ bool USRGenerator::GenLoc(const Decl *D, bool IncludeOffset) {
}
static void printQualifier(llvm::raw_ostream &Out, const LangOptions &LangOpts,
- NestedNameSpecifier *NNS) {
+ NestedNameSpecifier NNS) {
// FIXME: Encode the qualifier, don't just print it.
PrintingPolicy PO(LangOpts);
PO.SuppressTagKeyword = true;
PO.SuppressUnwrittenScope = true;
PO.ConstantArraySizeAsWritten = false;
PO.AnonymousTagLocations = false;
- NNS->print(Out, PO);
+ NNS.print(Out, PO);
}
void USRGenerator::VisitType(QualType T) {
@@ -910,9 +910,13 @@ void USRGenerator::VisitType(QualType T) {
continue;
}
if (const TagType *TT = T->getAs<TagType>()) {
- Out << '$';
- VisitTagDecl(TT->getDecl());
- return;
+ if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TT)) {
+ T = ICNT->getCanonicalInjectedTST();
+ } else {
+ Out << '$';
+ VisitTagDecl(TT->getOriginalDecl());
+ return;
+ }
}
if (const ObjCInterfaceType *OIT = T->getAs<ObjCInterfaceType>()) {
Out << '$';
@@ -945,10 +949,6 @@ void USRGenerator::VisitType(QualType T) {
Out << ':' << DNT->getIdentifier()->getName();
return;
}
- if (const InjectedClassNameType *InjT = T->getAs<InjectedClassNameType>()) {
- T = InjT->getInjectedSpecializationType();
- continue;
- }
if (const auto *VT = T->getAs<VectorType>()) {
Out << (T->isExtVectorType() ? ']' : '[');
Out << VT->getNumElements();
diff --git a/clang/lib/InstallAPI/Visitor.cpp b/clang/lib/InstallAPI/Visitor.cpp
index 487be2c300887..f12e04069817b 100644
--- a/clang/lib/InstallAPI/Visitor.cpp
+++ b/clang/lib/InstallAPI/Visitor.cpp
@@ -424,7 +424,7 @@ std::string
InstallAPIVisitor::getMangledCXXRTTIName(const CXXRecordDecl *D) const {
SmallString<256> Name;
raw_svector_ostream NameStream(Name);
- MC->mangleCXXRTTIName(QualType(D->getTypeForDecl(), 0), NameStream);
+ MC->mangleCXXRTTIName(MC->getASTContext().getCanonicalTagType(D), NameStream);
return getBackendMangledName(Name);
}
@@ -432,7 +432,7 @@ InstallAPIVisitor::getMangledCXXRTTIName(const CXXRecordDecl *D) const {
std::string InstallAPIVisitor::getMangledCXXRTTI(const CXXRecordDecl *D) const {
SmallString<256> Name;
raw_svector_ostream NameStream(Name);
- MC->mangleCXXRTTI(QualType(D->getTypeForDecl(), 0), NameStream);
+ MC->mangleCXXRTTI(MC->getASTContext().getCanonicalTagType(D), NameStream);
return getBackendMangledName(Name);
}
@@ -543,8 +543,8 @@ void InstallAPIVisitor::emitVTableSymbols(const CXXRecordDecl *D,
}
for (const auto &It : D->bases()) {
- const CXXRecordDecl *Base =
- cast<CXXRecordDecl>(It.getType()->castAs<RecordType>()->getDecl());
+ const CXXRecordDecl *Base = cast<CXXRecordDecl>(
+ It.getType()->castAs<RecordType>()->getOriginalDecl());
const auto BaseAccess = getAccessForDecl(Base);
if (!BaseAccess)
continue;
diff --git a/clang/lib/Interpreter/InterpreterValuePrinter.cpp b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
index 3e7e32b2e8557..00f9a7a631e36 100644
--- a/clang/lib/Interpreter/InterpreterValuePrinter.cpp
+++ b/clang/lib/Interpreter/InterpreterValuePrinter.cpp
@@ -324,7 +324,7 @@ extern "C" void REPL_EXTERNAL_VISIBILITY __clang_Interpreter_SetValueNoAlloc(
VRef.setPtr(va_arg(args, void *));
} else {
if (const auto *ET = QT->getAs<EnumType>())
- QT = ET->getDecl()->getIntegerType();
+ QT = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
switch (QT->castAs<BuiltinType>()->getKind()) {
default:
llvm_unreachable("unknown type kind!");
diff --git a/clang/lib/Interpreter/Value.cpp b/clang/lib/Interpreter/Value.cpp
index afdf406b37253..526cca80a983a 100644
--- a/clang/lib/Interpreter/Value.cpp
+++ b/clang/lib/Interpreter/Value.cpp
@@ -99,7 +99,7 @@ static Value::Kind ConvertQualTypeToKind(const ASTContext &Ctx, QualType QT) {
return Value::K_Void;
if (const auto *ET = QT->getAs<EnumType>())
- QT = ET->getDecl()->getIntegerType();
+ QT = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
const auto *BT = QT->getAs<BuiltinType>();
if (!BT || BT->isNullPtrType())
@@ -145,9 +145,9 @@ Value::Value(Interpreter *In, void *Ty) : Interp(In), OpaqueType(Ty) {
}
if (const auto *RT = DtorTy->getAs<RecordType>()) {
if (CXXRecordDecl *CXXRD =
- llvm::dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ llvm::dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
if (llvm::Expected<llvm::orc::ExecutorAddr> Addr =
- Interp.CompileDtorCall(CXXRD))
+ Interp.CompileDtorCall(CXXRD->getDefinitionOrSelf()))
DtorF = reinterpret_cast<void *>(Addr->getValue());
else
llvm::logAllUnhandledErrors(Addr.takeError(), llvm::errs());
diff --git a/clang/lib/Parse/ParseDeclCXX.cpp b/clang/lib/Parse/ParseDeclCXX.cpp
index eae8281964692..779958230ada2 100644
--- a/clang/lib/Parse/ParseDeclCXX.cpp
+++ b/clang/lib/Parse/ParseDeclCXX.cpp
@@ -591,8 +591,7 @@ bool Parser::ParseUsingDeclarator(DeclaratorContext Context,
NextToken().isRegularKeywordAttribute() ||
NextToken().is(tok::kw___attribute)) &&
D.SS.isNotEmpty() && LastII == Tok.getIdentifierInfo() &&
- !D.SS.getScopeRep()->getAsNamespace() &&
- !D.SS.getScopeRep()->getAsNamespaceAlias()) {
+ D.SS.getScopeRep().getKind() != NestedNameSpecifier::Kind::Namespace) {
SourceLocation IdLoc = ConsumeToken();
ParsedType Type =
Actions.getInheritingConstructorName(D.SS, IdLoc, *LastII);
diff --git a/clang/lib/Parse/ParseExprCXX.cpp b/clang/lib/Parse/ParseExprCXX.cpp
index 8dce2268082d9..8605ba2cdb49b 100644
--- a/clang/lib/Parse/ParseExprCXX.cpp
+++ b/clang/lib/Parse/ParseExprCXX.cpp
@@ -195,9 +195,10 @@ bool Parser::ParseOptionalCXXScopeSpecifier(
if (DS.getTypeSpecType() == DeclSpec::TST_error)
return false;
- QualType Type = Actions.ActOnPackIndexingType(
- DS.getRepAsType().get(), DS.getPackIndexingExpr(), DS.getBeginLoc(),
- DS.getEllipsisLoc());
+ QualType Pattern = Sema::GetTypeFromParser(DS.getRepAsType());
+ QualType Type =
+ Actions.ActOnPackIndexingType(Pattern, DS.getPackIndexingExpr(),
+ DS.getBeginLoc(), DS.getEllipsisLoc());
if (Type.isNull())
return false;
@@ -2355,8 +2356,10 @@ bool Parser::ParseUnqualifiedIdTemplateId(
// Constructor and destructor names.
TypeResult Type = Actions.ActOnTemplateIdType(
- getCurScope(), SS, TemplateKWLoc, Template, Name, NameLoc, LAngleLoc,
- TemplateArgsPtr, RAngleLoc, /*IsCtorOrDtorName=*/true);
+ getCurScope(), ElaboratedTypeKeyword::None,
+ /*ElaboratedKeywordLoc=*/SourceLocation(), SS, TemplateKWLoc, Template,
+ Name, NameLoc, LAngleLoc, TemplateArgsPtr, RAngleLoc,
+ /*IsCtorOrDtorName=*/true);
if (Type.isInvalid())
return true;
diff --git a/clang/lib/Parse/ParseTemplate.cpp b/clang/lib/Parse/ParseTemplate.cpp
index 9a04bf298c0ac..004cb40445eab 100644
--- a/clang/lib/Parse/ParseTemplate.cpp
+++ b/clang/lib/Parse/ParseTemplate.cpp
@@ -1109,12 +1109,14 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
// Build the annotation token.
if (TNK == TNK_Type_template && AllowTypeAnnotation) {
- TypeResult Type = ArgsInvalid
- ? TypeError()
- : Actions.ActOnTemplateIdType(
- getCurScope(), SS, TemplateKWLoc, Template,
- TemplateName.Identifier, TemplateNameLoc,
- LAngleLoc, TemplateArgsPtr, RAngleLoc);
+ TypeResult Type =
+ ArgsInvalid
+ ? TypeError()
+ : Actions.ActOnTemplateIdType(
+ getCurScope(), ElaboratedTypeKeyword::None,
+ /*ElaboratedKeywordLoc=*/SourceLocation(), SS, TemplateKWLoc,
+ Template, TemplateName.Identifier, TemplateNameLoc, LAngleLoc,
+ TemplateArgsPtr, RAngleLoc);
Tok.setKind(tok::annot_typename);
setTypeAnnotation(Tok, Type);
@@ -1175,10 +1177,11 @@ void Parser::AnnotateTemplateIdTokenAsType(
TemplateId->isInvalid()
? TypeError()
: Actions.ActOnTemplateIdType(
- getCurScope(), SS, TemplateId->TemplateKWLoc,
- TemplateId->Template, TemplateId->Name,
- TemplateId->TemplateNameLoc, TemplateId->LAngleLoc,
- TemplateArgsPtr, TemplateId->RAngleLoc,
+ getCurScope(), ElaboratedTypeKeyword::None,
+ /*ElaboratedKeywordLoc=*/SourceLocation(), SS,
+ TemplateId->TemplateKWLoc, TemplateId->Template,
+ TemplateId->Name, TemplateId->TemplateNameLoc,
+ TemplateId->LAngleLoc, TemplateArgsPtr, TemplateId->RAngleLoc,
/*IsCtorOrDtorName=*/false, IsClassName, AllowImplicitTypename);
// Create the new "type" annotation token.
Tok.setKind(tok::annot_typename);
@@ -1243,7 +1246,8 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
Actions.ActOnTemplateName(getCurScope(), SS, TemplateKWLoc, Name,
/*ObjectType=*/nullptr,
/*EnteringContext=*/false, Template))
- Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
+ Result = ParsedTemplateArgument(TemplateKWLoc, SS, Template,
+ Name.StartLocation);
}
} else if (Tok.is(tok::identifier)) {
// We may have a (non-dependent) template name.
@@ -1264,7 +1268,8 @@ ParsedTemplateArgument Parser::ParseTemplateTemplateArgument() {
if (TNK == TNK_Dependent_template_name || TNK == TNK_Type_template) {
// We have an id-expression that refers to a class template or
// (C++0x) alias template.
- Result = ParsedTemplateArgument(SS, Template, Name.StartLocation);
+ Result = ParsedTemplateArgument(/*TemplateKwLoc=*/SourceLocation(), SS,
+ Template, Name.StartLocation);
}
}
}
diff --git a/clang/lib/Parse/ParseTentative.cpp b/clang/lib/Parse/ParseTentative.cpp
index 95cee824c40b7..5a4b1740f5fb5 100644
--- a/clang/lib/Parse/ParseTentative.cpp
+++ b/clang/lib/Parse/ParseTentative.cpp
@@ -1326,7 +1326,7 @@ Parser::isCXXDeclarationSpecifier(ImplicitTypenameContext AllowImplicitTypename,
Actions.RestoreNestedNameSpecifierAnnotation(Tok.getAnnotationValue(),
Tok.getAnnotationRange(),
SS);
- if (SS.getScopeRep() && SS.getScopeRep()->isDependent()) {
+ if (SS.getScopeRep().isDependent()) {
RevertingTentativeParsingAction PA(*this);
ConsumeAnnotationToken();
ConsumeToken();
diff --git a/clang/lib/Parse/Parser.cpp b/clang/lib/Parse/Parser.cpp
index 8834bf80c4016..1ddc59a5b6fe3 100644
--- a/clang/lib/Parse/Parser.cpp
+++ b/clang/lib/Parse/Parser.cpp
@@ -1774,9 +1774,9 @@ Parser::TryAnnotateName(CorrectionCandidateCallback *CCC,
/// An Objective-C object type followed by '<' is a specialization of
/// a parameterized class type or a protocol-qualified type.
ParsedType Ty = Classification.getType();
+ QualType T = Actions.GetTypeFromParser(Ty);
if (getLangOpts().ObjC && NextToken().is(tok::less) &&
- (Ty.get()->isObjCObjectType() ||
- Ty.get()->isObjCObjectPointerType())) {
+ (T->isObjCObjectType() || T->isObjCObjectPointerType())) {
// Consume the name.
SourceLocation IdentifierLoc = ConsumeToken();
SourceLocation NewEndLoc;
@@ -2031,11 +2031,12 @@ bool Parser::TryAnnotateTypeOrScopeTokenAfterScopeSpec(
if (SS.isNotEmpty()) // it was a C++ qualified type name.
BeginLoc = SS.getBeginLoc();
+ QualType T = Actions.GetTypeFromParser(Ty);
+
/// An Objective-C object type followed by '<' is a specialization of
/// a parameterized class type or a protocol-qualified type.
if (getLangOpts().ObjC && NextToken().is(tok::less) &&
- (Ty.get()->isObjCObjectType() ||
- Ty.get()->isObjCObjectPointerType())) {
+ (T->isObjCObjectType() || T->isObjCObjectPointerType())) {
// Consume the name.
SourceLocation IdentifierLoc = ConsumeToken();
SourceLocation NewEndLoc;
diff --git a/clang/lib/Sema/AnalysisBasedWarnings.cpp b/clang/lib/Sema/AnalysisBasedWarnings.cpp
index 7420ba2d461c6..6fcf02fc4ce37 100644
--- a/clang/lib/Sema/AnalysisBasedWarnings.cpp
+++ b/clang/lib/Sema/AnalysisBasedWarnings.cpp
@@ -223,14 +223,11 @@ static bool hasRecursiveCallInPath(const FunctionDecl *FD, CFGBlock &Block) {
// Skip function calls which are qualified with a templated class.
if (const DeclRefExpr *DRE =
- dyn_cast<DeclRefExpr>(CE->getCallee()->IgnoreParenImpCasts())) {
- if (NestedNameSpecifier *NNS = DRE->getQualifier()) {
- if (NNS->getKind() == NestedNameSpecifier::TypeSpec &&
- isa<TemplateSpecializationType>(NNS->getAsType())) {
+ dyn_cast<DeclRefExpr>(CE->getCallee()->IgnoreParenImpCasts()))
+ if (NestedNameSpecifier NNS = DRE->getQualifier();
+ NNS.getKind() == NestedNameSpecifier::Kind::Type)
+ if (isa_and_nonnull<TemplateSpecializationType>(NNS.getAsType()))
continue;
- }
- }
- }
const CXXMemberCallExpr *MCE = dyn_cast<CXXMemberCallExpr>(CE);
if (!MCE || isa<CXXThisExpr>(MCE->getImplicitObjectArgument()) ||
diff --git a/clang/lib/Sema/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index ee5a862c32509..cc385abc3059d 100644
--- a/clang/lib/Sema/DeclSpec.cpp
+++ b/clang/lib/Sema/DeclSpec.cpp
@@ -48,9 +48,9 @@ void UnqualifiedId::setConstructorTemplateId(TemplateIdAnnotation *TemplateId) {
EndLocation = TemplateId->RAngleLoc;
}
-void CXXScopeSpec::Extend(ASTContext &Context, TypeLoc TL,
- SourceLocation ColonColonLoc) {
- Builder.Extend(Context, TL, ColonColonLoc);
+void CXXScopeSpec::Make(ASTContext &Context, TypeLoc TL,
+ SourceLocation ColonColonLoc) {
+ Builder.Make(Context, TL, ColonColonLoc);
if (Range.getBegin().isInvalid())
Range.setBegin(TL.getBeginLoc());
Range.setEnd(ColonColonLoc);
@@ -59,20 +59,7 @@ void CXXScopeSpec::Extend(ASTContext &Context, TypeLoc TL,
"NestedNameSpecifierLoc range computation incorrect");
}
-void CXXScopeSpec::Extend(ASTContext &Context, IdentifierInfo *Identifier,
- SourceLocation IdentifierLoc,
- SourceLocation ColonColonLoc) {
- Builder.Extend(Context, Identifier, IdentifierLoc, ColonColonLoc);
-
- if (Range.getBegin().isInvalid())
- Range.setBegin(IdentifierLoc);
- Range.setEnd(ColonColonLoc);
-
- assert(Range == Builder.getSourceRange() &&
- "NestedNameSpecifierLoc range computation incorrect");
-}
-
-void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
+void CXXScopeSpec::Extend(ASTContext &Context, NamespaceBaseDecl *Namespace,
SourceLocation NamespaceLoc,
SourceLocation ColonColonLoc) {
Builder.Extend(Context, Namespace, NamespaceLoc, ColonColonLoc);
@@ -85,19 +72,6 @@ void CXXScopeSpec::Extend(ASTContext &Context, NamespaceDecl *Namespace,
"NestedNameSpecifierLoc range computation incorrect");
}
-void CXXScopeSpec::Extend(ASTContext &Context, NamespaceAliasDecl *Alias,
- SourceLocation AliasLoc,
- SourceLocation ColonColonLoc) {
- Builder.Extend(Context, Alias, AliasLoc, ColonColonLoc);
-
- if (Range.getBegin().isInvalid())
- Range.setBegin(AliasLoc);
- Range.setEnd(ColonColonLoc);
-
- assert(Range == Builder.getSourceRange() &&
- "NestedNameSpecifierLoc range computation incorrect");
-}
-
void CXXScopeSpec::MakeGlobal(ASTContext &Context,
SourceLocation ColonColonLoc) {
Builder.MakeGlobal(Context, ColonColonLoc);
@@ -121,7 +95,7 @@ void CXXScopeSpec::MakeSuper(ASTContext &Context, CXXRecordDecl *RD,
}
void CXXScopeSpec::MakeTrivial(ASTContext &Context,
- NestedNameSpecifier *Qualifier, SourceRange R) {
+ NestedNameSpecifier Qualifier, SourceRange R) {
Builder.MakeTrivial(Context, Qualifier, R);
Range = R;
}
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index e5c6220bfb47d..94ea7af88f923 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
@@ -313,9 +313,6 @@ TemplateParameterListBuilder::finalizeTemplateArgs(ConceptDecl *CD) {
Builder.Record->getDeclContext()->addDecl(Builder.Template);
Params.clear();
- QualType T = Builder.Template->getInjectedClassNameSpecialization();
- T = AST.getInjectedClassNameType(Builder.Record, T);
-
return Builder;
}
@@ -351,7 +348,7 @@ BuiltinTypeMethodBuilder::BuiltinTypeMethodBuilder(BuiltinTypeDeclBuilder &DB,
ASTContext &AST = DB.SemaRef.getASTContext();
if (IsCtor) {
Name = AST.DeclarationNames.getCXXConstructorName(
- DB.Record->getTypeForDecl()->getCanonicalTypeUnqualified());
+ AST.getCanonicalTagType(DB.Record));
} else {
const IdentifierInfo &II =
AST.Idents.get(NameStr, tok::TokenKind::identifier);
@@ -553,9 +550,9 @@ BuiltinTypeDeclBuilder::BuiltinTypeDeclBuilder(Sema &SemaRef,
return;
}
- Record = CXXRecordDecl::Create(AST, TagDecl::TagKind::Class, HLSLNamespace,
- SourceLocation(), SourceLocation(), &II,
- PrevDecl, true);
+ Record =
+ CXXRecordDecl::Create(AST, TagDecl::TagKind::Class, HLSLNamespace,
+ SourceLocation(), SourceLocation(), &II, PrevDecl);
Record->setImplicit(true);
Record->setLexicalDeclContext(HLSLNamespace);
Record->setHasExternalLexicalStorage();
@@ -570,18 +567,6 @@ BuiltinTypeDeclBuilder::~BuiltinTypeDeclBuilder() {
HLSLNamespace->addDecl(Record);
}
-CXXRecordDecl *BuiltinTypeDeclBuilder::finalizeForwardDeclaration() {
- // Force the QualType to be generated for the record declaration. In most
- // cases this will happen naturally when something uses the type the
- // QualType gets lazily created. Unfortunately, with our injected types if a
- // type isn't used in a translation unit the QualType may not get
- // automatically generated before a PCH is generated. To resolve this we
- // just force that the QualType is generated after we create a forward
- // declaration.
- (void)Record->getASTContext().getRecordType(Record);
- return Record;
-}
-
BuiltinTypeDeclBuilder &
BuiltinTypeDeclBuilder::addMemberVariable(StringRef Name, QualType Type,
llvm::ArrayRef<Attr *> Attrs,
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
index a52e2938104c7..d54b7ddd1adb1 100644
--- a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
+++ b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h
@@ -64,7 +64,7 @@ class BuiltinTypeDeclBuilder {
BuiltinTypeDeclBuilder &addSimpleTemplateParams(ArrayRef<StringRef> Names,
ConceptDecl *CD);
- CXXRecordDecl *finalizeForwardDeclaration();
+ CXXRecordDecl *finalizeForwardDeclaration() { return Record; }
BuiltinTypeDeclBuilder &completeDefinition();
BuiltinTypeDeclBuilder &
diff --git a/clang/lib/Sema/HeuristicResolver.cpp b/clang/lib/Sema/HeuristicResolver.cpp
index 6874d30516f8f..9c56dd356421e 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -44,7 +44,7 @@ class HeuristicResolverImpl {
resolveDependentNameType(const DependentNameType *DNT);
std::vector<const NamedDecl *> resolveTemplateSpecializationType(
const DependentTemplateSpecializationType *DTST);
- QualType resolveNestedNameSpecifierToType(const NestedNameSpecifier *NNS);
+ QualType resolveNestedNameSpecifierToType(NestedNameSpecifier NNS);
QualType getPointeeType(QualType T);
std::vector<const NamedDecl *>
lookupDependentName(CXXRecordDecl *RD, DeclarationName Name,
@@ -101,9 +101,8 @@ QualType resolveDeclsToType(const std::vector<const NamedDecl *> &Decls,
ASTContext &Ctx) {
if (Decls.size() != 1) // Names an overload set -- just bail.
return QualType();
- if (const auto *TD = dyn_cast<TypeDecl>(Decls[0])) {
- return Ctx.getTypeDeclType(TD);
- }
+ if (const auto *TD = dyn_cast<TypeDecl>(Decls[0]))
+ return Ctx.getCanonicalTypeDeclType(TD);
if (const auto *VD = dyn_cast<ValueDecl>(Decls[0])) {
return VD->getType();
}
@@ -139,8 +138,7 @@ TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
T = T->getCanonicalTypeInternal().getTypePtr();
}
- if (auto *TT = T->getAs<TagType>()) {
- TagDecl *TD = TT->getDecl();
+ if (auto *TD = T->getAsTagDecl()) {
// Template might not be instantiated yet, fall back to primary template
// in such cases.
if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(TD)) {
@@ -151,11 +149,6 @@ TagDecl *HeuristicResolverImpl::resolveTypeToTagDecl(QualType QT) {
return TD;
}
- if (const auto *ICNT = T->getAs<InjectedClassNameType>())
- T = ICNT->getInjectedSpecializationType().getTypePtrOrNull();
- if (!T)
- return nullptr;
-
TemplateName TN = getReferencedTemplateName(T);
if (TN.isNull())
return nullptr;
@@ -292,7 +285,7 @@ std::vector<const NamedDecl *> HeuristicResolverImpl::resolveMemberExpr(
// an instance method, it's represented as a CXXDependentScopeMemberExpr
// with `this` as the base expression as `X` as the qualifier
// (which could be valid if `X` names a base class after instantiation).
- if (NestedNameSpecifier *NNS = ME->getQualifier()) {
+ if (NestedNameSpecifier NNS = ME->getQualifier()) {
if (QualType QualifierType = resolveNestedNameSpecifierToType(NNS);
!QualifierType.isNull()) {
auto Decls =
@@ -348,7 +341,10 @@ HeuristicResolverImpl::resolveCalleeOfCallExpr(const CallExpr *CE) {
std::vector<const NamedDecl *> HeuristicResolverImpl::resolveUsingValueDecl(
const UnresolvedUsingValueDecl *UUVD) {
- return resolveDependentMember(QualType(UUVD->getQualifier()->getAsType(), 0),
+ NestedNameSpecifier Qualifier = UUVD->getQualifier();
+ if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
+ return {};
+ return resolveDependentMember(QualType(Qualifier.getAsType(), 0),
UUVD->getNameInfo().getName(), ValueFilter);
}
@@ -399,23 +395,23 @@ QualType HeuristicResolverImpl::resolveExprToType(const Expr *E) {
}
QualType HeuristicResolverImpl::resolveNestedNameSpecifierToType(
- const NestedNameSpecifier *NNS) {
- if (!NNS)
- return QualType();
-
+ NestedNameSpecifier NNS) {
// The purpose of this function is to handle the dependent (Kind ==
// Identifier) case, but we need to recurse on the prefix because
// that may be dependent as well, so for convenience handle
// the TypeSpec cases too.
- switch (NNS->getKind()) {
- case NestedNameSpecifier::TypeSpec:
- return QualType(NNS->getAsType(), 0);
- case NestedNameSpecifier::Identifier: {
- return resolveDeclsToType(
- resolveDependentMember(
- resolveNestedNameSpecifierToType(NNS->getPrefix()),
- NNS->getAsIdentifier(), TypeFilter),
- Ctx);
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Type: {
+ const auto *T = NNS.getAsType();
+ // FIXME: Should this handle the DependentTemplateSpecializationType as
+ // well?
+ if (const auto *DTN = dyn_cast<DependentNameType>(T))
+ return resolveDeclsToType(
+ resolveDependentMember(
+ resolveNestedNameSpecifierToType(DTN->getQualifier()),
+ DTN->getIdentifier(), TypeFilter),
+ Ctx);
+ return QualType(T, 0);
}
default:
break;
@@ -590,7 +586,7 @@ HeuristicResolver::resolveTemplateSpecializationType(
return HeuristicResolverImpl(Ctx).resolveTemplateSpecializationType(DTST);
}
QualType HeuristicResolver::resolveNestedNameSpecifierToType(
- const NestedNameSpecifier *NNS) const {
+ NestedNameSpecifier NNS) const {
return HeuristicResolverImpl(Ctx).resolveNestedNameSpecifierToType(NNS);
}
std::vector<const NamedDecl *> HeuristicResolver::lookupDependentName(
diff --git a/clang/lib/Sema/Sema.cpp b/clang/lib/Sema/Sema.cpp
index 56608e990fd50..48ec4a48b9e63 100644
--- a/clang/lib/Sema/Sema.cpp
+++ b/clang/lib/Sema/Sema.cpp
@@ -1882,9 +1882,10 @@ class DeferredDiagnosticsEmitter
for (const FieldDecl *FD : RD->fields()) {
QualType FT = FD->getType();
if (const auto *RT = FT->getAs<RecordType>())
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
- if (ClassDecl->hasDefinition())
- if (CXXDestructorDecl *MemberDtor = ClassDecl->getDestructor())
+ if (const auto *ClassDecl =
+ dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
+ if (const auto *Def = ClassDecl->getDefinition())
+ if (CXXDestructorDecl *MemberDtor = Def->getDestructor())
asImpl().visitUsedDecl(MemberDtor->getLocation(), MemberDtor);
}
@@ -1892,9 +1893,10 @@ class DeferredDiagnosticsEmitter
for (const auto &Base : RD->bases()) {
QualType BaseType = Base.getType();
if (const auto *RT = BaseType->getAs<RecordType>())
- if (const auto *BaseDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
- if (BaseDecl->hasDefinition())
- if (CXXDestructorDecl *BaseDtor = BaseDecl->getDestructor())
+ if (const auto *BaseDecl =
+ dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
+ if (const auto *Def = BaseDecl->getDefinition())
+ if (CXXDestructorDecl *BaseDtor = Def->getDestructor())
asImpl().visitUsedDecl(BaseDtor->getLocation(), BaseDtor);
}
}
@@ -1907,9 +1909,10 @@ class DeferredDiagnosticsEmitter
VD->needsDestruction(S.Context)) {
QualType VT = VD->getType();
if (const auto *RT = VT->getAs<RecordType>())
- if (const auto *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl()))
- if (ClassDecl->hasDefinition())
- if (CXXDestructorDecl *Dtor = ClassDecl->getDestructor())
+ if (const auto *ClassDecl =
+ dyn_cast<CXXRecordDecl>(RT->getOriginalDecl()))
+ if (const auto *Def = ClassDecl->getDefinition())
+ if (CXXDestructorDecl *Dtor = Def->getDestructor())
asImpl().visitUsedDecl(Dtor->getLocation(), Dtor);
}
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 39328b76a10c4..ba560d3c52340 100644
--- a/clang/lib/Sema/SemaAccess.cpp
+++ b/clang/lib/Sema/SemaAccess.cpp
@@ -318,11 +318,8 @@ static AccessResult IsDerivedFromInclusive(const CXXRecordDecl *Derived,
const CXXRecordDecl *RD;
QualType T = I.getType();
- if (const RecordType *RT = T->getAs<RecordType>()) {
- RD = cast<CXXRecordDecl>(RT->getDecl());
- } else if (const InjectedClassNameType *IT
- = T->getAs<InjectedClassNameType>()) {
- RD = IT->getDecl();
+ if (CXXRecordDecl *Rec = T->getAsCXXRecordDecl()) {
+ RD = Rec;
} else {
assert(T->isDependentType() && "non-dependent base wasn't a record?");
OnFailure = AR_dependent;
@@ -443,7 +440,9 @@ static AccessResult MatchesFriend(Sema &S,
const EffectiveContext &EC,
CanQualType Friend) {
if (const RecordType *RT = Friend->getAs<RecordType>())
- return MatchesFriend(S, EC, cast<CXXRecordDecl>(RT->getDecl()));
+ return MatchesFriend(
+ S, EC,
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf());
// TODO: we can do better than this
if (Friend->isDependentType())
@@ -671,11 +670,8 @@ struct ProtectedFriendContext {
const CXXRecordDecl *RD;
QualType T = I.getType();
- if (const RecordType *RT = T->getAs<RecordType>()) {
- RD = cast<CXXRecordDecl>(RT->getDecl());
- } else if (const InjectedClassNameType *IT
- = T->getAs<InjectedClassNameType>()) {
- RD = IT->getDecl();
+ if (CXXRecordDecl *Rec = T->getAsCXXRecordDecl()) {
+ RD = Rec;
} else {
assert(T->isDependentType() && "non-dependent base wasn't a record?");
EverDependent = true;
@@ -1072,7 +1068,7 @@ static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
// TODO: it would be great to have a fixit here, since this is
// such an obvious error.
S.Diag(D->getLocation(), diag::note_access_protected_restricted_noobject)
- << S.Context.getTypeDeclType(ECRecord);
+ << S.Context.getCanonicalTagType(ECRecord);
return true;
}
@@ -1101,7 +1097,7 @@ static bool TryDiagnoseProtectedAccess(Sema &S, const EffectiveContext &EC,
// Otherwise, use the generic diagnostic.
return S.Diag(D->getLocation(),
diag::note_access_protected_restricted_object)
- << S.Context.getTypeDeclType(ECRecord);
+ << S.Context.getCanonicalTagType(ECRecord);
}
return false;
@@ -1129,7 +1125,8 @@ static void diagnoseBadDirectAccess(Sema &S,
else if (TypedefNameDecl *TND = dyn_cast<TypedefNameDecl>(D))
PrevDecl = TND->getPreviousDecl();
else if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- if (isa<RecordDecl>(D) && cast<RecordDecl>(D)->isInjectedClassName())
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(TD);
+ RD && RD->isInjectedClassName())
break;
PrevDecl = TD->getPreviousDecl();
}
@@ -1283,10 +1280,10 @@ static void DiagnoseBadAccess(Sema &S, SourceLocation Loc,
NamedDecl *D = (Entity.isMemberAccess() ? Entity.getTargetDecl() : nullptr);
S.Diag(Loc, Entity.getDiag())
- << (Entity.getAccess() == AS_protected)
- << (D ? D->getDeclName() : DeclarationName())
- << S.Context.getTypeDeclType(NamingClass)
- << S.Context.getTypeDeclType(DeclaringClass);
+ << (Entity.getAccess() == AS_protected)
+ << (D ? D->getDeclName() : DeclarationName())
+ << S.Context.getCanonicalTagType(NamingClass)
+ << S.Context.getCanonicalTagType(DeclaringClass);
DiagnoseAccessPath(S, EC, Entity);
}
@@ -1639,7 +1636,8 @@ Sema::AccessResult Sema::CheckDestructorAccess(SourceLocation Loc,
return AR_accessible;
CXXRecordDecl *NamingClass = Dtor->getParent();
- if (ObjectTy.isNull()) ObjectTy = Context.getTypeDeclType(NamingClass);
+ if (ObjectTy.isNull())
+ ObjectTy = Context.getCanonicalTagType(NamingClass);
AccessTarget Entity(Context, AccessTarget::Member, NamingClass,
DeclAccessPair::make(Dtor, Access),
@@ -1727,7 +1725,7 @@ Sema::AccessResult Sema::CheckConstructorAccess(SourceLocation UseLoc,
AccessTarget AccessEntity(
Context, AccessTarget::Member, NamingClass,
DeclAccessPair::make(Constructor, Found.getAccess()),
- Context.getTypeDeclType(ObjectClass));
+ Context.getCanonicalTagType(ObjectClass));
AccessEntity.setDiag(PD);
return CheckAccess(*this, UseLoc, AccessEntity);
@@ -1775,7 +1773,7 @@ Sema::CheckStructuredBindingMemberAccess(SourceLocation UseLoc,
return AR_accessible;
AccessTarget Entity(Context, AccessTarget::Member, DecomposedClass, Field,
- Context.getRecordType(DecomposedClass));
+ Context.getCanonicalTagType(DecomposedClass));
Entity.setDiag(diag::err_decomp_decl_inaccessible_field);
return CheckAccess(*this, UseLoc, Entity);
@@ -1789,7 +1787,8 @@ Sema::AccessResult Sema::CheckMemberOperatorAccess(SourceLocation OpLoc,
return AR_accessible;
const RecordType *RT = ObjectExpr->getType()->castAs<RecordType>();
- CXXRecordDecl *NamingClass = cast<CXXRecordDecl>(RT->getDecl());
+ CXXRecordDecl *NamingClass =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
AccessTarget Entity(Context, AccessTarget::Member, NamingClass, Found,
ObjectExpr->getType());
diff --git a/clang/lib/Sema/SemaAvailability.cpp b/clang/lib/Sema/SemaAvailability.cpp
index 8c6a17301fba6..778941c128bdd 100644
--- a/clang/lib/Sema/SemaAvailability.cpp
+++ b/clang/lib/Sema/SemaAvailability.cpp
@@ -102,7 +102,7 @@ Sema::ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message,
break;
for (const Type *T = TD->getUnderlyingType().getTypePtr(); /**/; /**/) {
if (auto *TT = dyn_cast<TagType>(T)) {
- D = TT->getDecl();
+ D = TT->getOriginalDecl()->getDefinitionOrSelf();
} else if (isa<SubstTemplateTypeParmType>(T)) {
// A Subst* node represents a use through a template.
// Any uses of the underlying declaration happened through it's template
@@ -1011,7 +1011,7 @@ bool DiagnoseUnguardedAvailability::VisitTypeLoc(TypeLoc Ty) {
return true;
if (const auto *TT = dyn_cast<TagType>(TyPtr)) {
- TagDecl *TD = TT->getDecl();
+ TagDecl *TD = TT->getOriginalDecl()->getDefinitionOrSelf();
DiagnoseDeclAvailability(TD, Range);
} else if (const auto *TD = dyn_cast<TypedefType>(TyPtr)) {
diff --git a/clang/lib/Sema/SemaBPF.cpp b/clang/lib/Sema/SemaBPF.cpp
index 7c00084d62dd9..6428435ed9d2a 100644
--- a/clang/lib/Sema/SemaBPF.cpp
+++ b/clang/lib/Sema/SemaBPF.cpp
@@ -58,10 +58,10 @@ static bool isValidPreserveTypeInfoArg(Expr *Arg) {
// Record type or Enum type.
const Type *Ty = ArgType->getUnqualifiedDesugaredType();
if (const auto *RT = Ty->getAs<RecordType>()) {
- if (!RT->getDecl()->getDeclName().isEmpty())
+ if (!RT->getOriginalDecl()->getDeclName().isEmpty())
return true;
} else if (const auto *ET = Ty->getAs<EnumType>()) {
- if (!ET->getDecl()->getDeclName().isEmpty())
+ if (!ET->getOriginalDecl()->getDeclName().isEmpty())
return true;
}
@@ -105,7 +105,7 @@ static bool isValidPreserveEnumValueArg(Expr *Arg) {
return false;
// The enum value must be supported.
- return llvm::is_contained(ET->getDecl()->enumerators(), Enumerator);
+ return llvm::is_contained(ET->getOriginalDecl()->enumerators(), Enumerator);
}
bool SemaBPF::CheckBPFBuiltinFunctionCall(unsigned BuiltinID,
diff --git a/clang/lib/Sema/SemaCUDA.cpp b/clang/lib/Sema/SemaCUDA.cpp
index 24cb8c369790b..fbf64d3d57050 100644
--- a/clang/lib/Sema/SemaCUDA.cpp
+++ b/clang/lib/Sema/SemaCUDA.cpp
@@ -426,7 +426,8 @@ bool SemaCUDA::inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
continue;
}
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+ CXXRecordDecl *BaseClassDecl =
+ cast<CXXRecordDecl>(BaseType->getOriginalDecl())->getDefinitionOrSelf();
Sema::SpecialMemberOverloadResult SMOR =
SemaRef.LookupSpecialMember(BaseClassDecl, CSM,
/* ConstArg */ ConstRHS,
@@ -471,7 +472,9 @@ bool SemaCUDA::inferTargetForImplicitSpecialMember(CXXRecordDecl *ClassDecl,
continue;
}
- CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(FieldType->getDecl());
+ CXXRecordDecl *FieldRecDecl =
+ cast<CXXRecordDecl>(FieldType->getOriginalDecl())
+ ->getDefinitionOrSelf();
Sema::SpecialMemberOverloadResult SMOR =
SemaRef.LookupSpecialMember(FieldRecDecl, CSM,
/* ConstArg */ ConstRHS && !F->isMutable(),
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index ab83f625d2849..fefcfdcdb3fd4 100644
--- a/clang/lib/Sema/SemaCXXScopeSpec.cpp
+++ b/clang/lib/Sema/SemaCXXScopeSpec.cpp
@@ -28,24 +28,21 @@ static CXXRecordDecl *getCurrentInstantiationOf(QualType T,
if (T.isNull())
return nullptr;
- const Type *Ty = T->getCanonicalTypeInternal().getTypePtr();
- if (const RecordType *RecordTy = dyn_cast<RecordType>(Ty)) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(RecordTy->getDecl());
- if (Record->isCurrentInstantiation(CurContext))
- return Record;
-
- return nullptr;
- } else if (isa<InjectedClassNameType>(Ty))
- return cast<InjectedClassNameType>(Ty)->getDecl();
- else
+ const TagType *TagTy = dyn_cast<TagType>(T->getCanonicalTypeInternal());
+ if (!isa_and_present<RecordType, InjectedClassNameType>(TagTy))
return nullptr;
+ auto *RD =
+ cast<CXXRecordDecl>(TagTy->getOriginalDecl())->getDefinitionOrSelf();
+ if (isa<InjectedClassNameType>(TagTy) ||
+ RD->isCurrentInstantiation(CurContext))
+ return RD;
+ return nullptr;
}
DeclContext *Sema::computeDeclContext(QualType T) {
if (!T->isDependentType())
- if (const TagType *Tag = T->getAs<TagType>())
- return Tag->getDecl();
-
+ if (auto *D = T->getAsTagDecl())
+ return D;
return ::getCurrentInstantiationOf(T, CurContext);
}
@@ -54,18 +51,17 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
if (!SS.isSet() || SS.isInvalid())
return nullptr;
- NestedNameSpecifier *NNS = SS.getScopeRep();
- if (NNS->isDependent()) {
+ NestedNameSpecifier NNS = SS.getScopeRep();
+ if (NNS.isDependent()) {
// If this nested-name-specifier refers to the current
// instantiation, return its DeclContext.
if (CXXRecordDecl *Record = getCurrentInstantiationOf(NNS))
return Record;
if (EnteringContext) {
- const Type *NNSType = NNS->getAsType();
- if (!NNSType) {
+ if (NNS.getKind() != NestedNameSpecifier::Kind::Type)
return nullptr;
- }
+ const Type *NNSType = NNS.getAsType();
// Look through type alias templates, per C++0x [temp.dep.type]p1.
NNSType = Context.getCanonicalType(NNSType);
@@ -118,41 +114,39 @@ DeclContext *Sema::computeDeclContext(const CXXScopeSpec &SS,
// If the type of the nested name specifier is the same as the
// injected class name of the named class template, we're entering
// into that class template definition.
- QualType Injected =
- ClassTemplate->getInjectedClassNameSpecialization();
+ CanQualType Injected =
+ ClassTemplate->getCanonicalInjectedSpecializationType(Context);
if (Context.hasSameType(Injected, QualType(SpecType, 0)))
return ClassTemplate->getTemplatedDecl();
}
- } else if (const RecordType *RecordT = NNSType->getAs<RecordType>()) {
+ } else if (const auto *RecordT = dyn_cast<RecordType>(NNSType)) {
// The nested name specifier refers to a member of a class template.
- return RecordT->getDecl();
+ return RecordT->getOriginalDecl()->getDefinitionOrSelf();
}
}
return nullptr;
}
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- llvm_unreachable("Dependent nested-name-specifier has no DeclContext");
-
- case NestedNameSpecifier::Namespace:
- return NNS->getAsNamespace();
-
- case NestedNameSpecifier::NamespaceAlias:
- return NNS->getAsNamespaceAlias()->getNamespace();
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Namespace:
+ return const_cast<NamespaceDecl *>(
+ NNS.getAsNamespaceAndPrefix().Namespace->getNamespace());
- case NestedNameSpecifier::TypeSpec: {
- const TagType *Tag = NNS->getAsType()->getAs<TagType>();
- assert(Tag && "Non-tag type in nested-name-specifier");
- return Tag->getDecl();
+ case NestedNameSpecifier::Kind::Type: {
+ auto *TD = NNS.getAsType()->getAsTagDecl();
+ assert(TD && "Non-tag type in nested-name-specifier");
+ return TD;
}
- case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Kind::Global:
return Context.getTranslationUnitDecl();
- case NestedNameSpecifier::Super:
- return NNS->getAsRecordDecl();
+ case NestedNameSpecifier::Kind::Super:
+ return NNS.getAsSuper();
+
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
@@ -162,17 +156,17 @@ bool Sema::isDependentScopeSpecifier(const CXXScopeSpec &SS) {
if (!SS.isSet() || SS.isInvalid())
return false;
- return SS.getScopeRep()->isDependent();
+ return SS.getScopeRep().isDependent();
}
-CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier *NNS) {
+CXXRecordDecl *Sema::getCurrentInstantiationOf(NestedNameSpecifier NNS) {
assert(getLangOpts().CPlusPlus && "Only callable in C++");
- assert(NNS->isDependent() && "Only dependent nested-name-specifier allowed");
+ assert(NNS.isDependent() && "Only dependent nested-name-specifier allowed");
- if (!NNS->getAsType())
+ if (NNS.getKind() != NestedNameSpecifier::Kind::Type)
return nullptr;
- QualType T = QualType(NNS->getAsType(), 0);
+ QualType T = QualType(NNS.getAsType(), 0);
return ::getCurrentInstantiationOf(T, CurContext);
}
@@ -198,8 +192,7 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
return false;
// Grab the tag definition, if there is one.
- QualType type = Context.getTypeDeclType(tag);
- tag = type->getAsTagDecl();
+ tag = tag->getDefinitionOrSelf();
// If we're currently defining this type, then lookup into the
// type is okay: don't complain that it isn't complete yet.
@@ -210,7 +203,8 @@ bool Sema::RequireCompleteDeclContext(CXXScopeSpec &SS,
if (loc.isInvalid()) loc = SS.getRange().getBegin();
// The type must be complete.
- if (RequireCompleteType(loc, type, diag::err_incomplete_nested_name_spec,
+ if (RequireCompleteType(loc, Context.getCanonicalTagType(tag),
+ diag::err_incomplete_nested_name_spec,
SS.getRange())) {
SS.SetInvalid(SS.getRange());
return true;
@@ -262,10 +256,10 @@ bool Sema::RequireCompleteEnumDecl(EnumDecl *EnumD, SourceLocation L,
if (SS) {
Diag(L, diag::err_incomplete_nested_name_spec)
- << QualType(EnumD->getTypeForDecl(), 0) << SS->getRange();
+ << Context.getCanonicalTagType(EnumD) << SS->getRange();
SS->SetInvalid(SS->getRange());
} else {
- Diag(L, diag::err_incomplete_enum) << QualType(EnumD->getTypeForDecl(), 0);
+ Diag(L, diag::err_incomplete_enum) << Context.getCanonicalTagType(EnumD);
Diag(EnumD->getLocation(), diag::note_declared_at);
}
@@ -327,9 +321,6 @@ bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD,
// Determine whether we have a class (or, in C++11, an enum) or
// a typedef thereof. If so, build the nested-name-specifier.
- QualType T = Context.getTypeDeclType(cast<TypeDecl>(SD));
- if (T->isDependentType())
- return true;
if (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(SD)) {
if (TD->getUnderlyingType()->isRecordType())
return true;
@@ -347,32 +338,42 @@ bool Sema::isAcceptableNestedNameSpecifier(const NamedDecl *SD,
if (IsExtension)
*IsExtension = true;
}
+ if (auto *TD = dyn_cast<TagDecl>(SD)) {
+ if (TD->isDependentType())
+ return true;
+ } else if (Context.getCanonicalTypeDeclType(cast<TypeDecl>(SD))
+ ->isDependentType()) {
+ return true;
+ }
return false;
}
-NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier *NNS) {
- if (!S || !NNS)
+NamedDecl *Sema::FindFirstQualifierInScope(Scope *S, NestedNameSpecifier NNS) {
+ if (!S)
return nullptr;
- while (NNS->getPrefix())
- NNS = NNS->getPrefix();
-
- if (NNS->getKind() != NestedNameSpecifier::Identifier)
- return nullptr;
+ while (NNS.getKind() == NestedNameSpecifier::Kind::Type) {
+ const Type *T = NNS.getAsType();
+ if ((NNS = T->getPrefix()))
+ continue;
- LookupResult Found(*this, NNS->getAsIdentifier(), SourceLocation(),
- LookupNestedNameSpecifierName);
- LookupName(Found, S);
- assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
+ const auto *DNT = dyn_cast<DependentNameType>(T);
+ if (!DNT)
+ break;
- if (!Found.isSingleResult())
- return nullptr;
+ LookupResult Found(*this, DNT->getIdentifier(), SourceLocation(),
+ LookupNestedNameSpecifierName);
+ LookupName(Found, S);
+ assert(!Found.isAmbiguous() && "Cannot handle ambiguities here yet");
- NamedDecl *Result = Found.getFoundDecl();
- if (isAcceptableNestedNameSpecifier(Result))
- return Result;
+ if (!Found.isSingleResult())
+ return nullptr;
+ NamedDecl *Result = Found.getFoundDecl();
+ if (isAcceptableNestedNameSpecifier(Result))
+ return Result;
+ }
return nullptr;
}
@@ -496,7 +497,18 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
// base object type or prior nested-name-specifier, so this
// nested-name-specifier refers to an unknown specialization. Just build
// a dependent nested-name-specifier.
- SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc, IdInfo.CCLoc);
+
+ TypeLocBuilder TLB;
+
+ QualType DTN = Context.getDependentNameType(
+ ElaboratedTypeKeyword::None, SS.getScopeRep(), IdInfo.Identifier);
+ auto DTNL = TLB.push<DependentNameTypeLoc>(DTN);
+ DTNL.setElaboratedKeywordLoc(SourceLocation());
+ DTNL.setNameLoc(IdInfo.IdentifierLoc);
+ DTNL.setQualifierLoc(SS.getWithLocInContext(Context));
+
+ SS.clear();
+ SS.Make(Context, TLB.getTypeLocInContext(Context, DTN), IdInfo.CCLoc);
return false;
}
@@ -602,8 +614,8 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
OuterDecl->getCanonicalDecl() != SD->getCanonicalDecl() &&
(!isa<TypeDecl>(OuterDecl) || !isa<TypeDecl>(SD) ||
!Context.hasSameType(
- Context.getTypeDeclType(cast<TypeDecl>(OuterDecl)),
- Context.getTypeDeclType(cast<TypeDecl>(SD))))) {
+ Context.getCanonicalTypeDeclType(cast<TypeDecl>(OuterDecl)),
+ Context.getCanonicalTypeDeclType(cast<TypeDecl>(SD))))) {
if (ErrorRecoveryLookup)
return true;
@@ -616,7 +628,7 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
// Fall through so that we'll pick the name we found in the object
// type, since that's probably what the user wanted anyway.
- }
+ }
}
if (auto *TD = dyn_cast_or_null<TypedefNameDecl>(SD))
@@ -640,50 +652,44 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
return false;
}
- QualType T =
- Context.getTypeDeclType(cast<TypeDecl>(SD->getUnderlyingDecl()));
-
- if (T->isEnumeralType())
+ const auto *TD = cast<TypeDecl>(SD->getUnderlyingDecl());
+ if (isa<EnumDecl>(TD))
Diag(IdInfo.IdentifierLoc, diag::warn_cxx98_compat_enum_nested_name_spec);
+ QualType T;
TypeLocBuilder TLB;
if (const auto *USD = dyn_cast<UsingShadowDecl>(SD)) {
- T = Context.getUsingType(USD, T);
- TLB.pushTypeSpec(T).setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<InjectedClassNameType>(T)) {
- InjectedClassNameTypeLoc InjectedTL
- = TLB.push<InjectedClassNameTypeLoc>(T);
- InjectedTL.setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<RecordType>(T)) {
- RecordTypeLoc RecordTL = TLB.push<RecordTypeLoc>(T);
- RecordTL.setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<TypedefType>(T)) {
- TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(T);
- TypedefTL.setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<EnumType>(T)) {
- EnumTypeLoc EnumTL = TLB.push<EnumTypeLoc>(T);
- EnumTL.setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<TemplateTypeParmType>(T)) {
- TemplateTypeParmTypeLoc TemplateTypeTL
- = TLB.push<TemplateTypeParmTypeLoc>(T);
- TemplateTypeTL.setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<UnresolvedUsingType>(T)) {
- UnresolvedUsingTypeLoc UnresolvedTL
- = TLB.push<UnresolvedUsingTypeLoc>(T);
- UnresolvedTL.setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<SubstTemplateTypeParmType>(T)) {
- SubstTemplateTypeParmTypeLoc TL
- = TLB.push<SubstTemplateTypeParmTypeLoc>(T);
- TL.setNameLoc(IdInfo.IdentifierLoc);
- } else if (isa<SubstTemplateTypeParmPackType>(T)) {
- SubstTemplateTypeParmPackTypeLoc TL
- = TLB.push<SubstTemplateTypeParmPackTypeLoc>(T);
- TL.setNameLoc(IdInfo.IdentifierLoc);
+ T = Context.getUsingType(ElaboratedTypeKeyword::None, SS.getScopeRep(),
+ USD);
+ TLB.push<UsingTypeLoc>(T).set(/*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context),
+ IdInfo.IdentifierLoc);
+ } else if (const auto *Tag = dyn_cast<TagDecl>(TD)) {
+ T = Context.getTagType(ElaboratedTypeKeyword::None, SS.getScopeRep(), Tag,
+ /*OwnsTag=*/false);
+ auto TTL = TLB.push<TagTypeLoc>(T);
+ TTL.setElaboratedKeywordLoc(SourceLocation());
+ TTL.setQualifierLoc(SS.getWithLocInContext(SemaRef.Context));
+ TTL.setNameLoc(IdInfo.IdentifierLoc);
+ } else if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) {
+ T = Context.getTypedefType(ElaboratedTypeKeyword::None, SS.getScopeRep(),
+ TN);
+ TLB.push<TypedefTypeLoc>(T).set(/*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(SemaRef.Context),
+ IdInfo.IdentifierLoc);
+ } else if (auto *UD = dyn_cast<UnresolvedUsingTypenameDecl>(TD)) {
+ T = Context.getUnresolvedUsingType(ElaboratedTypeKeyword::None,
+ SS.getScopeRep(), UD);
+ TLB.push<UnresolvedUsingTypeLoc>(T).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(SemaRef.Context), IdInfo.IdentifierLoc);
} else {
- llvm_unreachable("Unhandled TypeDecl node in nested-name-specifier");
+ assert(SS.isEmpty());
+ T = Context.getTypeDeclType(TD);
+ TLB.pushTypeSpec(T).setNameLoc(IdInfo.IdentifierLoc);
}
-
- SS.Extend(Context, TLB.getTypeLocInContext(Context, T), IdInfo.CCLoc);
+ SS.clear();
+ SS.Make(Context, TLB.getTypeLocInContext(Context, T), IdInfo.CCLoc);
return false;
}
@@ -725,16 +731,34 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
Diag(IdInfo.IdentifierLoc,
diag::ext_undeclared_unqual_id_with_dependent_base)
<< IdInfo.Identifier << ContainingClass;
+
+ TypeLocBuilder TLB;
+
// Fake up a nested-name-specifier that starts with the
// injected-class-name of the enclosing class.
- QualType T = Context.getTypeDeclType(ContainingClass);
- TypeLocBuilder TLB;
- TLB.pushTrivial(Context, T, IdInfo.IdentifierLoc);
- SS.Extend(Context, TLB.getTypeLocInContext(Context, T),
- IdInfo.IdentifierLoc);
- // Add the identifier to form a dependent name.
- SS.Extend(Context, IdInfo.Identifier, IdInfo.IdentifierLoc,
- IdInfo.CCLoc);
+ // FIXME: This should be done as part of an adjustment, so that this
+ // doesn't get confused with something written in source.
+ QualType Result =
+ Context.getTagType(ElaboratedTypeKeyword::None, SS.getScopeRep(),
+ ContainingClass, /*OwnsTag=*/false);
+ auto TTL = TLB.push<TagTypeLoc>(Result);
+ TTL.setElaboratedKeywordLoc(SourceLocation());
+ TTL.setQualifierLoc(SS.getWithLocInContext(Context));
+ TTL.setNameLoc(IdInfo.IdentifierLoc);
+ SS.Make(Context, TLB.getTypeLocInContext(Context, Result),
+ SourceLocation());
+
+ TLB.clear();
+
+ // Form a DependentNameType.
+ QualType DTN = Context.getDependentNameType(
+ ElaboratedTypeKeyword::None, SS.getScopeRep(), IdInfo.Identifier);
+ auto DTNL = TLB.push<DependentNameTypeLoc>(DTN);
+ DTNL.setElaboratedKeywordLoc(SourceLocation());
+ DTNL.setNameLoc(IdInfo.IdentifierLoc);
+ DTNL.setQualifierLoc(SS.getWithLocInContext(Context));
+ SS.clear();
+ SS.Make(Context, TLB.getTypeLocInContext(Context, DTN), IdInfo.CCLoc);
return false;
}
}
@@ -742,8 +766,19 @@ bool Sema::BuildCXXNestedNameSpecifier(Scope *S, NestedNameSpecInfo &IdInfo,
if (!Found.empty()) {
if (TypeDecl *TD = Found.getAsSingle<TypeDecl>()) {
+ QualType T;
+ if (auto *TN = dyn_cast<TypedefNameDecl>(TD)) {
+ T = Context.getTypedefType(ElaboratedTypeKeyword::None,
+ SS.getScopeRep(), TN);
+ } else {
+ // FIXME: Enumerate the possibilities here.
+ assert(!isa<TagDecl>(TD));
+ assert(SS.isEmpty());
+ T = Context.getTypeDeclType(TD);
+ }
+
Diag(IdInfo.IdentifierLoc, diag::err_expected_class_or_namespace)
- << Context.getTypeDeclType(TD) << getLangOpts().CPlusPlus;
+ << T << getLangOpts().CPlusPlus;
} else if (Found.getAsSingle<TemplateDecl>()) {
ParsedType SuggestedType;
DiagnoseUnknownTypeName(IdInfo.Identifier, IdInfo.IdentifierLoc, S, &SS,
@@ -789,17 +824,19 @@ bool Sema::ActOnCXXNestedNameSpecifierDecltype(CXXScopeSpec &SS,
if (T.isNull())
return true;
- if (!T->isDependentType() && !T->getAs<TagType>()) {
+ if (!T->isDependentType() && !isa<TagType>(T.getCanonicalType())) {
Diag(DS.getTypeSpecTypeLoc(), diag::err_expected_class_or_namespace)
<< T << getLangOpts().CPlusPlus;
return true;
}
+ assert(SS.isEmpty());
+
TypeLocBuilder TLB;
DecltypeTypeLoc DecltypeTL = TLB.push<DecltypeTypeLoc>(T);
DecltypeTL.setDecltypeLoc(DS.getTypeSpecTypeLoc());
DecltypeTL.setRParenLoc(DS.getTypeofParensRange().getEnd());
- SS.Extend(Context, TLB.getTypeLocInContext(Context, T), ColonColonLoc);
+ SS.Make(Context, TLB.getTypeLocInContext(Context, T), ColonColonLoc);
return false;
}
@@ -815,13 +852,15 @@ bool Sema::ActOnCXXNestedNameSpecifierIndexedPack(CXXScopeSpec &SS,
if (Type.isNull())
return true;
+ assert(SS.isEmpty());
+
TypeLocBuilder TLB;
TLB.pushTrivial(getASTContext(),
cast<PackIndexingType>(Type.getTypePtr())->getPattern(),
DS.getBeginLoc());
PackIndexingTypeLoc PIT = TLB.push<PackIndexingTypeLoc>(Type);
PIT.setEllipsisLoc(DS.getEllipsisLoc());
- SS.Extend(Context, TLB.getTypeLocInContext(Context, Type), ColonColonLoc);
+ SS.Make(Context, TLB.getTypeLocInContext(Context, Type), ColonColonLoc);
return false;
}
@@ -861,7 +900,7 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
assert(DTN->getQualifier() == SS.getScopeRep());
QualType T = Context.getDependentTemplateSpecializationType(
ElaboratedTypeKeyword::None,
- {/*Qualifier=*/nullptr, DTN->getName().getIdentifier(),
+ {SS.getScopeRep(), DTN->getName().getIdentifier(),
TemplateKWLoc.isValid()},
TemplateArgs.arguments());
@@ -870,7 +909,7 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
DependentTemplateSpecializationTypeLoc SpecTL
= Builder.push<DependentTemplateSpecializationTypeLoc>(T);
SpecTL.setElaboratedKeywordLoc(SourceLocation());
- SpecTL.setQualifierLoc(NestedNameSpecifierLoc());
+ SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
SpecTL.setTemplateNameLoc(TemplateNameLoc);
SpecTL.setLAngleLoc(LAngleLoc);
@@ -878,7 +917,8 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
- SS.Extend(Context, Builder.getTypeLocInContext(Context, T), CCLoc);
+ SS.clear();
+ SS.Make(Context, Builder.getTypeLocInContext(Context, T), CCLoc);
return false;
}
@@ -903,30 +943,28 @@ bool Sema::ActOnCXXNestedNameSpecifier(Scope *S,
// We were able to resolve the template name to an actual template.
// Build an appropriate nested-name-specifier.
- QualType T = CheckTemplateIdType(Template, TemplateNameLoc, TemplateArgs);
+ QualType T = CheckTemplateIdType(ElaboratedTypeKeyword::None, Template,
+ TemplateNameLoc, TemplateArgs);
if (T.isNull())
return true;
// Alias template specializations can produce types which are not valid
// nested name specifiers.
- if (!T->isDependentType() && !T->getAs<TagType>()) {
+ if (!T->isDependentType() && !isa<TagType>(T.getCanonicalType())) {
Diag(TemplateNameLoc, diag::err_nested_name_spec_non_tag) << T;
NoteAllFoundTemplates(Template);
return true;
}
// Provide source-location information for the template specialization type.
- TypeLocBuilder Builder;
- TemplateSpecializationTypeLoc SpecTL
- = Builder.push<TemplateSpecializationTypeLoc>(T);
- SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
- SpecTL.setTemplateNameLoc(TemplateNameLoc);
- SpecTL.setLAngleLoc(LAngleLoc);
- SpecTL.setRAngleLoc(RAngleLoc);
- for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
- SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
-
- SS.Extend(Context, Builder.getTypeLocInContext(Context, T), CCLoc);
+ TypeLocBuilder TLB;
+ TLB.push<TemplateSpecializationTypeLoc>(T).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context), TemplateKWLoc, TemplateNameLoc,
+ TemplateArgs);
+
+ SS.clear();
+ SS.Make(Context, TLB.getTypeLocInContext(Context, T), CCLoc);
return false;
}
@@ -934,7 +972,7 @@ namespace {
/// A structure that stores a nested-name-specifier annotation,
/// including both the nested-name-specifier
struct NestedNameSpecifierAnnotation {
- NestedNameSpecifier *NNS;
+ NestedNameSpecifier NNS = std::nullopt;
};
}
@@ -973,8 +1011,6 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
if (isa<ObjCContainerDecl>(CurContext) || isa<ObjCMethodDecl>(CurContext))
return false;
- NestedNameSpecifier *Qualifier = SS.getScopeRep();
-
// There are only two places a well-formed program may qualify a
// declarator: first, when defining a namespace or class member
// out-of-line, and second, when naming an explicitly-qualified
@@ -989,19 +1025,20 @@ bool Sema::ShouldEnterDeclaratorScope(Scope *S, const CXXScopeSpec &SS) {
// granting friendship.
// i.e. we don't push a scope unless it's a class member.
- switch (Qualifier->getKind()) {
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
+ switch (SS.getScopeRep().getKind()) {
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Namespace:
// These are always namespace scopes. We never want to enter a
// namespace scope from anything but a file context.
return CurContext->getRedeclContext()->isFileContext();
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Type:
+ case NestedNameSpecifier::Kind::Super:
// These are never namespace scopes.
return true;
+
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index e27ed8fd4de14..adcb0df6213c5 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -964,7 +964,7 @@ void CastOperation::CheckDynamicCast() {
}
// C++ 5.2.7p6: Otherwise, v shall be [polymorphic].
- const RecordDecl *SrcDecl = SrcRecord->getDecl()->getDefinition();
+ const RecordDecl *SrcDecl = SrcRecord->getOriginalDecl()->getDefinition();
assert(SrcDecl && "Definition missing");
if (!cast<CXXRecordDecl>(SrcDecl)->isPolymorphic()) {
Self.Diag(OpRange.getBegin(), diag::err_bad_dynamic_cast_not_polymorphic)
@@ -1455,7 +1455,7 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
// converted to an integral type. [...] A value of a scoped enumeration type
// can also be explicitly converted to a floating-point type [...].
if (const EnumType *Enum = SrcType->getAs<EnumType>()) {
- if (Enum->getDecl()->isScoped()) {
+ if (Enum->getOriginalDecl()->isScoped()) {
if (DestType->isBooleanType()) {
Kind = CK_IntegralToBoolean;
return TC_Success;
@@ -1487,8 +1487,8 @@ static TryCastResult TryStaticCast(Sema &Self, ExprResult &SrcExpr,
// [expr.static.cast]p10 If the enumeration type has a fixed underlying
// type, the value is first converted to that type by integral conversion
const EnumType *Enum = DestType->castAs<EnumType>();
- Kind = Enum->getDecl()->isFixed() &&
- Enum->getDecl()->getIntegerType()->isBooleanType()
+ const EnumDecl *ED = Enum->getOriginalDecl()->getDefinitionOrSelf();
+ Kind = ED->isFixed() && ED->getIntegerType()->isBooleanType()
? CK_IntegralToBoolean
: CK_IntegralCast;
return TC_Success;
@@ -1858,7 +1858,7 @@ TryCastResult TryStaticMemberPointerUpcast(Sema &Self, ExprResult &SrcExpr,
FoundOverload)) {
CXXMethodDecl *M = cast<CXXMethodDecl>(Fn);
SrcType = Self.Context.getMemberPointerType(
- Fn->getType(), /*Qualifier=*/nullptr, M->getParent());
+ Fn->getType(), /*Qualifier=*/std::nullopt, M->getParent());
WasOverloadedFunction = true;
}
}
@@ -2104,9 +2104,9 @@ void Sema::CheckCompatibleReinterpretCast(QualType SrcType, QualType DestType,
return;
}
// or one of the types is a tag type.
- if (SrcTy->getAs<TagType>() || DestTy->getAs<TagType>()) {
+ if (isa<TagType>(SrcTy.getCanonicalType()) ||
+ isa<TagType>(DestTy.getCanonicalType()))
return;
- }
// FIXME: Scoped enums?
if ((SrcTy->isUnsignedIntegerType() && DestTy->isSignedIntegerType()) ||
@@ -3099,27 +3099,26 @@ void CastOperation::CheckCStyleCast() {
if (!DestType->isScalarType() && !DestType->isVectorType() &&
!DestType->isMatrixType()) {
- const RecordType *DestRecordTy = DestType->getAs<RecordType>();
-
- if (DestRecordTy && Self.Context.hasSameUnqualifiedType(DestType, SrcType)){
- // GCC struct/union extension: allow cast to self.
- Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
- << DestType << SrcExpr.get()->getSourceRange();
- Kind = CK_NoOp;
- return;
- }
-
- // GCC's cast to union extension.
- if (DestRecordTy && DestRecordTy->getDecl()->isUnion()) {
- RecordDecl *RD = DestRecordTy->getDecl();
- if (CastExpr::getTargetFieldForToUnionCast(RD, SrcType)) {
- Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
- << SrcExpr.get()->getSourceRange();
- Kind = CK_ToUnion;
+ if (const RecordType *DestRecordTy = DestType->getAs<RecordType>()) {
+ if (Self.Context.hasSameUnqualifiedType(DestType, SrcType)) {
+ // GCC struct/union extension: allow cast to self.
+ Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_nonscalar)
+ << DestType << SrcExpr.get()->getSourceRange();
+ Kind = CK_NoOp;
return;
- } else {
+ }
+
+ // GCC's cast to union extension.
+ if (RecordDecl *RD = DestRecordTy->getOriginalDecl(); RD->isUnion()) {
+ if (CastExpr::getTargetFieldForToUnionCast(RD->getDefinitionOrSelf(),
+ SrcType)) {
+ Self.Diag(OpRange.getBegin(), diag::ext_typecheck_cast_to_union)
+ << SrcExpr.get()->getSourceRange();
+ Kind = CK_ToUnion;
+ return;
+ }
Self.Diag(OpRange.getBegin(), diag::err_typecheck_cast_to_union_no_type)
- << SrcType << SrcExpr.get()->getSourceRange();
+ << SrcType << SrcExpr.get()->getSourceRange();
SrcExpr = ExprError();
return;
}
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index dd5b710d7e1d4..f4daa8f506ccf 100644
--- a/clang/lib/Sema/SemaChecking.cpp
+++ b/clang/lib/Sema/SemaChecking.cpp
@@ -603,7 +603,7 @@ struct BuiltinDumpStructGenerator {
bool dumpUnnamedRecord(const RecordDecl *RD, Expr *E, unsigned Depth) {
Expr *IndentLit = getIndentString(Depth);
- Expr *TypeLit = getTypeString(S.Context.getRecordType(RD));
+ Expr *TypeLit = getTypeString(S.Context.getCanonicalTagType(RD));
if (IndentLit ? callPrintFunction("%s%s", {IndentLit, TypeLit})
: callPrintFunction("%s", {TypeLit}))
return true;
@@ -2288,7 +2288,7 @@ static ExprResult BuiltinInvoke(Sema &S, CallExpr *TheCall) {
return ExprError();
}
- const Type *MemPtrClass = MPT->getQualifier()->getAsType();
+ const Type *MemPtrClass = MPT->getQualifier().getAsType();
QualType ObjectT = Args[1]->getType();
if (MPT->isMemberDataPointer() && S.checkArgCount(TheCall, 2))
@@ -3315,7 +3315,9 @@ static bool CheckNonNullExpr(Sema &S, const Expr *Expr) {
// As a special case, transparent unions initialized with zero are
// considered null for the purposes of the nonnull attribute.
if (const RecordType *UT = Expr->getType()->getAsUnionType();
- UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
+ UT && UT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<TransparentUnionAttr>()) {
if (const auto *CLE = dyn_cast<CompoundLiteralExpr>(Expr))
if (const auto *ILE = dyn_cast<InitListExpr>(CLE->getInitializer()))
Expr = ILE->getInit(0);
@@ -5172,7 +5174,9 @@ bool Sema::BuiltinVAStart(unsigned BuiltinID, CallExpr *TheCall) {
return false;
if (!Type->isEnumeralType())
return true;
- const EnumDecl *ED = Type->castAs<EnumType>()->getDecl();
+ const EnumDecl *ED = Type->castAs<EnumType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
return !(ED &&
Context.typesAreCompatible(ED->getPromotionType(), Type));
}()) {
@@ -7786,8 +7790,11 @@ CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty) {
if (!RT)
return Results;
- const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- if (!RD || !RD->getDefinition())
+ CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
+ if (!RD)
+ return Results;
+ RD = RD->getDefinition();
+ if (!RD)
return Results;
LookupResult R(S, &S.Context.Idents.get(Name), SourceLocation(),
@@ -7796,7 +7803,7 @@ CXXRecordMembersNamed(StringRef Name, Sema &S, QualType Ty) {
// We just need to include all members of the right kind turned up by the
// filter, at this point.
- if (S.LookupQualifiedName(R, RT->getDecl()))
+ if (S.LookupQualifiedName(R, RD))
for (LookupResult::iterator I = R.begin(), E = R.end(); I != E; ++I) {
NamedDecl *decl = (*I)->getUnderlyingDecl();
if (MemberKind *FK = dyn_cast<MemberKind>(decl))
@@ -8323,7 +8330,8 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
bool IsScopedEnum = false;
QualType IntendedTy = ExprTy;
if (auto EnumTy = ExprTy->getAs<EnumType>()) {
- IntendedTy = EnumTy->getDecl()->getIntegerType();
+ IntendedTy =
+ EnumTy->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (EnumTy->isUnscopedEnumerationType()) {
ExprTy = IntendedTy;
// This controls whether we're talking about the underlying type or not,
@@ -8359,7 +8367,9 @@ CheckPrintfHandler::checkFormatExpr(const analyze_printf::PrintfSpecifier &FS,
NamedDecl *ND = Result.getFoundDecl();
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(ND))
if (TD->getUnderlyingType() == IntendedTy)
- IntendedTy = S.Context.getTypedefType(TD);
+ IntendedTy =
+ S.Context.getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD);
}
}
}
@@ -9617,7 +9627,10 @@ struct SearchNonTrivialToInitializeField
S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 1);
}
void visitStruct(QualType FT, SourceLocation SL) {
- for (const FieldDecl *FD : FT->castAs<RecordType>()->getDecl()->fields())
+ for (const FieldDecl *FD : FT->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->fields())
visit(FD->getType(), FD->getLocation());
}
void visitArray(QualType::PrimitiveDefaultInitializeKind PDIK,
@@ -9662,7 +9675,10 @@ struct SearchNonTrivialToCopyField
S.DiagRuntimeBehavior(SL, E, S.PDiag(diag::note_nontrivial_field) << 0);
}
void visitStruct(QualType FT, SourceLocation SL) {
- for (const FieldDecl *FD : FT->castAs<RecordType>()->getDecl()->fields())
+ for (const FieldDecl *FD : FT->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->fields())
visit(FD->getType(), FD->getLocation());
}
void visitArray(QualType::PrimitiveCopyKind PCK, const ArrayType *AT,
@@ -9943,8 +9959,9 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
getLangOpts().CPlusPlus && !RT->isIncompleteType() &&
!RT->desugar().isTriviallyCopyableType(Context);
+ const auto *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if ((BId == Builtin::BImemset || BId == Builtin::BIbzero) &&
- RT->getDecl()->isNonTrivialToPrimitiveDefaultInitialize()) {
+ RD->isNonTrivialToPrimitiveDefaultInitialize()) {
DiagRuntimeBehavior(Dest->getExprLoc(), Dest,
PDiag(diag::warn_cstruct_memaccess)
<< ArgIdx << FnName << PointeeTy << 0);
@@ -9957,7 +9974,7 @@ void Sema::CheckMemaccessArguments(const CallExpr *Call,
PDiag(diag::warn_cxxstruct_memaccess)
<< FnName << PointeeTy);
} else if ((BId == Builtin::BImemcpy || BId == Builtin::BImemmove) &&
- RT->getDecl()->isNonTrivialToPrimitiveCopy()) {
+ RD->isNonTrivialToPrimitiveCopy()) {
DiagRuntimeBehavior(Dest->getExprLoc(), Dest,
PDiag(diag::warn_cstruct_memaccess)
<< ArgIdx << FnName << PointeeTy << 1);
@@ -10463,10 +10480,14 @@ struct IntRange {
if (!C.getLangOpts().CPlusPlus) {
// For enum types in C code, use the underlying datatype.
if (const auto *ET = dyn_cast<EnumType>(T))
- T = ET->getDecl()->getIntegerType().getDesugaredType(C).getTypePtr();
+ T = ET->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->getIntegerType()
+ .getDesugaredType(C)
+ .getTypePtr();
} else if (const auto *ET = dyn_cast<EnumType>(T)) {
// For enum types in C++, use the known bit width of the enumerators.
- EnumDecl *Enum = ET->getDecl();
+ EnumDecl *Enum = ET->getOriginalDecl()->getDefinitionOrSelf();
// In C++11, enums can have a fixed underlying type. Use this type to
// compute the range.
if (Enum->isFixed()) {
@@ -10508,7 +10529,9 @@ struct IntRange {
if (const AtomicType *AT = dyn_cast<AtomicType>(T))
T = AT->getValueType().getTypePtr();
if (const EnumType *ET = dyn_cast<EnumType>(T))
- T = C.getCanonicalType(ET->getDecl()->getIntegerType()).getTypePtr();
+ T = C.getCanonicalType(
+ ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType())
+ .getTypePtr();
if (const auto *EIT = dyn_cast<BitIntType>(T))
return IntRange(EIT->getNumBits(), EIT->isUnsigned());
@@ -11480,7 +11503,9 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
return false;
if (BitfieldType->isEnumeralType()) {
- EnumDecl *BitfieldEnumDecl = BitfieldType->castAs<EnumType>()->getDecl();
+ EnumDecl *BitfieldEnumDecl = BitfieldType->castAs<EnumType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
// If the underlying enum type was not explicitly specified as an unsigned
// type and the enum contain only positive values, MSVC++ will cause an
// inconsistency by storing this as a signed type.
@@ -11517,7 +11542,7 @@ static bool AnalyzeBitFieldAssignment(Sema &S, FieldDecl *Bitfield, Expr *Init,
EnumTy = PTAttr->getType()->getAs<EnumType>();
}
if (EnumTy) {
- EnumDecl *ED = EnumTy->getDecl();
+ EnumDecl *ED = EnumTy->getOriginalDecl()->getDefinitionOrSelf();
bool SignedBitfield = BitfieldType->isSignedIntegerOrEnumerationType();
// Enum types are implicitly signed on Windows, so check if there are any
@@ -12583,8 +12608,8 @@ void Sema::CheckImplicitConversion(Expr *E, QualType T, SourceLocation CC,
if (const EnumType *SourceEnum = Source->getAs<EnumType>())
if (const EnumType *TargetEnum = Target->getAs<EnumType>())
- if (SourceEnum->getDecl()->hasNameForLinkage() &&
- TargetEnum->getDecl()->hasNameForLinkage() &&
+ if (SourceEnum->getOriginalDecl()->hasNameForLinkage() &&
+ TargetEnum->getOriginalDecl()->hasNameForLinkage() &&
SourceEnum != TargetEnum) {
if (SourceMgr.isInSystemMacro(CC))
return;
@@ -15108,10 +15133,9 @@ static bool isLayoutCompatible(const ASTContext &C, const EnumDecl *ED1,
static bool isLayoutCompatible(const ASTContext &C, const FieldDecl *Field1,
const FieldDecl *Field2,
bool AreUnionMembers = false) {
- [[maybe_unused]] const Type *Field1Parent =
- Field1->getParent()->getTypeForDecl();
- [[maybe_unused]] const Type *Field2Parent =
- Field2->getParent()->getTypeForDecl();
+#ifndef NDEBUG
+ CanQualType Field1Parent = C.getCanonicalTagType(Field1->getParent());
+ CanQualType Field2Parent = C.getCanonicalTagType(Field2->getParent());
assert(((Field1Parent->isStructureOrClassType() &&
Field2Parent->isStructureOrClassType()) ||
(Field1Parent->isUnionType() && Field2Parent->isUnionType())) &&
@@ -15120,6 +15144,7 @@ static bool isLayoutCompatible(const ASTContext &C, const FieldDecl *Field1,
assert(((!AreUnionMembers && Field1Parent->isStructureOrClassType()) ||
(AreUnionMembers && Field1Parent->isUnionType())) &&
"AreUnionMembers should be 'true' for union fields (only).");
+#endif
if (!isLayoutCompatible(C, Field1->getType(), Field2->getType()))
return false;
@@ -15224,16 +15249,16 @@ static bool isLayoutCompatible(const ASTContext &C, QualType T1, QualType T2) {
return false;
if (TC1 == Type::Enum) {
- return isLayoutCompatible(C,
- cast<EnumType>(T1)->getDecl(),
- cast<EnumType>(T2)->getDecl());
+ return isLayoutCompatible(
+ C, cast<EnumType>(T1)->getOriginalDecl()->getDefinitionOrSelf(),
+ cast<EnumType>(T2)->getOriginalDecl()->getDefinitionOrSelf());
} else if (TC1 == Type::Record) {
if (!T1->isStandardLayoutType() || !T2->isStandardLayoutType())
return false;
- return isLayoutCompatible(C,
- cast<RecordType>(T1)->getDecl(),
- cast<RecordType>(T2)->getDecl());
+ return isLayoutCompatible(
+ C, cast<RecordType>(T1)->getOriginalDecl()->getDefinitionOrSelf(),
+ cast<RecordType>(T2)->getOriginalDecl()->getDefinitionOrSelf());
}
return false;
@@ -15587,7 +15612,9 @@ void Sema::RefersToMemberWithReducedAlignment(
return;
if (ME->isArrow())
BaseType = BaseType->getPointeeType();
- RecordDecl *RD = BaseType->castAs<RecordType>()->getDecl();
+ RecordDecl *RD = BaseType->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
if (RD->isInvalidDecl())
return;
@@ -15632,7 +15659,7 @@ void Sema::RefersToMemberWithReducedAlignment(
// Compute the CompleteObjectAlignment as the alignment of the whole chain.
CharUnits CompleteObjectAlignment = Context.getTypeAlignInChars(
- ReverseMemberChain.back()->getParent()->getTypeForDecl());
+ Context.getCanonicalTagType(ReverseMemberChain.back()->getParent()));
// The base expression of the innermost MemberExpr may give
// stronger guarantees than the class containing the member.
@@ -15662,9 +15689,9 @@ void Sema::RefersToMemberWithReducedAlignment(
if (FDI->hasAttr<PackedAttr>() ||
FDI->getParent()->hasAttr<PackedAttr>()) {
FD = FDI;
- Alignment = std::min(
- Context.getTypeAlignInChars(FD->getType()),
- Context.getTypeAlignInChars(FD->getParent()->getTypeForDecl()));
+ Alignment = std::min(Context.getTypeAlignInChars(FD->getType()),
+ Context.getTypeAlignInChars(
+ Context.getCanonicalTagType(FD->getParent())));
break;
}
}
diff --git a/clang/lib/Sema/SemaCodeComplete.cpp b/clang/lib/Sema/SemaCodeComplete.cpp
index a43ac9eb7610d..99492cea4e6c2 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -732,7 +732,7 @@ ResultBuilder::ShadowMapEntry::end() const {
///
/// \returns a nested name specifier that refers into the target context, or
/// NULL if no qualification is needed.
-static NestedNameSpecifier *
+static NestedNameSpecifier
getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
const DeclContext *TargetContext) {
SmallVector<const DeclContext *, 4> TargetParents;
@@ -747,7 +747,7 @@ getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
TargetParents.push_back(CommonAncestor);
}
- NestedNameSpecifier *Result = nullptr;
+ NestedNameSpecifier Result = std::nullopt;
while (!TargetParents.empty()) {
const DeclContext *Parent = TargetParents.pop_back_val();
@@ -755,10 +755,12 @@ getRequiredQualification(ASTContext &Context, const DeclContext *CurContext,
if (!Namespace->getIdentifier())
continue;
- Result = NestedNameSpecifier::Create(Context, Result, Namespace);
- } else if (const auto *TD = dyn_cast<TagDecl>(Parent))
- Result = NestedNameSpecifier::Create(
- Context, Result, Context.getTypeDeclType(TD).getTypePtr());
+ Result = NestedNameSpecifier(Context, Namespace, Result);
+ } else if (const auto *TD = dyn_cast<TagDecl>(Parent)) {
+ QualType TT = Context.getTagType(ElaboratedTypeKeyword::None, Result, TD,
+ /*OwnsTag=*/false);
+ Result = NestedNameSpecifier(TT.getTypePtr());
+ }
}
return Result;
}
@@ -937,11 +939,12 @@ SimplifiedTypeClass clang::getSimplifiedTypeClass(CanQualType T) {
/// Get the type that a given expression will have if this declaration
/// is used as an expression in its "typical" code-completion form.
-QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
+QualType clang::getDeclUsageType(ASTContext &C, NestedNameSpecifier Qualifier,
+ const NamedDecl *ND) {
ND = ND->getUnderlyingDecl();
if (const auto *Type = dyn_cast<TypeDecl>(ND))
- return C.getTypeDeclType(Type);
+ return C.getTypeDeclType(ElaboratedTypeKeyword::None, Qualifier, Type);
if (const auto *Iface = dyn_cast<ObjCInterfaceDecl>(ND))
return C.getObjCInterfaceType(Iface);
@@ -951,7 +954,9 @@ QualType clang::getDeclUsageType(ASTContext &C, const NamedDecl *ND) {
else if (const auto *Method = dyn_cast<ObjCMethodDecl>(ND))
T = Method->getSendResultType();
else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND))
- T = C.getTypeDeclType(cast<EnumDecl>(Enumerator->getDeclContext()));
+ T = C.getTagType(ElaboratedTypeKeyword::None, Qualifier,
+ cast<EnumDecl>(Enumerator->getDeclContext()),
+ /*OwnsTag=*/false);
else if (const auto *Property = dyn_cast<ObjCPropertyDecl>(ND))
T = Property->getType();
else if (const auto *Value = dyn_cast<ValueDecl>(ND))
@@ -1053,7 +1058,7 @@ void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
// If we have a preferred type, adjust the priority for results with exactly-
// matching or nearly-matching types.
if (!PreferredType.isNull()) {
- QualType T = getDeclUsageType(SemaRef.Context, R.Declaration);
+ QualType T = getDeclUsageType(SemaRef.Context, R.Qualifier, R.Declaration);
if (!T.isNull()) {
CanQualType TC = SemaRef.Context.getCanonicalType(T);
// Check for exactly-matching types (modulo qualifiers).
@@ -1070,10 +1075,9 @@ void ResultBuilder::AdjustResultPriorityForDecl(Result &R) {
static DeclContext::lookup_result getConstructors(ASTContext &Context,
const CXXRecordDecl *Record) {
- QualType RecordTy = Context.getTypeDeclType(Record);
+ CanQualType RecordTy = Context.getCanonicalTagType(Record);
DeclarationName ConstructorName =
- Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(RecordTy));
+ Context.DeclarationNames.getCXXConstructorName(RecordTy);
return Record->lookup(ConstructorName);
}
@@ -1216,11 +1220,13 @@ void ResultBuilder::MaybeAddResult(Result R, DeclContext *CurContext) {
const DeclContext *Ctx = R.Declaration->getDeclContext();
if (const NamespaceDecl *Namespace = dyn_cast<NamespaceDecl>(Ctx))
R.Qualifier =
- NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace);
+ NestedNameSpecifier(SemaRef.Context, Namespace, std::nullopt);
else if (const TagDecl *Tag = dyn_cast<TagDecl>(Ctx))
- R.Qualifier = NestedNameSpecifier::Create(
- SemaRef.Context, nullptr,
- SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
+ R.Qualifier = NestedNameSpecifier(
+ SemaRef.Context
+ .getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, Tag, /*OwnsTag=*/false)
+ .getTypePtr());
else
R.QualifierIsInformative = false;
}
@@ -1405,11 +1411,13 @@ void ResultBuilder::AddResult(Result R, DeclContext *CurContext,
const DeclContext *Ctx = R.Declaration->getDeclContext();
if (const auto *Namespace = dyn_cast<NamespaceDecl>(Ctx))
R.Qualifier =
- NestedNameSpecifier::Create(SemaRef.Context, nullptr, Namespace);
+ NestedNameSpecifier(SemaRef.Context, Namespace, std::nullopt);
else if (const auto *Tag = dyn_cast<TagDecl>(Ctx))
- R.Qualifier = NestedNameSpecifier::Create(
- SemaRef.Context, nullptr,
- SemaRef.Context.getTypeDeclType(Tag).getTypePtr());
+ R.Qualifier = NestedNameSpecifier(
+ SemaRef.Context
+ .getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, Tag, /*OwnsTag=*/false)
+ .getTypePtr());
else
R.QualifierIsInformative = false;
}
@@ -1664,7 +1672,8 @@ static bool isObjCReceiverType(ASTContext &C, QualType T) {
}
bool ResultBuilder::IsObjCMessageReceiver(const NamedDecl *ND) const {
- QualType T = getDeclUsageType(SemaRef.Context, ND);
+ QualType T =
+ getDeclUsageType(SemaRef.Context, /*Qualifier=*/std::nullopt, ND);
if (T.isNull())
return false;
@@ -1689,7 +1698,8 @@ bool ResultBuilder::IsObjCCollection(const NamedDecl *ND) const {
(!SemaRef.getLangOpts().CPlusPlus && !IsOrdinaryNonTypeName(ND)))
return false;
- QualType T = getDeclUsageType(SemaRef.Context, ND);
+ QualType T =
+ getDeclUsageType(SemaRef.Context, /*Qualifier=*/std::nullopt, ND);
if (T.isNull())
return false;
@@ -1745,8 +1755,10 @@ class CodeCompletionDeclConsumer : public VisibleDeclConsumer {
void FoundDecl(NamedDecl *ND, NamedDecl *Hiding, DeclContext *Ctx,
bool InBaseClass) override {
- ResultBuilder::Result Result(ND, Results.getBasePriority(ND), nullptr,
- false, IsAccessible(ND, Ctx), FixIts);
+ ResultBuilder::Result Result(ND, Results.getBasePriority(ND),
+ /*Qualifier=*/std::nullopt,
+ /*QualifierIsInformative=*/false,
+ IsAccessible(ND, Ctx), FixIts);
Results.AddResult(Result, InitialLookupCtx, Hiding, InBaseClass, BaseType);
}
@@ -2010,7 +2022,6 @@ static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
Policy.AnonymousTagLocations = false;
Policy.SuppressStrongLifetime = true;
Policy.SuppressUnwrittenScope = true;
- Policy.SuppressScope = true;
Policy.CleanUglifiedParameters = true;
return Policy;
}
@@ -2035,7 +2046,7 @@ static const char *GetCompletionTypeString(QualType T, ASTContext &Context,
// Anonymous tag types are constant strings.
if (const TagType *TagT = dyn_cast<TagType>(T))
- if (TagDecl *Tag = TagT->getDecl())
+ if (TagDecl *Tag = TagT->getOriginalDecl())
if (!Tag->hasNameForLinkage()) {
switch (Tag->getTagKind()) {
case TagTypeKind::Struct:
@@ -2925,8 +2936,8 @@ static void AddResultTypeChunk(ASTContext &Context,
else
T = Method->getReturnType();
} else if (const auto *Enumerator = dyn_cast<EnumConstantDecl>(ND)) {
- T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext()));
- T = clang::TypeName::getFullyQualifiedType(T, Context);
+ T = Context.getCanonicalTagType(
+ cast<EnumDecl>(Enumerator->getDeclContext()));
} else if (isa<UnresolvedUsingValueDecl>(ND)) {
/* Do nothing: ignore unresolved using declarations*/
} else if (const auto *Ivar = dyn_cast<ObjCIvarDecl>(ND)) {
@@ -3021,7 +3032,7 @@ static void findTypeLocationForBlockDecl(const TypeSourceInfo *TSInfo,
if (!SuppressBlock) {
if (TypedefTypeLoc TypedefTL = TL.getAsAdjusted<TypedefTypeLoc>()) {
if (TypeSourceInfo *InnerTSInfo =
- TypedefTL.getTypedefNameDecl()->getTypeSourceInfo()) {
+ TypedefTL.getDecl()->getTypeSourceInfo()) {
TL = InnerTSInfo->getTypeLoc().getUnqualifiedLoc();
continue;
}
@@ -3381,7 +3392,7 @@ static void AddTemplateParameterChunks(
/// Add a qualifier to the given code-completion string, if the
/// provided nested-name-specifier is non-NULL.
static void AddQualifierToCompletionString(CodeCompletionBuilder &Result,
- NestedNameSpecifier *Qualifier,
+ NestedNameSpecifier Qualifier,
bool QualifierIsInformative,
ASTContext &Context,
const PrintingPolicy &Policy) {
@@ -3391,7 +3402,7 @@ static void AddQualifierToCompletionString(CodeCompletionBuilder &Result,
std::string PrintedNNS;
{
llvm::raw_string_ostream OS(PrintedNNS);
- Qualifier->print(OS, Policy);
+ Qualifier.print(OS, Policy);
}
if (QualifierIsInformative)
Result.AddInformativeChunk(Result.getAllocator().CopyString(PrintedNNS));
@@ -3520,11 +3531,9 @@ static void AddTypedNameChunk(ASTContext &Context, const PrintingPolicy &Policy,
case DeclarationName::CXXConstructorName: {
CXXRecordDecl *Record = nullptr;
QualType Ty = Name.getCXXNameType();
- if (const auto *RecordTy = Ty->getAs<RecordType>())
- Record = cast<CXXRecordDecl>(RecordTy->getDecl());
- else if (const auto *InjectedTy = Ty->getAs<InjectedClassNameType>())
- Record = InjectedTy->getDecl();
- else {
+ if (auto *RD = Ty->getAsCXXRecordDecl()) {
+ Record = RD;
+ } else {
Result.AddTypedTextChunk(
Result.getAllocator().CopyString(ND->getNameAsString()));
break;
@@ -4498,12 +4507,12 @@ static void MaybeAddOverrideCalls(Sema &S, DeclContext *InContext,
// If we need a nested-name-specifier, add one now.
if (!InContext) {
- NestedNameSpecifier *NNS = getRequiredQualification(
+ NestedNameSpecifier NNS = getRequiredQualification(
S.Context, CurContext, Overridden->getDeclContext());
if (NNS) {
std::string Str;
llvm::raw_string_ostream OS(Str);
- NNS->print(OS, Policy);
+ NNS.print(OS, Policy);
Builder.AddTextChunk(Results.getAllocator().CopyString(Str));
}
} else if (!InContext->Equals(Overridden->getDeclContext()))
@@ -4912,14 +4921,14 @@ namespace {
/// Information that allows to avoid completing redundant enumerators.
struct CoveredEnumerators {
llvm::SmallPtrSet<EnumConstantDecl *, 8> Seen;
- NestedNameSpecifier *SuggestedQualifier = nullptr;
+ NestedNameSpecifier SuggestedQualifier = std::nullopt;
};
} // namespace
static void AddEnumerators(ResultBuilder &Results, ASTContext &Context,
EnumDecl *Enum, DeclContext *CurContext,
const CoveredEnumerators &Enumerators) {
- NestedNameSpecifier *Qualifier = Enumerators.SuggestedQualifier;
+ NestedNameSpecifier Qualifier = Enumerators.SuggestedQualifier;
if (Context.getLangOpts().CPlusPlus && !Qualifier && Enumerators.Seen.empty()) {
// If there are no prior enumerators in C++, check whether we have to
// qualify the names of the enumerators that we suggest, because they
@@ -5051,9 +5060,9 @@ void SemaCodeCompletion::CodeCompleteExpression(
Data.PreferredType->isMemberPointerType() ||
Data.PreferredType->isBlockPointerType();
if (Data.PreferredType->isEnumeralType()) {
- EnumDecl *Enum = Data.PreferredType->castAs<EnumType>()->getDecl();
- if (auto *Def = Enum->getDefinition())
- Enum = Def;
+ EnumDecl *Enum = Data.PreferredType->castAs<EnumType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
// FIXME: collect covered enumerators in cases like:
// if (x == my_enum::one) { ... } else if (x == ^) {}
AddEnumerators(Results, getASTContext(), Enum, SemaRef.CurContext,
@@ -5177,7 +5186,8 @@ AddObjCProperties(const CodeCompletionContext &CCContext,
// expressions.
if (!P->getType().getTypePtr()->isBlockPointerType() ||
!IsBaseExprStatement) {
- Result R = Result(P, Results.getBasePriority(P), nullptr);
+ Result R =
+ Result(P, Results.getBasePriority(P), /*Qualifier=*/std::nullopt);
if (!InOriginalClass)
setInBaseClass(R);
Results.MaybeAddResult(R, CurContext);
@@ -5191,7 +5201,8 @@ AddObjCProperties(const CodeCompletionContext &CCContext,
findTypeLocationForBlockDecl(P->getTypeSourceInfo(), BlockLoc,
BlockProtoLoc);
if (!BlockLoc) {
- Result R = Result(P, Results.getBasePriority(P), nullptr);
+ Result R =
+ Result(P, Results.getBasePriority(P), /*Qualifier=*/std::nullopt);
if (!InOriginalClass)
setInBaseClass(R);
Results.MaybeAddResult(R, CurContext);
@@ -5603,15 +5614,18 @@ class ConceptInfo {
// In T::foo, `foo` is a static member function/variable.
bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) override {
- if (E->getQualifier() && isApprox(E->getQualifier()->getAsType(), T))
+ NestedNameSpecifier Qualifier = E->getQualifier();
+ if (Qualifier.getKind() == NestedNameSpecifier::Kind::Type &&
+ isApprox(Qualifier.getAsType(), T))
addValue(E, E->getDeclName(), Member::Colons);
return true;
}
// In T::typename foo, `foo` is a type.
bool VisitDependentNameType(DependentNameType *DNT) override {
- const auto *Q = DNT->getQualifier();
- if (Q && isApprox(Q->getAsType(), T))
+ NestedNameSpecifier Q = DNT->getQualifier();
+ if (Q.getKind() == NestedNameSpecifier::Kind::Type &&
+ isApprox(Q.getAsType(), T))
addType(DNT->getIdentifier());
return true;
}
@@ -5620,10 +5634,15 @@ class ConceptInfo {
// VisitNNS() doesn't exist, and TraverseNNS isn't always called :-(
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSL) override {
if (NNSL) {
- NestedNameSpecifier *NNS = NNSL.getNestedNameSpecifier();
- const auto *Q = NNS->getPrefix();
- if (Q && isApprox(Q->getAsType(), T))
- addType(NNS->getAsIdentifier());
+ NestedNameSpecifier NNS = NNSL.getNestedNameSpecifier();
+ if (NNS.getKind() == NestedNameSpecifier::Kind::Type) {
+ const Type *NNST = NNS.getAsType();
+ if (NestedNameSpecifier Q = NNST->getPrefix();
+ Q.getKind() == NestedNameSpecifier::Kind::Type &&
+ isApprox(Q.getAsType(), T))
+ if (const auto *DNT = dyn_cast_or_null<DependentNameType>(NNST))
+ addType(DNT->getIdentifier());
+ }
}
// FIXME: also handle T::foo<X>::bar
return DynamicRecursiveASTVisitor::TraverseNestedNameSpecifierLoc(NNSL);
@@ -5769,7 +5788,7 @@ QualType getApproximateType(const Expr *E, HeuristicResolver &Resolver) {
if (auto Decls = Resolver.resolveDependentNameType(DNT);
Decls.size() == 1) {
if (const auto *TD = dyn_cast<TypeDecl>(Decls[0]))
- return QualType(TD->getTypeForDecl(), 0);
+ return TD->getASTContext().getTypeDeclType(TD);
}
}
// We only resolve DependentTy, or undeduced autos (including auto* etc).
@@ -6176,9 +6195,8 @@ void SemaCodeCompletion::CodeCompleteCase(Scope *S) {
// Code-complete the cases of a switch statement over an enumeration type
// by providing the list of
- EnumDecl *Enum = type->castAs<EnumType>()->getDecl();
- if (EnumDecl *Def = Enum->getDefinition())
- Enum = Def;
+ EnumDecl *Enum =
+ type->castAs<EnumType>()->getOriginalDecl()->getDefinitionOrSelf();
// Determine which enumerators we have already seen in the switch statement.
// FIXME: Ideally, we would also be able to look *past* the code-completion
@@ -6879,8 +6897,8 @@ void SemaCodeCompletion::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
// Try to instantiate any non-dependent declaration contexts before
// we look in them. Bail out if we fail.
- NestedNameSpecifier *NNS = SS.getScopeRep();
- if (NNS != nullptr && SS.isValid() && !NNS->isDependent()) {
+ NestedNameSpecifier NNS = SS.getScopeRep();
+ if (NNS && !NNS.isDependent()) {
if (Ctx == nullptr || SemaRef.RequireCompleteDeclContext(SS, Ctx))
return;
}
@@ -6894,14 +6912,13 @@ void SemaCodeCompletion::CodeCompleteQualifiedId(Scope *S, CXXScopeSpec &SS,
// The "template" keyword can follow "::" in the grammar, but only
// put it into the grammar if the nested-name-specifier is dependent.
// FIXME: results is always empty, this appears to be dead.
- if (!Results.empty() && NNS && NNS->isDependent())
+ if (!Results.empty() && NNS.isDependent())
Results.AddResult("template");
// If the scope is a concept-constrained type parameter, infer nested
// members based on the constraints.
- if (NNS) {
- if (const auto *TTPT =
- dyn_cast_or_null<TemplateTypeParmType>(NNS->getAsType())) {
+ if (NNS.getKind() == NestedNameSpecifier::Kind::Type) {
+ if (const auto *TTPT = dyn_cast<TemplateTypeParmType>(NNS.getAsType())) {
for (const auto &R : ConceptInfo(*TTPT, S).members()) {
if (R.Operator != ConceptInfo::Member::Colons)
continue;
@@ -7026,7 +7043,7 @@ void SemaCodeCompletion::CodeCompleteNamespaceDecl(Scope *S) {
NS != NSEnd; ++NS)
Results.AddResult(
CodeCompletionResult(NS->second, Results.getBasePriority(NS->second),
- nullptr),
+ /*Qualifier=*/std::nullopt),
SemaRef.CurContext, nullptr, false);
Results.ExitScope();
}
@@ -7813,7 +7830,8 @@ static void AddObjCMethods(ObjCContainerDecl *Container,
if (!Selectors.insert(M->getSelector()).second)
continue;
- Result R = Result(M, Results.getBasePriority(M), nullptr);
+ Result R =
+ Result(M, Results.getBasePriority(M), /*Qualifier=*/std::nullopt);
R.StartParameter = SelIdents.size();
R.AllParametersAreInformative = (WantKind != MK_Any);
if (!InOriginalClass)
@@ -8404,7 +8422,8 @@ AddClassMessageCompletions(Sema &SemaRef, Scope *S, ParsedType Receiver,
continue;
Result R(MethList->getMethod(),
- Results.getBasePriority(MethList->getMethod()), nullptr);
+ Results.getBasePriority(MethList->getMethod()),
+ /*Qualifier=*/std::nullopt);
R.StartParameter = SelIdents.size();
R.AllParametersAreInformative = false;
Results.MaybeAddResult(R, SemaRef.CurContext);
@@ -8580,7 +8599,8 @@ void SemaCodeCompletion::CodeCompleteObjCInstanceMessage(
continue;
Result R(MethList->getMethod(),
- Results.getBasePriority(MethList->getMethod()), nullptr);
+ Results.getBasePriority(MethList->getMethod()),
+ /*Qualifier=*/std::nullopt);
R.StartParameter = SelIdents.size();
R.AllParametersAreInformative = false;
Results.MaybeAddResult(R, SemaRef.CurContext);
@@ -8696,9 +8716,9 @@ static void AddProtocolResults(DeclContext *Ctx, DeclContext *CurContext,
// Record any protocols we find.
if (const auto *Proto = dyn_cast<ObjCProtocolDecl>(D))
if (!OnlyForwardDeclarations || !Proto->hasDefinition())
- Results.AddResult(
- Result(Proto, Results.getBasePriority(Proto), nullptr), CurContext,
- nullptr, false);
+ Results.AddResult(Result(Proto, Results.getBasePriority(Proto),
+ /*Qualifier=*/std::nullopt),
+ CurContext, nullptr, false);
}
}
@@ -8764,9 +8784,9 @@ static void AddInterfaceResults(DeclContext *Ctx, DeclContext *CurContext,
if (const auto *Class = dyn_cast<ObjCInterfaceDecl>(D))
if ((!OnlyForwardDeclarations || !Class->hasDefinition()) &&
(!OnlyUnimplemented || !Class->getImplementation()))
- Results.AddResult(
- Result(Class, Results.getBasePriority(Class), nullptr), CurContext,
- nullptr, false);
+ Results.AddResult(Result(Class, Results.getBasePriority(Class),
+ /*Qualifier=*/std::nullopt),
+ CurContext, nullptr, false);
}
}
@@ -8878,9 +8898,9 @@ void SemaCodeCompletion::CodeCompleteObjCInterfaceCategory(
for (const auto *D : TU->decls())
if (const auto *Category = dyn_cast<ObjCCategoryDecl>(D))
if (CategoryNames.insert(Category->getIdentifier()).second)
- Results.AddResult(
- Result(Category, Results.getBasePriority(Category), nullptr),
- SemaRef.CurContext, nullptr, false);
+ Results.AddResult(Result(Category, Results.getBasePriority(Category),
+ /*Qualifier=*/std::nullopt),
+ SemaRef.CurContext, nullptr, false);
Results.ExitScope();
HandleCodeCompleteResults(&SemaRef, CodeCompleter,
@@ -8915,7 +8935,8 @@ void SemaCodeCompletion::CodeCompleteObjCImplementationCategory(
for (const auto *Cat : Class->visible_categories()) {
if ((!IgnoreImplemented || !Cat->getImplementation()) &&
CategoryNames.insert(Cat->getIdentifier()).second)
- Results.AddResult(Result(Cat, Results.getBasePriority(Cat), nullptr),
+ Results.AddResult(Result(Cat, Results.getBasePriority(Cat),
+ /*Qualifier=*/std::nullopt),
SemaRef.CurContext, nullptr, false);
}
@@ -9015,7 +9036,8 @@ void SemaCodeCompletion::CodeCompleteObjCPropertySynthesizeIvar(
for (; Class; Class = Class->getSuperClass()) {
for (ObjCIvarDecl *Ivar = Class->all_declared_ivar_begin(); Ivar;
Ivar = Ivar->getNextIvar()) {
- Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar), nullptr),
+ Results.AddResult(Result(Ivar, Results.getBasePriority(Ivar),
+ /*Qualifier=*/std::nullopt),
SemaRef.CurContext, nullptr, false);
// Determine whether we've seen an ivar with a name similar to the
@@ -10031,7 +10053,8 @@ void SemaCodeCompletion::CodeCompleteObjCMethodDeclSelector(
}
Result R(MethList->getMethod(),
- Results.getBasePriority(MethList->getMethod()), nullptr);
+ Results.getBasePriority(MethList->getMethod()),
+ /*Qualifier=*/std::nullopt);
R.StartParameter = SelIdents.size();
R.AllParametersAreInformative = false;
R.DeclaringEntity = true;
diff --git a/clang/lib/Sema/SemaCoroutine.cpp b/clang/lib/Sema/SemaCoroutine.cpp
index a1389c6c034b1..b6843a8795459 100644
--- a/clang/lib/Sema/SemaCoroutine.cpp
+++ b/clang/lib/Sema/SemaCoroutine.cpp
@@ -89,8 +89,8 @@ static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD,
AddArg(T);
// Build the template-id.
- QualType CoroTrait =
- S.CheckTemplateIdType(TemplateName(CoroTraits), KwLoc, Args);
+ QualType CoroTrait = S.CheckTemplateIdType(
+ ElaboratedTypeKeyword::None, TemplateName(CoroTraits), KwLoc, Args);
if (CoroTrait.isNull())
return QualType();
if (S.RequireCompleteType(KwLoc, CoroTrait,
@@ -111,23 +111,18 @@ static QualType lookupPromiseType(Sema &S, const FunctionDecl *FD,
<< RD;
return QualType();
}
- // The promise type is required to be a class type.
- QualType PromiseType = S.Context.getTypeDeclType(Promise);
-
- auto buildElaboratedType = [&]() {
- auto *NNS = NestedNameSpecifier::Create(S.Context, nullptr, S.getStdNamespace());
- NNS = NestedNameSpecifier::Create(S.Context, NNS, CoroTrait.getTypePtr());
- return S.Context.getElaboratedType(ElaboratedTypeKeyword::None, NNS,
- PromiseType);
- };
+ NestedNameSpecifier Qualifier(CoroTrait.getTypePtr());
+ QualType PromiseType = S.Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ Qualifier, Promise);
+ // The promise type is required to be a class type.
if (!PromiseType->getAsCXXRecordDecl()) {
S.Diag(FuncLoc,
diag::err_implied_std_coroutine_traits_promise_type_not_class)
- << buildElaboratedType();
+ << PromiseType;
return QualType();
}
- if (S.RequireCompleteType(FuncLoc, buildElaboratedType(),
+ if (S.RequireCompleteType(FuncLoc, PromiseType,
diag::err_coroutine_promise_type_incomplete))
return QualType();
@@ -167,8 +162,8 @@ static QualType lookupCoroutineHandleType(Sema &S, QualType PromiseType,
S.Context.getTrivialTypeSourceInfo(PromiseType, Loc)));
// Build the template-id.
- QualType CoroHandleType =
- S.CheckTemplateIdType(TemplateName(CoroHandle), Loc, Args);
+ QualType CoroHandleType = S.CheckTemplateIdType(
+ ElaboratedTypeKeyword::None, TemplateName(CoroHandle), Loc, Args);
if (CoroHandleType.isNull())
return QualType();
if (S.RequireCompleteType(Loc, CoroHandleType,
@@ -643,7 +638,9 @@ static void checkNoThrow(Sema &S, const Stmt *E,
QualType::DestructionKind::DK_cxx_destructor) {
const auto *T =
cast<RecordType>(ReturnType.getCanonicalType().getTypePtr());
- checkDeclNoexcept(cast<CXXRecordDecl>(T->getDecl())->getDestructor(),
+ checkDeclNoexcept(cast<CXXRecordDecl>(T->getOriginalDecl())
+ ->getDefinition()
+ ->getDestructor(),
/*IsDtor=*/true);
}
} else
@@ -1082,9 +1079,9 @@ static Expr *buildStdNoThrowDeclRef(Sema &S, SourceLocation Loc) {
static TypeSourceInfo *getTypeSourceInfoForStdAlignValT(Sema &S,
SourceLocation Loc) {
- EnumDecl *StdAlignValT = S.getStdAlignValT();
- QualType StdAlignValDecl = S.Context.getTypeDeclType(StdAlignValT);
- return S.Context.getTrivialTypeSourceInfo(StdAlignValDecl);
+ EnumDecl *StdAlignValDecl = S.getStdAlignValT();
+ CanQualType StdAlignValT = S.Context.getCanonicalTagType(StdAlignValDecl);
+ return S.Context.getTrivialTypeSourceInfo(StdAlignValT);
}
// When searching for custom allocators on the PromiseType we want to
diff --git a/clang/lib/Sema/SemaDecl.cpp b/clang/lib/Sema/SemaDecl.cpp
index 11cbda412667f..ef74dddc218bb 100644
--- a/clang/lib/Sema/SemaDecl.cpp
+++ b/clang/lib/Sema/SemaDecl.cpp
@@ -140,8 +140,8 @@ class TypeNameValidatorCCC final : public CorrectionCandidateCallback {
} // end anonymous namespace
-QualType Sema::getTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK,
- TypeDecl *TD, SourceLocation NameLoc) {
+void Sema::checkTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK,
+ TypeDecl *TD, SourceLocation NameLoc) {
auto *LookupRD = dyn_cast_or_null<CXXRecordDecl>(LookupCtx);
auto *FoundRD = dyn_cast<CXXRecordDecl>(TD);
if (DCK != DiagCtorKind::None && LookupRD && FoundRD &&
@@ -157,7 +157,6 @@ QualType Sema::getTypeDeclType(DeclContext *LookupCtx, DiagCtorKind DCK,
DiagnoseUseOfDecl(TD, NameLoc);
MarkAnyDeclReferenced(TD->getLocation(), TD, /*OdrUse=*/false);
- return Context.getTypeDeclType(TD);
}
namespace {
@@ -182,13 +181,13 @@ lookupUnqualifiedTypeNameInBase(Sema &S, const IdentifierInfo &II,
UnqualifiedTypeNameLookupResult FoundTypeDecl =
UnqualifiedTypeNameLookupResult::NotFound;
for (const auto &Base : RD->bases()) {
- const CXXRecordDecl *BaseRD = nullptr;
- if (auto *BaseTT = Base.getType()->getAs<TagType>())
- BaseRD = BaseTT->getAsCXXRecordDecl();
- else if (auto *TST = Base.getType()->getAs<TemplateSpecializationType>()) {
+ const CXXRecordDecl *BaseRD = Base.getType()->getAsCXXRecordDecl();
+ if (BaseRD) {
+ } else if (auto *TST = dyn_cast<TemplateSpecializationType>(
+ Base.getType().getCanonicalType())) {
// Look for type decls in dependent base classes that have known primary
// templates.
- if (!TST || !TST->isDependentType())
+ if (!TST->isDependentType())
continue;
auto *TD = TST->getTemplateName().getAsTemplateDecl();
if (!TD)
@@ -253,8 +252,7 @@ static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,
S.Diag(NameLoc, diag::ext_found_in_dependent_base) << &II;
ASTContext &Context = S.Context;
- auto *NNS = NestedNameSpecifier::Create(
- Context, nullptr, cast<Type>(Context.getRecordType(RD)));
+ NestedNameSpecifier NNS(Context.getCanonicalTagType(RD).getTypePtr());
QualType T =
Context.getDependentNameType(ElaboratedTypeKeyword::None, NNS, &II);
@@ -269,45 +267,6 @@ static ParsedType recoverFromTypeInKnownDependentBase(Sema &S,
return S.CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
}
-/// Build a ParsedType for a simple-type-specifier with a nested-name-specifier.
-static ParsedType buildNamedType(Sema &S, const CXXScopeSpec *SS, QualType T,
- SourceLocation NameLoc,
- bool WantNontrivialTypeSourceInfo = true) {
- switch (T->getTypeClass()) {
- case Type::DeducedTemplateSpecialization:
- case Type::Enum:
- case Type::InjectedClassName:
- case Type::Record:
- case Type::Typedef:
- case Type::UnresolvedUsing:
- case Type::Using:
- break;
- // These can never be qualified so an ElaboratedType node
- // would carry no additional meaning.
- case Type::ObjCInterface:
- case Type::ObjCTypeParam:
- case Type::TemplateTypeParm:
- return ParsedType::make(T);
- default:
- llvm_unreachable("Unexpected Type Class");
- }
-
- if (!SS || SS->isEmpty())
- return ParsedType::make(S.Context.getElaboratedType(
- ElaboratedTypeKeyword::None, nullptr, T, nullptr));
-
- QualType ElTy = S.getElaboratedType(ElaboratedTypeKeyword::None, *SS, T);
- if (!WantNontrivialTypeSourceInfo)
- return ParsedType::make(ElTy);
-
- TypeLocBuilder Builder;
- Builder.pushTypeSpec(T).setNameLoc(NameLoc);
- ElaboratedTypeLoc ElabTL = Builder.push<ElaboratedTypeLoc>(ElTy);
- ElabTL.setElaboratedKeywordLoc(SourceLocation());
- ElabTL.setQualifierLoc(SS->getWithLocInContext(S.Context));
- return S.CreateParsedType(ElTy, Builder.getTypeSourceInfo(S.Context, ElTy));
-}
-
ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
Scope *S, CXXScopeSpec *SS, bool isClassName,
bool HasTrailingDot, ParsedType ObjectTypePtr,
@@ -348,9 +307,10 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
if (AllowImplicitTypename == ImplicitTypenameContext::No)
return nullptr;
SourceLocation QualifiedLoc = SS->getRange().getBegin();
- auto DB =
- DiagCompat(QualifiedLoc, diag_compat::implicit_typename)
- << NestedNameSpecifier::Create(Context, SS->getScopeRep(), &II);
+ // FIXME: Defer the diagnostic after we build the type and use it.
+ auto DB = DiagCompat(QualifiedLoc, diag_compat::implicit_typename)
+ << Context.getDependentNameType(ElaboratedTypeKeyword::None,
+ SS->getScopeRep(), &II);
if (!getLangOpts().CPlusPlus20)
DB << FixItHint::CreateInsertion(QualifiedLoc, "typename ");
}
@@ -430,7 +390,7 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
bool MemberOfUnknownSpecialization;
UnqualifiedId TemplateName;
TemplateName.setIdentifier(NewII, NameLoc);
- NestedNameSpecifier *NNS = Correction.getCorrectionSpecifier();
+ NestedNameSpecifier NNS = Correction.getCorrectionSpecifier();
CXXScopeSpec NewSS, *NewSSPtr = SS;
if (SS && NNS) {
NewSS.MakeTrivial(Context, NNS, SourceRange(NameLoc));
@@ -530,20 +490,78 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
assert(IIDecl && "Didn't find decl");
- QualType T;
+ TypeLocBuilder TLB;
if (TypeDecl *TD = dyn_cast<TypeDecl>(IIDecl)) {
- // C++ [class.qual]p2: A lookup that would find the injected-class-name
- // instead names the constructors of the class, except when naming a class.
- // This is ill-formed when we're not actually forming a ctor or dtor name.
- T = getTypeDeclType(LookupCtx,
- IsImplicitTypename ? DiagCtorKind::Implicit
- : DiagCtorKind::None,
- TD, NameLoc);
- } else if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
+ checkTypeDeclType(LookupCtx,
+ IsImplicitTypename ? DiagCtorKind::Implicit
+ : DiagCtorKind::None,
+ TD, NameLoc);
+ QualType T;
+ if (FoundUsingShadow) {
+ T = Context.getUsingType(ElaboratedTypeKeyword::None,
+ SS ? SS->getScopeRep() : std::nullopt,
+ FoundUsingShadow);
+ if (!WantNontrivialTypeSourceInfo)
+ return ParsedType::make(T);
+ TLB.push<UsingTypeLoc>(T).set(/*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS ? SS->getWithLocInContext(Context)
+ : NestedNameSpecifierLoc(),
+ NameLoc);
+ } else if (auto *Tag = dyn_cast<TagDecl>(TD)) {
+ T = Context.getTagType(ElaboratedTypeKeyword::None,
+ SS ? SS->getScopeRep() : std::nullopt, Tag,
+ /*OwnsTag=*/false);
+ if (!WantNontrivialTypeSourceInfo)
+ return ParsedType::make(T);
+ auto TL = TLB.push<TagTypeLoc>(T);
+ TL.setElaboratedKeywordLoc(SourceLocation());
+ TL.setQualifierLoc(SS ? SS->getWithLocInContext(Context)
+ : NestedNameSpecifierLoc());
+ TL.setNameLoc(NameLoc);
+ } else if (auto *TN = dyn_cast<TypedefNameDecl>(TD);
+ TN && !isa<ObjCTypeParamDecl>(TN)) {
+ T = Context.getTypedefType(ElaboratedTypeKeyword::None,
+ SS ? SS->getScopeRep() : std::nullopt, TN);
+ if (!WantNontrivialTypeSourceInfo)
+ return ParsedType::make(T);
+ TLB.push<TypedefTypeLoc>(T).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(),
+ NameLoc);
+ } else if (auto *UD = dyn_cast<UnresolvedUsingTypenameDecl>(TD)) {
+ T = Context.getUnresolvedUsingType(ElaboratedTypeKeyword::None,
+ SS ? SS->getScopeRep() : std::nullopt,
+ UD);
+ if (!WantNontrivialTypeSourceInfo)
+ return ParsedType::make(T);
+ TLB.push<UnresolvedUsingTypeLoc>(T).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS ? SS->getWithLocInContext(Context) : NestedNameSpecifierLoc(),
+ NameLoc);
+ } else {
+ T = Context.getTypeDeclType(TD);
+ if (!WantNontrivialTypeSourceInfo)
+ return ParsedType::make(T);
+ if (isa<ObjCTypeParamType>(T))
+ TLB.push<ObjCTypeParamTypeLoc>(T).setNameLoc(NameLoc);
+ else
+ TLB.pushTypeSpec(T).setNameLoc(NameLoc);
+ }
+ return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
+ }
+ if (ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(IIDecl)) {
(void)DiagnoseUseOfDecl(IDecl, NameLoc);
- if (!HasTrailingDot)
- T = Context.getObjCInterfaceType(IDecl);
- FoundUsingShadow = nullptr; // FIXME: Target must be a TypeDecl.
+ if (!HasTrailingDot) {
+ // FIXME: Support UsingType for this case.
+ QualType T = Context.getObjCInterfaceType(IDecl);
+ if (!WantNontrivialTypeSourceInfo)
+ return ParsedType::make(T);
+ auto TL = TLB.push<ObjCInterfaceTypeLoc>(T);
+ TL.setNameLoc(NameLoc);
+ // FIXME: Pass in this source location.
+ TL.setNameEndLoc(NameLoc);
+ return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
+ }
} else if (auto *UD = dyn_cast<UnresolvedUsingIfExistsDecl>(IIDecl)) {
(void)DiagnoseUseOfDecl(UD, NameLoc);
// Recover with 'int'
@@ -551,41 +569,38 @@ ParsedType Sema::getTypeName(const IdentifierInfo &II, SourceLocation NameLoc,
} else if (AllowDeducedTemplate) {
if (auto *TD = getAsTypeTemplateDecl(IIDecl)) {
assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD);
+ // FIXME: Support UsingType here.
TemplateName Template = Context.getQualifiedTemplateName(
- SS ? SS->getScopeRep() : nullptr, /*TemplateKeyword=*/false,
+ SS ? SS->getScopeRep() : std::nullopt, /*TemplateKeyword=*/false,
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD));
- T = Context.getDeducedTemplateSpecializationType(Template, QualType(),
- false);
- // Don't wrap in a further UsingType.
- FoundUsingShadow = nullptr;
+ QualType T = Context.getDeducedTemplateSpecializationType(
+ ElaboratedTypeKeyword::None, Template, QualType(), false);
+ auto TL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T);
+ TL.setElaboratedKWLoc(SourceLocation());
+ TL.setNameLoc(NameLoc);
+ TL.setQualifierLoc(SS ? SS->getWithLocInContext(Context)
+ : NestedNameSpecifierLoc());
+ return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
}
}
- if (T.isNull()) {
- // If it's not plausibly a type, suppress diagnostics.
- Result.suppressDiagnostics();
- return nullptr;
- }
-
- if (FoundUsingShadow)
- T = Context.getUsingType(FoundUsingShadow, T);
-
- return buildNamedType(*this, SS, T, NameLoc, WantNontrivialTypeSourceInfo);
+ // As it's not plausibly a type, suppress diagnostics.
+ Result.suppressDiagnostics();
+ return nullptr;
}
// Builds a fake NNS for the given decl context.
-static NestedNameSpecifier *
+static NestedNameSpecifier
synthesizeCurrentNestedNameSpecifier(ASTContext &Context, DeclContext *DC) {
for (;; DC = DC->getLookupParent()) {
DC = DC->getPrimaryContext();
auto *ND = dyn_cast<NamespaceDecl>(DC);
if (ND && !ND->isInline() && !ND->isAnonymousNamespace())
- return NestedNameSpecifier::Create(Context, nullptr, ND);
+ return NestedNameSpecifier(Context, ND, std::nullopt);
if (auto *RD = dyn_cast<CXXRecordDecl>(DC))
- return NestedNameSpecifier::Create(Context, nullptr,
- RD->getTypeForDecl());
+ return NestedNameSpecifier(Context.getCanonicalTagType(RD)->getTypePtr());
if (isa<TranslationUnitDecl>(DC))
- return NestedNameSpecifier::GlobalSpecifier(Context);
+ return NestedNameSpecifier::getGlobal();
}
llvm_unreachable("something isn't in TU scope?");
}
@@ -610,7 +625,7 @@ ParsedType Sema::ActOnMSVCUnknownTypeName(const IdentifierInfo &II,
bool IsTemplateTypeArg) {
assert(getLangOpts().MSVCCompat && "shouldn't be called in non-MSVC mode");
- NestedNameSpecifier *NNS = nullptr;
+ NestedNameSpecifier NNS = std::nullopt;
if (IsTemplateTypeArg && getCurScope()->isTemplateParamScope()) {
// If we weren't able to parse a default template argument, delay lookup
// until instantiation time by making a non-dependent DependentTypeName. We
@@ -625,7 +640,7 @@ ParsedType Sema::ActOnMSVCUnknownTypeName(const IdentifierInfo &II,
findRecordWithDependentBasesOfEnclosingMethod(CurContext)) {
// Build a DependentNameType that will perform lookup into RD at
// instantiation time.
- NNS = NestedNameSpecifier::Create(Context, nullptr, RD->getTypeForDecl());
+ NNS = NestedNameSpecifier(Context.getCanonicalTagType(RD)->getTypePtr());
// Diagnose that this identifier was undeclared, and retry the lookup during
// template instantiation.
@@ -678,19 +693,22 @@ DeclSpec::TST Sema::isTagName(IdentifierInfo &II, Scope *S) {
}
bool Sema::isMicrosoftMissingTypename(const CXXScopeSpec *SS, Scope *S) {
- if (CurContext->isRecord()) {
- if (SS->getScopeRep()->getKind() == NestedNameSpecifier::Super)
- return true;
-
- const Type *Ty = SS->getScopeRep()->getAsType();
+ if (!CurContext->isRecord())
+ return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
- CXXRecordDecl *RD = cast<CXXRecordDecl>(CurContext);
- for (const auto &Base : RD->bases())
- if (Ty && Context.hasSameUnqualifiedType(QualType(Ty, 1), Base.getType()))
+ switch (SS->getScopeRep().getKind()) {
+ case NestedNameSpecifier::Kind::Super:
+ return true;
+ case NestedNameSpecifier::Kind::Type: {
+ QualType T(SS->getScopeRep().getAsType(), 0);
+ for (const auto &Base : cast<CXXRecordDecl>(CurContext)->bases())
+ if (Context.hasSameUnqualifiedType(T, Base.getType()))
return true;
+ [[fallthrough]];
+ }
+ default:
return S->isFunctionPrototypeScope();
}
- return CurContext->isFunctionOrMethod() || S->isFunctionPrototypeScope();
}
void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
@@ -786,7 +804,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
Diag(IILoc, IsTemplateName ? diag::err_no_member_template
: diag::err_typename_nested_not_found)
<< II << DC << SS->getRange();
- else if (SS->isValid() && SS->getScopeRep()->containsErrors()) {
+ else if (SS->isValid() && SS->getScopeRep().containsErrors()) {
SuggestedType =
ActOnTypenameType(S, SourceLocation(), *SS, *II, IILoc).get();
} else if (isDependentScopeSpecifier(*SS)) {
@@ -794,12 +812,13 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S))
DiagID = diag::ext_typename_missing;
+ SuggestedType =
+ ActOnTypenameType(S, SourceLocation(), *SS, *II, IILoc).get();
+
Diag(SS->getRange().getBegin(), DiagID)
- << NestedNameSpecifier::Create(Context, SS->getScopeRep(), II)
+ << GetTypeFromParser(SuggestedType)
<< SourceRange(SS->getRange().getBegin(), IILoc)
<< FixItHint::CreateInsertion(SS->getRange().getBegin(), "typename ");
- SuggestedType = ActOnTypenameType(S, SourceLocation(),
- *SS, *II, IILoc).get();
} else {
assert(SS && SS->isInvalid() &&
"Invalid scope specifier has already been diagnosed");
@@ -1156,10 +1175,34 @@ Sema::NameClassification Sema::ClassifyName(Scope *S, CXXScopeSpec &SS,
}
auto BuildTypeFor = [&](TypeDecl *Type, NamedDecl *Found) {
- QualType T = Context.getTypeDeclType(Type);
- if (const auto *USD = dyn_cast<UsingShadowDecl>(Found))
- T = Context.getUsingType(USD, T);
- return buildNamedType(*this, &SS, T, NameLoc);
+ QualType T;
+ TypeLocBuilder TLB;
+ if (const auto *USD = dyn_cast<UsingShadowDecl>(Found)) {
+ T = Context.getUsingType(ElaboratedTypeKeyword::None, SS.getScopeRep(),
+ USD);
+ TLB.push<UsingTypeLoc>(T).set(/*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context), NameLoc);
+ } else {
+ T = Context.getTypeDeclType(ElaboratedTypeKeyword::None, SS.getScopeRep(),
+ Type);
+ if (isa<TagType>(T)) {
+ auto TTL = TLB.push<TagTypeLoc>(T);
+ TTL.setElaboratedKeywordLoc(SourceLocation());
+ TTL.setQualifierLoc(SS.getWithLocInContext(Context));
+ TTL.setNameLoc(NameLoc);
+ } else if (isa<TypedefType>(T)) {
+ TLB.push<TypedefTypeLoc>(T).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context), NameLoc);
+ } else if (isa<UnresolvedUsingType>(T)) {
+ TLB.push<UnresolvedUsingTypeLoc>(T).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context), NameLoc);
+ } else {
+ TLB.pushTypeSpec(T).setNameLoc(NameLoc);
+ }
+ }
+ return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
};
NamedDecl *FirstDecl = (*Result.begin())->getUnderlyingDecl();
@@ -2009,8 +2052,7 @@ static bool ShouldDiagnoseUnusedDecl(const LangOptions &LangOpts,
// consistent for both scalars and arrays.
Ty = Ty->getBaseElementTypeUnsafe();
- if (const TagType *TT = Ty->getAs<TagType>()) {
- const TagDecl *Tag = TT->getDecl();
+ if (const TagDecl *Tag = Ty->getAsTagDecl()) {
if (Tag->hasAttr<UnusedAttr>())
return false;
@@ -2070,7 +2112,7 @@ void Sema::DiagnoseUnusedNestedTypedefs(const RecordDecl *D) {
void Sema::DiagnoseUnusedNestedTypedefs(const RecordDecl *D,
DiagReceiverTy DiagReceiver) {
- if (D->getTypeForDecl()->isDependentType())
+ if (D->isDependentType())
return;
for (auto *TmpD : D->decls()) {
@@ -2128,8 +2170,7 @@ void Sema::DiagnoseUnusedButSetDecl(const VarDecl *VD,
if (Ty->isReferenceType() || Ty->isDependentType())
return;
- if (const TagType *TT = Ty->getAs<TagType>()) {
- const TagDecl *Tag = TT->getDecl();
+ if (const TagDecl *Tag = Ty->getAsTagDecl()) {
if (Tag->hasAttr<UnusedAttr>())
return;
// In C++, don't warn for record types that don't have WarnUnusedAttr, to
@@ -2508,7 +2549,8 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
}
Context.setObjCIdRedefinitionType(T);
// Install the built-in type for 'id', ignoring the current definition.
- New->setTypeForDecl(Context.getObjCIdType().getTypePtr());
+ New->setModedTypeSourceInfo(New->getTypeSourceInfo(),
+ Context.getObjCIdType());
return;
}
case 5:
@@ -2516,14 +2558,16 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
break;
Context.setObjCClassRedefinitionType(New->getUnderlyingType());
// Install the built-in type for 'Class', ignoring the current definition.
- New->setTypeForDecl(Context.getObjCClassType().getTypePtr());
+ New->setModedTypeSourceInfo(New->getTypeSourceInfo(),
+ Context.getObjCClassType());
return;
case 3:
if (!TypeID->isStr("SEL"))
break;
Context.setObjCSelRedefinitionType(New->getUnderlyingType());
// Install the built-in type for 'SEL', ignoring the current definition.
- New->setTypeForDecl(Context.getObjCSelType().getTypePtr());
+ New->setModedTypeSourceInfo(New->getTypeSourceInfo(),
+ Context.getObjCSelType());
return;
}
// Fall through - the typedef name was not a builtin type.
@@ -2555,7 +2599,6 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
!hasVisibleDefinition(OldTag, &Hidden)) {
// There is a definition of this tag, but it is not visible. Use it
// instead of our tag.
- New->setTypeForDecl(OldTD->getTypeForDecl());
if (OldTD->isModed())
New->setModedTypeSourceInfo(OldTD->getTypeSourceInfo(),
OldTD->getUnderlyingType());
@@ -2742,7 +2785,7 @@ static bool mergeAlignedAttrs(Sema &S, NamedDecl *New, Decl *Old) {
if (ValueDecl *VD = dyn_cast<ValueDecl>(New))
Ty = VD->getType();
else
- Ty = S.Context.getTagDeclType(cast<TagDecl>(New));
+ Ty = S.Context.getCanonicalTagType(cast<TagDecl>(New));
if (OldAlign == 0)
OldAlign = S.Context.getTypeAlign(Ty);
@@ -2913,8 +2956,11 @@ static bool mergeDeclAttribute(Sema &S, NamedDecl *D,
}
static const NamedDecl *getDefinition(const Decl *D) {
- if (const TagDecl *TD = dyn_cast<TagDecl>(D))
- return TD->getDefinition();
+ if (const TagDecl *TD = dyn_cast<TagDecl>(D)) {
+ if (const auto *Def = TD->getDefinition(); Def && !Def->isBeingDefined())
+ return Def;
+ return nullptr;
+ }
if (const VarDecl *VD = dyn_cast<VarDecl>(D)) {
const VarDecl *Def = VD->getDefinition();
if (Def)
@@ -5016,7 +5062,7 @@ void Sema::setTagNameForLinkagePurposes(TagDecl *TagFromDeclSpec,
// The type must match the tag exactly; no qualifiers allowed.
if (!Context.hasSameType(NewTD->getUnderlyingType(),
- Context.getTagDeclType(TagFromDeclSpec))) {
+ Context.getCanonicalTagType(TagFromDeclSpec))) {
if (getLangOpts().CPlusPlus)
Context.addTypedefNameForUnnamedTagDecl(TagFromDeclSpec, NewTD);
return;
@@ -5224,9 +5270,9 @@ Decl *Sema::ParsedFreeStandingDeclSpec(Scope *S, AccessSpecifier AS,
Record = dyn_cast<RecordDecl>(Tag);
else if (const RecordType *RT =
DS.getRepAsType().get()->getAsStructureType())
- Record = RT->getDecl();
+ Record = RT->getOriginalDecl()->getDefinitionOrSelf();
else if (const RecordType *UT = DS.getRepAsType().get()->getAsUnionType())
- Record = UT->getDecl();
+ Record = UT->getOriginalDecl()->getDefinitionOrSelf();
if (Record && getLangOpts().MicrosoftExt) {
Diag(DS.getBeginLoc(), diag::ext_ms_anonymous_record)
@@ -5754,7 +5800,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
if (RecordDecl *OwningClass = dyn_cast<RecordDecl>(Owner)) {
Anon = FieldDecl::Create(
Context, OwningClass, DS.getBeginLoc(), Record->getLocation(),
- /*IdentifierInfo=*/nullptr, Context.getTypeDeclType(Record), TInfo,
+ /*IdentifierInfo=*/nullptr, Context.getCanonicalTagType(Record), TInfo,
/*BitWidth=*/nullptr, /*Mutable=*/false,
/*InitStyle=*/ICIS_NoInit);
Anon->setAccess(AS);
@@ -5774,7 +5820,7 @@ Decl *Sema::BuildAnonymousStructOrUnion(Scope *S, DeclSpec &DS,
Anon = VarDecl::Create(Context, Owner, DS.getBeginLoc(),
Record->getLocation(), /*IdentifierInfo=*/nullptr,
- Context.getTypeDeclType(Record), TInfo, SC);
+ Context.getCanonicalTagType(Record), TInfo, SC);
if (Invalid)
Anon->setInvalidDecl();
@@ -5837,7 +5883,7 @@ Decl *Sema::BuildMicrosoftCAnonymousStruct(Scope *S, DeclSpec &DS,
assert(TInfo && "couldn't build declarator info for anonymous struct");
auto *ParentDecl = cast<RecordDecl>(CurContext);
- QualType RecTy = Context.getTypeDeclType(Record);
+ CanQualType RecTy = Context.getCanonicalTagType(Record);
// Create a declaration for this anonymous struct.
NamedDecl *Anon =
@@ -5956,14 +6002,14 @@ Sema::GetNameFromUnqualifiedId(const UnqualifiedId &Name) {
return DeclarationNameInfo();
// Determine the type of the class being constructed.
- QualType CurClassType = Context.getTypeDeclType(CurClass);
+ CanQualType CurClassType = Context.getCanonicalTagType(CurClass);
// FIXME: Check two things: that the template-id names the same type as
// CurClassType, and that the template-id does not occur when the name
// was qualified.
- NameInfo.setName(Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(CurClassType)));
+ NameInfo.setName(
+ Context.DeclarationNames.getCXXConstructorName(CurClassType));
// FIXME: should we retrieve TypeSourceInfo?
NameInfo.setNamedTypeInfo(nullptr);
return NameInfo;
@@ -6251,8 +6297,9 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
// that's the case, then drop this declaration entirely.
if ((Name.getNameKind() == DeclarationName::CXXConstructorName ||
Name.getNameKind() == DeclarationName::CXXDestructorName) &&
- !Context.hasSameType(Name.getCXXNameType(),
- Context.getTypeDeclType(cast<CXXRecordDecl>(Cur))))
+ !Context.hasSameType(
+ Name.getCXXNameType(),
+ Context.getCanonicalTagType(cast<CXXRecordDecl>(Cur))))
return true;
return false;
@@ -6272,36 +6319,48 @@ bool Sema::diagnoseQualifiedDeclaration(CXXScopeSpec &SS, DeclContext *DC,
<< FixItHint::CreateRemoval(TemplateId->TemplateKWLoc);
NestedNameSpecifierLoc SpecLoc(SS.getScopeRep(), SS.location_data());
- do {
- if (TypeLoc TL = SpecLoc.getTypeLoc()) {
- if (SourceLocation TemplateKeywordLoc = TL.getTemplateKeywordLoc();
- TemplateKeywordLoc.isValid())
- Diag(Loc, diag::ext_template_after_declarative_nns)
- << FixItHint::CreateRemoval(TemplateKeywordLoc);
- }
-
- if (const Type *T = SpecLoc.getNestedNameSpecifier()->getAsType()) {
- if (const auto *TST = T->getAsAdjusted<TemplateSpecializationType>()) {
- // C++23 [expr.prim.id.qual]p3:
- // [...] If a nested-name-specifier N is declarative and has a
- // simple-template-id with a template argument list A that involves a
- // template parameter, let T be the template nominated by N without A.
- // T shall be a class template.
- if (TST->isDependentType() && TST->isTypeAlias())
- Diag(Loc, diag::ext_alias_template_in_declarative_nns)
- << SpecLoc.getLocalSourceRange();
- } else if (T->isDecltypeType() || T->getAsAdjusted<PackIndexingType>()) {
- // C++23 [expr.prim.id.qual]p2:
- // [...] A declarative nested-name-specifier shall not have a
- // computed-type-specifier.
- //
- // CWG2858 changed this from 'decltype-specifier' to
- // 'computed-type-specifier'.
- Diag(Loc, diag::err_computed_type_in_declarative_nns)
- << T->isDecltypeType() << SpecLoc.getTypeLoc().getSourceRange();
- }
+ for (TypeLoc TL = SpecLoc.getAsTypeLoc(), NextTL; TL;
+ TL = std::exchange(NextTL, TypeLoc())) {
+ SourceLocation TemplateKeywordLoc;
+ switch (TL.getTypeLocClass()) {
+ case TypeLoc::TemplateSpecialization: {
+ auto TST = TL.castAs<TemplateSpecializationTypeLoc>();
+ TemplateKeywordLoc = TST.getTemplateKeywordLoc();
+ if (auto *T = TST.getTypePtr(); T->isDependentType() && T->isTypeAlias())
+ Diag(Loc, diag::ext_alias_template_in_declarative_nns)
+ << TST.getLocalSourceRange();
+ break;
+ }
+ case TypeLoc::Decltype:
+ case TypeLoc::PackIndexing: {
+ const Type *T = TL.getTypePtr();
+ // C++23 [expr.prim.id.qual]p2:
+ // [...] A declarative nested-name-specifier shall not have a
+ // computed-type-specifier.
+ //
+ // CWG2858 changed this from 'decltype-specifier' to
+ // 'computed-type-specifier'.
+ Diag(Loc, diag::err_computed_type_in_declarative_nns)
+ << T->isDecltypeType() << TL.getSourceRange();
+ break;
}
- } while ((SpecLoc = SpecLoc.getPrefix()));
+ case TypeLoc::DependentName:
+ NextTL =
+ TL.castAs<DependentNameTypeLoc>().getQualifierLoc().getAsTypeLoc();
+ break;
+ case TypeLoc::DependentTemplateSpecialization: {
+ auto TST = TL.castAs<DependentTemplateSpecializationTypeLoc>();
+ TemplateKeywordLoc = TST.getTemplateKeywordLoc();
+ NextTL = TST.getQualifierLoc().getAsTypeLoc();
+ break;
+ }
+ default:
+ break;
+ }
+ if (TemplateKeywordLoc.isValid())
+ Diag(Loc, diag::ext_template_after_declarative_nns)
+ << FixItHint::CreateRemoval(TemplateKeywordLoc);
+ }
return false;
}
@@ -9040,9 +9099,8 @@ bool Sema::AddOverriddenMethods(CXXRecordDecl *DC, CXXMethodDecl *MD) {
if (Name.getNameKind() == DeclarationName::CXXDestructorName) {
// We really want to find the base class destructor here.
- QualType T = Context.getTypeDeclType(BaseRecord);
- CanQualType CT = Context.getCanonicalType(T);
- Name = Context.DeclarationNames.getCXXDestructorName(CT);
+ Name = Context.DeclarationNames.getCXXDestructorName(
+ Context.getCanonicalTagType(BaseRecord));
}
for (NamedDecl *BaseND : BaseRecord->lookup(Name)) {
@@ -9728,7 +9786,8 @@ static void checkIsValidOpenCLKernelParameter(
// At this point we already handled everything except of a RecordType.
assert(PT->isRecordType() && "Unexpected type.");
- const RecordDecl *PD = PT->castAs<RecordType>()->getDecl();
+ const RecordDecl *PD =
+ PT->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
VisitStack.push_back(PD);
assert(VisitStack.back() && "First decl null?");
@@ -9756,7 +9815,9 @@ static void checkIsValidOpenCLKernelParameter(
"Unexpected type.");
const Type *FieldRecTy = FieldTy->getPointeeOrArrayElementType();
- RD = FieldRecTy->castAs<RecordType>()->getDecl();
+ RD = FieldRecTy->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
} else {
RD = cast<RecordDecl>(Next);
}
@@ -10763,7 +10824,7 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
// redeclaration lookup found nothing at all. Diagnose that now;
// nothing will diagnose that error later.
if (isFriend &&
- (D.getCXXScopeSpec().getScopeRep()->isDependent() ||
+ (D.getCXXScopeSpec().getScopeRep().isDependent() ||
(!Previous.empty() && CurContext->isDependentContext()))) {
// ignore these
} else if (NewFD->isCPUDispatchMultiVersion() ||
@@ -12267,11 +12328,11 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
// template struct A<B>;
if (NewFD->getFriendObjectKind() == Decl::FriendObjectKind::FOK_None ||
!Destructor->getFunctionObjectParameterType()->isDependentType()) {
- CXXRecordDecl *Record = Destructor->getParent();
- QualType ClassType = Context.getTypeDeclType(Record);
+ CanQualType ClassType =
+ Context.getCanonicalTagType(Destructor->getParent());
- DeclarationName Name = Context.DeclarationNames.getCXXDestructorName(
- Context.getCanonicalType(ClassType));
+ DeclarationName Name =
+ Context.DeclarationNames.getCXXDestructorName(ClassType);
if (NewFD->getDeclName() != Name) {
Diag(NewFD->getLocation(), diag::err_destructor_name);
NewFD->setInvalidDecl();
@@ -13275,7 +13336,8 @@ struct DiagNonTrivalCUnionDefaultInitializeVisitor
}
void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ QT->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion()) {
if (OrigLoc.isValid()) {
bool IsUnion = false;
@@ -13341,7 +13403,8 @@ struct DiagNonTrivalCUnionDestructedTypeVisitor
}
void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ QT->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion()) {
if (OrigLoc.isValid()) {
bool IsUnion = false;
@@ -13406,7 +13469,8 @@ struct DiagNonTrivalCUnionCopyVisitor
}
void visitStruct(QualType QT, const FieldDecl *FD, bool InNonTrivialUnion) {
- const RecordDecl *RD = QT->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ QT->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion()) {
if (OrigLoc.isValid()) {
bool IsUnion = false;
@@ -14379,7 +14443,9 @@ void Sema::ActOnUninitializedDecl(Decl *RealDecl) {
if (getLangOpts().CPlusPlus && Var->hasLocalStorage()) {
if (const RecordType *Record
= Context.getBaseElementType(Type)->getAs<RecordType>()) {
- CXXRecordDecl *CXXRecord = cast<CXXRecordDecl>(Record->getDecl());
+ CXXRecordDecl *CXXRecord =
+ cast<CXXRecordDecl>(Record->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Mark the function (if we're in one) for further checking even if the
// looser rules of C++11 do not require such checks, so that we can
// diagnose incompatibilities with C++98.
@@ -17454,6 +17520,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
// FIXME: Check member specializations more carefully.
bool isMemberSpecialization = false;
+ bool IsInjectedClassName = false;
bool Invalid = false;
// We only need to do this matching if we have template parameters
@@ -17904,8 +17971,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
// see http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#407
if (getLangOpts().CPlusPlus) {
if (TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(PrevDecl)) {
- if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
- TagDecl *Tag = TT->getDecl();
+ if (TagDecl *Tag = TD->getUnderlyingType()->getAsTagDecl()) {
if (Tag->getDeclName() == Name &&
Tag->getDeclContext()->getRedeclContext()
->Equals(TD->getDeclContext()->getRedeclContext())) {
@@ -17915,6 +17981,15 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
Previous.resolveKind();
}
}
+ } else if (auto *RD = dyn_cast<CXXRecordDecl>(PrevDecl);
+ RD && RD->isInjectedClassName()) {
+ // If lookup found the injected class name, the previous declaration is
+ // the class being injected into.
+ PrevDecl = cast<TagDecl>(RD->getDeclContext());
+ Previous.clear();
+ Previous.addDecl(PrevDecl);
+ Previous.resolveKind();
+ IsInjectedClassName = true;
}
}
@@ -18038,78 +18113,79 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
// Diagnose attempts to redefine a tag.
if (TUK == TagUseKind::Definition) {
- if (NamedDecl *Def = PrevTagDecl->getDefinition()) {
- // If we're defining a specialization and the previous definition
- // is from an implicit instantiation, don't emit an error
- // here; we'll catch this in the general case below.
- bool IsExplicitSpecializationAfterInstantiation = false;
- if (isMemberSpecialization) {
- if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Def))
- IsExplicitSpecializationAfterInstantiation =
- RD->getTemplateSpecializationKind() !=
- TSK_ExplicitSpecialization;
- else if (EnumDecl *ED = dyn_cast<EnumDecl>(Def))
- IsExplicitSpecializationAfterInstantiation =
- ED->getTemplateSpecializationKind() !=
- TSK_ExplicitSpecialization;
- }
-
- // Note that clang allows ODR-like semantics for ObjC/C, i.e., do
- // not keep more that one definition around (merge them). However,
- // ensure the decl passes the structural compatibility check in
- // C11 6.2.7/1 (or 6.1.2.6/1 in C89).
- NamedDecl *Hidden = nullptr;
- if (SkipBody &&
- (!hasVisibleDefinition(Def, &Hidden) || getLangOpts().C23)) {
- // There is a definition of this tag, but it is not visible. We
- // explicitly make use of C++'s one definition rule here, and
- // assume that this definition is identical to the hidden one
- // we already have. Make the existing definition visible and
- // use it in place of this one.
- if (!getLangOpts().CPlusPlus) {
- // Postpone making the old definition visible until after we
- // complete parsing the new one and do the structural
- // comparison.
- SkipBody->CheckSameAsPrevious = true;
- SkipBody->New = createTagFromNewDecl();
- SkipBody->Previous = Def;
-
- ProcessDeclAttributeList(S, SkipBody->New, Attrs);
- return Def;
- } else {
- SkipBody->ShouldSkip = true;
- SkipBody->Previous = Def;
- makeMergedDefinitionVisible(Hidden);
- // Carry on and handle it like a normal definition. We'll
- // skip starting the definition later.
- }
- } else if (!IsExplicitSpecializationAfterInstantiation) {
- // A redeclaration in function prototype scope in C isn't
- // visible elsewhere, so merely issue a warning.
- if (!getLangOpts().CPlusPlus && S->containedInPrototypeScope())
- Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name;
- else
- Diag(NameLoc, diag::err_redefinition) << Name;
- notePreviousDefinition(Def,
- NameLoc.isValid() ? NameLoc : KWLoc);
- // If this is a redefinition, recover by making this
- // struct be anonymous, which will make any later
- // references get the previous definition.
- Name = nullptr;
- Previous.clear();
- Invalid = true;
- }
- } else {
+ if (TagDecl *Def = PrevTagDecl->getDefinition()) {
// If the type is currently being defined, complain
// about a nested redefinition.
- auto *TD = Context.getTagDeclType(PrevTagDecl)->getAsTagDecl();
- if (TD->isBeingDefined()) {
+ if (Def->isBeingDefined()) {
Diag(NameLoc, diag::err_nested_redefinition) << Name;
Diag(PrevTagDecl->getLocation(),
diag::note_previous_definition);
Name = nullptr;
Previous.clear();
Invalid = true;
+ } else {
+ // If we're defining a specialization and the previous
+ // definition is from an implicit instantiation, don't emit an
+ // error here; we'll catch this in the general case below.
+ bool IsExplicitSpecializationAfterInstantiation = false;
+ if (isMemberSpecialization) {
+ if (CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(Def))
+ IsExplicitSpecializationAfterInstantiation =
+ RD->getTemplateSpecializationKind() !=
+ TSK_ExplicitSpecialization;
+ else if (EnumDecl *ED = dyn_cast<EnumDecl>(Def))
+ IsExplicitSpecializationAfterInstantiation =
+ ED->getTemplateSpecializationKind() !=
+ TSK_ExplicitSpecialization;
+ }
+
+ // Note that clang allows ODR-like semantics for ObjC/C, i.e.,
+ // do not keep more that one definition around (merge them).
+ // However, ensure the decl passes the structural compatibility
+ // check in C11 6.2.7/1 (or 6.1.2.6/1 in C89).
+ NamedDecl *Hidden = nullptr;
+ if (SkipBody && (!hasVisibleDefinition(Def, &Hidden) ||
+ getLangOpts().C23)) {
+ // There is a definition of this tag, but it is not visible.
+ // We explicitly make use of C++'s one definition rule here,
+ // and assume that this definition is identical to the hidden
+ // one we already have. Make the existing definition visible
+ // and use it in place of this one.
+ if (!getLangOpts().CPlusPlus) {
+ // Postpone making the old definition visible until after we
+ // complete parsing the new one and do the structural
+ // comparison.
+ SkipBody->CheckSameAsPrevious = true;
+ SkipBody->New = createTagFromNewDecl();
+ SkipBody->Previous = Def;
+
+ ProcessDeclAttributeList(S, SkipBody->New, Attrs);
+ return Def;
+ } else {
+ SkipBody->ShouldSkip = true;
+ SkipBody->Previous = Def;
+ makeMergedDefinitionVisible(Hidden);
+ // Carry on and handle it like a normal definition. We'll
+ // skip starting the definition later.
+ }
+ } else if (!IsExplicitSpecializationAfterInstantiation) {
+ // A redeclaration in function prototype scope in C isn't
+ // visible elsewhere, so merely issue a warning.
+ if (!getLangOpts().CPlusPlus &&
+ S->containedInPrototypeScope())
+ Diag(NameLoc, diag::warn_redefinition_in_param_list)
+ << Name;
+ else
+ Diag(NameLoc, diag::err_redefinition) << Name;
+ notePreviousDefinition(Def,
+ NameLoc.isValid() ? NameLoc : KWLoc);
+ // If this is a redefinition, recover by making this
+ // struct be anonymous, which will make any later
+ // references get the previous definition.
+ Name = nullptr;
+ Previous.clear();
+ Invalid = true;
+ }
}
}
@@ -18280,14 +18356,14 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
(IsTypeSpecifier || IsTemplateParamOrArg) &&
TUK == TagUseKind::Definition) {
Diag(New->getLocation(), diag::err_type_defined_in_type_specifier)
- << Context.getTagDeclType(New);
+ << Context.getCanonicalTagType(New);
Invalid = true;
}
if (!Invalid && getLangOpts().CPlusPlus && TUK == TagUseKind::Definition &&
DC->getDeclKind() == Decl::Enum) {
Diag(New->getLocation(), diag::err_type_defined_in_enum)
- << Context.getTagDeclType(New);
+ << Context.getCanonicalTagType(New);
Invalid = true;
}
@@ -18368,7 +18444,8 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
// In C23 mode, if the declaration is complete, we do not want to
// diagnose.
if (!getLangOpts().C23 || TUK != TagUseKind::Definition)
- Diag(Loc, diag::warn_decl_in_param_list) << Context.getTagDeclType(New);
+ Diag(Loc, diag::warn_decl_in_param_list)
+ << Context.getCanonicalTagType(New);
}
}
@@ -18400,7 +18477,7 @@ Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK, SourceLocation KWLoc,
AddPragmaAttributes(S, New);
// If this has an identifier, add it to the scope stack.
- if (TUK == TagUseKind::Friend) {
+ if (TUK == TagUseKind::Friend || IsInjectedClassName) {
// We might be replacing an existing declaration in the lookup tables;
// if so, borrow its access specifier.
if (PrevDecl)
@@ -18516,14 +18593,12 @@ void Sema::ActOnStartCXXMemberDeclarations(
// as if it were a public member name.
CXXRecordDecl *InjectedClassName = CXXRecordDecl::Create(
Context, Record->getTagKind(), CurContext, Record->getBeginLoc(),
- Record->getLocation(), Record->getIdentifier(),
- /*PrevDecl=*/nullptr,
- /*DelayTypeCreation=*/true);
- Context.getTypeDeclType(InjectedClassName, Record);
+ Record->getLocation(), Record->getIdentifier());
InjectedClassName->setImplicit();
InjectedClassName->setAccess(AS_public);
if (ClassTemplateDecl *Template = Record->getDescribedClassTemplate())
InjectedClassName->setDescribedClassTemplate(Template);
+
PushOnScopeChains(InjectedClassName, S);
assert(InjectedClassName->isInjectedClassName() &&
"Broken injected-class-name");
@@ -18953,7 +19028,7 @@ FieldDecl *Sema::CheckFieldDecl(DeclarationName Name, QualType T,
if (!InvalidDecl && getLangOpts().CPlusPlus) {
if (Record->isUnion()) {
if (const RecordType *RT = EltTy->getAs<RecordType>()) {
- CXXRecordDecl* RDecl = cast<CXXRecordDecl>(RT->getDecl());
+ CXXRecordDecl *RDecl = cast<CXXRecordDecl>(RT->getOriginalDecl());
if (RDecl->getDefinition()) {
// C++ [class.union]p1: An object of a class with a non-trivial
// constructor, a non-trivial copy constructor, a non-trivial
@@ -19019,7 +19094,8 @@ bool Sema::CheckNontrivialField(FieldDecl *FD) {
QualType EltTy = Context.getBaseElementType(FD->getType());
if (const RecordType *RT = EltTy->getAs<RecordType>()) {
- CXXRecordDecl *RDecl = cast<CXXRecordDecl>(RT->getDecl());
+ CXXRecordDecl *RDecl =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if (RDecl->getDefinition()) {
// We check for copy constructors before constructors
// because otherwise we'll never get complaints about
@@ -19342,7 +19418,7 @@ bool Sema::EntirelyFunctionPointers(const RecordDecl *Record) {
}
// If a member is a struct entirely of function pointers, that counts too.
if (const RecordType *RT = FieldType->getAs<RecordType>()) {
- const RecordDecl *Record = RT->getDecl();
+ const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf();
if (Record->isStruct() && EntirelyFunctionPointers(Record))
return true;
}
@@ -19500,7 +19576,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
EnclosingDecl->setInvalidDecl();
continue;
} else if (const RecordType *FDTTy = FDTy->getAs<RecordType>()) {
- if (Record && FDTTy->getDecl()->hasFlexibleArrayMember()) {
+ if (Record && FDTTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember()) {
// A type which contains a flexible array member is considered to be a
// flexible array member.
Record->setHasFlexibleArrayMember(true);
@@ -19526,9 +19604,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
// Ivars can not have abstract class types
FD->setInvalidDecl();
}
- if (Record && FDTTy->getDecl()->hasObjectMember())
+ const RecordDecl *RD = FDTTy->getOriginalDecl()->getDefinitionOrSelf();
+ if (Record && RD->hasObjectMember())
Record->setHasObjectMember(true);
- if (Record && FDTTy->getDecl()->hasVolatileMember())
+ if (Record && RD->hasVolatileMember())
Record->setHasVolatileMember(true);
} else if (FDTy->isObjCObjectType()) {
/// A field cannot be an Objective-c object
@@ -19559,8 +19638,10 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
Record->setHasObjectMember(true);
else if (Context.getAsArrayType(FD->getType())) {
QualType BaseType = Context.getBaseElementType(FD->getType());
- if (BaseType->isRecordType() &&
- BaseType->castAs<RecordType>()->getDecl()->hasObjectMember())
+ if (BaseType->isRecordType() && BaseType->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasObjectMember())
Record->setHasObjectMember(true);
else if (BaseType->isObjCObjectPointerType() ||
BaseType.isObjCGCStrong())
@@ -19593,7 +19674,9 @@ void Sema::ActOnFields(Scope *S, SourceLocation RecLoc, Decl *EnclosingDecl,
}
if (const auto *RT = FT->getAs<RecordType>()) {
- if (RT->getDecl()->getArgPassingRestrictions() ==
+ if (RT->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->getArgPassingRestrictions() ==
RecordArgPassingKind::CanNeverPassInRegs)
Record->setArgPassingRestrictions(
RecordArgPassingKind::CanNeverPassInRegs);
@@ -20359,7 +20442,7 @@ void Sema::ActOnEnumBody(SourceLocation EnumLoc, SourceRange BraceRange,
Decl *EnumDeclX, ArrayRef<Decl *> Elements, Scope *S,
const ParsedAttributesView &Attrs) {
EnumDecl *Enum = cast<EnumDecl>(EnumDeclX);
- QualType EnumType = Context.getTypeDeclType(Enum);
+ CanQualType EnumType = Context.getCanonicalTagType(Enum);
ProcessDeclAttributeList(S, Enum, Attrs);
ProcessAPINotes(Enum);
diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp
index 7ebb53318702c..19694d8b06c38 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -177,7 +177,7 @@ static bool threadSafetyCheckIsSmartPointer(Sema &S, const RecordType* RT) {
return !Result.empty();
};
- const RecordDecl *Record = RT->getDecl();
+ const RecordDecl *Record = RT->getOriginalDecl()->getDefinitionOrSelf();
bool foundStarOperator = IsOverloadedOperatorPresent(Record, OO_Star);
bool foundArrowOperator = IsOverloadedOperatorPresent(Record, OO_Arrow);
if (foundStarOperator && foundArrowOperator)
@@ -271,7 +271,8 @@ static bool checkRecordTypeForCapability(Sema &S, QualType Ty) {
if (threadSafetyCheckIsSmartPointer(S, RT))
return true;
- return checkRecordDeclForAttr<CapabilityAttr>(RT->getDecl());
+ return checkRecordDeclForAttr<CapabilityAttr>(
+ RT->getOriginalDecl()->getDefinitionOrSelf());
}
static bool checkRecordTypeForScopedCapability(Sema &S, QualType Ty) {
@@ -284,7 +285,8 @@ static bool checkRecordTypeForScopedCapability(Sema &S, QualType Ty) {
if (RT->isIncompleteType())
return true;
- return checkRecordDeclForAttr<ScopedLockableAttr>(RT->getDecl());
+ return checkRecordDeclForAttr<ScopedLockableAttr>(
+ RT->getOriginalDecl()->getDefinitionOrSelf());
}
static bool checkTypedefTypeForCapability(QualType Ty) {
@@ -1254,8 +1256,8 @@ bool Sema::isValidPointerAttrType(QualType T, bool RefOkay) {
// The nonnull attribute, and other similar attributes, can be applied to a
// transparent union that contains a pointer type.
if (const RecordType *UT = T->getAsUnionType()) {
- if (UT && UT->getDecl()->hasAttr<TransparentUnionAttr>()) {
- RecordDecl *UD = UT->getDecl();
+ RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ if (UD->hasAttr<TransparentUnionAttr>()) {
for (const auto *I : UD->fields()) {
QualType QT = I->getType();
if (QT->isAnyPointerType() || QT->isBlockPointerType())
@@ -3761,7 +3763,9 @@ static void handleFormatArgAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
}
Ty = getFunctionOrMethodResultType(D);
// replace instancetype with the class type
- auto Instancetype = S.Context.getObjCInstanceTypeDecl()->getTypeForDecl();
+ auto *Instancetype = cast<TypedefType>(S.Context.getTypedefType(
+ ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt,
+ S.Context.getObjCInstanceTypeDecl()));
if (Ty->getAs<TypedefType>() == Instancetype)
if (auto *OMD = dyn_cast<ObjCMethodDecl>(D))
if (auto *Interface = OMD->getClassInterface())
@@ -4355,7 +4359,10 @@ static void handleTransparentUnionAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
RecordDecl *RD = nullptr;
const auto *TD = dyn_cast<TypedefNameDecl>(D);
if (TD && TD->getUnderlyingType()->isUnionType())
- RD = TD->getUnderlyingType()->getAsUnionType()->getDecl();
+ RD = TD->getUnderlyingType()
+ ->getAsUnionType()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
else
RD = dyn_cast<RecordDecl>(D);
@@ -4708,7 +4715,7 @@ void Sema::CheckAlignasUnderalignment(Decl *D) {
if (const auto *VD = dyn_cast<ValueDecl>(D)) {
UnderlyingTy = DiagTy = VD->getType();
} else {
- UnderlyingTy = DiagTy = Context.getTagDeclType(cast<TagDecl>(D));
+ UnderlyingTy = DiagTy = Context.getCanonicalTagType(cast<TagDecl>(D));
if (const auto *ED = dyn_cast<EnumDecl>(D))
UnderlyingTy = ED->getIntegerType();
}
diff --git a/clang/lib/Sema/SemaDeclCXX.cpp b/clang/lib/Sema/SemaDeclCXX.cpp
index f0247f865ba40..3d2b7f021f9b5 100644
--- a/clang/lib/Sema/SemaDeclCXX.cpp
+++ b/clang/lib/Sema/SemaDeclCXX.cpp
@@ -10,6 +10,7 @@
//
//===----------------------------------------------------------------------===//
+#include "TypeLocBuilder.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/ASTMutationListener.h"
@@ -1101,15 +1102,13 @@ static std::string printTemplateArgs(const PrintingPolicy &PrintingPolicy,
return std::string(OS.str());
}
-static bool lookupStdTypeTraitMember(Sema &S, LookupResult &TraitMemberLookup,
- SourceLocation Loc, StringRef Trait,
- TemplateArgumentListInfo &Args,
- unsigned DiagID) {
+static QualType getStdTrait(Sema &S, SourceLocation Loc, StringRef Trait,
+ TemplateArgumentListInfo &Args, unsigned DiagID) {
auto DiagnoseMissing = [&] {
if (DiagID)
S.Diag(Loc, DiagID) << printTemplateArgs(S.Context.getPrintingPolicy(),
Args, /*Params*/ nullptr);
- return true;
+ return QualType();
};
// FIXME: Factor out duplication with lookupPromiseType in SemaCoroutine.
@@ -1122,12 +1121,12 @@ static bool lookupStdTypeTraitMember(Sema &S, LookupResult &TraitMemberLookup,
// missing specialization, because this can only fail if the user has been
// declaring their own names in namespace std or we don't support the
// standard library implementation in use.
- LookupResult Result(S, &S.PP.getIdentifierTable().get(Trait),
- Loc, Sema::LookupOrdinaryName);
+ LookupResult Result(S, &S.PP.getIdentifierTable().get(Trait), Loc,
+ Sema::LookupOrdinaryName);
if (!S.LookupQualifiedName(Result, Std))
return DiagnoseMissing();
if (Result.isAmbiguous())
- return true;
+ return QualType();
ClassTemplateDecl *TraitTD = Result.getAsSingle<ClassTemplateDecl>();
if (!TraitTD) {
@@ -1135,28 +1134,31 @@ static bool lookupStdTypeTraitMember(Sema &S, LookupResult &TraitMemberLookup,
NamedDecl *Found = *Result.begin();
S.Diag(Loc, diag::err_std_type_trait_not_class_template) << Trait;
S.Diag(Found->getLocation(), diag::note_declared_at);
- return true;
+ return QualType();
}
// Build the template-id.
- QualType TraitTy = S.CheckTemplateIdType(TemplateName(TraitTD), Loc, Args);
+ QualType TraitTy = S.CheckTemplateIdType(ElaboratedTypeKeyword::None,
+ TemplateName(TraitTD), Loc, Args);
if (TraitTy.isNull())
- return true;
+ return QualType();
+
if (!S.isCompleteType(Loc, TraitTy)) {
if (DiagID)
S.RequireCompleteType(
Loc, TraitTy, DiagID,
printTemplateArgs(S.Context.getPrintingPolicy(), Args,
TraitTD->getTemplateParameters()));
- return true;
+ return QualType();
}
+ return TraitTy;
+}
- CXXRecordDecl *RD = TraitTy->getAsCXXRecordDecl();
+static bool lookupMember(Sema &S, CXXRecordDecl *RD,
+ LookupResult &MemberLookup) {
assert(RD && "specialization of class template is not a class?");
-
- // Look up the member of the trait type.
- S.LookupQualifiedName(TraitMemberLookup, RD);
- return TraitMemberLookup.isAmbiguous();
+ S.LookupQualifiedName(MemberLookup, RD);
+ return MemberLookup.isAmbiguous();
}
static TemplateArgumentLoc
@@ -1178,17 +1180,20 @@ static IsTupleLike isTupleLike(Sema &S, SourceLocation Loc, QualType T,
EnterExpressionEvaluationContext ContextRAII(
S, Sema::ExpressionEvaluationContext::ConstantEvaluated);
- DeclarationName Value = S.PP.getIdentifierInfo("value");
- LookupResult R(S, Value, Loc, Sema::LookupOrdinaryName);
-
// Form template argument list for tuple_size<T>.
TemplateArgumentListInfo Args(Loc, Loc);
Args.addArgument(getTrivialTypeTemplateArgument(S, Loc, T));
+ QualType TraitTy = getStdTrait(S, Loc, "tuple_size", Args, /*DiagID=*/0);
+ if (TraitTy.isNull())
+ return IsTupleLike::NotTupleLike;
+
+ DeclarationName Value = S.PP.getIdentifierInfo("value");
+ LookupResult R(S, Value, Loc, Sema::LookupOrdinaryName);
+
// If there's no tuple_size specialization or the lookup of 'value' is empty,
// it's not tuple-like.
- if (lookupStdTypeTraitMember(S, R, Loc, "tuple_size", Args, /*DiagID*/ 0) ||
- R.empty())
+ if (lookupMember(S, TraitTy->getAsCXXRecordDecl(), R) || R.empty())
return IsTupleLike::NotTupleLike;
// If we get this far, we've committed to the tuple interpretation, but
@@ -1228,11 +1233,15 @@ static QualType getTupleLikeElementType(Sema &S, SourceLocation Loc,
getTrivialIntegralTemplateArgument(S, Loc, S.Context.getSizeType(), I));
Args.addArgument(getTrivialTypeTemplateArgument(S, Loc, T));
+ QualType TraitTy =
+ getStdTrait(S, Loc, "tuple_element", Args,
+ diag::err_decomp_decl_std_tuple_element_not_specialized);
+ if (TraitTy.isNull())
+ return QualType();
+
DeclarationName TypeDN = S.PP.getIdentifierInfo("type");
LookupResult R(S, TypeDN, Loc, Sema::LookupOrdinaryName);
- if (lookupStdTypeTraitMember(
- S, R, Loc, "tuple_element", Args,
- diag::err_decomp_decl_std_tuple_element_not_specialized))
+ if (lookupMember(S, TraitTy->getAsCXXRecordDecl(), R))
return QualType();
auto *TD = R.getAsSingle<TypeDecl>();
@@ -1246,7 +1255,8 @@ static QualType getTupleLikeElementType(Sema &S, SourceLocation Loc,
return QualType();
}
- return S.Context.getTypeDeclType(TD);
+ NestedNameSpecifier Qualifier(TraitTy.getTypePtr());
+ return S.Context.getTypeDeclType(ElaboratedTypeKeyword::None, Qualifier, TD);
}
namespace {
@@ -1452,7 +1462,7 @@ static DeclAccessPair findDecomposableBaseClass(Sema &S, SourceLocation Loc,
}
// ... [accessible, implied by other rules] base class of E.
- S.CheckBaseClassAccess(Loc, BaseType, S.Context.getRecordType(RD),
+ S.CheckBaseClassAccess(Loc, BaseType, S.Context.getCanonicalTagType(RD),
*BestPath, diag::err_decomp_decl_inaccessible_base);
AS = BestPath->Access;
@@ -1528,8 +1538,8 @@ static bool checkMemberDecomposition(Sema &S, ArrayRef<BindingDecl*> Bindings,
const auto *RD = cast_or_null<CXXRecordDecl>(BasePair.getDecl());
if (!RD)
return true;
- QualType BaseType = S.Context.getQualifiedType(S.Context.getRecordType(RD),
- DecompType.getQualifiers());
+ QualType BaseType = S.Context.getQualifiedType(
+ S.Context.getCanonicalTagType(RD), DecompType.getQualifiers());
auto *DD = cast<DecompositionDecl>(Src);
unsigned NumFields = llvm::count_if(
@@ -2174,7 +2184,10 @@ static bool CheckConstexprCtorInitializer(Sema &SemaRef,
return false;
}
} else if (Field->isAnonymousStructOrUnion()) {
- const RecordDecl *RD = Field->getType()->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD = Field->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
for (auto *I : RD->fields())
// If an anonymous union contains an anonymous struct of which any member
// is initialized, all members must be initialized.
@@ -2666,7 +2679,9 @@ void Sema::DiagnoseImmediateEscalatingReason(FunctionDecl *FD) {
return DynamicRecursiveASTVisitor::TraverseCXXConstructorDecl(Ctr);
}
- bool TraverseType(QualType T) override { return true; }
+ bool TraverseType(QualType T, bool TraverseQualifier) override {
+ return true;
+ }
bool VisitBlockExpr(BlockExpr *T) override { return true; }
} Visitor(*this, FD);
@@ -2969,7 +2984,8 @@ bool Sema::AttachBaseSpecifiers(CXXRecordDecl *Class,
NoteIndirectBases(Context, IndirectBaseTypes, NewBaseType);
if (const RecordType *Record = NewBaseType->getAs<RecordType>()) {
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getDecl());
+ const CXXRecordDecl *RD = cast<CXXRecordDecl>(Record->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (Class->isInterface() &&
(!RD->isInterfaceLike() ||
KnownBase->getAccessSpecifier() != AS_public)) {
@@ -3050,7 +3066,7 @@ bool Sema::IsDerivedFrom(SourceLocation Loc, CXXRecordDecl *Derived,
// FIXME: In a modules build, do we need the entire path to be visible for us
// to be able to use the inheritance relationship?
- if (!isCompleteType(Loc, Context.getTypeDeclType(Derived)) &&
+ if (!isCompleteType(Loc, Context.getCanonicalTagType(Derived)) &&
!Derived->isBeingDefined())
return false;
@@ -3205,7 +3221,8 @@ std::string Sema::getAmbiguousPathsDisplayString(CXXBasePaths &Paths) {
// We haven't displayed a path to this particular base
// class subobject yet.
PathDisplayStr += "\n ";
- PathDisplayStr += Context.getTypeDeclType(Paths.getOrigin()).getAsString();
+ PathDisplayStr += QualType(Context.getCanonicalTagType(Paths.getOrigin()))
+ .getAsString();
for (CXXBasePath::const_iterator Element = Path->begin();
Element != Path->end(); ++Element)
PathDisplayStr += " -> " + Element->Base->getType().getAsString();
@@ -4245,7 +4262,7 @@ static bool FindBaseInitializer(Sema &SemaRef,
CXXBasePaths Paths(/*FindAmbiguities=*/true, /*RecordPaths=*/true,
/*DetectVirtual=*/false);
if (SemaRef.IsDerivedFrom(ClassDecl->getLocation(),
- SemaRef.Context.getTypeDeclType(ClassDecl),
+ SemaRef.Context.getCanonicalTagType(ClassDecl),
BaseType, Paths)) {
for (CXXBasePaths::paths_iterator Path = Paths.begin();
Path != Paths.end(); ++Path) {
@@ -4481,7 +4498,7 @@ Sema::BuildMemInitializer(Decl *ConstructorD,
if (getLangOpts().MSVCCompat && !getLangOpts().CPlusPlus20) {
if (auto UnqualifiedBase = R.getAsSingle<ClassTemplateDecl>()) {
auto *TempSpec = cast<TemplateSpecializationType>(
- UnqualifiedBase->getInjectedClassNameSpecialization());
+ UnqualifiedBase->getCanonicalInjectedSpecializationType(Context));
TemplateName TN = TempSpec->getTemplateName();
for (auto const &Base : ClassDecl->bases()) {
auto BaseTemplate =
@@ -4545,14 +4562,29 @@ Sema::BuildMemInitializer(Decl *ConstructorD,
}
if (BaseType.isNull()) {
- BaseType = getElaboratedType(ElaboratedTypeKeyword::None, SS,
- Context.getTypeDeclType(TyD));
MarkAnyDeclReferenced(TyD->getLocation(), TyD, /*OdrUse=*/false);
- TInfo = Context.CreateTypeSourceInfo(BaseType);
- ElaboratedTypeLoc TL = TInfo->getTypeLoc().castAs<ElaboratedTypeLoc>();
- TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(IdLoc);
- TL.setElaboratedKeywordLoc(SourceLocation());
- TL.setQualifierLoc(SS.getWithLocInContext(Context));
+
+ TypeLocBuilder TLB;
+ if (const auto *TD = dyn_cast<TagDecl>(TyD)) {
+ BaseType = Context.getTagType(ElaboratedTypeKeyword::None,
+ SS.getScopeRep(), TD, /*OwnsTag=*/false);
+ auto TL = TLB.push<TagTypeLoc>(BaseType);
+ TL.setElaboratedKeywordLoc(SourceLocation());
+ TL.setQualifierLoc(SS.getWithLocInContext(Context));
+ TL.setNameLoc(IdLoc);
+ } else if (auto *TN = dyn_cast<TypedefNameDecl>(TyD)) {
+ BaseType = Context.getTypedefType(ElaboratedTypeKeyword::None,
+ SS.getScopeRep(), TN);
+ TLB.push<TypedefTypeLoc>(BaseType).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context), IdLoc);
+ } else {
+ // FIXME: What else can appear here?
+ assert(SS.isEmpty());
+ BaseType = Context.getTypeDeclType(TyD);
+ TLB.pushTypeSpec(BaseType).setNameLoc(IdLoc);
+ }
+ TInfo = TLB.getTypeSourceInfo(Context, BaseType);
}
}
@@ -4661,10 +4693,12 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
Args = MultiExprArg(ParenList->getExprs(), ParenList->getNumExprs());
}
+ CanQualType ClassType = Context.getCanonicalTagType(ClassDecl);
+
SourceRange InitRange = Init->getSourceRange();
// Initialize the object.
- InitializedEntity DelegationEntity = InitializedEntity::InitializeDelegation(
- QualType(ClassDecl->getTypeForDecl(), 0));
+ InitializedEntity DelegationEntity =
+ InitializedEntity::InitializeDelegation(ClassType);
InitializationKind Kind =
InitList ? InitializationKind::CreateDirectList(
NameLoc, Init->getBeginLoc(), Init->getEndLoc())
@@ -4686,9 +4720,8 @@ Sema::BuildDelegatingInitializer(TypeSourceInfo *TInfo, Expr *Init,
}
if (DelegationInit.isInvalid()) {
- DelegationInit =
- CreateRecoveryExpr(InitRange.getBegin(), InitRange.getEnd(), Args,
- QualType(ClassDecl->getTypeForDecl(), 0));
+ DelegationInit = CreateRecoveryExpr(InitRange.getBegin(),
+ InitRange.getEnd(), Args, ClassType);
if (DelegationInit.isInvalid())
return true;
} else {
@@ -4753,8 +4786,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
const CXXBaseSpecifier *DirectBaseSpec = nullptr;
const CXXBaseSpecifier *VirtualBaseSpec = nullptr;
if (!Dependent) {
- if (Context.hasSameUnqualifiedType(QualType(ClassDecl->getTypeForDecl(),0),
- BaseType))
+ if (declaresSameEntity(ClassDecl, BaseType->getAsCXXRecordDecl()))
return BuildDelegatingInitializer(BaseTInfo, Init, ClassDecl);
FindBaseInitializer(*this, ClassDecl, BaseType, DirectBaseSpec,
@@ -4774,7 +4806,7 @@ Sema::BuildBaseInitializer(QualType BaseType, TypeSourceInfo *BaseTInfo,
Dependent = true;
else
return Diag(BaseLoc, diag::err_not_direct_base_or_virtual)
- << BaseType << Context.getTypeDeclType(ClassDecl)
+ << BaseType << Context.getCanonicalTagType(ClassDecl)
<< BaseTInfo->getTypeLoc().getSourceRange();
}
}
@@ -5078,9 +5110,9 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
if (FieldBaseElementType->isReferenceType()) {
SemaRef.Diag(Constructor->getLocation(),
diag::err_uninitialized_member_in_ctor)
- << (int)Constructor->isImplicit()
- << SemaRef.Context.getTagDeclType(Constructor->getParent())
- << 0 << Field->getDeclName();
+ << (int)Constructor->isImplicit()
+ << SemaRef.Context.getCanonicalTagType(Constructor->getParent()) << 0
+ << Field->getDeclName();
SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
return true;
}
@@ -5088,9 +5120,9 @@ BuildImplicitMemberInitializer(Sema &SemaRef, CXXConstructorDecl *Constructor,
if (FieldBaseElementType.isConstQualified()) {
SemaRef.Diag(Constructor->getLocation(),
diag::err_uninitialized_member_in_ctor)
- << (int)Constructor->isImplicit()
- << SemaRef.Context.getTagDeclType(Constructor->getParent())
- << 1 << Field->getDeclName();
+ << (int)Constructor->isImplicit()
+ << SemaRef.Context.getCanonicalTagType(Constructor->getParent()) << 1
+ << Field->getDeclName();
SemaRef.Diag(Field->getLocation(), diag::note_declared_at);
return true;
}
@@ -5391,7 +5423,7 @@ static void MarkBaseDestructorsReferenced(Sema &S, SourceLocation Location,
S.CheckDestructorAccess(Base.getBeginLoc(), Dtor,
S.PDiag(diag::err_access_dtor_base)
<< Base.getType() << Base.getSourceRange(),
- S.Context.getTypeDeclType(ClassDecl));
+ S.Context.getCanonicalTagType(ClassDecl));
S.MarkFunctionReferenced(Location, Dtor);
S.DiagnoseUseOfDecl(Dtor, Location);
@@ -5594,9 +5626,9 @@ bool Sema::SetCtorInitializers(CXXConstructorDecl *Constructor, bool AnyErrors,
static void PopulateKeysForFields(FieldDecl *Field, SmallVectorImpl<const void*> &IdealInits) {
if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl();
if (RD->isAnonymousStructOrUnion()) {
- for (auto *Field : RD->fields())
+ for (auto *Field : RD->getDefinitionOrSelf()->fields())
PopulateKeysForFields(Field, IdealInits);
return;
}
@@ -5928,16 +5960,14 @@ void Sema::MarkVirtualBaseDestructorsReferenced(
if (!Dtor)
continue;
- if (CheckDestructorAccess(
- ClassDecl->getLocation(), Dtor,
- PDiag(diag::err_access_dtor_vbase)
- << Context.getTypeDeclType(ClassDecl) << VBase.getType(),
- Context.getTypeDeclType(ClassDecl)) ==
- AR_accessible) {
+ CanQualType CT = Context.getCanonicalTagType(ClassDecl);
+ if (CheckDestructorAccess(ClassDecl->getLocation(), Dtor,
+ PDiag(diag::err_access_dtor_vbase)
+ << CT << VBase.getType(),
+ CT) == AR_accessible) {
CheckDerivedToBaseConversion(
- Context.getTypeDeclType(ClassDecl), VBase.getType(),
- diag::err_access_dtor_vbase, 0, ClassDecl->getLocation(),
- SourceRange(), DeclarationName(), nullptr);
+ CT, VBase.getType(), diag::err_access_dtor_vbase, 0,
+ ClassDecl->getLocation(), SourceRange(), DeclarationName(), nullptr);
}
MarkFunctionReferenced(Location, Dtor);
@@ -6052,10 +6082,8 @@ struct AbstractUsageInfo {
bool Invalid;
AbstractUsageInfo(Sema &S, CXXRecordDecl *Record)
- : S(S), Record(Record),
- AbstractType(S.Context.getCanonicalType(
- S.Context.getTypeDeclType(Record))),
- Invalid(false) {}
+ : S(S), Record(Record),
+ AbstractType(S.Context.getCanonicalTagType(Record)), Invalid(false) {}
void DiagnoseAbstractType() {
if (Invalid) return;
@@ -6868,8 +6896,8 @@ static bool canPassInRegisters(Sema &S, CXXRecordDecl *D,
bool isAArch64 = S.Context.getTargetInfo().getTriple().isAArch64();
uint64_t TypeSize = isAArch64 ? 128 : 64;
- if (CopyCtorIsTrivial &&
- S.getASTContext().getTypeSize(D->getTypeForDecl()) <= TypeSize)
+ if (CopyCtorIsTrivial && S.getASTContext().getTypeSize(
+ S.Context.getCanonicalTagType(D)) <= TypeSize)
return true;
return false;
}
@@ -7000,7 +7028,8 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
if ((!dtor || (!dtor->isVirtual() && dtor->getAccess() == AS_public)) &&
!Record->hasAttr<FinalAttr>())
Diag(dtor ? dtor->getLocation() : Record->getLocation(),
- diag::warn_non_virtual_dtor) << Context.getRecordType(Record);
+ diag::warn_non_virtual_dtor)
+ << Context.getCanonicalTagType(Record);
}
if (Record->isAbstract()) {
@@ -7022,7 +7051,7 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
(FA->isSpelledAsSealed() ? " sealed" : " final"));
Diag(Record->getLocation(),
diag::note_final_dtor_non_final_class_silence)
- << Context.getRecordType(Record) << FA->isSpelledAsSealed();
+ << Context.getCanonicalTagType(Record) << FA->isSpelledAsSealed();
}
}
}
@@ -7177,7 +7206,7 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
return true;
};
EffectivelyConstexprDestructor =
- Check(QualType(Record->getTypeForDecl(), 0), Check);
+ Check(Context.getCanonicalTagType(Record), Check);
}
// Define defaulted constexpr virtual functions that override a base class
@@ -7333,7 +7362,7 @@ void Sema::CheckCompletedCXXClass(Scope *S, CXXRecordDecl *Record) {
NewDecls.empty() ? NewKind : DeleteKind);
Diag(Record->getLocation(),
diag::err_type_aware_allocator_missing_matching_operator)
- << FoundOperator << Context.getRecordType(Record)
+ << FoundOperator << Context.getCanonicalTagType(Record)
<< MissingOperator;
for (auto MD : NewDecls)
Diag(MD->getLocation(),
@@ -7572,7 +7601,9 @@ static bool defaultedSpecialMemberIsConstexpr(
const RecordType *BaseType = B.getType()->getAs<RecordType>();
if (!BaseType)
continue;
- CXXRecordDecl *BaseClassDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+ CXXRecordDecl *BaseClassDecl =
+ cast<CXXRecordDecl>(BaseType->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!specialMemberIsConstexpr(S, BaseClassDecl, CSM, 0, ConstArg,
InheritedCtor, Inherited))
return false;
@@ -7595,7 +7626,9 @@ static bool defaultedSpecialMemberIsConstexpr(
continue;
QualType BaseType = S.Context.getBaseElementType(F->getType());
if (const RecordType *RecordTy = BaseType->getAs<RecordType>()) {
- CXXRecordDecl *FieldRecDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
+ CXXRecordDecl *FieldRecDecl =
+ cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (!specialMemberIsConstexpr(S, FieldRecDecl, CSM,
BaseType.getCVRQualifiers(),
ConstArg && !F->isMutable()))
@@ -7782,9 +7815,9 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
ReturnType = Type->getReturnType();
QualType ThisType = MD->getFunctionObjectParameterType();
- QualType DeclType = Context.getTypeDeclType(RD);
- DeclType = Context.getElaboratedType(ElaboratedTypeKeyword::None, nullptr,
- DeclType, nullptr);
+ QualType DeclType =
+ Context.getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, RD, /*OwnsTag=*/false);
DeclType = Context.getAddrSpaceQualType(
DeclType, ThisType.getQualifiers().getAddressSpace());
QualType ExpectedReturnType = Context.getLValueReferenceType(DeclType);
@@ -7819,7 +7852,7 @@ bool Sema::CheckExplicitlyDefaultedSpecialMember(CXXMethodDecl *MD,
if (!ExplicitObjectParameter.isNull() &&
(!ExplicitObjectParameter->isReferenceType() ||
!Context.hasSameType(ExplicitObjectParameter.getNonReferenceType(),
- Context.getRecordType(RD)))) {
+ Context.getCanonicalTagType(RD)))) {
if (DeleteOnTypeMismatch)
ShouldDeleteForTypeMismatch = true;
else {
@@ -8278,7 +8311,7 @@ class DefaultedComparisonAnalyzer
Best->FoundDecl.getDecl()->isCXXClassMember()) {
QualType ObjectType = Subobj.Kind == Subobject::Member
? Args[0]->getType()
- : S.Context.getRecordType(RD);
+ : S.Context.getCanonicalTagType(RD);
if (!S.isMemberAccessibleForDeletion(
ArgClass, Best->FoundDecl, ObjectType, Subobj.Loc,
Diagnose == ExplainDeleted
@@ -8979,7 +9012,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
bool Ok = !IsMethod || FD->hasCXXExplicitFunctionObjectParameter();
QualType ExpectedTy;
if (RD)
- ExpectedTy = Context.getRecordType(RD);
+ ExpectedTy = Context.getCanonicalTagType(RD);
if (auto *Ref = CTy->getAs<LValueReferenceType>()) {
CTy = Ref->getPointeeType();
if (RD)
@@ -9002,7 +9035,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
// corresponding defaulted 'operator<=>' already.
if (!FD->isImplicit()) {
if (RD) {
- QualType PlainTy = Context.getRecordType(RD);
+ CanQualType PlainTy = Context.getCanonicalTagType(RD);
QualType RefTy =
Context.getLValueReferenceType(PlainTy.withConst());
Diag(FD->getLocation(), diag::err_defaulted_comparison_param)
@@ -9033,7 +9066,7 @@ bool Sema::CheckExplicitlyDefaultedComparison(Scope *S, FunctionDecl *FD,
} else {
// Out of class, require the defaulted comparison to be a friend (of a
// complete type, per CWG2547).
- if (RequireCompleteType(FD->getLocation(), Context.getRecordType(RD),
+ if (RequireCompleteType(FD->getLocation(), Context.getCanonicalTagType(RD),
diag::err_defaulted_comparison_not_friend, int(DCK),
int(1)))
return true;
@@ -9486,15 +9519,15 @@ bool SpecialMemberDeletionInfo::isAccessible(Subobject Subobj,
CXXMethodDecl *target) {
/// If we're operating on a base class, the object type is the
/// type of this special member.
- QualType objectTy;
+ CanQualType objectTy;
AccessSpecifier access = target->getAccess();
if (CXXBaseSpecifier *base = Subobj.dyn_cast<CXXBaseSpecifier*>()) {
- objectTy = S.Context.getTypeDeclType(MD->getParent());
+ objectTy = S.Context.getCanonicalTagType(MD->getParent());
access = CXXRecordDecl::MergeAccess(base->getAccessSpecifier(), access);
// If we're operating on a field, the object type is the type of the field.
} else {
- objectTy = S.Context.getTypeDeclType(target->getParent());
+ objectTy = S.Context.getCanonicalTagType(target->getParent());
}
return S.isMemberAccessibleForDeletion(
@@ -9912,7 +9945,7 @@ bool Sema::ShouldDeleteSpecialMember(CXXMethodDecl *MD,
// results in an ambiguity or in a function that is deleted or inaccessible
if (CSM == CXXSpecialMemberKind::Destructor && MD->isVirtual()) {
FunctionDecl *OperatorDelete = nullptr;
- QualType DeallocType = Context.getRecordType(RD);
+ CanQualType DeallocType = Context.getCanonicalTagType(RD);
DeclarationName Name =
Context.DeclarationNames.getCXXOperatorName(OO_Delete);
ImplicitDeallocationParameters IDP = {
@@ -10245,7 +10278,7 @@ static bool checkTrivialClassMembers(Sema &S, CXXRecordDecl *RD,
void Sema::DiagnoseNontrivial(const CXXRecordDecl *RD,
CXXSpecialMemberKind CSM) {
- QualType Ty = Context.getRecordType(RD);
+ CanQualType Ty = Context.getCanonicalTagType(RD);
bool ConstArg = (CSM == CXXSpecialMemberKind::CopyConstructor ||
CSM == CXXSpecialMemberKind::CopyAssignment);
@@ -10293,9 +10326,9 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
ClangABICompat14)) {
if (Diagnose)
Diag(Param0->getLocation(), diag::note_nontrivial_param_type)
- << Param0->getSourceRange() << Param0->getType()
- << Context.getLValueReferenceType(
- Context.getRecordType(RD).withConst());
+ << Param0->getSourceRange() << Param0->getType()
+ << Context.getLValueReferenceType(
+ Context.getCanonicalTagType(RD).withConst());
return false;
}
@@ -10312,8 +10345,8 @@ bool Sema::SpecialMemberIsTrivial(CXXMethodDecl *MD, CXXSpecialMemberKind CSM,
if (!RT || RT->getPointeeType().getCVRQualifiers()) {
if (Diagnose)
Diag(Param0->getLocation(), diag::note_nontrivial_param_type)
- << Param0->getSourceRange() << Param0->getType()
- << Context.getRValueReferenceType(Context.getRecordType(RD));
+ << Param0->getSourceRange() << Param0->getType()
+ << Context.getRValueReferenceType(Context.getCanonicalTagType(RD));
return false;
}
break;
@@ -10432,8 +10465,10 @@ struct FindHiddenVirtualMethod {
/// method overloads virtual methods in a base class without overriding any,
/// to be used with CXXRecordDecl::lookupInBases().
bool operator()(const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
- RecordDecl *BaseRecord =
- Specifier->getType()->castAs<RecordType>()->getDecl();
+ RecordDecl *BaseRecord = Specifier->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
DeclarationName Name = Method->getDeclName();
assert(Name.getNameKind() == DeclarationName::Identifier);
@@ -10591,7 +10626,8 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) {
if (const auto *RT = FT->getBaseElementTypeUnsafe()->getAs<RecordType>())
if (!RT->isDependentType() &&
- !cast<CXXRecordDecl>(RT->getDecl())->canPassInRegisters()) {
+ !cast<CXXRecordDecl>(RT->getOriginalDecl()->getDefinitionOrSelf())
+ ->canPassInRegisters()) {
PrintDiagAndRemoveAttr(5);
return;
}
@@ -10626,7 +10662,7 @@ void Sema::checkIllFormedTrivialABIStruct(CXXRecordDecl &RD) {
void Sema::checkIncorrectVTablePointerAuthenticationAttribute(
CXXRecordDecl &RD) {
- if (RequireCompleteType(RD.getLocation(), Context.getRecordType(&RD),
+ if (RequireCompleteType(RD.getLocation(), Context.getCanonicalTagType(&RD),
diag::err_incomplete_type_vtable_pointer_auth))
return;
@@ -11056,9 +11092,10 @@ void Sema::CheckConstructor(CXXConstructorDecl *Constructor) {
if (!Constructor->isInvalidDecl() &&
Constructor->hasOneParamOrDefaultArgs() &&
!Constructor->isFunctionTemplateSpecialization()) {
- QualType ParamType = Constructor->getParamDecl(0)->getType();
- QualType ClassTy = Context.getTagDeclType(ClassDecl);
- if (Context.getCanonicalType(ParamType).getUnqualifiedType() == ClassTy) {
+ CanQualType ParamType =
+ Constructor->getParamDecl(0)->getType()->getCanonicalTypeUnqualified();
+ CanQualType ClassTy = Context.getCanonicalTagType(ClassDecl);
+ if (ParamType == ClassTy) {
SourceLocation ParamLoc = Constructor->getParamDecl(0)->getLocation();
const char *ConstRef
= Constructor->getParamDecl(0)->getIdentifier() ? "const &"
@@ -11429,8 +11466,7 @@ Decl *Sema::ActOnConversionDeclarator(CXXConversionDecl *Conversion) {
// same object type (or a reference to it), to a (possibly
// cv-qualified) base class of that type (or a reference to it),
// or to (possibly cv-qualified) void.
- QualType ClassType
- = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
+ CanQualType ClassType = Context.getCanonicalTagType(ClassDecl);
if (const ReferenceType *ConvTypeRef = ConvType->getAs<ReferenceType>())
ConvType = ConvTypeRef->getPointeeType();
if (Conversion->getTemplateSpecializationKind() != TSK_Undeclared &&
@@ -11698,8 +11734,8 @@ bool Sema::CheckDeductionGuideDeclarator(Declarator &D, QualType &R,
const QualifiedTemplateName *Qualifiers =
SpecifiedName.getAsQualifiedTemplateName();
assert(Qualifiers && "expected QualifiedTemplate");
- bool SimplyWritten = !Qualifiers->hasTemplateKeyword() &&
- Qualifiers->getQualifier() == nullptr;
+ bool SimplyWritten =
+ !Qualifiers->hasTemplateKeyword() && !Qualifiers->getQualifier();
if (SimplyWritten && TemplateMatches)
AcceptableReturnType = true;
else {
@@ -11930,7 +11966,7 @@ Decl *Sema::ActOnStartNamespaceDef(Scope *NamespcScope,
/// getNamespaceDecl - Returns the namespace a decl represents. If the decl
/// is a namespace alias, returns the namespace it points to.
-static inline NamespaceDecl *getNamespaceDecl(NamedDecl *D) {
+static inline NamespaceDecl *getNamespaceDecl(NamespaceBaseDecl *D) {
if (NamespaceAliasDecl *AD = dyn_cast_or_null<NamespaceAliasDecl>(D))
return AD->getNamespace();
return dyn_cast_or_null<NamespaceDecl>(D);
@@ -12004,10 +12040,11 @@ QualType Sema::CheckComparisonCategoryType(ComparisonCategoryType Kind,
// Use an elaborated type for diagnostics which has a name containing the
// prepended 'std' namespace but not any inline namespace names.
auto TyForDiags = [&](ComparisonCategoryInfo *Info) {
- auto *NNS =
- NestedNameSpecifier::Create(Context, nullptr, getStdNamespace());
- return Context.getElaboratedType(ElaboratedTypeKeyword::None, NNS,
- Info->getType());
+ NestedNameSpecifier Qualifier(Context, getStdNamespace(),
+ /*Prefix=*/std::nullopt);
+ return Context.getTagType(ElaboratedTypeKeyword::None, Qualifier,
+ Info->Record,
+ /*OwnsTag=*/false);
};
// Check if we've already successfully checked the comparison category type
@@ -12143,26 +12180,14 @@ static bool isStdClassTemplate(Sema &S, QualType SugaredType, QualType *TypeArg,
ClassTemplateDecl *Template = nullptr;
ArrayRef<TemplateArgument> Arguments;
- {
- const TemplateSpecializationType *TST =
- SugaredType->getAsNonAliasTemplateSpecializationType();
- if (!TST)
- if (const auto *ICN = SugaredType->getAs<InjectedClassNameType>())
- TST = ICN->getInjectedTST();
- if (TST) {
- Template = dyn_cast_or_null<ClassTemplateDecl>(
- TST->getTemplateName().getAsTemplateDecl());
- Arguments = TST->template_arguments();
- } else if (const RecordType *RT = SugaredType->getAs<RecordType>()) {
- ClassTemplateSpecializationDecl *Specialization =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
- if (!Specialization) {
- ReportMatchingNameAsMalformed(RT->getDecl());
- return false;
- }
- Template = Specialization->getSpecializedTemplate();
- Arguments = Specialization->getTemplateArgs().asArray();
- }
+ if (const TemplateSpecializationType *TST =
+ SugaredType->getAsNonAliasTemplateSpecializationType()) {
+ Template = dyn_cast_or_null<ClassTemplateDecl>(
+ TST->getTemplateName().getAsTemplateDecl());
+ Arguments = TST->template_arguments();
+ } else if (const auto *TT = SugaredType->getAs<TagType>()) {
+ Template = TT->getTemplateDecl();
+ Arguments = TT->getTemplateArgs(S.Context);
}
if (!Template) {
@@ -12288,13 +12313,8 @@ static QualType BuildStdClassTemplate(Sema &S, ClassTemplateDecl *CTD,
auto TSI = S.Context.getTrivialTypeSourceInfo(TypeParam, Loc);
Args.addArgument(TemplateArgumentLoc(TemplateArgument(TypeParam), TSI));
- QualType T = S.CheckTemplateIdType(TemplateName(CTD), Loc, Args);
- if (T.isNull())
- return QualType();
-
- return S.Context.getElaboratedType(
- ElaboratedTypeKeyword::None,
- NestedNameSpecifier::Create(S.Context, nullptr, S.getStdNamespace()), T);
+ return S.CheckTemplateIdType(ElaboratedTypeKeyword::None, TemplateName(CTD),
+ Loc, Args);
}
QualType Sema::BuildStdInitializerList(QualType Element, SourceLocation Loc) {
@@ -12436,9 +12456,7 @@ Decl *Sema::ActOnUsingDirective(Scope *S, SourceLocation UsingLoc,
S = S->getDeclParent();
UsingDirectiveDecl *UDir = nullptr;
- NestedNameSpecifier *Qualifier = nullptr;
- if (SS.isSet())
- Qualifier = SS.getScopeRep();
+ NestedNameSpecifier Qualifier = SS.getScopeRep();
// Lookup namespace name.
LookupResult R(*this, NamespcName, IdentLoc, LookupNamespaceName);
@@ -12450,14 +12468,16 @@ Decl *Sema::ActOnUsingDirective(Scope *S, SourceLocation UsingLoc,
R.clear();
// Allow "using namespace std;" or "using namespace ::std;" even if
// "std" hasn't been defined yet, for GCC compatibility.
- if ((!Qualifier || Qualifier->getKind() == NestedNameSpecifier::Global) &&
+ if ((!Qualifier ||
+ Qualifier.getKind() == NestedNameSpecifier::Kind::Global) &&
NamespcName->isStr("std")) {
Diag(IdentLoc, diag::ext_using_undefined_std);
R.addDecl(getOrCreateStdNamespace());
R.resolveKind();
}
// Otherwise, attempt typo correction.
- else TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, NamespcName);
+ else
+ TryNamespaceTypoCorrection(*this, R, S, SS, IdentLoc, NamespcName);
}
if (!R.empty()) {
@@ -12584,7 +12604,7 @@ Decl *Sema::ActOnUsingDeclaration(Scope *S, AccessSpecifier AS,
DiagnoseUnexpandedParameterPack(TargetNameInfo, UPPC_UsingDeclaration))
return nullptr;
} else {
- if (!SS.getScopeRep()->containsUnexpandedParameterPack() &&
+ if (!SS.getScopeRep().containsUnexpandedParameterPack() &&
!TargetNameInfo.containsUnexpandedParameterPack()) {
Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
<< SourceRange(SS.getBeginLoc(), TargetNameInfo.getEndLoc());
@@ -12869,7 +12889,7 @@ UsingShadowDecl *Sema::BuildUsingShadowDecl(Scope *S, BaseUsingDecl *BUD,
UsingDecl *Using = cast<UsingDecl>(BUD);
bool IsVirtualBase =
isVirtualDirectBase(cast<CXXRecordDecl>(CurContext),
- Using->getQualifier()->getAsRecordDecl());
+ Using->getQualifier().getAsRecordDecl());
Shadow = ConstructorUsingShadowDecl::Create(
Context, CurContext, Using->getLocation(), Using, Orig, IsVirtualBase);
} else {
@@ -12935,7 +12955,7 @@ namespace {
class UsingValidatorCCC final : public CorrectionCandidateCallback {
public:
UsingValidatorCCC(bool HasTypenameKeyword, bool IsInstantiation,
- NestedNameSpecifier *NNS, CXXRecordDecl *RequireMemberOf)
+ NestedNameSpecifier NNS, CXXRecordDecl *RequireMemberOf)
: HasTypenameKeyword(HasTypenameKeyword),
IsInstantiation(IsInstantiation), OldNNS(NNS),
RequireMemberOf(RequireMemberOf) {}
@@ -12962,24 +12982,23 @@ class UsingValidatorCCC final : public CorrectionCandidateCallback {
ASTContext &Ctx = ND->getASTContext();
if (!Ctx.getLangOpts().CPlusPlus11)
return false;
- QualType FoundType = Ctx.getRecordType(FoundRecord);
+ CanQualType FoundType = Ctx.getCanonicalTagType(FoundRecord);
// Check that the injected-class-name is named as a member of its own
// type; we don't want to suggest 'using Derived::Base;', since that
// means something else.
- NestedNameSpecifier *Specifier =
- Candidate.WillReplaceSpecifier()
- ? Candidate.getCorrectionSpecifier()
- : OldNNS;
- if (!Specifier->getAsType() ||
- !Ctx.hasSameType(QualType(Specifier->getAsType(), 0), FoundType))
+ NestedNameSpecifier Specifier = Candidate.WillReplaceSpecifier()
+ ? Candidate.getCorrectionSpecifier()
+ : OldNNS;
+ if (Specifier.getKind() != NestedNameSpecifier::Kind::Type ||
+ !Ctx.hasSameType(QualType(Specifier.getAsType(), 0), FoundType))
return false;
// Check that this inheriting constructor declaration actually names a
// direct base class of the current class.
bool AnyDependentBases = false;
if (!findDirectBaseWithType(RequireMemberOf,
- Ctx.getRecordType(FoundRecord),
+ Ctx.getCanonicalTagType(FoundRecord),
AnyDependentBases) &&
!AnyDependentBases)
return false;
@@ -13009,7 +13028,7 @@ class UsingValidatorCCC final : public CorrectionCandidateCallback {
private:
bool HasTypenameKeyword;
bool IsInstantiation;
- NestedNameSpecifier *OldNNS;
+ NestedNameSpecifier OldNNS;
CXXRecordDecl *RequireMemberOf;
};
} // end anonymous namespace
@@ -13051,7 +13070,7 @@ NamedDecl *Sema::BuildUsingDeclaration(
if (UsingName.getName().getNameKind() == DeclarationName::CXXConstructorName)
if (auto *RD = dyn_cast<CXXRecordDecl>(CurContext))
UsingName.setName(Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(Context.getRecordType(RD))));
+ Context.getCanonicalTagType(RD)));
// Do the redeclaration lookup in the current scope.
LookupResult Previous(*this, UsingName, LookupUsingDeclName,
@@ -13154,7 +13173,7 @@ NamedDecl *Sema::BuildUsingDeclaration(
// equal to that of the current context.
if (CurContext->isRecord()) {
R.setBaseObjectType(
- Context.getTypeDeclType(cast<CXXRecordDecl>(CurContext)));
+ Context.getCanonicalTagType(cast<CXXRecordDecl>(CurContext)));
}
LookupQualifiedName(R, LookupContext);
@@ -13220,7 +13239,7 @@ NamedDecl *Sema::BuildUsingDeclaration(
// constructor.
auto *CurClass = cast<CXXRecordDecl>(CurContext);
UsingName.setName(Context.DeclarationNames.getCXXConstructorName(
- Context.getCanonicalType(Context.getRecordType(CurClass))));
+ Context.getCanonicalTagType(CurClass)));
UsingName.setNamedTypeInfo(nullptr);
for (auto *Ctor : LookupConstructors(RD))
R.addDecl(Ctor);
@@ -13366,20 +13385,16 @@ NamedDecl *Sema::BuildUsingPackDecl(NamedDecl *InstantiatedFrom,
bool Sema::CheckInheritingConstructorUsingDecl(UsingDecl *UD) {
assert(!UD->hasTypename() && "expecting a constructor name");
- const Type *SourceType = UD->getQualifier()->getAsType();
- assert(SourceType &&
- "Using decl naming constructor doesn't have type in scope spec.");
+ QualType SourceType(UD->getQualifier().getAsType(), 0);
CXXRecordDecl *TargetClass = cast<CXXRecordDecl>(CurContext);
// Check whether the named type is a direct base class.
bool AnyDependentBases = false;
- auto *Base = findDirectBaseWithType(TargetClass, QualType(SourceType, 0),
- AnyDependentBases);
+ auto *Base =
+ findDirectBaseWithType(TargetClass, SourceType, AnyDependentBases);
if (!Base && !AnyDependentBases) {
- Diag(UD->getUsingLoc(),
- diag::err_using_decl_constructor_not_in_direct_base)
- << UD->getNameInfo().getSourceRange()
- << QualType(SourceType, 0) << TargetClass;
+ Diag(UD->getUsingLoc(), diag::err_using_decl_constructor_not_in_direct_base)
+ << UD->getNameInfo().getSourceRange() << SourceType << TargetClass;
UD->setInvalidDecl();
return true;
}
@@ -13395,7 +13410,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
const CXXScopeSpec &SS,
SourceLocation NameLoc,
const LookupResult &Prev) {
- NestedNameSpecifier *Qual = SS.getScopeRep();
+ NestedNameSpecifier Qual = SS.getScopeRep();
// C++03 [namespace.udecl]p8:
// C++0x [namespace.udecl]p10:
@@ -13410,7 +13425,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
// declaration in the same scope.
// FIXME: How should we check for dependent type-type conflicts at block
// scope?
- if (Qual->isDependent() && !HasTypenameKeyword) {
+ if (Qual.isDependent() && !HasTypenameKeyword) {
for (auto *D : Prev) {
if (!isa<TypeDecl>(D) && !isa<UsingDecl>(D) && !isa<UsingPackDecl>(D)) {
bool OldCouldBeEnumerator =
@@ -13427,13 +13442,12 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
return false;
}
- const NestedNameSpecifier *CNNS =
- Context.getCanonicalNestedNameSpecifier(Qual);
+ NestedNameSpecifier CNNS = Qual.getCanonical();
for (LookupResult::iterator I = Prev.begin(), E = Prev.end(); I != E; ++I) {
NamedDecl *D = *I;
bool DTypename;
- NestedNameSpecifier *DQual;
+ NestedNameSpecifier DQual = std::nullopt;
if (UsingDecl *UD = dyn_cast<UsingDecl>(D)) {
DTypename = UD->hasTypename();
DQual = UD->getQualifier();
@@ -13454,7 +13468,7 @@ bool Sema::CheckUsingDeclRedeclaration(SourceLocation UsingLoc,
// using decls differ if they name different scopes (but note that
// template instantiation can cause this check to trigger when it
// didn't before instantiation).
- if (CNNS != Context.getCanonicalNestedNameSpecifier(DQual))
+ if (CNNS != DQual.getCanonical())
continue;
Diag(NameLoc, diag::err_using_decl_redeclaration) << SS.getRange();
@@ -13829,7 +13843,7 @@ Decl *Sema::ActOnNamespaceAliasDef(Scope *S, SourceLocation NamespaceLoc,
}
}
assert(!R.isAmbiguous() && !R.empty());
- NamedDecl *ND = R.getRepresentativeDecl();
+ auto *ND = cast<NamespaceBaseDecl>(R.getRepresentativeDecl());
// Check if we have a previous declaration with the same name.
LookupResult PrevR(*this, Alias, AliasLoc, LookupOrdinaryName,
@@ -13914,7 +13928,8 @@ bool SpecialMemberExceptionSpecInfo::visitBase(CXXBaseSpecifier *Base) {
if (!RT)
return false;
- auto *BaseClass = cast<CXXRecordDecl>(RT->getDecl());
+ auto *BaseClass =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
Sema::SpecialMemberOverloadResult SMOR = lookupInheritedCtor(BaseClass);
if (auto *BaseCtor = SMOR.getMethod()) {
visitSubobjectCall(Base, BaseCtor);
@@ -13940,8 +13955,9 @@ bool SpecialMemberExceptionSpecInfo::visitField(FieldDecl *FD) {
ExceptSpec.CalledExpr(E);
} else if (auto *RT = S.Context.getBaseElementType(FD->getType())
->getAs<RecordType>()) {
- visitClassSubobject(cast<CXXRecordDecl>(RT->getDecl()), FD,
- FD->getType().getCVRQualifiers());
+ visitClassSubobject(
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf(), FD,
+ FD->getType().getCVRQualifiers());
}
return false;
}
@@ -14003,7 +14019,7 @@ ComputeDefaultedSpecialMemberExceptionSpec(
// attempting to resolve an exception specification before it's known
// at a higher level.
if (S.RequireCompleteType(MD->getLocation(),
- S.Context.getRecordType(ClassDecl),
+ S.Context.getCanonicalTagType(ClassDecl),
diag::err_exception_spec_incomplete_type))
return Info.ExceptSpec;
@@ -14134,8 +14150,7 @@ CXXConstructorDecl *Sema::DeclareImplicitDefaultConstructor(
*this, ClassDecl, CXXSpecialMemberKind::DefaultConstructor, false);
// Create the actual constructor declaration.
- CanQualType ClassType
- = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
+ CanQualType ClassType = Context.getCanonicalTagType(ClassDecl);
SourceLocation ClassLoc = ClassDecl->getLocation();
DeclarationName Name
= Context.DeclarationNames.getCXXConstructorName(ClassType);
@@ -14420,8 +14435,7 @@ CXXDestructorDecl *Sema::DeclareImplicitDestructor(CXXRecordDecl *ClassDecl) {
*this, ClassDecl, CXXSpecialMemberKind::Destructor, false);
// Create the actual destructor declaration.
- CanQualType ClassType
- = Context.getCanonicalType(Context.getTypeDeclType(ClassDecl));
+ CanQualType ClassType = Context.getCanonicalTagType(ClassDecl);
SourceLocation ClassLoc = ClassDecl->getLocation();
DeclarationName Name
= Context.DeclarationNames.getCXXDestructorName(ClassType);
@@ -14759,9 +14773,10 @@ buildMemcpyForAssignmentOp(Sema &S, SourceLocation Loc, QualType T,
VK_PRValue, OK_Ordinary, Loc, false, S.CurFPFeatureOverrides());
const Type *E = T->getBaseElementTypeUnsafe();
- bool NeedsCollectableMemCpy =
- E->isRecordType() &&
- E->castAs<RecordType>()->getDecl()->hasObjectMember();
+ bool NeedsCollectableMemCpy = E->isRecordType() && E->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasObjectMember();
// Create a reference to the __builtin_objc_memmove_collectable function
StringRef MemCpyName = NeedsCollectableMemCpy ?
@@ -14838,7 +14853,8 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T,
// ignoring any possible virtual overriding functions in more derived
// classes);
if (const RecordType *RecordTy = T->getAs<RecordType>()) {
- CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(RecordTy->getDecl());
+ CXXRecordDecl *ClassDecl =
+ cast<CXXRecordDecl>(RecordTy->getOriginalDecl())->getDefinitionOrSelf();
// Look for operator=.
DeclarationName Name
@@ -14885,10 +14901,9 @@ buildSingleCopyAssignRecursively(Sema &S, SourceLocation Loc, QualType T,
// reference to operator=; this is required to suppress the virtual
// call mechanism.
CXXScopeSpec SS;
+ // FIXME: Don't canonicalize this.
const Type *CanonicalT = S.Context.getCanonicalType(T.getTypePtr());
- SS.MakeTrivial(S.Context,
- NestedNameSpecifier::Create(S.Context, nullptr, CanonicalT),
- Loc);
+ SS.MakeTrivial(S.Context, NestedNameSpecifier(CanonicalT), Loc);
// Create the reference to operator=.
ExprResult OpEqualRef
@@ -15042,9 +15057,9 @@ CXXMethodDecl *Sema::DeclareImplicitCopyAssignment(CXXRecordDecl *ClassDecl) {
if (DSM.isAlreadyBeingDeclared())
return nullptr;
- QualType ArgType = Context.getTypeDeclType(ClassDecl);
- ArgType = Context.getElaboratedType(ElaboratedTypeKeyword::None, nullptr,
- ArgType, nullptr);
+ QualType ArgType = Context.getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, ClassDecl,
+ /*OwnsTag=*/false);
LangAS AS = getDefaultCXXMethodAddrSpace();
if (AS != LangAS::Default)
ArgType = Context.getAddrSpaceQualType(ArgType, AS);
@@ -15303,7 +15318,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
// Check for members of reference type; we can't copy those.
if (Field->getType()->isReferenceType()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
- << Context.getTagDeclType(ClassDecl) << 0 << Field->getDeclName();
+ << Context.getCanonicalTagType(ClassDecl) << 0
+ << Field->getDeclName();
Diag(Field->getLocation(), diag::note_declared_at);
Invalid = true;
continue;
@@ -15313,7 +15329,8 @@ void Sema::DefineImplicitCopyAssignment(SourceLocation CurrentLocation,
QualType BaseType = Context.getBaseElementType(Field->getType());
if (!BaseType->getAs<RecordType>() && BaseType.isConstQualified()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
- << Context.getTagDeclType(ClassDecl) << 1 << Field->getDeclName();
+ << Context.getCanonicalTagType(ClassDecl) << 1
+ << Field->getDeclName();
Diag(Field->getLocation(), diag::note_declared_at);
Invalid = true;
continue;
@@ -15398,9 +15415,9 @@ CXXMethodDecl *Sema::DeclareImplicitMoveAssignment(CXXRecordDecl *ClassDecl) {
// Note: The following rules are largely analoguous to the move
// constructor rules.
- QualType ArgType = Context.getTypeDeclType(ClassDecl);
- ArgType = Context.getElaboratedType(ElaboratedTypeKeyword::None, nullptr,
- ArgType, nullptr);
+ QualType ArgType = Context.getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, ClassDecl,
+ /*OwnsTag=*/false);
LangAS AS = getDefaultCXXMethodAddrSpace();
if (AS != LangAS::Default)
ArgType = Context.getAddrSpaceQualType(ArgType, AS);
@@ -15690,7 +15707,8 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
// Check for members of reference type; we can't move those.
if (Field->getType()->isReferenceType()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
- << Context.getTagDeclType(ClassDecl) << 0 << Field->getDeclName();
+ << Context.getCanonicalTagType(ClassDecl) << 0
+ << Field->getDeclName();
Diag(Field->getLocation(), diag::note_declared_at);
Invalid = true;
continue;
@@ -15700,7 +15718,8 @@ void Sema::DefineImplicitMoveAssignment(SourceLocation CurrentLocation,
QualType BaseType = Context.getBaseElementType(Field->getType());
if (!BaseType->getAs<RecordType>() && BaseType.isConstQualified()) {
Diag(ClassDecl->getLocation(), diag::err_uninitialized_member_for_assign)
- << Context.getTagDeclType(ClassDecl) << 1 << Field->getDeclName();
+ << Context.getCanonicalTagType(ClassDecl) << 1
+ << Field->getDeclName();
Diag(Field->getLocation(), diag::note_declared_at);
Invalid = true;
continue;
@@ -15791,10 +15810,10 @@ CXXConstructorDecl *Sema::DeclareImplicitCopyConstructor(
if (DSM.isAlreadyBeingDeclared())
return nullptr;
- QualType ClassType = Context.getTypeDeclType(ClassDecl);
+ QualType ClassType = Context.getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, ClassDecl,
+ /*OwnsTag=*/false);
QualType ArgType = ClassType;
- ArgType = Context.getElaboratedType(ElaboratedTypeKeyword::None, nullptr,
- ArgType, nullptr);
bool Const = ClassDecl->implicitCopyConstructorHasConstParam();
if (Const)
ArgType = ArgType.withConst();
@@ -15938,11 +15957,11 @@ CXXConstructorDecl *Sema::DeclareImplicitMoveConstructor(
if (DSM.isAlreadyBeingDeclared())
return nullptr;
- QualType ClassType = Context.getTypeDeclType(ClassDecl);
+ QualType ClassType = Context.getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, ClassDecl,
+ /*OwnsTag=*/false);
QualType ArgType = ClassType;
- ArgType = Context.getElaboratedType(ElaboratedTypeKeyword::None, nullptr,
- ArgType, nullptr);
LangAS AS = getDefaultCXXMethodAddrSpace();
if (AS != LangAS::Default)
ArgType = Context.getAddrSpaceQualType(ClassType, AS);
@@ -16297,7 +16316,8 @@ void Sema::FinalizeVarWithDestructor(VarDecl *VD, const RecordType *Record) {
if (VD->getInit() && VD->getInit()->containsErrors())
return;
- CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(Record->getDecl());
+ CXXRecordDecl *ClassDecl =
+ cast<CXXRecordDecl>(Record->getOriginalDecl())->getDefinitionOrSelf();
if (ClassDecl->isInvalidDecl()) return;
if (ClassDecl->hasIrrelevantDestructor()) return;
if (ClassDecl->isDependentContext()) return;
@@ -16643,10 +16663,10 @@ static inline bool CheckOperatorNewDeleteTypes(
if (CheckType(SizeParameterIndex, SemaRef.Context.getSizeType(), "size_t"))
return true;
- TypeDecl *StdAlignValTDecl = SemaRef.getStdAlignValT();
- QualType StdAlignValT =
- StdAlignValTDecl ? SemaRef.Context.getTypeDeclType(StdAlignValTDecl)
- : QualType();
+ TagDecl *StdAlignValTDecl = SemaRef.getStdAlignValT();
+ CanQualType StdAlignValT =
+ StdAlignValTDecl ? SemaRef.Context.getCanonicalTagType(StdAlignValTDecl)
+ : CanQualType();
if (CheckType(SizeParameterIndex + 1, StdAlignValT, "std::align_val_t"))
return true;
@@ -16686,8 +16706,8 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) {
auto *MD = dyn_cast<CXXMethodDecl>(FnDecl);
auto ConstructDestroyingDeleteAddressType = [&]() {
assert(MD);
- return SemaRef.Context.getCanonicalType(SemaRef.Context.getPointerType(
- SemaRef.Context.getRecordType(MD->getParent())));
+ return SemaRef.Context.getPointerType(
+ SemaRef.Context.getCanonicalTagType(MD->getParent()));
};
// C++ P2719: A destroying operator delete cannot be type aware
@@ -16726,8 +16746,8 @@ CheckOperatorDeleteDeclaration(Sema &SemaRef, FunctionDecl *FnDecl) {
// function shall be of type void *.
CanQualType ExpectedAddressParamType =
MD && IsPotentiallyDestroyingOperatorDelete(SemaRef, MD)
- ? SemaRef.Context.getCanonicalType(SemaRef.Context.getPointerType(
- SemaRef.Context.getRecordType(MD->getParent())))
+ ? SemaRef.Context.getPointerType(
+ SemaRef.Context.getCanonicalTagType(MD->getParent()))
: SemaRef.Context.VoidPtrTy;
// C++ [basic.stc.dynamic.deallocation]p2:
@@ -17958,27 +17978,14 @@ DeclResult Sema::ActOnTemplatedFriendTag(
/*OOK=*/OffsetOfKind::Outside);
}
+ TypeSourceInfo *TSI = nullptr;
ElaboratedTypeKeyword Keyword
= TypeWithKeyword::getKeywordForTagTypeKind(Kind);
- QualType T = CheckTypenameType(Keyword, TagLoc, QualifierLoc,
- *Name, NameLoc);
+ QualType T = CheckTypenameType(Keyword, TagLoc, QualifierLoc, *Name,
+ NameLoc, &TSI, /*DeducedTSTContext=*/true);
if (T.isNull())
return true;
- TypeSourceInfo *TSI = Context.CreateTypeSourceInfo(T);
- if (isa<DependentNameType>(T)) {
- DependentNameTypeLoc TL =
- TSI->getTypeLoc().castAs<DependentNameTypeLoc>();
- TL.setElaboratedKeywordLoc(TagLoc);
- TL.setQualifierLoc(QualifierLoc);
- TL.setNameLoc(NameLoc);
- } else {
- ElaboratedTypeLoc TL = TSI->getTypeLoc().castAs<ElaboratedTypeLoc>();
- TL.setElaboratedKeywordLoc(TagLoc);
- TL.setQualifierLoc(QualifierLoc);
- TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(NameLoc);
- }
-
FriendDecl *Friend =
FriendDecl::Create(Context, CurContext, NameLoc, TSI, FriendLoc,
EllipsisLoc, TempParamLists);
@@ -18290,7 +18297,7 @@ NamedDecl *Sema::ActOnFriendFunctionDecl(Scope *S, Declarator &D,
// - There's a non-dependent scope specifier, in which case we
// compute it and do a previous lookup there for a function
// or function template.
- } else if (!SS.getScopeRep()->isDependent()) {
+ } else if (!SS.getScopeRep().isDependent()) {
DC = computeDeclContext(SS);
if (!DC) return nullptr;
@@ -18789,7 +18796,7 @@ bool Sema::CheckOverridingFunctionReturnType(const CXXMethodDecl *New,
// complete at the point of declaration of D::f or shall be the class
// type D.
if (const RecordType *RT = NewClassTy->getAs<RecordType>()) {
- if (!RT->isBeingDefined() &&
+ if (!RT->getOriginalDecl()->isEntityBeingDefined() &&
RequireCompleteType(New->getLocation(), NewClassTy,
diag::err_covariant_return_incomplete,
New->getDeclName()))
@@ -19166,8 +19173,9 @@ void Sema::MarkVirtualMembersReferenced(SourceLocation Loc,
return;
for (const auto &I : RD->bases()) {
- const auto *Base =
- cast<CXXRecordDecl>(I.getType()->castAs<RecordType>()->getDecl());
+ const auto *Base = cast<CXXRecordDecl>(
+ I.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (Base->getNumVBases() == 0)
continue;
MarkVirtualMembersReferenced(Loc, Base);
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index 9dbc3efbca405..4614cf766b19c 100644
--- a/clang/lib/Sema/SemaDeclObjC.cpp
+++ b/clang/lib/Sema/SemaDeclObjC.cpp
@@ -591,12 +591,13 @@ void SemaObjC::ActOnSuperClassOfClassInterface(
// The previous declaration was not a class decl. Check if we have a
// typedef. If we do, get the underlying class type.
if (const TypedefNameDecl *TDecl =
- dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
+ dyn_cast_or_null<TypedefNameDecl>(PrevDecl)) {
QualType T = TDecl->getUnderlyingType();
if (T->isObjCObjectType()) {
if (NamedDecl *IDecl = T->castAs<ObjCObjectType>()->getInterface()) {
SuperClassDecl = dyn_cast<ObjCInterfaceDecl>(IDecl);
- SuperClassType = Context.getTypeDeclType(TDecl);
+ SuperClassType = Context.getTypeDeclType(
+ ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt, TDecl);
// This handles the following case:
// @interface NewI @end
@@ -1389,11 +1390,9 @@ class ObjCTypeArgOrProtocolValidatorCCC final
// Make sure the type is something we would accept as a type
// argument.
- auto type = Context.getTypeDeclType(typeDecl);
- if (type->isObjCObjectPointerType() ||
- type->isBlockPointerType() ||
+ if (CanQualType type = Context.getCanonicalTypeDeclType(typeDecl);
type->isDependentType() ||
- type->isObjCObjectType())
+ isa<ObjCObjectPointerType, BlockPointerType, ObjCObjectType>(type))
return true;
return false;
@@ -1589,7 +1588,9 @@ void SemaObjC::actOnObjCTypeArgsOrProtocolQualifiers(
unsigned diagID; // unused
QualType type;
if (auto *actualTypeDecl = dyn_cast<TypeDecl *>(typeDecl))
- type = Context.getTypeDeclType(actualTypeDecl);
+ type =
+ Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, actualTypeDecl);
else
type = Context.getObjCInterfaceType(cast<ObjCInterfaceDecl *>(typeDecl));
TypeSourceInfo *parsedTSInfo = Context.getTrivialTypeSourceInfo(type, loc);
@@ -3231,8 +3232,10 @@ static bool tryMatchRecordTypes(ASTContext &Context,
assert(lt && rt && lt != rt);
if (!isa<RecordType>(lt) || !isa<RecordType>(rt)) return false;
- RecordDecl *left = cast<RecordType>(lt)->getDecl();
- RecordDecl *right = cast<RecordType>(rt)->getDecl();
+ RecordDecl *left =
+ cast<RecordType>(lt)->getOriginalDecl()->getDefinitionOrSelf();
+ RecordDecl *right =
+ cast<RecordType>(rt)->getOriginalDecl()->getDefinitionOrSelf();
// Require union-hood to match.
if (left->isUnion() != right->isUnion()) return false;
@@ -3846,7 +3849,9 @@ static bool IsVariableSizedType(QualType T) {
if (T->isIncompleteArrayType())
return true;
const auto *RecordTy = T->getAs<RecordType>();
- return (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember());
+ return (RecordTy && RecordTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember());
}
static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) {
@@ -3892,7 +3897,9 @@ static void DiagnoseVariableSizedIvars(Sema &S, ObjCContainerDecl *OCD) {
<< TagTypeKind::Class; // Use "class" for Obj-C.
IsInvalidIvar = true;
} else if (const RecordType *RecordTy = IvarTy->getAs<RecordType>()) {
- if (RecordTy->getDecl()->hasFlexibleArrayMember()) {
+ if (RecordTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember()) {
S.Diag(ivar->getLocation(),
diag::err_objc_variable_sized_type_not_at_end)
<< ivar->getDeclName() << IvarTy;
@@ -5537,7 +5544,8 @@ void SemaObjC::SetIvarInitializers(ObjCImplementationDecl *ObjCImplementation) {
if (const RecordType *RecordTy =
Context.getBaseElementType(Field->getType())
->getAs<RecordType>()) {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getDecl());
+ CXXRecordDecl *RD = cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (CXXDestructorDecl *Destructor = SemaRef.LookupDestructor(RD)) {
SemaRef.MarkFunctionReferenced(Field->getLocation(), Destructor);
SemaRef.CheckDestructorAccess(
diff --git a/clang/lib/Sema/SemaExceptionSpec.cpp b/clang/lib/Sema/SemaExceptionSpec.cpp
index 0a6cea8869c14..94413b5b92d22 100644
--- a/clang/lib/Sema/SemaExceptionSpec.cpp
+++ b/clang/lib/Sema/SemaExceptionSpec.cpp
@@ -163,8 +163,9 @@ bool Sema::CheckSpecifiedExceptionType(QualType &T, SourceRange Range) {
DiagID = diag::ext_incomplete_in_exception_spec;
ReturnValueOnError = false;
}
- if (!(PointeeT->isRecordType() &&
- PointeeT->castAs<RecordType>()->isBeingDefined()) &&
+ if (!(PointeeT->isRecordType() && PointeeT->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->isEntityBeingDefined()) &&
RequireCompleteType(Range.getBegin(), PointeeT, DiagID, Kind, Range))
return ReturnValueOnError;
diff --git a/clang/lib/Sema/SemaExpr.cpp b/clang/lib/Sema/SemaExpr.cpp
index 3c3d29c415249..fbab232f65701 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -1527,8 +1527,8 @@ void Sema::checkEnumArithmeticConversions(Expr *LHS, Expr *RHS,
// are ill-formed.
if (getLangOpts().CPlusPlus26)
DiagID = diag::warn_conv_mixed_enum_types_cxx26;
- else if (!L->castAs<EnumType>()->getDecl()->hasNameForLinkage() ||
- !R->castAs<EnumType>()->getDecl()->hasNameForLinkage()) {
+ else if (!L->castAs<EnumType>()->getOriginalDecl()->hasNameForLinkage() ||
+ !R->castAs<EnumType>()->getOriginalDecl()->hasNameForLinkage()) {
// If either enumeration type is unnamed, it's less likely that the
// user cares about this, but this situation is still deprecated in
// C++2a. Use a different warning group.
@@ -2529,7 +2529,7 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
if (isa<CXXRecordDecl>(DC)) {
if (ExplicitTemplateArgs) {
if (LookupTemplateName(
- R, S, SS, Context.getRecordType(cast<CXXRecordDecl>(DC)),
+ R, S, SS, Context.getCanonicalTagType(cast<CXXRecordDecl>(DC)),
/*EnteringContext*/ false, TemplateNameIsRequired,
/*RequiredTemplateKind*/ nullptr, /*AllowTypoCorrection*/ true))
return true;
@@ -2605,11 +2605,8 @@ bool Sema::DiagnoseEmptyLookup(Scope *S, CXXScopeSpec &SS, LookupResult &R,
}
R.addDecl(ND);
if (getLangOpts().CPlusPlus && ND->isCXXClassMember()) {
- CXXRecordDecl *Record = nullptr;
- if (Corrected.getCorrectionSpecifier()) {
- const Type *Ty = Corrected.getCorrectionSpecifier()->getAsType();
- Record = Ty->getAsCXXRecordDecl();
- }
+ CXXRecordDecl *Record =
+ Corrected.getCorrectionSpecifier().getAsRecordDecl();
if (!Record)
Record = cast<CXXRecordDecl>(
ND->getDeclContext()->getRedeclContext());
@@ -2705,8 +2702,7 @@ recoverFromMSUnqualifiedLookup(Sema &S, ASTContext &Context,
// Synthesize a fake NNS that points to the derived class. This will
// perform name lookup during template instantiation.
CXXScopeSpec SS;
- auto *NNS =
- NestedNameSpecifier::Create(Context, nullptr, RD->getTypeForDecl());
+ NestedNameSpecifier NNS(Context.getCanonicalTagType(RD)->getTypePtr());
SS.MakeTrivial(Context, NNS, SourceRange(Loc, Loc));
return DependentScopeDeclRefExpr::Create(
Context, SS.getWithLocInContext(Context), TemplateKWLoc, NameInfo,
@@ -2829,8 +2825,7 @@ Sema::ActOnIdExpression(Scope *S, CXXScopeSpec &SS,
// If this name wasn't predeclared and if this is not a function
// call, diagnose the problem.
- DefaultFilterCCC DefaultValidator(II, SS.isValid() ? SS.getScopeRep()
- : nullptr);
+ DefaultFilterCCC DefaultValidator(II, SS.getScopeRep());
DefaultValidator.IsAddressOfOperand = IsAddressOfOperand;
assert((!CCC || CCC->IsAddressOfOperand == IsAddressOfOperand) &&
"Typo correction callback misconfigured");
@@ -2940,8 +2935,28 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr(
}
if (const TypeDecl *TD = R.getAsSingle<TypeDecl>()) {
- QualType Ty = Context.getTypeDeclType(TD);
- QualType ET = getElaboratedType(ElaboratedTypeKeyword::None, SS, Ty);
+ QualType ET;
+ TypeLocBuilder TLB;
+ if (auto *TagD = dyn_cast<TagDecl>(TD)) {
+ ET = SemaRef.Context.getTagType(ElaboratedTypeKeyword::None,
+ SS.getScopeRep(), TagD,
+ /*OwnsTag=*/false);
+ auto TL = TLB.push<TagTypeLoc>(ET);
+ TL.setElaboratedKeywordLoc(SourceLocation());
+ TL.setQualifierLoc(SS.getWithLocInContext(Context));
+ TL.setNameLoc(NameInfo.getLoc());
+ } else if (auto *TypedefD = dyn_cast<TypedefNameDecl>(TD)) {
+ ET = SemaRef.Context.getTypedefType(ElaboratedTypeKeyword::None,
+ SS.getScopeRep(), TypedefD);
+ TLB.push<TypedefTypeLoc>(ET).set(
+ /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context), NameInfo.getLoc());
+ } else {
+ // FIXME: What else can appear here?
+ ET = SemaRef.Context.getTypeDeclType(TD);
+ TLB.pushTypeSpec(ET).setNameLoc(NameInfo.getLoc());
+ assert(SS.isEmpty());
+ }
// Diagnose a missing typename if this resolved unambiguously to a type in
// a dependent context. If we can recover with a type, downgrade this to
@@ -2962,13 +2977,6 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr(
D << FixItHint::CreateInsertion(Loc, "typename ");
// Recover by pretending this was an elaborated type.
- TypeLocBuilder TLB;
- TLB.pushTypeSpec(Ty).setNameLoc(NameInfo.getLoc());
-
- ElaboratedTypeLoc QTL = TLB.push<ElaboratedTypeLoc>(ET);
- QTL.setElaboratedKeywordLoc(SourceLocation());
- QTL.setQualifierLoc(SS.getWithLocInContext(Context));
-
*RecoveryTSI = TLB.getTypeSourceInfo(Context, ET);
return ExprEmpty();
@@ -2984,11 +2992,10 @@ ExprResult Sema::BuildQualifiedDeclarationNameExpr(
return BuildDeclarationNameExpr(SS, R, /*ADL=*/false);
}
-ExprResult
-Sema::PerformObjectMemberConversion(Expr *From,
- NestedNameSpecifier *Qualifier,
- NamedDecl *FoundDecl,
- NamedDecl *Member) {
+ExprResult Sema::PerformObjectMemberConversion(Expr *From,
+ NestedNameSpecifier Qualifier,
+ NamedDecl *FoundDecl,
+ NamedDecl *Member) {
const auto *RD = dyn_cast<CXXRecordDecl>(Member->getDeclContext());
if (!RD)
return From;
@@ -2999,7 +3006,7 @@ Sema::PerformObjectMemberConversion(Expr *From,
QualType FromType = From->getType();
bool PointerConversions = false;
if (isa<FieldDecl>(Member)) {
- DestRecordType = Context.getCanonicalType(Context.getTypeDeclType(RD));
+ DestRecordType = Context.getCanonicalTagType(RD);
auto FromPtrType = FromType->getAs<PointerType>();
DestRecordType = Context.getAddrSpaceQualType(
DestRecordType, FromPtrType
@@ -3077,8 +3084,8 @@ Sema::PerformObjectMemberConversion(Expr *From,
// x = 17; // error: ambiguous base subobjects
// Derived1::x = 17; // okay, pick the Base subobject of Derived1
// }
- if (Qualifier && Qualifier->getAsType()) {
- QualType QType = QualType(Qualifier->getAsType(), 0);
+ if (Qualifier.getKind() == NestedNameSpecifier::Kind::Type) {
+ QualType QType = QualType(Qualifier.getAsType(), 0);
assert(QType->isRecordType() && "lookup done with non-record type");
QualType QRecordType = QualType(QType->castAs<RecordType>(), 0);
@@ -4480,9 +4487,6 @@ static void captureVariablyModifiedType(ASTContext &Context, QualType T,
case Type::BitInt:
case Type::HLSLInlineSpirv:
llvm_unreachable("type class is never variably-modified!");
- case Type::Elaborated:
- T = cast<ElaboratedType>(Ty)->getNamedType();
- break;
case Type::Adjusted:
T = cast<AdjustedType>(Ty)->getOriginalType();
break;
@@ -5871,7 +5875,7 @@ static bool isParenthetizedAndQualifiedAddressOfExpr(Expr *Fn) {
return DRE->hasQualifier();
}
if (auto *OVL = dyn_cast<OverloadExpr>(UO->getSubExpr()->IgnoreParens()))
- return OVL->getQualifier();
+ return bool(OVL->getQualifier());
return false;
}
@@ -7071,7 +7075,7 @@ ExprResult Sema::BuildResolvedCallExpr(Expr *Fn, NamedDecl *NDecl,
for (unsigned i = 0, e = Args.size(); i != e; i++) {
if (const auto *RT =
dyn_cast<RecordType>(Args[i]->getType().getCanonicalType())) {
- if (RT->getDecl()->isOrContainsUnion())
+ if (RT->getOriginalDecl()->isOrContainsUnion())
Diag(Args[i]->getBeginLoc(), diag::warn_cmse_nonsecure_union)
<< 0 << i;
}
@@ -8600,7 +8604,8 @@ QualType Sema::CheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// type.
if (const RecordType *LHSRT = LHSTy->getAs<RecordType>()) { // C99 6.5.15p3
if (const RecordType *RHSRT = RHSTy->getAs<RecordType>())
- if (LHSRT->getDecl() == RHSRT->getDecl())
+ if (declaresSameEntity(LHSRT->getOriginalDecl(),
+ RHSRT->getOriginalDecl()))
// "If both the operands have structure or union type, the result has
// that type." This implies that CV qualifiers are dropped.
return Context.getCommonSugaredType(LHSTy.getUnqualifiedType(),
@@ -9669,11 +9674,14 @@ Sema::CheckTransparentUnionArgumentConstraints(QualType ArgType,
// If the ArgType is a Union type, we want to handle a potential
// transparent_union GCC extension.
const RecordType *UT = ArgType->getAsUnionType();
- if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
+ if (!UT)
+ return AssignConvertType::Incompatible;
+
+ RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ if (!UD->hasAttr<TransparentUnionAttr>())
return AssignConvertType::Incompatible;
// The field to initialize within the transparent union.
- RecordDecl *UD = UT->getDecl();
FieldDecl *InitField = nullptr;
// It's compatible if the expression matches any of the fields.
for (auto *it : UD->fields()) {
@@ -11396,7 +11404,7 @@ QualType Sema::CheckSubtractionOperands(ExprResult &LHS, ExprResult &RHS,
static bool isScopedEnumerationType(QualType T) {
if (const EnumType *ET = T->getAs<EnumType>())
- return ET->getDecl()->isScoped();
+ return ET->getOriginalDecl()->isScoped();
return false;
}
@@ -12285,8 +12293,10 @@ static QualType checkArithmeticOrEnumeralThreeWayCompare(Sema &S,
S.InvalidOperands(Loc, LHS, RHS);
return QualType();
}
- QualType IntType =
- LHSStrippedType->castAs<EnumType>()->getDecl()->getIntegerType();
+ QualType IntType = LHSStrippedType->castAs<EnumType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->getIntegerType();
assert(IntType->isArithmeticType());
// We can't use `CK_IntegralCast` when the underlying type is 'bool', so we
@@ -12452,7 +12462,7 @@ QualType Sema::CheckCompareOperands(ExprResult &LHS, ExprResult &RHS,
auto computeResultTy = [&]() {
if (Opc != BO_Cmp)
- return Context.getLogicalOperationType();
+ return QualType(Context.getLogicalOperationType());
assert(getLangOpts().CPlusPlus);
assert(Context.hasSameType(LHS.get()->getType(), RHS.get()->getType()));
@@ -13689,8 +13699,10 @@ static void DiagnoseRecursiveConstFields(Sema &S, const ValueDecl *VD,
// diagnostics in field nesting order.
while (RecordTypeList.size() > NextToCheckIndex) {
bool IsNested = NextToCheckIndex > 0;
- for (const FieldDecl *Field :
- RecordTypeList[NextToCheckIndex]->getDecl()->fields()) {
+ for (const FieldDecl *Field : RecordTypeList[NextToCheckIndex]
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->fields()) {
// First, check every field for constness.
QualType FieldTy = Field->getType();
if (FieldTy.isConstQualified()) {
@@ -16145,7 +16157,7 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
if (!RC)
return ExprError(Diag(OC.LocEnd, diag::err_offsetof_record_type)
<< CurrentType);
- RecordDecl *RD = RC->getDecl();
+ RecordDecl *RD = RC->getOriginalDecl()->getDefinitionOrSelf();
// C++ [lib.support.types]p5:
// The macro offsetof accepts a restricted set of type arguments in this
@@ -16206,8 +16218,8 @@ ExprResult Sema::BuildBuiltinOffsetOf(SourceLocation BuiltinLoc,
// If the member was found in a base class, introduce OffsetOfNodes for
// the base class indirections.
CXXBasePaths Paths;
- if (IsDerivedFrom(OC.LocStart, CurrentType, Context.getTypeDeclType(Parent),
- Paths)) {
+ if (IsDerivedFrom(OC.LocStart, CurrentType,
+ Context.getCanonicalTagType(Parent), Paths)) {
if (Paths.getDetectedVirtual()) {
Diag(OC.LocEnd, diag::err_offsetof_field_of_virtual_base)
<< MemberDecl->getDeclName()
@@ -16772,7 +16784,8 @@ ExprResult Sema::BuildVAArgExpr(SourceLocation BuiltinLoc,
// that.
QualType UnderlyingType = TInfo->getType();
if (const auto *ET = UnderlyingType->getAs<EnumType>())
- UnderlyingType = ET->getDecl()->getIntegerType();
+ UnderlyingType =
+ ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
if (Context.typesAreCompatible(PromoteType, UnderlyingType,
/*CompareUnqualified*/ true))
PromoteType = QualType();
@@ -16918,7 +16931,7 @@ ExprResult Sema::ActOnSourceLocExpr(SourceLocIdentKind Kind,
return ExprError();
}
ResultTy = Context.getPointerType(
- Context.getRecordType(StdSourceLocationImplDecl).withConst());
+ Context.getCanonicalTagType(StdSourceLocationImplDecl).withConst());
break;
}
@@ -18748,7 +18761,9 @@ static bool isVariableCapturable(CapturingScopeInfo *CSI, ValueDecl *Var,
// Prohibit structs with flexible array members too.
// We cannot capture what is in the tail end of the struct.
if (const RecordType *VTTy = Var->getType()->getAs<RecordType>()) {
- if (VTTy->getDecl()->hasFlexibleArrayMember()) {
+ if (VTTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember()) {
if (Diagnose) {
if (IsBlock)
S.Diag(Loc, diag::err_ref_flexarray_type);
@@ -21189,7 +21204,7 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
NamedDecl *Temp = *ULE->decls_begin();
const bool IsTypeAliasTemplateDecl = isa<TypeAliasTemplateDecl>(Temp);
- NestedNameSpecifier *NNS = ULE->getQualifierLoc().getNestedNameSpecifier();
+ NestedNameSpecifier NNS = ULE->getQualifierLoc().getNestedNameSpecifier();
// FIXME: AssumedTemplate is not very appropriate for error recovery here,
// as it models only the unqualified-id case, where this case can clearly be
// qualified. Thus we can't just qualify an assumed template.
@@ -21215,16 +21230,16 @@ ExprResult Sema::CheckPlaceholderExpr(Expr *E) {
QualType TST;
{
SFINAETrap Trap(*this);
- TST = CheckTemplateIdType(TN, NameInfo.getBeginLoc(), TAL);
+ TST = CheckTemplateIdType(ElaboratedTypeKeyword::None, TN,
+ NameInfo.getBeginLoc(), TAL);
}
if (TST.isNull())
TST = Context.getTemplateSpecializationType(
- TN, ULE->template_arguments(), /*CanonicalArgs=*/{},
+ ElaboratedTypeKeyword::None, TN, ULE->template_arguments(),
+ /*CanonicalArgs=*/{},
HasAnyDependentTA ? Context.DependentTy : Context.IntTy);
- QualType ET =
- Context.getElaboratedType(ElaboratedTypeKeyword::None, NNS, TST);
return CreateRecoveryExpr(NameInfo.getBeginLoc(), NameInfo.getEndLoc(), {},
- ET);
+ TST);
}
// Overloaded expressions.
diff --git a/clang/lib/Sema/SemaExprCXX.cpp b/clang/lib/Sema/SemaExprCXX.cpp
index f17a338825423..216f39db4cde6 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -57,11 +57,11 @@ using namespace sema;
ParsedType Sema::getInheritingConstructorName(CXXScopeSpec &SS,
SourceLocation NameLoc,
const IdentifierInfo &Name) {
- NestedNameSpecifier *NNS = SS.getScopeRep();
- if ([[maybe_unused]] const IdentifierInfo *II = NNS->getAsIdentifier())
- assert(II == &Name && "not a constructor name");
+ NestedNameSpecifier NNS = SS.getScopeRep();
+ QualType Type(NNS.getAsType(), 0);
+ if ([[maybe_unused]] const auto *DNT = dyn_cast<DependentNameType>(Type))
+ assert(DNT->getIdentifier() == &Name && "not a constructor name");
- QualType Type(NNS->translateToType(Context), 0);
// This reference to the type is located entirely at the location of the
// final identifier in the qualified-id.
return CreateParsedType(Type,
@@ -111,10 +111,8 @@ ParsedType Sema::getConstructorName(const IdentifierInfo &II,
return ParsedType();
}
- QualType T = Context.getTypeDeclType(InjectedClassName);
- DiagnoseUseOfDecl(InjectedClassName, NameLoc);
- MarkAnyDeclReferenced(NameLoc, InjectedClassName, /*OdrUse=*/false);
-
+ QualType T = Context.getTagType(ElaboratedTypeKeyword::None, SS.getScopeRep(),
+ InjectedClassName, /*OwnsTag=*/false);
return ParsedType::make(T);
}
@@ -175,7 +173,7 @@ ParsedType Sema::getDestructorName(const IdentifierInfo &II,
if (SearchType.isNull() || SearchType->isDependentType())
return true;
- QualType T = Context.getTypeDeclType(Type);
+ CanQualType T = Context.getCanonicalTypeDeclType(Type);
return Context.hasSameUnqualifiedType(T, SearchType);
};
@@ -207,7 +205,8 @@ ParsedType Sema::getDestructorName(const IdentifierInfo &II,
NamedDecl *D = F.next();
if (auto *TD = dyn_cast<TypeDecl>(D->getUnderlyingDecl()))
Diag(D->getLocation(), diag::note_destructor_type_here)
- << Context.getTypeDeclType(TD);
+ << Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD);
else
Diag(D->getLocation(), diag::note_destructor_nontype_here);
@@ -222,11 +221,11 @@ ParsedType Sema::getDestructorName(const IdentifierInfo &II,
if (TypeDecl *Type = Found.getAsSingle<TypeDecl>()) {
if (IsAcceptableResult(Type)) {
- QualType T = Context.getTypeDeclType(Type);
+ QualType T = Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, Type);
MarkAnyDeclReferenced(Type->getLocation(), Type, /*OdrUse=*/false);
- return CreateParsedType(
- Context.getElaboratedType(ElaboratedTypeKeyword::None, nullptr, T),
- Context.getTrivialTypeSourceInfo(T, NameLoc));
+ return CreateParsedType(T,
+ Context.getTrivialTypeSourceInfo(T, NameLoc));
}
}
@@ -311,15 +310,23 @@ ParsedType Sema::getDestructorName(const IdentifierInfo &II,
// If both lookups succeed and find a dependent result, which result should
// we retain? (Same question for p->~type-name().)
- if (NestedNameSpecifier *Prefix =
- SS.isSet() ? SS.getScopeRep()->getPrefix() : nullptr) {
+ auto Prefix = [&]() -> NestedNameSpecifierLoc {
+ NestedNameSpecifierLoc NNS = SS.getWithLocInContext(Context);
+ if (!NNS)
+ return NestedNameSpecifierLoc();
+ if (auto TL = NNS.getAsTypeLoc())
+ return TL.getPrefix();
+ return NNS.getAsNamespaceAndPrefix().Prefix;
+ }();
+
+ if (Prefix) {
// This is
//
// nested-name-specifier type-name :: ~ type-name
//
// Look for the second type-name in the nested-name-specifier.
CXXScopeSpec PrefixSS;
- PrefixSS.Adopt(NestedNameSpecifierLoc(Prefix, SS.location_data()));
+ PrefixSS.Adopt(Prefix);
if (ParsedType T = LookupInNestedNameSpec(PrefixSS))
return T;
} else {
@@ -374,7 +381,7 @@ ParsedType Sema::getDestructorName(const IdentifierInfo &II,
//
// also looks for type-name in the scope. Unfortunately, we can't
// reasonably apply this fallback for dependent nested-name-specifiers.
- if (SS.isValid() && SS.getScopeRep()->getPrefix()) {
+ if (Prefix) {
if (ParsedType T = LookupInScope()) {
Diag(SS.getEndLoc(), diag::ext_qualified_dtor_named_in_lexical_scope)
<< FixItHint::CreateRemoval(SS.getRange());
@@ -419,9 +426,10 @@ ParsedType Sema::getDestructorName(const IdentifierInfo &II,
if (auto *TD = dyn_cast<TypeDecl>(FoundDecls[0]->getUnderlyingDecl())) {
assert(!SearchType.isNull() &&
"should only reject a type result if we have a search type");
- QualType T = Context.getTypeDeclType(TD);
Diag(NameLoc, diag::err_destructor_expr_type_mismatch)
- << T << SearchType << MakeFixItHint();
+ << Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD)
+ << SearchType << MakeFixItHint();
} else {
Diag(NameLoc, diag::err_destructor_expr_nontype)
<< &II << MakeFixItHint();
@@ -435,7 +443,8 @@ ParsedType Sema::getDestructorName(const IdentifierInfo &II,
for (NamedDecl *FoundD : FoundDecls) {
if (auto *TD = dyn_cast<TypeDecl>(FoundD->getUnderlyingDecl()))
Diag(FoundD->getLocation(), diag::note_destructor_type_here)
- << Context.getTypeDeclType(TD);
+ << Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD);
else
Diag(FoundD->getLocation(), diag::note_destructor_nontype_here)
<< FoundD;
@@ -501,12 +510,8 @@ bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
<< II << static_cast<int>(Status) << Hint;
}
- if (!SS.isValid())
- return false;
-
- switch (SS.getScopeRep()->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::TypeSpec:
+ switch (SS.getScopeRep().getKind()) {
+ case NestedNameSpecifier::Kind::Type:
// Per C++11 [over.literal]p2, literal operators can only be declared at
// namespace scope. Therefore, this unqualified-id cannot name anything.
// Reject it early, because we have no AST representation for this in the
@@ -515,10 +520,10 @@ bool Sema::checkLiteralOperatorId(const CXXScopeSpec &SS,
<< SS.getScopeRep();
return true;
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
+ case NestedNameSpecifier::Kind::Namespace:
return false;
}
@@ -566,7 +571,8 @@ ExprResult Sema::BuildCXXTypeId(QualType TypeInfoType,
QualType T = E->getType();
if (const RecordType *RecordT = T->getAs<RecordType>()) {
- CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getDecl());
+ CXXRecordDecl *RecordD = cast<CXXRecordDecl>(RecordT->getOriginalDecl())
+ ->getDefinitionOrSelf();
// C++ [expr.typeid]p3:
// [...] If the type of the expression is a class type, the class
// shall be completely-defined.
@@ -660,7 +666,7 @@ Sema::ActOnCXXTypeid(SourceLocation OpLoc, SourceLocation LParenLoc,
return ExprError(Diag(OpLoc, diag::err_no_typeid_with_fno_rtti));
}
- QualType TypeInfoType = Context.getTypeDeclType(CXXTypeInfoDecl);
+ CanQualType TypeInfoType = Context.getCanonicalTagType(CXXTypeInfoDecl);
if (isType) {
// The operand is a type; handle it as such.
@@ -1215,7 +1221,7 @@ QualType Sema::getCurrentThisType() {
// This is a lambda call operator that is being instantiated as a default
// initializer. DC must point to the enclosing class type, so we can recover
// the 'this' type from it.
- QualType ClassTy = Context.getTypeDeclType(cast<CXXRecordDecl>(DC));
+ CanQualType ClassTy = Context.getCanonicalTagType(cast<CXXRecordDecl>(DC));
// There are no cv-qualifiers for 'this' within default initializers,
// per [expr.prim.general]p4.
ThisTy = Context.getPointerType(ClassTy);
@@ -1245,7 +1251,7 @@ Sema::CXXThisScopeRAII::CXXThisScopeRAII(Sema &S,
else
Record = cast<CXXRecordDecl>(ContextDecl);
- QualType T = S.Context.getRecordType(Record);
+ QualType T = S.Context.getCanonicalTagType(Record);
T = S.getASTContext().getQualifiedType(T, CXXThisTypeQuals);
S.CXXThisTypeOverride =
@@ -1733,7 +1739,7 @@ static bool isNonPlacementDeallocationFunction(Sema &S, FunctionDecl *FD) {
if (S.getLangOpts().AlignedAllocation && UsualParams < FD->getNumParams() &&
S.Context.hasSameUnqualifiedType(
FD->getParamDecl(UsualParams)->getType(),
- S.Context.getTypeDeclType(S.getStdAlignValT())))
+ S.Context.getCanonicalTagType(S.getStdAlignValT())))
++UsualParams;
return UsualParams == FD->getNumParams();
@@ -1861,8 +1867,8 @@ namespace {
if (FunctionTemplateDecl *Best = S.getMoreSpecializedTemplate(
PrimaryTemplate, OtherPrimaryTemplate, SourceLocation(),
TPOC_Call, ImplicitArgCount,
- DC ? QualType(DC->getTypeForDecl(), 0) : QualType{},
- OtherDC ? QualType(OtherDC->getTypeForDecl(), 0) : QualType{},
+ DC ? S.Context.getCanonicalTagType(DC) : QualType{},
+ OtherDC ? S.Context.getCanonicalTagType(OtherDC) : QualType{},
false)) {
return Best == PrimaryTemplate ? 1 : -1;
}
@@ -1978,7 +1984,7 @@ static bool doesUsualArrayDeleteWantSize(Sema &S, SourceLocation loc,
DeclarationName deleteName =
S.Context.DeclarationNames.getCXXOperatorName(OO_Array_Delete);
LookupResult ops(S, deleteName, loc, Sema::LookupOrdinaryName);
- S.LookupQualifiedName(ops, record->getDecl());
+ S.LookupQualifiedName(ops, record->getOriginalDecl()->getDefinitionOrSelf());
// We're just doing this for information.
ops.suppressDiagnostics();
@@ -2506,7 +2512,7 @@ ExprResult Sema::BuildCXXNew(SourceRange Range, bool UseGlobal,
// because there might not be a `std::align_val_t` type.
EnumDecl *StdAlignValT = getStdAlignValT();
QualType AlignValT =
- StdAlignValT ? Context.getTypeDeclType(StdAlignValT) : SizeTy;
+ StdAlignValT ? Context.getCanonicalTagType(StdAlignValT) : SizeTy;
IntegerLiteral AlignmentLiteral(
Context,
llvm::APInt(Context.getTypeSize(SizeTy),
@@ -2957,7 +2963,7 @@ bool Sema::FindAllocationFunctions(
isTypeAwareAllocation(IAP.PassTypeIdentity);
if (IncludeAlignParam) {
DeclareGlobalNewDelete();
- AlignValT = Context.getTypeDeclType(getStdAlignValT());
+ AlignValT = Context.getCanonicalTagType(getStdAlignValT());
}
CXXScalarValueInitExpr Align(AlignValT, nullptr, SourceLocation());
if (IncludeAlignParam)
@@ -3039,8 +3045,9 @@ bool Sema::FindAllocationFunctions(
LookupResult FoundDelete(*this, DeleteName, StartLoc, LookupOrdinaryName);
if (AllocElemType->isRecordType() &&
DeleteScope != AllocationFunctionScope::Global) {
- auto *RD =
- cast<CXXRecordDecl>(AllocElemType->castAs<RecordType>()->getDecl());
+ auto *RD = cast<CXXRecordDecl>(
+ AllocElemType->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
LookupQualifiedName(FoundDelete, RD);
}
if (FoundDelete.isAmbiguous())
@@ -3417,7 +3424,7 @@ void Sema::DeclareGlobalNewDelete() {
for (int Aligned = 0; Aligned < NumAlignVariants; ++Aligned) {
if (Aligned)
- Params.push_back(Context.getTypeDeclType(getStdAlignValT()));
+ Params.push_back(Context.getCanonicalTagType(getStdAlignValT()));
DeclareGlobalAllocationFunction(
Context.DeclarationNames.getCXXOperatorName(Kind), Return, Params);
@@ -3474,7 +3481,7 @@ void Sema::DeclareGlobalAllocationFunction(DeclarationName Name,
bool HasBadAllocExceptionSpec = Name.isAnyOperatorNew();
if (HasBadAllocExceptionSpec) {
if (!getLangOpts().CPlusPlus11) {
- BadAllocType = Context.getTypeDeclType(getStdBadAlloc());
+ BadAllocType = Context.getCanonicalTagType(getStdBadAlloc());
assert(StdBadAlloc && "Must have std::bad_alloc declared");
EPI.ExceptionSpec.Type = EST_Dynamic;
EPI.ExceptionSpec.Exceptions = llvm::ArrayRef(BadAllocType);
@@ -3584,7 +3591,7 @@ FunctionDecl *Sema::FindDeallocationFunctionForDestructor(SourceLocation Loc,
DeclarationName Name = Context.DeclarationNames.getCXXOperatorName(OO_Delete);
FunctionDecl *OperatorDelete = nullptr;
- QualType DeallocType = Context.getRecordType(RD);
+ CanQualType DeallocType = Context.getCanonicalTagType(RD);
ImplicitDeallocationParameters IDP = {
DeallocType, ShouldUseTypeAwareOperatorNewOrDelete(),
AlignedAllocationMode::No, SizedDeallocationMode::No};
@@ -3618,7 +3625,7 @@ bool Sema::FindDeallocationFunction(SourceLocation StartLoc, CXXRecordDecl *RD,
Found.suppressDiagnostics();
if (!isAlignedAllocation(IDP.PassAlignment) &&
- hasNewExtendedAlignment(*this, Context.getRecordType(RD)))
+ hasNewExtendedAlignment(*this, Context.getCanonicalTagType(RD)))
IDP.PassAlignment = AlignedAllocationMode::Yes;
// C++17 [expr.delete]p10:
@@ -4041,7 +4048,8 @@ Sema::ActOnCXXDelete(SourceLocation StartLoc, bool UseGlobal,
: diag::warn_delete_incomplete,
Ex.get())) {
if (const RecordType *RT = PointeeElem->getAs<RecordType>())
- PointeeRD = cast<CXXRecordDecl>(RT->getDecl());
+ PointeeRD =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
}
}
@@ -4566,7 +4574,7 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
// If the user-defined conversion is specified by a conversion function,
// the initial standard conversion sequence converts the source type to
// the implicit object parameter of the conversion function.
- BeforeToType = Context.getTagDeclType(Conv->getParent());
+ BeforeToType = Context.getCanonicalTagType(Conv->getParent());
} else {
const CXXConstructorDecl *Ctor = cast<CXXConstructorDecl>(FD);
CastKind = CK_ConstructorConversion;
@@ -4810,7 +4818,10 @@ Sema::PerformImplicitConversion(Expr *From, QualType ToType,
if (FromType->isVectorType() || ToType->isVectorType())
StepTy = adjustVectorType(Context, FromType, ToType, &ElTy);
if (ElTy->isBooleanType()) {
- assert(FromType->castAs<EnumType>()->getDecl()->isFixed() &&
+ assert(FromType->castAs<EnumType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->isFixed() &&
SCS.Second == ICK_Integral_Promotion &&
"only enums with fixed underlying type can promote to bool");
From = ImpCastExprToType(From, StepTy, CK_IntegralToBoolean, VK_PRValue,
@@ -5362,16 +5373,18 @@ QualType Sema::CheckPointerToMemberOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
+ // FIXME: use sugared type from member pointer.
+ CanQualType RHSClassType = Context.getCanonicalTagType(RHSClass);
CXXCastPath BasePath;
if (CheckDerivedToBaseConversion(
- LHSType, QualType(RHSClass->getTypeForDecl(), 0), Loc,
+ LHSType, RHSClassType, Loc,
SourceRange(LHS.get()->getBeginLoc(), RHS.get()->getEndLoc()),
&BasePath))
return QualType();
// Cast LHS to type of use.
- QualType UseType = Context.getQualifiedType(RHSClass->getTypeForDecl(),
- LHSType.getQualifiers());
+ QualType UseType =
+ Context.getQualifiedType(RHSClassType, LHSType.getQualifiers());
if (isIndirect)
UseType = Context.getPointerType(UseType);
ExprValueKind VK = isIndirect ? VK_PRValue : LHS.get()->getValueKind();
@@ -6176,7 +6189,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
case Pointer:
return Ctx.getPointerType(T);
case MemberPointer:
- return Ctx.getMemberPointerType(T, /*Qualifier=*/nullptr,
+ return Ctx.getMemberPointerType(T, /*Qualifier=*/std::nullopt,
ClassOrBound->getAsCXXRecordDecl());
case ObjCPointer:
return Ctx.getObjCObjectPointerType(T);
@@ -6349,7 +6362,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
return QualType();
Steps.emplace_back(Step::MemberPointer,
- Context.getTypeDeclType(Cls).getTypePtr());
+ Context.getCanonicalTagType(Cls).getTypePtr());
continue;
}
@@ -6628,7 +6641,8 @@ ExprResult Sema::MaybeBindToTemporary(Expr *E) {
// That should be enough to guarantee that this type is complete, if we're
// not processing a decltype expression.
- CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if (RD->isInvalidDecl() || RD->isDependentContext())
return E;
@@ -7235,16 +7249,13 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
TemplateIdAnnotation *TemplateId = SecondTypeName.TemplateId;
ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
- TypeResult T = ActOnTemplateIdType(S,
- SS,
- TemplateId->TemplateKWLoc,
- TemplateId->Template,
- TemplateId->Name,
- TemplateId->TemplateNameLoc,
- TemplateId->LAngleLoc,
- TemplateArgsPtr,
- TemplateId->RAngleLoc,
- /*IsCtorOrDtorName*/true);
+ TypeResult T = ActOnTemplateIdType(
+ S, ElaboratedTypeKeyword::None,
+ /*ElaboratedKeywordLoc=*/SourceLocation(), SS,
+ TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name,
+ TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr,
+ TemplateId->RAngleLoc,
+ /*IsCtorOrDtorName*/ true);
if (T.isInvalid() || !T.get()) {
// Recover by assuming we had the right type all along.
DestructedType = ObjectType;
@@ -7288,16 +7299,13 @@ ExprResult Sema::ActOnPseudoDestructorExpr(Scope *S, Expr *Base,
TemplateIdAnnotation *TemplateId = FirstTypeName.TemplateId;
ASTTemplateArgsPtr TemplateArgsPtr(TemplateId->getTemplateArgs(),
TemplateId->NumArgs);
- TypeResult T = ActOnTemplateIdType(S,
- SS,
- TemplateId->TemplateKWLoc,
- TemplateId->Template,
- TemplateId->Name,
- TemplateId->TemplateNameLoc,
- TemplateId->LAngleLoc,
- TemplateArgsPtr,
- TemplateId->RAngleLoc,
- /*IsCtorOrDtorName*/true);
+ TypeResult T = ActOnTemplateIdType(
+ S, ElaboratedTypeKeyword::None,
+ /*ElaboratedKeywordLoc=*/SourceLocation(), SS,
+ TemplateId->TemplateKWLoc, TemplateId->Template, TemplateId->Name,
+ TemplateId->TemplateNameLoc, TemplateId->LAngleLoc, TemplateArgsPtr,
+ TemplateId->RAngleLoc,
+ /*IsCtorOrDtorName*/ true);
if (T.isInvalid() || !T.get()) {
// Recover by dropping this type.
ScopeType = QualType();
@@ -7497,7 +7505,7 @@ ExprResult Sema::IgnoredValueConversions(Expr *E) {
// GCC seems to also exclude expressions of incomplete enum type.
if (const EnumType *T = E->getType()->getAs<EnumType>()) {
- if (!T->getDecl()->isComplete()) {
+ if (!T->getOriginalDecl()->getDefinitionOrSelf()->isComplete()) {
// FIXME: stupid workaround for a codegen bug!
E = ImpCastExprToType(E, Context.VoidTy, CK_ToVoid).get();
return E;
diff --git a/clang/lib/Sema/SemaExprMember.cpp b/clang/lib/Sema/SemaExprMember.cpp
index 5dca509d46fdb..4a31a139eaf4f 100644
--- a/clang/lib/Sema/SemaExprMember.cpp
+++ b/clang/lib/Sema/SemaExprMember.cpp
@@ -492,13 +492,14 @@ CheckExtVectorComponent(Sema &S, QualType baseType, ExprValueKind &VK,
QualType VT = S.Context.getExtVectorType(vecType->getElementType(), CompSize);
// Now look up the TypeDefDecl from the vector type. Without this,
- // diagostics look bad. We want extended vector types to appear built-in.
+ // diagnostics look bad. We want extended vector types to appear built-in.
for (Sema::ExtVectorDeclsType::iterator
I = S.ExtVectorDecls.begin(S.getExternalSource()),
E = S.ExtVectorDecls.end();
I != E; ++I) {
if ((*I)->getUnderlyingType() == VT)
- return S.Context.getTypedefType(*I);
+ return S.Context.getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, *I);
}
return VT; // should never get here (a typedef type should always be found).
@@ -881,7 +882,7 @@ Sema::BuildMemberReferenceExpr(Expr *BaseExpr, QualType BaseExprType,
// build a CXXDependentScopeMemberExpr.
if (R.wasNotFoundInCurrentInstantiation() ||
(R.getLookupName().getCXXOverloadedOperator() == OO_Equal &&
- (SS.isSet() ? SS.getScopeRep()->isDependent()
+ (SS.isSet() ? SS.getScopeRep().isDependent()
: BaseExprType->isDependentType())))
return ActOnDependentMemberExpr(BaseExpr, BaseExprType, IsArrow, OpLoc, SS,
TemplateKWLoc, FirstQualifierInScope,
diff --git a/clang/lib/Sema/SemaExprObjC.cpp b/clang/lib/Sema/SemaExprObjC.cpp
index e0662d82914f4..03b5c79cf70e3 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -639,14 +639,14 @@ ExprResult SemaObjC::BuildObjCBoxedExpr(SourceRange SR, Expr *ValueExpr) {
BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ValueType);
BoxedType = NSNumberPointer;
} else if (const EnumType *ET = ValueType->getAs<EnumType>()) {
- if (!ET->getDecl()->isComplete()) {
+ const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isComplete()) {
Diag(Loc, diag::err_objc_incomplete_boxed_expression_type)
<< ValueType << ValueExpr->getSourceRange();
return ExprError();
}
- BoxingMethod = getNSNumberFactoryMethod(*this, Loc,
- ET->getDecl()->getIntegerType());
+ BoxingMethod = getNSNumberFactoryMethod(*this, Loc, ED->getIntegerType());
BoxedType = NSNumberPointer;
} else if (ValueType->isObjCBoxableRecordType()) {
// Support for structure types, that marked as objc_boxable
@@ -2337,10 +2337,10 @@ SemaObjC::getObjCMessageKind(Scope *S, IdentifierInfo *Name,
if (ObjCInterfaceDecl *Class = dyn_cast<ObjCInterfaceDecl>(ND))
T = Context.getObjCInterfaceType(Class);
else if (TypeDecl *Type = dyn_cast<TypeDecl>(ND)) {
- T = Context.getTypeDeclType(Type);
SemaRef.DiagnoseUseOfDecl(Type, NameLoc);
- }
- else
+ T = Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, Type);
+ } else
return ObjCInstanceMessage;
// We have a class message, and T is the type we're
@@ -3847,7 +3847,8 @@ static inline T *getObjCBridgeAttr(const TypedefType *TD) {
if (QT->isPointerType()) {
QT = QT->getPointeeType();
if (const RecordType *RT = QT->getAs<RecordType>()) {
- for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
+ for (auto *Redecl :
+ RT->getOriginalDecl()->getMostRecentDecl()->redecls()) {
if (auto *attr = Redecl->getAttr<T>())
return attr;
}
diff --git a/clang/lib/Sema/SemaFunctionEffects.cpp b/clang/lib/Sema/SemaFunctionEffects.cpp
index 1592862416bf9..8590ee831084f 100644
--- a/clang/lib/Sema/SemaFunctionEffects.cpp
+++ b/clang/lib/Sema/SemaFunctionEffects.cpp
@@ -1352,11 +1352,15 @@ class Analyzer {
return true;
}
- bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node) override {
+ bool TraverseTypeOfExprTypeLoc(TypeOfExprTypeLoc Node,
+ bool TraverseQualifier) override {
return true;
}
- bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node) override { return true; }
+ bool TraverseDecltypeTypeLoc(DecltypeTypeLoc Node,
+ bool TraverseQualifier) override {
+ return true;
+ }
bool TraverseCXXNoexceptExpr(CXXNoexceptExpr *Node) override {
return true;
diff --git a/clang/lib/Sema/SemaHLSL.cpp b/clang/lib/Sema/SemaHLSL.cpp
index 968b96990bd85..7c134d404e143 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -231,7 +231,7 @@ static unsigned calculateLegacyCbufferSize(const ASTContext &Context,
constexpr unsigned CBufferAlign = 16;
if (const RecordType *RT = T->getAs<RecordType>()) {
unsigned Size = 0;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
for (const FieldDecl *Field : RD->fields()) {
QualType Ty = Field->getType();
unsigned FieldSize = calculateLegacyCbufferSize(Context, Ty);
@@ -370,7 +370,7 @@ static bool isInvalidConstantBufferLeafElementType(const Type *Ty) {
// needs to be created for HLSL Buffer use that will exclude these unwanted
// declarations (see createHostLayoutStruct function).
static bool requiresImplicitBufferLayoutStructure(const CXXRecordDecl *RD) {
- if (RD->getTypeForDecl()->isHLSLIntangibleType() || RD->isEmpty())
+ if (RD->isHLSLIntangible() || RD->isEmpty())
return true;
// check fields
for (const FieldDecl *Field : RD->fields()) {
@@ -455,7 +455,7 @@ static FieldDecl *createFieldForHostLayoutStruct(Sema &S, const Type *Ty,
RD = createHostLayoutStruct(S, RD);
if (!RD)
return nullptr;
- Ty = RD->getTypeForDecl();
+ Ty = S.Context.getCanonicalTagType(RD)->getTypePtr();
}
}
@@ -505,8 +505,8 @@ static CXXRecordDecl *createHostLayoutStruct(Sema &S,
if (requiresImplicitBufferLayoutStructure(BaseDecl)) {
BaseDecl = createHostLayoutStruct(S, BaseDecl);
if (BaseDecl) {
- TypeSourceInfo *TSI = AST.getTrivialTypeSourceInfo(
- QualType(BaseDecl->getTypeForDecl(), 0));
+ TypeSourceInfo *TSI =
+ AST.getTrivialTypeSourceInfo(AST.getCanonicalTagType(BaseDecl));
Base = CXXBaseSpecifier(SourceRange(), false, StructDecl->isClass(),
AS_none, TSI, SourceLocation());
}
@@ -1744,7 +1744,7 @@ SemaHLSL::TakeLocForHLSLAttribute(const HLSLAttributedResourceType *RT) {
// requirements and adds them to Bindings
void SemaHLSL::collectResourceBindingsOnUserRecordDecl(const VarDecl *VD,
const RecordType *RT) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
for (FieldDecl *FD : RD->fields()) {
const Type *Ty = FD->getType()->getUnqualifiedDesugaredType();
@@ -3297,7 +3297,7 @@ bool SemaHLSL::ContainsBitField(QualType BaseTy) {
continue;
}
if (const auto *RT = dyn_cast<RecordType>(T)) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isUnion())
continue;
@@ -3813,7 +3813,8 @@ class InitListTransformer {
}
while (!RecordTypes.empty()) {
const RecordType *RT = RecordTypes.pop_back_val();
- for (auto *FD : RT->getDecl()->fields()) {
+ for (auto *FD :
+ RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
DeclAccessPair Found = DeclAccessPair::make(FD, FD->getAccess());
DeclarationNameInfo NameInfo(FD->getDeclName(), E->getBeginLoc());
ExprResult Res = S.BuildFieldReferenceExpr(
@@ -3861,7 +3862,8 @@ class InitListTransformer {
}
while (!RecordTypes.empty()) {
const RecordType *RT = RecordTypes.pop_back_val();
- for (auto *FD : RT->getDecl()->fields()) {
+ for (auto *FD :
+ RT->getOriginalDecl()->getDefinitionOrSelf()->fields()) {
Inits.push_back(generateInitListsImpl(FD->getType()));
}
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 0844cb4d6c3cd..a8bfddbfe4191 100644
--- a/clang/lib/Sema/SemaInit.cpp
+++ b/clang/lib/Sema/SemaInit.cpp
@@ -446,7 +446,6 @@ class InitListChecker {
unsigned ExpectedNumInits);
int numArrayElements(QualType DeclType);
int numStructUnionElements(QualType DeclType);
- static RecordDecl *getRecordDecl(QualType DeclType);
ExprResult PerformEmptyInit(SourceLocation Loc,
const InitializedEntity &Entity);
@@ -776,7 +775,7 @@ void InitListChecker::FillInEmptyInitForField(unsigned Init, FieldDecl *Field,
if (Init >= NumInits || !ILE->getInit(Init)) {
if (const RecordType *RType = ILE->getType()->getAs<RecordType>())
- if (!RType->getDecl()->isUnion())
+ if (!RType->getOriginalDecl()->isUnion())
assert((Init < NumInits || VerifyOnly) &&
"This ILE should have been expanded");
@@ -922,7 +921,7 @@ InitListChecker::FillInEmptyInitializations(const InitializedEntity &Entity,
return;
if (const RecordType *RType = ILE->getType()->getAs<RecordType>()) {
- const RecordDecl *RDecl = RType->getDecl();
+ const RecordDecl *RDecl = RType->getOriginalDecl()->getDefinitionOrSelf();
if (RDecl->isUnion() && ILE->getInitializedFieldInUnion()) {
FillInEmptyInitForField(0, ILE->getInitializedFieldInUnion(), Entity, ILE,
RequiresSecondPass, FillWithNoInit);
@@ -1126,7 +1125,8 @@ int InitListChecker::numArrayElements(QualType DeclType) {
}
int InitListChecker::numStructUnionElements(QualType DeclType) {
- RecordDecl *structDecl = DeclType->castAs<RecordType>()->getDecl();
+ RecordDecl *structDecl =
+ DeclType->castAs<RecordType>()->getOriginalDecl()->getDefinitionOrSelf();
int InitializableMembers = 0;
if (auto *CXXRD = dyn_cast<CXXRecordDecl>(structDecl))
InitializableMembers += CXXRD->getNumBases();
@@ -1139,14 +1139,6 @@ int InitListChecker::numStructUnionElements(QualType DeclType) {
return InitializableMembers - structDecl->hasFlexibleArrayMember();
}
-RecordDecl *InitListChecker::getRecordDecl(QualType DeclType) {
- if (const auto *RT = DeclType->getAs<RecordType>())
- return RT->getDecl();
- if (const auto *Inject = DeclType->getAs<InjectedClassNameType>())
- return Inject->getDecl();
- return nullptr;
-}
-
/// Determine whether Entity is an entity for which it is idiomatic to elide
/// the braces in aggregate initialization.
static bool isIdiomaticBraceElisionEntity(const InitializedEntity &Entity) {
@@ -1163,16 +1155,22 @@ static bool isIdiomaticBraceElisionEntity(const InitializedEntity &Entity) {
// Allows elide brace initialization for aggregates with empty base.
if (Entity.getKind() == InitializedEntity::EK_Base) {
- auto *ParentRD =
- Entity.getParent()->getType()->castAs<RecordType>()->getDecl();
+ auto *ParentRD = Entity.getParent()
+ ->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
CXXRecordDecl *CXXRD = cast<CXXRecordDecl>(ParentRD);
return CXXRD->getNumBases() == 1 && CXXRD->field_empty();
}
// Allow brace elision if the only subobject is a field.
if (Entity.getKind() == InitializedEntity::EK_Member) {
- auto *ParentRD =
- Entity.getParent()->getType()->castAs<RecordType>()->getDecl();
+ auto *ParentRD = Entity.getParent()
+ ->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
if (CXXRecordDecl *CXXRD = dyn_cast<CXXRecordDecl>(ParentRD)) {
if (CXXRD->getNumBases()) {
return false;
@@ -1441,7 +1439,7 @@ void InitListChecker::CheckListElementTypes(const InitializedEntity &Entity,
} else if (DeclType->isVectorType()) {
CheckVectorType(Entity, IList, DeclType, Index,
StructuredList, StructuredIndex);
- } else if (const RecordDecl *RD = getRecordDecl(DeclType)) {
+ } else if (const RecordDecl *RD = DeclType->getAsRecordDecl()) {
auto Bases =
CXXRecordDecl::base_class_const_range(CXXRecordDecl::base_class_const_iterator(),
CXXRecordDecl::base_class_const_iterator());
@@ -2319,7 +2317,7 @@ void InitListChecker::CheckStructUnionTypes(
bool SubobjectIsDesignatorContext, unsigned &Index,
InitListExpr *StructuredList, unsigned &StructuredIndex,
bool TopLevelObject) {
- const RecordDecl *RD = getRecordDecl(DeclType);
+ const RecordDecl *RD = DeclType->getAsRecordDecl();
// If the record is invalid, some of it's members are invalid. To avoid
// confusion, we forgo checking the initializer for the entire record.
@@ -2888,7 +2886,7 @@ InitListChecker::CheckDesignatedInitializer(const InitializedEntity &Entity,
// then the current object (defined below) shall have
// structure or union type and the identifier shall be the
// name of a member of that type.
- RecordDecl *RD = getRecordDecl(CurrentObjectType);
+ RecordDecl *RD = CurrentObjectType->getAsRecordDecl();
if (!RD) {
SourceLocation Loc = D->getDotLoc();
if (Loc.isInvalid())
@@ -4336,8 +4334,8 @@ static bool hasCopyOrMoveCtorParam(ASTContext &Ctx,
QualType ParmT =
Info.Constructor->getParamDecl(0)->getType().getNonReferenceType();
- QualType ClassT =
- Ctx.getRecordType(cast<CXXRecordDecl>(Info.FoundDecl->getDeclContext()));
+ CanQualType ClassT = Ctx.getCanonicalTagType(
+ cast<CXXRecordDecl>(Info.FoundDecl->getDeclContext()));
return Ctx.hasSameUnqualifiedType(ParmT, ClassT);
}
@@ -4536,8 +4534,8 @@ static void TryConstructorInitialization(Sema &S,
const RecordType *DestRecordType = DestType->getAs<RecordType>();
assert(DestRecordType && "Constructor initialization requires record type");
- CXXRecordDecl *DestRecordDecl
- = cast<CXXRecordDecl>(DestRecordType->getDecl());
+ auto *DestRecordDecl = cast<CXXRecordDecl>(DestRecordType->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Build the candidate set directly in the initialization sequence
// structure, so that it will persist if we fail.
@@ -5057,8 +5055,8 @@ static void TryListInitialization(Sema &S,
// the underlying type of T, the program is ill-formed.
auto *ET = DestType->getAs<EnumType>();
if (S.getLangOpts().CPlusPlus17 &&
- Kind.getKind() == InitializationKind::IK_DirectList &&
- ET && ET->getDecl()->isFixed() &&
+ Kind.getKind() == InitializationKind::IK_DirectList && ET &&
+ ET->getOriginalDecl()->getDefinitionOrSelf()->isFixed() &&
!S.Context.hasSameUnqualifiedType(E->getType(), DestType) &&
(E->getType()->isIntegralOrUnscopedEnumerationType() ||
E->getType()->isFloatingType())) {
@@ -5168,7 +5166,8 @@ static OverloadingResult TryRefInitWithConversionFunction(
S.isCompleteType(Kind.getLocation(), T1)) {
// The type we're converting to is a class type. Enumerate its constructors
// to see if there is a suitable conversion.
- CXXRecordDecl *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getDecl());
+ auto *T1RecordDecl = cast<CXXRecordDecl>(T1RecordType->getOriginalDecl())
+ ->getDefinitionOrSelf();
for (NamedDecl *D : S.LookupConstructors(T1RecordDecl)) {
auto Info = getConstructorInfo(D);
@@ -5191,7 +5190,8 @@ static OverloadingResult TryRefInitWithConversionFunction(
}
}
}
- if (T1RecordType && T1RecordType->getDecl()->isInvalidDecl())
+ if (T1RecordType &&
+ T1RecordType->getOriginalDecl()->getDefinitionOrSelf()->isInvalidDecl())
return OR_No_Viable_Function;
const RecordType *T2RecordType = nullptr;
@@ -5199,7 +5199,8 @@ static OverloadingResult TryRefInitWithConversionFunction(
S.isCompleteType(Kind.getLocation(), T2)) {
// The type we're converting from is a class type, enumerate its conversion
// functions.
- CXXRecordDecl *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getDecl());
+ auto *T2RecordDecl = cast<CXXRecordDecl>(T2RecordType->getOriginalDecl())
+ ->getDefinitionOrSelf();
const auto &Conversions = T2RecordDecl->getVisibleConversionFunctions();
for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
@@ -5235,7 +5236,8 @@ static OverloadingResult TryRefInitWithConversionFunction(
}
}
}
- if (T2RecordType && T2RecordType->getDecl()->isInvalidDecl())
+ if (T2RecordType &&
+ T2RecordType->getOriginalDecl()->getDefinitionOrSelf()->isInvalidDecl())
return OR_No_Viable_Function;
SourceLocation DeclLoc = Initializer->getBeginLoc();
@@ -5713,7 +5715,9 @@ static void TryValueInitialization(Sema &S,
T = S.Context.getBaseElementType(T);
if (const RecordType *RT = T->getAs<RecordType>()) {
- if (CXXRecordDecl *ClassDecl = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ if (CXXRecordDecl *ClassDecl =
+ dyn_cast<CXXRecordDecl>(RT->getOriginalDecl())) {
+ ClassDecl = ClassDecl->getDefinitionOrSelf();
bool NeedZeroInitialization = true;
// C++98:
// -- if T is a class type (clause 9) with a user-declared constructor
@@ -5911,7 +5915,8 @@ static void TryOrBuildParenListInitialization(
}
} else if (auto *RT = Entity.getType()->getAs<RecordType>()) {
bool IsUnion = RT->isUnionType();
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ const auto *RD =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if (RD->isInvalidDecl()) {
// Exit early to avoid confusion when processing members.
// We do the same for braced list initialization in
@@ -6099,8 +6104,9 @@ static void TryUserDefinedConversion(Sema &S,
if (const RecordType *DestRecordType = DestType->getAs<RecordType>()) {
// The type we're converting to is a class type. Enumerate its constructors
// to see if there is a suitable conversion.
- CXXRecordDecl *DestRecordDecl
- = cast<CXXRecordDecl>(DestRecordType->getDecl());
+ auto *DestRecordDecl =
+ cast<CXXRecordDecl>(DestRecordType->getOriginalDecl())
+ ->getDefinitionOrSelf();
// Try to complete the type we're converting to.
if (S.isCompleteType(Kind.getLocation(), DestType)) {
@@ -6136,8 +6142,9 @@ static void TryUserDefinedConversion(Sema &S,
// We can only enumerate the conversion functions for a complete type; if
// the type isn't complete, simply skip this step.
if (S.isCompleteType(DeclLoc, SourceType)) {
- CXXRecordDecl *SourceRecordDecl
- = cast<CXXRecordDecl>(SourceRecordType->getDecl());
+ auto *SourceRecordDecl =
+ cast<CXXRecordDecl>(SourceRecordType->getOriginalDecl())
+ ->getDefinitionOrSelf();
const auto &Conversions =
SourceRecordDecl->getVisibleConversionFunctions();
@@ -7170,7 +7177,8 @@ static ExprResult CopyObject(Sema &S,
Expr *CurInitExpr = (Expr *)CurInit.get();
CXXRecordDecl *Class = nullptr;
if (const RecordType *Record = T->getAs<RecordType>())
- Class = cast<CXXRecordDecl>(Record->getDecl());
+ Class =
+ cast<CXXRecordDecl>(Record->getOriginalDecl())->getDefinitionOrSelf();
if (!Class)
return CurInit;
@@ -7325,8 +7333,8 @@ static void CheckCXX98CompatAccessibleCopy(Sema &S,
// Find constructors which would have been considered.
OverloadCandidateSet CandidateSet(Loc, OverloadCandidateSet::CSK_Normal);
- DeclContext::lookup_result Ctors =
- S.LookupConstructors(cast<CXXRecordDecl>(Record->getDecl()));
+ DeclContext::lookup_result Ctors = S.LookupConstructors(
+ cast<CXXRecordDecl>(Record->getOriginalDecl())->getDefinitionOrSelf());
// Perform overload resolution.
OverloadCandidateSet::iterator Best;
@@ -8156,8 +8164,9 @@ ExprResult InitializationSequence::Perform(Sema &S,
// regardless of how we initialized the entity.
QualType T = CurInit.get()->getType();
if (const RecordType *Record = T->getAs<RecordType>()) {
- CXXDestructorDecl *Destructor
- = S.LookupDestructor(cast<CXXRecordDecl>(Record->getDecl()));
+ CXXDestructorDecl *Destructor =
+ S.LookupDestructor(cast<CXXRecordDecl>(Record->getOriginalDecl())
+ ->getDefinitionOrSelf());
S.CheckDestructorAccess(CurInit.get()->getBeginLoc(), Destructor,
S.PDiag(diag::err_access_dtor_temp) << T);
S.MarkFunctionReferenced(CurInit.get()->getBeginLoc(), Destructor);
@@ -8804,8 +8813,8 @@ static void emitBadConversionNotes(Sema &S, const InitializedEntity &entity,
destPointeeType.getQualifiers().compatiblyIncludes(
fromPointeeType.getQualifiers(), S.getASTContext()))
S.Diag(fromDecl->getLocation(), diag::note_forward_class_conversion)
- << S.getASTContext().getTagDeclType(fromDecl)
- << S.getASTContext().getTagDeclType(destDecl);
+ << S.getASTContext().getCanonicalTagType(fromDecl)
+ << S.getASTContext().getCanonicalTagType(destDecl);
}
static void diagnoseListInit(Sema &S, const InitializedEntity &Entity,
@@ -9204,32 +9213,34 @@ bool InitializationSequence::Diagnose(Sema &S,
InheritedFrom = Inherited.getShadowDecl()->getNominatedBaseClass();
if (Entity.getKind() == InitializedEntity::EK_Base) {
S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
- << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0)
- << S.Context.getTypeDeclType(Constructor->getParent())
- << /*base=*/0
- << Entity.getType()
- << InheritedFrom;
-
- RecordDecl *BaseDecl
- = Entity.getBaseSpecifier()->getType()->castAs<RecordType>()
- ->getDecl();
+ << (InheritedFrom ? 2
+ : Constructor->isImplicit() ? 1
+ : 0)
+ << S.Context.getCanonicalTagType(Constructor->getParent())
+ << /*base=*/0 << Entity.getType() << InheritedFrom;
+
+ RecordDecl *BaseDecl = Entity.getBaseSpecifier()
+ ->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf();
S.Diag(BaseDecl->getLocation(), diag::note_previous_decl)
- << S.Context.getTagDeclType(BaseDecl);
+ << S.Context.getCanonicalTagType(BaseDecl);
} else {
S.Diag(Kind.getLocation(), diag::err_missing_default_ctor)
- << (InheritedFrom ? 2 : Constructor->isImplicit() ? 1 : 0)
- << S.Context.getTypeDeclType(Constructor->getParent())
- << /*member=*/1
- << Entity.getName()
- << InheritedFrom;
+ << (InheritedFrom ? 2
+ : Constructor->isImplicit() ? 1
+ : 0)
+ << S.Context.getCanonicalTagType(Constructor->getParent())
+ << /*member=*/1 << Entity.getName() << InheritedFrom;
S.Diag(Entity.getDecl()->getLocation(),
diag::note_member_declared_at);
if (const RecordType *Record
= Entity.getType()->getAs<RecordType>())
- S.Diag(Record->getDecl()->getLocation(),
+ S.Diag(Record->getOriginalDecl()->getLocation(),
diag::note_previous_decl)
- << S.Context.getTagDeclType(Record->getDecl());
+ << S.Context.getCanonicalTagType(Record->getOriginalDecl());
}
break;
}
@@ -9296,11 +9307,11 @@ bool InitializationSequence::Diagnose(Sema &S,
// initialized.
CXXConstructorDecl *Constructor = cast<CXXConstructorDecl>(S.CurContext);
S.Diag(Kind.getLocation(), diag::err_uninitialized_member_in_ctor)
- << (Constructor->getInheritedConstructor() ? 2 :
- Constructor->isImplicit() ? 1 : 0)
- << S.Context.getTypeDeclType(Constructor->getParent())
- << /*const=*/1
- << Entity.getName();
+ << (Constructor->getInheritedConstructor() ? 2
+ : Constructor->isImplicit() ? 1
+ : 0)
+ << S.Context.getCanonicalTagType(Constructor->getParent())
+ << /*const=*/1 << Entity.getName();
S.Diag(Entity.getDecl()->getLocation(), diag::note_previous_decl)
<< Entity.getName();
} else if (const auto *VD = dyn_cast_if_present<VarDecl>(Entity.getDecl());
@@ -10153,7 +10164,7 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
auto *RD = cast<CXXRecordDecl>(Pattern->getTemplatedDecl());
if (!(RD->getDefinition() && RD->isAggregate()))
return;
- QualType Ty = Context.getRecordType(RD);
+ QualType Ty = Context.getCanonicalTagType(RD);
SmallVector<QualType, 8> ElementTypes;
InitListChecker CheckInitList(*this, Entity, ListInit, Ty, ElementTypes);
@@ -10293,8 +10304,8 @@ QualType Sema::DeduceTemplateSpecializationFromInitializer(
case OR_No_Viable_Function: {
CXXRecordDecl *Primary =
cast<ClassTemplateDecl>(Template)->getTemplatedDecl();
- bool Complete =
- isCompleteType(Kind.getLocation(), Context.getTypeDeclType(Primary));
+ bool Complete = isCompleteType(Kind.getLocation(),
+ Context.getCanonicalTagType(Primary));
Candidates.NoteCandidates(
PartialDiagnosticAt(
Kind.getLocation(),
diff --git a/clang/lib/Sema/SemaLambda.cpp b/clang/lib/Sema/SemaLambda.cpp
index 2c00616bc62d7..1f47cd20b0359 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -427,7 +427,7 @@ bool Sema::DiagnoseInvalidExplicitObjectParameterInLambda(
.getNonReferenceType()
.getUnqualifiedType()
.getDesugaredType(getASTContext());
- QualType LambdaType = getASTContext().getRecordType(RD);
+ CanQualType LambdaType = getASTContext().getCanonicalTagType(RD);
if (LambdaType == ExplicitObjectParameterType)
return false;
@@ -459,7 +459,7 @@ bool Sema::DiagnoseInvalidExplicitObjectParameterInLambda(
return true;
}
- if (Paths.isAmbiguous(LambdaType->getCanonicalTypeUnqualified())) {
+ if (Paths.isAmbiguous(LambdaType)) {
std::string PathsDisplay = getAmbiguousPathsDisplayString(Paths);
Diag(CallLoc, diag::err_explicit_object_lambda_ambiguous_base)
<< LambdaType << PathsDisplay;
@@ -644,7 +644,7 @@ static EnumDecl *findEnumForBlockReturn(Expr *E) {
// - it is an expression of that formal enum type.
if (const EnumType *ET = E->getType()->getAs<EnumType>()) {
- return ET->getDecl();
+ return ET->getOriginalDecl()->getDefinitionOrSelf();
}
// Otherwise, nope.
@@ -761,7 +761,7 @@ void Sema::deduceClosureReturnType(CapturingScopeInfo &CSI) {
assert(isa<BlockScopeInfo>(CSI));
const EnumDecl *ED = findCommonEnumForBlockReturns(CSI.Returns);
if (ED) {
- CSI.ReturnType = Context.getTypeDeclType(ED);
+ CSI.ReturnType = Context.getCanonicalTagType(ED);
adjustBlockReturnsToEnum(*this, CSI.Returns, CSI.ReturnType);
return;
}
diff --git a/clang/lib/Sema/SemaLookup.cpp b/clang/lib/Sema/SemaLookup.cpp
index aa7191d2814fe..9299500e430f3 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -562,9 +562,8 @@ void LookupResult::resolveKind() {
// no ambiguity if they all refer to the same type, so unique based on the
// canonical type.
if (const auto *TD = dyn_cast<TypeDecl>(D)) {
- QualType T = getSema().Context.getTypeDeclType(TD);
auto UniqueResult = UniqueTypes.insert(
- std::make_pair(getSema().Context.getCanonicalType(T), I));
+ std::make_pair(getSema().Context.getCanonicalTypeDeclType(TD), I));
if (!UniqueResult.second) {
// The type is not unique.
ExistingI = UniqueResult.first->second;
@@ -716,7 +715,7 @@ static QualType getOpenCLEnumType(Sema &S, llvm::StringRef Name) {
EnumDecl *Decl = Result.getAsSingle<EnumDecl>();
if (!Decl)
return diagOpenCLBuiltinTypeError(S, "enum", Name);
- return S.Context.getEnumType(Decl);
+ return S.Context.getCanonicalTagType(Decl);
}
/// Lookup an OpenCL typedef type.
@@ -729,7 +728,8 @@ static QualType getOpenCLTypedefType(Sema &S, llvm::StringRef Name) {
TypedefNameDecl *Decl = Result.getAsSingle<TypedefNameDecl>();
if (!Decl)
return diagOpenCLBuiltinTypeError(S, "typedef", Name);
- return S.Context.getTypedefType(Decl);
+ return S.Context.getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, Decl);
}
/// Get the QualType instances of the return type and arguments for an OpenCL
@@ -1000,7 +1000,7 @@ static void LookupPredefedObjCSuperType(Sema &Sema, Scope *S) {
Sema.LookupName(Result, S);
if (Result.getResultKind() == LookupResultKind::Found)
if (const TagDecl *TD = Result.getAsSingle<TagDecl>())
- Context.setObjCSuperType(Context.getTagDeclType(TD));
+ Context.setObjCSuperType(Context.getCanonicalTagType(TD));
}
void Sema::LookupNecessaryTypesForBuiltin(Scope *S, unsigned ID) {
@@ -2434,12 +2434,12 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
if (!R.getLookupName())
return false;
+#ifndef NDEBUG
// Make sure that the declaration context is complete.
- assert((!isa<TagDecl>(LookupCtx) ||
- LookupCtx->isDependentContext() ||
- cast<TagDecl>(LookupCtx)->isCompleteDefinition() ||
- cast<TagDecl>(LookupCtx)->isBeingDefined()) &&
- "Declaration context must already be complete!");
+ if (const auto *TD = dyn_cast<TagDecl>(LookupCtx);
+ TD && !TD->isDependentType() && TD->getDefinition() == nullptr)
+ llvm_unreachable("Declaration context must already be complete!");
+#endif
struct QualifiedLookupInScope {
bool oldVal;
@@ -2595,10 +2595,8 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
// C++ [class.member.lookup]p3:
// type declarations (including injected-class-names) are replaced by
// the types they designate
- if (const TypeDecl *TD = dyn_cast<TypeDecl>(ND->getUnderlyingDecl())) {
- QualType T = Context.getTypeDeclType(TD);
- return T.getCanonicalType().getAsOpaquePtr();
- }
+ if (const TypeDecl *TD = dyn_cast<TypeDecl>(ND->getUnderlyingDecl()))
+ return Context.getCanonicalTypeDeclType(TD).getAsOpaquePtr();
return ND->getUnderlyingDecl()->getCanonicalDecl();
}
@@ -2703,12 +2701,10 @@ bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
bool Sema::LookupQualifiedName(LookupResult &R, DeclContext *LookupCtx,
CXXScopeSpec &SS) {
- auto *NNS = SS.getScopeRep();
- if (NNS && NNS->getKind() == NestedNameSpecifier::Super)
- return LookupInSuper(R, NNS->getAsRecordDecl());
- else
-
- return LookupQualifiedName(R, LookupCtx);
+ NestedNameSpecifier Qualifier = SS.getScopeRep();
+ if (Qualifier.getKind() == NestedNameSpecifier::Kind::Super)
+ return LookupInSuper(R, Qualifier.getAsSuper());
+ return LookupQualifiedName(R, LookupCtx);
}
bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
@@ -2730,7 +2726,9 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
IsDependent = !DC && ObjectType->isDependentType();
assert(((!DC && ObjectType->isDependentType()) ||
!ObjectType->isIncompleteType() || !ObjectType->getAs<TagType>() ||
- ObjectType->castAs<TagType>()->isBeingDefined()) &&
+ ObjectType->castAs<TagType>()
+ ->getOriginalDecl()
+ ->isEntityBeingDefined()) &&
"Caller should have completed object type");
} else if (SS && SS->isNotEmpty()) {
// This nested-name-specifier occurs after another nested-name-specifier,
@@ -2743,9 +2741,9 @@ bool Sema::LookupParsedName(LookupResult &R, Scope *S, CXXScopeSpec *SS,
// FIXME: '__super' lookup semantics could be implemented by a
// LookupResult::isSuperLookup flag which skips the initial search of
// the lookup context in LookupQualified.
- if (NestedNameSpecifier *NNS = SS->getScopeRep();
- NNS->getKind() == NestedNameSpecifier::Super)
- return LookupInSuper(R, NNS->getAsRecordDecl());
+ if (NestedNameSpecifier Qualifier = SS->getScopeRep();
+ Qualifier.getKind() == NestedNameSpecifier::Kind::Super)
+ return LookupInSuper(R, Qualifier.getAsSuper());
}
IsDependent = !DC && isDependentScopeSpecifier(*SS);
} else {
@@ -2771,10 +2769,12 @@ bool Sema::LookupInSuper(LookupResult &R, CXXRecordDecl *Class) {
// members of Class itself. That is, the naming class is Class, and the
// access includes the access of the base.
for (const auto &BaseSpec : Class->bases()) {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(
- BaseSpec.getType()->castAs<RecordType>()->getDecl());
+ CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(
+ BaseSpec.getType()->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
LookupResult Result(*this, R.getLookupNameInfo(), R.getLookupKind());
- Result.setBaseObjectType(Context.getRecordType(Class));
+ Result.setBaseObjectType(Context.getCanonicalTagType(Class));
LookupQualifiedName(Result, RD);
// Copy the lookup results into the target, merging the base's access into
@@ -3100,7 +3100,7 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
// Only recurse into base classes for complete types.
if (!Result.S.isCompleteType(Result.InstantiationLoc,
- Result.S.Context.getRecordType(Class)))
+ Result.S.Context.getCanonicalTagType(Class)))
return;
// Add direct and indirect base classes along with their associated
@@ -3122,7 +3122,8 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result,
// the classes and namespaces of known non-dependent arguments.
if (!BaseType)
continue;
- CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getDecl());
+ CXXRecordDecl *BaseDecl = cast<CXXRecordDecl>(BaseType->getOriginalDecl())
+ ->getDefinitionOrSelf();
if (Result.addClassTransitive(BaseDecl)) {
// Find the associated namespace for this base class.
DeclContext *BaseCtx = BaseDecl->getDeclContext();
@@ -3193,8 +3194,10 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
// Its associated namespaces are the innermost enclosing
// namespaces of its associated classes.
case Type::Record: {
+ // FIXME: This should use the original decl.
CXXRecordDecl *Class =
- cast<CXXRecordDecl>(cast<RecordType>(T)->getDecl());
+ cast<CXXRecordDecl>(cast<RecordType>(T)->getOriginalDecl())
+ ->getDefinitionOrSelf();
addAssociatedClassesAndNamespaces(Result, Class);
break;
}
@@ -3204,7 +3207,9 @@ addAssociatedClassesAndNamespaces(AssociatedLookup &Result, QualType Ty) {
// If it is a class member, its associated class is the
// member’s class; else it has no associated class.
case Type::Enum: {
- EnumDecl *Enum = cast<EnumType>(T)->getDecl();
+ // FIXME: This should use the original decl.
+ EnumDecl *Enum =
+ cast<EnumType>(T)->getOriginalDecl()->getDefinitionOrSelf();
DeclContext *Ctx = Enum->getDeclContext();
if (CXXRecordDecl *EnclosingClass = dyn_cast<CXXRecordDecl>(Ctx))
@@ -3437,7 +3442,7 @@ Sema::LookupSpecialMember(CXXRecordDecl *RD, CXXSpecialMemberKind SM,
// Prepare for overload resolution. Here we construct a synthetic argument
// if necessary and make sure that implicit functions are declared.
- CanQualType CanTy = Context.getCanonicalType(Context.getTagDeclType(RD));
+ CanQualType CanTy = Context.getCanonicalTagType(RD);
DeclarationName Name;
Expr *Arg = nullptr;
unsigned NumArgs;
@@ -3644,7 +3649,7 @@ DeclContext::lookup_result Sema::LookupConstructors(CXXRecordDecl *Class) {
});
}
- CanQualType T = Context.getCanonicalType(Context.getTypeDeclType(Class));
+ CanQualType T = Context.getCanonicalTagType(Class);
DeclarationName Name = Context.DeclarationNames.getCXXConstructorName(T);
return Class->lookup(Name);
}
@@ -4259,7 +4264,7 @@ class LookupVisibleHelper {
const auto *Record = BaseType->getAs<RecordType>();
if (!Record)
continue;
- RD = Record->getDecl();
+ RD = Record->getOriginalDecl()->getDefinitionOrSelf();
}
// FIXME: It would be nice to be able to determine whether referencing
@@ -4545,41 +4550,101 @@ static void checkCorrectionVisibility(Sema &SemaRef, TypoCorrection &TC) {
// the given NestedNameSpecifier (i.e. given a NestedNameSpecifier "foo::bar::",
// fill the vector with the IdentifierInfo pointers for "foo" and "bar").
static void getNestedNameSpecifierIdentifiers(
- NestedNameSpecifier *NNS,
- SmallVectorImpl<const IdentifierInfo*> &Identifiers) {
- if (NestedNameSpecifier *Prefix = NNS->getPrefix())
- getNestedNameSpecifierIdentifiers(Prefix, Identifiers);
- else
+ NestedNameSpecifier NNS,
+ SmallVectorImpl<const IdentifierInfo *> &Identifiers) {
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
Identifiers.clear();
+ return;
- const IdentifierInfo *II = nullptr;
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- II = NNS->getAsIdentifier();
- break;
-
- case NestedNameSpecifier::Namespace:
- if (NNS->getAsNamespace()->isAnonymousNamespace())
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = NNS.getAsNamespaceAndPrefix();
+ getNestedNameSpecifierIdentifiers(Prefix, Identifiers);
+ if (const auto *NS = dyn_cast<NamespaceDecl>(Namespace);
+ NS && NS->isAnonymousNamespace())
return;
- II = NNS->getAsNamespace()->getIdentifier();
- break;
-
- case NestedNameSpecifier::NamespaceAlias:
- II = NNS->getAsNamespaceAlias()->getIdentifier();
- break;
+ Identifiers.push_back(Namespace->getIdentifier());
+ return;
+ }
- case NestedNameSpecifier::TypeSpec:
- II = QualType(NNS->getAsType(), 0).getBaseTypeIdentifier();
+ case NestedNameSpecifier::Kind::Type: {
+ for (const Type *T = NNS.getAsType(); /**/; /**/) {
+ switch (T->getTypeClass()) {
+ case Type::DependentName: {
+ auto *DT = cast<DependentNameType>(T);
+ getNestedNameSpecifierIdentifiers(DT->getQualifier(), Identifiers);
+ Identifiers.push_back(DT->getIdentifier());
+ return;
+ }
+ case Type::TemplateSpecialization: {
+ TemplateName Name =
+ cast<TemplateSpecializationType>(T)->getTemplateName();
+ if (const QualifiedTemplateName *QTN =
+ Name.getAsAdjustedQualifiedTemplateName()) {
+ getNestedNameSpecifierIdentifiers(QTN->getQualifier(), Identifiers);
+ Name = QTN->getUnderlyingTemplate();
+ }
+ if (const auto *TD = Name.getAsTemplateDecl(/*IgnoreDeduced=*/true))
+ Identifiers.push_back(TD->getIdentifier());
+ return;
+ }
+ case Type::DependentTemplateSpecialization: {
+ const DependentTemplateStorage &S =
+ cast<DependentTemplateSpecializationType>(T)
+ ->getDependentTemplateName();
+ getNestedNameSpecifierIdentifiers(S.getQualifier(), Identifiers);
+ // FIXME: Should this dig into the Name as well?
+ // Identifiers.push_back(S.getName().getIdentifier());
+ return;
+ }
+ case Type::SubstTemplateTypeParm:
+ T = cast<SubstTemplateTypeParmType>(T)
+ ->getReplacementType()
+ .getTypePtr();
+ continue;
+ case Type::TemplateTypeParm:
+ Identifiers.push_back(cast<TemplateTypeParmType>(T)->getIdentifier());
+ return;
+ case Type::Decltype:
+ return;
+ case Type::Enum:
+ case Type::Record:
+ case Type::InjectedClassName: {
+ auto *TT = cast<TagType>(T);
+ getNestedNameSpecifierIdentifiers(TT->getQualifier(), Identifiers);
+ Identifiers.push_back(TT->getOriginalDecl()->getIdentifier());
+ return;
+ }
+ case Type::Typedef: {
+ auto *TT = cast<TypedefType>(T);
+ getNestedNameSpecifierIdentifiers(TT->getQualifier(), Identifiers);
+ Identifiers.push_back(TT->getDecl()->getIdentifier());
+ return;
+ }
+ case Type::Using: {
+ auto *TT = cast<UsingType>(T);
+ getNestedNameSpecifierIdentifiers(TT->getQualifier(), Identifiers);
+ Identifiers.push_back(TT->getDecl()->getIdentifier());
+ return;
+ }
+ case Type::UnresolvedUsing: {
+ auto *TT = cast<UnresolvedUsingType>(T);
+ getNestedNameSpecifierIdentifiers(TT->getQualifier(), Identifiers);
+ Identifiers.push_back(TT->getDecl()->getIdentifier());
+ return;
+ }
+ default:
+ Identifiers.push_back(QualType(T, 0).getBaseTypeIdentifier());
+ return;
+ }
+ }
break;
+ }
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
return;
}
-
- if (II)
- Identifiers.push_back(II);
}
void TypoCorrectionConsumer::FoundDecl(NamedDecl *ND, NamedDecl *Hiding,
@@ -4612,11 +4677,11 @@ void TypoCorrectionConsumer::FoundName(StringRef Name) {
void TypoCorrectionConsumer::addKeywordResult(StringRef Keyword) {
// Compute the edit distance between the typo and this keyword,
// and add the keyword to the list of results.
- addName(Keyword, nullptr, nullptr, true);
+ addName(Keyword, /*ND=*/nullptr, /*NNS=*/std::nullopt, /*isKeyword=*/true);
}
void TypoCorrectionConsumer::addName(StringRef Name, NamedDecl *ND,
- NestedNameSpecifier *NNS, bool isKeyword) {
+ NestedNameSpecifier NNS, bool isKeyword) {
// Use a simple length-based heuristic to determine the minimum possible
// edit distance. If the minimum isn't good enough, bail out early.
StringRef TypoStr = Typo->getName();
@@ -4708,10 +4773,10 @@ void TypoCorrectionConsumer::addNamespaces(
Namespaces.addNameSpecifier(KNPair.first);
bool SSIsTemplate = false;
- if (NestedNameSpecifier *NNS =
- (SS && SS->isValid()) ? SS->getScopeRep() : nullptr) {
- if (const Type *T = NNS->getAsType())
- SSIsTemplate = T->getTypeClass() == Type::TemplateSpecialization;
+ if (NestedNameSpecifier NNS = (SS ? SS->getScopeRep() : std::nullopt)) {
+ if (NNS.getKind() == NestedNameSpecifier::Kind::Type)
+ SSIsTemplate =
+ NNS.getAsType()->getTypeClass() == Type::TemplateSpecialization;
}
// Do not transform this into an iterator-based loop. The loop body can
// trigger the creation of further types (through lazy deserialization) and
@@ -4813,17 +4878,15 @@ void TypoCorrectionConsumer::performQualifiedLookups() {
for (const TypoCorrection &QR : QualifiedResults) {
for (const auto &NSI : Namespaces) {
DeclContext *Ctx = NSI.DeclCtx;
- const Type *NSType = NSI.NameSpecifier->getAsType();
+ CXXRecordDecl *NamingClass = NSI.NameSpecifier.getAsRecordDecl();
// If the current NestedNameSpecifier refers to a class and the
// current correction candidate is the name of that class, then skip
// it as it is unlikely a qualified version of the class' constructor
// is an appropriate correction.
- if (CXXRecordDecl *NSDecl = NSType ? NSType->getAsCXXRecordDecl() :
- nullptr) {
- if (NSDecl->getIdentifier() == QR.getCorrectionAsIdentifierInfo())
- continue;
- }
+ if (NamingClass &&
+ NamingClass->getIdentifier() == QR.getCorrectionAsIdentifierInfo())
+ continue;
TypoCorrection TC(QR);
TC.ClearCorrectionDecls();
@@ -4853,7 +4916,7 @@ void TypoCorrectionConsumer::performQualifiedLookups() {
std::string NewQualified = TC.getAsString(SemaRef.getLangOpts());
std::string OldQualified;
llvm::raw_string_ostream OldOStream(OldQualified);
- SS->getScopeRep()->print(OldOStream, SemaRef.getPrintingPolicy());
+ SS->getScopeRep().print(OldOStream, SemaRef.getPrintingPolicy());
OldOStream << Typo->getName();
// If correction candidate would be an identical written qualified
// identifier, then the existing CXXScopeSpec probably included a
@@ -4864,8 +4927,7 @@ void TypoCorrectionConsumer::performQualifiedLookups() {
for (LookupResult::iterator TRD = Result.begin(), TRDEnd = Result.end();
TRD != TRDEnd; ++TRD) {
if (SemaRef.CheckMemberAccess(TC.getCorrectionRange().getBegin(),
- NSType ? NSType->getAsCXXRecordDecl()
- : nullptr,
+ NamingClass,
TRD.getPair()) == Sema::AR_accessible)
TC.addCorrectionDecl(*TRD);
}
@@ -4889,10 +4951,10 @@ void TypoCorrectionConsumer::performQualifiedLookups() {
TypoCorrectionConsumer::NamespaceSpecifierSet::NamespaceSpecifierSet(
ASTContext &Context, DeclContext *CurContext, CXXScopeSpec *CurScopeSpec)
: Context(Context), CurContextChain(buildContextChain(CurContext)) {
- if (NestedNameSpecifier *NNS =
- CurScopeSpec ? CurScopeSpec->getScopeRep() : nullptr) {
+ if (NestedNameSpecifier NNS =
+ CurScopeSpec ? CurScopeSpec->getScopeRep() : std::nullopt) {
llvm::raw_string_ostream SpecifierOStream(CurNameSpecifier);
- NNS->print(SpecifierOStream, Context.getPrintingPolicy());
+ NNS.print(SpecifierOStream, Context.getPrintingPolicy());
getNestedNameSpecifierIdentifiers(NNS, CurNameSpecifierIdentifiers);
}
@@ -4906,7 +4968,7 @@ TypoCorrectionConsumer::NamespaceSpecifierSet::NamespaceSpecifierSet(
// Add the global context as a NestedNameSpecifier
SpecifierInfo SI = {cast<DeclContext>(Context.getTranslationUnitDecl()),
- NestedNameSpecifier::GlobalSpecifier(Context), 1};
+ NestedNameSpecifier::getGlobal(), 1};
DistanceMap[1].push_back(SI);
}
@@ -4926,14 +4988,16 @@ auto TypoCorrectionConsumer::NamespaceSpecifierSet::buildContextChain(
unsigned
TypoCorrectionConsumer::NamespaceSpecifierSet::buildNestedNameSpecifier(
- DeclContextList &DeclChain, NestedNameSpecifier *&NNS) {
+ DeclContextList &DeclChain, NestedNameSpecifier &NNS) {
unsigned NumSpecifiers = 0;
for (DeclContext *C : llvm::reverse(DeclChain)) {
if (auto *ND = dyn_cast_or_null<NamespaceDecl>(C)) {
- NNS = NestedNameSpecifier::Create(Context, NNS, ND);
+ NNS = NestedNameSpecifier(Context, ND, NNS);
++NumSpecifiers;
} else if (auto *RD = dyn_cast_or_null<RecordDecl>(C)) {
- NNS = NestedNameSpecifier::Create(Context, NNS, RD->getTypeForDecl());
+ QualType T = Context.getTagType(ElaboratedTypeKeyword::None, NNS, RD,
+ /*OwnsTag=*/false);
+ NNS = NestedNameSpecifier(T.getTypePtr());
++NumSpecifiers;
}
}
@@ -4942,7 +5006,7 @@ TypoCorrectionConsumer::NamespaceSpecifierSet::buildNestedNameSpecifier(
void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(
DeclContext *Ctx) {
- NestedNameSpecifier *NNS = nullptr;
+ NestedNameSpecifier NNS = std::nullopt;
unsigned NumSpecifiers = 0;
DeclContextList NamespaceDeclChain(buildContextChain(Ctx));
DeclContextList FullNamespaceDeclChain(NamespaceDeclChain);
@@ -4960,7 +5024,7 @@ void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(
// Add an explicit leading '::' specifier if needed.
if (NamespaceDeclChain.empty()) {
// Rebuild the NestedNameSpecifier as a globally-qualified specifier.
- NNS = NestedNameSpecifier::GlobalSpecifier(Context);
+ NNS = NestedNameSpecifier::getGlobal();
NumSpecifiers =
buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
} else if (NamedDecl *ND =
@@ -4972,12 +5036,12 @@ void TypoCorrectionConsumer::NamespaceSpecifierSet::addNameSpecifier(
llvm::raw_string_ostream SpecifierOStream(NewNameSpecifier);
SmallVector<const IdentifierInfo *, 4> NewNameSpecifierIdentifiers;
getNestedNameSpecifierIdentifiers(NNS, NewNameSpecifierIdentifiers);
- NNS->print(SpecifierOStream, Context.getPrintingPolicy());
+ NNS.print(SpecifierOStream, Context.getPrintingPolicy());
SameNameSpecifier = NewNameSpecifier == CurNameSpecifier;
}
if (SameNameSpecifier || llvm::is_contained(CurContextIdentifiers, Name)) {
// Rebuild the NestedNameSpecifier as a globally-qualified specifier.
- NNS = NestedNameSpecifier::GlobalSpecifier(Context);
+ NNS = NestedNameSpecifier::getGlobal();
NumSpecifiers =
buildNestedNameSpecifier(FullNamespaceDeclChain, NNS);
}
@@ -5463,7 +5527,7 @@ std::string TypoCorrection::getAsString(const LangOptions &LO) const {
if (CorrectionNameSpec) {
std::string tmpBuffer;
llvm::raw_string_ostream PrefixOStream(tmpBuffer);
- CorrectionNameSpec->print(PrefixOStream, PrintingPolicy(LO));
+ CorrectionNameSpec.print(PrefixOStream, PrintingPolicy(LO));
PrefixOStream << CorrectionName;
return PrefixOStream.str();
}
diff --git a/clang/lib/Sema/SemaObjC.cpp b/clang/lib/Sema/SemaObjC.cpp
index 0f39a9817ce7f..27951c9105411 100644
--- a/clang/lib/Sema/SemaObjC.cpp
+++ b/clang/lib/Sema/SemaObjC.cpp
@@ -1407,7 +1407,8 @@ SemaObjC::ObjCSubscriptKind SemaObjC::CheckSubscriptingKind(Expr *FromE) {
int NoIntegrals = 0, NoObjCIdPointers = 0;
SmallVector<CXXConversionDecl *, 4> ConversionDecls;
- for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getDecl())
+ for (NamedDecl *D : cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
+ ->getDefinitionOrSelf()
->getVisibleConversionFunctions()) {
if (CXXConversionDecl *Conversion =
dyn_cast<CXXConversionDecl>(D->getUnderlyingDecl())) {
@@ -1510,7 +1511,7 @@ bool SemaObjC::isCFStringType(QualType T) {
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl();
if (RD->getTagKind() != TagTypeKind::Struct)
return false;
diff --git a/clang/lib/Sema/SemaObjCProperty.cpp b/clang/lib/Sema/SemaObjCProperty.cpp
index 9d5106805892a..3dbce070e0e18 100644
--- a/clang/lib/Sema/SemaObjCProperty.cpp
+++ b/clang/lib/Sema/SemaObjCProperty.cpp
@@ -1312,7 +1312,9 @@ Decl *SemaObjC::ActOnPropertyImplDecl(
}
if (!CompleteTypeErr) {
const RecordType *RecordTy = PropertyIvarType->getAs<RecordType>();
- if (RecordTy && RecordTy->getDecl()->hasFlexibleArrayMember()) {
+ if (RecordTy && RecordTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember()) {
Diag(PropertyIvarLoc, diag::err_synthesize_variable_sized_ivar)
<< PropertyIvarType;
CompleteTypeErr = true; // suppress later diagnostics about the ivar
diff --git a/clang/lib/Sema/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index a30acbe9a4bca..d3cd86e86f992 100644
--- a/clang/lib/Sema/SemaOpenMP.cpp
+++ b/clang/lib/Sema/SemaOpenMP.cpp
@@ -7358,7 +7358,9 @@ SemaOpenMP::checkOpenMPDeclareVariantFunction(SemaOpenMP::DeclGroupPtrTy DG,
Diag(SR.getBegin(), diag::err_omp_interop_type_not_found) << SR;
return std::nullopt;
}
- QualType InteropType = Context.getTypeDeclType(TD);
+ QualType InteropType =
+ Context.getTypeDeclType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD);
if (PTy->isVariadic()) {
Diag(FD->getLocation(), diag::err_omp_append_args_with_varargs) << SR;
return std::nullopt;
@@ -7378,7 +7380,7 @@ SemaOpenMP::checkOpenMPDeclareVariantFunction(SemaOpenMP::DeclGroupPtrTy DG,
auto *Method = dyn_cast<CXXMethodDecl>(FD);
if (Method && !Method->isStatic()) {
FnPtrType = Context.getMemberPointerType(
- AdjustedFnType, /*Qualifier=*/nullptr, Method->getParent());
+ AdjustedFnType, /*Qualifier=*/std::nullopt, Method->getParent());
ExprResult ER;
{
// Build addr_of unary op to correctly handle type checks for member
@@ -18612,10 +18614,11 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
if (const auto *TyRec = Ty->getAs<RecordType>()) {
// Complete the type if it can be completed.
// If the type is neither complete nor being defined, bail out now.
- if (SemaRef.isCompleteType(Loc, Ty) || TyRec->isBeingDefined() ||
- TyRec->getDecl()->getDefinition()) {
+ bool IsComplete = SemaRef.isCompleteType(Loc, Ty);
+ RecordDecl *RD = TyRec->getOriginalDecl()->getDefinition();
+ if (IsComplete || RD) {
Lookup.clear();
- SemaRef.LookupQualifiedName(Lookup, TyRec->getDecl());
+ SemaRef.LookupQualifiedName(Lookup, RD);
if (Lookup.empty()) {
Lookups.emplace_back();
Lookups.back().append(Lookup.begin(), Lookup.end());
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 34f512b13d6a8..180071828a5be 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -370,7 +370,7 @@ NarrowingKind StandardConversionSequence::getNarrowingKind(
// the underlying type is narrowing. This only arises for expressions of
// the form 'Enum{init}'.
if (auto *ET = ToType->getAs<EnumType>())
- ToType = ET->getDecl()->getIntegerType();
+ ToType = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
switch (Second) {
// 'bool' is an integral type; dispatch to the right place to handle it.
@@ -1063,7 +1063,8 @@ static bool shouldAddReversedEqEq(Sema &S, SourceLocation OpLoc,
return true;
LookupResult Members(S, NotEqOp, OpLoc,
Sema::LookupNameKind::LookupMemberName);
- S.LookupQualifiedName(Members, RHSRec->getDecl());
+ S.LookupQualifiedName(Members,
+ RHSRec->getOriginalDecl()->getDefinitionOrSelf());
Members.suppressAccessDiagnostics();
for (NamedDecl *Op : Members)
if (FunctionsCorrespond(S.Context, EqFD, Op->getAsFunction()))
@@ -1268,7 +1269,7 @@ OverloadKind Sema::CheckOverload(Scope *S, FunctionDecl *New,
//
// Exception: if the scope is dependent and this is not a class
// member, the using declaration can only introduce an enumerator.
- if (UUD->getQualifier()->isDependent() && !UUD->isCXXClassMember()) {
+ if (UUD->getQualifier().isDependent() && !UUD->isCXXClassMember()) {
Match = *I;
return OverloadKind::NonFunction;
}
@@ -1471,9 +1472,8 @@ static bool IsOverloadOrOverrideImpl(Sema &SemaRef, FunctionDecl *New,
if (OldMethod->isImplicitObjectMemberFunction() &&
OldMethod->getParent() != NewMethod->getParent()) {
- QualType ParentType =
- SemaRef.Context.getTypeDeclType(OldMethod->getParent())
- .getCanonicalType();
+ CanQualType ParentType =
+ SemaRef.Context.getCanonicalTagType(OldMethod->getParent());
if (ParentType.getTypePtr() != BS.Ty)
return false;
BS.Ty = DS.Ty;
@@ -2293,7 +2293,7 @@ static bool IsStandardConversion(Sema &S, Expr* From, QualType ToType,
== UO_AddrOf &&
"Non-address-of operator on non-static member address");
FromType = S.Context.getMemberPointerType(
- FromType, /*Qualifier=*/nullptr, Method->getParent());
+ FromType, /*Qualifier=*/std::nullopt, Method->getParent());
} else if (isa<UnaryOperator>(From->IgnoreParens())) {
assert(cast<UnaryOperator>(From->IgnoreParens())->getOpcode() ==
UO_AddrOf &&
@@ -2602,10 +2602,12 @@ IsTransparentUnionStandardConversion(Sema &S, Expr* From,
bool CStyle) {
const RecordType *UT = ToType->getAsUnionType();
- if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
+ if (!UT)
return false;
// The field to initialize within the transparent union.
- RecordDecl *UD = UT->getDecl();
+ const RecordDecl *UD = UT->getOriginalDecl()->getDefinitionOrSelf();
+ if (!UD->hasAttr<TransparentUnionAttr>())
+ return false;
// It's compatible if the expression matches any of the fields.
for (const auto *it : UD->fields()) {
if (IsStandardConversion(S, From, it->getType(), InOverloadResolution, SCS,
@@ -2663,15 +2665,17 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
if (const EnumType *FromEnumType = FromType->getAs<EnumType>()) {
// C++0x 7.2p9: Note that this implicit enum to int conversion is not
// provided for a scoped enumeration.
- if (FromEnumType->getDecl()->isScoped())
+ const EnumDecl *FromED =
+ FromEnumType->getOriginalDecl()->getDefinitionOrSelf();
+ if (FromED->isScoped())
return false;
// We can perform an integral promotion to the underlying type of the enum,
// even if that's not the promoted type. Note that the check for promoting
// the underlying type is based on the type alone, and does not consider
// the bitfield-ness of the actual source expression.
- if (FromEnumType->getDecl()->isFixed()) {
- QualType Underlying = FromEnumType->getDecl()->getIntegerType();
+ if (FromED->isFixed()) {
+ QualType Underlying = FromED->getIntegerType();
return Context.hasSameUnqualifiedType(Underlying, ToType) ||
IsIntegralPromotion(nullptr, Underlying, ToType);
}
@@ -2679,8 +2683,7 @@ bool Sema::IsIntegralPromotion(Expr *From, QualType FromType, QualType ToType) {
// We have already pre-calculated the promotion type, so this is trivial.
if (ToType->isIntegerType() &&
isCompleteType(From->getBeginLoc(), FromType))
- return Context.hasSameUnqualifiedType(
- ToType, FromEnumType->getDecl()->getPromotionType());
+ return Context.hasSameUnqualifiedType(ToType, FromED->getPromotionType());
// C++ [conv.prom]p5:
// If the bit-field has an enumerated type, it is treated as any other
@@ -3347,12 +3350,12 @@ void Sema::HandleFunctionTypeMismatch(PartialDiagnostic &PDiag,
ToMember->getMostRecentCXXRecordDecl())) {
PDiag << ft_different_class;
if (ToMember->isSugared())
- PDiag << Context.getTypeDeclType(
+ PDiag << Context.getCanonicalTagType(
ToMember->getMostRecentCXXRecordDecl());
else
PDiag << ToMember->getQualifier();
if (FromMember->isSugared())
- PDiag << Context.getTypeDeclType(
+ PDiag << Context.getCanonicalTagType(
FromMember->getMostRecentCXXRecordDecl());
else
PDiag << FromMember->getQualifier();
@@ -3636,12 +3639,12 @@ Sema::MemberPointerConversionResult Sema::CheckMemberPointerConversion(
CXXRecordDecl *FromClass = FromPtrType->getMostRecentCXXRecordDecl(),
*ToClass = ToPtrType->getMostRecentCXXRecordDecl();
- auto DiagCls = [](PartialDiagnostic &PD, NestedNameSpecifier *Qual,
- const CXXRecordDecl *Cls) {
- if (declaresSameEntity(Qual->getAsRecordDecl(), Cls))
+ auto DiagCls = [&](PartialDiagnostic &PD, NestedNameSpecifier Qual,
+ const CXXRecordDecl *Cls) {
+ if (declaresSameEntity(Qual.getAsRecordDecl(), Cls))
PD << Qual;
else
- PD << QualType(Cls->getTypeForDecl(), 0);
+ PD << Context.getCanonicalTagType(Cls);
};
auto DiagFromTo = [&](PartialDiagnostic &PD) -> PartialDiagnostic & {
DiagCls(PD, FromPtrType->getQualifier(), FromClass);
@@ -3658,8 +3661,7 @@ Sema::MemberPointerConversionResult Sema::CheckMemberPointerConversion(
if (!IsDerivedFrom(OpRange.getBegin(), Derived, Base, Paths))
return MemberPointerConversionResult::NotDerived;
- if (Paths.isAmbiguous(
- Base->getTypeForDecl()->getCanonicalTypeUnqualified())) {
+ if (Paths.isAmbiguous(Context.getCanonicalTagType(Base))) {
PartialDiagnostic PD = PDiag(diag::err_ambiguous_memptr_conv);
PD << int(Direction);
DiagFromTo(PD) << getAmbiguousPathsDisplayString(Paths) << OpRange;
@@ -3687,8 +3689,8 @@ Sema::MemberPointerConversionResult Sema::CheckMemberPointerConversion(
? diag::err_upcast_to_inaccessible_base
: diag::err_downcast_from_inaccessible_base,
[&](PartialDiagnostic &PD) {
- NestedNameSpecifier *BaseQual = FromPtrType->getQualifier(),
- *DerivedQual = ToPtrType->getQualifier();
+ NestedNameSpecifier BaseQual = FromPtrType->getQualifier(),
+ DerivedQual = ToPtrType->getQualifier();
if (Direction == MemberPointerConversionDirection::Upcast)
std::swap(BaseQual, DerivedQual);
DiagCls(PD, DerivedQual, Derived);
@@ -3983,8 +3985,9 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
if (!S.isCompleteType(From->getExprLoc(), ToType)) {
// We're not going to find any constructors.
- } else if (CXXRecordDecl *ToRecordDecl
- = dyn_cast<CXXRecordDecl>(ToRecordType->getDecl())) {
+ } else if (auto *ToRecordDecl =
+ dyn_cast<CXXRecordDecl>(ToRecordType->getOriginalDecl())) {
+ ToRecordDecl = ToRecordDecl->getDefinitionOrSelf();
Expr **Args = &From;
unsigned NumArgs = 1;
@@ -4057,8 +4060,9 @@ IsUserDefinedConversion(Sema &S, Expr *From, QualType ToType,
// No conversion functions from incomplete types.
} else if (const RecordType *FromRecordType =
From->getType()->getAs<RecordType>()) {
- if (CXXRecordDecl *FromRecordDecl
- = dyn_cast<CXXRecordDecl>(FromRecordType->getDecl())) {
+ if (auto *FromRecordDecl =
+ dyn_cast<CXXRecordDecl>(FromRecordType->getOriginalDecl())) {
+ FromRecordDecl = FromRecordDecl->getDefinitionOrSelf();
// Add all of the conversion functions as candidates.
const auto &Conversions = FromRecordDecl->getVisibleConversionFunctions();
for (auto I = Conversions.begin(), E = Conversions.end(); I != E; ++I) {
@@ -4509,7 +4513,8 @@ getFixedEnumPromtion(Sema &S, const StandardConversionSequence &SCS) {
if (!FromType->isEnumeralType())
return FixedEnumPromotion::None;
- EnumDecl *Enum = FromType->castAs<EnumType>()->getDecl();
+ EnumDecl *Enum =
+ FromType->castAs<EnumType>()->getOriginalDecl()->getDefinitionOrSelf();
if (!Enum->isFixed())
return FixedEnumPromotion::None;
@@ -5145,7 +5150,9 @@ FindConversionForRefInit(Sema &S, ImplicitConversionSequence &ICS,
Expr *Init, QualType T2, bool AllowRvalues,
bool AllowExplicit) {
assert(T2->isRecordType() && "Can only find conversions of record types.");
- auto *T2RecordDecl = cast<CXXRecordDecl>(T2->castAs<RecordType>()->getDecl());
+ auto *T2RecordDecl =
+ cast<CXXRecordDecl>(T2->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
OverloadCandidateSet CandidateSet(
DeclLoc, OverloadCandidateSet::CSK_InitByUserDefinedConversion);
@@ -5934,7 +5941,7 @@ static ImplicitConversionSequence TryObjectArgumentInitialization(
assert(FromType->isRecordType());
- QualType ClassType = S.Context.getTypeDeclType(ActingContext);
+ CanQualType ClassType = S.Context.getCanonicalTagType(ActingContext);
// C++98 [class.dtor]p2:
// A destructor can be invoked for a const, volatile or const volatile
// object.
@@ -6055,7 +6062,7 @@ static ImplicitConversionSequence TryObjectArgumentInitialization(
/// the implicit object parameter for the given Method with the given
/// expression.
ExprResult Sema::PerformImplicitObjectArgumentInitialization(
- Expr *From, NestedNameSpecifier *Qualifier, NamedDecl *FoundDecl,
+ Expr *From, NestedNameSpecifier Qualifier, NamedDecl *FoundDecl,
CXXMethodDecl *Method) {
QualType FromRecordType, DestType;
QualType ImplicitParamRecordType = Method->getFunctionObjectParameterType();
@@ -6840,8 +6847,9 @@ ExprResult Sema::PerformContextualImplicitConversion(
UnresolvedSet<4>
ViableConversions; // These are *potentially* viable in C++1y.
UnresolvedSet<4> ExplicitConversions;
- const auto &Conversions =
- cast<CXXRecordDecl>(RecordTy->getDecl())->getVisibleConversionFunctions();
+ const auto &Conversions = cast<CXXRecordDecl>(RecordTy->getOriginalDecl())
+ ->getDefinitionOrSelf()
+ ->getVisibleConversionFunctions();
bool HadMultipleCandidates =
(std::distance(Conversions.begin(), Conversions.end()) > 1);
@@ -7160,7 +7168,8 @@ void Sema::AddOverloadCandidate(
// C++ [class.copy]p3:
// A member function template is never instantiated to perform the copy
// of a class object to an object of its class type.
- QualType ClassType = Context.getTypeDeclType(Constructor->getParent());
+ CanQualType ClassType =
+ Context.getCanonicalTagType(Constructor->getParent());
if (Args.size() == 1 && Constructor->isSpecializationCopyingObject() &&
(Context.hasSameUnqualifiedType(ClassType, Args[0]->getType()) ||
IsDerivedFrom(Args[0]->getBeginLoc(), Args[0]->getType(),
@@ -7181,8 +7190,8 @@ void Sema::AddOverloadCandidate(
if (Shadow && Args.size() == 1 && Constructor->getNumParams() >= 1 &&
Constructor->getParamDecl(0)->getType()->isReferenceType()) {
QualType P = Constructor->getParamDecl(0)->getType()->getPointeeType();
- QualType C = Context.getRecordType(Constructor->getParent());
- QualType D = Context.getRecordType(Shadow->getParent());
+ CanQualType C = Context.getCanonicalTagType(Constructor->getParent());
+ CanQualType D = Context.getCanonicalTagType(Shadow->getParent());
SourceLocation Loc = Args.front()->getExprLoc();
if ((Context.hasSameUnqualifiedType(P, C) || IsDerivedFrom(Loc, P, C)) &&
(Context.hasSameUnqualifiedType(D, P) || IsDerivedFrom(Loc, D, P))) {
@@ -7403,7 +7412,7 @@ static bool convertArgsForAvailabilityChecks(
"Shouldn't have `this` for ctors!");
assert(!Method->isStatic() && "Shouldn't have `this` for static methods!");
ExprResult R = S.PerformImplicitObjectArgumentInitialization(
- ThisArg, /*Qualifier=*/nullptr, Method, Method);
+ ThisArg, /*Qualifier=*/std::nullopt, Method, Method);
if (R.isInvalid())
return false;
ConvertedThis = R.get();
@@ -8137,29 +8146,24 @@ bool Sema::CheckNonDependentConversions(
ArgType = ArgType->getPointeeType();
}
- if (auto *RT = ParamType->getAs<RecordType>())
- if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- RD && RD->hasDefinition()) {
- if (llvm::any_of(LookupConstructors(RD), [](NamedDecl *ND) {
- auto Info = getConstructorInfo(ND);
- if (!Info)
- return false;
- CXXConstructorDecl *Ctor = Info.Constructor;
- /// isConvertingConstructor takes copy/move constructors into
- /// account!
- return !Ctor->isCopyOrMoveConstructor() &&
- Ctor->isConvertingConstructor(
- /*AllowExplicit=*/true);
- }))
- return true;
- }
-
- if (auto *RT = ArgType->getAs<RecordType>())
- if (auto *RD = dyn_cast<CXXRecordDecl>(RT->getDecl());
- RD && RD->hasDefinition() &&
- !RD->getVisibleConversionFunctions().empty()) {
- return true;
- }
+ if (auto *RD = ParamType->getAsCXXRecordDecl();
+ RD && RD->hasDefinition() &&
+ llvm::any_of(LookupConstructors(RD), [](NamedDecl *ND) {
+ auto Info = getConstructorInfo(ND);
+ if (!Info)
+ return false;
+ CXXConstructorDecl *Ctor = Info.Constructor;
+ /// isConvertingConstructor takes copy/move constructors into
+ /// account!
+ return !Ctor->isCopyOrMoveConstructor() &&
+ Ctor->isConvertingConstructor(
+ /*AllowExplicit=*/true);
+ }))
+ return true;
+ if (auto *RD = ArgType->getAsCXXRecordDecl();
+ RD && RD->hasDefinition() &&
+ !RD->getVisibleConversionFunctions().empty())
+ return true;
return false;
};
@@ -8313,7 +8317,8 @@ void Sema::AddConversionCandidate(
if (const auto *FromPtrType = ObjectType->getAs<PointerType>())
ObjectType = FromPtrType->getPointeeType();
const auto *ConversionContext =
- cast<CXXRecordDecl>(ObjectType->castAs<RecordType>()->getDecl());
+ cast<CXXRecordDecl>(ObjectType->castAs<RecordType>()->getOriginalDecl())
+ ->getDefinitionOrSelf();
// C++23 [over.best.ics.general]
// However, if the target is [...]
@@ -8713,15 +8718,16 @@ void Sema::AddMemberOperatorCandidates(OverloadedOperatorKind Op,
// qualified lookup of T1::operator@ (13.3.1.1.1); otherwise,
// the set of member candidates is empty.
if (const RecordType *T1Rec = T1->getAs<RecordType>()) {
+ bool IsComplete = isCompleteType(OpLoc, T1);
+ CXXRecordDecl *T1RD =
+ cast<CXXRecordDecl>(T1Rec->getOriginalDecl())->getDefinition();
// Complete the type if it can be completed.
- if (!isCompleteType(OpLoc, T1) && !T1Rec->isBeingDefined())
- return;
// If the type is neither complete nor being defined, bail out now.
- if (!T1Rec->getDecl()->getDefinition())
+ if (!T1RD || (!IsComplete && !T1RD->isBeingDefined()))
return;
LookupResult Operators(*this, OpName, OpLoc, LookupOrdinaryName);
- LookupQualifiedName(Operators, T1Rec->getDecl());
+ LookupQualifiedName(Operators, T1RD);
Operators.suppressAccessDiagnostics();
for (LookupResult::iterator Oper = Operators.begin(),
@@ -8986,8 +8992,8 @@ BuiltinCandidateTypeSet::AddMemberPointerWithMoreQualifiedTypeVariants(
if ((CVR | BaseCVR) != CVR) continue;
QualType QPointeeTy = Context.getCVRQualifiedType(PointeeTy, CVR);
- MemberPointerTypes.insert(
- Context.getMemberPointerType(QPointeeTy, /*Qualifier=*/nullptr, Cls));
+ MemberPointerTypes.insert(Context.getMemberPointerType(
+ QPointeeTy, /*Qualifier=*/std::nullopt, Cls));
}
return true;
@@ -9064,7 +9070,8 @@ BuiltinCandidateTypeSet::AddTypesConvertedFrom(QualType Ty,
if (!SemaRef.isCompleteType(Loc, Ty))
return;
- CXXRecordDecl *ClassDecl = cast<CXXRecordDecl>(TyRec->getDecl());
+ auto *ClassDecl =
+ cast<CXXRecordDecl>(TyRec->getOriginalDecl())->getDefinitionOrSelf();
for (NamedDecl *D : ClassDecl->getVisibleConversionFunctions()) {
if (isa<UsingShadowDecl>(D))
D = cast<UsingShadowDecl>(D)->getTargetDecl();
@@ -10176,7 +10183,7 @@ class BuiltinOperatorOverloadBuilder {
if (S.getLangOpts().CPlusPlus11) {
for (QualType EnumTy : CandidateTypes[ArgIdx].enumeration_types()) {
- if (!EnumTy->castAs<EnumType>()->getDecl()->isScoped())
+ if (!EnumTy->castAs<EnumType>()->getOriginalDecl()->isScoped())
continue;
if (!AddedTypes.insert(S.Context.getCanonicalType(EnumTy)).second)
@@ -10931,9 +10938,9 @@ bool clang::isBetterOverloadCandidate(
isa<CXXConversionDecl>(Cand1.Function) ? TPOC_Conversion
: TPOC_Call,
Cand1.ExplicitCallArguments,
- Obj1Context ? QualType(Obj1Context->getTypeForDecl(), 0)
+ Obj1Context ? S.Context.getCanonicalTagType(Obj1Context)
: QualType{},
- Obj2Context ? QualType(Obj2Context->getTypeForDecl(), 0)
+ Obj2Context ? S.Context.getCanonicalTagType(Obj2Context)
: QualType{},
Cand1.isReversed() ^ Cand2.isReversed(), PartialOverloading)) {
return BetterTemplate == Cand1.Function->getPrimaryTemplate();
@@ -14873,8 +14880,8 @@ ExprResult Sema::BuildCXXMemberCallExpr(Expr *E, NamedDecl *FoundDecl,
if (Method->isExplicitObjectMemberFunction())
Exp = InitializeExplicitObjectArgument(*this, E, Method);
else
- Exp = PerformImplicitObjectArgumentInitialization(E, /*Qualifier=*/nullptr,
- FoundDecl, Method);
+ Exp = PerformImplicitObjectArgumentInitialization(
+ E, /*Qualifier=*/std::nullopt, FoundDecl, Method);
if (Exp.isInvalid())
return true;
@@ -15035,7 +15042,7 @@ Sema::CreateOverloadedUnaryOp(SourceLocation OpLoc, UnaryOperatorKind Opc,
InputInit = InitializeExplicitObjectArgument(*this, Input, Method);
else
InputInit = PerformImplicitObjectArgumentInitialization(
- Input, /*Qualifier=*/nullptr, Best->FoundDecl, Method);
+ Input, /*Qualifier=*/std::nullopt, Best->FoundDecl, Method);
if (InputInit.isInvalid())
return ExprError();
Base = Input = InputInit.get();
@@ -15418,7 +15425,7 @@ ExprResult Sema::CreateOverloadedBinOp(SourceLocation OpLoc,
ParamIdx = 1;
} else {
Arg0 = PerformImplicitObjectArgumentInitialization(
- Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method);
+ Args[0], /*Qualifier=*/std::nullopt, Best->FoundDecl, Method);
}
Arg1 = PerformCopyInitialization(
InitializedEntity::InitializeParameter(
@@ -15888,7 +15895,7 @@ ExprResult Sema::CreateOverloadedArraySubscriptExpr(SourceLocation LLoc,
ArgExpr = Args;
} else {
ExprResult Arg0 = PerformImplicitObjectArgumentInitialization(
- Args[0], /*Qualifier=*/nullptr, Best->FoundDecl, Method);
+ Args[0], /*Qualifier=*/std::nullopt, Best->FoundDecl, Method);
if (Arg0.isInvalid())
return ExprError();
@@ -16084,7 +16091,7 @@ ExprResult Sema::BuildCallToMemberFunction(Scope *S, Expr *MemExprE,
CXXMethodDecl *Method = nullptr;
bool HadMultipleCandidates = false;
DeclAccessPair FoundDecl = DeclAccessPair::make(nullptr, AS_public);
- NestedNameSpecifier *Qualifier = nullptr;
+ NestedNameSpecifier Qualifier = std::nullopt;
if (isa<MemberExpr>(NakedMemExpr)) {
MemExpr = cast<MemberExpr>(NakedMemExpr);
Method = cast<CXXMethodDecl>(MemExpr->getMemberDecl());
@@ -16356,7 +16363,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
const auto *Record = Object.get()->getType()->castAs<RecordType>();
LookupResult R(*this, OpName, LParenLoc, LookupOrdinaryName);
- LookupQualifiedName(R, Record->getDecl());
+ LookupQualifiedName(R, Record->getOriginalDecl()->getDefinitionOrSelf());
R.suppressAccessDiagnostics();
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
@@ -16400,8 +16407,9 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
// functions for each conversion function declared in an
// accessible base class provided the function is not hidden
// within T by another intervening declaration.
- const auto &Conversions =
- cast<CXXRecordDecl>(Record->getDecl())->getVisibleConversionFunctions();
+ const auto &Conversions = cast<CXXRecordDecl>(Record->getOriginalDecl())
+ ->getDefinitionOrSelf()
+ ->getVisibleConversionFunctions();
for (auto I = Conversions.begin(), E = Conversions.end();
!IgnoreSurrogateFunctions && I != E; ++I) {
NamedDecl *D = *I;
@@ -16551,7 +16559,7 @@ Sema::BuildCallToObjectOfClassType(Scope *S, Expr *Obj,
IsError |= PrepareExplicitObjectArgument(*this, Method, Obj, Args, NewArgs);
} else {
ExprResult ObjRes = PerformImplicitObjectArgumentInitialization(
- Object.get(), /*Qualifier=*/nullptr, Best->FoundDecl, Method);
+ Object.get(), /*Qualifier=*/std::nullopt, Best->FoundDecl, Method);
if (ObjRes.isInvalid())
IsError = true;
else
@@ -16622,7 +16630,10 @@ ExprResult Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base,
return ExprError();
LookupResult R(*this, OpName, OpLoc, LookupOrdinaryName);
- LookupQualifiedName(R, Base->getType()->castAs<RecordType>()->getDecl());
+ LookupQualifiedName(R, Base->getType()
+ ->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf());
R.suppressAccessDiagnostics();
for (LookupResult::iterator Oper = R.begin(), OperEnd = R.end();
@@ -16696,7 +16707,7 @@ ExprResult Sema::BuildOverloadedArrowExpr(Scope *S, Expr *Base,
Base = R.get();
} else {
ExprResult BaseResult = PerformImplicitObjectArgumentInitialization(
- Base, /*Qualifier=*/nullptr, Best->FoundDecl, Method);
+ Base, /*Qualifier=*/std::nullopt, Best->FoundDecl, Method);
if (BaseResult.isInvalid())
return ExprError();
Base = BaseResult.get();
@@ -16950,7 +16961,7 @@ ExprResult Sema::FixOverloadedFunctionReference(Expr *E, DeclAccessPair Found,
assert(isa<DeclRefExpr>(SubExpr.get()) &&
"fixed to something other than a decl ref");
- NestedNameSpecifier *Qualifier =
+ NestedNameSpecifier Qualifier =
cast<DeclRefExpr>(SubExpr.get())->getQualifier();
assert(Qualifier &&
"fixed to a member ref with no nested name qualifier");
diff --git a/clang/lib/Sema/SemaPPC.cpp b/clang/lib/Sema/SemaPPC.cpp
index d5c83aedb3008..7c82e540a9194 100644
--- a/clang/lib/Sema/SemaPPC.cpp
+++ b/clang/lib/Sema/SemaPPC.cpp
@@ -41,8 +41,10 @@ void SemaPPC::checkAIXMemberAlignment(SourceLocation Loc, const Expr *Arg) {
return;
QualType ArgType = Arg->getType();
- for (const FieldDecl *FD :
- ArgType->castAs<RecordType>()->getDecl()->fields()) {
+ for (const FieldDecl *FD : ArgType->castAs<RecordType>()
+ ->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->fields()) {
if (const auto *AA = FD->getAttr<AlignedAttr>()) {
CharUnits Alignment = getASTContext().toCharUnitsFromBits(
AA->getAlignment(getASTContext()));
diff --git a/clang/lib/Sema/SemaSYCL.cpp b/clang/lib/Sema/SemaSYCL.cpp
index 3e03cb4bd5f99..76b705e7ad4a2 100644
--- a/clang/lib/Sema/SemaSYCL.cpp
+++ b/clang/lib/Sema/SemaSYCL.cpp
@@ -221,7 +221,7 @@ static SourceLocation SourceLocationForUserDeclaredType(QualType QT) {
SourceLocation Loc;
const Type *T = QT->getUnqualifiedDesugaredType();
if (const TagType *TT = dyn_cast<TagType>(T))
- Loc = TT->getDecl()->getLocation();
+ Loc = TT->getOriginalDecl()->getLocation();
else if (const ObjCInterfaceType *ObjCIT = dyn_cast<ObjCInterfaceType>(T))
Loc = ObjCIT->getDecl()->getLocation();
return Loc;
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index 923a9e81fbd6a..b5a5082d6e844 100644
--- a/clang/lib/Sema/SemaStmt.cpp
+++ b/clang/lib/Sema/SemaStmt.cpp
@@ -801,7 +801,7 @@ bool Sema::checkMustTailAttr(const Stmt *St, const Attr &MTA) {
const auto *MPT =
CalleeBinOp->getRHS()->getType()->castAs<MemberPointerType>();
CalleeType.This =
- Context.getTypeDeclType(MPT->getMostRecentCXXRecordDecl());
+ Context.getCanonicalTagType(MPT->getMostRecentCXXRecordDecl());
CalleeType.Func = MPT->getPointeeType()->castAs<FunctionProtoType>();
CalleeType.MemberType = FuncType::ft_pointer_to_member;
} else if (isa<CXXPseudoDestructorExpr>(CalleeExpr)) {
@@ -1257,7 +1257,7 @@ static bool ShouldDiagnoseSwitchCaseNotInEnum(const Sema &S,
dyn_cast<DeclRefExpr>(CaseExpr->IgnoreParenImpCasts())) {
if (const VarDecl *VD = dyn_cast<VarDecl>(DRE->getDecl())) {
QualType VarType = VD->getType();
- QualType EnumType = S.Context.getTypeDeclType(ED);
+ CanQualType EnumType = S.Context.getCanonicalTagType(ED);
if (VD->hasGlobalStorage() && VarType.isConstQualified() &&
S.Context.hasSameUnqualifiedType(EnumType, VarType))
return false;
@@ -1287,11 +1287,11 @@ static void checkEnumTypesInSwitchStmt(Sema &S, const Expr *Cond,
return;
// Ignore anonymous enums.
- if (!CondEnumType->getDecl()->getIdentifier() &&
- !CondEnumType->getDecl()->getTypedefNameForAnonDecl())
+ if (!CondEnumType->getOriginalDecl()->getIdentifier() &&
+ !CondEnumType->getOriginalDecl()->getTypedefNameForAnonDecl())
return;
- if (!CaseEnumType->getDecl()->getIdentifier() &&
- !CaseEnumType->getDecl()->getTypedefNameForAnonDecl())
+ if (!CaseEnumType->getOriginalDecl()->getIdentifier() &&
+ !CaseEnumType->getOriginalDecl()->getTypedefNameForAnonDecl())
return;
if (S.Context.hasSameUnqualifiedType(CondType, CaseType))
@@ -1604,9 +1604,11 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
// If switch has default case, then ignore it.
if (!CaseListIsErroneous && !CaseListIsIncomplete && !HasConstantCond &&
- ET && ET->getDecl()->isCompleteDefinition() &&
- !ET->getDecl()->enumerators().empty()) {
- const EnumDecl *ED = ET->getDecl();
+ ET) {
+ const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
+ if (!ED->isCompleteDefinition() || ED->enumerators().empty())
+ goto enum_out;
+
EnumValsTy EnumVals;
// Gather all enum values, set their type and sort them,
@@ -1719,6 +1721,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
if (!hasCasesNotInSwitch)
SS->setAllEnumCasesCovered();
}
+ enum_out:;
}
if (BodyStmt)
@@ -1748,7 +1751,7 @@ Sema::DiagnoseAssignmentEnum(QualType DstType, QualType SrcType,
if (SrcExpr->isTypeDependent() || SrcExpr->isValueDependent())
return;
- const EnumDecl *ED = ET->getDecl();
+ const EnumDecl *ED = ET->getOriginalDecl()->getDefinitionOrSelf();
if (!ED->isClosed())
return;
@@ -3708,7 +3711,7 @@ class LocalTypedefNameReferencer : public DynamicRecursiveASTVisitor {
Sema &S;
};
bool LocalTypedefNameReferencer::VisitRecordType(RecordType *RT) {
- auto *R = dyn_cast<CXXRecordDecl>(RT->getDecl());
+ auto *R = dyn_cast<CXXRecordDecl>(RT->getOriginalDecl());
if (!R || !R->isLocalClass() || !R->isLocalClass()->isExternallyVisible() ||
R->isDependentType())
return true;
@@ -3927,7 +3930,7 @@ StmtResult Sema::BuildReturnStmt(SourceLocation ReturnLoc, Expr *RetValExp,
<< RetValExp->getSourceRange();
if (FD->hasAttr<CmseNSEntryAttr>() && RetValExp) {
if (const auto *RT = dyn_cast<RecordType>(FnRetType.getCanonicalType())) {
- if (RT->getDecl()->isOrContainsUnion())
+ if (RT->getOriginalDecl()->isOrContainsUnion())
Diag(RetValExp->getBeginLoc(), diag::warn_cmse_nonsecure_union) << 1;
}
}
@@ -4618,7 +4621,8 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
// Build the context parameter
DeclContext *DC = CapturedDecl::castToDeclContext(CD);
IdentifierInfo *ParamName = &Context.Idents.get("__context");
- QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+ CanQualType ParamType =
+ Context.getPointerType(Context.getCanonicalTagType(RD));
auto *Param =
ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType,
ImplicitParamKind::CapturedContext);
@@ -4660,9 +4664,10 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
assert(!ContextIsFound &&
"null type has been found already for '__context' parameter");
IdentifierInfo *ParamName = &Context.Idents.get("__context");
- QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD))
- .withConst()
- .withRestrict();
+ QualType ParamType =
+ Context.getPointerType(Context.getCanonicalTagType(RD))
+ .withConst()
+ .withRestrict();
auto *Param =
ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType,
ImplicitParamKind::CapturedContext);
@@ -4682,7 +4687,8 @@ void Sema::ActOnCapturedRegionStart(SourceLocation Loc, Scope *CurScope,
if (!ContextIsFound) {
// Add __context implicitly if it is not specified.
IdentifierInfo *ParamName = &Context.Idents.get("__context");
- QualType ParamType = Context.getPointerType(Context.getTagDeclType(RD));
+ CanQualType ParamType =
+ Context.getPointerType(Context.getCanonicalTagType(RD));
auto *Param =
ImplicitParamDecl::Create(Context, DC, Loc, ParamName, ParamType,
ImplicitParamKind::CapturedContext);
diff --git a/clang/lib/Sema/SemaStmtAsm.cpp b/clang/lib/Sema/SemaStmtAsm.cpp
index 4507a21a4c111..cd8b98c7444eb 100644
--- a/clang/lib/Sema/SemaStmtAsm.cpp
+++ b/clang/lib/Sema/SemaStmtAsm.cpp
@@ -894,7 +894,7 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
QT = PT->getPointeeType();
RT = QT->getAs<RecordType>();
} else if (TypeDecl *TD = dyn_cast<TypeDecl>(FoundDecl))
- RT = TD->getTypeForDecl()->getAs<RecordType>();
+ RT = Context.getTypeDeclType(TD)->getAs<RecordType>();
else if (FieldDecl *TD = dyn_cast<FieldDecl>(FoundDecl))
RT = TD->getType()->getAs<RecordType>();
if (!RT)
@@ -907,7 +907,8 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
LookupResult FieldResult(*this, &Context.Idents.get(NextMember),
SourceLocation(), LookupMemberName);
- if (!LookupQualifiedName(FieldResult, RT->getDecl()))
+ RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
+ if (!LookupQualifiedName(FieldResult, RD))
return true;
if (!FieldResult.isSingleResult())
@@ -919,7 +920,7 @@ bool Sema::LookupInlineAsmField(StringRef Base, StringRef Member,
if (!FD)
return true;
- const ASTRecordLayout &RL = Context.getASTRecordLayout(RT->getDecl());
+ const ASTRecordLayout &RL = Context.getASTRecordLayout(RD);
unsigned i = FD->getFieldIndex();
CharUnits Result = Context.toCharUnitsFromBits(RL.getFieldOffset(i));
Offset += (unsigned)Result.getQuantity();
@@ -951,7 +952,8 @@ Sema::LookupInlineAsmVarDeclField(Expr *E, StringRef Member,
LookupResult FieldResult(*this, &Context.Idents.get(Member), AsmLoc,
LookupMemberName);
- if (!LookupQualifiedName(FieldResult, RT->getDecl()))
+ if (!LookupQualifiedName(FieldResult,
+ RT->getOriginalDecl()->getDefinitionOrSelf()))
return ExprResult();
// Only normal and indirect field results will work.
diff --git a/clang/lib/Sema/SemaSwift.cpp b/clang/lib/Sema/SemaSwift.cpp
index 4000beff7dc49..a99222c5ed55f 100644
--- a/clang/lib/Sema/SemaSwift.cpp
+++ b/clang/lib/Sema/SemaSwift.cpp
@@ -130,7 +130,7 @@ static bool isErrorParameter(Sema &S, QualType QT) {
// Check for CFError**.
if (const auto *PT = Pointee->getAs<PointerType>())
if (const auto *RT = PT->getPointeeType()->getAs<RecordType>())
- if (S.ObjC().isCFError(RT->getDecl()))
+ if (S.ObjC().isCFError(RT->getOriginalDecl()->getDefinitionOrSelf()))
return true;
return false;
@@ -272,7 +272,8 @@ static void checkSwiftAsyncErrorBlock(Sema &S, Decl *D,
// Check for CFError *.
if (const auto *PtrTy = Param->getAs<PointerType>()) {
if (const auto *RT = PtrTy->getPointeeType()->getAs<RecordType>()) {
- if (S.ObjC().isCFError(RT->getDecl())) {
+ if (S.ObjC().isCFError(
+ RT->getOriginalDecl()->getDefinitionOrSelf())) {
AnyErrorParams = true;
break;
}
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 1a98b3583185e..d71594dc2ba8f 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -291,7 +291,7 @@ TemplateNameKind Sema::isTemplateName(Scope *S,
FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD);
assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD);
if (!SS.isInvalid()) {
- NestedNameSpecifier *Qualifier = SS.getScopeRep();
+ NestedNameSpecifier Qualifier = SS.getScopeRep();
Template = Context.getQualifiedTemplateName(Qualifier, hasTemplateKeyword,
Template);
}
@@ -363,9 +363,8 @@ bool Sema::DiagnoseUnknownTemplateName(const IdentifierInfo &II,
// The code is missing a 'template' keyword prior to the dependent template
// name.
- NestedNameSpecifier *Qualifier = (NestedNameSpecifier *)SS->getScopeRep();
SuggestedTemplate = TemplateTy::make(Context.getDependentTemplateName(
- {Qualifier, &II, /*HasTemplateKeyword=*/false}));
+ {SS->getScopeRep(), &II, /*HasTemplateKeyword=*/false}));
Diag(IILoc, diag::err_template_kw_missing)
<< SuggestedTemplate.get()
<< FixItHint::CreateInsertion(IILoc, "template ");
@@ -397,7 +396,9 @@ bool Sema::LookupTemplateName(LookupResult &Found, Scope *S, CXXScopeSpec &SS,
IsDependent = !LookupCtx && ObjectType->isDependentType();
assert((IsDependent || !ObjectType->isIncompleteType() ||
!ObjectType->getAs<TagType>() ||
- ObjectType->castAs<TagType>()->isBeingDefined()) &&
+ ObjectType->castAs<TagType>()
+ ->getOriginalDecl()
+ ->isEntityBeingDefined()) &&
"Caller should have completed object type");
// Template names cannot appear inside an Objective-C class or object type
@@ -797,9 +798,9 @@ bool Sema::DiagnoseUninstantiableTemplate(SourceLocation PointOfInstantiation,
if (!Complain || (PatternDef && PatternDef->isInvalidDecl()))
return true;
- QualType InstantiationTy;
+ CanQualType InstantiationTy;
if (TagDecl *TD = dyn_cast<TagDecl>(Instantiation))
- InstantiationTy = Context.getTypeDeclType(TD);
+ InstantiationTy = Context.getCanonicalTagType(TD);
if (PatternDef) {
Diag(PointOfInstantiation,
diag::err_template_instantiate_within_definition)
@@ -907,7 +908,7 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
TypeSourceInfo *DI;
QualType T = SemaRef.GetTypeFromParser(Arg.getAsType(), &DI);
if (!DI)
- DI = SemaRef.Context.getTrivialTypeSourceInfo(T, Arg.getLocation());
+ DI = SemaRef.Context.getTrivialTypeSourceInfo(T, Arg.getNameLoc());
return TemplateArgumentLoc(TemplateArgument(T), DI);
}
@@ -924,9 +925,9 @@ static TemplateArgumentLoc translateTemplateArgument(Sema &SemaRef,
else
TArg = Template;
return TemplateArgumentLoc(
- SemaRef.Context, TArg,
+ SemaRef.Context, TArg, Arg.getTemplateKwLoc(),
Arg.getScopeSpec().getWithLocInContext(SemaRef.Context),
- Arg.getLocation(), Arg.getEllipsisLoc());
+ Arg.getNameLoc(), Arg.getEllipsisLoc());
}
}
@@ -967,15 +968,12 @@ ParsedTemplateArgument Sema::ActOnTemplateTypeArgument(TypeResult ParsedType) {
TL = PET.getPatternLoc();
}
- CXXScopeSpec SS;
- if (auto ET = TL.getAs<ElaboratedTypeLoc>()) {
- SS.Adopt(ET.getQualifierLoc());
- TL = ET.getNamedTypeLoc();
- }
-
if (auto DTST = TL.getAs<DeducedTemplateSpecializationTypeLoc>()) {
TemplateName Name = DTST.getTypePtr()->getTemplateName();
- ParsedTemplateArgument Result(SS, TemplateTy::make(Name),
+ CXXScopeSpec SS;
+ SS.Adopt(DTST.getQualifierLoc());
+ ParsedTemplateArgument Result(/*TemplateKwLoc=*/SourceLocation(), SS,
+ TemplateTy::make(Name),
DTST.getTemplateNameLoc());
if (EllipsisLoc.isValid())
Result = Result.getTemplatePackExpansion(EllipsisLoc);
@@ -2106,11 +2104,11 @@ DeclResult Sema::CheckClassTemplate(
bool ShouldAddRedecl =
!(TUK == TagUseKind::Friend && CurContext->isDependentContext());
- CXXRecordDecl *NewClass =
- CXXRecordDecl::Create(Context, Kind, SemanticContext, KWLoc, NameLoc, Name,
- PrevClassTemplate && ShouldAddRedecl ?
- PrevClassTemplate->getTemplatedDecl() : nullptr,
- /*DelayTypeCreation=*/true);
+ CXXRecordDecl *NewClass = CXXRecordDecl::Create(
+ Context, Kind, SemanticContext, KWLoc, NameLoc, Name,
+ PrevClassTemplate && ShouldAddRedecl
+ ? PrevClassTemplate->getTemplatedDecl()
+ : nullptr);
SetNestedNameSpecifier(*this, NewClass, SS);
if (NumOuterTemplateParamLists > 0)
NewClass->setTemplateParameterListsInfo(
@@ -2139,12 +2137,6 @@ DeclResult Sema::CheckClassTemplate(
if (ModulePrivateLoc.isValid())
NewTemplate->setModulePrivate();
- // Build the type for the class template declaration now.
- QualType T = NewTemplate->getInjectedClassNameSpecialization();
- T = Context.getInjectedClassNameType(NewClass, T);
- assert(T->isDependentType() && "Class template type is not dependent?");
- (void)T;
-
// If we are providing an explicit specialization of a member that is a
// class template, make a note of that.
if (PrevClassTemplate &&
@@ -2635,11 +2627,11 @@ struct DependencyChecker : DynamicRecursiveASTVisitor {
return DynamicRecursiveASTVisitor::TraverseStmt(S);
}
- bool TraverseTypeLoc(TypeLoc TL) override {
+ bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) override {
if (IgnoreNonTypeDependent && !TL.isNull() &&
!TL.getType()->isDependentType())
return true;
- return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL);
+ return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL, TraverseQualifier);
}
bool VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) override {
@@ -2676,8 +2668,12 @@ struct DependencyChecker : DynamicRecursiveASTVisitor {
return TraverseTemplateArgument(T->getArgumentPack());
}
- bool TraverseInjectedClassNameType(InjectedClassNameType *T) override {
- return TraverseType(T->getInjectedSpecializationType());
+ bool TraverseInjectedClassNameType(InjectedClassNameType *T,
+ bool TraverseQualifier) override {
+ // An InjectedClassNameType will never have a dependent template name,
+ // so no need to traverse it.
+ return TraverseTemplateArguments(
+ T->getTemplateArgs(T->getOriginalDecl()->getASTContext()));
}
};
} // end anonymous namespace
@@ -2700,14 +2696,14 @@ static SourceRange getRangeOfTypeInNestedNameSpecifier(ASTContext &Context,
QualType T,
const CXXScopeSpec &SS) {
NestedNameSpecifierLoc NNSLoc(SS.getScopeRep(), SS.location_data());
- while (NestedNameSpecifier *NNS = NNSLoc.getNestedNameSpecifier()) {
- if (const Type *CurType = NNS->getAsType()) {
- if (Context.hasSameUnqualifiedType(T, QualType(CurType, 0)))
- return NNSLoc.getTypeLoc().getSourceRange();
- } else
+ for (;;) {
+ NestedNameSpecifier NNS = NNSLoc.getNestedNameSpecifier();
+ if (NNS.getKind() != NestedNameSpecifier::Kind::Type)
break;
-
- NNSLoc = NNSLoc.getPrefix();
+ if (Context.hasSameUnqualifiedType(T, QualType(NNS.getAsType(), 0)))
+ return NNSLoc.castAsTypeLoc().getSourceRange();
+ // FIXME: This will always be empty.
+ NNSLoc = NNSLoc.getAsNamespaceAndPrefix().Prefix;
}
return SourceRange();
@@ -2726,12 +2722,13 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
// by the nested-name-specifier and walking out until we run out of types.
SmallVector<QualType, 4> NestedTypes;
QualType T;
- if (SS.getScopeRep()) {
- if (CXXRecordDecl *Record
- = dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS, true)))
- T = Context.getTypeDeclType(Record);
+ if (NestedNameSpecifier Qualifier = SS.getScopeRep();
+ Qualifier.getKind() == NestedNameSpecifier::Kind::Type) {
+ if (CXXRecordDecl *Record =
+ dyn_cast_or_null<CXXRecordDecl>(computeDeclContext(SS, true)))
+ T = Context.getCanonicalTagType(Record);
else
- T = QualType(SS.getScopeRep()->getAsType(), 0);
+ T = QualType(Qualifier.getAsType(), 0);
}
// If we found an explicit specialization that prevents us from needing
@@ -2779,9 +2776,10 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
// Look one step prior in a dependent template specialization type.
if (const DependentTemplateSpecializationType *DependentTST
= T->getAs<DependentTemplateSpecializationType>()) {
- if (NestedNameSpecifier *NNS =
- DependentTST->getDependentTemplateName().getQualifier())
- T = QualType(NNS->getAsType(), 0);
+ if (NestedNameSpecifier NNS =
+ DependentTST->getDependentTemplateName().getQualifier();
+ NNS.getKind() == NestedNameSpecifier::Kind::Type)
+ T = QualType(NNS.getAsType(), 0);
else
T = QualType();
continue;
@@ -2789,8 +2787,9 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
// Look one step prior in a dependent name type.
if (const DependentNameType *DependentName = T->getAs<DependentNameType>()){
- if (NestedNameSpecifier *NNS = DependentName->getQualifier())
- T = QualType(NNS->getAsType(), 0);
+ if (NestedNameSpecifier NNS = DependentName->getQualifier();
+ NNS.getKind() == NestedNameSpecifier::Kind::Type)
+ T = QualType(NNS.getAsType(), 0);
else
T = QualType();
continue;
@@ -2800,7 +2799,7 @@ TemplateParameterList *Sema::MatchTemplateParametersToScopeSpecifier(
if (const EnumType *EnumT = T->getAs<EnumType>()) {
// FIXME: Forward-declared enums require a TSK_ExplicitSpecialization
// check here.
- EnumDecl *Enum = EnumT->getDecl();
+ EnumDecl *Enum = EnumT->getOriginalDecl();
// Get to the parent type.
if (TypeDecl *Parent = dyn_cast<TypeDecl>(Enum->getParent()))
@@ -3100,7 +3099,8 @@ void Sema::NoteAllFoundTemplates(TemplateName Name) {
}
}
-static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate,
+static QualType builtinCommonTypeImpl(Sema &S, ElaboratedTypeKeyword Keyword,
+ TemplateName BaseTemplate,
SourceLocation TemplateLoc,
ArrayRef<TemplateArgument> Ts) {
auto lookUpCommonType = [&](TemplateArgument T1,
@@ -3108,7 +3108,8 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate,
// Don't bother looking for other specializations if both types are
// builtins - users aren't allowed to specialize for them
if (T1.getAsType()->isBuiltinType() && T2.getAsType()->isBuiltinType())
- return builtinCommonTypeImpl(S, BaseTemplate, TemplateLoc, {T1, T2});
+ return builtinCommonTypeImpl(S, Keyword, BaseTemplate, TemplateLoc,
+ {T1, T2});
TemplateArgumentListInfo Args;
Args.addArgument(TemplateArgumentLoc(
@@ -3122,7 +3123,7 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate,
Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
QualType BaseTemplateInst =
- S.CheckTemplateIdType(BaseTemplate, TemplateLoc, Args);
+ S.CheckTemplateIdType(Keyword, BaseTemplate, TemplateLoc, Args);
if (SFINAE.hasErrorOccurred())
return QualType();
@@ -3235,7 +3236,7 @@ static QualType builtinCommonTypeImpl(Sema &S, TemplateName BaseTemplate,
}
static bool isInVkNamespace(const RecordType *RT) {
- DeclContext *DC = RT->getDecl()->getDeclContext();
+ DeclContext *DC = RT->getOriginalDecl()->getDeclContext();
if (!DC)
return false;
@@ -3252,8 +3253,9 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef,
if (auto *RT = OperandArg->getAs<RecordType>()) {
bool Literal = false;
SourceLocation LiteralLoc;
- if (isInVkNamespace(RT) && RT->getDecl()->getName() == "Literal") {
- auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
+ if (isInVkNamespace(RT) && RT->getOriginalDecl()->getName() == "Literal") {
+ auto SpecDecl =
+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
assert(SpecDecl);
const TemplateArgumentList &LiteralArgs = SpecDecl->getTemplateArgs();
@@ -3264,8 +3266,9 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef,
}
if (RT && isInVkNamespace(RT) &&
- RT->getDecl()->getName() == "integral_constant") {
- auto SpecDecl = dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl());
+ RT->getOriginalDecl()->getName() == "integral_constant") {
+ auto SpecDecl =
+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl());
assert(SpecDecl);
const TemplateArgumentList &ConstantArgs = SpecDecl->getTemplateArgs();
@@ -3287,11 +3290,10 @@ static SpirvOperand checkHLSLSpirvTypeOperand(Sema &SemaRef,
return SpirvOperand::createType(OperandArg);
}
-static QualType
-checkBuiltinTemplateIdType(Sema &SemaRef, BuiltinTemplateDecl *BTD,
- ArrayRef<TemplateArgument> Converted,
- SourceLocation TemplateLoc,
- TemplateArgumentListInfo &TemplateArgs) {
+static QualType checkBuiltinTemplateIdType(
+ Sema &SemaRef, ElaboratedTypeKeyword Keyword, BuiltinTemplateDecl *BTD,
+ ArrayRef<TemplateArgument> Converted, SourceLocation TemplateLoc,
+ TemplateArgumentListInfo &TemplateArgs) {
ASTContext &Context = SemaRef.getASTContext();
switch (BTD->getBuiltinTemplateKind()) {
@@ -3338,7 +3340,7 @@ checkBuiltinTemplateIdType(Sema &SemaRef, BuiltinTemplateDecl *BTD,
// The first template argument will be reused as the template decl that
// our synthetic template arguments will be applied to.
- return SemaRef.CheckTemplateIdType(Converted[0].getAsTemplate(),
+ return SemaRef.CheckTemplateIdType(Keyword, Converted[0].getAsTemplate(),
TemplateLoc, SyntheticTemplateArgs);
}
@@ -3375,14 +3377,16 @@ checkBuiltinTemplateIdType(Sema &SemaRef, BuiltinTemplateDecl *BTD,
TemplateName BaseTemplate = Converted[0].getAsTemplate();
ArrayRef<TemplateArgument> Ts = Converted[3].getPackAsArray();
- if (auto CT = builtinCommonTypeImpl(SemaRef, BaseTemplate, TemplateLoc, Ts);
+ if (auto CT = builtinCommonTypeImpl(SemaRef, Keyword, BaseTemplate,
+ TemplateLoc, Ts);
!CT.isNull()) {
TemplateArgumentListInfo TAs;
TAs.addArgument(TemplateArgumentLoc(
TemplateArgument(CT), SemaRef.Context.getTrivialTypeSourceInfo(
CT, TemplateArgs[1].getLocation())));
TemplateName HasTypeMember = Converted[1].getAsTemplate();
- return SemaRef.CheckTemplateIdType(HasTypeMember, TemplateLoc, TAs);
+ return SemaRef.CheckTemplateIdType(Keyword, HasTypeMember, TemplateLoc,
+ TAs);
}
QualType HasNoTypeMember = Converted[2].getAsType();
return HasNoTypeMember;
@@ -3494,7 +3498,7 @@ class FailedBooleanConditionPrinterHelper : public PrinterHelper {
if (DR && DR->getQualifier()) {
// If this is a qualified name, expand the template arguments in nested
// qualifiers.
- DR->getQualifier()->print(OS, Policy, true);
+ DR->getQualifier().print(OS, Policy, true);
// Then print the decl itself.
const ValueDecl *VD = DR->getDecl();
OS << VD->getName();
@@ -3559,7 +3563,8 @@ Sema::findFailedBooleanCondition(Expr *Cond) {
return { FailedCond, Description };
}
-QualType Sema::CheckTemplateIdType(TemplateName Name,
+QualType Sema::CheckTemplateIdType(ElaboratedTypeKeyword Keyword,
+ TemplateName Name,
SourceLocation TemplateLoc,
TemplateArgumentListInfo &TemplateArgs) {
// FIXME: 'getUnderlying' loses SubstTemplateTemplateParm nodes from alias
@@ -3610,6 +3615,18 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
} else if (TypeAliasTemplateDecl *AliasTemplate =
dyn_cast<TypeAliasTemplateDecl>(Template)) {
+ // C++0x [dcl.type.elab]p2:
+ // If the identifier resolves to a typedef-name or the simple-template-id
+ // resolves to an alias template specialization, the
+ // elaborated-type-specifier is ill-formed.
+ if (Keyword != ElaboratedTypeKeyword::None &&
+ Keyword != ElaboratedTypeKeyword::Typename) {
+ SemaRef.Diag(TemplateLoc, diag::err_tag_reference_non_tag)
+ << AliasTemplate << NonTagKind::TypeAliasTemplate
+ << KeywordHelpers::getTagTypeKindForKeyword(Keyword);
+ SemaRef.Diag(AliasTemplate->getLocation(), diag::note_declared_at);
+ }
+
// Find the canonical type for this type alias template specialization.
TypeAliasDecl *Pattern = AliasTemplate->getTemplatedDecl();
if (Pattern->isInvalidDecl())
@@ -3677,8 +3694,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
return QualType();
}
} else if (auto *BTD = dyn_cast<BuiltinTemplateDecl>(Template)) {
- CanonType = checkBuiltinTemplateIdType(*this, BTD, CTAI.SugaredConverted,
- TemplateLoc, TemplateArgs);
+ CanonType = checkBuiltinTemplateIdType(
+ *this, Keyword, BTD, CTAI.SugaredConverted, TemplateLoc, TemplateArgs);
} else if (Name.isDependent() ||
TemplateSpecializationType::anyDependentTemplateArguments(
TemplateArgs, CTAI.CanonicalConverted)) {
@@ -3717,16 +3734,15 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// Fetch the injected class name type and check whether its
// injected type is equal to the type we just built.
- QualType ICNT = Context.getTypeDeclType(Record);
- QualType Injected = cast<InjectedClassNameType>(ICNT)
- ->getInjectedSpecializationType();
+ CanQualType ICNT = Context.getCanonicalTagType(Record);
+ CanQualType Injected =
+ cast<InjectedClassNameType>(ICNT)->getCanonicalInjectedTST();
- if (CanonType != Injected->getCanonicalTypeInternal())
+ if (CanonType != Injected)
continue;
// If so, the canonical type of this TST is the injected
// class name type of the record we just found.
- assert(ICNT.isCanonical());
CanonType = ICNT;
break;
}
@@ -3768,7 +3784,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// Diagnose uses of this specialization.
(void)DiagnoseUseOfDecl(Decl, TemplateLoc);
- CanonType = Context.getTypeDeclType(Decl);
+ CanonType = Context.getCanonicalTagType(Decl);
assert(isa<RecordType>(CanonType) &&
"type of non-dependent specialization is not a RecordType");
} else {
@@ -3779,7 +3795,8 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
// specialization, which refers back to the class template
// specialization we created or found.
return Context.getTemplateSpecializationType(
- Name, TemplateArgs.arguments(), CTAI.CanonicalConverted, CanonType);
+ Keyword, Name, TemplateArgs.arguments(), CTAI.CanonicalConverted,
+ CanonType);
}
void Sema::ActOnUndeclaredTypeTemplateName(Scope *S, TemplateTy &ParsedName,
@@ -3827,7 +3844,7 @@ bool Sema::resolveAssumedTemplateNameAsType(Scope *S, TemplateName &Name,
diagnoseTypo(Corrected, PDiag(diag::err_no_template_suggest)
<< ATN->getDeclName());
Name = Context.getQualifiedTemplateName(
- /*NNS=*/nullptr, /*TemplateKeyword=*/false,
+ /*Qualifier=*/std::nullopt, /*TemplateKeyword=*/false,
TemplateName(Corrected.getCorrectionDeclAs<TemplateDecl>()));
return false;
}
@@ -3838,11 +3855,12 @@ bool Sema::resolveAssumedTemplateNameAsType(Scope *S, TemplateName &Name,
}
TypeResult Sema::ActOnTemplateIdType(
- Scope *S, CXXScopeSpec &SS, SourceLocation TemplateKWLoc,
- TemplateTy TemplateD, const IdentifierInfo *TemplateII,
- SourceLocation TemplateIILoc, SourceLocation LAngleLoc,
- ASTTemplateArgsPtr TemplateArgsIn, SourceLocation RAngleLoc,
- bool IsCtorOrDtorName, bool IsClassName,
+ Scope *S, ElaboratedTypeKeyword ElaboratedKeyword,
+ SourceLocation ElaboratedKeywordLoc, CXXScopeSpec &SS,
+ SourceLocation TemplateKWLoc, TemplateTy TemplateD,
+ const IdentifierInfo *TemplateII, SourceLocation TemplateIILoc,
+ SourceLocation LAngleLoc, ASTTemplateArgsPtr TemplateArgsIn,
+ SourceLocation RAngleLoc, bool IsCtorOrDtorName, bool IsClassName,
ImplicitTypenameContext AllowImplicitTypename) {
if (SS.isInvalid())
return true;
@@ -3858,8 +3876,9 @@ TypeResult Sema::ActOnTemplateIdType(
// elaborated-type-specifier (7.1.5.3).
if (!LookupCtx && isDependentScopeSpecifier(SS)) {
// C++2a relaxes some of those restrictions in [temp.res]p5.
- NestedNameSpecifier *NNS =
- NestedNameSpecifier::Create(Context, SS.getScopeRep(), TemplateII);
+ QualType DNT = Context.getDependentNameType(ElaboratedTypeKeyword::None,
+ SS.getScopeRep(), TemplateII);
+ NestedNameSpecifier NNS(DNT.getTypePtr());
if (AllowImplicitTypename == ImplicitTypenameContext::Yes) {
auto DB = DiagCompat(SS.getBeginLoc(), diag_compat::implicit_typename)
<< NNS;
@@ -3903,12 +3922,12 @@ TypeResult Sema::ActOnTemplateIdType(
if (DependentTemplateName *DTN = Template.getAsDependentTemplateName()) {
assert(SS.getScopeRep() == DTN->getQualifier());
QualType T = Context.getDependentTemplateSpecializationType(
- ElaboratedTypeKeyword::None, *DTN, TemplateArgs.arguments());
+ ElaboratedKeyword, *DTN, TemplateArgs.arguments());
// Build type-source information.
TypeLocBuilder TLB;
DependentTemplateSpecializationTypeLoc SpecTL
= TLB.push<DependentTemplateSpecializationTypeLoc>(T);
- SpecTL.setElaboratedKeywordLoc(SourceLocation());
+ SpecTL.setElaboratedKeywordLoc(ElaboratedKeywordLoc);
SpecTL.setQualifierLoc(SS.getWithLocInContext(Context));
SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
SpecTL.setTemplateNameLoc(TemplateIILoc);
@@ -3919,30 +3938,17 @@ TypeResult Sema::ActOnTemplateIdType(
return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
}
- QualType SpecTy = CheckTemplateIdType(Template, TemplateIILoc, TemplateArgs);
+ QualType SpecTy = CheckTemplateIdType(ElaboratedKeyword, Template,
+ TemplateIILoc, TemplateArgs);
if (SpecTy.isNull())
return true;
// Build type-source information.
TypeLocBuilder TLB;
- TemplateSpecializationTypeLoc SpecTL =
- TLB.push<TemplateSpecializationTypeLoc>(SpecTy);
- SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
- SpecTL.setTemplateNameLoc(TemplateIILoc);
- SpecTL.setLAngleLoc(LAngleLoc);
- SpecTL.setRAngleLoc(RAngleLoc);
- for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i)
- SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
-
- // Create an elaborated-type-specifier containing the nested-name-specifier.
- QualType ElTy =
- getElaboratedType(ElaboratedTypeKeyword::None,
- !IsCtorOrDtorName ? SS : CXXScopeSpec(), SpecTy);
- ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(ElTy);
- ElabTL.setElaboratedKeywordLoc(SourceLocation());
- if (!ElabTL.isEmpty())
- ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
- return CreateParsedType(ElTy, TLB.getTypeSourceInfo(Context, ElTy));
+ TLB.push<TemplateSpecializationTypeLoc>(SpecTy).set(
+ ElaboratedKeywordLoc, SS.getWithLocInContext(Context), TemplateKWLoc,
+ TemplateIILoc, TemplateArgs);
+ return CreateParsedType(SpecTy, TLB.getTypeSourceInfo(Context, SpecTy));
}
TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK,
@@ -3989,24 +3995,14 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK,
return CreateParsedType(T, TLB.getTypeSourceInfo(Context, T));
}
- if (TypeAliasTemplateDecl *TAT =
- dyn_cast_or_null<TypeAliasTemplateDecl>(Template.getAsTemplateDecl())) {
- // C++0x [dcl.type.elab]p2:
- // If the identifier resolves to a typedef-name or the simple-template-id
- // resolves to an alias template specialization, the
- // elaborated-type-specifier is ill-formed.
- Diag(TemplateLoc, diag::err_tag_reference_non_tag)
- << TAT << NonTagKind::TypeAliasTemplate << TagKind;
- Diag(TAT->getLocation(), diag::note_declared_at);
- }
-
- QualType Result = CheckTemplateIdType(Template, TemplateLoc, TemplateArgs);
+ QualType Result =
+ CheckTemplateIdType(Keyword, Template, TemplateLoc, TemplateArgs);
if (Result.isNull())
return TypeResult(true);
// Check the tag kind
if (const RecordType *RT = Result->getAs<RecordType>()) {
- RecordDecl *D = RT->getDecl();
+ RecordDecl *D = RT->getOriginalDecl()->getDefinitionOrSelf();
IdentifierInfo *Id = D->getIdentifier();
assert(Id && "templated class must have an identifier");
@@ -4022,21 +4018,9 @@ TypeResult Sema::ActOnTagTemplateIdType(TagUseKind TUK,
// Provide source-location information for the template specialization.
TypeLocBuilder TLB;
- TemplateSpecializationTypeLoc SpecTL
- = TLB.push<TemplateSpecializationTypeLoc>(Result);
- SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
- SpecTL.setTemplateNameLoc(TemplateLoc);
- SpecTL.setLAngleLoc(LAngleLoc);
- SpecTL.setRAngleLoc(RAngleLoc);
- for (unsigned i = 0, e = SpecTL.getNumArgs(); i != e; ++i)
- SpecTL.setArgLocInfo(i, TemplateArgs[i].getLocInfo());
-
- // Construct an elaborated type containing the nested-name-specifier (if any)
- // and tag keyword.
- Result = Context.getElaboratedType(Keyword, SS.getScopeRep(), Result);
- ElaboratedTypeLoc ElabTL = TLB.push<ElaboratedTypeLoc>(Result);
- ElabTL.setElaboratedKeywordLoc(TagLoc);
- ElabTL.setQualifierLoc(SS.getWithLocInContext(Context));
+ TLB.push<TemplateSpecializationTypeLoc>(Result).set(
+ TagLoc, SS.getWithLocInContext(Context), TemplateKWLoc, TemplateLoc,
+ TemplateArgs);
return CreateParsedType(Result, TLB.getTypeSourceInfo(Context, Result));
}
@@ -4958,7 +4942,7 @@ TemplateNameKind Sema::ActOnTemplateName(Scope *S,
return TNK_Non_template;
}
- NestedNameSpecifier *Qualifier = SS.getScopeRep();
+ NestedNameSpecifier Qualifier = SS.getScopeRep();
switch (Name.getKind()) {
case UnqualifiedIdKind::IK_Identifier:
@@ -5246,8 +5230,9 @@ static bool SubstDefaultTemplateArgument(
///
/// \returns the substituted template argument, or NULL if an error occurred.
static TemplateName SubstDefaultTemplateArgument(
- Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateLoc,
- SourceLocation RAngleLoc, TemplateTemplateParmDecl *Param,
+ Sema &SemaRef, TemplateDecl *Template, SourceLocation TemplateKWLoc,
+ SourceLocation TemplateLoc, SourceLocation RAngleLoc,
+ TemplateTemplateParmDecl *Param,
ArrayRef<TemplateArgument> SugaredConverted,
ArrayRef<TemplateArgument> CanonicalConverted,
NestedNameSpecifierLoc &QualifierLoc) {
@@ -5264,25 +5249,17 @@ static TemplateName SubstDefaultTemplateArgument(
TemplateArgLists.addOuterTemplateArguments(std::nullopt);
Sema::ContextRAII SavedContext(SemaRef, Template->getDeclContext());
- // Substitute into the nested-name-specifier first,
- QualifierLoc = Param->getDefaultArgument().getTemplateQualifierLoc();
- if (QualifierLoc) {
- QualifierLoc =
- SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgLists);
- if (!QualifierLoc)
- return TemplateName();
- }
- return SemaRef.SubstTemplateName(
- QualifierLoc,
- Param->getDefaultArgument().getArgument().getAsTemplate(),
- Param->getDefaultArgument().getTemplateNameLoc(),
- TemplateArgLists);
+ const TemplateArgumentLoc &A = Param->getDefaultArgument();
+ QualifierLoc = A.getTemplateQualifierLoc();
+ return SemaRef.SubstTemplateName(TemplateKWLoc, QualifierLoc,
+ A.getArgument().getAsTemplate(),
+ A.getTemplateNameLoc(), TemplateArgLists);
}
TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
- TemplateDecl *Template, SourceLocation TemplateLoc,
- SourceLocation RAngleLoc, Decl *Param,
+ TemplateDecl *Template, SourceLocation TemplateKWLoc,
+ SourceLocation TemplateNameLoc, SourceLocation RAngleLoc, Decl *Param,
ArrayRef<TemplateArgument> SugaredConverted,
ArrayRef<TemplateArgument> CanonicalConverted, bool &HasDefaultArg) {
HasDefaultArg = false;
@@ -5293,8 +5270,8 @@ TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
HasDefaultArg = true;
TemplateArgumentLoc Output;
- if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc,
- TypeParm, SugaredConverted,
+ if (SubstDefaultTemplateArgument(*this, Template, TemplateNameLoc,
+ RAngleLoc, TypeParm, SugaredConverted,
CanonicalConverted, Output))
return TemplateArgumentLoc();
return Output;
@@ -5307,8 +5284,8 @@ TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
HasDefaultArg = true;
TemplateArgumentLoc Output;
- if (SubstDefaultTemplateArgument(*this, Template, TemplateLoc, RAngleLoc,
- NonTypeParm, SugaredConverted,
+ if (SubstDefaultTemplateArgument(*this, Template, TemplateNameLoc,
+ RAngleLoc, NonTypeParm, SugaredConverted,
CanonicalConverted, Output))
return TemplateArgumentLoc();
return Output;
@@ -5320,17 +5297,16 @@ TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
return TemplateArgumentLoc();
HasDefaultArg = true;
+ const TemplateArgumentLoc &A = TempTempParm->getDefaultArgument();
NestedNameSpecifierLoc QualifierLoc;
TemplateName TName = SubstDefaultTemplateArgument(
- *this, Template, TemplateLoc, RAngleLoc, TempTempParm, SugaredConverted,
- CanonicalConverted, QualifierLoc);
+ *this, Template, TemplateKWLoc, TemplateNameLoc, RAngleLoc, TempTempParm,
+ SugaredConverted, CanonicalConverted, QualifierLoc);
if (TName.isNull())
return TemplateArgumentLoc();
- return TemplateArgumentLoc(
- Context, TemplateArgument(TName),
- TempTempParm->getDefaultArgument().getTemplateQualifierLoc(),
- TempTempParm->getDefaultArgument().getTemplateNameLoc());
+ return TemplateArgumentLoc(Context, TemplateArgument(TName), TemplateKWLoc,
+ QualifierLoc, A.getTemplateNameLoc());
}
/// Convert a template-argument that we parsed as a type into a template, if
@@ -5338,33 +5314,24 @@ TemplateArgumentLoc Sema::SubstDefaultTemplateArgumentIfAvailable(
/// template template arguments and as template type arguments.
static TemplateArgumentLoc
convertTypeTemplateArgumentToTemplate(ASTContext &Context, TypeLoc TLoc) {
- // Extract and step over any surrounding nested-name-specifier.
- NestedNameSpecifierLoc QualLoc;
- if (auto ETLoc = TLoc.getAs<ElaboratedTypeLoc>()) {
- if (ETLoc.getTypePtr()->getKeyword() != ElaboratedTypeKeyword::None)
- return TemplateArgumentLoc();
+ auto TagLoc = TLoc.getAs<TagTypeLoc>();
+ if (!TagLoc)
+ return TemplateArgumentLoc();
- QualLoc = ETLoc.getQualifierLoc();
- TLoc = ETLoc.getNamedTypeLoc();
- }
// If this type was written as an injected-class-name, it can be used as a
// template template argument.
- if (auto InjLoc = TLoc.getAs<InjectedClassNameTypeLoc>())
- return TemplateArgumentLoc(Context, InjLoc.getTypePtr()->getTemplateName(),
- QualLoc, InjLoc.getNameLoc());
-
// If this type was written as an injected-class-name, it may have been
// converted to a RecordType during instantiation. If the RecordType is
// *not* wrapped in a TemplateSpecializationType and denotes a class
// template specialization, it must have come from an injected-class-name.
- if (auto RecLoc = TLoc.getAs<RecordTypeLoc>())
- if (auto *CTSD =
- dyn_cast<ClassTemplateSpecializationDecl>(RecLoc.getDecl()))
- return TemplateArgumentLoc(Context,
- TemplateName(CTSD->getSpecializedTemplate()),
- QualLoc, RecLoc.getNameLoc());
- return TemplateArgumentLoc();
+ TemplateName Name = TagLoc.getTypePtr()->getTemplateName(Context);
+ if (Name.isNull())
+ return TemplateArgumentLoc();
+
+ return TemplateArgumentLoc(Context, Name,
+ /*TemplateKWLoc=*/SourceLocation(),
+ TagLoc.getQualifierLoc(), TagLoc.getNameLoc());
}
bool Sema::CheckTemplateArgument(NamedDecl *Param, TemplateArgumentLoc &ArgLoc,
@@ -5897,8 +5864,8 @@ bool Sema::CheckTemplateArgumentList(
// (when the template parameter was part of a nested template) into
// the default argument.
TemplateArgumentLoc Arg = SubstDefaultTemplateArgumentIfAvailable(
- Template, TemplateLoc, RAngleLoc, *Param, CTAI.SugaredConverted,
- CTAI.CanonicalConverted, HasDefaultArg);
+ Template, /*TemplateKWLoc=*/SourceLocation(), TemplateLoc, RAngleLoc,
+ *Param, CTAI.SugaredConverted, CTAI.CanonicalConverted, HasDefaultArg);
if (Arg.getArgument().isNull()) {
if (!HasDefaultArg) {
@@ -6042,7 +6009,7 @@ namespace {
#include "clang/AST/TypeNodes.inc"
bool VisitTagDecl(const TagDecl *Tag);
- bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS);
+ bool VisitNestedNameSpecifier(NestedNameSpecifier NNS);
};
} // end anonymous namespace
@@ -6187,11 +6154,11 @@ bool UnnamedLocalNoLinkageFinder::VisitDeducedTemplateSpecializationType(
}
bool UnnamedLocalNoLinkageFinder::VisitRecordType(const RecordType* T) {
- return VisitTagDecl(T->getDecl());
+ return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf());
}
bool UnnamedLocalNoLinkageFinder::VisitEnumType(const EnumType* T) {
- return VisitTagDecl(T->getDecl());
+ return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf());
}
bool UnnamedLocalNoLinkageFinder::VisitTemplateTypeParmType(
@@ -6211,7 +6178,7 @@ bool UnnamedLocalNoLinkageFinder::VisitTemplateSpecializationType(
bool UnnamedLocalNoLinkageFinder::VisitInjectedClassNameType(
const InjectedClassNameType* T) {
- return VisitTagDecl(T->getDecl());
+ return VisitTagDecl(T->getOriginalDecl()->getDefinitionOrSelf());
}
bool UnnamedLocalNoLinkageFinder::VisitDependentNameType(
@@ -6221,10 +6188,7 @@ bool UnnamedLocalNoLinkageFinder::VisitDependentNameType(
bool UnnamedLocalNoLinkageFinder::VisitDependentTemplateSpecializationType(
const DependentTemplateSpecializationType* T) {
- if (auto *Q = T->getDependentTemplateName().getQualifier())
- return VisitNestedNameSpecifier(Q);
-
- return false;
+ return VisitNestedNameSpecifier(T->getDependentTemplateName().getQualifier());
}
bool UnnamedLocalNoLinkageFinder::VisitPackExpansionType(
@@ -6270,11 +6234,10 @@ bool UnnamedLocalNoLinkageFinder::VisitDependentBitIntType(
bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
if (Tag->getDeclContext()->isFunctionOrMethod()) {
- S.Diag(SR.getBegin(),
- S.getLangOpts().CPlusPlus11 ?
- diag::warn_cxx98_compat_template_arg_local_type :
- diag::ext_template_arg_local_type)
- << S.Context.getTypeDeclType(Tag) << SR;
+ S.Diag(SR.getBegin(), S.getLangOpts().CPlusPlus11
+ ? diag::warn_cxx98_compat_template_arg_local_type
+ : diag::ext_template_arg_local_type)
+ << S.Context.getCanonicalTagType(Tag) << SR;
return true;
}
@@ -6291,21 +6254,15 @@ bool UnnamedLocalNoLinkageFinder::VisitTagDecl(const TagDecl *Tag) {
}
bool UnnamedLocalNoLinkageFinder::VisitNestedNameSpecifier(
- NestedNameSpecifier *NNS) {
- assert(NNS);
- if (NNS->getPrefix() && VisitNestedNameSpecifier(NNS->getPrefix()))
- return true;
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Super:
+ NestedNameSpecifier NNS) {
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Namespace:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
return false;
-
- case NestedNameSpecifier::TypeSpec:
- return Visit(QualType(NNS->getAsType(), 0));
+ case NestedNameSpecifier::Kind::Type:
+ return Visit(QualType(NNS.getAsType(), 0));
}
llvm_unreachable("Invalid NestedNameSpecifier::Kind!");
}
@@ -7266,7 +7223,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
// that case, this may extend the argument from 1 bit to 8 bits.
QualType IntegerType = ParamType;
if (const EnumType *Enum = IntegerType->getAs<EnumType>())
- IntegerType = Enum->getDecl()->getIntegerType();
+ IntegerType =
+ Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
Value = Value.extOrTrunc(IntegerType->isBitIntType()
? Context.getIntWidth(IntegerType)
: Context.getTypeSize(IntegerType));
@@ -7364,7 +7322,8 @@ ExprResult Sema::CheckTemplateArgument(NonTypeTemplateParmDecl *Param,
QualType IntegerType = ParamType;
if (const EnumType *Enum = IntegerType->getAs<EnumType>()) {
- IntegerType = Enum->getDecl()->getIntegerType();
+ IntegerType =
+ Enum->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
}
if (ParamType->isBooleanType()) {
@@ -7727,10 +7686,9 @@ ExprResult Sema::BuildExpressionFromDeclTemplateArgument(
assert(VD->getDeclContext()->isRecord() &&
(isa<CXXMethodDecl>(VD) || isa<FieldDecl>(VD) ||
isa<IndirectFieldDecl>(VD)));
- QualType ClassType
- = Context.getTypeDeclType(cast<RecordDecl>(VD->getDeclContext()));
- NestedNameSpecifier *Qualifier =
- NestedNameSpecifier::Create(Context, nullptr, ClassType.getTypePtr());
+ CanQualType ClassType =
+ Context.getCanonicalTagType(cast<RecordDecl>(VD->getDeclContext()));
+ NestedNameSpecifier Qualifier(ClassType.getTypePtr());
SS.MakeTrivial(Context, Qualifier, Loc);
}
@@ -7822,7 +7780,7 @@ static Expr *BuildExpressionFromIntegralTemplateArgumentValue(
// type of literal for it.
QualType T = OrigT;
if (const EnumType *ET = OrigT->getAs<EnumType>())
- T = ET->getDecl()->getIntegerType();
+ T = ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType();
Expr *E;
if (T->isAnyCharacterType()) {
@@ -8691,7 +8649,6 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
isPartialSpecialization))
return true;
- QualType CanonType;
if (!isPartialSpecialization) {
// Create a new class template specialization declaration node for
// this explicit specialization or friend declaration.
@@ -8707,18 +8664,14 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
if (!PrevDecl)
ClassTemplate->AddSpecialization(Specialization, InsertPos);
-
- if (!CurContext->isDependentContext())
- CanonType = Context.getTypeDeclType(Specialization);
- }
-
- TypeSourceInfo *WrittenTy = Context.getTemplateSpecializationTypeInfo(
- Name, TemplateNameLoc, TemplateArgs, CTAI.CanonicalConverted, CanonType);
-
- if (isPartialSpecialization) {
+ } else {
+ CanQualType CanonType = CanQualType::CreateUnsafe(
+ Context.getCanonicalTemplateSpecializationType(
+ TemplateName(ClassTemplate->getCanonicalDecl()),
+ CTAI.CanonicalConverted));
if (Context.hasSameType(
- WrittenTy->getType(),
- ClassTemplate->getInjectedClassNameSpecialization()) &&
+ CanonType,
+ ClassTemplate->getCanonicalInjectedSpecializationType(Context)) &&
(!Context.getLangOpts().CPlusPlus20 ||
!TemplateParams->hasAssociatedConstraints())) {
// C++ [temp.class.spec]p9b3:
@@ -8740,13 +8693,12 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
}
// Create a new class template partial specialization declaration node.
- ClassTemplatePartialSpecializationDecl *PrevPartial
- = cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
+ ClassTemplatePartialSpecializationDecl *PrevPartial =
+ cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl);
ClassTemplatePartialSpecializationDecl *Partial =
ClassTemplatePartialSpecializationDecl::Create(
Context, Kind, DC, KWLoc, TemplateNameLoc, TemplateParams,
- ClassTemplate, CTAI.CanonicalConverted, WrittenTy->getType(),
- PrevPartial);
+ ClassTemplate, CTAI.CanonicalConverted, CanonType, PrevPartial);
Partial->setTemplateArgsAsWritten(TemplateArgs);
SetNestedNameSpecifier(*this, Partial, SS);
if (TemplateParameterLists.size() > 1 && SS.isSet()) {
@@ -8785,7 +8737,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
if (!Okay) {
SourceRange Range(TemplateNameLoc, RAngleLoc);
Diag(TemplateNameLoc, diag::err_specialization_after_instantiation)
- << Context.getTypeDeclType(Specialization) << Range;
+ << Context.getCanonicalTagType(Specialization) << Range;
Diag(PrevDecl->getPointOfInstantiation(),
diag::note_instantiation_required_here)
@@ -8848,6 +8800,13 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
Specialization->startDefinition();
if (TUK == TagUseKind::Friend) {
+ CanQualType CanonType = Context.getCanonicalTagType(Specialization);
+ TypeSourceInfo *WrittenTy = Context.getTemplateSpecializationTypeInfo(
+ ElaboratedTypeKeyword::None, /*ElaboratedKeywordLoc=*/SourceLocation(),
+ SS.getWithLocInContext(Context),
+ /*TemplateKeywordLoc=*/SourceLocation(), Name, TemplateNameLoc,
+ TemplateArgs, CTAI.CanonicalConverted, CanonType);
+
// Build the fully-sugared type for this class template
// specialization as the user wrote in the specialization
// itself. This means that we'll pretty-print the type retrieved
@@ -9884,9 +9843,6 @@ static bool CheckExplicitInstantiation(Sema &S, NamedDecl *D,
/// Determine whether the given scope specifier has a template-id in it.
static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
- if (!SS.isSet())
- return false;
-
// C++11 [temp.explicit]p3:
// If the explicit instantiation is for a member function, a member class
// or a static data member of a class template specialization, the name of
@@ -9894,12 +9850,14 @@ static bool ScopeSpecifierHasTemplateId(const CXXScopeSpec &SS) {
// name shall be a simple-template-id.
//
// C++98 has the same restriction, just worded differently.
- for (NestedNameSpecifier *NNS = SS.getScopeRep(); NNS;
- NNS = NNS->getPrefix())
- if (const Type *T = NNS->getAsType())
- if (isa<TemplateSpecializationType>(T))
- return true;
-
+ for (NestedNameSpecifier NNS = SS.getScopeRep();
+ NNS.getKind() == NestedNameSpecifier::Kind::Type;
+ /**/) {
+ const Type *T = NNS.getAsType();
+ if (isa<TemplateSpecializationType>(T))
+ return true;
+ NNS = T->getPrefix();
+ }
return false;
}
@@ -10254,7 +10212,7 @@ Sema::ActOnExplicitInstantiation(Scope *S, SourceLocation ExternLoc,
CXXRecordDecl *Pattern = Record->getInstantiatedFromMemberClass();
if (!Pattern) {
Diag(TemplateLoc, diag::err_explicit_instantiation_nontemplate_type)
- << Context.getTypeDeclType(Record);
+ << Context.getCanonicalTagType(Record);
Diag(Record->getLocation(), diag::note_nontemplate_decl_here);
return true;
}
@@ -10801,7 +10759,7 @@ TypeResult Sema::ActOnDependentTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// This has to hold, because SS is expected to be defined.
assert(Name && "Expected a name in a dependent tag");
- NestedNameSpecifier *NNS = SS.getScopeRep();
+ NestedNameSpecifier NNS = SS.getScopeRep();
if (!NNS)
return true;
@@ -10913,7 +10871,10 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
return CreateParsedType(T, Builder.getTypeSourceInfo(Context, T));
}
- QualType T = CheckTemplateIdType(Template, TemplateIILoc, TemplateArgs);
+ QualType T = CheckTemplateIdType(TypenameLoc.isValid()
+ ? ElaboratedTypeKeyword::Typename
+ : ElaboratedTypeKeyword::None,
+ Template, TemplateIILoc, TemplateArgs);
if (T.isNull())
return true;
@@ -10921,18 +10882,8 @@ Sema::ActOnTypenameType(Scope *S, SourceLocation TypenameLoc,
TypeLocBuilder Builder;
TemplateSpecializationTypeLoc SpecTL
= Builder.push<TemplateSpecializationTypeLoc>(T);
- SpecTL.setTemplateKeywordLoc(TemplateKWLoc);
- SpecTL.setTemplateNameLoc(TemplateIILoc);
- SpecTL.setLAngleLoc(LAngleLoc);
- SpecTL.setRAngleLoc(RAngleLoc);
- for (unsigned I = 0, N = TemplateArgs.size(); I != N; ++I)
- SpecTL.setArgLocInfo(I, TemplateArgs[I].getLocInfo());
-
- T = Context.getElaboratedType(Keyword, SS.getScopeRep(), T);
- ElaboratedTypeLoc TL = Builder.push<ElaboratedTypeLoc>(T);
- TL.setElaboratedKeywordLoc(TypenameLoc);
- TL.setQualifierLoc(SS.getWithLocInContext(Context));
-
+ SpecTL.set(TypenameLoc, SS.getWithLocInContext(Context), TemplateKWLoc,
+ TemplateIILoc, TemplateArgs);
TypeSourceInfo *TSI = Builder.getTypeSourceInfo(Context, T);
return CreateParsedType(T, TSI);
}
@@ -10946,11 +10897,12 @@ static bool isEnableIf(NestedNameSpecifierLoc NNS, const IdentifierInfo &II,
return false;
// ... within an explicitly-written template specialization...
- if (!NNS || !NNS.getNestedNameSpecifier()->getAsType())
+ if (NNS.getNestedNameSpecifier().getKind() != NestedNameSpecifier::Kind::Type)
return false;
- TypeLoc EnableIfTy = NNS.getTypeLoc();
- TemplateSpecializationTypeLoc EnableIfTSTLoc =
- EnableIfTy.getAs<TemplateSpecializationTypeLoc>();
+
+ // FIXME: Look through sugar.
+ auto EnableIfTSTLoc =
+ NNS.castAsTypeLoc().getAs<TemplateSpecializationTypeLoc>();
if (!EnableIfTSTLoc || EnableIfTSTLoc.getNumArgs() == 0)
return false;
const TemplateSpecializationType *EnableIfTST = EnableIfTSTLoc.getTypePtr();
@@ -10998,19 +10950,33 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
if (T.isNull())
return QualType();
- *TSI = Context.CreateTypeSourceInfo(T);
+ TypeLocBuilder TLB;
if (isa<DependentNameType>(T)) {
- DependentNameTypeLoc TL =
- (*TSI)->getTypeLoc().castAs<DependentNameTypeLoc>();
+ auto TL = TLB.push<DependentNameTypeLoc>(T);
TL.setElaboratedKeywordLoc(KeywordLoc);
TL.setQualifierLoc(QualifierLoc);
TL.setNameLoc(IILoc);
- } else {
- ElaboratedTypeLoc TL = (*TSI)->getTypeLoc().castAs<ElaboratedTypeLoc>();
+ } else if (isa<DeducedTemplateSpecializationType>(T)) {
+ auto TL = TLB.push<DeducedTemplateSpecializationTypeLoc>(T);
+ TL.setElaboratedKWLoc(KeywordLoc);
+ TL.setQualifierLoc(QualifierLoc);
+ TL.setNameLoc(IILoc);
+ } else if (isa<TemplateTypeParmType>(T)) {
+ // FIXME: There might be a 'typename' keyword here, but we just drop it
+ // as it can't be represented.
+ assert(!QualifierLoc);
+ TLB.pushTypeSpec(T).setNameLoc(IILoc);
+ } else if (isa<TagType>(T)) {
+ auto TL = TLB.push<TagTypeLoc>(T);
TL.setElaboratedKeywordLoc(KeywordLoc);
TL.setQualifierLoc(QualifierLoc);
- TL.getNamedTypeLoc().castAs<TypeSpecTypeLoc>().setNameLoc(IILoc);
+ TL.setNameLoc(IILoc);
+ } else if (isa<TypedefType>(T)) {
+ TLB.push<TypedefTypeLoc>(T).set(KeywordLoc, QualifierLoc, IILoc);
+ } else {
+ TLB.push<UnresolvedUsingTypeLoc>(T).set(KeywordLoc, QualifierLoc, IILoc);
}
+ *TSI = TLB.getTypeSourceInfo(Context, T);
return T;
}
@@ -11033,7 +10999,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
if (!Ctx) {
// If the nested-name-specifier is dependent and couldn't be
// resolved to a type, build a typename type.
- assert(QualifierLoc.getNestedNameSpecifier()->isDependent());
+ assert(QualifierLoc.getNestedNameSpecifier().isDependent());
return Context.getDependentNameType(Keyword,
QualifierLoc.getNestedNameSpecifier(),
&II);
@@ -11115,6 +11081,7 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
&II);
case LookupResultKind::Found:
+ // FXIME: Missing support for UsingShadowDecl on this path?
if (TypeDecl *Type = dyn_cast<TypeDecl>(Result.getFoundDecl())) {
// C++ [class.qual]p2:
// In a lookup in which function names are not ignored and the
@@ -11130,15 +11097,20 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
//
// FIXME: That's not strictly true: mem-initializer-id lookup does not
// ignore functions, but that appears to be an oversight.
- QualType T = getTypeDeclType(Ctx,
- Keyword == ElaboratedTypeKeyword::Typename
- ? DiagCtorKind::Typename
- : DiagCtorKind::None,
- Type, IILoc);
- // We found a type. Build an ElaboratedType, since the
- // typename-specifier was just sugar.
- return Context.getElaboratedType(
- Keyword, QualifierLoc.getNestedNameSpecifier(), T);
+ checkTypeDeclType(Ctx,
+ Keyword == ElaboratedTypeKeyword::Typename
+ ? DiagCtorKind::Typename
+ : DiagCtorKind::None,
+ Type, IILoc);
+ // FIXME: This appears to be the only case where a template type parameter
+ // can have an elaborated keyword. We should preserve it somehow.
+ if (isa<TemplateTypeParmDecl>(Type)) {
+ assert(Keyword == ElaboratedTypeKeyword::Typename);
+ assert(!QualifierLoc);
+ Keyword = ElaboratedTypeKeyword::None;
+ }
+ return Context.getTypeDeclType(
+ Keyword, QualifierLoc.getNestedNameSpecifier(), Type);
}
// C++ [dcl.type.simple]p2:
@@ -11148,22 +11120,22 @@ Sema::CheckTypenameType(ElaboratedTypeKeyword Keyword,
if (getLangOpts().CPlusPlus17) {
if (auto *TD = getAsTypeTemplateDecl(Result.getFoundDecl())) {
if (!DeducedTSTContext) {
- QualType T(QualifierLoc
- ? QualifierLoc.getNestedNameSpecifier()->getAsType()
- : nullptr, 0);
- if (!T.isNull())
+ NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
+ if (Qualifier.getKind() == NestedNameSpecifier::Kind::Type)
Diag(IILoc, diag::err_dependent_deduced_tst)
- << (int)getTemplateNameKindForDiagnostics(TemplateName(TD)) << T;
+ << (int)getTemplateNameKindForDiagnostics(TemplateName(TD))
+ << QualType(Qualifier.getAsType(), 0);
else
Diag(IILoc, diag::err_deduced_tst)
<< (int)getTemplateNameKindForDiagnostics(TemplateName(TD));
NoteTemplateLocation(*TD);
return QualType();
}
- return Context.getElaboratedType(
- Keyword, QualifierLoc.getNestedNameSpecifier(),
- Context.getDeducedTemplateSpecializationType(TemplateName(TD),
- QualType(), false));
+ TemplateName Name = Context.getQualifiedTemplateName(
+ QualifierLoc.getNestedNameSpecifier(), /*TemplateKeyword=*/false,
+ TemplateName(TD));
+ return Context.getDeducedTemplateSpecializationType(
+ Keyword, Name, /*DeducedType=*/QualType(), /*IsDependent=*/false);
}
}
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 94edd553aacd7..cebe2203a8407 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -613,38 +613,29 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
TemplateDeductionInfo &Info, bool PartialOrdering,
SmallVectorImpl<DeducedTemplateArgument> &Deduced,
bool *HasDeducedAnyParam) {
- QualType UP = P;
- if (const auto *IP = P->getAs<InjectedClassNameType>())
- UP = IP->getInjectedSpecializationType();
-
- assert(isa<TemplateSpecializationType>(UP.getCanonicalType()));
- const TemplateSpecializationType *TP = ::getLastTemplateSpecType(UP);
- TemplateName TNP = TP->getTemplateName();
+ TemplateName TNP;
+ ArrayRef<TemplateArgument> PResolved;
+ if (isa<TemplateSpecializationType>(P.getCanonicalType())) {
+ const TemplateSpecializationType *TP = ::getLastTemplateSpecType(P);
+ TNP = TP->getTemplateName();
+ // FIXME: To preserve sugar, the TST needs to carry sugared resolved
+ // arguments.
+ PResolved = TP->getCanonicalTypeInternal()
+ ->castAs<TemplateSpecializationType>()
+ ->template_arguments();
+ } else {
+ const auto *TT = P->castAs<InjectedClassNameType>();
+ TNP = TT->getTemplateName(S.Context);
+ PResolved = TT->getTemplateArgs(S.Context);
+ }
// If the parameter is an alias template, there is nothing to deduce.
if (const auto *TD = TNP.getAsTemplateDecl(); TD && TD->isTypeAlias())
return TemplateDeductionResult::Success;
- // FIXME: To preserve sugar, the TST needs to carry sugared resolved
- // arguments.
- ArrayRef<TemplateArgument> PResolved =
- TP->getCanonicalTypeInternal()
- ->castAs<TemplateSpecializationType>()
- ->template_arguments();
-
- QualType UA = A;
- std::optional<NestedNameSpecifier *> NNS;
- // Treat an injected-class-name as its underlying template-id.
- if (const auto *Elaborated = A->getAs<ElaboratedType>()) {
- NNS = Elaborated->getQualifier();
- } else if (const auto *Injected = A->getAs<InjectedClassNameType>()) {
- UA = Injected->getInjectedSpecializationType();
- NNS = nullptr;
- }
-
// Check whether the template argument is a dependent template-id.
- if (isa<TemplateSpecializationType>(UA.getCanonicalType())) {
- const TemplateSpecializationType *SA = ::getLastTemplateSpecType(UA);
+ if (isa<TemplateSpecializationType>(A.getCanonicalType())) {
+ const TemplateSpecializationType *SA = ::getLastTemplateSpecType(A);
TemplateName TNA = SA->getTemplateName();
// If the argument is an alias template, there is nothing to deduce.
@@ -678,34 +669,36 @@ DeduceTemplateSpecArguments(Sema &S, TemplateParameterList *TemplateParams,
// If the argument type is a class template specialization, we
// perform template argument deduction using its template
// arguments.
- const auto *RA = UA->getAs<RecordType>();
- const auto *SA =
- RA ? dyn_cast<ClassTemplateSpecializationDecl>(RA->getDecl()) : nullptr;
- if (!SA) {
+ const auto *TA = A->getAs<TagType>();
+ TemplateName TNA;
+ if (TA) {
+ // FIXME: Can't use the template arguments from this TST, as they are not
+ // resolved.
+ if (const auto *TST = A->getAsNonAliasTemplateSpecializationType())
+ TNA = TST->getTemplateName();
+ else
+ TNA = TA->getTemplateName(S.Context);
+ }
+ if (TNA.isNull()) {
Info.FirstArg = TemplateArgument(P);
Info.SecondArg = TemplateArgument(A);
return TemplateDeductionResult::NonDeducedMismatch;
}
- TemplateName TNA = TemplateName(SA->getSpecializedTemplate());
- if (NNS)
- TNA = S.Context.getQualifiedTemplateName(
- *NNS, false, TemplateName(SA->getSpecializedTemplate()));
-
+ ArrayRef<TemplateArgument> AResolved = TA->getTemplateArgs(S.Context);
// Perform template argument deduction for the template name.
- if (auto Result = DeduceTemplateArguments(
- S, TemplateParams, TNP, TNA, Info,
- /*DefaultArguments=*/SA->getTemplateArgs().asArray(), PartialOrdering,
- Deduced, HasDeducedAnyParam);
+ if (auto Result =
+ DeduceTemplateArguments(S, TemplateParams, TNP, TNA, Info,
+ /*DefaultArguments=*/AResolved,
+ PartialOrdering, Deduced, HasDeducedAnyParam);
Result != TemplateDeductionResult::Success)
return Result;
// Perform template argument deduction for the template arguments.
- return DeduceTemplateArguments(S, TemplateParams, PResolved,
- SA->getTemplateArgs().asArray(), Info, Deduced,
- /*NumberOfArgumentsMustMatch=*/true,
- PartialOrdering, PackFold::ParameterToArgument,
- HasDeducedAnyParam);
+ return DeduceTemplateArguments(
+ S, TemplateParams, PResolved, AResolved, Info, Deduced,
+ /*NumberOfArgumentsMustMatch=*/true, PartialOrdering,
+ PackFold::ParameterToArgument, HasDeducedAnyParam);
}
static bool IsPossiblyOpaquelyQualifiedTypeInternal(const Type *T) {
@@ -2110,26 +2103,19 @@ static TemplateDeductionResult DeduceTemplateArgumentsByTypeMatch(
Result != TemplateDeductionResult::Success)
return Result;
- QualType TP;
- if (MPP->isSugared()) {
- TP = S.Context.getTypeDeclType(MPP->getMostRecentCXXRecordDecl());
- } else {
- NestedNameSpecifier *QP = MPP->getQualifier();
- if (QP->getKind() == NestedNameSpecifier::Identifier)
- // Skip translation if it's a non-deduced context anyway.
- return TemplateDeductionResult::Success;
- TP = QualType(QP->translateToType(S.Context), 0);
- }
+ QualType TP =
+ MPP->isSugared()
+ ? S.Context.getCanonicalTagType(MPP->getMostRecentCXXRecordDecl())
+ : QualType(MPP->getQualifier().getAsType(), 0);
assert(!TP.isNull() && "member pointer with non-type class");
- QualType TA;
- if (MPA->isSugared()) {
- TA = S.Context.getTypeDeclType(MPA->getMostRecentCXXRecordDecl());
- } else {
- NestedNameSpecifier *QA = MPA->getQualifier();
- TA = QualType(QA->translateToType(S.Context), 0).getUnqualifiedType();
- }
+ QualType TA =
+ MPA->isSugared()
+ ? S.Context.getCanonicalTagType(MPA->getMostRecentCXXRecordDecl())
+ : QualType(MPA->getQualifier().getAsType(), 0)
+ .getUnqualifiedType();
assert(!TA.isNull() && "member pointer with non-type class");
+
return DeduceTemplateArgumentsByTypeMatch(
S, TemplateParams, TP, TA, Info, Deduced, SubTDF,
degradeCallPartialOrderingKind(POK),
@@ -2853,13 +2839,11 @@ Sema::getTrivialTemplateArgumentLoc(const TemplateArgument &Arg,
else if (QualifiedTemplateName *QTN =
Template.getAsQualifiedTemplateName())
Builder.MakeTrivial(Context, QTN->getQualifier(), Loc);
-
- if (Arg.getKind() == TemplateArgument::Template)
- return TemplateArgumentLoc(Context, Arg,
- Builder.getWithLocInContext(Context), Loc);
-
return TemplateArgumentLoc(
- Context, Arg, Builder.getWithLocInContext(Context), Loc, Loc);
+ Context, Arg, Loc, Builder.getWithLocInContext(Context), Loc,
+ /*EllipsisLoc=*/Arg.getKind() == TemplateArgument::TemplateExpansion
+ ? Loc
+ : SourceLocation());
}
case TemplateArgument::Expression:
@@ -3077,8 +3061,9 @@ static TemplateDeductionResult ConvertDeducedTemplateArguments(
S.getLangOpts().CPlusPlus17);
DefArg = S.SubstDefaultTemplateArgumentIfAvailable(
- TD, TD->getLocation(), TD->getSourceRange().getEnd(), Param,
- CTAI.SugaredConverted, CTAI.CanonicalConverted, HasDefaultArg);
+ TD, /*TemplateKWLoc=*/SourceLocation(), TD->getLocation(),
+ TD->getSourceRange().getEnd(), Param, CTAI.SugaredConverted,
+ CTAI.CanonicalConverted, HasDefaultArg);
}
// If there was no default argument, deduction is incomplete.
@@ -3437,7 +3422,7 @@ Sema::DeduceTemplateArgumentsFromType(TemplateDecl *TD, QualType FromType,
QualType PType;
if (const auto *CTD = dyn_cast<ClassTemplateDecl>(TD)) {
// Use the InjectedClassNameType.
- PType = Context.getTypeDeclType(CTD->getTemplatedDecl());
+ PType = Context.getCanonicalTagType(CTD->getTemplatedDecl());
} else if (const auto *AliasTemplate = dyn_cast<TypeAliasTemplateDecl>(TD)) {
PType = AliasTemplate->getTemplatedDecl()->getUnderlyingType();
} else {
@@ -4103,7 +4088,7 @@ static QualType GetTypeOfFunction(Sema &S, const OverloadExpr::FindResult &R,
return {};
return S.Context.getMemberPointerType(
- Fn->getType(), /*Qualifier=*/nullptr, Method->getParent());
+ Fn->getType(), /*Qualifier=*/std::nullopt, Method->getParent());
}
if (!R.IsAddressOfOperand) return Fn->getType();
@@ -5058,10 +5043,12 @@ namespace {
return TransformDesugared(TLB, TL);
QualType Result = SemaRef.Context.getDeducedTemplateSpecializationType(
- TL.getTypePtr()->getTemplateName(),
+ TL.getTypePtr()->getKeyword(), TL.getTypePtr()->getTemplateName(),
Replacement, Replacement.isNull());
auto NewTL = TLB.push<DeducedTemplateSpecializationTypeLoc>(Result);
+ NewTL.setElaboratedKWLoc(TL.getElaboratedKWLoc());
NewTL.setNameLoc(TL.getNameLoc());
+ NewTL.setQualifierLoc(TL.getQualifierLoc());
return Result;
}
@@ -6376,8 +6363,8 @@ Sema::getMoreSpecializedPartialSpecialization(
ClassTemplatePartialSpecializationDecl *PS1,
ClassTemplatePartialSpecializationDecl *PS2,
SourceLocation Loc) {
- QualType PT1 = PS1->getInjectedSpecializationType().getCanonicalType();
- QualType PT2 = PS2->getInjectedSpecializationType().getCanonicalType();
+ QualType PT1 = PS1->getCanonicalInjectedSpecializationType(Context);
+ QualType PT2 = PS2->getCanonicalInjectedSpecializationType(Context);
TemplateDeductionInfo Info(Loc);
return getMoreSpecialized(*this, PT1, PT2, PS1, PS2, Info);
@@ -6386,9 +6373,8 @@ Sema::getMoreSpecializedPartialSpecialization(
bool Sema::isMoreSpecializedThanPrimary(
ClassTemplatePartialSpecializationDecl *Spec, TemplateDeductionInfo &Info) {
ClassTemplateDecl *Primary = Spec->getSpecializedTemplate();
- QualType PrimaryT =
- Primary->getInjectedClassNameSpecialization().getCanonicalType();
- QualType PartialT = Spec->getInjectedSpecializationType().getCanonicalType();
+ QualType PrimaryT = Primary->getCanonicalInjectedSpecializationType(Context);
+ QualType PartialT = Spec->getCanonicalInjectedSpecializationType(Context);
ClassTemplatePartialSpecializationDecl *MaybeSpec =
getMoreSpecialized(*this, PartialT, PrimaryT, Spec, Primary, Info);
@@ -6672,19 +6658,13 @@ MarkUsedTemplateParameters(ASTContext &Ctx,
/// Mark the template parameters that are used by the given
/// nested name specifier.
-static void
-MarkUsedTemplateParameters(ASTContext &Ctx,
- NestedNameSpecifier *NNS,
- bool OnlyDeduced,
- unsigned Depth,
- llvm::SmallBitVector &Used) {
- if (!NNS)
+static void MarkUsedTemplateParameters(ASTContext &Ctx, NestedNameSpecifier NNS,
+ bool OnlyDeduced, unsigned Depth,
+ llvm::SmallBitVector &Used) {
+ if (NNS.getKind() != NestedNameSpecifier::Kind::Type)
return;
-
- MarkUsedTemplateParameters(Ctx, NNS->getPrefix(), OnlyDeduced, Depth,
- Used);
- MarkUsedTemplateParameters(Ctx, QualType(NNS->getAsType(), 0),
- OnlyDeduced, Depth, Used);
+ MarkUsedTemplateParameters(Ctx, QualType(NNS.getAsType(), 0), OnlyDeduced,
+ Depth, Used);
}
/// Mark the template parameters that are used by the given
@@ -6758,7 +6738,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
MarkUsedTemplateParameters(Ctx, MemPtr->getPointeeType(), OnlyDeduced,
Depth, Used);
MarkUsedTemplateParameters(Ctx,
- QualType(MemPtr->getQualifier()->getAsType(), 0),
+ QualType(MemPtr->getQualifier().getAsType(), 0),
OnlyDeduced, Depth, Used);
break;
}
@@ -6876,7 +6856,7 @@ MarkUsedTemplateParameters(ASTContext &Ctx, QualType T,
}
case Type::InjectedClassName:
- T = cast<InjectedClassNameType>(T)->getInjectedSpecializationType();
+ T = cast<InjectedClassNameType>(T)->getCanonicalInjectedTST();
[[fallthrough]];
case Type::TemplateSpecialization: {
diff --git a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
index bdc46a0115a45..4a7b31a942f31 100644
--- a/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
+++ b/clang/lib/Sema/SemaTemplateDeductionGuide.cpp
@@ -105,22 +105,21 @@ class ExtractTypeForDeductionGuide
return false;
}
- QualType
- RebuildTemplateSpecializationType(TemplateName Template,
- SourceLocation TemplateNameLoc,
- TemplateArgumentListInfo &TemplateArgs) {
+ QualType RebuildTemplateSpecializationType(
+ ElaboratedTypeKeyword Keyword, TemplateName Template,
+ SourceLocation TemplateNameLoc, TemplateArgumentListInfo &TemplateArgs) {
if (!OuterInstantiationArgs ||
!isa_and_present<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()))
- return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
- TemplateArgs);
+ return Base::RebuildTemplateSpecializationType(
+ Keyword, Template, TemplateNameLoc, TemplateArgs);
auto *TATD = cast<TypeAliasTemplateDecl>(Template.getAsTemplateDecl());
auto *Pattern = TATD;
while (Pattern->getInstantiatedFromMemberTemplate())
Pattern = Pattern->getInstantiatedFromMemberTemplate();
if (!mightReferToOuterTemplateParameters(Pattern->getTemplatedDecl()))
- return Base::RebuildTemplateSpecializationType(Template, TemplateNameLoc,
- TemplateArgs);
+ return Base::RebuildTemplateSpecializationType(
+ Keyword, Template, TemplateNameLoc, TemplateArgs);
Decl *NewD =
TypedefNameInstantiator->InstantiateTypeAliasTemplateDecl(TATD);
@@ -131,13 +130,14 @@ class ExtractTypeForDeductionGuide
MaterializedTypedefs.push_back(NewTATD->getTemplatedDecl());
return Base::RebuildTemplateSpecializationType(
- TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
+ Keyword, TemplateName(NewTATD), TemplateNameLoc, TemplateArgs);
}
QualType TransformTypedefType(TypeLocBuilder &TLB, TypedefTypeLoc TL) {
ASTContext &Context = SemaRef.getASTContext();
- TypedefNameDecl *OrigDecl = TL.getTypedefNameDecl();
+ TypedefNameDecl *OrigDecl = TL.getDecl();
TypedefNameDecl *Decl = OrigDecl;
+ const TypedefType *T = TL.getTypePtr();
// Transform the underlying type of the typedef and clone the Decl only if
// the typedef has a dependent context.
bool InDependentContext = OrigDecl->getDeclContext()->isDependentContext();
@@ -155,7 +155,7 @@ class ExtractTypeForDeductionGuide
// };
// };
if (OuterInstantiationArgs && InDependentContext &&
- TL.getTypePtr()->isInstantiationDependentType()) {
+ T->isInstantiationDependentType()) {
Decl = cast_if_present<TypedefNameDecl>(
TypedefNameInstantiator->InstantiateTypedefNameDecl(
OrigDecl, /*IsTypeAlias=*/isa<TypeAliasDecl>(OrigDecl)));
@@ -180,10 +180,17 @@ class ExtractTypeForDeductionGuide
MaterializedTypedefs.push_back(Decl);
}
- QualType TDTy = Context.getTypedefType(Decl);
- TypedefTypeLoc TypedefTL = TLB.push<TypedefTypeLoc>(TDTy);
- TypedefTL.setNameLoc(TL.getNameLoc());
+ NestedNameSpecifierLoc QualifierLoc = TL.getQualifierLoc();
+ if (QualifierLoc) {
+ QualifierLoc = getDerived().TransformNestedNameSpecifierLoc(QualifierLoc);
+ if (!QualifierLoc)
+ return QualType();
+ }
+ QualType TDTy = Context.getTypedefType(
+ T->getKeyword(), QualifierLoc.getNestedNameSpecifier(), Decl);
+ TLB.push<TypedefTypeLoc>(TDTy).set(TL.getElaboratedKeywordLoc(),
+ QualifierLoc, TL.getNameLoc());
return TDTy;
}
};
@@ -327,7 +334,7 @@ struct ConvertConstructorToDeductionGuideTransform {
DeclarationName DeductionGuideName =
SemaRef.Context.DeclarationNames.getCXXDeductionGuideName(Template);
- QualType DeducedType = SemaRef.Context.getTypeDeclType(Primary);
+ QualType DeducedType = SemaRef.Context.getCanonicalTagType(Primary);
// Index adjustment to apply to convert depth-1 template parameters into
// depth-0 template parameters.
@@ -593,7 +600,10 @@ struct ConvertConstructorToDeductionGuideTransform {
// context of the template), so implicit deduction guides can never collide
// with explicit ones.
QualType ReturnType = DeducedType;
- TLB.pushTypeSpec(ReturnType).setNameLoc(Primary->getLocation());
+ auto TTL = TLB.push<TagTypeLoc>(ReturnType);
+ TTL.setElaboratedKeywordLoc(SourceLocation());
+ TTL.setQualifierLoc(NestedNameSpecifierLoc());
+ TTL.setNameLoc(Primary->getLocation());
// Resolving a wording defect, we also inherit the variadicness of the
// constructor.
@@ -954,7 +964,8 @@ Expr *buildIsDeducibleConstraint(Sema &SemaRef,
SmallVector<TypeSourceInfo *> IsDeducibleTypeTraitArgs = {
Context.getTrivialTypeSourceInfo(
Context.getDeducedTemplateSpecializationType(
- TemplateName(AliasTemplate), /*DeducedType=*/QualType(),
+ ElaboratedTypeKeyword::None, TemplateName(AliasTemplate),
+ /*DeducedType=*/QualType(),
/*IsDependent=*/true),
AliasTemplate->getLocation()), // template specialization type whose
// arguments will be deduced.
@@ -970,10 +981,7 @@ Expr *buildIsDeducibleConstraint(Sema &SemaRef,
std::pair<TemplateDecl *, llvm::ArrayRef<TemplateArgument>>
getRHSTemplateDeclAndArgs(Sema &SemaRef, TypeAliasTemplateDecl *AliasTemplate) {
- // Unwrap the sugared ElaboratedType.
- auto RhsType = AliasTemplate->getTemplatedDecl()
- ->getUnderlyingType()
- .getSingleStepDesugaredType(SemaRef.Context);
+ auto RhsType = AliasTemplate->getTemplatedDecl()->getUnderlyingType();
TemplateDecl *Template = nullptr;
llvm::ArrayRef<TemplateArgument> AliasRhsTemplateArgs;
if (const auto *TST = RhsType->getAs<TemplateSpecializationType>()) {
@@ -1029,12 +1037,10 @@ BuildDeductionGuideForTypeAlias(Sema &SemaRef,
// The (trailing) return type of the deduction guide.
const TemplateSpecializationType *FReturnType =
RType->getAs<TemplateSpecializationType>();
- if (const auto *InjectedCNT = RType->getAs<InjectedClassNameType>())
+ if (const auto *ICNT = RType->getAs<InjectedClassNameType>())
// implicitly-generated deduction guide.
- FReturnType = InjectedCNT->getInjectedTST();
- else if (const auto *ET = RType->getAs<ElaboratedType>())
- // explicit deduction guide.
- FReturnType = ET->getNamedType()->getAs<TemplateSpecializationType>();
+ FReturnType =
+ cast<TemplateSpecializationType>(ICNT->getCanonicalInjectedTST());
assert(FReturnType && "expected to see a return type");
// Deduce template arguments of the deduction guide f from the RHS of
// the alias.
diff --git a/clang/lib/Sema/SemaTemplateInstantiate.cpp b/clang/lib/Sema/SemaTemplateInstantiate.cpp
index 9140f00fcd740..7dbaf387f6d13 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -339,45 +339,50 @@ Response HandleFunctionTemplateDecl(Sema &SemaRef,
SemaRef.Context),
/*Final=*/false);
- NestedNameSpecifier *NNS = FTD->getTemplatedDecl()->getQualifier();
-
- while (const Type *Ty = NNS ? NNS->getAsType() : nullptr) {
- if (NNS->isInstantiationDependent()) {
- if (const auto *TSTy = Ty->getAs<TemplateSpecializationType>()) {
- ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
- // Prefer template arguments from the injected-class-type if possible.
- // For example,
- // ```cpp
- // template <class... Pack> struct S {
- // template <class T> void foo();
- // };
- // template <class... Pack> template <class T>
- // ^^^^^^^^^^^^^ InjectedTemplateArgs
- // They're of kind TemplateArgument::Pack, not of
- // TemplateArgument::Type.
- // void S<Pack...>::foo() {}
- // ^^^^^^^
- // TSTy->template_arguments() (which are of PackExpansionType)
- // ```
- // This meets the contract in
- // TreeTransform::TryExpandParameterPacks that the template arguments
- // for unexpanded parameters should be of a Pack kind.
- if (TSTy->isCurrentInstantiation()) {
- auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
- if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
- Arguments = CTD->getInjectedTemplateArgs(SemaRef.Context);
- else if (auto *Specialization =
- dyn_cast<ClassTemplateSpecializationDecl>(RD))
- Arguments =
- Specialization->getTemplateInstantiationArgs().asArray();
- }
- Result.addOuterTemplateArguments(
- TSTy->getTemplateName().getAsTemplateDecl(), Arguments,
- /*Final=*/false);
- }
- }
+ NestedNameSpecifier NNS = FTD->getTemplatedDecl()->getQualifier();
+
+ for (const Type *Ty = NNS.getKind() == NestedNameSpecifier::Kind::Type
+ ? NNS.getAsType()
+ : nullptr,
+ *NextTy = nullptr;
+ Ty && Ty->isInstantiationDependentType();
+ Ty = std::exchange(NextTy, nullptr)) {
+ if (NestedNameSpecifier P = Ty->getPrefix();
+ P.getKind() == NestedNameSpecifier::Kind::Type)
+ NextTy = P.getAsType();
+ const auto *TSTy = dyn_cast<TemplateSpecializationType>(Ty);
+ if (!TSTy)
+ continue;
- NNS = NNS->getPrefix();
+ ArrayRef<TemplateArgument> Arguments = TSTy->template_arguments();
+ // Prefer template arguments from the injected-class-type if possible.
+ // For example,
+ // ```cpp
+ // template <class... Pack> struct S {
+ // template <class T> void foo();
+ // };
+ // template <class... Pack> template <class T>
+ // ^^^^^^^^^^^^^ InjectedTemplateArgs
+ // They're of kind TemplateArgument::Pack, not of
+ // TemplateArgument::Type.
+ // void S<Pack...>::foo() {}
+ // ^^^^^^^
+ // TSTy->template_arguments() (which are of PackExpansionType)
+ // ```
+ // This meets the contract in
+ // TreeTransform::TryExpandParameterPacks that the template arguments
+ // for unexpanded parameters should be of a Pack kind.
+ if (TSTy->isCurrentInstantiation()) {
+ auto *RD = TSTy->getCanonicalTypeInternal()->getAsCXXRecordDecl();
+ if (ClassTemplateDecl *CTD = RD->getDescribedClassTemplate())
+ Arguments = CTD->getInjectedTemplateArgs(SemaRef.Context);
+ else if (auto *Specialization =
+ dyn_cast<ClassTemplateSpecializationDecl>(RD))
+ Arguments = Specialization->getTemplateInstantiationArgs().asArray();
+ }
+ Result.addOuterTemplateArguments(
+ TSTy->getTemplateName().getAsTemplateDecl(), Arguments,
+ /*Final=*/false);
}
}
@@ -1165,7 +1170,7 @@ void Sema::PrintInstantiationStack(InstantiationContextDiagFuncRef DiagFunc) {
DiagFunc(Active->PointOfInstantiation,
PDiag(diag::note_member_synthesized_at)
<< MD->isExplicitlyDefaulted() << DFK.asSpecialMember()
- << Context.getTagDeclType(MD->getParent()));
+ << Context.getCanonicalTagType(MD->getParent()));
} else if (DFK.isComparison()) {
QualType RecordType = FD->getParamDecl(0)
->getType()
@@ -1595,15 +1600,9 @@ namespace {
VarDecl *RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
TypeSourceInfo *TSInfo, QualType T);
- /// Check for tag mismatches when instantiating an
- /// elaborated type.
- QualType RebuildElaboratedType(SourceLocation KeywordLoc,
- ElaboratedTypeKeyword Keyword,
- NestedNameSpecifierLoc QualifierLoc,
- QualType T);
-
TemplateName
- TransformTemplateName(CXXScopeSpec &SS, TemplateName Name,
+ TransformTemplateName(NestedNameSpecifierLoc &QualifierLoc,
+ SourceLocation TemplateKWLoc, TemplateName Name,
SourceLocation NameLoc,
QualType ObjectType = QualType(),
NamedDecl *FirstQualifierInScope = nullptr,
@@ -1649,22 +1648,18 @@ namespace {
return inherited::TransformFunctionProtoType(TLB, TL);
}
- QualType TransformInjectedClassNameType(TypeLocBuilder &TLB,
- InjectedClassNameTypeLoc TL) {
- auto Type = inherited::TransformInjectedClassNameType(TLB, TL);
+ QualType TransformTagType(TypeLocBuilder &TLB, TagTypeLoc TL) {
+ auto Type = inherited::TransformTagType(TLB, TL);
+ if (!Type.isNull())
+ return Type;
// Special case for transforming a deduction guide, we return a
// transformed TemplateSpecializationType.
- if (Type.isNull() &&
- SemaRef.CodeSynthesisContexts.back().Kind ==
- Sema::CodeSynthesisContext::BuildingDeductionGuides) {
- // Return a TemplateSpecializationType for transforming a deduction
- // guide.
- if (auto *ICT = TL.getType()->getAs<InjectedClassNameType>()) {
- auto Type =
- inherited::TransformType(ICT->getInjectedSpecializationType());
- TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc());
- return Type;
- }
+ // FIXME: Why is this hack necessary?
+ if (const auto *ICNT = dyn_cast<InjectedClassNameType>(TL.getTypePtr());
+ ICNT && SemaRef.CodeSynthesisContexts.back().Kind ==
+ Sema::CodeSynthesisContext::BuildingDeductionGuides) {
+ Type = inherited::TransformType(ICNT->getCanonicalInjectedTST());
+ TLB.pushTrivial(SemaRef.Context, Type, TL.getNameLoc());
}
return Type;
}
@@ -2050,7 +2045,7 @@ TemplateInstantiator::TransformFirstQualifierInScope(NamedDecl *D,
return cast_or_null<NamedDecl>(TransformDecl(Loc, D));
if (const TagType *Tag = T->getAs<TagType>())
- return Tag->getDecl();
+ return Tag->getOriginalDecl();
// The resulting type is not a tag; complain.
getSema().Diag(Loc, diag::err_nested_name_spec_non_tag) << T;
@@ -2083,41 +2078,10 @@ VarDecl *TemplateInstantiator::RebuildObjCExceptionDecl(VarDecl *ExceptionDecl,
return Var;
}
-QualType
-TemplateInstantiator::RebuildElaboratedType(SourceLocation KeywordLoc,
- ElaboratedTypeKeyword Keyword,
- NestedNameSpecifierLoc QualifierLoc,
- QualType T) {
- if (const TagType *TT = T->getAs<TagType>()) {
- TagDecl* TD = TT->getDecl();
-
- SourceLocation TagLocation = KeywordLoc;
-
- IdentifierInfo *Id = TD->getIdentifier();
-
- // TODO: should we even warn on struct/class mismatches for this? Seems
- // like it's likely to produce a lot of spurious errors.
- if (Id && Keyword != ElaboratedTypeKeyword::None &&
- Keyword != ElaboratedTypeKeyword::Typename) {
- TagTypeKind Kind = TypeWithKeyword::getTagTypeKindForKeyword(Keyword);
- if (!SemaRef.isAcceptableTagRedeclaration(TD, Kind, /*isDefinition*/false,
- TagLocation, Id)) {
- SemaRef.Diag(TagLocation, diag::err_use_with_wrong_tag)
- << Id
- << FixItHint::CreateReplacement(SourceRange(TagLocation),
- TD->getKindName());
- SemaRef.Diag(TD->getLocation(), diag::note_previous_use);
- }
- }
- }
-
- return inherited::RebuildElaboratedType(KeywordLoc, Keyword, QualifierLoc, T);
-}
-
TemplateName TemplateInstantiator::TransformTemplateName(
- CXXScopeSpec &SS, TemplateName Name, SourceLocation NameLoc,
- QualType ObjectType, NamedDecl *FirstQualifierInScope,
- bool AllowInjectedClassName) {
+ NestedNameSpecifierLoc &QualifierLoc, SourceLocation TemplateKWLoc,
+ TemplateName Name, SourceLocation NameLoc, QualType ObjectType,
+ NamedDecl *FirstQualifierInScope, bool AllowInjectedClassName) {
if (TemplateTemplateParmDecl *TTP
= dyn_cast_or_null<TemplateTemplateParmDecl>(Name.getAsTemplateDecl())) {
if (TTP->getDepth() < TemplateArgs.getNumLevels()) {
@@ -2164,6 +2128,12 @@ TemplateName TemplateInstantiator::TransformTemplateName(
TemplateName Template = Arg.getAsTemplate();
assert(!Template.isNull() && "Null template template argument");
+ if (NestedNameSpecifier Qualifier = Template.getQualifier()) {
+ NestedNameSpecifierLocBuilder Builder;
+ Builder.MakeTrivial(SemaRef.Context, Qualifier, NameLoc);
+ QualifierLoc = Builder.getWithLocInContext(SemaRef.Context);
+ }
+
return getSema().Context.getSubstTemplateTemplateParm(
Template, AssociatedDecl, TTP->getIndex(), PackIndex, Final);
}
@@ -2182,9 +2152,9 @@ TemplateName TemplateInstantiator::TransformTemplateName(
getPackIndex(Pack), SubstPack->getFinal());
}
- return inherited::TransformTemplateName(SS, Name, NameLoc, ObjectType,
- FirstQualifierInScope,
- AllowInjectedClassName);
+ return inherited::TransformTemplateName(
+ QualifierLoc, TemplateKWLoc, Name, NameLoc, ObjectType,
+ FirstQualifierInScope, AllowInjectedClassName);
}
ExprResult
@@ -3160,10 +3130,6 @@ namespace {
// Only these types can contain 'auto' types, and subsequently be replaced
// by references to invented parameters.
- TemplateTypeParmDecl *VisitElaboratedType(const ElaboratedType *T) {
- return Visit(T->getNamedType());
- }
-
TemplateTypeParmDecl *VisitPointerType(const PointerType *T) {
return Visit(T->getPointeeType());
}
@@ -4554,14 +4520,14 @@ Sema::SubstDeclarationNameInfo(const DeclarationNameInfo &NameInfo,
}
TemplateName
-Sema::SubstTemplateName(NestedNameSpecifierLoc QualifierLoc,
- TemplateName Name, SourceLocation Loc,
+Sema::SubstTemplateName(SourceLocation TemplateKWLoc,
+ NestedNameSpecifierLoc &QualifierLoc, TemplateName Name,
+ SourceLocation NameLoc,
const MultiLevelTemplateArgumentList &TemplateArgs) {
- TemplateInstantiator Instantiator(*this, TemplateArgs, Loc,
+ TemplateInstantiator Instantiator(*this, TemplateArgs, NameLoc,
DeclarationName());
- CXXScopeSpec SS;
- SS.Adopt(QualifierLoc);
- return Instantiator.TransformTemplateName(SS, Name, Loc);
+ return Instantiator.TransformTemplateName(QualifierLoc, TemplateKWLoc, Name,
+ NameLoc);
}
static const Decl *getCanonicalParmVarDecl(const Decl *D) {
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index a25bfd1c48dee..e608b39b49d89 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1483,9 +1483,9 @@ Decl *TemplateDeclInstantiator::InstantiateTypedefNameDecl(TypedefNameDecl *D,
// If the old typedef was the name for linkage purposes of an anonymous
// tag decl, re-establish that relationship for the new typedef.
if (const TagType *oldTagType = D->getUnderlyingType()->getAs<TagType>()) {
- TagDecl *oldTag = oldTagType->getDecl();
+ TagDecl *oldTag = oldTagType->getOriginalDecl();
if (oldTag->getTypedefNameForAnonDecl() == D && !Invalid) {
- TagDecl *newTag = DI->getType()->castAs<TagType>()->getDecl();
+ TagDecl *newTag = DI->getType()->castAs<TagType>()->getOriginalDecl();
assert(!newTag->hasNameForLinkage());
newTag->setTypedefNameForAnonDecl(Typedef);
}
@@ -2241,8 +2241,7 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
CXXRecordDecl *RecordInst = CXXRecordDecl::Create(
SemaRef.Context, Pattern->getTagKind(), DC, Pattern->getBeginLoc(),
- Pattern->getLocation(), Pattern->getIdentifier(), PrevDecl,
- /*DelayTypeCreation=*/true);
+ Pattern->getLocation(), Pattern->getIdentifier(), PrevDecl);
if (QualifierLoc)
RecordInst->setQualifierInfo(QualifierLoc);
@@ -2262,8 +2261,6 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (PrevClassTemplate) {
Inst->setCommonPtr(PrevClassTemplate->getCommonPtr());
- RecordInst->setTypeForDecl(
- PrevClassTemplate->getTemplatedDecl()->getTypeForDecl());
const ClassTemplateDecl *MostRecentPrevCT =
PrevClassTemplate->getMostRecentDecl();
TemplateParameterList *PrevParams =
@@ -2297,10 +2294,6 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
Inst->setPreviousDecl(PrevClassTemplate);
- // Trigger creation of the type for the instantiation.
- SemaRef.Context.getInjectedClassNameType(
- RecordInst, Inst->getInjectedClassNameSpecialization());
-
// Finish handling of friends.
if (isFriend) {
DC->makeDeclVisibleInContext(Inst);
@@ -2506,11 +2499,9 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
else
Record = CXXRecordDecl::Create(SemaRef.Context, D->getTagKind(), Owner,
D->getBeginLoc(), D->getLocation(),
- D->getIdentifier(), PrevDecl,
- /*DelayTypeCreation=*/IsInjectedClassName);
- // Link the type of the injected-class-name to that of the outer class.
- if (IsInjectedClassName)
- (void)SemaRef.Context.getTypeDeclType(Record, cast<CXXRecordDecl>(Owner));
+ D->getIdentifier(), PrevDecl);
+
+ Record->setImplicit(D->isImplicit());
// Substitute the nested name specifier, if any.
if (SubstQualifier(D, Record))
@@ -2519,7 +2510,6 @@ Decl *TemplateDeclInstantiator::VisitCXXRecordDecl(CXXRecordDecl *D) {
SemaRef.InstantiateAttrsForDecl(TemplateArgs, D, Record, LateAttrs,
StartingScope);
- Record->setImplicit(D->isImplicit());
// FIXME: Check against AS_none is an ugly hack to work around the issue that
// the tag decls introduced by friend class declarations don't have an access
// specifier. Remove once this area of the code gets sorted out.
@@ -3155,8 +3145,8 @@ Decl *TemplateDeclInstantiator::VisitCXXMethodDecl(
Method->setIneligibleOrNotSelected(true);
Method->setRangeEnd(Destructor->getEndLoc());
Method->setDeclName(SemaRef.Context.DeclarationNames.getCXXDestructorName(
- SemaRef.Context.getCanonicalType(
- SemaRef.Context.getTypeDeclType(Record))));
+
+ SemaRef.Context.getCanonicalTagType(Record)));
} else if (CXXConversionDecl *Conversion = dyn_cast<CXXConversionDecl>(D)) {
Method = CXXConversionDecl::Create(
SemaRef.Context, Record, StartLoc, NameInfo, T, TInfo,
@@ -3784,19 +3774,18 @@ TemplateDeclInstantiator::VisitTemplateTemplateParmDecl(
D->getPosition(), D->isParameterPack(), D->getIdentifier(),
D->wasDeclaredWithTypename(), InstParams);
if (D->hasDefaultArgument() && !D->defaultArgumentWasInherited()) {
- NestedNameSpecifierLoc QualifierLoc =
- D->getDefaultArgument().getTemplateQualifierLoc();
- QualifierLoc =
- SemaRef.SubstNestedNameSpecifierLoc(QualifierLoc, TemplateArgs);
+ const TemplateArgumentLoc &A = D->getDefaultArgument();
+ NestedNameSpecifierLoc QualifierLoc = A.getTemplateQualifierLoc();
+ // FIXME: Pass in the template keyword location.
TemplateName TName = SemaRef.SubstTemplateName(
- QualifierLoc, D->getDefaultArgument().getArgument().getAsTemplate(),
- D->getDefaultArgument().getTemplateNameLoc(), TemplateArgs);
+ A.getTemplateKWLoc(), QualifierLoc, A.getArgument().getAsTemplate(),
+ A.getTemplateNameLoc(), TemplateArgs);
if (!TName.isNull())
Param->setDefaultArgument(
SemaRef.Context,
TemplateArgumentLoc(SemaRef.Context, TemplateArgument(TName),
- D->getDefaultArgument().getTemplateQualifierLoc(),
- D->getDefaultArgument().getTemplateNameLoc()));
+ A.getTemplateKWLoc(), QualifierLoc,
+ A.getTemplateNameLoc()));
}
Param->setAccess(AS_public);
Param->setImplicit(D->isImplicit());
@@ -3898,7 +3887,7 @@ Decl *TemplateDeclInstantiator::VisitUsingDecl(UsingDecl *D) {
if (NameInfo.getName().getNameKind() == DeclarationName::CXXConstructorName)
if (auto *RD = dyn_cast<CXXRecordDecl>(SemaRef.CurContext))
NameInfo.setName(SemaRef.Context.DeclarationNames.getCXXConstructorName(
- SemaRef.Context.getCanonicalType(SemaRef.Context.getRecordType(RD))));
+ SemaRef.Context.getCanonicalTagType(RD)));
// We only need to do redeclaration lookups if we're in a class scope (in
// fact, it's not really even possible in non-class scopes).
@@ -4810,18 +4799,13 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
ClassTemplate->findPartialSpecialization(CTAI.CanonicalConverted,
InstParams, InsertPos);
- // Build the type that describes the converted template arguments of the class
- // template partial specialization.
- TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo(
- TemplateName(ClassTemplate), TemplArgInfo->getLAngleLoc(),
- InstTemplateArgs, CTAI.CanonicalConverted);
-
// Create the class template partial specialization declaration.
ClassTemplatePartialSpecializationDecl *InstPartialSpec =
ClassTemplatePartialSpecializationDecl::Create(
SemaRef.Context, PartialSpec->getTagKind(), Owner,
PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams,
- ClassTemplate, CTAI.CanonicalConverted, WrittenTy->getType(),
+ ClassTemplate, CTAI.CanonicalConverted,
+ /*CanonInjectedTST=*/CanQualType(),
/*PrevDecl=*/nullptr);
InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs);
@@ -4852,7 +4836,7 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
diag::err_partial_spec_redeclared)
<< InstPartialSpec;
SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here)
- << SemaRef.Context.getTypeDeclType(PrevDecl);
+ << SemaRef.Context.getCanonicalTagType(PrevDecl);
return nullptr;
}
@@ -5741,15 +5725,19 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
QualType TransformRecordType(TypeLocBuilder &TLB, RecordTypeLoc TL) {
const RecordType *T = TL.getTypePtr();
RecordDecl *Record = cast_or_null<RecordDecl>(
- getDerived().TransformDecl(TL.getNameLoc(), T->getDecl()));
+ getDerived().TransformDecl(TL.getNameLoc(), T->getOriginalDecl()));
if (Record != OldDecl)
return Base::TransformRecordType(TLB, TL);
- QualType Result = getDerived().RebuildRecordType(NewDecl);
+ // FIXME: transform the rest of the record type.
+ QualType Result = getDerived().RebuildTagType(
+ ElaboratedTypeKeyword::None, /*Qualifier=*/std::nullopt, NewDecl);
if (Result.isNull())
return QualType();
- RecordTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
+ TagTypeLoc NewTL = TLB.push<RecordTypeLoc>(Result);
+ NewTL.setElaboratedKeywordLoc(SourceLocation());
+ NewTL.setQualifierLoc(NestedNameSpecifierLoc());
NewTL.setNameLoc(TL.getNameLoc());
return Result;
}
@@ -6910,7 +6898,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
Args.addArgument(
getTrivialTemplateArgumentLoc(UnpackedArg, QualType(), Loc));
}
- QualType T = CheckTemplateIdType(TemplateName(TD), Loc, Args);
+ QualType T = CheckTemplateIdType(ElaboratedTypeKeyword::None,
+ TemplateName(TD), Loc, Args);
// We may get a non-null type with errors, in which case
// `getAsCXXRecordDecl` will return `nullptr`. For instance, this
// happens when one of the template arguments is an invalid
@@ -6976,16 +6965,17 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
bool IsBeingInstantiated = false;
if (CXXRecordDecl *Spec = dyn_cast<CXXRecordDecl>(ParentDC)) {
if (!Spec->isDependentContext()) {
- QualType T = Context.getTypeDeclType(Spec);
+ CanQualType T = Context.getCanonicalTagType(Spec);
const RecordType *Tag = T->getAs<RecordType>();
assert(Tag && "type of non-dependent record is not a RecordType");
- if (Tag->isBeingDefined())
+ auto *TagDecl =
+ cast<CXXRecordDecl>(Tag->getOriginalDecl())->getDefinitionOrSelf();
+ if (TagDecl->isBeingDefined())
IsBeingInstantiated = true;
- if (!Tag->isBeingDefined() &&
- RequireCompleteType(Loc, T, diag::err_incomplete_type))
+ else if (RequireCompleteType(Loc, T, diag::err_incomplete_type))
return nullptr;
- ParentDC = Tag->getDecl();
+ ParentDC = TagDecl;
}
}
@@ -7031,8 +7021,8 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
// of member classes, and introduces ordering dependencies via
// template instantiation.
Diag(Loc, diag::err_member_not_yet_instantiated)
- << D->getDeclName()
- << Context.getTypeDeclType(cast<CXXRecordDecl>(ParentDC));
+ << D->getDeclName()
+ << Context.getCanonicalTagType(cast<CXXRecordDecl>(ParentDC));
Diag(D->getLocation(), diag::note_non_instantiated_member_here);
} else if (EnumConstantDecl *ED = dyn_cast<EnumConstantDecl>(D)) {
// This enumeration constant was found when the template was defined,
@@ -7047,7 +7037,7 @@ NamedDecl *Sema::FindInstantiatedDecl(SourceLocation Loc, NamedDecl *D,
<< D->getDeclName()
<< Context.getTypeDeclType(cast<TypeDecl>(Spec->getDeclContext()));
Diag(Spec->getLocation(), diag::note_enum_specialized_here)
- << Context.getTypeDeclType(Spec);
+ << Context.getCanonicalTagType(Spec);
} else {
// We should have found something, but didn't.
llvm_unreachable("Unable to find instantiation of declaration!");
diff --git a/clang/lib/Sema/SemaTemplateVariadic.cpp b/clang/lib/Sema/SemaTemplateVariadic.cpp
index 572dbf2e7393f..b518400b60c7e 100644
--- a/clang/lib/Sema/SemaTemplateVariadic.cpp
+++ b/clang/lib/Sema/SemaTemplateVariadic.cpp
@@ -155,21 +155,22 @@ class CollectUnexpandedParameterPacksVisitor
/// Suppress traversal into types that do not contain
/// unexpanded parameter packs.
- bool TraverseType(QualType T) override {
+ bool TraverseType(QualType T, bool TraverseQualifier = true) override {
if ((!T.isNull() && T->containsUnexpandedParameterPack()) ||
InLambdaOrBlock)
- return DynamicRecursiveASTVisitor::TraverseType(T);
+ return DynamicRecursiveASTVisitor::TraverseType(T, TraverseQualifier);
return true;
}
/// Suppress traversal into types with location information
/// that do not contain unexpanded parameter packs.
- bool TraverseTypeLoc(TypeLoc TL) override {
+ bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) override {
if ((!TL.getType().isNull() &&
TL.getType()->containsUnexpandedParameterPack()) ||
InLambdaOrBlock)
- return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL);
+ return DynamicRecursiveASTVisitor::TraverseTypeLoc(TL,
+ TraverseQualifier);
return true;
}
@@ -195,10 +196,12 @@ class CollectUnexpandedParameterPacksVisitor
/// Suppress traversal of pack expansion expressions and types.
///@{
- bool TraversePackExpansionType(PackExpansionType *T) override {
+ bool TraversePackExpansionType(PackExpansionType *T,
+ bool TraverseQualifier) override {
return true;
}
- bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL) override {
+ bool TraversePackExpansionTypeLoc(PackExpansionTypeLoc TL,
+ bool TraverseQualifier) override {
return true;
}
bool TraversePackExpansionExpr(PackExpansionExpr *E) override {
@@ -208,10 +211,12 @@ class CollectUnexpandedParameterPacksVisitor
bool TraversePackIndexingExpr(PackIndexingExpr *E) override {
return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr());
}
- bool TraversePackIndexingType(PackIndexingType *E) override {
+ bool TraversePackIndexingType(PackIndexingType *E,
+ bool TraverseQualifier) override {
return DynamicRecursiveASTVisitor::TraverseStmt(E->getIndexExpr());
}
- bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL) override {
+ bool TraversePackIndexingTypeLoc(PackIndexingTypeLoc TL,
+ bool TraverseQualifier) override {
return DynamicRecursiveASTVisitor::TraverseStmt(TL.getIndexExpr());
}
@@ -515,8 +520,7 @@ bool Sema::DiagnoseUnexpandedParameterPack(const CXXScopeSpec &SS,
// C++0x [temp.variadic]p5:
// An appearance of a name of a parameter pack that is not expanded is
// ill-formed.
- if (!SS.getScopeRep() ||
- !SS.getScopeRep()->containsUnexpandedParameterPack())
+ if (!SS.getScopeRep().containsUnexpandedParameterPack())
return false;
SmallVector<UnexpandedParameterPack, 2> Unexpanded;
@@ -644,7 +648,7 @@ Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
return ParsedTemplateArgument();
return ParsedTemplateArgument(Arg.getKind(), Result.get().getAsOpaquePtr(),
- Arg.getLocation());
+ Arg.getNameLoc());
}
case ParsedTemplateArgument::NonType: {
@@ -653,12 +657,12 @@ Sema::ActOnPackExpansion(const ParsedTemplateArgument &Arg,
return ParsedTemplateArgument();
return ParsedTemplateArgument(Arg.getKind(), Result.get(),
- Arg.getLocation());
+ Arg.getNameLoc());
}
case ParsedTemplateArgument::Template:
if (!Arg.getAsTemplate().get().containsUnexpandedParameterPack()) {
- SourceRange R(Arg.getLocation());
+ SourceRange R(Arg.getNameLoc());
if (Arg.getScopeSpec().isValid())
R.setBegin(Arg.getScopeSpec().getBeginLoc());
Diag(EllipsisLoc, diag::err_pack_expansion_without_parameter_packs)
@@ -1105,8 +1109,7 @@ bool Sema::containsUnexpandedParameterPacks(Declarator &D) {
break;
case DeclaratorChunk::MemberPointer:
- if (Chunk.Mem.Scope().getScopeRep() &&
- Chunk.Mem.Scope().getScopeRep()->containsUnexpandedParameterPack())
+ if (Chunk.Mem.Scope().getScopeRep().containsUnexpandedParameterPack())
return true;
break;
}
@@ -1290,9 +1293,9 @@ TemplateArgumentLoc Sema::getTemplateArgumentPackExpansionPattern(
case TemplateArgument::TemplateExpansion:
Ellipsis = OrigLoc.getTemplateEllipsisLoc();
NumExpansions = Argument.getNumTemplateExpansions();
- return TemplateArgumentLoc(Context, Argument.getPackExpansionPattern(),
- OrigLoc.getTemplateQualifierLoc(),
- OrigLoc.getTemplateNameLoc());
+ return TemplateArgumentLoc(
+ Context, Argument.getPackExpansionPattern(), OrigLoc.getTemplateKWLoc(),
+ OrigLoc.getTemplateQualifierLoc(), OrigLoc.getTemplateNameLoc());
case TemplateArgument::Declaration:
case TemplateArgument::NullPtr:
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 88aa63d3b9e83..b96592f5cb48e 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -1211,14 +1211,11 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
DS.getTypeSpecSign() == TypeSpecifierSign::Unspecified &&
"No qualifiers on tag names!");
+ ElaboratedTypeKeyword Keyword =
+ KeywordHelpers::getKeywordForTypeSpec(DS.getTypeSpecType());
// TypeQuals handled by caller.
- Result = Context.getTypeDeclType(D);
-
- // In both C and C++, make an ElaboratedType.
- ElaboratedTypeKeyword Keyword
- = ElaboratedType::getKeywordForTypeSpec(DS.getTypeSpecType());
- Result = S.getElaboratedType(Keyword, DS.getTypeSpecScope(), Result,
- DS.isTypeSpecOwned() ? D : nullptr);
+ Result = Context.getTagType(Keyword, DS.getTypeSpecScope().getScopeRep(), D,
+ DS.isTypeSpecOwned());
break;
}
case DeclSpec::TST_typename: {
@@ -1241,7 +1238,7 @@ static QualType ConvertDeclSpecToType(TypeProcessingState &state) {
assert(!Result.isNull() && "Didn't get a type for typeof?");
if (!Result->isDependentType())
if (const TagType *TT = Result->getAs<TagType>())
- S.DiagnoseUseOfDecl(TT->getDecl(), DS.getTypeSpecTypeLoc());
+ S.DiagnoseUseOfDecl(TT->getOriginalDecl(), DS.getTypeSpecTypeLoc());
// TypeQuals handled by caller.
Result = Context.getTypeOfType(
Result, DS.getTypeSpecType() == DeclSpec::TST_typeof_unqualType
@@ -2085,7 +2082,7 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM,
// an inheritance model, even if it's inside an unused typedef.
if (Context.getTargetInfo().getCXXABI().isMicrosoft())
if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>())
- if (!MPTy->getQualifier()->isDependent())
+ if (!MPTy->getQualifier().isDependent())
(void)isCompleteType(Loc, T);
} else {
@@ -2120,7 +2117,9 @@ QualType Sema::BuildArrayType(QualType T, ArraySizeModifier ASM,
if (const RecordType *EltTy = T->getAs<RecordType>()) {
// If the element type is a struct or union that contains a variadic
// array, accept it as a GNU extension: C99 6.7.2.1p2.
- if (EltTy->getDecl()->hasFlexibleArrayMember())
+ if (EltTy->getOriginalDecl()
+ ->getDefinitionOrSelf()
+ ->hasFlexibleArrayMember())
Diag(Loc, diag::ext_flexible_array_in_array) << T;
} else if (T->isObjCObjectType()) {
Diag(Loc, diag::err_objc_array_of_interfaces) << T;
@@ -3462,7 +3461,7 @@ static QualType GetDeclSpecTypeForDeclarator(TypeProcessingState &state,
if (DiagID != 0) {
SemaRef.Diag(OwnedTagDecl->getLocation(), DiagID)
- << SemaRef.Context.getTypeDeclType(OwnedTagDecl);
+ << SemaRef.Context.getCanonicalTagType(OwnedTagDecl);
D.setInvalidType(true);
}
}
@@ -3655,11 +3654,22 @@ static void warnAboutRedundantParens(Sema &S, Declarator &D, QualType T) {
// here: even (e.g.) "int ::x" is visually ambiguous even though it's
// formally unambiguous.
if (StartsWithDeclaratorId && D.getCXXScopeSpec().isValid()) {
- for (NestedNameSpecifier *NNS = D.getCXXScopeSpec().getScopeRep(); NNS;
- NNS = NNS->getPrefix()) {
- if (NNS->getKind() == NestedNameSpecifier::Global)
+ NestedNameSpecifier NNS = D.getCXXScopeSpec().getScopeRep();
+ for (;;) {
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Global:
return;
+ case NestedNameSpecifier::Kind::Type:
+ NNS = NNS.getAsType()->getPrefix();
+ continue;
+ case NestedNameSpecifier::Kind::Namespace:
+ NNS = NNS.getAsNamespaceAndPrefix().Prefix;
+ continue;
+ default:
+ goto out;
+ }
}
+ out:;
}
S.Diag(Paren.Loc, diag::warn_redundant_parens_around_declarator)
@@ -3967,7 +3977,8 @@ classifyPointerDeclarator(Sema &S, QualType type, Declarator &declarator,
return PointerDeclaratorKind::NonPointer;
if (auto recordType = type->getAs<RecordType>()) {
- RecordDecl *recordDecl = recordType->getDecl();
+ RecordDecl *recordDecl =
+ recordType->getOriginalDecl()->getDefinitionOrSelf();
// If this is CFErrorRef*, report it as such.
if (numNormalPointers == 2 && numTypeSpecifierPointers < 2 &&
@@ -5101,7 +5112,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
// Types shall not be defined in return or parameter types.
TagDecl *Tag = cast<TagDecl>(D.getDeclSpec().getRepAsDecl());
S.Diag(Tag->getLocation(), diag::err_type_defined_in_result_type)
- << Context.getTypeDeclType(Tag);
+ << Context.getCanonicalTagType(Tag);
}
// Exception specs are not allowed in typedefs. Complain, but add it
@@ -5319,7 +5330,7 @@ static TypeSourceInfo *GetFullTypeForDeclarator(TypeProcessingState &state,
state.getDeclarator()
.getCXXScopeSpec()
.getScopeRep()
- ->getKind() == NestedNameSpecifier::TypeSpec) ||
+ .getKind() == NestedNameSpecifier::Kind::Type) ||
state.getDeclarator().getContext() ==
DeclaratorContext::Member ||
state.getDeclarator().getContext() ==
@@ -5898,7 +5909,49 @@ namespace {
// int __attr * __attr * __attr *p;
void VisitPointerTypeLoc(PointerTypeLoc TL) { Visit(TL.getNextTypeLoc()); }
void VisitTypedefTypeLoc(TypedefTypeLoc TL) {
- TL.setNameLoc(DS.getTypeSpecTypeLoc());
+ if (DS.getTypeSpecType() == TST_typename) {
+ TypeSourceInfo *TInfo = nullptr;
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+ if (TInfo) {
+ TL.copy(TInfo->getTypeLoc().castAs<TypedefTypeLoc>());
+ return;
+ }
+ }
+ TL.set(TL.getTypePtr()->getKeyword() != ElaboratedTypeKeyword::None
+ ? DS.getTypeSpecTypeLoc()
+ : SourceLocation(),
+ DS.getTypeSpecScope().getWithLocInContext(Context),
+ DS.getTypeSpecTypeNameLoc());
+ }
+ void VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+ if (DS.getTypeSpecType() == TST_typename) {
+ TypeSourceInfo *TInfo = nullptr;
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+ if (TInfo) {
+ TL.copy(TInfo->getTypeLoc().castAs<UnresolvedUsingTypeLoc>());
+ return;
+ }
+ }
+ TL.set(TL.getTypePtr()->getKeyword() != ElaboratedTypeKeyword::None
+ ? DS.getTypeSpecTypeLoc()
+ : SourceLocation(),
+ DS.getTypeSpecScope().getWithLocInContext(Context),
+ DS.getTypeSpecTypeNameLoc());
+ }
+ void VisitUsingTypeLoc(UsingTypeLoc TL) {
+ if (DS.getTypeSpecType() == TST_typename) {
+ TypeSourceInfo *TInfo = nullptr;
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+ if (TInfo) {
+ TL.copy(TInfo->getTypeLoc().castAs<UsingTypeLoc>());
+ return;
+ }
+ }
+ TL.set(TL.getTypePtr()->getKeyword() != ElaboratedTypeKeyword::None
+ ? DS.getTypeSpecTypeLoc()
+ : SourceLocation(),
+ DS.getTypeSpecScope().getWithLocInContext(Context),
+ DS.getTypeSpecTypeNameLoc());
}
void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc TL) {
TL.setNameLoc(DS.getTypeSpecTypeLoc());
@@ -5929,16 +5982,9 @@ namespace {
}
TypeLoc OldTL = TInfo->getTypeLoc();
- if (TInfo->getType()->getAs<ElaboratedType>()) {
- ElaboratedTypeLoc ElabTL = OldTL.castAs<ElaboratedTypeLoc>();
- TemplateSpecializationTypeLoc NamedTL = ElabTL.getNamedTypeLoc()
- .castAs<TemplateSpecializationTypeLoc>();
- TL.copy(NamedTL);
- } else {
- TL.copy(OldTL.castAs<TemplateSpecializationTypeLoc>());
- assert(TL.getRAngleLoc() == OldTL.castAs<TemplateSpecializationTypeLoc>().getRAngleLoc());
- }
-
+ TL.copy(OldTL.castAs<TemplateSpecializationTypeLoc>());
+ assert(TL.getRAngleLoc() ==
+ OldTL.castAs<TemplateSpecializationTypeLoc>().getRAngleLoc());
}
void VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
assert(DS.getTypeSpecType() == DeclSpec::TST_typeofExpr ||
@@ -5987,24 +6033,6 @@ namespace {
TL.expandBuiltinRange(DS.getTypeSpecWidthRange());
}
}
- void VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
- if (DS.getTypeSpecType() == TST_typename) {
- TypeSourceInfo *TInfo = nullptr;
- Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
- if (TInfo)
- if (auto ETL = TInfo->getTypeLoc().getAs<ElaboratedTypeLoc>()) {
- TL.copy(ETL);
- return;
- }
- }
- const ElaboratedType *T = TL.getTypePtr();
- TL.setElaboratedKeywordLoc(T->getKeyword() != ElaboratedTypeKeyword::None
- ? DS.getTypeSpecTypeLoc()
- : SourceLocation());
- const CXXScopeSpec& SS = DS.getTypeSpecScope();
- TL.setQualifierLoc(SS.getWithLocInContext(Context));
- Visit(TL.getNextTypeLoc().getUnqualifiedLoc());
- }
void VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
assert(DS.getTypeSpecType() == TST_typename);
TypeSourceInfo *TInfo = nullptr;
@@ -6063,7 +6091,29 @@ namespace {
ASTTemplateArgumentListInfo::Create(Context, TemplateArgsInfo));
TL.setConceptReference(CR);
}
+ void VisitDeducedTemplateSpecializationTypeLoc(
+ DeducedTemplateSpecializationTypeLoc TL) {
+ assert(DS.getTypeSpecType() == TST_typename);
+ TypeSourceInfo *TInfo = nullptr;
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+ assert(TInfo);
+ TL.copy(
+ TInfo->getTypeLoc().castAs<DeducedTemplateSpecializationTypeLoc>());
+ }
void VisitTagTypeLoc(TagTypeLoc TL) {
+ if (DS.getTypeSpecType() == TST_typename) {
+ TypeSourceInfo *TInfo = nullptr;
+ Sema::GetTypeFromParser(DS.getRepAsType(), &TInfo);
+ if (TInfo) {
+ TL.copy(TInfo->getTypeLoc().castAs<TagTypeLoc>());
+ return;
+ }
+ }
+ TL.setElaboratedKeywordLoc(TL.getTypePtr()->getKeyword() !=
+ ElaboratedTypeKeyword::None
+ ? DS.getTypeSpecTypeLoc()
+ : SourceLocation());
+ TL.setQualifierLoc(DS.getTypeSpecScope().getWithLocInContext(Context));
TL.setNameLoc(DS.getTypeSpecTypeNameLoc());
}
void VisitAtomicTypeLoc(AtomicTypeLoc TL) {
@@ -7029,9 +7079,6 @@ static bool handleMSPointerTypeQualifierAttr(TypeProcessingState &State,
if (const TypedefType *TT = dyn_cast<TypedefType>(Desugared)) {
Desugared = TT->desugar();
continue;
- } else if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(Desugared)) {
- Desugared = ET->desugar();
- continue;
}
const AttributedType *AT = dyn_cast<AttributedType>(Desugared);
if (!AT)
@@ -9170,11 +9217,9 @@ bool Sema::RequireCompleteType(SourceLocation Loc, QualType T,
TypeDiagnoser &Diagnoser) {
if (RequireCompleteTypeImpl(Loc, T, Kind, &Diagnoser))
return true;
- if (const TagType *Tag = T->getAs<TagType>()) {
- if (!Tag->getDecl()->isCompleteDefinitionRequired()) {
- Tag->getDecl()->setCompleteDefinitionRequired();
- Consumer.HandleTagDeclRequiredDefinition(Tag->getDecl());
- }
+ if (auto *TD = T->getAsTagDecl(); TD && !TD->isCompleteDefinitionRequired()) {
+ TD->setCompleteDefinitionRequired();
+ Consumer.HandleTagDeclRequiredDefinition(TD);
}
return false;
}
@@ -9312,7 +9357,7 @@ bool Sema::hasReachableDefinition(NamedDecl *D, NamedDecl **Suggested,
/// Locks in the inheritance model for the given class and all of its bases.
static void assignInheritanceModel(Sema &S, CXXRecordDecl *RD) {
- RD = RD->getMostRecentNonInjectedDecl();
+ RD = RD->getMostRecentDecl();
if (!RD->hasAttr<MSInheritanceAttr>()) {
MSInheritanceModel IM;
bool BestCase = false;
@@ -9352,10 +9397,10 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
// assert(!T->isDependentType() &&
// "Can't ask whether a dependent type is complete");
- if (const MemberPointerType *MPTy = T->getAs<MemberPointerType>()) {
+ if (const auto *MPTy = dyn_cast<MemberPointerType>(T.getCanonicalType())) {
if (CXXRecordDecl *RD = MPTy->getMostRecentCXXRecordDecl();
RD && !RD->isDependentType()) {
- QualType T = Context.getTypeDeclType(RD);
+ CanQualType T = Context.getCanonicalTagType(RD);
if (getLangOpts().CompleteMemberPointers && !RD->isBeingDefined() &&
RequireCompleteType(Loc, T, Kind, diag::err_memptr_incomplete))
return true;
@@ -9492,10 +9537,10 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
// If the type was a forward declaration of a class/struct/union
// type, produce a note.
if (Tag && !Tag->isInvalidDecl() && !Tag->getLocation().isInvalid())
- Diag(Tag->getLocation(),
- Tag->isBeingDefined() ? diag::note_type_being_defined
- : diag::note_forward_declaration)
- << Context.getTagDeclType(Tag);
+ Diag(Tag->getLocation(), Tag->isBeingDefined()
+ ? diag::note_type_being_defined
+ : diag::note_forward_declaration)
+ << Context.getCanonicalTagType(Tag);
// If the Objective-C class was a forward declaration, produce a note.
if (IFace && !IFace->isInvalidDecl() && !IFace->getLocation().isInvalid())
@@ -9550,7 +9595,8 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T,
if (!RT)
return true;
- const CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ const CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
// A partially-defined class type can't be a literal type, because a literal
// class type must have a trivial destructor (which can't be checked until
@@ -9628,15 +9674,6 @@ bool Sema::RequireLiteralType(SourceLocation Loc, QualType T, unsigned DiagID) {
return RequireLiteralType(Loc, T, Diagnoser);
}
-QualType Sema::getElaboratedType(ElaboratedTypeKeyword Keyword,
- const CXXScopeSpec &SS, QualType T,
- TagDecl *OwnedTagDecl) {
- if (T.isNull())
- return T;
- return Context.getElaboratedType(
- Keyword, SS.isValid() ? SS.getScopeRep() : nullptr, T, OwnedTagDecl);
-}
-
QualType Sema::BuildTypeofExprType(Expr *E, TypeOfKind Kind) {
assert(!E->hasPlaceholderType() && "unexpected placeholder");
@@ -9647,7 +9684,7 @@ QualType Sema::BuildTypeofExprType(Expr *E, TypeOfKind Kind) {
if (!E->isTypeDependent()) {
QualType T = E->getType();
if (const TagType *TT = T->getAs<TagType>())
- DiagnoseUseOfDecl(TT->getDecl(), E->getExprLoc());
+ DiagnoseUseOfDecl(TT->getOriginalDecl(), E->getExprLoc());
}
return Context.getTypeOfExprType(E, Kind);
}
@@ -9813,8 +9850,7 @@ QualType Sema::BuildPackIndexingType(QualType Pattern, Expr *IndexExpr,
static QualType GetEnumUnderlyingType(Sema &S, QualType BaseType,
SourceLocation Loc) {
assert(BaseType->isEnumeralType());
- EnumDecl *ED = BaseType->castAs<EnumType>()->getDecl();
- assert(ED && "EnumType has no EnumDecl");
+ EnumDecl *ED = BaseType->castAs<EnumType>()->getOriginalDecl();
S.DiagnoseUseOfDecl(ED, Loc);
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index 1d8687e4bf1c1..9b9dd172003a0 100644
--- a/clang/lib/Sema/SemaTypeTraits.cpp
+++ b/clang/lib/Sema/SemaTypeTraits.cpp
@@ -32,8 +32,7 @@ static CXXMethodDecl *LookupSpecialMemberFromXValue(Sema &SemaRef,
RD = RD->getDefinition();
SourceLocation LookupLoc = RD->getLocation();
- CanQualType CanTy = SemaRef.getASTContext().getCanonicalType(
- SemaRef.getASTContext().getTagDeclType(RD));
+ CanQualType CanTy = SemaRef.getASTContext().getCanonicalTagType(RD);
DeclarationName Name;
Expr *Arg = nullptr;
unsigned NumArgs;
@@ -562,7 +561,8 @@ static bool HasNoThrowOperator(const RecordType *RT, OverloadedOperatorKind Op,
bool (CXXRecordDecl::*HasTrivial)() const,
bool (CXXRecordDecl::*HasNonTrivial)() const,
bool (CXXMethodDecl::*IsDesiredOp)() const) {
- CXXRecordDecl *RD = cast<CXXRecordDecl>(RT->getDecl());
+ CXXRecordDecl *RD =
+ cast<CXXRecordDecl>(RT->getOriginalDecl())->getDefinitionOrSelf();
if ((RD->*HasTrivial)() && !(RD->*HasNonTrivial)())
return true;
@@ -599,6 +599,7 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
if (Decl->isLambda())
return Decl->isCapturelessLambda();
+ CanQualType T = S.Context.getCanonicalTagType(Decl);
{
EnterExpressionEvaluationContext UnevaluatedContext(
S, Sema::ExpressionEvaluationContext::Unevaluated);
@@ -606,10 +607,7 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
Sema::ContextRAII TUContext(S, S.Context.getTranslationUnitDecl());
// const ClassT& obj;
- OpaqueValueExpr Operand(
- KeyLoc,
- Decl->getTypeForDecl()->getCanonicalTypeUnqualified().withConst(),
- ExprValueKind::VK_LValue);
+ OpaqueValueExpr Operand(KeyLoc, T.withConst(), ExprValueKind::VK_LValue);
UnresolvedSet<16> Functions;
// obj == obj;
S.LookupBinOp(S.TUScope, {}, BinaryOperatorKind::BO_EQ, Functions);
@@ -628,8 +626,7 @@ static bool HasNonDeletedDefaultedEqualityComparison(Sema &S,
return false;
if (!ParamT->isReferenceType() && !Decl->isTriviallyCopyable())
return false;
- if (ParamT.getNonReferenceType()->getUnqualifiedDesugaredType() !=
- Decl->getTypeForDecl())
+ if (!S.Context.hasSameUnqualifiedType(ParamT.getNonReferenceType(), T))
return false;
}
@@ -1613,9 +1610,9 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT,
// Unions are never base classes, and never have base classes.
// It doesn't matter if they are complete or not. See PR#41843
- if (lhsRecord && lhsRecord->getDecl()->isUnion())
+ if (lhsRecord && lhsRecord->getOriginalDecl()->isUnion())
return false;
- if (rhsRecord && rhsRecord->getDecl()->isUnion())
+ if (rhsRecord && rhsRecord->getOriginalDecl()->isUnion())
return false;
if (lhsRecord == rhsRecord)
@@ -1629,8 +1626,8 @@ bool Sema::BuiltinIsBaseOf(SourceLocation RhsTLoc, QualType LhsT,
diag::err_incomplete_type_used_in_type_trait_expr))
return false;
- return cast<CXXRecordDecl>(rhsRecord->getDecl())
- ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getDecl()));
+ return cast<CXXRecordDecl>(rhsRecord->getOriginalDecl())
+ ->isDerivedFrom(cast<CXXRecordDecl>(lhsRecord->getOriginalDecl()));
}
static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
@@ -1670,8 +1667,9 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT,
diag::err_incomplete_type))
return false;
- return cast<CXXRecordDecl>(DerivedRecord->getDecl())
- ->isVirtuallyDerivedFrom(cast<CXXRecordDecl>(BaseRecord->getDecl()));
+ return cast<CXXRecordDecl>(DerivedRecord->getOriginalDecl())
+ ->isVirtuallyDerivedFrom(
+ cast<CXXRecordDecl>(BaseRecord->getOriginalDecl()));
}
case BTT_IsSame:
return Self.Context.hasSameType(LhsT, RhsT);
@@ -2018,11 +2016,10 @@ static ExtractedTypeTraitInfo ExtractTypeTraitFromExpression(const Expr *E) {
// std::is_xxx<>::value
if (const auto *VD = dyn_cast<VarDecl>(Ref->getDecl());
Ref->hasQualifier() && VD && VD->getIdentifier()->isStr("value")) {
- const Type *T = Ref->getQualifier()->getAsType();
- if (!T)
+ NestedNameSpecifier Qualifier = Ref->getQualifier();
+ if (Qualifier.getKind() != NestedNameSpecifier::Kind::Type)
return std::nullopt;
- const TemplateSpecializationType *Ts =
- T->getAs<TemplateSpecializationType>();
+ const auto *Ts = Qualifier.getAsType()->getAs<TemplateSpecializationType>();
if (!Ts)
return std::nullopt;
const TemplateDecl *D = Ts->getTemplateName().getAsTemplateDecl();
diff --git a/clang/lib/Sema/UsedDeclVisitor.h b/clang/lib/Sema/UsedDeclVisitor.h
index 580d702f96fe5..ad475ab0f42ae 100644
--- a/clang/lib/Sema/UsedDeclVisitor.h
+++ b/clang/lib/Sema/UsedDeclVisitor.h
@@ -71,9 +71,10 @@ class UsedDeclVisitor : public EvaluatedExprVisitor<Derived> {
if (!DestroyedOrNull.isNull()) {
QualType Destroyed = S.Context.getBaseElementType(DestroyedOrNull);
if (const RecordType *DestroyedRec = Destroyed->getAs<RecordType>()) {
- CXXRecordDecl *Record = cast<CXXRecordDecl>(DestroyedRec->getDecl());
- if (Record->getDefinition())
- asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Record));
+ CXXRecordDecl *Record =
+ cast<CXXRecordDecl>(DestroyedRec->getOriginalDecl());
+ if (auto *Def = Record->getDefinition())
+ asImpl().visitUsedDecl(E->getBeginLoc(), S.LookupDestructor(Def));
}
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 30e0973149594..353560fab6692 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -5413,7 +5413,7 @@ void ASTReader::InitializeContext() {
Error("Invalid FILE type in AST file");
return;
}
- Context.setFILEDecl(Tag->getDecl());
+ Context.setFILEDecl(Tag->getOriginalDecl());
}
}
}
@@ -5434,7 +5434,7 @@ void ASTReader::InitializeContext() {
Error("Invalid jmp_buf type in AST file");
return;
}
- Context.setjmp_bufDecl(Tag->getDecl());
+ Context.setjmp_bufDecl(Tag->getOriginalDecl());
}
}
}
@@ -5452,7 +5452,7 @@ void ASTReader::InitializeContext() {
else {
const TagType *Tag = Sigjmp_bufType->getAs<TagType>();
assert(Tag && "Invalid sigjmp_buf type in AST file");
- Context.setsigjmp_bufDecl(Tag->getDecl());
+ Context.setsigjmp_bufDecl(Tag->getOriginalDecl());
}
}
}
@@ -5487,7 +5487,7 @@ void ASTReader::InitializeContext() {
else {
const TagType *Tag = Ucontext_tType->getAs<TagType>();
assert(Tag && "Invalid ucontext_t type in AST file");
- Context.setucontext_tDecl(Tag->getDecl());
+ Context.setucontext_tDecl(Tag->getOriginalDecl());
}
}
}
@@ -7107,6 +7107,7 @@ class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
void VisitFunctionTypeLoc(FunctionTypeLoc);
void VisitArrayTypeLoc(ArrayTypeLoc);
+ void VisitTagTypeLoc(TagTypeLoc TL);
};
} // namespace clang
@@ -7253,15 +7254,24 @@ void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
}
void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
- TL.setNameLoc(readSourceLocation());
+ SourceLocation ElaboratedKeywordLoc = readSourceLocation();
+ NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc();
+ SourceLocation NameLoc = readSourceLocation();
+ TL.set(ElaboratedKeywordLoc, QualifierLoc, NameLoc);
}
void TypeLocReader::VisitUsingTypeLoc(UsingTypeLoc TL) {
- TL.setNameLoc(readSourceLocation());
+ SourceLocation ElaboratedKeywordLoc = readSourceLocation();
+ NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc();
+ SourceLocation NameLoc = readSourceLocation();
+ TL.set(ElaboratedKeywordLoc, QualifierLoc, NameLoc);
}
void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
- TL.setNameLoc(readSourceLocation());
+ SourceLocation ElaboratedKeywordLoc = readSourceLocation();
+ NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc();
+ SourceLocation NameLoc = readSourceLocation();
+ TL.set(ElaboratedKeywordLoc, QualifierLoc, NameLoc);
}
void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) {
@@ -7315,17 +7325,27 @@ void TypeLocReader::VisitAutoTypeLoc(AutoTypeLoc TL) {
void TypeLocReader::VisitDeducedTemplateSpecializationTypeLoc(
DeducedTemplateSpecializationTypeLoc TL) {
+ TL.setElaboratedKWLoc(readSourceLocation());
+ TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
TL.setTemplateNameLoc(readSourceLocation());
}
-void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
+void TypeLocReader::VisitTagTypeLoc(TagTypeLoc TL) {
+ TL.setElaboratedKeywordLoc(readSourceLocation());
+ TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
TL.setNameLoc(readSourceLocation());
}
-void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) {
- TL.setNameLoc(readSourceLocation());
+void TypeLocReader::VisitRecordTypeLoc(RecordTypeLoc TL) {
+ VisitTagTypeLoc(TL);
}
+void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+ VisitTagTypeLoc(TL);
+}
+
+void TypeLocReader::VisitEnumTypeLoc(EnumTypeLoc TL) { VisitTagTypeLoc(TL); }
+
void TypeLocReader::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
TL.setAttr(ReadAttr());
}
@@ -7363,14 +7383,18 @@ void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc(
void TypeLocReader::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
- TL.setTemplateKeywordLoc(readSourceLocation());
- TL.setTemplateNameLoc(readSourceLocation());
- TL.setLAngleLoc(readSourceLocation());
- TL.setRAngleLoc(readSourceLocation());
- for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
- TL.setArgLocInfo(i,
- Reader.readTemplateArgumentLocInfo(
- TL.getTypePtr()->template_arguments()[i].getKind()));
+ SourceLocation ElaboratedKeywordLoc = readSourceLocation();
+ NestedNameSpecifierLoc QualifierLoc = ReadNestedNameSpecifierLoc();
+ SourceLocation TemplateKeywordLoc = readSourceLocation();
+ SourceLocation NameLoc = readSourceLocation();
+ SourceLocation LAngleLoc = readSourceLocation();
+ SourceLocation RAngleLoc = readSourceLocation();
+ TL.set(ElaboratedKeywordLoc, QualifierLoc, TemplateKeywordLoc, NameLoc,
+ LAngleLoc, RAngleLoc);
+ MutableArrayRef<TemplateArgumentLocInfo> Args = TL.getArgLocInfos();
+ for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
+ Args[I] = Reader.readTemplateArgumentLocInfo(
+ TL.getTypePtr()->template_arguments()[I].getKind());
}
void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
@@ -7378,15 +7402,6 @@ void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) {
TL.setRParenLoc(readSourceLocation());
}
-void TypeLocReader::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
- TL.setElaboratedKeywordLoc(readSourceLocation());
- TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
-}
-
-void TypeLocReader::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- TL.setNameLoc(readSourceLocation());
-}
-
void TypeLocReader::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
TL.setElaboratedKeywordLoc(readSourceLocation());
TL.setQualifierLoc(ReadNestedNameSpecifierLoc());
@@ -7838,18 +7853,15 @@ ASTRecordReader::readTemplateArgumentLocInfo(TemplateArgument::ArgKind Kind) {
return readExpr();
case TemplateArgument::Type:
return readTypeSourceInfo();
- case TemplateArgument::Template: {
- NestedNameSpecifierLoc QualifierLoc =
- readNestedNameSpecifierLoc();
- SourceLocation TemplateNameLoc = readSourceLocation();
- return TemplateArgumentLocInfo(getASTContext(), QualifierLoc,
- TemplateNameLoc, SourceLocation());
- }
+ case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion: {
+ SourceLocation TemplateKWLoc = readSourceLocation();
NestedNameSpecifierLoc QualifierLoc = readNestedNameSpecifierLoc();
SourceLocation TemplateNameLoc = readSourceLocation();
- SourceLocation EllipsisLoc = readSourceLocation();
- return TemplateArgumentLocInfo(getASTContext(), QualifierLoc,
+ SourceLocation EllipsisLoc = Kind == TemplateArgument::TemplateExpansion
+ ? readSourceLocation()
+ : SourceLocation();
+ return TemplateArgumentLocInfo(getASTContext(), TemplateKWLoc, QualifierLoc,
TemplateNameLoc, EllipsisLoc);
}
case TemplateArgument::Null:
@@ -9458,12 +9470,6 @@ void ASTReader::AssignedLambdaNumbering(CXXRecordDecl *Lambda) {
CXXRecordDecl *Previous =
cast<CXXRecordDecl>(Iter->second)->getMostRecentDecl();
Lambda->setPreviousDecl(Previous);
- // FIXME: It will be best to use the Previous type when we creating the
- // lambda directly. But that requires us to get the lambda context decl and
- // lambda index before creating the lambda, which needs a drastic change in
- // the parser.
- const_cast<QualType &>(Lambda->TypeForDecl->CanonicalType) =
- Previous->TypeForDecl->CanonicalType;
return;
}
@@ -9979,48 +9985,37 @@ ASTRecordReader::readNestedNameSpecifierLoc() {
for (unsigned I = 0; I != N; ++I) {
auto Kind = readNestedNameSpecifierKind();
switch (Kind) {
- case NestedNameSpecifier::Identifier: {
- IdentifierInfo *II = readIdentifier();
- SourceRange Range = readSourceRange();
- Builder.Extend(Context, II, Range.getBegin(), Range.getEnd());
- break;
- }
-
- case NestedNameSpecifier::Namespace: {
- NamespaceDecl *NS = readDeclAs<NamespaceDecl>();
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto *NS = readDeclAs<NamespaceBaseDecl>();
SourceRange Range = readSourceRange();
Builder.Extend(Context, NS, Range.getBegin(), Range.getEnd());
break;
}
- case NestedNameSpecifier::NamespaceAlias: {
- NamespaceAliasDecl *Alias = readDeclAs<NamespaceAliasDecl>();
- SourceRange Range = readSourceRange();
- Builder.Extend(Context, Alias, Range.getBegin(), Range.getEnd());
- break;
- }
-
- case NestedNameSpecifier::TypeSpec: {
+ case NestedNameSpecifier::Kind::Type: {
TypeSourceInfo *T = readTypeSourceInfo();
if (!T)
return NestedNameSpecifierLoc();
SourceLocation ColonColonLoc = readSourceLocation();
- Builder.Extend(Context, T->getTypeLoc(), ColonColonLoc);
+ Builder.Make(Context, T->getTypeLoc(), ColonColonLoc);
break;
}
- case NestedNameSpecifier::Global: {
+ case NestedNameSpecifier::Kind::Global: {
SourceLocation ColonColonLoc = readSourceLocation();
Builder.MakeGlobal(Context, ColonColonLoc);
break;
}
- case NestedNameSpecifier::Super: {
+ case NestedNameSpecifier::Kind::Super: {
CXXRecordDecl *RD = readDeclAs<CXXRecordDecl>();
SourceRange Range = readSourceRange();
Builder.MakeSuper(Context, RD, Range.getBegin(), Range.getEnd());
break;
}
+
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
}
@@ -10416,12 +10411,7 @@ void ASTReader::finishPendingActions() {
// happen now, after the redeclaration chains have been fully wired.
for (Decl *D : PendingDefinitions) {
if (TagDecl *TD = dyn_cast<TagDecl>(D)) {
- if (const TagType *TagT = dyn_cast<TagType>(TD->getTypeForDecl())) {
- // Make sure that the TagType points at the definition.
- const_cast<TagType*>(TagT)->decl = TD;
- }
-
- if (auto RD = dyn_cast<CXXRecordDecl>(D)) {
+ if (auto *RD = dyn_cast<CXXRecordDecl>(TD)) {
for (auto *R = getMostRecentExistingDecl(RD); R;
R = R->getPreviousDecl()) {
assert((R == D) ==
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 8bde213dc4cb3..ecaf3ad2d9333 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -538,7 +538,11 @@ void ASTDeclReader::Visit(Decl *D) {
if (auto *TD = dyn_cast<TypeDecl>(D)) {
// We have a fully initialized TypeDecl. Read its type now.
- TD->setTypeForDecl(Reader.GetType(DeferredTypeID).getTypePtrOrNull());
+ if (isa<TagDecl, TypedefDecl, TypeAliasDecl>(TD))
+ assert(DeferredTypeID == 0 &&
+ "Deferred type not used for TagDecls and Typedefs");
+ else
+ TD->setTypeForDecl(Reader.GetType(DeferredTypeID).getTypePtrOrNull());
// If this is a tag declaration with a typedef name for linkage, it's safe
// to load that typedef now.
@@ -695,7 +699,8 @@ void ASTDeclReader::VisitTypeDecl(TypeDecl *TD) {
VisitNamedDecl(TD);
TD->setLocStart(readSourceLocation());
// Delay type reading until after we have fully initialized the decl.
- DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
+ if (!isa<TagDecl, TypedefDecl, TypeAliasDecl>(TD))
+ DeferredTypeID = Record.getGlobalTypeID(Record.readInt());
}
RedeclarableResult ASTDeclReader::VisitTypedefNameDecl(TypedefNameDecl *TD) {
@@ -1888,7 +1893,7 @@ void ASTDeclReader::VisitNamespaceAliasDecl(NamespaceAliasDecl *D) {
D->NamespaceLoc = readSourceLocation();
D->IdentLoc = readSourceLocation();
D->QualifierLoc = Record.readNestedNameSpecifierLoc();
- D->Namespace = readDeclAs<NamedDecl>();
+ D->Namespace = readDeclAs<NamespaceBaseDecl>();
mergeRedeclarable(D, Redecl);
}
@@ -2235,15 +2240,6 @@ RedeclarableResult ASTDeclReader::VisitCXXRecordDeclImpl(CXXRecordDecl *D) {
// Merged when we merge the template.
auto *Template = readDeclAs<ClassTemplateDecl>();
D->TemplateOrInstantiation = Template;
- if (!Template->getTemplatedDecl()) {
- // We've not actually loaded the ClassTemplateDecl yet, because we're
- // currently being loaded as its pattern. Rely on it to set up our
- // TypeForDecl (see VisitClassTemplateDecl).
- //
- // Beware: we do not yet know our canonical declaration, and may still
- // get merged once the surrounding class template has got off the ground.
- DeferredTypeID = 0;
- }
break;
}
case CXXRecMemberSpecialization: {
@@ -2477,14 +2473,6 @@ void ASTDeclReader::VisitClassTemplateDecl(ClassTemplateDecl *D) {
ReadSpecializations(*Loc.F, D, Loc.F->DeclsCursor, /*IsPartial=*/false);
ReadSpecializations(*Loc.F, D, Loc.F->DeclsCursor, /*IsPartial=*/true);
}
-
- if (D->getTemplatedDecl()->TemplateOrInstantiation) {
- // We were loaded before our templated declaration was. We've not set up
- // its corresponding type yet (see VisitCXXRecordDeclImpl), so reconstruct
- // it now.
- Reader.getContext().getInjectedClassNameType(
- D->getTemplatedDecl(), D->getInjectedClassNameSpecialization());
- }
}
void ASTDeclReader::VisitBuiltinTemplateDecl(BuiltinTemplateDecl *D) {
diff --git a/clang/lib/Serialization/ASTWriter.cpp b/clang/lib/Serialization/ASTWriter.cpp
index 1a20fc9595dce..2d41482327c15 100644
--- a/clang/lib/Serialization/ASTWriter.cpp
+++ b/clang/lib/Serialization/ASTWriter.cpp
@@ -345,6 +345,7 @@ class TypeLocWriter : public TypeLocVisitor<TypeLocWriter> {
void VisitArrayTypeLoc(ArrayTypeLoc TyLoc);
void VisitFunctionTypeLoc(FunctionTypeLoc TyLoc);
+ void VisitTagTypeLoc(TagTypeLoc TL);
};
} // namespace
@@ -490,14 +491,20 @@ void TypeLocWriter::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) {
}
void TypeLocWriter::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+ addSourceLocation(TL.getElaboratedKeywordLoc());
+ Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
addSourceLocation(TL.getNameLoc());
}
void TypeLocWriter::VisitUsingTypeLoc(UsingTypeLoc TL) {
+ addSourceLocation(TL.getElaboratedKeywordLoc());
+ Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
addSourceLocation(TL.getNameLoc());
}
void TypeLocWriter::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
+ addSourceLocation(TL.getElaboratedKeywordLoc());
+ Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
addSourceLocation(TL.getNameLoc());
}
@@ -564,17 +571,27 @@ void TypeLocWriter::VisitAutoTypeLoc(AutoTypeLoc TL) {
void TypeLocWriter::VisitDeducedTemplateSpecializationTypeLoc(
DeducedTemplateSpecializationTypeLoc TL) {
+ addSourceLocation(TL.getElaboratedKWLoc());
+ Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
addSourceLocation(TL.getTemplateNameLoc());
}
-void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
+void TypeLocWriter::VisitTagTypeLoc(TagTypeLoc TL) {
+ addSourceLocation(TL.getElaboratedKeywordLoc());
+ Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
addSourceLocation(TL.getNameLoc());
}
-void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) {
- addSourceLocation(TL.getNameLoc());
+void TypeLocWriter::VisitRecordTypeLoc(RecordTypeLoc TL) {
+ VisitTagTypeLoc(TL);
+}
+
+void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
+ VisitTagTypeLoc(TL);
}
+void TypeLocWriter::VisitEnumTypeLoc(EnumTypeLoc TL) { VisitTagTypeLoc(TL); }
+
void TypeLocWriter::VisitAttributedTypeLoc(AttributedTypeLoc TL) {
Record.AddAttr(TL.getAttr());
}
@@ -612,13 +629,14 @@ void TypeLocWriter::VisitSubstTemplateTypeParmPackTypeLoc(
void TypeLocWriter::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
+ addSourceLocation(TL.getElaboratedKeywordLoc());
+ Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
addSourceLocation(TL.getTemplateKeywordLoc());
addSourceLocation(TL.getTemplateNameLoc());
addSourceLocation(TL.getLAngleLoc());
addSourceLocation(TL.getRAngleLoc());
for (unsigned i = 0, e = TL.getNumArgs(); i != e; ++i)
- Record.AddTemplateArgumentLocInfo(TL.getArgLoc(i).getArgument().getKind(),
- TL.getArgLoc(i).getLocInfo());
+ Record.AddTemplateArgumentLocInfo(TL.getArgLoc(i));
}
void TypeLocWriter::VisitParenTypeLoc(ParenTypeLoc TL) {
@@ -630,15 +648,6 @@ void TypeLocWriter::VisitMacroQualifiedTypeLoc(MacroQualifiedTypeLoc TL) {
addSourceLocation(TL.getExpansionLoc());
}
-void TypeLocWriter::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
- addSourceLocation(TL.getElaboratedKeywordLoc());
- Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
-}
-
-void TypeLocWriter::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- addSourceLocation(TL.getNameLoc());
-}
-
void TypeLocWriter::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
addSourceLocation(TL.getElaboratedKeywordLoc());
Record.AddNestedNameSpecifierLoc(TL.getQualifierLoc());
@@ -654,8 +663,7 @@ void TypeLocWriter::VisitDependentTemplateSpecializationTypeLoc(
addSourceLocation(TL.getLAngleLoc());
addSourceLocation(TL.getRAngleLoc());
for (unsigned I = 0, E = TL.getNumArgs(); I != E; ++I)
- Record.AddTemplateArgumentLocInfo(TL.getArgLoc(I).getArgument().getKind(),
- TL.getArgLoc(I).getLocInfo());
+ Record.AddTemplateArgumentLocInfo(TL.getArgLoc(I));
}
void TypeLocWriter::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
@@ -1033,7 +1041,6 @@ void ASTWriter::WriteBlockInfoBlock() {
RECORD(TYPE_OBJC_INTERFACE);
RECORD(TYPE_OBJC_OBJECT_POINTER);
RECORD(TYPE_DECLTYPE);
- RECORD(TYPE_ELABORATED);
RECORD(TYPE_SUBST_TEMPLATE_TYPE_PARM);
RECORD(TYPE_UNRESOLVED_USING);
RECORD(TYPE_INJECTED_CLASS_NAME);
@@ -6749,22 +6756,22 @@ void ASTRecordWriter::AddCXXTemporary(const CXXTemporary *Temp) {
}
void ASTRecordWriter::AddTemplateArgumentLocInfo(
- TemplateArgument::ArgKind Kind, const TemplateArgumentLocInfo &Arg) {
- switch (Kind) {
+ const TemplateArgumentLoc &Arg) {
+ const TemplateArgumentLocInfo &Info = Arg.getLocInfo();
+ switch (auto K = Arg.getArgument().getKind()) {
case TemplateArgument::Expression:
- AddStmt(Arg.getAsExpr());
+ AddStmt(Info.getAsExpr());
break;
case TemplateArgument::Type:
- AddTypeSourceInfo(Arg.getAsTypeSourceInfo());
+ AddTypeSourceInfo(Info.getAsTypeSourceInfo());
break;
case TemplateArgument::Template:
- AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc());
- AddSourceLocation(Arg.getTemplateNameLoc());
- break;
case TemplateArgument::TemplateExpansion:
+ AddSourceLocation(Arg.getTemplateKWLoc());
AddNestedNameSpecifierLoc(Arg.getTemplateQualifierLoc());
AddSourceLocation(Arg.getTemplateNameLoc());
- AddSourceLocation(Arg.getTemplateEllipsisLoc());
+ if (K == TemplateArgument::TemplateExpansion)
+ AddSourceLocation(Arg.getTemplateEllipsisLoc());
break;
case TemplateArgument::Null:
case TemplateArgument::Integral:
@@ -6787,7 +6794,7 @@ void ASTRecordWriter::AddTemplateArgumentLoc(const TemplateArgumentLoc &Arg) {
if (InfoHasSameExpr)
return; // Avoid storing the same expr twice.
}
- AddTemplateArgumentLocInfo(Arg.getArgument().getKind(), Arg.getLocInfo());
+ AddTemplateArgumentLocInfo(Arg);
}
void ASTRecordWriter::AddTypeSourceInfo(TypeSourceInfo *TInfo) {
@@ -7045,54 +7052,50 @@ void ASTRecordWriter::AddQualifierInfo(const QualifierInfo &Info) {
AddTemplateParameterList(Info.TemplParamLists[i]);
}
-void ASTRecordWriter::AddNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+void ASTRecordWriter::AddNestedNameSpecifierLoc(
+ NestedNameSpecifierLoc QualifierLoc) {
// Nested name specifiers usually aren't too long. I think that 8 would
// typically accommodate the vast majority.
SmallVector<NestedNameSpecifierLoc , 8> NestedNames;
// Push each of the nested-name-specifiers's onto a stack for
// serialization in reverse order.
- while (NNS) {
- NestedNames.push_back(NNS);
- NNS = NNS.getPrefix();
+ while (QualifierLoc) {
+ NestedNames.push_back(QualifierLoc);
+ QualifierLoc = QualifierLoc.getAsNamespaceAndPrefix().Prefix;
}
Record->push_back(NestedNames.size());
while(!NestedNames.empty()) {
- NNS = NestedNames.pop_back_val();
- NestedNameSpecifier::SpecifierKind Kind
- = NNS.getNestedNameSpecifier()->getKind();
- Record->push_back(Kind);
+ QualifierLoc = NestedNames.pop_back_val();
+ NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
+ NestedNameSpecifier::Kind Kind = Qualifier.getKind();
+ Record->push_back(llvm::to_underlying(Kind));
switch (Kind) {
- case NestedNameSpecifier::Identifier:
- AddIdentifierRef(NNS.getNestedNameSpecifier()->getAsIdentifier());
- AddSourceRange(NNS.getLocalSourceRange());
+ case NestedNameSpecifier::Kind::Namespace:
+ AddDeclRef(Qualifier.getAsNamespaceAndPrefix().Namespace);
+ AddSourceRange(QualifierLoc.getLocalSourceRange());
break;
- case NestedNameSpecifier::Namespace:
- AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespace());
- AddSourceRange(NNS.getLocalSourceRange());
- break;
-
- case NestedNameSpecifier::NamespaceAlias:
- AddDeclRef(NNS.getNestedNameSpecifier()->getAsNamespaceAlias());
- AddSourceRange(NNS.getLocalSourceRange());
+ case NestedNameSpecifier::Kind::Type: {
+ TypeLoc TL = QualifierLoc.castAsTypeLoc();
+ AddTypeRef(TL.getType());
+ AddTypeLoc(TL);
+ AddSourceLocation(QualifierLoc.getLocalSourceRange().getEnd());
break;
+ }
- case NestedNameSpecifier::TypeSpec:
- AddTypeRef(NNS.getTypeLoc().getType());
- AddTypeLoc(NNS.getTypeLoc());
- AddSourceLocation(NNS.getLocalSourceRange().getEnd());
+ case NestedNameSpecifier::Kind::Global:
+ AddSourceLocation(QualifierLoc.getLocalSourceRange().getEnd());
break;
- case NestedNameSpecifier::Global:
- AddSourceLocation(NNS.getLocalSourceRange().getEnd());
+ case NestedNameSpecifier::Kind::Super:
+ AddDeclRef(Qualifier.getAsSuper());
+ AddSourceRange(QualifierLoc.getLocalSourceRange());
break;
- case NestedNameSpecifier::Super:
- AddDeclRef(NNS.getNestedNameSpecifier()->getAsRecordDecl());
- AddSourceRange(NNS.getLocalSourceRange());
- break;
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
}
}
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index b8a68afc30738..b426a9c58a74f 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -524,7 +524,7 @@ void ASTDeclWriter::VisitDecl(Decl *D) {
// bits actually. However, if we changed the order to be 0x0f, then we can
// store it as 0b001111, which takes 6 bits only now.
DeclBits.addBits((uint64_t)D->getModuleOwnershipKind(), /*BitWidth=*/3);
- DeclBits.addBit(D->isReferenced());
+ DeclBits.addBit(D->isThisDeclarationReferenced());
DeclBits.addBit(D->isUsed(false));
DeclBits.addBits(D->getAccess(), /*BitWidth=*/2);
DeclBits.addBit(D->isImplicit());
@@ -601,7 +601,8 @@ void ASTDeclWriter::VisitNamedDecl(NamedDecl *D) {
void ASTDeclWriter::VisitTypeDecl(TypeDecl *D) {
VisitNamedDecl(D);
Record.AddSourceLocation(D->getBeginLoc());
- Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
+ if (!isa<TagDecl, TypedefDecl, TypeAliasDecl>(D))
+ Record.AddTypeRef(QualType(D->getTypeForDecl(), 0));
}
void ASTDeclWriter::VisitTypedefNameDecl(TypedefNameDecl *D) {
@@ -2559,7 +2560,6 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
// TypeDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
// TagDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
Abv->Add(BitCodeAbbrevOp(
@@ -2605,7 +2605,6 @@ void ASTWriter::WriteDeclAbbrevs() {
Abv->Add(BitCodeAbbrevOp(0)); // AnonDeclNumber
// TypeDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Source Location
- Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // Type Ref
// TagDecl
Abv->Add(BitCodeAbbrevOp(BitCodeAbbrevOp::VBR, 6)); // IdentifierNamespace
Abv->Add(BitCodeAbbrevOp(
diff --git a/clang/lib/Serialization/TemplateArgumentHasher.cpp b/clang/lib/Serialization/TemplateArgumentHasher.cpp
index c56138e8893c1..3e8ffea78c2f1 100644
--- a/clang/lib/Serialization/TemplateArgumentHasher.cpp
+++ b/clang/lib/Serialization/TemplateArgumentHasher.cpp
@@ -320,7 +320,7 @@ class TypeVisitorHelper : public TypeVisitor<TypeVisitorHelper> {
void VisitMemberPointerType(const MemberPointerType *T) {
AddQualType(T->getPointeeType());
- AddType(T->getQualifier()->getAsType());
+ AddType(T->getQualifier().getAsType());
if (auto *RD = T->getMostRecentCXXRecordDecl())
AddDecl(RD->getCanonicalDecl());
}
@@ -358,7 +358,7 @@ class TypeVisitorHelper : public TypeVisitor<TypeVisitorHelper> {
AddQualType(T->getReplacementType());
}
- void VisitTagType(const TagType *T) { AddDecl(T->getDecl()); }
+ void VisitTagType(const TagType *T) { AddDecl(T->getOriginalDecl()); }
void VisitRecordType(const RecordType *T) { VisitTagType(T); }
void VisitEnumType(const EnumType *T) { VisitTagType(T); }
@@ -379,10 +379,6 @@ class TypeVisitorHelper : public TypeVisitor<TypeVisitorHelper> {
void VisitTypedefType(const TypedefType *T) { AddDecl(T->getDecl()); }
- void VisitElaboratedType(const ElaboratedType *T) {
- AddQualType(T->getNamedType());
- }
-
void VisitUnaryTransformType(const UnaryTransformType *T) {
AddQualType(T->getUnderlyingType());
AddQualType(T->getBaseType());
diff --git a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
index 23935647a5826..731e506a5d259 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CallAndMessageChecker.cpp
@@ -250,7 +250,7 @@ class FindUninitializedField {
bool Find(const TypedValueRegion *R) {
QualType T = R->getValueType();
if (const RecordType *RT = T->getAsStructureType()) {
- const RecordDecl *RD = RT->getDecl()->getDefinition();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
assert(RD && "Referred record has no definition");
for (const auto *I : RD->fields()) {
if (I->isUnnamedBitField())
diff --git a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
index 0b52c9bd8ac2a..90c6537d71d9d 100644
--- a/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/CastSizeChecker.cpp
@@ -53,7 +53,7 @@ static bool evenFlexibleArraySize(ASTContext &Ctx, CharUnits RegionSize,
if (!RT)
return false;
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
RecordDecl::field_iterator Iter(RD->field_begin());
RecordDecl::field_iterator End(RD->field_end());
const FieldDecl *Last = nullptr;
diff --git a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
index 4982cd59b0a4a..cee744aecb686 100644
--- a/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/DynamicTypePropagation.cpp
@@ -245,7 +245,7 @@ static void recordFixedType(const MemRegion *Region, const CXXMethodDecl *MD,
assert(MD);
ASTContext &Ctx = C.getASTContext();
- QualType Ty = Ctx.getPointerType(Ctx.getRecordType(MD->getParent()));
+ CanQualType Ty = Ctx.getPointerType(Ctx.getCanonicalTagType(MD->getParent()));
ProgramStateRef State = C.getState();
State = setDynamicTypeInfo(State, Region, Ty, /*CanBeSubClassed=*/false);
diff --git a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
index 355e82e465e82..054b2e96bd13b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/EnumCastOutOfRangeChecker.cpp
@@ -148,7 +148,8 @@ void EnumCastOutOfRangeChecker::checkPreStmt(const CastExpr *CE,
// If the isEnumeralType() returned true, then the declaration must exist
// even if it is a stub declaration. It is up to the getDeclValuesForEnum()
// function to handle this.
- const EnumDecl *ED = T->castAs<EnumType>()->getDecl();
+ const EnumDecl *ED =
+ T->castAs<EnumType>()->getOriginalDecl()->getDefinitionOrSelf();
// [[clang::flag_enum]] annotated enums are by definition should be ignored.
if (ED->hasAttr<FlagEnumAttr>())
diff --git a/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
index 1cb3848cfed2a..828b6f91d81c2 100644
--- a/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
@@ -47,9 +47,6 @@ static bool InNamespace(const Decl *D, StringRef NS) {
}
static bool IsStdString(QualType T) {
- if (const ElaboratedType *QT = T->getAs<ElaboratedType>())
- T = QT->getNamedType();
-
const TypedefType *TT = T->getAs<TypedefType>();
if (!TT)
return false;
@@ -201,7 +198,7 @@ static bool IsPartOfAST(const CXXRecordDecl *R) {
for (const auto &BS : R->bases()) {
QualType T = BS.getType();
if (const RecordType *baseT = T->getAs<RecordType>()) {
- CXXRecordDecl *baseD = cast<CXXRecordDecl>(baseT->getDecl());
+ CXXRecordDecl *baseD = cast<CXXRecordDecl>(baseT->getOriginalDecl());
if (IsPartOfAST(baseD))
return true;
}
@@ -247,7 +244,7 @@ void ASTFieldVisitor::Visit(FieldDecl *D) {
ReportError(T);
if (const RecordType *RT = T->getAs<RecordType>()) {
- const RecordDecl *RD = RT->getDecl()->getDefinition();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinition();
for (auto *I : RD->fields())
Visit(I);
}
diff --git a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
index 0aea981252259..b1a7cd7620424 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NonNullParamChecker.cpp
@@ -148,7 +148,9 @@ void NonNullParamChecker::checkPreCall(const CallEvent &Call,
QualType T = ArgE->getType();
const RecordType *UT = T->getAsUnionType();
- if (!UT || !UT->getDecl()->hasAttr<TransparentUnionAttr>())
+ if (!UT || !UT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<TransparentUnionAttr>())
continue;
auto CSV = DV->getAs<nonloc::CompoundVal>();
diff --git a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
index 7927967093dcb..b5e32495235aa 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NonnullGlobalConstantsChecker.cpp
@@ -114,10 +114,7 @@ bool NonnullGlobalConstantsChecker::isGlobalConstString(SVal V) const {
if (AT->getAttrKind() == attr::TypeNonNull)
return true;
Ty = AT->getModifiedType();
- } else if (const auto *ET = dyn_cast<ElaboratedType>(T)) {
- const auto *TT = dyn_cast<TypedefType>(ET->getNamedType());
- if (!TT)
- return false;
+ } else if (const auto *TT = dyn_cast<TypedefType>(T)) {
Ty = TT->getDecl()->getUnderlyingType();
// It is sufficient for any intermediate typedef
// to be classified const.
diff --git a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
index f217520d8f4a0..68ab22a44e7b6 100644
--- a/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/NumberObjectConversionChecker.cpp
@@ -197,9 +197,9 @@ void NumberObjectConversionChecker::checkASTCodeBody(const Decl *D,
BugReporter &BR) const {
// Currently this matches CoreFoundation opaque pointer typedefs.
auto CSuspiciousNumberObjectExprM = expr(ignoringParenImpCasts(
- expr(hasType(elaboratedType(namesType(typedefType(
+ expr(hasType(typedefType(
hasDeclaration(anyOf(typedefDecl(hasName("CFNumberRef")),
- typedefDecl(hasName("CFBooleanRef")))))))))
+ typedefDecl(hasName("CFBooleanRef")))))))
.bind("c_object")));
// Currently this matches XNU kernel number-object pointers.
@@ -238,8 +238,7 @@ void NumberObjectConversionChecker::checkASTCodeBody(const Decl *D,
// The .bind here is in order to compose the error message more accurately.
auto ObjCSuspiciousScalarBooleanTypeM =
- qualType(elaboratedType(namesType(
- typedefType(hasDeclaration(typedefDecl(hasName("BOOL")))))))
+ qualType(typedefType(hasDeclaration(typedefDecl(hasName("BOOL")))))
.bind("objc_bool_type");
// The .bind here is in order to compose the error message more accurately.
@@ -252,8 +251,8 @@ void NumberObjectConversionChecker::checkASTCodeBody(const Decl *D,
// for storing pointers.
auto SuspiciousScalarNumberTypeM =
qualType(hasCanonicalType(isInteger()),
- unless(elaboratedType(namesType(typedefType(hasDeclaration(
- typedefDecl(matchesName("^::u?intptr_t$"))))))))
+ unless(typedefType(
+ hasDeclaration(typedefDecl(matchesName("^::u?intptr_t$"))))))
.bind("int_type");
auto SuspiciousScalarTypeM =
diff --git a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
index d4efbdd54fc22..7ef659518ab1b 100644
--- a/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/PaddingChecker.cpp
@@ -104,7 +104,7 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
// There is not enough excess padding to trigger a warning.
return;
}
- reportRecord(RD, BaselinePad, OptimalPad, OptimalFieldsOrder);
+ reportRecord(ASTContext, RD, BaselinePad, OptimalPad, OptimalFieldsOrder);
}
/// Look for arrays of overly padded types. If the padding of the
@@ -123,7 +123,7 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
return;
// TODO: Recurse into the fields to see if they have excess padding.
- visitRecord(RT->getDecl(), Elts);
+ visitRecord(RT->getOriginalDecl()->getDefinitionOrSelf(), Elts);
}
bool shouldSkipDecl(const RecordDecl *RD) const {
@@ -159,9 +159,7 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
return true;
// Can't layout a template, so skip it. We do still layout the
// instantiations though.
- if (CXXRD->getTypeForDecl()->isDependentType())
- return true;
- if (CXXRD->getTypeForDecl()->isInstantiationDependentType())
+ if (CXXRD->isDependentType())
return true;
}
// How do you reorder fields if you haven't got any?
@@ -306,14 +304,14 @@ class PaddingChecker : public Checker<check::ASTDecl<TranslationUnitDecl>> {
}
void reportRecord(
- const RecordDecl *RD, CharUnits BaselinePad, CharUnits OptimalPad,
+ const ASTContext &Ctx, const RecordDecl *RD, CharUnits BaselinePad,
+ CharUnits OptimalPad,
const SmallVector<const FieldDecl *, 20> &OptimalFieldsOrder) const {
SmallString<100> Buf;
llvm::raw_svector_ostream Os(Buf);
Os << "Excessive padding in '";
- Os << QualType::getAsString(RD->getTypeForDecl(), Qualifiers(),
- LangOptions())
- << "'";
+ QualType(Ctx.getCanonicalTagType(RD)).print(Os, LangOptions());
+ Os << "'";
if (auto *TSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
// TODO: make this show up better in the console output and in
diff --git a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 1c748f9bc1828..c82618fc7a3fb 100644
--- a/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -1589,7 +1589,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
// and we have a TypedefDecl with the name 'FILE'.
for (Decl *D : LookupRes)
if (auto *TD = dyn_cast<TypedefNameDecl>(D))
- return ACtx.getTypeDeclType(TD).getCanonicalType();
+ return ACtx.getCanonicalTypeDeclType(TD);
// Find the first TypeDecl.
// There maybe cases when a function has the same name as a struct.
@@ -1597,7 +1597,7 @@ void StdLibraryFunctionsChecker::initFunctionSummaries(
// int stat(const char *restrict path, struct stat *restrict buf);
for (Decl *D : LookupRes)
if (auto *TD = dyn_cast<TypeDecl>(D))
- return ACtx.getTypeDeclType(TD).getCanonicalType();
+ return ACtx.getCanonicalTypeDeclType(TD);
return std::nullopt;
}
} lookupTy(ACtx);
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
index 72199af2f80a5..36c12582a5787 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/PtrTypesSemantics.cpp
@@ -181,10 +181,6 @@ template <typename Predicate>
static bool isPtrOfType(const clang::QualType T, Predicate Pred) {
QualType type = T;
while (!type.isNull()) {
- if (auto *elaboratedT = type->getAs<ElaboratedType>()) {
- type = elaboratedT->desugar();
- continue;
- }
if (auto *SpecialT = type->getAs<TemplateSpecializationType>()) {
auto *Decl = SpecialT->getTemplateName().getAsTemplateDecl();
return Decl && Pred(Decl->getNameAsString());
@@ -248,13 +244,15 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) {
const RecordType *RT = PointeeQT->getAs<RecordType>();
if (!RT) {
if (TD->hasAttr<ObjCBridgeAttr>() || TD->hasAttr<ObjCBridgeMutableAttr>()) {
- if (auto *Type = TD->getTypeForDecl())
- RecordlessTypes.insert(Type);
+ RecordlessTypes.insert(TD->getASTContext()
+ .getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, TD)
+ .getTypePtr());
}
return;
}
- for (auto *Redecl : RT->getDecl()->getMostRecentDecl()->redecls()) {
+ for (auto *Redecl : RT->getOriginalDecl()->getMostRecentDecl()->redecls()) {
if (Redecl->getAttr<ObjCBridgeAttr>() ||
Redecl->getAttr<ObjCBridgeMutableAttr>()) {
CFPointees.insert(RT);
@@ -266,21 +264,10 @@ void RetainTypeChecker::visitTypedef(const TypedefDecl *TD) {
bool RetainTypeChecker::isUnretained(const QualType QT, bool ignoreARC) {
if (ento::cocoa::isCocoaObjectRef(QT) && (!IsARCEnabled || ignoreARC))
return true;
- auto CanonicalType = QT.getCanonicalType();
- auto PointeeType = CanonicalType->getPointeeType();
- auto *RT = dyn_cast_or_null<RecordType>(PointeeType.getTypePtrOrNull());
- if (!RT) {
- auto *Type = QT.getTypePtrOrNull();
- while (Type) {
- if (RecordlessTypes.contains(Type))
- return true;
- auto *ET = dyn_cast_or_null<ElaboratedType>(Type);
- if (!ET)
- break;
- Type = ET->desugar().getTypePtrOrNull();
- }
- }
- return RT && CFPointees.contains(RT);
+ if (auto *RT = dyn_cast_or_null<RecordType>(
+ QT.getCanonicalType()->getPointeeType().getTypePtrOrNull()))
+ return CFPointees.contains(RT);
+ return RecordlessTypes.contains(QT.getTypePtr());
}
std::optional<bool> isUnretained(const QualType T, bool IsARCEnabled) {
@@ -306,7 +293,7 @@ std::optional<bool> isUnretained(const QualType T, bool IsARCEnabled) {
auto *Record = PointeeType->getAsStructureType();
if (!Record)
return false;
- auto *Decl = Record->getDecl();
+ auto *Decl = Record->getOriginalDecl();
if (!Decl)
return false;
auto TypeName = Decl->getName();
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
index 98c587d62978b..6f3a280971cb8 100644
--- a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
+++ b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
@@ -113,10 +113,6 @@ class DerefFuncDeleteExprVisitor
auto CastType = Cast->getType();
if (auto *PtrType = dyn_cast<PointerType>(CastType)) {
auto PointeeType = PtrType->getPointeeType();
- while (auto *ET = dyn_cast<ElaboratedType>(PointeeType)) {
- if (ET->isSugared())
- PointeeType = ET->desugar();
- }
if (auto *ParmType = dyn_cast<TemplateTypeParmType>(PointeeType)) {
if (ArgList) {
auto ParmIndex = ParmType->getIndex();
@@ -125,13 +121,13 @@ class DerefFuncDeleteExprVisitor
return true;
}
} else if (auto *RD = dyn_cast<RecordType>(PointeeType)) {
- if (RD->getDecl() == ClassDecl)
+ if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl))
return true;
} else if (auto *ST =
dyn_cast<SubstTemplateTypeParmType>(PointeeType)) {
auto Type = ST->getReplacementType();
if (auto *RD = dyn_cast<RecordType>(Type)) {
- if (RD->getDecl() == ClassDecl)
+ if (declaresSameEntity(RD->getOriginalDecl(), ClassDecl))
return true;
}
}
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 34fcb9b64d555..180056cf68b64 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -89,7 +89,7 @@ static bool isCallback(QualType T) {
T = T->getPointeeType();
if (const RecordType *RT = T->getAsStructureType()) {
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
for (const auto *I : RD->fields()) {
QualType FieldT = I->getType();
if (FieldT->isBlockPointerType() || FieldT->isFunctionPointerType())
@@ -391,7 +391,9 @@ bool CallEvent::isVariadic(const Decl *D) {
static bool isTransparentUnion(QualType T) {
const RecordType *UT = T->getAsUnionType();
- return UT && UT->getDecl()->hasAttr<TransparentUnionAttr>();
+ return UT && UT->getOriginalDecl()
+ ->getMostRecentDecl()
+ ->hasAttr<TransparentUnionAttr>();
}
// In some cases, symbolic cases should be transformed before we associate
@@ -843,7 +845,7 @@ void CXXInstanceCall::getInitialStackFrameContents(
if (MD->getCanonicalDecl() != getDecl()->getCanonicalDecl()) {
ASTContext &Ctx = SVB.getContext();
const CXXRecordDecl *Class = MD->getParent();
- QualType Ty = Ctx.getPointerType(Ctx.getRecordType(Class));
+ CanQualType Ty = Ctx.getPointerType(Ctx.getCanonicalTagType(Class));
// FIXME: CallEvent maybe shouldn't be directly accessing StoreManager.
std::optional<SVal> V =
@@ -854,7 +856,8 @@ void CXXInstanceCall::getInitialStackFrameContents(
// Fall back to a generic pointer cast for this-value.
const CXXMethodDecl *StaticMD = cast<CXXMethodDecl>(getDecl());
const CXXRecordDecl *StaticClass = StaticMD->getParent();
- QualType StaticTy = Ctx.getPointerType(Ctx.getRecordType(StaticClass));
+ CanQualType StaticTy =
+ Ctx.getPointerType(Ctx.getCanonicalTagType(StaticClass));
ThisVal = SVB.evalCast(ThisVal, Ty, StaticTy);
} else
ThisVal = *V;
diff --git a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
index 63ad567ab7151..68bf97e43f3c1 100644
--- a/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
+++ b/clang/lib/StaticAnalyzer/Core/MemRegion.cpp
@@ -192,11 +192,11 @@ QualType ObjCIvarRegion::getValueType() const {
}
QualType CXXBaseObjectRegion::getValueType() const {
- return QualType(getDecl()->getTypeForDecl(), 0);
+ return getContext().getCanonicalTagType(getDecl());
}
QualType CXXDerivedObjectRegion::getValueType() const {
- return QualType(getDecl()->getTypeForDecl(), 0);
+ return getContext().getCanonicalTagType(getDecl());
}
QualType ParamVarRegion::getValueType() const {
diff --git a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
index 388034b087789..02375b0c3469a 100644
--- a/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
+++ b/clang/lib/StaticAnalyzer/Core/RegionStore.cpp
@@ -2453,7 +2453,8 @@ NonLoc RegionStoreManager::createLazyBinding(RegionBindingsConstRef B,
SVal RegionStoreManager::getBindingForStruct(RegionBindingsConstRef B,
const TypedValueRegion *R) {
- const RecordDecl *RD = R->getValueType()->castAs<RecordType>()->getDecl();
+ const RecordDecl *RD =
+ R->getValueType()->castAs<RecordType>()->getOriginalDecl();
if (!RD->getDefinition())
return UnknownVal();
@@ -2844,7 +2845,7 @@ RegionStoreManager::bindStruct(LimitedRegionBindingsConstRef B,
assert(T->isStructureOrClassType());
const RecordType* RT = T->castAs<RecordType>();
- const RecordDecl *RD = RT->getDecl();
+ const RecordDecl *RD = RT->getOriginalDecl()->getDefinitionOrSelf();
if (!RD->isCompleteDefinition())
return B;
diff --git a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
index 2276c452cce76..a6f4463852a9b 100644
--- a/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
+++ b/clang/lib/StaticAnalyzer/Core/SValBuilder.cpp
@@ -320,8 +320,8 @@ loc::MemRegionVal SValBuilder::getCXXThis(const CXXMethodDecl *D,
/// Return a memory region for the 'this' object reference.
loc::MemRegionVal SValBuilder::getCXXThis(const CXXRecordDecl *D,
const StackFrameContext *SFC) {
- const Type *T = D->getTypeForDecl();
- QualType PT = getContext().getPointerType(QualType(T, 0));
+ CanQualType PT =
+ getContext().getPointerType(getContext().getCanonicalTagType(D));
return loc::MemRegionVal(getRegionManager().getCXXThisRegion(PT, SFC));
}
diff --git a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
index 5f7153cd53ac2..d70a679cc8dd0 100644
--- a/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
+++ b/clang/lib/Tooling/ASTDiff/ASTDiff.cpp
@@ -246,7 +246,7 @@ struct PreorderVisitor : public RecursiveASTVisitor<PreorderVisitor> {
PostTraverse(SavedState);
return true;
}
- bool TraverseType(QualType T) { return true; }
+ bool TraverseType(QualType T, bool TraverseQualifier = true) { return true; }
bool TraverseConstructorInitializer(CXXCtorInitializer *Init) {
if (isNodeExcluded(Tree.AST.getSourceManager(), Init))
return true;
@@ -428,11 +428,12 @@ std::string SyntaxTree::Impl::getDeclValue(const Decl *D) const {
Value += getRelativeName(N) + ";";
if (auto *T = dyn_cast<TypedefNameDecl>(D))
return Value + T->getUnderlyingType().getAsString(TypePP) + ";";
- if (auto *T = dyn_cast<TypeDecl>(D))
- if (T->getTypeForDecl())
- Value +=
- T->getTypeForDecl()->getCanonicalTypeInternal().getAsString(TypePP) +
- ";";
+ if (auto *T = dyn_cast<TypeDecl>(D)) {
+ const ASTContext &Ctx = T->getASTContext();
+ Value +=
+ Ctx.getTypeDeclType(T)->getCanonicalTypeInternal().getAsString(TypePP) +
+ ";";
+ }
if (auto *U = dyn_cast<UsingDirectiveDecl>(D))
return std::string(U->getNominatedNamespace()->getName());
if (auto *A = dyn_cast<AccessSpecDecl>(D)) {
diff --git a/clang/lib/Tooling/Refactoring/Lookup.cpp b/clang/lib/Tooling/Refactoring/Lookup.cpp
index 757fba0404e62..dedde860516ab 100644
--- a/clang/lib/Tooling/Refactoring/Lookup.cpp
+++ b/clang/lib/Tooling/Refactoring/Lookup.cpp
@@ -108,16 +108,6 @@ static StringRef getBestNamespaceSubstr(const DeclContext *DeclA,
}
}
-/// Check if the name specifier begins with a written "::".
-static bool isFullyQualified(const NestedNameSpecifier *NNS) {
- while (NNS) {
- if (NNS->getKind() == NestedNameSpecifier::Global)
- return true;
- NNS = NNS->getPrefix();
- }
- return false;
-}
-
// Adds more scope specifier to the spelled name until the spelling is not
// ambiguous. A spelling is ambiguous if the resolution of the symbol is
// ambiguous. For example, if QName is "::y::bar", the spelling is "y::bar", and
@@ -182,7 +172,7 @@ static std::string disambiguateSpellingInScope(StringRef Spelling,
return Disambiguated;
}
-std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
+std::string tooling::replaceNestedName(NestedNameSpecifier Use,
SourceLocation UseLoc,
const DeclContext *UseContext,
const NamedDecl *FromDecl,
@@ -217,7 +207,7 @@ std::string tooling::replaceNestedName(const NestedNameSpecifier *Use,
// We work backwards (from most specific possible namespace to least
// specific).
StringRef Suggested = getBestNamespaceSubstr(UseContext, ReplacementString,
- isFullyQualified(Use));
+ Use.isFullyQualified());
return disambiguateSpellingInScope(Suggested, ReplacementString, *UseContext,
UseLoc);
diff --git a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index 8eff77861f753..d9444110d421c 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -107,45 +107,83 @@ class USRLocFindingASTVisitor
};
SourceLocation StartLocationForType(TypeLoc TL) {
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
+
// For elaborated types (e.g. `struct a::A`) we want the portion after the
- // `struct` but including the namespace qualifier, `a::`.
- if (auto ElaboratedTypeLoc = TL.getAs<clang::ElaboratedTypeLoc>()) {
- NestedNameSpecifierLoc NestedNameSpecifier =
- ElaboratedTypeLoc.getQualifierLoc();
- if (NestedNameSpecifier.getNestedNameSpecifier())
- return NestedNameSpecifier.getBeginLoc();
- TL = TL.getNextTypeLoc();
+ // `struct`, including the namespace qualifier, `a::`.
+ switch (TL.getTypeLocClass()) {
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName:
+ case TypeLoc::Enum: {
+ auto TTL = TL.castAs<TagTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = TTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return TTL.getNameLoc();
+ }
+ case TypeLoc::Typedef: {
+ auto TTL = TL.castAs<TypedefTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = TTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return TTL.getNameLoc();
+ }
+ case TypeLoc::UnresolvedUsing: {
+ auto TTL = TL.castAs<UnresolvedUsingTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = TTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return TTL.getNameLoc();
+ }
+ case TypeLoc::Using: {
+ auto TTL = TL.castAs<UsingTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = TTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return TTL.getNameLoc();
+ }
+ case TypeLoc::TemplateSpecialization: {
+ auto TTL = TL.castAs<TemplateSpecializationTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = TTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return TTL.getTemplateNameLoc();
+ }
+ case TypeLoc::DeducedTemplateSpecialization: {
+ auto DTL = TL.castAs<clang::DeducedTemplateSpecializationTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = DTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return DTL.getTemplateNameLoc();
+ }
+ case TypeLoc::DependentName: {
+ auto TTL = TL.castAs<DependentNameTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = TTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return TTL.getNameLoc();
+ }
+ case TypeLoc::DependentTemplateSpecialization: {
+ auto TTL = TL.castAs<DependentTemplateSpecializationTypeLoc>();
+ if (NestedNameSpecifierLoc QualifierLoc = TTL.getQualifierLoc())
+ return QualifierLoc.getBeginLoc();
+ return TTL.getTemplateNameLoc();
+ }
+ default:
+ llvm_unreachable("unhandled TypeLoc class");
}
- return TL.getBeginLoc();
}
SourceLocation EndLocationForType(TypeLoc TL) {
- // Dig past any namespace or keyword qualifications.
- while (TL.getTypeLocClass() == TypeLoc::Elaborated ||
- TL.getTypeLocClass() == TypeLoc::Qualified)
- TL = TL.getNextTypeLoc();
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = 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
// before the `<` character.
- if (TL.getTypeLocClass() == TypeLoc::TemplateSpecialization) {
- return TL.castAs<TemplateSpecializationTypeLoc>()
- .getLAngleLoc()
- .getLocWithOffset(-1);
- }
+ if (auto TTL = TL.getAs<TemplateSpecializationTypeLoc>())
+ return TTL.getLAngleLoc().getLocWithOffset(-1);
return TL.getEndLoc();
}
-NestedNameSpecifier *GetNestedNameForType(TypeLoc TL) {
- // Dig past any keyword qualifications.
- while (TL.getTypeLocClass() == TypeLoc::Qualified)
- TL = TL.getNextTypeLoc();
-
- // For elaborated types (e.g. `struct a::A`) we want the portion after the
- // `struct` but including the namespace qualifier, `a::`.
- if (auto ElaboratedTypeLoc = TL.getAs<clang::ElaboratedTypeLoc>())
- return ElaboratedTypeLoc.getQualifierLoc().getNestedNameSpecifier();
- return nullptr;
+NestedNameSpecifier GetNestedNameForType(TypeLoc TL) {
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
+ return TL.getPrefix().getNestedNameSpecifier();
}
// Find all locations identified by the given USRs for rename.
@@ -168,14 +206,14 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
const NamedDecl *FromDecl;
// The declaration in which the nested name is contained (can be nullptr).
const Decl *Context;
- // The nested name being replaced (can be nullptr).
- const NestedNameSpecifier *Specifier;
+ // The nested name being replaced.
+ NestedNameSpecifier Specifier;
// Determine whether the prefix qualifiers of the NewName should be ignored.
// Normally, we set it to true for the symbol declaration and definition to
// avoid adding prefix qualifiers.
// For example, if it is true and NewName is "a::b::foo", then the symbol
// occurrence which the RenameInfo points to will be renamed to "foo".
- bool IgnorePrefixQualifers;
+ bool IgnorePrefixQualifiers;
};
bool VisitNamedDecl(const NamedDecl *Decl) {
@@ -203,8 +241,8 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
EndLoc,
/*FromDecl=*/nullptr,
/*Context=*/nullptr,
- /*Specifier=*/nullptr,
- /*IgnorePrefixQualifers=*/true};
+ /*Specifier=*/std::nullopt,
+ /*IgnorePrefixQualifiers=*/true};
RenameInfos.push_back(Info);
}
}
@@ -217,10 +255,10 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
auto EndLoc = Expr->getMemberLoc();
if (isInUSRSet(Decl)) {
RenameInfos.push_back({StartLoc, EndLoc,
- /*FromDecl=*/nullptr,
- /*Context=*/nullptr,
- /*Specifier=*/nullptr,
- /*IgnorePrefixQualifiers=*/true});
+ /*FromDecl=*/nullptr,
+ /*Context=*/nullptr,
+ /*Specifier=*/std::nullopt,
+ /*IgnorePrefixQualifiers=*/true});
}
return true;
}
@@ -235,7 +273,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
RenameInfos.push_back({StartLoc, EndLoc,
/*FromDecl=*/nullptr,
/*Context=*/nullptr,
- /*Specifier=*/nullptr,
+ /*Specifier=*/std::nullopt,
/*IgnorePrefixQualifiers=*/true});
}
}
@@ -257,7 +295,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
RenameInfos.push_back({Loc, Loc,
/*FromDecl=*/nullptr,
/*Context=*/nullptr,
- /*Specifier=*/nullptr,
+ /*Specifier=*/std::nullopt,
/*IgnorePrefixQualifiers=*/true});
}
}
@@ -288,7 +326,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
RenameInfos.push_back({EndLoc, EndLoc,
/*FromDecl=*/nullptr,
/*Context=*/nullptr,
- /*Specifier=*/nullptr,
+ /*Specifier=*/std::nullopt,
/*IgnorePrefixQualifiers=*/true});
return true;
}
@@ -332,7 +370,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
Decl,
getClosestAncestorDecl(*Expr),
Expr->getQualifier(),
- /*IgnorePrefixQualifers=*/false};
+ /*IgnorePrefixQualifiers=*/false};
RenameInfos.push_back(Info);
}
@@ -350,18 +388,18 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
}
bool VisitNestedNameSpecifierLocations(NestedNameSpecifierLoc NestedLoc) {
- if (!NestedLoc.getNestedNameSpecifier()->getAsType())
+ TypeLoc TL = NestedLoc.getAsTypeLoc();
+ if (!TL)
return true;
- if (const auto *TargetDecl =
- getSupportedDeclFromTypeLoc(NestedLoc.getTypeLoc())) {
+ if (const auto *TargetDecl = getSupportedDeclFromTypeLoc(TL)) {
if (isInUSRSet(TargetDecl)) {
RenameInfo Info = {NestedLoc.getBeginLoc(),
- EndLocationForType(NestedLoc.getTypeLoc()),
+ EndLocationForType(TL),
TargetDecl,
getClosestAncestorDecl(NestedLoc),
- NestedLoc.getNestedNameSpecifier()->getPrefix(),
- /*IgnorePrefixQualifers=*/false};
+ /*Specifier=*/std::nullopt,
+ /*IgnorePrefixQualifiers=*/false};
RenameInfos.push_back(Info);
}
}
@@ -411,7 +449,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
TargetDecl,
getClosestAncestorDecl(Loc),
GetNestedNameForType(Loc),
- /*IgnorePrefixQualifers=*/false};
+ /*IgnorePrefixQualifiers=*/false};
RenameInfos.push_back(Info);
}
return true;
@@ -421,33 +459,17 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
// Handle specific template class specialiation cases.
if (const auto *TemplateSpecType =
dyn_cast<TemplateSpecializationType>(Loc.getType())) {
- TypeLoc TargetLoc = Loc;
- if (!ParentTypeLoc.isNull()) {
- if (llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
- TargetLoc = ParentTypeLoc;
- }
-
if (isInUSRSet(TemplateSpecType->getTemplateName().getAsTemplateDecl())) {
- TypeLoc TargetLoc = Loc;
- // FIXME: Find a better way to handle this case.
- // For the qualified template class specification type like
- // "ns::Foo<int>" in "ns::Foo<int>& f();", we want the parent typeLoc
- // (ElaboratedType) of the TemplateSpecializationType in order to
- // catch the prefix qualifiers "ns::".
- if (!ParentTypeLoc.isNull() &&
- llvm::isa<ElaboratedType>(ParentTypeLoc.getType()))
- TargetLoc = ParentTypeLoc;
-
- auto StartLoc = StartLocationForType(TargetLoc);
- auto EndLoc = EndLocationForType(TargetLoc);
+ auto StartLoc = StartLocationForType(Loc);
+ auto EndLoc = EndLocationForType(Loc);
if (IsValidEditLoc(Context.getSourceManager(), StartLoc)) {
RenameInfo Info = {
StartLoc,
EndLoc,
TemplateSpecType->getTemplateName().getAsTemplateDecl(),
- getClosestAncestorDecl(DynTypedNode::create(TargetLoc)),
- GetNestedNameForType(TargetLoc),
- /*IgnorePrefixQualifers=*/false};
+ getClosestAncestorDecl(DynTypedNode::create(Loc)),
+ GetNestedNameForType(Loc),
+ /*IgnorePrefixQualifiers=*/false};
RenameInfos.push_back(Info);
}
}
@@ -469,12 +491,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
const NamedDecl *getSupportedDeclFromTypeLoc(TypeLoc Loc) {
if (const auto* TT = Loc.getType()->getAs<clang::TypedefType>())
return TT->getDecl();
- if (const auto *RD = Loc.getType()->getAsCXXRecordDecl())
- return RD;
- if (const auto *ED =
- llvm::dyn_cast_or_null<EnumDecl>(Loc.getType()->getAsTagDecl()))
- return ED;
- return nullptr;
+ return Loc.getType()->getAsTagDecl();
}
// Get the closest ancester which is a declaration of a given AST node.
@@ -549,7 +566,7 @@ createRenameAtomicChanges(llvm::ArrayRef<std::string> USRs,
for (const auto &RenameInfo : Finder.getRenameInfos()) {
std::string ReplacedName = NewName.str();
- if (RenameInfo.IgnorePrefixQualifers) {
+ if (RenameInfo.IgnorePrefixQualifiers) {
// Get the name without prefix qualifiers from NewName.
size_t LastColonPos = NewName.find_last_of(':');
if (LastColonPos != std::string::npos)
diff --git a/clang/lib/Tooling/Syntax/BuildTree.cpp b/clang/lib/Tooling/Syntax/BuildTree.cpp
index caac719caf8e8..546161cee33f4 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -918,98 +918,91 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
return true;
}
- // FIXME: Fix `NestedNameSpecifierLoc::getLocalSourceRange` for the
- // `DependentTemplateSpecializationType` case.
- /// Given a nested-name-specifier return the range for the last name
- /// specifier.
- ///
- /// e.g. `std::T::template X<U>::` => `template X<U>::`
- SourceRange getLocalSourceRange(const NestedNameSpecifierLoc &NNSLoc) {
- auto SR = NNSLoc.getLocalSourceRange();
-
- // The method `NestedNameSpecifierLoc::getLocalSourceRange` *should*
- // return the desired `SourceRange`, but there is a corner case. For a
- // `DependentTemplateSpecializationType` this method returns its
- // qualifiers as well, in other words in the example above this method
- // returns `T::template X<U>::` instead of only `template X<U>::`
- if (auto TL = NNSLoc.getTypeLoc()) {
- if (auto DependentTL =
- TL.getAs<DependentTemplateSpecializationTypeLoc>()) {
- // The 'template' keyword is always present in dependent template
- // specializations. Except in the case of incorrect code
- // TODO: Treat the case of incorrect code.
- SR.setBegin(DependentTL.getTemplateKeywordLoc());
- }
- }
-
- return SR;
- }
-
- syntax::NodeKind getNameSpecifierKind(const NestedNameSpecifier &NNS) {
- switch (NNS.getKind()) {
- case NestedNameSpecifier::Global:
- return syntax::NodeKind::GlobalNameSpecifier;
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Identifier:
- return syntax::NodeKind::IdentifierNameSpecifier;
- case NestedNameSpecifier::TypeSpec: {
- const auto *NNSType = NNS.getAsType();
- assert(NNSType);
- if (isa<DecltypeType>(NNSType))
- return syntax::NodeKind::DecltypeNameSpecifier;
- if (isa<TemplateSpecializationType, DependentTemplateSpecializationType>(
- NNSType))
- return syntax::NodeKind::SimpleTemplateNameSpecifier;
- return syntax::NodeKind::IdentifierNameSpecifier;
- }
- default:
- // FIXME: Support Microsoft's __super
- llvm::report_fatal_error("We don't yet support the __super specifier",
- true);
- }
+ syntax::NameSpecifier *buildIdentifier(SourceRange SR,
+ bool DropBack = false) {
+ auto NameSpecifierTokens = Builder.getRange(SR).drop_back(DropBack);
+ assert(NameSpecifierTokens.size() == 1);
+ Builder.markChildToken(NameSpecifierTokens.begin(),
+ syntax::NodeRole::Unknown);
+ auto *NS = new (allocator()) syntax::IdentifierNameSpecifier;
+ Builder.foldNode(NameSpecifierTokens, NS, nullptr);
+ return NS;
+ }
+
+ syntax::NameSpecifier *buildSimpleTemplateName(SourceRange SR) {
+ auto NameSpecifierTokens = Builder.getRange(SR);
+ // TODO: Build `SimpleTemplateNameSpecifier` children and implement
+ // accessors to them.
+ // Be aware, we cannot do that simply by calling `TraverseTypeLoc`,
+ // some `TypeLoc`s have inside them the previous name specifier and
+ // we want to treat them independently.
+ auto *NS = new (allocator()) syntax::SimpleTemplateNameSpecifier;
+ Builder.foldNode(NameSpecifierTokens, NS, nullptr);
+ return NS;
}
syntax::NameSpecifier *
buildNameSpecifier(const NestedNameSpecifierLoc &NNSLoc) {
assert(NNSLoc.hasQualifier());
- auto NameSpecifierTokens =
- Builder.getRange(getLocalSourceRange(NNSLoc)).drop_back();
- switch (getNameSpecifierKind(*NNSLoc.getNestedNameSpecifier())) {
- case syntax::NodeKind::GlobalNameSpecifier:
+ switch (NNSLoc.getNestedNameSpecifier().getKind()) {
+ case NestedNameSpecifier::Kind::Global:
return new (allocator()) syntax::GlobalNameSpecifier;
- case syntax::NodeKind::IdentifierNameSpecifier: {
- assert(NameSpecifierTokens.size() == 1);
- Builder.markChildToken(NameSpecifierTokens.begin(),
- syntax::NodeRole::Unknown);
- auto *NS = new (allocator()) syntax::IdentifierNameSpecifier;
- Builder.foldNode(NameSpecifierTokens, NS, nullptr);
- return NS;
- }
- case syntax::NodeKind::SimpleTemplateNameSpecifier: {
- // TODO: Build `SimpleTemplateNameSpecifier` children and implement
- // accessors to them.
- // Be aware, we cannot do that simply by calling `TraverseTypeLoc`,
- // some `TypeLoc`s have inside them the previous name specifier and
- // we want to treat them independently.
- auto *NS = new (allocator()) syntax::SimpleTemplateNameSpecifier;
- Builder.foldNode(NameSpecifierTokens, NS, nullptr);
- return NS;
- }
- case syntax::NodeKind::DecltypeNameSpecifier: {
- const auto TL = NNSLoc.getTypeLoc().castAs<DecltypeTypeLoc>();
- if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(TL))
- return nullptr;
- auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;
- // TODO: Implement accessor to `DecltypeNameSpecifier` inner
- // `DecltypeTypeLoc`.
- // For that add mapping from `TypeLoc` to `syntax::Node*` then:
- // Builder.markChild(TypeLoc, syntax::NodeRole);
- Builder.foldNode(NameSpecifierTokens, NS, nullptr);
- return NS;
+
+ case NestedNameSpecifier::Kind::Namespace:
+ return buildIdentifier(NNSLoc.getLocalSourceRange(), /*DropBack=*/true);
+
+ case NestedNameSpecifier::Kind::Type: {
+ TypeLoc TL = NNSLoc.castAsTypeLoc();
+ switch (TL.getTypeLocClass()) {
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName:
+ case TypeLoc::Enum:
+ return buildIdentifier(TL.castAs<TagTypeLoc>().getNameLoc());
+ case TypeLoc::Typedef:
+ return buildIdentifier(TL.castAs<TypedefTypeLoc>().getNameLoc());
+ case TypeLoc::UnresolvedUsing:
+ return buildIdentifier(
+ TL.castAs<UnresolvedUsingTypeLoc>().getNameLoc());
+ case TypeLoc::Using:
+ return buildIdentifier(TL.castAs<UsingTypeLoc>().getNameLoc());
+ case TypeLoc::DependentName:
+ return buildIdentifier(TL.castAs<DependentNameTypeLoc>().getNameLoc());
+ case TypeLoc::TemplateSpecialization: {
+ auto TST = TL.castAs<TemplateSpecializationTypeLoc>();
+ SourceLocation BeginLoc = TST.getTemplateKeywordLoc();
+ if (BeginLoc.isInvalid())
+ BeginLoc = TST.getTemplateNameLoc();
+ return buildSimpleTemplateName({BeginLoc, TST.getEndLoc()});
+ }
+ case TypeLoc::DependentTemplateSpecialization: {
+ auto DT = TL.castAs<DependentTemplateSpecializationTypeLoc>();
+ SourceLocation BeginLoc = DT.getTemplateKeywordLoc();
+ if (BeginLoc.isInvalid())
+ BeginLoc = DT.getTemplateNameLoc();
+ return buildSimpleTemplateName({BeginLoc, DT.getEndLoc()});
+ }
+ case TypeLoc::Decltype: {
+ const auto DTL = TL.castAs<DecltypeTypeLoc>();
+ if (!RecursiveASTVisitor::TraverseDecltypeTypeLoc(
+ DTL, /*TraverseQualifier=*/true))
+ return nullptr;
+ auto *NS = new (allocator()) syntax::DecltypeNameSpecifier;
+ // TODO: Implement accessor to `DecltypeNameSpecifier` inner
+ // `DecltypeTypeLoc`.
+ // For that add mapping from `TypeLoc` to `syntax::Node*` then:
+ // Builder.markChild(TypeLoc, syntax::NodeRole);
+ Builder.foldNode(Builder.getRange(DTL.getLocalSourceRange()), NS,
+ nullptr);
+ return NS;
+ }
+ default:
+ return buildIdentifier(TL.getLocalSourceRange());
+ }
}
default:
- llvm_unreachable("getChildKind() does not return this value");
+ // FIXME: Support Microsoft's __super
+ llvm::report_fatal_error("We don't yet support the __super specifier",
+ true);
}
}
@@ -1020,12 +1013,16 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) {
if (!QualifierLoc)
return true;
- for (auto It = QualifierLoc; It; It = It.getPrefix()) {
+ for (auto It = QualifierLoc; It; /**/) {
auto *NS = buildNameSpecifier(It);
if (!NS)
return false;
Builder.markChild(NS, syntax::NodeRole::ListElement);
Builder.markChildToken(It.getEndLoc(), syntax::NodeRole::ListDelimiter);
+ if (TypeLoc TL = It.getAsTypeLoc())
+ It = TL.getPrefix();
+ else
+ It = It.getAsNamespaceAndPrefix().Prefix;
}
Builder.foldNode(Builder.getRange(QualifierLoc.getSourceRange()),
new (allocator()) syntax::NestedNameSpecifier,
@@ -1329,7 +1326,7 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
// FIXME: Deleting the `TraverseParenTypeLoc` override doesn't change test
// results. Find test coverage or remove it.
- bool TraverseParenTypeLoc(ParenTypeLoc L) {
+ bool TraverseParenTypeLoc(ParenTypeLoc L, bool TraverseQualifier) {
// We reverse order of traversal to get the proper syntax structure.
if (!WalkUpFromParenTypeLoc(L))
return false;
@@ -1392,7 +1389,8 @@ class BuildTreeVisitor : public RecursiveASTVisitor<BuildTreeVisitor> {
return WalkUpFromFunctionTypeLoc(L);
}
- bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L) {
+ bool TraverseMemberPointerTypeLoc(MemberPointerTypeLoc L,
+ bool TraverseQualifier) {
// In the source code "void (Y::*mp)()" `MemberPointerTypeLoc` corresponds
// to "Y::*" but it points to a `ParenTypeLoc` that corresponds to
// "(Y::*mp)" We thus reverse the order of traversal to get the proper
diff --git a/clang/lib/Tooling/Transformer/RangeSelector.cpp b/clang/lib/Tooling/Transformer/RangeSelector.cpp
index 00f4611ddb5d4..171c786bc366f 100644
--- a/clang/lib/Tooling/Transformer/RangeSelector.cpp
+++ b/clang/lib/Tooling/Transformer/RangeSelector.cpp
@@ -222,14 +222,10 @@ RangeSelector transformer::name(std::string ID) {
return CharSourceRange::getTokenRange(L, L);
}
if (const auto *T = Node.get<TypeLoc>()) {
- TypeLoc Loc = *T;
- auto ET = Loc.getAs<ElaboratedTypeLoc>();
- if (!ET.isNull())
- Loc = ET.getNamedTypeLoc();
- if (auto SpecLoc = Loc.getAs<TemplateSpecializationTypeLoc>();
+ if (auto SpecLoc = T->getAs<TemplateSpecializationTypeLoc>();
!SpecLoc.isNull())
return CharSourceRange::getTokenRange(SpecLoc.getTemplateNameLoc());
- return CharSourceRange::getTokenRange(Loc.getSourceRange());
+ return CharSourceRange::getTokenRange(T->getSourceRange());
}
return typeError(ID, Node.getNodeKind(),
"DeclRefExpr, NamedDecl, CXXCtorInitializer, TypeLoc");
diff --git a/clang/tools/libclang/CIndex.cpp b/clang/tools/libclang/CIndex.cpp
index 9089984fa4a54..08e34d7261626 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1420,90 +1420,25 @@ bool CursorVisitor::VisitDeclarationNameInfo(DeclarationNameInfo Name) {
llvm_unreachable("Invalid DeclarationName::Kind!");
}
-bool CursorVisitor::VisitNestedNameSpecifier(NestedNameSpecifier *NNS,
- SourceRange Range) {
- // FIXME: This whole routine is a hack to work around the lack of proper
- // source information in nested-name-specifiers (PR5791). Since we do have
- // a beginning source location, we can visit the first component of the
- // nested-name-specifier, if it's a single-token component.
- if (!NNS)
- return false;
-
- // Get the first component in the nested-name-specifier.
- while (NestedNameSpecifier *Prefix = NNS->getPrefix())
- NNS = Prefix;
-
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Namespace:
- return Visit(
- MakeCursorNamespaceRef(NNS->getAsNamespace(), Range.getBegin(), TU));
-
- case NestedNameSpecifier::NamespaceAlias:
- return Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
- Range.getBegin(), TU));
-
- case NestedNameSpecifier::TypeSpec: {
- // If the type has a form where we know that the beginning of the source
- // range matches up with a reference cursor. Visit the appropriate reference
- // cursor.
- const Type *T = NNS->getAsType();
- if (const TypedefType *Typedef = dyn_cast<TypedefType>(T))
- return Visit(MakeCursorTypeRef(Typedef->getDecl(), Range.getBegin(), TU));
- if (const TagType *Tag = dyn_cast<TagType>(T))
- return Visit(MakeCursorTypeRef(Tag->getDecl(), Range.getBegin(), TU));
- if (const TemplateSpecializationType *TST =
- dyn_cast<TemplateSpecializationType>(T))
- return VisitTemplateName(TST->getTemplateName(), Range.getBegin());
- break;
- }
-
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Super:
- break;
- }
-
- return false;
-}
-
bool CursorVisitor::VisitNestedNameSpecifierLoc(
NestedNameSpecifierLoc Qualifier) {
- SmallVector<NestedNameSpecifierLoc, 4> Qualifiers;
- for (; Qualifier; Qualifier = Qualifier.getPrefix())
- Qualifiers.push_back(Qualifier);
-
- while (!Qualifiers.empty()) {
- NestedNameSpecifierLoc Q = Qualifiers.pop_back_val();
- NestedNameSpecifier *NNS = Q.getNestedNameSpecifier();
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Namespace:
- if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespace(),
- Q.getLocalBeginLoc(), TU)))
- return true;
-
- break;
-
- case NestedNameSpecifier::NamespaceAlias:
- if (Visit(MakeCursorNamespaceRef(NNS->getAsNamespaceAlias(),
- Q.getLocalBeginLoc(), TU)))
- return true;
-
- break;
-
- case NestedNameSpecifier::TypeSpec:
- if (Visit(Q.getTypeLoc()))
- return true;
-
- break;
-
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Identifier:
- case NestedNameSpecifier::Super:
- break;
- }
+ NestedNameSpecifier NNS = Qualifier.getNestedNameSpecifier();
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Namespace: {
+ auto [Namespace, Prefix] = Qualifier.castAsNamespaceAndPrefix();
+ if (VisitNestedNameSpecifierLoc(Prefix))
+ return true;
+ return Visit(
+ MakeCursorNamespaceRef(Namespace, Qualifier.getLocalBeginLoc(), TU));
}
-
- return false;
+ case NestedNameSpecifier::Kind::Type:
+ return Visit(Qualifier.castAsTypeLoc());
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
+ return false;
+ }
+ llvm_unreachable("unexpected nested name specifier kind");
}
bool CursorVisitor::VisitTemplateParameters(
@@ -1526,16 +1461,23 @@ bool CursorVisitor::VisitTemplateParameters(
return false;
}
-bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
+bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation NameLoc,
+ NestedNameSpecifierLoc NNS) {
switch (Name.getKind()) {
+ case TemplateName::QualifiedTemplate: {
+ const QualifiedTemplateName *QTN = Name.getAsQualifiedTemplateName();
+ assert(QTN->getQualifier() == NNS.getNestedNameSpecifier());
+ if (VisitNestedNameSpecifierLoc(NNS))
+ return true;
+ return VisitTemplateName(QTN->getUnderlyingTemplate(), NameLoc, /*NNS=*/{});
+ }
case TemplateName::Template:
case TemplateName::UsingTemplate:
- case TemplateName::QualifiedTemplate: // FIXME: Visit nested-name-specifier.
- return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), Loc, TU));
+ return Visit(MakeCursorTemplateRef(Name.getAsTemplateDecl(), NameLoc, TU));
case TemplateName::OverloadedTemplate:
// Visit the overloaded template set.
- if (Visit(MakeCursorOverloadedDeclRef(Name, Loc, TU)))
+ if (Visit(MakeCursorOverloadedDeclRef(Name, NameLoc, TU)))
return true;
return false;
@@ -1544,17 +1486,19 @@ bool CursorVisitor::VisitTemplateName(TemplateName Name, SourceLocation Loc) {
// FIXME: Visit DeclarationName?
return false;
- case TemplateName::DependentTemplate:
- // FIXME: Visit nested-name-specifier.
- return false;
+ case TemplateName::DependentTemplate: {
+ assert(Name.getAsDependentTemplateName()->getQualifier() ==
+ NNS.getNestedNameSpecifier());
+ return VisitNestedNameSpecifierLoc(NNS);
+ }
case TemplateName::SubstTemplateTemplateParm:
return Visit(MakeCursorTemplateRef(
- Name.getAsSubstTemplateTemplateParm()->getParameter(), Loc, TU));
+ Name.getAsSubstTemplateTemplateParm()->getParameter(), NameLoc, TU));
case TemplateName::SubstTemplateTemplateParmPack:
return Visit(MakeCursorTemplateRef(
- Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), Loc,
+ Name.getAsSubstTemplateTemplateParmPack()->getParameterPack(), NameLoc,
TU));
case TemplateName::DeducedTemplate:
@@ -1598,11 +1542,9 @@ bool CursorVisitor::VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL) {
case TemplateArgument::Template:
case TemplateArgument::TemplateExpansion:
- if (VisitNestedNameSpecifierLoc(TAL.getTemplateQualifierLoc()))
- return true;
-
return VisitTemplateName(TAL.getArgument().getAsTemplateOrTemplatePattern(),
- TAL.getTemplateNameLoc());
+ TAL.getTemplateNameLoc(),
+ TAL.getTemplateQualifierLoc());
}
llvm_unreachable("Invalid TemplateArgument::Kind!");
@@ -1680,18 +1622,27 @@ bool CursorVisitor::VisitBuiltinTypeLoc(BuiltinTypeLoc TL) {
}
bool CursorVisitor::VisitTypedefTypeLoc(TypedefTypeLoc TL) {
- return Visit(MakeCursorTypeRef(TL.getTypedefNameDecl(), TL.getNameLoc(), TU));
+ if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+ return true;
+
+ return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}
bool CursorVisitor::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) {
+ if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+ return true;
+
return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
}
bool CursorVisitor::VisitTagTypeLoc(TagTypeLoc TL) {
+ if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+ return true;
+
if (TL.isDefinition())
- return Visit(MakeCXCursor(TL.getDecl(), TU, RegionOfInterest));
+ return Visit(MakeCXCursor(TL.getOriginalDecl(), TU, RegionOfInterest));
- return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+ return Visit(MakeCursorTypeRef(TL.getOriginalDecl(), TL.getNameLoc(), TU));
}
bool CursorVisitor::VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc TL) {
@@ -1770,7 +1721,10 @@ bool CursorVisitor::VisitRValueReferenceTypeLoc(RValueReferenceTypeLoc TL) {
}
bool CursorVisitor::VisitUsingTypeLoc(UsingTypeLoc TL) {
- auto *underlyingDecl = TL.getUnderlyingType()->getAsTagDecl();
+ if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+ return true;
+
+ auto *underlyingDecl = TL.getTypePtr()->desugar()->getAsTagDecl();
if (underlyingDecl) {
return Visit(MakeCursorTypeRef(underlyingDecl, TL.getNameLoc(), TU));
}
@@ -1833,7 +1787,7 @@ bool CursorVisitor::VisitAdjustedTypeLoc(AdjustedTypeLoc TL) {
bool CursorVisitor::VisitDeducedTemplateSpecializationTypeLoc(
DeducedTemplateSpecializationTypeLoc TL) {
if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
- TL.getTemplateNameLoc()))
+ TL.getTemplateNameLoc(), TL.getQualifierLoc()))
return true;
return false;
@@ -1843,7 +1797,7 @@ bool CursorVisitor::VisitTemplateSpecializationTypeLoc(
TemplateSpecializationTypeLoc TL) {
// Visit the template name.
if (VisitTemplateName(TL.getTypePtr()->getTemplateName(),
- TL.getTemplateNameLoc()))
+ TL.getTemplateNameLoc(), TL.getQualifierLoc()))
return true;
// Visit the template arguments.
@@ -1878,8 +1832,7 @@ bool CursorVisitor::VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc TL) {
- // Visit the nested-name-specifier, if there is one.
- if (TL.getQualifierLoc() && VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
+ if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
return true;
// Visit the template arguments.
@@ -1890,13 +1843,6 @@ bool CursorVisitor::VisitDependentTemplateSpecializationTypeLoc(
return false;
}
-bool CursorVisitor::VisitElaboratedTypeLoc(ElaboratedTypeLoc TL) {
- if (VisitNestedNameSpecifierLoc(TL.getQualifierLoc()))
- return true;
-
- return Visit(TL.getNamedTypeLoc());
-}
-
bool CursorVisitor::VisitPackExpansionTypeLoc(PackExpansionTypeLoc TL) {
return Visit(TL.getPatternLoc());
}
@@ -1915,7 +1861,7 @@ bool CursorVisitor::VisitPackIndexingTypeLoc(PackIndexingTypeLoc TL) {
}
bool CursorVisitor::VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- return Visit(MakeCursorTypeRef(TL.getDecl(), TL.getNameLoc(), TU));
+ return Visit(MakeCursorTypeRef(TL.getOriginalDecl(), TL.getNameLoc(), TU));
}
bool CursorVisitor::VisitAtomicTypeLoc(AtomicTypeLoc TL) {
@@ -2072,7 +2018,7 @@ class NestedNameSpecifierLocVisit : public VisitorJob {
public:
NestedNameSpecifierLocVisit(NestedNameSpecifierLoc Qualifier, CXCursor parent)
: VisitorJob(parent, VisitorJob::NestedNameSpecifierLocVisitKind,
- Qualifier.getNestedNameSpecifier(),
+ Qualifier.getNestedNameSpecifier().getAsVoidPointer(),
Qualifier.getOpaqueData()) {}
static bool classof(const VisitorJob *VJ) {
@@ -2081,8 +2027,7 @@ class NestedNameSpecifierLocVisit : public VisitorJob {
NestedNameSpecifierLoc get() const {
return NestedNameSpecifierLoc(
- const_cast<NestedNameSpecifier *>(
- static_cast<const NestedNameSpecifier *>(data[0])),
+ NestedNameSpecifier::getFromVoidPointer(data[0]),
const_cast<void *>(data[1]));
}
};
@@ -5367,9 +5312,13 @@ CXString clang_getCursorSpelling(CXCursor C) {
case CXCursor_TypeRef: {
const TypeDecl *Type = getCursorTypeRef(C).first;
assert(Type && "Missing type decl");
+ const ASTContext &Ctx = getCursorContext(C);
+ QualType T = Ctx.getTypeDeclType(Type);
- return cxstring::createDup(
- getCursorContext(C).getTypeDeclType(Type).getAsString());
+ PrintingPolicy Policy = Ctx.getPrintingPolicy();
+ Policy.FullyQualifiedName = true;
+ Policy.SuppressTagKeyword = false;
+ return cxstring::createDup(T.getAsString(Policy));
}
case CXCursor_TemplateRef: {
const TemplateDecl *Template = getCursorTemplateRef(C).first;
diff --git a/clang/tools/libclang/CIndexCodeCompletion.cpp b/clang/tools/libclang/CIndexCodeCompletion.cpp
index 8f6729b83ffa0..1636e1e5e0a7b 100644
--- a/clang/tools/libclang/CIndexCodeCompletion.cpp
+++ b/clang/tools/libclang/CIndexCodeCompletion.cpp
@@ -616,7 +616,7 @@ namespace {
if (!baseType.isNull()) {
// Get the declaration for a class/struct/union/enum type
if (const TagType *Tag = baseType->getAs<TagType>())
- D = Tag->getDecl();
+ D = Tag->getOriginalDecl();
// Get the @interface declaration for a (possibly-qualified) Objective-C
// object pointer type, e.g., NSString*
else if (const ObjCObjectPointerType *ObjPtr =
@@ -628,7 +628,7 @@ namespace {
// Get the class for a C++ injected-class-name
else if (const InjectedClassNameType *Injected =
baseType->getAs<InjectedClassNameType>())
- D = Injected->getDecl();
+ D = Injected->getOriginalDecl();
}
if (D != nullptr) {
diff --git a/clang/tools/libclang/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index a6301daa672c3..3c4062410eac1 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -1332,16 +1332,10 @@ CXCursor cxcursor::getTypeRefCursor(CXCursor cursor) {
TypeLoc TL = Type->getTypeLoc();
SourceLocation Loc = TL.getBeginLoc();
- if (const ElaboratedType *ElabT = Ty->getAs<ElaboratedType>()) {
- Ty = ElabT->getNamedType();
- ElaboratedTypeLoc ElabTL = TL.castAs<ElaboratedTypeLoc>();
- Loc = ElabTL.getNamedTypeLoc().getBeginLoc();
- }
-
if (const TypedefType *Typedef = Ty->getAs<TypedefType>())
return MakeCursorTypeRef(Typedef->getDecl(), Loc, TU);
if (const TagType *Tag = Ty->getAs<TagType>())
- return MakeCursorTypeRef(Tag->getDecl(), Loc, TU);
+ return MakeCursorTypeRef(Tag->getOriginalDecl(), Loc, TU);
if (const TemplateTypeParmType *TemplP = Ty->getAs<TemplateTypeParmType>())
return MakeCursorTypeRef(TemplP->getDecl(), Loc, TU);
diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp
index f0d92e8c40124..941e39a582758 100644
--- a/clang/tools/libclang/CXIndexDataConsumer.cpp
+++ b/clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -357,7 +357,7 @@ CXIndexDataConsumer::CXXBasesListInfo::CXXBasesListInfo(const CXXRecordDecl *D,
TST = T->getAs<TemplateSpecializationType>()) {
BaseD = TST->getTemplateName().getAsTemplateDecl();
} else if (const RecordType *RT = T->getAs<RecordType>()) {
- BaseD = RT->getDecl();
+ BaseD = RT->getOriginalDecl();
}
if (BaseD)
@@ -389,13 +389,22 @@ SourceLocation CXIndexDataConsumer::CXXBasesListInfo::getBaseLoc(
if (QualifiedTypeLoc QL = TL.getAs<QualifiedTypeLoc>())
TL = QL.getUnqualifiedLoc();
- if (ElaboratedTypeLoc EL = TL.getAs<ElaboratedTypeLoc>())
- return EL.getNamedTypeLoc().getBeginLoc();
- if (DependentNameTypeLoc DL = TL.getAs<DependentNameTypeLoc>())
- return DL.getNameLoc();
- if (DependentTemplateSpecializationTypeLoc DTL =
- TL.getAs<DependentTemplateSpecializationTypeLoc>())
- return DTL.getTemplateNameLoc();
+ // FIXME: Factor this out, a lot of TypeLoc users seem to need a generic
+ // TypeLoc::getNameLoc()
+ if (auto TTL = TL.getAs<DependentNameTypeLoc>())
+ return TTL.getNameLoc();
+ if (auto TTL = TL.getAs<DependentTemplateSpecializationTypeLoc>())
+ return TTL.getTemplateNameLoc();
+ if (auto TTL = TL.getAs<TemplateSpecializationTypeLoc>())
+ return TTL.getTemplateNameLoc();
+ if (auto TTL = TL.getAs<TagTypeLoc>())
+ return TTL.getNameLoc();
+ if (auto TTL = TL.getAs<TypedefTypeLoc>())
+ return TTL.getNameLoc();
+ if (auto TTL = TL.getAs<UnresolvedUsingTypeLoc>())
+ return TTL.getNameLoc();
+ if (auto TTL = TL.getAs<UsingTypeLoc>())
+ return TTL.getNameLoc();
return Loc;
}
diff --git a/clang/tools/libclang/CXType.cpp b/clang/tools/libclang/CXType.cpp
index e7864e6d62e4d..11d02d8088918 100644
--- a/clang/tools/libclang/CXType.cpp
+++ b/clang/tools/libclang/CXType.cpp
@@ -118,7 +118,6 @@ static CXTypeKind GetTypeKind(QualType T) {
TKCASE(ExtVector);
TKCASE(MemberPointer);
TKCASE(Auto);
- TKCASE(Elaborated);
TKCASE(Pipe);
TKCASE(Attributed);
TKCASE(BTFTagAttributed);
@@ -225,6 +224,11 @@ FindTemplateArgumentTypeAt(ArrayRef<TemplateArgument> TA, unsigned index) {
return std::nullopt;
}
+static CXType getTypeDeclType(const ASTContext &Context, CXTranslationUnit TU,
+ const TypeDecl *TD) {
+ return MakeCXType(Context.getTypeDeclType(TD), TU);
+}
+
CXType clang_getCursorType(CXCursor C) {
using namespace cxcursor;
@@ -244,7 +248,7 @@ CXType clang_getCursorType(CXCursor C) {
return MakeCXType(QualType(), TU);
if (const TypeDecl *TD = dyn_cast<TypeDecl>(D))
- return MakeCXType(Context.getTypeDeclType(TD), TU);
+ return getTypeDeclType(Context, TU, TD);
if (const ObjCInterfaceDecl *ID = dyn_cast<ObjCInterfaceDecl>(D))
return MakeCXType(Context.getObjCInterfaceType(ID), TU);
if (const DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(D))
@@ -271,11 +275,8 @@ CXType clang_getCursorType(CXCursor C) {
return MakeCXType(T, TU);
}
- case CXCursor_TypeRef: {
- QualType T = Context.getTypeDeclType(getCursorTypeRef(C).first);
- return MakeCXType(T, TU);
-
- }
+ case CXCursor_TypeRef:
+ return getTypeDeclType(Context, TU, getCursorTypeRef(C).first);
case CXCursor_CXXBaseSpecifier:
return cxtype::MakeCXType(getCursorCXXBaseSpecifier(C)->getType(), TU);
@@ -545,11 +546,11 @@ CXCursor clang_getTypeDeclaration(CXType CT) {
break;
case Type::Record:
case Type::Enum:
- D = cast<TagType>(TP)->getDecl();
+ D = cast<TagType>(TP)->getOriginalDecl();
break;
case Type::TemplateSpecialization:
if (const RecordType *Record = TP->getAs<RecordType>())
- D = Record->getDecl();
+ D = Record->getOriginalDecl();
else
D = cast<TemplateSpecializationType>(TP)->getTemplateName()
.getAsTemplateDecl();
@@ -563,14 +564,10 @@ CXCursor clang_getTypeDeclaration(CXType CT) {
break;
case Type::InjectedClassName:
- D = cast<InjectedClassNameType>(TP)->getDecl();
+ D = cast<InjectedClassNameType>(TP)->getOriginalDecl();
break;
- // FIXME: Template type parameters!
-
- case Type::Elaborated:
- TP = cast<ElaboratedType>(TP)->getNamedType().getTypePtrOrNull();
- goto try_again;
+ // FIXME: Template type parameters!
default:
break;
@@ -990,7 +987,7 @@ CXType clang_Type_getClassType(CXType CT) {
const Type *TP = T.getTypePtrOrNull();
if (TP && TP->getTypeClass() == Type::MemberPointer) {
- ET = Ctx.getTypeDeclType(
+ ET = Ctx.getCanonicalTagType(
cast<MemberPointerType>(TP)->getMostRecentCXXRecordDecl());
}
return MakeCXType(ET, GetTU(CT));
@@ -1040,7 +1037,7 @@ static long long visitRecordForValidation(const RecordDecl *RD) {
return CXTypeLayoutError_Dependent;
// recurse
if (const RecordType *ChildType = I->getType()->getAs<RecordType>()) {
- if (const RecordDecl *Child = ChildType->getDecl()) {
+ if (const RecordDecl *Child = ChildType->getOriginalDecl()) {
long long ret = visitRecordForValidation(Child);
if (ret < 0)
return ret;
@@ -1390,10 +1387,9 @@ unsigned clang_Cursor_isInlineNamespace(CXCursor C) {
CXType clang_Type_getNamedType(CXType CT){
QualType T = GetQualType(CT);
- const Type *TP = T.getTypePtrOrNull();
- if (TP && TP->getTypeClass() == Type::Elaborated)
- return MakeCXType(cast<ElaboratedType>(TP)->getNamedType(), GetTU(CT));
+ if (!T.isNull() && T->getPrefix())
+ return MakeCXType(T, GetTU(CT));
return MakeCXType(QualType(), GetTU(CT));
}
diff --git a/clang/tools/libclang/CursorVisitor.h b/clang/tools/libclang/CursorVisitor.h
index 949b73908c315..d5ab699756988 100644
--- a/clang/tools/libclang/CursorVisitor.h
+++ b/clang/tools/libclang/CursorVisitor.h
@@ -255,12 +255,12 @@ class CursorVisitor : public DeclVisitor<CursorVisitor, bool>,
// Name visitor
bool VisitDeclarationNameInfo(DeclarationNameInfo Name);
- bool VisitNestedNameSpecifier(NestedNameSpecifier *NNS, SourceRange Range);
bool VisitNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS);
// Template visitors
bool VisitTemplateParameters(const TemplateParameterList *Params);
- bool VisitTemplateName(TemplateName Name, SourceLocation Loc);
+ bool VisitTemplateName(TemplateName Name, SourceLocation NameLoc,
+ NestedNameSpecifierLoc NNS);
bool VisitTemplateArgumentLoc(const TemplateArgumentLoc &TAL);
// Type visitors
>From bd2dd9499b18404a6485ca8eb930feec26e91c99 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Thu, 10 Jul 2025 14:09:12 -0300
Subject: [PATCH 3/4] clang test changes
---
.../test/AST/HLSL/StructuredBuffers-AST.hlsl | 36 +-
clang/test/AST/HLSL/TypedBuffers-AST.hlsl | 24 +-
.../test/AST/HLSL/cbuffer_and_namespaces.hlsl | 4 +-
clang/test/AST/HLSL/vector-constructors.hlsl | 8 +-
clang/test/AST/arm-mfp8.cpp | 2 +-
clang/test/AST/ast-dump-color.cpp | 16 +-
clang/test/AST/ast-dump-ctad-alias.cpp | 23 +-
.../test/AST/ast-dump-cxx2b-deducing-this.cpp | 2 +-
clang/test/AST/ast-dump-decl-json.c | 3 -
clang/test/AST/ast-dump-decl.cpp | 38 +--
clang/test/AST/ast-dump-expr-json.cpp | 14 -
clang/test/AST/ast-dump-expr.cpp | 7 +-
.../test/AST/ast-dump-for-range-lifetime.cpp | 318 +++++++++---------
...openmp-begin-declare-variant_reference.cpp | 24 +-
...penmp-begin-declare-variant_template_3.cpp | 2 +-
.../ast-dump-record-definition-data-json.cpp | 5 -
clang/test/AST/ast-dump-records-json.cpp | 2 -
clang/test/AST/ast-dump-records.c | 8 +-
clang/test/AST/ast-dump-records.cpp | 8 +-
clang/test/AST/ast-dump-recovery.cpp | 6 +-
clang/test/AST/ast-dump-stmt-json.cpp | 86 ++++-
clang/test/AST/ast-dump-stmt.m | 2 +-
clang/test/AST/ast-dump-template-decls.cpp | 3 +-
...dump-template-json-win32-mangler-crash.cpp | 112 +++---
clang/test/AST/ast-dump-template-name.cpp | 47 ++-
clang/test/AST/ast-dump-templates.cpp | 215 ++++++------
clang/test/AST/ast-dump-traits.cpp | 5 +-
clang/test/AST/ast-dump-types-json.cpp | 77 +++--
clang/test/AST/ast-dump-using-template.cpp | 38 +--
clang/test/AST/ast-dump-using.cpp | 16 +-
clang/test/AST/attr-swift_attr.m | 2 +-
clang/test/AST/coroutine-locals-cleanup.cpp | 4 +-
clang/test/AST/cxx2c-variadic-friends.cpp | 4 +-
clang/test/AST/deduction-guides.cpp | 18 +-
clang/test/AST/float16.cpp | 2 +-
clang/test/AST/sourceranges.cpp | 6 +-
.../ast-dump-sycl-kernel-call-stmt.cpp | 8 +-
clang/test/Analysis/anonymous-decls.cpp | 4 +-
.../basic.lookup.qual/class.qual/p2.cpp | 2 +-
clang/test/CXX/class.access/p6.cpp | 2 +-
.../class.derived.general/p2.cpp | 8 +-
.../class/class.mem/class.mem.general/p8.cpp | 8 +-
.../dcl.spec/dcl.type/dcl.type.elab/p3.cpp | 2 +-
.../dcl.init/dcl.init.ref/p5-examples.cpp | 2 +-
.../CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp | 2 +-
clang/test/CXX/dcl/dcl.fct/p17.cpp | 2 +-
clang/test/CXX/drs/cwg0xx.cpp | 6 +-
clang/test/CXX/drs/cwg12xx.cpp | 2 +-
clang/test/CXX/drs/cwg13xx.cpp | 2 +-
clang/test/CXX/drs/cwg2149.cpp | 8 +-
clang/test/CXX/drs/cwg26xx.cpp | 8 +-
clang/test/CXX/drs/cwg28xx.cpp | 12 +-
clang/test/CXX/drs/cwg2xx.cpp | 10 +-
clang/test/CXX/drs/cwg3xx.cpp | 8 +-
clang/test/CXX/drs/cwg4xx.cpp | 2 +-
clang/test/CXX/drs/cwg6xx.cpp | 8 +-
.../expr.prim.req/compound-requirement.cpp | 2 +-
.../over.match.class.deduct/p2.cpp | 2 +-
.../CXX/temp/temp.arg/temp.arg.nontype/p5.cpp | 4 +-
.../temp.constr.decl/func-template-decl.cpp | 2 +-
.../temp/temp.decls/temp.class.spec/p6.cpp | 4 +-
.../temp.deduct/temp.deduct.call/p3-0x.cpp | 4 +-
clang/test/CXX/temp/temp.param/p15-cxx0x.cpp | 4 +-
.../temp.res/temp.dep/temp.dep.type/p4.cpp | 40 +--
clang/test/CodeGen/builtin-bpf-btf-type-id.c | 2 +-
.../builtins-bpf-preserve-field-info-3.c | 2 +-
.../Index/Core/index-instantiated-source.cpp | 4 +-
clang/test/Index/Core/index-source.cpp | 4 +-
clang/test/Index/c-index-api-loadTU-test.m | 2 +-
clang/test/Index/copy-assignment-operator.cpp | 4 +-
clang/test/Index/index-refs.cpp | 4 +-
clang/test/Index/keep-going.cpp | 4 +-
clang/test/Index/move-assignment-operator.cpp | 2 +-
clang/test/Index/opencl-types.cl | 16 +-
clang/test/Index/paren-type.c | 2 +-
clang/test/Index/print-type-size.cpp | 8 +-
clang/test/Index/print-type.c | 14 +-
clang/test/Index/print-type.cpp | 56 +--
.../test/Index/recursive-cxx-member-calls.cpp | 20 +-
clang/test/Index/redeclarations.cpp | 2 +-
.../skip-parsed-bodies/compile_commands.json | 6 +-
.../test/Misc/diag-template-diffing-cxx11.cpp | 8 +-
clang/test/Modules/modules-merge-enum.m | 24 +-
clang/test/Modules/odr_hash.cpp | 12 +-
.../OpenMP/allocate_modifiers_messages.cpp | 2 +-
...of_structs_with_nested_mapper_ast_dump.cpp | 2 +-
...of_structs_with_nested_mapper_ast_dump.cpp | 2 +-
clang/test/PCH/cxx-explicit-specifier.cpp | 6 +-
clang/test/Parser/MicrosoftExtensions.cpp | 2 +-
...xx1z-class-template-argument-deduction.cpp | 6 +-
clang/test/SemaCXX/MicrosoftExtensions.cpp | 8 +-
.../SemaCXX/builtin-get-vtable-pointer.cpp | 2 +-
clang/test/SemaCXX/class-base-member-init.cpp | 2 +-
clang/test/SemaCXX/co_await-ast.cpp | 34 +-
clang/test/SemaCXX/compound-literal.cpp | 34 +-
clang/test/SemaCXX/constant-expression.cpp | 2 +-
clang/test/SemaCXX/constructor.cpp | 2 +-
clang/test/SemaCXX/coroutine-allocs.cpp | 6 +-
.../coroutine-traits-undefined-template.cpp | 2 +-
clang/test/SemaCXX/coroutines.cpp | 4 +-
clang/test/SemaCXX/ctad.cpp | 4 +-
.../cxx1y-variable-templates_in_class.cpp | 10 +-
...xx1z-class-template-argument-deduction.cpp | 6 +-
.../test/SemaCXX/cxx2a-destroying-delete.cpp | 2 +-
clang/test/SemaCXX/cxx2b-deducing-this.cpp | 4 +-
clang/test/SemaCXX/cxx2c-variadic-friends.cpp | 2 +-
clang/test/SemaCXX/destructor.cpp | 6 +-
.../SemaCXX/elaborated-type-specifier.cpp | 2 +-
clang/test/SemaCXX/enum-scoped.cpp | 2 +-
.../SemaCXX/err_init_conversion_failed.cpp | 2 +-
clang/test/SemaCXX/gh102293.cpp | 2 +-
clang/test/SemaCXX/incomplete-call.cpp | 2 +-
clang/test/SemaCXX/matrix-casts.cpp | 4 +-
clang/test/SemaCXX/nested-name-spec.cpp | 8 +-
...nter-forward-declared-class-conversion.cpp | 4 +-
clang/test/SemaCXX/pseudo-destructors.cpp | 2 +-
clang/test/SemaCXX/return.cpp | 4 +-
clang/test/SemaCXX/static-assert.cpp | 2 +-
clang/test/SemaCXX/sugar-common-types.cpp | 5 +-
clang/test/SemaCXX/sugared-auto.cpp | 2 +-
clang/test/SemaCXX/type-aware-coroutines.cpp | 8 +-
.../undefined-partial-specialization.cpp | 2 +-
.../SemaObjCXX/Inputs/nullability-pragmas-1.h | 2 +-
clang/test/SemaObjCXX/arc-bridged-cast.mm | 4 +-
.../objc-boxed-expressions-nsvalue.mm | 4 +-
.../SemaObjCXX/objcbridge-attribute-arc.mm | 178 +++++-----
clang/test/SemaObjCXX/objcbridge-attribute.mm | 180 +++++-----
.../objcbridge-related-attribute.mm | 12 +-
.../test/SemaObjCXX/objcbridge-static-cast.mm | 104 +++---
.../combined-construct-num_workers-ast.cpp | 2 +-
.../compute-construct-intexpr-clause-ast.cpp | 2 +-
.../compute-construct-varlist-ast.cpp | 4 +-
.../aggregate-deduction-candidate.cpp | 84 +++--
clang/test/SemaTemplate/ctad.cpp | 8 +-
.../SemaTemplate/current-instantiation.cpp | 2 +-
clang/test/SemaTemplate/deduction-crash.cpp | 4 +-
clang/test/SemaTemplate/deduction-guide.cpp | 96 +++---
.../SemaTemplate/dependent-base-classes.cpp | 10 +-
clang/test/SemaTemplate/dependent-names.cpp | 2 +-
.../elaborated-type-specifier.cpp | 11 +-
.../instantiate-requires-expr.cpp | 4 +-
clang/test/SemaTemplate/make_integer_seq.cpp | 162 +++++----
.../ms-lookup-template-base-classes.cpp | 2 +-
.../ms-sizeof-missing-typename.cpp | 12 +-
.../nested-implicit-deduction-guides.cpp | 6 +-
.../nested-name-spec-template.cpp | 2 +-
clang/test/SemaTemplate/nested-template.cpp | 4 +-
.../test/SemaTemplate/overload-candidates.cpp | 12 +-
clang/test/SemaTemplate/temp_arg_nontype.cpp | 2 +-
clang/test/SemaTemplate/template-id-expr.cpp | 2 +-
clang/test/SemaTemplate/type_pack_element.cpp | 86 +++--
.../SemaTemplate/typename-specifier-4.cpp | 2 +-
.../test/SemaTemplate/typename-specifier.cpp | 6 +-
.../unittests/AST/ASTContextParentMapTest.cpp | 10 +-
clang/unittests/AST/ASTExprTest.cpp | 4 +-
clang/unittests/AST/ASTImporterFixtures.h | 3 +-
clang/unittests/AST/ASTImporterTest.cpp | 132 ++++----
clang/unittests/AST/DeclPrinterTest.cpp | 62 ++--
clang/unittests/AST/ProfilingTest.cpp | 8 +-
clang/unittests/AST/RandstructTest.cpp | 2 +-
.../unittests/AST/RecursiveASTVisitorTest.cpp | 5 +-
clang/unittests/AST/SizelessTypesTest.cpp | 2 +-
.../AST/StructuralEquivalenceTest.cpp | 15 +-
clang/unittests/AST/TemplateNameTest.cpp | 13 +-
clang/unittests/AST/TypePrinterTest.cpp | 13 +-
.../ASTMatchers/ASTMatchersNarrowingTest.cpp | 25 +-
.../ASTMatchers/ASTMatchersNodeTest.cpp | 88 +----
.../ASTMatchers/ASTMatchersTraversalTest.cpp | 245 ++++++--------
.../CachedConstAccessorsLatticeTest.cpp | 6 +-
.../FlowSensitive/DataflowEnvironmentTest.cpp | 2 +-
.../unittests/CodeGen/CodeGenExternalTest.cpp | 5 +-
clang/unittests/Index/IndexTests.cpp | 2 +-
.../unittests/Sema/HeuristicResolverTest.cpp | 32 +-
clang/unittests/StaticAnalyzer/SValTest.cpp | 13 +-
clang/unittests/Tooling/LookupTest.cpp | 18 +-
clang/unittests/Tooling/QualTypeNamesTest.cpp | 40 +--
clang/unittests/Tooling/RangeSelectorTest.cpp | 6 +-
.../RecursiveASTVisitorTestTypeLocVisitor.cpp | 12 +-
.../MemberPointerTypeLoc.cpp | 2 +-
.../NestedNameSpecifiers.cpp | 19 +-
clang/unittests/Tooling/RefactoringTest.cpp | 8 +-
181 files changed, 1726 insertions(+), 1829 deletions(-)
diff --git a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
index b74e183eec9cc..d319bee54aa6f 100644
--- a/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/StructuredBuffers-AST.hlsl
@@ -91,21 +91,21 @@ RESOURCE<float> Buffer;
// Default constructor
-// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void ()' inline
+// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void ()' inline
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_uninitializedhandle'
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: AlwaysInlineAttr
// Constructor from binding
-// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
@@ -114,12 +114,12 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: CompoundStmt {{.*}}
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding'
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int'
@@ -129,7 +129,7 @@ RESOURCE<float> Buffer;
// Constructor from implicit binding
-// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int'
@@ -138,12 +138,12 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: CompoundStmt {{.*}}
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding'
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int'
@@ -166,7 +166,7 @@ RESOURCE<float> Buffer;
// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-SUBSCRIPT-SAME: ' lvalue .__handle {{.*}}
-// CHECK-SUBSCRIPT-NEXT: CXXThisExpr {{.*}} 'const [[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-SUBSCRIPT-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -183,7 +183,7 @@ RESOURCE<float> Buffer;
// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-SUBSCRIPT-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-SUBSCRIPT-SAME: ' lvalue .__handle {{.*}}
-// CHECK-SUBSCRIPT-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-SUBSCRIPT-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-SUBSCRIPT-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-SUBSCRIPT-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -204,7 +204,7 @@ RESOURCE<float> Buffer;
// CHECK-LOAD-SAME{LITERAL}: [[hlsl::resource_class(
// CHECK-LOAD-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-LOAD-SAME: ' lvalue .__handle {{.*}}
-// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-LOAD-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-LOAD-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-LOAD-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -220,7 +220,7 @@ RESOURCE<float> Buffer;
// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle
-// CHECK-COUNTER-NEXT: CXXThisExpr {{.*}} 'RWStructuredBuffer<element_type>' lvalue implicit this
+// CHECK-COUNTER-NEXT: CXXThisExpr {{.*}} 'hlsl::RWStructuredBuffer<element_type>' lvalue implicit this
// CHECK-COUNTER-NEXT: IntegerLiteral {{.*}} 'int' 1
// CHECK-COUNTER-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -236,7 +236,7 @@ RESOURCE<float> Buffer;
// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-COUNTER-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle
-// CHECK-COUNTER-NEXT: CXXThisExpr {{.*}} 'RWStructuredBuffer<element_type>' lvalue implicit this
+// CHECK-COUNTER-NEXT: CXXThisExpr {{.*}} 'hlsl::RWStructuredBuffer<element_type>' lvalue implicit this
// CHECK-COUNTER-NEXT: IntegerLiteral {{.*}} 'int' -1
// CHECK-COUNTER-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -254,7 +254,7 @@ RESOURCE<float> Buffer;
// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle
-// CHECK-APPEND-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-APPEND-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-APPEND-NEXT: CallExpr {{.*}} 'unsigned int'
// CHECK-APPEND-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-APPEND-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept'
@@ -262,7 +262,7 @@ RESOURCE<float> Buffer;
// CHECK-APPEND-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-APPEND-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-APPEND-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle
-// CHECK-APPEND-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-APPEND-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-APPEND-NEXT: IntegerLiteral {{.*}} 'int' 1
// CHECK-APPEND-NEXT: DeclRefExpr {{.*}} 'element_type' ParmVar {{.*}} 'value' 'element_type'
@@ -279,7 +279,7 @@ RESOURCE<float> Buffer;
// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle
-// CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-CONSUME-NEXT: CallExpr {{.*}} 'unsigned int'
// CHECK-CONSUME-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-CONSUME-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_buffer_update_counter' 'unsigned int (...) noexcept'
@@ -287,7 +287,7 @@ RESOURCE<float> Buffer;
// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::resource_class(UAV)]]
// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::raw_buffer]]
// CHECK-CONSUME-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]' lvalue .__handle
-// CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-CONSUME-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-CONSUME-NEXT: IntegerLiteral {{.*}} 'int' -1
// CHECK: ClassTemplateSpecializationDecl {{.*}} class [[RESOURCE]] definition
diff --git a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
index d098e5a323ca7..53e4b27c91dac 100644
--- a/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
+++ b/clang/test/AST/HLSL/TypedBuffers-AST.hlsl
@@ -66,21 +66,21 @@ RESOURCE<float> Buffer;
// Default constructor
-// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void ()' inline
+// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void ()' inline
// CHECK-NEXT: CompoundStmt
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_uninitializedhandle'
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: AlwaysInlineAttr
// Constructor from binding
-// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, unsigned int, int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} registerNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
@@ -89,12 +89,12 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: CompoundStmt {{.*}}
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefrombinding'
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'registerNo' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int'
@@ -104,7 +104,7 @@ RESOURCE<float> Buffer;
// Constructor from implicit binding
-// CHECK: CXXConstructorDecl {{.*}} [[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
+// CHECK: CXXConstructorDecl {{.*}} hlsl::[[RESOURCE]]<element_type> 'void (unsigned int, int, unsigned int, unsigned int, const char *)' inline
// CHECK-NEXT: ParmVarDecl {{.*}} spaceNo 'unsigned int'
// CHECK-NEXT: ParmVarDecl {{.*}} range 'int'
// CHECK-NEXT: ParmVarDecl {{.*}} index 'unsigned int'
@@ -113,12 +113,12 @@ RESOURCE<float> Buffer;
// CHECK-NEXT: CompoundStmt {{.*}}
// CHECK-NEXT: BinaryOperator {{.*}} '='
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: CallExpr {{.*}} '__hlsl_resource_t
// CHECK-NEXT: ImplicitCastExpr {{.*}} <BuiltinFnToFnPtr>
// CHECK-NEXT: DeclRefExpr {{.*}} '<builtin fn type>' Function {{.*}} '__builtin_hlsl_resource_handlefromimplicitbinding'
// CHECK-NEXT: MemberExpr {{.*}} lvalue .__handle
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'spaceNo' 'unsigned int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'int' ParmVar {{.*}} 'range' 'int'
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'index' 'unsigned int'
@@ -141,7 +141,7 @@ RESOURCE<float> Buffer;
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-SAME: ' lvalue .__handle {{.*}}
-// CHECK-NEXT: CXXThisExpr {{.*}} 'const [[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'const hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -158,7 +158,7 @@ RESOURCE<float> Buffer;
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-SAME: ' lvalue .__handle {{.*}}
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
@@ -177,7 +177,7 @@ RESOURCE<float> Buffer;
// CHECK-SRV-SAME{LITERAL}: [[hlsl::resource_class(SRV)]]
// CHECK-SAME{LITERAL}: [[hlsl::contained_type(element_type)]]
// CHECK-SAME: ' lvalue .__handle {{.*}}
-// CHECK-NEXT: CXXThisExpr {{.*}} '[[RESOURCE]]<element_type>' lvalue implicit this
+// CHECK-NEXT: CXXThisExpr {{.*}} 'hlsl::[[RESOURCE]]<element_type>' lvalue implicit this
// CHECK-NEXT: DeclRefExpr {{.*}} 'unsigned int' ParmVar {{.*}} 'Index' 'unsigned int'
// CHECK-NEXT: AlwaysInlineAttr {{.*}} Implicit always_inline
diff --git a/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl b/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl
index 2f08531000f32..1c5e06789c3e4 100644
--- a/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl
+++ b/clang/test/AST/HLSL/cbuffer_and_namespaces.hlsl
@@ -63,9 +63,9 @@ namespace NS2 {
// CHECK: HLSLBufferDecl {{.*}} line:[[# @LINE + 2]]:11 cbuffer CB2
// CHECK: HLSLResourceClassAttr {{.*}} Implicit CBuffer
cbuffer CB2 {
- // CHECK: VarDecl {{.*}} foo0 'hlsl_constant ::Foo':'hlsl_constant Foo'
+ // CHECK: VarDecl {{.*}} foo0 'hlsl_constant ::Foo'
::Foo foo0;
- // CHECK: VarDecl {{.*}} foo1 'hlsl_constant Foo':'hlsl_constant NS2::Foo'
+ // CHECK: VarDecl {{.*}} foo1 'hlsl_constant Foo'
Foo foo1;
// CHECK: VarDecl {{.*}} foo2 'hlsl_constant NS1::Foo'
NS1::Foo foo2;
diff --git a/clang/test/AST/HLSL/vector-constructors.hlsl b/clang/test/AST/HLSL/vector-constructors.hlsl
index 31d8dd0fdac8e..fd43a7dcbfcca 100644
--- a/clang/test/AST/HLSL/vector-constructors.hlsl
+++ b/clang/test/AST/HLSL/vector-constructors.hlsl
@@ -88,10 +88,10 @@ void entry() {
// CHECK-NEXT: InitListExpr
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue>
// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .f {{.*}}
-// CHECK-NEXT: DeclRefExpr {{.*}} 'struct S':'S' lvalue Var {{.*}} 's' 'struct S':'S'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'struct S' lvalue Var {{.*}} 's' 'struct S'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <LValueToRValue>
// CHECK-NEXT: MemberExpr {{.*}} 'float' lvalue .f {{.*}}
-// CHECK-NEXT: DeclRefExpr {{.*}} 'struct S':'S' lvalue Var {{.*}} 's' 'struct S':'S'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'struct S' lvalue Var {{.*}} 's' 'struct S'
struct T {
operator float() const { return 1.0f; }
@@ -105,12 +105,12 @@ void entry() {
// CHECK-NEXT: CXXMemberCallExpr {{.*}} 'float'
// CHECK-NEXT: MemberExpr {{.*}} '<bound member function type>' .operator float {{.*}}
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const T' lvalue <NoOp>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'struct T':'T' lvalue Var {{.*}} 't' 'struct T':'T'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'struct T' lvalue Var {{.*}} 't' 'struct T'
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'float' <UserDefinedConversion>
// CHECK-NEXT: CXXMemberCallExpr {{.*}} 'float'
// CHECK-NEXT: MemberExpr {{.*}} '<bound member function type>' .operator float {{.*}}
// CHECK-NEXT: ImplicitCastExpr {{.*}} 'const T' lvalue <NoOp>
-// CHECK-NEXT: DeclRefExpr {{.*}} 'struct T':'T' lvalue Var {{.*}} 't' 'struct T':'T'
+// CHECK-NEXT: DeclRefExpr {{.*}} 'struct T' lvalue Var {{.*}} 't' 'struct T'
typedef float2 second_level_of_typedefs;
second_level_of_typedefs foo6 = float2(1.0f, 2.0f);
diff --git a/clang/test/AST/arm-mfp8.cpp b/clang/test/AST/arm-mfp8.cpp
index 195c734fc753e..b1fa04a3a79c1 100644
--- a/clang/test/AST/arm-mfp8.cpp
+++ b/clang/test/AST/arm-mfp8.cpp
@@ -49,7 +49,7 @@ class C1 {
}
};
-//CHECK: | |-CXXRecordDecl {{.*}} referenced class C1
+//CHECK: | |-CXXRecordDecl {{.*}} class C1
//CHECK-NEXT: | |-FieldDecl {{.*}} f1c '__mfp8'
//CHECK-NEXT: | |-VarDecl {{.*}} f2c 'const __mfp8' static
//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile __mfp8'
diff --git a/clang/test/AST/ast-dump-color.cpp b/clang/test/AST/ast-dump-color.cpp
index 87797f6bffc5b..2e60e760283de 100644
--- a/clang/test/AST/ast-dump-color.cpp
+++ b/clang/test/AST/ast-dump-color.cpp
@@ -82,15 +82,15 @@ struct Invalid {
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'const Mutex &'[[RESET]]{{$}}
//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] implicit constexpr[[CYAN]] Mutex[[RESET]] [[Green]]'void (Mutex &&)'[[RESET]] inline{{ .*$}}
//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Yellow]]col:33[[RESET]] [[Green]]'Mutex &&'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]> [[Yellow]]col:3[[RESET]] referenced[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]]
-//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]{{$}}
-//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]> [[Yellow]]col:8[[RESET]][[CYAN]] mu2[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]]
-//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]> [[Yellow]]col:3[[RESET]] referenced[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex'[[RESET]]
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]{{$}}
+//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]> [[Yellow]]col:8[[RESET]][[CYAN]] mu2[[RESET]] [[Green]]'class Mutex'[[RESET]]
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]{{$}}
//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]> [[Yellow]]col:5[[RESET]][[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]]
//CHECK: {{^}}[[Blue]]| `-[[RESET]][[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]], [[Yellow]]col:43[[RESET]]>{{$}}
-//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'Mutex'[[RESET]] non_odr_use_unevaluated{{$}}
+//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex'[[RESET]] non_odr_use_unevaluated{{$}}
//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:28:1[[RESET]], [[Yellow]]line:30:1[[RESET]]> [[Yellow]]line:28:8[[RESET]] struct[[CYAN]] Invalid[[RESET]] definition
-//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit referenced struct[[CYAN]] Invalid[[RESET]]
+//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit struct[[CYAN]] Invalid[[RESET]]
//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:29:3[[RESET]], [[Yellow]]col:42[[RESET]]> [[Yellow]]col:29[[RESET]] invalid[[CYAN]] Invalid[[RESET]] [[Green]]'void (int)'[[RESET]]
//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:37[[RESET]], [[Yellow]]<invalid sloc>[[RESET]]> [[Yellow]]col:42[[RESET]] invalid [[Green]]'int'[[RESET]]
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[BLUE]]NoInlineAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:18[[RESET]]>
@@ -100,5 +100,5 @@ struct Invalid {
//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'const Invalid &'[[RESET]]
//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] implicit constexpr[[CYAN]] Invalid[[RESET]] [[Green]]'void (Invalid &&)'[[RESET]] inline default trivial noexcept-unevaluated 0x{{[0-9a-fA-F]*}}
//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Yellow]]col:8[[RESET]] [[Green]]'Invalid &&'[[RESET]]
-//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:30:3[[RESET]]> [[Yellow]]col:3[[RESET]][[CYAN]] Invalid[[RESET]] [[Green]]'struct Invalid':'Invalid'[[RESET]]
-//CHECK: {{^}}[[Blue]] `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'struct Invalid':'Invalid'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]
+//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:30:3[[RESET]]> [[Yellow]]col:3[[RESET]][[CYAN]] Invalid[[RESET]] [[Green]]'struct Invalid'[[RESET]]
+//CHECK: {{^}}[[Blue]] `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'struct Invalid'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void () noexcept'[[RESET]]
diff --git a/clang/test/AST/ast-dump-ctad-alias.cpp b/clang/test/AST/ast-dump-ctad-alias.cpp
index f39a4cee518ce..781fb9f28cb8d 100644
--- a/clang/test/AST/ast-dump-ctad-alias.cpp
+++ b/clang/test/AST/ast-dump-ctad-alias.cpp
@@ -39,15 +39,14 @@ Out2<double>::AInner t(1.0);
// CHECK-NEXT: | | |-DeducedTemplateSpecializationType {{.*}} 'Out2<double>::AInner' dependent
// CHECK-NEXT: | | | `-name: 'Out2<double>::AInner'
// CHECK-NEXT: | | | `-TypeAliasTemplateDecl {{.+}} AInner{{$}}
-// CHECK-NEXT: | | `-ElaboratedType {{.*}} 'Inner<Y>' sugar dependent
-// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner<Y>' dependent
-// CHECK-NEXT: | | |-name: 'Inner':'Out<int>::Inner' qualified
-// CHECK-NEXT: | | | `-ClassTemplateDecl {{.+}} Inner{{$}}
-// CHECK-NEXT: | | `-TemplateArgument type 'Y'
-// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'Y'
-// CHECK-NEXT: | | |-FunctionTemplate {{.*}} '<deduction guide for Inner>'
-// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'Y' dependent depth 1 index 0
-// CHECK-NEXT: | | `-TemplateTypeParm {{.*}} 'Y'
+// CHECK-NEXT: | | `-TemplateSpecializationType {{.*}} 'Inner<Y>' dependent
+// CHECK-NEXT: | | |-name: 'Inner':'Out<int>::Inner' qualified
+// CHECK-NEXT: | | | `-ClassTemplateDecl {{.+}} Inner{{$}}
+// CHECK-NEXT: | | `-TemplateArgument type 'Y'
+// CHECK-NEXT: | | `-SubstTemplateTypeParmType {{.*}} 'Y'
+// CHECK-NEXT: | | |-FunctionTemplate {{.*}} '<deduction guide for Inner>'
+// CHECK-NEXT: | | `-TemplateTypeParmType {{.*}} 'Y' dependent depth 1 index 0
+// CHECK-NEXT: | | `-TemplateTypeParm {{.*}} 'Y'
// CHECK-NEXT: | |-CXXDeductionGuideDecl {{.*}} <deduction guide for AInner> 'auto (Y) -> Inner<Y>'
// CHECK-NEXT: | | `-ParmVarDecl {{.*}} 'Y'
// CHECK-NEXT: | `-CXXDeductionGuideDecl {{.*}} used <deduction guide for AInner> 'auto (double) -> Inner<double>' implicit_instantiation
@@ -188,9 +187,9 @@ void foo() {
// CHECK-NEXT: | | | |-ImplicitConceptSpecializationDecl {{.*}}
// CHECK-NEXT: | | | | |-TemplateArgument type 'type-parameter-0-2'
// CHECK-NEXT: | | | | | `-TemplateTypeParmType {{.*}} 'type-parameter-0-2' dependent depth 0 index 2
-// CHECK-NEXT: | | | | `-TemplateArgument pack '<Packs<type-parameter-0-1...>>'
-// CHECK-NEXT: | | | | `-TemplateArgument type 'Packs<type-parameter-0-1...>'
-// CHECK-NEXT: | | | | `-TemplateSpecializationType {{.*}} 'Packs<type-parameter-0-1...>' dependent
+// CHECK-NEXT: | | | | `-TemplateArgument pack '<GH124715::Packs<type-parameter-0-1...>>'
+// CHECK-NEXT: | | | | `-TemplateArgument type 'GH124715::Packs<type-parameter-0-1...>'
+// CHECK-NEXT: | | | | `-TemplateSpecializationType {{.*}} 'GH124715::Packs<type-parameter-0-1...>' dependent
// CHECK-NEXT: | | | | |-name: 'GH124715::Packs'
// CHECK-NEXT: | | | | | `-ClassTemplateDecl {{.*}} Packs
// CHECK-NEXT: | | | | `-TemplateArgument pack '<type-parameter-0-1...>'
diff --git a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp
index fc86aeb3e5ec3..09a274aa46422 100644
--- a/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp
+++ b/clang/test/AST/ast-dump-cxx2b-deducing-this.cpp
@@ -33,5 +33,5 @@ struct B {
operator A(this B);
};
A a = A(B{});
-// CHECK: CallExpr 0x{{[^ ]*}} <col:9, col:11> 'A':'GH130272::A'
+// CHECK: CallExpr 0x{{[^ ]*}} <col:9, col:11> 'A'
}
diff --git a/clang/test/AST/ast-dump-decl-json.c b/clang/test/AST/ast-dump-decl-json.c
index ec2d75ba7195d..b84ddf93f44c3 100644
--- a/clang/test/AST/ast-dump-decl-json.c
+++ b/clang/test/AST/ast-dump-decl-json.c
@@ -585,7 +585,6 @@ void testParmVarDecl(int TestParmVarDecl);
// CHECK-NEXT: },
// CHECK-NEXT: "name": "e",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "enum TestEnumDeclAnon::(unnamed at {{.*}}:31:3)",
// CHECK-NEXT: "qualType": "enum (unnamed enum at {{.*}}:31:3)"
// CHECK-NEXT: }
// CHECK-NEXT: }
@@ -777,7 +776,6 @@ void testParmVarDecl(int TestParmVarDecl);
// CHECK-NEXT: },
// CHECK-NEXT: "name": "testRecordDeclAnon1",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "struct TestRecordDeclAnon1::(unnamed at {{.*}}:46:3)",
// CHECK-NEXT: "qualType": "struct (unnamed struct at {{.*}}:46:3)"
// CHECK-NEXT: }
// CHECK-NEXT: }
@@ -1204,7 +1202,6 @@ void testParmVarDecl(int TestParmVarDecl);
// CHECK-NEXT: },
// CHECK-NEXT: "name": "y",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "enum (unnamed at {{.*}}:69:29)",
// CHECK-NEXT: "qualType": "enum (unnamed enum at {{.*}}:69:29)"
// CHECK-NEXT: }
// CHECK-NEXT: },
diff --git a/clang/test/AST/ast-dump-decl.cpp b/clang/test/AST/ast-dump-decl.cpp
index 08d8fba795daa..dca0e9b9ca10a 100644
--- a/clang/test/AST/ast-dump-decl.cpp
+++ b/clang/test/AST/ast-dump-decl.cpp
@@ -35,9 +35,9 @@ namespace testVarDeclNRVO {
// CHECK: FunctionDecl{{.*}} TestFuncNRVO 'A ()'
// CHECK-NEXT: `-CompoundStmt
// CHECK-NEXT: |-DeclStmt
-// CHECK-NEXT: | `-VarDecl{{.*}} TestVarDeclNRVO 'A':'testVarDeclNRVO::A' nrvo callinit
+// CHECK-NEXT: | `-VarDecl{{.*}} TestVarDeclNRVO 'A' nrvo callinit
// CHECK-NEXT: | `-CXXConstructExpr
-// CHECK-NEXT: `-ReturnStmt{{.*}} nrvo_candidate(Var {{.*}} 'TestVarDeclNRVO' 'A':'testVarDeclNRVO::A')
+// CHECK-NEXT: `-ReturnStmt{{.*}} nrvo_candidate(Var {{.*}} 'TestVarDeclNRVO' 'A')
void testParmVarDeclInit(int TestParmVarDeclInit = 0);
// CHECK: ParmVarDecl{{.*}} TestParmVarDeclInit 'int'
@@ -131,8 +131,8 @@ namespace testCXXRecordDecl {
// CHECK-NEXT: CopyAssignment simple non_trivial has_const_param
// CHECK-NEXT: MoveAssignment exists simple non_trivial
// CHECK-NEXT: Destructor simple irrelevant trivial
-// CHECK-NEXT: virtual private 'A':'testCXXRecordDecl::A'
-// CHECK-NEXT: public 'B':'testCXXRecordDecl::B'
+// CHECK-NEXT: virtual private 'A'
+// CHECK-NEXT: public 'B'
// CHECK-NEXT: CXXRecordDecl{{.*}} class TestCXXRecordDecl
// CHECK-NEXT: FieldDecl
@@ -269,7 +269,7 @@ namespace testFunctionTemplateDecl {
// CHECK-NEXT: |-TemplateArgument type 'testFunctionTemplateDecl::B'
// CHECK-NEXT: | `-RecordType 0{{.+}} 'testFunctionTemplateDecl::B'
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'B'
- // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} <col:40> col:41 'B':'testFunctionTemplateDecl::B'
+ // CHECK-NEXT: `-ParmVarDecl 0x{{.+}} <col:40> col:41 'B'
namespace testClassTemplateDecl {
@@ -330,8 +330,8 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | | `-Destructor irrelevant non_trivial user_declared{{$}}
// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:24, col:30> col:30 implicit referenced class TestClassTemplate{{$}}
// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-50]]:3, col:9> col:3 public{{$}}
-// CHECK-NEXT: | |-CXXConstructorDecl 0x[[#%x,TEMPLATE_CONSTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:23> col:5 TestClassTemplate<T> 'void ()'{{$}}
-// CHECK-NEXT: | |-CXXDestructorDecl 0x[[#%x,TEMPLATE_DESTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:24> col:5 ~TestClassTemplate<T> 'void ()' not_selected{{$}}
+// CHECK-NEXT: | |-CXXConstructorDecl 0x[[#%x,TEMPLATE_CONSTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:23> col:5 testClassTemplateDecl::TestClassTemplate<T> 'void ()'{{$}}
+// CHECK-NEXT: | |-CXXDestructorDecl 0x[[#%x,TEMPLATE_DESTRUCTOR_DECL:]] <line:[[@LINE-50]]:5, col:24> col:5 ~testClassTemplateDecl::TestClassTemplate<T> 'void ()' not_selected{{$}}
// CHECK-NEXT: | |-CXXMethodDecl 0x[[#%x,TEMPLATE_METHOD_DECL:]] <line:[[@LINE-50]]:5, col:11> col:9 j 'int ()'{{$}}
// CHECK-NEXT: | `-FieldDecl 0x{{.+}} <line:[[@LINE-50]]:5, col:9> col:9 i 'int'{{$}}
// CHECK-NEXT: |-ClassTemplateSpecializationDecl 0x{{.+}} <line:[[@LINE-56]]:3, line:[[@LINE-50]]:3> line:[[@LINE-56]]:30 class TestClassTemplate definition implicit_instantiation{{$}}
@@ -343,7 +343,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | | |-MoveAssignment{{$}}
// CHECK-NEXT: | | `-Destructor non_trivial user_declared{{$}}
// CHECK-NEXT: | |-TemplateArgument type 'testClassTemplateDecl::A'{{$}}
-// CHECK-NEXT: | | `-RecordType 0{{.+}} 'testClassTemplateDecl::A'{{$}}
+// CHECK-NEXT: | | `-RecordType 0{{.+}} 'testClassTemplateDecl::A' canonical{{$}}
// CHECK-NEXT: | | `-CXXRecord 0x{{.+}} 'A'{{$}}
// CHECK-NEXT: | |-CXXRecordDecl 0x{{.+}} <col:24, col:30> col:30 implicit class TestClassTemplate{{$}}
// CHECK-NEXT: | |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-67]]:3, col:9> col:3 public{{$}}
@@ -366,7 +366,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit{{$}}
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit{{$}}
// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::B'{{$}}
-// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::B'{{$}}
+// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::B' canonical{{$}}
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'B'{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:14, col:20> col:20 implicit class TestClassTemplate{{$}}
// CHECK-NEXT: `-FieldDecl 0x{{.+}} <line:[[@LINE-78]]:5, col:9> col:9 j 'int'{{$}}
@@ -380,7 +380,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | |-MoveAssignment{{$}}
// CHECK-NEXT: | `-Destructor non_trivial user_declared{{$}}
// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::C'{{$}}
-// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::C'{{$}}
+// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::C' canonical{{$}}
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'C'{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <line:[[@LINE-104]]:24, col:30> col:30 implicit class TestClassTemplate{{$}}
// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-104]]:3, col:9> col:3 public{{$}}
@@ -398,7 +398,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: | |-MoveAssignment{{$}}
// CHECK-NEXT: | `-Destructor non_trivial user_declared{{$}}
// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::D'{{$}}
-// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::D'{{$}}
+// CHECK-NEXT: | `-RecordType 0{{.+}} 'testClassTemplateDecl::D' canonical{{$}}
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'D'{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <line:[[@LINE-122]]:24, col:30> col:30 implicit class TestClassTemplate{{$}}
// CHECK-NEXT: |-AccessSpecDecl 0x{{.+}} <line:[[@LINE-122]]:3, col:9> col:3 public{{$}}
@@ -432,7 +432,7 @@ namespace testClassTemplateDecl {
// CHECK-NEXT: |-TemplateArgument type 'type-parameter-0-0'{{$}}
// CHECK-NEXT: | `-TemplateTypeParmType 0x{{.+}} 'type-parameter-0-0' dependent depth 0 index 0{{$}}
// CHECK-NEXT: |-TemplateArgument type 'testClassTemplateDecl::A'{{$}}
-// CHECK-NEXT: | `-RecordType 0x{{.+}} 'testClassTemplateDecl::A'{{$}}
+// CHECK-NEXT: | `-RecordType 0x{{.+}} 'testClassTemplateDecl::A' canonical{{$}}
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A'{{$}}
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:12, col:21> col:21 referenced typename depth 0 index 0 T1{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplatePartial{{$}}
@@ -605,7 +605,7 @@ namespace testCanonicalTemplate {
// CHECK-NEXT: | `-ParmVarDecl 0x{{.*}} <col:50> col:51 'T'{{$}}
// CHECK-NEXT: `-FunctionDecl 0x{{.*}} <line:[[@LINE-6]]:24, col:51> col:29 used TestFunctionTemplate 'void (testCanonicalTemplate::A)' implicit_instantiation{{$}}
// CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'{{$}}
- // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A'{{$}}
+ // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' canonical{{$}}
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A'{{$}}
// CHECK-NEXT: `-ParmVarDecl 0x{{.*}} <col:50> col:51 'testCanonicalTemplate::A'{{$}}
@@ -644,7 +644,7 @@ namespace testCanonicalTemplate {
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit{{$}}
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit{{$}}
// CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'{{$}}
- // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A'{{$}}
+ // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' canonical{{$}}
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A'{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate{{$}}
// CHECK-NEXT: |-FriendDecl 0x{{.+}} <line:[[@LINE-30]]:5, col:40> col:40{{$}}
@@ -677,7 +677,7 @@ namespace testCanonicalTemplate {
// CHECK-NEXT: | |-MoveAssignment exists simple trivial needs_implicit{{$}}
// CHECK-NEXT: | `-Destructor simple irrelevant trivial needs_implicit{{$}}
// CHECK-NEXT: |-TemplateArgument type 'testCanonicalTemplate::A'{{$}}
- // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A'{{$}}
+ // CHECK-NEXT: | `-RecordType 0x{{.+}} 'testCanonicalTemplate::A' canonical{{$}}
// CHECK-NEXT: | `-CXXRecord 0x{{.+}} 'A'{{$}}
// CHECK-NEXT: |-CXXRecordDecl 0x{{.+}} <col:25, col:31> col:31 implicit class TestClassTemplate2{{$}}
// CHECK-NEXT: |-CXXConstructorDecl 0x{{.+}} <col:31> col:31 implicit used constexpr TestClassTemplate2 'void () noexcept' inline default trivial{{$}}
@@ -721,7 +721,7 @@ namespace testCanonicalTemplate {
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <col:16, col:25> col:25 referenced typename depth 0 index 0 T{{$}}
// CHECK-NEXT: |-VarDecl 0x{{.+}} <col:28, col:43> col:43 TestVarTemplate 'const T' static{{$}}
// CHECK-NEXT: |-VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-12]]:3, line:[[@LINE-11]]:34> col:14 referenced TestVarTemplate 'const int' implicit_instantiation cinit{{$}}
- // CHECK-NEXT: | |-NestedNameSpecifier TypeSpec 'testCanonicalTemplate::S'{{$}}
+ // CHECK-NEXT: | |-NestedNameSpecifier TypeSpec 'S'{{$}}
// CHECK-NEXT: | |-TemplateArgument type 'int'{{$}}
// CHECK-NEXT: | | `-BuiltinType 0x{{.+}} 'int'{{$}}
// CHECK-NEXT: | `-InitListExpr 0x{{.+}} <col:32, col:34> 'int'{{$}}
@@ -735,13 +735,13 @@ namespace testCanonicalTemplate {
// CHECK: VarTemplateDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-24]]:3, line:[[@LINE-23]]:34> col:14 TestVarTemplate{{$}}
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <line:[[@LINE-25]]:12, col:21> col:21 referenced typename depth 0 index 0 T{{$}}
// CHECK-NEXT: |-VarDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <line:[[@LINE-25]]:3, col:34> col:14 TestVarTemplate 'const T' cinit{{$}}
- // CHECK-NEXT: | |-NestedNameSpecifier TypeSpec 'testCanonicalTemplate::S'{{$}}
+ // CHECK-NEXT: | |-NestedNameSpecifier TypeSpec 'S'{{$}}
// CHECK-NEXT: | `-InitListExpr 0x{{.+}} <col:32, col:34> 'void'{{$}}
// CHECK-NEXT: |-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int'{{$}}
// CHECK-NEXT: `-VarTemplateSpecialization 0x{{.+}} 'TestVarTemplate' 'const int'{{$}}
// CHECK: VarTemplateSpecializationDecl 0x{{.+}} parent 0x{{.+}} prev 0x{{.+}} <{{.+}}:[[@LINE-32]]:3, line:[[@LINE-31]]:34> col:14 referenced TestVarTemplate 'const int' implicit_instantiation cinit{{$}}
- // CHECK-NEXT: |-NestedNameSpecifier TypeSpec 'testCanonicalTemplate::S'{{$}}
+ // CHECK-NEXT: |-NestedNameSpecifier TypeSpec 'S'{{$}}
// CHECK-NEXT: |-TemplateArgument type 'int'{{$}}
// CHECK-NEXT: | `-BuiltinType 0x{{.+}} 'int'{{$}}
// CHECK-NEXT: `-InitListExpr 0x{{.+}} <col:32, col:34> 'int'{{$}}
@@ -901,7 +901,7 @@ template<typename T> class TestFriendDecl {
// CHECK: CXXRecord{{.*}} TestFriendDecl
// CHECK-NEXT: FriendDecl
// CHECK-NEXT: FunctionDecl{{.*}} foo
-// CHECK-NEXT: FriendDecl{{.*}} 'class A':'A'
+// CHECK-NEXT: FriendDecl{{.*}} 'class A'
// CHECK-NEXT: CXXRecordDecl{{.*}} class A
// CHECK-NEXT: FriendDecl{{.*}} 'T'
diff --git a/clang/test/AST/ast-dump-expr-json.cpp b/clang/test/AST/ast-dump-expr-json.cpp
index 5a762acad7917..0a979d14e3848 100644
--- a/clang/test/AST/ast-dump-expr-json.cpp
+++ b/clang/test/AST/ast-dump-expr-json.cpp
@@ -7958,7 +7958,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
@@ -7984,7 +7983,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "const NS::X",
// CHECK-NEXT: "qualType": "const X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
@@ -8138,7 +8136,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "const NS::X",
// CHECK-NEXT: "qualType": "const X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
@@ -8391,7 +8388,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
@@ -8417,7 +8413,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "const NS::X",
// CHECK-NEXT: "qualType": "const X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
@@ -8716,7 +8711,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
@@ -8742,7 +8736,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "const NS::X",
// CHECK-NEXT: "qualType": "const X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
@@ -8896,7 +8889,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "const NS::X",
// CHECK-NEXT: "qualType": "const X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
@@ -9028,7 +9020,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: "isUsed": true,
// CHECK-NEXT: "name": "x",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: },
// CHECK-NEXT: "init": "call",
@@ -9049,7 +9040,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
@@ -9151,7 +9141,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "prvalue",
@@ -9177,7 +9166,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "const NS::X",
// CHECK-NEXT: "qualType": "const X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
@@ -9199,7 +9187,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: },
// CHECK-NEXT: "valueCategory": "lvalue",
@@ -9208,7 +9195,6 @@ void TestNonADLCall3() {
// CHECK-NEXT: "kind": "VarDecl",
// CHECK-NEXT: "name": "x",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "NS::X",
// CHECK-NEXT: "qualType": "X"
// CHECK-NEXT: }
// CHECK-NEXT: }
diff --git a/clang/test/AST/ast-dump-expr.cpp b/clang/test/AST/ast-dump-expr.cpp
index 8ccb39f8f3165..5b1de44a69b2b 100644
--- a/clang/test/AST/ast-dump-expr.cpp
+++ b/clang/test/AST/ast-dump-expr.cpp
@@ -219,13 +219,10 @@ void PostfixExpressions(S a, S *p, U<int> *r) {
// CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:5> '<bound member function type>' .~S 0x{{[^ ]*}}
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S' lvalue ParmVar 0x{{[^ ]*}} 'a' 'S'
- // FIXME: similarly, there is no way to distinguish the construct below from
- // the p->~S() case.
p->::S::~S();
// CHECK: CXXMemberCallExpr 0x{{[^ ]*}} <line:[[@LINE-1]]:3, col:14> 'void'
// CHECK-NEXT: MemberExpr 0x{{[^ ]*}} <col:3, col:12> '<bound member function type>' ->~S 0x{{[^ ]*}}
- // CHECK-NEXT: NestedNameSpecifier TypeSpec 'S'
- // CHECK-NEXT: NestedNameSpecifier Global
+ // CHECK-NEXT: NestedNameSpecifier TypeSpec '::S'
// CHECK-NEXT: ImplicitCastExpr
// CHECK-NEXT: DeclRefExpr 0x{{[^ ]*}} <col:3> 'S *' lvalue ParmVar 0x{{[^ ]*}} 'p' 'S *'
@@ -597,5 +594,5 @@ struct S {
void f() {
S(S(0, 1));
}
-// CHECK: CXXTemporaryObjectExpr {{.*}} <col:5, col:11> 'S':'GH143711::S' 'void (int, int)'
+// CHECK: CXXTemporaryObjectExpr {{.*}} <col:5, col:11> 'S' 'void (int, int)'
}
diff --git a/clang/test/AST/ast-dump-for-range-lifetime.cpp b/clang/test/AST/ast-dump-for-range-lifetime.cpp
index ee046be19ab63..c330342f3328e 100644
--- a/clang/test/AST/ast-dump-for-range-lifetime.cpp
+++ b/clang/test/AST/ast-dump-for-range-lifetime.cpp
@@ -24,14 +24,14 @@ void test1() {
// CHECK-NEXT: | |-<<<NULL>>>
// CHECK-NEXT: | |-DeclStmt {{.*}}
// CHECK-NEXT: | | `-VarDecl {{.*}} implicit used __range1 'const A &' cinit
- // CHECK-NEXT: | | `-ExprWithCleanups {{.*}} 'const A':'const P2718R0::A' lvalue
- // CHECK-NEXT: | | `-CallExpr {{.*}} 'const A':'const P2718R0::A' lvalue
+ // CHECK-NEXT: | | `-ExprWithCleanups {{.*}} 'const A' lvalue
+ // CHECK-NEXT: | | `-CallExpr {{.*}} 'const A' lvalue
// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const A &(*)(const A &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const A &(const A &)' lvalue Function {{.*}} 'f1' 'const A &(const A &)'
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const A':'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'const A &'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'const A &'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CallExpr {{.*}} 'A'
// CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'A (*)()' <FunctionToPointerDecay>
// CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'A ()' lvalue Function {{.*}} 'g' 'A ()'
for (auto e : f1(g()))
@@ -56,11 +56,11 @@ void test2() {
// CHECK-NEXT: | | `-CallExpr {{.*}} 'const A *'
// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const A *(*)(const A &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const A *(const A &)' lvalue Function {{.*}} 'g' 'const A *(const A &)'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' lvalue <DerivedToBase (A)>
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const B':'const P2718R0::B' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const B':'const P2718R0::B' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'B':'P2718R0::B' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'B':'P2718R0::B' 'void () noexcept(false)' zeroing
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A' lvalue <DerivedToBase (A)>
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const B' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const B' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'B' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'B' 'void () noexcept(false)' zeroing
for (auto e : f(g(B())))
bar(e);
}
@@ -82,9 +82,9 @@ void test3() {
// CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue
// CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','
// CHECK-NEXT: | |-CXXStaticCastExpr {{.*}} 'void' static_cast<void> <ToVoid>
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' 'void ()'
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'
for ([[maybe_unused]] int x : static_cast<void>(LockGuard()), v)
LockGuard guard;
@@ -96,9 +96,9 @@ void test3() {
// CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue
// CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','
// CHECK-NEXT: | |-CStyleCastExpr {{.*}} 'void' <ToVoid>
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' 'void ()'
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'
for ([[maybe_unused]] int x : (void)LockGuard(), v)
LockGuard guard;
@@ -109,9 +109,9 @@ void test3() {
// CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'int (&)[3]' cinit
// CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'int[3]' lvalue
// CHECK-NEXT: | `-BinaryOperator {{.*}} 'int[3]' lvalue ','
- // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' 'void ()'
+ // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'LockGuard' xvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'
for ([[maybe_unused]] int x : LockGuard(), v)
LockGuard guard;
@@ -130,12 +130,12 @@ void test4() {
// CHECK-NEXT: | `-CallExpr {{.*}} 'int[3]' lvalue
// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'int (&(*)(const A &))[3]' <FunctionToPointerDecay>
// CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int (&(const A &))[3]' lvalue Function {{.*}} 'default_arg_fn' 'int (&(const A &))[3]'
- // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const A':'const P2718R0::A' lvalue has rewritten init
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A':'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' <NoOp>
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'A':'P2718R0::A' 'void ()'
- for (auto e : default_arg_fn())
+ // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const A' lvalue has rewritten init
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'A' 'void ()'
+ for (auto e : default_arg_fn())
bar(e);
}
@@ -158,43 +158,43 @@ void test5() {
// CHECK-NEXT: | `-CallExpr {{.*}} 'int[3]' lvalue
// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'int (&(*)(const A &))[3]' <FunctionToPointerDecay>
// CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'int (&(const A &))[3]' lvalue Function {{.*}} 'default_arg_fn' 'int (&(const A &))[3]'
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A':'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' <NoOp>
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A'
- // CHECK-NEXT: | `-CallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A'
+ // CHECK-NEXT: | `-CallExpr {{.*}} 'A'
// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'A (*)(const A &, const DefaultA &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'A (const A &, const DefaultA &)' lvalue Function {{.*}} 'foo' 'A (const A &, const DefaultA &)'
- // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'const A':'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A'
- // CHECK-NEXT: | | `-CallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'A'
+ // CHECK-NEXT: | | `-CallExpr {{.*}} 'A'
// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'A (*)(const A &, const DefaultA &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'A (const A &, const DefaultA &)' lvalue Function {{.*}} 'foo' 'A (const A &, const DefaultA &)'
- // CHECK-NEXT: | | |-MaterializeTemporaryExpr {{.*}} 'const A':'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' <NoOp>
- // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A'
- // CHECK-NEXT: | | | `-CallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | | |-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>
+ // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'A'
+ // CHECK-NEXT: | | | `-CallExpr {{.*}} 'A'
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'A (*)(const A &, const DefaultA &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'A (const A &, const DefaultA &)' lvalue Function {{.*}} 'foo' 'A (const A &, const DefaultA &)'
- // CHECK-NEXT: | | | |-MaterializeTemporaryExpr {{.*}} 'const A':'const P2718R0::A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' <NoOp>
- // CHECK-NEXT: | | | | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A'
- // CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'A':'P2718R0::A' 'void ()'
- // CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
- // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
- // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
- // CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
- // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
+ // CHECK-NEXT: | | | |-MaterializeTemporaryExpr {{.*}} 'const A' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const A' <NoOp>
+ // CHECK-NEXT: | | | | `-CXXBindTemporaryExpr {{.*}} 'A'
+ // CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'A' 'void ()'
+ // CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init
+ // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>
+ // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'
+ // CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'
+ // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'
for (auto e : default_arg_fn(foo(foo(foo(A())))))
bar(e);
}
@@ -210,40 +210,40 @@ void test6() {
// CHECK-NEXT: |-<<<NULL>>>
// CHECK-NEXT: |-DeclStmt {{.*}}
// CHECK-NEXT: | `-VarDecl {{.*}} col:17 implicit used __range1 'C &&' cinit
- // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'C':'P2718R0::C' xvalue
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'C':'P2718R0::C' xvalue extended by Var {{.*}} '__range1' 'C &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'C':'P2718R0::C'
- // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'C':'P2718R0::C' 'void (int, const C &, const DefaultA &)'
+ // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'C' xvalue
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'C' xvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'C'
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void (int, const C &, const DefaultA &)'
// CHECK-NEXT: | |-IntegerLiteral {{.*}}'int' 0
- // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'const C':'const P2718R0::C' lvalue extended by Var {{.*}} '__range1' 'C &&'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const C':'const P2718R0::C' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'C':'P2718R0::C'
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'C':'P2718R0::C' 'void (int, const C &, const DefaultA &)'
+ // CHECK-NEXT: | |-MaterializeTemporaryExpr {{.*}} 'const C' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const C' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'C'
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void (int, const C &, const DefaultA &)'
// CHECK-NEXT: | | |-IntegerLiteral {{.*}} 'int' 0
- // CHECK-NEXT: | | |-MaterializeTemporaryExpr {{.*}} 'const C':'const P2718R0::C' lvalue extended by Var {{.*}} '__range1' 'C &&'
- // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const C':'const P2718R0::C' <NoOp>
- // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'C':'P2718R0::C'
- // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'C':'P2718R0::C' 'void (int, const C &, const DefaultA &)'
+ // CHECK-NEXT: | | |-MaterializeTemporaryExpr {{.*}} 'const C' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const C' <NoOp>
+ // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'C'
+ // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void (int, const C &, const DefaultA &)'
// CHECK-NEXT: | | | |-IntegerLiteral {{.*}} 'int' 0
- // CHECK-NEXT: | | | |-MaterializeTemporaryExpr {{.*}} 'const C':'const P2718R0::C' lvalue extended by Var {{.*}} '__range1' 'C &&'
- // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const C':'const P2718R0::C' <NoOp>
- // CHECK-NEXT: | | | | `-CXXBindTemporaryExpr {{.*}} 'C':'P2718R0::C'
- // CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'C':'P2718R0::C' 'void ()'
- // CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
- // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
- // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
- // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
- // CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
- // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA':'const P2718R0::DefaultA' lvalue has rewritten init
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA':'const P2718R0::DefaultA' <NoOp>
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA':'P2718R0::DefaultA' 'void ()'
+ // CHECK-NEXT: | | | |-MaterializeTemporaryExpr {{.*}} 'const C' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | | | | `-ImplicitCastExpr {{.*}} 'const C' <NoOp>
+ // CHECK-NEXT: | | | | `-CXXBindTemporaryExpr {{.*}} 'C'
+ // CHECK-NEXT: | | | | `-CXXTemporaryObjectExpr {{.*}} 'C' 'void ()'
+ // CHECK-NEXT: | | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init
+ // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>
+ // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'
+ // CHECK-NEXT: | | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'
+ // CHECK-NEXT: | `-CXXDefaultArgExpr {{.*}} <<invalid sloc>> 'const DefaultA' lvalue has rewritten init
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const DefaultA' lvalue extended by Var {{.*}} '__range1' 'C &&'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const DefaultA' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'DefaultA' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'DefaultA' 'void ()'
for (auto e : C(0, C(0, C(0, C()))))
bar(e);
}
@@ -255,28 +255,28 @@ void test7() {
// CHECK-NEXT: |-<<<NULL>>>
// CHECK-NEXT: |-DeclStmt {{.*}}
// CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'A &&' cinit
- // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'A':'P2718R0::A' xvalue
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A':'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'A' xvalue
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A' lvalue
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A':'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A' lvalue
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A':'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A' lvalue
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A':'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CallExpr {{.*}} 'A'
// CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'A (*)()' <FunctionToPointerDecay>
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'A ()' lvalue Function {{.*}} 'g' 'A ()'
for (auto e : g().r().g().r().g().r().g())
@@ -324,11 +324,11 @@ void test9() {
// CHECK-NEXT: | `-CallExpr {{.*}} 'const A *'
// CHECK-NEXT: | |-ImplicitCastExpr {{.*}} 'const A *(*)(const A &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | `-DeclRefExpr {{.*}} 'const A *(const A &)' lvalue Function {{.*}} 'dg2' 'const A *(const A &)'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A':'const P2718R0::A' lvalue <DerivedToBase (A)>
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const B':'const P2718R0::B' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const B':'const P2718R0::B' <NoOp>
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'B':'P2718R0::B' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'B':'P2718R0::B' 'void () noexcept(false)' zeroing
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A' lvalue <DerivedToBase (A)>
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const B' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const B' <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'B' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXTemporaryObjectExpr {{.*}} 'B' 'void () noexcept(false)' zeroing
for (auto e : df2(dg2(B())))
bar(e);
}
@@ -348,10 +348,10 @@ void test10() {
// CHECK-NEXT: | | `-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue
// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' 'void ()'
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'
for ([[maybe_unused]] int x : static_cast<void>(df1(LockGuard())), v)
LockGuard guard;
@@ -366,10 +366,10 @@ void test10() {
// CHECK-NEXT: | | `-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue
// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' 'void ()'
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'
for ([[maybe_unused]] int x : (void)df1(LockGuard()), v)
LockGuard guard;
@@ -384,17 +384,17 @@ void test10() {
// CHECK-NEXT: | | |-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue
// CHECK-NEXT: | | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')
- // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' <NoOp>
- // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' 'void ()'
+ // CHECK-NEXT: | | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>
+ // CHECK-NEXT: | | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'
// CHECK-NEXT: | | `-CallExpr {{.*}} 'const P2718R0::LockGuard' lvalue
// CHECK-NEXT: | | |-ImplicitCastExpr {{.*}} 'const P2718R0::LockGuard &(*)(const P2718R0::LockGuard &)' <FunctionToPointerDecay>
// CHECK-NEXT: | | | `-DeclRefExpr {{.*}} 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' lvalue Function {{.*}} 'df1' 'const P2718R0::LockGuard &(const P2718R0::LockGuard &)' (FunctionTemplate {{.*}} 'df1')
- // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
- // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard':'const P2718R0::LockGuard' <NoOp>
- // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' (CXXTemporary {{.*}})
- // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard':'P2718R0::LockGuard' 'void ()'
+ // CHECK-NEXT: | | `-MaterializeTemporaryExpr {{.*}} 'const LockGuard' lvalue extended by Var {{.*}} '__range1' 'int (&)[3]'
+ // CHECK-NEXT: | | `-ImplicitCastExpr {{.*}} 'const LockGuard' <NoOp>
+ // CHECK-NEXT: | | `-CXXBindTemporaryExpr {{.*}} 'LockGuard' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | | `-CXXTemporaryObjectExpr {{.*}} 'LockGuard' 'void ()'
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'int[3]' lvalue Var {{.*}} 'v' 'int[3]'
for ([[maybe_unused]] int x : df1(LockGuard()), df1(LockGuard()), v)
LockGuard guard;
@@ -403,7 +403,7 @@ void test10() {
// Test default argument && dependent context
template <typename T> int (&default_arg_fn2(const T & = T()))[3];
void test11() {
- for (auto e : default_arg_fn2<A>())
+ for (auto e : default_arg_fn2<A>())
bar(e);
}
@@ -422,24 +422,24 @@ void test13() {
// CHECK-NEXT: |-<<<NULL>>>
// CHECK-NEXT: |-DeclStmt {{.*}}
// CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'A &&' cinit
- // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'A':'P2718R0::A' xvalue
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A':'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'A' xvalue
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A' lvalue
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A':'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A' lvalue
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A':'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A':'P2718R0::A' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A'
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'A' xvalue extended by Var {{.*}} '__range1' 'A &&'
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A'
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .g {{.*}}
- // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A':'P2718R0::A' lvalue
+ // CHECK-NEXT: | `-CXXMemberCallExpr {{.*}} 'A' lvalue
// CHECK-NEXT: | `-MemberExpr {{.*}} '<bound member function type>' .r {{.*}}
// CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'P2718R0::A' xvalue extended by Var {{.*}} '__range1' 'A &&'
// CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'P2718R0::A' (CXXTemporary {{.*}})
@@ -474,17 +474,17 @@ void test14() {
// CHECK-NEXT: | `-VarDecl {{.*}} implicit used __range1 'const int (&)[1]' cinit
// CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'const int[1]' lvalue
// CHECK-NEXT: | `-MemberExpr {{.*}} 'const int[1]' lvalue .arr {{.*}}
- // CHECK-NEXT: | `-MemberExpr {{.*}} 'const A14':'const P2718R0::A14' lvalue .a {{.*}}
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'B14':'P2718R0::B14' xvalue extended by Var {{.*}} '__range1' 'const int (&)[1]'
- // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'B14':'P2718R0::B14' functional cast to B14 <NoOp>
- // CHECK-NEXT: | `-InitListExpr {{.*}} 'B14':'P2718R0::B14'
+ // CHECK-NEXT: | `-MemberExpr {{.*}} 'const A14' lvalue .a {{.*}}
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'B14' xvalue extended by Var {{.*}} '__range1' 'const int (&)[1]'
+ // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'B14' functional cast to B14 <NoOp>
+ // CHECK-NEXT: | `-InitListExpr {{.*}} 'B14'
// CHECK-NEXT: | |-IntegerLiteral {{.*}} 'int' 0
- // CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} 'const A14':'const P2718R0::A14' lvalue has rewritten init
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A14':'const P2718R0::A14' lvalue extended by Var {{.*}} '__range1' 'const int (&)[1]'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A14':'const P2718R0::A14' <NoOp>
- // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'A14':'P2718R0::A14' functional cast to A14 <NoOp>
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A14':'P2718R0::A14' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-InitListExpr {{.*}} 'A14':'P2718R0::A14'
+ // CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} 'const A14' lvalue has rewritten init
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A14' lvalue extended by Var {{.*}} '__range1' 'const int (&)[1]'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A14' <NoOp>
+ // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'A14' functional cast to A14 <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A14' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-InitListExpr {{.*}} 'A14'
// CHECK-NEXT: | `-InitListExpr {{.*}} 'int[1]'
// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 0
for (auto &&x : B14{0}.a.arr) { exit(0); }
@@ -493,17 +493,17 @@ void test14() {
// CHECK-NEXT: |-<<<NULL>>>
// CHECK-NEXT: |-DeclStmt {{.*}}
// CHECK-NEXT: | `-VarDecl {{.*}} col:19 implicit used __range1 'B14 &&' cinit
- // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'B14':'P2718R0::B14' xvalue
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'B14':'P2718R0::B14' xvalue extended by Var {{.*}} '__range1' 'B14 &&'
- // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'B14':'P2718R0::B14' functional cast to B14 <NoOp>
- // CHECK-NEXT: | `-InitListExpr {{.*}} 'B14':'P2718R0::B14'
+ // CHECK-NEXT: | `-ExprWithCleanups {{.*}} 'B14' xvalue
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'B14' xvalue extended by Var {{.*}} '__range1' 'B14 &&'
+ // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'B14' functional cast to B14 <NoOp>
+ // CHECK-NEXT: | `-InitListExpr {{.*}} 'B14'
// CHECK-NEXT: | |-IntegerLiteral {{.*}} 'int' 0
- // CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} 'const A14':'const P2718R0::A14' lvalue has rewritten init
- // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A14':'const P2718R0::A14' lvalue extended by Var {{.*}} '__range1' 'B14 &&'
- // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A14':'const P2718R0::A14' <NoOp>
- // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'A14':'P2718R0::A14' functional cast to A14 <NoOp>
- // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A14':'P2718R0::A14' (CXXTemporary {{.*}})
- // CHECK-NEXT: | `-InitListExpr {{.*}} 'A14':'P2718R0::A14'
+ // CHECK-NEXT: | `-CXXDefaultInitExpr {{.*}} 'const A14' lvalue has rewritten init
+ // CHECK-NEXT: | `-MaterializeTemporaryExpr {{.*}} 'const A14' lvalue extended by Var {{.*}} '__range1' 'B14 &&'
+ // CHECK-NEXT: | `-ImplicitCastExpr {{.*}} 'const A14' <NoOp>
+ // CHECK-NEXT: | `-CXXFunctionalCastExpr {{.*}} 'A14' functional cast to A14 <NoOp>
+ // CHECK-NEXT: | `-CXXBindTemporaryExpr {{.*}} 'A14' (CXXTemporary {{.*}})
+ // CHECK-NEXT: | `-InitListExpr {{.*}} 'A14'
// CHECK-NEXT: | `-InitListExpr {{.*}} 'int[1]'
// CHECK-NEXT: | `-IntegerLiteral {{.*}} 'int' 0
for (auto &&x : B14{0}) { exit(0); }
diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp b/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp
index 1937a5d1c3eb3..9584e77b9e414 100644
--- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp
+++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_reference.cpp
@@ -192,12 +192,12 @@ int test(float &&f, short &&s) {
// CHECK-NEXT: | | `-CompoundStmt [[ADDR_44:0x[a-z0-9]*]] <col:17, line:14:1>
// CHECK-NEXT: | | |-DeclStmt [[ADDR_45:0x[a-z0-9]*]] <line:12:3, col:51>
// CHECK-NEXT: | | | `-TypedefDecl [[ADDR_46:0x[a-z0-9]*]] <col:3, col:48> col:48 referenced _Up 'typename remove_reference<float &>::type':'float'
-// CHECK-NEXT: | | | `-ElaboratedType [[ADDR_47:0x[a-z0-9]*]] 'typename remove_reference<float &>::type' sugar
-// CHECK-NEXT: | | | `-TypedefType [[ADDR_48:0x[a-z0-9]*]] 'remove_reference<float &>::type' sugar
-// CHECK-NEXT: | | | |-Typedef [[ADDR_10]] 'type'
-// CHECK-NEXT: | | | `-SubstTemplateTypeParmType [[ADDR_11]] 'float' sugar class depth 0 index 0 _Tp
-// CHECK-NEXT: | | | |-ClassTemplateSpecialization [[ADDR_6]] 'remove_reference'
-// CHECK-NEXT: | | | `-BuiltinType [[ADDR_8]] 'float'
+// CHECK-NEXT: | | | `-TypedefType [[ADDR_48:0x[a-z0-9]*]] 'typename remove_reference<float &>::type' sugar typename
+// CHECK-NEXT: | | | |-NestedNameSpecifier TypeSpec 'remove_reference<float &>'
+// CHECK-NEXT: | | | |-Typedef [[ADDR_10]] 'type'
+// CHECK-NEXT: | | | `-SubstTemplateTypeParmType [[ADDR_11]] 'float' sugar class depth 0 index 0 _Tp
+// CHECK-NEXT: | | | |-ClassTemplateSpecialization [[ADDR_6]] 'remove_reference'
+// CHECK-NEXT: | | | `-BuiltinType [[ADDR_8]] 'float'
// CHECK-NEXT: | | `-ReturnStmt [[ADDR_49:0x[a-z0-9]*]] <line:13:3, col:33>
// CHECK-NEXT: | | `-CXXStaticCastExpr [[ADDR_50:0x[a-z0-9]*]] <col:10, col:33> '_Up':'float' xvalue static_cast<_Up &&> <NoOp>
// CHECK-NEXT: | | `-DeclRefExpr [[ADDR_51:0x[a-z0-9]*]] <col:30> 'float' {{.*}}ParmVar [[ADDR_43]] '__t' 'float &'
@@ -209,12 +209,12 @@ int test(float &&f, short &&s) {
// CHECK-NEXT: | `-CompoundStmt [[ADDR_54:0x[a-z0-9]*]] <col:17, line:14:1>
// CHECK-NEXT: | |-DeclStmt [[ADDR_55:0x[a-z0-9]*]] <line:12:3, col:51>
// CHECK-NEXT: | | `-TypedefDecl [[ADDR_56:0x[a-z0-9]*]] <col:3, col:48> col:48 referenced _Up 'typename remove_reference<short &>::type':'short'
-// CHECK-NEXT: | | `-ElaboratedType [[ADDR_57:0x[a-z0-9]*]] 'typename remove_reference<short &>::type' sugar
-// CHECK-NEXT: | | `-TypedefType [[ADDR_58:0x[a-z0-9]*]] 'remove_reference<short &>::type' sugar
-// CHECK-NEXT: | | |-Typedef [[ADDR_18]] 'type'
-// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_19]] 'short' sugar class depth 0 index 0 _Tp
-// CHECK-NEXT: | | |-ClassTemplateSpecialization [[ADDR_14]] 'remove_reference'
-// CHECK-NEXT: | | `-BuiltinType [[ADDR_16]] 'short'
+// CHECK-NEXT: | | `-TypedefType [[ADDR_58:0x[a-z0-9]*]] 'typename remove_reference<short &>::type' sugar typename
+// CHECK-NEXT: | | |-NestedNameSpecifier TypeSpec 'remove_reference<short &>'
+// CHECK-NEXT: | | |-Typedef [[ADDR_18]] 'type'
+// CHECK-NEXT: | | `-SubstTemplateTypeParmType [[ADDR_19]] 'short' sugar class depth 0 index 0 _Tp
+// CHECK-NEXT: | | |-ClassTemplateSpecialization [[ADDR_14]] 'remove_reference'
+// CHECK-NEXT: | | `-BuiltinType [[ADDR_16]] 'short'
// CHECK-NEXT: | `-ReturnStmt [[ADDR_59:0x[a-z0-9]*]] <line:13:3, col:33>
// CHECK-NEXT: | `-CXXStaticCastExpr [[ADDR_60:0x[a-z0-9]*]] <col:10, col:33> '_Up':'short' xvalue static_cast<_Up &&> <NoOp>
// CHECK-NEXT: | `-DeclRefExpr [[ADDR_61:0x[a-z0-9]*]] <col:30> 'short' {{.*}}ParmVar [[ADDR_53]] '__t' 'short &'
diff --git a/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp b/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
index ad269506042c8..44d1cb462cd58 100644
--- a/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
+++ b/clang/test/AST/ast-dump-openmp-begin-declare-variant_template_3.cpp
@@ -54,7 +54,7 @@ int test() {
// CHECK-NEXT: | | | |-CopyAssignment simple trivial has_const_param needs_implicit implicit_has_const_param
// CHECK-NEXT: | | | |-MoveAssignment exists simple trivial needs_implicit
// CHECK-NEXT: | | | `-Destructor simple irrelevant trivial {{(constexpr )?}}needs_implicit
-// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_3:0x[a-z0-9]*]] <col:23, col:30> col:30 implicit referenced struct S
+// CHECK-NEXT: | | |-CXXRecordDecl [[ADDR_3:0x[a-z0-9]*]] <col:23, col:30> col:30 implicit struct S
// CHECK-NEXT: | | `-CXXConstructorDecl [[ADDR_4:0x[a-z0-9]*]] <line:6:3, col:16> col:3 S<T> 'void (int, T *)'
// CHECK-NEXT: | | |-ParmVarDecl [[ADDR_5:0x[a-z0-9]*]] <col:5> col:8 'int'
// CHECK-NEXT: | | |-ParmVarDecl [[ADDR_6:0x[a-z0-9]*]] <col:10, col:12> col:13 'T *'
diff --git a/clang/test/AST/ast-dump-record-definition-data-json.cpp b/clang/test/AST/ast-dump-record-definition-data-json.cpp
index c119089def716..e35bec78c6847 100644
--- a/clang/test/AST/ast-dump-record-definition-data-json.cpp
+++ b/clang/test/AST/ast-dump-record-definition-data-json.cpp
@@ -2516,7 +2516,6 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
-// CHECK-NEXT: "isReferenced": true,
// CHECK-NEXT: "name": "IsTrivial",
// CHECK-NEXT: "tagUsed": "struct"
// CHECK-NEXT: },
@@ -2646,7 +2645,6 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
-// CHECK-NEXT: "isReferenced": true,
// CHECK-NEXT: "name": "IsNotTrivial",
// CHECK-NEXT: "tagUsed": "struct"
// CHECK-NEXT: },
@@ -3980,7 +3978,6 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
-// CHECK-NEXT: "isReferenced": true,
// CHECK-NEXT: "name": "HasUserDeclaredConstructor",
// CHECK-NEXT: "tagUsed": "struct"
// CHECK-NEXT: },
@@ -4234,7 +4231,6 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
-// CHECK-NEXT: "isReferenced": true,
// CHECK-NEXT: "name": "HasConstexprNonCopyMoveConstructor",
// CHECK-NEXT: "tagUsed": "struct"
// CHECK-NEXT: },
@@ -4381,7 +4377,6 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: }
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
-// CHECK-NEXT: "isReferenced": true,
// CHECK-NEXT: "name": "HasNoConstexprNonCopyMoveConstructor",
// CHECK-NEXT: "tagUsed": "struct"
// CHECK-NEXT: },
diff --git a/clang/test/AST/ast-dump-records-json.cpp b/clang/test/AST/ast-dump-records-json.cpp
index 7efdcb0b61318..941c6a675448a 100644
--- a/clang/test/AST/ast-dump-records-json.cpp
+++ b/clang/test/AST/ast-dump-records-json.cpp
@@ -795,7 +795,6 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: },
// CHECK-NEXT: "name": "b",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "C::(unnamed struct at {{.*}}:16:3)",
// CHECK-NEXT: "qualType": "struct (unnamed struct at {{.*}}:16:3)"
// CHECK-NEXT: }
// CHECK-NEXT: },
@@ -2072,7 +2071,6 @@ struct Derived6 : virtual public Bases... {
// CHECK-NEXT: },
// CHECK-NEXT: "name": "b",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "G::(unnamed struct at {{.*}}:50:3)",
// CHECK-NEXT: "qualType": "struct (unnamed struct at {{.*}}:50:3)"
// CHECK-NEXT: }
// CHECK-NEXT: },
diff --git a/clang/test/AST/ast-dump-records.c b/clang/test/AST/ast-dump-records.c
index f4a540f3fa872..1dc175c4a8560 100644
--- a/clang/test/AST/ast-dump-records.c
+++ b/clang/test/AST/ast-dump-records.c
@@ -47,7 +47,7 @@ struct C {
int a;
// CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int'
} b;
- // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-5]]:3)':'struct C::(unnamed at {{.*}}:[[@LINE-5]]:3)'
+ // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-5]]:3)'
union {
// CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+5]]:3> line:[[@LINE-1]]:3 union definition
@@ -122,15 +122,13 @@ union E {
};
union G {
- // CHECK: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+38]]:1> line:[[@LINE-1]]:7 union G definition
+ // CHECK: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+36]]:1> line:[[@LINE-1]]:7 union G definition
struct {
// CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+3]]:3> line:[[@LINE-1]]:3 struct definition
int a;
// CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int'
} b;
- // FIXME: note that it talks about 'struct G' below; the same happens in
- // other cases with union G as well.
- // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-7]]:3, line:[[@LINE-3]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-7]]:3)':'struct G::(unnamed at {{.*}}:[[@LINE-7]]:3)'
+ // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-5]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-5]]:3)'
union {
// CHECK-NEXT: RecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+5]]:3> line:[[@LINE-1]]:3 union definition
diff --git a/clang/test/AST/ast-dump-records.cpp b/clang/test/AST/ast-dump-records.cpp
index e9b37b73002dd..edd13ba1c6f12 100644
--- a/clang/test/AST/ast-dump-records.cpp
+++ b/clang/test/AST/ast-dump-records.cpp
@@ -72,7 +72,7 @@ struct C {
int a;
// CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int'
} b;
- // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-12]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-12]]:3)':'C::(unnamed struct at {{.*}}:[[@LINE-12]]:3)'
+ // CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-12]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-12]]:3)'
union {
// CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+12]]:3> line:[[@LINE-1]]:3 union definition
@@ -179,7 +179,7 @@ union E {
};
union G {
- // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+71]]:1> line:[[@LINE-1]]:7 union G definition
+ // CHECK: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, line:[[@LINE+69]]:1> line:[[@LINE-1]]:7 union G definition
// CHECK-NEXT: DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
// CHECK-NEXT: DefaultConstructor exists trivial needs_implicit
// CHECK-NEXT: CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
@@ -202,9 +202,7 @@ union G {
int a;
// CHECK-NEXT: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:5, col:9> col:9 a 'int'
} b;
- // FIXME: note that it talks about 'struct G' below; the same happens in
- // other cases with union G as well.
- // CHECK: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-15]]:3, line:[[@LINE-3]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-15]]:3)':'G::(unnamed struct at {{.*}}:[[@LINE-15]]:3)'
+ // CHECK: FieldDecl 0x{{[^ ]*}} <line:[[@LINE-13]]:3, line:[[@LINE-1]]:5> col:5 b 'struct (unnamed struct at {{.*}}:[[@LINE-13]]:3)'
union {
// CHECK-NEXT: CXXRecordDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:3, line:[[@LINE+13]]:3> line:[[@LINE-1]]:3 union definition
diff --git a/clang/test/AST/ast-dump-recovery.cpp b/clang/test/AST/ast-dump-recovery.cpp
index a8e30f1759e9f..060ae3b62b6f8 100644
--- a/clang/test/AST/ast-dump-recovery.cpp
+++ b/clang/test/AST/ast-dump-recovery.cpp
@@ -128,7 +128,7 @@ void test2(Foo2 f) {
// CHECK-NEXT: | `-DeclRefExpr {{.*}} 'f'
// CHECK-NEXT: `-IntegerLiteral {{.*}} 'int' 1
f.func(1);
- // CHECK: RecoveryExpr {{.*}} 'ForwardClass':'Foo2::ForwardClass'
+ // CHECK: RecoveryExpr {{.*}} 'ForwardClass'
// CHECK-NEXT: `-MemberExpr {{.*}} '<bound member function type>' .createFwd
// CHECK-NEXT: `-DeclRefExpr {{.*}} 'f'
f.createFwd();
@@ -292,8 +292,8 @@ union U {
// CHECK: FunctionDecl {{.*}} foo 'void ()'
// CHECK-NEXT: `-CompoundStmt {{.*}}
// CHECK-NEXT: `-DeclStmt {{.*}}
-// CHECK-NEXT: `-VarDecl {{.*}} g 'U':'GH112560::U' listinit
-// CHECK-NEXT: `-InitListExpr {{.*}} 'U':'GH112560::U' contains-errors field Field {{.*}} 'f' 'int'
+// CHECK-NEXT: `-VarDecl {{.*}} g 'U' listinit
+// CHECK-NEXT: `-InitListExpr {{.*}} 'U' contains-errors field Field {{.*}} 'f' 'int'
// CHECK-NEXT: `-CXXDefaultInitExpr {{.*}} 'int' contains-errors has rewritten init
// CHECK-NEXT: `-RecoveryExpr {{.*}} 'int' contains-errors
// DISABLED-NOT: -RecoveryExpr {{.*}} contains-errors
diff --git a/clang/test/AST/ast-dump-stmt-json.cpp b/clang/test/AST/ast-dump-stmt-json.cpp
index a473d17da9424..caa22ecab7200 100644
--- a/clang/test/AST/ast-dump-stmt-json.cpp
+++ b/clang/test/AST/ast-dump-stmt-json.cpp
@@ -224,7 +224,55 @@ void TestDependentGenericSelectionExpr(Ty T) {
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "void ()"
// CHECK-NEXT: }
-// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "FunctionDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 125,
+// CHECK-NEXT: "line": 4,
+// CHECK-NEXT: "col": 6,
+// CHECK-NEXT: "tokLen": 8
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 120,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 137,
+// CHECK-NEXT: "col": 18,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "isUsed": true,
+// CHECK-NEXT: "name": "function",
+// CHECK-NEXT: "mangledName": "_ZN1n8functionEv",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "void ()"
+// CHECK-NEXT: },
+// CHECK-NEXT: "inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CompoundStmt",
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 136,
+// CHECK-NEXT: "col": 17,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 137,
+// CHECK-NEXT: "col": 18,
+// CHECK-NEXT: "tokLen": 1
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
// CHECK-NEXT: }
@@ -279,7 +327,37 @@ void TestDependentGenericSelectionExpr(Ty T) {
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "int"
// CHECK-NEXT: }
-// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "VarDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 143,
+// CHECK-NEXT: "line": 5,
+// CHECK-NEXT: "col": 5,
+// CHECK-NEXT: "tokLen": 8
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 139,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 3
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 143,
+// CHECK-NEXT: "col": 5,
+// CHECK-NEXT: "tokLen": 8
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "isUsed": true,
+// CHECK-NEXT: "name": "Variable",
+// CHECK-NEXT: "mangledName": "_ZN1n8VariableE",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
// CHECK-NEXT: }
@@ -1863,6 +1941,7 @@ void TestDependentGenericSelectionExpr(Ty T) {
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "FunctionDecl",
// CHECK-NEXT: "loc": {},
@@ -1929,6 +2008,7 @@ void TestDependentGenericSelectionExpr(Ty T) {
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "FunctionDecl",
// CHECK-NEXT: "loc": {},
@@ -2078,6 +2158,7 @@ void TestDependentGenericSelectionExpr(Ty T) {
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "FunctionDecl",
// CHECK-NEXT: "loc": {},
@@ -2144,6 +2225,7 @@ void TestDependentGenericSelectionExpr(Ty T) {
// CHECK-NEXT: ]
// CHECK-NEXT: }
+
// CHECK-NOT: {{^}}Dumping
// CHECK: "kind": "FunctionTemplateDecl",
// CHECK-NEXT: "loc": {
diff --git a/clang/test/AST/ast-dump-stmt.m b/clang/test/AST/ast-dump-stmt.m
index e0fc16b3fa825..b68f5b6bd1d3f 100644
--- a/clang/test/AST/ast-dump-stmt.m
+++ b/clang/test/AST/ast-dump-stmt.m
@@ -55,4 +55,4 @@ id TestCompoundLiteral(id a) {
// CHECK: FunctionDecl{{.*}}TestCompoundLiteral
// CHECK: ExprWithCleanups
// CHECK-NEXT: cleanup CompoundLiteralExpr
-// CHECK: CompoundLiteralExpr{{.*}}'S' lvalue
+ // CHECK: CompoundLiteralExpr{{.*}}'S':'struct S' lvalue
diff --git a/clang/test/AST/ast-dump-template-decls.cpp b/clang/test/AST/ast-dump-template-decls.cpp
index d5228d4667304..ba3e405eb18aa 100644
--- a/clang/test/AST/ast-dump-template-decls.cpp
+++ b/clang/test/AST/ast-dump-template-decls.cpp
@@ -115,8 +115,7 @@ template <class T> struct C {
};
using type2 = typename C<int>::type1<void>;
// CHECK: TypeAliasDecl 0x{{[^ ]*}} <line:[[@LINE-1]]:1, col:42> col:7 type2 'typename C<int>::type1<void>':'void (int)'
-// CHECK-NEXT: ElaboratedType 0x{{[^ ]*}} 'typename C<int>::type1<void>' sugar
-// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'type1<void>' sugar alias
+// CHECK-NEXT: TemplateSpecializationType 0x{{[^ ]*}} 'typename C<int>::type1<void>' sugar alias
// CHECK-NEXT: name: 'C<int>::type1':'PR55886::C<int>::type1' qualified
// CHECK-NEXT: NestedNameSpecifier TypeSpec 'C<int>':'PR55886::C<int>'
// CHECK-NEXT: TypeAliasTemplateDecl {{.+}} type1
diff --git a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
index cc9a82cb7bfff..3e0877f131e94 100644
--- a/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
+++ b/clang/test/AST/ast-dump-template-json-win32-mangler-crash.cpp
@@ -537,28 +537,17 @@ int main()
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ElaboratedType",
+// CHECK-NEXT: "kind": "InjectedClassNameType",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "integral_constant<_Ty, _Val>"
// CHECK-NEXT: },
// CHECK-NEXT: "isDependent": true,
// CHECK-NEXT: "isInstantiationDependent": true,
-// CHECK-NEXT: "inner": [
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "InjectedClassNameType",
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "integral_constant<_Ty, _Val>"
-// CHECK-NEXT: },
-// CHECK-NEXT: "isDependent": true,
-// CHECK-NEXT: "isInstantiationDependent": true,
-// CHECK-NEXT: "decl": {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CXXRecordDecl",
-// CHECK-NEXT: "name": "integral_constant"
-// CHECK-NEXT: }
-// CHECK-NEXT: }
-// CHECK-NEXT: ]
+// CHECK-NEXT: "decl": {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "name": "integral_constant"
+// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: },
@@ -885,71 +874,60 @@ int main()
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ElaboratedType",
+// CHECK-NEXT: "kind": "TemplateSpecializationType",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "integral_constant<bool, _Val>"
// CHECK-NEXT: },
// CHECK-NEXT: "isDependent": true,
// CHECK-NEXT: "isInstantiationDependent": true,
+// CHECK-NEXT: "templateName": "integral_constant",
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "TemplateSpecializationType",
+// CHECK-NEXT: "kind": "TemplateArgument",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "integral_constant<bool, _Val>"
+// CHECK-NEXT: "qualType": "bool"
// CHECK-NEXT: },
-// CHECK-NEXT: "isDependent": true,
-// CHECK-NEXT: "isInstantiationDependent": true,
-// CHECK-NEXT: "templateName": "integral_constant",
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
-// CHECK-NEXT: "kind": "TemplateArgument",
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "BuiltinType",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "bool"
-// CHECK-NEXT: },
-// CHECK-NEXT: "inner": [
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "BuiltinType",
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "bool"
-// CHECK-NEXT: }
-// CHECK-NEXT: }
-// CHECK-NEXT: ]
-// CHECK-NEXT: },
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
+// CHECK-NEXT: },
+// CHECK-NEXT: {
+// CHECK-NEXT: "kind": "TemplateArgument",
+// CHECK-NEXT: "isExpr": true,
+// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
-// CHECK-NEXT: "kind": "TemplateArgument",
-// CHECK-NEXT: "isExpr": true,
-// CHECK-NEXT: "inner": [
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "DeclRefExpr",
-// CHECK-NEXT: "range": {
-// CHECK-NEXT: "begin": {
-// CHECK-NEXT: "offset": 554,
-// CHECK-NEXT: "col": 47,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: },
-// CHECK-NEXT: "end": {
-// CHECK-NEXT: "offset": 554,
-// CHECK-NEXT: "col": 47,
-// CHECK-NEXT: "tokLen": 4
-// CHECK-NEXT: }
-// CHECK-NEXT: },
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "bool"
-// CHECK-NEXT: },
-// CHECK-NEXT: "valueCategory": "prvalue",
-// CHECK-NEXT: "referencedDecl": {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "NonTypeTemplateParmDecl",
-// CHECK-NEXT: "name": "_Val",
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "bool"
-// CHECK-NEXT: }
-// CHECK-NEXT: }
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "DeclRefExpr",
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 554,
+// CHECK-NEXT: "col": 47,
+// CHECK-NEXT: "tokLen": 4
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 554,
+// CHECK-NEXT: "col": 47,
+// CHECK-NEXT: "tokLen": 4
// CHECK-NEXT: }
-// CHECK-NEXT: ]
+// CHECK-NEXT: },
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "bool"
+// CHECK-NEXT: },
+// CHECK-NEXT: "valueCategory": "prvalue",
+// CHECK-NEXT: "referencedDecl": {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "NonTypeTemplateParmDecl",
+// CHECK-NEXT: "name": "_Val",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "bool"
+// CHECK-NEXT: }
+// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
diff --git a/clang/test/AST/ast-dump-template-name.cpp b/clang/test/AST/ast-dump-template-name.cpp
index acacdac857954..7f085086ab6a3 100644
--- a/clang/test/AST/ast-dump-template-name.cpp
+++ b/clang/test/AST/ast-dump-template-name.cpp
@@ -11,13 +11,12 @@ namespace qualified {
// CHECK: Dumping qualified::TestQualified:
// CHECK-NEXT: TypeAliasDecl
-// CHECK-NEXT: `-ElaboratedType
-// CHECK-NEXT: `-TemplateSpecializationType
-// CHECK-NEXT: |-name: 'N' qualified
-// CHECK-NEXT: | `-TypeAliasTemplateDecl {{.+}} N{{$}}
-// CHECK-NEXT: |-TemplateArgument template 'foo::A':'qualified::foo::A' qualified{{$}}
-// CHECK-NEXT: | |-NestedNameSpecifier Namespace 0x{{.+}} 'foo'{{$}}
-// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
+// CHECK-NEXT: `-TemplateSpecializationType
+// CHECK-NEXT: |-name: 'N' qualified
+// CHECK-NEXT: | `-TypeAliasTemplateDecl {{.+}} N{{$}}
+// CHECK-NEXT: |-TemplateArgument template 'foo::A':'qualified::foo::A' qualified{{$}}
+// CHECK-NEXT: | |-NestedNameSpecifier Namespace 0x{{.+}} 'foo'{{$}}
+// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
namespace dependent {
template <class T> struct B {
@@ -27,12 +26,11 @@ namespace dependent {
// CHECK: Dumping dependent::B::TestDependent:
// CHECK-NEXT: TypeAliasDecl
-// CHECK-NEXT: `-ElaboratedType
-// CHECK-NEXT: `-TemplateSpecializationType
-// CHECK-NEXT: |-name: 'N' qualified
-// CHECK-NEXT: | `-TypeAliasTemplateDecl
-// CHECK-NEXT: |-TemplateArgument template 'T::template X':'type-parameter-0-0::template X' dependent{{$}}
-// CHECK-NEXT: | `-NestedNameSpecifier TypeSpec 'T'{{$}}
+// CHECK-NEXT: `-TemplateSpecializationType
+// CHECK-NEXT: |-name: 'N' qualified
+// CHECK-NEXT: | `-TypeAliasTemplateDecl
+// CHECK-NEXT: |-TemplateArgument template 'T::template X':'type-parameter-0-0::template X' dependent{{$}}
+// CHECK-NEXT: | `-NestedNameSpecifier TypeSpec 'T'{{$}}
namespace subst {
template <class> struct A;
@@ -46,15 +44,14 @@ namespace subst {
// CHECK: Dumping subst::TestSubst:
// CHECK-NEXT: TypeAliasDecl
-// CHECK-NEXT: `-ElaboratedType
-// CHECK-NEXT: `-TypedefType
-// CHECK-NEXT: |-TypeAlias
-// CHECK-NEXT: `-ElaboratedType
-// CHECK-NEXT: `-TemplateSpecializationType
-// CHECK-NEXT: |-name: 'C':'subst::B<subst::A>::C' qualified
-// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} C
-// CHECK-NEXT: |-TemplateArgument template 'subst::A' subst index 0
-// CHECK-NEXT: | |-parameter: TemplateTemplateParmDecl {{.+}} depth 0 index 0 TT{{$}}
-// CHECK-NEXT: | |-associated ClassTemplateSpecialization {{.+}} 'B'{{$}}
-// CHECK-NEXT: | `-replacement:
-// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
+// CHECK-NEXT: `-TypedefType
+// CHECK-NEXT: |-NestedNameSpecifier TypeSpec 'B<A>':'subst::B<subst::A>'
+// CHECK-NEXT: |-TypeAlias
+// CHECK-NEXT: `-TemplateSpecializationType
+// CHECK-NEXT: |-name: 'C':'subst::B<subst::A>::C' qualified
+// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} C
+// CHECK-NEXT: |-TemplateArgument template 'subst::A' subst index 0
+// CHECK-NEXT: | |-parameter: TemplateTemplateParmDecl {{.+}} depth 0 index 0 TT{{$}}
+// CHECK-NEXT: | |-associated ClassTemplateSpecialization {{.+}} 'B'{{$}}
+// CHECK-NEXT: | `-replacement:
+// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
diff --git a/clang/test/AST/ast-dump-templates.cpp b/clang/test/AST/ast-dump-templates.cpp
index b504accb927dc..d7c482d80ddc1 100644
--- a/clang/test/AST/ast-dump-templates.cpp
+++ b/clang/test/AST/ast-dump-templates.cpp
@@ -171,10 +171,11 @@ namespace TestDependentMemberPointer {
// DUMP-NEXT: | `-BuiltinType {{.+}} 'int'
// DUMP-NEXT: |-TypeAliasDecl {{.+}} Y 'int U::test::*'{{$}}
// DUMP-NEXT: | `-MemberPointerType {{.+}} 'int U::test::*' dependent
+// DUMP-NEXT: | |-DependentNameType {{.+}} 'U::test' dependent
// DUMP-NEXT: | `-BuiltinType {{.+}} 'int'
// DUMP-NEXT: `-TypeAliasDecl {{.+}} Z 'int U::template V<int>::*'{{$}}
// DUMP-NEXT: `-MemberPointerType {{.+}} 'int U::template V<int>::*' dependent
-// DUMP-NEXT: |-DependentTemplateSpecializationType {{.+}} 'template V<int>' dependent
+// DUMP-NEXT: |-DependentTemplateSpecializationType {{.+}} 'U::template V<int>' dependent
// DUMP-NEXT: `-BuiltinType {{.+}} 'int'
} // namespace TestDependentMemberPointer
@@ -186,8 +187,8 @@ namespace TestPartialSpecNTTP {
template <class U1, bool U2, bool U3>
struct Template2<Template1<U1, U2>, U3> {};
// DUMP: ClassTemplatePartialSpecializationDecl {{.+}} struct Template2
-// DUMP: |-TemplateArgument type 'Template1<type-parameter-0-0, value-parameter-0-1>'
-// DUMP-NEXT: | `-TemplateSpecializationType {{.+}} 'Template1<type-parameter-0-0, value-parameter-0-1>' dependent
+// DUMP: |-TemplateArgument type 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>'
+// DUMP-NEXT: | `-TemplateSpecializationType {{.+}} 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>' dependent
// DUMP-NEXT: | |-name: 'TestPartialSpecNTTP::Template1'
// DUMP-NEXT: | | `-ClassTemplateDecl {{.+}} Template1
// DUMP-NEXT: | |-TemplateArgument type 'type-parameter-0-0'
@@ -204,8 +205,8 @@ namespace TestPartialSpecNTTP {
template <typename U1, bool U3, bool U2>
struct Template2<Template1<U1, U2>, U3> {};
// DUMP: ClassTemplatePartialSpecializationDecl {{.+}} struct Template2 definition explicit_specialization
-// DUMP: |-TemplateArgument type 'Template1<type-parameter-0-0, value-parameter-0-2>'
-// DUMP-NEXT: | `-TemplateSpecializationType {{.+}} 'Template1<type-parameter-0-0, value-parameter-0-2>' dependent
+// DUMP: |-TemplateArgument type 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>'
+// DUMP-NEXT: | `-TemplateSpecializationType {{.+}} 'TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>' dependent
// DUMP-NEXT: | |-name: 'TestPartialSpecNTTP::Template1'
// DUMP-NEXT: | | `-ClassTemplateDecl {{.+}} Template1
// DUMP-NEXT: | |-TemplateArgument type 'type-parameter-0-0'
@@ -621,7 +622,6 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: "isImplicit": true,
-// JSON-NEXT: "isReferenced": true,
// JSON-NEXT: "name": "foo",
// JSON-NEXT: "tagUsed": "struct"
// JSON-NEXT: },
@@ -4109,7 +4109,7 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "isImplicit": true,
// JSON-NEXT: "name": "<deduction guide for A>",
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "auto () -> A<T>"
+// JSON-NEXT: "qualType": "auto () -> test3::A<T>"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: ]
@@ -4185,7 +4185,7 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "isImplicit": true,
// JSON-NEXT: "name": "<deduction guide for A>",
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "auto (A<T>) -> A<T>"
+// JSON-NEXT: "qualType": "auto (test3::A<T>) -> test3::A<T>"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
@@ -4209,7 +4209,7 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: }
// JSON-NEXT: },
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "A<T>"
+// JSON-NEXT: "qualType": "test3::A<T>"
// JSON-NEXT: }
// JSON-NEXT: }
// JSON-NEXT: ]
@@ -6630,8 +6630,8 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6356,
-// JSON-NEXT: "line": 179,
+// JSON-NEXT: "offset": 6425,
+// JSON-NEXT: "line": 180,
// JSON-NEXT: "col": 1,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -6889,6 +6889,15 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "DependentNameType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "U::test"
+// JSON-NEXT: },
+// JSON-NEXT: "isDependent": true,
+// JSON-NEXT: "isInstantiationDependent": true
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "BuiltinType",
// JSON-NEXT: "type": {
// JSON-NEXT: "qualType": "int"
@@ -6938,7 +6947,7 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "DependentTemplateSpecializationType",
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "template V<int>"
+// JSON-NEXT: "qualType": "U::template V<int>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true
@@ -6964,20 +6973,20 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "NamespaceDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6409,
-// JSON-NEXT: "line": 181,
+// JSON-NEXT: "offset": 6478,
+// JSON-NEXT: "line": 182,
// JSON-NEXT: "col": 11,
// JSON-NEXT: "tokLen": 19
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6399,
+// JSON-NEXT: "offset": 6468,
// JSON-NEXT: "col": 1,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 9184,
-// JSON-NEXT: "line": 221,
+// JSON-NEXT: "offset": 9337,
+// JSON-NEXT: "line": 222,
// JSON-NEXT: "col": 1,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -6988,19 +6997,19 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "ClassTemplateDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6532,
-// JSON-NEXT: "line": 183,
+// JSON-NEXT: "offset": 6601,
+// JSON-NEXT: "line": 184,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6494,
+// JSON-NEXT: "offset": 6563,
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": 8
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6543,
+// JSON-NEXT: "offset": 6612,
// JSON-NEXT: "col": 52,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -7011,18 +7020,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6510,
+// JSON-NEXT: "offset": 6579,
// JSON-NEXT: "col": 19,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6504,
+// JSON-NEXT: "offset": 6573,
// JSON-NEXT: "col": 13,
// JSON-NEXT: "tokLen": 5
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6510,
+// JSON-NEXT: "offset": 6579,
// JSON-NEXT: "col": 19,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: }
@@ -7036,18 +7045,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6520,
+// JSON-NEXT: "offset": 6589,
// JSON-NEXT: "col": 29,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6515,
+// JSON-NEXT: "offset": 6584,
// JSON-NEXT: "col": 24,
// JSON-NEXT: "tokLen": 4
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6520,
+// JSON-NEXT: "offset": 6589,
// JSON-NEXT: "col": 29,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: }
@@ -7063,18 +7072,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6532,
+// JSON-NEXT: "offset": 6601,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6525,
+// JSON-NEXT: "offset": 6594,
// JSON-NEXT: "col": 34,
// JSON-NEXT: "tokLen": 6
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6543,
+// JSON-NEXT: "offset": 6612,
// JSON-NEXT: "col": 52,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -7137,18 +7146,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6532,
+// JSON-NEXT: "offset": 6601,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6525,
+// JSON-NEXT: "offset": 6594,
// JSON-NEXT: "col": 34,
// JSON-NEXT: "tokLen": 6
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6532,
+// JSON-NEXT: "offset": 6601,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: }
@@ -7165,19 +7174,19 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "ClassTemplateDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6586,
-// JSON-NEXT: "line": 184,
+// JSON-NEXT: "offset": 6655,
+// JSON-NEXT: "line": 185,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6548,
+// JSON-NEXT: "offset": 6617,
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": 8
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6597,
+// JSON-NEXT: "offset": 6666,
// JSON-NEXT: "col": 52,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -7188,18 +7197,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6564,
+// JSON-NEXT: "offset": 6633,
// JSON-NEXT: "col": 19,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6558,
+// JSON-NEXT: "offset": 6627,
// JSON-NEXT: "col": 13,
// JSON-NEXT: "tokLen": 5
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6564,
+// JSON-NEXT: "offset": 6633,
// JSON-NEXT: "col": 19,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: }
@@ -7213,18 +7222,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6574,
+// JSON-NEXT: "offset": 6643,
// JSON-NEXT: "col": 29,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6569,
+// JSON-NEXT: "offset": 6638,
// JSON-NEXT: "col": 24,
// JSON-NEXT: "tokLen": 4
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6574,
+// JSON-NEXT: "offset": 6643,
// JSON-NEXT: "col": 29,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: }
@@ -7240,18 +7249,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6586,
+// JSON-NEXT: "offset": 6655,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6579,
+// JSON-NEXT: "offset": 6648,
// JSON-NEXT: "col": 34,
// JSON-NEXT: "tokLen": 6
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6597,
+// JSON-NEXT: "offset": 6666,
// JSON-NEXT: "col": 52,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -7314,18 +7323,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6586,
+// JSON-NEXT: "offset": 6655,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6579,
+// JSON-NEXT: "offset": 6648,
// JSON-NEXT: "col": 34,
// JSON-NEXT: "tokLen": 6
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6586,
+// JSON-NEXT: "offset": 6655,
// JSON-NEXT: "col": 41,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: }
@@ -7342,21 +7351,21 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "ClassTemplatePartialSpecializationDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6650,
-// JSON-NEXT: "line": 187,
+// JSON-NEXT: "offset": 6719,
+// JSON-NEXT: "line": 188,
// JSON-NEXT: "col": 10,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6603,
-// JSON-NEXT: "line": 186,
+// JSON-NEXT: "offset": 6672,
+// JSON-NEXT: "line": 187,
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": 8
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6684,
-// JSON-NEXT: "line": 187,
+// JSON-NEXT: "offset": 6753,
+// JSON-NEXT: "line": 188,
// JSON-NEXT: "col": 44,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -7418,14 +7427,14 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "Template1<type-parameter-0-0, value-parameter-0-1>"
+// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "TemplateSpecializationType",
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "Template1<type-parameter-0-0, value-parameter-0-1>"
+// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-1>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
@@ -7463,13 +7472,13 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6520,
-// JSON-NEXT: "line": 183,
+// JSON-NEXT: "offset": 6589,
+// JSON-NEXT: "line": 184,
// JSON-NEXT: "col": 29,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6520,
+// JSON-NEXT: "offset": 6589,
// JSON-NEXT: "col": 29,
// JSON-NEXT: "tokLen": 3
// JSON-NEXT: }
@@ -7503,13 +7512,13 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6679,
-// JSON-NEXT: "line": 187,
+// JSON-NEXT: "offset": 6748,
+// JSON-NEXT: "line": 188,
// JSON-NEXT: "col": 39,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6679,
+// JSON-NEXT: "offset": 6748,
// JSON-NEXT: "col": 39,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7533,19 +7542,19 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6619,
-// JSON-NEXT: "line": 186,
+// JSON-NEXT: "offset": 6688,
+// JSON-NEXT: "line": 187,
// JSON-NEXT: "col": 19,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6613,
+// JSON-NEXT: "offset": 6682,
// JSON-NEXT: "col": 13,
// JSON-NEXT: "tokLen": 5
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6619,
+// JSON-NEXT: "offset": 6688,
// JSON-NEXT: "col": 19,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7560,18 +7569,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6628,
+// JSON-NEXT: "offset": 6697,
// JSON-NEXT: "col": 28,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6623,
+// JSON-NEXT: "offset": 6692,
// JSON-NEXT: "col": 23,
// JSON-NEXT: "tokLen": 4
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6628,
+// JSON-NEXT: "offset": 6697,
// JSON-NEXT: "col": 28,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7588,18 +7597,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6637,
+// JSON-NEXT: "offset": 6706,
// JSON-NEXT: "col": 37,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6632,
+// JSON-NEXT: "offset": 6701,
// JSON-NEXT: "col": 32,
// JSON-NEXT: "tokLen": 4
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6637,
+// JSON-NEXT: "offset": 6706,
// JSON-NEXT: "col": 37,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7616,19 +7625,19 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 6650,
-// JSON-NEXT: "line": 187,
+// JSON-NEXT: "offset": 6719,
+// JSON-NEXT: "line": 188,
// JSON-NEXT: "col": 10,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 6643,
+// JSON-NEXT: "offset": 6712,
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": 6
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 6650,
+// JSON-NEXT: "offset": 6719,
// JSON-NEXT: "col": 10,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: }
@@ -7643,21 +7652,21 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "ClassTemplatePartialSpecializationDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 7925,
-// JSON-NEXT: "line": 205,
+// JSON-NEXT: "offset": 8036,
+// JSON-NEXT: "line": 206,
// JSON-NEXT: "col": 10,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 7875,
-// JSON-NEXT: "line": 204,
+// JSON-NEXT: "offset": 7986,
+// JSON-NEXT: "line": 205,
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": 8
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 7959,
-// JSON-NEXT: "line": 205,
+// JSON-NEXT: "offset": 8070,
+// JSON-NEXT: "line": 206,
// JSON-NEXT: "col": 44,
// JSON-NEXT: "tokLen": 1
// JSON-NEXT: }
@@ -7719,14 +7728,14 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: {
// JSON-NEXT: "kind": "TemplateArgument",
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "Template1<type-parameter-0-0, value-parameter-0-2>"
+// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>"
// JSON-NEXT: },
// JSON-NEXT: "inner": [
// JSON-NEXT: {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "TemplateSpecializationType",
// JSON-NEXT: "type": {
-// JSON-NEXT: "qualType": "Template1<type-parameter-0-0, value-parameter-0-2>"
+// JSON-NEXT: "qualType": "TestPartialSpecNTTP::Template1<type-parameter-0-0, value-parameter-0-2>"
// JSON-NEXT: },
// JSON-NEXT: "isDependent": true,
// JSON-NEXT: "isInstantiationDependent": true,
@@ -7764,12 +7773,12 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 7949,
+// JSON-NEXT: "offset": 8060,
// JSON-NEXT: "col": 34,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 7949,
+// JSON-NEXT: "offset": 8060,
// JSON-NEXT: "col": 34,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7803,12 +7812,12 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "kind": "DeclRefExpr",
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 7954,
+// JSON-NEXT: "offset": 8065,
// JSON-NEXT: "col": 39,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 7954,
+// JSON-NEXT: "offset": 8065,
// JSON-NEXT: "col": 39,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7832,19 +7841,19 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "TemplateTypeParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 7894,
-// JSON-NEXT: "line": 204,
+// JSON-NEXT: "offset": 8005,
+// JSON-NEXT: "line": 205,
// JSON-NEXT: "col": 22,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 7885,
+// JSON-NEXT: "offset": 7996,
// JSON-NEXT: "col": 13,
// JSON-NEXT: "tokLen": 8
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 7894,
+// JSON-NEXT: "offset": 8005,
// JSON-NEXT: "col": 22,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7859,18 +7868,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 7903,
+// JSON-NEXT: "offset": 8014,
// JSON-NEXT: "col": 31,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 7898,
+// JSON-NEXT: "offset": 8009,
// JSON-NEXT: "col": 26,
// JSON-NEXT: "tokLen": 4
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 7903,
+// JSON-NEXT: "offset": 8014,
// JSON-NEXT: "col": 31,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7887,18 +7896,18 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "NonTypeTemplateParmDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 7912,
+// JSON-NEXT: "offset": 8023,
// JSON-NEXT: "col": 40,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 7907,
+// JSON-NEXT: "offset": 8018,
// JSON-NEXT: "col": 35,
// JSON-NEXT: "tokLen": 4
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 7912,
+// JSON-NEXT: "offset": 8023,
// JSON-NEXT: "col": 40,
// JSON-NEXT: "tokLen": 2
// JSON-NEXT: }
@@ -7915,19 +7924,19 @@ namespace TestPartialSpecNTTP {
// JSON-NEXT: "id": "0x{{.*}}",
// JSON-NEXT: "kind": "CXXRecordDecl",
// JSON-NEXT: "loc": {
-// JSON-NEXT: "offset": 7925,
-// JSON-NEXT: "line": 205,
+// JSON-NEXT: "offset": 8036,
+// JSON-NEXT: "line": 206,
// JSON-NEXT: "col": 10,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: },
// JSON-NEXT: "range": {
// JSON-NEXT: "begin": {
-// JSON-NEXT: "offset": 7918,
+// JSON-NEXT: "offset": 8029,
// JSON-NEXT: "col": 3,
// JSON-NEXT: "tokLen": 6
// JSON-NEXT: },
// JSON-NEXT: "end": {
-// JSON-NEXT: "offset": 7925,
+// JSON-NEXT: "offset": 8036,
// JSON-NEXT: "col": 10,
// JSON-NEXT: "tokLen": 9
// JSON-NEXT: }
diff --git a/clang/test/AST/ast-dump-traits.cpp b/clang/test/AST/ast-dump-traits.cpp
index 3085e5883fd2e..83e590fea1734 100644
--- a/clang/test/AST/ast-dump-traits.cpp
+++ b/clang/test/AST/ast-dump-traits.cpp
@@ -40,9 +40,8 @@ void test_unary_expr_or_type_trait() {
// CHECK-NEXT: | | `-EnumDecl {{.*}} <col:3, col:11> col:8{{( imported)?}} referenced E
// CHECK-NEXT: | |-CStyleCastExpr {{.*}} <line:13:3, col:21> 'void' <ToVoid>
// CHECK-NEXT: | | `-TypeTraitExpr {{.*}} <col:10, col:21> 'bool' __is_enum
-// CHECK-NEXT: | | `-ElaboratedType {{.*}} 'E' sugar
-// CHECK-NEXT: | | `-EnumType {{.*}} 'E'
-// CHECK-NEXT: | | `-Enum {{.*}} 'E'
+// CHECK-NEXT: | | `-EnumType {{.*}} 'E'
+// CHECK-NEXT: | | `-Enum {{.*}} 'E'
// CHECK-NEXT: | |-CStyleCastExpr {{.*}} <line:15:3, col:30> 'void' <ToVoid>
// CHECK-NEXT: | | `-TypeTraitExpr {{.*}} <col:10, col:30> 'bool' __is_same
// CHECK-NEXT: | | |-BuiltinType {{.*}} 'int'
diff --git a/clang/test/AST/ast-dump-types-json.cpp b/clang/test/AST/ast-dump-types-json.cpp
index cc4d4d9a64872..aac602780e8c0 100644
--- a/clang/test/AST/ast-dump-types-json.cpp
+++ b/clang/test/AST/ast-dump-types-json.cpp
@@ -51,30 +51,20 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "name": "TestElaboratedType1",
// CHECK-NEXT: "type": {
-// CHECK-NEXT: "desugaredQualType": "T",
// CHECK-NEXT: "qualType": "struct T"
// CHECK-NEXT: },
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ElaboratedType",
+// CHECK-NEXT: "kind": "RecordType",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "struct T"
// CHECK-NEXT: },
-// CHECK-NEXT: "inner": [
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "RecordType",
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "T"
-// CHECK-NEXT: },
-// CHECK-NEXT: "decl": {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CXXRecordDecl",
-// CHECK-NEXT: "name": "T"
-// CHECK-NEXT: }
-// CHECK-NEXT: }
-// CHECK-NEXT: ]
+// CHECK-NEXT: "decl": {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "name": "T"
+// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
@@ -108,25 +98,16 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "ElaboratedType",
+// CHECK-NEXT: "kind": "RecordType",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "NS::S"
// CHECK-NEXT: },
// CHECK-NEXT: "qualifier": "NS::",
-// CHECK-NEXT: "inner": [
-// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "RecordType",
-// CHECK-NEXT: "type": {
-// CHECK-NEXT: "qualType": "NS::S"
-// CHECK-NEXT: },
-// CHECK-NEXT: "decl": {
-// CHECK-NEXT: "id": "0x{{.*}}",
-// CHECK-NEXT: "kind": "CXXRecordDecl",
-// CHECK-NEXT: "name": "S"
-// CHECK-NEXT: }
-// CHECK-NEXT: }
-// CHECK-NEXT: ]
+// CHECK-NEXT: "decl": {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "CXXRecordDecl",
+// CHECK-NEXT: "name": "S"
+// CHECK-NEXT: }
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
@@ -538,7 +519,39 @@ using ::TestUsingShadowDeclType;
// CHECK-NEXT: },
// CHECK-NEXT: "inner": [
// CHECK-NEXT: {
-// CHECK-NEXT: "id": "0x0"
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "TypedefDecl",
+// CHECK-NEXT: "loc": {
+// CHECK-NEXT: "offset": 506,
+// CHECK-NEXT: "line": 23,
+// CHECK-NEXT: "col": 13,
+// CHECK-NEXT: "tokLen": 23
+// CHECK-NEXT: },
+// CHECK-NEXT: "range": {
+// CHECK-NEXT: "begin": {
+// CHECK-NEXT: "offset": 494,
+// CHECK-NEXT: "col": 1,
+// CHECK-NEXT: "tokLen": 7
+// CHECK-NEXT: },
+// CHECK-NEXT: "end": {
+// CHECK-NEXT: "offset": 506,
+// CHECK-NEXT: "col": 13,
+// CHECK-NEXT: "tokLen": 23
+// CHECK-NEXT: }
+// CHECK-NEXT: },
+// CHECK-NEXT: "name": "TestUsingShadowDeclType",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: },
+// CHECK-NEXT: "inner": [
+// CHECK-NEXT: {
+// CHECK-NEXT: "id": "0x{{.*}}",
+// CHECK-NEXT: "kind": "BuiltinType",
+// CHECK-NEXT: "type": {
+// CHECK-NEXT: "qualType": "int"
+// CHECK-NEXT: }
+// CHECK-NEXT: }
+// CHECK-NEXT: ]
// CHECK-NEXT: }
// CHECK-NEXT: ]
// CHECK-NEXT: }
diff --git a/clang/test/AST/ast-dump-using-template.cpp b/clang/test/AST/ast-dump-using-template.cpp
index 2c9584966e843..a5a0e4d07d683 100644
--- a/clang/test/AST/ast-dump-using-template.cpp
+++ b/clang/test/AST/ast-dump-using-template.cpp
@@ -19,40 +19,36 @@ using ns::S2;
template<typename T>
using A = S<T>;
// CHECK: TypeAliasDecl
-// CHECK-NEXT: `-ElaboratedType {{.*}} 'S<T>' sugar dependent
-// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'S<T>' dependent
-// CHECK-NEXT: |-name: 'S':'ns::S' qualified
-// CHECK-NEXT: | |-UsingShadowDecl {{.+}} ClassTemplate {{.+}} 'S'
+// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'S<T>' dependent
+// CHECK-NEXT: |-name: 'S':'ns::S' qualified
+// CHECk-NEXT: | |-UsingShadowDecl {{.+}} ClassTemplate {{.+}} 'S'
// TemplateName in TemplateArgument.
template <template <typename> class T> class X {};
using B = X<S>;
// CHECK: TypeAliasDecl
-// CHECK-NEXT: `-ElaboratedType {{.*}} 'X<S>' sugar
-// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'X<S>' sugar
-// CHECK-NEXT: |-name: 'X' qualified
-// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} X
-// CHECK-NEXT: |-TemplateArgument template 'S':'ns::S' qualified
-// CHECK-NEXT: | |-UsingShadowDecl {{.*}} implicit ClassTemplate {{.*}} 'S'
-// CHECK-NEXT: | `-target: ClassTemplateDecl {{.*}} S
-// CHECK-NEXT: `-RecordType {{.*}} 'X<ns::S>'
-// CHECK-NEXT: `-ClassTemplateSpecialization {{.*}} 'X'
+// CHECK-NEXT: `-TemplateSpecializationType {{.*}} 'X<S>' sugar
+// CHECK-NEXT: |-name: 'X' qualified
+// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} X
+// CHECK-NEXT: |-TemplateArgument template 'S':'ns::S' qualified
+// CHECK-NEXT: | |-UsingShadowDecl {{.*}} implicit ClassTemplate {{.*}} 'S'
+// CHECK-NEXT: | `-target: ClassTemplateDecl {{.*}} S
+// CHECK-NEXT: `-RecordType {{.*}} 'X<ns::S>'
+// CHECK-NEXT: `-ClassTemplateSpecialization {{.*}} 'X'
// TemplateName in DeducedTemplateSpecializationType.
S DeducedTemplateSpecializationT(123);
using C = decltype(DeducedTemplateSpecializationT);
// CHECK: DecltypeType {{.*}}
// CHECK-NEXT: |-DeclRefExpr {{.*}}
-// CHECK-NEXT: `-ElaboratedType {{.*}} 'S<int>' sugar
-// CHECK-NEXT: `-DeducedTemplateSpecializationType {{.*}} 'ns::S<int>' sugar
-// CHECK-NEXT: |-name: 'S':'ns::S' qualified
-// CHECK-NEXT: | |-UsingShadowDecl {{.+}} 'S'
+// CHECK-NEXT: `-DeducedTemplateSpecializationType {{.*}} 'S<int>' sugar
+// CHECK-NEXT: |-name: 'S':'ns::S' qualified
+// CHECK-NEXT: | |-UsingShadowDecl {{.+}} 'S'
S2 DeducedTemplateSpecializationT2(123);
using D = decltype(DeducedTemplateSpecializationT2);
// CHECK: DecltypeType {{.*}}
// CHECK-NEXT: |-DeclRefExpr {{.*}}
-// CHECK-NEXT: `-ElaboratedType {{.*}} 'S2<int>' sugar
-// CHECK-NEXT: `-DeducedTemplateSpecializationType {{.*}} 'S2<int>' sugar
-// CHECK-NEXT: |-name: 'S2':'ns::S2' qualified
-// CHECK-NEXT: | |-UsingShadowDecl {{.+}} ClassTemplate {{.+}} 'S2'
+// CHECK-NEXT: `-DeducedTemplateSpecializationType {{.*}} 'S2<int>' sugar
+// CHECK-NEXT: |-name: 'S2':'ns::S2' qualified
+// CHECk-NEXT: | |-UsingShadowDecl {{.+}} ClassTemplate {{.+}} 'S2'
diff --git a/clang/test/AST/ast-dump-using.cpp b/clang/test/AST/ast-dump-using.cpp
index 8e5c60d3aabf4..0c8405bc5a52b 100644
--- a/clang/test/AST/ast-dump-using.cpp
+++ b/clang/test/AST/ast-dump-using.cpp
@@ -9,19 +9,17 @@ using a::S;
// CHECK: UsingDecl {{.*}} a::S
// CHECK-NEXT: | `-NestedNameSpecifier Namespace {{.*}} 'a'
// CHECK-NEXT: UsingShadowDecl {{.*}} implicit CXXRecord {{.*}} 'S'
-// CHECK-NEXT: `-RecordType {{.*}} 'a::S'
+// CHECK-NEXT: `-CXXRecordDecl {{.*}} referenced struct S
typedef S f; // to dump the introduced type
// CHECK: TypedefDecl
-// CHECK-NEXT: `-ElaboratedType {{.*}} 'S' sugar
-// CHECK-NEXT: `-UsingType [[TYPE_ADDR:.*]] 'a::S' sugar
-// CHECK-NEXT: |-UsingShadow [[SHADOW_ADDR:.*]] 'S'
-// CHECK-NEXT: `-RecordType {{.*}} 'a::S'
+// CHECK-NEXT: `-UsingType [[TYPE_ADDR:.*]] 'S' sugar 'a::S'
+// CHECK-NEXT: |-UsingShadow [[SHADOW_ADDR:.*]] 'S'
+// CHECK-NEXT: `-RecordType {{.*}} 'a::S'
typedef S e; // check the same UsingType is reused.
// CHECK: TypedefDecl
-// CHECK-NEXT: `-ElaboratedType {{.*}} 'S' sugar
-// CHECK-NEXT: `-UsingType [[TYPE_ADDR]] 'a::S' sugar
-// CHECK-NEXT: |-UsingShadow [[SHADOW_ADDR]] 'S'
-// CHECK-NEXT: `-RecordType {{.*}} 'a::S'
+// CHECK-NEXT: `-UsingType [[TYPE_ADDR]] 'S' sugar 'a::S'
+// CHECK-NEXT: |-UsingShadow [[SHADOW_ADDR]] 'S'
+// CHECK-NEXT: `-RecordType {{.*}} 'a::S'
using a::x;
void foo() {
diff --git a/clang/test/AST/attr-swift_attr.m b/clang/test/AST/attr-swift_attr.m
index 6888745fe95d4..766da93db811e 100644
--- a/clang/test/AST/attr-swift_attr.m
+++ b/clang/test/AST/attr-swift_attr.m
@@ -43,7 +43,7 @@ @interface Generic<T: SWIFT_SENDABLE id>
void *ptr;
} SendableStruct;
-// CHECK-LABEL: TypedefDecl {{.*}} SendableStruct 'struct SendableStruct':'SendableStruct'
+// CHECK-LABEL: TypedefDecl {{.*}} SendableStruct 'struct SendableStruct'
// CHECK: SwiftAttrAttr {{.*}} "@Sendable"
@interface TestAttrPlacementInBlock1
diff --git a/clang/test/AST/coroutine-locals-cleanup.cpp b/clang/test/AST/coroutine-locals-cleanup.cpp
index a7f524b0b1ac9..b0577f9b8e235 100644
--- a/clang/test/AST/coroutine-locals-cleanup.cpp
+++ b/clang/test/AST/coroutine-locals-cleanup.cpp
@@ -86,7 +86,7 @@ Task bar() {
// CHECK: ExprWithCleanups {{.*}} 'void'
// CHECK-NEXT: CoawaitExpr
// CHECK-NEXT: CXXBindTemporaryExpr {{.*}} 'Task' (CXXTemporary {{.*}})
-// CHECK: MaterializeTemporaryExpr {{.*}} 'Awaiter':'Task::Awaiter'
+// CHECK: MaterializeTemporaryExpr {{.*}} 'Awaiter'
// CHECK: ExprWithCleanups {{.*}} 'bool'
// CHECK-NEXT: CXXMemberCallExpr {{.*}} 'bool'
// CHECK-NEXT: MemberExpr {{.*}} .await_ready
@@ -96,7 +96,7 @@ Task bar() {
// CHECK: ExprWithCleanups {{.*}} 'void'
// CHECK-NEXT: CoawaitExpr
// CHECK-NEXT: CXXBindTemporaryExpr {{.*}} 'Task' (CXXTemporary {{.*}})
-// CHECK: MaterializeTemporaryExpr {{.*}} 'Awaiter':'Task::Awaiter'
+// CHECK: MaterializeTemporaryExpr {{.*}} 'Awaiter'
// CHECK: ExprWithCleanups {{.*}} 'bool'
// CHECK-NEXT: CXXMemberCallExpr {{.*}} 'bool'
// CHECK-NEXT: MemberExpr {{.*}} .await_ready
diff --git a/clang/test/AST/cxx2c-variadic-friends.cpp b/clang/test/AST/cxx2c-variadic-friends.cpp
index fc84e7346fe03..6147d7f75895f 100644
--- a/clang/test/AST/cxx2c-variadic-friends.cpp
+++ b/clang/test/AST/cxx2c-variadic-friends.cpp
@@ -70,11 +70,11 @@ template <typename ...Pack> struct Variadic {
// CHECK-LABEL: ClassTemplateDecl {{.*}} S2
// PRINT-LABEL: template <class ...Ts> struct S2 {
template<class ...Ts> struct S2 {
- // CHECK: FriendDecl {{.*}} 'class C<Ts>':'C<Ts>'...
+ // CHECK: FriendDecl {{.*}} 'class C<Ts>'...
// PRINT-NEXT: friend class C<Ts>...;
friend class C<Ts>...;
- // CHECK-NEXT: FriendDecl {{.*}} 'class N::C<Ts>':'C<Ts>'...
+ // CHECK-NEXT: FriendDecl {{.*}} 'class N::C<Ts>'...
// PRINT-NEXT: friend class N::C<Ts>...
friend class N::C<Ts>...;
};
diff --git a/clang/test/AST/deduction-guides.cpp b/clang/test/AST/deduction-guides.cpp
index d96c7e6bd5e35..5ecb276370bcc 100644
--- a/clang/test/AST/deduction-guides.cpp
+++ b/clang/test/AST/deduction-guides.cpp
@@ -30,11 +30,11 @@ struct HasDeductionGuideTypeAlias {
HasDeductionGuideTypeAlias()->HasDeductionGuideTypeAlias<int>;
// The parameter to this one shouldn't be an elaborated type.
-// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuide> 'auto (typename STy::Child) -> HasDeductionGuide<T>'
-// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuide> 'auto (HasDeductionGuide<T>) -> HasDeductionGuide<T>'
+// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuide> 'auto (typename STy::Child) -> PR46111::HasDeductionGuide<T>'
+// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuide> 'auto (PR46111::HasDeductionGuide<T>) -> PR46111::HasDeductionGuide<T>'
// CHECK: CXXDeductionGuideDecl {{.*}} <deduction guide for HasDeductionGuide> 'auto () -> HasDeductionGuide<int>'
-// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuideTypeAlias> 'auto (typename STy::Child) -> HasDeductionGuideTypeAlias<T>'
-// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuideTypeAlias> 'auto (HasDeductionGuideTypeAlias<T>) -> HasDeductionGuideTypeAlias<T>'
+// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuideTypeAlias> 'auto (typename STy::Child) -> PR46111::HasDeductionGuideTypeAlias<T>'
+// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for HasDeductionGuideTypeAlias> 'auto (PR46111::HasDeductionGuideTypeAlias<T>) -> PR46111::HasDeductionGuideTypeAlias<T>'
// CHECK: CXXDeductionGuideDecl {{.*}} <deduction guide for HasDeductionGuideTypeAlias> 'auto () -> HasDeductionGuideTypeAlias<int>'
} // namespace PR46111
@@ -64,15 +64,15 @@ namespace PR48177 {
// CHECK: CXXRecordDecl {{.*}} struct Derived
// CHECK: TypeAliasDecl {{.*}} type_alias 'typename Derived<int, 1, int>::type_alias':'int'
-// CHECK-NEXT: ElaboratedType {{.*}} 'typename Derived<int, 1, int>::type_alias' sugar
-// CHECK-NEXT: TypedefType {{.*}} 'PR48177::Base<int>::type_alias' sugar
+// CHECK-NEXT: TypedefType {{.*}} 'typename Derived<int, 1, int>::type_alias' sugar
+// CHECK-NEXT: NestedNameSpecifier TypeSpec 'Derived<int, 1, int>'
// CHECK-NEXT: TypeAlias {{.*}} 'type_alias'
// CHECK-NEXT: SubstTemplateTypeParmType {{.*}} 'int' sugar class depth 0 index 0 A
// CHECK-NEXT: ClassTemplateSpecialization {{.*}} 'Base'
// CHECK-NEXT: BuiltinType {{.*}} 'int'
-// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for Derived> 'auto (Derived<T, S, A> &&, const typename Derived<T, S, A>::type_alias &) -> Derived<T, S, A>'
-// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for Derived> 'auto (T) -> Derived<T, S, A>'
-// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for Derived> 'auto (Derived<T, S, A>) -> Derived<T, S, A>'
+// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for Derived> 'auto (Derived<T, S, A> &&, const typename Derived<T, S, A>::type_alias &) -> PR48177::Derived<T, S, A>'
+// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for Derived> 'auto (T) -> PR48177::Derived<T, S, A>'
+// CHECK: CXXDeductionGuideDecl {{.*}} implicit <deduction guide for Derived> 'auto (PR48177::Derived<T, S, A>) -> PR48177::Derived<T, S, A>'
// CHECK: CXXDeductionGuideDecl {{.*}} <deduction guide for Derived> 'auto (T, A) -> Derived<T, 1, A>'
// CHECK: CXXDeductionGuideDecl {{.*}} <deduction guide for Derived> 'auto (int, int) -> Derived<int, 1, int>'
diff --git a/clang/test/AST/float16.cpp b/clang/test/AST/float16.cpp
index a9e1144cf0958..643d37cfc9436 100644
--- a/clang/test/AST/float16.cpp
+++ b/clang/test/AST/float16.cpp
@@ -126,7 +126,7 @@ class C1 {
};
//CHECK: |-CXXRecordDecl {{.*}} referenced class C1 definition
-//CHECK: | |-CXXRecordDecl {{.*}} implicit referenced class C1
+//CHECK: | |-CXXRecordDecl {{.*}} implicit class C1
//CHECK-NEXT: | |-FieldDecl {{.*}} referenced f1c '_Float16'
//CHECK-NEXT: | |-VarDecl {{.*}} used f2c 'const _Float16' static
//CHECK-NEXT: | |-FieldDecl {{.*}} f3c 'volatile _Float16'
diff --git a/clang/test/AST/sourceranges.cpp b/clang/test/AST/sourceranges.cpp
index f78d34c1ee7e3..598a28bddad60 100644
--- a/clang/test/AST/sourceranges.cpp
+++ b/clang/test/AST/sourceranges.cpp
@@ -47,7 +47,7 @@ struct D {
void construct() {
using namespace foo;
A a = A(12);
- // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'A':'foo::A' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
+ // CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'A' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
D d = D(12);
// CHECK: CXXConstructExpr {{0x[0-9a-fA-F]+}} <col:9, col:13> 'D' 'void (int){{( __attribute__\(\(thiscall\)\))?}}'
}
@@ -174,7 +174,7 @@ namespace in_class_init {
// CHECK-1Z: CXXRecordDecl {{.*}} struct B definition
struct B {
- // CHECK-1Z: FieldDecl {{.*}} a 'A':'in_class_init::A'
+ // CHECK-1Z: FieldDecl {{.*}} a 'A'
// CHECK-1Z-NEXT: InitListExpr {{.*}} <col:11, col:12
A a = {};
};
@@ -192,7 +192,7 @@ namespace delegating_constructor_init {
// CHECK-1Z: CXXRecordDecl {{.*}} struct C definition
struct C : B {
// CHECK-1Z: CXXConstructorDecl {{.*}} C
- // CHECK-1Z-NEXT: CXXCtorInitializer 'B':'delegating_constructor_init::B'
+ // CHECK-1Z-NEXT: CXXCtorInitializer 'B'
// CHECK-1Z-NEXT: CXXConstructExpr {{.*}} <col:11, col:15
// CHECK-1Z-NEXT: InitListExpr {{.*}} <col:13, col:14
C() : B({}) {};
diff --git a/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp b/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp
index 27604e237adbb..8e8e03c2451a0 100644
--- a/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp
+++ b/clang/test/ASTSYCL/ast-dump-sycl-kernel-call-stmt.cpp
@@ -64,10 +64,10 @@ void skep2<KN<2>>(K<2>);
// CHECK-NEXT: | `-FunctionDecl {{.*}} skep2 'void (K<2>)' explicit_instantiation_definition
// CHECK-NEXT: | |-TemplateArgument type 'KN<2>'
-// CHECK-NEXT: | | `-RecordType {{.*}} 'KN<2>'
+// CHECK-NEXT: | | `-RecordType {{.*}} 'KN<2>' canonical
// CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'KN'
// CHECK-NEXT: | |-TemplateArgument type 'K<2>'
-// CHECK-NEXT: | | `-RecordType {{.*}} 'K<2>'
+// CHECK-NEXT: | | `-RecordType {{.*}} 'K<2>' canonical
// CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'K'
// CHECK-NEXT: | |-ParmVarDecl {{.*}} k 'K<2>'
// CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}}
@@ -110,10 +110,10 @@ void skep3<KN<3>>(K<3> k) {
// CHECK-NEXT: | `-Function {{.*}} 'skep3' 'void (K<3>)'
// CHECK-NEXT: |-FunctionDecl {{.*}} skep3 'void (K<3>)' explicit_specialization
// CHECK-NEXT: | |-TemplateArgument type 'KN<3>'
-// CHECK-NEXT: | | `-RecordType {{.*}} 'KN<3>'
+// CHECK-NEXT: | | `-RecordType {{.*}} 'KN<3>' canonical
// CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'KN'
// CHECK-NEXT: | |-TemplateArgument type 'K<3>'
-// CHECK-NEXT: | | `-RecordType {{.*}} 'K<3>'
+// CHECK-NEXT: | | `-RecordType {{.*}} 'K<3>' canonical
// CHECK-NEXT: | | `-ClassTemplateSpecialization {{.*}} 'K'
// CHECK-NEXT: | |-ParmVarDecl {{.*}} k 'K<3>'
// CHECK-NEXT: | |-SYCLKernelCallStmt {{.*}}
diff --git a/clang/test/Analysis/anonymous-decls.cpp b/clang/test/Analysis/anonymous-decls.cpp
index 85449caa46972..3f972a33aa621 100644
--- a/clang/test/Analysis/anonymous-decls.cpp
+++ b/clang/test/Analysis/anonymous-decls.cpp
@@ -78,12 +78,12 @@ int main() {
// CHECK-NEXT: 8: decomposition-a-b
// CHECK-NEXT: 9: [B3.7]([B3.8])
// CHECK-NEXT: 10: [B3.9]
-// CHECK-NEXT: 11: std::tuple_element<0, std::pair<int, int>>::type a = get<0UL>(decomposition-a-b);
+// CHECK-NEXT: 11: std::tuple_element<0UL, std::pair<int, int>>::type a = get<0UL>(decomposition-a-b);
// CHECK-NEXT: 12: get<1UL>
// CHECK-NEXT: 13: [B3.12] (ImplicitCastExpr, FunctionToPointerDecay, tuple_element<1L, pair<int, int> >::type (*)(pair<int, int> &))
// CHECK-NEXT: 14: decomposition-a-b
// CHECK-NEXT: 15: [B3.13]([B3.14])
// CHECK-NEXT: 16: [B3.15]
-// CHECK-NEXT: 17: std::tuple_element<1, std::pair<int, int>>::type b = get<1UL>(decomposition-a-b);
+// CHECK-NEXT: 17: std::tuple_element<1UL, std::pair<int, int>>::type b = get<1UL>(decomposition-a-b);
// CHECK-NEXT: Preds (1): B1
// CHECK-NEXT: Succs (1): B2
diff --git a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
index 5c281ac806836..76e2afb3a8515 100644
--- a/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
+++ b/clang/test/CXX/basic/basic.lookup/basic.lookup.qual/class.qual/p2.cpp
@@ -197,7 +197,7 @@ namespace InhCtor {
// FIXME: Consider reusing the same diagnostic between dependent and non-dependent contexts
typedef int I;
struct UsingInt {
- using I::I; // expected-error {{'InhCtor::I' (aka 'int') is not a class, namespace, or enumeration}}
+ using I::I; // expected-error {{'I' (aka 'int') is not a class, namespace, or enumeration}}
};
template<typename T> struct UsingIntTemplate {
using T::T; // expected-error {{type 'int' cannot be used prior to '::' because it has no members}}
diff --git a/clang/test/CXX/class.access/p6.cpp b/clang/test/CXX/class.access/p6.cpp
index 15f2644f6ac1d..9a8aebe76706a 100644
--- a/clang/test/CXX/class.access/p6.cpp
+++ b/clang/test/CXX/class.access/p6.cpp
@@ -176,7 +176,7 @@ namespace test8 {
};
void test(A &a) {
- if (a) return; // expected-error-re {{'operator void *(A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
+ if (a) return; // expected-error-re {{'operator void *(test8::A::*)(){{( __attribute__\(\(thiscall\)\))?}} const' is a private member of 'test8::A'}}
}
}
diff --git a/clang/test/CXX/class.derived/class.derived.general/p2.cpp b/clang/test/CXX/class.derived/class.derived.general/p2.cpp
index 1423eeabebf59..c700e8a3ce14e 100644
--- a/clang/test/CXX/class.derived/class.derived.general/p2.cpp
+++ b/clang/test/CXX/class.derived/class.derived.general/p2.cpp
@@ -2,7 +2,7 @@
namespace CurrentInstantiation {
template<typename T>
- struct A0 { // expected-note 6{{definition of 'A0<T>' is not complete until the closing '}'}}
+ struct A0 { // expected-note 6{{definition of 'CurrentInstantiation::A0<T>' is not complete until the closing '}'}}
struct B0 : A0 { }; // expected-error {{base class has incomplete type}}
template<typename U>
@@ -26,7 +26,7 @@ namespace CurrentInstantiation {
};
template<typename U>
- struct B5 { // expected-note 2{{definition of 'B5<U>' is not complete until the closing '}'}}
+ struct B5 { // expected-note 2{{definition of 'CurrentInstantiation::A0::B5<U>' is not complete until the closing '}'}}
struct C0 : A0, B5 { }; // expected-error 2{{base class has incomplete type}}
template<typename V>
@@ -63,7 +63,7 @@ namespace CurrentInstantiation {
struct A0<T>::B5<U>::C3 : A0, B5 { };
template<typename T>
- struct A0<T*> { // expected-note 2{{definition of 'A0<T *>' is not complete until the closing '}'}}
+ struct A0<T*> { // expected-note 2{{definition of 'CurrentInstantiation::A0<T *>' is not complete until the closing '}'}}
struct B0 : A0 { }; // expected-error {{base class has incomplete type}}
template<typename U>
@@ -91,7 +91,7 @@ namespace MemberOfCurrentInstantiation {
template<typename U>
struct C : C<U> { }; // expected-error {{base class has incomplete type}}
- // expected-note at -1 {{definition of 'C<U>' is not complete until the closing '}'}}
+ // expected-note at -1 {{definition of 'MemberOfCurrentInstantiation::A0::C<U>' is not complete until the closing '}'}}
};
template<typename T>
diff --git a/clang/test/CXX/class/class.mem/class.mem.general/p8.cpp b/clang/test/CXX/class/class.mem/class.mem.general/p8.cpp
index 8cc9b41eaca91..c4aca327fbb37 100644
--- a/clang/test/CXX/class/class.mem/class.mem.general/p8.cpp
+++ b/clang/test/CXX/class/class.mem/class.mem.general/p8.cpp
@@ -45,7 +45,7 @@ namespace N1 {
void g0() noexcept(y); // expected-error {{use of undeclared identifier 'y'}}
void f1() noexcept(A::x);
- void g1() noexcept(A::y); // expected-error {{no member named 'y' in 'A<T>'}}
+ void g1() noexcept(A::y); // expected-error {{no member named 'y' in 'N1::A<T>'}}
template<typename U>
void f2() noexcept(x);
@@ -55,13 +55,13 @@ namespace N1 {
template<typename U>
void f3() noexcept(A::x);
template<typename U>
- void g3() noexcept(A::y); // expected-error {{no member named 'y' in 'A<T>'}}
+ void g3() noexcept(A::y); // expected-error {{no member named 'y' in 'N1::A<T>'}}
friend void f4() noexcept(x);
friend void g4() noexcept(y); // expected-error {{use of undeclared identifier 'y'}}
friend void f5() noexcept(A::x);
- friend void g5() noexcept(A::y); // expected-error {{no member named 'y' in 'A<T>'}}
+ friend void g5() noexcept(A::y); // expected-error {{no member named 'y' in 'N1::A<T>'}}
template<typename U>
friend void f6() noexcept(x);
@@ -71,7 +71,7 @@ namespace N1 {
template<typename U>
friend void f7() noexcept(A::x);
template<typename U>
- friend void g7() noexcept(A::y); // expected-error {{no member named 'y' in 'A<T>'}}
+ friend void g7() noexcept(A::y); // expected-error {{no member named 'y' in 'N1::A<T>'}}
static constexpr bool x = true;
};
diff --git a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
index 8bdd490531119..c7b331e84cc0f 100644
--- a/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
+++ b/clang/test/CXX/dcl.dcl/dcl.spec/dcl.type/dcl.type.elab/p3.cpp
@@ -38,7 +38,7 @@ template <> struct B<A> {
void b1(struct B<float>);
void b2(class B<float>);
-void b3(union B<float>); // expected-error {{use of 'B<float>' with tag type that does not match previous declaration}}
+void b3(union B<float>); // expected-error {{use of 'union B<float>' with tag type that does not match previous declaration}}
//void b4(enum B<float>); // this just doesn't parse; you can't template an enum directly
void c1(struct B<float>::Member);
diff --git a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
index 77aef99eaa7c8..ad3b0145d6cbb 100644
--- a/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.init/dcl.init.ref/p5-examples.cpp
@@ -22,7 +22,7 @@ void example1() {
// CHECK: VarDecl{{.*}}rca 'const A &'
// CHECK: ImplicitCastExpr{{.*}}'const A' lvalue <DerivedToBase (A)>
// CHECK-NOT: MaterializeTemporaryExpr
- // CHECK: ImplicitCastExpr{{.*}}'const B' lvalue <NoOp>
+ // CHECK: ImplicitCastExpr{{.*}}'const struct B' lvalue <NoOp>
const A& rca = b;
}
diff --git a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp
index a06b107755596..bb1eb732b063b 100644
--- a/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp
+++ b/clang/test/CXX/dcl.decl/dcl.meaning/dcl.mptr/p2.cpp
@@ -59,6 +59,6 @@ namespace TypoCorrection {
int A<T>::template typo<int>::* f();
template<typename T>
- int A<T>::typo<int>::* g(); // expected-error {{no template named 'typo' in 'A<T>'; did you mean 'Typo'?}}
+ int A<T>::typo<int>::* g(); // expected-error {{no template named 'typo' in 'TypoCorrection::A<T>'; did you mean 'Typo'?}}
// expected-error at -1 {{expected unqualified-id}}
}
diff --git a/clang/test/CXX/dcl/dcl.fct/p17.cpp b/clang/test/CXX/dcl/dcl.fct/p17.cpp
index 4a81875cb4f89..431a8fbdf38a0 100644
--- a/clang/test/CXX/dcl/dcl.fct/p17.cpp
+++ b/clang/test/CXX/dcl/dcl.fct/p17.cpp
@@ -109,7 +109,7 @@ namespace unconstrained {
template<typename T>
template<typename U>
constexpr auto S<T>::f2(auto x, U u, T t) -> decltype(x + u + t) { return x + u + t; }
- // expected-error at -1 {{out-of-line definition of 'f2' does not match any declaration in 'S<T>'}}
+ // expected-error at -1 {{out-of-line definition of 'f2' does not match any declaration in 'unconstrained::S<T>'}}
// expected-note@#defined-here {{S defined here}}
template<typename T>
diff --git a/clang/test/CXX/drs/cwg0xx.cpp b/clang/test/CXX/drs/cwg0xx.cpp
index 4d4e2f64ff643..9aeee7a76903d 100644
--- a/clang/test/CXX/drs/cwg0xx.cpp
+++ b/clang/test/CXX/drs/cwg0xx.cpp
@@ -859,7 +859,7 @@ namespace cwg54 { // cwg54: 2.8
// expected-error at -1 {{cannot cast 'struct B' to its private base class 'A'}}
// expected-note@#cwg54-B {{declared private here}}
int A::*smab = static_cast<int A::*>(&B::b);
- // expected-error at -1 {{cannot cast 'B' to its private base class 'A'}}
+ // expected-error at -1 {{cannot cast 'cwg54::B' to its private base class 'A'}}
// expected-note@#cwg54-B {{declared private here}}
B &sba = static_cast<B&>(a);
// expected-error at -1 {{cannot cast private base class 'cwg54::A' to 'cwg54::B'}}
@@ -874,7 +874,7 @@ namespace cwg54 { // cwg54: 2.8
V &svb = static_cast<V&>(b);
V *spvb = static_cast<V*>(&b);
int V::*smvb = static_cast<int V::*>(&B::b);
- // expected-error at -1 {{conversion from pointer to member of class 'B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
+ // expected-error at -1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
B &sbv = static_cast<B&>(v);
// expected-error at -1 {{cannot cast 'struct V' to 'B &' via virtual base 'cwg54::V'}}
B *spbv = static_cast<B*>(&v);
@@ -892,7 +892,7 @@ namespace cwg54 { // cwg54: 2.8
V &cvb = (V&)(b);
V *cpvb = (V*)(&b);
int V::*cmvb = (int V::*)(&B::b);
- // expected-error at -1 {{conversion from pointer to member of class 'B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
+ // expected-error at -1 {{conversion from pointer to member of class 'cwg54::B' to pointer to member of class 'V' via virtual base 'cwg54::V' is not allowed}}
B &cbv = (B&)(v);
// expected-error at -1 {{cannot cast 'struct V' to 'B &' via virtual base 'cwg54::V'}}
B *cpbv = (B*)(&v);
diff --git a/clang/test/CXX/drs/cwg12xx.cpp b/clang/test/CXX/drs/cwg12xx.cpp
index e02a7e11b80b2..03a92287008c0 100644
--- a/clang/test/CXX/drs/cwg12xx.cpp
+++ b/clang/test/CXX/drs/cwg12xx.cpp
@@ -81,7 +81,7 @@ void g() {
A b(auto ()->C);
static_assert(sizeof(B ()->C[1] == sizeof(int)), "");
sizeof(auto () -> C[1]);
- // since-cxx11-error at -1 {{function cannot return array type 'C[1]' (aka 'cwg1223::BB[1]')}}
+ // since-cxx11-error at -1 {{function cannot return array type 'C[1]' (aka 'struct BB[1]')}}
}
#endif
} // namespace cwg1223
diff --git a/clang/test/CXX/drs/cwg13xx.cpp b/clang/test/CXX/drs/cwg13xx.cpp
index c4acafd5fd79a..ad6ee01483b4a 100644
--- a/clang/test/CXX/drs/cwg13xx.cpp
+++ b/clang/test/CXX/drs/cwg13xx.cpp
@@ -252,7 +252,7 @@ namespace cwg1330 { // cwg1330: 4 c++11
void (B<P>::*bpf3)() = &B<P>::f;
void (B<P>::*bpf4)() throw() = &B<P>::f;
// cxx98-14-error at -1 {{target exception specification is not superset of source}}
- // since-cxx17-error at -2 {{cannot initialize a variable of type 'void (B<P>::*)() throw()' with an rvalue of type 'void (B<P>::*)() throw(T, typename P::type)': different exception specifications}}
+ // since-cxx17-error at -2 {{cannot initialize a variable of type 'void (B<P>::*)() throw()' with an rvalue of type 'void (B<P>::*)() throw(T, typename cwg1330::P::type)': different exception specifications}}
#if __cplusplus >= 201103L
static_assert(noexcept(B<P>().g()), "");
diff --git a/clang/test/CXX/drs/cwg2149.cpp b/clang/test/CXX/drs/cwg2149.cpp
index 416c895e9ff30..6b54223eb6785 100644
--- a/clang/test/CXX/drs/cwg2149.cpp
+++ b/clang/test/CXX/drs/cwg2149.cpp
@@ -56,22 +56,22 @@ void f() {
// CXX98: VarDecl {{.+}} a 'X[2]'
// CXX98-NEXT: `-InitListExpr {{.+}} 'X[2]'
-// CXX98-NEXT: |-InitListExpr {{.+}} 'X':'cwg2149::X'
+// CXX98-NEXT: |-InitListExpr {{.+}} 'X'{{$}}
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 1
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 2
// CXX98-NEXT: | `-IntegerLiteral {{.+}} 'int' 3
-// CXX98-NEXT: `-InitListExpr {{.+}} 'X':'cwg2149::X'
+// CXX98-NEXT: `-InitListExpr {{.+}} 'X'{{$}}
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 4
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 5
// CXX98-NEXT: `-IntegerLiteral {{.+}} 'int' 6
// CXX98: VarDecl {{.+}} b 'X[2]'
// CXX98-NEXT: `-InitListExpr {{.+}} 'X[2]'
-// CXX98-NEXT: |-InitListExpr {{.+}} 'X':'cwg2149::X'
+// CXX98-NEXT: |-InitListExpr {{.+}} 'X'{{$}}
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 1
// CXX98-NEXT: | |-IntegerLiteral {{.+}} 'int' 2
// CXX98-NEXT: | `-IntegerLiteral {{.+}} 'int' 3
-// CXX98-NEXT: `-InitListExpr {{.+}} 'X':'cwg2149::X'
+// CXX98-NEXT: `-InitListExpr {{.+}} 'X'{{$}}
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 4
// CXX98-NEXT: |-IntegerLiteral {{.+}} 'int' 5
// CXX98-NEXT: `-IntegerLiteral {{.+}} 'int' 6
diff --git a/clang/test/CXX/drs/cwg26xx.cpp b/clang/test/CXX/drs/cwg26xx.cpp
index 60d896443ecd1..89e0a17ce17fb 100644
--- a/clang/test/CXX/drs/cwg26xx.cpp
+++ b/clang/test/CXX/drs/cwg26xx.cpp
@@ -291,12 +291,12 @@ static_assert(__is_same(decltype(i), I<char, 4>));
J j = { "ghi" };
// since-cxx20-error at -1 {{no viable constructor or deduction guide}}
-// since-cxx20-note@#cwg2681-J {{candidate template ignored: could not match 'J<N>' against 'const char *'}}
-// since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J(J<N>) -> J<N>'}}
+// since-cxx20-note@#cwg2681-J {{candidate template ignored: could not match 'cwg2681::J<N>' against 'const char *'}}
+// since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J(cwg2681::J<N>) -> cwg2681::J<N>'}}
// since-cxx20-note@#cwg2681-J {{candidate template ignored: could not match 'const unsigned char' against 'const char'}}
-// since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J(const unsigned char (&)[N]) -> J<N>'}}
+// since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J(const unsigned char (&)[N]) -> cwg2681::J<N>'}}
// since-cxx20-note@#cwg2681-J {{candidate function template not viable: requires 0 arguments, but 1 was provided}}
-// since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J() -> J<N>'}}
+// since-cxx20-note@#cwg2681-J {{implicit deduction guide declared as 'template <size_t N> J() -> cwg2681::J<N>'}}
#endif
} // namespace cwg2681
diff --git a/clang/test/CXX/drs/cwg28xx.cpp b/clang/test/CXX/drs/cwg28xx.cpp
index b32e649374893..a6b2b99e0c3f1 100644
--- a/clang/test/CXX/drs/cwg28xx.cpp
+++ b/clang/test/CXX/drs/cwg28xx.cpp
@@ -227,12 +227,12 @@ void f() {
auto L2 = [&](this auto&& self) { (void) &x; };
O1<decltype(L1)>{L1, L1}();
/* since-cxx23-error-re at -1 {{inaccessible due to ambiguity:
- struct cwg2881::O1<class (lambda at {{.+}})> -> A<(lambda at {{.+}})> -> class (lambda at {{.+}})
- struct cwg2881::O1<class (lambda at {{.+}})> -> B<(lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
+ struct cwg2881::O1<class (lambda at {{.+}})> -> A<class (lambda at {{.+}})> -> class (lambda at {{.+}})
+ struct cwg2881::O1<class (lambda at {{.+}})> -> B<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
O1<decltype(L2)>{L2, L2}();
/* since-cxx23-error-re at -1 {{inaccessible due to ambiguity:
- struct cwg2881::O1<class (lambda at {{.+}})> -> A<(lambda at {{.+}})> -> class (lambda at {{.+}})
- struct cwg2881::O1<class (lambda at {{.+}})> -> B<(lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
+ struct cwg2881::O1<class (lambda at {{.+}})> -> A<class (lambda at {{.+}})> -> class (lambda at {{.+}})
+ struct cwg2881::O1<class (lambda at {{.+}})> -> B<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
O2{L1}();
// since-cxx23-error-re at -1 {{invalid explicit object parameter type 'cwg2881::O2<(lambda at {{.+}})>' in lambda with capture; the type must derive publicly from the lambda}}
// since-cxx23-note@#cwg2881-O2 {{declared protected here}}
@@ -277,7 +277,7 @@ struct Indirect : T {
template<typename T>
struct Ambiguous : Indirect<T>, T {
/* since-cxx23-warning-re at -1 {{direct base '(lambda at {{.+}})' is inaccessible due to ambiguity:
- struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<(lambda at {{.+}})> -> class (lambda at {{.+}})
+ struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<class (lambda at {{.+}})> -> class (lambda at {{.+}})
struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
// since-cxx23-note-re@#cwg2881-f4 {{in instantiation of template class 'cwg2881::Ambiguous<(lambda at {{.+}})>' requested here}}
// since-cxx34-note-re@#cwg2881-f4-call {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}}
@@ -303,7 +303,7 @@ void g() {
// expected-error at -1 {{no matching function for call to 'f4'}}
// expected-note-re at -2 {{while substituting deduced template arguments into function template 'f4' [with L = (lambda at {{.+}})]}}
/* expected-note-re@#cwg2881-f4 {{candidate template ignored: substitution failure [with L = (lambda at {{.+}})]: lambda '(lambda at {{.+}})' is inaccessible due to ambiguity:
- struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<(lambda at {{.+}})> -> class (lambda at {{.+}})
+ struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> Indirect<class (lambda at {{.+}})> -> class (lambda at {{.+}})
struct cwg2881::Ambiguous<class (lambda at {{.+}})> -> class (lambda at {{.+}})}}*/
static_assert(!is_callable<Private<decltype(lambda)>>);
static_assert(!is_callable<Ambiguous<decltype(lambda)>>);
diff --git a/clang/test/CXX/drs/cwg2xx.cpp b/clang/test/CXX/drs/cwg2xx.cpp
index a53a8d1ed64a8..d78cef8bf1d5f 100644
--- a/clang/test/CXX/drs/cwg2xx.cpp
+++ b/clang/test/CXX/drs/cwg2xx.cpp
@@ -98,8 +98,8 @@ template <class T> class Templ { // #cwg203-ex3-Templ
void foo() { Templ<Derived> x(&Derived::func); }
// expected-error at -1 {{no matching constructor for initialization of 'Templ<Derived>'}}
-// expected-note@#cwg203-ex3-Templ {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int (Derived::*)() const' (aka 'int (Base::*)() const') to 'const Templ<cwg203::ex3::Derived>' for 1st argument}}
-// since-cxx11-note@#cwg203-ex3-Templ {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int (Derived::*)() const' (aka 'int (Base::*)() const') to 'Templ<cwg203::ex3::Derived>' for 1st argument}}
+// expected-note@#cwg203-ex3-Templ {{candidate constructor (the implicit copy constructor) not viable: no known conversion from 'int (Derived::*)() const' (aka 'int (cwg203::ex3::Base::*)() const') to 'const Templ<cwg203::ex3::Derived>' for 1st argument}}
+// since-cxx11-note@#cwg203-ex3-Templ {{candidate constructor (the implicit move constructor) not viable: no known conversion from 'int (Derived::*)() const' (aka 'int (cwg203::ex3::Base::*)() const') to 'Templ<cwg203::ex3::Derived>' for 1st argument}}
// expected-note@#cwg203-ex3-Templ-ctor {{candidate template ignored: could not match 'cwg203::ex3::Derived' against 'cwg203::ex3::Base'}}
} // namespace ex3
@@ -690,8 +690,8 @@ namespace cwg244 { // cwg244: 11
void f() {
D_object.~B();
- // expected-error at -1 {{destructor type 'cwg244::B' in object destruction expression does not match the type 'D' of the object being destroyed}}
- // expected-note@#cwg244-B {{type 'cwg244::B' found by destructor name lookup}}
+ // expected-error at -1 {{destructor type 'B' in object destruction expression does not match the type 'D' of the object being destroyed}}
+ // expected-note@#cwg244-B {{type 'B' found by destructor name lookup}}
D_object.B::~B();
D_object.D::~B(); // FIXME: Missing diagnostic for this.
B_ptr->~B();
@@ -1400,7 +1400,7 @@ namespace cwg298 { // cwg298: 3.1
// expected-error at -1 {{a type specifier is required for all declarations}}
B::A() {} // ok
C::~C() {}
- // expected-error at -1 {{destructor cannot be declared using a typedef 'C' (aka 'const cwg298::A') of the class name}}
+ // expected-error at -1 {{destructor cannot be declared using a typedef 'C' (aka 'const A') of the class name}}
typedef struct D E; // #cwg298-E
struct E {};
diff --git a/clang/test/CXX/drs/cwg3xx.cpp b/clang/test/CXX/drs/cwg3xx.cpp
index 8b035cf6f2370..5d09697a3cf6b 100644
--- a/clang/test/CXX/drs/cwg3xx.cpp
+++ b/clang/test/CXX/drs/cwg3xx.cpp
@@ -143,7 +143,7 @@ namespace cwg305 { // cwg305: no
void h(B *b) {
struct B {}; // #cwg305-h-B
b->~B();
- // expected-error at -1 {{destructor type 'B' in object destruction expression does not match the type 'B' (aka 'cwg305::A') of the object being destroyed}}
+ // expected-error at -1 {{destructor type 'B' in object destruction expression does not match the type 'B' (aka 'A') of the object being destroyed}}
// expected-note@#cwg305-h-B {{type 'B' found by destructor name lookup}}
}
@@ -1027,7 +1027,7 @@ namespace cwg357 { // cwg357: 2.7
void f() const; // #cwg357-f
};
template<typename T> void A<T>::f() {}
- // expected-error at -1 {{out-of-line definition of 'f' does not match any declaration in 'A<T>'}}
+ // expected-error at -1 {{out-of-line definition of 'f' does not match any declaration in 'cwg357::A<T>'}}
// expected-note@#cwg357-A {{defined here}}
// expected-note@#cwg357-f {{member declaration does not match because it is const qualified}}
@@ -1800,8 +1800,8 @@ namespace cwg399 { // cwg399: 11
void f() {
D_object.~B();
- // expected-error at -1 {{destructor type 'cwg399::B' in object destruction expression does not match the type 'D' of the object being destroyed}}
- // expected-note@#cwg399-B {{type 'cwg399::B' found by destructor name lookup}}
+ // expected-error at -1 {{destructor type 'B' in object destruction expression does not match the type 'D' of the object being destroyed}}
+ // expected-note@#cwg399-B {{type 'B' found by destructor name lookup}}
D_object.B::~B();
D_object.D::~B(); // FIXME: Missing diagnostic for this.
B_ptr->~B();
diff --git a/clang/test/CXX/drs/cwg4xx.cpp b/clang/test/CXX/drs/cwg4xx.cpp
index dc53ae712a0b5..8497f974b2ece 100644
--- a/clang/test/CXX/drs/cwg4xx.cpp
+++ b/clang/test/CXX/drs/cwg4xx.cpp
@@ -1185,7 +1185,7 @@ namespace cwg480 { // cwg480: 2.7
extern int D::*c;
int A::*d = static_cast<int A::*>(c);
- // expected-error at -1 {{conversion from pointer to member of class 'D' to pointer to member of class 'A' via virtual base 'cwg480::B' is not allowed}}
+ // expected-error at -1 {{conversion from pointer to member of class 'cwg480::D' to pointer to member of class 'A' via virtual base 'cwg480::B' is not allowed}}
D *e;
A *f = e;
diff --git a/clang/test/CXX/drs/cwg6xx.cpp b/clang/test/CXX/drs/cwg6xx.cpp
index e2eb009508b52..659fa499a2f49 100644
--- a/clang/test/CXX/drs/cwg6xx.cpp
+++ b/clang/test/CXX/drs/cwg6xx.cpp
@@ -383,7 +383,7 @@ namespace cwg635 { // cwg635: 2.7
template<typename T> template<typename U> D<T>::D() {}
template<typename T> D<T>::D<T>() {} // #cwg635-D-T
// expected-error@#cwg635-D-T {{out-of-line constructor for 'D' cannot have template arguments}}
- // expected-error@#cwg635-D-T {{redefinition of 'D<T>'}}
+ // expected-error@#cwg635-D-T {{redefinition of 'cwg635::D<T>'}}
// expected-note@#cwg635-D {{previous definition is here}}
} // namespace cwg635
@@ -895,12 +895,12 @@ namespace cwg666 { // cwg666: 2.8
template<int> int f();
template<typename T> int f() {
T::type *p = 0;
- // expected-error at -1 {{missing 'typename' prior to dependent type name 'Y::type'}}
+ // expected-error at -1 {{missing 'typename' prior to dependent type name 'cwg666::Y::type'}}
// expected-note@#cwg666-f-Y {{in instantiation of function template specialization 'cwg666::f<cwg666::Y>' requested here}}
int a(T::type);
- // expected-error at -1 {{missing 'typename' prior to dependent type name 'Y::type'}}
+ // expected-error at -1 {{missing 'typename' prior to dependent type name 'cwg666::Y::type'}}
return f<T::type>();
- // expected-error at -1 {{missing 'typename' prior to dependent type name 'Y::type'}}
+ // expected-error at -1 {{missing 'typename' prior to dependent type name 'cwg666::Y::type'}}
}
struct X { static const int type = 0; };
struct Y { typedef int type; };
diff --git a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
index dc0e84280e056..31587a956b8ab 100644
--- a/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
+++ b/clang/test/CXX/expr/expr.prim/expr.prim.req/compound-requirement.cpp
@@ -160,7 +160,7 @@ namespace std_example {
template<typename T> concept C2 =
requires(T x) {
{*x} -> same_as<typename T::inner>;
- // expected-note at -1{{because type constraint 'same_as<int, typename T2::inner>' was not satisfied:}}
+ // expected-note at -1{{because type constraint 'same_as<int, typename std_example::T2::inner>' was not satisfied:}}
// expected-note at -2{{because '*x' would be invalid: indirection requires pointer operand ('int' invalid)}}
};
diff --git a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
index d192070132d78..a32295ee224fb 100644
--- a/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
+++ b/clang/test/CXX/over/over.match/over.match.funcs/over.match.class.deduct/p2.cpp
@@ -37,7 +37,7 @@ namespace std {
namespace p0702r1 {
template<typename T> struct X { // expected-note {{candidate}} expected-note {{implicit deduction guide}}
X(std::initializer_list<T>); // expected-note {{candidate template ignored: could not match 'std::initializer_list<T>' against 'Z'}} \
- // expected-note {{implicit deduction guide declared as 'template <typename T> X(std::initializer_list<T>) -> X<T>'}}
+ // expected-note {{implicit deduction guide declared as 'template <typename T> X(std::initializer_list<T>) -> p0702r1::X<T>'}}
};
X xi = {0};
diff --git a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
index 01ce33b6ef51d..4b93d865c8b19 100644
--- a/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
+++ b/clang/test/CXX/temp/temp.arg/temp.arg.nontype/p5.cpp
@@ -238,9 +238,9 @@ namespace pointer_to_member_data {
X0<&Y::y> x0a;
X0<&Y::x> x0b;
#if __cplusplus <= 201402L
- // expected-error at -2 {{non-type template argument of type 'int Y::*' (aka 'int X::*') cannot be converted to a value of type 'int Y::*'}}
+ // expected-error at -2 {{non-type template argument of type 'int Y::*' (aka 'int pointer_to_member_data::X::*') cannot be converted to a value of type 'int Y::*'}}
#else
- // expected-error at -4 {{conversion from 'int Y::*' (aka 'int X::*') to 'int Y::*' is not allowed in a converted constant expression}}
+ // expected-error at -4 {{conversion from 'int Y::*' (aka 'int pointer_to_member_data::X::*') to 'int Y::*' (aka 'int pointer_to_member_data::Y::*') is not allowed in a converted constant expression}}
#endif
// Test qualification conversions
diff --git a/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp b/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
index 9a8148bdf625f..499e6abc1df1a 100644
--- a/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
+++ b/clang/test/CXX/temp/temp.constr/temp.constr.decl/func-template-decl.cpp
@@ -54,7 +54,7 @@ struct TA { // #defined-here
template <unsigned N>
template <template <unsigned> class TT> int TA<N>::A() { return sizeof(TT<N>); }
-// expected-error at -1{{out-of-line definition of 'A' does not match any declaration in 'TA<N>'}}
+// expected-error at -1{{out-of-line definition of 'A' does not match any declaration in 'diag::TA<N>'}}
// expected-note@#defined-here{{defined here}}
} // end namespace diag
diff --git a/clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp b/clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
index 2da0382accff3..5345b080ea3da 100644
--- a/clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
+++ b/clang/test/CXX/temp/temp.decls/temp.class.spec/p6.cpp
@@ -38,7 +38,7 @@ A<short>::C::B<int*> absip;
template<typename T, typename U>
struct Outer {
template<typename X, typename Y> struct Inner;
- template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous declaration of class template partial specialization 'Inner<int, Y>' is here}}
+ template<typename Y> struct Inner<T, Y> {}; // expected-note{{previous declaration of class template partial specialization 'Outer<int, int>::Inner<int, Y>' is here}}
template<typename Y> struct Inner<U, Y> {}; // expected-error{{cannot be redeclared}}
};
@@ -80,7 +80,7 @@ namespace print_dependent_TemplateSpecializationType {
template <class T, class U> struct Foo {
template <unsigned long, class X, class Y> struct Bar;
template <class Y> struct Bar<0, T, Y> {};
- // expected-note-re at -1 {{previous declaration {{.*}} 'Bar<0, int, Y>' is here}}
+ // expected-note-re at -1 {{previous declaration {{.*}} 'print_dependent_TemplateSpecializationType::Foo<int, int>::Bar<0, int, Y>' is here}}
template <class Y> struct Bar<0, U, Y> {};
// expected-error at -1 {{partial specialization 'Bar<0, int, Y>' cannot be redeclared}}
};
diff --git a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
index 7d5be01a8d017..1eb35ab221ea4 100644
--- a/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
+++ b/clang/test/CXX/temp/temp.fct.spec/temp.deduct/temp.deduct.call/p3-0x.cpp
@@ -78,9 +78,9 @@ namespace std_example {
template<class T> struct A { // expected-note {{candidate}} expected-note {{implicit deduction guide}}
template<class U>
A(T &&, U &&, int *); // expected-note {{[with T = int, U = int] not viable: expects an rvalue}} \
- // expected-note {{implicit deduction guide declared as 'template <class T, class U> A(T &&, U &&, int *) -> A<T>'}}
+ // expected-note {{implicit deduction guide declared as 'template <class T, class U> A(T &&, U &&, int *) -> std_example::A<T>'}}
A(T &&, int *); // expected-note {{requires 2}} \
- // expected-note {{implicit deduction guide declared as 'template <class T> A(T &&, int *) -> A<T>'}}
+ // expected-note {{implicit deduction guide declared as 'template <class T> A(T &&, int *) -> std_example::A<T>'}}
};
template<class T> A(T &&, int *) -> A<T>; // expected-note {{requires 2}}
diff --git a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
index 83144a494937b..238490c3e0d82 100644
--- a/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
+++ b/clang/test/CXX/temp/temp.param/p15-cxx0x.cpp
@@ -97,14 +97,14 @@ template<unsigned N, typename...Ts> struct drop {
using T1 = take<3, int, char, double, long>::type; // expected-note {{previous}}
// FIXME: Desguar the types on the RHS in this diagnostic.
// desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, (no argument)>'}}
-using T1 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, (no argument)>'}}
+using T1 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename ParameterPackExpansions::wrap<int>::inner<_>::type, typename ParameterPackExpansions::wrap<char>::inner<_>::type, typename ParameterPackExpansions::wrap<double>::inner<_>::type, (no argument)>'}}
using D1 = drop<3, int, char, double, long>::type;
using D1 = types<long>;
using T2 = take<4, int, char, double, long>::type; // expected-note {{previous}}
// FIXME: Desguar the types on the RHS in this diagnostic.
// desired-error {{'types<void, void, void, void>' vs 'types<int, char, double, long>'}}
-using T2 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename inner<_>::type, typename inner<_>::type, typename inner<_>::type, typename inner<_>::type>'}}
+using T2 = types<void, void, void, void>; // expected-error {{'types<void, void, void, void>' vs 'types<typename ParameterPackExpansions::wrap<int>::inner<_>::type, typename ParameterPackExpansions::wrap<char>::inner<_>::type, typename ParameterPackExpansions::wrap<double>::inner<_>::type, typename ParameterPackExpansions::wrap<long>::inner<_>::type>'}}
using T2 = types<int, char, double, long>;
using D2 = drop<4, int, char, double, long>::type;
using D2 = types<>;
diff --git a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
index f32f49ef4539a..75805a764c666 100644
--- a/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
+++ b/clang/test/CXX/temp/temp.res/temp.dep/temp.dep.type/p4.cpp
@@ -326,52 +326,52 @@ namespace N0 {
// None of the following should be found in the current instantiation.
new M4; // expected-error{{unknown type name 'M4'}}
- new B::M4; // expected-error{{no type named 'M4' in 'B<T>'}}
+ new B::M4; // expected-error{{no type named 'M4' in 'N0::B<T>'}}
new A::M4; // expected-error{{no type named 'M4' in 'N0::A'}}
new B::A::M4; // expected-error{{no type named 'M4' in 'N0::A'}}
x4; // expected-error{{use of undeclared identifier 'x4'}}
- B::x4; // expected-error{{no member named 'x4' in 'B<T>'}}
+ B::x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
B::A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
f4(); // expected-error{{use of undeclared identifier 'f4'}}
- B::f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
+ B::f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
B::A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
- this->x4; // expected-error{{no member named 'x4' in 'B<T>'}}
- this->B::x4; // expected-error{{no member named 'x4' in 'B<T>'}}
+ this->x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
+ this->B::x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
this->A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
this->B::A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
- this->f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
- this->B::f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
+ this->f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
+ this->B::f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
this->A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
this->B::A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
- a->x4; // expected-error{{no member named 'x4' in 'B<T>'}}
- a->B::x4; // expected-error{{no member named 'x4' in 'B<T>'}}
+ a->x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
+ a->B::x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
a->A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
a->B::A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
- a->f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
- a->B::f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
+ a->f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
+ a->B::f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
a->A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
a->B::A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
- (*this).x4; // expected-error{{no member named 'x4' in 'B<T>'}}
- (*this).B::x4; // expected-error{{no member named 'x4' in 'B<T>'}}
+ (*this).x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
+ (*this).B::x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
(*this).A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
(*this).B::A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
- (*this).f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
- (*this).B::f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
+ (*this).f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
+ (*this).B::f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
(*this).A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
(*this).B::A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
- b.x4; // expected-error{{no member named 'x4' in 'B<T>'}}
- b.B::x4; // expected-error{{no member named 'x4' in 'B<T>'}}
+ b.x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
+ b.B::x4; // expected-error{{no member named 'x4' in 'N0::B<T>'}}
b.A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
b.B::A::x4; // expected-error{{no member named 'x4' in 'N0::A'}}
- b.f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
- b.B::f4(); // expected-error{{no member named 'f4' in 'B<T>'}}
+ b.f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
+ b.B::f4(); // expected-error{{no member named 'f4' in 'N0::B<T>'}}
b.A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
b.B::A::f4(); // expected-error{{no member named 'f4' in 'N0::A'}}
}
@@ -424,7 +424,7 @@ namespace N2 {
void not_instantiated(A *a, B *b) {
b->x; // expected-error{{no member named 'x' in 'N2::A::B'}}
b->B::x; // expected-error{{no member named 'x' in 'N2::A::B'}}
- a->B::C::x; // expected-error{{no member named 'x' in 'A<T>'}}
+ a->B::C::x; // expected-error{{no member named 'x' in 'N2::A<T>'}}
}
};
diff --git a/clang/test/CodeGen/builtin-bpf-btf-type-id.c b/clang/test/CodeGen/builtin-bpf-btf-type-id.c
index 4c6efd69eb956..c8f29ee5fe4ab 100644
--- a/clang/test/CodeGen/builtin-bpf-btf-type-id.c
+++ b/clang/test/CodeGen/builtin-bpf-btf-type-id.c
@@ -21,5 +21,5 @@ unsigned test3() {
//
// CHECK: ![[INT]] = !DIBasicType(name: "int", size: 32, encoding: DW_ATE_signed
// CHECK: ![[INT_POINTER]] = !DIDerivedType(tag: DW_TAG_pointer_type, baseType: ![[INT]], size: 64
-// CHECK: ![[STRUCT_T1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1"
// CHECK: ![[TYPEDEF_T1]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__t1"
+// CHECK: ![[STRUCT_T1]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "t1"
diff --git a/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c b/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c
index 53b448908a0a6..a8cc073974604 100644
--- a/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c
+++ b/clang/test/CodeGen/builtins-bpf-preserve-field-info-3.c
@@ -37,5 +37,5 @@ unsigned unit3() {
// CHECK: call i32 @llvm.bpf.preserve.type.info(i32 5, i64 1), !dbg !{{[0-9]+}}, !llvm.preserve.access.index ![[ENUM_AA]]
// CHECK: ![[ENUM_AA]] = !DICompositeType(tag: DW_TAG_enumeration_type, name: "AA"
-// CHECK: ![[STRUCT_S]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s"
// CHECK: ![[TYPEDEF_INT]] = !DIDerivedType(tag: DW_TAG_typedef, name: "__int"
+// CHECK: ![[STRUCT_S]] = distinct !DICompositeType(tag: DW_TAG_structure_type, name: "s"
diff --git a/clang/test/Index/Core/index-instantiated-source.cpp b/clang/test/Index/Core/index-instantiated-source.cpp
index 2a67a3a3c7938..91be4a4138f24 100644
--- a/clang/test/Index/Core/index-instantiated-source.cpp
+++ b/clang/test/Index/Core/index-instantiated-source.cpp
@@ -73,8 +73,8 @@ void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
typedef TemplateClass<int, float> TT;
TT::NestedType::SubNestedType subNestedType(0);
-// CHECK: [[@LINE-1]]:7 | struct/C++ | NestedType | c:@ST>2#T#T at TemplateClass@S at NestedType |
-// CHECK: [[@LINE-2]]:19 | class/C++ | SubNestedType | c:@ST>2#T#T at TemplateClass@S at NestedType@S at SubNestedType |
+// CHECK: [[@LINE-1]]:19 | class/C++ | SubNestedType | c:@ST>2#T#T at TemplateClass@S at NestedType@S at SubNestedType |
+// CHECK: [[@LINE-2]]:7 | struct/C++ | NestedType | c:@ST>2#T#T at TemplateClass@S at NestedType |
TT::NestedType::TypeAlias nestedTypeAlias;
// CHECK: [[@LINE-1]]:19 | type-alias/C++ | TypeAlias | c:@ST>2#T#T at TemplateClass@S at NestedType@TypeAlias |
diff --git a/clang/test/Index/Core/index-source.cpp b/clang/test/Index/Core/index-source.cpp
index 043e616a1d366..36bc663b89684 100644
--- a/clang/test/Index/Core/index-source.cpp
+++ b/clang/test/Index/Core/index-source.cpp
@@ -525,9 +525,9 @@ struct Outer {
template<>
struct rd33122110::Outer::Nested<int>;
-// CHECK: [[@LINE-1]]:8 | namespace/C++ | rd33122110 | c:@N at rd33122110 | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-1]]:20 | struct/C++ | Outer | c:@N at rd33122110@S at Outer | <no-cgname> | Ref,RelCont | rel: 1
// CHECK-NEXT: RelCont | Nested | c:@N at rd33122110@S at Outer@S at Nested>#I
-// CHECK: [[@LINE-3]]:20 | struct/C++ | Outer | c:@N at rd33122110@S at Outer | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:8 | namespace/C++ | rd33122110 | c:@N at rd33122110 | <no-cgname> | Ref,RelCont | rel: 1
// CHECK-NEXT: RelCont | Nested | c:@N at rd33122110@S at Outer@S at Nested>#I
namespace index_offsetof {
diff --git a/clang/test/Index/c-index-api-loadTU-test.m b/clang/test/Index/c-index-api-loadTU-test.m
index eb3fde08a36fd..8ddb193e42428 100644
--- a/clang/test/Index/c-index-api-loadTU-test.m
+++ b/clang/test/Index/c-index-api-loadTU-test.m
@@ -164,7 +164,7 @@ @interface TestAttributes()
// CHECK: c-index-api-loadTU-test.m:66:28: TypeRef=id:0:0 Extent=[66:28 - 66:30]
// CHECK: c-index-api-loadTU-test.m:69:16: StructDecl=X0:69:16 Extent=[69:9 - 69:18]
// CHECK: c-index-api-loadTU-test.m:69:19: TypedefDecl=X1:69:19 (Definition) Extent=[69:1 - 69:21]
-// CHECK: c-index-api-loadTU-test.m:69:16: TypeRef=struct X0:71:8 Extent=[69:16 - 69:18]
+// CHECK: c-index-api-loadTU-test.m:69:16: TypeRef=struct X0:69:16 Extent=[69:16 - 69:18]
// CHECK: c-index-api-loadTU-test.m:70:8: StructDecl=X0:70:8 Extent=[70:1 - 70:10]
// CHECK: c-index-api-loadTU-test.m:71:8: StructDecl=X0:71:8 (Definition) Extent=[71:1 - 71:14]
// CHECK: c-index-api-loadTU-test.m:73:12: ObjCCategoryDecl=:73:12 Extent=[73:1 - 76:5]
diff --git a/clang/test/Index/copy-assignment-operator.cpp b/clang/test/Index/copy-assignment-operator.cpp
index 7f741931f9cef..46902c04e21c8 100644
--- a/clang/test/Index/copy-assignment-operator.cpp
+++ b/clang/test/Index/copy-assignment-operator.cpp
@@ -32,7 +32,7 @@ class Bar {
// CHECK: CXXMethod=operator=:4:10 (copy-assignment operator) [type=bool (Foo &)] [typekind=FunctionProto] [canonicaltype=bool (Foo &)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Foo &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:5:10 (copy-assignment operator) [type=bool (volatile Foo &)] [typekind=FunctionProto] [canonicaltype=bool (volatile Foo &)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [volatile Foo &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:6:10 (copy-assignment operator) [type=bool (const volatile Foo &)] [typekind=FunctionProto] [canonicaltype=bool (const volatile Foo &)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [const volatile Foo &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
-// CHECK: CXXMethod=operator=:7:10 (copy-assignment operator) [type=bool (Foo)] [typekind=FunctionProto] [canonicaltype=bool (Foo)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Foo] [Elaborated]] [isPOD=0] [isAnonRecDecl=0]
+// CHECK: CXXMethod=operator=:7:10 (copy-assignment operator) [type=bool (Foo)] [typekind=FunctionProto] [canonicaltype=bool (Foo)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Foo] [Record]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: FunctionTemplate=operator=:11:10 [type=bool (const T &)] [typekind=FunctionProto] [canonicaltype=bool (const type-parameter-0-0 &)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:12:10 [type=bool (const bool &)] [typekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [const bool &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:13:10 [type=bool (char &)] [typekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [char &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
@@ -44,4 +44,4 @@ class Bar {
// CHECK: CXXMethod=operator=:23:10 (copy-assignment operator) [type=bool (Bar<T> &)] [typekind=FunctionProto] [canonicaltype=bool (Bar<T> &)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Bar<T> &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:24:10 (copy-assignment operator) [type=bool (volatile Bar<T> &)] [typekind=FunctionProto] [canonicaltype=bool (volatile Bar<T> &)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [volatile Bar<T> &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:25:10 (copy-assignment operator) [type=bool (const volatile Bar<T> &)] [typekind=FunctionProto] [canonicaltype=bool (const volatile Bar<T> &)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [const volatile Bar<T> &] [LValueReference]] [isPOD=0] [isAnonRecDecl=0]
-// CHECK: CXXMethod=operator=:26:10 (copy-assignment operator) [type=bool (Bar<T>)] [typekind=FunctionProto] [canonicaltype=bool (Bar<T>)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Bar<T>] [Elaborated]] [isPOD=0] [isAnonRecDecl=0]
+// CHECK: CXXMethod=operator=:26:10 (copy-assignment operator) [type=bool (Bar<T>)] [typekind=FunctionProto] [canonicaltype=bool (Bar<T>)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Bar<T>] [Unexposed]] [isPOD=0] [isAnonRecDecl=0]
diff --git a/clang/test/Index/index-refs.cpp b/clang/test/Index/index-refs.cpp
index 14946849777d4..22eb7532ffad6 100644
--- a/clang/test/Index/index-refs.cpp
+++ b/clang/test/Index/index-refs.cpp
@@ -81,13 +81,13 @@ int ginitlist[] = {EnumVal};
// CHECK-NEXT: [indexDeclaration]: kind: enum
// CHECK-NEXT: [indexDeclaration]: kind: enumerator | name: EnumVal
// CHECK-NEXT: [indexDeclaration]: kind: variable | name: gx
-// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS
// CHECK-NEXT: [indexEntityReference]: kind: typedef | name: MyInt
// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS
// CHECK-NEXT: [indexEntityReference]: kind: enumerator | name: EnumVal
// CHECK-NEXT: [indexDeclaration]: kind: function | name: foo
-// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS
// CHECK-NEXT: [indexEntityReference]: kind: typedef | name: MyInt
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS
// CHECK-NEXT: [indexDeclaration]: kind: enum
// CHECK-NEXT: [indexDeclaration]: kind: enumerator | name: SecondVal
// CHECK-NEXT: [indexEntityReference]: kind: enumerator | name: EnumVal
diff --git a/clang/test/Index/keep-going.cpp b/clang/test/Index/keep-going.cpp
index 635415178cf09..0b2df725a5a73 100644
--- a/clang/test/Index/keep-going.cpp
+++ b/clang/test/Index/keep-going.cpp
@@ -26,10 +26,10 @@ class C : public A<float> { };
// CHECK: FieldDecl=a:4:13 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
// CHECK: TypeRef=T:3:16 [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
// CHECK: ClassDecl=B:6:7 (Definition) [type=B] [typekind=Record] [isPOD=0]
-// CHECK: C++ base class specifier=A<int>:4:7 [access=public isVirtual=false] [type=A<int>] [typekind=Elaborated] [templateargs/1= [type=int] [typekind=Int]] [canonicaltype=A<int>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=int] [typekind=Int]] [isPOD=0] [nbFields=1]
+// CHECK: C++ base class specifier=A<int>:4:7 [access=public isVirtual=false] [type=A<int>] [typekind=Unexposed] [templateargs/1= [type=int] [typekind=Int]] [canonicaltype=A<int>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=int] [typekind=Int]] [isPOD=0] [nbFields=1]
// CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: ClassDecl=C:10:7 (Definition) [type=C] [typekind=Record] [isPOD=0]
-// CHECK: C++ base class specifier=A<float>:4:7 [access=public isVirtual=false] [type=A<float>] [typekind=Elaborated] [templateargs/1= [type=float] [typekind=Float]] [canonicaltype=A<float>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=float] [typekind=Float]] [isPOD=0] [nbFields=1]
+// CHECK: C++ base class specifier=A<float>:4:7 [access=public isVirtual=false] [type=A<float>] [typekind=Unexposed] [templateargs/1= [type=float] [typekind=Float]] [canonicaltype=A<float>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=float] [typekind=Float]] [isPOD=0] [nbFields=1]
// CHECK: TemplateRef=A:4:7 [type=] [typekind=Invalid] [isPOD=0]
// CHECK-KEEP-GOING-ONLY: VarDecl=global_var:1:12 [type=int] [typekind=Int] [isPOD=1]
diff --git a/clang/test/Index/move-assignment-operator.cpp b/clang/test/Index/move-assignment-operator.cpp
index a2c71e679e0c6..d6c4e9a64789f 100644
--- a/clang/test/Index/move-assignment-operator.cpp
+++ b/clang/test/Index/move-assignment-operator.cpp
@@ -37,7 +37,7 @@ class Bar {
// CHECK: CXXMethod=operator=:13:10 [type=bool (volatile unsigned int &&)] [typekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [volatile unsigned int &&] [RValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:14:10 [type=bool (const volatile unsigned char &&)] [typekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [const volatile unsigned char &&] [RValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:15:10 [type=bool (int)] [typekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [int] [Int]] [isPOD=0] [isAnonRecDecl=0]
-// CHECK: CXXMethod=operator=:16:10 (copy-assignment operator) [type=bool (Foo)] [typekind=FunctionProto] [canonicaltype=bool (Foo)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Foo] [Elaborated]] [isPOD=0] [isAnonRecDecl=0]
+// CHECK: CXXMethod=operator=:16:10 (copy-assignment operator) [type=bool (Foo)] [typekind=FunctionProto] [canonicaltype=bool (Foo)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Foo] [Record]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: ClassTemplate=Bar:21:7 (Definition) [type=] [typekind=Invalid] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:22:10 (move-assignment operator) [type=bool (const Bar<T> &&)] [typekind=FunctionProto] [canonicaltype=bool (const Bar<T> &&)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [const Bar<T> &&] [RValueReference]] [isPOD=0] [isAnonRecDecl=0]
// CHECK: CXXMethod=operator=:23:10 (move-assignment operator) [type=bool (Bar<T> &&)] [typekind=FunctionProto] [canonicaltype=bool (Bar<T> &&)] [canonicaltypekind=FunctionProto] [resulttype=bool] [resulttypekind=Bool] [args= [Bar<T> &&] [RValueReference]] [isPOD=0] [isAnonRecDecl=0]
diff --git a/clang/test/Index/opencl-types.cl b/clang/test/Index/opencl-types.cl
index 13d7937b85447..485060167d218 100644
--- a/clang/test/Index/opencl-types.cl
+++ b/clang/test/Index/opencl-types.cl
@@ -17,11 +17,11 @@ void kernel testFloatTypes() {
}
// CHECK: VarDecl=scalarHalf:11:8 (Definition){{( \(invalid\))?}} [type=__private half] [typekind=Half] [isPOD=1]
-// CHECK: VarDecl=vectorHalf:12:9 (Definition) [type=__private half4] [typekind=Elaborated] [canonicaltype=half __private __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
+// CHECK: VarDecl=vectorHalf:12:9 (Definition) [type=__private half4] [typekind=Typedef] [canonicaltype=half __private __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
// CHECK: VarDecl=scalarFloat:13:9 (Definition) [type=__private float] [typekind=Float] [isPOD=1]
-// CHECK: VarDecl=vectorFloat:14:10 (Definition) [type=__private float4] [typekind=Elaborated] [canonicaltype=float __private __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
+// CHECK: VarDecl=vectorFloat:14:10 (Definition) [type=__private float4] [typekind=Typedef] [canonicaltype=float __private __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
// CHECK: VarDecl=scalarDouble:15:10 (Definition){{( \(invalid\))?}} [type=__private double] [typekind=Double] [isPOD=1]
-// CHECK: VarDecl=vectorDouble:16:11 (Definition){{( \(invalid\))?}} [type=__private double4] [typekind=Elaborated] [canonicaltype=double __private __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
+// CHECK: VarDecl=vectorDouble:16:11 (Definition){{( \(invalid\))?}} [type=__private double4] [typekind=Typedef] [canonicaltype=double __private __attribute__((ext_vector_type(4)))] [canonicaltypekind=ExtVector] [isPOD=1]
#pragma OPENCL EXTENSION cl_khr_gl_msaa_sharing : enable
@@ -120,10 +120,10 @@ void kernel testMiscOpenCLTypes() {
reserve_id_t scalarOCLReserveID;
}
-// CHECK: VarDecl=scalarOCLSampler:117:19 (Definition) [type=const sampler_t] [typekind=Elaborated] const [canonicaltype=const sampler_t] [canonicaltypekind=OCLSampler] [isPOD=1]
-// CHECK: VarDecl=scalarOCLEvent:118:15 (Definition) [type=__private clk_event_t] [typekind=Elaborated] [canonicaltype=__private clk_event_t] [canonicaltypekind=Unexposed] [isPOD=1]
-// CHECK: VarDecl=scalarOCLQueue:119:11 (Definition) [type=__private queue_t] [typekind=Elaborated] [canonicaltype=__private queue_t] [canonicaltypekind=OCLQueue] [isPOD=1]
-// CHECK: VarDecl=scalarOCLReserveID:120:16 (Definition) [type=__private reserve_id_t] [typekind=Elaborated] [canonicaltype=__private reserve_id_t] [canonicaltypekind=OCLReserveID] [isPOD=1]
+// CHECK: VarDecl=scalarOCLSampler:117:19 (Definition) [type=const sampler_t] [typekind=Typedef] const [canonicaltype=const sampler_t] [canonicaltypekind=OCLSampler] [isPOD=1]
+// CHECK: VarDecl=scalarOCLEvent:118:15 (Definition) [type=__private clk_event_t] [typekind=Typedef] [canonicaltype=__private clk_event_t] [canonicaltypekind=Unexposed] [isPOD=1]
+// CHECK: VarDecl=scalarOCLQueue:119:11 (Definition) [type=__private queue_t] [typekind=Typedef] [canonicaltype=__private queue_t] [canonicaltypekind=OCLQueue] [isPOD=1]
+// CHECK: VarDecl=scalarOCLReserveID:120:16 (Definition) [type=__private reserve_id_t] [typekind=Typedef] [canonicaltype=__private reserve_id_t] [canonicaltypekind=OCLReserveID] [isPOD=1]
#pragma OPENCL EXTENSION cl_intel_device_side_avc_motion_estimation : enable
@@ -131,4 +131,4 @@ void kernel testExtOpenCLTypes() {
intel_sub_group_avc_mce_payload_t mce_payload;
}
-// CHECK: VarDecl=mce_payload:131:37 (Definition){{( \(invalid\))?}} [type=__private intel_sub_group_avc_mce_payload_t] [typekind=Elaborated] [canonicaltype=__private intel_sub_group_avc_mce_payload_t] [canonicaltypekind=OCLIntelSubgroupAVCMcePayload] [isPOD=1]
+// CHECK: VarDecl=mce_payload:131:37 (Definition){{( \(invalid\))?}} [type=__private intel_sub_group_avc_mce_payload_t] [typekind=Typedef] [canonicaltype=__private intel_sub_group_avc_mce_payload_t] [canonicaltypekind=OCLIntelSubgroupAVCMcePayload] [isPOD=1]
diff --git a/clang/test/Index/paren-type.c b/clang/test/Index/paren-type.c
index 09751917a7f44..14a7785e0580d 100644
--- a/clang/test/Index/paren-type.c
+++ b/clang/test/Index/paren-type.c
@@ -9,7 +9,7 @@ extern int (VariableWithParentheses);
typedef int MyTypedef;
// CHECK-TYPE: VarDecl=VariableWithParentheses2:
-// CHECK-TYPE-SAME: [type=MyTypedef] [typekind=Elaborated]
+// CHECK-TYPE-SAME: [type=MyTypedef] [typekind=Typedef]
// CHECK-TYPE-SAME: [canonicaltype=int] [canonicaltypekind=Int]
// CHECK-TYPEDECL: VarDecl=VariableWithParentheses2
// CHECK-TYPEDECL-SAME: [typedeclaration=MyTypedef] [typekind=Typedef]
diff --git a/clang/test/Index/print-type-size.cpp b/clang/test/Index/print-type-size.cpp
index a365528f5bc9f..6a5a02a085693 100644
--- a/clang/test/Index/print-type-size.cpp
+++ b/clang/test/Index/print-type-size.cpp
@@ -45,8 +45,8 @@ union u {
struct simple s1;
};
-// CHECK64: VarDecl=s1:[[@LINE+2]]:8 (Definition) [type=simple] [typekind=Elaborated] [sizeof=48] [alignof=8]
-// CHECK32: VarDecl=s1:[[@LINE+1]]:8 (Definition) [type=simple] [typekind=Elaborated] [sizeof=36] [alignof=4]
+// CHECK64: VarDecl=s1:[[@LINE+2]]:8 (Definition) [type=simple] [typekind=Record] [sizeof=48] [alignof=8]
+// CHECK32: VarDecl=s1:[[@LINE+1]]:8 (Definition) [type=simple] [typekind=Record] [sizeof=36] [alignof=4]
simple s1;
struct Test {
@@ -354,8 +354,8 @@ struct BaseStruct
BaseStruct(){}
double v0;
float v1;
-// CHECK64: FieldDecl=fg:[[@LINE+2]]:7 (Definition) [type=C] [typekind=Elaborated] [sizeof=88] [alignof=8] [offsetof=128]
-// CHECK32: FieldDecl=fg:[[@LINE+1]]:7 (Definition) [type=C] [typekind=Elaborated] [sizeof=60] [alignof=4] [offsetof=96]
+// CHECK64: FieldDecl=fg:[[@LINE+2]]:7 (Definition) [type=C] [typekind=Record] [sizeof=88] [alignof=8] [offsetof=128]
+// CHECK32: FieldDecl=fg:[[@LINE+1]]:7 (Definition) [type=C] [typekind=Record] [sizeof=60] [alignof=4] [offsetof=96]
C fg;
// CHECK64: FieldDecl=rg:[[@LINE+2]]:8 (Definition) [type=C &] [typekind=LValueReference] [sizeof=88] [alignof=8] [offsetof=832]
// CHECK32: FieldDecl=rg:[[@LINE+1]]:8 (Definition) [type=C &] [typekind=LValueReference] [sizeof=60] [alignof=4] [offsetof=576]
diff --git a/clang/test/Index/print-type.c b/clang/test/Index/print-type.c
index 7375644f10059..d30f4bed246c5 100644
--- a/clang/test/Index/print-type.c
+++ b/clang/test/Index/print-type.c
@@ -32,10 +32,10 @@ void fun(struct { int x; int y; } *param);
_Atomic(unsigned long) aul;
// RUN: c-index-test -test-print-type %s | FileCheck %s
-// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Elaborated] [int[5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
+// CHECK: FunctionDecl=f:3:6 (Definition) [type=int *(int *, char *, FooType, int *, void (*)(int))] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int, int *, void (*)(int))] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef] [int[5]] [ConstantArray] [void (*)(int)] [Pointer]] [isPOD=0]
// CHECK: ParmDecl=p:3:13 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
// CHECK: ParmDecl=x:3:22 (Definition) [type=char *] [typekind=Pointer] [isPOD=1] [pointeetype=char] [pointeekind=Char_{{[US]}}]
-// CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: ParmDecl=z:3:33 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: ParmDecl=arr:3:40 (Definition) [type=int[5]] [typekind=ConstantArray] [isPOD=1]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
@@ -47,14 +47,14 @@ _Atomic(unsigned long) aul;
// CHECK: UnaryOperator= [type=int] [typekind=Int] [isPOD=1]
// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
// CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: VarDecl=w:5:17 (Definition) [type=const FooType] [typekind=Elaborated] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: VarDecl=w:5:17 (Definition) [type=const FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: TypeRef=FooType:1:13 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
// CHECK: BinaryOperator=+ [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
// CHECK: BinaryOperator=+ [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
// CHECK: DeclRefExpr=p:3:13 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: DeclRefExpr=z:3:33 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: ArraySubscriptExpr= [type=int] [typekind=Int] [isPOD=1]
// CHECK: UnexposedExpr=arr:3:40 [type=int[5]] [typekind=ConstantArray] [isPOD=1]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
@@ -64,10 +64,10 @@ _Atomic(unsigned long) aul;
// CHECK: VarDecl=x:10:38 [type=__attribute__((__vector_size__(4 * sizeof(int)))) int] [typekind=Vector] [isPOD=1]
// CHECK: TypedefDecl=int4_t:11:46 (Definition) [type=int4_t] [typekind=Typedef] [canonicaltype=__attribute__((__vector_size__(4 * sizeof(int)))) int] [canonicaltypekind=Vector] [isPOD=1]
// CHECK: ParmDecl=incompletearray:13:12 (Definition) [type=int[]] [typekind=IncompleteArray] [isPOD=1]
-// CHECK: FunctionDecl=elaboratedEnumType:15:25 [type=enum Enum ()] [typekind=FunctionNoProto] [canonicaltype=enum Enum ()] [canonicaltypekind=FunctionNoProto] [resulttype=enum Enum] [resulttypekind=Elaborated] [isPOD=0]
+// CHECK: FunctionDecl=elaboratedEnumType:15:25 [type=enum Enum ()] [typekind=FunctionNoProto] [canonicaltype=enum Enum ()] [canonicaltypekind=FunctionNoProto] [resulttype=enum Enum] [resulttypekind=Enum] [isPOD=0]
// CHECK: TypeRef=enum Enum:15:6 [type=enum Enum] [typekind=Enum] [isPOD=1]
// CHECK: StructDecl=Struct:16:8 (Definition) [type=struct Struct] [typekind=Record] [isPOD=1]
-// CHECK: FunctionDecl=elaboratedStructType:16:32 [type=struct Struct ()] [typekind=FunctionNoProto] [canonicaltype=struct Struct ()] [canonicaltypekind=FunctionNoProto] [resulttype=struct Struct] [resulttypekind=Elaborated] [isPOD=0]
+// CHECK: FunctionDecl=elaboratedStructType:16:32 [type=struct Struct ()] [typekind=FunctionNoProto] [canonicaltype=struct Struct ()] [canonicaltypekind=FunctionNoProto] [resulttype=struct Struct] [resulttypekind=Record] [isPOD=0]
// CHECK: TypeRef=struct Struct:16:8 [type=struct Struct] [typekind=Record] [isPOD=1]
// CHECK: StructDecl=struct (unnamed at {{.*}}):18:1 (Definition) [type=struct (unnamed at {{.*}}print-type.c:18:1)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
// CHECK: StructDecl=struct (unnamed at {{.*}}):23:1 (Definition) [type=struct (unnamed at {{.*}}print-type.c:23:1)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] [isAnonRecDecl=0]
diff --git a/clang/test/Index/print-type.cpp b/clang/test/Index/print-type.cpp
index 141895d1dd2b2..ef9805f6a1c62 100644
--- a/clang/test/Index/print-type.cpp
+++ b/clang/test/Index/print-type.cpp
@@ -105,38 +105,38 @@ inline namespace InlineNS {}
// CHECK: Namespace=inner:14:11 (Definition) [type=] [typekind=Invalid] [isPOD=0]
// CHECK: StructDecl=Bar:16:8 (Definition) [type=outer::inner::Bar] [typekind=Record] [isPOD=0] [nbFields=3]
// CHECK: CXXConstructor=Bar:17:3 (Definition) (converting constructor) [type=void (outer::Foo<bool> *){{.*}}] [typekind=FunctionProto] [canonicaltype=void (outer::Foo<bool> *){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=void] [resulttypekind=Void] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0]
-// CHECK: ParmDecl=foo:17:25 (Definition) [type=outer::Foo<bool> *] [typekind=Pointer] [canonicaltype=outer::Foo<bool> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=outer::Foo<bool>] [pointeekind=Elaborated]
+// CHECK: ParmDecl=foo:17:25 (Definition) [type=outer::Foo<bool> *] [typekind=Pointer] [canonicaltype=outer::Foo<bool> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=outer::Foo<bool>] [pointeekind=Unexposed]
// CHECK: NamespaceRef=outer:1:11 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: TypedefDecl=FooType:19:15 (Definition) [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypeAliasDecl=AliasType:20:9 (Definition) [type=outer::inner::Bar::AliasType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
+// CHECK: TypedefDecl=FooType:19:15 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypeAliasDecl=AliasType:20:9 (Definition) [type=AliasType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
// CHECK: FieldDecl=p:21:8 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: CXXMethod=f:22:8 (Definition) [type=int *(int *, char *, FooType){{.*}}] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Elaborated]] [isPOD=0]
+// CHECK: CXXMethod=f:22:8 (Definition) [type=int *(int *, char *, FooType){{.*}}] [typekind=FunctionProto] [canonicaltype=int *(int *, char *, int){{.*}}] [canonicaltypekind=FunctionProto] [resulttype=int *] [resulttypekind=Pointer] [args= [int *] [Pointer] [char *] [Pointer] [FooType] [Typedef]] [isPOD=0]
// CHECK: ParmDecl=p:22:15 (Definition) [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
// CHECK: ParmDecl=x:22:24 (Definition) [type=char *] [typekind=Pointer] [isPOD=1] [pointeetype=char] [pointeekind=Char_{{[US]}}]
-// CHECK: ParmDecl=z:22:35 (Definition) [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypeRef=outer::inner::Bar::FooType:19:15 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: ParmDecl=z:22:35 (Definition) [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypeRef=outer::inner::Bar::FooType:19:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
// CHECK: DeclStmt= [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: VarDecl=w:23:19 (Definition) [type=const FooType] [typekind=Elaborated] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypeRef=outer::inner::Bar::FooType:19:15 [type=outer::inner::Bar::FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: UnexposedExpr=z:22:35 [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: DeclRefExpr=z:22:35 [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: VarDecl=w:23:19 (Definition) [type=const FooType] [typekind=Typedef] const [canonicaltype=const int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypeRef=outer::inner::Bar::FooType:19:15 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: UnexposedExpr=z:22:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: DeclRefExpr=z:22:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
// CHECK: BinaryOperator=+ [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
// CHECK: UnexposedExpr=p:22:15 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
// CHECK: DeclRefExpr=p:22:15 [type=int *] [typekind=Pointer] [isPOD=1] [pointeetype=int] [pointeekind=Int]
-// CHECK: UnexposedExpr=z:22:35 [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: DeclRefExpr=z:22:35 [type=FooType] [typekind=Elaborated] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
-// CHECK: TypedefDecl=OtherType:26:18 (Definition) [type=outer::inner::Bar::OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
-// CHECK: TypedefDecl=ArrayType:27:15 (Definition) [type=outer::inner::Bar::ArrayType] [typekind=Typedef] [canonicaltype=int[5]] [canonicaltypekind=ConstantArray] [isPOD=1]
+// CHECK: UnexposedExpr=z:22:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: DeclRefExpr=z:22:35 [type=FooType] [typekind=Typedef] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
+// CHECK: TypedefDecl=OtherType:26:18 (Definition) [type=OtherType] [typekind=Typedef] [canonicaltype=double] [canonicaltypekind=Double] [isPOD=1]
+// CHECK: TypedefDecl=ArrayType:27:15 (Definition) [type=ArrayType] [typekind=Typedef] [canonicaltype=int[5]] [canonicaltypekind=ConstantArray] [isPOD=1]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
-// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, Foo>] [typekind=Elaborated] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, outer::Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
+// CHECK: FieldDecl=baz:28:20 (Definition) [type=Baz<int, 1, Foo>] [typekind=Unexposed] [templateargs/3= [type=int] [typekind=Int]] [canonicaltype=outer::Baz<int, 1, outer::Foo>] [canonicaltypekind=Record] [canonicaltemplateargs/3= [type=int] [typekind=Int]] [isPOD=1]
// CHECK: TemplateRef=Baz:9:8 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: FieldDecl=qux:29:38 (Definition) [type=Qux<int, char *, Foo<int>, FooType>] [typekind=Elaborated] [templateargs/4= [type=int] [typekind=Int] [type=char *] [typekind=Pointer] [type=Foo<int>] [typekind=Elaborated] [type=FooType] [typekind=Elaborated]] [canonicaltype=outer::Qux<int, char *, outer::Foo<int>, int>] [canonicaltypekind=Record] [canonicaltemplateargs/4= [type=int] [typekind=Int] [type=char *] [typekind=Pointer] [type=outer::Foo<int>] [typekind=Record] [type=int] [typekind=Int]] [isPOD=1]
+// CHECK: FieldDecl=qux:29:38 (Definition) [type=Qux<int, char *, Foo<int>, FooType>] [typekind=Unexposed] [templateargs/4= [type=int] [typekind=Int] [type=char *] [typekind=Pointer] [type=Foo<int>] [typekind=Unexposed] [type=FooType] [typekind=Typedef]] [canonicaltype=outer::Qux<int, char *, outer::Foo<int>, int>] [canonicaltypekind=Record] [canonicaltemplateargs/4= [type=int] [typekind=Int] [type=char *] [typekind=Pointer] [type=outer::Foo<int>] [typekind=Record] [type=int] [typekind=Int]] [isPOD=1]
// CHECK: TemplateRef=Qux:12:8 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: TemplateRef=Foo:4:8 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: FunctionTemplate=tbar:36:3 [type=T (int)] [typekind=FunctionProto] [canonicaltype=type-parameter-0-0 (int)] [canonicaltypekind=FunctionProto] [resulttype=T] [resulttypekind=Unexposed] [isPOD=0]
@@ -163,11 +163,11 @@ inline namespace InlineNS {}
// CHECK: DeclRefExpr=i:44:14 [type=int] [typekind=Int] [isPOD=1]
// CHECK: StructDecl=Blob:46:8 (Definition) [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
// CHECK: FieldDecl=i:47:7 (Definition) [type=int] [typekind=Int] [isPOD=1]
-// CHECK: VarDecl=member_pointer:50:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [isPOD=1] [pointeetype=int] [pointeekind=Int] [isAnonRecDecl=0]
-// CHECK: FunctionDecl=elaboratedNamespaceType:52:42 [type=NS::Type (const NS::Type)] [typekind=FunctionProto] [canonicaltype=NS::Type (NS::Type)] [canonicaltypekind=FunctionProto] [resulttype=NS::Type] [resulttypekind=Elaborated] [args= [const NS::Type] [Elaborated]] [isPOD=0]
+// CHECK: VarDecl=member_pointer:50:12 (Definition) [type=int Blob::*] [typekind=MemberPointer] [canonicaltype=int Blob::*] [canonicaltypekind=MemberPointer] [isPOD=1] [pointeetype=int] [pointeekind=Int] [isAnonRecDecl=0]
+// CHECK: FunctionDecl=elaboratedNamespaceType:52:42 [type=NS::Type (const NS::Type)] [typekind=FunctionProto] [canonicaltype=NS::Type (NS::Type)] [canonicaltypekind=FunctionProto] [resulttype=NS::Type] [resulttypekind=Record] [args= [const NS::Type] [Record]] [isPOD=0]
// CHECK: NamespaceRef=NS:52:11 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: TypeRef=struct NS::Type:52:23 [type=NS::Type] [typekind=Record] [isPOD=1]
-// CHECK: ParmDecl=t:52:81 (Definition) [type=const NS::Type] [typekind=Elaborated] const [canonicaltype=const NS::Type] [canonicaltypekind=Record] [isPOD=1]
+// CHECK: ParmDecl=t:52:81 (Definition) [type=const NS::Type] [typekind=Record] const [canonicaltype=const NS::Type] [canonicaltypekind=Record] [isPOD=1]
// CHECK: VarDecl=autoI:54:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: VarDecl=autoTbar:55:6 (Definition) [type=int] [typekind=Auto] [canonicaltype=int] [canonicaltypekind=Int] [isPOD=1]
@@ -176,9 +176,9 @@ inline namespace InlineNS {}
// CHECK: DeclRefExpr=tbar:36:3 RefName=[55:17 - 55:21] RefName=[55:21 - 55:26] [type=int (int)] [typekind=FunctionProto] [canonicaltype=int (int)] [canonicaltypekind=FunctionProto] [isPOD=0]
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: VarDecl=autoBlob:56:6 (Definition) [type=Blob *] [typekind=Auto] [canonicaltype=Blob *] [canonicaltypekind=Pointer] [isPOD=1]
-// CHECK: CXXNewExpr= [type=Blob *] [typekind=Pointer] [canonicaltype=Blob *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=Blob] [pointeekind=Elaborated]
+// CHECK: CXXNewExpr= [type=Blob *] [typekind=Pointer] [canonicaltype=Blob *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=Blob] [pointeekind=Record]
// CHECK: TypeRef=struct Blob:46:8 [type=Blob] [typekind=Record] [isPOD=1] [nbFields=2]
-// CHECK: CallExpr=Blob:46:8 [type=Blob] [typekind=Elaborated] [canonicaltype=Blob] [canonicaltypekind=Record] [isPOD=1] [nbFields=2]
+// CHECK: CallExpr=Blob:46:8 [type=Blob] [typekind=Record] [canonicaltype=Blob] [canonicaltypekind=Record] [isPOD=1] [nbFields=2]
// CHECK: FunctionDecl=autoFunction:57:6 (Definition) [type=int ()] [typekind=FunctionProto] [canonicaltype=int ()] [canonicaltypekind=FunctionProto] [resulttype=int] [resulttypekind=Auto] [isPOD=0]
// CHECK: CompoundStmt= [type=] [typekind=Invalid] [isPOD=0]
// CHECK: ReturnStmt= [type=] [typekind=Invalid] [isPOD=0]
@@ -187,20 +187,20 @@ inline namespace InlineNS {}
// CHECK: IntegerLiteral= [type=int] [typekind=Int] [isPOD=1]
// CHECK: TypeAliasTemplateDecl=TypeAlias:61:1 (Definition) [type=] [typekind=Invalid] [isPOD=0]
// CHECK: TemplateTypeParameter=T:60:20 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
-// CHECK: FieldDecl=foo:63:39 (Definition) [type=TypeAlias<int>] [typekind=Elaborated] [templateargs/1= [type=int] [typekind=Int]] [canonicaltype=outer::Qux<int>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=int] [typekind=Int]] [isPOD=1]
+// CHECK: FieldDecl=foo:63:39 (Definition) [type=TypeAlias<int>] [typekind=Unexposed] [templateargs/1= [type=int] [typekind=Int]] [canonicaltype=outer::Qux<int>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=int] [typekind=Int]] [isPOD=1]
// CHECK: TemplateRef=TypeAlias:61:1 [type=] [typekind=Invalid] [isPOD=0]
// CHECK: ClassTemplate=Specialization:66:8 (Definition) [type=] [typekind=Invalid] [isPOD=0]
// CHECK: TemplateTypeParameter=T:65:19 (Definition) [type=T] [typekind=Unexposed] [canonicaltype=type-parameter-0-0] [canonicaltypekind=Unexposed] [isPOD=0]
// CHECK: StructDecl=Specialization:69:8 [Specialization of Specialization:66:8] [Template arg 0: kind: 1, type: int] [type=Specialization<int>] [typekind=Record] [templateargs/1= [type=int] [typekind=Int]] [isPOD=0]
-// CHECK: VarDecl=templRefParam:71:40 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Elaborated] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: VarDecl=templRefParam:71:40 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
// CHECK: TemplateRef=Specialization:66:8 [type=] [typekind=Invalid] [isPOD=0]
-// CHECK: CallExpr=Specialization:66:8 [type=Specialization<Specialization<bool> &>] [typekind=Elaborated] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: CallExpr=Specialization:66:8 [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
// CHECK: VarDecl=autoTemplRefParam:72:6 (Definition) [type=Specialization<Specialization<bool> &>] [typekind=Auto] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
-// CHECK: UnexposedExpr=templRefParam:71:40 [type=const Specialization<Specialization<bool> &>] [typekind=Elaborated] const [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=const Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1] [isAnonRecDecl=0]
-// CHECK: DeclRefExpr=templRefParam:71:40 [type=Specialization<Specialization<bool> &>] [typekind=Elaborated] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
-// CHECK: TypeAliasDecl=baz:76:7 (Definition) [type=baz] [typekind=Typedef] [templateargs/1= [type=A<void>] [typekind=Elaborated]] [canonicaltype=A<void>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=void] [typekind=Void]] [isPOD=0]
+// CHECK: UnexposedExpr=templRefParam:71:40 [type=const Specialization<Specialization<bool> &>] [typekind=Record] const [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=const Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1] [isAnonRecDecl=0]
+// CHECK: DeclRefExpr=templRefParam:71:40 [type=Specialization<Specialization<bool> &>] [typekind=Unexposed] [templateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [canonicaltype=Specialization<Specialization<bool> &>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=Specialization<bool> &] [typekind=LValueReference]] [isPOD=1]
+// CHECK: TypeAliasDecl=baz:76:7 (Definition) [type=baz] [typekind=Typedef] [templateargs/1= [type=A<void>] [typekind=Unexposed]] [canonicaltype=A<void>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=void] [typekind=Void]] [isPOD=0]
// CHECK: VarDecl=autoTemplPointer:78:6 (Definition) [type=Specialization<Specialization<bool> &> *] [typekind=Auto] [canonicaltype=Specialization<Specialization<bool> &> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=Specialization<Specialization<bool> &>] [pointeekind=Auto]
-// CHECK: CallExpr=Bar:17:3 [type=outer::inner::Bar] [typekind=Elaborated] [canonicaltype=outer::inner::Bar] [canonicaltypekind=Record] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0] [nbFields=3]
+// CHECK: CallExpr=Bar:17:3 [type=outer::inner::Bar] [typekind=Record] [canonicaltype=outer::inner::Bar] [canonicaltypekind=Record] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0] [nbFields=3]
// CHECK: StructDecl=(anonymous struct at {{.*}}):84:3 (Definition) [type=X::(anonymous struct at {{.*}}print-type.cpp:84:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
// CHECK: ClassDecl=(anonymous class at {{.*}}:85:3 (Definition) [type=X::(anonymous class at {{.*}}print-type.cpp:85:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
// CHECK: UnionDecl=(anonymous union at {{.*}}:86:3 (Definition) [type=X::(anonymous union at {{.*}}print-type.cpp:86:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1]
diff --git a/clang/test/Index/recursive-cxx-member-calls.cpp b/clang/test/Index/recursive-cxx-member-calls.cpp
index 11c011a432cd4..b378975b5a763 100644
--- a/clang/test/Index/recursive-cxx-member-calls.cpp
+++ b/clang/test/Index/recursive-cxx-member-calls.cpp
@@ -402,7 +402,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Identifier: "getKind" [33:17 - 33:24] CXXMethod=getKind:33:17 (static)
// CHECK-tokens: Punctuation: "(" [33:24 - 33:25] CXXMethod=getKind:33:17 (static)
// CHECK-tokens: Keyword: "const" [33:25 - 33:30] ParmDecl=Name:33:48 (Definition)
-// CHECK-tokens: Identifier: "IdentifierInfo" [33:31 - 33:45] TypeRef=class clang::IdentifierInfo:66:7
+// CHECK-tokens: Identifier: "IdentifierInfo" [33:31 - 33:45] TypeRef=class clang::IdentifierInfo:11:9
// CHECK-tokens: Punctuation: "*" [33:46 - 33:47] ParmDecl=Name:33:48 (Definition)
// CHECK-tokens: Identifier: "Name" [33:48 - 33:52] ParmDecl=Name:33:48 (Definition)
// CHECK-tokens: Punctuation: ")" [33:52 - 33:53] CXXMethod=getKind:33:17 (static)
@@ -823,18 +823,18 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Punctuation: ";" [85:18 - 85:19] ClassTemplate=StringSwitch:83:47 (Definition)
// CHECK-tokens: Keyword: "public" [86:1 - 86:7] CXXAccessSpecifier=:86:1 (Definition)
// CHECK-tokens: Punctuation: ":" [86:7 - 86:8] CXXAccessSpecifier=:86:1 (Definition)
-// CHECK-tokens: Keyword: "explicit" [87:3 - 87:11] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
-// CHECK-tokens: Identifier: "StringSwitch" [87:12 - 87:24] CXXConstructor=StringSwitch<T, R>:87:12 (Definition) (explicit)
-// CHECK-tokens: Punctuation: "(" [87:24 - 87:25] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Keyword: "explicit" [87:3 - 87:11] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Identifier: "StringSwitch" [87:12 - 87:24] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition) (explicit)
+// CHECK-tokens: Punctuation: "(" [87:24 - 87:25] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
// CHECK-tokens: Identifier: "StringRef" [87:25 - 87:34] TypeRef=class llvm::StringRef:38:7
// CHECK-tokens: Identifier: "Str" [87:35 - 87:38] ParmDecl=Str:87:35 (Definition)
-// CHECK-tokens: Punctuation: ")" [87:38 - 87:39] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
-// CHECK-tokens: Punctuation: ":" [87:40 - 87:41] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Punctuation: ")" [87:38 - 87:39] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Punctuation: ":" [87:40 - 87:41] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
// CHECK-tokens: Identifier: "Str" [87:42 - 87:45] MemberRef=Str:84:13
// CHECK-tokens: Punctuation: "(" [87:45 - 87:46] CallExpr=StringRef:38:7
// CHECK-tokens: Identifier: "Str" [87:46 - 87:49] DeclRefExpr=Str:87:35
// CHECK-tokens: Punctuation: ")" [87:49 - 87:50] CallExpr=StringRef:38:7
-// CHECK-tokens: Punctuation: "," [87:50 - 87:51] CXXConstructor=StringSwitch<T, R>:87:12 (Definition)
+// CHECK-tokens: Punctuation: "," [87:50 - 87:51] CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition)
// CHECK-tokens: Identifier: "Result" [87:52 - 87:58] MemberRef=Result:85:12
// CHECK-tokens: Punctuation: "(" [87:58 - 87:59] UnexposedExpr=
// CHECK-tokens: Literal: "0" [87:59 - 87:60] IntegerLiteral=
@@ -846,7 +846,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK-tokens: Keyword: "unsigned" [88:14 - 88:22] NonTypeTemplateParameter=N:88:23 (Definition)
// CHECK-tokens: Identifier: "N" [88:23 - 88:24] NonTypeTemplateParameter=N:88:23 (Definition)
// CHECK-tokens: Punctuation: ">" [88:25 - 88:26] FunctionTemplate=Case:88:42 (Definition)
-// CHECK-tokens: Identifier: "StringSwitch" [88:27 - 88:39] TypeRef=StringSwitch<T, R>:83:47
+// CHECK-tokens: Identifier: "StringSwitch" [88:27 - 88:39] TypeRef=llvm::StringSwitch<T, R>:83:47
// CHECK-tokens: Punctuation: "&" [88:40 - 88:41] FunctionTemplate=Case:88:42 (Definition)
// CHECK-tokens: Identifier: "Case" [88:42 - 88:46] FunctionTemplate=Case:88:42 (Definition)
// CHECK-tokens: Punctuation: "(" [88:46 - 88:47] FunctionTemplate=Case:88:42 (Definition)
@@ -1619,7 +1619,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 33:17: CXXMethod=getKind:33:17 (static) Extent=[33:5 - 33:53]
// CHECK: 33:12: TypeRef=enum clang::AttributeList::Kind:13:10 Extent=[33:12 - 33:16]
// CHECK: 33:48: ParmDecl=Name:33:48 (Definition) Extent=[33:25 - 33:52]
-// CHECK: 33:31: TypeRef=class clang::IdentifierInfo:66:7 Extent=[33:31 - 33:45]
+// CHECK: 33:31: TypeRef=class clang::IdentifierInfo:11:9 Extent=[33:31 - 33:45]
// CHECK: 36:8: FunctionDecl=magic_length:36:8 Extent=[36:1 - 36:35]
// CHECK: 36:1: TypeRef=size_t:2:25 Extent=[36:1 - 36:7]
// CHECK: 36:33: ParmDecl=s:36:33 (Definition) Extent=[36:21 - 36:34]
@@ -1839,7 +1839,7 @@ AttributeList::Kind AttributeList::getKind(const IdentifierInfo * Name) {
// CHECK: 84:3: TypeRef=class llvm::StringRef:38:7 Extent=[84:3 - 84:12]
// CHECK: 85:12: FieldDecl=Result:85:12 (Definition) Extent=[85:3 - 85:18]
// CHECK: 86:1: CXXAccessSpecifier=:86:1 (Definition) Extent=[86:1 - 86:8]
-// CHECK: 87:12: CXXConstructor=StringSwitch<T, R>:87:12 (Definition) (explicit) Extent=[87:3 - 87:64]
+// CHECK: 87:12: CXXConstructor=llvm::StringSwitch<T, R>:87:12 (Definition) (explicit) Extent=[87:3 - 87:64]
// CHECK: 87:35: ParmDecl=Str:87:35 (Definition) Extent=[87:25 - 87:38]
// CHECK: 87:25: TypeRef=class llvm::StringRef:38:7 Extent=[87:25 - 87:34]
// CHECK: 87:42: MemberRef=Str:84:13 Extent=[87:42 - 87:45]
diff --git a/clang/test/Index/redeclarations.cpp b/clang/test/Index/redeclarations.cpp
index 11dc9320430c1..ea5e9706cbcbf 100644
--- a/clang/test/Index/redeclarations.cpp
+++ b/clang/test/Index/redeclarations.cpp
@@ -17,5 +17,5 @@ class A
// CHECK: redeclarations.h:19:19: FieldDecl=x:19:19 (Definition) Extent=[19:5 - 19:20]
// CHECK: redeclarations.h:19:5: TemplateRef=B:8:7 Extent=[19:5 - 19:6]
// CHECK: redeclarations.h:19:7: TypeRef=class D:17:7 Extent=[19:7 - 19:8]
-// CHECK: redeclarations.h:19:16: TypeRef=class A:3:7 Extent=[19:16 - 19:17]
+// CHECK: redeclarations.h:19:16: TypeRef=class A:19:16 Extent=[19:16 - 19:17]
// CHECK: redeclarations.cpp:3:7: ClassDecl=A:3:7 (Definition) Extent=[3:1 - 5:2]
diff --git a/clang/test/Index/skip-parsed-bodies/compile_commands.json b/clang/test/Index/skip-parsed-bodies/compile_commands.json
index 991227a843b1d..e087a28b1cf2c 100644
--- a/clang/test/Index/skip-parsed-bodies/compile_commands.json
+++ b/clang/test/Index/skip-parsed-bodies/compile_commands.json
@@ -25,8 +25,8 @@
// CHECK-NEXT: [indexEntityReference]: kind: variable | name: some_val | {{.*}} | loc: .{{/|\\\\?}}t.h:9:27
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def2 | {{.*}} | isRedecl: 0 | isDef: 0 | isContainer: 0
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def2 | {{.*}} | isRedecl: 1 | isDef: 1 | isContainer: 1
-// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS |
// CHECK-NEXT: [indexEntityReference]: kind: c++-class | name: C |
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS |
// CHECK-NEXT: [indexEntityReference]: kind: variable | name: some_val | {{.*}} | loc: .{{/|\\\\?}}t.h:15:5
// CHECK-NEXT: [indexDeclaration]: kind: function | name: foo1 | {{.*}} | isRedecl: 0 | isDef: 1 | isContainer: 1
// CHECK-NEXT: [indexEntityReference]: kind: variable | name: some_val | {{.*}} | loc: .{{/|\\\\?}}t.h:19:5
@@ -40,8 +40,8 @@
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def1 | {{.*}} | isRedecl: 0 | isDef: 1 | isContainer: skipped
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def2 | {{.*}} | isRedecl: 0 | isDef: 0 | isContainer: 0
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def2 | {{.*}} | isContainer: skipped
-// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS |
// CHECK-NEXT: [indexEntityReference]: kind: c++-class | name: C |
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS |
// CHECK-NEXT: [indexDeclaration]: kind: function | name: foo1 | {{.*}} | isRedecl: 0 | isDef: 1 | isContainer: skipped
// CHECK-NEXT: [ppIncludedFile]: .{{/|\\\\?}}pragma_once.h
// CHECK-NEXT: [indexDeclaration]: kind: function | name: foo2 | {{.*}} | isRedecl: 0 | isDef: 1 | isContainer: 1
@@ -60,8 +60,8 @@
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def1 | {{.*}} | isRedecl: 0 | isDef: 1 | isContainer: skipped
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def2 | {{.*}} | isRedecl: 0 | isDef: 0 | isContainer: 0
// CHECK-NEXT: [indexDeclaration]: kind: c++-instance-method | name: method_def2 | {{.*}} | isRedecl: 1 | isDef: 1 | isContainer: skipped
-// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS |
// CHECK-NEXT: [indexEntityReference]: kind: c++-class | name: C |
+// CHECK-NEXT: [indexEntityReference]: kind: namespace | name: NS |
// CHECK-NEXT: [indexDeclaration]: kind: function | name: foo1 | {{.*}} | isRedecl: 0 | isDef: 1 | isContainer: skipped
// CHECK-NEXT: [ppIncludedFile]: .{{/|\\\\?}}pragma_once.h
// CHECK-NEXT: [indexDeclaration]: kind: function | name: foo2 | {{.*}} | isRedecl: 0 | isDef: 1 | isContainer: skipped
diff --git a/clang/test/Misc/diag-template-diffing-cxx11.cpp b/clang/test/Misc/diag-template-diffing-cxx11.cpp
index c62bffe2b458d..0b145475fe191 100644
--- a/clang/test/Misc/diag-template-diffing-cxx11.cpp
+++ b/clang/test/Misc/diag-template-diffing-cxx11.cpp
@@ -24,17 +24,17 @@ namespace std {
}
} // end namespace std
// CHECK-ELIDE-NOTREE: no matching function for call to 'f'
-// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::string>' to 'vector<string>' for 1st argument
+// CHECK-ELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::basic_string>' to 'vector<versa_string>' for 1st argument
// CHECK-NOELIDE-NOTREE: no matching function for call to 'f'
-// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::string>' to 'vector<string>' for 1st argument
+// CHECK-NOELIDE-NOTREE: candidate function not viable: no known conversion from 'vector<std::basic_string>' to 'vector<versa_string>' for 1st argument
// CHECK-ELIDE-TREE: no matching function for call to 'f'
// CHECK-ELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-ELIDE-TREE: vector<
-// CHECK-ELIDE-TREE: [std::string != string]>
+// CHECK-ELIDE-TREE: [std::basic_string != versa_string]>
// CHECK-NOELIDE-TREE: no matching function for call to 'f'
// CHECK-NOELIDE-TREE: candidate function not viable: no known conversion from argument type to parameter type for 1st argument
// CHECK-NOELIDE-TREE: vector<
-// CHECK-NOELIDE-TREE: [std::string != string]>
+// CHECK-NOELIDE-TREE: [std::basic_string != versa_string]>
template <int... A>
class I1{};
diff --git a/clang/test/Modules/modules-merge-enum.m b/clang/test/Modules/modules-merge-enum.m
index f1010c1decc24..fc07c46a5117e 100644
--- a/clang/test/Modules/modules-merge-enum.m
+++ b/clang/test/Modules/modules-merge-enum.m
@@ -18,9 +18,8 @@
// CHECK-NEXT: | |-also in ModB
// CHECK-NEXT: | `-EnumConstantDecl 0x{{.*}} imported in ModA.ModAFile1 referenced MyVal_A 'int'
// CHECK-NEXT: |-TypedefDecl 0x{{.*}} imported in ModA.ModAFile1 hidden MyEnum1 'enum MyEnum1'
-// CHECK-NEXT: | `-ElaboratedType 0x{{.*}} 'enum MyEnum1' sugar imported
-// CHECK-NEXT: | `-EnumType 0x{{.*}} 'enum MyEnum1' imported
-// CHECK-NEXT: | `-Enum 0x{{.*}} 'MyEnum1'
+// CHECK-NEXT: | `-EnumType 0x{{.*}} 'enum MyEnum1' imported
+// CHECK-NEXT: | `-Enum 0x{{.*}} 'MyEnum1'
enum MyEnum2 { MyVal_B };
@@ -33,10 +32,9 @@
// CHECK: |-EnumDecl 0x{{.*}} imported in ModA.ModAFile1 <undeserialized declarations>
// CHECK-NEXT: | |-also in ModB
// CHECK-NEXT: | `-EnumConstantDecl 0x{{.*}} imported in ModA.ModAFile1 referenced MyVal_C 'int'
-// CHECK-NEXT: |-TypedefDecl 0x{{.*}} imported in ModA.ModAFile1 hidden MyEnum3 'enum MyEnum3':'MyEnum3'
-// CHECK-NEXT: | `-ElaboratedType 0x{{.*}} 'enum MyEnum3' sugar imported
-// CHECK-NEXT: | `-EnumType 0x{{.*}} 'MyEnum3' imported
-// CHECK-NEXT: | `-Enum 0x{{.*}}
+// CHECK-NEXT: |-TypedefDecl 0x{{.*}} imported in ModA.ModAFile1 hidden MyEnum3 'enum MyEnum3'
+// CHECK-NEXT: | `-EnumType 0x{{.*}} 'enum MyEnum3' imported
+// CHECK-NEXT: | `-Enum 0x{{.*}}
struct MyStruct {
enum MyEnum5 { MyVal_D } Field;
@@ -57,17 +55,15 @@
// Redeclarations coming from ModB.
// CHECK: |-TypedefDecl 0x{{.*}} prev 0x{{.*}} imported in ModB MyEnum1 'enum MyEnum1'
-// CHECK-NEXT: | `-ElaboratedType 0x{{.*}} 'enum MyEnum1' sugar imported
-// CHECK-NEXT: | `-EnumType 0x{{.*}} 'enum MyEnum1' imported
-// CHECK-NEXT: | `-Enum 0x{{.*}} 'MyEnum1'
+// CHECK-NEXT: | `-EnumType 0x{{.*}} 'enum MyEnum1' imported
+// CHECK-NEXT: | `-Enum 0x{{.*}} 'MyEnum1'
// CHECK: |-EnumDecl 0x{{.*}} prev 0x{{.*}} imported in ModB <undeserialized declarations>
// CHECK-NEXT: | |-also in ModB
// CHECK-NEXT: | `-EnumConstantDecl 0x{{.*}} imported in ModB MyVal_C 'int'
-// CHECK-NEXT: |-TypedefDecl 0x{{.*}} prev 0x{{.*}} imported in ModB MyEnum3 'enum MyEnum3':'MyEnum3'
-// CHECK-NEXT: | `-ElaboratedType 0x{{.*}} 'enum MyEnum3' sugar imported
-// CHECK-NEXT: | `-EnumType 0x{{.*}} 'MyEnum3' imported
-// CHECK-NEXT: | `-Enum 0x{{.*}}
+// CHECK-NEXT: |-TypedefDecl 0x{{.*}} prev 0x{{.*}} imported in ModB MyEnum3 'enum MyEnum3'
+// CHECK-NEXT: | `-EnumType 0x{{.*}} 'enum MyEnum3' imported
+// CHECK-NEXT: | `-Enum 0x{{.*}}
// CHECK: |-EnumDecl 0x{{.*}} imported in ModB <undeserialized declarations>
// CHECK-NEXT: | `-EnumConstantDecl 0x{{.*}} first 0x{{.*}} imported in ModB referenced MyVal_E 'int'
diff --git a/clang/test/Modules/odr_hash.cpp b/clang/test/Modules/odr_hash.cpp
index 8ef53e32f2e95..f22f3c71f44d2 100644
--- a/clang/test/Modules/odr_hash.cpp
+++ b/clang/test/Modules/odr_hash.cpp
@@ -1314,7 +1314,7 @@ class S1 {
#else
template<class T>
using U1 = S1<T>;
-// expected-error at first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}}
+// expected-error at first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'DependentType::S1<T>' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
@@ -2343,7 +2343,7 @@ struct S1 {
};
#else
using TemplateTypeParmType::S1;
-// expected-error at first.h:* {{'TemplateTypeParmType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T1, T2>' in module 'SecondModule'}}
+// expected-error at first.h:* {{'TemplateTypeParmType::S1::x' from module 'FirstModule' is not present in definition of 'TemplateTypeParmType::S1<T1, T2>' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
#endif
@@ -2365,9 +2365,9 @@ class S2 {
};
#else
using TemplateTypeParmType::S2;
-// expected-error at first.h:* {{'TemplateTypeParmType::S2::x' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
+// expected-error at first.h:* {{'TemplateTypeParmType::S2::x' from module 'FirstModule' is not present in definition of 'TemplateTypeParmType::S2<T, U>' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
-// expected-error at first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}}
+// expected-error at first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'TemplateTypeParmType::S2<T, U>' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'type' does not match}}
#endif
@@ -4020,7 +4020,7 @@ struct Valid {
};
#else
Invalid::L2<1>::L3<1> invalid;
-// expected-error at second.h:* {{'Types::InjectedClassName::Invalid::L2::L3::x' from module 'SecondModule' is not present in definition of 'L3<value-parameter-1-0>' in module 'FirstModule'}}
+// expected-error at second.h:* {{'Types::InjectedClassName::Invalid::L2::L3::x' from module 'SecondModule' is not present in definition of 'Types::InjectedClassName::Invalid::L2::L3<value-parameter-1-0>' in module 'FirstModule'}}
// expected-note at first.h:* {{declaration of 'x' does not match}}
Valid::L2<1>::L3<1> valid;
#endif
@@ -4291,7 +4291,7 @@ struct Valid {
};
#else
template <class T> using I = Invalid<T>;
-// expected-error at first.h:* {{'Types::UnresolvedUsing::Invalid::x' from module 'FirstModule' is not present in definition of 'Invalid<T>' in module 'SecondModule'}}
+// expected-error at first.h:* {{'Types::UnresolvedUsing::Invalid::x' from module 'FirstModule' is not present in definition of 'Types::UnresolvedUsing::Invalid<T>' in module 'SecondModule'}}
// expected-note at second.h:* {{declaration of 'x' does not match}}
template <class T> using V = Valid<T>;
diff --git a/clang/test/OpenMP/allocate_modifiers_messages.cpp b/clang/test/OpenMP/allocate_modifiers_messages.cpp
index 6867e78a89ee9..83314a5b61e6b 100644
--- a/clang/test/OpenMP/allocate_modifiers_messages.cpp
+++ b/clang/test/OpenMP/allocate_modifiers_messages.cpp
@@ -88,7 +88,7 @@ int main() {
// expected-warning at +2 {{extra tokens at the end of '#pragma omp scope' are ignored}}
// expected-note at +1 {{to match this '('}}
#pragma omp scope private(a,b,c) allocate(allocator(omp_const_mem_alloc):c:b;a)
- // expected-error at +1 {{initializing 'const omp_allocator_handle_t' with an expression of incompatible type 'int'}}
+ // expected-error at +1 {{initializing 'const omp_allocator_handle_t' (aka 'const enum omp_allocator_handle_t') with an expression of incompatible type 'int'}}
#pragma omp scope private(c,a,b) allocate(allocator(myAlloc()):a,b,c)
// expected-error at +2 {{missing ':' after allocate clause modifier}}
// expected-error at +1 {{expected expression}}
diff --git a/clang/test/OpenMP/target_map_array_of_structs_with_nested_mapper_ast_dump.cpp b/clang/test/OpenMP/target_map_array_of_structs_with_nested_mapper_ast_dump.cpp
index a5847709d3e76..15b976f0d7d1d 100644
--- a/clang/test/OpenMP/target_map_array_of_structs_with_nested_mapper_ast_dump.cpp
+++ b/clang/test/OpenMP/target_map_array_of_structs_with_nested_mapper_ast_dump.cpp
@@ -27,7 +27,7 @@ void foo() {
// DUM-NEXT: |-OMPMapClause {{.*}}<<invalid sloc>> <implicit>
// DUM-NEXT: | |-MemberExpr {{.*}}<line:9:3> 'int' lvalue .e
// DUM-NEXT: | | `-DeclRefExpr {{.*}}<<invalid sloc>> 'D' lvalue Var {{.*}} '_s' 'D'
-// DUM-NEXT: | |-MemberExpr {{.*}}<line:10:3> 'C' lvalue .f {{.*}}
+// DUM-NEXT: | |-MemberExpr {{.*}}<line:10:3> 'C':'struct C' lvalue .f {{.*}}
// DUM-NEXT: | | `-DeclRefExpr {{.*}}<<invalid sloc>> 'D' lvalue Var {{.*}} '_s' 'D'
// DUM-NEXT: | `-MemberExpr {{.*}}<line:11:3> 'int' lvalue .h {{.*}}
// DUM-NEXT: | `-DeclRefExpr {{.*}}<<invalid sloc>> 'D' lvalue Var {{.*}} '_s' 'D'
diff --git a/clang/test/OpenMP/target_map_array_section_of_structs_with_nested_mapper_ast_dump.cpp b/clang/test/OpenMP/target_map_array_section_of_structs_with_nested_mapper_ast_dump.cpp
index b2fb8fbaa50b4..bdf3dd0d4fbfe 100644
--- a/clang/test/OpenMP/target_map_array_section_of_structs_with_nested_mapper_ast_dump.cpp
+++ b/clang/test/OpenMP/target_map_array_section_of_structs_with_nested_mapper_ast_dump.cpp
@@ -27,7 +27,7 @@ void foo() {
// DUM-NEXT: |-OMPMapClause {{.*}}<<invalid sloc>> <implicit>
// DUM-NEXT: | |-MemberExpr {{.*}}<line:9:3> 'int' lvalue .e
// DUM-NEXT: | | `-DeclRefExpr {{.*}}<<invalid sloc>> 'D' lvalue Var {{.*}} '_s' 'D'
-// DUM-NEXT: | |-MemberExpr {{.*}}<line:10:3> 'C' lvalue .f {{.*}}
+// DUM-NEXT: | |-MemberExpr {{.*}}<line:10:3> 'C':'struct C' lvalue .f {{.*}}
// DUM-NEXT: | | `-DeclRefExpr {{.*}}<<invalid sloc>> 'D' lvalue Var {{.*}} '_s' 'D'
// DUM-NEXT: | `-MemberExpr {{.*}}<line:11:3> 'int' lvalue .h {{.*}}
// DUM-NEXT: | `-DeclRefExpr {{.*}}<<invalid sloc>> 'D' lvalue Var {{.*}} '_s' 'D'
diff --git a/clang/test/PCH/cxx-explicit-specifier.cpp b/clang/test/PCH/cxx-explicit-specifier.cpp
index 84548faf48810..a30c669fddb47 100644
--- a/clang/test/PCH/cxx-explicit-specifier.cpp
+++ b/clang/test/PCH/cxx-explicit-specifier.cpp
@@ -79,13 +79,13 @@ struct A {
B<true> b_true;
B<false> b_false;
#else
-//expected-note at -8 {{candidate template ignored}} expected-note at -8 {{implicit deduction guide declared as 'template <bool b> A(A<b>) -> A<b>'}}
-//expected-note at -8 {{explicit constructor declared here}} expected-note at -8 {{implicit deduction guide declared as 'template <bool b> explicit(b) A(B<b>) -> A<b>'}}
+//expected-note at -8 {{candidate template ignored}} expected-note at -8 {{implicit deduction guide declared as 'template <bool b> A(templ::A<b>) -> templ::A<b>'}}
+//expected-note at -8 {{explicit constructor declared here}} expected-note at -8 {{implicit deduction guide declared as 'template <bool b> explicit(b) A(B<b>) -> templ::A<b>'}}
//expected-note at -15+ {{candidate constructor}}
//expected-note at -8+ {{explicit conversion function is not a candidate (explicit specifier}}
//expected-note at -11 {{explicit constructor is not a candidate (explicit specifier}}
-//CHECK: explicit(b){{ +}}A
+//CHECK: explicit(b){{ +}}templ::A<b>(B<b>)
//CHECK: explicit(b{{ +}}^{{ +}}T::value){{ +}}operator
A a = { b_true }; //expected-error {{class template argument deduction}}
diff --git a/clang/test/Parser/MicrosoftExtensions.cpp b/clang/test/Parser/MicrosoftExtensions.cpp
index 9102bca8f6bb2..e32d7fae6af39 100644
--- a/clang/test/Parser/MicrosoftExtensions.cpp
+++ b/clang/test/Parser/MicrosoftExtensions.cpp
@@ -145,7 +145,7 @@ typedef COM_CLASS_TEMPLATE_REF<struct_with_uuid, __uuidof(struct_with_uuid)> COM
COM_CLASS_TEMPLATE_REF<int, __uuidof(struct_with_uuid)> good_template_arg;
-COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument for template parameter of pointer type 'const GUID *' (aka 'const _GUID *') must have its address taken}}
+COM_CLASS_TEMPLATE<int, __uuidof(struct_with_uuid)> bad_template_arg; // expected-error {{non-type template argument for template parameter of pointer type 'const GUID *' (aka 'const struct _GUID *') must have its address taken}}
namespace PR16911 {
struct __declspec(uuid("{12345678-1234-1234-1234-1234567890aB}")) uuid;
diff --git a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
index d29eed40b1864..9d27f83698e00 100644
--- a/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/Parser/cxx1z-class-template-argument-deduction.cpp
@@ -196,8 +196,8 @@ namespace typename_specifier {
new typename T::A{0};
typename T::A a = 0;
const typename T::A b = 0;
- if (typename T::A a = 0) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
- for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error {{value of type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
+ if (typename T::A a = 0) {} // expected-error {{value of type 'typename typename_specifier::X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
+ for (typename T::A a = 0; typename T::A b = 0; /**/) {} // expected-error {{value of type 'typename typename_specifier::X::A<int>' (aka 'typename_specifier::X::A<int>') is not contextually convertible to 'bool'}}
{(void)(typename T::A)(0);} // expected-error{{refers to class template member}}
{(void)(typename T::A){0};} // expected-error{{refers to class template member}}
@@ -208,7 +208,7 @@ namespace typename_specifier {
{typename T::A arr[3] = 0;} // expected-error {{refers to class template member}}
{typename T::A F::*pm = 0;} // expected-error {{refers to class template member}}
{typename T::A (*fp)() = 0;} // expected-error {{refers to class template member}}
- {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename X::A<int>' (aka 'typename_specifier::X::A<int>') decomposes into 0}}
+ {typename T::A [x, y] = 0;} // expected-error {{cannot be declared with type 'typename T::A'}} expected-error {{type 'typename typename_specifier::X::A<int>' (aka 'typename_specifier::X::A<int>') decomposes into 0}}
}
template void f<X>(); // expected-note {{instantiation of}}
diff --git a/clang/test/SemaCXX/MicrosoftExtensions.cpp b/clang/test/SemaCXX/MicrosoftExtensions.cpp
index 4dff2b1c362a7..ca072d8bd2f6a 100644
--- a/clang/test/SemaCXX/MicrosoftExtensions.cpp
+++ b/clang/test/SemaCXX/MicrosoftExtensions.cpp
@@ -126,17 +126,17 @@ __inline void FreeIDListArray(LPITEMIDLIST *ppidls) {
typedef struct in_addr {
public:
in_addr(in_addr &a) {} // precxx17-note {{candidate constructor not viable: expects an lvalue for 1st argument}}
- in_addr(in_addr *a) {} // precxx17-note {{candidate constructor not viable: no known conversion from 'IN_ADDR' (aka 'in_addr') to 'in_addr *' for 1st argument}}
+ in_addr(in_addr *a) {} // precxx17-note {{candidate constructor not viable: no known conversion from 'IN_ADDR' (aka 'struct in_addr') to 'in_addr *' for 1st argument}}
} IN_ADDR;
void f(IN_ADDR __unaligned *a) {
IN_ADDR local_addr = *a;
// FIXME: MSVC accepts the following; not sure why clang tries to
// copy-construct an in_addr.
- IN_ADDR local_addr2 = a; // precxx17-error {{no viable constructor copying variable of type 'IN_ADDR' (aka 'in_addr')}}
- // expected-warning at -1 {{implicit cast from type '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to type 'in_addr *' drops __unaligned qualifier}}
+ IN_ADDR local_addr2 = a; // precxx17-error {{no viable constructor copying variable of type 'IN_ADDR' (aka 'struct in_addr')}}
+ // expected-warning at -1 {{implicit cast from type '__unaligned IN_ADDR *' (aka '__unaligned struct in_addr *') to type 'in_addr *' drops __unaligned qualifier}}
IN_ADDR local_addr3(a);
- // expected-warning at -1 {{implicit cast from type '__unaligned IN_ADDR *' (aka '__unaligned in_addr *') to type 'in_addr *' drops __unaligned qualifier}}
+ // expected-warning at -1 {{implicit cast from type '__unaligned IN_ADDR *' (aka '__unaligned struct in_addr *') to type 'in_addr *' drops __unaligned qualifier}}
}
template<typename T> void h1(T (__stdcall M::* const )()) { }
diff --git a/clang/test/SemaCXX/builtin-get-vtable-pointer.cpp b/clang/test/SemaCXX/builtin-get-vtable-pointer.cpp
index 273f9c3b4c667..b04b38d7996eb 100644
--- a/clang/test/SemaCXX/builtin-get-vtable-pointer.cpp
+++ b/clang/test/SemaCXX/builtin-get-vtable-pointer.cpp
@@ -53,7 +53,7 @@ const void *getThing(const Bar<T> *b = nullptr) {
return __builtin_get_vtable_pointer(b->ty()); // expected-error{{__builtin_get_vtable_pointer requires an argument of class pointer type, but 'SubType *' (aka 'int *') was provided}}
// expected-error at -1{{__builtin_get_vtable_pointer requires an argument of polymorphic class pointer type, but 'Thing1' has no virtual methods}}
// expected-error at -2{{__builtin_get_vtable_pointer requires an argument of polymorphic class pointer type, but 'NonPolymorphic' has no virtual methods}}
- // expected-error at -3{{__builtin_get_vtable_pointer requires an argument with a complete type, but 'SubType' (aka 'basic::ForwardDeclaration') is incomplete}}
+ // expected-error at -3{{__builtin_get_vtable_pointer requires an argument with a complete type, but 'SubType' (aka 'ForwardDeclaration') is incomplete}}
}
template <typename>
struct IncompleteTemplate; // expected-note{{template is declared here}}
diff --git a/clang/test/SemaCXX/class-base-member-init.cpp b/clang/test/SemaCXX/class-base-member-init.cpp
index f5489e2da3e93..29b4545e4fb16 100644
--- a/clang/test/SemaCXX/class-base-member-init.cpp
+++ b/clang/test/SemaCXX/class-base-member-init.cpp
@@ -83,7 +83,7 @@ namespace test5 {
A() : decltype(Base(1))(3) {
}
A(int) : Base(3), // expected-note {{previous initialization is here}}
- decltype(Base(1))(2), // expected-error {{multiple initializations given for base 'decltype(Base(1))' (aka 'test5::Base')}}
+ decltype(Base(1))(2), // expected-error {{multiple initializations given for base 'decltype(Base(1))' (aka 'Base')}}
decltype(int())() { // expected-error {{constructor initializer 'decltype(int())' (aka 'int') does not name a class}}
}
A(float) : decltype(A())(3) {
diff --git a/clang/test/SemaCXX/co_await-ast.cpp b/clang/test/SemaCXX/co_await-ast.cpp
index f792a2cb7b1a1..5be2004eb1072 100644
--- a/clang/test/SemaCXX/co_await-ast.cpp
+++ b/clang/test/SemaCXX/co_await-ast.cpp
@@ -48,9 +48,9 @@ awaitable foo() {
// CHECK: | `-ExprWithCleanups {{.*}} 'void'
// CHECK: | `-CoawaitExpr {{.*}} 'void'
// CHECK: | |-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
-// CHECK: | |-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
-// CHECK: | | `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
-// CHECK: | | `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
+// CHECK: | |-MaterializeTemporaryExpr {{.*}} 'result_t' lvalue
+// CHECK: | | `-CXXBindTemporaryExpr {{.*}} 'result_t' (CXXTemporary {{.*}})
+// CHECK: | | `-CXXMemberCallExpr {{.*}} 'result_t'
// CHECK: | | |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK: | | | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK: | | `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
@@ -58,27 +58,27 @@ awaitable foo() {
// CHECK: | | `-CXXMemberCallExpr {{.*}} 'bool'
// CHECK: | | `-MemberExpr {{.*}} '<bound member function type>' .await_ready {{.*}}
// CHECK: | | `-ImplicitCastExpr {{.*}} 'const awaitable_frame::result_t' lvalue <NoOp>
-// CHECK: | | `-OpaqueValueExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
-// CHECK: | | `-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
-// CHECK: | | `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
-// CHECK: | | `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
+// CHECK: | | `-OpaqueValueExpr {{.*}} 'result_t' lvalue
+// CHECK: | | `-MaterializeTemporaryExpr {{.*}} 'result_t' lvalue
+// CHECK: | | `-CXXBindTemporaryExpr {{.*}} 'result_t' (CXXTemporary {{.*}})
+// CHECK: | | `-CXXMemberCallExpr {{.*}} 'result_t'
// CHECK: | | |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK: | | | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK: | | `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
// CHECK: | |-ExprWithCleanups {{.*}} 'void'
// CHECK: | | `-CXXMemberCallExpr {{.*}} 'void'
// CHECK: | | |-MemberExpr {{.*}} '<bound member function type>' .await_suspend {{.*}}
-// CHECK: | | | `-OpaqueValueExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
-// CHECK: | | | `-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
-// CHECK: | | | `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
-// CHECK: | | | `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
+// CHECK: | | | `-OpaqueValueExpr {{.*}} 'result_t' lvalue
+// CHECK: | | | `-MaterializeTemporaryExpr {{.*}} 'result_t' lvalue
+// CHECK: | | | `-CXXBindTemporaryExpr {{.*}} 'result_t' (CXXTemporary {{.*}})
+// CHECK: | | | `-CXXMemberCallExpr {{.*}} 'result_t'
// CHECK: | | | |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK: | | | | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK: | | | `-CXXTemporaryObjectExpr {{.*}} 'executor' 'void (){{.*}} noexcept' zeroing
// CHECK: | | `-ImplicitCastExpr {{.*}} 'std::coroutine_handle<void>' <ConstructorConversion>
// CHECK: | | `-CXXConstructExpr {{.*}} 'std::coroutine_handle<void>' 'void (coroutine_handle<awaitable_frame> &&){{.*}} noexcept'
-// CHECK: | | `-MaterializeTemporaryExpr {{.*}} 'coroutine_handle<awaitable_frame>':'std::coroutine_handle<awaitable_frame>' xvalue
-// CHECK: | | `-CallExpr {{.*}} 'coroutine_handle<awaitable_frame>':'std::coroutine_handle<awaitable_frame>'
+// CHECK: | | `-MaterializeTemporaryExpr {{.*}} 'coroutine_handle<awaitable_frame>' xvalue
+// CHECK: | | `-CallExpr {{.*}} 'coroutine_handle<awaitable_frame>'
// CHECK: | | |-ImplicitCastExpr {{.*}} 'coroutine_handle<awaitable_frame> (*)(void *) noexcept' <FunctionToPointerDecay>
// CHECK: | | | `-DeclRefExpr {{.*}} 'coroutine_handle<awaitable_frame> (void *) noexcept' lvalue CXXMethod {{.*}} 'from_address' 'coroutine_handle<awaitable_frame> (void *) noexcept'
// CHECK: | | `-CallExpr {{.*}} 'void *'
@@ -87,10 +87,10 @@ awaitable foo() {
// CHECK: | `-CXXMemberCallExpr {{.*}} 'void'
// CHECK: | `-MemberExpr {{.*}} '<bound member function type>' .await_resume {{.*}}
// CHECK: | `-ImplicitCastExpr {{.*}} 'const awaitable_frame::result_t' lvalue <NoOp>
-// CHECK: | `-OpaqueValueExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
-// CHECK: | `-MaterializeTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' lvalue
-// CHECK: | `-CXXBindTemporaryExpr {{.*}} 'result_t':'awaitable_frame::result_t' (CXXTemporary {{.*}})
-// CHECK: | `-CXXMemberCallExpr {{.*}} 'result_t':'awaitable_frame::result_t'
+// CHECK: | `-OpaqueValueExpr {{.*}} 'result_t' lvalue
+// CHECK: | `-MaterializeTemporaryExpr {{.*}} 'result_t' lvalue
+// CHECK: | `-CXXBindTemporaryExpr {{.*}} 'result_t' (CXXTemporary {{.*}})
+// CHECK: | `-CXXMemberCallExpr {{.*}} 'result_t'
// CHECK: | |-MemberExpr {{.*}} '<bound member function type>' .await_transform {{.*}}
// CHECK: | | `-DeclRefExpr {{.*}} 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame' lvalue Var {{.*}} '__promise' 'std::coroutine_traits<awaitable>::promise_type':'awaitable_frame'
// CHECK: | `-CXXTemporaryObjectExpr {{.*}} <col:12, col:21> 'executor' 'void (){{.*}} noexcept' zeroing
diff --git a/clang/test/SemaCXX/compound-literal.cpp b/clang/test/SemaCXX/compound-literal.cpp
index a62e4f79b5a07..c112e12fbc1bf 100644
--- a/clang/test/SemaCXX/compound-literal.cpp
+++ b/clang/test/SemaCXX/compound-literal.cpp
@@ -37,8 +37,8 @@ namespace brace_initializers {
POD p = (POD){1, 2};
// CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'brace_initializers::POD'
- // CHECK: CompoundLiteralExpr {{.*}} 'POD':'brace_initializers::POD'
- // CHECK-NEXT: InitListExpr {{.*}} 'POD':'brace_initializers::POD'
+ // CHECK: CompoundLiteralExpr {{.*}} 'POD'{{$}}
+ // CHECK-NEXT: InitListExpr {{.*}} 'POD'{{$}}
// CHECK-NEXT: ConstantExpr {{.*}}
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-NEXT: ConstantExpr {{.*}}
@@ -46,34 +46,34 @@ namespace brace_initializers {
void test() {
(void)(POD){1, 2};
- // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'POD':'brace_initializers::POD'
- // CHECK-NOT: ConstantExpr {{.*}} 'POD':'brace_initializers::POD'
- // CHECK: CompoundLiteralExpr {{.*}} 'POD':'brace_initializers::POD'
- // CHECK-NEXT: InitListExpr {{.*}} 'POD':'brace_initializers::POD'
+ // CHECK-NOT: CXXBindTemporaryExpr {{.*}} 'POD'
+ // CHECK-NOT: ConstantExpr {{.*}} 'POD'
+ // CHECK: CompoundLiteralExpr {{.*}} 'POD'{{$}}
+ // CHECK-NEXT: InitListExpr {{.*}} 'POD'{{$}}
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
(void)(HasDtor){1, 2};
- // CHECK: CXXBindTemporaryExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
- // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
- // CHECK-NEXT: InitListExpr {{.*}} 'HasDtor':'brace_initializers::HasDtor'
+ // CHECK: CXXBindTemporaryExpr {{.*}} 'HasDtor'
+ // CHECK-NEXT: CompoundLiteralExpr {{.*}} 'HasDtor'{{$}}
+ // CHECK-NEXT: InitListExpr {{.*}} 'HasDtor'{{$}}
// CHECK-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-NEXT: IntegerLiteral {{.*}} 2{{$}}
#if __cplusplus >= 201103L
(void)(HasCtor){1, 2};
- // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
- // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
- // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
- // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtor':'brace_initializers::HasCtor'
+ // CHECK-CXX11-NOT: CXXBindTemporaryExpr {{.*}} 'HasCtor'
+ // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtor'
+ // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtor'{{$}}
+ // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtor'
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
(void)(HasCtorDtor){1, 2};
- // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
- // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
- // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
- // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtorDtor':'brace_initializers::HasCtorDtor'
+ // CHECK-CXX11: CXXBindTemporaryExpr {{.*}} 'HasCtorDtor'
+ // CHECK-CXX11-NOT: ConstantExpr {{.*}} 'HasCtorDtor'
+ // CHECK-CXX11: CompoundLiteralExpr {{.*}} 'HasCtorDtor'{{$}}
+ // CHECK-CXX11-NEXT: CXXTemporaryObjectExpr {{.*}} 'HasCtorDtor'
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 1{{$}}
// CHECK-CXX11-NEXT: IntegerLiteral {{.*}} 2{{$}}
#endif
diff --git a/clang/test/SemaCXX/constant-expression.cpp b/clang/test/SemaCXX/constant-expression.cpp
index cc041a4acd18c..ef48ee50be288 100644
--- a/clang/test/SemaCXX/constant-expression.cpp
+++ b/clang/test/SemaCXX/constant-expression.cpp
@@ -149,7 +149,7 @@ namespace PR31701 {
};
template <int M> class D;
template <int M>
- template<int i> void D<M>::set() { // expected-error {{from class 'D<M>' without definition}}
+ template<int i> void D<M>::set() { // expected-error {{from class 'PR31701::D<M>' without definition}}
const C c = C::n<i>;
}
}
diff --git a/clang/test/SemaCXX/constructor.cpp b/clang/test/SemaCXX/constructor.cpp
index b0b580b6aac9b..b278fd5cff204 100644
--- a/clang/test/SemaCXX/constructor.cpp
+++ b/clang/test/SemaCXX/constructor.cpp
@@ -92,7 +92,7 @@ namespace PR38286 {
template<typename T> A<T>::A() {} // expected-error {{incomplete type 'A' named in nested name specifier}}
/*FIXME: needed to recover properly from previous error*/;
template<typename> struct B;
- template<typename T> void B<T>::f() {} // expected-error {{out-of-line definition of 'f' from class 'B<type-parameter-0-0>'}}
+ template<typename T> void B<T>::f() {} // expected-error {{out-of-line definition of 'f' from class 'PR38286::B<type-parameter-0-0>'}}
template<typename> struct C; // expected-note {{non-type declaration found}}
template<typename T> C<T>::~C() {} // expected-error {{identifier 'C' after '~' in destructor name does not name a type}}
}
diff --git a/clang/test/SemaCXX/coroutine-allocs.cpp b/clang/test/SemaCXX/coroutine-allocs.cpp
index cce56deaa5f10..e6b086bd1c720 100644
--- a/clang/test/SemaCXX/coroutine-allocs.cpp
+++ b/clang/test/SemaCXX/coroutine-allocs.cpp
@@ -19,7 +19,7 @@ struct resumable {
};
};
-resumable f1() { // expected-error {{'operator new' provided by 'std::coroutine_traits<resumable>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f1'}}
+resumable f1() { // expected-error {{'operator new' provided by 'std::coroutine_traits<resumable>::promise_type' (aka 'typename resumable::promise_type') is not usable with the function signature of 'f1'}}
co_return;
}
@@ -52,11 +52,11 @@ resumable f4(Allocator) {
co_return;
}
-resumable f5(const Allocator) { // expected-error {{operator new' provided by 'std::coroutine_traits<resumable, const Allocator>::promise_type' (aka 'resumable::promise_type') is not usable}}
+resumable f5(const Allocator) { // expected-error {{operator new' provided by 'std::coroutine_traits<resumable, const Allocator>::promise_type' (aka 'typename resumable::promise_type') is not usable}}
co_return;
}
-resumable f6(const Allocator &) { // expected-error {{operator new' provided by 'std::coroutine_traits<resumable, const Allocator &>::promise_type' (aka 'resumable::promise_type') is not usable}}
+resumable f6(const Allocator &) { // expected-error {{operator new' provided by 'std::coroutine_traits<resumable, const Allocator &>::promise_type' (aka 'typename resumable::promise_type') is not usable}}
co_return;
}
diff --git a/clang/test/SemaCXX/coroutine-traits-undefined-template.cpp b/clang/test/SemaCXX/coroutine-traits-undefined-template.cpp
index ea25cea365b94..e7de0c80d7343 100644
--- a/clang/test/SemaCXX/coroutine-traits-undefined-template.cpp
+++ b/clang/test/SemaCXX/coroutine-traits-undefined-template.cpp
@@ -14,5 +14,5 @@ template <> struct coroutine_traits<void>; // expected-note {{forward declaratio
} // namespace std
void uses_forward_declaration() {
- co_return; // expected-error {{this function cannot be a coroutine: missing definition of specialization 'coroutine_traits<void>'}}
+ co_return; // expected-error {{this function cannot be a coroutine: missing definition of specialization 'std::coroutine_traits<void>'}}
}
diff --git a/clang/test/SemaCXX/coroutines.cpp b/clang/test/SemaCXX/coroutines.cpp
index c9cefeb30c15a..098c1c21a5962 100644
--- a/clang/test/SemaCXX/coroutines.cpp
+++ b/clang/test/SemaCXX/coroutines.cpp
@@ -1396,7 +1396,7 @@ struct bad_promise_deleted_constructor {
coro<bad_promise_deleted_constructor>
bad_coroutine_calls_deleted_promise_constructor() {
- // expected-error at -1 {{call to deleted constructor of 'std::coroutine_traits<coro<CoroHandleMemberFunctionTest::bad_promise_deleted_constructor>>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_deleted_constructor')}}
+ // expected-error at -1 {{call to deleted constructor of 'std::coroutine_traits<coro<bad_promise_deleted_constructor>>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_deleted_constructor')}}
co_return;
}
@@ -1463,7 +1463,7 @@ struct bad_promise_no_matching_constructor {
coro<bad_promise_no_matching_constructor>
bad_coroutine_calls_with_no_matching_constructor(int, int) {
- // expected-error at -1 {{call to deleted constructor of 'std::coroutine_traits<coro<CoroHandleMemberFunctionTest::bad_promise_no_matching_constructor>, int, int>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_no_matching_constructor')}}
+ // expected-error at -1 {{call to deleted constructor of 'std::coroutine_traits<coro<bad_promise_no_matching_constructor>, int, int>::promise_type' (aka 'CoroHandleMemberFunctionTest::bad_promise_no_matching_constructor')}}
co_return;
}
diff --git a/clang/test/SemaCXX/ctad.cpp b/clang/test/SemaCXX/ctad.cpp
index 50b64e39c3f92..8380b564bdcdd 100644
--- a/clang/test/SemaCXX/ctad.cpp
+++ b/clang/test/SemaCXX/ctad.cpp
@@ -186,7 +186,7 @@ namespace GH136624 {
template<class Y> using Alias = A<Y>;
}
- // FIXME: This diagnostic prints incorrect qualification for `A<int>`.
+ // FIXME: This diagnostic is missing 'foo::Alias', as written.
foo::Alias t = 0;
- // expected-error at -1 {{no viable conversion from 'int' to 'foo::A<int>' (aka 'A<int>')}}
+ // expected-error at -1 {{no viable conversion from 'int' to 'GH136624::A<int>' (aka 'A<int>')}}
} // namespace GH136624
diff --git a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
index 57a48fac56cd6..e18223d6a6df7 100644
--- a/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
+++ b/clang/test/SemaCXX/cxx1y-variable-templates_in_class.cpp
@@ -302,17 +302,17 @@ namespace in_class_template {
};
template<typename T> void f() {
- typename T::template A<int> a; // expected-error {{template name refers to non-type template 'S::template A'}}
+ typename T::template A<int> a; // expected-error {{template name refers to non-type template 'in_class_template::bad_reference::S::template A'}}
}
template<typename T> void g() {
- T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'S::template A'}}
+ T::template A<int>::B = 0; // expected-error {{template name refers to non-type template 'in_class_template::bad_reference::S::template A'}}
}
template<typename T> void h() {
- class T::template A<int> c; // expected-error {{template name refers to non-type template 'S::template A'}}
+ class T::template A<int> c; // expected-error {{template name refers to non-type template 'in_class_template::bad_reference::S::template A'}}
}
template<typename T>
- struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'S::template A'}}
+ struct X : T::template A<int> {}; // expected-error {{template name refers to non-type template 'in_class_template::bad_reference::S::template A'}}
template void f<S>(); // expected-note {{in instantiation of}}
template void g<S>(); // expected-note {{in instantiation of}}
@@ -393,7 +393,7 @@ namespace dependent_static_var_template {
int &r = A::template n; // expected-error {{use of variable template 'A::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
template<typename T>
- int &f() { return T::template n; } // expected-error {{use of variable template 'A::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
+ int &f() { return T::template n; } // expected-error {{use of variable template 'dependent_static_var_template::A::template n' requires template arguments}} expected-error {{a template argument list is expected after a name prefixed by the template keyword}}
int &s = f<A>(); // expected-note {{instantiation of}}
namespace B {
diff --git a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
index 8745185a1135c..204dd9b077b93 100644
--- a/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
+++ b/clang/test/SemaCXX/cxx1z-class-template-argument-deduction.cpp
@@ -142,13 +142,13 @@ namespace look_into_current_instantiation {
// templates, and members of the current instantiation
A<float> &r = a;
- template<typename T> struct B { // expected-note {{could not match 'B<T>' against 'int'}} \
- // expected-note {{implicit deduction guide declared as 'template <typename T> B(B<T>) -> B<T>'}}
+ template<typename T> struct B { // expected-note {{could not match 'look_into_current_instantiation::B<T>' against 'int'}} \
+ // expected-note {{implicit deduction guide declared as 'template <typename T> B(look_into_current_instantiation::B<T>) -> look_into_current_instantiation::B<T>'}}
struct X {
typedef T type;
};
B(typename X::type); // expected-note {{couldn't infer template argument 'T'}} \
- // expected-note {{implicit deduction guide declared as 'template <typename T> B(typename X::type) -> B<T>'}}
+ // expected-note {{implicit deduction guide declared as 'template <typename T> B(typename X::type) -> look_into_current_instantiation::B<T>'}}
};
B b = 0; // expected-error {{no viable}}
diff --git a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
index 27ea6663bae6a..812fd789f0c5e 100644
--- a/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
+++ b/clang/test/SemaCXX/cxx2a-destroying-delete.cpp
@@ -138,7 +138,7 @@ namespace templated {
void operator delete(id_alias<C> *, std::destroying_delete_t);
};
template<typename T> struct D {
- void operator delete(typename id_struct<D>::type *, std::destroying_delete_t); // expected-error {{use 'D<T> *'}}
+ void operator delete(typename id_struct<D>::type *, std::destroying_delete_t); // expected-error {{use 'templated::D<T> *'}}
};
}
diff --git a/clang/test/SemaCXX/cxx2b-deducing-this.cpp b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
index 2286da8d1c0e5..d29857c7961c9 100644
--- a/clang/test/SemaCXX/cxx2b-deducing-this.cpp
+++ b/clang/test/SemaCXX/cxx2b-deducing-this.cpp
@@ -96,12 +96,12 @@ struct Test {
void test() {
[i = 0](this Test) { }();
- // expected-error at -1 {{invalid explicit object parameter type 'ThisInLambdaWithCaptures::Test' in lambda with capture; the type must be the same as, or derived from, the lambda}}
+ // expected-error at -1 {{invalid explicit object parameter type 'Test' in lambda with capture; the type must be the same as, or derived from, the lambda}}
struct Derived;
auto ok = [i = 0](this const Derived&) {};
auto ko = [i = 0](this const Test&) {};
- // expected-error at -1 {{invalid explicit object parameter type 'ThisInLambdaWithCaptures::Test' in lambda with capture; the type must be the same as, or derived from, the lambda}}
+ // expected-error at -1 {{invalid explicit object parameter type 'Test' in lambda with capture; the type must be the same as, or derived from, the lambda}}
struct Derived : decltype(ok){};
Derived dok{ok};
diff --git a/clang/test/SemaCXX/cxx2c-variadic-friends.cpp b/clang/test/SemaCXX/cxx2c-variadic-friends.cpp
index a4d7c8078338d..0b01907c8c722 100644
--- a/clang/test/SemaCXX/cxx2c-variadic-friends.cpp
+++ b/clang/test/SemaCXX/cxx2c-variadic-friends.cpp
@@ -145,7 +145,7 @@ class S {
template <typename U>
struct T {
static_assert(S<U, T>::a == 42);
- static_assert(S<U, T>::a == 43); // expected-error {{static assertion failed due to requirement 'S<int, template_template::T>::a == 43'}} \
+ static_assert(S<U, T>::a == 43); // expected-error {{static assertion failed due to requirement 'template_template::S<int, template_template::T>::a == 43'}} \
// expected-note {{expression evaluates to '42 == 43'}}
};
diff --git a/clang/test/SemaCXX/destructor.cpp b/clang/test/SemaCXX/destructor.cpp
index b9e0b17d510ab..bc47d873c4e28 100644
--- a/clang/test/SemaCXX/destructor.cpp
+++ b/clang/test/SemaCXX/destructor.cpp
@@ -431,15 +431,15 @@ namespace PR9238 {
}
namespace PR7900 {
- struct A { // expected-note 2{{type 'PR7900::A' found by destructor name lookup}}
+ struct A { // expected-note 2{{type 'A' found by destructor name lookup}}
};
struct B : public A {
};
void foo() {
B b;
b.~B();
- b.~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'B' of the object being destroyed}}
- (&b)->~A(); // expected-error{{destructor type 'PR7900::A' in object destruction expression does not match the type 'B' of the object being destroyed}}
+ b.~A(); // expected-error{{destructor type 'A' in object destruction expression does not match the type 'B' of the object being destroyed}}
+ (&b)->~A(); // expected-error{{destructor type 'A' in object destruction expression does not match the type 'B' of the object being destroyed}}
}
}
diff --git a/clang/test/SemaCXX/elaborated-type-specifier.cpp b/clang/test/SemaCXX/elaborated-type-specifier.cpp
index a96e696edcc6c..a80ba0794bf12 100644
--- a/clang/test/SemaCXX/elaborated-type-specifier.cpp
+++ b/clang/test/SemaCXX/elaborated-type-specifier.cpp
@@ -27,7 +27,7 @@ namespace NS {
void test_X_elab(NS::X x) {
struct S4 *s4 = 0; // expected-note{{'S4' is not defined, but forward declared here; conversion would be valid if it was derived from 'NS::S4'}}
- x.test_elab2(s4); // expected-error{{cannot initialize a parameter of type 'S4 *' (aka 'NS::S4 *') with an lvalue of type 'struct S4 *'}}
+ x.test_elab2(s4); // expected-error{{cannot initialize a parameter of type 'S4 *' with an lvalue of type 'struct S4 *'}}
}
namespace NS {
diff --git a/clang/test/SemaCXX/enum-scoped.cpp b/clang/test/SemaCXX/enum-scoped.cpp
index d7b7923430aff..22f9107524609 100644
--- a/clang/test/SemaCXX/enum-scoped.cpp
+++ b/clang/test/SemaCXX/enum-scoped.cpp
@@ -334,7 +334,7 @@ namespace test11 {
typedef E E2;
E2 f1() { return E::a; }
- bool f() { return !f1(); } // expected-error {{invalid argument type 'E2' (aka 'test11::E') to unary expression}}
+ bool f() { return !f1(); } // expected-error {{invalid argument type 'E2' (aka 'E') to unary expression}}
}
namespace PR35586 {
diff --git a/clang/test/SemaCXX/err_init_conversion_failed.cpp b/clang/test/SemaCXX/err_init_conversion_failed.cpp
index f1949c079ecb6..e2617a1061ed7 100644
--- a/clang/test/SemaCXX/err_init_conversion_failed.cpp
+++ b/clang/test/SemaCXX/err_init_conversion_failed.cpp
@@ -56,6 +56,6 @@ template <class P> struct S2 {
void test_15() {
S2<S> X = {&S::foo};
- // expected-error-re at -1{{cannot initialize a member subobject of type 'void (S::*)(const int &){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (S::*)(int){{( __attribute__\(\(thiscall\)\))?}}': type mismatch at 1st parameter ('const int &' vs 'int')}}
+ // expected-error-re at -1{{cannot initialize a member subobject of type 'void (template_test::S::*)(const int &){{( __attribute__\(\(thiscall\)\))?}}' with an rvalue of type 'void (S::*)(int){{( __attribute__\(\(thiscall\)\))?}}': type mismatch at 1st parameter ('const int &' vs 'int')}}
}
}
diff --git a/clang/test/SemaCXX/gh102293.cpp b/clang/test/SemaCXX/gh102293.cpp
index fe417e697841b..37b674d98a282 100644
--- a/clang/test/SemaCXX/gh102293.cpp
+++ b/clang/test/SemaCXX/gh102293.cpp
@@ -35,7 +35,7 @@ class bar { // expected-note {{definition of 'GH104802::bar' is not comple
class baz { // expected-note {{definition of 'GH104802::baz' is not complete until the closing '}'}}
typedef class baz blech;
- blech a; // expected-error {{field has incomplete type 'blech' (aka 'GH104802::baz')}}
+ blech a; // expected-error {{field has incomplete type 'blech' (aka 'class baz')}}
virtual int c();
};
diff --git a/clang/test/SemaCXX/incomplete-call.cpp b/clang/test/SemaCXX/incomplete-call.cpp
index 0846c88cd68f4..8f24d455c4110 100644
--- a/clang/test/SemaCXX/incomplete-call.cpp
+++ b/clang/test/SemaCXX/incomplete-call.cpp
@@ -59,7 +59,7 @@ namespace pr18542 {
int count;
template<typename CharT> class basic_istream;
template<typename CharT>
- void basic_istream<CharT>::read() { // expected-error{{out-of-line definition of 'read' from class 'basic_istream<CharT>' without definition}}
+ void basic_istream<CharT>::read() { // expected-error{{out-of-line definition of 'read' from class 'pr18542::X::basic_istream<CharT>' without definition}}
count = 0;
}
};
diff --git a/clang/test/SemaCXX/matrix-casts.cpp b/clang/test/SemaCXX/matrix-casts.cpp
index c0f3df1ae8106..708b3fa3f3d16 100644
--- a/clang/test/SemaCXX/matrix-casts.cpp
+++ b/clang/test/SemaCXX/matrix-casts.cpp
@@ -35,7 +35,7 @@ void f1() {
(matrix_4_4<char>)v; // expected-error {{C-style cast from 'vec' (vector of 1 'int' value) to 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') is not allowed}}
(test_struct *)m1; // expected-error {{cannot cast from type 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') to pointer type 'test_struct *'}}
- (matrix_5_5<float>)s; // expected-error {{C-style cast from 'test_struct *' to 'matrix_5_5<float>' (aka 'float __attribute__((matrix_type(5, 5)))') is not allowed}}
+ (matrix_5_5<float>)s; // expected-error {{C-style cast from 'test_struct *' (aka 'struct test_struct *') to 'matrix_5_5<float>' (aka 'float __attribute__((matrix_type(5, 5)))') is not allowed}}
}
void f2() {
@@ -59,7 +59,7 @@ void f2() {
static_cast<matrix_4_4<char>>(v); // expected-error {{static_cast from 'vec' (vector of 1 'int' value) to 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') is not allowed}}
static_cast<test_struct *>(m1); // expected-error {{cannot cast from type 'matrix_4_4<char>' (aka 'char __attribute__((matrix_type(4, 4)))') to pointer type 'test_struct *'}}
- static_cast<matrix_5_5<float>>(s); // expected-error {{static_cast from 'test_struct *' to 'matrix_5_5<float>' (aka 'float __attribute__((matrix_type(5, 5)))') is not allowed}}
+ static_cast<matrix_5_5<float>>(s); // expected-error {{static_cast from 'test_struct *' (aka 'struct test_struct *') to 'matrix_5_5<float>' (aka 'float __attribute__((matrix_type(5, 5)))') is not allowed}}
}
void f3() {
diff --git a/clang/test/SemaCXX/nested-name-spec.cpp b/clang/test/SemaCXX/nested-name-spec.cpp
index fedbb3070070b..c60275b709ddb 100644
--- a/clang/test/SemaCXX/nested-name-spec.cpp
+++ b/clang/test/SemaCXX/nested-name-spec.cpp
@@ -15,7 +15,9 @@ namespace A {
static int Ag1();
static int Ag2();
};
- int ax; // expected-note {{'ax' declared here}}
+ int ax;
+ // expected-note at -1 {{'ax' declared here}}
+ // expected-note at -2 {{'::A::ax' declared here}}
void Af();
}
@@ -100,7 +102,7 @@ void f3() {
N::x = 0; // expected-error {{'N' is not a class, namespace, or enumeration}}
{ int A; A::ax = 0; }
{ typedef int A; A::ax = 0; } // expected-error{{'A' (aka 'int') is not a class, namespace, or enumeration}}
- { typedef A::C A; A::ax = 0; } // expected-error {{no member named 'ax'}}
+ { typedef A::C A; A::ax = 0; } // expected-error {{no member named 'ax' in 'A::C'; did you mean '::A::ax'?}}
{ typedef A::C A; A::cx = 0; }
}
@@ -474,7 +476,7 @@ namespace A {
class B {
typedef C D; // expected-error{{unknown type name 'C'}}
A::D::F;
- // expected-error at -1{{'PR30619::A::B::D' (aka 'int') is not a class, namespace, or enumeration}}
+ // expected-error at -1{{'A::D' (aka 'int') is not a class, namespace, or enumeration}}
};
}
}
diff --git a/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp b/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp
index b0a101e0fdcd5..8d0cdcdc22139 100644
--- a/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp
+++ b/clang/test/SemaCXX/pointer-forward-declared-class-conversion.cpp
@@ -12,6 +12,6 @@ A2<int> *a2 = b2; // expected-error{{cannot initialize a variable of type 'A2<in
typedef struct S s;
const s *f();
-s *g1() { return f(); } // expected-error{{cannot initialize return object of type 's *' (aka 'S *') with an rvalue of type 'const s *' (aka 'const S *')}}
+s *g1() { return f(); } // expected-error{{cannot initialize return object of type 's *' (aka 'struct S *') with an rvalue of type 'const s *' (aka 'const struct S *')}}
-B1 *g2() { return f(); } // expected-error{{cannot initialize return object of type 'B1 *' with an rvalue of type 'const s *' (aka 'const S *')}}
+B1 *g2() { return f(); } // expected-error{{cannot initialize return object of type 'B1 *' with an rvalue of type 'const s *' (aka 'const struct S *')}}
diff --git a/clang/test/SemaCXX/pseudo-destructors.cpp b/clang/test/SemaCXX/pseudo-destructors.cpp
index 812029285c4e0..55849d69b9b38 100644
--- a/clang/test/SemaCXX/pseudo-destructors.cpp
+++ b/clang/test/SemaCXX/pseudo-destructors.cpp
@@ -116,7 +116,7 @@ typedef Derived *Foo;
void test2(Foo d) {
d.~Foo(); // This is ok
- d.~Derived(); // expected-error {{member reference type 'Foo' (aka 'dotPointerAccess::Derived *') is a pointer; did you mean to use '->'}}
+ d.~Derived(); // expected-error {{member reference type 'Foo' (aka 'Derived *') is a pointer; did you mean to use '->'}}
}
}
diff --git a/clang/test/SemaCXX/return.cpp b/clang/test/SemaCXX/return.cpp
index 796c9ae91dedc..60accbde9d701 100644
--- a/clang/test/SemaCXX/return.cpp
+++ b/clang/test/SemaCXX/return.cpp
@@ -115,9 +115,9 @@ namespace ctor_returns_void {
};
template <typename T> struct ST {
- ST() { return f(); } // expected-error {{constructor 'ST<T>' must not return void expression}}
+ ST() { return f(); } // expected-error {{constructor 'ctor_returns_void::ST<T>' must not return void expression}}
// expected-error at -1 {{constructor 'ST' must not return void expression}}
- ~ST() { return f(); } // expected-error {{destructor '~ST<T>' must not return void expression}}
+ ~ST() { return f(); } // expected-error {{destructor '~ctor_returns_void::ST<T>' must not return void expression}}
// expected-error at -1 {{destructor '~ST' must not return void expression}}
};
diff --git a/clang/test/SemaCXX/static-assert.cpp b/clang/test/SemaCXX/static-assert.cpp
index bf6a2eeb432a3..354016db36432 100644
--- a/clang/test/SemaCXX/static-assert.cpp
+++ b/clang/test/SemaCXX/static-assert.cpp
@@ -199,7 +199,7 @@ void foo2() {
// FIXME: Here the template keyword is dropped because the failed condition
// for a static assert is always printed with canonical types.
static_assert(::ns::NestedTemplates1<T, a>::NestedTemplates2::template NestedTemplates3<U>::value, "message");
- // expected-error at -1{{static assertion failed due to requirement '::ns::NestedTemplates1<int, 3>::NestedTemplates2::NestedTemplates3<float>::value': message}}
+ // expected-error at -1{{static assertion failed due to requirement 'ns::NestedTemplates1<int, 3>::NestedTemplates2::NestedTemplates3<float>::value': message}}
}
template void foo2<int, float, 3>();
// expected-note at -1{{in instantiation of function template specialization 'foo2<int, float, 3>' requested here}}
diff --git a/clang/test/SemaCXX/sugar-common-types.cpp b/clang/test/SemaCXX/sugar-common-types.cpp
index d58f6cdd900fc..dd5fc4a654795 100644
--- a/clang/test/SemaCXX/sugar-common-types.cpp
+++ b/clang/test/SemaCXX/sugar-common-types.cpp
@@ -44,7 +44,8 @@ template <class T> struct S1 {
};
N t10 = 0 ? S1<X1>() : S1<Y1>(); // expected-error {{from 'S1<B1>' (aka 'S1<int>')}}
-N t11 = 0 ? S1<X1>::S2<X2>() : S1<Y1>::S2<Y2>(); // expected-error {{from 'S1<B1>::S2<B2>' (aka 'S2<void>')}}
+// FIXME: needs to compute common sugar for qualified template names
+N t11 = 0 ? S1<X1>::S2<X2>() : S1<Y1>::S2<Y2>(); // expected-error {{from 'S1<int>::S2<B2>' (aka 'S1<int>::S2<void>')}}
template <class T> using Al = S1<T>;
@@ -200,5 +201,5 @@ namespace member_pointers {
// FIXME: adjusted MemberPointer does not preserve qualifier
N t3 = 0 ? &W1::a : &W2::b;
- // expected-error at -1 {{rvalue of type 'B1 W<void>::*'}}
+ // expected-error at -1 {{rvalue of type 'B1 member_pointers::W<void>::*'}}
} // namespace member_pointers
diff --git a/clang/test/SemaCXX/sugared-auto.cpp b/clang/test/SemaCXX/sugared-auto.cpp
index b5bb4f0f85a77..cf879efd393d0 100644
--- a/clang/test/SemaCXX/sugared-auto.cpp
+++ b/clang/test/SemaCXX/sugared-auto.cpp
@@ -54,7 +54,7 @@ N t4 = x4; // expected-error {{lvalue of type 'Man' (aka 'int')}}
N t5 = x5; // expected-error {{lvalue of type 'Dog' (aka 'int')}}
auto x6 = { Man(), Dog() };
-N t6 = x6; // expected-error {{from 'std::initializer_list<Animal>' (aka 'initializer_list<int>')}}
+N t6 = x6; // expected-error {{from 'std::initializer_list<Animal>' (aka 'std::initializer_list<int>')}}
} // namespace variable
diff --git a/clang/test/SemaCXX/type-aware-coroutines.cpp b/clang/test/SemaCXX/type-aware-coroutines.cpp
index a54d37c47dbd9..9a6bfa310dbb2 100644
--- a/clang/test/SemaCXX/type-aware-coroutines.cpp
+++ b/clang/test/SemaCXX/type-aware-coroutines.cpp
@@ -93,7 +93,7 @@ struct resumable5 {
};
resumable f1(int) {
- // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable, int>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f1'}}
+ // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable, int>::promise_type' (aka 'typename resumable::promise_type') is not usable with the function signature of 'f1'}}
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable_tan1 {{type aware 'operator new' declared here}}
// expected-note@#resumable_tan2 {{type aware 'operator new' declared here}}
@@ -101,7 +101,7 @@ resumable f1(int) {
}
resumable f2(float) {
- // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable, float>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f2'}}
+ // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable, float>::promise_type' (aka 'typename resumable::promise_type') is not usable with the function signature of 'f2'}}
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable_tan1 {{type aware 'operator new' declared here}}
// expected-note@#resumable_tan2 {{type aware 'operator new' declared here}}
@@ -109,7 +109,7 @@ resumable f2(float) {
}
resumable2 f3(int, float, const char*, Allocator) {
- // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable2, int, float, const char *, Allocator>::promise_type' (aka 'resumable2::promise_type') is not usable with the function signature of 'f3'}}
+ // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable2, int, float, const char *, Allocator>::promise_type' (aka 'typename resumable2::promise_type') is not usable with the function signature of 'f3'}}
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable2_tan1 {{type aware 'operator new' declared here}}
co_yield 1;
@@ -117,7 +117,7 @@ resumable2 f3(int, float, const char*, Allocator) {
}
resumable f4(int n = 10) {
- // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable, int>::promise_type' (aka 'resumable::promise_type') is not usable with the function signature of 'f4'}}
+ // expected-error at -1 {{'operator new' provided by 'std::coroutine_traits<resumable, int>::promise_type' (aka 'typename resumable::promise_type') is not usable with the function signature of 'f4'}}
// expected-note at -2 {{type aware 'operator new' will not be used for coroutine allocation}}
// expected-note@#resumable_tan1 {{type aware 'operator new' declared here}}
// expected-note@#resumable_tan2 {{type aware 'operator new' declared here}}
diff --git a/clang/test/SemaCXX/undefined-partial-specialization.cpp b/clang/test/SemaCXX/undefined-partial-specialization.cpp
index 0f776a6145fef..3992d02f479f0 100644
--- a/clang/test/SemaCXX/undefined-partial-specialization.cpp
+++ b/clang/test/SemaCXX/undefined-partial-specialization.cpp
@@ -10,6 +10,6 @@ template <typename T>
class boo<T, true>;
template<typename T>
-void boo<T, true>::foo(){} // expected-error{{out-of-line definition of 'foo' from class 'boo<T, true>' without definition}}
+void boo<T, true>::foo(){} // expected-error{{out-of-line definition of 'foo' from class 'GH61356::boo<T, true>' without definition}}
}
diff --git a/clang/test/SemaObjCXX/Inputs/nullability-pragmas-1.h b/clang/test/SemaObjCXX/Inputs/nullability-pragmas-1.h
index 91753ca7f3ca5..9d5329c9d03c4 100644
--- a/clang/test/SemaObjCXX/Inputs/nullability-pragmas-1.h
+++ b/clang/test/SemaObjCXX/Inputs/nullability-pragmas-1.h
@@ -39,7 +39,7 @@ A *f14(void);
int * _Null_unspecified f15(void);
A * _Null_unspecified f16(void);
-void f17(CFErrorRef *error); // expected-note{{no known conversion from 'A * _Nonnull' to 'CFErrorRef _Nullable * _Nullable' (aka '__CFError **') for 1st argument}}
+void f17(CFErrorRef *error); // expected-note{{no known conversion from 'A * _Nonnull' to 'CFErrorRef _Nullable * _Nullable' (aka 'struct __CFError **') for 1st argument}}
void f18(A **); // expected-warning 2{{pointer is missing a nullability type specifier}}
// expected-note at -1 2 {{insert '_Nullable' if the pointer may be null}}
// expected-note at -2 2 {{insert '_Nonnull' if the pointer should never be null}}
diff --git a/clang/test/SemaObjCXX/arc-bridged-cast.mm b/clang/test/SemaObjCXX/arc-bridged-cast.mm
index 1f68897dede57..67769ebabad33 100644
--- a/clang/test/SemaObjCXX/arc-bridged-cast.mm
+++ b/clang/test/SemaObjCXX/arc-bridged-cast.mm
@@ -63,7 +63,7 @@ void testObjCBridgeId() {
void testExternC() {
id obj;
obj = (id)r0;
- obj = (id)r1; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
+ obj = (id)r1; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const struct __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
obj = (id)r2;
- obj = (id)r3; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
+ obj = (id)r3; // expected-error{{cast of C pointer type 'CFAnnotatedObjectRef' (aka 'const struct __CFAnnotatedObject *') to Objective-C pointer type 'id' requires a bridged cast}} expected-note{{use __bridge to convert directly}} expected-note{{use __bridge_transfer to transfer ownership of a +1 'CFAnnotatedObjectRef'}}
}
diff --git a/clang/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm b/clang/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm
index 3b590c46f004b..57aaa62221b65 100644
--- a/clang/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm
+++ b/clang/test/SemaObjCXX/objc-boxed-expressions-nsvalue.mm
@@ -81,7 +81,7 @@ int main() {
id edge_insets_object = @(edge_insets);
SomeStruct s;
- id err = @(s); // expected-error{{illegal type 'SomeStruct' (aka '_SomeStruct') used in a boxed expression}}
+ id err = @(s); // expected-error{{illegal type 'SomeStruct' (aka 'struct _SomeStruct') used in a boxed expression}}
NonTriviallyCopyable ntc;
id ntcErr = @(ntc); // expected-error{{non-trivially copyable type 'NonTriviallyCopyable' cannot be used in a boxed expression}}
@@ -99,7 +99,7 @@ SomeStruct getSomeStruct() {
void rvalue() {
id rv_rect = @(getRect());
- id rv_some_struct = @(getSomeStruct()); // expected-error {{illegal type 'SomeStruct' (aka '_SomeStruct') used in a boxed expression}}
+ id rv_some_struct = @(getSomeStruct()); // expected-error {{illegal type 'SomeStruct' (aka 'struct _SomeStruct') used in a boxed expression}}
}
template <class T> id box(T value) { return @(value); } // expected-error{{non-trivially copyable type 'NonTriviallyCopyable' cannot be used in a boxed expression}}
diff --git a/clang/test/SemaObjCXX/objcbridge-attribute-arc.mm b/clang/test/SemaObjCXX/objcbridge-attribute-arc.mm
index 0a86ee9f329ff..0d3751f3fd121 100644
--- a/clang/test/SemaObjCXX/objcbridge-attribute-arc.mm
+++ b/clang/test/SemaObjCXX/objcbridge-attribute-arc.mm
@@ -26,10 +26,10 @@ @protocol NSTesting @end
typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
id Test1(CFTestingRef cf) {
- return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka '__CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
- // expected-error {{cast of C pointer type 'CFTestingRef' (aka '__CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+ return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka 'struct __CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
+ // expected-error {{cast of C pointer type 'CFTestingRef' (aka 'struct __CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTestingRef' (aka '__CFError *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTestingRef' (aka 'struct __CFError *') into ARC}}
}
typedef CFErrorRef CFErrorRef1;
@@ -52,105 +52,105 @@ @interface NSUColor @end
@class NSString;
void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
- (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} \
- // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+ (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} \
+ // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
// expected-note {{__bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
// expected-note {{__bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} \
- // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}}
- (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} \
+ // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}}
+ (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}}
- (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') into ARC}}
+ (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \\
- // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} \\
+ // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}} \\
- // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} \\
+ // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *}} \\
- // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *'}} \\
+ // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
void Test3(CFErrorRef cf, NSError *ns) {
- (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
- (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
- (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka '__CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
- // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka 'struct __CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
+ // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
}
void Test4(CFMyErrorRef cf) {
- (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka '__CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
- // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
+ // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
}
void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
- (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
- (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
}
typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}}
@@ -159,51 +159,51 @@ @interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}}
@end
void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
- (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
}
void Test8(CFMyPersonalErrorRef cf) {
- (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \
- // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \
+ // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
}
void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
- (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}}
+ (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}}
(void)(__bridge NSError *)cf; // okay
(void)(__bridge NSUColor *)cf2; // okay
(void)(__bridge CFErrorRef)ns; // okay
- (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}}
- (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}}
+ (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
diff --git a/clang/test/SemaObjCXX/objcbridge-attribute.mm b/clang/test/SemaObjCXX/objcbridge-attribute.mm
index 907163b7115b3..c04fba1c1d84f 100644
--- a/clang/test/SemaObjCXX/objcbridge-attribute.mm
+++ b/clang/test/SemaObjCXX/objcbridge-attribute.mm
@@ -26,10 +26,10 @@ @protocol NSTesting @end
typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
id Test1(CFTestingRef cf) {
- return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka '__CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
- // expected-error {{cast of C pointer type 'CFTestingRef' (aka '__CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+ return (NSString *)cf; // expected-error {{CF object of type 'CFTestingRef' (aka 'struct __CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
+ // expected-error {{cast of C pointer type 'CFTestingRef' (aka 'struct __CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTestingRef' (aka '__CFError *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFTestingRef' (aka 'struct __CFError *') into ARC}}
}
typedef CFErrorRef CFErrorRef1;
@@ -52,105 +52,105 @@ @interface NSUColor @end
@class NSString;
void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
- (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} \
- // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+ (void)(NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} \
+ // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
// expected-note {{__bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(NSError *)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(MyError*)cf; // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
// expected-note {{__bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} \
- // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}}
- (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} \
+ // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}}
+ (void)(NSUColor *)cf2; // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}}
- (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') into ARC}}
+ (void)(CFErrorRef)ns; // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \\
- // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} \\
+ // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}} \\
- // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} \\
+ // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \
- // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} \
+ // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
void Test3(CFErrorRef cf, NSError *ns) {
- (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)(id)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
- (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
- (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka '__CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
- // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFErrorRef' (aka 'struct __CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
+ // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
}
void Test4(CFMyErrorRef cf) {
- (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka '__CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
- // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)(id<P1, P2, P4>)cf; // expected-warning {{'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
+ // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
}
void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
- (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ (void)(CFErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(CFErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
void Test6(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
- (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ (void)(CFMyErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
- (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
+ (void)(CFMyErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *')}}
}
typedef struct __attribute__ ((objc_bridge(MyPersonalError))) __CFMyPersonalErrorRef * CFMyPersonalErrorRef; // expected-note 1 {{declared here}}
@@ -159,52 +159,52 @@ @interface MyPersonalError : NSError <P4> // expected-note 1 {{declared here}}
@end
void Test7(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
- (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ (void)(CFMyPersonalErrorRef)ID; // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P123; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P1234; // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P12; // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
- (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
+ (void)(CFMyPersonalErrorRef)P23; // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *')}}
+ // expected-note {{use __bridge_retained to make an ARC object available as a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *')}}
}
void Test8(CFMyPersonalErrorRef cf) {
- (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)(id)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3, P4>)cf; // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
- (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \
- // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
+ (void)(id<P1, P2, P3, P4, P5>)cf; // expected-warning {{'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') bridges to MyPersonalError, not 'id<P1,P2,P3,P4,P5>'}} \
+ // expected-error {{cast of C pointer type 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') to Objective-C pointer type 'id<P1,P2,P3,P4,P5>' requires a bridged cast}} \
// expected-note {{use __bridge to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka '__CFMyPersonalErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer to transfer ownership of a +1 'CFMyPersonalErrorRef' (aka 'struct __CFMyPersonalErrorRef *') into ARC}}
}
void Test9(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
- (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}}
+ (void)(__bridge NSString *)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}}
(void)(__bridge NSError *)cf; // okay
- (void)(__bridge MyError*)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}}
+ (void)(__bridge MyError*)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}}
(void)(__bridge NSUColor *)cf2; // okay
(void)(__bridge CFErrorRef)ns; // okay
- (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}}
- (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}}
+ (void)(__bridge CFErrorRef)str; // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)(__bridge Class)cf; // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}}
+ (void)(__bridge CFErrorRef)c; // expected-warning {{'__unsafe_unretained Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
diff --git a/clang/test/SemaObjCXX/objcbridge-related-attribute.mm b/clang/test/SemaObjCXX/objcbridge-related-attribute.mm
index 66755f3d413fd..b835a104e47cf 100644
--- a/clang/test/SemaObjCXX/objcbridge-related-attribute.mm
+++ b/clang/test/SemaObjCXX/objcbridge-related-attribute.mm
@@ -13,14 +13,14 @@ - (NSColor *)backgroundColor;
NSColor *Test1(NSColor *nsColor, CGColorRef newColor) {
- nsColor = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
- NSColor *ns = newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
- return newColor; // expected-error {{'CGColorRef' (aka 'CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+ nsColor = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+ NSColor *ns = newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
+ return newColor; // expected-error {{'CGColorRef' (aka 'struct CGColor *') must be explicitly converted to 'NSColor *'; use '+colorWithCGColor:' method for this conversion}}
}
CGColorRef Test2(NSColor *newColor, CGColorRef cgColor) {
- cgColor = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}
- CGColorRef cg = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}
- return newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'CGColor *'); use '-CGColor' method for this conversion}}
+ cgColor = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+ CGColorRef cg = newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
+ return newColor; // expected-error {{'NSColor *' must be explicitly converted to 'CGColorRef' (aka 'struct CGColor *'); use '-CGColor' method for this conversion}}
}
diff --git a/clang/test/SemaObjCXX/objcbridge-static-cast.mm b/clang/test/SemaObjCXX/objcbridge-static-cast.mm
index 6cb913792a6eb..ad939da9762a4 100644
--- a/clang/test/SemaObjCXX/objcbridge-static-cast.mm
+++ b/clang/test/SemaObjCXX/objcbridge-static-cast.mm
@@ -26,10 +26,10 @@ @protocol NSTesting @end
typedef struct __attribute__((objc_bridge(NSTesting))) __CFError *CFTestingRef; // expected-note {{declared here}}
id Test1(CFTestingRef cf) {
- return static_cast<NSString *>(cf); // expected-error {{CF object of type 'CFTestingRef' (aka '__CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
- // expected-error {{cast of C pointer type 'CFTestingRef' (aka '__CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+ return static_cast<NSString *>(cf); // expected-error {{CF object of type 'CFTestingRef' (aka 'struct __CFError *') is bridged to 'NSTesting', which is not an Objective-C class}} \
+ // expected-error {{cast of C pointer type 'CFTestingRef' (aka 'struct __CFError *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFTestingRef' (aka '__CFError *') into ARC}}
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFTestingRef' (aka 'struct __CFError *') into ARC}}
}
typedef CFErrorRef CFErrorRef1;
@@ -52,84 +52,84 @@ @interface NSUColor @end
@class NSString;
void Test2(CFErrorRef2 cf, NSError *ns, NSString *str, Class c, CFUColor2Ref cf2) {
- (void)static_cast<NSString *>(cf); // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'NSString'}} \
- // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
+ (void)static_cast<NSString *>(cf); // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'NSString'}} \
+ // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSString *' requires a bridged cast}} \
// expected-note {{__bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)static_cast<NSError *>(cf); // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)static_cast<NSError *>(cf); // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'NSError *' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)static_cast<MyError*>(cf); // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)static_cast<MyError*>(cf); // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'MyError *' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}} \
- // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'MyError'}}
- (void)static_cast<NSUColor *>(cf2); // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka '__CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}} \
+ // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'MyError'}}
+ (void)static_cast<NSUColor *>(cf2); // expected-error {{cast of C pointer type 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') to Objective-C pointer type 'NSUColor *' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFUColor2Ref' (aka '__CFUPrimeColor *') into ARC}}
- (void)static_cast<CFErrorRef>(ns); // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFUColor2Ref' (aka 'union __CFUPrimeColor *') into ARC}}
+ (void)static_cast<CFErrorRef>(ns); // expected-error {{cast of Objective-C pointer type 'NSError *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)static_cast<CFErrorRef>(str); // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *')}} \\
- // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(str); // expected-warning {{'NSString' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *')}} \\
+ // expected-error {{cast of Objective-C pointer type 'NSString *' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)static_cast<Class>(cf); // expected-warning {{'CFErrorRef2' (aka '__CFErrorRef *') bridges to NSError, not 'Class'}} \\
- // expected-error {{cast of C pointer type 'CFErrorRef2' (aka '__CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)static_cast<Class>(cf); // expected-warning {{'CFErrorRef2' (aka 'struct __CFErrorRef *') bridges to NSError, not 'Class'}} \\
+ // expected-error {{cast of C pointer type 'CFErrorRef2' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'Class' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka '__CFErrorRef *') into ARC}}
- (void)static_cast<CFErrorRef>(c); // expected-warning {{'Class' cannot bridge to 'CFErrorRef' (aka '__CFErrorRef *}} \\
- // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef2' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)static_cast<CFErrorRef>(c); // expected-warning {{'Class' cannot bridge to 'CFErrorRef' (aka 'struct __CFErrorRef *'}} \\
+ // expected-error {{cast of Objective-C pointer type 'Class' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
void Test3(CFErrorRef cf, NSError *ns) {
- (void)static_cast<id>(cf); // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)static_cast<id>(cf); // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
- (void)static_cast< id<P1, P2> >(cf); // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2> >(cf); // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
- (void)static_cast< id<P1, P2, P4> >(cf); // expected-warning {{'CFErrorRef' (aka '__CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
- // expected-error {{cast of C pointer type 'CFErrorRef' (aka '__CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2, P4> >(cf); // expected-warning {{'CFErrorRef' (aka 'struct __CFErrorRef *') bridges to NSError, not 'id<P1,P2,P4>'}} \
+ // expected-error {{cast of C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka '__CFErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFErrorRef' (aka 'struct __CFErrorRef *') into ARC}}
}
void Test4(CFMyErrorRef cf) {
- (void)static_cast<id>(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
+ (void)static_cast<id>(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)static_cast< id<P1, P2> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2>' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)static_cast< id<P1, P2, P3> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2, P3> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)static_cast< id<P2, P3> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P2, P3> >(cf); // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P2,P3>' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
- (void)static_cast< id<P1, P2, P4> >(cf); // expected-warning {{'CFMyErrorRef' (aka '__CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
- // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka '__CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
+ (void)static_cast< id<P1, P2, P4> >(cf); // expected-warning {{'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') bridges to MyError, not 'id<P1,P2,P4>'}} \
+ // expected-error {{cast of C pointer type 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') to Objective-C pointer type 'id<P1,P2,P4>' requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka '__CFMyErrorRef *') into ARC}}
+ // expected-note {{use __bridge_transfer with C-style cast to transfer ownership of a +1 'CFMyErrorRef' (aka 'struct __CFMyErrorRef *') into ARC}}
}
void Test5(id<P1, P2, P3> P123, id ID, id<P1, P2, P3, P4> P1234, id<P1, P2> P12, id<P2, P3> P23) {
- (void)static_cast<CFErrorRef>(ID); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ (void)static_cast<CFErrorRef>(ID); // expected-error {{cast of Objective-C pointer type 'id' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)static_cast<CFErrorRef>(P123); // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P123); // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)static_cast<CFErrorRef>(P1234); // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P1234); // expected-error {{cast of Objective-C pointer type 'id<P1,P2,P3,P4>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)static_cast<CFErrorRef>(P12); // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P12); // expected-error {{cast of Objective-C pointer type 'id<P1,P2>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
- (void)static_cast<CFErrorRef>(P23); // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka '__CFErrorRef *') requires a bridged cast}} \
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
+ (void)static_cast<CFErrorRef>(P23); // expected-error {{cast of Objective-C pointer type 'id<P2,P3>' to C pointer type 'CFErrorRef' (aka 'struct __CFErrorRef *') requires a bridged cast}} \
// expected-note {{use __bridge with C-style cast to convert directly (no change in ownership)}} \
- // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka '__CFErrorRef *')}}
+ // expected-note {{use __bridge_retained with C-style cast to make an ARC object available as a +1 'CFErrorRef' (aka 'struct __CFErrorRef *')}}
}
diff --git a/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp b/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp
index a04fcdd3903df..cdd6bc77c765f 100644
--- a/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp
+++ b/clang/test/SemaOpenACC/combined-construct-num_workers-ast.cpp
@@ -66,7 +66,7 @@ void NormalUses() {
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <UserDefinedConversion>
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'int'
// CHECK-NEXT: MemberExpr{{.*}} '<bound member function type>' .operator int
- // CHECK-NEXT: DeclRefExpr{{.*}} 'struct CorrectConvert':'CorrectConvert' lvalue Var
+ // CHECK-NEXT: DeclRefExpr{{.*}} 'struct CorrectConvert' lvalue Var
// CHECK-NEXT: ForStmt
// CHECK: NullStmt
}
diff --git a/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp b/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
index 58476dfcee06d..63c5cdee9c966 100644
--- a/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-intexpr-clause-ast.cpp
@@ -73,7 +73,7 @@ void NormalUses() {
// CHECK-NEXT: ImplicitCastExpr{{.*}} 'int' <UserDefinedConversion>
// CHECK-NEXT: CXXMemberCallExpr{{.*}}'int'
// CHECK-NEXT: MemberExpr{{.*}} '<bound member function type>' .operator int
- // CHECK-NEXT: DeclRefExpr{{.*}} 'struct CorrectConvert':'CorrectConvert' lvalue Var
+ // CHECK-NEXT: DeclRefExpr{{.*}} 'struct CorrectConvert' lvalue Var
// CHECK-NEXT: WhileStmt
// CHECK-NEXT: CXXBoolLiteralExpr
// CHECK-NEXT: CompoundStmt
diff --git a/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp b/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
index e3c41849eba81..2d2b20f1b77f3 100644
--- a/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
+++ b/clang/test/SemaOpenACC/compute-construct-varlist-ast.cpp
@@ -102,7 +102,7 @@ void NormalUses(float *PointerParam) {
#pragma acc parallel copy(GlobalArray) pcopy(always: PointerParam[Global]) present_or_copy(alwaysin, alwaysout: Global)
while(true);
// CHECK-NEXT: OpenACCComputeConstruct{{.*}} parallel
- // CHECK-NEXT: copy clause
+ // CHECK-NEXT: copy clause
// CHECK-NEXT: DeclRefExpr{{.*}}'short[5]' lvalue Var{{.*}}'GlobalArray' 'short[5]'
// CHECK-NEXT: pcopy clause modifiers: always
// CHECK-NEXT: ArraySubscriptExpr{{.*}}'float' lvalue
@@ -649,7 +649,7 @@ void TemplUses(T t, U u, T*PointerParam) {
struct S {
// CHECK-NEXT: CXXRecordDecl{{.*}} struct S definition
- // CHECK: CXXRecordDecl{{.*}} implicit struct S
+ // CHECK: CXXRecordDecl{{.*}} implicit {{.*}}struct S{{$}}
int ThisMember;
// CHECK-NEXT: FieldDecl{{.*}} ThisMember 'int'
int *ThisMemberPtr;
diff --git a/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp b/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp
index 2ecd2694ce09d..bf153b2ec3708 100644
--- a/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp
+++ b/clang/test/SemaTemplate/aggregate-deduction-candidate.cpp
@@ -15,7 +15,7 @@ namespace Basic {
// CHECK-LABEL: Dumping Basic::<deduction guide for A>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for A>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced class depth 0 index 0 T
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T, T) -> A<T>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T, T) -> Basic::A<T>'
// CHECK: | |-ParmVarDecl {{.*}} 'T'
// CHECK: | `-ParmVarDecl {{.*}} 'T'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (double, double) -> Basic::A<double>'
@@ -23,8 +23,8 @@ namespace Basic {
// CHECK: | `-BuiltinType {{.*}} 'double'
// CHECK: |-ParmVarDecl {{.*}} 'double'
// CHECK: `-ParmVarDecl {{.*}} 'double'
- // CHECK: FunctionProtoType {{.*}} 'auto (T, T) -> A<T>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'A<T>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (T, T) -> Basic::A<T>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'Basic::A<T>' dependent
// CHECK: | `-CXXRecord {{.*}} 'A'
// CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
// CHECK: | `-TemplateTypeParm {{.*}} 'T'
@@ -66,7 +66,7 @@ namespace Basic {
// CHECK-LABEL: Dumping Basic::<deduction guide for C>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for C>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for C> 'auto (S<T>, T) -> C<T>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for C> 'auto (S<T>, T) -> Basic::C<T>'
// CHECK: | |-ParmVarDecl {{.*}} 'S<T>'
// CHECK: | `-ParmVarDecl {{.*}} 'T'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for C> 'auto (S<int>, int) -> Basic::C<int>'
@@ -74,25 +74,24 @@ namespace Basic {
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: |-ParmVarDecl {{.*}} 'S<int>':'Basic::S<int>'
// CHECK: `-ParmVarDecl {{.*}} 'int'
- // CHECK: FunctionProtoType {{.*}} 'auto (S<T>, T) -> C<T>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'C<T>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (S<T>, T) -> Basic::C<T>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'Basic::C<T>' dependent
// CHECK: | `-CXXRecord {{.*}} 'C'
- // CHECK: |-ElaboratedType {{.*}} 'S<T>' sugar dependent
- // CHECK: | `-TemplateSpecializationType {{.*}} 'S<T>' dependent
- // CHECK: | `-TemplateArgument type 'T'
- // CHECK: | `-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
- // CHECK: | `-TemplateTypeParm {{.*}} 'T'
+ // CHECK: |-TemplateSpecializationType {{.*}} 'S<T>' dependent
+ // CHECK: | `-TemplateArgument type 'T'
+ // CHECK: | `-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
+ // CHECK: | `-TemplateTypeParm {{.*}} 'T'
// CHECK: `-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
// CHECK: `-TemplateTypeParm {{.*}} 'T'
// CHECK-LABEL: Dumping Basic::<deduction guide for D>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for D>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
- // CHECK: `-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for D> 'auto (int, int) -> D<T>'
+ // CHECK: `-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for D> 'auto (int, int) -> Basic::D<T>'
// CHECK: |-ParmVarDecl {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'
- // CHECK: FunctionProtoType {{.*}} 'auto (int, int) -> D<T>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'D<T>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (int, int) -> Basic::D<T>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'Basic::D<T>' dependent
// CHECK: | `-CXXRecord {{.*}} 'D'
// CHECK: |-SubstTemplateTypeParmType {{.*}} 'int' sugar typename depth 0 index 0 T
// CHECK: | |-ClassTemplateSpecialization {{.*}} 'S'
@@ -113,7 +112,7 @@ namespace Basic {
// CHECK-LABEL: Dumping Basic::<deduction guide for E>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for E>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for E> 'auto (T, decltype(t)) -> E<T>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for E> 'auto (T, decltype(t)) -> Basic::E<T>'
// CHECK: | |-ParmVarDecl {{.*}} 'T'
// CHECK: | `-ParmVarDecl {{.*}} 'decltype(t)'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for E> 'auto (int, decltype(t)) -> Basic::E<int>'
@@ -121,8 +120,8 @@ namespace Basic {
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: |-ParmVarDecl {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'decltype(t)':'int'
- // CHECK: FunctionProtoType {{.*}} 'auto (T, decltype(t)) -> E<T>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'E<T>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (T, decltype(t)) -> Basic::E<T>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'Basic::E<T>' dependent
// CHECK: | `-CXXRecord {{.*}} 'E'
// CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
// CHECK: | `-TemplateTypeParm {{.*}} 'T'
@@ -145,7 +144,7 @@ namespace Basic {
// CHECK-LABEL: Dumping Basic::<deduction guide for F>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for F>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for F> 'auto (typename I<T>::type, T) -> F<T>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for F> 'auto (typename I<T>::type, T) -> Basic::F<T>'
// CHECK: | |-ParmVarDecl {{.*}} 'typename I<T>::type'
// CHECK: | `-ParmVarDecl {{.*}} 'T'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for F> 'auto (typename I<int>::type, int) -> Basic::F<int>'
@@ -153,8 +152,8 @@ namespace Basic {
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: |-ParmVarDecl {{.*}} 'typename I<int>::type':'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'
- // CHECK: FunctionProtoType {{.*}} 'auto (typename I<T>::type, T) -> F<T>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'F<T>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (typename I<T>::type, T) -> Basic::F<T>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'Basic::F<T>' dependent
// CHECK: | `-CXXRecord {{.*}} 'F'
// CHECK: |-DependentNameType {{.*}} 'typename I<T>::type' dependent
// CHECK: `-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
@@ -181,15 +180,15 @@ namespace Array {
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for A>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'size_t':'unsigned {{.*}}' depth 0 index 1 N
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T (&&)[N]) -> A<T, N>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T (&&)[N]) -> Array::A<T, N>'
// CHECK: | `-ParmVarDecl {{.*}} 'T (&&)[N]'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (int (&&)[3]) -> Array::A<int, 3>'
// CHECK: |-TemplateArgument type 'int'
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: |-TemplateArgument integral '3UL'
// CHECK: `-ParmVarDecl {{.*}} 'int (&&)[3]'
- // CHECK: FunctionProtoType {{.*}} 'auto (T (&&)[N]) -> A<T, N>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'A<T, N>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (T (&&)[N]) -> Array::A<T, N>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'Array::A<T, N>' dependent
// CHECK: | `-CXXRecord {{.*}} 'A'
// CHECK: `-RValueReferenceType {{.*}} 'T (&&)[N]' dependent
// CHECK: `-DependentSizedArrayType {{.*}} 'T[N]' dependent
@@ -201,15 +200,15 @@ namespace Array {
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for A>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
// CHECK: |-NonTypeTemplateParmDecl {{.*}} 'size_t':'unsigned {{.*}}' depth 0 index 1 N
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (const T (&)[N]) -> A<T, N>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (const T (&)[N]) -> Array::A<T, N>'
// CHECK: | `-ParmVarDecl {{.*}} 'const T (&)[N]'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (const char (&)[5]) -> Array::A<char, 5>'
// CHECK: |-TemplateArgument type 'char'
// CHECK: | `-BuiltinType {{.*}} 'char'
// CHECK: |-TemplateArgument integral '5UL'
// CHECK: `-ParmVarDecl {{.*}} 'const char (&)[5]'
- // CHECK: FunctionProtoType {{.*}} 'auto (const T (&)[N]) -> A<T, N>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'A<T, N>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (const T (&)[N]) -> Array::A<T, N>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'Array::A<T, N>' dependent
// CHECK: | `-CXXRecord {{.*}} 'A'
// CHECK: `-LValueReferenceType {{.*}} 'const T (&)[N]' dependent
// CHECK: `-QualType {{.*}} 'const T[N]' const
@@ -232,7 +231,7 @@ namespace BraceElision {
// CHECK-LABEL: Dumping BraceElision::<deduction guide for A>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for A>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 T
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T, T) -> A<T>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T, T) -> BraceElision::A<T>'
// CHECK: | |-ParmVarDecl {{.*}} 'T'
// CHECK: | `-ParmVarDecl {{.*}} 'T'
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A> 'auto (int, int) -> BraceElision::A<int>'
@@ -240,8 +239,8 @@ namespace BraceElision {
// CHECK: | `-BuiltinType {{.*}} 'int'
// CHECK: |-ParmVarDecl {{.*}} 'int'
// CHECK: `-ParmVarDecl {{.*}} 'int'
- // CHECK: FunctionProtoType {{.*}} 'auto (T, T) -> A<T>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'A<T>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (T, T) -> BraceElision::A<T>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'BraceElision::A<T>' dependent
// CHECK: | `-CXXRecord {{.*}} 'A'
// CHECK: |-TemplateTypeParmType {{.*}} 'T' dependent depth 0 index 0
// CHECK: | `-TemplateTypeParm {{.*}} 'T'
@@ -266,7 +265,7 @@ namespace TrailingPack {
// CHECK-LABEL: Dumping TrailingPack::<deduction guide for A>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for A>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 ... T
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T...) -> A<T...>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for A> 'auto (T...) -> TrailingPack::A<T...>'
// CHECK: | `-ParmVarDecl {{.*}} 'T...' pack
// CHECK: `-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for A>
// CHECK-SAME: 'auto (TrailingPack::(lambda at {{.*}}), TrailingPack::(lambda at {{.*}})) ->
@@ -274,14 +273,14 @@ namespace TrailingPack {
// CHECK: |-TemplateArgument pack
// CHECK: | |-TemplateArgument type 'TrailingPack::(lambda at {{.*}})'
// CHECK: | | `-RecordType {{.*}} 'TrailingPack::(lambda at {{.*}})'
- // CHECK: | | `-CXXRecord {{.*}} <line:262:5>
+ // CHECK: | | `-CXXRecord {{.*}} <line:261:5>
// CHECK: | `-TemplateArgument type 'TrailingPack::(lambda at {{.*}})'
// CHECK: | `-RecordType {{.*}} 'TrailingPack::(lambda at {{.*}})'
- // CHECK: | `-CXXRecord {{.*}} <line:263:5>
+ // CHECK: | `-CXXRecord {{.*}} <line:262:5>
// CHECK: |-ParmVarDecl {{.*}} 'TrailingPack::(lambda at {{.*}})'
// CHECK: `-ParmVarDecl {{.*}} 'TrailingPack::(lambda at {{.*}})'
- // CHECK: FunctionProtoType {{.*}} 'auto (T...) -> A<T...>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'A<T...>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (T...) -> TrailingPack::A<T...>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'TrailingPack::A<T...>' dependent
// CHECK: | `-CXXRecord {{.*}} 'A'
// CHECK: `-PackExpansionType {{.*}} 'T...' dependent
// CHECK: `-TemplateTypeParmType {{.*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
@@ -327,7 +326,7 @@ namespace DeduceArity {
// CHECK-LABEL: Dumping DeduceArity::<deduction guide for F>:
// CHECK: FunctionTemplateDecl {{.*}} implicit <deduction guide for F>
// CHECK: |-TemplateTypeParmDecl {{.*}} referenced typename depth 0 index 0 ... T
- // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for F> 'auto (Types<T...>, T...) -> F<T...>'
+ // CHECK: |-CXXDeductionGuideDecl {{.*}} implicit <deduction guide for F> 'auto (Types<T...>, T...) -> DeduceArity::F<T...>'
// CHECK: | |-ParmVarDecl {{.*}} 'Types<T...>'
// CHECK: | `-ParmVarDecl {{.*}} 'T...' pack
// CHECK: |-CXXDeductionGuideDecl {{.*}} implicit used <deduction guide for F>
@@ -354,15 +353,14 @@ namespace DeduceArity {
// CHECK: | `-CXXRecord {{.*}} 'X'
// CHECK: |-ParmVarDecl {{.*}} 'Types<DeduceArity::X>':'DeduceArity::Types<DeduceArity::X>'
// CHECK: `-ParmVarDecl {{.*}} 'DeduceArity::X'
- // CHECK: FunctionProtoType {{.*}} 'auto (Types<T...>, T...) -> F<T...>' dependent trailing_return cdecl
- // CHECK: |-InjectedClassNameType {{.*}} 'F<T...>' dependent
+ // CHECK: FunctionProtoType {{.*}} 'auto (Types<T...>, T...) -> DeduceArity::F<T...>' dependent trailing_return cdecl
+ // CHECK: |-InjectedClassNameType {{.*}} 'DeduceArity::F<T...>' dependent
// CHECK: | `-CXXRecord {{.*}} 'F'
- // CHECK: |-ElaboratedType {{.*}} 'Types<T...>' sugar dependent
- // CHECK: | `-TemplateSpecializationType {{.*}} 'Types<T...>' dependent
- // CHECK: | `-TemplateArgument type 'T...'
- // CHECK: | `-PackExpansionType {{.*}} 'T...' dependent
- // CHECK: | `-TemplateTypeParmType {{.*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
- // CHECK: | `-TemplateTypeParm {{.*}} 'T'
+ // CHECK: |-TemplateSpecializationType {{.*}} 'Types<T...>' dependent
+ // CHECK: | `-TemplateArgument type 'T...'
+ // CHECK: | `-PackExpansionType {{.*}} 'T...' dependent
+ // CHECK: | `-TemplateTypeParmType {{.*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
+ // CHECK: | `-TemplateTypeParm {{.*}} 'T'
// CHECK: `-PackExpansionType {{.*}} 'T...' dependent
// CHECK: `-TemplateTypeParmType {{.*}} 'T' dependent contains_unexpanded_pack depth 0 index 0 pack
// CHECK: `-TemplateTypeParm {{.*}} 'T'
diff --git a/clang/test/SemaTemplate/ctad.cpp b/clang/test/SemaTemplate/ctad.cpp
index 1bf605f823bbe..f80bc050f4b76 100644
--- a/clang/test/SemaTemplate/ctad.cpp
+++ b/clang/test/SemaTemplate/ctad.cpp
@@ -21,9 +21,9 @@ namespace Access {
struct type {};
};
template<typename T> struct D : B { // expected-note {{not viable}} \
- expected-note {{implicit deduction guide declared as 'template <typename T> D(D<T>) -> D<T>'}}
+ expected-note {{implicit deduction guide declared as 'template <typename T> D(Access::D<T>) -> Access::D<T>'}}
D(T, typename T::type); // expected-note {{private member}} \
- // expected-note {{implicit deduction guide declared as 'template <typename T> D(T, typename T::type) -> D<T>'}}
+ // expected-note {{implicit deduction guide declared as 'template <typename T> D(T, typename T::type) -> Access::D<T>'}}
};
D b = {B(), {}};
@@ -61,14 +61,14 @@ namespace NoCrashOnGettingDefaultArgLoc {
template <typename>
class A {
A(int = 1); // expected-note {{candidate template ignored: couldn't infer template argumen}} \
- // expected-note {{implicit deduction guide declared as 'template <typename> D(int = <null expr>) -> D<type-parameter-0-0>'}}
+ // expected-note {{implicit deduction guide declared as 'template <typename> D(int = <null expr>) -> NoCrashOnGettingDefaultArgLoc::D<type-parameter-0-0>'}}
};
class C : A<int> {
using A::A;
};
template <typename>
class D : C { // expected-note {{candidate function template not viable: requires 1 argument}} \
- expected-note {{implicit deduction guide declared as 'template <typename> D(D<type-parameter-0-0>) -> D<type-parameter-0-0>'}}
+ expected-note {{implicit deduction guide declared as 'template <typename> D(NoCrashOnGettingDefaultArgLoc::D<type-parameter-0-0>) -> NoCrashOnGettingDefaultArgLoc::D<type-parameter-0-0>'}}
using C::C;
};
D abc; // expected-error {{no viable constructor or deduction guide}}
diff --git a/clang/test/SemaTemplate/current-instantiation.cpp b/clang/test/SemaTemplate/current-instantiation.cpp
index 9030768846b28..9214bbeb973d6 100644
--- a/clang/test/SemaTemplate/current-instantiation.cpp
+++ b/clang/test/SemaTemplate/current-instantiation.cpp
@@ -245,5 +245,5 @@ namespace RebuildDependentScopeDeclRefExpr {
};
template<typename T> N<X<T>::thing> X<T>::data() {}
// FIXME: We should issue a typo-correction here.
- template<typename T> N<X<T>::think> X<T>::foo() {} // expected-error {{no member named 'think' in 'X<T>'}}
+ template<typename T> N<X<T>::think> X<T>::foo() {} // expected-error {{no member named 'think' in 'RebuildDependentScopeDeclRefExpr::X<T>'}}
}
diff --git a/clang/test/SemaTemplate/deduction-crash.cpp b/clang/test/SemaTemplate/deduction-crash.cpp
index 287c61aef00d6..99ca0b365ff6f 100644
--- a/clang/test/SemaTemplate/deduction-crash.cpp
+++ b/clang/test/SemaTemplate/deduction-crash.cpp
@@ -166,9 +166,9 @@ namespace PR51872_part1 {
template<int> class T1 { template <struct U1> T1(); };
// expected-error at -1 {{non-type template parameter has incomplete type 'struct U1'}}
// expected-note at -2 {{forward declaration of 'PR51872_part1::U1'}}
- // expected-note at -3 {{implicit deduction guide declared as 'template <int> T1(T1<value-parameter-0-0>) -> T1<value-parameter-0-0>'}}
+ // expected-note at -3 {{implicit deduction guide declared as 'template <int> T1(PR51872_part1::T1<value-parameter-0-0>) -> PR51872_part1::T1<value-parameter-0-0>'}}
T1 t1 = 0;
// expected-error at -1 {{no viable constructor or deduction guide for deduction of template arguments of 'T1'}}
- // expected-note at -7 {{candidate template ignored: could not match 'T1<value-parameter-0-0>' against 'int'}}
+ // expected-note at -7 {{candidate template ignored: could not match 'PR51872_part1::T1<value-parameter-0-0>' against 'int'}}
}
diff --git a/clang/test/SemaTemplate/deduction-guide.cpp b/clang/test/SemaTemplate/deduction-guide.cpp
index 0953f647426fa..c8982ae37f7ef 100644
--- a/clang/test/SemaTemplate/deduction-guide.cpp
+++ b/clang/test/SemaTemplate/deduction-guide.cpp
@@ -43,11 +43,10 @@ using AT = A<int[3], int, int, short>;
// CHECK: `-ParmVarDecl {{.*}} 'short (*)[4]'
// CHECK: FunctionProtoType {{.*}} 'auto (X<Ps...>, Ts (*)[Ns]...) -> A<T, Ts...>' dependent trailing_return
// CHECK: |-InjectedClassNameType {{.*}} 'A<T, Ts...>' dependent
-// CHECK: |-ElaboratedType {{.*}} 'X<Ps...>' sugar dependent
-// CHECK: | `-TemplateSpecializationType {{.*}} 'X<Ps...>' dependent
-// CHECK: | `-TemplateArgument expr
-// CHECK: | `-PackExpansionExpr {{.*}} 'T *'
-// CHECK: | `-DeclRefExpr {{.*}} 'T *' NonTypeTemplateParm {{.*}} 'Ps' 'T *'
+// CHECK: |-TemplateSpecializationType {{.*}} 'X<Ps...>' dependent
+// CHECK: | `-TemplateArgument expr
+// CHECK: | `-PackExpansionExpr {{.*}} 'T *'
+// CHECK: | `-DeclRefExpr {{.*}} 'T *' NonTypeTemplateParm {{.*}} 'Ps' 'T *'
// CHECK: `-PackExpansionType {{.*}} 'Ts (*)[Ns]...' dependent
// CHECK: `-PointerType {{.*}} 'Ts (*)[Ns]' dependent contains_unexpanded_pack
// CHECK: `-ParenType {{.*}} 'Ts[Ns]' sugar dependent contains_unexpanded_pack
@@ -118,9 +117,8 @@ using CT = C<int>;
// CHECK: |-InjectedClassNameType {{.*}} 'C<A>' dependent
// CHECK: |-TemplateTypeParmType {{.*}} 'A' dependent depth 0 index 0
// CHECK: | `-TemplateTypeParm {{.*}} 'A'
-// CHECK: |-ElaboratedType {{.*}} 'Y<T>' sugar dependent
-// CHECK: | `-TemplateSpecializationType {{.*}} 'Y<T>' dependent
-// CHECK: | `-TemplateArgument template
+// CHECK: |-TemplateSpecializationType {{.*}} 'Y<T>' dependent
+// CHECK: | `-TemplateArgument template
// CHECK: `-TemplateTypeParmType {{.*}} 'U' dependent depth 0 index 2
template<typename ...T> struct D { // expected-note {{candidate}} \
@@ -321,24 +319,23 @@ namespace TTP {
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 0 T{{$}}
// CHECK-NEXT: |-TemplateTemplateParmDecl {{.+}} depth 0 index 1 TT{{$}}
// CHECK-NEXT: | `-TemplateTypeParmDecl {{.+}} class depth 1 index 0{{$}}
-// CHECK-NEXT: |-CXXDeductionGuideDecl {{.+}} 'auto (TT<T>) -> B<T>'{{$}}
+// CHECK-NEXT: |-CXXDeductionGuideDecl {{.+}} 'auto (TT<T>) -> TTP::B<T>'{{$}}
// CHECK-NEXT: | `-ParmVarDecl {{.+}} 'TT<T>'{{$}}
-// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} 'auto (A<int>) -> TTP::B<int>'
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} 'auto (TTP::A<int>) -> TTP::B<int>'
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'{{$}}
// CHECK-NEXT: |-TemplateArgument template 'TTP::A'{{$}}
// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A{{$}}
-// CHECK-NEXT: `-ParmVarDecl {{.+}} 'A<int>':'TTP::A<int>'{{$}}
-// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (TT<T>) -> B<T>' dependent trailing_return cdecl{{$}}
-// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'B<T>' dependent{{$}}
+// CHECK-NEXT: `-ParmVarDecl {{.+}} 'TTP::A<int>'{{$}}
+// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (TT<T>) -> TTP::B<T>' dependent trailing_return cdecl{{$}}
+// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'TTP::B<T>' dependent{{$}}
// CHECK-NEXT: | `-CXXRecord {{.+}} 'B'{{$}}
-// CHECK-NEXT: `-ElaboratedType {{.+}} 'TT<T>' sugar dependent{{$}}
-// CHECK-NEXT: `-TemplateSpecializationType {{.+}} 'TT<T>' dependent{{$}}
-// CHECK-NEXT: |-name: 'TT':'template-parameter-0-1' qualified
-// CHECK-NEXT: | `-TemplateTemplateParmDecl {{.+}} depth 0 index 1
-// CHECK-NEXT: `-TemplateArgument type 'T':'type-parameter-0-0'{{$}}
-// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0{{$}}
-// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'T'{{$}}
+// CHECK-NEXT: `-TemplateSpecializationType {{.+}} 'TT<T>' dependent{{$}}
+// CHECK-NEXT: |-name: 'TT':'template-parameter-0-1' qualified
+// CHECK-NEXT: | `-TemplateTemplateParmDecl {{.+}} depth 0 index 1
+// CHECK-NEXT: `-TemplateArgument type 'T':'type-parameter-0-0'{{$}}
+// CHECK-NEXT: `-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0{{$}}
+// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'T'{{$}}
namespace GH64625 {
@@ -351,14 +348,14 @@ X x = {{1, 2}};
// CHECK-LABEL: Dumping GH64625::<deduction guide for X>:
// CHECK-NEXT: FunctionTemplateDecl {{.+}} <{{.+}}:[[#@LINE - 7]]:1, col:27> col:27 implicit <deduction guide for X>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} <col:11, col:17> col:17 referenced class depth 0 index 0 T
-// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:27> col:27 implicit <deduction guide for X> 'auto (T (&&)[2]) -> X<T>' aggregate
+// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:27> col:27 implicit <deduction guide for X> 'auto (T (&&)[2]) -> GH64625::X<T>' aggregate
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:27> col:27 'T (&&)[2]'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:27> col:27 implicit used <deduction guide for X> 'auto (int (&&)[2]) -> GH64625::X<int>' implicit_instantiation aggregate
// CHECK-NEXT: |-TemplateArgument type 'int'
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:27> col:27 'int (&&)[2]'
-// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2]) -> X<T>' dependent trailing_return
-// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'X<T>' dependent
+// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2]) -> GH64625::X<T>' dependent trailing_return
+// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'GH64625::X<T>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'X'
// CHECK-NEXT: `-RValueReferenceType {{.+}} 'T (&&)[2]' dependent
// CHECK-NEXT: `-ConstantArrayType {{.+}} 'T[2]' dependent 2
@@ -375,7 +372,7 @@ TwoArrays ta = {{1, 2}, {3, 4, 5}};
// CHECK-NEXT: FunctionTemplateDecl {{.+}} <{{.+}}:[[#@LINE - 7]]:1, col:36> col:36 implicit <deduction guide for TwoArrays>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} <col:11, col:17> col:17 referenced class depth 0 index 0 T
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} <col:20, col:26> col:26 referenced class depth 0 index 1 U
-// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T (&&)[2], U (&&)[3]) -> TwoArrays<T, U>' aggregate
+// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T (&&)[2], U (&&)[3]) -> GH64625::TwoArrays<T, U>' aggregate
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T (&&)[2]'
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:36> col:36 'U (&&)[3]'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit used <deduction guide for TwoArrays> 'auto (int (&&)[2], int (&&)[3]) -> GH64625::TwoArrays<int, int>' implicit_instantiation aggregate
@@ -385,8 +382,8 @@ TwoArrays ta = {{1, 2}, {3, 4, 5}};
// CHECK-NEXT: | `-BuiltinType {{.+}} 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int (&&)[2]'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:36> col:36 'int (&&)[3]'
-// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2], U (&&)[3]) -> TwoArrays<T, U>' dependent trailing_return
-// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'TwoArrays<T, U>' dependent
+// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2], U (&&)[3]) -> GH64625::TwoArrays<T, U>' dependent trailing_return
+// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'GH64625::TwoArrays<T, U>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'TwoArrays'
// CHECK-NEXT: |-RValueReferenceType {{.+}} 'T (&&)[2]' dependent
// CHECK-NEXT: | `-ConstantArrayType {{.+}} 'T[2]' dependent 2
@@ -398,7 +395,7 @@ TwoArrays ta = {{1, 2}, {3, 4, 5}};
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'U'
TwoArrays tb = {1, 2, {3, 4, 5}};
-// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T, T, U (&&)[3]) -> TwoArrays<T, U>' aggregate
+// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T, T, U (&&)[3]) -> GH64625::TwoArrays<T, U>' aggregate
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T'
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T'
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:36> col:36 'U (&&)[3]'
@@ -410,8 +407,8 @@ TwoArrays tb = {1, 2, {3, 4, 5}};
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:36> col:36 'int (&&)[3]'
-// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T, T, U (&&)[3]) -> TwoArrays<T, U>' dependent trailing_return
-// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'TwoArrays<T, U>' dependent
+// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T, T, U (&&)[3]) -> GH64625::TwoArrays<T, U>' dependent trailing_return
+// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'GH64625::TwoArrays<T, U>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'TwoArrays'
// CHECK-NEXT: |-TemplateTypeParmType {{.+}} 'T' dependent depth 0 index 0
// CHECK-NEXT: | `-TemplateTypeParm {{.+}} 'T'
@@ -423,7 +420,7 @@ TwoArrays tb = {1, 2, {3, 4, 5}};
// CHECK-NEXT: `-TemplateTypeParm {{.+}} 'U'
TwoArrays tc = {{1, 2}, 3, 4, 5};
-// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T (&&)[2], U, U, U) -> TwoArrays<T, U>' aggregate
+// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:36> col:36 implicit <deduction guide for TwoArrays> 'auto (T (&&)[2], U, U, U) -> GH64625::TwoArrays<T, U>' aggregate
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'T (&&)[2]'
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'U'
// CHECK-NEXT: | |-ParmVarDecl {{.+}} <col:36> col:36 'U'
@@ -437,8 +434,8 @@ TwoArrays tc = {{1, 2}, 3, 4, 5};
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: |-ParmVarDecl {{.+}} <col:36> col:36 'int'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:36> col:36 'int'
-// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2], U, U, U) -> TwoArrays<T, U>' dependent trailing_return
-// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'TwoArrays<T, U>' dependent
+// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (T (&&)[2], U, U, U) -> GH64625::TwoArrays<T, U>' dependent trailing_return
+// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'GH64625::TwoArrays<T, U>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'TwoArrays'
// CHECK-NEXT: |-RValueReferenceType {{.+}} 'T (&&)[2]' dependent
// CHECK-NEXT: | `-ConstantArrayType {{.+}} 'T[2]' dependent 2
@@ -464,13 +461,13 @@ A a{.f1 = {1}};
// CHECK-LABEL: Dumping GH83368::<deduction guide for A>:
// CHECK-NEXT: FunctionTemplateDecl 0x{{.+}} <{{.+}}:[[#@LINE - 7]]:1, col:25> col:25 implicit <deduction guide for A>
// CHECK-NEXT: |-NonTypeTemplateParmDecl {{.+}} <col:11, col:15> col:15 referenced 'int' depth 0 index 0 N
-// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:25> col:25 implicit <deduction guide for A> 'auto (int (&&)[N]) -> A<N>' aggregate
+// CHECK: |-CXXDeductionGuideDecl {{.+}} <col:25> col:25 implicit <deduction guide for A> 'auto (int (&&)[N]) -> GH83368::A<N>' aggregate
// CHECK-NEXT: | `-ParmVarDecl {{.+}} <col:25> col:25 'int (&&)[N]'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <col:25> col:25 implicit used <deduction guide for A> 'auto (int (&&)[1]) -> GH83368::A<1>' implicit_instantiation aggregate
// CHECK-NEXT: |-TemplateArgument integral '1'
// CHECK-NEXT: `-ParmVarDecl {{.+}} <col:25> col:25 'int (&&)[1]'
-// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (int (&&)[N]) -> A<N>' dependent trailing_return
-// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'A<N>' dependent
+// CHECK-NEXT: FunctionProtoType {{.+}} 'auto (int (&&)[N]) -> GH83368::A<N>' dependent trailing_return
+// CHECK-NEXT: |-InjectedClassNameType {{.+}} 'GH83368::A<N>' dependent
// CHECK-NEXT: | `-CXXRecord {{.+}} 'A'
// CHECK-NEXT: `-RValueReferenceType {{.+}} 'int (&&)[N]' dependent
// CHECK-NEXT: `-DependentSizedArrayType {{.+}} 'int[N]' dependent
@@ -512,7 +509,7 @@ A a(42);
// CHECK-NEXT: | | `-TemplateTypeParm 0x{{.+}} 'Ts'
// CHECK-NEXT: | `-ImplicitCastExpr {{.+}} <IntegralCast>
// CHECK-NEXT: | `-IntegerLiteral 0x{{.+}} <{{.+}}> 'int' 0
-// CHECK-NEXT: |-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> line:{{.+}} implicit <deduction guide for A> 'auto (T, Ts...) -> A<T>'
+// CHECK-NEXT: |-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> line:{{.+}} implicit <deduction guide for A> 'auto (T, Ts...) -> GH60777::A<T>'
// CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <{{.+}}> col:{{.+}} val 'T'
// CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <{{.+}}> col:{{.+}} tail 'Ts...' pack
// CHECK-NEXT: | `-BinaryOperator 0x{{.+}} <{{.+}}> 'bool' '&&'
@@ -541,9 +538,9 @@ B b(42, 43);
// expected-error at -1 {{no viable constructor}} \
// expected-note at -6 {{constraints not satisfied}} \
// expected-note at -5 {{because substituted constraint expression is ill-formed}} \
-// expected-note at -6 {{implicit deduction guide declared as 'template <typename T, typename ...Ts> B(T val, Ts ...tail) -> B<T> requires (True<tail...>())'}} \
+// expected-note at -6 {{implicit deduction guide declared as 'template <typename T, typename ...Ts> B(T val, Ts ...tail) -> GH60777::B<T> requires (True<tail...>())'}} \
// expected-note at -8 {{function template not viable}} \
-// expected-note at -8 {{implicit deduction guide declared as 'template <typename T> B(B<T>) -> B<T>'}}
+// expected-note at -8 {{implicit deduction guide declared as 'template <typename T> B(GH60777::B<T>) -> GH60777::B<T>'}}
} // namespace GH60777
@@ -572,7 +569,7 @@ static_assert(x.size == 4);
// CHECK-NEXT: FunctionTemplateDecl 0x{{.+}} <{{.+}}> col:13 implicit <deduction guide for X>
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:17 referenced class depth 0 index 0 T
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{.+}} <{{.+}}> col:19 class depth 0 index 1 U
-// CHECK-NEXT: |-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> col:13 implicit <deduction guide for X> 'auto (T, U (&)[3]) -> X<T>'
+// CHECK-NEXT: |-CXXDeductionGuideDecl 0x{{.+}} <{{.+}}> col:13 implicit <deduction guide for X> 'auto (T, U (&)[3]) -> GH98592::X<T>'
// CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <col:15> col:16 'T'
// CHECK-NEXT: | |-ParmVarDecl 0x{{.+}} <col:18, col:24> col:21 'U (&)[3]'
// CHECK-NEXT: | `-ConceptSpecializationExpr 0x{{.+}} <col:36, col:42> 'bool' Concept 0x{{.+}} 'True'
@@ -719,7 +716,7 @@ void test() { NewDeleteAllocator abc(42); } // expected-error {{no viable constr
// CHECK-NEXT: | |-inherited from TemplateTypeParm {{.+}} depth 0 index 0
// CHECK-NEXT: | `-BuiltinType {{.+}} 'void'
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 1 T
-// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <deduction guide for NewDeleteAllocator> 'auto (T) -> NewDeleteAllocator<type-parameter-0-0>'
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} <deduction guide for NewDeleteAllocator> 'auto (T) -> GH128691::NewDeleteAllocator<type-parameter-0-0>'
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'T'
} // namespace GH128691
@@ -745,7 +742,7 @@ B b(24);
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for B>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
-// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for B> 'auto (U) -> B<type-parameter-0-0>'
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for B> 'auto (U) -> GH132616_DeductionGuide::B<type-parameter-0-0>'
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U'
struct C {
@@ -767,7 +764,7 @@ D d(24);
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for D>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} typename depth 0 index 0
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
-// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for D> 'auto (U) -> D<type-parameter-0-0>'
+// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for D> 'auto (U) -> GH132616_DeductionGuide::D<type-parameter-0-0>'
// CHECK-NEXT: `-ParmVarDecl {{.+}} 'U'
} // namespace GH132616_DeductionGuide
@@ -859,13 +856,12 @@ CC c{};
// CHECK-NEXT: | `-IntegerLiteral {{.+}} 'int' 42
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} class depth 0 index 1 U
// CHECK-NEXT: | `-TemplateArgument type 'A<decltype(N)>'
-// CHECK-NEXT: | `-ElaboratedType {{.+}} 'A<decltype(N)>' sugar dependent
-// CHECK-NEXT: | `-TemplateSpecializationType {{.+}} 'A<decltype(N)>' dependent
-// CHECK-NEXT: | |-name: 'A':'GH133132::A' qualified
-// CHECK-NEXT: | | `-ClassTemplateDecl {{.+}} A
-// CHECK-NEXT: | `-TemplateArgument type 'decltype(N)'
-// CHECK-NEXT: | `-DecltypeType {{.+}} 'decltype(N)' dependent
-// CHECK-NEXT: | `-DeclRefExpr {{.+}} 'int' NonTypeTemplateParm {{.+}} 'N' 'int'
+// CHECK-NEXT: | `-TemplateSpecializationType {{.+}} 'A<decltype(N)>' dependent
+// CHECK-NEXT: | |-name: 'A':'GH133132::A' qualified
+// CHECK-NEXT: | | `-ClassTemplateDecl {{.+}} A
+// CHECK-NEXT: | `-TemplateArgument type 'decltype(N)'
+// CHECK-NEXT: | `-DecltypeType {{.+}} 'decltype(N)' dependent
+// CHECK-NEXT: | `-DeclRefExpr {{.+}} 'int' NonTypeTemplateParm {{.+}} 'N' 'int'
// CHECK-NEXT: |-TypeTraitExpr {{.+}} 'bool' __is_deducible
// CHECK-NEXT: | |-DeducedTemplateSpecializationType {{.+}} 'GH133132::CC' dependent
// CHECK-NEXT: | | `-name: 'GH133132::CC'
@@ -903,7 +899,7 @@ void f() {
// CHECK-LABEL: Dumping GH67173::<deduction guide for Vec2d>:
// CHECK-NEXT: FunctionTemplateDecl {{.+}} implicit <deduction guide for Vec2d>
// CHECK-NEXT: |-TemplateTypeParmDecl {{.+}} referenced class depth 0 index 0 T
-// CHECK: |-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for Vec2d> 'auto (T, T) -> Vec2d<T>' aggregate
+// CHECK: |-CXXDeductionGuideDecl {{.+}} implicit <deduction guide for Vec2d> 'auto (T, T) -> GH67173::Vec2d<T>' aggregate
// CHECK-NEXT: | |-ParmVarDecl {{.+}} col:27 'T'
// CHECK-NEXT: | `-ParmVarDecl {{.+}} col:27 'T'
// CHECK-NEXT: `-CXXDeductionGuideDecl {{.+}} implicit used <deduction guide for Vec2d> 'auto (int, int) -> GH67173::Vec2d<int>' implicit_instantiation aggregate
diff --git a/clang/test/SemaTemplate/dependent-base-classes.cpp b/clang/test/SemaTemplate/dependent-base-classes.cpp
index b4b26698ebf9c..b1c6102ea5666 100644
--- a/clang/test/SemaTemplate/dependent-base-classes.cpp
+++ b/clang/test/SemaTemplate/dependent-base-classes.cpp
@@ -32,7 +32,7 @@ namespace PR6031 {
template <class TT>
struct FI2
{
- C<typename FI2::type> a; // expected-error{{no type named 'type' in 'FI2<TT>'}}
+ C<typename FI2::type> a; // expected-error{{no type named 'type' in 'PR6031::FI2<TT>'}}
};
template<typename T>
@@ -54,9 +54,9 @@ namespace PR6031 {
template<typename T>
struct NoDepBase {
int foo() {
- class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'NoDepBase<T>'}}
- typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{no member named 'MemberTemplate' in 'NoDepBase<T>'}}
- return NoDepBase::a; // expected-error{{no member named 'a' in 'NoDepBase<T>'}}
+ class NoDepBase::Nested nested; // expected-error{{no class named 'Nested' in 'PR6031::NoDepBase<T>'}}
+ typedef typename NoDepBase::template MemberTemplate<T>::type type; // expected-error{{no member named 'MemberTemplate' in 'PR6031::NoDepBase<T>'}}
+ return NoDepBase::a; // expected-error{{no member named 'a' in 'PR6031::NoDepBase<T>'}}
}
};
}
@@ -102,7 +102,7 @@ namespace PR6081 {
template< class X >
void f0(const X & k)
{
- this->template f1<int>()(k); // expected-error{{no member named 'f1' in 'C<T>'}}
+ this->template f1<int>()(k); // expected-error{{no member named 'f1' in 'PR6081::C<T>'}}
}
};
}
diff --git a/clang/test/SemaTemplate/dependent-names.cpp b/clang/test/SemaTemplate/dependent-names.cpp
index 54ce3760d2d01..d6bd670841c08 100644
--- a/clang/test/SemaTemplate/dependent-names.cpp
+++ b/clang/test/SemaTemplate/dependent-names.cpp
@@ -336,7 +336,7 @@ template < unsigned > struct X {
static const unsigned dimension = 3;
template<unsigned dim=dimension>
struct Y: Y<dim> { }; // expected-error{{base class has incomplete type}}
- // expected-note at -1{{definition of 'Y<dim>' is not complete until the closing '}'}}
+ // expected-note at -1{{definition of 'PR11421::X::Y<dim>' is not complete until the closing '}'}}
};
typedef X<3> X3;
X3::Y<>::iterator it; // expected-error {{no type named 'iterator' in 'PR11421::X<3>::Y<>'}}
diff --git a/clang/test/SemaTemplate/elaborated-type-specifier.cpp b/clang/test/SemaTemplate/elaborated-type-specifier.cpp
index 95c2aa9f60a39..ce6e2588a02b7 100644
--- a/clang/test/SemaTemplate/elaborated-type-specifier.cpp
+++ b/clang/test/SemaTemplate/elaborated-type-specifier.cpp
@@ -79,21 +79,18 @@ namespace canon {
// expected-note@#canon-t3-3 {{candidate function}}
template <class T> constexpr int t4(typename T::template X<int>* = 0) { return 0; }
- // expected-note at -1 3{{candidate function}}
+ // expected-note at -1 2{{candidate function}}
template <class T> constexpr int t4(struct T::template X<int>* = 0) { return 1; }
- // expected-note at -1 3{{candidate function}}
+ // expected-note at -1 2{{candidate function}}
template <class T> constexpr int t4(union T::template X<int>* = 0) { return 2; }
- // expected-note at -1 3{{candidate function}}
+ // expected-note at -1 2{{candidate function}}
- // FIXME: This should work.
struct E { template <class T> using X = T; };
- static_assert(t4<E>() == 0); // expected-error {{call to 't4' is ambiguous}}
+ static_assert(t4<E>() == 0);
- // FIXME: Should not match the union overload.
struct F { template <class> struct X {}; };
static_assert(t4<F>() == 1); // expected-error {{call to 't4' is ambiguous}}
- // FIXME: Should not match the struct overload.
struct G { template <class> union X {}; };
static_assert(t4<G>() == 2); // expected-error {{call to 't4' is ambiguous}}
} // namespace canon
diff --git a/clang/test/SemaTemplate/instantiate-requires-expr.cpp b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
index 47689b93db50f..e60f79230aa00 100644
--- a/clang/test/SemaTemplate/instantiate-requires-expr.cpp
+++ b/clang/test/SemaTemplate/instantiate-requires-expr.cpp
@@ -72,8 +72,8 @@ namespace type_requirement {
template<typename T> requires
false_v<requires { typename T::template temp<T>; }>
- // expected-note at -1 {{because 'false_v<requires { typename contains_template<int>::template temp<type_requirement::contains_template<int>>; }>' evaluated to false}}
- // expected-note at -2 {{because 'false_v<requires { typename contains_template<short>::template temp<type_requirement::contains_template<short>>; }>' evaluated to false}}
+ // expected-note at -1 {{because 'false_v<requires { typename type_requirement::contains_template<int>::template temp<type_requirement::contains_template<int>>; }>' evaluated to false}}
+ // expected-note at -2 {{because 'false_v<requires { typename type_requirement::contains_template<short>::template temp<type_requirement::contains_template<short>>; }>' evaluated to false}}
struct r2 {};
using r2i1 = r2<contains_template<int>>; // expected-error{{constraints not satisfied for class template 'r2' [with T = type_requirement::contains_template<int>]}}
diff --git a/clang/test/SemaTemplate/make_integer_seq.cpp b/clang/test/SemaTemplate/make_integer_seq.cpp
index cd36d1e2c8e09..1203a5812b991 100644
--- a/clang/test/SemaTemplate/make_integer_seq.cpp
+++ b/clang/test/SemaTemplate/make_integer_seq.cpp
@@ -4,116 +4,110 @@ template <class A1, A1... A2> struct A {};
using test1 = __make_integer_seq<A, int, 1>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:5:1, col:43> col:7 test1 '__make_integer_seq<A, int, 1>':'A<int, 0>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias
+// CHECK-NEXT: |-name: '__make_integer_seq' qualified
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
+// CHECK-NEXT: |-TemplateArgument template 'A'
+// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
+// CHECK-NEXT: |-TemplateArgument type 'int'
+// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: |-TemplateArgument expr '1'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'int'
+// CHECK-NEXT: | |-value: Int 1
+// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar
+// CHECK-NEXT: |-name: 'A' qualified
+// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A
+// CHECK-NEXT: |-TemplateArgument type 'int'
+// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: |-TemplateArgument expr '0'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'int'
+// CHECK-NEXT: | |-value: Int 0
+// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 0
+// CHECK-NEXT: `-RecordType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>'
+// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A'
+
+template <class B1, B1 B2> using B = __make_integer_seq<A, B1, B2>;
+using test2 = B<int, 1>;
+// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar alias
+// CHECK-NEXT: |-name: 'B' qualified
+// CHECK-NEXT: | `-TypeAliasTemplateDecl {{.+}} B
+// CHECK-NEXT: |-TemplateArgument type 'int'
+// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: |-TemplateArgument expr '1'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:22> 'int'
+// CHECK-NEXT: | |-value: Int 1
+// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:22> 'int' 1
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias
// CHECK-NEXT: |-name: '__make_integer_seq' qualified
// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
// CHECK-NEXT: |-TemplateArgument template 'A'
// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
// CHECK-NEXT: |-TemplateArgument type 'int'
-// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1 final
+// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B'
+// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr '1'
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'int'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:64> 'int'
// CHECK-NEXT: | |-value: Int 1
-// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
+// CHECK-NEXT: | `-SubstNonTypeTemplateParmExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
+// CHECK-NEXT: | |-NonTypeTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <col:21, col:24> col:24 referenced 'B1' depth 0 index 1 B2
+// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 1
// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar
// CHECK-NEXT: |-name: 'A' qualified
// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A
// CHECK-NEXT: |-TemplateArgument type 'int'
-// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1 final
+// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B'
+// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
// CHECK-NEXT: |-TemplateArgument expr '0'
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'int'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:64> 'int'
// CHECK-NEXT: | |-value: Int 0
-// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 0
+// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 0
// CHECK-NEXT: `-RecordType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>'
// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A'
-template <class B1, B1 B2> using B = __make_integer_seq<A, B1, B2>;
-using test2 = B<int, 1>;
-// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:23> col:7 test2 'B<int, 1>':'A<int, 0>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'B<int, 1>' sugar alias
-// CHECK-NEXT: |-name: 'B' qualified
-// CHECK-NEXT: | `-TypeAliasTemplateDecl {{.+}} B
-// CHECK-NEXT: |-TemplateArgument type 'int'
-// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
-// CHECK-NEXT: |-TemplateArgument expr '1'
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:22> 'int'
-// CHECK-NEXT: | |-value: Int 1
-// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:22> 'int' 1
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, 1>' sugar alias
-// CHECK-NEXT: |-name: '__make_integer_seq' qualified
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
-// CHECK-NEXT: |-TemplateArgument template 'A'
-// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
-// CHECK-NEXT: |-TemplateArgument type 'int'
-// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1 final
-// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B'
-// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
-// CHECK-NEXT: |-TemplateArgument expr '1'
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:64> 'int'
-// CHECK-NEXT: | |-value: Int 1
-// CHECK-NEXT: | `-SubstNonTypeTemplateParmExpr 0x{{[0-9A-Fa-f]+}} <col:64> 'int'
-// CHECK-NEXT: | |-NonTypeTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <col:21, col:24> col:24 referenced 'B1' depth 0 index 1 B2
-// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 1
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>' sugar
-// CHECK-NEXT: |-name: 'A' qualified
-// CHECK-NEXT: | `-ClassTemplateDecl {{.+}} A
-// CHECK-NEXT: |-TemplateArgument type 'int'
-// CHECK-NEXT: | `-SubstTemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'int' sugar class depth 0 index 0 B1 final
-// CHECK-NEXT: | |-TypeAliasTemplate 0x{{[0-9A-Fa-f]+}} 'B'
-// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
-// CHECK-NEXT: |-TemplateArgument expr '0'
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:64> 'int'
-// CHECK-NEXT: | |-value: Int 0
-// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:64> 'int' 0
-// CHECK-NEXT: `-RecordType 0x{{[0-9A-Fa-f]+}} 'A<int, 0>'
-// CHECK-NEXT: `-ClassTemplateSpecialization 0x{{[0-9A-Fa-f]+}} 'A'
-
template <template <class T, T...> class S, class T, int N> struct C {
using test3 = __make_integer_seq<S, T, N>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:43> col:9 test3 '__make_integer_seq<S, T, N>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<S, T, N>' sugar dependent
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<S, T, N>' dependent
-// CHECK-NEXT: |-name: '__make_integer_seq'
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
-// CHECK-NEXT: |-TemplateArgument template 'S'
-// CHECK-NEXT: | | `-TemplateTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:11, col:42> col:42 depth 0 index 0 S
-// CHECK-NEXT: |-TemplateArgument type 'T'
-// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1
-// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T'
-// CHECK-NEXT: `-TemplateArgument expr 'N'
-// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'T' <Dependent>
-// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<S, T, N>' dependent
+// CHECK-NEXT: |-name: '__make_integer_seq'
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
+// CHECK-NEXT: |-TemplateArgument template 'S'
+// CHECK-NEXT: | | `-TemplateTemplateParmDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:11, col:42> col:42 depth 0 index 0 S
+// CHECK-NEXT: |-TemplateArgument type 'T'
+// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1
+// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T'
+// CHECK-NEXT: `-TemplateArgument expr 'N'
+// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'T' <Dependent>
+// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:42> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
using test4 = __make_integer_seq<A, T, 1>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:43> col:9 test4 '__make_integer_seq<A, T, 1>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, T, 1>' sugar dependent
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, T, 1>' dependent
-// CHECK-NEXT: |-name: '__make_integer_seq'
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
-// CHECK-NEXT: |-TemplateArgument template 'A'
-// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
-// CHECK-NEXT: |-TemplateArgument type 'T'
-// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1
-// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T'
-// CHECK-NEXT: `-TemplateArgument expr '1'
-// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'T' <Dependent>
-// CHECK-NEXT: `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, T, 1>' dependent
+// CHECK-NEXT: |-name: '__make_integer_seq'
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
+// CHECK-NEXT: |-TemplateArgument template 'A'
+// CHECK-NEXT: | `-ClassTemplateDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:1, col:41> col:38 A
+// CHECK-NEXT: |-TemplateArgument type 'T'
+// CHECK-NEXT: | `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'T' dependent depth 0 index 1
+// CHECK-NEXT: | `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'T'
+// CHECK-NEXT: `-TemplateArgument expr '1'
+// CHECK-NEXT: `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:42> 'T' <Dependent>
+// CHECK-NEXT: `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:42> 'int' 1
using test5 = __make_integer_seq<A, int, N>;
// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:45> col:9 test5 '__make_integer_seq<A, int, N>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' sugar dependent
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' dependent
-// CHECK-NEXT: |-name: '__make_integer_seq'
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
-// CHECK-NEXT: |-TemplateArgument template 'A'
-// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:1, col:41> col:38 A
-// CHECK-NEXT: |-TemplateArgument type 'int'
-// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
-// CHECK-NEXT: `-TemplateArgument expr 'N'
-// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:44> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__make_integer_seq<A, int, N>' dependent
+// CHECK-NEXT: |-name: '__make_integer_seq'
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __make_integer_seq
+// CHECK-NEXT: |-TemplateArgument template 'A'
+// CHECK-NEXT: | `-ClassTemplateDecl 0x{{.+}} <line:{{.+}}:1, col:41> col:38 A
+// CHECK-NEXT: |-TemplateArgument type 'int'
+// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: `-TemplateArgument expr 'N'
+// CHECK-NEXT: `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:44> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
};
// expected-no-diagnostics
diff --git a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 547e5945ac6bc..16fe8d3c78897 100644
--- a/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/clang/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -76,7 +76,7 @@ template<typename T> struct C;
// Test lookup with incomplete lookup context
template<typename T>
auto C<T>::f() -> decltype(x) { } // expected-error {{use of undeclared identifier 'x'}}
- // expected-error at -1 {{out-of-line definition of 'f' from class 'C<T>' without definition}}
+ // expected-error at -1 {{out-of-line definition of 'f' from class 'lookup_dependent_bases_id_expr::C<T>' without definition}}
}
diff --git a/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp b/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
index 463d86f0d3b94..ea723324212a2 100644
--- a/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
+++ b/clang/test/SemaTemplate/ms-sizeof-missing-typename.cpp
@@ -4,9 +4,9 @@
// get the size of this type, so they don't get errors after inserting typename.
namespace basic {
-template <typename T> int type_f() { return sizeof T::type; } // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
-template <typename T> int type_g() { return sizeof(T::type); } // expected-warning {{missing 'typename' prior to dependent type name 'X::type'}}
-template <typename T> int type_h() { return sizeof((T::type)); } // expected-error {{missing 'typename' prior to dependent type name 'X::type'}}
+template <typename T> int type_f() { return sizeof T::type; } // expected-error {{missing 'typename' prior to dependent type name 'basic::X::type'}}
+template <typename T> int type_g() { return sizeof(T::type); } // expected-warning {{missing 'typename' prior to dependent type name 'basic::X::type'}}
+template <typename T> int type_h() { return sizeof((T::type)); } // expected-error {{missing 'typename' prior to dependent type name 'basic::X::type'}}
template <typename T> int value_f() { return sizeof T::not_a_type; }
template <typename T> int value_g() { return sizeof(T::not_a_type); }
template <typename T> int value_h() { return sizeof((T::not_a_type)); }
@@ -30,9 +30,9 @@ template <typename T>
struct Foo {
enum {
// expected-warning at +2 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}}
- // expected-warning at +1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}}
+ // expected-warning at +1 {{missing 'typename' prior to dependent type name 'nested_sizeof::Bar::InnerType'}}
x1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(/*typename*/ T::InnerType)>),
- // expected-warning at +1 {{missing 'typename' prior to dependent type name 'Bar::InnerType'}}
+ // expected-warning at +1 {{missing 'typename' prior to dependent type name 'nested_sizeof::Bar::InnerType'}}
x2 = sizeof(typename T::template InnerTemplate<sizeof(/*typename*/ T::InnerType)>),
// expected-warning at +1 {{use 'template' keyword to treat 'InnerTemplate' as a dependent template name}}
y1 = sizeof(typename T::/*template*/ InnerTemplate<sizeof(T::InnerVar)>),
@@ -50,7 +50,7 @@ template struct Foo<Bar>; // expected-note-re {{in instantiation {{.*}} requeste
}
namespace ambiguous_missing_parens {
-// expected-error at +1 {{'Q::template U' is expected to be a non-type template, but instantiated to a class template}}
+// expected-error at +1 {{'ambiguous_missing_parens::Q::template U' is expected to be a non-type template, but instantiated to a class template}}
template <typename T> void f() { int a = sizeof T::template U<0> + 4; }
struct Q {
// expected-note at +1 {{class template declared here}}
diff --git a/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp b/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
index 5c7a90273d0e0..8e3b1b6b6ca77 100644
--- a/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
+++ b/clang/test/SemaTemplate/nested-implicit-deduction-guides.cpp
@@ -84,11 +84,11 @@ nested_init_list<int>::concept_fail nil_invalid{1, ""};
// expected-note@#INIT_LIST_INNER_INVALID {{candidate template ignored: constraints not satisfied [with F = const char *]}}
// expected-note@#INIT_LIST_INNER_INVALID_HEADER {{because 'const char *' does not satisfy 'False'}}
// expected-note@#False {{because 'false' evaluated to false}}
-// expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail(int, F) -> concept_fail<F>'}}
+// expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail(int, F) -> nested_init_list<int>::concept_fail<F>'}}
// expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not viable: requires 1 argument, but 2 were provided}}
-// expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail(concept_fail<F>) -> concept_fail<F>'}}
+// expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail(nested_init_list<int>::concept_fail<F>) -> nested_init_list<int>::concept_fail<F>'}}
// expected-note@#INIT_LIST_INNER_INVALID {{candidate function template not viable: requires 0 arguments, but 2 were provided}}
-// expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail() -> concept_fail<F>'}}
+// expected-note@#INIT_LIST_INNER_INVALID {{implicit deduction guide declared as 'template <False F> concept_fail() -> nested_init_list<int>::concept_fail<F>'}}
namespace GH88142 {
diff --git a/clang/test/SemaTemplate/nested-name-spec-template.cpp b/clang/test/SemaTemplate/nested-name-spec-template.cpp
index d36692570c0c2..8163f8f0e2432 100644
--- a/clang/test/SemaTemplate/nested-name-spec-template.cpp
+++ b/clang/test/SemaTemplate/nested-name-spec-template.cpp
@@ -130,7 +130,7 @@ namespace PR9226 {
template<typename T, typename U>
struct Y {
- typedef typename T::template f<U> type; // expected-error{{template name refers to non-type template 'X::template f'}}
+ typedef typename T::template f<U> type; // expected-error{{template name refers to non-type template 'PR9226::X::template f'}}
};
Y<X, int> yxi; // expected-note{{in instantiation of template class 'PR9226::Y<PR9226::X, int>' requested here}}
diff --git a/clang/test/SemaTemplate/nested-template.cpp b/clang/test/SemaTemplate/nested-template.cpp
index 7911cf555f4b4..b5da1b1c3ccd4 100644
--- a/clang/test/SemaTemplate/nested-template.cpp
+++ b/clang/test/SemaTemplate/nested-template.cpp
@@ -152,14 +152,14 @@ namespace PR10924 {
template< class Topology, class ctype >
template< int codim >
- class ReferenceElement< Topology, ctype > :: BaryCenterArray // expected-error{{out-of-line definition of 'BaryCenterArray' does not match any declaration in 'ReferenceElement<Topology, ctype>'}}
+ class ReferenceElement< Topology, ctype > :: BaryCenterArray // expected-error{{out-of-line definition of 'BaryCenterArray' does not match any declaration in 'PR10924::ReferenceElement<Topology, ctype>'}}
{
};
}
class Outer1 {
template <typename T> struct X;
- template <typename T> int X<T>::func() {} // expected-error{{out-of-line definition of 'func' from class 'X<T>' without definition}}
+ template <typename T> int X<T>::func() {} // expected-error{{out-of-line definition of 'func' from class 'Outer1::X<T>' without definition}}
};
namespace RefPack {
diff --git a/clang/test/SemaTemplate/overload-candidates.cpp b/clang/test/SemaTemplate/overload-candidates.cpp
index de998d74f9af6..a9c86b2118fbb 100644
--- a/clang/test/SemaTemplate/overload-candidates.cpp
+++ b/clang/test/SemaTemplate/overload-candidates.cpp
@@ -16,9 +16,9 @@ void test_dyn_cast(int* ptr) {
(void)dyn_cast(ptr); // expected-error{{no matching function for call to 'dyn_cast'}}
}
-template<int I, typename T>
+template<int I, typename T>
void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for template parameter 'I'}}
-template<template<class T> class, typename T>
+template<template<class T> class, typename T>
void get(const T&); // expected-note{{candidate template ignored: invalid explicitly-specified argument for 1st template parameter}}
void test_get(void *ptr) {
@@ -100,7 +100,7 @@ namespace PR15673 {
#if __cplusplus <= 199711L
// expected-warning at -2 {{default template arguments for a function template are a C++11 extension}}
#endif
- // expected-note at +1 {{candidate template ignored: requirement 'a_trait<int>::value' was not satisfied [with T = int]}}
+ // expected-note at +1 {{candidate template ignored: requirement 'PR15673::a_trait<int>::value' was not satisfied [with T = int]}}
void foo() {}
void bar() { foo<int>(); } // expected-error {{no matching function for call to 'foo'}}
@@ -128,7 +128,7 @@ namespace PR15673 {
#if __cplusplus <= 199711L
// expected-warning at -2 {{alias declarations are a C++11 extension}}
#endif
- // expected-note at +7 {{candidate template ignored: requirement 'some_trait<int>::value' was not satisfied [with T = int]}}
+ // expected-note at +7 {{candidate template ignored: requirement 'PR15673::some_trait<int>::value' was not satisfied [with T = int]}}
template<typename T,
typename Requires = unicorns<T> >
@@ -148,7 +148,7 @@ namespace PR15673 {
template<typename T,
int n = 42,
typename std::enable_if<n == 43 || (some_passing_trait<T>::value && some_trait<T>::value), int>::type = 0>
- void almost_rangesv3(); // expected-note{{candidate template ignored: requirement '42 == 43 || (some_passing_trait<int>::value && some_trait<int>::value)' was not satisfied}}
+ void almost_rangesv3(); // expected-note{{candidate template ignored: requirement '42 == 43 || (PR15673::some_passing_trait<int>::value && PR15673::some_trait<int>::value)' was not satisfied}}
void test_almost_rangesv3() { almost_rangesv3<int>(); } // expected-error{{no matching function for call to 'almost_rangesv3'}}
#define CONCEPT_REQUIRES_(...) \
@@ -161,6 +161,6 @@ namespace PR15673 {
#endif
template<typename T,
CONCEPT_REQUIRES_(some_passing_trait<T>::value && some_trait<T>::value)>
- void rangesv3(); // expected-note{{candidate template ignored: requirement 'some_trait<int>::value' was not satisfied [with T = int, x = 42]}}
+ void rangesv3(); // expected-note{{candidate template ignored: requirement 'PR15673::some_trait<int>::value' was not satisfied [with T = int, x = 42]}}
void test_rangesv3() { rangesv3<int>(); } // expected-error{{no matching function for call to 'rangesv3'}}
}
diff --git a/clang/test/SemaTemplate/temp_arg_nontype.cpp b/clang/test/SemaTemplate/temp_arg_nontype.cpp
index 9363e748c7028..7d2a010295b47 100644
--- a/clang/test/SemaTemplate/temp_arg_nontype.cpp
+++ b/clang/test/SemaTemplate/temp_arg_nontype.cpp
@@ -438,7 +438,7 @@ namespace dependent_nested_partial_specialization {
template<template<typename> class X> struct A {
template<typename T, X<T> N> struct B; // expected-note 2{{here}}
- template <typename T> struct B<T, 0> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'Y<T>' (aka 'T *')}}
+ template <typename T> struct B<T, 0> {}; // expected-error {{non-type template argument specializes a template parameter with dependent type 'dependent_nested_partial_specialization::Y<T>' (aka 'T *')}}
};
A<X>::B<int, 0> ax;
A<Y>::B<int, &n> ay; // expected-error {{undefined}} expected-note {{instantiation of}}
diff --git a/clang/test/SemaTemplate/template-id-expr.cpp b/clang/test/SemaTemplate/template-id-expr.cpp
index a13013a1ffd47..0527af4cfd887 100644
--- a/clang/test/SemaTemplate/template-id-expr.cpp
+++ b/clang/test/SemaTemplate/template-id-expr.cpp
@@ -202,7 +202,7 @@ struct P {
struct Q {
template <typename T> int foo() {
return T::template I<int>;
- // expected-error at -1 {{'P::template I' is expected to be a non-type template, but instantiated to a type alias template}}
+ // expected-error at -1 {{'non_functions::PR88832::P::template I' is expected to be a non-type template, but instantiated to a type alias template}}
// expected-note@#TypeAlias {{type alias template declared here}}
}
};
diff --git a/clang/test/SemaTemplate/type_pack_element.cpp b/clang/test/SemaTemplate/type_pack_element.cpp
index 264b4dcdc044d..11afaf91bd81d 100644
--- a/clang/test/SemaTemplate/type_pack_element.cpp
+++ b/clang/test/SemaTemplate/type_pack_element.cpp
@@ -2,61 +2,57 @@
using test1 = __type_pack_element<0, int>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <<stdin>:3:1, col:41> col:7 test1 '__type_pack_element<0, int>':'int'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, int>' sugar
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, int>' sugar alias
-// CHECK-NEXT: |-name: '__type_pack_element' qualified
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
-// CHECK-NEXT: |-TemplateArgument expr '0'
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:35> 'unsigned long'
-// CHECK-NEXT: | |-value: Int 0
-// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:35> 'unsigned long' <IntegralCast>
-// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:35> 'int' 0
-// CHECK-NEXT: |-TemplateArgument type 'int'
-// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
-// CHECK-NEXT: `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, int>' sugar alias
+// CHECK-NEXT: |-name: '__type_pack_element' qualified
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
+// CHECK-NEXT: |-TemplateArgument expr '0'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:35> 'unsigned long'
+// CHECK-NEXT: | |-value: Int 0
+// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:35> 'unsigned long' <IntegralCast>
+// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:35> 'int' 0
+// CHECK-NEXT: |-TemplateArgument type 'int'
+// CHECK-NEXT: | `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
template<int N, class ...Ts> struct A {
using test2 = __type_pack_element<N, Ts...>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:45> col:9 test2 '__type_pack_element<N, Ts...>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, Ts...>' sugar dependent
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, Ts...>' dependent
-// CHECK-NEXT: |-name: '__type_pack_element' qualified
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
-// CHECK-NEXT: |-TemplateArgument expr 'N'
-// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
-// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
-// CHECK-NEXT: `-TemplateArgument type 'Ts...'
-// CHECK-NEXT: `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'Ts...' dependent
-// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
-// CHECK-NEXT: `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'Ts'
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, Ts...>' dependent
+// CHECK-NEXT: |-name: '__type_pack_element' qualified
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
+// CHECK-NEXT: |-TemplateArgument expr 'N'
+// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
+// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
+// CHECK-NEXT: `-TemplateArgument type 'Ts...'
+// CHECK-NEXT: `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'Ts...' dependent
+// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
+// CHECK-NEXT: `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'Ts'
using test3 = __type_pack_element<0, Ts...>;
// CHECK: |-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:45> col:9 test3 '__type_pack_element<0, Ts...>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, Ts...>' sugar dependent
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, Ts...>' dependent
-// CHECK-NEXT: |-name: '__type_pack_element' qualified
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
-// CHECK-NEXT: |-TemplateArgument expr '0'
-// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long'
-// CHECK-NEXT: | |-value: Int 0
-// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
-// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:37> 'int' 0
-// CHECK-NEXT: `-TemplateArgument type 'Ts...'
-// CHECK-NEXT: `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'Ts...' dependent
-// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
-// CHECK-NEXT: `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'Ts'
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<0, Ts...>' dependent
+// CHECK-NEXT: |-name: '__type_pack_element' qualified
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
+// CHECK-NEXT: |-TemplateArgument expr '0'
+// CHECK-NEXT: | `-ConstantExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long'
+// CHECK-NEXT: | |-value: Int 0
+// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
+// CHECK-NEXT: | `-IntegerLiteral 0x{{[0-9A-Fa-f]+}} <col:37> 'int' 0
+// CHECK-NEXT: `-TemplateArgument type 'Ts...'
+// CHECK-NEXT: `-PackExpansionType 0x{{[0-9A-Fa-f]+}} 'Ts...' dependent
+// CHECK-NEXT: `-TemplateTypeParmType 0x{{[0-9A-Fa-f]+}} 'Ts' dependent contains_unexpanded_pack depth 0 index 1 pack
+// CHECK-NEXT: `-TemplateTypeParm 0x{{[0-9A-Fa-f]+}} 'Ts'
using test4 = __type_pack_element<N, int>;
// CHECK: `-TypeAliasDecl 0x{{[0-9A-Fa-f]+}} <line:{{.+}}:3, col:43> col:9 test4 '__type_pack_element<N, int>'
-// CHECK-NEXT: `-ElaboratedType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' sugar dependent
-// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' dependent
-// CHECK-NEXT: |-name: '__type_pack_element' qualified
-// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
-// CHECK-NEXT: |-TemplateArgument expr 'N'
-// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
-// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
-// CHECK-NEXT: `-TemplateArgument type 'int'
-// CHECK-NEXT: `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
+// CHECK-NEXT: `-TemplateSpecializationType 0x{{[0-9A-Fa-f]+}} '__type_pack_element<N, int>' dependent
+// CHECK-NEXT: |-name: '__type_pack_element' qualified
+// CHECK-NEXT: | `-BuiltinTemplateDecl {{.+}} __type_pack_element
+// CHECK-NEXT: |-TemplateArgument expr 'N'
+// CHECK-NEXT: | `-ImplicitCastExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'unsigned long' <IntegralCast>
+// CHECK-NEXT: | `-DeclRefExpr 0x{{[0-9A-Fa-f]+}} <col:37> 'int' NonTypeTemplateParm 0x{{[0-9A-Fa-f]+}} 'N' 'int'
+// CHECK-NEXT: `-TemplateArgument type 'int'
+// CHECK-NEXT: `-BuiltinType 0x{{[0-9A-Fa-f]+}} 'int'
};
// expected-no-diagnostics
diff --git a/clang/test/SemaTemplate/typename-specifier-4.cpp b/clang/test/SemaTemplate/typename-specifier-4.cpp
index 8d9962eafbcd1..8f9dce6e69fa0 100644
--- a/clang/test/SemaTemplate/typename-specifier-4.cpp
+++ b/clang/test/SemaTemplate/typename-specifier-4.cpp
@@ -147,7 +147,7 @@ namespace rdar8740998 {
// expected-error{{dependent using declaration resolved to type without 'typename'}}
void f() {
- typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'X<T>'}}
+ typename X<T>::iterator i; // expected-error{{typename specifier refers to a dependent using declaration for a value 'iterator' in 'rdar8740998::X<T>'}}
}
};
diff --git a/clang/test/SemaTemplate/typename-specifier.cpp b/clang/test/SemaTemplate/typename-specifier.cpp
index 01acc34f3bb37..27175c5b0b568 100644
--- a/clang/test/SemaTemplate/typename-specifier.cpp
+++ b/clang/test/SemaTemplate/typename-specifier.cpp
@@ -40,7 +40,7 @@ void test(double d) {
// expected-warning at -3 2{{'typename' outside of a template is a C++11 extension}}
#endif
int five = f(5);
-
+
using namespace N;
for (typename A::type i = 0; i < 10; ++i)
#if __cplusplus <= 199711L
@@ -102,7 +102,7 @@ D<long> struct_D; // expected-note {{in instantiation of template class 'D<long
template<typename T> struct E {
typedef typename T::foo foo;
- typedef typename foo::bar bar; // expected-error {{type 'E<F>::foo' (aka 'double') cannot be used prior to '::' because it has no members}}
+ typedef typename foo::bar bar; // expected-error {{type 'foo' (aka 'double') cannot be used prior to '::' because it has no members}}
};
struct F {
@@ -245,7 +245,7 @@ void j() {
namespace pointer_vs_multiply {
int x;
-// expected-error at +1 {{missing 'typename' prior to dependent type name 'B::type_or_int'}}
+// expected-error at +1 {{missing 'typename' prior to dependent type name 'pointer_vs_multiply::B::type_or_int'}}
template <typename T> void g() { T::type_or_int * x; }
// expected-error at +1 {{typename specifier refers to non-type member 'type_or_int' in 'pointer_vs_multiply::A'}}
template <typename T> void h() { typename T::type_or_int * x; }
diff --git a/clang/unittests/AST/ASTContextParentMapTest.cpp b/clang/unittests/AST/ASTContextParentMapTest.cpp
index 9af0a46817a25..4a8aa488cb70e 100644
--- a/clang/unittests/AST/ASTContextParentMapTest.cpp
+++ b/clang/unittests/AST/ASTContextParentMapTest.cpp
@@ -131,10 +131,10 @@ TEST(GetParents, FriendTypeLoc) {
auto &FrB = *cast<FriendDecl>(*++(cast<CXXRecordDecl>(B).decls_begin()));
TypeLoc FrALoc = FrA.getFriendType()->getTypeLoc();
TypeLoc FrBLoc = FrB.getFriendType()->getTypeLoc();
+ bool FrAOwnsTag = FrALoc.getTypePtr()->getAs<TagType>()->isTagOwned();
TagDecl *FrATagDecl =
- FrALoc.getTypePtr()->getAs<ElaboratedType>()->getOwnedTagDecl();
- TagDecl *FrBTagDecl =
- FrBLoc.getTypePtr()->getAs<ElaboratedType>()->getOwnedTagDecl();
+ FrALoc.getTypePtr()->getAs<TagType>()->getOriginalDecl();
+ bool FrBOwnsTag = FrBLoc.getTypePtr()->getAs<TagType>()->isTagOwned();
EXPECT_THAT(Ctx.getParents(A), ElementsAre(DynTypedNode::create(TU)));
EXPECT_THAT(Ctx.getParents(B), ElementsAre(DynTypedNode::create(TU)));
@@ -142,8 +142,8 @@ TEST(GetParents, FriendTypeLoc) {
EXPECT_THAT(Ctx.getParents(FrB), ElementsAre(DynTypedNode::create(B)));
EXPECT_THAT(Ctx.getParents(FrALoc), ElementsAre(DynTypedNode::create(FrA)));
EXPECT_THAT(Ctx.getParents(FrBLoc), ElementsAre(DynTypedNode::create(FrB)));
- EXPECT_TRUE(FrATagDecl);
- EXPECT_FALSE(FrBTagDecl);
+ EXPECT_TRUE(FrAOwnsTag);
+ EXPECT_FALSE(FrBOwnsTag);
EXPECT_THAT(Ctx.getParents(*FrATagDecl),
ElementsAre(DynTypedNode::create(FrA)));
}
diff --git a/clang/unittests/AST/ASTExprTest.cpp b/clang/unittests/AST/ASTExprTest.cpp
index 5ec6aea8edba3..adaceb76de8b4 100644
--- a/clang/unittests/AST/ASTExprTest.cpp
+++ b/clang/unittests/AST/ASTExprTest.cpp
@@ -89,14 +89,14 @@ TEST(ASTExpr, InitListIsConstantInitialized) {
SourceLocation Loc{};
InitListExpr *BaseInit = new (Ctx) InitListExpr(Ctx, Loc, {}, Loc);
- BaseInit->setType(Ctx.getRecordType(Empty));
+ BaseInit->setType(Ctx.getCanonicalTagType(Empty));
Expr *Exprs[3] = {
BaseInit,
createIntLiteral(Ctx, 13),
createIntLiteral(Ctx, 42),
};
InitListExpr *FooInit = new (Ctx) InitListExpr(Ctx, Loc, Exprs, Loc);
- FooInit->setType(Ctx.getRecordType(Foo));
+ FooInit->setType(Ctx.getCanonicalTagType(Foo));
EXPECT_TRUE(FooInit->isConstantInitializer(Ctx, false));
// Replace the last initializer with something non-constant and make sure
diff --git a/clang/unittests/AST/ASTImporterFixtures.h b/clang/unittests/AST/ASTImporterFixtures.h
index 87e62cbda422a..2af69c62bc62d 100644
--- a/clang/unittests/AST/ASTImporterFixtures.h
+++ b/clang/unittests/AST/ASTImporterFixtures.h
@@ -425,8 +425,7 @@ class TestImportBase
};
template <typename T> RecordDecl *getRecordDecl(T *D) {
- auto *ET = cast<ElaboratedType>(D->getType().getTypePtr());
- return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
+ return D->getType()->getAsRecordDecl();
}
template <class T>
diff --git a/clang/unittests/AST/ASTImporterTest.cpp b/clang/unittests/AST/ASTImporterTest.cpp
index 86c3bd686c031..7d493c3ba3a1c 100644
--- a/clang/unittests/AST/ASTImporterTest.cpp
+++ b/clang/unittests/AST/ASTImporterTest.cpp
@@ -28,7 +28,7 @@ using internal::Matcher;
static const RecordDecl *getRecordDeclOfFriend(FriendDecl *FD) {
QualType Ty = FD->getFriendType()->getType().getCanonicalType();
- return cast<RecordType>(Ty)->getDecl();
+ return cast<RecordType>(Ty)->getOriginalDecl();
}
struct ImportExpr : TestImportBase {};
@@ -426,15 +426,14 @@ TEST_P(ImportExpr, ImportParenListExpr) {
"typedef dummy<int> declToImport;"
"template class dummy<int>;",
Lang_CXX03, "", Lang_CXX03, Verifier,
- typedefDecl(hasType(elaboratedType(namesType(templateSpecializationType(
+ typedefDecl(hasType(templateSpecializationType(
hasDeclaration(classTemplateSpecializationDecl(hasSpecializedTemplate(
- classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(
- allOf(hasName("f"),
- hasBody(compoundStmt(has(declStmt(hasSingleDecl(varDecl(
- hasInitializer(parenListExpr(has(unaryOperator(
- hasOperatorName("*"),
- hasUnaryOperand(
- cxxThisExpr())))))))))))))))))))))))));
+ classTemplateDecl(hasTemplateDecl(cxxRecordDecl(hasMethod(allOf(
+ hasName("f"),
+ hasBody(compoundStmt(has(declStmt(hasSingleDecl(
+ varDecl(hasInitializer(parenListExpr(has(unaryOperator(
+ hasOperatorName("*"),
+ hasUnaryOperand(cxxThisExpr())))))))))))))))))))))));
}
TEST_P(ImportExpr, ImportSwitch) {
@@ -690,8 +689,8 @@ TEST_P(ImportType, ImportUsingType) {
testImport("struct C {};"
"void declToImport() { using ::C; new C{}; }",
Lang_CXX11, "", Lang_CXX11, Verifier,
- functionDecl(hasDescendant(cxxNewExpr(hasType(pointerType(
- pointee(elaboratedType(namesType(usingType())))))))));
+ functionDecl(hasDescendant(
+ cxxNewExpr(hasType(pointerType(pointee(usingType())))))));
}
TEST_P(ImportDecl, ImportFunctionTemplateDecl) {
@@ -784,8 +783,7 @@ TEST_P(ImportType, ImportDeducedTemplateSpecialization) {
"class C { public: C(T); };"
"C declToImport(123);",
Lang_CXX17, "", Lang_CXX17, Verifier,
- varDecl(hasType(elaboratedType(
- namesType(deducedTemplateSpecializationType())))));
+ varDecl(hasType(deducedTemplateSpecializationType())));
}
const internal::VariadicDynCastAllOfMatcher<Stmt, SizeOfPackExpr>
@@ -995,9 +993,9 @@ TEST_P(ImportDecl, ImportUsingTemplate) {
"void declToImport() {"
"using ns::S; X<S> xi; }",
Lang_CXX11, "", Lang_CXX11, Verifier,
- functionDecl(hasDescendant(varDecl(hasTypeLoc(elaboratedTypeLoc(
- hasNamedTypeLoc(templateSpecializationTypeLoc(
- hasAnyTemplateArgumentLoc(templateArgumentLoc())))))))));
+ functionDecl(
+ hasDescendant(varDecl(hasTypeLoc(templateSpecializationTypeLoc(
+ hasAnyTemplateArgumentLoc(templateArgumentLoc())))))));
}
TEST_P(ImportDecl, ImportUsingEnumDecl) {
@@ -1018,24 +1016,10 @@ TEST_P(ImportDecl, ImportUsingPackDecl) {
"template<typename ...T> struct C : T... { using T::operator()...; };"
"C<A, B> declToImport;",
Lang_CXX20, "", Lang_CXX20, Verifier,
- varDecl(hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(classTemplateSpecializationDecl(
- hasDescendant(usingPackDecl())))))))));
+ varDecl(hasType(templateSpecializationType(hasDeclaration(
+ classTemplateSpecializationDecl(hasDescendant(usingPackDecl())))))));
}
-/// \brief Matches shadow declarations introduced into a scope by a
-/// (resolved) using declaration.
-///
-/// Given
-/// \code
-/// namespace n { int f; }
-/// namespace declToImport { using n::f; }
-/// \endcode
-/// usingShadowDecl()
-/// matches \code f \endcode
-const internal::VariadicDynCastAllOfMatcher<Decl,
- UsingShadowDecl> usingShadowDecl;
-
TEST_P(ImportDecl, ImportUsingShadowDecl) {
MatchVerifier<Decl> Verifier;
// from using-decl
@@ -2854,8 +2838,9 @@ TEST_P(ImportFriendFunctions, ImportFriendFunctionRedeclChainDefWithClass) {
EXPECT_FALSE(InClassFD->doesThisDeclarationHaveABody());
EXPECT_EQ(InClassFD->getPreviousDecl(), ImportedD);
// The parameters must refer the same type
- EXPECT_EQ((*InClassFD->param_begin())->getOriginalType(),
- (*ImportedD->param_begin())->getOriginalType());
+ EXPECT_TRUE(ToTU->getASTContext().hasSameType(
+ (*InClassFD->param_begin())->getOriginalType(),
+ (*ImportedD->param_begin())->getOriginalType()));
}
TEST_P(ImportFriendFunctions,
@@ -2883,8 +2868,9 @@ TEST_P(ImportFriendFunctions,
EXPECT_TRUE(OutOfClassFD->doesThisDeclarationHaveABody());
EXPECT_EQ(ImportedD->getPreviousDecl(), OutOfClassFD);
// The parameters must refer the same type
- EXPECT_EQ((*OutOfClassFD->param_begin())->getOriginalType(),
- (*ImportedD->param_begin())->getOriginalType());
+ EXPECT_TRUE(ToTU->getASTContext().hasSameType(
+ (*OutOfClassFD->param_begin())->getOriginalType(),
+ (*ImportedD->param_begin())->getOriginalType()));
}
TEST_P(ImportFriendFunctions, ImportFriendFunctionFromMultipleTU) {
@@ -4389,8 +4375,7 @@ TEST_P(ImportFriendClasses, TypeForDeclShouldBeSetInTemplated) {
auto *Definition = FirstDeclMatcher<ClassTemplateDecl>().match(
FromTU1, classTemplateDecl(hasName("F")));
auto *Imported1 = cast<ClassTemplateDecl>(Import(Definition, Lang_CXX03));
- EXPECT_EQ(Imported0->getTemplatedDecl()->getTypeForDecl(),
- Imported1->getTemplatedDecl()->getTypeForDecl());
+ EXPECT_TRUE(declaresSameEntity(Imported0, Imported1));
}
TEST_P(ImportFriendClasses, DeclsFromFriendsShouldBeInRedeclChains) {
@@ -4451,8 +4436,10 @@ TEST_P(ImportFriendClasses, SkipComparingFriendTemplateDepth) {
classTemplateDecl(has(cxxRecordDecl(hasDefinition(), hasName("A")))));
auto *ToA = Import(FromA, Lang_CXX11);
EXPECT_TRUE(ToA);
- EXPECT_EQ(Fwd->getTemplatedDecl()->getTypeForDecl(),
- ToA->getTemplatedDecl()->getTypeForDecl());
+ const ASTContext &Ctx = ToTU->getASTContext();
+ EXPECT_TRUE(
+ Ctx.hasSameType(Ctx.getCanonicalTagType(Fwd->getTemplatedDecl()),
+ Ctx.getCanonicalTagType(ToA->getTemplatedDecl())));
}
TEST_P(ImportFriendClasses,
@@ -4530,7 +4517,7 @@ TEST_P(ImportFriendClasses, ImportOfClassDefinitionAndFwdFriendShouldBeLinked) {
auto *Friend = FirstDeclMatcher<FriendDecl>().match(FromTU0, friendDecl());
QualType FT = Friend->getFriendType()->getType();
FT = FromTU0->getASTContext().getCanonicalType(FT);
- auto *Fwd = cast<TagType>(FT)->getDecl();
+ auto *Fwd = cast<TagType>(FT)->getOriginalDecl();
auto *ImportedFwd = Import(Fwd, Lang_CXX03);
Decl *FromTU1 = getTuDecl(
R"(
@@ -7445,7 +7432,8 @@ TEST_P(ImportAutoFunctions, ReturnWithTypedefDeclaredInside) {
ASTContext &Ctx = From->getASTContext();
TypeAliasDecl *FromTA =
FirstDeclMatcher<TypeAliasDecl>().match(FromTU, typeAliasDecl());
- QualType TT = Ctx.getTypedefType(FromTA);
+ QualType TT = Ctx.getTypedefType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, FromTA);
const FunctionProtoType *FPT = cast<FunctionProtoType>(From->getType());
QualType NewFunType =
Ctx.getFunctionType(TT, FPT->getParamTypes(), FPT->getExtProtoInfo());
@@ -9095,41 +9083,39 @@ TEST_P(ASTImporterOptionSpecificTestBase, isNewDecl) {
struct ImportInjectedClassNameType : public ASTImporterOptionSpecificTestBase {
protected:
- const CXXRecordDecl *findInjected(const CXXRecordDecl *Parent) {
- for (Decl *Found : Parent->decls()) {
- const auto *Record = dyn_cast<CXXRecordDecl>(Found);
- if (Record && Record->isInjectedClassName())
- return Record;
- }
- return nullptr;
- }
-
- void checkInjType(const CXXRecordDecl *D) {
- // The whole redecl chain should have the same InjectedClassNameType
- // instance. The injected record declaration is a separate chain, this
- // should contain the same type too.
- const Type *Ty = nullptr;
- for (const Decl *ReD : D->redecls()) {
- const auto *ReRD = cast<CXXRecordDecl>(ReD);
- EXPECT_TRUE(ReRD->getTypeForDecl());
- EXPECT_TRUE(!Ty || Ty == ReRD->getTypeForDecl());
- Ty = ReRD->getTypeForDecl();
- }
+ void checkInjType(const ASTContext &Ctx, const CXXRecordDecl *D) {
+ ASSERT_TRUE(D->hasInjectedClassType());
+ const Type *Ty = Ctx.getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, D,
+ /*OwnsTag=*/false)
+ .getTypePtr();
ASSERT_TRUE(Ty);
+ EXPECT_FALSE(Ty->isCanonicalUnqualified());
const auto *InjTy = Ty->castAs<InjectedClassNameType>();
EXPECT_TRUE(InjTy);
- if (CXXRecordDecl *Def = D->getDefinition()) {
- const CXXRecordDecl *InjRD = findInjected(Def);
- EXPECT_TRUE(InjRD);
- EXPECT_EQ(InjRD->getTypeForDecl(), InjTy);
+ for (const Decl *ReD : D->redecls()) {
+ if (ReD == D)
+ continue;
+ const auto *ReRD = cast<CXXRecordDecl>(ReD);
+ ASSERT_TRUE(ReRD->hasInjectedClassType());
+ const Type *ReTy = Ctx.getTagType(ElaboratedTypeKeyword::None,
+ /*Qualifier=*/std::nullopt, ReRD,
+ /*OwnsTag=*/false)
+ .getTypePtr();
+ ASSERT_TRUE(ReTy);
+ EXPECT_FALSE(ReTy->isCanonicalUnqualified());
+ EXPECT_NE(ReTy, Ty);
+ EXPECT_TRUE(Ctx.hasSameType(ReTy, Ty));
+ const auto *ReInjTy = Ty->castAs<InjectedClassNameType>();
+ EXPECT_TRUE(ReInjTy);
}
}
void testImport(Decl *ToTU, Decl *FromTU, Decl *FromD) {
- checkInjType(cast<CXXRecordDecl>(FromD));
+ checkInjType(FromTU->getASTContext(), cast<CXXRecordDecl>(FromD));
Decl *ToD = Import(FromD, Lang_CXX11);
if (auto *ToRD = dyn_cast<CXXRecordDecl>(ToD))
- checkInjType(ToRD);
+ checkInjType(ToTU->getASTContext(), ToRD);
}
const char *ToCodeA =
@@ -9581,8 +9567,7 @@ TEST_P(ASTImporterOptionSpecificTestBase,
auto *ToX = Import(FromX, Lang_CXX11);
auto *ToXType = ToX->getType()->getAs<TypedefType>();
- // FIXME: This should be false.
- EXPECT_TRUE(ToXType->typeMatchesDecl());
+ EXPECT_FALSE(ToXType->typeMatchesDecl());
}
TEST_P(ASTImporterOptionSpecificTestBase,
@@ -9940,7 +9925,12 @@ struct ImportTemplateParmDeclDefaultValue
.getInheritedFrom(),
GetTemplateParm(ToD));
- EXPECT_EQ(ToD->getPreviousDecl(), ToDInherited);
+ if (FromD->getPreviousDecl() == FromDInherited) {
+ EXPECT_EQ(ToD->getPreviousDecl(), ToDInherited);
+ } else {
+ EXPECT_EQ(FromD, FromDInherited->getPreviousDecl());
+ EXPECT_EQ(ToD, ToDInherited->getPreviousDecl());
+ }
}
const char *CodeFunction =
diff --git a/clang/unittests/AST/DeclPrinterTest.cpp b/clang/unittests/AST/DeclPrinterTest.cpp
index 124b1a166cb18..28750c41796d4 100644
--- a/clang/unittests/AST/DeclPrinterTest.cpp
+++ b/clang/unittests/AST/DeclPrinterTest.cpp
@@ -356,42 +356,40 @@ TEST(DeclPrinter, TestCXXRecordDecl11) {
}
TEST(DeclPrinter, TestCXXRecordDecl12) {
- ASSERT_TRUE(
- PrintedDeclCXX98Matches("struct S { int x; };"
- "namespace NS { class C {};}"
- "void foo() {using namespace NS; C c;}",
- "foo",
- "void foo() {\nusing namespace NS;\nclass "
- "NS::C c;\n}\n",
- [](PrintingPolicy &Policy) {
- Policy.SuppressTagKeyword = false;
- Policy.SuppressScope = true;
- Policy.TerseOutput = false;
- }));
+ ASSERT_TRUE(PrintedDeclCXX98Matches("struct S { int x; };"
+ "namespace NS { class C {};}"
+ "void foo() {using namespace NS; C c;}",
+ "foo",
+ "void foo() {\nusing namespace NS;\n"
+ "C c;\n}\n",
+ [](PrintingPolicy &Policy) {
+ Policy.SuppressTagKeyword = false;
+ Policy.SuppressScope = true;
+ Policy.TerseOutput = false;
+ }));
}
TEST(DeclPrinter, TestCXXRecordDecl13) {
- ASSERT_TRUE(PrintedDeclCXX98Matches(
- "struct S { int x; };"
- "S s1;"
- "S foo() {return s1;}",
- "foo", "struct S foo() {\nreturn s1;\n}\n", [](PrintingPolicy &Policy) {
- Policy.SuppressTagKeyword = false;
- Policy.SuppressScope = true;
- Policy.TerseOutput = false;
- }));
+ ASSERT_TRUE(PrintedDeclCXX98Matches("struct S { int x; };"
+ "S s1;"
+ "S foo() {return s1;}",
+ "foo", "S foo() {\nreturn s1;\n}\n",
+ [](PrintingPolicy &Policy) {
+ Policy.SuppressTagKeyword = false;
+ Policy.SuppressScope = true;
+ Policy.TerseOutput = false;
+ }));
}
TEST(DeclPrinter, TestCXXRecordDecl14) {
- ASSERT_TRUE(PrintedDeclCXX98Matches(
- "struct S { int x; };"
- "S foo(S s1) {return s1;}",
- "foo", "struct S foo(struct S s1) {\nreturn s1;\n}\n",
- [](PrintingPolicy &Policy) {
- Policy.SuppressTagKeyword = false;
- Policy.SuppressScope = true;
- Policy.TerseOutput = false;
- }));
+ ASSERT_TRUE(PrintedDeclCXX98Matches("struct S { int x; };"
+ "S foo(S s1) {return s1;}",
+ "foo", "S foo(S s1) {\nreturn s1;\n}\n",
+ [](PrintingPolicy &Policy) {
+ Policy.SuppressTagKeyword = false;
+ Policy.SuppressScope = true;
+ Policy.TerseOutput = false;
+ }));
}
TEST(DeclPrinter, TestCXXRecordDecl15) {
ASSERT_TRUE(PrintedDeclCXX98Matches(
@@ -399,8 +397,8 @@ TEST(DeclPrinter, TestCXXRecordDecl15) {
"namespace NS { class C {};}"
"S foo(S s1, NS::C c1) {using namespace NS; C c; return s1;}",
"foo",
- "struct S foo(struct S s1, class NS::C c1) {\nusing namespace NS;\nclass "
- "NS::C c;\nreturn s1;\n}\n",
+ "S foo(S s1, NS::C c1) {\nusing namespace NS;\n"
+ "C c;\nreturn s1;\n}\n",
[](PrintingPolicy &Policy) {
Policy.SuppressTagKeyword = false;
Policy.SuppressScope = true;
diff --git a/clang/unittests/AST/ProfilingTest.cpp b/clang/unittests/AST/ProfilingTest.cpp
index 27a4a197f1cbf..b46bade186301 100644
--- a/clang/unittests/AST/ProfilingTest.cpp
+++ b/clang/unittests/AST/ProfilingTest.cpp
@@ -63,11 +63,11 @@ TEST(Profiling, DeducedTemplateSpecializationType_Name) {
ASTContext &Ctx = AST->getASTContext();
auto *T1 = cast<DeducedTemplateSpecializationType>(
- Ctx.getDeducedTemplateSpecializationType(TemplateName(CTD1), QualType(),
- false));
+ Ctx.getDeducedTemplateSpecializationType(
+ ElaboratedTypeKeyword::None, TemplateName(CTD1), QualType(), false));
auto *T2 = cast<DeducedTemplateSpecializationType>(
- Ctx.getDeducedTemplateSpecializationType(TemplateName(CTD2), QualType(),
- false));
+ Ctx.getDeducedTemplateSpecializationType(
+ ElaboratedTypeKeyword::None, TemplateName(CTD2), QualType(), false));
testTypeNode(T1, T2);
}
diff --git a/clang/unittests/AST/RandstructTest.cpp b/clang/unittests/AST/RandstructTest.cpp
index c22d866ed4fad..cba446fc529e1 100644
--- a/clang/unittests/AST/RandstructTest.cpp
+++ b/clang/unittests/AST/RandstructTest.cpp
@@ -532,7 +532,7 @@ TEST(RANDSTRUCT_TEST, AnonymousStructsAndUnionsRetainFieldOrder) {
for (const Decl *D : RD->decls())
if (const FieldDecl *FD = dyn_cast<FieldDecl>(D)) {
if (const auto *Record = FD->getType()->getAs<RecordType>()) {
- RD = Record->getDecl();
+ RD = Record->getOriginalDecl()->getDefinitionOrSelf();
if (RD->isAnonymousStructOrUnion()) {
// These field orders shouldn't change.
if (RD->isUnion()) {
diff --git a/clang/unittests/AST/RecursiveASTVisitorTest.cpp b/clang/unittests/AST/RecursiveASTVisitorTest.cpp
index 9d7ff5947fe53..c5ad29a77d211 100644
--- a/clang/unittests/AST/RecursiveASTVisitorTest.cpp
+++ b/clang/unittests/AST/RecursiveASTVisitorTest.cpp
@@ -95,9 +95,10 @@ class CollectInterestingEvents
return Ret;
}
- bool TraverseTypedefTypeLoc(TypedefTypeLoc TL) {
+ bool TraverseTypedefTypeLoc(TypedefTypeLoc TL, bool TraverseQualifier) {
Events.push_back(VisitEvent::StartTraverseTypedefType);
- bool Ret = RecursiveASTVisitor::TraverseTypedefTypeLoc(TL);
+ bool Ret =
+ RecursiveASTVisitor::TraverseTypedefTypeLoc(TL, TraverseQualifier);
Events.push_back(VisitEvent::EndTraverseTypedefType);
return Ret;
diff --git a/clang/unittests/AST/SizelessTypesTest.cpp b/clang/unittests/AST/SizelessTypesTest.cpp
index 0b984b6922934..4a945a439492d 100644
--- a/clang/unittests/AST/SizelessTypesTest.cpp
+++ b/clang/unittests/AST/SizelessTypesTest.cpp
@@ -24,7 +24,7 @@ struct SizelessTypeTester : public ::testing::Test {
ASTContext &Ctx = AST->getASTContext();
TranslationUnitDecl &TU = *Ctx.getTranslationUnitDecl();
TypeDecl *Foo = cast<TypeDecl>(TU.lookup(&Ctx.Idents.get("foo")).front());
- const Type *FooTy = Foo->getTypeForDecl();
+ const Type *FooTy = Ctx.getTypeDeclType(Foo).getTypePtr();
};
TEST_F(SizelessTypeTester, TestSizelessBuiltin) {
diff --git a/clang/unittests/AST/StructuralEquivalenceTest.cpp b/clang/unittests/AST/StructuralEquivalenceTest.cpp
index ef82afaf3f8dc..bee288dbfe436 100644
--- a/clang/unittests/AST/StructuralEquivalenceTest.cpp
+++ b/clang/unittests/AST/StructuralEquivalenceTest.cpp
@@ -617,8 +617,7 @@ TEST_F(StructuralEquivalenceCXXMethodTest, OutOfClass2) {
struct StructuralEquivalenceRecordTest : StructuralEquivalenceTest {
// FIXME Use a common getRecordDecl with ASTImporterTest.cpp!
RecordDecl *getRecordDecl(FieldDecl *FD) {
- auto *ET = cast<ElaboratedType>(FD->getType().getTypePtr());
- return cast<RecordType>(ET->getNamedType().getTypePtr())->getDecl();
+ return FD->getType()->getAsRecordDecl();
};
};
@@ -720,11 +719,13 @@ TEST_F(StructuralEquivalenceRecordTest, AnonymousRecordsShouldBeInequivalent) {
auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
TU, indirectFieldDecl(hasName("a")));
auto *FA = cast<FieldDecl>(A->chain().front());
- RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
+ RecordDecl *RA =
+ cast<RecordType>(FA->getType().getTypePtr())->getOriginalDecl();
auto *B = FirstDeclMatcher<IndirectFieldDecl>().match(
TU, indirectFieldDecl(hasName("b")));
auto *FB = cast<FieldDecl>(B->chain().front());
- RecordDecl *RB = cast<RecordType>(FB->getType().getTypePtr())->getDecl();
+ RecordDecl *RB =
+ cast<RecordType>(FB->getType().getTypePtr())->getOriginalDecl();
ASSERT_NE(RA, RB);
EXPECT_TRUE(testStructuralMatch(RA, RA));
@@ -753,13 +754,15 @@ TEST_F(StructuralEquivalenceRecordTest,
auto *A = FirstDeclMatcher<IndirectFieldDecl>().match(
TU, indirectFieldDecl(hasName("a")));
auto *FA = cast<FieldDecl>(A->chain().front());
- RecordDecl *RA = cast<RecordType>(FA->getType().getTypePtr())->getDecl();
+ RecordDecl *RA =
+ cast<RecordType>(FA->getType().getTypePtr())->getOriginalDecl();
auto *TU1 = get<1>(t);
auto *A1 = FirstDeclMatcher<IndirectFieldDecl>().match(
TU1, indirectFieldDecl(hasName("a")));
auto *FA1 = cast<FieldDecl>(A1->chain().front());
- RecordDecl *RA1 = cast<RecordType>(FA1->getType().getTypePtr())->getDecl();
+ RecordDecl *RA1 =
+ cast<RecordType>(FA1->getType().getTypePtr())->getOriginalDecl();
RecordDecl *X =
FirstDeclMatcher<RecordDecl>().match(TU, recordDecl(hasName("X")));
diff --git a/clang/unittests/AST/TemplateNameTest.cpp b/clang/unittests/AST/TemplateNameTest.cpp
index 2eac5c508d059..31655e2fd6be9 100644
--- a/clang/unittests/AST/TemplateNameTest.cpp
+++ b/clang/unittests/AST/TemplateNameTest.cpp
@@ -120,14 +120,14 @@ TEST(TemplateName, UsingTemplate) {
// are rather part of the ElaboratedType)!
absl::vector<int> v(123);
)cpp");
- auto Matcher = elaboratedTypeLoc(
- hasNamedTypeLoc(loc(templateSpecializationType().bind("id"))));
+ auto Matcher = templateSpecializationTypeLoc().bind("id");
auto MatchResults = match(Matcher, AST->getASTContext());
const auto *TST =
- MatchResults.front().getNodeAs<TemplateSpecializationType>("id");
+ MatchResults.front().getNodeAs<TemplateSpecializationTypeLoc>("id");
ASSERT_TRUE(TST);
- EXPECT_EQ(TST->getTemplateName().getKind(), TemplateName::QualifiedTemplate);
- EXPECT_TRUE(TST->getTemplateName().getAsUsingShadowDecl() != nullptr);
+ TemplateName TN = TST->getTypePtr()->getTemplateName();
+ EXPECT_EQ(TN.getKind(), TemplateName::QualifiedTemplate);
+ EXPECT_TRUE(TN.getAsUsingShadowDecl() != nullptr);
AST = tooling::buildASTFromCodeWithArgs(R"cpp(
namespace std {
@@ -139,8 +139,7 @@ TEST(TemplateName, UsingTemplate) {
absl::vector DTST(123);
)cpp",
{"-std=c++17"});
- Matcher = elaboratedTypeLoc(
- hasNamedTypeLoc(loc(deducedTemplateSpecializationType().bind("id"))));
+ Matcher = loc(deducedTemplateSpecializationType().bind("id"));
MatchResults = match(Matcher, AST->getASTContext());
const auto *DTST =
MatchResults.front().getNodeAs<DeducedTemplateSpecializationType>("id");
diff --git a/clang/unittests/AST/TypePrinterTest.cpp b/clang/unittests/AST/TypePrinterTest.cpp
index 2b37add007086..ca0380b3c9dd3 100644
--- a/clang/unittests/AST/TypePrinterTest.cpp
+++ b/clang/unittests/AST/TypePrinterTest.cpp
@@ -60,7 +60,7 @@ TEST(TypePrinter, TemplateId) {
[](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; }));
ASSERT_TRUE(PrintedTypeMatches(
- Code, {}, Matcher, "const Type<T> &",
+ Code, {}, Matcher, "const N::Type<T> &",
[](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; }));
}
@@ -97,7 +97,7 @@ TEST(TypePrinter, ParamsUglified) {
"const f<Tp &> *", Clean));
}
-TEST(TypePrinter, SuppressElaboration) {
+TEST(TypePrinter, TemplateSpecializationFullyQualified) {
llvm::StringLiteral Code = R"cpp(
namespace shared {
namespace a {
@@ -115,13 +115,10 @@ TEST(TypePrinter, SuppressElaboration) {
hasType(qualType().bind("id")));
ASSERT_TRUE(PrintedTypeMatches(
Code, {}, Matcher, "a::S<b::Foo>",
+ [](PrintingPolicy &Policy) { Policy.FullyQualifiedName = false; }));
+ ASSERT_TRUE(PrintedTypeMatches(
+ Code, {}, Matcher, "shared::a::S<shared::b::Foo>",
[](PrintingPolicy &Policy) { Policy.FullyQualifiedName = true; }));
- ASSERT_TRUE(PrintedTypeMatches(Code, {}, Matcher,
- "shared::a::S<shared::b::Foo>",
- [](PrintingPolicy &Policy) {
- Policy.SuppressElaboration = true;
- Policy.FullyQualifiedName = true;
- }));
}
TEST(TypePrinter, TemplateIdWithNTTP) {
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
index 49abe881eeabb..ecbfc47790f55 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNarrowingTest.cpp
@@ -1172,8 +1172,8 @@ TEST_P(ASTMatchersTest, IsDerivedFrom_ElaboratedType) {
return;
}
- DeclarationMatcher IsDerivenFromBase =
- cxxRecordDecl(isDerivedFrom(decl().bind("typedef")));
+ DeclarationMatcher IsDerivenFromBase = cxxRecordDecl(
+ isDerivedFrom(decl().bind("typedef")), unless(isImplicit()));
EXPECT_TRUE(matchAndVerifyResultTrue(
"struct AnInterface {};"
@@ -2302,10 +2302,9 @@ TEST(ASTMatchersTest, NamesMember_CXXDependentScopeMemberExpr) {
EXPECT_TRUE(matches(
Code,
cxxDependentScopeMemberExpr(
- hasObjectExpression(declRefExpr(hasType(elaboratedType(namesType(
- templateSpecializationType(hasDeclaration(classTemplateDecl(
- has(cxxRecordDecl(has(cxxMethodDecl(hasName("mem"))
- .bind("templMem")))))))))))),
+ hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
+ hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
+ has(cxxMethodDecl(hasName("mem")).bind("templMem")))))))))),
memberHasSameNameAsBoundNode("templMem"))));
EXPECT_TRUE(
@@ -2323,10 +2322,9 @@ TEST(ASTMatchersTest, NamesMember_CXXDependentScopeMemberExpr) {
EXPECT_TRUE(matches(
Code,
cxxDependentScopeMemberExpr(
- hasObjectExpression(declRefExpr(
- hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(classTemplateDecl(has(cxxRecordDecl(has(
- fieldDecl(hasName("mem")).bind("templMem")))))))))))),
+ hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
+ hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
+ has(fieldDecl(hasName("mem")).bind("templMem")))))))))),
memberHasSameNameAsBoundNode("templMem"))));
}
@@ -2341,10 +2339,9 @@ TEST(ASTMatchersTest, NamesMember_CXXDependentScopeMemberExpr) {
EXPECT_TRUE(matches(
Code,
cxxDependentScopeMemberExpr(
- hasObjectExpression(declRefExpr(
- hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
- has(varDecl(hasName("mem")).bind("templMem")))))))))))),
+ hasObjectExpression(declRefExpr(hasType(templateSpecializationType(
+ hasDeclaration(classTemplateDecl(has(cxxRecordDecl(
+ has(varDecl(hasName("mem")).bind("templMem")))))))))),
memberHasSameNameAsBoundNode("templMem"))));
}
{
diff --git a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
index 07450a0c59ec6..b55928f7060da 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersNodeTest.cpp
@@ -1938,8 +1938,7 @@ TEST_P(ASTMatchersTest, PointerType_MatchesPointersToConstTypes) {
TEST_P(ASTMatchersTest, TypedefType) {
EXPECT_TRUE(matches("typedef int X; X a;",
- varDecl(hasName("a"), hasType(elaboratedType(
- namesType(typedefType()))))));
+ varDecl(hasName("a"), hasType(typedefType()))));
}
TEST_P(ASTMatchersTest, MacroQualifiedType) {
@@ -2018,22 +2017,6 @@ TEST_P(ASTMatchersTest, RecordType_CXX) {
recordType(hasDeclaration(recordDecl(hasName("S"))))));
}
-TEST_P(ASTMatchersTest, ElaboratedType) {
- if (!GetParam().isCXX()) {
- // FIXME: Add a test for `elaboratedType()` that does not depend on C++.
- return;
- }
- EXPECT_TRUE(matches("namespace N {"
- " namespace M {"
- " class D {};"
- " }"
- "}"
- "N::M::D d;",
- elaboratedType()));
- EXPECT_TRUE(matches("class C {} c;", elaboratedType()));
- EXPECT_TRUE(matches("class C {}; C c;", elaboratedType()));
-}
-
TEST_P(ASTMatchersTest, SubstTemplateTypeParmType) {
if (!GetParam().isCXX()) {
return;
@@ -2133,16 +2116,16 @@ TEST_P(ASTMatchersTest,
if (!GetParam().isCXX()) {
return;
}
- EXPECT_TRUE(matches(
- "struct A { struct B { struct C {}; }; }; A::B::C c;",
- nestedNameSpecifier(hasPrefix(specifiesType(asString("struct A"))))));
+ EXPECT_TRUE(
+ matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
+ nestedNameSpecifier(hasPrefix(specifiesType(asString("A"))))));
EXPECT_TRUE(matches("struct A { struct B { struct C {}; }; }; A::B::C c;",
- nestedNameSpecifierLoc(hasPrefix(specifiesTypeLoc(
- loc(qualType(asString("struct A"))))))));
+ nestedNameSpecifierLoc(hasPrefix(
+ specifiesTypeLoc(loc(qualType(asString("A"))))))));
EXPECT_TRUE(matches(
"namespace N { struct A { struct B { struct C {}; }; }; } N::A::B::C c;",
- nestedNameSpecifierLoc(hasPrefix(
- specifiesTypeLoc(loc(qualType(asString("struct N::A"))))))));
+ nestedNameSpecifierLoc(
+ hasPrefix(specifiesTypeLoc(loc(qualType(asString("N::A"))))))));
}
template <typename T>
@@ -2338,8 +2321,7 @@ TEST_P(ASTMatchersTest,
}
EXPECT_TRUE(matches(
"template <typename T> class C {}; C<char> var;",
- varDecl(hasName("var"), hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
- templateSpecializationTypeLoc()))))));
+ varDecl(hasName("var"), hasTypeLoc(templateSpecializationTypeLoc()))));
}
TEST_P(
@@ -2353,58 +2335,6 @@ TEST_P(
varDecl(hasName("var"), hasTypeLoc(templateSpecializationTypeLoc()))));
}
-TEST_P(ASTMatchersTest,
- ElaboratedTypeLocTest_BindsToElaboratedObjectDeclaration) {
- if (!GetParam().isCXX()) {
- return;
- }
- EXPECT_TRUE(matches("class C {}; class C c;",
- varDecl(hasName("c"), hasTypeLoc(elaboratedTypeLoc()))));
-}
-
-TEST_P(ASTMatchersTest,
- ElaboratedTypeLocTest_BindsToNamespaceElaboratedObjectDeclaration) {
- if (!GetParam().isCXX()) {
- return;
- }
- EXPECT_TRUE(matches("namespace N { class D {}; } N::D d;",
- varDecl(hasName("d"), hasTypeLoc(elaboratedTypeLoc()))));
-}
-
-TEST_P(ASTMatchersTest,
- ElaboratedTypeLocTest_BindsToElaboratedStructDeclaration) {
- EXPECT_TRUE(matches("struct s {}; struct s ss;",
- varDecl(hasName("ss"), hasTypeLoc(elaboratedTypeLoc()))));
-}
-
-TEST_P(ASTMatchersTest,
- ElaboratedTypeLocTest_BindsToBareElaboratedObjectDeclaration) {
- if (!GetParam().isCXX()) {
- return;
- }
- EXPECT_TRUE(matches("class C {}; C c;",
- varDecl(hasName("c"), hasTypeLoc(elaboratedTypeLoc()))));
-}
-
-TEST_P(
- ASTMatchersTest,
- ElaboratedTypeLocTest_DoesNotBindToNamespaceNonElaboratedObjectDeclaration) {
- if (!GetParam().isCXX()) {
- return;
- }
- EXPECT_TRUE(matches("namespace N { class D {}; } using N::D; D d;",
- varDecl(hasName("d"), hasTypeLoc(elaboratedTypeLoc()))));
-}
-
-TEST_P(ASTMatchersTest,
- ElaboratedTypeLocTest_BindsToBareElaboratedStructDeclaration) {
- if (!GetParam().isCXX()) {
- return;
- }
- EXPECT_TRUE(matches("struct s {}; s ss;",
- varDecl(hasName("ss"), hasTypeLoc(elaboratedTypeLoc()))));
-}
-
TEST_P(ASTMatchersTest, LambdaCaptureTest) {
if (!GetParam().isCXX11OrLater()) {
return;
diff --git a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
index 8ddae4e47004b..d58bc00c995e0 100644
--- a/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
+++ b/clang/unittests/ASTMatchers/ASTMatchersTraversalTest.cpp
@@ -190,13 +190,11 @@ TEST(TypeMatcher, MatchesDeclTypes) {
EXPECT_TRUE(matches("template <typename T> struct S {"
" void f(S s);"
"};",
- parmVarDecl(hasType(elaboratedType(
- namesType(injectedClassNameType()))))));
+ parmVarDecl(hasType(injectedClassNameType()))));
EXPECT_TRUE(notMatches("template <typename T> struct S {"
" void g(S<T> s);"
"};",
- parmVarDecl(hasType(elaboratedType(
- namesType(injectedClassNameType()))))));
+ parmVarDecl(hasType(injectedClassNameType()))));
// InjectedClassNameType -> CXXRecordDecl
EXPECT_TRUE(matches("template <typename T> struct S {"
" void f(S s);"
@@ -228,46 +226,39 @@ TEST(HasDeclaration, HasDeclarationOfEnumType) {
TEST(HasDeclaration, HasGetDeclTraitTest) {
static_assert(internal::has_getDecl<TypedefType>,
"Expected TypedefType to have a getDecl.");
- static_assert(internal::has_getDecl<RecordType>,
- "Expected RecordType to have a getDecl.");
static_assert(!internal::has_getDecl<TemplateSpecializationType>,
"Expected TemplateSpecializationType to *not* have a getDecl.");
}
TEST(HasDeclaration, ElaboratedType) {
- EXPECT_TRUE(matches(
- "namespace n { template <typename T> struct X {}; }"
- "void f(n::X<int>);",
- parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl()))))));
- EXPECT_TRUE(matches(
- "namespace n { template <typename T> struct X {}; }"
- "void f(n::X<int>);",
- parmVarDecl(hasType(elaboratedType(hasDeclaration(cxxRecordDecl()))))));
+ static const char Elaborated[] = "namespace n { struct X {}; }"
+ "void f(n::X);";
+ EXPECT_TRUE(
+ matches(Elaborated,
+ parmVarDecl(hasType(qualType(hasDeclaration(cxxRecordDecl()))))));
+ EXPECT_TRUE(matches(Elaborated, parmVarDecl(hasType(recordType(
+ hasDeclaration(cxxRecordDecl()))))));
}
TEST(HasDeclaration, HasDeclarationOfTypeWithDecl) {
EXPECT_TRUE(matches(
"typedef int X; X a;",
- varDecl(hasName("a"), hasType(elaboratedType(namesType(
- typedefType(hasDeclaration(decl()))))))));
+ varDecl(hasName("a"), hasType(typedefType(hasDeclaration(decl()))))));
// FIXME: Add tests for other types with getDecl() (e.g. RecordType)
}
TEST(HasDeclaration, HasDeclarationOfTemplateSpecializationType) {
- EXPECT_TRUE(matches(
- "template <typename T> class A {}; A<int> a;",
- varDecl(hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(namedDecl(hasName("A"))))))))));
- EXPECT_TRUE(matches(
- "template <typename T> class A {};"
- "template <typename T> class B { A<T> a; };",
- fieldDecl(hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(namedDecl(hasName("A"))))))))));
- EXPECT_TRUE(matches(
- "template <typename T> class A {}; A<int> a;",
- varDecl(hasType(elaboratedType(namesType(
- templateSpecializationType(hasDeclaration(cxxRecordDecl()))))))));
+ EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
+ varDecl(hasType(templateSpecializationType(
+ hasDeclaration(namedDecl(hasName("A"))))))));
+ EXPECT_TRUE(matches("template <typename T> class A {};"
+ "template <typename T> class B { A<T> a; };",
+ fieldDecl(hasType(templateSpecializationType(
+ hasDeclaration(namedDecl(hasName("A"))))))));
+ EXPECT_TRUE(matches("template <typename T> class A {}; A<int> a;",
+ varDecl(hasType(templateSpecializationType(
+ hasDeclaration(cxxRecordDecl()))))));
}
TEST(HasDeclaration, HasDeclarationOfCXXNewExpr) {
@@ -277,10 +268,9 @@ TEST(HasDeclaration, HasDeclarationOfCXXNewExpr) {
}
TEST(HasDeclaration, HasDeclarationOfTypeAlias) {
- EXPECT_TRUE(matches(
- "template <typename T> using C = T; C<int> c;",
- varDecl(hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(typeAliasTemplateDecl()))))))));
+ EXPECT_TRUE(matches("template <typename T> using C = T; C<int> c;",
+ varDecl(hasType(templateSpecializationType(
+ hasDeclaration(typeAliasTemplateDecl()))))));
}
TEST(HasDeclaration, HasDeclarationOfObjCInterface) {
@@ -5410,14 +5400,15 @@ TEST(LoopingMatchers, DoNotOverwritePreviousMatchResultOnFailure) {
functionDecl(parameterCountIs(1))))),
std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
EXPECT_TRUE(matchAndVerifyResultTrue(
- "class A{}; class B{}; class C : B, A {};",
- cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A")),
- std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
+ "class A{}; class B{}; class C : B, A {};",
+ cxxRecordDecl(decl().bind("x"), isDerivedFrom("::A"),
+ unless(isImplicit())),
+ std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
EXPECT_TRUE(matchAndVerifyResultTrue(
- "class A{}; typedef A B; typedef A C; typedef A D;"
+ "class A{}; typedef A B; typedef A C; typedef A D;"
"class E : A {};",
- cxxRecordDecl(decl().bind("x"), isDerivedFrom("C")),
- std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
+ cxxRecordDecl(decl().bind("x"), isDerivedFrom("C"), unless(isImplicit())),
+ std::make_unique<VerifyIdIsBoundTo<Decl>>("x", 1)));
EXPECT_TRUE(matchAndVerifyResultTrue(
"class A { class B { void f() {} }; };",
functionDecl(decl().bind("x"), hasAncestor(recordDecl(hasName("::A")))),
@@ -5710,7 +5701,7 @@ TEST(HasAnyBase, BindsInnerBoundNodes) {
EXPECT_TRUE(matchAndVerifyResultTrue(
"struct Inner {}; struct Proxy : Inner {}; struct Main : public "
"Proxy {};",
- cxxRecordDecl(hasName("Main"),
+ cxxRecordDecl(hasName("Main"), unless(isImplicit()),
hasAnyBase(cxxBaseSpecifier(hasType(
cxxRecordDecl(hasName("Inner")).bind("base-class")))))
.bind("class"),
@@ -5736,47 +5727,28 @@ TEST(TypeMatching, PointeeTypes) {
TEST(ElaboratedTypeNarrowing, hasQualifier) {
EXPECT_TRUE(matches(
- "namespace N {"
+ "namespace N {"
" namespace M {"
" class D {};"
" }"
"}"
"N::M::D d;",
- elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
+ recordType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
EXPECT_TRUE(notMatches(
- "namespace M {"
+ "namespace M {"
" class D {};"
"}"
"M::D d;",
- elaboratedType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
- EXPECT_TRUE(notMatches(
- "struct D {"
- "} d;",
- elaboratedType(hasQualifier(nestedNameSpecifier()))));
-}
-
-TEST(ElaboratedTypeNarrowing, namesType) {
- EXPECT_TRUE(matches(
- "namespace N {"
- " namespace M {"
- " class D {};"
- " }"
- "}"
- "N::M::D d;",
- elaboratedType(elaboratedType(namesType(recordType(
- hasDeclaration(namedDecl(hasName("D")))))))));
- EXPECT_TRUE(notMatches(
- "namespace M {"
- " class D {};"
- "}"
- "M::D d;",
- elaboratedType(elaboratedType(namesType(typedefType())))));
+ recordType(hasQualifier(hasPrefix(specifiesNamespace(hasName("N")))))));
+ EXPECT_TRUE(notMatches("struct D {"
+ "} d;",
+ recordType(hasQualifier(nestedNameSpecifier()))));
}
TEST(NNS, BindsNestedNameSpecifiers) {
EXPECT_TRUE(matchAndVerifyResultTrue(
"namespace ns { struct E { struct B {}; }; } ns::E::B b;",
- nestedNameSpecifier(specifiesType(asString("struct ns::E"))).bind("nns"),
+ nestedNameSpecifier(specifiesType(asString("ns::E"))).bind("nns"),
std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("nns",
"ns::E::")));
}
@@ -5793,38 +5765,33 @@ TEST(NNS, DescendantsOfNestedNameSpecifiers) {
"namespace a { struct A { struct B { struct C {}; }; }; };"
"void f() { a::A::B::C c; }";
EXPECT_TRUE(matches(
- Fragment,
- nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
- hasDescendant(nestedNameSpecifier(
- specifiesNamespace(hasName("a")))))));
+ Fragment, nestedNameSpecifier(specifiesType(asString("a::A::B")),
+ hasDescendant(nestedNameSpecifier(
+ specifiesNamespace(hasName("a")))))));
EXPECT_TRUE(notMatches(
- Fragment,
- nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
- has(nestedNameSpecifier(
- specifiesNamespace(hasName("a")))))));
+ Fragment, nestedNameSpecifier(specifiesType(asString("a::A::B")),
+ has(nestedNameSpecifier(
+ specifiesNamespace(hasName("a")))))));
EXPECT_TRUE(matches(
- Fragment,
- nestedNameSpecifier(specifiesType(asString("struct a::A")),
- has(nestedNameSpecifier(
- specifiesNamespace(hasName("a")))))));
+ Fragment, nestedNameSpecifier(specifiesType(asString("a::A")),
+ has(nestedNameSpecifier(
+ specifiesNamespace(hasName("a")))))));
// Not really useful because a NestedNameSpecifier can af at most one child,
// but to complete the interface.
EXPECT_TRUE(matchAndVerifyResultTrue(
- Fragment,
- nestedNameSpecifier(specifiesType(asString("struct a::A::B")),
- forEach(nestedNameSpecifier().bind("x"))),
- std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1)));
+ Fragment,
+ nestedNameSpecifier(specifiesType(asString("a::A::B")),
+ forEach(nestedNameSpecifier().bind("x"))),
+ std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifier>>("x", 1)));
}
TEST(NNS, NestedNameSpecifiersAsDescendants) {
StringRef Fragment =
"namespace a { struct A { struct B { struct C {}; }; }; };"
"void f() { a::A::B::C c; }";
- EXPECT_TRUE(matches(
- Fragment,
- decl(hasDescendant(nestedNameSpecifier(specifiesType(
- asString("struct a::A")))))));
+ EXPECT_TRUE(matches(Fragment, decl(hasDescendant(nestedNameSpecifier(
+ specifiesType(asString("a::A")))))));
EXPECT_TRUE(matchAndVerifyResultTrue(
Fragment,
functionDecl(hasName("f"),
@@ -5837,37 +5804,34 @@ TEST(NNSLoc, DescendantsOfNestedNameSpecifierLocs) {
StringRef Fragment =
"namespace a { struct A { struct B { struct C {}; }; }; };"
"void f() { a::A::B::C c; }";
- EXPECT_TRUE(matches(
- Fragment,
- nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
- hasDescendant(loc(nestedNameSpecifier(
- specifiesNamespace(hasName("a"))))))));
+ EXPECT_TRUE(matches(Fragment, nestedNameSpecifierLoc(
+ loc(specifiesType(asString("a::A::B"))),
+ hasDescendant(loc(nestedNameSpecifier(
+ specifiesNamespace(hasName("a"))))))));
EXPECT_TRUE(notMatches(
- Fragment,
- nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
- has(loc(nestedNameSpecifier(
- specifiesNamespace(hasName("a"))))))));
+ Fragment,
+ nestedNameSpecifierLoc(
+ loc(specifiesType(asString("a::A::B"))),
+ has(loc(nestedNameSpecifier(specifiesNamespace(hasName("a"))))))));
EXPECT_TRUE(matches(
- Fragment,
- nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A"))),
- has(loc(nestedNameSpecifier(
- specifiesNamespace(hasName("a"))))))));
+ Fragment,
+ nestedNameSpecifierLoc(
+ loc(specifiesType(asString("a::A"))),
+ has(loc(nestedNameSpecifier(specifiesNamespace(hasName("a"))))))));
EXPECT_TRUE(matchAndVerifyResultTrue(
- Fragment,
- nestedNameSpecifierLoc(loc(specifiesType(asString("struct a::A::B"))),
- forEach(nestedNameSpecifierLoc().bind("x"))),
- std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1)));
+ Fragment,
+ nestedNameSpecifierLoc(loc(specifiesType(asString("a::A::B"))),
+ forEach(nestedNameSpecifierLoc().bind("x"))),
+ std::make_unique<VerifyIdIsBoundTo<NestedNameSpecifierLoc>>("x", 1)));
}
TEST(NNSLoc, NestedNameSpecifierLocsAsDescendants) {
StringRef Fragment =
"namespace a { struct A { struct B { struct C {}; }; }; };"
"void f() { a::A::B::C c; }";
- EXPECT_TRUE(matches(
- Fragment,
- decl(hasDescendant(loc(nestedNameSpecifier(specifiesType(
- asString("struct a::A"))))))));
+ EXPECT_TRUE(matches(Fragment, decl(hasDescendant(loc(nestedNameSpecifier(
+ specifiesType(asString("a::A"))))))));
EXPECT_TRUE(matchAndVerifyResultTrue(
Fragment,
functionDecl(hasName("f"),
@@ -5883,7 +5847,9 @@ TEST(Attr, AttrsAsDescendants) {
EXPECT_TRUE(matchAndVerifyResultTrue(
Fragment,
namespaceDecl(hasName("a"),
- forEachDescendant(attr(unless(isImplicit())).bind("x"))),
+ forEachDescendant(decl(
+ hasDescendant(attr(unless(isImplicit())).bind("x")),
+ unless(isImplicit())))),
std::make_unique<VerifyIdIsBoundTo<Attr>>("x", 2)));
}
@@ -6531,21 +6497,19 @@ TEST(HasReferentLoc, DoesNotBindToParameterWithoutIntReferenceTypeLoc) {
}
TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
- EXPECT_TRUE(matches(
- "template<typename T> class A {}; A<int> a;",
- varDecl(hasName("a"),
- hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
- templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
- hasTypeLoc(loc(asString("int")))))))))));
+ EXPECT_TRUE(
+ matches("template<typename T> class A {}; A<int> a;",
+ varDecl(hasName("a"), hasTypeLoc(templateSpecializationTypeLoc(
+ hasAnyTemplateArgumentLoc(hasTypeLoc(
+ loc(asString("int")))))))));
}
TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
- EXPECT_TRUE(matches(
- "template<typename T> class A {}; A<double> a;",
- varDecl(hasName("a"),
- hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
- templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
- hasTypeLoc(loc(asString("double")))))))))));
+ EXPECT_TRUE(
+ matches("template<typename T> class A {}; A<double> a;",
+ varDecl(hasName("a"), hasTypeLoc(templateSpecializationTypeLoc(
+ hasAnyTemplateArgumentLoc(hasTypeLoc(
+ loc(asString("double")))))))));
}
TEST(HasAnyTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
@@ -6598,30 +6562,27 @@ TEST(HasAnyTemplateArgumentLoc,
}
TEST(HasTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
- EXPECT_TRUE(
- matches("template<typename T> class A {}; A<int> a;",
- varDecl(hasName("a"),
- hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
- templateSpecializationTypeLoc(hasTemplateArgumentLoc(
- 0, hasTypeLoc(loc(asString("int")))))))))));
+ EXPECT_TRUE(matches(
+ "template<typename T> class A {}; A<int> a;",
+ varDecl(hasName("a"),
+ hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
+ 0, hasTypeLoc(loc(asString("int")))))))));
}
TEST(HasTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
- EXPECT_TRUE(
- matches("template<typename T> class A {}; A<double> a;",
- varDecl(hasName("a"),
- hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
- templateSpecializationTypeLoc(hasTemplateArgumentLoc(
- 0, hasTypeLoc(loc(asString("double")))))))))));
+ EXPECT_TRUE(matches(
+ "template<typename T> class A {}; A<double> a;",
+ varDecl(hasName("a"),
+ hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
+ 0, hasTypeLoc(loc(asString("double")))))))));
}
TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
EXPECT_TRUE(notMatches(
"template<typename T> class A {}; A<int> a;",
varDecl(hasName("a"),
- hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
- templateSpecializationTypeLoc(hasTemplateArgumentLoc(
- 0, hasTypeLoc(loc(asString("double")))))))))));
+ hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
+ 0, hasTypeLoc(loc(asString("double")))))))));
}
TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
@@ -6735,12 +6696,11 @@ TEST(HasNamedTypeLoc, BindsToElaboratedObjectDeclaration) {
class C<int> c;
)",
varDecl(hasName("c"),
- hasTypeLoc(elaboratedTypeLoc(
- hasNamedTypeLoc(templateSpecializationTypeLoc(
- hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
+ hasTypeLoc(templateSpecializationTypeLoc(
+ hasAnyTemplateArgumentLoc(templateArgumentLoc()))))));
}
-TEST(HasNamedTypeLoc, DoesNotBindToNonElaboratedObjectDeclaration) {
+TEST(HasNamedTypeLoc, BindsToNonElaboratedObjectDeclaration) {
EXPECT_TRUE(matches(
R"(
template <typename T>
@@ -6748,9 +6708,8 @@ TEST(HasNamedTypeLoc, DoesNotBindToNonElaboratedObjectDeclaration) {
C<int> c;
)",
varDecl(hasName("c"),
- hasTypeLoc(elaboratedTypeLoc(
- hasNamedTypeLoc(templateSpecializationTypeLoc(
- hasAnyTemplateArgumentLoc(templateArgumentLoc()))))))));
+ hasTypeLoc(templateSpecializationTypeLoc(
+ hasAnyTemplateArgumentLoc(templateArgumentLoc()))))));
}
} // namespace ast_matchers
diff --git a/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp b/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp
index ffc50fbb65523..fb3ab7c0dc9b4 100644
--- a/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/CachedConstAccessorsLatticeTest.cpp
@@ -80,7 +80,7 @@ struct CommonTestInputs {
)cpp") {
auto *SDecl = cast<CXXRecordDecl>(
lookup("S", *AST.context().getTranslationUnitDecl()));
- SType = AST.context().getRecordType(SDecl);
+ SType = AST.context().getCanonicalTagType(SDecl);
CallVal = selectFirst<CallExpr>(
"call",
match(cxxMemberCallExpr(callee(functionDecl(hasName("valProperty"))))
@@ -163,7 +163,7 @@ TEST_F(CachedConstAccessorsLatticeTest,
)cpp");
auto *SDecl =
cast<CXXRecordDecl>(lookup("S", *AST.context().getTranslationUnitDecl()));
- QualType SType = AST.context().getRecordType(SDecl);
+ CanQualType SType = AST.context().getCanonicalTagType(SDecl);
const CallExpr *CE = selectFirst<CallExpr>(
"call", match(cxxMemberCallExpr(
callee(functionDecl(hasName("structValProperty"))))
@@ -237,7 +237,7 @@ TEST_F(CachedConstAccessorsLatticeTest, DifferentValsFromDifferentLocs) {
)cpp");
auto *SDecl =
cast<CXXRecordDecl>(lookup("S", *AST.context().getTranslationUnitDecl()));
- QualType SType = AST.context().getRecordType(SDecl);
+ CanQualType SType = AST.context().getCanonicalTagType(SDecl);
SmallVector<BoundNodes, 1> valPropertyCalls =
match(cxxMemberCallExpr(callee(functionDecl(hasName("valProperty"))))
.bind("call"),
diff --git a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
index 737277e167edd..0780db921652c 100644
--- a/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
+++ b/clang/unittests/Analysis/FlowSensitive/DataflowEnvironmentTest.cpp
@@ -402,7 +402,7 @@ TEST_F(EnvironmentTest,
// `Target<&S::accessor>`.
Environment Env(DAContext, *Fun);
Env.initialize();
- EXPECT_THAT(DAContext.getModeledFields(QualType(Struct->getTypeForDecl(), 0)),
+ EXPECT_THAT(DAContext.getModeledFields(Context.getCanonicalTagType(Struct)),
Contains(Member));
}
diff --git a/clang/unittests/CodeGen/CodeGenExternalTest.cpp b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
index 00815889d7796..be3be147460f3 100644
--- a/clang/unittests/CodeGen/CodeGenExternalTest.cpp
+++ b/clang/unittests/CodeGen/CodeGenExternalTest.cpp
@@ -172,6 +172,7 @@ static void test_codegen_fns(MyASTConsumer *my) {
bool mytest_struct_ok = false;
CodeGen::CodeGenModule &CGM = my->Builder->CGM();
+ const ASTContext &Ctx = my->toplevel_decls.front()->getASTContext();
for (auto decl : my->toplevel_decls ) {
if (FunctionDecl *fd = dyn_cast<FunctionDecl>(decl)) {
@@ -189,9 +190,7 @@ static void test_codegen_fns(MyASTConsumer *my) {
if (rd->getName() == "mytest_struct") {
RecordDecl *def = rd->getDefinition();
ASSERT_TRUE(def != NULL);
- const clang::Type *clangTy = rd->getCanonicalDecl()->getTypeForDecl();
- ASSERT_TRUE(clangTy != NULL);
- QualType qType = clangTy->getCanonicalTypeInternal();
+ CanQualType qType = Ctx.getCanonicalTagType(rd);
// Check convertTypeForMemory
llvm::Type *llvmTy = CodeGen::convertTypeForMemory(CGM, qType);
diff --git a/clang/unittests/Index/IndexTests.cpp b/clang/unittests/Index/IndexTests.cpp
index 05ce448237fdf..6df4b577d98a0 100644
--- a/clang/unittests/Index/IndexTests.cpp
+++ b/clang/unittests/Index/IndexTests.cpp
@@ -347,7 +347,7 @@ TEST(IndexTest, Constructors) {
WrittenAt(Position(4, 8)))));
}
-TEST(IndexTest, InjecatedNameClass) {
+TEST(IndexTest, InjectedNameClass) {
std::string Code = R"cpp(
template <typename T>
class Foo {
diff --git a/clang/unittests/Sema/HeuristicResolverTest.cpp b/clang/unittests/Sema/HeuristicResolverTest.cpp
index ee434f7a1d43a..7df25e01e66d4 100644
--- a/clang/unittests/Sema/HeuristicResolverTest.cpp
+++ b/clang/unittests/Sema/HeuristicResolverTest.cpp
@@ -29,7 +29,7 @@ MATCHER_P2(matchAdapter, MatcherForElement, MatchFunction, "matchAdapter") {
template <typename InputNode>
using ResolveFnT = std::function<std::vector<const NamedDecl *>(
- const HeuristicResolver *, const InputNode *)>;
+ const HeuristicResolver *, InputNode)>;
// Test heuristic resolution on `Code` using the resolution procedure
// `ResolveFn`, which takes a `HeuristicResolver` and an input AST node of type
@@ -37,8 +37,9 @@ using ResolveFnT = std::function<std::vector<const NamedDecl *>(
// `InputMatcher` should be an AST matcher that matches a single node to pass as
// input to `ResolveFn`, bound to the ID "input". `OutputMatchers` should be AST
// matchers that each match a single node, bound to the ID "output".
-template <typename InputNode, typename InputMatcher, typename... OutputMatchers>
-void expectResolution(llvm::StringRef Code, ResolveFnT<InputNode> ResolveFn,
+template <typename InputNode, typename ParamT, typename InputMatcher,
+ typename... OutputMatchers>
+void expectResolution(llvm::StringRef Code, ResolveFnT<ParamT> ResolveFn,
const InputMatcher &IM, const OutputMatchers &...OMS) {
auto TU = tooling::buildASTFromCodeWithArgs(Code, {"-std=c++20"});
auto &Ctx = TU->getASTContext();
@@ -59,7 +60,11 @@ void expectResolution(llvm::StringRef Code, ResolveFnT<InputNode> ResolveFn,
};
HeuristicResolver H(Ctx);
- auto Results = ResolveFn(&H, Input);
+ std::vector<const NamedDecl *> Results;
+ if constexpr (std::is_pointer_v<ParamT>)
+ Results = ResolveFn(&H, Input);
+ else
+ Results = ResolveFn(&H, *Input);
EXPECT_THAT(Results, ElementsAre(matchAdapter(OMS, OutputNodeMatches)...));
}
@@ -71,8 +76,8 @@ void expectResolution(llvm::StringRef Code,
HeuristicResolver::*ResolveFn)(const InputNode *)
const,
const InputMatcher &IM, const OutputMatchers &...OMS) {
- expectResolution(Code, ResolveFnT<InputNode>(std::mem_fn(ResolveFn)), IM,
- OMS...);
+ expectResolution<InputNode>(
+ Code, ResolveFnT<const InputNode *>(std::mem_fn(ResolveFn)), IM, OMS...);
}
TEST(HeuristicResolver, MemberExpr) {
@@ -643,15 +648,16 @@ TEST(HeuristicResolver, NestedNameSpecifier) {
// expected by expectResolution() (returning a vector of decls).
ResolveFnT<NestedNameSpecifier> ResolveFn =
[](const HeuristicResolver *H,
- const NestedNameSpecifier *NNS) -> std::vector<const NamedDecl *> {
+ NestedNameSpecifier NNS) -> std::vector<const NamedDecl *> {
return {H->resolveNestedNameSpecifierToType(NNS)->getAsCXXRecordDecl()};
};
- expectResolution(Code, ResolveFn,
- nestedNameSpecifier(hasPrefix(specifiesType(hasDeclaration(
- classTemplateDecl(hasName("A"))))))
- .bind("input"),
- classTemplateDecl(has(cxxRecordDecl(
- has(cxxRecordDecl(hasName("B")).bind("output"))))));
+ expectResolution<NestedNameSpecifier>(
+ Code, ResolveFn,
+ nestedNameSpecifier(hasPrefix(specifiesType(
+ hasDeclaration(classTemplateDecl(hasName("A"))))))
+ .bind("input"),
+ classTemplateDecl(
+ has(cxxRecordDecl(has(cxxRecordDecl(hasName("B")).bind("output"))))));
}
TEST(HeuristicResolver, TemplateSpecializationType) {
diff --git a/clang/unittests/StaticAnalyzer/SValTest.cpp b/clang/unittests/StaticAnalyzer/SValTest.cpp
index d8897b0f2183d..a5781518c23d9 100644
--- a/clang/unittests/StaticAnalyzer/SValTest.cpp
+++ b/clang/unittests/StaticAnalyzer/SValTest.cpp
@@ -301,13 +301,13 @@ void foo(int x) {
ASSERT_FALSE(B.getType(Context).isNull());
const auto *BRecordType = dyn_cast<RecordType>(B.getType(Context));
ASSERT_NE(BRecordType, nullptr);
- EXPECT_EQ("TestStruct", BRecordType->getDecl()->getName());
+ EXPECT_EQ("TestStruct", BRecordType->getOriginalDecl()->getName());
SVal C = getByName("c");
ASSERT_FALSE(C.getType(Context).isNull());
const auto *CRecordType = dyn_cast<RecordType>(C.getType(Context));
ASSERT_NE(CRecordType, nullptr);
- EXPECT_EQ("TestUnion", CRecordType->getDecl()->getName());
+ EXPECT_EQ("TestUnion", CRecordType->getOriginalDecl()->getName());
auto D = getByName("d").getAs<nonloc::CompoundVal>();
ASSERT_TRUE(D.has_value());
@@ -319,12 +319,9 @@ void foo(int x) {
ASSERT_TRUE(LD.has_value());
auto LDT = LD->getType(Context);
ASSERT_FALSE(LDT.isNull());
- const auto *DElaboratedType = dyn_cast<ElaboratedType>(LDT);
- ASSERT_NE(DElaboratedType, nullptr);
- const auto *DRecordType =
- dyn_cast<RecordType>(DElaboratedType->getNamedType());
+ const auto *DRecordType = dyn_cast<RecordType>(LDT);
ASSERT_NE(DRecordType, nullptr);
- EXPECT_EQ("TestStruct", DRecordType->getDecl()->getName());
+ EXPECT_EQ("TestStruct", DRecordType->getOriginalDecl()->getName());
}
SVAL_TEST(GetStringType, R"(
@@ -353,7 +350,7 @@ void TestClass::foo() {
ASSERT_NE(APtrTy, nullptr);
const auto *ARecordType = dyn_cast<RecordType>(APtrTy->getPointeeType());
ASSERT_NE(ARecordType, nullptr);
- EXPECT_EQ("TestClass", ARecordType->getDecl()->getName());
+ EXPECT_EQ("TestClass", ARecordType->getOriginalDecl()->getName());
}
SVAL_TEST(GetFunctionPtrType, R"(
diff --git a/clang/unittests/Tooling/LookupTest.cpp b/clang/unittests/Tooling/LookupTest.cpp
index acd1714a26e07..4c49ebe47acb9 100644
--- a/clang/unittests/Tooling/LookupTest.cpp
+++ b/clang/unittests/Tooling/LookupTest.cpp
@@ -193,16 +193,16 @@ TEST(LookupTest, replaceNestedClassName) {
auto replaceTypeLoc = [&](const NamedDecl *ND, SourceLocation Loc,
StringRef ReplacementString) {
return tooling::replaceNestedName(
- nullptr, Loc, Visitor.DeclStack.back()->getDeclContext(), ND,
- ReplacementString);
+ /*Use=*/std::nullopt, Loc, Visitor.DeclStack.back()->getDeclContext(),
+ ND, ReplacementString);
};
Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
// Filter Types by name since there are other `RecordTypeLoc` in the test
// file.
- if (Type.getDecl()->getQualifiedNameAsString() == "a::b::Foo") {
- EXPECT_EQ("x::Bar", replaceTypeLoc(Type.getDecl(), Type.getBeginLoc(),
- "::a::x::Bar"));
+ if (Type.getOriginalDecl()->getQualifiedNameAsString() == "a::b::Foo") {
+ EXPECT_EQ("x::Bar", replaceTypeLoc(Type.getOriginalDecl(),
+ Type.getBeginLoc(), "::a::x::Bar"));
}
};
Visitor.runOver("namespace a { namespace b {\n"
@@ -214,7 +214,7 @@ TEST(LookupTest, replaceNestedClassName) {
// Filter Types by name since there are other `RecordTypeLoc` in the test
// file.
// `a::b::Foo` in using shadow decl is not `TypeLoc`.
- auto *TD = Type.getFoundDecl()->getTargetDecl();
+ auto *TD = Type.getDecl()->getTargetDecl();
if (TD->getQualifiedNameAsString() == "a::b::Foo") {
EXPECT_EQ("Bar", replaceTypeLoc(TD, Type.getBeginLoc(), "::a::x::Bar"));
}
@@ -227,9 +227,9 @@ TEST(LookupTest, replaceNestedClassName) {
// `x::y::Foo` in c.cc [1], it should not make "Foo" at [0] ambiguous because
// it's not visible at [0].
Visitor.OnRecordTypeLoc = [&](RecordTypeLoc Type) {
- if (Type.getDecl()->getQualifiedNameAsString() == "x::y::Old") {
- EXPECT_EQ("Foo",
- replaceTypeLoc(Type.getDecl(), Type.getBeginLoc(), "::x::Foo"));
+ if (Type.getOriginalDecl()->getQualifiedNameAsString() == "x::y::Old") {
+ EXPECT_EQ("Foo", replaceTypeLoc(Type.getOriginalDecl(),
+ Type.getBeginLoc(), "::x::Foo"));
}
};
Visitor.runOver(R"(
diff --git a/clang/unittests/Tooling/QualTypeNamesTest.cpp b/clang/unittests/Tooling/QualTypeNamesTest.cpp
index bcf7d8935f792..1139392983fce 100644
--- a/clang/unittests/Tooling/QualTypeNamesTest.cpp
+++ b/clang/unittests/Tooling/QualTypeNamesTest.cpp
@@ -295,9 +295,9 @@ TEST(QualTypeNameTest, TemplatedClass) {
auto *A2 = *ASpec;
// Their type names follow the records.
- QualType A1RecordTy = Context.getRecordType(A1);
+ CanQualType A1RecordTy = Context.getCanonicalTagType(A1);
EXPECT_EQ(getFullyQualifiedName(A1RecordTy), "A<1>");
- QualType A2RecordTy = Context.getRecordType(A2);
+ CanQualType A2RecordTy = Context.getCanonicalTagType(A2);
EXPECT_EQ(getFullyQualifiedName(A2RecordTy), "A<2U>");
// getTemplateSpecializationType() gives types that print the integral
@@ -305,13 +305,13 @@ TEST(QualTypeNameTest, TemplatedClass) {
TemplateArgument Args1[] = {
{Context, llvm::APSInt::getUnsigned(1u), Context.UnsignedIntTy}};
QualType A1TemplateSpecTy = Context.getTemplateSpecializationType(
- TemplateName(A), Args1, Args1, A1RecordTy);
+ ElaboratedTypeKeyword::None, TemplateName(A), Args1, Args1, A1RecordTy);
EXPECT_EQ(A1TemplateSpecTy.getAsString(), "A<1>");
TemplateArgument Args2[] = {
{Context, llvm::APSInt::getUnsigned(2u), Context.UnsignedIntTy}};
QualType A2TemplateSpecTy = Context.getTemplateSpecializationType(
- TemplateName(A), Args2, Args2, A2RecordTy);
+ ElaboratedTypeKeyword::None, TemplateName(A), Args2, Args2, A2RecordTy);
EXPECT_EQ(A2TemplateSpecTy.getAsString(), "A<2>");
// Find A<1>::B and its specialization B<3>.
@@ -321,21 +321,19 @@ TEST(QualTypeNameTest, TemplatedClass) {
auto A1BSpec = A1B->spec_begin();
ASSERT_NE(A1BSpec, A1B->spec_end());
auto *A1B3 = *A1BSpec;
- QualType A1B3RecordTy = Context.getRecordType(A1B3);
+ CanQualType A1B3RecordTy = Context.getCanonicalTagType(A1B3);
EXPECT_EQ(getFullyQualifiedName(A1B3RecordTy), "A<1>::B<3>");
// Construct A<1>::B<3> and check name.
+ NestedNameSpecifier A1Nested(A1TemplateSpecTy.getTypePtr());
+ TemplateName A1B3Name = Context.getQualifiedTemplateName(
+ A1Nested, /*TemplateKeyword=*/false, TemplateName(A1B));
+
TemplateArgument Args3[] = {
{Context, llvm::APSInt::getUnsigned(3u), Context.UnsignedIntTy}};
QualType A1B3TemplateSpecTy = Context.getTemplateSpecializationType(
- TemplateName(A1B), Args3, Args3, A1B3RecordTy);
- EXPECT_EQ(A1B3TemplateSpecTy.getAsString(), "B<3>");
-
- NestedNameSpecifier *A1Nested = NestedNameSpecifier::Create(
- Context, nullptr, A1TemplateSpecTy.getTypePtr());
- QualType A1B3ElaboratedTy = Context.getElaboratedType(
- ElaboratedTypeKeyword::None, A1Nested, A1B3TemplateSpecTy);
- EXPECT_EQ(A1B3ElaboratedTy.getAsString(), "A<1>::B<3>");
+ ElaboratedTypeKeyword::None, A1B3Name, Args3, Args3, A1B3RecordTy);
+ EXPECT_EQ(A1B3TemplateSpecTy.getAsString(), "A<1>::B<3>");
// Find A<2u>::B and its specialization B<4u>.
auto *A2B =
@@ -344,21 +342,19 @@ TEST(QualTypeNameTest, TemplatedClass) {
auto A2BSpec = A2B->spec_begin();
ASSERT_NE(A2BSpec, A2B->spec_end());
auto *A2B4 = *A2BSpec;
- QualType A2B4RecordTy = Context.getRecordType(A2B4);
+ CanQualType A2B4RecordTy = Context.getCanonicalTagType(A2B4);
EXPECT_EQ(getFullyQualifiedName(A2B4RecordTy), "A<2U>::B<4U>");
// Construct A<2>::B<4> and check name.
+ NestedNameSpecifier A2Nested(A2TemplateSpecTy.getTypePtr());
+ TemplateName A2B4Name = Context.getQualifiedTemplateName(
+ A2Nested, /*TemplateKeyword=*/false, TemplateName(A2B));
+
TemplateArgument Args4[] = {
{Context, llvm::APSInt::getUnsigned(4u), Context.UnsignedIntTy}};
QualType A2B4TemplateSpecTy = Context.getTemplateSpecializationType(
- TemplateName(A2B), Args4, Args4, A2B4RecordTy);
- EXPECT_EQ(A2B4TemplateSpecTy.getAsString(), "B<4>");
-
- NestedNameSpecifier *A2Nested = NestedNameSpecifier::Create(
- Context, nullptr, A2TemplateSpecTy.getTypePtr());
- QualType A2B4ElaboratedTy = Context.getElaboratedType(
- ElaboratedTypeKeyword::None, A2Nested, A2B4TemplateSpecTy);
- EXPECT_EQ(A2B4ElaboratedTy.getAsString(), "A<2>::B<4>");
+ ElaboratedTypeKeyword::None, A2B4Name, Args4, Args4, A2B4RecordTy);
+ EXPECT_EQ(A2B4TemplateSpecTy.getAsString(), "A<2>::B<4>");
}
TEST(QualTypeNameTest, AnonStrucs) {
diff --git a/clang/unittests/Tooling/RangeSelectorTest.cpp b/clang/unittests/Tooling/RangeSelectorTest.cpp
index 12f7a8c5223e7..adf5e74ea3192 100644
--- a/clang/unittests/Tooling/RangeSelectorTest.cpp
+++ b/clang/unittests/Tooling/RangeSelectorTest.cpp
@@ -474,15 +474,15 @@ TEST(RangeSelectorTest, NameOpTypeLoc) {
// Matches declaration of `a`
TestMatch MatchA = matchCode(
Code, varDecl(hasName("a"), hasTypeLoc(typeLoc().bind(CtorTy))));
- EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchA), HasValue("Foo"));
+ EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchA), HasValue("ns::Foo"));
// Matches call of Foo(int)
TestMatch MatchB = matchCode(
Code, cxxFunctionalCastExpr(hasTypeLoc(typeLoc().bind(CtorTy))));
- EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchB), HasValue("Foo"));
+ EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchB), HasValue("ns::Foo"));
// Matches call of Foo(int, int)
TestMatch MatchC = matchCode(
Code, cxxTemporaryObjectExpr(hasTypeLoc(typeLoc().bind(CtorTy))));
- EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchC), HasValue("Foo"));
+ EXPECT_THAT_EXPECTED(select(name(CtorTy), MatchC), HasValue("ns::Foo"));
}
TEST(RangeSelectorTest, NameOpTemplateSpecializationTypeLoc) {
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
index eec628ca39641..7a3566114fbea 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTestTypeLocVisitor.cpp
@@ -22,13 +22,13 @@ class TypeLocVisitor : public ExpectedLocationVisitor {
TEST(RecursiveASTVisitor, VisitsBaseClassDeclarations) {
TypeLocVisitor Visitor;
- Visitor.ExpectMatch("class X", 1, 30);
+ Visitor.ExpectMatch("X", 1, 30);
EXPECT_TRUE(Visitor.runOver("class X {}; class Y : public X {};"));
}
TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfForwardDeclaredClass) {
TypeLocVisitor Visitor;
- Visitor.ExpectMatch("class X", 3, 18);
+ Visitor.ExpectMatch("X", 3, 18);
EXPECT_TRUE(Visitor.runOver(
"class Y;\n"
"class X {};\n"
@@ -37,7 +37,7 @@ TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfForwardDeclaredClass) {
TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersWithIncompleteInnerClass) {
TypeLocVisitor Visitor;
- Visitor.ExpectMatch("class X", 2, 18);
+ Visitor.ExpectMatch("X", 2, 18);
EXPECT_TRUE(Visitor.runOver(
"class X {};\n"
"class Y : public X { class Z; };"));
@@ -45,7 +45,7 @@ TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersWithIncompleteInnerClass) {
TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) {
TypeLocVisitor Visitor;
- Visitor.ExpectMatch("X<Y>", 2, 18, 2);
+ Visitor.ExpectMatch("X<Y>", 2, 18);
EXPECT_TRUE(Visitor.runOver(
"template<typename T> class X {};\n"
"class Y : public X<Y> {};"));
@@ -53,7 +53,7 @@ TEST(RecursiveASTVisitor, VisitsCXXBaseSpecifiersOfSelfReferentialType) {
TEST(RecursiveASTVisitor, VisitsClassTemplateTypeParmDefaultArgument) {
TypeLocVisitor Visitor;
- Visitor.ExpectMatch("class X", 2, 23);
+ Visitor.ExpectMatch("X", 2, 23);
EXPECT_TRUE(Visitor.runOver(
"class X;\n"
"template<typename T = X> class Y;\n"
@@ -62,7 +62,7 @@ TEST(RecursiveASTVisitor, VisitsClassTemplateTypeParmDefaultArgument) {
TEST(RecursiveASTVisitor, VisitsCompoundLiteralType) {
TypeLocVisitor Visitor;
- Visitor.ExpectMatch("struct S", 1, 26);
+ Visitor.ExpectMatch("struct S", 1, 19);
EXPECT_TRUE(Visitor.runOver(
"int f() { return (struct S { int a; }){.a = 0}.a; }",
TypeLocVisitor::Lang_C));
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
index 587a00dd27051..88cebb7c28033 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/MemberPointerTypeLoc.cpp
@@ -24,7 +24,7 @@ class MemberPointerTypeLocVisitor : public ExpectedLocationVisitor {
bool VisitRecordTypeLoc(RecordTypeLoc RTL) override {
if (!RTL)
return true;
- Match(RTL.getDecl()->getName(), RTL.getNameLoc());
+ Match(RTL.getOriginalDecl()->getName(), RTL.getNameLoc());
return true;
}
};
diff --git a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
index ddc663e2b6fd3..4181cd2881054 100644
--- a/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
+++ b/clang/unittests/Tooling/RecursiveASTVisitorTests/NestedNameSpecifiers.cpp
@@ -18,17 +18,20 @@ class NestedNameSpecifiersVisitor : public ExpectedLocationVisitor {
bool VisitRecordTypeLoc(RecordTypeLoc RTL) override {
if (!RTL)
return true;
- Match(RTL.getDecl()->getName(), RTL.getNameLoc());
+ Match(RTL.getOriginalDecl()->getName(), RTL.getNameLoc());
return true;
}
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) override {
- if (!NNS)
- return true;
- if (const NamespaceDecl *ND =
- NNS.getNestedNameSpecifier()->getAsNamespace())
- Match(ND->getName(), NNS.getLocalBeginLoc());
- return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(NNS);
+ bool
+ TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc QualifierLoc) override {
+ NestedNameSpecifier Qualifier = QualifierLoc.getNestedNameSpecifier();
+ if (Qualifier.getKind() == NestedNameSpecifier::Kind::Namespace) {
+ if (const auto *ND = dyn_cast<NamespaceDecl>(
+ Qualifier.getAsNamespaceAndPrefix().Namespace))
+ Match(ND->getName(), QualifierLoc.getLocalBeginLoc());
+ }
+ return ExpectedLocationVisitor::TraverseNestedNameSpecifierLoc(
+ QualifierLoc);
}
};
diff --git a/clang/unittests/Tooling/RefactoringTest.cpp b/clang/unittests/Tooling/RefactoringTest.cpp
index 254d95bc20cb0..250a2630c00cf 100644
--- a/clang/unittests/Tooling/RefactoringTest.cpp
+++ b/clang/unittests/Tooling/RefactoringTest.cpp
@@ -747,8 +747,12 @@ TEST(Replacement, TemplatedFunctionCall) {
class NestedNameSpecifierAVisitor : public TestVisitor {
public:
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNSLoc) override {
- if (NNSLoc.getNestedNameSpecifier()) {
- if (const NamespaceDecl* NS = NNSLoc.getNestedNameSpecifier()->getAsNamespace()) {
+ if (NestedNameSpecifier NNS = NNSLoc.getNestedNameSpecifier();
+ NNS.getKind() == NestedNameSpecifier::Kind::Namespace) {
+ if (const auto *NS =
+ dyn_cast<NamespaceDecl>(NNSLoc.getNestedNameSpecifier()
+ .getAsNamespaceAndPrefix()
+ .Namespace)) {
if (NS->getName() == "a") {
Replace = Replacement(*SM, &NNSLoc, "", Context->getLangOpts());
}
>From 4730e9aa33af212207ceb21fe1f0369d1c7b4776 Mon Sep 17 00:00:00 2001
From: Matheus Izvekov <mizvekov at gmail.com>
Date: Thu, 10 Jul 2025 14:07:34 -0300
Subject: [PATCH 4/4] clang tools extra changes
---
.../ChangeNamespace.cpp | 53 +++-----
clang-tools-extra/clang-doc/Serialize.cpp | 4 +-
.../find-all-symbols/FindAllSymbols.cpp | 3 +-
.../ClangTidyDiagnosticConsumer.cpp | 3 +-
.../CrtpConstructorAccessibilityCheck.cpp | 6 +-
.../EasilySwappableParametersCheck.cpp | 14 +-
.../ForwardDeclarationNamespaceCheck.cpp | 11 +-
.../ForwardingReferenceOverloadCheck.cpp | 18 +--
.../bugprone/IncorrectEnableIfCheck.cpp | 19 ++-
.../bugprone/MoveForwardingReferenceCheck.cpp | 17 ++-
.../bugprone/SizeofExpressionCheck.cpp | 10 +-
.../NoSuspendWithLockCheck.cpp | 4 +-
.../ProTypeMemberInitCheck.cpp | 2 +-
.../cppcoreguidelines/SlicingCheck.cpp | 2 +-
.../fuchsia/MultipleInheritanceCheck.cpp | 8 +-
.../google/AvoidCStyleCastsCheck.cpp | 31 ++++-
.../google/ExplicitConstructorCheck.cpp | 2 +-
.../google/UpgradeGoogletestCaseCheck.cpp | 9 +-
.../clang-tidy/misc/ConstCorrectnessCheck.cpp | 11 +-
.../clang-tidy/misc/MisplacedConstCheck.cpp | 14 +-
.../misc/RedundantExpressionCheck.cpp | 13 +-
.../clang-tidy/misc/UnusedAliasDeclsCheck.cpp | 9 +-
.../clang-tidy/misc/UnusedUsingDeclsCheck.cpp | 8 +-
.../DeprecatedIosBaseAliasesCheck.cpp | 11 +-
.../clang-tidy/modernize/PassByValueCheck.cpp | 3 +-
.../modernize/ReplaceAutoPtrCheck.cpp | 15 +--
.../clang-tidy/modernize/TypeTraitsCheck.cpp | 63 ++++-----
.../clang-tidy/modernize/UseAutoCheck.cpp | 18 ++-
.../modernize/UseConstraintsCheck.cpp | 7 +-
.../clang-tidy/modernize/UseEmplaceCheck.cpp | 53 ++++----
.../modernize/UseScopedLockCheck.cpp | 43 +++---
.../modernize/UseTrailingReturnTypeCheck.cpp | 93 +++++++------
.../modernize/UseTransparentFunctorsCheck.cpp | 16 +--
.../performance/NoAutomaticMoveCheck.cpp | 8 +-
.../portability/StdAllocatorConstCheck.cpp | 11 +-
.../StaticAccessedThroughInstanceCheck.cpp | 26 ++--
.../SuspiciousCallArgumentCheck.cpp | 4 +-
.../readability/UseStdMinMaxCheck.cpp | 6 +-
.../utils/ExceptionSpecAnalyzer.cpp | 3 +-
.../utils/FormatStringConverter.cpp | 5 +-
.../clang-tidy/utils/Matchers.cpp | 2 +-
.../utils/RenamerClangTidyCheck.cpp | 36 ++---
.../clang-tidy/utils/TypeTraits.cpp | 3 +-
clang-tools-extra/clangd/AST.cpp | 92 ++++++++-----
clang-tools-extra/clangd/AST.h | 3 +-
clang-tools-extra/clangd/CodeComplete.cpp | 19 +--
clang-tools-extra/clangd/DumpAST.cpp | 42 +++---
clang-tools-extra/clangd/FindTarget.cpp | 126 +++++++-----------
clang-tools-extra/clangd/Hover.cpp | 20 +--
clang-tools-extra/clangd/IncludeFixer.cpp | 23 ++--
clang-tools-extra/clangd/InlayHints.cpp | 28 ++--
clang-tools-extra/clangd/Quality.cpp | 2 +-
clang-tools-extra/clangd/Selection.cpp | 17 ++-
.../clangd/SemanticHighlighting.cpp | 17 +--
clang-tools-extra/clangd/XRefs.cpp | 13 +-
.../clangd/refactor/tweaks/AddUsing.cpp | 123 +++++++++++------
.../refactor/tweaks/ExtractFunction.cpp | 7 +-
.../clangd/refactor/tweaks/PopulateSwitch.cpp | 2 +-
.../clangd/unittests/ASTTests.cpp | 7 +-
.../clangd/unittests/DumpASTTests.cpp | 15 +--
.../clangd/unittests/FindTargetTests.cpp | 4 +-
.../clangd/unittests/HoverTests.cpp | 10 +-
.../clangd/unittests/InlayHintTests.cpp | 9 +-
.../clangd/unittests/QualityTests.cpp | 14 +-
.../clangd/unittests/SelectionTests.cpp | 4 +-
.../include-cleaner/lib/WalkAST.cpp | 29 ++--
.../bugprone/copy-constructor-init.cpp | 1 -
.../unused-local-non-trivial-variable.cpp | 6 +-
.../portability/std-allocator-const.cpp | 22 +--
69 files changed, 659 insertions(+), 693 deletions(-)
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 ((LPtrTy == RPtrTy) && (LPtrTy == SizeofArgTy)) {
+ if (Ctx.hasSameType(LPtrTy, RPtrTy) &&
+ Ctx.hasSameType(LPtrTy, SizeofArgTy)) {
diag(SizeOfExpr->getBeginLoc(), "suspicious usage of 'sizeof(...)' in "
"pointer arithmetic")
<< SizeOfExpr->getSourceRange() << E->getOperatorLoc()
@@ -477,7 +478,8 @@ void SizeofExpressionCheck::check(const MatchFinder::MatchResult &Result) {
const auto *SizeOfExpr =
Result.Nodes.getNodeAs<UnaryExprOrTypeTraitExpr>("sizeof-ptr-div-expr");
- if ((LPtrTy == RPtrTy) && (LPtrTy == SizeofArgTy)) {
+ if (Ctx.hasSameType(LPtrTy, RPtrTy) &&
+ Ctx.hasSameType(LPtrTy, SizeofArgTy)) {
diag(SizeOfExpr->getBeginLoc(), "suspicious usage of 'sizeof(...)' in "
"pointer arithmetic")
<< SizeOfExpr->getSourceRange() << E->getOperatorLoc()
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
index ca293178c78b4..29470b1f725fb 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/NoSuspendWithLockCheck.cpp
@@ -23,9 +23,9 @@ void NoSuspendWithLockCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
}
void NoSuspendWithLockCheck::registerMatchers(MatchFinder *Finder) {
- auto LockType = elaboratedType(namesType(templateSpecializationType(
+ auto LockType = templateSpecializationType(
hasDeclaration(namedDecl(matchers::matchesAnyListedName(
- utils::options::parseStringList(LockGuards)))))));
+ utils::options::parseStringList(LockGuards)))));
StatementMatcher Lock =
declStmt(has(varDecl(hasType(LockType)).bind("lock-decl")))
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
index b413b12cd37ab..40607597297b5 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/ProTypeMemberInitCheck.cpp
@@ -190,7 +190,7 @@ struct InitializerInsertion {
// Convenience utility to get a RecordDecl from a QualType.
const RecordDecl *getCanonicalRecordDecl(const QualType &Type) {
if (const auto *RT = Type.getCanonicalType()->getAs<RecordType>())
- return RT->getDecl();
+ return RT->getOriginalDecl();
return nullptr;
}
diff --git a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
index 76754394de760..40fd15c08f0a1 100644
--- a/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
+++ b/clang-tools-extra/clang-tidy/cppcoreguidelines/SlicingCheck.cpp
@@ -92,7 +92,7 @@ void SlicingCheck::diagnoseSlicedOverriddenMethods(
for (const auto &Base : DerivedDecl.bases()) {
if (const auto *BaseRecordType = Base.getType()->getAs<RecordType>()) {
if (const auto *BaseRecord = cast_or_null<CXXRecordDecl>(
- BaseRecordType->getDecl()->getDefinition()))
+ BaseRecordType->getOriginalDecl()->getDefinition()))
diagnoseSlicedOverriddenMethods(Call, *BaseRecord, BaseDecl);
}
}
diff --git a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
index 80ff97a762134..0302a5ad4957c 100644
--- a/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/fuchsia/MultipleInheritanceCheck.cpp
@@ -74,7 +74,7 @@ bool MultipleInheritanceCheck::isInterface(const CXXRecordDecl *Node) {
const auto *Ty = I.getType()->getAs<RecordType>();
if (!Ty)
continue;
- const RecordDecl *D = Ty->getDecl()->getDefinition();
+ const RecordDecl *D = Ty->getOriginalDecl()->getDefinition();
if (!D)
continue;
const auto *Base = cast<CXXRecordDecl>(D);
@@ -106,7 +106,8 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Ty = I.getType()->getAs<RecordType>();
if (!Ty)
continue;
- const auto *Base = cast<CXXRecordDecl>(Ty->getDecl()->getDefinition());
+ const auto *Base =
+ cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
if (!isInterface(Base))
NumConcrete++;
}
@@ -117,7 +118,8 @@ void MultipleInheritanceCheck::check(const MatchFinder::MatchResult &Result) {
const auto *Ty = V.getType()->getAs<RecordType>();
if (!Ty)
continue;
- const auto *Base = cast<CXXRecordDecl>(Ty->getDecl()->getDefinition());
+ const auto *Base =
+ cast<CXXRecordDecl>(Ty->getOriginalDecl()->getDefinition());
if (!isInterface(Base))
NumConcrete++;
}
diff --git a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp b/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp
index e076b39b5d978..14e11eb0bc697 100644
--- a/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/AvoidCStyleCastsCheck.cpp
@@ -89,6 +89,30 @@ static StringRef getDestTypeString(const SourceManager &SM,
SM, LangOpts);
}
+static bool sameTypeAsWritten(QualType X, QualType Y) {
+ if (X.getCanonicalType() != Y.getCanonicalType())
+ return false;
+
+ auto TC = X->getTypeClass();
+ if (TC != Y->getTypeClass())
+ return false;
+
+ switch (TC) {
+ case Type::Typedef:
+ return declaresSameEntity(cast<TypedefType>(X)->getDecl(),
+ cast<TypedefType>(Y)->getDecl());
+ case Type::Pointer:
+ return sameTypeAsWritten(cast<PointerType>(X)->getPointeeType(),
+ cast<PointerType>(Y)->getPointeeType());
+ case Type::RValueReference:
+ case Type::LValueReference:
+ return sameTypeAsWritten(cast<ReferenceType>(X)->getPointeeType(),
+ cast<ReferenceType>(Y)->getPointeeType());
+ default:
+ return true;
+ }
+}
+
void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
const auto *CastExpr = Result.Nodes.getNodeAs<ExplicitCastExpr>("cast");
@@ -128,12 +152,7 @@ void AvoidCStyleCastsCheck::check(const MatchFinder::MatchResult &Result) {
// case of overloaded functions, so detection of redundant casts is trickier
// in this case. Don't emit "redundant cast" warnings for function
// pointer/reference types.
- QualType Src = SourceTypeAsWritten, Dst = DestTypeAsWritten;
- if (const auto *ElTy = dyn_cast<ElaboratedType>(Src))
- Src = ElTy->getNamedType();
- if (const auto *ElTy = dyn_cast<ElaboratedType>(Dst))
- Dst = ElTy->getNamedType();
- if (Src == Dst) {
+ if (sameTypeAsWritten(SourceTypeAsWritten, DestTypeAsWritten)) {
diag(CastExpr->getBeginLoc(), "redundant cast to the same type")
<< FixItHint::CreateRemoval(ReplaceRange);
return;
diff --git a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
index 3deea0620514b..68233ec6bd441 100644
--- a/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/ExplicitConstructorCheck.cpp
@@ -72,7 +72,7 @@ static bool isStdInitializerList(QualType Type) {
}
if (const auto *RT = Type->getAs<RecordType>()) {
if (const auto *Specialization =
- dyn_cast<ClassTemplateSpecializationDecl>(RT->getDecl()))
+ dyn_cast<ClassTemplateSpecializationDecl>(RT->getOriginalDecl()))
return declIsStdInitializerList(Specialization->getSpecializedTemplate());
}
return false;
diff --git a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
index 805dcaf3ce402..274b8afa98bd6 100644
--- a/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
+++ b/clang-tools-extra/clang-tidy/google/UpgradeGoogletestCaseCheck.cpp
@@ -257,8 +257,13 @@ getAliasNameRange(const MatchFinder::MatchResult &Result) {
return CharSourceRange::getTokenRange(
Using->getNameInfo().getSourceRange());
}
- return CharSourceRange::getTokenRange(
- Result.Nodes.getNodeAs<TypeLoc>("typeloc")->getSourceRange());
+ TypeLoc TL = *Result.Nodes.getNodeAs<TypeLoc>("typeloc");
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
+
+ if (auto TTL = TL.getAs<TypedefTypeLoc>())
+ return CharSourceRange::getTokenRange(TTL.getNameLoc());
+ return CharSourceRange::getTokenRange(TL.castAs<UsingTypeLoc>().getNameLoc());
}
void UpgradeGoogletestCaseCheck::check(const MatchFinder::MatchResult &Result) {
diff --git a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
index 697398a54332d..b32507d66cbac 100644
--- a/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/ConstCorrectnessCheck.cpp
@@ -98,11 +98,12 @@ void ConstCorrectnessCheck::registerMatchers(MatchFinder *Finder) {
hasType(referenceType(pointee(hasCanonicalType(templateTypeParmType())))),
hasType(referenceType(pointee(substTemplateTypeParmType()))));
- const auto AllowedType = hasType(qualType(anyOf(
- hasDeclaration(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
- references(namedDecl(matchers::matchesAnyListedName(AllowedTypes))),
- pointerType(pointee(hasDeclaration(
- namedDecl(matchers::matchesAnyListedName(AllowedTypes))))))));
+ auto AllowedTypeDecl = namedDecl(
+ anyOf(matchers::matchesAnyListedName(AllowedTypes), usingShadowDecl()));
+
+ const auto AllowedType = hasType(qualType(
+ anyOf(hasDeclaration(AllowedTypeDecl), references(AllowedTypeDecl),
+ pointerType(pointee(hasDeclaration(AllowedTypeDecl))))));
const auto AutoTemplateType = varDecl(
anyOf(hasType(autoType()), hasType(referenceType(pointee(autoType()))),
diff --git a/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp b/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp
index 0cdd48c13b2a6..bb64a5618620c 100644
--- a/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/MisplacedConstCheck.cpp
@@ -19,13 +19,13 @@ void MisplacedConstCheck::registerMatchers(MatchFinder *Finder) {
pointee(anyOf(isConstQualified(), ignoringParens(functionType()))))));
Finder->addMatcher(
- valueDecl(hasType(qualType(
- isConstQualified(),
- elaboratedType(namesType(typedefType(hasDeclaration(
- anyOf(typedefDecl(NonConstAndNonFunctionPointerType)
- .bind("typedef"),
- typeAliasDecl(NonConstAndNonFunctionPointerType)
- .bind("typeAlias")))))))))
+ valueDecl(
+ hasType(qualType(isConstQualified(),
+ typedefType(hasDeclaration(anyOf(
+ typedefDecl(NonConstAndNonFunctionPointerType)
+ .bind("typedef"),
+ typeAliasDecl(NonConstAndNonFunctionPointerType)
+ .bind("typeAlias")))))))
.bind("decl"),
this);
}
diff --git a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
index cf81da816964f..9fd0842d3ae4f 100644
--- a/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/RedundantExpressionCheck.cpp
@@ -45,14 +45,6 @@ static bool incrementWithoutOverflow(const APSInt &Value, APSInt &Result) {
return Value < Result;
}
-static bool areEquivalentNameSpecifier(const NestedNameSpecifier *Left,
- const NestedNameSpecifier *Right) {
- llvm::FoldingSetNodeID LeftID, RightID;
- Left->Profile(LeftID);
- Right->Profile(RightID);
- return LeftID == RightID;
-}
-
static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
if (!Left || !Right)
return !Left && !Right;
@@ -104,9 +96,8 @@ static bool areEquivalentExpr(const Expr *Left, const Expr *Right) {
if (cast<DependentScopeDeclRefExpr>(Left)->getDeclName() !=
cast<DependentScopeDeclRefExpr>(Right)->getDeclName())
return false;
- return areEquivalentNameSpecifier(
- cast<DependentScopeDeclRefExpr>(Left)->getQualifier(),
- cast<DependentScopeDeclRefExpr>(Right)->getQualifier());
+ return cast<DependentScopeDeclRefExpr>(Left)->getQualifier() ==
+ cast<DependentScopeDeclRefExpr>(Right)->getQualifier();
case Stmt::DeclRefExprClass:
return cast<DeclRefExpr>(Left)->getDecl() ==
cast<DeclRefExpr>(Right)->getDecl();
diff --git a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
index 2dfaca19a8981..4fa679aa8dd88 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnusedAliasDeclsCheck.cpp
@@ -35,11 +35,12 @@ void UnusedAliasDeclsCheck::check(const MatchFinder::MatchResult &Result) {
}
if (const auto *NestedName =
- Result.Nodes.getNodeAs<NestedNameSpecifier>("nns")) {
- if (const auto *AliasDecl = NestedName->getAsNamespaceAlias()) {
+ Result.Nodes.getNodeAs<NestedNameSpecifier>("nns");
+ NestedName &&
+ NestedName->getKind() == NestedNameSpecifier::Kind::Namespace)
+ if (const auto *AliasDecl = dyn_cast<NamespaceAliasDecl>(
+ NestedName->getAsNamespaceAndPrefix().Namespace))
FoundDecls[AliasDecl] = CharSourceRange();
- }
- }
}
void UnusedAliasDeclsCheck::onEndOfTranslationUnit() {
diff --git a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
index d5c5fa3364d63..8211a0ec6a5e1 100644
--- a/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/misc/UnusedUsingDeclsCheck.cpp
@@ -71,11 +71,7 @@ void UnusedUsingDeclsCheck::registerMatchers(MatchFinder *Finder) {
templateArgument().bind("used")))),
this);
Finder->addMatcher(userDefinedLiteral().bind("used"), this);
- Finder->addMatcher(
- loc(elaboratedType(unless(hasQualifier(nestedNameSpecifier())),
- hasUnqualifiedDesugaredType(
- type(asTagDecl(tagDecl().bind("used")))))),
- this);
+ Finder->addMatcher(loc(asTagDecl(tagDecl().bind("used"))), this);
// Cases where we can identify the UsingShadowDecl directly, rather than
// just its target.
// FIXME: cover more cases in this way, as the AST supports it.
@@ -136,7 +132,7 @@ void UnusedUsingDeclsCheck::check(const MatchFinder::MatchResult &Result) {
}
if (const auto *ECD = dyn_cast<EnumConstantDecl>(Used)) {
if (const auto *ET = ECD->getType()->getAs<EnumType>())
- removeFromFoundDecls(ET->getDecl());
+ removeFromFoundDecls(ET->getOriginalDecl());
}
};
// We rely on the fact that the clang AST is walked in order, usages are only
diff --git a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
index f22f48d831608..2aca61021166d 100644
--- a/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/DeprecatedIosBaseAliasesCheck.cpp
@@ -29,8 +29,7 @@ static std::optional<const char *> getReplacementType(StringRef Type) {
void DeprecatedIosBaseAliasesCheck::registerMatchers(MatchFinder *Finder) {
auto IoStateDecl = typedefDecl(hasAnyName(DeprecatedTypes)).bind("TypeDecl");
- auto IoStateType =
- qualType(hasDeclaration(IoStateDecl), unless(elaboratedType()));
+ auto IoStateType = typedefType(hasDeclaration(IoStateDecl));
Finder->addMatcher(typeLoc(loc(IoStateType)).bind("TypeLoc"), this);
}
@@ -43,12 +42,14 @@ void DeprecatedIosBaseAliasesCheck::check(
StringRef TypeName = Typedef->getName();
auto Replacement = getReplacementType(TypeName);
- const auto *TL = Result.Nodes.getNodeAs<TypeLoc>("TypeLoc");
- SourceLocation IoStateLoc = TL->getBeginLoc();
+ TypeLoc TL = *Result.Nodes.getNodeAs<TypeLoc>("TypeLoc");
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
+ SourceLocation IoStateLoc = TL.castAs<TypedefTypeLoc>().getNameLoc();
// Do not generate fixits for matches depending on template arguments and
// macro expansions.
- bool Fix = Replacement && !TL->getType()->isDependentType();
+ bool Fix = Replacement && !TL.getType()->isDependentType();
if (IoStateLoc.isMacroID()) {
IoStateLoc = SM.getSpellingLoc(IoStateLoc);
Fix = false;
diff --git a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
index 35f90fb8da15b..d4759c2e249a7 100644
--- a/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/PassByValueCheck.cpp
@@ -46,8 +46,7 @@ AST_MATCHER(CXXRecordDecl, isMoveConstructible) {
static TypeMatcher notTemplateSpecConstRefType() {
return lValueReferenceType(
- pointee(unless(elaboratedType(namesType(templateSpecializationType()))),
- isConstQualified()));
+ pointee(unless(templateSpecializationType()), isConstQualified()));
}
static TypeMatcher nonConstValueType() {
diff --git a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
index 1ad31d315dc2a..f2142b810a126 100644
--- a/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/ReplaceAutoPtrCheck.cpp
@@ -48,7 +48,7 @@ void ReplaceAutoPtrCheck::storeOptions(ClangTidyOptions::OptionMap &Opts) {
void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
auto AutoPtrDecl = recordDecl(hasName("auto_ptr"), isInStdNamespace());
- auto AutoPtrType = qualType(hasDeclaration(AutoPtrDecl));
+ auto AutoPtrType = hasCanonicalType(recordType(hasDeclaration(AutoPtrDecl)));
// std::auto_ptr<int> a;
// ^~~~~~~~~~~~~
@@ -58,11 +58,7 @@ void ReplaceAutoPtrCheck::registerMatchers(MatchFinder *Finder) {
//
// std::auto_ptr<int> fn(std::auto_ptr<int>);
// ^~~~~~~~~~~~~ ^~~~~~~~~~~~~
- Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType,
- // Skip elaboratedType() as the named
- // type will match soon thereafter.
- unless(elaboratedType()))))
- .bind(AutoPtrTokenId),
+ Finder->addMatcher(typeLoc(loc(qualType(AutoPtrType))).bind(AutoPtrTokenId),
this);
// using std::auto_ptr;
@@ -118,10 +114,13 @@ void ReplaceAutoPtrCheck::check(const MatchFinder::MatchResult &Result) {
}
SourceLocation AutoPtrLoc;
- if (const auto *TL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
+ if (const auto *PTL = Result.Nodes.getNodeAs<TypeLoc>(AutoPtrTokenId)) {
+ auto TL = *PTL;
+ if (auto QTL = TL.getAs<QualifiedTypeLoc>())
+ TL = QTL.getUnqualifiedLoc();
// std::auto_ptr<int> i;
// ^
- if (auto Loc = TL->getAs<TemplateSpecializationTypeLoc>())
+ if (auto Loc = TL.getAs<TemplateSpecializationTypeLoc>())
AutoPtrLoc = Loc.getTemplateNameLoc();
} else if (const auto *D =
Result.Nodes.getNodeAs<UsingDecl>(AutoPtrTokenId)) {
diff --git a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
index c0766395ec5cc..34ce10519595c 100644
--- a/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/TypeTraitsCheck.cpp
@@ -140,19 +140,6 @@ static DeclarationName getName(const DeclRefExpr &D) {
return D.getDecl()->getDeclName();
}
-static bool isNamedType(const ElaboratedTypeLoc &ETL) {
- if (const auto *TFT =
- ETL.getNamedTypeLoc().getTypePtr()->getAs<TypedefType>()) {
- const TypedefNameDecl *Decl = TFT->getDecl();
- return Decl->getDeclName().isIdentifier() && Decl->getName() == "type";
- }
- return false;
-}
-
-static bool isNamedType(const DependentNameTypeLoc &DTL) {
- return DTL.getTypePtr()->getIdentifier()->getName() == "type";
-}
-
namespace {
AST_POLYMORPHIC_MATCHER(isValue, AST_POLYMORPHIC_SUPPORTED_TYPES(
DeclRefExpr, DependentScopeDeclRefExpr)) {
@@ -160,10 +147,14 @@ AST_POLYMORPHIC_MATCHER(isValue, AST_POLYMORPHIC_SUPPORTED_TYPES(
return Ident && Ident->isStr("value");
}
-AST_POLYMORPHIC_MATCHER(isType,
- AST_POLYMORPHIC_SUPPORTED_TYPES(ElaboratedTypeLoc,
- DependentNameTypeLoc)) {
- return Node.getBeginLoc().isValid() && isNamedType(Node);
+AST_MATCHER(TypeLoc, isType) {
+ if (auto TL = Node.getAs<TypedefTypeLoc>()) {
+ const auto *TD = TL.getDecl();
+ return TD->getDeclName().isIdentifier() && TD->getName() == "type";
+ }
+ if (auto TL = Node.getAs<DependentNameTypeLoc>())
+ return TL.getTypePtr()->getIdentifier()->getName() == "type";
+ return false;
}
} // namespace
@@ -186,10 +177,7 @@ void TypeTraitsCheck::registerMatchers(MatchFinder *Finder) {
.bind(Bind),
this);
}
- Finder->addMatcher(mapAnyOf(elaboratedTypeLoc, dependentNameTypeLoc)
- .with(isType())
- .bind(Bind),
- this);
+ Finder->addMatcher(typeLoc(isType()).bind(Bind), this);
}
static bool isNamedDeclInStdTraitsSet(const NamedDecl *ND,
@@ -198,14 +186,11 @@ static bool isNamedDeclInStdTraitsSet(const NamedDecl *ND,
Set.contains(ND->getName());
}
-static bool checkTemplatedDecl(const NestedNameSpecifier *NNS,
+static bool checkTemplatedDecl(NestedNameSpecifier NNS,
const llvm::StringSet<> &Set) {
- if (!NNS)
+ if (NNS.getKind() != NestedNameSpecifier::Kind::Type)
return false;
- const Type *NNST = NNS->getAsType();
- if (!NNST)
- return false;
- const auto *TST = NNST->getAs<TemplateSpecializationType>();
+ const auto *TST = NNS.getAsType()->getAs<TemplateSpecializationType>();
if (!TST)
return false;
if (const TemplateDecl *TD = TST->getTemplateName().getAsTemplateDecl()) {
@@ -222,8 +207,8 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) {
auto EmitValueWarning = [this, &Result](const NestedNameSpecifierLoc &QualLoc,
SourceLocation EndLoc) {
SourceLocation TemplateNameEndLoc;
- if (auto TSTL = QualLoc.getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
- !TSTL.isNull())
+ if (auto TSTL =
+ QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
TemplateNameEndLoc = Lexer::getLocForEndOfToken(
TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
Result.Context->getLangOpts());
@@ -246,8 +231,8 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) {
SourceLocation EndLoc,
SourceLocation TypenameLoc) {
SourceLocation TemplateNameEndLoc;
- if (auto TSTL = QualLoc.getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
- !TSTL.isNull())
+ if (auto TSTL =
+ QualLoc.getAsTypeLoc().getAs<TemplateSpecializationTypeLoc>())
TemplateNameEndLoc = Lexer::getLocForEndOfToken(
TSTL.getTemplateNameLoc(), 0, *Result.SourceManager,
Result.Context->getLangOpts());
@@ -273,23 +258,21 @@ void TypeTraitsCheck::check(const MatchFinder::MatchResult &Result) {
if (!DRE->hasQualifier())
return;
if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
- DRE->getQualifier()->getAsRecordDecl())) {
+ DRE->getQualifier().getAsRecordDecl())) {
if (isNamedDeclInStdTraitsSet(CTSD, ValueTraits))
EmitValueWarning(DRE->getQualifierLoc(), DRE->getEndLoc());
}
return;
}
- if (const auto *ETL = Result.Nodes.getNodeAs<ElaboratedTypeLoc>(Bind)) {
- const NestedNameSpecifierLoc QualLoc = ETL->getQualifierLoc();
- const auto *NNS = QualLoc.getNestedNameSpecifier();
- if (!NNS)
- return;
+ if (const auto *TL = Result.Nodes.getNodeAs<TypedefTypeLoc>(Bind)) {
+ const NestedNameSpecifierLoc QualLoc = TL->getQualifierLoc();
+ NestedNameSpecifier NNS = QualLoc.getNestedNameSpecifier();
if (const auto *CTSD = dyn_cast_if_present<ClassTemplateSpecializationDecl>(
- NNS->getAsRecordDecl())) {
+ NNS.getAsRecordDecl())) {
if (isNamedDeclInStdTraitsSet(CTSD, TypeTraits))
- EmitTypeWarning(ETL->getQualifierLoc(), ETL->getEndLoc(),
- ETL->getElaboratedKeywordLoc());
+ EmitTypeWarning(TL->getQualifierLoc(), TL->getEndLoc(),
+ TL->getElaboratedKeywordLoc());
}
return;
}
diff --git a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
index f4b63087b7234..b601620633cee 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseAutoCheck.cpp
@@ -186,16 +186,14 @@ TypeMatcher nestedIterator() {
/// declarations and which name standard iterators for standard containers.
TypeMatcher iteratorFromUsingDeclaration() {
auto HasIteratorDecl = hasDeclaration(namedDecl(hasStdIteratorName()));
- // Types resulting from using declarations are represented by elaboratedType.
- return elaboratedType(
- // Unwrap the nested name specifier to test for one of the standard
- // containers.
- hasQualifier(specifiesType(templateSpecializationType(hasDeclaration(
- namedDecl(hasStdContainerName(), isInStdNamespace()))))),
- // the named type is what comes after the final '::' in the type. It
- // should name one of the standard iterator names.
- namesType(
- anyOf(typedefType(HasIteratorDecl), recordType(HasIteratorDecl))));
+ // Unwrap the nested name specifier to test for one of the standard
+ // containers.
+ auto Qualifier = hasQualifier(specifiesType(templateSpecializationType(
+ hasDeclaration(namedDecl(hasStdContainerName(), isInStdNamespace())))));
+ // the named type is what comes after the final '::' in the type. It should
+ // name one of the standard iterator names.
+ return anyOf(typedefType(HasIteratorDecl, Qualifier),
+ recordType(HasIteratorDecl, Qualifier));
}
/// This matcher returns declaration statements that contain variable
diff --git a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
index 9e4d184c4b6e1..9df2e992477fe 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseConstraintsCheck.cpp
@@ -60,9 +60,11 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) {
Keyword != ElaboratedTypeKeyword::None)) {
return std::nullopt;
}
- TheType = Dep.getQualifierLoc().getTypeLoc();
+ TheType = Dep.getQualifierLoc().getAsTypeLoc();
if (TheType.isNull())
return std::nullopt;
+ } else {
+ return std::nullopt;
}
if (const auto SpecializationLoc =
@@ -89,9 +91,6 @@ matchEnableIfSpecializationImplTypename(TypeLoc TheType) {
static std::optional<TemplateSpecializationTypeLoc>
matchEnableIfSpecializationImplTrait(TypeLoc TheType) {
- if (const auto Elaborated = TheType.getAs<ElaboratedTypeLoc>())
- TheType = Elaborated.getNamedTypeLoc();
-
if (const auto SpecializationLoc =
TheType.getAs<TemplateSpecializationTypeLoc>()) {
diff --git a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
index aaf24eaa33c1b..ee49d8a7cb0b0 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseEmplaceCheck.cpp
@@ -164,10 +164,10 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
auto CallEmplacy = cxxMemberCallExpr(
hasDeclaration(
functionDecl(hasAnyNameIgnoringTemplates(EmplacyFunctions))),
- on(hasTypeOrPointeeType(hasCanonicalType(hasDeclaration(
- has(typedefNameDecl(hasName("value_type"),
- hasType(type(hasUnqualifiedDesugaredType(
- recordType().bind("value_type")))))))))));
+ on(hasTypeOrPointeeType(
+ hasCanonicalType(hasDeclaration(has(typedefNameDecl(
+ hasName("value_type"),
+ hasType(hasCanonicalType(recordType().bind("value_type"))))))))));
// We can't replace push_backs of smart pointer because
// if emplacement fails (f.e. bad_alloc in vector) we will have leak of
@@ -241,17 +241,16 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
auto HasConstructExprWithValueTypeType =
has(ignoringImplicit(cxxConstructExpr(
- SoughtConstructExpr, hasType(type(hasUnqualifiedDesugaredType(
- type(equalsBoundNode("value_type"))))))));
-
- auto HasBracedInitListWithValueTypeType =
- anyOf(allOf(HasConstructInitListExpr,
- has(initListExpr(hasType(type(hasUnqualifiedDesugaredType(
- type(equalsBoundNode("value_type")))))))),
- has(cxxBindTemporaryExpr(
- HasConstructInitListExpr,
- has(initListExpr(hasType(type(hasUnqualifiedDesugaredType(
- type(equalsBoundNode("value_type"))))))))));
+ SoughtConstructExpr,
+ hasType(hasCanonicalType(type(equalsBoundNode("value_type")))))));
+
+ auto HasBracedInitListWithValueTypeType = anyOf(
+ allOf(HasConstructInitListExpr,
+ has(initListExpr(hasType(
+ hasCanonicalType(type(equalsBoundNode("value_type"))))))),
+ has(cxxBindTemporaryExpr(HasConstructInitListExpr,
+ has(initListExpr(hasType(hasCanonicalType(
+ type(equalsBoundNode("value_type")))))))));
auto HasConstructExprWithValueTypeTypeAsLastArgument = hasLastArgument(
materializeTemporaryExpr(
@@ -289,19 +288,17 @@ void UseEmplaceCheck::registerMatchers(MatchFinder *Finder) {
this);
Finder->addMatcher(
- traverse(
- TK_AsIs,
- cxxMemberCallExpr(
- CallEmplacy,
- on(hasType(cxxRecordDecl(has(typedefNameDecl(
- hasName("value_type"),
- hasType(type(
- hasUnqualifiedDesugaredType(recordType(hasDeclaration(
- cxxRecordDecl(hasAnyName(SmallVector<StringRef, 2>(
- TupleTypes.begin(), TupleTypes.end()))))))))))))),
- has(MakeTuple), hasSameNumArgsAsDeclNumParams(),
- unless(isInTemplateInstantiation()))
- .bind("emplacy_call")),
+ traverse(TK_AsIs,
+ cxxMemberCallExpr(
+ CallEmplacy,
+ on(hasType(cxxRecordDecl(has(typedefNameDecl(
+ hasName("value_type"),
+ hasType(hasCanonicalType(recordType(hasDeclaration(
+ cxxRecordDecl(hasAnyName(SmallVector<StringRef, 2>(
+ TupleTypes.begin(), TupleTypes.end())))))))))))),
+ has(MakeTuple), hasSameNumArgsAsDeclNumParams(),
+ unless(isInTemplateInstantiation()))
+ .bind("emplacy_call")),
this);
}
diff --git a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp
index 9c2fc9e06fb45..7eba5678ad9df 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseScopedLockCheck.cpp
@@ -29,7 +29,7 @@ static bool isLockGuardDecl(const NamedDecl *Decl) {
static bool isLockGuard(const QualType &Type) {
if (const auto *Record = Type->getAs<RecordType>())
- if (const RecordDecl *Decl = Record->getDecl())
+ if (const RecordDecl *Decl = Record->getOriginalDecl())
return isLockGuardDecl(Decl);
if (const auto *TemplateSpecType = Type->getAs<TemplateSpecializationType>())
@@ -89,17 +89,6 @@ findLocksInCompoundStmt(const CompoundStmt *Block,
return LockGuardGroups;
}
-static TemplateSpecializationTypeLoc
-getTemplateLockGuardTypeLoc(const TypeSourceInfo *SourceInfo) {
- const TypeLoc Loc = SourceInfo->getTypeLoc();
-
- const auto ElaboratedLoc = Loc.getAs<ElaboratedTypeLoc>();
- if (!ElaboratedLoc)
- return {};
-
- return ElaboratedLoc.getNamedTypeLoc().getAs<TemplateSpecializationTypeLoc>();
-}
-
// Find the exact source range of the 'lock_guard' token
static SourceRange getLockGuardRange(const TypeSourceInfo *SourceInfo) {
const TypeLoc LockGuardTypeLoc = SourceInfo->getTypeLoc();
@@ -111,7 +100,7 @@ static SourceRange getLockGuardRange(const TypeSourceInfo *SourceInfo) {
// Find the exact source range of the 'lock_guard' name token
static SourceRange getLockGuardNameRange(const TypeSourceInfo *SourceInfo) {
const TemplateSpecializationTypeLoc TemplateLoc =
- getTemplateLockGuardTypeLoc(SourceInfo);
+ SourceInfo->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
if (!TemplateLoc)
return {};
@@ -137,11 +126,11 @@ void UseScopedLockCheck::registerMatchers(MatchFinder *Finder) {
const auto LockGuardClassDecl =
namedDecl(hasName("lock_guard"), isInStdNamespace());
- const auto LockGuardType = qualType(anyOf(
- hasUnqualifiedDesugaredType(
- recordType(hasDeclaration(LockGuardClassDecl))),
- elaboratedType(namesType(hasUnqualifiedDesugaredType(
- templateSpecializationType(hasDeclaration(LockGuardClassDecl)))))));
+ const auto LockGuardType =
+ qualType(anyOf(hasUnqualifiedDesugaredType(
+ recordType(hasDeclaration(LockGuardClassDecl))),
+ hasUnqualifiedDesugaredType(templateSpecializationType(
+ hasDeclaration(LockGuardClassDecl)))));
const auto LockVarDecl = varDecl(hasType(LockGuardType));
@@ -166,18 +155,16 @@ void UseScopedLockCheck::registerMatchers(MatchFinder *Finder) {
if (WarnOnUsingAndTypedef) {
// Match 'typedef std::lock_guard<std::mutex> Lock'
Finder->addMatcher(typedefDecl(unless(isExpansionInSystemHeader()),
- hasUnderlyingType(LockGuardType))
+ hasType(hasUnderlyingType(LockGuardType)))
.bind("lock-guard-typedef"),
this);
// Match 'using Lock = std::lock_guard<std::mutex>'
- Finder->addMatcher(
- typeAliasDecl(
- unless(isExpansionInSystemHeader()),
- hasType(elaboratedType(namesType(templateSpecializationType(
- hasDeclaration(LockGuardClassDecl))))))
- .bind("lock-guard-using-alias"),
- this);
+ Finder->addMatcher(typeAliasDecl(unless(isExpansionInSystemHeader()),
+ hasType(templateSpecializationType(
+ hasDeclaration(LockGuardClassDecl))))
+ .bind("lock-guard-using-alias"),
+ this);
// Match 'using std::lock_guard'
Finder->addMatcher(
@@ -289,8 +276,8 @@ void UseScopedLockCheck::diagOnSourceInfo(
const ast_matchers::MatchFinder::MatchResult &Result) {
const TypeLoc TL = LockGuardSourceInfo->getTypeLoc();
- if (const auto ElaboratedTL = TL.getAs<ElaboratedTypeLoc>()) {
- auto Diag = diag(ElaboratedTL.getBeginLoc(), UseScopedLockMessage);
+ if (const auto TTL = TL.getAs<TemplateSpecializationTypeLoc>()) {
+ auto Diag = diag(TTL.getBeginLoc(), UseScopedLockMessage);
const SourceRange LockGuardRange =
getLockGuardNameRange(LockGuardSourceInfo);
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
index ced4825f79a99..82f64096cbec1 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseTrailingReturnTypeCheck.cpp
@@ -64,66 +64,65 @@ struct UnqualNameVisitor : public RecursiveASTVisitor<UnqualNameVisitor> {
return false;
}
- bool TraverseTypeLoc(TypeLoc TL, bool Elaborated = false) {
+ bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) {
if (TL.isNull())
return true;
- if (!Elaborated) {
- switch (TL.getTypeLocClass()) {
- case TypeLoc::Record:
- if (visitUnqualName(
- TL.getAs<RecordTypeLoc>().getTypePtr()->getDecl()->getName()))
- return false;
+ switch (TL.getTypeLocClass()) {
+ case TypeLoc::InjectedClassName:
+ case TypeLoc::Record:
+ case TypeLoc::Enum: {
+ auto TTL = TL.getAs<TagTypeLoc>();
+ const auto *T = TTL.getTypePtr();
+ if (T->getKeyword() != ElaboratedTypeKeyword::None ||
+ TTL.getQualifierLoc())
break;
- case TypeLoc::Enum:
- if (visitUnqualName(
- TL.getAs<EnumTypeLoc>().getTypePtr()->getDecl()->getName()))
- return false;
- break;
- case TypeLoc::TemplateSpecialization:
- if (visitUnqualName(TL.getAs<TemplateSpecializationTypeLoc>()
- .getTypePtr()
- ->getTemplateName()
- .getAsTemplateDecl()
- ->getName()))
- return false;
- break;
- case TypeLoc::Typedef:
- if (visitUnqualName(
- TL.getAs<TypedefTypeLoc>().getTypePtr()->getDecl()->getName()))
- return false;
+ if (visitUnqualName(T->getOriginalDecl()->getName()))
+ return false;
+ break;
+ }
+ case TypeLoc::TemplateSpecialization: {
+ auto TTL = TL.getAs<TemplateSpecializationTypeLoc>();
+ const auto *T = TTL.getTypePtr();
+ if (T->getKeyword() != ElaboratedTypeKeyword::None ||
+ TTL.getQualifierLoc())
break;
- case TypeLoc::Using:
- if (visitUnqualName(TL.getAs<UsingTypeLoc>()
- .getTypePtr()
- ->getFoundDecl()
- ->getName()))
- return false;
+ if (visitUnqualName(T->getTemplateName().getAsTemplateDecl()->getName()))
+ return false;
+ break;
+ }
+ case TypeLoc::Typedef: {
+ auto TTL = TL.getAs<TypedefTypeLoc>();
+ const auto *T = TTL.getTypePtr();
+ if (T->getKeyword() != ElaboratedTypeKeyword::None ||
+ TTL.getQualifierLoc())
break;
- default:
+ if (visitUnqualName(T->getDecl()->getName()))
+ return false;
+ break;
+ }
+ case TypeLoc::Using: {
+ auto TTL = TL.getAs<UsingTypeLoc>();
+ const auto *T = TTL.getTypePtr();
+ if (T->getKeyword() != ElaboratedTypeKeyword::None ||
+ TTL.getQualifierLoc())
break;
- }
+ if (visitUnqualName(T->getDecl()->getName()))
+ return false;
+ break;
+ }
+ default:
+ break;
}
- return RecursiveASTVisitor<UnqualNameVisitor>::TraverseTypeLoc(TL);
+ return RecursiveASTVisitor<UnqualNameVisitor>::TraverseTypeLoc(
+ TL, TraverseQualifier);
}
// Replace the base method in order to call our own
// TraverseTypeLoc().
- bool TraverseQualifiedTypeLoc(QualifiedTypeLoc TL) {
- return TraverseTypeLoc(TL.getUnqualifiedLoc());
- }
-
- // Replace the base version to inform TraverseTypeLoc that the type is
- // elaborated.
- bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc TL) {
- if (TL.getQualifierLoc() &&
- !TraverseNestedNameSpecifierLoc(TL.getQualifierLoc()))
- return false;
- const auto *T = TL.getTypePtr();
- return TraverseTypeLoc(TL.getNamedTypeLoc(),
- T->getKeyword() != ElaboratedTypeKeyword::None ||
- T->getQualifier());
+ bool TraverseQualifiedTypeLoc(QualifiedTypeLoc TL, bool TraverseQualifier) {
+ return TraverseTypeLoc(TL.getUnqualifiedLoc(), TraverseQualifier);
}
bool VisitDeclRefExpr(DeclRefExpr *S) {
diff --git a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
index a053c07f95ce2..2373a26fe48b4 100644
--- a/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
+++ b/clang-tools-extra/clang-tidy/modernize/UseTransparentFunctorsCheck.cpp
@@ -37,15 +37,13 @@ void UseTransparentFunctorsCheck::registerMatchers(MatchFinder *Finder) {
// Non-transparent functor mentioned as a template parameter. FIXIT.
Finder->addMatcher(
- loc(qualType(
- unless(elaboratedType()),
- hasDeclaration(classTemplateSpecializationDecl(
- unless(hasAnyTemplateArgument(templateArgument(refersToType(
- qualType(pointsTo(qualType(isAnyCharacter()))))))),
- hasAnyTemplateArgument(
- templateArgument(refersToType(qualType(hasDeclaration(
- TransparentFunctors))))
- .bind("Functor"))))))
+ loc(qualType(hasDeclaration(classTemplateSpecializationDecl(
+ unless(hasAnyTemplateArgument(templateArgument(refersToType(
+ qualType(pointsTo(qualType(isAnyCharacter()))))))),
+ hasAnyTemplateArgument(
+ templateArgument(refersToType(qualType(
+ hasDeclaration(TransparentFunctors))))
+ .bind("Functor"))))))
.bind("FunctorParentLoc"),
this);
diff --git a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
index 7022e9d784fa7..1c018999432e3 100644
--- a/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
+++ b/clang-tools-extra/clang-tidy/performance/NoAutomaticMoveCheck.cpp
@@ -42,11 +42,11 @@ void NoAutomaticMoveCheck::registerMatchers(MatchFinder *Finder) {
// A matcher for a `DstT::DstT(const Src&)` where DstT also has a
// `DstT::DstT(Src&&)`.
const auto LValueRefCtor = cxxConstructorDecl(
- hasParameter(0,
- hasType(lValueReferenceType(pointee(type().bind("SrcT"))))),
+ hasParameter(0, hasType(hasCanonicalType(
+ lValueReferenceType(pointee(type().bind("SrcT")))))),
ofClass(cxxRecordDecl(hasMethod(cxxConstructorDecl(
- hasParameter(0, hasType(rValueReferenceType(
- pointee(type(equalsBoundNode("SrcT")))))))))));
+ hasParameter(0, hasType(hasCanonicalType(rValueReferenceType(
+ pointee(type(equalsBoundNode("SrcT"))))))))))));
// A matcher for `DstT::DstT(const Src&&)`, which typically comes from an
// instantiation of `template <typename U> DstT::DstT(U&&)`.
diff --git a/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp b/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp
index 3b4d65be7dfa1..5a3c9a4203eb9 100644
--- a/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp
+++ b/clang-tools-extra/clang-tidy/portability/StdAllocatorConstCheck.cpp
@@ -15,10 +15,11 @@ namespace clang::tidy::portability {
void StdAllocatorConstCheck::registerMatchers(MatchFinder *Finder) {
// Match std::allocator<const T>.
- auto AllocatorConst =
+ auto AllocatorConst = qualType(hasCanonicalType(
recordType(hasDeclaration(classTemplateSpecializationDecl(
hasName("::std::allocator"),
- hasTemplateArgument(0, refersToType(qualType(isConstQualified()))))));
+ hasTemplateArgument(0,
+ refersToType(qualType(isConstQualified()))))))));
auto HasContainerName =
hasAnyName("::std::vector", "::std::deque", "::std::list",
@@ -31,8 +32,10 @@ void StdAllocatorConstCheck::registerMatchers(MatchFinder *Finder) {
// aren't caught.
Finder->addMatcher(
typeLoc(
- templateSpecializationTypeLoc(),
- loc(hasUnqualifiedDesugaredType(anyOf(
+ anyOf(templateSpecializationTypeLoc(),
+ qualifiedTypeLoc(
+ hasUnqualifiedLoc(templateSpecializationTypeLoc()))),
+ loc(qualType(anyOf(
recordType(hasDeclaration(classTemplateSpecializationDecl(
HasContainerName,
anyOf(
diff --git a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
index fffb136e5a332..8392f9ad685e2 100644
--- a/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/StaticAccessedThroughInstanceCheck.cpp
@@ -19,19 +19,25 @@ namespace {
AST_MATCHER(CXXMethodDecl, isStatic) { return Node.isStatic(); }
} // namespace
-static unsigned getNameSpecifierNestingLevel(const QualType &QType) {
- if (const auto *ElType = QType->getAs<ElaboratedType>()) {
- if (const NestedNameSpecifier *NestedSpecifiers = ElType->getQualifier()) {
- unsigned NameSpecifierNestingLevel = 1;
- do {
- NameSpecifierNestingLevel++;
- NestedSpecifiers = NestedSpecifiers->getPrefix();
- } while (NestedSpecifiers);
-
+static unsigned getNameSpecifierNestingLevel(QualType QType) {
+ unsigned NameSpecifierNestingLevel = 1;
+ for (NestedNameSpecifier Qualifier = QType->getPrefix(); /**/;
+ ++NameSpecifierNestingLevel) {
+ switch (Qualifier.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
return NameSpecifierNestingLevel;
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Super:
+ return NameSpecifierNestingLevel + 1;
+ case NestedNameSpecifier::Kind::Namespace:
+ Qualifier = Qualifier.getAsNamespaceAndPrefix().Prefix;
+ continue;
+ case NestedNameSpecifier::Kind::Type:
+ Qualifier = Qualifier.getAsType()->getPrefix();
+ continue;
}
+ llvm_unreachable("unhandled nested name specifier kind");
}
- return 0;
}
void StaticAccessedThroughInstanceCheck::storeOptions(
diff --git a/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp b/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
index 9db059c26d6f2..0115dfda22c89 100644
--- a/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/SuspiciousCallArgumentCheck.cpp
@@ -414,9 +414,9 @@ static bool areTypesCompatible(QualType ArgType, QualType ParamType,
// Arithmetic types are interconvertible, except scoped enums.
if (ParamType->isArithmeticType() && ArgType->isArithmeticType()) {
if ((ParamType->isEnumeralType() &&
- ParamType->castAs<EnumType>()->getDecl()->isScoped()) ||
+ ParamType->castAs<EnumType>()->getOriginalDecl()->isScoped()) ||
(ArgType->isEnumeralType() &&
- ArgType->castAs<EnumType>()->getDecl()->isScoped()))
+ ArgType->castAs<EnumType>()->getOriginalDecl()->isScoped()))
return false;
return true;
diff --git a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
index 6f6b8a853a91e..718467ed02f0a 100644
--- a/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
+++ b/clang-tools-extra/clang-tidy/readability/UseStdMinMaxCheck.cpp
@@ -67,11 +67,7 @@ static QualType getNonTemplateAlias(QualType QT) {
if (!TT->getDecl()->getDescribedTemplate() &&
!TT->getDecl()->getDeclContext()->isDependentContext())
return QT;
- QT = TT->getDecl()->getUnderlyingType();
- }
- // cast to elaborated type
- else if (const ElaboratedType *ET = dyn_cast<ElaboratedType>(QT)) {
- QT = ET->getNamedType();
+ QT = TT->desugar();
} else {
break;
}
diff --git a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp
index 0637d0eff688c..aa6aefcf0c493 100644
--- a/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp
+++ b/clang-tools-extra/clang-tidy/utils/ExceptionSpecAnalyzer.cpp
@@ -66,7 +66,8 @@ ExceptionSpecAnalyzer::analyzeBase(const CXXBaseSpecifier &Base,
if (!RecType)
return State::Unknown;
- const auto *BaseClass = cast<CXXRecordDecl>(RecType->getDecl());
+ const auto *BaseClass =
+ cast<CXXRecordDecl>(RecType->getOriginalDecl())->getDefinitionOrSelf();
return analyzeRecord(BaseClass, Kind);
}
diff --git a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp
index 7f4ccca84faa5..3229efb957067 100644
--- a/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp
+++ b/clang-tools-extra/clang-tidy/utils/FormatStringConverter.cpp
@@ -465,8 +465,9 @@ bool FormatStringConverter::emitIntegerArgument(
// the signedness based on the format string, so we need to do the
// same.
if (const auto *ET = ArgType->getAs<EnumType>()) {
- if (const std::optional<std::string> MaybeCastType =
- castTypeForArgument(ArgKind, ET->getDecl()->getIntegerType()))
+ if (const std::optional<std::string> MaybeCastType = castTypeForArgument(
+ ArgKind,
+ ET->getOriginalDecl()->getDefinitionOrSelf()->getIntegerType()))
ArgFixes.emplace_back(
ArgIndex, (Twine("static_cast<") + *MaybeCastType + ">(").str());
else
diff --git a/clang-tools-extra/clang-tidy/utils/Matchers.cpp b/clang-tools-extra/clang-tidy/utils/Matchers.cpp
index 4974a9cdb9f4b..bd7b03eb39ad7 100644
--- a/clang-tools-extra/clang-tidy/utils/Matchers.cpp
+++ b/clang-tools-extra/clang-tidy/utils/Matchers.cpp
@@ -34,7 +34,7 @@ bool MatchesAnyListedTypeNameMatcher::matches(
PrintingPolicy PrintingPolicyWithSuppressedTag(
Finder->getASTContext().getLangOpts());
PrintingPolicyWithSuppressedTag.PrintAsCanonical = CanonicalTypes;
- PrintingPolicyWithSuppressedTag.SuppressElaboration = true;
+ PrintingPolicyWithSuppressedTag.FullyQualifiedName = true;
PrintingPolicyWithSuppressedTag.SuppressScope = false;
PrintingPolicyWithSuppressedTag.SuppressTagKeyword = true;
PrintingPolicyWithSuppressedTag.SuppressUnwrittenScope = true;
diff --git a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
index 9104723c7f1c0..87441db05b0dc 100644
--- a/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
+++ b/clang-tools-extra/clang-tidy/utils/RenamerClangTidyCheck.cpp
@@ -281,8 +281,10 @@ class RenamerClangTidyVisitor
}
bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc Loc) {
- if (const NestedNameSpecifier *Spec = Loc.getNestedNameSpecifier()) {
- if (const NamespaceDecl *Decl = Spec->getAsNamespace())
+ if (NestedNameSpecifier Spec = Loc.getNestedNameSpecifier();
+ Spec.getKind() == NestedNameSpecifier::Kind::Namespace) {
+ if (const auto *Decl =
+ dyn_cast<NamespaceDecl>(Spec.getAsNamespaceAndPrefix().Namespace))
Check->addUsage(Decl, Loc.getLocalSourceRange(), SM);
}
@@ -322,48 +324,34 @@ class RenamerClangTidyVisitor
}
bool VisitTypedefTypeLoc(const TypedefTypeLoc &Loc) {
- Check->addUsage(Loc.getTypedefNameDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getDecl(), Loc.getNameLoc(), SM);
return true;
}
bool VisitTagTypeLoc(const TagTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
- return true;
- }
-
- bool VisitInjectedClassNameTypeLoc(const InjectedClassNameTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getOriginalDecl(), Loc.getNameLoc(), SM);
return true;
}
bool VisitUnresolvedUsingTypeLoc(const UnresolvedUsingTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getDecl(), Loc.getNameLoc(), SM);
return true;
}
bool VisitTemplateTypeParmTypeLoc(const TemplateTypeParmTypeLoc &Loc) {
- Check->addUsage(Loc.getDecl(), Loc.getSourceRange(), SM);
+ Check->addUsage(Loc.getDecl(), Loc.getNameLoc(), SM);
return true;
}
bool
VisitTemplateSpecializationTypeLoc(const TemplateSpecializationTypeLoc &Loc) {
const TemplateDecl *Decl =
- Loc.getTypePtr()->getTemplateName().getAsTemplateDecl();
+ Loc.getTypePtr()->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true);
- SourceRange Range(Loc.getTemplateNameLoc(), Loc.getTemplateNameLoc());
- if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl)) {
+ if (const auto *ClassDecl = dyn_cast<TemplateDecl>(Decl))
if (const NamedDecl *TemplDecl = ClassDecl->getTemplatedDecl())
- Check->addUsage(TemplDecl, Range, SM);
- }
-
- return true;
- }
-
- bool VisitDependentTemplateSpecializationTypeLoc(
- const DependentTemplateSpecializationTypeLoc &Loc) {
- if (const TagDecl *Decl = Loc.getTypePtr()->getAsTagDecl())
- Check->addUsage(Decl, Loc.getSourceRange(), SM);
+ Check->addUsage(TemplDecl, Loc.getTemplateNameLoc(), SM);
return true;
}
diff --git a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
index 44db0c2aed607..96d3a5bbd86a2 100644
--- a/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
+++ b/clang-tools-extra/clang-tidy/utils/TypeTraits.cpp
@@ -124,7 +124,8 @@ bool isTriviallyDefaultConstructible(QualType Type, const ASTContext &Context) {
return true;
if (const auto *RT = CanonicalType->getAs<RecordType>()) {
- return recordIsTriviallyDefaultConstructible(*RT->getDecl(), Context);
+ return recordIsTriviallyDefaultConstructible(
+ *RT->getOriginalDecl()->getDefinitionOrSelf(), Context);
}
// No other types can match.
diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp
index e274236527817..a7ba8a1e16891 100644
--- a/clang-tools-extra/clangd/AST.cpp
+++ b/clang-tools-extra/clangd/AST.cpp
@@ -102,54 +102,78 @@ getUsingNamespaceDirectives(const DeclContext *DestContext,
// ancestor is redundant, therefore we stop at lowest common ancestor.
// In addition to that stops early whenever IsVisible returns true. This can be
// used to implement support for "using namespace" decls.
-std::string
-getQualification(ASTContext &Context, const DeclContext *DestContext,
- const DeclContext *SourceContext,
- llvm::function_ref<bool(NestedNameSpecifier *)> IsVisible) {
- std::vector<const NestedNameSpecifier *> Parents;
- bool ReachedNS = false;
+std::string getQualification(ASTContext &Context,
+ const DeclContext *DestContext,
+ const DeclContext *SourceContext,
+ llvm::function_ref<bool(const Decl *)> IsVisible) {
+ std::vector<const Decl *> Parents;
+ [[maybe_unused]] bool ReachedNS = false;
for (const DeclContext *CurContext = SourceContext; CurContext;
CurContext = CurContext->getLookupParent()) {
// Stop once we reach a common ancestor.
if (CurContext->Encloses(DestContext))
break;
- NestedNameSpecifier *NNS = nullptr;
+ const Decl *CurD;
if (auto *TD = llvm::dyn_cast<TagDecl>(CurContext)) {
// There can't be any more tag parents after hitting a namespace.
assert(!ReachedNS);
- (void)ReachedNS;
- NNS = NestedNameSpecifier::Create(Context, nullptr, TD->getTypeForDecl());
+ CurD = TD;
} else if (auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) {
ReachedNS = true;
- NNS = NestedNameSpecifier::Create(Context, nullptr, NSD);
// Anonymous and inline namespace names are not spelled while qualifying
// a name, so skip those.
if (NSD->isAnonymousNamespace() || NSD->isInlineNamespace())
continue;
+ CurD = NSD;
} else {
// Other types of contexts cannot be spelled in code, just skip over
// them.
continue;
}
// Stop if this namespace is already visible at DestContext.
- if (IsVisible(NNS))
+ if (IsVisible(CurD))
break;
- Parents.push_back(NNS);
+ Parents.push_back(CurD);
+ }
+
+ // Go over the declarations in reverse order, since we stored inner-most
+ // parent first.
+ NestedNameSpecifier Qualifier = std::nullopt;
+ bool IsFirst = true;
+ for (const auto *CurD : llvm::reverse(Parents)) {
+ if (auto *TD = llvm::dyn_cast<TagDecl>(CurD)) {
+ QualType T;
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(TD);
+ ClassTemplateDecl *CTD = RD->getDescribedClassTemplate()) {
+ ArrayRef<TemplateArgument> Args;
+ if (const auto *SD = dyn_cast<ClassTemplateSpecializationDecl>(RD))
+ Args = SD->getTemplateArgs().asArray();
+ else
+ Args = CTD->getTemplateParameters()->getInjectedTemplateArgs(Context);
+ T = Context.getTemplateSpecializationType(
+ ElaboratedTypeKeyword::None,
+ Context.getQualifiedTemplateName(
+ Qualifier, /*TemplateKeyword=*/!IsFirst, TemplateName(CTD)),
+ Args, /*CanonicalArgs=*/{}, Context.getCanonicalTagType(RD));
+ } else {
+ T = Context.getTagType(ElaboratedTypeKeyword::None, Qualifier, TD,
+ /*OwnsTag=*/false);
+ }
+ Qualifier = NestedNameSpecifier(T.getTypePtr());
+ } else {
+ Qualifier =
+ NestedNameSpecifier(Context, cast<NamespaceDecl>(CurD), Qualifier);
+ }
+ IsFirst = false;
}
+ if (!Qualifier)
+ return "";
- // Go over name-specifiers in reverse order to create necessary qualification,
- // since we stored inner-most parent first.
std::string Result;
llvm::raw_string_ostream OS(Result);
- for (const auto *Parent : llvm::reverse(Parents)) {
- if (Parent != *Parents.rbegin() && Parent->isDependent() &&
- Parent->getAsRecordDecl() &&
- Parent->getAsRecordDecl()->getDescribedClassTemplate())
- OS << "template ";
- Parent->print(OS, Context.getPrintingPolicy());
- }
+ Qualifier.print(OS, Context.getPrintingPolicy());
return OS.str();
}
@@ -187,6 +211,7 @@ std::string printQualifiedName(const NamedDecl &ND) {
// include them, but at query time it's hard to find all the inline
// namespaces to query: the preamble doesn't have a dedicated list.
Policy.SuppressUnwrittenScope = true;
+ Policy.SuppressScope = true;
// (unnamed struct), not (unnamed struct at /path/to/foo.cc:42:1).
// In clangd, context is usually available and paths are mostly noise.
Policy.AnonymousTagLocations = false;
@@ -213,8 +238,7 @@ std::string printUsingNamespaceName(const ASTContext &Ctx,
std::string Name;
llvm::raw_string_ostream Out(Name);
- if (auto *Qual = D.getQualifier())
- Qual->print(Out, PP);
+ D.getQualifier().print(Out, PP);
D.getNominatedNamespaceAsWritten()->printName(Out);
return Out.str();
}
@@ -229,8 +253,7 @@ std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
// Handle 'using namespace'. They all have the same name - <using-directive>.
if (auto *UD = llvm::dyn_cast<UsingDirectiveDecl>(&ND)) {
Out << "using namespace ";
- if (auto *Qual = UD->getQualifier())
- Qual->print(Out, PP);
+ UD->getQualifier().print(Out, PP);
UD->getNominatedNamespaceAsWritten()->printName(Out);
return Out.str();
}
@@ -250,8 +273,7 @@ std::string printName(const ASTContext &Ctx, const NamedDecl &ND) {
}
// Print nested name qualifier if it was written in the source code.
- if (auto *Qualifier = getQualifierLoc(ND).getNestedNameSpecifier())
- Qualifier->print(Out, PP);
+ getQualifierLoc(ND).getNestedNameSpecifier().print(Out, PP);
// Print the name itself.
ND.getDeclName().print(Out, PP);
// Print template arguments.
@@ -391,12 +413,13 @@ preferredIncludeDirective(llvm::StringRef FileName, const LangOptions &LangOpts,
}
std::string printType(const QualType QT, const DeclContext &CurContext,
- const llvm::StringRef Placeholder) {
+ const llvm::StringRef Placeholder, bool FullyQualify) {
std::string Result;
llvm::raw_string_ostream OS(Result);
PrintingPolicy PP(CurContext.getParentASTContext().getPrintingPolicy());
PP.SuppressTagKeyword = true;
PP.SuppressUnwrittenScope = true;
+ PP.FullyQualifiedName = FullyQualify;
class PrintCB : public PrintingCallbacks {
public:
@@ -439,6 +462,7 @@ QualType declaredType(const TypeDecl *D) {
if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
if (const auto *Args = CTSD->getTemplateArgsAsWritten())
return Context.getTemplateSpecializationType(
+ ElaboratedTypeKeyword::None,
TemplateName(CTSD->getSpecializedTemplate()), Args->arguments(),
/*CanonicalArgs=*/{});
return Context.getTypeDeclType(D);
@@ -664,11 +688,10 @@ std::string getQualification(ASTContext &Context,
auto VisibleNamespaceDecls =
getUsingNamespaceDirectives(DestContext, InsertionPoint);
return getQualification(
- Context, DestContext, ND->getDeclContext(),
- [&](NestedNameSpecifier *NNS) {
- if (NNS->getKind() != NestedNameSpecifier::Namespace)
+ Context, DestContext, ND->getDeclContext(), [&](const Decl *D) {
+ if (D->getKind() != Decl::Namespace)
return false;
- const auto *CanonNSD = NNS->getAsNamespace()->getCanonicalDecl();
+ const auto *CanonNSD = cast<NamespaceDecl>(D)->getCanonicalDecl();
return llvm::any_of(VisibleNamespaceDecls,
[CanonNSD](const NamespaceDecl *NSD) {
return NSD->getCanonicalDecl() == CanonNSD;
@@ -685,12 +708,11 @@ std::string getQualification(ASTContext &Context,
(void)NS;
}
return getQualification(
- Context, DestContext, ND->getDeclContext(),
- [&](NestedNameSpecifier *NNS) {
+ Context, DestContext, ND->getDeclContext(), [&](const Decl *D) {
return llvm::any_of(VisibleNamespaces, [&](llvm::StringRef Namespace) {
std::string NS;
llvm::raw_string_ostream OS(NS);
- NNS->print(OS, Context.getPrintingPolicy());
+ D->print(OS, Context.getPrintingPolicy());
return OS.str() == Namespace;
});
});
diff --git a/clang-tools-extra/clangd/AST.h b/clang-tools-extra/clangd/AST.h
index fb0722d697cd0..1538d12172593 100644
--- a/clang-tools-extra/clangd/AST.h
+++ b/clang-tools-extra/clangd/AST.h
@@ -135,7 +135,8 @@ preferredIncludeDirective(llvm::StringRef FileName, const LangOptions &LangOpts,
/// Returns a QualType as string. The result doesn't contain unwritten scopes
/// like anonymous/inline namespace.
std::string printType(const QualType QT, const DeclContext &CurContext,
- llvm::StringRef Placeholder = "");
+ llvm::StringRef Placeholder = "",
+ bool FullyQualify = false);
/// Indicates if \p D is a template instantiation implicitly generated by the
/// compiler, e.g.
diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp
index 14679fea6ac8a..c4cf00075e5f1 100644
--- a/clang-tools-extra/clangd/CodeComplete.cpp
+++ b/clang-tools-extra/clangd/CodeComplete.cpp
@@ -870,7 +870,7 @@ bool contextAllowsIndex(enum CodeCompletionContext::Kind K) {
}
static bool isInjectedClass(const NamedDecl &D) {
- if (auto *R = dyn_cast_or_null<RecordDecl>(&D))
+ if (auto *R = dyn_cast_or_null<CXXRecordDecl>(&D))
if (R->isInjectedClassName())
return true;
return false;
@@ -1462,20 +1462,15 @@ bool allowIndex(CodeCompletionContext &CC) {
auto Scope = CC.getCXXScopeSpecifier();
if (!Scope)
return true;
- NestedNameSpecifier *NameSpec = (*Scope)->getScopeRep();
- if (!NameSpec)
- return true;
// We only query the index when qualifier is a namespace.
// If it's a class, we rely solely on sema completions.
- switch (NameSpec->getKind()) {
- case NestedNameSpecifier::Global:
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
+ switch ((*Scope)->getScopeRep().getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Global:
+ case NestedNameSpecifier::Kind::Namespace:
return true;
- case NestedNameSpecifier::Super:
- case NestedNameSpecifier::TypeSpec:
- // Unresolved inside a template.
- case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Kind::Super:
+ case NestedNameSpecifier::Kind::Type:
return false;
}
llvm_unreachable("invalid NestedNameSpecifier kind");
diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp
index 8f24477ecd3de..aea568d1c3a6e 100644
--- a/clang-tools-extra/clangd/DumpAST.cpp
+++ b/clang-tools-extra/clangd/DumpAST.cpp
@@ -147,18 +147,17 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
}
llvm_unreachable("Unhandled ArgKind enum");
}
- std::string getKind(const NestedNameSpecifierLoc &NNSL) {
- assert(NNSL.getNestedNameSpecifier());
- switch (NNSL.getNestedNameSpecifier()->getKind()) {
+ std::string getKind(NestedNameSpecifierLoc NNSL) {
+ switch (NNSL.getNestedNameSpecifier().getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
#define NNS_KIND(X) \
- case NestedNameSpecifier::X: \
+ case NestedNameSpecifier::Kind::X: \
return #X
- NNS_KIND(Identifier);
NNS_KIND(Namespace);
- NNS_KIND(TypeSpec);
+ NNS_KIND(Type);
NNS_KIND(Global);
NNS_KIND(Super);
- NNS_KIND(NamespaceAlias);
#undef NNS_KIND
}
llvm_unreachable("Unhandled SpecifierKind enum");
@@ -262,7 +261,7 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
return TL.getType().getLocalQualifiers().getAsString(
Ctx.getPrintingPolicy());
if (const auto *TT = dyn_cast<TagType>(TL.getTypePtr()))
- return getDetail(TT->getDecl());
+ return getDetail(TT->getOriginalDecl());
if (const auto *DT = dyn_cast<DeducedType>(TL.getTypePtr()))
if (DT->isDeduced())
return DT->getDeducedType().getAsString(Ctx.getPrintingPolicy());
@@ -274,18 +273,11 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
return getDetail(TT->getDecl());
return "";
}
- std::string getDetail(const NestedNameSpecifierLoc &NNSL) {
- const auto &NNS = *NNSL.getNestedNameSpecifier();
- switch (NNS.getKind()) {
- case NestedNameSpecifier::Identifier:
- return NNS.getAsIdentifier()->getName().str() + "::";
- case NestedNameSpecifier::Namespace:
- return NNS.getAsNamespace()->getNameAsString() + "::";
- case NestedNameSpecifier::NamespaceAlias:
- return NNS.getAsNamespaceAlias()->getNameAsString() + "::";
- default:
+ std::string getDetail(NestedNameSpecifierLoc NNSL) {
+ NestedNameSpecifier NNS = NNSL.getNestedNameSpecifier();
+ if (NNS.getKind() != NestedNameSpecifier::Kind::Namespace)
return "";
- }
+ return NNS.getAsNamespaceAndPrefix().Namespace->getNameAsString() + "::";
}
std::string getDetail(const CXXCtorInitializer *CCI) {
if (FieldDecl *FD = CCI->getAnyMember())
@@ -349,8 +341,10 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
return !D || isInjectedClassName(D) ||
traverseNode("declaration", D, [&] { Base::TraverseDecl(D); });
}
- bool TraverseTypeLoc(TypeLoc TL) {
- return !TL || traverseNode("type", TL, [&] { Base::TraverseTypeLoc(TL); });
+ bool TraverseTypeLoc(TypeLoc TL, bool TraverseQualifier = true) {
+ return !TL || traverseNode("type", TL, [&] {
+ Base::TraverseTypeLoc(TL, TraverseQualifier);
+ });
}
bool TraverseTemplateName(const TemplateName &TN) {
return traverseNode("template name", TN,
@@ -392,11 +386,11 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> {
// This means we'd never see 'int' in 'const int'! Work around that here.
// (The reason for the behavior is to avoid traversing the nested Type twice,
// but we ignore TraverseType anyway).
- bool TraverseQualifiedTypeLoc(QualifiedTypeLoc QTL) {
+ bool TraverseQualifiedTypeLoc(QualifiedTypeLoc QTL, bool TraverseQualifier) {
return TraverseTypeLoc(QTL.getUnqualifiedLoc());
}
// Uninteresting parts of the AST that don't have locations within them.
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *) { return true; }
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier) { return true; }
bool TraverseType(QualType) { return true; }
// OpaqueValueExpr blocks traversal, we must explicitly traverse it.
@@ -423,7 +417,7 @@ ASTNode dumpAST(const DynTypedNode &N, const syntax::TokenBuffer &Tokens,
V.TraverseNestedNameSpecifierLoc(
*const_cast<NestedNameSpecifierLoc *>(NNSL));
else if (const auto *NNS = N.get<NestedNameSpecifier>())
- V.TraverseNestedNameSpecifier(const_cast<NestedNameSpecifier *>(NNS));
+ V.TraverseNestedNameSpecifier(*NNS);
else if (const auto *TL = N.get<TypeLoc>())
V.TraverseTypeLoc(*const_cast<TypeLoc *>(TL));
else if (const auto *QT = N.get<QualType>())
diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp
index 91fd3b0f8567b..92ce7a5290751 100644
--- a/clang-tools-extra/clangd/FindTarget.cpp
+++ b/clang-tools-extra/clangd/FindTarget.cpp
@@ -366,19 +366,11 @@ struct TargetFinder {
Visitor(TargetFinder &Outer, RelSet Flags) : Outer(Outer), Flags(Flags) {}
void VisitTagType(const TagType *TT) {
- Outer.add(TT->getAsTagDecl(), Flags);
- }
-
- void VisitElaboratedType(const ElaboratedType *ET) {
- Outer.add(ET->desugar(), Flags);
+ Outer.add(cast<TagType>(TT)->getOriginalDecl(), Flags);
}
void VisitUsingType(const UsingType *ET) {
- Outer.add(ET->getFoundDecl(), Flags);
- }
-
- void VisitInjectedClassNameType(const InjectedClassNameType *ICNT) {
- Outer.add(ICNT->getDecl(), Flags);
+ Outer.add(ET->getDecl(), Flags);
}
void VisitDecltypeType(const DecltypeType *DTT) {
@@ -483,33 +475,27 @@ struct TargetFinder {
Visitor(*this, Flags).Visit(T.getTypePtr());
}
- void add(const NestedNameSpecifier *NNS, RelSet Flags) {
+ void add(NestedNameSpecifier NNS, RelSet Flags) {
if (!NNS)
return;
- debug(*NNS, Flags);
- switch (NNS->getKind()) {
- case NestedNameSpecifier::Namespace:
- add(NNS->getAsNamespace(), Flags);
+ debug(NNS, Flags);
+ switch (NNS.getKind()) {
+ case NestedNameSpecifier::Kind::Namespace:
+ add(NNS.getAsNamespaceAndPrefix().Namespace, Flags);
return;
- case NestedNameSpecifier::NamespaceAlias:
- add(NNS->getAsNamespaceAlias(), Flags);
- return;
- case NestedNameSpecifier::Identifier:
- if (Resolver) {
- add(Resolver->resolveNestedNameSpecifierToType(NNS), Flags);
- }
+ case NestedNameSpecifier::Kind::Type:
+ add(QualType(NNS.getAsType(), 0), Flags);
return;
- case NestedNameSpecifier::TypeSpec:
- add(QualType(NNS->getAsType(), 0), Flags);
- return;
- case NestedNameSpecifier::Global:
+ case NestedNameSpecifier::Kind::Global:
// This should be TUDecl, but we can't get a pointer to it!
return;
- case NestedNameSpecifier::Super:
- add(NNS->getAsRecordDecl(), Flags);
+ case NestedNameSpecifier::Kind::Super:
+ add(NNS.getAsSuper(), Flags);
return;
+ case NestedNameSpecifier::Kind::Null:
+ llvm_unreachable("unexpected null nested name specifier");
}
- llvm_unreachable("unhandled NestedNameSpecifier::SpecifierKind");
+ llvm_unreachable("unhandled NestedNameSpecifier::Kind");
}
void add(const CXXCtorInitializer *CCI, RelSet Flags) {
@@ -558,7 +544,7 @@ allTargetDecls(const DynTypedNode &N, const HeuristicResolver *Resolver) {
else if (const NestedNameSpecifierLoc *NNSL = N.get<NestedNameSpecifierLoc>())
Finder.add(NNSL->getNestedNameSpecifier(), Flags);
else if (const NestedNameSpecifier *NNS = N.get<NestedNameSpecifier>())
- Finder.add(NNS, Flags);
+ Finder.add(*NNS, Flags);
else if (const TypeLoc *TL = N.get<TypeLoc>())
Finder.add(TL->getType(), Flags);
else if (const QualType *QT = N.get<QualType>())
@@ -864,32 +850,25 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
const HeuristicResolver *Resolver;
llvm::SmallVector<ReferenceLoc> Refs;
- void VisitElaboratedTypeLoc(ElaboratedTypeLoc L) {
- // We only know about qualifier, rest if filled by inner locations.
- size_t InitialSize = Refs.size();
- Visit(L.getNamedTypeLoc().getUnqualifiedLoc());
- size_t NewSize = Refs.size();
- // Add qualifier for the newly-added refs.
- for (unsigned I = InitialSize; I < NewSize; ++I) {
- ReferenceLoc *Ref = &Refs[I];
- // Fill in the qualifier.
- assert(!Ref->Qualifier.hasQualifier() && "qualifier already set");
- Ref->Qualifier = L.getQualifierLoc();
- }
+ void VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc L) {
+ Refs.push_back(ReferenceLoc{L.getQualifierLoc(),
+ L.getLocalSourceRange().getBegin(),
+ /*IsDecl=*/false,
+ {L.getDecl()}});
}
void VisitUsingTypeLoc(UsingTypeLoc L) {
- Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
+ Refs.push_back(ReferenceLoc{L.getQualifierLoc(),
L.getLocalSourceRange().getBegin(),
/*IsDecl=*/false,
- {L.getFoundDecl()}});
+ {L.getDecl()}});
}
void VisitTagTypeLoc(TagTypeLoc L) {
- Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
+ Refs.push_back(ReferenceLoc{L.getQualifierLoc(),
L.getNameLoc(),
/*IsDecl=*/false,
- {L.getDecl()}});
+ {L.getOriginalDecl()}});
}
void VisitTemplateTypeParmTypeLoc(TemplateTypeParmTypeLoc L) {
@@ -909,25 +888,18 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
// 2. 'vector<int>' with mask 'Underlying'.
// we want to return only #1 in this case.
Refs.push_back(ReferenceLoc{
- NestedNameSpecifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
+ L.getQualifierLoc(), L.getTemplateNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()),
DeclRelation::Alias, Resolver)});
}
void VisitDeducedTemplateSpecializationTypeLoc(
DeducedTemplateSpecializationTypeLoc L) {
Refs.push_back(ReferenceLoc{
- NestedNameSpecifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
+ L.getQualifierLoc(), L.getNameLoc(), /*IsDecl=*/false,
explicitReferenceTargets(DynTypedNode::create(L.getType()),
DeclRelation::Alias, Resolver)});
}
- void VisitInjectedClassNameTypeLoc(InjectedClassNameTypeLoc TL) {
- Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
- TL.getNameLoc(),
- /*IsDecl=*/false,
- {TL.getDecl()}});
- }
-
void VisitDependentTemplateSpecializationTypeLoc(
DependentTemplateSpecializationTypeLoc L) {
Refs.push_back(
@@ -946,12 +918,12 @@ refInTypeLoc(TypeLoc L, const HeuristicResolver *Resolver) {
}
void VisitTypedefTypeLoc(TypedefTypeLoc L) {
- if (shouldSkipTypedef(L.getTypedefNameDecl()))
+ if (shouldSkipTypedef(L.getDecl()))
return;
- Refs.push_back(ReferenceLoc{NestedNameSpecifierLoc(),
+ Refs.push_back(ReferenceLoc{L.getQualifierLoc(),
L.getNameLoc(),
/*IsDecl=*/false,
- {L.getTypedefNameDecl()}});
+ {L.getDecl()}});
}
void VisitObjCInterfaceTypeLoc(ObjCInterfaceTypeLoc L) {
@@ -983,17 +955,6 @@ class ExplicitReferenceCollector
return true;
}
- bool TraverseElaboratedTypeLoc(ElaboratedTypeLoc L) {
- // ElaboratedTypeLoc will reports information for its inner type loc.
- // Otherwise we loose information about inner types loc's qualifier.
- TypeLoc Inner = L.getNamedTypeLoc().getUnqualifiedLoc();
- if (L.getBeginLoc() == Inner.getBeginLoc())
- return RecursiveASTVisitor::TraverseTypeLoc(Inner);
- else
- TypeLocsToSkip.insert(Inner.getBeginLoc());
- return RecursiveASTVisitor::TraverseElaboratedTypeLoc(L);
- }
-
bool VisitStmt(Stmt *S) {
visitNode(DynTypedNode::create(*S));
return true;
@@ -1054,7 +1015,7 @@ class ExplicitReferenceCollector
return true;
visitNode(DynTypedNode::create(L));
// Inner type is missing information about its qualifier, skip it.
- if (auto TL = L.getTypeLoc())
+ if (auto TL = L.getAsTypeLoc())
TypeLocsToSkip.insert(TL.getBeginLoc());
return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(L);
}
@@ -1095,12 +1056,21 @@ class ExplicitReferenceCollector
if (auto *S = N.get<Stmt>())
return refInStmt(S, Resolver);
if (auto *NNSL = N.get<NestedNameSpecifierLoc>()) {
- // (!) 'DeclRelation::Alias' ensures we do not loose namespace aliases.
- return {ReferenceLoc{
- NNSL->getPrefix(), NNSL->getLocalBeginLoc(), false,
- explicitReferenceTargets(
- DynTypedNode::create(*NNSL->getNestedNameSpecifier()),
- DeclRelation::Alias, Resolver)}};
+ // (!) 'DeclRelation::Alias' ensures we do not lose namespace aliases.
+ NestedNameSpecifierLoc Qualifier;
+ SourceLocation NameLoc;
+ if (auto TL = NNSL->getAsTypeLoc()) {
+ Qualifier = TL.getPrefix();
+ NameLoc = TL.getNonPrefixBeginLoc();
+ } else {
+ Qualifier = NNSL->getAsNamespaceAndPrefix().Prefix;
+ NameLoc = NNSL->getLocalBeginLoc();
+ }
+ return {
+ ReferenceLoc{Qualifier, NameLoc, false,
+ explicitReferenceTargets(
+ DynTypedNode::create(NNSL->getNestedNameSpecifier()),
+ DeclRelation::Alias, Resolver)}};
}
if (const TypeLoc *TL = N.get<TypeLoc>())
return refInTypeLoc(*TL, Resolver);
@@ -1213,8 +1183,8 @@ llvm::raw_ostream &operator<<(llvm::raw_ostream &OS, ReferenceLoc R) {
OS << "}";
if (R.Qualifier) {
OS << ", qualifier = '";
- R.Qualifier.getNestedNameSpecifier()->print(OS,
- PrintingPolicy(LangOptions()));
+ R.Qualifier.getNestedNameSpecifier().print(OS,
+ PrintingPolicy(LangOptions()));
OS << "'";
}
if (R.IsDecl)
diff --git a/clang-tools-extra/clangd/Hover.cpp b/clang-tools-extra/clangd/Hover.cpp
index e39d8bfcf83f3..f4b312cde6349 100644
--- a/clang-tools-extra/clangd/Hover.cpp
+++ b/clang-tools-extra/clangd/Hover.cpp
@@ -169,13 +169,14 @@ HoverInfo::PrintedType printType(QualType QT, ASTContext &ASTCtx,
QT = QT->castAs<DecltypeType>()->getUnderlyingType();
HoverInfo::PrintedType Result;
llvm::raw_string_ostream OS(Result.Type);
- // Special case: if the outer type is a tag type without qualifiers, then
- // include the tag for extra clarity.
- // This isn't very idiomatic, so don't attempt it for complex cases, including
- // pointers/references, template specializations, etc.
+ // Special case: if the outer type is a canonical tag type, then include the
+ // tag for extra clarity. This isn't very idiomatic, so don't attempt it for
+ // complex cases, including pointers/references, template specializations,
+ // etc.
if (!QT.isNull() && !QT.hasQualifiers() && PP.SuppressTagKeyword) {
- if (auto *TT = llvm::dyn_cast<TagType>(QT.getTypePtr()))
- OS << TT->getDecl()->getKindName() << " ";
+ if (auto *TT = llvm::dyn_cast<TagType>(QT.getTypePtr());
+ TT && TT->isCanonicalUnqualified())
+ OS << TT->getOriginalDecl()->getKindName() << " ";
}
QT.print(OS, PP);
@@ -451,7 +452,7 @@ std::optional<std::string> printExprValue(const Expr *E,
// Compare to int64_t to avoid bit-width match requirements.
int64_t Val = Constant.Val.getInt().getExtValue();
for (const EnumConstantDecl *ECD :
- T->castAs<EnumType>()->getDecl()->enumerators())
+ T->castAs<EnumType>()->getOriginalDecl()->enumerators())
if (ECD->getInitVal() == Val)
return llvm::formatv("{0} ({1})", ECD->getNameAsString(),
printHex(Constant.Val.getInt()))
@@ -1002,10 +1003,11 @@ void addLayoutInfo(const NamedDecl &ND, HoverInfo &HI) {
const auto &Ctx = ND.getASTContext();
if (auto *RD = llvm::dyn_cast<RecordDecl>(&ND)) {
- if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RD->getTypeForDecl()))
+ CanQualType RT = Ctx.getCanonicalTagType(RD);
+ if (auto Size = Ctx.getTypeSizeInCharsIfKnown(RT))
HI.Size = Size->getQuantity() * 8;
if (!RD->isDependentType() && RD->isCompleteDefinition())
- HI.Align = Ctx.getTypeAlign(RD->getTypeForDecl());
+ HI.Align = Ctx.getTypeAlign(RT);
return;
}
diff --git a/clang-tools-extra/clangd/IncludeFixer.cpp b/clang-tools-extra/clangd/IncludeFixer.cpp
index 4ff021c4c390a..e89318a9500a2 100644
--- a/clang-tools-extra/clangd/IncludeFixer.cpp
+++ b/clang-tools-extra/clangd/IncludeFixer.cpp
@@ -173,7 +173,7 @@ std::vector<Fix> IncludeFixer::fix(DiagnosticsEngine::Level DiagLevel,
// `enum x : int;' is not formally an incomplete type.
// We may need a full definition anyway.
if (auto * ET = llvm::dyn_cast<EnumType>(T))
- if (!ET->getDecl()->getDefinition())
+ if (!ET->getOriginalDecl()->getDefinition())
return fixIncompleteType(*T);
}
}
@@ -400,10 +400,12 @@ std::optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
CheapUnresolvedName Result;
Result.Name = Unresolved.getAsString();
if (SS && SS->isNotEmpty()) { // "::" or "ns::"
- if (auto *Nested = SS->getScopeRep()) {
- if (Nested->getKind() == NestedNameSpecifier::Global) {
- Result.ResolvedScope = "";
- } else if (const auto *NS = Nested->getAsNamespace()) {
+ NestedNameSpecifier Nested = SS->getScopeRep();
+ if (Nested.getKind() == NestedNameSpecifier::Kind::Global) {
+ Result.ResolvedScope = "";
+ } else if (Nested.getKind() == NestedNameSpecifier::Kind::Namespace) {
+ const NamespaceBaseDecl *NSB = Nested.getAsNamespaceAndPrefix().Namespace;
+ if (const auto *NS = dyn_cast<NamespaceDecl>(NSB)) {
std::string SpecifiedNS = printNamespaceScope(*NS);
std::optional<std::string> Spelling = getSpelledSpecifier(*SS, SM);
@@ -420,13 +422,14 @@ std::optional<CheapUnresolvedName> extractUnresolvedNameCheaply(
} else {
Result.UnresolvedScope = std::move(*Spelling);
}
- } else if (const auto *ANS = Nested->getAsNamespaceAlias()) {
- Result.ResolvedScope = printNamespaceScope(*ANS->getNamespace());
} else {
- // We don't fix symbols in scopes that are not top-level e.g. class
- // members, as we don't collect includes for them.
- return std::nullopt;
+ const auto *ANS = cast<NamespaceAliasDecl>(NSB);
+ Result.ResolvedScope = printNamespaceScope(*ANS->getNamespace());
}
+ } else {
+ // We don't fix symbols in scopes that are not top-level e.g. class
+ // members, as we don't collect includes for them.
+ return std::nullopt;
}
}
diff --git a/clang-tools-extra/clangd/InlayHints.cpp b/clang-tools-extra/clangd/InlayHints.cpp
index 197c62c40dcf0..cd479e1b7c9bc 100644
--- a/clang-tools-extra/clangd/InlayHints.cpp
+++ b/clang-tools-extra/clangd/InlayHints.cpp
@@ -55,18 +55,24 @@ void stripLeadingUnderscores(StringRef &Name) { Name = Name.ltrim('_'); }
// getDeclForType() returns the decl responsible for Type's spelling.
// This is the inverse of ASTContext::getTypeDeclType().
-template <typename Ty, typename = decltype(((Ty *)nullptr)->getDecl())>
-const NamedDecl *getDeclForTypeImpl(const Ty *T) {
- return T->getDecl();
-}
-const NamedDecl *getDeclForTypeImpl(const void *T) { return nullptr; }
const NamedDecl *getDeclForType(const Type *T) {
switch (T->getTypeClass()) {
-#define ABSTRACT_TYPE(TY, BASE)
-#define TYPE(TY, BASE) \
- case Type::TY: \
- return getDeclForTypeImpl(llvm::cast<TY##Type>(T));
-#include "clang/AST/TypeNodes.inc"
+ case Type::Enum:
+ case Type::Record:
+ case Type::InjectedClassName:
+ return cast<TagType>(T)->getOriginalDecl();
+ case Type::TemplateSpecialization:
+ return cast<TemplateSpecializationType>(T)
+ ->getTemplateName()
+ .getAsTemplateDecl(/*IgnoreDeduced=*/true);
+ case Type::Typedef:
+ return cast<TypedefType>(T)->getDecl();
+ case Type::UnresolvedUsing:
+ return cast<UnresolvedUsingType>(T)->getDecl();
+ case Type::Using:
+ return cast<UsingType>(T)->getDecl();
+ default:
+ return nullptr;
}
llvm_unreachable("Unknown TypeClass enum");
}
@@ -81,8 +87,6 @@ llvm::StringRef getSimpleName(const NamedDecl &D) {
return getSimpleName(D.getDeclName());
}
llvm::StringRef getSimpleName(QualType T) {
- if (const auto *ET = llvm::dyn_cast<ElaboratedType>(T))
- return getSimpleName(ET->getNamedType());
if (const auto *BT = llvm::dyn_cast<BuiltinType>(T)) {
PrintingPolicy PP(LangOptions{});
PP.adjustForCPlusPlus();
diff --git a/clang-tools-extra/clangd/Quality.cpp b/clang-tools-extra/clangd/Quality.cpp
index c1ab63fb22f61..3f630b05c654b 100644
--- a/clang-tools-extra/clangd/Quality.cpp
+++ b/clang-tools-extra/clangd/Quality.cpp
@@ -258,7 +258,7 @@ static SymbolRelevanceSignals::AccessibleScope
computeScope(const NamedDecl *D) {
// Injected "Foo" within the class "Foo" has file scope, not class scope.
const DeclContext *DC = D->getDeclContext();
- if (auto *R = dyn_cast_or_null<RecordDecl>(D))
+ if (auto *R = dyn_cast_or_null<CXXRecordDecl>(D))
if (R->isInjectedClassName())
DC = DC->getParent();
// Class constructor should have the same scope as the class.
diff --git a/clang-tools-extra/clangd/Selection.cpp b/clang-tools-extra/clangd/Selection.cpp
index 277cb8769a1b1..06165dfbbcdd2 100644
--- a/clang-tools-extra/clangd/Selection.cpp
+++ b/clang-tools-extra/clangd/Selection.cpp
@@ -62,7 +62,8 @@ void recordMetrics(const SelectionTree &S, const LangOptions &Lang) {
}
// Return the range covering a node and all its children.
-SourceRange getSourceRange(const DynTypedNode &N) {
+SourceRange getSourceRange(const DynTypedNode &N,
+ bool IncludeQualifier = false) {
// MemberExprs to implicitly access anonymous fields should not claim any
// tokens for themselves. Given:
// struct A { struct { int b; }; };
@@ -80,7 +81,7 @@ SourceRange getSourceRange(const DynTypedNode &N) {
? getSourceRange(DynTypedNode::create(*ME->getBase()))
: SourceRange();
}
- return N.getSourceRange();
+ return N.getSourceRange(IncludeQualifier);
}
// An IntervalSet maintains a set of disjoint subranges of an array.
@@ -643,8 +644,9 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
}
return traverseNode(X, [&] { return Base::TraverseDecl(X); });
}
- bool TraverseTypeLoc(TypeLoc X) {
- return traverseNode(&X, [&] { return Base::TraverseTypeLoc(X); });
+ bool TraverseTypeLoc(TypeLoc X, bool TraverseQualifier = true) {
+ return traverseNode(
+ &X, [&] { return Base::TraverseTypeLoc(X, TraverseQualifier); });
}
bool TraverseTemplateArgumentLoc(const TemplateArgumentLoc &X) {
return traverseNode(&X,
@@ -690,7 +692,8 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
// This means we'd never see 'int' in 'const int'! Work around that here.
// (The reason for the behavior is to avoid traversing the nested Type twice,
// but we ignore TraverseType anyway).
- bool TraverseQualifiedTypeLoc(QualifiedTypeLoc QX) {
+ bool TraverseQualifiedTypeLoc(QualifiedTypeLoc QX,
+ bool TraverseQualifier = true) {
return traverseNode<TypeLoc>(
&QX, [&] { return TraverseTypeLoc(QX.getUnqualifiedLoc()); });
}
@@ -698,7 +701,7 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
return traverseNode(&PL, [&] { return Base::TraverseObjCProtocolLoc(PL); });
}
// Uninteresting parts of the AST that don't have locations within them.
- bool TraverseNestedNameSpecifier(NestedNameSpecifier *) { return true; }
+ bool TraverseNestedNameSpecifier(NestedNameSpecifier) { return true; }
bool TraverseType(QualType) { return true; }
// The DeclStmt for the loop variable claims to cover the whole range
@@ -798,7 +801,7 @@ class SelectionVisitor : public RecursiveASTVisitor<SelectionVisitor> {
// An optimization for a common case: nodes outside macro expansions that
// don't intersect the selection may be recursively skipped.
bool canSafelySkipNode(const DynTypedNode &N) {
- SourceRange S = getSourceRange(N);
+ SourceRange S = getSourceRange(N, /*IncludeQualifier=*/true);
if (auto *TL = N.get<TypeLoc>()) {
// FIXME: TypeLoc::getBeginLoc()/getEndLoc() are pretty fragile
// heuristics. We should consider only pruning critical TypeLoc nodes, to
diff --git a/clang-tools-extra/clangd/SemanticHighlighting.cpp b/clang-tools-extra/clangd/SemanticHighlighting.cpp
index dc574dcd11703..2b151b1274428 100644
--- a/clang-tools-extra/clangd/SemanticHighlighting.cpp
+++ b/clang-tools-extra/clangd/SemanticHighlighting.cpp
@@ -597,7 +597,7 @@ class HighlightingsBuilder {
std::optional<HighlightingModifier> scopeModifier(const NamedDecl *D) {
const DeclContext *DC = D->getDeclContext();
// Injected "Foo" within the class "Foo" has file scope, not class scope.
- if (auto *R = dyn_cast_or_null<RecordDecl>(D))
+ if (auto *R = dyn_cast_or_null<CXXRecordDecl>(D))
if (R->isInjectedClassName())
DC = DC->getParent();
// Lambda captures are considered function scope, not class scope.
@@ -1127,21 +1127,6 @@ class CollectExtraHighlightings
return RecursiveASTVisitor::TraverseTemplateArgumentLoc(L);
}
- // findExplicitReferences will walk nested-name-specifiers and
- // find anything that can be resolved to a Decl. However, non-leaf
- // components of nested-name-specifiers which are dependent names
- // (kind "Identifier") cannot be resolved to a decl, so we visit
- // them here.
- bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc Q) {
- if (NestedNameSpecifier *NNS = Q.getNestedNameSpecifier()) {
- if (NNS->getKind() == NestedNameSpecifier::Identifier)
- H.addToken(Q.getLocalBeginLoc(), HighlightingKind::Type)
- .addModifier(HighlightingModifier::DependentName)
- .addModifier(HighlightingModifier::ClassScope);
- }
- return RecursiveASTVisitor::TraverseNestedNameSpecifierLoc(Q);
- }
-
private:
HighlightingsBuilder &H;
};
diff --git a/clang-tools-extra/clangd/XRefs.cpp b/clang-tools-extra/clangd/XRefs.cpp
index 089f8158c9aa5..731ae0fe119d0 100644
--- a/clang-tools-extra/clangd/XRefs.cpp
+++ b/clang-tools-extra/clangd/XRefs.cpp
@@ -1935,7 +1935,8 @@ std::vector<const CXXRecordDecl *> findRecordTypeAt(ParsedAST &AST,
// Return the type most associated with an AST node.
// This isn't precisely defined: we want "go to type" to do something useful.
-static QualType typeForNode(const SelectionTree::Node *N) {
+static QualType typeForNode(const ASTContext &Ctx,
+ const SelectionTree::Node *N) {
// If we're looking at a namespace qualifier, walk up to what it's qualifying.
// (If we're pointing at a *class* inside a NNS, N will be a TypeLoc).
while (N && N->ASTNode.get<NestedNameSpecifierLoc>())
@@ -1969,10 +1970,13 @@ static QualType typeForNode(const SelectionTree::Node *N) {
if (const Decl *D = N->ASTNode.get<Decl>()) {
struct Visitor : ConstDeclVisitor<Visitor, QualType> {
+ const ASTContext &Ctx;
+ Visitor(const ASTContext &Ctx) : Ctx(Ctx) {}
+
QualType VisitValueDecl(const ValueDecl *D) { return D->getType(); }
// Declaration of a type => that type.
QualType VisitTypeDecl(const TypeDecl *D) {
- return QualType(D->getTypeForDecl(), 0);
+ return Ctx.getTypeDeclType(D);
}
// Exception: alias declaration => the underlying type, not the alias.
QualType VisitTypedefNameDecl(const TypedefNameDecl *D) {
@@ -1982,7 +1986,7 @@ static QualType typeForNode(const SelectionTree::Node *N) {
QualType VisitTemplateDecl(const TemplateDecl *D) {
return Visit(D->getTemplatedDecl());
}
- } V;
+ } V(Ctx);
return V.Visit(D);
}
@@ -2126,7 +2130,8 @@ std::vector<LocatedSymbol> findType(ParsedAST &AST, Position Pos,
// unique_ptr<unique_ptr<T>>. Let's *not* remove them, because it gives you some
// information about the type you may have not known before
// (since unique_ptr<unique_ptr<T>> != unique_ptr<T>).
- for (const QualType& Type : unwrapFindType(typeForNode(N), AST.getHeuristicResolver()))
+ for (const QualType &Type : unwrapFindType(
+ typeForNode(AST.getASTContext(), N), AST.getHeuristicResolver()))
llvm::copy(locateSymbolForType(AST, Type, Index),
std::back_inserter(LocatedSymbols));
diff --git a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
index 00c05ebdb5216..f65c74fdbc9ee 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/AddUsing.cpp
@@ -115,13 +115,6 @@ class UsingFinder : public RecursiveASTVisitor<UsingFinder> {
const SourceManager &SM;
};
-bool isFullyQualified(const NestedNameSpecifier *NNS) {
- if (!NNS)
- return false;
- return NNS->getKind() == NestedNameSpecifier::Global ||
- isFullyQualified(NNS->getPrefix());
-}
-
struct InsertionPointData {
// Location to insert the "using" statement. If invalid then the statement
// should not be inserted at all (it already exists).
@@ -167,17 +160,20 @@ findInsertionPoint(const Tweak::Selection &Inputs,
for (auto &U : Usings) {
// Only "upgrade" to fully qualified is all relevant using decls are fully
// qualified. Otherwise trust what the user typed.
- if (!isFullyQualified(U->getQualifier()))
+ if (!U->getQualifier().isFullyQualified())
AlwaysFullyQualify = false;
if (SM.isBeforeInTranslationUnit(Inputs.Cursor, U->getUsingLoc()))
// "Usings" is sorted, so we're done.
break;
- if (const auto *Namespace = U->getQualifier()->getAsNamespace()) {
+ if (NestedNameSpecifier Qualifier = U->getQualifier();
+ Qualifier.getKind() == NestedNameSpecifier::Kind::Namespace) {
+ const auto *Namespace =
+ U->getQualifier().getAsNamespaceAndPrefix().Namespace;
if (Namespace->getCanonicalDecl() ==
QualifierToRemove.getNestedNameSpecifier()
- ->getAsNamespace()
- ->getCanonicalDecl() &&
+ .getAsNamespaceAndPrefix()
+ .Namespace->getCanonicalDecl() &&
U->getName() == Name) {
return InsertionPointData();
}
@@ -231,8 +227,12 @@ findInsertionPoint(const Tweak::Selection &Inputs,
}
bool isNamespaceForbidden(const Tweak::Selection &Inputs,
- const NestedNameSpecifier &Namespace) {
- std::string NamespaceStr = printNamespaceScope(*Namespace.getAsNamespace());
+ NestedNameSpecifier Namespace) {
+ const auto *NS =
+ dyn_cast<NamespaceDecl>(Namespace.getAsNamespaceAndPrefix().Namespace);
+ if (!NS)
+ return true;
+ std::string NamespaceStr = printNamespaceScope(*NS);
for (StringRef Banned : Config::current().Style.FullyQualifiedNamespaces) {
StringRef PrefixMatch = NamespaceStr;
@@ -243,11 +243,11 @@ bool isNamespaceForbidden(const Tweak::Selection &Inputs,
return false;
}
-std::string getNNSLAsString(NestedNameSpecifierLoc &NNSL,
+std::string getNNSLAsString(NestedNameSpecifierLoc NNSL,
const PrintingPolicy &Policy) {
std::string Out;
llvm::raw_string_ostream OutStream(Out);
- NNSL.getNestedNameSpecifier()->print(OutStream, Policy);
+ NNSL.getNestedNameSpecifier().print(OutStream, Policy);
return OutStream.str();
}
@@ -272,16 +272,15 @@ bool AddUsing::prepare(const Selection &Inputs) {
continue;
}
if (auto *T = Node->ASTNode.get<TypeLoc>()) {
- if (T->getAs<ElaboratedTypeLoc>()) {
+ // Find the outermost TypeLoc.
+ if (Node->Parent->ASTNode.get<NestedNameSpecifierLoc>())
+ continue;
+ if (isa<TagType, TemplateSpecializationType, TypedefType, UsingType,
+ UnresolvedUsingType>(T->getTypePtr()))
break;
- }
- if (Node->Parent->ASTNode.get<TypeLoc>() ||
- Node->Parent->ASTNode.get<NestedNameSpecifierLoc>()) {
- // Node is TypeLoc, but it's parent is either TypeLoc or
- // NestedNameSpecifier. In both cases, we want to go up, to find
- // the outermost TypeLoc.
+ // Find the outermost TypeLoc.
+ if (Node->Parent->ASTNode.get<TypeLoc>())
continue;
- }
}
break;
}
@@ -303,32 +302,70 @@ bool AddUsing::prepare(const Selection &Inputs) {
MustInsertAfterLoc = D->getDecl()->getBeginLoc();
}
} else if (auto *T = Node->ASTNode.get<TypeLoc>()) {
- if (auto E = T->getAs<ElaboratedTypeLoc>()) {
- QualifierToRemove = E.getQualifierLoc();
-
- SpelledNameRange = E.getSourceRange();
- if (auto T = E.getNamedTypeLoc().getAs<TemplateSpecializationTypeLoc>()) {
- // Remove the template arguments from the name.
- SpelledNameRange.setEnd(T.getLAngleLoc().getLocWithOffset(-1));
- }
-
- if (const auto *ET = E.getTypePtr()) {
- if (const auto *TDT =
- dyn_cast<TypedefType>(ET->getNamedType().getTypePtr())) {
- MustInsertAfterLoc = TDT->getDecl()->getBeginLoc();
- } else if (auto *TD = ET->getAsTagDecl()) {
- MustInsertAfterLoc = TD->getBeginLoc();
- }
- }
+ switch (T->getTypeLocClass()) {
+ case TypeLoc::TemplateSpecialization: {
+ auto TL = T->castAs<TemplateSpecializationTypeLoc>();
+ QualifierToRemove = TL.getQualifierLoc();
+ if (!QualifierToRemove)
+ break;
+ SpelledNameRange = TL.getTemplateNameLoc();
+ if (auto *TD = TL.getTypePtr()->getTemplateName().getAsTemplateDecl(
+ /*IgnoreDeduced=*/true))
+ MustInsertAfterLoc = TD->getBeginLoc();
+ break;
+ }
+ case TypeLoc::Enum:
+ case TypeLoc::Record:
+ case TypeLoc::InjectedClassName: {
+ auto TL = T->castAs<TagTypeLoc>();
+ QualifierToRemove = TL.getQualifierLoc();
+ if (!QualifierToRemove)
+ break;
+ SpelledNameRange = TL.getNameLoc();
+ MustInsertAfterLoc = TL.getOriginalDecl()->getBeginLoc();
+ break;
+ }
+ case TypeLoc::Typedef: {
+ auto TL = T->castAs<TypedefTypeLoc>();
+ QualifierToRemove = TL.getQualifierLoc();
+ if (!QualifierToRemove)
+ break;
+ SpelledNameRange = TL.getNameLoc();
+ MustInsertAfterLoc = TL.getDecl()->getBeginLoc();
+ break;
+ }
+ case TypeLoc::UnresolvedUsing: {
+ auto TL = T->castAs<UnresolvedUsingTypeLoc>();
+ QualifierToRemove = TL.getQualifierLoc();
+ if (!QualifierToRemove)
+ break;
+ SpelledNameRange = TL.getNameLoc();
+ MustInsertAfterLoc = TL.getDecl()->getBeginLoc();
+ break;
+ }
+ case TypeLoc::Using: {
+ auto TL = T->castAs<UsingTypeLoc>();
+ QualifierToRemove = TL.getQualifierLoc();
+ if (!QualifierToRemove)
+ break;
+ SpelledNameRange = TL.getNameLoc();
+ MustInsertAfterLoc = TL.getDecl()->getBeginLoc();
+ break;
+ }
+ default:
+ break;
}
+ if (QualifierToRemove)
+ SpelledNameRange.setBegin(QualifierToRemove.getBeginLoc());
}
if (!QualifierToRemove ||
// FIXME: This only supports removing qualifiers that are made up of just
// namespace names. If qualifier contains a type, we could take the
// longest namespace prefix and remove that.
- !QualifierToRemove.getNestedNameSpecifier()->getAsNamespace() ||
+ QualifierToRemove.getNestedNameSpecifier().getKind() !=
+ NestedNameSpecifier::Kind::Namespace ||
// Respect user config.
- isNamespaceForbidden(Inputs, *QualifierToRemove.getNestedNameSpecifier()))
+ isNamespaceForbidden(Inputs, QualifierToRemove.getNestedNameSpecifier()))
return false;
// Macros are difficult. We only want to offer code action when what's spelled
// under the cursor is a namespace qualifier. If it's a macro that expands to
@@ -380,7 +417,7 @@ Expected<Tweak::Effect> AddUsing::apply(const Selection &Inputs) {
llvm::raw_string_ostream UsingTextStream(UsingText);
UsingTextStream << "using ";
if (InsertionPoint->AlwaysFullyQualify &&
- !isFullyQualified(QualifierToRemove.getNestedNameSpecifier()))
+ !QualifierToRemove.getNestedNameSpecifier().isFullyQualified())
UsingTextStream << "::";
UsingTextStream << QualifierToSpell << SpelledName << ";"
<< InsertionPoint->Suffix;
diff --git a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
index cd07cbf73635c..134ae89288300 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/ExtractFunction.cpp
@@ -362,7 +362,7 @@ struct NewFunction {
SourceLocation DefinitionPoint;
std::optional<SourceLocation> ForwardDeclarationPoint;
const CXXRecordDecl *EnclosingClass = nullptr;
- const NestedNameSpecifier *DefinitionQualifier = nullptr;
+ NestedNameSpecifier DefinitionQualifier = std::nullopt;
const DeclContext *SemanticDC = nullptr;
const DeclContext *SyntacticDC = nullptr;
const DeclContext *ForwardDeclarationSyntacticDC = nullptr;
@@ -455,13 +455,12 @@ std::string NewFunction::renderQualifiers() const {
}
std::string NewFunction::renderDeclarationName(FunctionDeclKind K) const {
- if (DefinitionQualifier == nullptr || K != OutOfLineDefinition) {
+ if (!DefinitionQualifier || K != OutOfLineDefinition)
return Name;
- }
std::string QualifierName;
llvm::raw_string_ostream Oss(QualifierName);
- DefinitionQualifier->print(Oss, *LangOpts);
+ DefinitionQualifier.print(Oss, *LangOpts);
return llvm::formatv("{0}{1}", QualifierName, Name);
}
diff --git a/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp b/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
index 43cfc769f7f71..7e616968c6046 100644
--- a/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
+++ b/clang-tools-extra/clangd/refactor/tweaks/PopulateSwitch.cpp
@@ -116,7 +116,7 @@ bool PopulateSwitch::prepare(const Selection &Sel) {
EnumT = Cond->getType().getCanonicalType()->getAsAdjusted<EnumType>();
if (!EnumT)
return false;
- EnumD = EnumT->getDecl();
+ EnumD = EnumT->getOriginalDecl();
if (!EnumD || EnumD->isDependentType())
return false;
diff --git a/clang-tools-extra/clangd/unittests/ASTTests.cpp b/clang-tools-extra/clangd/unittests/ASTTests.cpp
index d0bc3c4d7db98..76d46bad82224 100644
--- a/clang-tools-extra/clangd/unittests/ASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/ASTTests.cpp
@@ -421,7 +421,7 @@ TEST(ClangdAST, GetQualification) {
{
R"cpp(
namespace ns1 { namespace ns2 { void Foo(); } }
- void insert(); // ns2::Foo
+ void insert(); // ns1::ns2::Foo
namespace ns1 {
void insert(); // ns2::Foo
namespace ns2 {
@@ -429,7 +429,7 @@ TEST(ClangdAST, GetQualification) {
}
}
)cpp",
- {"ns2::", "ns2::", ""},
+ {"ns1::ns2::", "ns2::", ""},
{"ns1::"},
},
{
@@ -531,7 +531,8 @@ TEST(ClangdAST, PrintType) {
ASSERT_EQ(InsertionPoints.size(), Case.Types.size());
for (size_t I = 0, E = InsertionPoints.size(); I != E; ++I) {
const auto *DC = InsertionPoints[I];
- EXPECT_EQ(printType(AST.getASTContext().getTypeDeclType(TargetDecl), *DC),
+ EXPECT_EQ(printType(AST.getASTContext().getTypeDeclType(TargetDecl), *DC,
+ /*Placeholder=*/"", /*FullyQualify=*/true),
Case.Types[I]);
}
}
diff --git a/clang-tools-extra/clangd/unittests/DumpASTTests.cpp b/clang-tools-extra/clangd/unittests/DumpASTTests.cpp
index cb2c17ad4ef0d..5c857d0b8ae3e 100644
--- a/clang-tools-extra/clangd/unittests/DumpASTTests.cpp
+++ b/clang-tools-extra/clangd/unittests/DumpASTTests.cpp
@@ -72,15 +72,14 @@ declaration: Namespace - root
expression: BinaryOperator - +
expression: ImplicitCast - LValueToRValue
expression: DeclRef - x
- specifier: TypeSpec
+ specifier: Type
type: Record - S
expression: ImplicitCast - LValueToRValue
expression: Member - x
expression: CXXBindTemporary
expression: CXXTemporaryObject - S
- type: Elaborated
+ type: Record - S
specifier: Namespace - root::
- type: Record - S
)"},
{R"cpp(
namespace root {
@@ -104,14 +103,13 @@ declaration: Namespace - root
expression: BinaryOperator - +
expression: ImplicitCast - LValueToRValue
expression: DeclRef - x
- specifier: TypeSpec
+ specifier: Type
type: Record - S
expression: ImplicitCast - LValueToRValue
expression: Member - x
expression: CXXTemporaryObject - S
- type: Elaborated
+ type: Record - S
specifier: Namespace - root::
- type: Record - S
)"},
{R"cpp(
namespace root {
@@ -138,7 +136,7 @@ declaration: Namespace - root
type: Builtin - unsigned int
statement: Return
expression: DependentScopeDeclRef - value
- specifier: TypeSpec
+ specifier: Type
type: TemplateTypeParm - T
)"},
{R"cpp(
@@ -154,8 +152,7 @@ declaration: Var - root
expression: DeclRef - operator+
expression: MaterializeTemporary - lvalue
expression: CXXTemporaryObject - Foo
- type: Elaborated
- type: Record - Foo
+ type: Record - Foo
expression: IntegerLiteral - 42
)"},
{R"cpp(
diff --git a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
index 602f61d9ecb41..a2593df9c201d 100644
--- a/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
+++ b/clang-tools-extra/clangd/unittests/FindTargetTests.cpp
@@ -992,7 +992,7 @@ TEST_F(TargetDeclTest, DependentTypes) {
)cpp";
EXPECT_DECLS("DependentNameTypeLoc", "struct B");
- // Heuristic resolution of dependent type name which doesn't get a TypeLoc
+ // Heuristic resolution of dependent type name within a NestedNameSpecifierLoc
Code = R"cpp(
template <typename>
struct A { struct B { struct C {}; }; };
@@ -1000,7 +1000,7 @@ TEST_F(TargetDeclTest, DependentTypes) {
template <typename T>
void foo(typename A<T>::[[B]]::C);
)cpp";
- EXPECT_DECLS("NestedNameSpecifierLoc", "struct B");
+ EXPECT_DECLS("DependentNameTypeLoc", "struct B");
// Heuristic resolution of dependent type name whose qualifier is also
// dependent
diff --git a/clang-tools-extra/clangd/unittests/HoverTests.cpp b/clang-tools-extra/clangd/unittests/HoverTests.cpp
index 775278ccf694b..931b1c975d978 100644
--- a/clang-tools-extra/clangd/unittests/HoverTests.cpp
+++ b/clang-tools-extra/clangd/unittests/HoverTests.cpp
@@ -2893,7 +2893,7 @@ TEST(Hover, All) {
)cpp",
[](HoverInfo &HI) {
HI.Name = "this";
- HI.Definition = "const Foo<T> *";
+ HI.Definition = "const ns::Foo<T> *";
}},
{
R"cpp(// this expr for specialization class
@@ -2909,7 +2909,7 @@ TEST(Hover, All) {
)cpp",
[](HoverInfo &HI) {
HI.Name = "this";
- HI.Definition = "Foo<int> *";
+ HI.Definition = "ns::Foo<int> *";
}},
{
R"cpp(// this expr for partial specialization struct
@@ -2925,7 +2925,7 @@ TEST(Hover, All) {
)cpp",
[](HoverInfo &HI) {
HI.Name = "this";
- HI.Definition = "const Foo<int, F> *";
+ HI.Definition = "const ns::Foo<int, F> *";
}},
{
R"cpp(
@@ -3045,8 +3045,8 @@ TEST(Hover, All) {
HI.Kind = index::SymbolKind::Function;
HI.NamespaceScope = "";
HI.Definition = "MyRect foobar()";
- HI.Type = {"MyRect ()", "MyRect ()"};
- HI.ReturnType = {"MyRect", "MyRect"};
+ HI.Type = {"MyRect ()", "struct MyRect ()"};
+ HI.ReturnType = {"MyRect", "struct MyRect"};
HI.Parameters.emplace();
}},
{R"cpp(
diff --git a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
index e0cd955bb1c9a..99e728c40063d 100644
--- a/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
+++ b/clang-tools-extra/clangd/unittests/InlayHintTests.cpp
@@ -1295,14 +1295,7 @@ TEST(TypeHints, NoQualifiers) {
}
}
)cpp",
- ExpectedHint{": S1", "x"},
- // FIXME: We want to suppress scope specifiers
- // here because we are into the whole
- // brevity thing, but the ElaboratedType
- // printer does not honor the SuppressScope
- // flag by design, so we need to extend the
- // PrintingPolicy to support this use case.
- ExpectedHint{": S2::Inner<int>", "y"});
+ ExpectedHint{": S1", "x"}, ExpectedHint{": Inner<int>", "y"});
}
TEST(TypeHints, Lambda) {
diff --git a/clang-tools-extra/clangd/unittests/QualityTests.cpp b/clang-tools-extra/clangd/unittests/QualityTests.cpp
index 619ea32115357..4954659a45e02 100644
--- a/clang-tools-extra/clangd/unittests/QualityTests.cpp
+++ b/clang-tools-extra/clangd/unittests/QualityTests.cpp
@@ -121,7 +121,9 @@ TEST(QualityTests, SymbolRelevanceSignalExtraction) {
SymbolRelevanceSignals Relevance;
Relevance.merge(CodeCompletionResult(&findDecl(AST, "deprecated"),
- /*Priority=*/42, nullptr, false,
+ /*Priority=*/42,
+ /*Qualifier=*/std::nullopt,
+ /*QualifierIsInformative=*/false,
/*Accessible=*/false));
EXPECT_EQ(Relevance.NameMatch, SymbolRelevanceSignals().NameMatch);
EXPECT_TRUE(Relevance.Forbidden);
@@ -487,13 +489,15 @@ TEST(QualityTests, ItemWithFixItsRankedDown) {
auto AST = Header.build();
SymbolRelevanceSignals RelevanceWithFixIt;
- RelevanceWithFixIt.merge(CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr,
- false, true, {FixItHint{}}));
+ RelevanceWithFixIt.merge(CodeCompletionResult(
+ &findDecl(AST, "x"), /*Priority=*/0, /*Qualifier=*/std::nullopt,
+ /*QualifierIsInformative=*/false, /*Accessible=*/true, {FixItHint{}}));
EXPECT_TRUE(RelevanceWithFixIt.NeedsFixIts);
SymbolRelevanceSignals RelevanceWithoutFixIt;
- RelevanceWithoutFixIt.merge(
- CodeCompletionResult(&findDecl(AST, "x"), 0, nullptr, false, true, {}));
+ RelevanceWithoutFixIt.merge(CodeCompletionResult(
+ &findDecl(AST, "x"), /*Priority=*/0, /*Qualifier=*/std::nullopt,
+ /*QualifierIsInformative=*/false, /*Accessible=*/true, {}));
EXPECT_FALSE(RelevanceWithoutFixIt.NeedsFixIts);
EXPECT_LT(RelevanceWithFixIt.evaluateHeuristics(),
diff --git a/clang-tools-extra/clangd/unittests/SelectionTests.cpp b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
index aaaf758e72236..3df19d8fc174d 100644
--- a/clang-tools-extra/clangd/unittests/SelectionTests.cpp
+++ b/clang-tools-extra/clangd/unittests/SelectionTests.cpp
@@ -104,9 +104,9 @@ TEST(SelectionTest, CommonAncestor) {
{
R"cpp(
template <typename T>
- int x = [[T::^U::]]ccc();
+ int x = T::[[^U]]::ccc();
)cpp",
- "NestedNameSpecifierLoc",
+ "DependentNameTypeLoc",
},
{
R"cpp(
diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
index baff90faa6eae..6e7be9c414246 100644
--- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
+++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp
@@ -60,14 +60,10 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
NamedDecl *getMemberProvider(QualType Base) {
if (Base->isPointerType())
return getMemberProvider(Base->getPointeeType());
- // Unwrap the sugar ElaboratedType.
- if (const auto *ElTy = dyn_cast<ElaboratedType>(Base))
- return getMemberProvider(ElTy->getNamedType());
-
if (const auto *TT = dyn_cast<TypedefType>(Base))
return TT->getDecl();
if (const auto *UT = dyn_cast<UsingType>(Base))
- return UT->getFoundDecl();
+ return UT->getDecl();
// A heuristic: to resolve a template type to **only** its template name.
// We're only using this method for the base type of MemberExpr, in general
// the template provides the member, and the critical case `unique_ptr<Foo>`
@@ -135,17 +131,14 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
}
bool qualifierIsNamespaceOrNone(DeclRefExpr *DRE) {
- const auto *Qual = DRE->getQualifier();
- if (!Qual)
- return true;
- switch (Qual->getKind()) {
- case NestedNameSpecifier::Namespace:
- case NestedNameSpecifier::NamespaceAlias:
- case NestedNameSpecifier::Global:
+ NestedNameSpecifier Qual = DRE->getQualifier();
+ switch (Qual.getKind()) {
+ case NestedNameSpecifier::Kind::Null:
+ case NestedNameSpecifier::Kind::Namespace:
+ case NestedNameSpecifier::Kind::Global:
return true;
- case NestedNameSpecifier::TypeSpec:
- case NestedNameSpecifier::Super:
- case NestedNameSpecifier::Identifier:
+ case NestedNameSpecifier::Kind::Type:
+ case NestedNameSpecifier::Kind::Super:
return false;
}
llvm_unreachable("Unknown value for NestedNameSpecifierKind");
@@ -342,17 +335,17 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> {
}
bool VisitUsingTypeLoc(UsingTypeLoc TL) {
- reportType(TL.getNameLoc(), TL.getFoundDecl());
+ reportType(TL.getNameLoc(), TL.getDecl());
return true;
}
bool VisitTagTypeLoc(TagTypeLoc TTL) {
- reportType(TTL.getNameLoc(), TTL.getDecl());
+ reportType(TTL.getNameLoc(), TTL.getOriginalDecl());
return true;
}
bool VisitTypedefTypeLoc(TypedefTypeLoc TTL) {
- reportType(TTL.getNameLoc(), TTL.getTypedefNameDecl());
+ reportType(TTL.getNameLoc(), TTL.getDecl());
return true;
}
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp
index b42d3fcd2b62b..35314d12b59bf 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/copy-constructor-init.cpp
@@ -165,7 +165,6 @@ FROMMACRO
class X15 : public CopyableAlias2 {
X15(const X15 &other) {}
// CHECK-MESSAGES: :[[@LINE-1]]:3: warning: calling a base constructor
- // CHECK-FIXES: X15(const X15 &other) : Copyable5(other) {}
};
class X16 : public NonCopyable {
diff --git a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp
index 721c55b1fb538..5dd23871b21b3 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/bugprone/unused-local-non-trivial-variable.cpp
@@ -69,14 +69,14 @@ template<typename T>
T qux(T Generic) {
async::Future<Units> PendingA = acquireUnits();
auto PendingB = acquireUnits();
- // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'Future<Units>') [bugprone-unused-local-non-trivial-variable]
+ // CHECK-MESSAGES: :[[@LINE-1]]:10: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'async::Future<Units>') [bugprone-unused-local-non-trivial-variable]
async::Future<Units> MustBeUsed;
// CHECK-MESSAGES: :[[@LINE-1]]:26: warning: unused local variable 'MustBeUsed' of type 'async::Future<Units>' [bugprone-unused-local-non-trivial-variable]
PendingA.get();
async::Future<T> TemplateType;
// CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'TemplateType' of type 'async::Future<T>' [bugprone-unused-local-non-trivial-variable]
a::Future<T> AliasTemplateType;
- // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future<T>' (aka 'Future<T>') [bugprone-unused-local-non-trivial-variable]
+ // CHECK-MESSAGES: :[[@LINE-1]]:18: warning: unused local variable 'AliasTemplateType' of type 'a::Future<T>' (aka 'async::Future<T>') [bugprone-unused-local-non-trivial-variable]
[[maybe_unused]] async::Future<Units> MaybeUnused;
return Generic;
}
@@ -86,7 +86,7 @@ async::Future<int> Global;
int bar(int Num) {
a::Future<Units> PendingA = acquireUnits();
a::Future<Units> PendingB = acquireUnits(); // not used at all, unused variable not fired because of destructor side effect
- // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'Future<Units>') [bugprone-unused-local-non-trivial-variable]
+ // CHECK-MESSAGES: :[[@LINE-1]]:22: warning: unused local variable 'PendingB' of type 'a::Future<Units>' (aka 'async::Future<Units>') [bugprone-unused-local-non-trivial-variable]
auto Num2 = PendingA.get();
auto Num3 = qux(Num);
async::Ptr<a::Future<Units>> Shared = async::Ptr<a::Future<Units>>(acquireUnits());
diff --git a/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp b/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp
index 732cf5d34aca9..a38594aa94cbb 100644
--- a/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp
+++ b/clang-tools-extra/test/clang-tidy/checkers/portability/std-allocator-const.cpp
@@ -43,25 +43,25 @@ template <class T>
class allocator {};
void simple(const std::vector<const char> &v, std::deque<const short> *d) {
- // CHECK-MESSAGES: [[#@LINE-1]]:24: warning: container using std::allocator<const T> is a deprecated libc++ extension; remove const for compatibility with other standard libraries
- // CHECK-MESSAGES: [[#@LINE-2]]:52: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:19: warning: container using std::allocator<const T> is a deprecated libc++ extension; remove const for compatibility with other standard libraries
+ // CHECK-MESSAGES: [[#@LINE-2]]:47: warning: container
std::list<const long> l;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::multiset<int *const> ms;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::set<const std::hash<int>> s;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::unordered_multiset<int *const> ums;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::unordered_set<const int> us;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
absl::flat_hash_set<const int> fhs;
- // CHECK-MESSAGES: [[#@LINE-1]]:9: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
using my_vector = std::vector<const int>;
- // CHECK-MESSAGES: [[#@LINE-1]]:26: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:21: warning: container
my_vector v1;
using my_vector2 = my_vector;
@@ -76,7 +76,7 @@ void simple(const std::vector<const char> &v, std::deque<const short> *d) {
template <class T>
void temp1() {
std::vector<const T> v;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::vector<T> neg1;
std::forward_list<const T> neg2;
@@ -87,7 +87,7 @@ template <class T>
void temp2() {
// Match std::vector<const dependent> for the uninstantiated temp2.
std::vector<const T> v;
- // CHECK-MESSAGES: [[#@LINE-1]]:8: warning: container
+ // CHECK-MESSAGES: [[#@LINE-1]]:3: warning: container
std::vector<T> neg1;
std::forward_list<const T> neg2;
More information about the cfe-commits
mailing list