llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-libcxx Author: Matheus Izvekov (mizvekov) <details> <summary>Changes</summary> This makes it so clang can better represent the abscence of the template keyword for a template which cannot be resolved due to a dependent prefix. The tracking of the template keyword is removed from the NestedNameSpecifier, and added to the last type node which had it missing, the DependentTemplateSpecializationType (DTST). The DTST and the DependentTemplateName are refactored to share most of their implementation. That refactoring along with the removal of the TypeSpecWithTemplate kind from the nested name specifiers amounts to a large amount of code removed, making this patch a small performance improvement overall.  This will also enable future further simplifications. As a drive-by, this removes some special cases from the type printer, allowing template arguments within NestedNameSpecifiers to not have their nested names suppressed when printing. --- Patch is 139.90 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/133610.diff 66 Files Affected: - (modified) clang-tools-extra/clangd/AST.cpp (+1-2) - (modified) clang-tools-extra/clangd/CodeComplete.cpp (-1) - (modified) clang-tools-extra/clangd/DumpAST.cpp (-1) - (modified) clang-tools-extra/clangd/FindTarget.cpp (-1) - (modified) clang-tools-extra/include-cleaner/lib/WalkAST.cpp (-1) - (modified) clang/docs/ReleaseNotes.rst (+4) - (modified) clang/include/clang/AST/ASTContext.h (+9-11) - (modified) clang/include/clang/AST/ASTImporter.h (+8) - (modified) clang/include/clang/AST/ASTNodeTraverser.h (+1-2) - (modified) clang/include/clang/AST/AbstractBasicReader.h (+1-3) - (modified) clang/include/clang/AST/AbstractBasicWriter.h (-1) - (modified) clang/include/clang/AST/NestedNameSpecifier.h (+5-15) - (modified) clang/include/clang/AST/ODRHash.h (+1) - (modified) clang/include/clang/AST/PropertiesBase.td (+8-7) - (modified) clang/include/clang/AST/RecursiveASTVisitor.h (+2-3) - (modified) clang/include/clang/AST/TemplateName.h (+56-77) - (modified) clang/include/clang/AST/Type.h (+8-14) - (modified) clang/include/clang/AST/TypeLoc.h (+5-4) - (modified) clang/include/clang/AST/TypeProperties.td (+25-22) - (modified) clang/include/clang/Sema/DeclSpec.h (+1-2) - (modified) clang/lib/AST/ASTContext.cpp (+81-133) - (modified) clang/lib/AST/ASTImporter.cpp (+22-41) - (modified) clang/lib/AST/ASTStructuralEquivalence.cpp (+19-18) - (modified) clang/lib/AST/ItaniumMangle.cpp (+22-13) - (modified) clang/lib/AST/NestedNameSpecifier.cpp (+23-79) - (modified) clang/lib/AST/ODRHash.cpp (+15-4) - (modified) clang/lib/AST/QualTypeNames.cpp (+3-5) - (modified) clang/lib/AST/TemplateName.cpp (+58-9) - (modified) clang/lib/AST/TextNodeDumper.cpp (-4) - (modified) clang/lib/AST/Type.cpp (+10-17) - (modified) clang/lib/AST/TypeLoc.cpp (+3-2) - (modified) clang/lib/AST/TypePrinter.cpp (+7-5) - (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (-7) - (modified) clang/lib/Index/IndexTypeSourceInfo.cpp (-1) - (modified) clang/lib/Parse/ParseExprCXX.cpp (+4-4) - (modified) clang/lib/Sema/DeclSpec.cpp (+3-3) - (modified) clang/lib/Sema/HeuristicResolver.cpp (+3-3) - (modified) clang/lib/Sema/SemaCXXScopeSpec.cpp (+12-19) - (modified) clang/lib/Sema/SemaCodeComplete.cpp (+3-3) - (modified) clang/lib/Sema/SemaCoroutine.cpp (+1-2) - (modified) clang/lib/Sema/SemaDecl.cpp (+12-12) - (modified) clang/lib/Sema/SemaDeclCXX.cpp (+1-2) - (modified) clang/lib/Sema/SemaExpr.cpp (+1-1) - (modified) clang/lib/Sema/SemaExprCXX.cpp (-1) - (modified) clang/lib/Sema/SemaLookup.cpp (+1-3) - (modified) clang/lib/Sema/SemaTemplate.cpp (+19-22) - (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (+2-1) - (modified) clang/lib/Sema/TreeTransform.h (+73-76) - (modified) clang/lib/Serialization/ASTReader.cpp (+2-8) - (modified) clang/lib/Serialization/ASTWriter.cpp (-2) - (modified) clang/lib/Tooling/Syntax/BuildTree.cpp (-2) - (modified) clang/test/AST/ast-dump-decl.cpp (+10-10) - (modified) clang/test/AST/ast-dump-expr.cpp (+1-2) - (modified) clang/test/AST/ast-dump-templates.cpp (+3-3) - (modified) clang/test/CXX/class.access/p6.cpp (+2-2) - (modified) clang/test/CXX/drs/cwg2xx.cpp (+2-2) - (modified) clang/test/CXX/expr/expr.prim/expr.prim.req/nested-requirement.cpp (+1-1) - (modified) clang/test/SemaCXX/static-assert.cpp (+3-1) - (modified) clang/test/SemaTemplate/aggregate-deduction-candidate.cpp (+4-4) - (modified) clang/test/SemaTemplate/dependent-template-recover.cpp (+18) - (modified) clang/test/SemaTemplate/instantiate-requires-expr.cpp (+2-2) - (modified) clang/tools/libclang/CIndex.cpp (-2) - (modified) libcxx/test/std/containers/sequences/array/array.overview/nttp.verify.cpp (+1-1) - (modified) libcxx/test/std/utilities/smartptr/adapt/inout_ptr/inout_ptr.verify.cpp (+1-1) - (modified) libcxx/test/std/utilities/smartptr/adapt/out_ptr/out_ptr.verify.cpp (+1-1) - (modified) libcxx/test/std/utilities/utility/pairs/pairs.pair/nttp.verify.cpp (+2-1) ``````````diff diff --git a/clang-tools-extra/clangd/AST.cpp b/clang-tools-extra/clangd/AST.cpp index f3eee1c6335f9..66b587f00ff4a 100644 --- a/clang-tools-extra/clangd/AST.cpp +++ b/clang-tools-extra/clangd/AST.cpp @@ -119,8 +119,7 @@ getQualification(ASTContext &Context, const DeclContext *DestContext, // There can't be any more tag parents after hitting a namespace. assert(!ReachedNS); (void)ReachedNS; - NNS = NestedNameSpecifier::Create(Context, nullptr, false, - TD->getTypeForDecl()); + NNS = NestedNameSpecifier::Create(Context, nullptr, TD->getTypeForDecl()); } else if (auto *NSD = llvm::dyn_cast<NamespaceDecl>(CurContext)) { ReachedNS = true; NNS = NestedNameSpecifier::Create(Context, nullptr, NSD); diff --git a/clang-tools-extra/clangd/CodeComplete.cpp b/clang-tools-extra/clangd/CodeComplete.cpp index 008cc96c91996..0eb196fbad46a 100644 --- a/clang-tools-extra/clangd/CodeComplete.cpp +++ b/clang-tools-extra/clangd/CodeComplete.cpp @@ -1467,7 +1467,6 @@ bool allowIndex(CodeCompletionContext &CC) { return true; case NestedNameSpecifier::Super: case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: // Unresolved inside a template. case NestedNameSpecifier::Identifier: return false; diff --git a/clang-tools-extra/clangd/DumpAST.cpp b/clang-tools-extra/clangd/DumpAST.cpp index e605f82e91fe4..584bb1f088380 100644 --- a/clang-tools-extra/clangd/DumpAST.cpp +++ b/clang-tools-extra/clangd/DumpAST.cpp @@ -157,7 +157,6 @@ class DumpVisitor : public RecursiveASTVisitor<DumpVisitor> { NNS_KIND(Identifier); NNS_KIND(Namespace); NNS_KIND(TypeSpec); - NNS_KIND(TypeSpecWithTemplate); NNS_KIND(Global); NNS_KIND(Super); NNS_KIND(NamespaceAlias); diff --git a/clang-tools-extra/clangd/FindTarget.cpp b/clang-tools-extra/clangd/FindTarget.cpp index bb4c91b831354..62f220b32bd10 100644 --- a/clang-tools-extra/clangd/FindTarget.cpp +++ b/clang-tools-extra/clangd/FindTarget.cpp @@ -500,7 +500,6 @@ struct TargetFinder { } return; case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: add(QualType(NNS->getAsType(), 0), Flags); return; case NestedNameSpecifier::Global: diff --git a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp index 7a140c991925c..dff0c711f04c5 100644 --- a/clang-tools-extra/include-cleaner/lib/WalkAST.cpp +++ b/clang-tools-extra/include-cleaner/lib/WalkAST.cpp @@ -144,7 +144,6 @@ class ASTWalker : public RecursiveASTVisitor<ASTWalker> { case NestedNameSpecifier::Global: return true; case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: case NestedNameSpecifier::Super: case NestedNameSpecifier::Identifier: return false; diff --git a/clang/docs/ReleaseNotes.rst b/clang/docs/ReleaseNotes.rst index eaecead0e6b9d..3ae852d59bbf8 100644 --- a/clang/docs/ReleaseNotes.rst +++ b/clang/docs/ReleaseNotes.rst @@ -275,6 +275,10 @@ Improvements to Clang's diagnostics - Diagnostics on chained comparisons (``a < b < c``) are now an error by default. This can be disabled with ``-Wno-error=parentheses``. - Clang now better preserves the sugared types of pointers to member. +- Clang now better preserves the presence of the template keyword with dependent + prefixes. +- When printing types for diagnostics, clang now doesn't suppress the scopes of + template arguments contained within nested names. - The ``-Wshift-bool`` warning has been added to warn about shifting a boolean. (#GH28334) - Fixed diagnostics adding a trailing ``::`` when printing some source code constructs, like base classes. diff --git a/clang/include/clang/AST/ASTContext.h b/clang/include/clang/AST/ASTContext.h index af8c49e99a7ce..6fbe170e17242 100644 --- a/clang/include/clang/AST/ASTContext.h +++ b/clang/include/clang/AST/ASTContext.h @@ -1837,15 +1837,15 @@ class ASTContext : public RefCountedBase<ASTContext> { TagDecl *OwnedTagDecl = nullptr) const; QualType getDependentNameType(ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, - const IdentifierInfo *Name, - QualType Canon = QualType()) const; + const IdentifierInfo *Name) const; QualType getDependentTemplateSpecializationType( - ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, - const IdentifierInfo *Name, ArrayRef<TemplateArgumentLoc> Args) const; - QualType getDependentTemplateSpecializationType( - ElaboratedTypeKeyword Keyword, NestedNameSpecifier *NNS, - const IdentifierInfo *Name, ArrayRef<TemplateArgument> Args) const; + ElaboratedTypeKeyword Keyword, const DependentTemplateStorage &Name, + ArrayRef<TemplateArgumentLoc> Args) const; + QualType + getDependentTemplateSpecializationType(ElaboratedTypeKeyword Keyword, + const DependentTemplateStorage &Name, + ArrayRef<TemplateArgument> Args) const; TemplateArgument getInjectedTemplateArg(NamedDecl *ParamDecl) const; @@ -2394,10 +2394,8 @@ class ASTContext : public RefCountedBase<ASTContext> { bool TemplateKeyword, TemplateName Template) const; - TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, - const IdentifierInfo *Name) const; - TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, - OverloadedOperatorKind Operator) const; + TemplateName + getDependentTemplateName(const DependentTemplateStorage &Name) const; TemplateName getSubstTemplateTemplateParm(TemplateName replacement, Decl *AssociatedDecl, unsigned Index, diff --git a/clang/include/clang/AST/ASTImporter.h b/clang/include/clang/AST/ASTImporter.h index 8c3fa842ab8b9..a2550716e3c7f 100644 --- a/clang/include/clang/AST/ASTImporter.h +++ b/clang/include/clang/AST/ASTImporter.h @@ -446,6 +446,14 @@ class TypeSourceInfo; /// returns nullptr only if the FromId was nullptr. IdentifierInfo *Import(const IdentifierInfo *FromId); + /// Import the given identifier or overloaded operator from the "from" + /// context into the "to" context. + /// + /// \returns The equivalent identifier or overloaded operator in the "to" + /// context. + IdentifierOrOverloadedOperator + Import(IdentifierOrOverloadedOperator FromIO); + /// Import the given Objective-C selector from the "from" /// context into the "to" context. /// diff --git a/clang/include/clang/AST/ASTNodeTraverser.h b/clang/include/clang/AST/ASTNodeTraverser.h index 83a6b77704f34..f086d8134a64b 100644 --- a/clang/include/clang/AST/ASTNodeTraverser.h +++ b/clang/include/clang/AST/ASTNodeTraverser.h @@ -396,8 +396,7 @@ class ASTNodeTraverser // FIXME: Provide a NestedNameSpecifier visitor. NestedNameSpecifier *Qualifier = T->getQualifier(); if (NestedNameSpecifier::SpecifierKind K = Qualifier->getKind(); - K == NestedNameSpecifier::TypeSpec || - K == NestedNameSpecifier::TypeSpecWithTemplate) + K == NestedNameSpecifier::TypeSpec) Visit(Qualifier->getAsType()); if (T->isSugared()) Visit(T->getMostRecentCXXRecordDecl()->getTypeForDecl()); diff --git a/clang/include/clang/AST/AbstractBasicReader.h b/clang/include/clang/AST/AbstractBasicReader.h index 4b627c65e276b..5ab438715ecf7 100644 --- a/clang/include/clang/AST/AbstractBasicReader.h +++ b/clang/include/clang/AST/AbstractBasicReader.h @@ -279,10 +279,8 @@ class DataStreamBasicReader : public BasicReaderBase<Impl> { continue; case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: cur = NestedNameSpecifier::Create(ctx, cur, - kind == NestedNameSpecifier::TypeSpecWithTemplate, - asImpl().readQualType().getTypePtr()); + asImpl().readQualType().getTypePtr()); continue; case NestedNameSpecifier::Global: diff --git a/clang/include/clang/AST/AbstractBasicWriter.h b/clang/include/clang/AST/AbstractBasicWriter.h index b941add8bde88..f65d94abc2ff1 100644 --- a/clang/include/clang/AST/AbstractBasicWriter.h +++ b/clang/include/clang/AST/AbstractBasicWriter.h @@ -260,7 +260,6 @@ class DataStreamBasicWriter : public BasicWriterBase<Impl> { continue; case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: asImpl().writeQualType(QualType(NNS->getAsType(), 0)); continue; diff --git a/clang/include/clang/AST/NestedNameSpecifier.h b/clang/include/clang/AST/NestedNameSpecifier.h index 273e73e7c1e95..d7da3272d0943 100644 --- a/clang/include/clang/AST/NestedNameSpecifier.h +++ b/clang/include/clang/AST/NestedNameSpecifier.h @@ -52,8 +52,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode { enum StoredSpecifierKind { StoredIdentifier = 0, StoredDecl = 1, - StoredTypeSpec = 2, - StoredTypeSpecWithTemplate = 3 + StoredTypeSpec = 2 }; /// The nested name specifier that precedes this nested name @@ -89,10 +88,6 @@ class NestedNameSpecifier : public llvm::FoldingSetNode { /// A type, stored as a Type*. TypeSpec, - /// A type that was preceded by the 'template' keyword, - /// stored as a Type*. - TypeSpecWithTemplate, - /// The global specifier '::'. There is no stored value. Global, @@ -137,9 +132,8 @@ class NestedNameSpecifier : public llvm::FoldingSetNode { const NamespaceAliasDecl *Alias); /// Builds a nested name specifier that names a type. - static NestedNameSpecifier *Create(const ASTContext &Context, - NestedNameSpecifier *Prefix, - bool Template, const Type *T); + static NestedNameSpecifier * + Create(const ASTContext &Context, NestedNameSpecifier *Prefix, const Type *T); /// Builds a specifier that consists of just an identifier. /// @@ -194,8 +188,7 @@ class NestedNameSpecifier : public llvm::FoldingSetNode { /// Retrieve the type stored in this nested name specifier. const Type *getAsType() const { - if (Prefix.getInt() == StoredTypeSpec || - Prefix.getInt() == StoredTypeSpecWithTemplate) + if (Prefix.getInt() == StoredTypeSpec) return (const Type *)Specifier; return nullptr; @@ -401,13 +394,10 @@ class NestedNameSpecifierLocBuilder { /// \param Context The AST context in which this nested-name-specifier /// resides. /// - /// \param TemplateKWLoc The location of the 'template' keyword, if present. - /// /// \param TL The TypeLoc that describes the type preceding the '::'. /// /// \param ColonColonLoc The location of the trailing '::'. - void Extend(ASTContext &Context, SourceLocation TemplateKWLoc, TypeLoc TL, - SourceLocation ColonColonLoc); + void Extend(ASTContext &Context, TypeLoc TL, SourceLocation ColonColonLoc); /// Extend the current nested-name-specifier by another /// nested-name-specifier component of the form 'identifier::'. diff --git a/clang/include/clang/AST/ODRHash.h b/clang/include/clang/AST/ODRHash.h index a1caa6d39a87c..a923901b32dc0 100644 --- a/clang/include/clang/AST/ODRHash.h +++ b/clang/include/clang/AST/ODRHash.h @@ -94,6 +94,7 @@ class ODRHash { void AddStmt(const Stmt *S); void AddIdentifierInfo(const IdentifierInfo *II); void AddNestedNameSpecifier(const NestedNameSpecifier *NNS); + void AddDependentTemplateName(const DependentTemplateStorage &Name); void AddTemplateName(TemplateName Name); void AddDeclarationName(DeclarationName Name, bool TreatAsDecl = false); void AddTemplateArgument(TemplateArgument TA); diff --git a/clang/include/clang/AST/PropertiesBase.td b/clang/include/clang/AST/PropertiesBase.td index 42883b6419261..178308a24e1a0 100644 --- a/clang/include/clang/AST/PropertiesBase.td +++ b/clang/include/clang/AST/PropertiesBase.td @@ -692,25 +692,26 @@ let Class = PropertyTypeCase<TemplateName, "QualifiedTemplate"> in { let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in { def : ReadHelper<[{ auto dtn = node.getAsDependentTemplateName(); + auto name = dtn->getName(); }]>; def : Property<"qualifier", NestedNameSpecifier> { let Read = [{ dtn->getQualifier() }]; } def : Property<"identifier", Optional<Identifier>> { - let Read = [{ makeOptionalFromPointer( - dtn->isIdentifier() - ? dtn->getIdentifier() - : nullptr) }]; + let Read = [{ makeOptionalFromPointer(name.getIdentifier()) }]; } def : Property<"operatorKind", OverloadedOperatorKind> { let Conditional = [{ !identifier }]; - let Read = [{ dtn->getOperator() }]; + let Read = [{ name.getOperator() }]; + } + def : Property<"HasTemplateKeyword", Bool> { + let Read = [{ dtn->hasTemplateKeyword() }]; } def : Creator<[{ if (identifier) { - return ctx.getDependentTemplateName(qualifier, *identifier); + return ctx.getDependentTemplateName({qualifier, *identifier, HasTemplateKeyword}); } else { - return ctx.getDependentTemplateName(qualifier, *operatorKind); + return ctx.getDependentTemplateName({qualifier, *operatorKind, HasTemplateKeyword}); } }]>; } diff --git a/clang/include/clang/AST/RecursiveASTVisitor.h b/clang/include/clang/AST/RecursiveASTVisitor.h index 0d5d515c0e6f7..0530996ed20d3 100644 --- a/clang/include/clang/AST/RecursiveASTVisitor.h +++ b/clang/include/clang/AST/RecursiveASTVisitor.h @@ -795,7 +795,6 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifier( return true; case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: TRY_TO(TraverseType(QualType(NNS->getAsType(), 0))); } @@ -820,7 +819,6 @@ bool RecursiveASTVisitor<Derived>::TraverseNestedNameSpecifierLoc( return true; case NestedNameSpecifier::TypeSpec: - case NestedNameSpecifier::TypeSpecWithTemplate: TRY_TO(TraverseTypeLoc(NNS.getTypeLoc())); break; } @@ -1172,7 +1170,8 @@ DEF_TRAVERSE_TYPE(DependentNameType, { TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); }) DEF_TRAVERSE_TYPE(DependentTemplateSpecializationType, { - TRY_TO(TraverseNestedNameSpecifier(T->getQualifier())); + const DependentTemplateStorage &S = T->getDependentTemplateName(); + TRY_TO(TraverseNestedNameSpecifier(S.getQualifier())); TRY_TO(TraverseTemplateArguments(T->template_arguments())); }) diff --git a/clang/include/clang/AST/TemplateName.h b/clang/include/clang/AST/TemplateName.h index ce97f834bfc1d..1a56133b72d6e 100644 --- a/clang/include/clang/AST/TemplateName.h +++ b/clang/include/clang/AST/TemplateName.h @@ -16,6 +16,7 @@ #include "clang/AST/DependenceFlags.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/Basic/LLVM.h" +#include "clang/Basic/OperatorKinds.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" @@ -537,6 +538,35 @@ class QualifiedTemplateName : public llvm::FoldingSetNode { } }; +struct IdentifierOrOverloadedOperator { + IdentifierOrOverloadedOperator() = default; + IdentifierOrOverloadedOperator(const IdentifierInfo *II); + IdentifierOrOverloadedOperator(OverloadedOperatorKind OOK); + + /// Returns the identifier to which this template name refers. + const IdentifierInfo *getIdentifier() const { + if (getOperator() != OO_None) + return nullptr; + return reinterpret_cast<const IdentifierInfo *>(PtrOrOp); + } + + /// Return the overloaded operator to which this template name refers. + OverloadedOperatorKind getOperator() const { + uintptr_t OOK = -PtrOrOp; + return OOK < NUM_OVERLOADED_OPERATORS ? OverloadedOperatorKind(OOK) + : OO_None; + } + + void Profile(llvm::FoldingSetNodeID &ID) const; + + bool operator==(const IdentifierOrOverloadedOperator &Other) const { + return PtrOrOp == Other.PtrOrOp; + }; + +private: + uintptr_t PtrOrOp = 0; +}; + /// Represents a dependent template name that cannot be /// resolved prior to template instantiation. /// @@ -545,104 +575,53 @@ class QualifiedTemplateName : public llvm::FoldingSetNode { /// DependentTemplateName can refer to "MetaFun::template apply", /// where "MetaFun::" is the nested name specifier and "apply" is the /// template name referenced. The "template" keyword is implied. -class DependentTemplateName : public llvm::FoldingSetNode { - friend class ASTContext; - +class DependentTemplateStorage { /// The nested name specifier that qualifies the template /// name. /// /// The bit stored in this qualifier describes whether the \c Name field - /// is interpreted as an IdentifierInfo pointer (when clear) or as an - /// overloaded operator kind (when set). + /// was preceeded by a template keyword. llvm::PointerIntPair<NestedNameSpecifier *, 1, bool> Qualifier; /// The dependent template name. - union { - /// The identifier template name. - /// - /// Only valid when the bit on \c Qualifier is clear. - const IdentifierInfo *Identifier; - - /// The overloaded operator name. - /// - /// Only valid when the bit on \c Qualifier is set. - OverloadedOperatorKind Operator; - }; - - /// The canonical template name to which this dependent - /// template name refers. - /// - /// The canonical template name for a dependent template name is - /// another dependent template name whose nested name specifier is - /// canonical. - TemplateName CanonicalTemplateName; - - DependentTemplateName(NestedNameSpecifier *Qualifier, - const IdentifierInfo *Identifier) - : Qualifier(Qualifier, false), Identifier(Identifier), - CanonicalTemplateName(this) {} - - DependentTemplateName(NestedNameSpecifier *Qualifier, - const IdentifierInfo *Identifier, - TemplateName Canon) - : Qualifier(Qualifier, false), Identifier(Identifier), - CanonicalTemplateName(Canon) {} - - DependentTemplateName(NestedNameSpecifier *Qualifier, - OverloadedOperatorKind Operator) - : Qualifier(Qualifier, true), Operator(Operator), - CanonicalTemplateName(this) {} - - DependentTemplateName(NestedNameSpecifier *Qualifier, - OverloadedOperatorKind Operator, - TemplateName Canon) - : Qualifier(Qualifier, true), Operator(Operator), - CanonicalTemplateName(Canon) {} + IdentifierOrOverloadedOperator Name; public: + DependentTemplateStorage(NestedNameSpecifier *Qualifier, + IdentifierOrOverloadedOperator Name, + bool HasTemplateKeyword); + /// Return the nested name specifier that qualifies this name. NestedNameSpecifier *getQualifier() const { return Qualifier.getPointer(); } - /// Determine whether this template name refers to an identifier. - bool isIdentifier() const { return !Qualifier.getInt(); } + IdentifierOrOverloadedOperator getName() const { return Name; } - /// Returns the identifier to which this template name refers. - const IdentifierInfo *getIdentifier() const { - assert(isIdentifier() && "Template name isn't an identifier?"); - return Identifier; - } - - /// Determine whether this template name refers to an overloaded - /// operator. - bool isOverloadedOperator() const { return Qualifier.getInt(); } + /// Was this template name was preceeded by the template keyword? + bool hasTemplateKeyword() const { return Qualifier.getInt(); } - /// Return the overloaded operator to which this template name refers. - OverloadedOperatorKind getOperator() const { - assert(isOverloadedOperator() && - "Template name isn't an overloaded operator?"); - return Operator; - } + TemplateNameDependence getDependence() const; - void Profile(llvm::FoldingSe... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/133610 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits