Skip to content

Commit ccd2606

Browse files
authored
[clang] fix getTemplateInstantiationArgs (llvm#199528)
This implements a new strategy for collecting the template arguments, by relying on the qualifiers and template parameter lists to navigate the template context of out-of-line definitions. This greatly simplifies the signature of that function, by removing a bunch of workarounds, and simpliffying a couple that weren't removed yet. Since this now relies on qualifiers and template parameter lists, this patch expends most of its effort making sure these are placed, transformed and propagated to template instantiations. Also makes the explicit specialization AST nodes stop abusing the template parameter lists by storing it's own template parameter list, creating a dedicated field for them, similar to partial specializations. Fixes llvm#101330
1 parent f9ae788 commit ccd2606

58 files changed

Lines changed: 1454 additions & 1714 deletions

File tree

Some content is hidden

Large Commits have some content hidden by default. Use the searchbox below for content that may be hidden.

clang-tools-extra/clang-tidy/misc/DefinitionsInHeadersCheck.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -106,7 +106,7 @@ void DefinitionsInHeadersCheck::check(const MatchFinder::MatchResult &Result) {
106106
return;
107107
diag(FD->getLocation(), "mark the definition as 'inline'",
108108
DiagnosticIDs::Note)
109-
<< FixItHint::CreateInsertion(FD->getInnerLocStart(), "inline ");
109+
<< FixItHint::CreateInsertion(FD->getFunctionLocStart(), "inline ");
110110
} else if (const auto *VD = dyn_cast<VarDecl>(ND)) {
111111
// C++14 variable templates are allowed.
112112
if (VD->getDescribedVarTemplate())

clang-tools-extra/clangd/SemanticHighlighting.cpp

Lines changed: 21 additions & 18 deletions
Original file line numberDiff line numberDiff line change
@@ -590,28 +590,28 @@ class CollectExtraHighlightings
590590

591591
bool
592592
VisitClassTemplateSpecializationDecl(ClassTemplateSpecializationDecl *D) {
593-
if (auto *Args = D->getTemplateArgsAsWritten())
594-
H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
595-
return true;
596-
}
597-
598-
bool VisitClassTemplatePartialSpecializationDecl(
599-
ClassTemplatePartialSpecializationDecl *D) {
600-
if (auto *TPL = D->getTemplateParameters())
601-
H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
593+
if (const auto *Info = D->getExplicitInstantiationInfo()) {
594+
H.addAngleBracketTokens(Info->TemplateArgsAsWritten->getLAngleLoc(),
595+
Info->TemplateArgsAsWritten->getRAngleLoc());
596+
} else if (const auto *Info = D->getExplicitSpecializationInfo()) {
597+
H.addAngleBracketTokens(Info->TemplateParams->getLAngleLoc(),
598+
Info->TemplateParams->getRAngleLoc());
599+
H.addAngleBracketTokens(Info->TemplateArgsAsWritten->getLAngleLoc(),
600+
Info->TemplateArgsAsWritten->getRAngleLoc());
601+
}
602602
return true;
603603
}
604604

605605
bool VisitVarTemplateSpecializationDecl(VarTemplateSpecializationDecl *D) {
606-
if (auto *Args = D->getTemplateArgsAsWritten())
607-
H.addAngleBracketTokens(Args->getLAngleLoc(), Args->getRAngleLoc());
608-
return true;
609-
}
610-
611-
bool VisitVarTemplatePartialSpecializationDecl(
612-
VarTemplatePartialSpecializationDecl *D) {
613-
if (auto *TPL = D->getTemplateParameters())
614-
H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
606+
if (const auto *Info = D->getExplicitInstantiationInfo()) {
607+
H.addAngleBracketTokens(Info->TemplateArgsAsWritten->getLAngleLoc(),
608+
Info->TemplateArgsAsWritten->getRAngleLoc());
609+
} else if (const auto *Info = D->getExplicitSpecializationInfo()) {
610+
H.addAngleBracketTokens(Info->TemplateParams->getLAngleLoc(),
611+
Info->TemplateParams->getRAngleLoc());
612+
H.addAngleBracketTokens(Info->TemplateArgsAsWritten->getLAngleLoc(),
613+
Info->TemplateArgsAsWritten->getRAngleLoc());
614+
}
615615
return true;
616616
}
617617

@@ -625,6 +625,9 @@ class CollectExtraHighlightings
625625
}
626626

627627
bool VisitFunctionDecl(FunctionDecl *D) {
628+
if (const TemplateParameterList *TPL =
629+
D->getTemplateSpecializationParameters())
630+
H.addAngleBracketTokens(TPL->getLAngleLoc(), TPL->getRAngleLoc());
628631
if (D->isOverloadedOperator()) {
629632
const auto AddOpDeclToken = [&](SourceLocation Loc) {
630633
auto &Token = H.addToken(Loc, HighlightingKind::Operator)

clang-tools-extra/clangd/refactor/tweaks/DefineInline.cpp

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -364,7 +364,7 @@ addInlineIfInHeader(const FunctionDecl *FD) {
364364
if (!isHeaderFile(FileName, FD->getASTContext().getLangOpts()))
365365
return std::nullopt;
366366

367-
return tooling::Replacement(SM, FD->getInnerLocStart(), 0, "inline ");
367+
return tooling::Replacement(SM, FD->getFunctionLocStart(), 0, "inline ");
368368
}
369369

370370
/// Moves definition of a function/method to its declaration location.

clang/docs/ReleaseNotes.rst

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -687,6 +687,7 @@ Bug Fixes to C++ Support
687687
- Fixed an alias template CTAD crash.
688688
- Correctly diagnose uses of ``co_await`` / ``co_yield`` in the default argument of nested function declarations. (#GH98923)
689689
- Fixed a crash when diagnosing an invalid static member function with an explicit object parameter (#GH177741)
690+
- Fixed clang incorrectly rejecting several cases of out-of-line definitions. (#GH101330)
690691
- Clang incorrectly instantiated variable specializations outside of the immediate context. (#GH54439)
691692
- Fixed a crash when pack expansions are used as arguments for non-pack parameters of built-in templates. (#GH180307)
692693
- Fixed crash instantiating class member specializations.

clang/include/clang/AST/Decl.h

Lines changed: 21 additions & 37 deletions
Original file line numberDiff line numberDiff line change
@@ -2122,34 +2122,6 @@ class FunctionDecl : public DeclaratorDecl,
21222122
/// the DeclaratorDecl base class.
21232123
DeclarationNameLoc DNLoc;
21242124

2125-
/// Specify that this function declaration is actually a function
2126-
/// template specialization.
2127-
///
2128-
/// \param C the ASTContext.
2129-
///
2130-
/// \param Template the function template that this function template
2131-
/// specialization specializes.
2132-
///
2133-
/// \param TemplateArgs the template arguments that produced this
2134-
/// function template specialization from the template.
2135-
///
2136-
/// \param InsertPos If non-NULL, the position in the function template
2137-
/// specialization set where the function template specialization data will
2138-
/// be inserted.
2139-
///
2140-
/// \param TSK the kind of template specialization this is.
2141-
///
2142-
/// \param TemplateArgsAsWritten location info of template arguments.
2143-
///
2144-
/// \param PointOfInstantiation point at which the function template
2145-
/// specialization was first instantiated.
2146-
void setFunctionTemplateSpecialization(
2147-
ASTContext &C, FunctionTemplateDecl *Template,
2148-
TemplateArgumentList *TemplateArgs, void *InsertPos,
2149-
TemplateSpecializationKind TSK,
2150-
const TemplateArgumentListInfo *TemplateArgsAsWritten,
2151-
SourceLocation PointOfInstantiation);
2152-
21532125
/// Specify that this record is an instantiation of the
21542126
/// member function FD.
21552127
void setInstantiationOfMemberFunction(ASTContext &C, FunctionDecl *FD,
@@ -2245,6 +2217,8 @@ class FunctionDecl : public DeclaratorDecl,
22452217
return SourceLocation();
22462218
}
22472219

2220+
SourceLocation getFunctionLocStart() const;
2221+
22482222
SourceRange getSourceRange() const override LLVM_READONLY;
22492223

22502224
// Function definitions.
@@ -3070,9 +3044,14 @@ class FunctionDecl : public DeclaratorDecl,
30703044
const ASTTemplateArgumentListInfo*
30713045
getTemplateSpecializationArgsAsWritten() const;
30723046

3047+
/// Returns the template parameter list for an explicit specialization.
3048+
const TemplateParameterList *getTemplateSpecializationParameters() const;
3049+
30733050
/// Specify that this function declaration is actually a function
30743051
/// template specialization.
30753052
///
3053+
/// \param C the ASTContext.
3054+
///
30763055
/// \param Template the function template that this function template
30773056
/// specialization specializes.
30783057
///
@@ -3085,25 +3064,30 @@ class FunctionDecl : public DeclaratorDecl,
30853064
///
30863065
/// \param TSK the kind of template specialization this is.
30873066
///
3067+
/// \param TemplateParams the template parameters if this is an explicit
3068+
/// specialization.
3069+
///
30883070
/// \param TemplateArgsAsWritten location info of template arguments.
30893071
///
30903072
/// \param PointOfInstantiation point at which the function template
30913073
/// specialization was first instantiated.
3074+
///
3075+
/// \param AddSpecialization whether to add this specialization to the
3076+
/// template's specialization set.
3077+
///
30923078
void setFunctionTemplateSpecialization(
3093-
FunctionTemplateDecl *Template, TemplateArgumentList *TemplateArgs,
3094-
void *InsertPos,
3095-
TemplateSpecializationKind TSK = TSK_ImplicitInstantiation,
3096-
TemplateArgumentListInfo *TemplateArgsAsWritten = nullptr,
3097-
SourceLocation PointOfInstantiation = SourceLocation()) {
3098-
setFunctionTemplateSpecialization(getASTContext(), Template, TemplateArgs,
3099-
InsertPos, TSK, TemplateArgsAsWritten,
3100-
PointOfInstantiation);
3101-
}
3079+
ASTContext &C, FunctionTemplateDecl *Template,
3080+
TemplateArgumentList *TemplateArgs, void *InsertPos,
3081+
TemplateSpecializationKind TSK,
3082+
const TemplateParameterList *TemplateParams,
3083+
const TemplateArgumentListInfo *TemplateArgsAsWritten,
3084+
SourceLocation PointOfInstantiation, bool AddSpecialization);
31023085

31033086
/// Specifies that this function declaration is actually a
31043087
/// dependent function template specialization.
31053088
void setDependentTemplateSpecialization(
31063089
ASTContext &Context, const UnresolvedSetImpl &Templates,
3090+
const TemplateParameterList *TemplateParams,
31073091
const TemplateArgumentListInfo *TemplateArgs);
31083092

31093093
DependentFunctionTemplateSpecializationInfo *

0 commit comments

Comments
 (0)