Skip to content

Commit 2ab6927

Browse files
evelez7daniel-grumberg
authored andcommitted
[clang][ExtractAPI] improve template argument name deduction (llvm#77716)
The names of template arguments in partial specializations or parameters used as types might be mangled according to index and depth. Instead of looping through parameter lists to find matches like we do now, they can be deduced via their QualTypes or as written from the AST.
1 parent ddd87a1 commit 2ab6927

File tree

2 files changed

+23
-66
lines changed

2 files changed

+23
-66
lines changed

clang/include/clang/ExtractAPI/DeclarationFragments.h

Lines changed: 5 additions & 17 deletions
Original file line numberDiff line numberDiff line change
@@ -27,8 +27,6 @@
2727
#include "clang/AST/TypeLoc.h"
2828
#include "clang/Basic/Specifiers.h"
2929
#include "clang/Lex/MacroInfo.h"
30-
#include "llvm/ADT/SmallVector.h"
31-
#include "llvm/ADT/StringRef.h"
3230
#include <vector>
3331

3432
namespace clang {
@@ -315,13 +313,9 @@ class DeclarationFragmentsBuilder {
315313
static DeclarationFragments
316314
getFragmentsForTemplateParameters(ArrayRef<NamedDecl *>);
317315

318-
static std::string
319-
getNameForTemplateArgument(const ArrayRef<NamedDecl *>, std::string);
320-
321-
static DeclarationFragments
322-
getFragmentsForTemplateArguments(const ArrayRef<TemplateArgument>,
323-
ASTContext &,
324-
const std::optional<ArrayRef<NamedDecl *>>);
316+
static DeclarationFragments getFragmentsForTemplateArguments(
317+
const ArrayRef<TemplateArgument>, ASTContext &,
318+
const std::optional<ArrayRef<TemplateArgumentLoc>>);
325319

326320
static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
327321

@@ -429,14 +423,8 @@ DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
429423
Function->getASTContext(), After);
430424
if (isa<FunctionDecl>(Function) &&
431425
dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
432-
ReturnType.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
433-
0) {
434-
std::string ProperArgName =
435-
getNameForTemplateArgument(dyn_cast<FunctionDecl>(Function)
436-
->getDescribedFunctionTemplate()
437-
->getTemplateParameters()
438-
->asArray(),
439-
ReturnType.begin()->Spelling);
426+
StringRef(ReturnType.begin()->Spelling).starts_with("type-parameter")) {
427+
std::string ProperArgName = Function->getReturnType().getAsString();
440428
ReturnType.begin()->Spelling.swap(ProperArgName);
441429
}
442430
ReturnType.append(std::move(After));

clang/lib/ExtractAPI/DeclarationFragments.cpp

Lines changed: 18 additions & 49 deletions
Original file line numberDiff line numberDiff line change
@@ -14,14 +14,11 @@
1414
#include "clang/ExtractAPI/DeclarationFragments.h"
1515
#include "clang/AST/Decl.h"
1616
#include "clang/AST/DeclCXX.h"
17-
#include "clang/AST/QualTypeNames.h"
1817
#include "clang/AST/Type.h"
1918
#include "clang/AST/TypeLoc.h"
20-
#include "clang/Basic/OperatorKinds.h"
2119
#include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h"
2220
#include "clang/Index/USRGeneration.h"
2321
#include "llvm/ADT/StringSwitch.h"
24-
#include <typeinfo>
2522

2623
using namespace clang::extractapi;
2724
using namespace llvm;
@@ -573,11 +570,9 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) {
573570
DeclarationFragments After;
574571
DeclarationFragments ArgumentFragment =
575572
getFragmentsForType(T, Var->getASTContext(), After);
576-
if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
577-
"type-parameter") == 0) {
578-
std::string ProperArgName = getNameForTemplateArgument(
579-
Var->getDescribedVarTemplate()->getTemplateParameters()->asArray(),
580-
ArgumentFragment.begin()->Spelling);
573+
if (StringRef(ArgumentFragment.begin()->Spelling)
574+
.starts_with("type-parameter")) {
575+
std::string ProperArgName = T.getAsString();
581576
ArgumentFragment.begin()->Spelling.swap(ProperArgName);
582577
}
583578
Fragments.append(std::move(ArgumentFragment))
@@ -608,14 +603,9 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
608603
else
609604
TypeFragments.append(getFragmentsForType(T, Param->getASTContext(), After));
610605

611-
if (TypeFragments.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
612-
0) {
613-
std::string ProperArgName = getNameForTemplateArgument(
614-
dyn_cast<FunctionDecl>(Param->getDeclContext())
615-
->getDescribedFunctionTemplate()
616-
->getTemplateParameters()
617-
->asArray(),
618-
TypeFragments.begin()->Spelling);
606+
if (StringRef(TypeFragments.begin()->Spelling)
607+
.starts_with("type-parameter")) {
608+
std::string ProperArgName = Param->getOriginalType().getAsString();
619609
TypeFragments.begin()->Spelling.swap(ProperArgName);
620610
}
621611

@@ -706,13 +696,9 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) {
706696
DeclarationFragments After;
707697
auto ReturnValueFragment =
708698
getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After);
709-
if (ReturnValueFragment.begin()->Spelling.substr(0, 14).compare(
710-
"type-parameter") == 0) {
711-
std::string ProperArgName =
712-
getNameForTemplateArgument(Func->getDescribedFunctionTemplate()
713-
->getTemplateParameters()
714-
->asArray(),
715-
ReturnValueFragment.begin()->Spelling);
699+
if (StringRef(ReturnValueFragment.begin()->Spelling)
700+
.starts_with("type-parameter")) {
701+
std::string ProperArgName = Func->getReturnType().getAsString();
716702
ReturnValueFragment.begin()->Spelling.swap(ProperArgName);
717703
}
718704

@@ -1001,25 +987,6 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters(
1001987
return Fragments;
1002988
}
1003989

1004-
// Find the name of a template argument from the template's parameters.
1005-
std::string DeclarationFragmentsBuilder::getNameForTemplateArgument(
1006-
const ArrayRef<NamedDecl *> TemplateParameters, std::string TypeParameter) {
1007-
// The arg is a generic parameter from a partial spec, e.g.
1008-
// T in template<typename T> Foo<T, int>.
1009-
//
1010-
// Those names appear as "type-parameter-<index>-<depth>", so we must find its
1011-
// name from the template's parameter list.
1012-
for (unsigned i = 0; i < TemplateParameters.size(); ++i) {
1013-
const auto *Parameter =
1014-
dyn_cast<TemplateTypeParmDecl>(TemplateParameters[i]);
1015-
if (TypeParameter.compare("type-parameter-" +
1016-
std::to_string(Parameter->getDepth()) + "-" +
1017-
std::to_string(Parameter->getIndex())) == 0)
1018-
return std::string(TemplateParameters[i]->getName());
1019-
}
1020-
llvm_unreachable("Could not find the name of a template argument.");
1021-
}
1022-
1023990
// Get fragments for template arguments, e.g. int in template<typename T>
1024991
// Foo<int>;
1025992
//
@@ -1029,7 +996,7 @@ std::string DeclarationFragmentsBuilder::getNameForTemplateArgument(
1029996
DeclarationFragments
1030997
DeclarationFragmentsBuilder::getFragmentsForTemplateArguments(
1031998
const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context,
1032-
const std::optional<ArrayRef<NamedDecl *>> TemplateParameters) {
999+
const std::optional<ArrayRef<TemplateArgumentLoc>> TemplateArgumentLocs) {
10331000
DeclarationFragments Fragments;
10341001
for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) {
10351002
if (i)
@@ -1041,10 +1008,12 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateArguments(
10411008
DeclarationFragments ArgumentFragment =
10421009
getFragmentsForType(TemplateArguments[i].getAsType(), Context, After);
10431010

1044-
if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
1045-
"type-parameter") == 0) {
1046-
std::string ProperArgName = getNameForTemplateArgument(
1047-
TemplateParameters.value(), ArgumentFragment.begin()->Spelling);
1011+
if (StringRef(ArgumentFragment.begin()->Spelling)
1012+
.starts_with("type-parameter")) {
1013+
std::string ProperArgName = TemplateArgumentLocs.value()[i]
1014+
.getTypeSourceInfo()
1015+
->getType()
1016+
.getAsString();
10481017
ArgumentFragment.begin()->Spelling.swap(ProperArgName);
10491018
}
10501019
Fragments.append(std::move(ArgumentFragment));
@@ -1129,7 +1098,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization(
11291098
.append("<", DeclarationFragments::FragmentKind::Text)
11301099
.append(getFragmentsForTemplateArguments(
11311100
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1132-
Decl->getTemplateParameters()->asArray()))
1101+
Decl->getTemplateArgsAsWritten()->arguments()))
11331102
.append(">", DeclarationFragments::FragmentKind::Text)
11341103
.append(";", DeclarationFragments::FragmentKind::Text);
11351104
}
@@ -1170,7 +1139,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization(
11701139
.append("<", DeclarationFragments::FragmentKind::Text)
11711140
.append(getFragmentsForTemplateArguments(
11721141
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1173-
Decl->getTemplateParameters()->asArray()))
1142+
Decl->getTemplateArgsAsWritten()->arguments()))
11741143
.append(">", DeclarationFragments::FragmentKind::Text)
11751144
.append(";", DeclarationFragments::FragmentKind::Text);
11761145
}

0 commit comments

Comments
 (0)