Skip to content

Commit 2b6c038

Browse files
authored
[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 31880df commit 2b6c038

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 {
@@ -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

@@ -430,12 +424,7 @@ DeclarationFragmentsBuilder::getFunctionSignature(const FunctionT *Function) {
430424
if (isa<FunctionDecl>(Function) &&
431425
dyn_cast<FunctionDecl>(Function)->getDescribedFunctionTemplate() &&
432426
StringRef(ReturnType.begin()->Spelling).starts_with("type-parameter")) {
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 (StringRef(ArgumentFragment.begin()->Spelling)
537534
.starts_with("type-parameter")) {
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 (StringRef(TypeFragments.begin()->Spelling)
572567
.starts_with("type-parameter")) {
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 (StringRef(ReturnValueFragment.begin()->Spelling)
670660
.starts_with("type-parameter")) {
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

@@ -961,25 +947,6 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters(
961947
return Fragments;
962948
}
963949

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

1004971
if (StringRef(ArgumentFragment.begin()->Spelling)
1005972
.starts_with("type-parameter")) {
1006-
std::string ProperArgName = getNameForTemplateArgument(
1007-
TemplateParameters.value(), ArgumentFragment.begin()->Spelling);
973+
std::string ProperArgName = TemplateArgumentLocs.value()[i]
974+
.getTypeSourceInfo()
975+
->getType()
976+
.getAsString();
1008977
ArgumentFragment.begin()->Spelling.swap(ProperArgName);
1009978
}
1010979
Fragments.append(std::move(ArgumentFragment));
@@ -1089,7 +1058,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization(
10891058
.append("<", DeclarationFragments::FragmentKind::Text)
10901059
.append(getFragmentsForTemplateArguments(
10911060
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1092-
Decl->getTemplateParameters()->asArray()))
1061+
Decl->getTemplateArgsAsWritten()->arguments()))
10931062
.append(">", DeclarationFragments::FragmentKind::Text)
10941063
.append(";", DeclarationFragments::FragmentKind::Text);
10951064
}
@@ -1130,7 +1099,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization(
11301099
.append("<", DeclarationFragments::FragmentKind::Text)
11311100
.append(getFragmentsForTemplateArguments(
11321101
Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
1133-
Decl->getTemplateParameters()->asArray()))
1102+
Decl->getTemplateArgsAsWritten()->arguments()))
11341103
.append(">", DeclarationFragments::FragmentKind::Text)
11351104
.append(";", DeclarationFragments::FragmentKind::Text);
11361105
}

0 commit comments

Comments
 (0)