hokein updated this revision to Diff 423687. hokein added a comment. format
Repository: rG LLVM Github Monorepo CHANGES SINCE LAST ACTION https://reviews.llvm.org/D123775/new/ https://reviews.llvm.org/D123775 Files: clang/include/clang/AST/ASTContext.h clang/include/clang/AST/PropertiesBase.td clang/include/clang/AST/TemplateName.h clang/lib/AST/ASTContext.cpp clang/lib/AST/ASTImporter.cpp clang/lib/AST/QualTypeNames.cpp clang/lib/Sema/SemaDecl.cpp clang/lib/Sema/SemaTemplate.cpp clang/lib/Sema/TreeTransform.h clang/unittests/AST/TemplateNameTest.cpp
Index: clang/unittests/AST/TemplateNameTest.cpp =================================================================== --- clang/unittests/AST/TemplateNameTest.cpp +++ clang/unittests/AST/TemplateNameTest.cpp @@ -58,5 +58,69 @@ "vector"); } +TEST(TemplateName, QualifiedUsingTemplate) { + std::string Code = R"cpp( + namespace std { + template <typename> struct vector {}; + } + namespace absl { using std::vector; } + + template<template <typename> class T> class X; + + using A = X<absl::vector>; // QualifiedTemplateName in a template argument. + )cpp"; + auto AST = tooling::buildASTFromCode(Code); + // Match the template argument absl::vector in X<absl::vector>. + auto Matcher = templateArgumentLoc().bind("id"); + auto MatchResults = match(Matcher, AST->getASTContext()); + const auto *TAL = MatchResults.front().getNodeAs<TemplateArgumentLoc>("id"); + ASSERT_TRUE(TAL); + TemplateName TN = TAL->getArgument().getAsTemplate(); + EXPECT_EQ(TN.getKind(), TemplateName::QualifiedTemplate); + const auto *QTN = TN.getAsQualifiedTemplateName(); + // Verify that we have the Using template name in the QualifiedTemplateName. + const auto *USD = QTN->getUnderlyingTemplate().getAsUsingShadowDecl(); + EXPECT_TRUE(USD); + EXPECT_EQ(USD->getTargetDecl(), TN.getAsTemplateDecl()); +} + +TEST(TemplateName, UsingTemplate) { + auto AST = tooling::buildASTFromCode(R"cpp( + namespace std { + template <typename T> struct vector { vector(T); }; + } + namespace absl { using std::vector; } + // The "absl::vector<int>" is an elaborated TemplateSpecializationType with + // an inner Using TemplateName (not a Qualified TemplateName, the qualifiers + // are rather part of the ElaboratedType)! + absl::vector<int> v(123); + )cpp"); + auto Matcher = elaboratedTypeLoc( + hasNamedTypeLoc(loc(templateSpecializationType().bind("id")))); + auto MatchResults = match(Matcher, AST->getASTContext()); + const auto *TST = + MatchResults.front().getNodeAs<TemplateSpecializationType>("id"); + ASSERT_TRUE(TST); + EXPECT_EQ(TST->getTemplateName().getKind(), TemplateName::UsingTemplate); + + AST = tooling::buildASTFromCodeWithArgs(R"cpp( + namespace std { + template <typename T> struct vector { vector(T); }; + } + namespace absl { using std::vector; } + // Similiar to the TemplateSpecializationType, absl::vector is an elaborated + // DeducedTemplateSpecializationType with an inner Using TemplateName! + absl::vector DTST(123); + )cpp", + {"-std=c++17"}); + Matcher = elaboratedTypeLoc( + hasNamedTypeLoc(loc(deducedTemplateSpecializationType().bind("id")))); + MatchResults = match(Matcher, AST->getASTContext()); + const auto *DTST = + MatchResults.front().getNodeAs<DeducedTemplateSpecializationType>("id"); + ASSERT_TRUE(DTST); + EXPECT_EQ(DTST->getTemplateName().getKind(), TemplateName::UsingTemplate); +} + } // namespace } // namespace clang Index: clang/lib/Sema/TreeTransform.h =================================================================== --- clang/lib/Sema/TreeTransform.h +++ clang/lib/Sema/TreeTransform.h @@ -14715,7 +14715,7 @@ bool TemplateKW, TemplateDecl *Template) { return SemaRef.Context.getQualifiedTemplateName(SS.getScopeRep(), TemplateKW, - Template); + TemplateName(Template)); } template<typename Derived> Index: clang/lib/Sema/SemaTemplate.cpp =================================================================== --- clang/lib/Sema/SemaTemplate.cpp +++ clang/lib/Sema/SemaTemplate.cpp @@ -284,17 +284,13 @@ } TemplateDecl *TD = cast<TemplateDecl>(D); - + Template = + FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD); + assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD); if (SS.isSet() && !SS.isInvalid()) { NestedNameSpecifier *Qualifier = SS.getScopeRep(); - // FIXME: store the using TemplateName in QualifiedTemplateName if - // the TD is referred via a using-declaration. - Template = - Context.getQualifiedTemplateName(Qualifier, hasTemplateKeyword, TD); - } else { - Template = - FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD); - assert(!FoundUsingShadow || FoundUsingShadow->getTargetDecl() == TD); + Template = Context.getQualifiedTemplateName(Qualifier, hasTemplateKeyword, + Template); } if (isa<FunctionTemplateDecl>(TD)) { @@ -1006,7 +1002,7 @@ if (SS.isSet()) Name = Context.getQualifiedTemplateName(SS.getScopeRep(), /*HasTemplateKeyword*/ false, - Name.getAsTemplateDecl()); + Name); ParsedTemplateArgument Result(SS, TemplateTy::make(Name), DTST.getTemplateNameLoc()); if (EllipsisLoc.isValid()) Index: clang/lib/Sema/SemaDecl.cpp =================================================================== --- clang/lib/Sema/SemaDecl.cpp +++ clang/lib/Sema/SemaDecl.cpp @@ -1111,18 +1111,14 @@ UsingShadowDecl *FoundUsingShadow = dyn_cast<UsingShadowDecl>(*Result.begin()); - - if (SS.isNotEmpty()) { - // FIXME: support using shadow-declaration in qualified template name. - Template = - Context.getQualifiedTemplateName(SS.getScopeRep(), - /*TemplateKeyword=*/false, TD); - } else { - assert(!FoundUsingShadow || - TD == cast<TemplateDecl>(FoundUsingShadow->getTargetDecl())); - Template = FoundUsingShadow ? TemplateName(FoundUsingShadow) - : TemplateName(TD); - } + assert(!FoundUsingShadow || + TD == cast<TemplateDecl>(FoundUsingShadow->getTargetDecl())); + Template = + FoundUsingShadow ? TemplateName(FoundUsingShadow) : TemplateName(TD); + if (SS.isNotEmpty()) + Template = Context.getQualifiedTemplateName(SS.getScopeRep(), + /*TemplateKeyword=*/false, + Template); } else { // All results were non-template functions. This is a function template // name. Index: clang/lib/AST/QualTypeNames.cpp =================================================================== --- clang/lib/AST/QualTypeNames.cpp +++ clang/lib/AST/QualTypeNames.cpp @@ -80,8 +80,12 @@ Ctx, ArgTDecl, true, WithGlobalNsPrefix); } if (NNS) { - TName = Ctx.getQualifiedTemplateName(NNS, - /*TemplateKeyword=*/false, ArgTDecl); + TemplateName UnderlyingTN(ArgTDecl); + if (UsingShadowDecl *USD = TName.getAsUsingShadowDecl()) + UnderlyingTN = TemplateName(USD); + TName = + Ctx.getQualifiedTemplateName(NNS, + /*TemplateKeyword=*/false, UnderlyingTN); Changed = true; } return Changed; Index: clang/lib/AST/ASTImporter.cpp =================================================================== --- clang/lib/AST/ASTImporter.cpp +++ clang/lib/AST/ASTImporter.cpp @@ -9185,11 +9185,20 @@ auto QualifierOrErr = Import(QTN->getQualifier()); if (!QualifierOrErr) return QualifierOrErr.takeError(); + TemplateName UnderlyingTN = QTN->getUnderlyingTemplate(); + if (UsingShadowDecl *USD = UnderlyingTN.getAsUsingShadowDecl()) { + if (ExpectedDecl ToUSDOrErr = Import(USD)) + return ToContext.getQualifiedTemplateName( + *QualifierOrErr, QTN->hasTemplateKeyword(), + TemplateName(cast<UsingShadowDecl>(*ToUSDOrErr))); + else + return ToUSDOrErr.takeError(); + } - if (ExpectedDecl ToTemplateOrErr = Import(From.getAsTemplateDecl())) + if (ExpectedDecl ToTemplateOrErr = Import(UnderlyingTN.getAsTemplateDecl())) return ToContext.getQualifiedTemplateName( *QualifierOrErr, QTN->hasTemplateKeyword(), - cast<TemplateDecl>(*ToTemplateOrErr)); + TemplateName(cast<TemplateDecl>(*ToTemplateOrErr))); else return ToTemplateOrErr.takeError(); } Index: clang/lib/AST/ASTContext.cpp =================================================================== --- clang/lib/AST/ASTContext.cpp +++ clang/lib/AST/ASTContext.cpp @@ -4852,11 +4852,10 @@ "No dependent template names here!"); // Look through qualified template names. if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - Template = TemplateName(QTN->getTemplateDecl()); + Template = QTN->getUnderlyingTemplate(); bool IsTypeAlias = - Template.getAsTemplateDecl() && - isa<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()); + isa_and_nonnull<TypeAliasTemplateDecl>(Template.getAsTemplateDecl()); QualType CanonType; if (!Underlying.isNull()) CanonType = getCanonicalType(Underlying); @@ -4908,7 +4907,7 @@ // Look through qualified template names. if (QualifiedTemplateName *QTN = Template.getAsQualifiedTemplateName()) - Template = TemplateName(QTN->getTemplateDecl()); + Template = TemplateName(QTN->getUnderlyingTemplate()); // Build the canonical template specialization type. TemplateName CanonTemplate = getCanonicalTemplateName(Template); @@ -8971,10 +8970,9 @@ /// Retrieve the template name that represents a qualified /// template name such as \c std::vector. -TemplateName -ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, - bool TemplateKeyword, - TemplateDecl *Template) const { +TemplateName ASTContext::getQualifiedTemplateName(NestedNameSpecifier *NNS, + bool TemplateKeyword, + TemplateName Template) const { assert(NNS && "Missing nested-name-specifier in qualified template name"); // FIXME: Canonicalization? Index: clang/include/clang/AST/TemplateName.h =================================================================== --- clang/include/clang/AST/TemplateName.h +++ clang/include/clang/AST/TemplateName.h @@ -414,13 +414,19 @@ /// this name with DependentTemplateName). llvm::PointerIntPair<NestedNameSpecifier *, 1> Qualifier; - /// The template declaration or set of overloaded function templates - /// that this qualified name refers to. - TemplateDecl *Template; + /// The underlying template name, it is either + /// 1) a Template -- a template declaration that this qualified name refers + /// to. + /// 2) or a UsingTemplate -- a template declaration introduced by a + /// using-shadow declaration. + TemplateName UnderlyingTemplate; QualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, - TemplateDecl *Template) - : Qualifier(NNS, TemplateKeyword? 1 : 0), Template(Template) {} + TemplateName Template) + : Qualifier(NNS, TemplateKeyword ? 1 : 0), UnderlyingTemplate(Template) { + assert(UnderlyingTemplate.getKind() == TemplateName::Template || + UnderlyingTemplate.getKind() == TemplateName::UsingTemplate); + } public: /// Return the nested name specifier that qualifies this name. @@ -430,19 +436,25 @@ /// keyword. bool hasTemplateKeyword() const { return Qualifier.getInt(); } + /// Return the underlying template name. + TemplateName getUnderlyingTemplate() const { return UnderlyingTemplate; } + /// The template declaration to which this qualified name /// refers. - TemplateDecl *getTemplateDecl() const { return Template; } + /// FIXME: remove this and use getUnderlyingTemplate() instead. + TemplateDecl *getTemplateDecl() const { + return UnderlyingTemplate.getAsTemplateDecl(); + } void Profile(llvm::FoldingSetNodeID &ID) { - Profile(ID, getQualifier(), hasTemplateKeyword(), getTemplateDecl()); + Profile(ID, getQualifier(), hasTemplateKeyword(), UnderlyingTemplate); } static void Profile(llvm::FoldingSetNodeID &ID, NestedNameSpecifier *NNS, - bool TemplateKeyword, TemplateDecl *Template) { + bool TemplateKeyword, TemplateName TN) { ID.AddPointer(NNS); ID.AddBoolean(TemplateKeyword); - ID.AddPointer(Template); + ID.AddPointer(TN.getAsVoidPointer()); } }; Index: clang/include/clang/AST/PropertiesBase.td =================================================================== --- clang/include/clang/AST/PropertiesBase.td +++ clang/include/clang/AST/PropertiesBase.td @@ -663,12 +663,12 @@ def : Property<"hasTemplateKeyword", Bool> { let Read = [{ qtn->hasTemplateKeyword() }]; } - def : Property<"declaration", TemplateDeclRef> { - let Read = [{ qtn->getTemplateDecl() }]; + def : Property<"underlyingTemplateName", TemplateName> { + let Read = [{ qtn->getUnderlyingTemplate() }]; } def : Creator<[{ return ctx.getQualifiedTemplateName(qualifier, hasTemplateKeyword, - declaration); + underlyingTemplateName); }]>; } let Class = PropertyTypeCase<TemplateName, "DependentTemplate"> in { Index: clang/include/clang/AST/ASTContext.h =================================================================== --- clang/include/clang/AST/ASTContext.h +++ clang/include/clang/AST/ASTContext.h @@ -2182,7 +2182,7 @@ TemplateName getQualifiedTemplateName(NestedNameSpecifier *NNS, bool TemplateKeyword, - TemplateDecl *Template) const; + TemplateName Template) const; TemplateName getDependentTemplateName(NestedNameSpecifier *NNS, const IdentifierInfo *Name) const;
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits