mirror of
https://github.com/llvm/llvm-project.git
synced 2025-04-16 09:16:31 +00:00
Revert "[Clang] Unify interface for accessing template arguments as written for class/variable template specializations (#81642)"
This reverts commit 7115ed0fff027b65fa76fdfae215ed1382ed1473. This commit broke several LLDB tests. https://green.lab.llvm.org/job/llvm.org/view/LLDB/job/as-lldb-cmake/3480/
This commit is contained in:
parent
2e4abfae57
commit
c6855ab24e
@ -50,12 +50,17 @@ getTemplateSpecializationArgLocs(const NamedDecl &ND) {
|
||||
if (const ASTTemplateArgumentListInfo *Args =
|
||||
Func->getTemplateSpecializationArgsAsWritten())
|
||||
return Args->arguments();
|
||||
} else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
|
||||
} else if (auto *Cls =
|
||||
llvm::dyn_cast<ClassTemplatePartialSpecializationDecl>(&ND)) {
|
||||
if (auto *Args = Cls->getTemplateArgsAsWritten())
|
||||
return Args->arguments();
|
||||
} else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) {
|
||||
} else if (auto *Var =
|
||||
llvm::dyn_cast<VarTemplatePartialSpecializationDecl>(&ND)) {
|
||||
if (auto *Args = Var->getTemplateArgsAsWritten())
|
||||
return Args->arguments();
|
||||
} else if (auto *Var = llvm::dyn_cast<VarTemplateSpecializationDecl>(&ND)) {
|
||||
if (auto *Args = Var->getTemplateArgsInfo())
|
||||
return Args->arguments();
|
||||
}
|
||||
// We return std::nullopt for ClassTemplateSpecializationDecls because it does
|
||||
// not contain TemplateArgumentLoc information.
|
||||
@ -265,10 +270,22 @@ std::string printTemplateSpecializationArgs(const NamedDecl &ND) {
|
||||
getTemplateSpecializationArgLocs(ND)) {
|
||||
printTemplateArgumentList(OS, *Args, Policy);
|
||||
} else if (auto *Cls = llvm::dyn_cast<ClassTemplateSpecializationDecl>(&ND)) {
|
||||
// FIXME: Fix cases when getTypeAsWritten returns null inside clang AST,
|
||||
// e.g. friend decls. Currently we fallback to Template Arguments without
|
||||
// location information.
|
||||
printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
|
||||
if (const TypeSourceInfo *TSI = Cls->getTypeAsWritten()) {
|
||||
// ClassTemplateSpecializationDecls do not contain
|
||||
// TemplateArgumentTypeLocs, they only have TemplateArgumentTypes. So we
|
||||
// create a new argument location list from TypeSourceInfo.
|
||||
auto STL = TSI->getTypeLoc().getAs<TemplateSpecializationTypeLoc>();
|
||||
llvm::SmallVector<TemplateArgumentLoc> ArgLocs;
|
||||
ArgLocs.reserve(STL.getNumArgs());
|
||||
for (unsigned I = 0; I < STL.getNumArgs(); ++I)
|
||||
ArgLocs.push_back(STL.getArgLoc(I));
|
||||
printTemplateArgumentList(OS, ArgLocs, Policy);
|
||||
} else {
|
||||
// FIXME: Fix cases when getTypeAsWritten returns null inside clang AST,
|
||||
// e.g. friend decls. Currently we fallback to Template Arguments without
|
||||
// location information.
|
||||
printTemplateArgumentList(OS, Cls->getTemplateArgs().asArray(), Policy);
|
||||
}
|
||||
}
|
||||
OS.flush();
|
||||
return TemplateArgs;
|
||||
@ -436,12 +453,10 @@ bool hasReservedScope(const DeclContext &DC) {
|
||||
}
|
||||
|
||||
QualType declaredType(const TypeDecl *D) {
|
||||
ASTContext &Context = D->getASTContext();
|
||||
if (const auto *CTSD = llvm::dyn_cast<ClassTemplateSpecializationDecl>(D))
|
||||
if (const auto *Args = CTSD->getTemplateArgsAsWritten())
|
||||
return Context.getTemplateSpecializationType(
|
||||
TemplateName(CTSD->getSpecializedTemplate()), Args->arguments());
|
||||
return Context.getTypeDeclType(D);
|
||||
if (const auto *TSI = CTSD->getTypeAsWritten())
|
||||
return TSI->getType();
|
||||
return D->getASTContext().getTypeDeclType(D);
|
||||
}
|
||||
|
||||
namespace {
|
||||
|
@ -693,22 +693,17 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
bool
|
||||
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D) {
|
||||
bool VisitClassTemplatePartialSpecializationDecl(
|
||||
ClassTemplatePartialSpecializationDecl *D) {
|
||||
if (auto *TPL = D->getTemplateParameters())
|
||||
H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
|
||||
if (auto *Args = D->getTemplateArgsAsWritten())
|
||||
H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitClassTemplatePartialSpecializationDecl(
|
||||
ClassTemplatePartialSpecializationDecl *D) {
|
||||
if (auto *TPL = D->getTemplateParameters())
|
||||
H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) {
|
||||
if (auto *Args = D->getTemplateArgsAsWritten())
|
||||
if (auto *Args = D->getTemplateArgsInfo())
|
||||
H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
|
||||
return true;
|
||||
}
|
||||
@ -717,6 +712,8 @@ public:
|
||||
VarTemplatePartialSpecializationDecl *D) {
|
||||
if (auto *TPL = D->getTemplateParameters())
|
||||
H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
|
||||
if (auto *Args = D->getTemplateArgsAsWritten())
|
||||
H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -267,21 +267,18 @@ public:
|
||||
return true;
|
||||
}
|
||||
|
||||
// Report a reference from explicit specializations/instantiations to the
|
||||
// specialized template. Implicit ones are filtered out by RAV.
|
||||
// Report a reference from explicit specializations to the specialized
|
||||
// template. Implicit ones are filtered out by RAV and explicit instantiations
|
||||
// are already traversed through typelocs.
|
||||
bool
|
||||
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *CTSD) {
|
||||
// if (CTSD->isExplicitSpecialization())
|
||||
if (clang::isTemplateExplicitInstantiationOrSpecialization(
|
||||
CTSD->getTemplateSpecializationKind()))
|
||||
if (CTSD->isExplicitSpecialization())
|
||||
report(CTSD->getLocation(),
|
||||
CTSD->getSpecializedTemplate()->getTemplatedDecl());
|
||||
return true;
|
||||
}
|
||||
bool VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *VTSD) {
|
||||
// if (VTSD->isExplicitSpecialization())
|
||||
if (clang::isTemplateExplicitInstantiationOrSpecialization(
|
||||
VTSD->getTemplateSpecializationKind()))
|
||||
if (VTSD->isExplicitSpecialization())
|
||||
report(VTSD->getLocation(),
|
||||
VTSD->getSpecializedTemplate()->getTemplatedDecl());
|
||||
return true;
|
||||
|
@ -3546,6 +3546,21 @@ cxxMethodDecl(isConst()) matches A::foo() but not A::bar()
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isExplicitObjectMemberFunction0')"><a name="isExplicitObjectMemberFunction0Anchor">isExplicitObjectMemberFunction</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isExplicitObjectMemberFunction0"><pre>Matches if the given method declaration declares a member function with an explicit object parameter.
|
||||
|
||||
Given
|
||||
struct A {
|
||||
int operator-(this A, int);
|
||||
void fun(this A &&self);
|
||||
static int operator()(int);
|
||||
int operator+(int);
|
||||
};
|
||||
|
||||
cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two methods but not the last two.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isCopyAssignmentOperator0')"><a name="isCopyAssignmentOperator0Anchor">isCopyAssignmentOperator</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isCopyAssignmentOperator0"><pre>Matches if the given method declaration declares a copy assignment
|
||||
operator.
|
||||
@ -3561,23 +3576,6 @@ the second one.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isExplicitObjectMemberFunction0')"><a name="isExplicitObjectMemberFunction0Anchor">isExplicitObjectMemberFunction</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isExplicitObjectMemberFunction0"><pre>Matches if the given method declaration declares a member function with an
|
||||
explicit object parameter.
|
||||
|
||||
Given
|
||||
struct A {
|
||||
int operator-(this A, int);
|
||||
void fun(this A &&self);
|
||||
static int operator()(int);
|
||||
int operator+(int);
|
||||
};
|
||||
|
||||
cxxMethodDecl(isExplicitObjectMemberFunction()) matches the first two
|
||||
methods but not the last two.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXMethodDecl.html">CXXMethodDecl</a>></td><td class="name" onclick="toggle('isFinal1')"><a name="isFinal1Anchor">isFinal</a></td><td></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="isFinal1"><pre>Matches if the given method or class declaration is final.
|
||||
|
||||
@ -6715,7 +6713,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -6759,7 +6757,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -6987,7 +6985,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -7221,7 +7219,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -7418,7 +7416,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -7622,7 +7620,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -7679,7 +7677,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -7877,10 +7875,9 @@ int a = b ?: 1;
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('forEachTemplateArgument0')"><a name="forEachTemplateArgument0Anchor">forEachTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="forEachTemplateArgument0"><pre>Matches templateSpecializationType, class template specialization,
|
||||
variable template specialization, and function template specialization
|
||||
nodes where the template argument matches the inner matcher. This matcher
|
||||
may produce multiple matches.
|
||||
<tr><td colspan="4" class="doc" id="forEachTemplateArgument0"><pre>Matches classTemplateSpecialization, templateSpecializationType and
|
||||
functionDecl nodes where the template argument matches the inner matcher.
|
||||
This matcher may produce multiple matches.
|
||||
|
||||
Given
|
||||
template <typename T, unsigned N, unsigned M>
|
||||
@ -7902,25 +7899,10 @@ functionDecl(forEachTemplateArgument(refersToType(builtinType())))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgumentLoc0')"><a name="hasAnyTemplateArgumentLoc0Anchor">hasAnyTemplateArgumentLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgumentLoc0"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one `TemplateArgumentLoc` matching the given
|
||||
`InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
A<int> a;
|
||||
varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
hasTypeLoc(loc(asString("int")))))))
|
||||
matches `A<int> a`.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgument0')"><a name="hasAnyTemplateArgument0Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument0"><pre>Matches templateSpecializationTypes, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one TemplateArgument matching the given InnerMatcher.
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument0"><pre>Matches classTemplateSpecializations, templateSpecializationType and
|
||||
functionDecl that have at least one TemplateArgument matching the given
|
||||
InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
@ -7951,25 +7933,9 @@ classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasTemplateArgumentLoc0')"><a name="hasTemplateArgumentLoc0Anchor">hasTemplateArgumentLoc</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgumentLoc0"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th `TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
A<double, int> b;
|
||||
A<int, double> c;
|
||||
varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0,
|
||||
hasTypeLoc(loc(asString("double")))))))
|
||||
matches `A<double, int> b`, but not `A<int, double> c`.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasTemplateArgument0')"><a name="hasTemplateArgument0Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgument0"><pre>Matches templateSpecializationType, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgument0"><pre>Matches classTemplateSpecializations, templateSpecializationType and
|
||||
functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
@ -7987,22 +7953,7 @@ functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ComplexType.html">ComplexType</a>></td><td class="name" onclick="toggle('hasElementType1')"><a name="hasElementType1Anchor">hasElementType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasElementType1"><pre>Matches arrays and C99 complex types that have a specific element
|
||||
type.
|
||||
|
||||
Given
|
||||
struct A {};
|
||||
A a[7];
|
||||
int b[7];
|
||||
arrayType(hasElementType(builtinType()))
|
||||
matches "int b[7]"
|
||||
|
||||
Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ArrayType.html">ArrayType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ComplexType.html">ComplexType</a>>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>></td><td class="name" onclick="toggle('hasTypeLoc7')"><a name="hasTypeLoc7Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc7')"><a name="hasTypeLoc7Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc7"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
|
||||
Examples:
|
||||
@ -8023,7 +7974,50 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ComplexType.html">ComplexType</a>></td><td class="name" onclick="toggle('hasElementType1')"><a name="hasElementType1Anchor">hasElementType</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Type.html">Type</a>></td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasElementType1"><pre>Matches arrays and C99 complex types that have a specific element
|
||||
type.
|
||||
|
||||
Given
|
||||
struct A {};
|
||||
A a[7];
|
||||
int b[7];
|
||||
arrayType(hasElementType(builtinType()))
|
||||
matches "int b[7]"
|
||||
|
||||
Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ArrayType.html">ArrayType</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ComplexType.html">ComplexType</a>>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>></td><td class="name" onclick="toggle('hasTypeLoc8')"><a name="hasTypeLoc8Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc8"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
|
||||
Examples:
|
||||
int x;
|
||||
declaratorDecl(hasTypeLoc(loc(asString("int"))))
|
||||
matches int x
|
||||
|
||||
auto x = int(3);
|
||||
cxxTemporaryObjectExpr(hasTypeLoc(loc(asString("int"))))
|
||||
matches int(3)
|
||||
|
||||
struct Foo { Foo(int, int); };
|
||||
auto x = Foo(1, 2);
|
||||
cxxFunctionalCastExpr(hasTypeLoc(loc(asString("struct Foo"))))
|
||||
matches Foo(1, 2)
|
||||
|
||||
Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1BlockDecl.html">BlockDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXBaseSpecifier.html">CXXBaseSpecifier</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -8072,21 +8066,6 @@ with compoundStmt()
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgumentLoc3')"><a name="hasAnyTemplateArgumentLoc3Anchor">hasAnyTemplateArgumentLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgumentLoc3"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one `TemplateArgumentLoc` matching the given
|
||||
`InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
A<int> a;
|
||||
varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
hasTypeLoc(loc(asString("int")))))))
|
||||
matches `A<int> a`.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('hasDeclaration11')"><a name="hasDeclaration11Anchor">hasDeclaration</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Decl.html">Decl</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasDeclaration11"><pre>Matches a node if the declaration associated with that node
|
||||
matches the given matcher.
|
||||
@ -8121,10 +8100,9 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Addr
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('hasTemplateArgumentLoc3')"><a name="hasTemplateArgumentLoc3Anchor">hasTemplateArgumentLoc</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgumentLoc3"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th `TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclRefExpr.html">DeclRefExpr</a>></td><td class="name" onclick="toggle('hasTemplateArgumentLoc0')"><a name="hasTemplateArgumentLoc0Anchor">hasTemplateArgumentLoc</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgumentLoc0"><pre>Matches template specialization `TypeLoc`s where the n'th
|
||||
`TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
@ -8198,8 +8176,8 @@ declStmt(hasSingleDecl(anything()))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc8')"><a name="hasTypeLoc8Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc8"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc9')"><a name="hasTypeLoc9Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc9"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
|
||||
Examples:
|
||||
int x;
|
||||
@ -8219,7 +8197,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -8415,8 +8393,8 @@ actual casts "explicit" casts.)
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>></td><td class="name" onclick="toggle('hasTypeLoc9')"><a name="hasTypeLoc9Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc9"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>></td><td class="name" onclick="toggle('hasTypeLoc10')"><a name="hasTypeLoc10Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc10"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
|
||||
Examples:
|
||||
int x;
|
||||
@ -8436,7 +8414,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -8729,10 +8707,9 @@ Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('forEachTemplateArgument2')"><a name="forEachTemplateArgument2Anchor">forEachTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="forEachTemplateArgument2"><pre>Matches templateSpecializationType, class template specialization,
|
||||
variable template specialization, and function template specialization
|
||||
nodes where the template argument matches the inner matcher. This matcher
|
||||
may produce multiple matches.
|
||||
<tr><td colspan="4" class="doc" id="forEachTemplateArgument2"><pre>Matches classTemplateSpecialization, templateSpecializationType and
|
||||
functionDecl nodes where the template argument matches the inner matcher.
|
||||
This matcher may produce multiple matches.
|
||||
|
||||
Given
|
||||
template <typename T, unsigned N, unsigned M>
|
||||
@ -8801,25 +8778,10 @@ matching y.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgumentLoc2')"><a name="hasAnyTemplateArgumentLoc2Anchor">hasAnyTemplateArgumentLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgumentLoc2"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one `TemplateArgumentLoc` matching the given
|
||||
`InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
A<int> a;
|
||||
varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
hasTypeLoc(loc(asString("int")))))))
|
||||
matches `A<int> a`.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgument2')"><a name="hasAnyTemplateArgument2Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument2"><pre>Matches templateSpecializationTypes, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one TemplateArgument matching the given InnerMatcher.
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument2"><pre>Matches classTemplateSpecializations, templateSpecializationType and
|
||||
functionDecl that have at least one TemplateArgument matching the given
|
||||
InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
@ -8916,25 +8878,9 @@ functionDecl(hasReturnTypeLoc(loc(asString("int"))))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasTemplateArgumentLoc2')"><a name="hasTemplateArgumentLoc2Anchor">hasTemplateArgumentLoc</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgumentLoc2"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th `TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
A<double, int> b;
|
||||
A<int, double> c;
|
||||
varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0,
|
||||
hasTypeLoc(loc(asString("double")))))))
|
||||
matches `A<double, int> b`, but not `A<int, double> c`.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1FunctionDecl.html">FunctionDecl</a>></td><td class="name" onclick="toggle('hasTemplateArgument2')"><a name="hasTemplateArgument2Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgument2"><pre>Matches templateSpecializationType, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgument2"><pre>Matches classTemplateSpecializations, templateSpecializationType and
|
||||
functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
@ -9527,8 +9473,8 @@ matching y.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc10')"><a name="hasTypeLoc10Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc10"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc11')"><a name="hasTypeLoc11Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc11"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
|
||||
Examples:
|
||||
int x;
|
||||
@ -9548,7 +9494,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -9973,8 +9919,8 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Addr
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>></td><td class="name" onclick="toggle('hasTypeLoc11')"><a name="hasTypeLoc11Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc11"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>></td><td class="name" onclick="toggle('hasTypeLoc12')"><a name="hasTypeLoc12Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc12"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
|
||||
Examples:
|
||||
int x;
|
||||
@ -9994,7 +9940,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -10068,11 +10014,9 @@ matches the specialization of struct A generated by A<X>.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationTypeLoc.html">TemplateSpecializationTypeLoc</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgumentLoc4')"><a name="hasAnyTemplateArgumentLoc4Anchor">hasAnyTemplateArgumentLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgumentLoc4"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one `TemplateArgumentLoc` matching the given
|
||||
`InnerMatcher`.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationTypeLoc.html">TemplateSpecializationTypeLoc</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgumentLoc0')"><a name="hasAnyTemplateArgumentLoc0Anchor">hasAnyTemplateArgumentLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgumentLoc0"><pre>Matches template specialization `TypeLoc`s that have at least one
|
||||
`TemplateArgumentLoc` matching the given `InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
@ -10083,10 +10027,9 @@ varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationTypeLoc.html">TemplateSpecializationTypeLoc</a>></td><td class="name" onclick="toggle('hasTemplateArgumentLoc4')"><a name="hasTemplateArgumentLoc4Anchor">hasTemplateArgumentLoc</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgumentLoc4"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th `TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationTypeLoc.html">TemplateSpecializationTypeLoc</a>></td><td class="name" onclick="toggle('hasTemplateArgumentLoc1')"><a name="hasTemplateArgumentLoc1Anchor">hasTemplateArgumentLoc</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgumentLoc1"><pre>Matches template specialization `TypeLoc`s where the n'th
|
||||
`TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
@ -10098,11 +10041,10 @@ varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0,
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('forEachTemplateArgument3')"><a name="forEachTemplateArgument3Anchor">forEachTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="forEachTemplateArgument3"><pre>Matches templateSpecializationType, class template specialization,
|
||||
variable template specialization, and function template specialization
|
||||
nodes where the template argument matches the inner matcher. This matcher
|
||||
may produce multiple matches.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('forEachTemplateArgument1')"><a name="forEachTemplateArgument1Anchor">forEachTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="forEachTemplateArgument1"><pre>Matches classTemplateSpecialization, templateSpecializationType and
|
||||
functionDecl nodes where the template argument matches the inner matcher.
|
||||
This matcher may produce multiple matches.
|
||||
|
||||
Given
|
||||
template <typename T, unsigned N, unsigned M>
|
||||
@ -10124,10 +10066,10 @@ functionDecl(forEachTemplateArgument(refersToType(builtinType())))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgument3')"><a name="hasAnyTemplateArgument3Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument3"><pre>Matches templateSpecializationTypes, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one TemplateArgument matching the given InnerMatcher.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgument1')"><a name="hasAnyTemplateArgument1Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument1"><pre>Matches classTemplateSpecializations, templateSpecializationType and
|
||||
functionDecl that have at least one TemplateArgument matching the given
|
||||
InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
@ -10180,10 +10122,9 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Addr
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasTemplateArgument3')"><a name="hasTemplateArgument3Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgument3"><pre>Matches templateSpecializationType, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateSpecializationType.html">TemplateSpecializationType</a>></td><td class="name" onclick="toggle('hasTemplateArgument1')"><a name="hasTemplateArgument1Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgument1"><pre>Matches classTemplateSpecializations, templateSpecializationType and
|
||||
functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
@ -10241,8 +10182,8 @@ QualType-matcher matches.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc12')"><a name="hasTypeLoc12Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc12"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>></td><td class="name" onclick="toggle('hasTypeLoc13')"><a name="hasTypeLoc13Anchor">hasTypeLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypeLoc.html">TypeLoc</a>> Inner</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTypeLoc13"><pre>Matches if the type location of a node matches the inner matcher.
|
||||
|
||||
Examples:
|
||||
int x;
|
||||
@ -10262,7 +10203,7 @@ Usable as: Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Bloc
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXCtorInitializer.html">CXXCtorInitializer</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXFunctionalCastExpr.html">CXXFunctionalCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXNewExpr.html">CXXNewExpr</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXTemporaryObjectExpr.html">CXXTemporaryObjectExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CXXUnresolvedConstructExpr.html">CXXUnresolvedConstructExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ClassTemplateSpecializationDecl.html">ClassTemplateSpecializationDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1CompoundLiteralExpr.html">CompoundLiteralExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1DeclaratorDecl.html">DeclaratorDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ExplicitCastExpr.html">ExplicitCastExpr</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1ObjCPropertyDecl.html">ObjCPropertyDecl</a>>, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>>,
|
||||
Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TypedefNameDecl.html">TypedefNameDecl</a>>
|
||||
@ -10508,105 +10449,6 @@ Example matches x (matcher = varDecl(hasInitializer(callExpr())))
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1VarTemplateSpecializationDecl.html">VarTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('forEachTemplateArgument1')"><a name="forEachTemplateArgument1Anchor">forEachTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="forEachTemplateArgument1"><pre>Matches templateSpecializationType, class template specialization,
|
||||
variable template specialization, and function template specialization
|
||||
nodes where the template argument matches the inner matcher. This matcher
|
||||
may produce multiple matches.
|
||||
|
||||
Given
|
||||
template <typename T, unsigned N, unsigned M>
|
||||
struct Matrix {};
|
||||
|
||||
constexpr unsigned R = 2;
|
||||
Matrix<int, R * 2, R * 4> M;
|
||||
|
||||
template <typename T, typename U>
|
||||
void f(T&& t, U&& u) {}
|
||||
|
||||
bool B = false;
|
||||
f(R, B);
|
||||
templateSpecializationType(forEachTemplateArgument(isExpr(expr())))
|
||||
matches twice, with expr() matching 'R * 2' and 'R * 4'
|
||||
functionDecl(forEachTemplateArgument(refersToType(builtinType())))
|
||||
matches the specialization f<unsigned, bool> twice, for 'unsigned'
|
||||
and 'bool'
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1VarTemplateSpecializationDecl.html">VarTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgumentLoc1')"><a name="hasAnyTemplateArgumentLoc1Anchor">hasAnyTemplateArgumentLoc</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgumentLoc1"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one `TemplateArgumentLoc` matching the given
|
||||
`InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
A<int> a;
|
||||
varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
hasTypeLoc(loc(asString("int")))))))
|
||||
matches `A<int> a`.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1VarTemplateSpecializationDecl.html">VarTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasAnyTemplateArgument1')"><a name="hasAnyTemplateArgument1Anchor">hasAnyTemplateArgument</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasAnyTemplateArgument1"><pre>Matches templateSpecializationTypes, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
that have at least one TemplateArgument matching the given InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T> class A {};
|
||||
template<> class A<double> {};
|
||||
A<int> a;
|
||||
|
||||
template<typename T> f() {};
|
||||
void func() { f<int>(); };
|
||||
|
||||
classTemplateSpecializationDecl(hasAnyTemplateArgument(
|
||||
refersToType(asString("int"))))
|
||||
matches the specialization A<int>
|
||||
|
||||
functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
|
||||
matches the specialization f<int>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1VarTemplateSpecializationDecl.html">VarTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasTemplateArgumentLoc1')"><a name="hasTemplateArgumentLoc1Anchor">hasTemplateArgumentLoc</a></td><td>unsigned Index, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgumentLoc.html">TemplateArgumentLoc</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgumentLoc1"><pre>Matches template specialization `TypeLoc`s, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th `TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
A<double, int> b;
|
||||
A<int, double> c;
|
||||
varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(0,
|
||||
hasTypeLoc(loc(asString("double")))))))
|
||||
matches `A<double, int> b`, but not `A<int, double> c`.
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1VarTemplateSpecializationDecl.html">VarTemplateSpecializationDecl</a>></td><td class="name" onclick="toggle('hasTemplateArgument1')"><a name="hasTemplateArgument1Anchor">hasTemplateArgument</a></td><td>unsigned N, Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1TemplateArgument.html">TemplateArgument</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasTemplateArgument1"><pre>Matches templateSpecializationType, class template specializations,
|
||||
variable template specializations, and function template specializations
|
||||
where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
|
||||
Given
|
||||
template<typename T, typename U> class A {};
|
||||
A<bool, int> b;
|
||||
A<int, bool> c;
|
||||
|
||||
template<typename T> void f() {}
|
||||
void func() { f<int>(); };
|
||||
classTemplateSpecializationDecl(hasTemplateArgument(
|
||||
1, refersToType(asString("int"))))
|
||||
matches the specialization A<bool, int>
|
||||
|
||||
functionDecl(hasTemplateArgument(0, refersToType(asString("int"))))
|
||||
matches the specialization f<int>
|
||||
</pre></td></tr>
|
||||
|
||||
|
||||
<tr><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1VariableArrayType.html">VariableArrayType</a>></td><td class="name" onclick="toggle('hasSizeExpr0')"><a name="hasSizeExpr0Anchor">hasSizeExpr</a></td><td>Matcher<<a href="https://clang.llvm.org/doxygen/classclang_1_1Expr.html">Expr</a>> InnerMatcher</td></tr>
|
||||
<tr><td colspan="4" class="doc" id="hasSizeExpr0"><pre>Matches VariableArrayType nodes that have a specific size
|
||||
expression.
|
||||
|
@ -111,9 +111,6 @@ Clang Frontend Potentially Breaking Changes
|
||||
$ clang --target=<your target triple> -print-target-triple
|
||||
<the normalized target triple>
|
||||
|
||||
- The ``hasTypeLoc`` AST matcher will no longer match a ``classTemplateSpecializationDecl``;
|
||||
existing uses should switch to ``templateArgumentLoc`` or ``hasAnyTemplateArgumentLoc`` instead.
|
||||
|
||||
What's New in Clang |release|?
|
||||
==============================
|
||||
Some of the major new features and improvements to Clang are listed
|
||||
|
@ -1776,25 +1776,6 @@ public:
|
||||
BuiltinTemplateKind getBuiltinTemplateKind() const { return BTK; }
|
||||
};
|
||||
|
||||
/// Provides information about an explicit instantiation of a variable or class
|
||||
/// template.
|
||||
struct ExplicitInstantiationInfo {
|
||||
/// The template arguments as written..
|
||||
const ASTTemplateArgumentListInfo *TemplateArgsAsWritten = nullptr;
|
||||
|
||||
/// The location of the extern keyword.
|
||||
SourceLocation ExternKeywordLoc;
|
||||
|
||||
/// The location of the template keyword.
|
||||
SourceLocation TemplateKeywordLoc;
|
||||
|
||||
ExplicitInstantiationInfo() = default;
|
||||
};
|
||||
|
||||
using SpecializationOrInstantiationInfo =
|
||||
llvm::PointerUnion<const ASTTemplateArgumentListInfo *,
|
||||
ExplicitInstantiationInfo *>;
|
||||
|
||||
/// Represents a class template specialization, which refers to
|
||||
/// a class template with a given set of template arguments.
|
||||
///
|
||||
@ -1808,8 +1789,8 @@ using SpecializationOrInstantiationInfo =
|
||||
/// template<>
|
||||
/// class array<bool> { }; // class template specialization array<bool>
|
||||
/// \endcode
|
||||
class ClassTemplateSpecializationDecl : public CXXRecordDecl,
|
||||
public llvm::FoldingSetNode {
|
||||
class ClassTemplateSpecializationDecl
|
||||
: public CXXRecordDecl, public llvm::FoldingSetNode {
|
||||
/// Structure that stores information about a class template
|
||||
/// specialization that was instantiated from a class template partial
|
||||
/// specialization.
|
||||
@ -1827,9 +1808,23 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
|
||||
llvm::PointerUnion<ClassTemplateDecl *, SpecializedPartialSpecialization *>
|
||||
SpecializedTemplate;
|
||||
|
||||
/// Further info for explicit template specialization/instantiation.
|
||||
struct ExplicitSpecializationInfo {
|
||||
/// The type-as-written.
|
||||
TypeSourceInfo *TypeAsWritten = nullptr;
|
||||
|
||||
/// The location of the extern keyword.
|
||||
SourceLocation ExternLoc;
|
||||
|
||||
/// The location of the template keyword.
|
||||
SourceLocation TemplateKeywordLoc;
|
||||
|
||||
ExplicitSpecializationInfo() = default;
|
||||
};
|
||||
|
||||
/// Further info for explicit template specialization/instantiation.
|
||||
/// Does not apply to implicit specializations.
|
||||
SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
|
||||
ExplicitSpecializationInfo *ExplicitInfo = nullptr;
|
||||
|
||||
/// The template arguments used to describe this specialization.
|
||||
const TemplateArgumentList *TemplateArgs;
|
||||
@ -2006,48 +2001,43 @@ public:
|
||||
SpecializedTemplate = TemplDecl;
|
||||
}
|
||||
|
||||
/// Retrieve the template argument list as written in the sources,
|
||||
/// if any.
|
||||
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
return Info->TemplateArgsAsWritten;
|
||||
return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
|
||||
/// Sets the type of this specialization as it was written by
|
||||
/// the user. This will be a class template specialization type.
|
||||
void setTypeAsWritten(TypeSourceInfo *T) {
|
||||
if (!ExplicitInfo)
|
||||
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
|
||||
ExplicitInfo->TypeAsWritten = T;
|
||||
}
|
||||
|
||||
/// Set the template argument list as written in the sources.
|
||||
void
|
||||
setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
Info->TemplateArgsAsWritten = ArgsWritten;
|
||||
else
|
||||
ExplicitInfo = ArgsWritten;
|
||||
}
|
||||
|
||||
/// Set the template argument list as written in the sources.
|
||||
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
|
||||
setTemplateArgsAsWritten(
|
||||
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo));
|
||||
/// Gets the type of this specialization as it was written by
|
||||
/// the user, if it was so written.
|
||||
TypeSourceInfo *getTypeAsWritten() const {
|
||||
return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
|
||||
}
|
||||
|
||||
/// Gets the location of the extern keyword, if present.
|
||||
SourceLocation getExternKeywordLoc() const {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
return Info->ExternKeywordLoc;
|
||||
return SourceLocation();
|
||||
SourceLocation getExternLoc() const {
|
||||
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
|
||||
}
|
||||
|
||||
/// Sets the location of the extern keyword.
|
||||
void setExternKeywordLoc(SourceLocation Loc);
|
||||
|
||||
/// Gets the location of the template keyword, if present.
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
return Info->TemplateKeywordLoc;
|
||||
return SourceLocation();
|
||||
void setExternLoc(SourceLocation Loc) {
|
||||
if (!ExplicitInfo)
|
||||
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
|
||||
ExplicitInfo->ExternLoc = Loc;
|
||||
}
|
||||
|
||||
/// Sets the location of the template keyword.
|
||||
void setTemplateKeywordLoc(SourceLocation Loc);
|
||||
void setTemplateKeywordLoc(SourceLocation Loc) {
|
||||
if (!ExplicitInfo)
|
||||
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
|
||||
ExplicitInfo->TemplateKeywordLoc = Loc;
|
||||
}
|
||||
|
||||
/// Gets the location of the template keyword, if present.
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY;
|
||||
|
||||
@ -2076,6 +2066,10 @@ class ClassTemplatePartialSpecializationDecl
|
||||
/// The list of template parameters
|
||||
TemplateParameterList* TemplateParams = nullptr;
|
||||
|
||||
/// The source info for the template arguments as written.
|
||||
/// FIXME: redundant with TypeAsWritten?
|
||||
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
|
||||
|
||||
/// The class template partial specialization from which this
|
||||
/// class template partial specialization was instantiated.
|
||||
///
|
||||
@ -2084,11 +2078,15 @@ class ClassTemplatePartialSpecializationDecl
|
||||
llvm::PointerIntPair<ClassTemplatePartialSpecializationDecl *, 1, bool>
|
||||
InstantiatedFromMember;
|
||||
|
||||
ClassTemplatePartialSpecializationDecl(
|
||||
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl);
|
||||
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
|
||||
DeclContext *DC,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation IdLoc,
|
||||
TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
const ASTTemplateArgumentListInfo *ArgsAsWritten,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl);
|
||||
|
||||
ClassTemplatePartialSpecializationDecl(ASTContext &C)
|
||||
: ClassTemplateSpecializationDecl(C, ClassTemplatePartialSpecialization),
|
||||
@ -2103,8 +2101,11 @@ public:
|
||||
static ClassTemplatePartialSpecializationDecl *
|
||||
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
TemplateParameterList *Params, ClassTemplateDecl *SpecializedTemplate,
|
||||
ArrayRef<TemplateArgument> Args, QualType CanonInjectedType,
|
||||
TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
const TemplateArgumentListInfo &ArgInfos,
|
||||
QualType CanonInjectedType,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl);
|
||||
|
||||
static ClassTemplatePartialSpecializationDecl *
|
||||
@ -2135,6 +2136,11 @@ public:
|
||||
return TemplateParams->hasAssociatedConstraints();
|
||||
}
|
||||
|
||||
/// Get the template arguments as written.
|
||||
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
|
||||
return ArgsAsWritten;
|
||||
}
|
||||
|
||||
/// Retrieve the member class template partial specialization from
|
||||
/// which this particular class template partial specialization was
|
||||
/// instantiated.
|
||||
@ -2607,12 +2613,27 @@ class VarTemplateSpecializationDecl : public VarDecl,
|
||||
llvm::PointerUnion<VarTemplateDecl *, SpecializedPartialSpecialization *>
|
||||
SpecializedTemplate;
|
||||
|
||||
/// Further info for explicit template specialization/instantiation.
|
||||
struct ExplicitSpecializationInfo {
|
||||
/// The type-as-written.
|
||||
TypeSourceInfo *TypeAsWritten = nullptr;
|
||||
|
||||
/// The location of the extern keyword.
|
||||
SourceLocation ExternLoc;
|
||||
|
||||
/// The location of the template keyword.
|
||||
SourceLocation TemplateKeywordLoc;
|
||||
|
||||
ExplicitSpecializationInfo() = default;
|
||||
};
|
||||
|
||||
/// Further info for explicit template specialization/instantiation.
|
||||
/// Does not apply to implicit specializations.
|
||||
SpecializationOrInstantiationInfo ExplicitInfo = nullptr;
|
||||
ExplicitSpecializationInfo *ExplicitInfo = nullptr;
|
||||
|
||||
/// The template arguments used to describe this specialization.
|
||||
const TemplateArgumentList *TemplateArgs;
|
||||
const ASTTemplateArgumentListInfo *TemplateArgsInfo = nullptr;
|
||||
|
||||
/// The point where this template was instantiated (if any).
|
||||
SourceLocation PointOfInstantiation;
|
||||
@ -2666,6 +2687,14 @@ public:
|
||||
/// specialization.
|
||||
const TemplateArgumentList &getTemplateArgs() const { return *TemplateArgs; }
|
||||
|
||||
// TODO: Always set this when creating the new specialization?
|
||||
void setTemplateArgsInfo(const TemplateArgumentListInfo &ArgsInfo);
|
||||
void setTemplateArgsInfo(const ASTTemplateArgumentListInfo *ArgsInfo);
|
||||
|
||||
const ASTTemplateArgumentListInfo *getTemplateArgsInfo() const {
|
||||
return TemplateArgsInfo;
|
||||
}
|
||||
|
||||
/// Determine the kind of specialization that this
|
||||
/// declaration represents.
|
||||
TemplateSpecializationKind getSpecializationKind() const {
|
||||
@ -2769,48 +2798,43 @@ public:
|
||||
SpecializedTemplate = TemplDecl;
|
||||
}
|
||||
|
||||
/// Retrieve the template argument list as written in the sources,
|
||||
/// if any.
|
||||
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
return Info->TemplateArgsAsWritten;
|
||||
return ExplicitInfo.get<const ASTTemplateArgumentListInfo *>();
|
||||
/// Sets the type of this specialization as it was written by
|
||||
/// the user.
|
||||
void setTypeAsWritten(TypeSourceInfo *T) {
|
||||
if (!ExplicitInfo)
|
||||
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
|
||||
ExplicitInfo->TypeAsWritten = T;
|
||||
}
|
||||
|
||||
/// Set the template argument list as written in the sources.
|
||||
void
|
||||
setTemplateArgsAsWritten(const ASTTemplateArgumentListInfo *ArgsWritten) {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
Info->TemplateArgsAsWritten = ArgsWritten;
|
||||
else
|
||||
ExplicitInfo = ArgsWritten;
|
||||
}
|
||||
|
||||
/// Set the template argument list as written in the sources.
|
||||
void setTemplateArgsAsWritten(const TemplateArgumentListInfo &ArgsInfo) {
|
||||
setTemplateArgsAsWritten(
|
||||
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo));
|
||||
/// Gets the type of this specialization as it was written by
|
||||
/// the user, if it was so written.
|
||||
TypeSourceInfo *getTypeAsWritten() const {
|
||||
return ExplicitInfo ? ExplicitInfo->TypeAsWritten : nullptr;
|
||||
}
|
||||
|
||||
/// Gets the location of the extern keyword, if present.
|
||||
SourceLocation getExternKeywordLoc() const {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
return Info->ExternKeywordLoc;
|
||||
return SourceLocation();
|
||||
SourceLocation getExternLoc() const {
|
||||
return ExplicitInfo ? ExplicitInfo->ExternLoc : SourceLocation();
|
||||
}
|
||||
|
||||
/// Sets the location of the extern keyword.
|
||||
void setExternKeywordLoc(SourceLocation Loc);
|
||||
|
||||
/// Gets the location of the template keyword, if present.
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
if (auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>())
|
||||
return Info->TemplateKeywordLoc;
|
||||
return SourceLocation();
|
||||
void setExternLoc(SourceLocation Loc) {
|
||||
if (!ExplicitInfo)
|
||||
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
|
||||
ExplicitInfo->ExternLoc = Loc;
|
||||
}
|
||||
|
||||
/// Sets the location of the template keyword.
|
||||
void setTemplateKeywordLoc(SourceLocation Loc);
|
||||
void setTemplateKeywordLoc(SourceLocation Loc) {
|
||||
if (!ExplicitInfo)
|
||||
ExplicitInfo = new (getASTContext()) ExplicitSpecializationInfo;
|
||||
ExplicitInfo->TemplateKeywordLoc = Loc;
|
||||
}
|
||||
|
||||
/// Gets the location of the template keyword, if present.
|
||||
SourceLocation getTemplateKeywordLoc() const {
|
||||
return ExplicitInfo ? ExplicitInfo->TemplateKeywordLoc : SourceLocation();
|
||||
}
|
||||
|
||||
SourceRange getSourceRange() const override LLVM_READONLY;
|
||||
|
||||
@ -2839,6 +2863,10 @@ class VarTemplatePartialSpecializationDecl
|
||||
/// The list of template parameters
|
||||
TemplateParameterList *TemplateParams = nullptr;
|
||||
|
||||
/// The source info for the template arguments as written.
|
||||
/// FIXME: redundant with TypeAsWritten?
|
||||
const ASTTemplateArgumentListInfo *ArgsAsWritten = nullptr;
|
||||
|
||||
/// The variable template partial specialization from which this
|
||||
/// variable template partial specialization was instantiated.
|
||||
///
|
||||
@ -2851,7 +2879,8 @@ class VarTemplatePartialSpecializationDecl
|
||||
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
|
||||
StorageClass S, ArrayRef<TemplateArgument> Args);
|
||||
StorageClass S, ArrayRef<TemplateArgument> Args,
|
||||
const ASTTemplateArgumentListInfo *ArgInfos);
|
||||
|
||||
VarTemplatePartialSpecializationDecl(ASTContext &Context)
|
||||
: VarTemplateSpecializationDecl(VarTemplatePartialSpecialization,
|
||||
@ -2868,8 +2897,8 @@ public:
|
||||
Create(ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
VarTemplateDecl *SpecializedTemplate, QualType T,
|
||||
TypeSourceInfo *TInfo, StorageClass S,
|
||||
ArrayRef<TemplateArgument> Args);
|
||||
TypeSourceInfo *TInfo, StorageClass S, ArrayRef<TemplateArgument> Args,
|
||||
const TemplateArgumentListInfo &ArgInfos);
|
||||
|
||||
static VarTemplatePartialSpecializationDecl *
|
||||
CreateDeserialized(ASTContext &C, GlobalDeclID ID);
|
||||
@ -2885,6 +2914,11 @@ public:
|
||||
return TemplateParams;
|
||||
}
|
||||
|
||||
/// Get the template arguments as written.
|
||||
const ASTTemplateArgumentListInfo *getTemplateArgsAsWritten() const {
|
||||
return ArgsAsWritten;
|
||||
}
|
||||
|
||||
/// \brief All associated constraints of this partial specialization,
|
||||
/// including the requires clause and any constraints derived from
|
||||
/// constrained-parameters.
|
||||
|
@ -2030,15 +2030,6 @@ DEF_TRAVERSE_DECL(RecordDecl, { TRY_TO(TraverseRecordHelper(D)); })
|
||||
|
||||
DEF_TRAVERSE_DECL(CXXRecordDecl, { TRY_TO(TraverseCXXRecordHelper(D)); })
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
|
||||
const TemplateArgumentLoc *TAL, unsigned Count) {
|
||||
for (unsigned I = 0; I < Count; ++I) {
|
||||
TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DEF_TRAVERSE_TMPL_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
|
||||
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplateSpecializationDecl, { \
|
||||
/* For implicit instantiations ("set<int> x;"), we don't want to \
|
||||
@ -2048,12 +2039,9 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
|
||||
TemplateSpecializationType). For explicit instantiations \
|
||||
("template set<int>;"), we do need a callback, since this \
|
||||
is the only callback that's made for this instantiation. \
|
||||
We use getTemplateArgsAsWritten() to distinguish. */ \
|
||||
if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) { \
|
||||
/* The args that remains unspecialized. */ \
|
||||
TRY_TO(TraverseTemplateArgumentLocsHelper( \
|
||||
ArgsWritten->getTemplateArgs(), ArgsWritten->NumTemplateArgs)); \
|
||||
} \
|
||||
We use getTypeAsWritten() to distinguish. */ \
|
||||
if (TypeSourceInfo *TSI = D->getTypeAsWritten()) \
|
||||
TRY_TO(TraverseTypeLoc(TSI->getTypeLoc())); \
|
||||
\
|
||||
if (getDerived().shouldVisitTemplateInstantiations() || \
|
||||
D->getTemplateSpecializationKind() == TSK_ExplicitSpecialization) { \
|
||||
@ -2073,6 +2061,15 @@ bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
|
||||
DEF_TRAVERSE_TMPL_SPEC_DECL(Class, CXXRecord)
|
||||
DEF_TRAVERSE_TMPL_SPEC_DECL(Var, Var)
|
||||
|
||||
template <typename Derived>
|
||||
bool RecursiveASTVisitor<Derived>::TraverseTemplateArgumentLocsHelper(
|
||||
const TemplateArgumentLoc *TAL, unsigned Count) {
|
||||
for (unsigned I = 0; I < Count; ++I) {
|
||||
TRY_TO(TraverseTemplateArgumentLoc(TAL[I]));
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
#define DEF_TRAVERSE_TMPL_PART_SPEC_DECL(TMPLDECLKIND, DECLKIND) \
|
||||
DEF_TRAVERSE_DECL(TMPLDECLKIND##TemplatePartialSpecializationDecl, { \
|
||||
/* The partial specialization. */ \
|
||||
|
@ -764,9 +764,9 @@ AST_POLYMORPHIC_MATCHER(isImplicit,
|
||||
return Node.isImplicit();
|
||||
}
|
||||
|
||||
/// Matches templateSpecializationTypes, class template specializations,
|
||||
/// variable template specializations, and function template specializations
|
||||
/// that have at least one TemplateArgument matching the given InnerMatcher.
|
||||
/// Matches classTemplateSpecializations, templateSpecializationType and
|
||||
/// functionDecl that have at least one TemplateArgument matching the given
|
||||
/// InnerMatcher.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
@ -788,8 +788,8 @@ AST_POLYMORPHIC_MATCHER(isImplicit,
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
hasAnyTemplateArgument,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
|
||||
VarTemplateSpecializationDecl, FunctionDecl,
|
||||
TemplateSpecializationType),
|
||||
TemplateSpecializationType,
|
||||
FunctionDecl),
|
||||
internal::Matcher<TemplateArgument>, InnerMatcher) {
|
||||
ArrayRef<TemplateArgument> List =
|
||||
internal::getTemplateSpecializationArgs(Node);
|
||||
@ -1047,9 +1047,8 @@ AST_MATCHER(Expr, isTypeDependent) { return Node.isTypeDependent(); }
|
||||
/// expr(isValueDependent()) matches return Size
|
||||
AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }
|
||||
|
||||
/// Matches templateSpecializationType, class template specializations,
|
||||
/// variable template specializations, and function template specializations
|
||||
/// where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
/// Matches classTemplateSpecializations, templateSpecializationType and
|
||||
/// functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
@ -1069,8 +1068,8 @@ AST_MATCHER(Expr, isValueDependent) { return Node.isValueDependent(); }
|
||||
AST_POLYMORPHIC_MATCHER_P2(
|
||||
hasTemplateArgument,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
|
||||
VarTemplateSpecializationDecl, FunctionDecl,
|
||||
TemplateSpecializationType),
|
||||
TemplateSpecializationType,
|
||||
FunctionDecl),
|
||||
unsigned, N, internal::Matcher<TemplateArgument>, InnerMatcher) {
|
||||
ArrayRef<TemplateArgument> List =
|
||||
internal::getTemplateSpecializationArgs(Node);
|
||||
@ -4067,7 +4066,7 @@ AST_POLYMORPHIC_MATCHER_P_OVERLOAD(
|
||||
/// Matcher<CXXCtorInitializer>, Matcher<CXXFunctionalCastExpr>,
|
||||
/// Matcher<CXXNewExpr>, Matcher<CXXTemporaryObjectExpr>,
|
||||
/// Matcher<CXXUnresolvedConstructExpr>,
|
||||
/// Matcher<CompoundLiteralExpr>,
|
||||
/// Matcher<ClassTemplateSpecializationDecl>, Matcher<CompoundLiteralExpr>,
|
||||
/// Matcher<DeclaratorDecl>, Matcher<ExplicitCastExpr>,
|
||||
/// Matcher<ObjCPropertyDecl>, Matcher<TemplateArgumentLoc>,
|
||||
/// Matcher<TypedefNameDecl>
|
||||
@ -4076,8 +4075,9 @@ AST_POLYMORPHIC_MATCHER_P(
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(
|
||||
BlockDecl, CXXBaseSpecifier, CXXCtorInitializer, CXXFunctionalCastExpr,
|
||||
CXXNewExpr, CXXTemporaryObjectExpr, CXXUnresolvedConstructExpr,
|
||||
CompoundLiteralExpr, DeclaratorDecl, ExplicitCastExpr, ObjCPropertyDecl,
|
||||
TemplateArgumentLoc, TypedefNameDecl),
|
||||
ClassTemplateSpecializationDecl, CompoundLiteralExpr, DeclaratorDecl,
|
||||
ExplicitCastExpr, ObjCPropertyDecl, TemplateArgumentLoc,
|
||||
TypedefNameDecl),
|
||||
internal::Matcher<TypeLoc>, Inner) {
|
||||
TypeSourceInfo *source = internal::GetTypeSourceInfo(Node);
|
||||
if (source == nullptr) {
|
||||
@ -5304,10 +5304,9 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
|
||||
return Node.getNumParams() == N;
|
||||
}
|
||||
|
||||
/// Matches templateSpecializationType, class template specialization,
|
||||
/// variable template specialization, and function template specialization
|
||||
/// nodes where the template argument matches the inner matcher. This matcher
|
||||
/// may produce multiple matches.
|
||||
/// Matches classTemplateSpecialization, templateSpecializationType and
|
||||
/// functionDecl nodes where the template argument matches the inner matcher.
|
||||
/// This matcher may produce multiple matches.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
@ -5331,8 +5330,7 @@ AST_POLYMORPHIC_MATCHER_P(parameterCountIs,
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
forEachTemplateArgument,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
|
||||
VarTemplateSpecializationDecl, FunctionDecl,
|
||||
TemplateSpecializationType),
|
||||
TemplateSpecializationType, FunctionDecl),
|
||||
internal::Matcher<TemplateArgument>, InnerMatcher) {
|
||||
ArrayRef<TemplateArgument> TemplateArgs =
|
||||
clang::ast_matchers::internal::getTemplateSpecializationArgs(Node);
|
||||
@ -6907,10 +6905,8 @@ extern const internal::VariadicDynCastAllOfMatcher<
|
||||
TypeLoc, TemplateSpecializationTypeLoc>
|
||||
templateSpecializationTypeLoc;
|
||||
|
||||
/// Matches template specialization `TypeLoc`s, class template specializations,
|
||||
/// variable template specializations, and function template specializations
|
||||
/// that have at least one `TemplateArgumentLoc` matching the given
|
||||
/// `InnerMatcher`.
|
||||
/// Matches template specialization `TypeLoc`s that have at least one
|
||||
/// `TemplateArgumentLoc` matching the given `InnerMatcher`.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
@ -6920,21 +6916,20 @@ extern const internal::VariadicDynCastAllOfMatcher<
|
||||
/// varDecl(hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
/// hasTypeLoc(loc(asString("int")))))))
|
||||
/// matches `A<int> a`.
|
||||
AST_POLYMORPHIC_MATCHER_P(
|
||||
hasAnyTemplateArgumentLoc,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
|
||||
VarTemplateSpecializationDecl, FunctionDecl,
|
||||
DeclRefExpr, TemplateSpecializationTypeLoc),
|
||||
internal::Matcher<TemplateArgumentLoc>, InnerMatcher) {
|
||||
auto Args = internal::getTemplateArgsWritten(Node);
|
||||
return matchesFirstInRange(InnerMatcher, Args.begin(), Args.end(), Finder,
|
||||
Builder) != Args.end();
|
||||
AST_MATCHER_P(TemplateSpecializationTypeLoc, hasAnyTemplateArgumentLoc,
|
||||
internal::Matcher<TemplateArgumentLoc>, InnerMatcher) {
|
||||
for (unsigned Index = 0, N = Node.getNumArgs(); Index < N; ++Index) {
|
||||
clang::ast_matchers::internal::BoundNodesTreeBuilder Result(*Builder);
|
||||
if (InnerMatcher.matches(Node.getArgLoc(Index), Finder, &Result)) {
|
||||
*Builder = std::move(Result);
|
||||
return true;
|
||||
}
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Matches template specialization `TypeLoc`s, class template specializations,
|
||||
/// variable template specializations, and function template specializations
|
||||
/// where the n'th `TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
/// Matches template specialization `TypeLoc`s where the n'th
|
||||
/// `TemplateArgumentLoc` matches the given `InnerMatcher`.
|
||||
///
|
||||
/// Given
|
||||
/// \code
|
||||
@ -6947,13 +6942,10 @@ AST_POLYMORPHIC_MATCHER_P(
|
||||
/// matches `A<double, int> b`, but not `A<int, double> c`.
|
||||
AST_POLYMORPHIC_MATCHER_P2(
|
||||
hasTemplateArgumentLoc,
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(ClassTemplateSpecializationDecl,
|
||||
VarTemplateSpecializationDecl, FunctionDecl,
|
||||
DeclRefExpr, TemplateSpecializationTypeLoc),
|
||||
AST_POLYMORPHIC_SUPPORTED_TYPES(DeclRefExpr, TemplateSpecializationTypeLoc),
|
||||
unsigned, Index, internal::Matcher<TemplateArgumentLoc>, InnerMatcher) {
|
||||
auto Args = internal::getTemplateArgsWritten(Node);
|
||||
return Index < Args.size() &&
|
||||
InnerMatcher.matches(Args[Index], Finder, Builder);
|
||||
return internal::MatchTemplateArgLocAt(Node, Index, InnerMatcher, Finder,
|
||||
Builder);
|
||||
}
|
||||
|
||||
/// Matches C or C++ elaborated `TypeLoc`s.
|
||||
|
@ -186,6 +186,10 @@ inline TypeSourceInfo *GetTypeSourceInfo(const BlockDecl &Node) {
|
||||
inline TypeSourceInfo *GetTypeSourceInfo(const CXXNewExpr &Node) {
|
||||
return Node.getAllocatedTypeSourceInfo();
|
||||
}
|
||||
inline TypeSourceInfo *
|
||||
GetTypeSourceInfo(const ClassTemplateSpecializationDecl &Node) {
|
||||
return Node.getTypeAsWritten();
|
||||
}
|
||||
|
||||
/// Unifies obtaining the FunctionProtoType pointer from both
|
||||
/// FunctionProtoType and FunctionDecl nodes..
|
||||
@ -1935,11 +1939,6 @@ getTemplateSpecializationArgs(const ClassTemplateSpecializationDecl &D) {
|
||||
return D.getTemplateArgs().asArray();
|
||||
}
|
||||
|
||||
inline ArrayRef<TemplateArgument>
|
||||
getTemplateSpecializationArgs(const VarTemplateSpecializationDecl &D) {
|
||||
return D.getTemplateArgs().asArray();
|
||||
}
|
||||
|
||||
inline ArrayRef<TemplateArgument>
|
||||
getTemplateSpecializationArgs(const TemplateSpecializationType &T) {
|
||||
return T.template_arguments();
|
||||
@ -1949,46 +1948,7 @@ inline ArrayRef<TemplateArgument>
|
||||
getTemplateSpecializationArgs(const FunctionDecl &FD) {
|
||||
if (const auto* TemplateArgs = FD.getTemplateSpecializationArgs())
|
||||
return TemplateArgs->asArray();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline ArrayRef<TemplateArgumentLoc>
|
||||
getTemplateArgsWritten(const ClassTemplateSpecializationDecl &D) {
|
||||
if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten())
|
||||
return Args->arguments();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline ArrayRef<TemplateArgumentLoc>
|
||||
getTemplateArgsWritten(const VarTemplateSpecializationDecl &D) {
|
||||
if (const ASTTemplateArgumentListInfo *Args = D.getTemplateArgsAsWritten())
|
||||
return Args->arguments();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline ArrayRef<TemplateArgumentLoc>
|
||||
getTemplateArgsWritten(const FunctionDecl &FD) {
|
||||
if (const auto *Args = FD.getTemplateSpecializationArgsAsWritten())
|
||||
return Args->arguments();
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline ArrayRef<TemplateArgumentLoc>
|
||||
getTemplateArgsWritten(const DeclRefExpr &DRE) {
|
||||
if (const auto *Args = DRE.getTemplateArgs())
|
||||
return {Args, DRE.getNumTemplateArgs()};
|
||||
return std::nullopt;
|
||||
}
|
||||
|
||||
inline SmallVector<TemplateArgumentLoc>
|
||||
getTemplateArgsWritten(const TemplateSpecializationTypeLoc &T) {
|
||||
SmallVector<TemplateArgumentLoc> Args;
|
||||
if (!T.isNull()) {
|
||||
Args.reserve(T.getNumArgs());
|
||||
for (unsigned I = 0; I < T.getNumArgs(); ++I)
|
||||
Args.emplace_back(T.getArgLoc(I));
|
||||
}
|
||||
return Args;
|
||||
return ArrayRef<TemplateArgument>();
|
||||
}
|
||||
|
||||
struct NotEqualsBoundNodePredicate {
|
||||
|
@ -443,9 +443,8 @@ namespace clang {
|
||||
Expected<FunctionTemplateAndArgsTy>
|
||||
ImportFunctionTemplateWithTemplateArgsFromSpecialization(
|
||||
FunctionDecl *FromFD);
|
||||
|
||||
template <typename DeclTy>
|
||||
Error ImportTemplateParameterLists(const DeclTy *FromD, DeclTy *ToD);
|
||||
Error ImportTemplateParameterLists(const DeclaratorDecl *FromD,
|
||||
DeclaratorDecl *ToD);
|
||||
|
||||
Error ImportTemplateInformation(FunctionDecl *FromFD, FunctionDecl *ToFD);
|
||||
|
||||
@ -3323,9 +3322,8 @@ ExpectedDecl ASTNodeImporter::VisitEnumConstantDecl(EnumConstantDecl *D) {
|
||||
return ToEnumerator;
|
||||
}
|
||||
|
||||
template <typename DeclTy>
|
||||
Error ASTNodeImporter::ImportTemplateParameterLists(const DeclTy *FromD,
|
||||
DeclTy *ToD) {
|
||||
Error ASTNodeImporter::ImportTemplateParameterLists(const DeclaratorDecl *FromD,
|
||||
DeclaratorDecl *ToD) {
|
||||
unsigned int Num = FromD->getNumTemplateParameterLists();
|
||||
if (Num == 0)
|
||||
return Error::success();
|
||||
@ -6212,16 +6210,15 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
|
||||
if (!IdLocOrErr)
|
||||
return IdLocOrErr.takeError();
|
||||
|
||||
// Import TemplateArgumentListInfo.
|
||||
TemplateArgumentListInfo ToTAInfo;
|
||||
if (const auto *ASTTemplateArgs = D->getTemplateArgsAsWritten()) {
|
||||
if (Error Err = ImportTemplateArgumentListInfo(*ASTTemplateArgs, ToTAInfo))
|
||||
return std::move(Err);
|
||||
}
|
||||
|
||||
// Create the specialization.
|
||||
ClassTemplateSpecializationDecl *D2 = nullptr;
|
||||
if (PartialSpec) {
|
||||
// Import TemplateArgumentListInfo.
|
||||
TemplateArgumentListInfo ToTAInfo;
|
||||
const auto &ASTTemplateArgs = *PartialSpec->getTemplateArgsAsWritten();
|
||||
if (Error Err = ImportTemplateArgumentListInfo(ASTTemplateArgs, ToTAInfo))
|
||||
return std::move(Err);
|
||||
|
||||
QualType CanonInjType;
|
||||
if (Error Err = importInto(
|
||||
CanonInjType, PartialSpec->getInjectedSpecializationType()))
|
||||
@ -6231,7 +6228,7 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
|
||||
if (GetImportedOrCreateDecl<ClassTemplatePartialSpecializationDecl>(
|
||||
D2, D, Importer.getToContext(), D->getTagKind(), DC, *BeginLocOrErr,
|
||||
*IdLocOrErr, ToTPList, ClassTemplate,
|
||||
llvm::ArrayRef(TemplateArgs.data(), TemplateArgs.size()),
|
||||
llvm::ArrayRef(TemplateArgs.data(), TemplateArgs.size()), ToTAInfo,
|
||||
CanonInjType,
|
||||
cast_or_null<ClassTemplatePartialSpecializationDecl>(PrevDecl)))
|
||||
return D2;
|
||||
@ -6279,27 +6276,28 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
|
||||
else
|
||||
return BraceRangeOrErr.takeError();
|
||||
|
||||
if (Error Err = ImportTemplateParameterLists(D, D2))
|
||||
return std::move(Err);
|
||||
|
||||
// Import the qualifier, if any.
|
||||
if (auto LocOrErr = import(D->getQualifierLoc()))
|
||||
D2->setQualifierInfo(*LocOrErr);
|
||||
else
|
||||
return LocOrErr.takeError();
|
||||
|
||||
if (D->getTemplateArgsAsWritten())
|
||||
D2->setTemplateArgsAsWritten(ToTAInfo);
|
||||
if (auto *TSI = D->getTypeAsWritten()) {
|
||||
if (auto TInfoOrErr = import(TSI))
|
||||
D2->setTypeAsWritten(*TInfoOrErr);
|
||||
else
|
||||
return TInfoOrErr.takeError();
|
||||
|
||||
if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
|
||||
D2->setTemplateKeywordLoc(*LocOrErr);
|
||||
else
|
||||
return LocOrErr.takeError();
|
||||
if (auto LocOrErr = import(D->getTemplateKeywordLoc()))
|
||||
D2->setTemplateKeywordLoc(*LocOrErr);
|
||||
else
|
||||
return LocOrErr.takeError();
|
||||
|
||||
if (auto LocOrErr = import(D->getExternKeywordLoc()))
|
||||
D2->setExternKeywordLoc(*LocOrErr);
|
||||
else
|
||||
return LocOrErr.takeError();
|
||||
if (auto LocOrErr = import(D->getExternLoc()))
|
||||
D2->setExternLoc(*LocOrErr);
|
||||
else
|
||||
return LocOrErr.takeError();
|
||||
}
|
||||
|
||||
if (D->getPointOfInstantiation().isValid()) {
|
||||
if (auto POIOrErr = import(D->getPointOfInstantiation()))
|
||||
@ -6519,7 +6517,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
|
||||
VarTemplateSpecializationDecl *D2 = nullptr;
|
||||
|
||||
TemplateArgumentListInfo ToTAInfo;
|
||||
if (const auto *Args = D->getTemplateArgsAsWritten()) {
|
||||
if (const ASTTemplateArgumentListInfo *Args = D->getTemplateArgsInfo()) {
|
||||
if (Error Err = ImportTemplateArgumentListInfo(*Args, ToTAInfo))
|
||||
return std::move(Err);
|
||||
}
|
||||
@ -6527,6 +6525,14 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
|
||||
using PartVarSpecDecl = VarTemplatePartialSpecializationDecl;
|
||||
// Create a new specialization.
|
||||
if (auto *FromPartial = dyn_cast<PartVarSpecDecl>(D)) {
|
||||
// Import TemplateArgumentListInfo
|
||||
TemplateArgumentListInfo ArgInfos;
|
||||
const auto *FromTAArgsAsWritten = FromPartial->getTemplateArgsAsWritten();
|
||||
// NOTE: FromTAArgsAsWritten and template parameter list are non-null.
|
||||
if (Error Err =
|
||||
ImportTemplateArgumentListInfo(*FromTAArgsAsWritten, ArgInfos))
|
||||
return std::move(Err);
|
||||
|
||||
auto ToTPListOrErr = import(FromPartial->getTemplateParameters());
|
||||
if (!ToTPListOrErr)
|
||||
return ToTPListOrErr.takeError();
|
||||
@ -6535,7 +6541,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
|
||||
if (GetImportedOrCreateDecl(ToPartial, D, Importer.getToContext(), DC,
|
||||
*BeginLocOrErr, *IdLocOrErr, *ToTPListOrErr,
|
||||
VarTemplate, QualType(), nullptr,
|
||||
D->getStorageClass(), TemplateArgs))
|
||||
D->getStorageClass(), TemplateArgs, ArgInfos))
|
||||
return ToPartial;
|
||||
|
||||
if (Expected<PartVarSpecDecl *> ToInstOrErr =
|
||||
@ -6578,9 +6584,7 @@ ExpectedDecl ASTNodeImporter::VisitVarTemplateSpecializationDecl(
|
||||
}
|
||||
|
||||
D2->setSpecializationKind(D->getSpecializationKind());
|
||||
|
||||
if (D->getTemplateArgsAsWritten())
|
||||
D2->setTemplateArgsAsWritten(ToTAInfo);
|
||||
D2->setTemplateArgsInfo(ToTAInfo);
|
||||
|
||||
if (auto LocOrErr = import(D->getQualifierLoc()))
|
||||
D2->setQualifierInfo(*LocOrErr);
|
||||
|
@ -1083,15 +1083,15 @@ void DeclPrinter::VisitCXXRecordDecl(CXXRecordDecl *D) {
|
||||
NNS->print(Out, Policy);
|
||||
Out << *D;
|
||||
|
||||
if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
|
||||
const TemplateParameterList *TParams =
|
||||
S->getSpecializedTemplate()->getTemplateParameters();
|
||||
const ASTTemplateArgumentListInfo *TArgAsWritten =
|
||||
S->getTemplateArgsAsWritten();
|
||||
if (TArgAsWritten && !Policy.PrintCanonicalTypes)
|
||||
printTemplateArguments(TArgAsWritten->arguments(), TParams);
|
||||
else
|
||||
printTemplateArguments(S->getTemplateArgs().asArray(), TParams);
|
||||
if (auto S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
|
||||
ArrayRef<TemplateArgument> Args = S->getTemplateArgs().asArray();
|
||||
if (!Policy.PrintCanonicalTypes)
|
||||
if (const auto* TSI = S->getTypeAsWritten())
|
||||
if (const auto *TST =
|
||||
dyn_cast<TemplateSpecializationType>(TSI->getType()))
|
||||
Args = TST->template_arguments();
|
||||
printTemplateArguments(
|
||||
Args, S->getSpecializedTemplate()->getTemplateParameters());
|
||||
}
|
||||
}
|
||||
|
||||
|
@ -985,63 +985,41 @@ ClassTemplateSpecializationDecl::getSpecializedTemplate() const {
|
||||
|
||||
SourceRange
|
||||
ClassTemplateSpecializationDecl::getSourceRange() const {
|
||||
if (getSpecializationKind() == TSK_ExplicitInstantiationDeclaration) {
|
||||
return SourceRange(getExternKeywordLoc(),
|
||||
getTemplateArgsAsWritten()->getRAngleLoc());
|
||||
} else if (getSpecializationKind() == TSK_ExplicitInstantiationDefinition) {
|
||||
return SourceRange(getTemplateKeywordLoc(),
|
||||
getTemplateArgsAsWritten()->getRAngleLoc());
|
||||
} else if (!isExplicitSpecialization()) {
|
||||
if (ExplicitInfo) {
|
||||
SourceLocation Begin = getTemplateKeywordLoc();
|
||||
if (Begin.isValid()) {
|
||||
// Here we have an explicit (partial) specialization or instantiation.
|
||||
assert(getSpecializationKind() == TSK_ExplicitSpecialization ||
|
||||
getSpecializationKind() == TSK_ExplicitInstantiationDeclaration ||
|
||||
getSpecializationKind() == TSK_ExplicitInstantiationDefinition);
|
||||
if (getExternLoc().isValid())
|
||||
Begin = getExternLoc();
|
||||
SourceLocation End = getBraceRange().getEnd();
|
||||
if (End.isInvalid())
|
||||
End = getTypeAsWritten()->getTypeLoc().getEndLoc();
|
||||
return SourceRange(Begin, End);
|
||||
}
|
||||
// An implicit instantiation of a class template partial specialization
|
||||
// uses ExplicitInfo to record the TypeAsWritten, but the source
|
||||
// locations should be retrieved from the instantiation pattern.
|
||||
using CTPSDecl = ClassTemplatePartialSpecializationDecl;
|
||||
auto *ctpsd = const_cast<CTPSDecl *>(cast<CTPSDecl>(this));
|
||||
CTPSDecl *inst_from = ctpsd->getInstantiatedFromMember();
|
||||
assert(inst_from != nullptr);
|
||||
return inst_from->getSourceRange();
|
||||
}
|
||||
else {
|
||||
// No explicit info available.
|
||||
llvm::PointerUnion<ClassTemplateDecl *,
|
||||
ClassTemplatePartialSpecializationDecl *>
|
||||
InstFrom = getInstantiatedFrom();
|
||||
if (InstFrom.isNull())
|
||||
inst_from = getInstantiatedFrom();
|
||||
if (inst_from.isNull())
|
||||
return getSpecializedTemplate()->getSourceRange();
|
||||
if (const auto *CTD = InstFrom.dyn_cast<ClassTemplateDecl *>())
|
||||
return CTD->getSourceRange();
|
||||
return InstFrom.get<ClassTemplatePartialSpecializationDecl *>()
|
||||
->getSourceRange();
|
||||
if (const auto *ctd = inst_from.dyn_cast<ClassTemplateDecl *>())
|
||||
return ctd->getSourceRange();
|
||||
return inst_from.get<ClassTemplatePartialSpecializationDecl *>()
|
||||
->getSourceRange();
|
||||
}
|
||||
SourceLocation Begin = TagDecl::getOuterLocStart();
|
||||
if (const auto *CTPSD =
|
||||
dyn_cast<ClassTemplatePartialSpecializationDecl>(this)) {
|
||||
if (const auto *InstFrom = CTPSD->getInstantiatedFromMember())
|
||||
return InstFrom->getSourceRange();
|
||||
else if (!getNumTemplateParameterLists())
|
||||
Begin = CTPSD->getTemplateParameters()->getTemplateLoc();
|
||||
}
|
||||
SourceLocation End = getBraceRange().getEnd();
|
||||
if (End.isInvalid())
|
||||
End = getTemplateArgsAsWritten()->getRAngleLoc();
|
||||
return SourceRange(Begin, End);
|
||||
}
|
||||
|
||||
void ClassTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
|
||||
auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
|
||||
if (!Info) {
|
||||
// Don't allocate if the location is invalid.
|
||||
if (Loc.isInvalid())
|
||||
return;
|
||||
Info = new (getASTContext()) ExplicitInstantiationInfo;
|
||||
Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
|
||||
ExplicitInfo = Info;
|
||||
}
|
||||
Info->ExternKeywordLoc = Loc;
|
||||
}
|
||||
|
||||
void ClassTemplateSpecializationDecl::setTemplateKeywordLoc(
|
||||
SourceLocation Loc) {
|
||||
auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
|
||||
if (!Info) {
|
||||
// Don't allocate if the location is invalid.
|
||||
if (Loc.isInvalid())
|
||||
return;
|
||||
Info = new (getASTContext()) ExplicitInstantiationInfo;
|
||||
Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
|
||||
ExplicitInfo = Info;
|
||||
}
|
||||
Info->TemplateKeywordLoc = Loc;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
@ -1109,29 +1087,43 @@ void ImplicitConceptSpecializationDecl::setTemplateArguments(
|
||||
//===----------------------------------------------------------------------===//
|
||||
void ClassTemplatePartialSpecializationDecl::anchor() {}
|
||||
|
||||
ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
|
||||
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl)
|
||||
: ClassTemplateSpecializationDecl(
|
||||
Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
|
||||
SpecializedTemplate, Args, PrevDecl),
|
||||
TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
|
||||
ClassTemplatePartialSpecializationDecl::
|
||||
ClassTemplatePartialSpecializationDecl(ASTContext &Context, TagKind TK,
|
||||
DeclContext *DC,
|
||||
SourceLocation StartLoc,
|
||||
SourceLocation IdLoc,
|
||||
TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
const ASTTemplateArgumentListInfo *ArgInfos,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl)
|
||||
: ClassTemplateSpecializationDecl(Context,
|
||||
ClassTemplatePartialSpecialization,
|
||||
TK, DC, StartLoc, IdLoc,
|
||||
SpecializedTemplate, Args, PrevDecl),
|
||||
TemplateParams(Params), ArgsAsWritten(ArgInfos),
|
||||
InstantiatedFromMember(nullptr, false) {
|
||||
if (AdoptTemplateParameterList(Params, this))
|
||||
setInvalidDecl();
|
||||
}
|
||||
|
||||
ClassTemplatePartialSpecializationDecl *
|
||||
ClassTemplatePartialSpecializationDecl::Create(
|
||||
ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
|
||||
QualType CanonInjectedType,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl) {
|
||||
auto *Result = new (Context, DC) ClassTemplatePartialSpecializationDecl(
|
||||
Context, TK, DC, StartLoc, IdLoc, Params, SpecializedTemplate, Args,
|
||||
PrevDecl);
|
||||
ClassTemplatePartialSpecializationDecl::
|
||||
Create(ASTContext &Context, TagKind TK,DeclContext *DC,
|
||||
SourceLocation StartLoc, SourceLocation IdLoc,
|
||||
TemplateParameterList *Params,
|
||||
ClassTemplateDecl *SpecializedTemplate,
|
||||
ArrayRef<TemplateArgument> Args,
|
||||
const TemplateArgumentListInfo &ArgInfos,
|
||||
QualType CanonInjectedType,
|
||||
ClassTemplatePartialSpecializationDecl *PrevDecl) {
|
||||
const ASTTemplateArgumentListInfo *ASTArgInfos =
|
||||
ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
|
||||
|
||||
auto *Result = new (Context, DC)
|
||||
ClassTemplatePartialSpecializationDecl(Context, TK, DC, StartLoc, IdLoc,
|
||||
Params, SpecializedTemplate, Args,
|
||||
ASTArgInfos, PrevDecl);
|
||||
Result->setSpecializationKind(TSK_ExplicitSpecialization);
|
||||
Result->setMayHaveOutOfDateDef(false);
|
||||
|
||||
@ -1379,47 +1371,26 @@ VarTemplateDecl *VarTemplateSpecializationDecl::getSpecializedTemplate() const {
|
||||
return SpecializedTemplate.get<VarTemplateDecl *>();
|
||||
}
|
||||
|
||||
void VarTemplateSpecializationDecl::setTemplateArgsInfo(
|
||||
const TemplateArgumentListInfo &ArgsInfo) {
|
||||
TemplateArgsInfo =
|
||||
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
|
||||
}
|
||||
|
||||
void VarTemplateSpecializationDecl::setTemplateArgsInfo(
|
||||
const ASTTemplateArgumentListInfo *ArgsInfo) {
|
||||
TemplateArgsInfo =
|
||||
ASTTemplateArgumentListInfo::Create(getASTContext(), ArgsInfo);
|
||||
}
|
||||
|
||||
SourceRange VarTemplateSpecializationDecl::getSourceRange() const {
|
||||
if (isExplicitSpecialization() && !hasInit()) {
|
||||
if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
|
||||
if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsInfo())
|
||||
return SourceRange(getOuterLocStart(), Info->getRAngleLoc());
|
||||
} else if (getTemplateSpecializationKind() ==
|
||||
TSK_ExplicitInstantiationDeclaration) {
|
||||
if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
|
||||
return SourceRange(getExternKeywordLoc(), Info->getRAngleLoc());
|
||||
} else if (getTemplateSpecializationKind() ==
|
||||
TSK_ExplicitInstantiationDefinition) {
|
||||
if (const ASTTemplateArgumentListInfo *Info = getTemplateArgsAsWritten())
|
||||
return SourceRange(getTemplateKeywordLoc(), Info->getRAngleLoc());
|
||||
}
|
||||
return VarDecl::getSourceRange();
|
||||
}
|
||||
|
||||
void VarTemplateSpecializationDecl::setExternKeywordLoc(SourceLocation Loc) {
|
||||
auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
|
||||
if (!Info) {
|
||||
// Don't allocate if the location is invalid.
|
||||
if (Loc.isInvalid())
|
||||
return;
|
||||
Info = new (getASTContext()) ExplicitInstantiationInfo;
|
||||
Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
|
||||
ExplicitInfo = Info;
|
||||
}
|
||||
Info->ExternKeywordLoc = Loc;
|
||||
}
|
||||
|
||||
void VarTemplateSpecializationDecl::setTemplateKeywordLoc(SourceLocation Loc) {
|
||||
auto *Info = ExplicitInfo.dyn_cast<ExplicitInstantiationInfo *>();
|
||||
if (!Info) {
|
||||
// Don't allocate if the location is invalid.
|
||||
if (Loc.isInvalid())
|
||||
return;
|
||||
Info = new (getASTContext()) ExplicitInstantiationInfo;
|
||||
Info->TemplateArgsAsWritten = getTemplateArgsAsWritten();
|
||||
ExplicitInfo = Info;
|
||||
}
|
||||
Info->TemplateKeywordLoc = Loc;
|
||||
}
|
||||
|
||||
//===----------------------------------------------------------------------===//
|
||||
// VarTemplatePartialSpecializationDecl Implementation
|
||||
@ -1431,11 +1402,13 @@ VarTemplatePartialSpecializationDecl::VarTemplatePartialSpecializationDecl(
|
||||
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
|
||||
StorageClass S, ArrayRef<TemplateArgument> Args)
|
||||
StorageClass S, ArrayRef<TemplateArgument> Args,
|
||||
const ASTTemplateArgumentListInfo *ArgInfos)
|
||||
: VarTemplateSpecializationDecl(VarTemplatePartialSpecialization, Context,
|
||||
DC, StartLoc, IdLoc, SpecializedTemplate, T,
|
||||
TInfo, S, Args),
|
||||
TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
|
||||
TemplateParams(Params), ArgsAsWritten(ArgInfos),
|
||||
InstantiatedFromMember(nullptr, false) {
|
||||
if (AdoptTemplateParameterList(Params, DC))
|
||||
setInvalidDecl();
|
||||
}
|
||||
@ -1445,10 +1418,15 @@ VarTemplatePartialSpecializationDecl::Create(
|
||||
ASTContext &Context, DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, TemplateParameterList *Params,
|
||||
VarTemplateDecl *SpecializedTemplate, QualType T, TypeSourceInfo *TInfo,
|
||||
StorageClass S, ArrayRef<TemplateArgument> Args) {
|
||||
auto *Result = new (Context, DC) VarTemplatePartialSpecializationDecl(
|
||||
Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo, S,
|
||||
Args);
|
||||
StorageClass S, ArrayRef<TemplateArgument> Args,
|
||||
const TemplateArgumentListInfo &ArgInfos) {
|
||||
const ASTTemplateArgumentListInfo *ASTArgInfos
|
||||
= ASTTemplateArgumentListInfo::Create(Context, ArgInfos);
|
||||
|
||||
auto *Result =
|
||||
new (Context, DC) VarTemplatePartialSpecializationDecl(
|
||||
Context, DC, StartLoc, IdLoc, Params, SpecializedTemplate, T, TInfo,
|
||||
S, Args, ASTArgInfos);
|
||||
Result->setSpecializationKind(TSK_ExplicitSpecialization);
|
||||
return Result;
|
||||
}
|
||||
|
@ -1472,18 +1472,21 @@ void TypePrinter::printTag(TagDecl *D, raw_ostream &OS) {
|
||||
|
||||
// If this is a class template specialization, print the template
|
||||
// arguments.
|
||||
if (auto *S = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
|
||||
const TemplateParameterList *TParams =
|
||||
S->getSpecializedTemplate()->getTemplateParameters();
|
||||
const ASTTemplateArgumentListInfo *TArgAsWritten =
|
||||
S->getTemplateArgsAsWritten();
|
||||
if (const auto *Spec = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
|
||||
ArrayRef<TemplateArgument> Args;
|
||||
TypeSourceInfo *TAW = Spec->getTypeAsWritten();
|
||||
if (!Policy.PrintCanonicalTypes && TAW) {
|
||||
const TemplateSpecializationType *TST =
|
||||
cast<TemplateSpecializationType>(TAW->getType());
|
||||
Args = TST->template_arguments();
|
||||
} else {
|
||||
const TemplateArgumentList &TemplateArgs = Spec->getTemplateArgs();
|
||||
Args = TemplateArgs.asArray();
|
||||
}
|
||||
IncludeStrongLifetimeRAII Strong(Policy);
|
||||
if (TArgAsWritten && !Policy.PrintCanonicalTypes)
|
||||
printTemplateArgumentList(OS, TArgAsWritten->arguments(), Policy,
|
||||
TParams);
|
||||
else
|
||||
printTemplateArgumentList(OS, S->getTemplateArgs().asArray(), Policy,
|
||||
TParams);
|
||||
printTemplateArgumentList(
|
||||
OS, Args, Policy,
|
||||
Spec->getSpecializedTemplate()->getTemplateParameters());
|
||||
}
|
||||
|
||||
spaceBeforePlaceHolder(OS);
|
||||
|
@ -673,12 +673,9 @@ public:
|
||||
IndexCtx.indexTagDecl(
|
||||
D, SymbolRelation(SymbolRoleSet(SymbolRole::RelationSpecializationOf),
|
||||
SpecializationOf));
|
||||
// Template specialization arguments.
|
||||
if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
|
||||
D->getTemplateArgsAsWritten()) {
|
||||
for (const auto &Arg : TemplateArgInfo->arguments())
|
||||
handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
|
||||
}
|
||||
if (TypeSourceInfo *TSI = D->getTypeAsWritten())
|
||||
IndexCtx.indexTypeSourceInfo(TSI, /*Parent=*/nullptr,
|
||||
D->getLexicalDeclContext());
|
||||
return true;
|
||||
}
|
||||
|
||||
|
@ -1408,7 +1408,7 @@ void Sema::ActOnEndOfTranslationUnit() {
|
||||
SourceRange DiagRange = DiagD->getLocation();
|
||||
if (const auto *VTSD = dyn_cast<VarTemplateSpecializationDecl>(DiagD)) {
|
||||
if (const ASTTemplateArgumentListInfo *ASTTAL =
|
||||
VTSD->getTemplateArgsAsWritten())
|
||||
VTSD->getTemplateArgsInfo())
|
||||
DiagRange.setEnd(ASTTAL->RAngleLoc);
|
||||
}
|
||||
if (DiagD->isReferenced()) {
|
||||
|
@ -5166,8 +5166,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
|
||||
VarTemplatePartialSpecializationDecl::Create(
|
||||
Context, VarTemplate->getDeclContext(), TemplateKWLoc,
|
||||
TemplateNameLoc, TemplateParams, VarTemplate, DI->getType(), DI, SC,
|
||||
CanonicalConverted);
|
||||
Partial->setTemplateArgsAsWritten(TemplateArgs);
|
||||
CanonicalConverted, TemplateArgs);
|
||||
|
||||
if (!PrevPartial)
|
||||
VarTemplate->AddPartialSpecialization(Partial, InsertPos);
|
||||
@ -5185,7 +5184,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
|
||||
Specialization = VarTemplateSpecializationDecl::Create(
|
||||
Context, VarTemplate->getDeclContext(), TemplateKWLoc, TemplateNameLoc,
|
||||
VarTemplate, DI->getType(), DI, SC, CanonicalConverted);
|
||||
Specialization->setTemplateArgsAsWritten(TemplateArgs);
|
||||
Specialization->setTemplateArgsInfo(TemplateArgs);
|
||||
|
||||
if (!PrevDecl)
|
||||
VarTemplate->AddSpecialization(Specialization, InsertPos);
|
||||
@ -5220,6 +5219,7 @@ DeclResult Sema::ActOnVarTemplateSpecialization(
|
||||
}
|
||||
}
|
||||
|
||||
Specialization->setTemplateKeywordLoc(TemplateKWLoc);
|
||||
Specialization->setLexicalDeclContext(CurContext);
|
||||
|
||||
// Add the specialization into its lexical context, so that it can
|
||||
@ -9489,8 +9489,7 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
|
||||
ClassTemplatePartialSpecializationDecl::Create(
|
||||
Context, Kind, ClassTemplate->getDeclContext(), KWLoc,
|
||||
TemplateNameLoc, TemplateParams, ClassTemplate, CanonicalConverted,
|
||||
CanonType, PrevPartial);
|
||||
Partial->setTemplateArgsAsWritten(TemplateArgs);
|
||||
TemplateArgs, CanonType, PrevPartial);
|
||||
SetNestedNameSpecifier(*this, Partial, SS);
|
||||
if (TemplateParameterLists.size() > 1 && SS.isSet()) {
|
||||
Partial->setTemplateParameterListsInfo(
|
||||
@ -9513,7 +9512,6 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
|
||||
Specialization = ClassTemplateSpecializationDecl::Create(
|
||||
Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc,
|
||||
ClassTemplate, CanonicalConverted, PrevDecl);
|
||||
Specialization->setTemplateArgsAsWritten(TemplateArgs);
|
||||
SetNestedNameSpecifier(*this, Specialization, SS);
|
||||
if (TemplateParameterLists.size() > 0) {
|
||||
Specialization->setTemplateParameterListsInfo(Context,
|
||||
@ -9597,6 +9595,21 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
|
||||
<< (isPartialSpecialization? 1 : 0)
|
||||
<< FixItHint::CreateRemoval(ModulePrivateLoc);
|
||||
|
||||
// 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
|
||||
// from the specialization's declaration the way that the user
|
||||
// actually wrote the specialization, rather than formatting the
|
||||
// name based on the "canonical" representation used to store the
|
||||
// template arguments in the specialization.
|
||||
TypeSourceInfo *WrittenTy
|
||||
= Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
|
||||
TemplateArgs, CanonType);
|
||||
if (TUK != TUK_Friend) {
|
||||
Specialization->setTypeAsWritten(WrittenTy);
|
||||
Specialization->setTemplateKeywordLoc(TemplateKWLoc);
|
||||
}
|
||||
|
||||
// C++ [temp.expl.spec]p9:
|
||||
// A template explicit specialization is in the scope of the
|
||||
// namespace in which the template was defined.
|
||||
@ -9612,15 +9625,6 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
|
||||
Specialization->startDefinition();
|
||||
|
||||
if (TUK == TUK_Friend) {
|
||||
// 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
|
||||
// from the specialization's declaration the way that the user
|
||||
// actually wrote the specialization, rather than formatting the
|
||||
// name based on the "canonical" representation used to store the
|
||||
// template arguments in the specialization.
|
||||
TypeSourceInfo *WrittenTy = Context.getTemplateSpecializationTypeInfo(
|
||||
Name, TemplateNameLoc, TemplateArgs, CanonType);
|
||||
FriendDecl *Friend = FriendDecl::Create(Context, CurContext,
|
||||
TemplateNameLoc,
|
||||
WrittenTy,
|
||||
@ -10826,10 +10830,21 @@ DeclResult Sema::ActOnExplicitInstantiation(
|
||||
}
|
||||
}
|
||||
|
||||
Specialization->setTemplateArgsAsWritten(TemplateArgs);
|
||||
// Build the fully-sugared type for this explicit instantiation as
|
||||
// the user wrote in the explicit instantiation itself. This means
|
||||
// that we'll pretty-print the type retrieved from the
|
||||
// specialization's declaration the way that the user actually wrote
|
||||
// the explicit instantiation, rather than formatting the name based
|
||||
// on the "canonical" representation used to store the template
|
||||
// arguments in the specialization.
|
||||
TypeSourceInfo *WrittenTy
|
||||
= Context.getTemplateSpecializationTypeInfo(Name, TemplateNameLoc,
|
||||
TemplateArgs,
|
||||
Context.getTypeDeclType(Specialization));
|
||||
Specialization->setTypeAsWritten(WrittenTy);
|
||||
|
||||
// Set source locations for keywords.
|
||||
Specialization->setExternKeywordLoc(ExternLoc);
|
||||
Specialization->setExternLoc(ExternLoc);
|
||||
Specialization->setTemplateKeywordLoc(TemplateLoc);
|
||||
Specialization->setBraceRange(SourceRange());
|
||||
|
||||
@ -11242,11 +11257,6 @@ DeclResult Sema::ActOnExplicitInstantiation(Scope *S,
|
||||
if (!HasNoEffect) {
|
||||
// Instantiate static data member or variable template.
|
||||
Prev->setTemplateSpecializationKind(TSK, D.getIdentifierLoc());
|
||||
if (auto *VTSD = dyn_cast<VarTemplatePartialSpecializationDecl>(Prev)) {
|
||||
VTSD->setExternKeywordLoc(ExternLoc);
|
||||
VTSD->setTemplateKeywordLoc(TemplateLoc);
|
||||
}
|
||||
|
||||
// Merge attributes.
|
||||
ProcessDeclAttributeList(S, Prev, D.getDeclSpec().getAttributes());
|
||||
if (PrevTemplate)
|
||||
|
@ -3858,16 +3858,15 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
|
||||
|
||||
// Substitute into the template arguments of the class template explicit
|
||||
// specialization.
|
||||
TemplateArgumentListInfo InstTemplateArgs;
|
||||
if (const ASTTemplateArgumentListInfo *TemplateArgsInfo =
|
||||
D->getTemplateArgsAsWritten()) {
|
||||
InstTemplateArgs.setLAngleLoc(TemplateArgsInfo->getLAngleLoc());
|
||||
InstTemplateArgs.setRAngleLoc(TemplateArgsInfo->getRAngleLoc());
|
||||
|
||||
if (SemaRef.SubstTemplateArguments(TemplateArgsInfo->arguments(),
|
||||
TemplateArgs, InstTemplateArgs))
|
||||
return nullptr;
|
||||
}
|
||||
TemplateSpecializationTypeLoc Loc = D->getTypeAsWritten()->getTypeLoc().
|
||||
castAs<TemplateSpecializationTypeLoc>();
|
||||
TemplateArgumentListInfo InstTemplateArgs(Loc.getLAngleLoc(),
|
||||
Loc.getRAngleLoc());
|
||||
SmallVector<TemplateArgumentLoc, 4> ArgLocs;
|
||||
for (unsigned I = 0; I != Loc.getNumArgs(); ++I)
|
||||
ArgLocs.push_back(Loc.getArgLoc(I));
|
||||
if (SemaRef.SubstTemplateArguments(ArgLocs, TemplateArgs, InstTemplateArgs))
|
||||
return nullptr;
|
||||
|
||||
// Check that the template argument list is well-formed for this
|
||||
// class template.
|
||||
@ -3921,7 +3920,6 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
|
||||
ClassTemplateSpecializationDecl::Create(
|
||||
SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(),
|
||||
D->getLocation(), InstClassTemplate, CanonicalConverted, PrevDecl);
|
||||
InstD->setTemplateArgsAsWritten(InstTemplateArgs);
|
||||
|
||||
// Add this partial specialization to the set of class template partial
|
||||
// specializations.
|
||||
@ -3938,10 +3936,22 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
|
||||
TemplateName(InstClassTemplate), CanonicalConverted,
|
||||
SemaRef.Context.getRecordType(InstD));
|
||||
|
||||
// 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
|
||||
// from the specialization's declaration the way that the user
|
||||
// actually wrote the specialization, rather than formatting the
|
||||
// name based on the "canonical" representation used to store the
|
||||
// template arguments in the specialization.
|
||||
TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo(
|
||||
TemplateName(InstClassTemplate), D->getLocation(), InstTemplateArgs,
|
||||
CanonType);
|
||||
|
||||
InstD->setAccess(D->getAccess());
|
||||
InstD->setInstantiationOfMemberClass(D, TSK_ImplicitInstantiation);
|
||||
InstD->setSpecializationKind(D->getSpecializationKind());
|
||||
InstD->setExternKeywordLoc(D->getExternKeywordLoc());
|
||||
InstD->setTypeAsWritten(WrittenTy);
|
||||
InstD->setExternLoc(D->getExternLoc());
|
||||
InstD->setTemplateKeywordLoc(D->getTemplateKeywordLoc());
|
||||
|
||||
Owner->addDecl(InstD);
|
||||
@ -3975,7 +3985,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
|
||||
|
||||
// Substitute the current template arguments.
|
||||
if (const ASTTemplateArgumentListInfo *TemplateArgsInfo =
|
||||
D->getTemplateArgsAsWritten()) {
|
||||
D->getTemplateArgsInfo()) {
|
||||
VarTemplateArgsInfo.setLAngleLoc(TemplateArgsInfo->getLAngleLoc());
|
||||
VarTemplateArgsInfo.setRAngleLoc(TemplateArgsInfo->getRAngleLoc());
|
||||
|
||||
@ -4033,7 +4043,7 @@ Decl *TemplateDeclInstantiator::VisitVarTemplateSpecializationDecl(
|
||||
VarTemplateSpecializationDecl *Var = VarTemplateSpecializationDecl::Create(
|
||||
SemaRef.Context, Owner, D->getInnerLocStart(), D->getLocation(),
|
||||
VarTemplate, DI->getType(), DI, D->getStorageClass(), Converted);
|
||||
Var->setTemplateArgsAsWritten(TemplateArgsInfo);
|
||||
Var->setTemplateArgsInfo(TemplateArgsInfo);
|
||||
if (!PrevDecl) {
|
||||
void *InsertPos = nullptr;
|
||||
VarTemplate->findSpecialization(Converted, InsertPos);
|
||||
@ -4275,21 +4285,19 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
|
||||
QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
|
||||
TemplateName(ClassTemplate), CanonicalConverted);
|
||||
|
||||
// Create the class template partial specialization declaration.
|
||||
ClassTemplatePartialSpecializationDecl *InstPartialSpec =
|
||||
ClassTemplatePartialSpecializationDecl::Create(
|
||||
SemaRef.Context, PartialSpec->getTagKind(), Owner,
|
||||
PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams,
|
||||
ClassTemplate, CanonicalConverted, CanonType,
|
||||
/*PrevDecl=*/nullptr);
|
||||
|
||||
InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs);
|
||||
|
||||
// Substitute the nested name specifier, if any.
|
||||
if (SubstQualifier(PartialSpec, InstPartialSpec))
|
||||
return nullptr;
|
||||
|
||||
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
|
||||
// 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
|
||||
// from the specialization's declaration the way that the user
|
||||
// actually wrote the specialization, rather than formatting the
|
||||
// name based on the "canonical" representation used to store the
|
||||
// template arguments in the specialization.
|
||||
TypeSourceInfo *WrittenTy
|
||||
= SemaRef.Context.getTemplateSpecializationTypeInfo(
|
||||
TemplateName(ClassTemplate),
|
||||
PartialSpec->getLocation(),
|
||||
InstTemplateArgs,
|
||||
CanonType);
|
||||
|
||||
if (PrevDecl) {
|
||||
// We've already seen a partial specialization with the same template
|
||||
@ -4307,14 +4315,28 @@ TemplateDeclInstantiator::InstantiateClassTemplatePartialSpecialization(
|
||||
//
|
||||
// Outer<int, int> outer; // error: the partial specializations of Inner
|
||||
// // have the same signature.
|
||||
SemaRef.Diag(InstPartialSpec->getLocation(),
|
||||
diag::err_partial_spec_redeclared)
|
||||
<< InstPartialSpec;
|
||||
SemaRef.Diag(PartialSpec->getLocation(), diag::err_partial_spec_redeclared)
|
||||
<< WrittenTy->getType();
|
||||
SemaRef.Diag(PrevDecl->getLocation(), diag::note_prev_partial_spec_here)
|
||||
<< SemaRef.Context.getTypeDeclType(PrevDecl);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
|
||||
// Create the class template partial specialization declaration.
|
||||
ClassTemplatePartialSpecializationDecl *InstPartialSpec =
|
||||
ClassTemplatePartialSpecializationDecl::Create(
|
||||
SemaRef.Context, PartialSpec->getTagKind(), Owner,
|
||||
PartialSpec->getBeginLoc(), PartialSpec->getLocation(), InstParams,
|
||||
ClassTemplate, CanonicalConverted, InstTemplateArgs, CanonType,
|
||||
nullptr);
|
||||
// Substitute the nested name specifier, if any.
|
||||
if (SubstQualifier(PartialSpec, InstPartialSpec))
|
||||
return nullptr;
|
||||
|
||||
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
|
||||
InstPartialSpec->setTypeAsWritten(WrittenTy);
|
||||
|
||||
// Check the completed partial specialization.
|
||||
SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec);
|
||||
|
||||
@ -4383,34 +4405,21 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
|
||||
VarTemplate->findPartialSpecialization(CanonicalConverted, InstParams,
|
||||
InsertPos);
|
||||
|
||||
// Do substitution on the type of the declaration
|
||||
TypeSourceInfo *DI = SemaRef.SubstType(
|
||||
PartialSpec->getTypeSourceInfo(), TemplateArgs,
|
||||
PartialSpec->getTypeSpecStartLoc(), PartialSpec->getDeclName());
|
||||
if (!DI)
|
||||
return nullptr;
|
||||
// Build the canonical type that describes the converted template
|
||||
// arguments of the variable template partial specialization.
|
||||
QualType CanonType = SemaRef.Context.getTemplateSpecializationType(
|
||||
TemplateName(VarTemplate), CanonicalConverted);
|
||||
|
||||
if (DI->getType()->isFunctionType()) {
|
||||
SemaRef.Diag(PartialSpec->getLocation(),
|
||||
diag::err_variable_instantiates_to_function)
|
||||
<< PartialSpec->isStaticDataMember() << DI->getType();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the variable template partial specialization declaration.
|
||||
VarTemplatePartialSpecializationDecl *InstPartialSpec =
|
||||
VarTemplatePartialSpecializationDecl::Create(
|
||||
SemaRef.Context, Owner, PartialSpec->getInnerLocStart(),
|
||||
PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(),
|
||||
DI, PartialSpec->getStorageClass(), CanonicalConverted);
|
||||
|
||||
InstPartialSpec->setTemplateArgsAsWritten(InstTemplateArgs);
|
||||
|
||||
// Substitute the nested name specifier, if any.
|
||||
if (SubstQualifier(PartialSpec, InstPartialSpec))
|
||||
return nullptr;
|
||||
|
||||
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
|
||||
// Build the fully-sugared type for this variable template
|
||||
// specialization as the user wrote in the specialization
|
||||
// itself. This means that we'll pretty-print the type retrieved
|
||||
// from the specialization's declaration the way that the user
|
||||
// actually wrote the specialization, rather than formatting the
|
||||
// name based on the "canonical" representation used to store the
|
||||
// template arguments in the specialization.
|
||||
TypeSourceInfo *WrittenTy = SemaRef.Context.getTemplateSpecializationTypeInfo(
|
||||
TemplateName(VarTemplate), PartialSpec->getLocation(), InstTemplateArgs,
|
||||
CanonType);
|
||||
|
||||
if (PrevDecl) {
|
||||
// We've already seen a partial specialization with the same template
|
||||
@ -4430,11 +4439,41 @@ TemplateDeclInstantiator::InstantiateVarTemplatePartialSpecialization(
|
||||
// // have the same signature.
|
||||
SemaRef.Diag(PartialSpec->getLocation(),
|
||||
diag::err_var_partial_spec_redeclared)
|
||||
<< InstPartialSpec;
|
||||
<< WrittenTy->getType();
|
||||
SemaRef.Diag(PrevDecl->getLocation(),
|
||||
diag::note_var_prev_partial_spec_here);
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Do substitution on the type of the declaration
|
||||
TypeSourceInfo *DI = SemaRef.SubstType(
|
||||
PartialSpec->getTypeSourceInfo(), TemplateArgs,
|
||||
PartialSpec->getTypeSpecStartLoc(), PartialSpec->getDeclName());
|
||||
if (!DI)
|
||||
return nullptr;
|
||||
|
||||
if (DI->getType()->isFunctionType()) {
|
||||
SemaRef.Diag(PartialSpec->getLocation(),
|
||||
diag::err_variable_instantiates_to_function)
|
||||
<< PartialSpec->isStaticDataMember() << DI->getType();
|
||||
return nullptr;
|
||||
}
|
||||
|
||||
// Create the variable template partial specialization declaration.
|
||||
VarTemplatePartialSpecializationDecl *InstPartialSpec =
|
||||
VarTemplatePartialSpecializationDecl::Create(
|
||||
SemaRef.Context, Owner, PartialSpec->getInnerLocStart(),
|
||||
PartialSpec->getLocation(), InstParams, VarTemplate, DI->getType(),
|
||||
DI, PartialSpec->getStorageClass(), CanonicalConverted,
|
||||
InstTemplateArgs);
|
||||
|
||||
// Substitute the nested name specifier, if any.
|
||||
if (SubstQualifier(PartialSpec, InstPartialSpec))
|
||||
return nullptr;
|
||||
|
||||
InstPartialSpec->setInstantiatedFromMember(PartialSpec);
|
||||
InstPartialSpec->setTypeAsWritten(WrittenTy);
|
||||
|
||||
// Check the completed partial specialization.
|
||||
SemaRef.CheckTemplatePartialSpecialization(InstPartialSpec);
|
||||
|
||||
@ -5696,7 +5735,7 @@ void Sema::InstantiateVariableDefinition(SourceLocation PointOfInstantiation,
|
||||
|
||||
TemplateArgumentListInfo TemplateArgInfo;
|
||||
if (const ASTTemplateArgumentListInfo *ArgInfo =
|
||||
VarSpec->getTemplateArgsAsWritten()) {
|
||||
VarSpec->getTemplateArgsInfo()) {
|
||||
TemplateArgInfo.setLAngleLoc(ArgInfo->getLAngleLoc());
|
||||
TemplateArgInfo.setRAngleLoc(ArgInfo->getRAngleLoc());
|
||||
for (const TemplateArgumentLoc &Arg : ArgInfo->arguments())
|
||||
|
@ -2548,17 +2548,16 @@ ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
|
||||
}
|
||||
}
|
||||
|
||||
// extern/template keyword locations for explicit instantiations
|
||||
if (Record.readBool()) {
|
||||
auto *ExplicitInfo = new (C) ExplicitInstantiationInfo;
|
||||
ExplicitInfo->ExternKeywordLoc = readSourceLocation();
|
||||
// Explicit info.
|
||||
if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) {
|
||||
auto *ExplicitInfo =
|
||||
new (C) ClassTemplateSpecializationDecl::ExplicitSpecializationInfo;
|
||||
ExplicitInfo->TypeAsWritten = TyInfo;
|
||||
ExplicitInfo->ExternLoc = readSourceLocation();
|
||||
ExplicitInfo->TemplateKeywordLoc = readSourceLocation();
|
||||
D->ExplicitInfo = ExplicitInfo;
|
||||
}
|
||||
|
||||
if (Record.readBool())
|
||||
D->setTemplateArgsAsWritten(Record.readASTTemplateArgumentListInfo());
|
||||
|
||||
return Redecl;
|
||||
}
|
||||
|
||||
@ -2568,6 +2567,7 @@ void ASTDeclReader::VisitClassTemplatePartialSpecializationDecl(
|
||||
// need them for profiling
|
||||
TemplateParameterList *Params = Record.readTemplateParameterList();
|
||||
D->TemplateParams = Params;
|
||||
D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
|
||||
|
||||
RedeclarableResult Redecl = VisitClassTemplateSpecializationDeclImpl(D);
|
||||
|
||||
@ -2617,17 +2617,16 @@ ASTDeclReader::VisitVarTemplateSpecializationDeclImpl(
|
||||
}
|
||||
}
|
||||
|
||||
// extern/template keyword locations for explicit instantiations
|
||||
if (Record.readBool()) {
|
||||
auto *ExplicitInfo = new (C) ExplicitInstantiationInfo;
|
||||
ExplicitInfo->ExternKeywordLoc = readSourceLocation();
|
||||
// Explicit info.
|
||||
if (TypeSourceInfo *TyInfo = readTypeSourceInfo()) {
|
||||
auto *ExplicitInfo =
|
||||
new (C) VarTemplateSpecializationDecl::ExplicitSpecializationInfo;
|
||||
ExplicitInfo->TypeAsWritten = TyInfo;
|
||||
ExplicitInfo->ExternLoc = readSourceLocation();
|
||||
ExplicitInfo->TemplateKeywordLoc = readSourceLocation();
|
||||
D->ExplicitInfo = ExplicitInfo;
|
||||
}
|
||||
|
||||
if (Record.readBool())
|
||||
D->setTemplateArgsAsWritten(Record.readASTTemplateArgumentListInfo());
|
||||
|
||||
SmallVector<TemplateArgument, 8> TemplArgs;
|
||||
Record.readTemplateArgumentList(TemplArgs, /*Canonicalize*/ true);
|
||||
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
|
||||
@ -2667,6 +2666,7 @@ void ASTDeclReader::VisitVarTemplatePartialSpecializationDecl(
|
||||
VarTemplatePartialSpecializationDecl *D) {
|
||||
TemplateParameterList *Params = Record.readTemplateParameterList();
|
||||
D->TemplateParams = Params;
|
||||
D->ArgsAsWritten = Record.readASTTemplateArgumentListInfo();
|
||||
|
||||
RedeclarableResult Redecl = VisitVarTemplateSpecializationDeclImpl(D);
|
||||
|
||||
|
@ -1765,28 +1765,20 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
|
||||
Record.AddDeclRef(D->getSpecializedTemplate()->getCanonicalDecl());
|
||||
}
|
||||
|
||||
bool ExplicitInstantiation =
|
||||
D->getTemplateSpecializationKind() ==
|
||||
TSK_ExplicitInstantiationDeclaration ||
|
||||
D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
|
||||
Record.push_back(ExplicitInstantiation);
|
||||
if (ExplicitInstantiation) {
|
||||
Record.AddSourceLocation(D->getExternKeywordLoc());
|
||||
// Explicit info.
|
||||
Record.AddTypeSourceInfo(D->getTypeAsWritten());
|
||||
if (D->getTypeAsWritten()) {
|
||||
Record.AddSourceLocation(D->getExternLoc());
|
||||
Record.AddSourceLocation(D->getTemplateKeywordLoc());
|
||||
}
|
||||
|
||||
const ASTTemplateArgumentListInfo *ArgsWritten =
|
||||
D->getTemplateArgsAsWritten();
|
||||
Record.push_back(!!ArgsWritten);
|
||||
if (ArgsWritten)
|
||||
Record.AddASTTemplateArgumentListInfo(ArgsWritten);
|
||||
|
||||
Code = serialization::DECL_CLASS_TEMPLATE_SPECIALIZATION;
|
||||
}
|
||||
|
||||
void ASTDeclWriter::VisitClassTemplatePartialSpecializationDecl(
|
||||
ClassTemplatePartialSpecializationDecl *D) {
|
||||
Record.AddTemplateParameterList(D->getTemplateParameters());
|
||||
Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
|
||||
|
||||
VisitClassTemplateSpecializationDecl(D);
|
||||
|
||||
@ -1820,22 +1812,13 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
|
||||
Record.AddTemplateArgumentList(&D->getTemplateInstantiationArgs());
|
||||
}
|
||||
|
||||
bool ExplicitInstantiation =
|
||||
D->getTemplateSpecializationKind() ==
|
||||
TSK_ExplicitInstantiationDeclaration ||
|
||||
D->getTemplateSpecializationKind() == TSK_ExplicitInstantiationDefinition;
|
||||
Record.push_back(ExplicitInstantiation);
|
||||
if (ExplicitInstantiation) {
|
||||
Record.AddSourceLocation(D->getExternKeywordLoc());
|
||||
// Explicit info.
|
||||
Record.AddTypeSourceInfo(D->getTypeAsWritten());
|
||||
if (D->getTypeAsWritten()) {
|
||||
Record.AddSourceLocation(D->getExternLoc());
|
||||
Record.AddSourceLocation(D->getTemplateKeywordLoc());
|
||||
}
|
||||
|
||||
const ASTTemplateArgumentListInfo *ArgsWritten =
|
||||
D->getTemplateArgsAsWritten();
|
||||
Record.push_back(!!ArgsWritten);
|
||||
if (ArgsWritten)
|
||||
Record.AddASTTemplateArgumentListInfo(ArgsWritten);
|
||||
|
||||
Record.AddTemplateArgumentList(&D->getTemplateArgs());
|
||||
Record.AddSourceLocation(D->getPointOfInstantiation());
|
||||
Record.push_back(D->getSpecializationKind());
|
||||
@ -1856,6 +1839,7 @@ void ASTDeclWriter::VisitVarTemplateSpecializationDecl(
|
||||
void ASTDeclWriter::VisitVarTemplatePartialSpecializationDecl(
|
||||
VarTemplatePartialSpecializationDecl *D) {
|
||||
Record.AddTemplateParameterList(D->getTemplateParameters());
|
||||
Record.AddASTTemplateArgumentListInfo(D->getTemplateArgsAsWritten());
|
||||
|
||||
VisitVarTemplateSpecializationDecl(D);
|
||||
|
||||
|
@ -735,8 +735,7 @@ public:
|
||||
auto *Declaration =
|
||||
cast<syntax::SimpleDeclaration>(handleFreeStandingTagDecl(C));
|
||||
foldExplicitTemplateInstantiation(
|
||||
Builder.getTemplateRange(C),
|
||||
Builder.findToken(C->getExternKeywordLoc()),
|
||||
Builder.getTemplateRange(C), Builder.findToken(C->getExternLoc()),
|
||||
Builder.findToken(C->getTemplateKeywordLoc()), Declaration, C);
|
||||
return true;
|
||||
}
|
||||
|
@ -1,12 +1,12 @@
|
||||
// Test without serialization:
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -ast-dump %s \
|
||||
// RUN: | FileCheck -strict-whitespace %s
|
||||
// RUN: | FileCheck -strict-whitespace %s --check-prefix=DIRECT
|
||||
//
|
||||
// Test with serialization:
|
||||
// RUN: %clang_cc1 -std=c++17 -triple x86_64-unknown-unknown -emit-pch -o %t %s
|
||||
// RUN: %clang_cc1 -x c++ -std=c++17 -triple x86_64-unknown-unknown -include-pch %t -ast-dump-all /dev/null \
|
||||
// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
|
||||
// RUN: | FileCheck --strict-whitespace %s
|
||||
// RUN: | FileCheck --strict-whitespace %s --check-prefix=SERIALIZED
|
||||
|
||||
template <typename Ty>
|
||||
// CHECK: FunctionTemplateDecl 0x{{[^ ]*}} <{{.*}}:1, line:[[@LINE+2]]:10> col:6 a
|
||||
@ -189,13 +189,15 @@ T unTempl = 1;
|
||||
|
||||
template<>
|
||||
int unTempl<int>;
|
||||
// CHECK: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:16> col:5 unTempl 'int'
|
||||
// FIXME (#61680) - serializing and loading AST should not affect reported source range
|
||||
// DIRECT: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:16> col:5 unTempl 'int'
|
||||
// SERIALIZED: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:5> col:5 unTempl 'int'
|
||||
// CHECK-NEXT: `-TemplateArgument type 'int'
|
||||
// CHECK-NEXT: `-BuiltinType 0x{{[^ ]*}} 'int'
|
||||
|
||||
template<>
|
||||
float unTempl<float> = 1;
|
||||
// CHECK: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:24> col:7 unTempl 'float'
|
||||
// CHECK: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:24> col:7 unTempl 'float' cinit
|
||||
// CHECK-NEXT: |-TemplateArgument type 'float'
|
||||
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
|
||||
// CHECK-NEXT: `-ImplicitCastExpr 0x{{[^ ]*}} <col:24> 'float' <IntegralToFloating>
|
||||
@ -220,7 +222,7 @@ int binTempl<int, U>;
|
||||
|
||||
template<class U>
|
||||
float binTempl<float, U> = 1;
|
||||
// CHECK: VarTemplatePartialSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:28> col:7 binTempl 'float'
|
||||
// CHECK: VarTemplatePartialSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:24> col:7 binTempl 'float' cinit
|
||||
// CHECK-NEXT: |-TemplateTypeParmDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:10, col:16> col:16 referenced class depth 0 index 0 U
|
||||
// CHECK-NEXT: |-TemplateArgument type 'float'
|
||||
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
|
||||
@ -231,7 +233,9 @@ float binTempl<float, U> = 1;
|
||||
|
||||
template<>
|
||||
int binTempl<int, int>;
|
||||
// CHECK: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:22> col:5 binTempl 'int'
|
||||
// FIXME (#61680) - serializing and loading AST should not affect reported source range
|
||||
// DIRECT: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:22> col:5 binTempl 'int'
|
||||
// SERIALIZED: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:5> col:5 binTempl 'int'
|
||||
// CHECK-NEXT: |-TemplateArgument type 'int'
|
||||
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'int'
|
||||
// CHECK-NEXT: `-TemplateArgument type 'int'
|
||||
@ -239,7 +243,7 @@ int binTempl<int, int>;
|
||||
|
||||
template<>
|
||||
float binTempl<float, float> = 1;
|
||||
// CHECK: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:32> col:7 binTempl 'float'
|
||||
// CHECK: VarTemplateSpecializationDecl 0x{{[^ ]*}} <line:{{[0-9]+}}:1, line:{{[0-9]+}}:32> col:7 binTempl 'float' cinit
|
||||
// CHECK-NEXT: |-TemplateArgument type 'float'
|
||||
// CHECK-NEXT: | `-BuiltinType 0x{{[^ ]*}} 'float'
|
||||
// CHECK-NEXT: |-TemplateArgument type 'float'
|
||||
|
@ -285,17 +285,20 @@ template<>
|
||||
class SpecializationDecl<int>;
|
||||
// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Decl,RelSpecialization | rel: 1
|
||||
// CHECK-NEXT: RelSpecialization | SpecializationDecl | c:@ST>1#T@SpecializationDecl
|
||||
// CHECK: [[@LINE-3]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Ref | rel: 0
|
||||
|
||||
template<>
|
||||
class SpecializationDecl<int> { };
|
||||
// CHECK: [[@LINE-1]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Def,RelSpecialization | rel: 1
|
||||
// CHECK-NEXT: RelSpecialization | SpecializationDecl | c:@ST>1#T@SpecializationDecl
|
||||
// CHECK-NEXT: [[@LINE-3]]:7 | class(Gen,TS)/C++ | SpecializationDecl | c:@S@SpecializationDecl>#I | <no-cgname> | Ref | rel: 0
|
||||
|
||||
template<typename T>
|
||||
class PartialSpecilizationClass<Cls, T>;
|
||||
// CHECK: [[@LINE-1]]:7 | class(Gen,TPS)/C++ | PartialSpecilizationClass | c:@SP>1#T@PartialSpecilizationClass>#$@S@Cls#t0.0 | <no-cgname> | Decl,RelSpecialization | rel: 1
|
||||
// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass
|
||||
// CHECK-NEXT: [[@LINE-3]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
|
||||
// CHECK: [[@LINE-3]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Ref | rel: 0
|
||||
// CHECK-NEXT: [[@LINE-4]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
|
||||
|
||||
template<>
|
||||
class PartialSpecilizationClass<Cls, Cls> : Cls { };
|
||||
@ -303,10 +306,9 @@ class PartialSpecilizationClass<Cls, Cls> : Cls { };
|
||||
// CHECK-NEXT: RelSpecialization | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass
|
||||
// CHECK-NEXT: [[@LINE-3]]:45 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelBase,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelBase,RelCont | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_
|
||||
// CHECK-NEXT: [[@LINE-5]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_
|
||||
// CHECK-NEXT: [[@LINE-7]]:38 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_
|
||||
// CHECK-NEXT: [[@LINE-5]]:7 | class(Gen,TS)/C++ | PartialSpecilizationClass | c:@S@PartialSpecilizationClass>#$@S@Cls#S0_ | <no-cgname> | Ref | rel: 0
|
||||
// CHECK-NEXT: [[@LINE-6]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
|
||||
// CHECK-NEXT: [[@LINE-7]]:38 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
|
||||
|
||||
template<typename T, int x>
|
||||
void functionSp() { }
|
||||
@ -330,14 +332,10 @@ class ClassWithCorrectSpecialization { };
|
||||
|
||||
template<>
|
||||
class ClassWithCorrectSpecialization<SpecializationDecl<Cls>, Record::C> { };
|
||||
// CHECK: [[@LINE-1]]:38 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | ClassWithCorrectSpecialization | c:@S@ClassWithCorrectSpecialization>#$@S@SpecializationDecl>#$@S@Cls#VI2
|
||||
// CHECK-NEXT: [[@LINE-3]]:57 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | ClassWithCorrectSpecialization | c:@S@ClassWithCorrectSpecialization>#$@S@SpecializationDecl>#$@S@Cls#VI2
|
||||
// CHECK-NEXT: [[@LINE-5]]:71 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | ClassWithCorrectSpecialization | c:@S@ClassWithCorrectSpecialization>#$@S@SpecializationDecl>#$@S@Cls#VI2
|
||||
// CHECK-NEXT: [[@LINE-7]]:63 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
|
||||
// CHECK-NEXT: RelCont | ClassWithCorrectSpecialization | c:@S@ClassWithCorrectSpecialization>#$@S@SpecializationDecl>#$@S@Cls#VI2
|
||||
// CHECK: [[@LINE-1]]:38 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
|
||||
// CHECK: [[@LINE-2]]:57 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
|
||||
// CHECK: [[@LINE-3]]:71 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read | rel: 0
|
||||
// CHECK: [[@LINE-4]]:63 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref | rel: 0
|
||||
|
||||
namespace ns {
|
||||
// CHECK: [[@LINE-1]]:11 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Decl | rel: 0
|
||||
|
@ -108,6 +108,7 @@ int ginitlist[] = {EnumVal};
|
||||
// CHECK: [indexDeclaration]: kind: c++-class-template | name: TS | {{.*}} | loc: 47:8
|
||||
// CHECK-NEXT: [indexDeclaration]: kind: struct-template-partial-spec | name: TS | USR: c:@SP>1#T@TS>#t0.0#I | {{.*}} | loc: 50:8
|
||||
// CHECK-NEXT: [indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@SP>1#T@TS>#t0.0#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
|
||||
// CHECK-NEXT: [indexEntityReference]: kind: c++-class-template | name: TS | USR: c:@ST>2#T#T@TS | lang: C++ | cursor: TemplateRef=TS:47:8 | loc: 50:8 | <parent>:: <<NULL>> | container: [TU] | refkind: direct | role: ref
|
||||
/* when indexing implicit instantiations
|
||||
[indexDeclaration]: kind: struct-template-spec | name: TS | USR: c:@S@TS>#I | {{.*}} | loc: 50:8
|
||||
[indexDeclaration]: kind: typedef | name: MyInt | USR: c:index-refs.cpp@593@S@TS>#I@T@MyInt | {{.*}} | loc: 51:15 | semantic-container: [TS:50:8] | lexical-container: [TS:50:8]
|
||||
|
@ -743,10 +743,14 @@ bool CursorVisitor::VisitClassTemplateSpecializationDecl(
|
||||
}
|
||||
|
||||
// Visit the template arguments used in the specialization.
|
||||
if (const auto *ArgsWritten = D->getTemplateArgsAsWritten()) {
|
||||
for (const TemplateArgumentLoc &Arg : ArgsWritten->arguments())
|
||||
if (VisitTemplateArgumentLoc(Arg))
|
||||
return true;
|
||||
if (TypeSourceInfo *SpecType = D->getTypeAsWritten()) {
|
||||
TypeLoc TL = SpecType->getTypeLoc();
|
||||
if (TemplateSpecializationTypeLoc TSTLoc =
|
||||
TL.getAs<TemplateSpecializationTypeLoc>()) {
|
||||
for (unsigned I = 0, N = TSTLoc.getNumArgs(); I != N; ++I)
|
||||
if (VisitTemplateArgumentLoc(TSTLoc.getArgLoc(I)))
|
||||
return true;
|
||||
}
|
||||
}
|
||||
|
||||
return ShouldVisitBody && VisitCXXRecordDecl(D);
|
||||
@ -5655,19 +5659,16 @@ CXString clang_getCursorDisplayName(CXCursor C) {
|
||||
|
||||
if (const ClassTemplateSpecializationDecl *ClassSpec =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(D)) {
|
||||
// If the type was explicitly written, use that.
|
||||
if (TypeSourceInfo *TSInfo = ClassSpec->getTypeAsWritten())
|
||||
return cxstring::createDup(TSInfo->getType().getAsString(Policy));
|
||||
|
||||
SmallString<128> Str;
|
||||
llvm::raw_svector_ostream OS(Str);
|
||||
OS << *ClassSpec;
|
||||
// If the template arguments were written explicitly, use them..
|
||||
if (const auto *ArgsWritten = ClassSpec->getTemplateArgsAsWritten()) {
|
||||
printTemplateArgumentList(
|
||||
OS, ArgsWritten->arguments(), Policy,
|
||||
ClassSpec->getSpecializedTemplate()->getTemplateParameters());
|
||||
} else {
|
||||
printTemplateArgumentList(
|
||||
OS, ClassSpec->getTemplateArgs().asArray(), Policy,
|
||||
ClassSpec->getSpecializedTemplate()->getTemplateParameters());
|
||||
}
|
||||
printTemplateArgumentList(
|
||||
OS, ClassSpec->getTemplateArgs().asArray(), Policy,
|
||||
ClassSpec->getSpecializedTemplate()->getTemplateParameters());
|
||||
return cxstring::createDup(OS.str());
|
||||
}
|
||||
|
||||
|
@ -2213,6 +2213,18 @@ TEST_P(ASTMatchersTest, ReferenceTypeLocTest_BindsToAnyRvalueReferenceTypeLoc) {
|
||||
EXPECT_TRUE(matches("float&& r = 3.0;", matcher));
|
||||
}
|
||||
|
||||
TEST_P(
|
||||
ASTMatchersTest,
|
||||
TemplateSpecializationTypeLocTest_BindsToTemplateSpecializationExplicitInstantiation) {
|
||||
if (!GetParam().isCXX()) {
|
||||
return;
|
||||
}
|
||||
EXPECT_TRUE(
|
||||
matches("template <typename T> class C {}; template class C<int>;",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("C"), hasTypeLoc(templateSpecializationTypeLoc()))));
|
||||
}
|
||||
|
||||
TEST_P(ASTMatchersTest,
|
||||
TemplateSpecializationTypeLocTest_BindsToVarDeclTemplateSpecialization) {
|
||||
if (!GetParam().isCXX()) {
|
||||
|
@ -430,6 +430,12 @@ TEST(HasTypeLoc, MatchesCXXUnresolvedConstructExpr) {
|
||||
cxxUnresolvedConstructExpr(hasTypeLoc(loc(asString("T"))))));
|
||||
}
|
||||
|
||||
TEST(HasTypeLoc, MatchesClassTemplateSpecializationDecl) {
|
||||
EXPECT_TRUE(matches(
|
||||
"template <typename T> class Foo; template <> class Foo<int> {};",
|
||||
classTemplateSpecializationDecl(hasTypeLoc(loc(asString("Foo<int>"))))));
|
||||
}
|
||||
|
||||
TEST(HasTypeLoc, MatchesCompoundLiteralExpr) {
|
||||
EXPECT_TRUE(
|
||||
matches("int* x = (int[2]) { 0, 1 };",
|
||||
@ -6378,7 +6384,8 @@ TEST(HasAnyTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
|
||||
"template<typename T> class A {}; template<> class A<int> {};",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(
|
||||
hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))))));
|
||||
}
|
||||
|
||||
TEST(HasAnyTemplateArgumentLoc,
|
||||
@ -6387,7 +6394,8 @@ TEST(HasAnyTemplateArgumentLoc,
|
||||
"template<typename T> class A {}; template<> class A<double> {};",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
hasTypeLoc(loc(asString("double")))))))));
|
||||
}
|
||||
|
||||
TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
|
||||
@ -6397,20 +6405,24 @@ TEST(HasAnyTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
|
||||
)";
|
||||
EXPECT_TRUE(
|
||||
matches(code, classTemplateSpecializationDecl(
|
||||
hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc(
|
||||
loc(asString("double")))))));
|
||||
|
||||
hasName("A"), hasTypeLoc(templateSpecializationTypeLoc(
|
||||
hasAnyTemplateArgumentLoc(hasTypeLoc(
|
||||
loc(asString("double")))))))));
|
||||
EXPECT_TRUE(matches(
|
||||
code, classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))));
|
||||
code,
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTypeLoc(templateSpecializationTypeLoc(
|
||||
hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("int")))))))));
|
||||
}
|
||||
|
||||
TEST(HasAnyTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
|
||||
EXPECT_TRUE(notMatches("template<typename T> class A {}; A<int> a;",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"), hasAnyTemplateArgumentLoc(hasTypeLoc(
|
||||
loc(asString("double")))))));
|
||||
EXPECT_TRUE(notMatches(
|
||||
"template<typename T> class A {}; A<int> a;",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
hasTypeLoc(loc(asString("double")))))))));
|
||||
}
|
||||
|
||||
TEST(HasAnyTemplateArgumentLoc,
|
||||
@ -6419,7 +6431,8 @@ TEST(HasAnyTemplateArgumentLoc,
|
||||
"template<typename T> class A {}; template<> class A<int> {};",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasAnyTemplateArgumentLoc(hasTypeLoc(loc(asString("double")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasAnyTemplateArgumentLoc(
|
||||
hasTypeLoc(loc(asString("double")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, BindsToSpecializationWithIntArgument) {
|
||||
@ -6440,21 +6453,13 @@ TEST(HasTemplateArgumentLoc, BindsToSpecializationWithDoubleArgument) {
|
||||
0, hasTypeLoc(loc(asString("double")))))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
|
||||
EXPECT_TRUE(notMatches(
|
||||
"template<typename T> class A {}; A<int> a;",
|
||||
varDecl(hasName("a"),
|
||||
hasTypeLoc(elaboratedTypeLoc(hasNamedTypeLoc(
|
||||
templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
0, hasTypeLoc(loc(asString("double")))))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithIntArgument) {
|
||||
EXPECT_TRUE(matches(
|
||||
"template<typename T> class A {}; template<> class A<int> {};",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(
|
||||
hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithDoubleArgument) {
|
||||
@ -6462,7 +6467,8 @@ TEST(HasTemplateArgumentLoc, BindsToExplicitSpecializationWithDoubleArgument) {
|
||||
"template<typename T> class A {}; template<> class A<double> {};",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
0, hasTypeLoc(loc(asString("double")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
|
||||
@ -6472,12 +6478,23 @@ TEST(HasTemplateArgumentLoc, BindsToSpecializationWithMultipleArguments) {
|
||||
)";
|
||||
EXPECT_TRUE(matches(
|
||||
code, classTemplateSpecializationDecl(
|
||||
hasName("A"), hasTemplateArgumentLoc(
|
||||
0, hasTypeLoc(loc(asString("double")))))));
|
||||
hasName("A"),
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
0, hasTypeLoc(loc(asString("double")))))))));
|
||||
EXPECT_TRUE(matches(
|
||||
code, classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTemplateArgumentLoc(1, hasTypeLoc(loc(asString("int")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
1, hasTypeLoc(loc(asString("int")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, DoesNotBindToSpecializationWithIntArgument) {
|
||||
EXPECT_TRUE(notMatches(
|
||||
"template<typename T> class A {}; A<int> a;",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
0, hasTypeLoc(loc(asString("double")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc,
|
||||
@ -6486,7 +6503,8 @@ TEST(HasTemplateArgumentLoc,
|
||||
"template<typename T> class A {}; template<> class A<int> {};",
|
||||
classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("double")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
0, hasTypeLoc(loc(asString("double")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc,
|
||||
@ -6497,12 +6515,14 @@ TEST(HasTemplateArgumentLoc,
|
||||
)";
|
||||
EXPECT_TRUE(notMatches(
|
||||
code, classTemplateSpecializationDecl(
|
||||
hasName("A"), hasTemplateArgumentLoc(
|
||||
1, hasTypeLoc(loc(asString("double")))))));
|
||||
hasName("A"),
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
1, hasTypeLoc(loc(asString("double")))))))));
|
||||
EXPECT_TRUE(notMatches(
|
||||
code, classTemplateSpecializationDecl(
|
||||
hasName("A"),
|
||||
hasTemplateArgumentLoc(0, hasTypeLoc(loc(asString("int")))))));
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
0, hasTypeLoc(loc(asString("int")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, DoesNotBindWithBadIndex) {
|
||||
@ -6512,12 +6532,14 @@ TEST(HasTemplateArgumentLoc, DoesNotBindWithBadIndex) {
|
||||
)";
|
||||
EXPECT_TRUE(notMatches(
|
||||
code, classTemplateSpecializationDecl(
|
||||
hasName("A"), hasTemplateArgumentLoc(
|
||||
-1, hasTypeLoc(loc(asString("double")))))));
|
||||
hasName("A"),
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
-1, hasTypeLoc(loc(asString("double")))))))));
|
||||
EXPECT_TRUE(notMatches(
|
||||
code, classTemplateSpecializationDecl(
|
||||
hasName("A"), hasTemplateArgumentLoc(
|
||||
100, hasTypeLoc(loc(asString("int")))))));
|
||||
hasName("A"),
|
||||
hasTypeLoc(templateSpecializationTypeLoc(hasTemplateArgumentLoc(
|
||||
100, hasTypeLoc(loc(asString("int")))))))));
|
||||
}
|
||||
|
||||
TEST(HasTemplateArgumentLoc, BindsToDeclRefExprWithIntArgument) {
|
||||
|
Loading…
x
Reference in New Issue
Block a user