hokein updated this revision to Diff 423843.
hokein marked an inline comment as done.
hokein added a comment.
simplify the code in ASTImporter.
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,13 +9185,11 @@
auto QualifierOrErr = Import(QTN->getQualifier());
if (!QualifierOrErr)
return QualifierOrErr.takeError();
-
- if (ExpectedDecl ToTemplateOrErr = Import(From.getAsTemplateDecl()))
- return ToContext.getQualifiedTemplateName(
- *QualifierOrErr, QTN->hasTemplateKeyword(),
- cast<TemplateDecl>(*ToTemplateOrErr));
- else
- return ToTemplateOrErr.takeError();
+ auto TNOrErr = Import(QTN->getUnderlyingTemplate());
+ if (!TNOrErr)
+ return TNOrErr.takeError();
+ return ToContext.getQualifiedTemplateName(
+ *QualifierOrErr, QTN->hasTemplateKeyword(), *TNOrErr);
}
case TemplateName::DependentTemplate: {
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
[email protected]
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits