Skip to content

Commit c6373dc

Browse files
committed
[clang][ExtractAPI] improve template argument name deduction
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 5c9b713 commit c6373dc

File tree

2 files changed

+14
-56
lines changed

2 files changed

+14
-56
lines changed

clang/include/clang/ExtractAPI/DeclarationFragments.h

Lines changed: 4 additions & 15 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 {
@@ -314,13 +312,9 @@ class DeclarationFragmentsBuilder {
314312
static DeclarationFragments
315313
getFragmentsForTemplateParameters(ArrayRef<NamedDecl *>);
316314

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

325319
static DeclarationFragments getFragmentsForConcept(const ConceptDecl *);
326320

@@ -430,12 +424,7 @@ DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
430424
dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
431425
ReturnType.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
432426
0) {
433-
std::string ProperArgName =
434-
getNameForTemplateArgument(dyn_cast<FunctionDecl>(Function)
435-
->getDescribedFunctionTemplate()
436-
->getTemplateParameters()
437-
->asArray(),
438-
ReturnType.begin()->Spelling);
427+
std::string ProperArgName = Function->getReturnType().getAsString();
439428
ReturnType.begin()->Spelling.swap(ProperArgName);
440429
}
441430
ReturnType.append(std::move(After));

clang/lib/ExtractAPI/DeclarationFragments.cpp

Lines changed: 10 additions & 41 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;
@@ -535,9 +532,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplate(const VarDecl *Var) {
535532
getFragmentsForType(T, Var->getASTContext(), After);
536533
if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
537534
"type-parameter") == 0) {
538-
std::string ProperArgName = getNameForTemplateArgument(
539-
Var->getDescribedVarTemplate()->getTemplateParameters()->asArray(),
540-
ArgumentFragment.begin()->Spelling);
535+
std::string ProperArgName = T.getAsString();
541536
ArgumentFragment.begin()->Spelling.swap(ProperArgName);
542537
}
543538
Fragments.append(std::move(ArgumentFragment))
@@ -570,12 +565,7 @@ DeclarationFragmentsBuilder::getFragmentsForParam(const ParmVarDecl *Param) {
570565

571566
if (TypeFragments.begin()->Spelling.substr(0, 14).compare("type-parameter") ==
572567
0) {
573-
std::string ProperArgName = getNameForTemplateArgument(
574-
dyn_cast<FunctionDecl>(Param->getDeclContext())
575-
->getDescribedFunctionTemplate()
576-
->getTemplateParameters()
577-
->asArray(),
578-
TypeFragments.begin()->Spelling);
568+
std::string ProperArgName = Param->getOriginalType().getAsString();
579569
TypeFragments.begin()->Spelling.swap(ProperArgName);
580570
}
581571

@@ -668,11 +658,7 @@ DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) {
668658
getFragmentsForType(Func->getReturnType(), Func->getASTContext(), After);
669659
if (ReturnValueFragment.begin()->Spelling.substr(0, 14).compare(
670660
"type-parameter") == 0) {
671-
std::string ProperArgName =
672-
getNameForTemplateArgument(Func->getDescribedFunctionTemplate()
673-
->getTemplateParameters()
674-
->asArray(),
675-
ReturnValueFragment.begin()->Spelling);
661+
std::string ProperArgName = Func->getReturnType().getAsString();
676662
ReturnValueFragment.begin()->Spelling.swap(ProperArgName);
677663
}
678664

@@ -958,25 +944,6 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters(
958944
return Fragments;
959945
}
960946

961-
// Find the name of a template argument from the template's parameters.
962-
std::string DeclarationFragmentsBuilder::getNameForTemplateArgument(
963-
const ArrayRef<NamedDecl *> TemplateParameters, std::string TypeParameter) {
964-
// The arg is a generic parameter from a partial spec, e.g.
965-
// T in template<typename T> Foo<T, int>.
966-
//
967-
// Those names appear as "type-parameter-<index>-<depth>", so we must find its
968-
// name from the template's parameter list.
969-
for (unsigned i = 0; i < TemplateParameters.size(); ++i) {
970-
const auto *Parameter =
971-
dyn_cast<TemplateTypeParmDecl>(TemplateParameters[i]);
972-
if (TypeParameter.compare("type-parameter-" +
973-
std::to_string(Parameter->getDepth()) + "-" +
974-
std::to_string(Parameter->getIndex())) == 0)
975-
return std::string(TemplateParameters[i]->getName());
976-
}
977-
llvm_unreachable("Could not find the name of a template argument.");
978-
}
979-
980947
// Get fragments for template arguments, e.g. int in template<typename T>
981948
// Foo<int>;
982949
//
@@ -986,7 +953,7 @@ std::string DeclarationFragmentsBuilder::getNameForTemplateArgument(
986953
DeclarationFragments
987954
DeclarationFragmentsBuilder::getFragmentsForTemplateArguments(
988955
const ArrayRef<TemplateArgument> TemplateArguments, ASTContext &Context,
989-
const std::optional<ArrayRef<NamedDecl *>> TemplateParameters) {
956+
const std::optional<ArrayRef<TemplateArgumentLoc>> TemplateArgumentLocs) {
990957
DeclarationFragments Fragments;
991958
for (unsigned i = 0, end = TemplateArguments.size(); i != end; ++i) {
992959
if (i)
@@ -1000,8 +967,10 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateArguments(
1000967

1001968
if (ArgumentFragment.begin()->Spelling.substr(0, 14).compare(
1002969
"type-parameter") == 0) {
1003-
std::string ProperArgName = getNameForTemplateArgument(
1004-
TemplateParameters.value(), ArgumentFragment.begin()->Spelling);
970+
std::string ProperArgName = TemplateArgumentLocs.value()[i]
971+
.getTypeSourceInfo()
972+
->getType()
973+
.getAsString();
1005974
ArgumentFragment.begin()->Spelling.swap(ProperArgName);
1006975
}
1007976
Fragments.append(std::move(ArgumentFragment));
@@ -1086,7 +1055,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization(
10861055
.append("<", DeclarationFragments::FragmentKind::Text)
10871056
.append(getFragmentsForTemplateArguments(
10881057
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1089-
Decl->getTemplateParameters()->asArray()))
1058+
Decl->getTemplateArgsAsWritten()->arguments()))
10901059
.append(">", DeclarationFragments::FragmentKind::Text)
10911060
.append(";", DeclarationFragments::FragmentKind::Text);
10921061
}
@@ -1127,7 +1096,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization(
11271096
.append("<", DeclarationFragments::FragmentKind::Text)
11281097
.append(getFragmentsForTemplateArguments(
11291098
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1130-
Decl->getTemplateParameters()->asArray()))
1099+
Decl->getTemplateArgsAsWritten()->arguments()))
11311100
.append(">", DeclarationFragments::FragmentKind::Text)
11321101
.append(";", DeclarationFragments::FragmentKind::Text);
11331102
}

0 commit comments

Comments
 (0)