[llvm-branch-commits] [clang] [PATCH 2/6] [clang] Improve nested name specifier AST representation (PR #148012)
Matheus Izvekov via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Sun Jul 20 17:07:25 PDT 2025
https://github.com/mizvekov updated https://github.com/llvm/llvm-project/pull/148012
>From 533e5173b6a5c2b05f5f90f503324e7345eeba62 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] [PATCH 2/6] [clang] Improve nested name specifier AST
representation
Other changes
---
clang/include/clang/ASTMatchers/ASTMatchers.h | 117 ++---
.../clang/ASTMatchers/ASTMatchersInternal.h | 18 +-
.../clang/Analysis/FlowSensitive/ASTOps.h | 10 +-
clang/include/clang/Sema/DeclSpec.h | 24 +-
clang/include/clang/Sema/ParsedTemplate.h | 26 +-
clang/include/clang/Sema/Sema.h | 25 +-
.../clang/Serialization/ASTRecordWriter.h | 3 +-
clang/lib/ASTMatchers/ASTMatchFinder.cpp | 73 +--
clang/lib/ASTMatchers/ASTMatchersInternal.cpp | 5 +-
clang/lib/ASTMatchers/Dynamic/Registry.cpp | 5 +-
.../FlowSensitive/DataflowEnvironment.cpp | 6 +-
clang/lib/Analysis/UnsafeBufferUsage.cpp | 12 +-
clang/lib/CodeGen/CGCXXABI.cpp | 4 +-
clang/lib/CodeGen/CGCall.cpp | 10 +-
clang/lib/CodeGen/CGClass.cpp | 52 +-
clang/lib/CodeGen/CGDebugInfo.cpp | 95 ++--
clang/lib/CodeGen/CGDecl.cpp | 6 +-
clang/lib/CodeGen/CGExpr.cpp | 16 +-
clang/lib/CodeGen/CGExprCXX.cpp | 13 +-
clang/lib/CodeGen/CGHLSLRuntime.cpp | 3 +-
clang/lib/CodeGen/CGNonTrivialStruct.cpp | 3 +-
clang/lib/CodeGen/CGObjCMac.cpp | 4 +-
clang/lib/CodeGen/CGOpenMPRuntime.cpp | 23 +-
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 | 4 -
clang/lib/CodeGen/CodeGenModule.cpp | 22 +-
clang/lib/CodeGen/CodeGenTypes.cpp | 17 +-
clang/lib/CodeGen/ItaniumCXXABI.cpp | 21 +-
clang/lib/CodeGen/MicrosoftCXXABI.cpp | 25 +-
clang/lib/CodeGen/Targets/X86.cpp | 2 +-
clang/lib/ExtractAPI/DeclarationFragments.cpp | 68 +--
clang/lib/Frontend/ASTConsumers.cpp | 7 +-
clang/lib/Frontend/ASTUnit.cpp | 2 +-
clang/lib/Index/IndexTypeSourceInfo.cpp | 10 +-
clang/lib/Index/USRGeneration.cpp | 4 -
clang/lib/InstallAPI/Visitor.cpp | 4 +-
clang/lib/Parse/ParseExprCXX.cpp | 13 +-
clang/lib/Parse/ParseTemplate.cpp | 29 +-
clang/lib/Parse/Parser.cpp | 9 +-
clang/lib/Sema/DeclSpec.cpp | 6 +-
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp | 23 +-
clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.h | 2 +-
clang/lib/Sema/HeuristicResolver.cpp | 13 +-
clang/lib/Sema/SemaAccess.cpp | 35 +-
clang/lib/Sema/SemaCXXScopeSpec.cpp | 217 ++++----
clang/lib/Sema/SemaCast.cpp | 6 +-
clang/lib/Sema/SemaChecking.cpp | 28 +-
clang/lib/Sema/SemaCodeComplete.cpp | 86 ++--
clang/lib/Sema/SemaCoroutine.cpp | 31 +-
clang/lib/Sema/SemaDecl.cpp | 463 ++++++++++--------
clang/lib/Sema/SemaDeclAttr.cpp | 6 +-
clang/lib/Sema/SemaDeclCXX.cpp | 382 +++++++--------
clang/lib/Sema/SemaDeclObjC.cpp | 15 +-
clang/lib/Sema/SemaExceptionSpec.cpp | 5 +-
clang/lib/Sema/SemaExpr.cpp | 68 +--
clang/lib/Sema/SemaExprCXX.cpp | 101 ++--
clang/lib/Sema/SemaExprMember.cpp | 7 +-
clang/lib/Sema/SemaExprObjC.cpp | 6 +-
clang/lib/Sema/SemaFunctionEffects.cpp | 8 +-
clang/lib/Sema/SemaHLSL.cpp | 8 +-
clang/lib/Sema/SemaInit.cpp | 73 ++-
clang/lib/Sema/SemaLambda.cpp | 6 +-
clang/lib/Sema/SemaLookup.cpp | 51 +-
clang/lib/Sema/SemaOpenMP.cpp | 6 +-
clang/lib/Sema/SemaOverload.cpp | 93 ++--
clang/lib/Sema/SemaStmt.cpp | 18 +-
clang/lib/Sema/SemaStmtAsm.cpp | 4 +-
clang/lib/Sema/SemaTemplate.cpp | 318 ++++++------
clang/lib/Sema/SemaTemplateDeduction.cpp | 117 +++--
clang/lib/Sema/SemaTemplateDeductionGuide.cpp | 45 +-
clang/lib/Sema/SemaTemplateInstantiate.cpp | 67 +--
.../lib/Sema/SemaTemplateInstantiateDecl.cpp | 57 +--
clang/lib/Sema/SemaTemplateVariadic.cpp | 39 +-
clang/lib/Sema/SemaType.cpp | 148 +++---
clang/lib/Sema/SemaTypeTraits.cpp | 12 +-
clang/lib/Serialization/ASTReader.cpp | 74 +--
clang/lib/Serialization/ASTReaderDecl.cpp | 26 +-
clang/lib/Serialization/ASTWriter.cpp | 59 ++-
clang/lib/Serialization/ASTWriterDecl.cpp | 7 +-
.../Serialization/TemplateArgumentHasher.cpp | 6 +-
.../Checkers/DynamicTypePropagation.cpp | 2 +-
.../Checkers/LLVMConventionsChecker.cpp | 3 -
.../NonnullGlobalConstantsChecker.cpp | 5 +-
.../NumberObjectConversionChecker.cpp | 11 +-
.../Checkers/PaddingChecker.cpp | 14 +-
.../Checkers/StdLibraryFunctionsChecker.cpp | 4 +-
.../Checkers/WebKit/PtrTypesSemantics.cpp | 29 +-
.../WebKit/RefCntblBaseVirtualDtorChecker.cpp | 4 -
clang/lib/StaticAnalyzer/Core/CallEvent.cpp | 5 +-
clang/lib/StaticAnalyzer/Core/MemRegion.cpp | 4 +-
clang/lib/StaticAnalyzer/Core/SValBuilder.cpp | 4 +-
clang/lib/Tooling/ASTDiff/ASTDiff.cpp | 13 +-
clang/lib/Tooling/Refactoring/Lookup.cpp | 2 +-
.../Refactoring/Rename/USRLocFinder.cpp | 57 +--
clang/lib/Tooling/Syntax/BuildTree.cpp | 5 +-
.../lib/Tooling/Transformer/RangeSelector.cpp | 8 +-
clang/tools/libclang/CIndex.cpp | 30 +-
clang/tools/libclang/CXCursor.cpp | 6 -
clang/tools/libclang/CXIndexDataConsumer.cpp | 23 +-
clang/tools/libclang/CXType.cpp | 28 +-
104 files changed, 1885 insertions(+), 1931 deletions(-)
diff --git a/clang/include/clang/ASTMatchers/ASTMatchers.h b/clang/include/clang/ASTMatchers/ASTMatchers.h
index 08c898f7758ec..02d79b7488f82 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchers.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchers.h
@@ -222,6 +222,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
@@ -3740,7 +3753,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>>
@@ -4375,7 +4388,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;
@@ -7004,37 +7023,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
@@ -7301,7 +7289,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
@@ -7311,10 +7299,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.
///
@@ -7593,27 +7584,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
@@ -7628,34 +7599,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
diff --git a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
index 5df2294792552..f074bc5fed2cc 100644
--- a/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
+++ b/clang/include/clang/ASTMatchers/ASTMatchersInternal.h
@@ -1017,10 +1017,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);
@@ -1031,6 +1028,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);
}
@@ -1066,12 +1066,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.
@@ -1211,8 +1205,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>;
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/Sema/DeclSpec.h b/clang/include/clang/Sema/DeclSpec.h
index e5680813e74de..797ef9b601ebc 100644
--- a/clang/include/clang/Sema/DeclSpec.h
+++ b/clang/include/clang/Sema/DeclSpec.h
@@ -106,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::'.
@@ -189,14 +175,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) {
@@ -209,7 +195,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/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 b331acbe606b7..24dccffcd5675 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -3574,8 +3574,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.
@@ -11603,13 +11603,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,
@@ -11838,8 +11841,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);
@@ -15155,14 +15158,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/Serialization/ASTRecordWriter.h b/clang/include/clang/Serialization/ASTRecordWriter.h
index ee005ec287708..97178a4aa980c 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);
diff --git a/clang/lib/ASTMatchers/ASTMatchFinder.cpp b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
index 6d0ba0b7907a1..b0fa7f4c95719 100644
--- a/clang/lib/ASTMatchers/ASTMatchFinder.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchFinder.cpp
@@ -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);
@@ -396,13 +396,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;
@@ -577,13 +577,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 +1289,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 +1515,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
diff --git a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
index 80dc888811657..653b3810cb68b 100644
--- a/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
+++ b/clang/lib/ASTMatchers/ASTMatchersInternal.cpp
@@ -755,6 +755,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;
@@ -808,8 +810,6 @@ const internal::VariadicDynCastAllOfMatcher<TypeLoc, ReferenceTypeLoc>
const internal::VariadicDynCastAllOfMatcher<TypeLoc,
TemplateSpecializationTypeLoc>
templateSpecializationTypeLoc;
-const internal::VariadicDynCastAllOfMatcher<TypeLoc, ElaboratedTypeLoc>
- elaboratedTypeLoc;
const internal::VariadicDynCastAllOfMatcher<Stmt, UnaryExprOrTypeTraitExpr>
unaryExprOrTypeTraitExpr;
@@ -1103,7 +1103,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/UnsafeBufferUsage.cpp b/clang/lib/Analysis/UnsafeBufferUsage.cpp
index ac47b12cc8d72..8ffff91eb1216 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/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 0bceecec6e555..82216e8a748a3 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.
diff --git a/clang/lib/CodeGen/CGClass.cpp b/clang/lib/CodeGen/CGClass.cpp
index 4a465e6526da0..e6437a6865fd3 100644
--- a/clang/lib/CodeGen/CGClass.cpp
+++ b/clang/lib/CodeGen/CGClass.cpp
@@ -326,7 +326,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 +401,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 =
@@ -638,7 +637,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 +973,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 +1121,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) {
@@ -1588,7 +1587,7 @@ namespace {
const CXXRecordDecl *ClassDecl = Dtor->getParent();
CGF.EmitDeleteCall(Dtor->getOperatorDelete(),
LoadThisForDtorDelete(CGF, Dtor),
- CGF.getContext().getTagDeclType(ClassDecl));
+ CGF.getContext().getCanonicalTagType(ClassDecl));
}
};
@@ -1606,7 +1605,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 +1646,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 +1870,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);
@@ -2057,7 +2057,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));
@@ -2158,7 +2158,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 +2210,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 +2227,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;
@@ -2772,7 +2773,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);
@@ -2896,8 +2897,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 +2907,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 +2957,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 +3040,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 +3068,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 +3120,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 e24c68ed02865..d7918e8d3449a 100644
--- a/clang/lib/CodeGen/CGDebugInfo.cpp
+++ b/clang/lib/CodeGen/CGDebugInfo.cpp
@@ -366,7 +366,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;
}
@@ -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();
@@ -2831,12 +2833,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 +2908,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 +2917,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,7 +3021,7 @@ 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);
@@ -3076,7 +3078,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 +3100,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 +3109,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 +3656,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 +3693,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 +3742,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 +3817,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 +3850,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 +3910,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) {
@@ -4054,7 +4056,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:
@@ -4114,7 +4115,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;
@@ -4184,7 +4185,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))
@@ -4208,8 +4209,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;
@@ -4415,9 +4416,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()) {
@@ -5539,7 +5541,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");
@@ -5708,7 +5710,7 @@ 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())) {
@@ -5729,7 +5731,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;
@@ -5959,8 +5961,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
@@ -5972,10 +5972,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;
}
}
@@ -5994,7 +5993,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..6e0d55059cfeb 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 = ? }
diff --git a/clang/lib/CodeGen/CGExpr.cpp b/clang/lib/CodeGen/CGExpr.cpp
index 85c768807572f..f865ba5eb13a4 100644
--- a/clang/lib/CodeGen/CGExpr.cpp
+++ b/clang/lib/CodeGen/CGExpr.cpp
@@ -1198,9 +1198,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
@@ -1920,7 +1921,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;
@@ -5032,10 +5032,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 +5162,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);
diff --git a/clang/lib/CodeGen/CGExprCXX.cpp b/clang/lib/CodeGen/CGExprCXX.cpp
index 359e30cb8f5cd..e4791faaf187e 100644
--- a/clang/lib/CodeGen/CGExprCXX.cpp
+++ b/clang/lib/CodeGen/CGExprCXX.cpp
@@ -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);
}
diff --git a/clang/lib/CodeGen/CGHLSLRuntime.cpp b/clang/lib/CodeGen/CGHLSLRuntime.cpp
index a47d1cc22980d..65c708022fc09 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..8529ec4190d13 100644
--- a/clang/lib/CodeGen/CGNonTrivialStruct.cpp
+++ b/clang/lib/CodeGen/CGNonTrivialStruct.cpp
@@ -560,7 +560,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/CGObjCMac.cpp b/clang/lib/CodeGen/CGObjCMac.cpp
index 8c66176942cb5..14273dd2e5e12 100644
--- a/clang/lib/CodeGen/CGObjCMac.cpp
+++ b/clang/lib/CodeGen/CGObjCMac.cpp
@@ -5670,7 +5670,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));
@@ -6016,7 +6016,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/CGOpenMPRuntime.cpp b/clang/lib/CodeGen/CGOpenMPRuntime.cpp
index ce2dd4d76368a..7276b74a43ebb 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);
@@ -4015,7 +4016,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 +5715,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 +10641,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 +11223,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 +11719,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 ab345a598c4e8..1f03472d91a0f 100644
--- a/clang/lib/CodeGen/CodeGenFunction.cpp
+++ b/clang/lib/CodeGen/CodeGenFunction.cpp
@@ -2494,10 +2494,6 @@ void CodeGenFunction::EmitVariablyModifiedType(QualType type) {
case Type::PredefinedSugar:
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/CodeGenModule.cpp b/clang/lib/CodeGen/CodeGenModule.cpp
index 236cc3d9e8907..52a8e3fec539d 100644
--- a/clang/lib/CodeGen/CodeGenModule.cpp
+++ b/clang/lib/CodeGen/CodeGenModule.cpp
@@ -2793,7 +2793,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);
}
}
@@ -6737,7 +6737,7 @@ QualType CodeGenModule::getObjCFastEnumerationStateType() {
}
D->completeDefinition();
- ObjCFastEnumerationStateType = Context.getTagDeclType(D);
+ ObjCFastEnumerationStateType = Context.getCanonicalTagType(D);
}
return ObjCFastEnumerationStateType;
@@ -7247,7 +7247,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 +7467,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 +7937,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/CodeGenTypes.cpp b/clang/lib/CodeGen/CodeGenTypes.cpp
index c98503e4bbd26..d0209e03808ee 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();
@@ -725,8 +726,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 +792,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];
@@ -830,7 +833,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())
diff --git a/clang/lib/CodeGen/ItaniumCXXABI.cpp b/clang/lib/CodeGen/ItaniumCXXABI.cpp
index f4a99467010af..25f06050e59e7 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);
}
@@ -2016,7 +2016,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);
@@ -3815,9 +3815,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());
@@ -4554,9 +4552,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 +4571,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 +5152,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/Targets/X86.cpp b/clang/lib/CodeGen/Targets/X86.cpp
index abb91486e7ee6..1d0645751480d 100644
--- a/clang/lib/CodeGen/Targets/X86.cpp
+++ b/clang/lib/CodeGen/Targets/X86.cpp
@@ -2889,7 +2889,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,
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 51a6f6b779e77..63118d6bd5f12 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -273,26 +273,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.
@@ -303,7 +283,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);
}
@@ -396,14 +387,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)
@@ -413,14 +416,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("{ ... }",
@@ -432,6 +440,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/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 67ed17bdd7b5d..b2579c427ec44 100644
--- a/clang/lib/Frontend/ASTUnit.cpp
+++ b/clang/lib/Frontend/ASTUnit.cpp
@@ -396,7 +396,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 adc33b3abd822..bb4ff93be0397 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,
@@ -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());
diff --git a/clang/lib/Index/USRGeneration.cpp b/clang/lib/Index/USRGeneration.cpp
index 6a884f7be00e1..16dcf88cbded8 100644
--- a/clang/lib/Index/USRGeneration.cpp
+++ b/clang/lib/Index/USRGeneration.cpp
@@ -945,10 +945,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..5a5eba2ca10d6 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);
}
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/Parser.cpp b/clang/lib/Parse/Parser.cpp
index ff50b3f83908c..14ccf4d67e6ba 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/DeclSpec.cpp b/clang/lib/Sema/DeclSpec.cpp
index f0f1d66f66e93..3ea5aa55c1e94 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);
diff --git a/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp b/clang/lib/Sema/HLSLBuiltinTypeDeclBuilder.cpp
index 87f9ae07550c2..806800cb7b213 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 36c4add20b225..098b72692bd3a 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..5bd5d15c6709c 100644
--- a/clang/lib/Sema/HeuristicResolver.cpp
+++ b/clang/lib/Sema/HeuristicResolver.cpp
@@ -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;
diff --git a/clang/lib/Sema/SemaAccess.cpp b/clang/lib/Sema/SemaAccess.cpp
index 83a07a23f3414..576074a1f4aeb 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;
@@ -671,11 +668,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 +1066,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 +1095,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 +1123,7 @@ 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 (auto *RD = dyn_cast<CXXRecordDecl>(D);
+ if (const auto *RD = dyn_cast<CXXRecordDecl>(TD);
RD && RD->isInjectedClassName())
break;
PrevDecl = TD->getPreviousDecl();
@@ -1284,10 +1278,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);
}
@@ -1640,7 +1634,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),
@@ -1728,7 +1723,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);
@@ -1776,7 +1771,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);
diff --git a/clang/lib/Sema/SemaCXXScopeSpec.cpp b/clang/lib/Sema/SemaCXXScopeSpec.cpp
index 6ac04837708f6..8e055aacf5b27 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);
}
@@ -118,12 +115,12 @@ 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();
}
@@ -195,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.
@@ -207,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;
@@ -259,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);
}
@@ -324,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;
@@ -493,7 +487,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;
}
@@ -599,8 +604,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;
@@ -613,7 +618,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))
@@ -637,50 +642,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;
}
@@ -722,16 +721,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;
}
}
@@ -739,8 +756,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,
@@ -786,17 +814,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;
}
@@ -812,13 +842,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;
}
@@ -858,7 +890,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());
@@ -875,7 +907,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;
}
@@ -900,30 +933,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;
}
diff --git a/clang/lib/Sema/SemaCast.cpp b/clang/lib/Sema/SemaCast.cpp
index 01252a4bc69c6..41277a25410ef 100644
--- a/clang/lib/Sema/SemaCast.cpp
+++ b/clang/lib/Sema/SemaCast.cpp
@@ -1856,7 +1856,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;
}
}
@@ -2102,9 +2102,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()) ||
diff --git a/clang/lib/Sema/SemaChecking.cpp b/clang/lib/Sema/SemaChecking.cpp
index 5e523fe887318..223e2bc8a4a57 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))
@@ -7798,7 +7798,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))
@@ -8361,7 +8361,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);
}
}
}
@@ -9959,7 +9961,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);
@@ -15110,10 +15112,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())) &&
@@ -15122,6 +15123,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;
@@ -15634,7 +15636,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.
@@ -15664,9 +15666,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..443cb146c0ff3 100644
--- a/clang/lib/Sema/SemaCodeComplete.cpp
+++ b/clang/lib/Sema/SemaCodeComplete.cpp
@@ -951,7 +951,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 +1055,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 +1072,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);
}
@@ -1664,7 +1665,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 +1691,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 +1748,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 +2015,6 @@ static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context,
Policy.AnonymousTagLocations = false;
Policy.SuppressStrongLifetime = true;
Policy.SuppressUnwrittenScope = true;
- Policy.SuppressScope = true;
Policy.CleanUglifiedParameters = true;
return Policy;
}
@@ -2925,8 +2929,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 +3025,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;
}
@@ -3391,7 +3395,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 +3524,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;
@@ -5177,7 +5179,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 +5194,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);
@@ -5769,7 +5773,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).
@@ -7026,7 +7030,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 +7817,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 +8409,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 +8586,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 +8703,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 +8771,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 +8885,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 +8922,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 +9023,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 +10040,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 d193a33f22393..6f09a7cbb6e64 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,
@@ -1083,9 +1078,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 14403e65e8f42..b8a49b324d9b2 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,
@@ -530,20 +489,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'
@@ -786,7 +803,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)) {
@@ -1156,10 +1173,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 +2050,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 +2110,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 +2168,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 +2547,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 +2556,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 +2597,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 +2783,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 +2954,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 +5060,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;
@@ -5754,7 +5798,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 +5818,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 +5881,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 +6000,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 +6295,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 +6317,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;
}
- } while ((SpecLoc = SpecLoc.getPrefix()));
+ 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;
+ }
+ 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 +9097,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)) {
@@ -10763,7 +10819,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 +12323,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();
@@ -17478,6 +17534,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
@@ -17943,8 +18000,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())) {
@@ -17954,6 +18010,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;
}
}
@@ -18077,78 +18142,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;
+ }
}
}
@@ -18319,14 +18385,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;
}
@@ -18407,7 +18473,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);
}
}
@@ -18439,7 +18506,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)
@@ -18555,14 +18622,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");
@@ -20398,7 +20463,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 78f4804202ddc..efc99868c80d9 100644
--- a/clang/lib/Sema/SemaDeclAttr.cpp
+++ b/clang/lib/Sema/SemaDeclAttr.cpp
@@ -3766,7 +3766,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())
@@ -4713,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 f5b4614576086..7519fa91bd631 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(
@@ -2666,7 +2676,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);
@@ -3050,7 +3062,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 +3217,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 +4258,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 +4494,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 +4558,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 +4689,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 +4716,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 +4782,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 +4802,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 +5106,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 +5116,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 +5419,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);
@@ -5928,16 +5956,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 +6078,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 +6892,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 +7024,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 +7047,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 +7202,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 +7358,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(),
@@ -7782,9 +7807,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 +7844,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 +8303,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 +9004,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 +9027,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 +9058,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 +9511,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 +9937,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 +10270,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 +10318,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 +10337,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;
@@ -10626,7 +10651,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 +11081,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 +11455,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 +11723,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 {
@@ -12004,10 +12029,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 +12169,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 +12302,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) {
@@ -12584,7 +12593,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 +12878,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 {
@@ -13051,7 +13060,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 +13163,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 +13229,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 +13375,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;
}
@@ -13410,7 +13415,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 =
@@ -14003,7 +14008,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 +14139,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 +14424,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);
@@ -15042,9 +15045,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 +15306,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 +15317,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 +15403,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 +15695,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 +15706,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 +15798,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 +15945,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);
@@ -16639,10 +16646,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;
@@ -16682,8 +16689,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
@@ -16722,8 +16729,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:
@@ -17954,27 +17961,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);
@@ -18286,7 +18280,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;
@@ -18793,7 +18787,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()))
diff --git a/clang/lib/Sema/SemaDeclObjC.cpp b/clang/lib/Sema/SemaDeclObjC.cpp
index bbd104909956f..d228f432f0e1b 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);
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 45c7178c6965d..feaf1749c842f 100644
--- a/clang/lib/Sema/SemaExpr.cpp
+++ b/clang/lib/Sema/SemaExpr.cpp
@@ -2531,7 +2531,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;
@@ -2607,11 +2607,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());
@@ -2831,8 +2828,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");
@@ -2942,8 +2938,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
@@ -2964,13 +2980,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();
@@ -3001,7 +3010,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
@@ -4482,9 +4491,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;
@@ -5876,7 +5882,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;
}
@@ -12457,7 +12463,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()));
@@ -16211,8 +16217,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()
@@ -16923,7 +16929,7 @@ ExprResult Sema::ActOnSourceLocExpr(SourceLocIdentKind Kind,
return ExprError();
}
ResultTy = Context.getPointerType(
- Context.getRecordType(StdSourceLocationImplDecl).withConst());
+ Context.getCanonicalTagType(StdSourceLocationImplDecl).withConst());
break;
}
@@ -21239,16 +21245,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 0edfd6015cbd9..da17134bf39a6 100644
--- a/clang/lib/Sema/SemaExprCXX.cpp
+++ b/clang/lib/Sema/SemaExprCXX.cpp
@@ -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));
}
}
@@ -374,7 +373,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 +418,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 +435,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;
@@ -659,7 +660,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.
@@ -1214,7 +1215,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);
@@ -1244,7 +1245,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 =
@@ -1732,7 +1733,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();
@@ -1860,8 +1861,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;
}
@@ -2505,7 +2506,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),
@@ -2966,7 +2967,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)
@@ -3426,7 +3427,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);
@@ -3483,7 +3484,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);
@@ -3593,7 +3594,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};
@@ -3627,7 +3628,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:
@@ -4574,7 +4575,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;
@@ -5370,16 +5371,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();
@@ -6184,7 +6187,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);
@@ -6357,7 +6360,7 @@ QualType Sema::FindCompositePointerType(SourceLocation Loc,
return QualType();
Steps.emplace_back(Step::MemberPointer,
- Context.getTypeDeclType(Cls).getTypePtr());
+ Context.getCanonicalTagType(Cls).getTypePtr());
continue;
}
@@ -7243,16 +7246,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;
@@ -7296,16 +7296,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();
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..b8d548d3416d8 100644
--- a/clang/lib/Sema/SemaExprObjC.cpp
+++ b/clang/lib/Sema/SemaExprObjC.cpp
@@ -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
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 9276554bebf9d..f8012c450973d 100644
--- a/clang/lib/Sema/SemaHLSL.cpp
+++ b/clang/lib/Sema/SemaHLSL.cpp
@@ -372,7 +372,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()) {
@@ -457,7 +457,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();
}
}
@@ -507,8 +507,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());
}
diff --git a/clang/lib/Sema/SemaInit.cpp b/clang/lib/Sema/SemaInit.cpp
index 1c6f292454ed6..345a23ae99511 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);
@@ -1140,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) {
@@ -1442,7 +1433,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());
@@ -2320,7 +2311,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.
@@ -2889,7 +2880,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())
@@ -4337,8 +4328,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);
}
@@ -8808,8 +8799,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,
@@ -9208,24 +9199,26 @@ 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);
@@ -9233,7 +9226,7 @@ bool InitializationSequence::Diagnose(Sema &S,
= Entity.getType()->getAs<RecordType>())
S.Diag(Record->getDecl()->getLocation(),
diag::note_previous_decl)
- << S.Context.getTagDeclType(Record->getDecl());
+ << S.Context.getCanonicalTagType(Record->getOriginalDecl());
}
break;
}
@@ -9300,11 +9293,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());
@@ -10157,7 +10150,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);
@@ -10297,8 +10290,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 bc3c4b0addeba..56bebb213e3e9 100644
--- a/clang/lib/Sema/SemaLambda.cpp
+++ b/clang/lib/Sema/SemaLambda.cpp
@@ -425,7 +425,7 @@ bool Sema::DiagnoseInvalidExplicitObjectParameterInLambda(
.getNonReferenceType()
.getUnqualifiedType()
.getDesugaredType(getASTContext());
- QualType LambdaType = getASTContext().getRecordType(RD);
+ CanQualType LambdaType = getASTContext().getCanonicalTagType(RD);
if (LambdaType == ExplicitObjectParameterType)
return false;
@@ -457,7 +457,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;
@@ -759,7 +759,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 8bde18f64f80b..b00f61d9c00f6 100644
--- a/clang/lib/Sema/SemaLookup.cpp
+++ b/clang/lib/Sema/SemaLookup.cpp
@@ -563,9 +563,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;
@@ -717,7 +716,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.
@@ -730,7 +729,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
@@ -1001,7 +1001,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) {
@@ -2435,12 +2435,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;
@@ -2596,10 +2596,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();
}
@@ -2731,7 +2729,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,
@@ -2772,10 +2772,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
@@ -3101,7 +3103,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
@@ -3438,7 +3440,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;
@@ -3645,7 +3647,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);
}
@@ -4853,7 +4855,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 +4866,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);
}
@@ -5463,7 +5464,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/SemaOpenMP.cpp b/clang/lib/Sema/SemaOpenMP.cpp
index 4ecc9b0d4c5c8..738692755a0ab 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
diff --git a/clang/lib/Sema/SemaOverload.cpp b/clang/lib/Sema/SemaOverload.cpp
index 5dd5b495480d9..7ce6c52fc4f7a 100644
--- a/clang/lib/Sema/SemaOverload.cpp
+++ b/clang/lib/Sema/SemaOverload.cpp
@@ -1268,7 +1268,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 +1471,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 +2292,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 &&
@@ -2679,8 +2678,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 +3345,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();
@@ -3658,8 +3656,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;
@@ -5934,7 +5931,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.
@@ -7160,7 +7157,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 +7179,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 +7401,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();
@@ -8159,29 +8157,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;
};
@@ -9009,8 +9002,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;
@@ -10955,9 +10948,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();
@@ -14863,8 +14856,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;
@@ -15025,7 +15018,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();
@@ -15408,7 +15401,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(
@@ -15878,7 +15871,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();
@@ -16541,7 +16534,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
@@ -16686,7 +16679,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();
diff --git a/clang/lib/Sema/SemaStmt.cpp b/clang/lib/Sema/SemaStmt.cpp
index f85826aecadf3..aa03d36bb69f2 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;
@@ -1719,6 +1719,7 @@ Sema::ActOnFinishSwitchStmt(SourceLocation SwitchLoc, Stmt *Switch,
if (!hasCasesNotInSwitch)
SS->setAllEnumCasesCovered();
}
+ enum_out:;
}
if (BodyStmt)
@@ -4619,7 +4620,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);
@@ -4661,9 +4663,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);
@@ -4683,7 +4686,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..ceca15dd3e388 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)
@@ -919,7 +919,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();
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 698d1270be634..68f637fd8eab2 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -397,7 +397,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 +799,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 +909,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 +926,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 +969,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);
@@ -2139,12 +2138,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 +2628,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 +2669,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
@@ -3100,7 +3097,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 +3106,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 +3121,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();
@@ -3287,11 +3286,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 +3336,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 +3373,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 +3494,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 +3559,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 +3611,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 +3690,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 +3730,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 +3780,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 +3791,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 +3840,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 +3851,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;
@@ -3903,12 +3917,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 +3933,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,18 +3990,8 @@ 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);
@@ -4022,21 +4013,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));
}
@@ -5293,8 +5272,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 +5286,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;
@@ -5897,8 +5876,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) {
@@ -6270,11 +6249,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;
}
@@ -8690,7 +8668,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.
@@ -8706,18 +8683,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:
@@ -8784,7 +8757,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)
@@ -8847,6 +8820,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
@@ -9885,9 +9865,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
@@ -10255,7 +10232,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;
}
@@ -10914,7 +10891,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;
@@ -10922,18 +10902,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);
}
@@ -10999,19 +10969,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;
}
@@ -11116,6 +11100,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
@@ -11131,15 +11116,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:
@@ -11149,22 +11139,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 e1a975bcfb3e1..902b97e99cc8a 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) {
@@ -2853,13 +2846,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 +3068,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.
@@ -3435,7 +3427,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 {
@@ -4105,7 +4097,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();
@@ -5061,10 +5053,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;
}
@@ -6379,8 +6373,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);
@@ -6389,9 +6383,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);
@@ -6761,7 +6754,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;
}
@@ -6879,7 +6872,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 9be1c9c356cb2..037001a0b2bbc 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)));
@@ -327,7 +327,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 +593,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 +957,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 +974,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>()) {
@@ -1048,12 +1049,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()->getAsNonAliasTemplateSpecializationType();
+ 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 20bac0e56b195..163994c17caa6 100644
--- a/clang/lib/Sema/SemaTemplateInstantiate.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiate.cpp
@@ -1165,7 +1165,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()
@@ -1649,22 +1649,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;
}
@@ -2083,37 +2079,6 @@ 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,
@@ -2182,9 +2147,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 +3125,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());
}
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index e2c3cdcd536bc..76da4deab1e9c 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -2250,8 +2250,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);
@@ -2271,8 +2270,6 @@ Decl *TemplateDeclInstantiator::VisitClassTemplateDecl(ClassTemplateDecl *D) {
if (PrevClassTemplate) {
Inst->setCommonPtr(PrevClassTemplate->getCommonPtr());
- RecordInst->setTypeForDecl(
- PrevClassTemplate->getTemplatedDecl()->getTypeForDecl());
const ClassTemplateDecl *MostRecentPrevCT =
PrevClassTemplate->getMostRecentDecl();
TemplateParameterList *PrevParams =
@@ -2306,10 +2303,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);
@@ -2515,11 +2508,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))
@@ -2528,7 +2519,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.
@@ -3164,8 +3154,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,
@@ -3907,7 +3897,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).
@@ -4819,18 +4809,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);
@@ -4861,7 +4846,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;
}
@@ -5754,11 +5739,15 @@ void Sema::InstantiateFunctionDefinition(SourceLocation PointOfInstantiation,
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;
}
@@ -6920,7 +6909,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
@@ -6986,13 +6976,12 @@ 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())
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();
@@ -7041,8 +7030,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,
@@ -7057,7 +7046,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 7dbd4bb0ed125..3d301624eb366 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: {
@@ -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 {
@@ -3462,7 +3459,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);
}
}
@@ -5103,7 +5100,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
@@ -5900,7 +5897,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());
@@ -5931,16 +5970,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 ||
@@ -5989,24 +6021,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;
@@ -6065,7 +6079,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) {
@@ -7031,9 +7067,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)
@@ -9172,11 +9205,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;
}
@@ -9314,7 +9345,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;
@@ -9354,10 +9385,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;
@@ -9494,10 +9525,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())
@@ -9630,15 +9661,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");
diff --git a/clang/lib/Sema/SemaTypeTraits.cpp b/clang/lib/Sema/SemaTypeTraits.cpp
index 1d8687e4bf1c1..a541f1ff692bd 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;
@@ -599,6 +598,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 +606,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 +625,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;
}
diff --git a/clang/lib/Serialization/ASTReader.cpp b/clang/lib/Serialization/ASTReader.cpp
index 10aedb68fcd9d..2e5e1b60f16de 100644
--- a/clang/lib/Serialization/ASTReader.cpp
+++ b/clang/lib/Serialization/ASTReader.cpp
@@ -7227,6 +7227,7 @@ class TypeLocReader : public TypeLocVisitor<TypeLocReader> {
void VisitFunctionTypeLoc(FunctionTypeLoc);
void VisitArrayTypeLoc(ArrayTypeLoc);
+ void VisitTagTypeLoc(TagTypeLoc TL);
};
} // namespace clang
@@ -7373,15 +7374,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) {
@@ -7435,17 +7445,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());
}
@@ -7483,14 +7503,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) {
@@ -7498,15 +7522,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());
@@ -9583,12 +9598,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;
}
@@ -10534,12 +10543,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 bd84a9741d01b..922440e949756 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) {
@@ -2236,15 +2241,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: {
@@ -2478,14 +2474,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 a6957e54b66f1..ef7190da062ea 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) {
@@ -1038,7 +1046,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);
@@ -6772,22 +6779,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:
@@ -6810,7 +6817,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) {
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index e414910469a64..1ce75eba525b1 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) {
@@ -2560,7 +2561,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(
@@ -2606,7 +2606,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..353e8a2daa925 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());
}
@@ -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/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/LLVMConventionsChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/LLVMConventionsChecker.cpp
index 1cb3848cfed2a..29ed4ad171aec 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;
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..844316c4a8f7d 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
@@ -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 52b3d1e95942c..844447f59f7f6 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..d53aad46d7699 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,8 +244,10 @@ 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;
}
@@ -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) {
diff --git a/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp b/clang/lib/StaticAnalyzer/Checkers/WebKit/RefCntblBaseVirtualDtorChecker.cpp
index 98c587d62978b..3be2b19574e40 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();
diff --git a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
index 34fcb9b64d555..e99816fa782d8 100644
--- a/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
+++ b/clang/lib/StaticAnalyzer/Core/CallEvent.cpp
@@ -843,7 +843,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 +854,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 3e68373028b10..37117b55abd12 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/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..8372371aff368 100644
--- a/clang/lib/Tooling/Refactoring/Lookup.cpp
+++ b/clang/lib/Tooling/Refactoring/Lookup.cpp
@@ -217,7 +217,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..7d153ec958bef 100644
--- a/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/clang/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -203,8 +203,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 +217,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 +235,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
RenameInfos.push_back({StartLoc, EndLoc,
/*FromDecl=*/nullptr,
/*Context=*/nullptr,
- /*Specifier=*/nullptr,
+ /*Specifier=*/std::nullopt,
/*IgnorePrefixQualifiers=*/true});
}
}
@@ -257,7 +257,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
RenameInfos.push_back({Loc, Loc,
/*FromDecl=*/nullptr,
/*Context=*/nullptr,
- /*Specifier=*/nullptr,
+ /*Specifier=*/std::nullopt,
/*IgnorePrefixQualifiers=*/true});
}
}
@@ -288,7 +288,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 +332,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
Decl,
getClosestAncestorDecl(*Expr),
Expr->getQualifier(),
- /*IgnorePrefixQualifers=*/false};
+ /*IgnorePrefixQualifiers=*/false};
RenameInfos.push_back(Info);
}
@@ -411,7 +411,7 @@ class RenameLocFinder : public RecursiveASTVisitor<RenameLocFinder> {
TargetDecl,
getClosestAncestorDecl(Loc),
GetNestedNameForType(Loc),
- /*IgnorePrefixQualifers=*/false};
+ /*IgnorePrefixQualifiers=*/false};
RenameInfos.push_back(Info);
}
return true;
@@ -421,33 +421,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 +453,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 +528,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 eb9fa7a7fa1e8..2e43714b16c1c 100644
--- a/clang/lib/Tooling/Syntax/BuildTree.cpp
+++ b/clang/lib/Tooling/Syntax/BuildTree.cpp
@@ -1328,7 +1328,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;
@@ -1391,7 +1391,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 9412d9735ef82..27ab412e1e685 100644
--- a/clang/tools/libclang/CIndex.cpp
+++ b/clang/tools/libclang/CIndex.cpp
@@ -1677,10 +1677,16 @@ bool CursorVisitor::VisitPredefinedSugarTypeLoc(PredefinedSugarTypeLoc TL) {
}
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));
@@ -1763,7 +1769,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));
}
@@ -1826,7 +1835,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;
@@ -1836,7 +1845,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.
@@ -1883,13 +1892,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());
}
@@ -5360,9 +5362,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/CXCursor.cpp b/clang/tools/libclang/CXCursor.cpp
index a6301daa672c3..a51efe28c0b01 100644
--- a/clang/tools/libclang/CXCursor.cpp
+++ b/clang/tools/libclang/CXCursor.cpp
@@ -1332,12 +1332,6 @@ 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>())
diff --git a/clang/tools/libclang/CXIndexDataConsumer.cpp b/clang/tools/libclang/CXIndexDataConsumer.cpp
index f0d92e8c40124..ebab5135605b6 100644
--- a/clang/tools/libclang/CXIndexDataConsumer.cpp
+++ b/clang/tools/libclang/CXIndexDataConsumer.cpp
@@ -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..0c2b2c08fd9d5 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);
@@ -566,11 +567,7 @@ CXCursor clang_getTypeDeclaration(CXType CT) {
D = cast<InjectedClassNameType>(TP)->getDecl();
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));
@@ -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));
}
More information about the llvm-branch-commits
mailing list