llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT--> @llvm/pr-subscribers-clang Author: Daniel Grumberg (daniel-grumberg) <details> <summary>Changes</summary> Previously we only generated declaration fragments for template type parameters/arguments, this adds supports for most other possible template parameters/arguments. rdar://127732598 --- Patch is 31.66 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/91958.diff 15 Files Affected: - (modified) clang/lib/ExtractAPI/DeclarationFragments.cpp (+189-37) - (modified) clang/test/ExtractAPI/class_template.cpp (+1-1) - (modified) clang/test/ExtractAPI/class_template_param_inheritance.cpp (+1-1) - (modified) clang/test/ExtractAPI/class_template_partial_spec.cpp (+2-2) - (modified) clang/test/ExtractAPI/class_template_spec.cpp (+2-2) - (modified) clang/test/ExtractAPI/concept.cpp (+1-1) - (modified) clang/test/ExtractAPI/field_template.cpp (+1-1) - (modified) clang/test/ExtractAPI/global_func_template.cpp (+2-2) - (modified) clang/test/ExtractAPI/global_func_template_spec.cpp (+2-2) - (modified) clang/test/ExtractAPI/global_var_template.cpp (+1-1) - (modified) clang/test/ExtractAPI/global_var_template_partial_spec.cpp (+2-2) - (modified) clang/test/ExtractAPI/global_var_template_spec.cpp (+2-2) - (modified) clang/test/ExtractAPI/method_template.cpp (+1-1) - (modified) clang/test/ExtractAPI/method_template_spec.cpp (+2-2) - (added) clang/test/ExtractAPI/non_type_template.cpp (+313) ``````````diff diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp index 9bf7950888dbb..98b9343924a83 100644 --- a/clang/lib/ExtractAPI/DeclarationFragments.cpp +++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp @@ -12,13 +12,19 @@ //===----------------------------------------------------------------------===// #include "clang/ExtractAPI/DeclarationFragments.h" +#include "clang/AST/ASTFwd.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" #include "clang/AST/TypeLoc.h" #include "clang/ExtractAPI/TypedefUnderlyingTypeResolver.h" #include "clang/Index/USRGeneration.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/raw_ostream.h" +#include <optional> using namespace clang::extractapi; using namespace llvm; @@ -386,6 +392,25 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForType( getFragmentsForType(AT->getElementType(), Context, After)); } + if (const TemplateSpecializationType *TemplSpecTy = + dyn_cast<TemplateSpecializationType>(T)) { + const auto TemplName = TemplSpecTy->getTemplateName(); + std::string Str; + raw_string_ostream Stream(Str); + TemplName.print(Stream, Context.getPrintingPolicy(), + TemplateName::Qualified::AsWritten); + SmallString<64> USR(""); + if (const auto *TemplDecl = TemplName.getAsTemplateDecl()) + index::generateUSRForDecl(TemplDecl, USR); + + return Fragments + .append(Str, DeclarationFragments::FragmentKind::TypeIdentifier, USR) + .append("<", DeclarationFragments::FragmentKind::Text) + .append(getFragmentsForTemplateArguments( + TemplSpecTy->template_arguments(), Context, std::nullopt)) + .append(">", DeclarationFragments::FragmentKind::Text); + } + // Everything we care about has been handled now, reduce to the canonical // unqualified base type. QualType Base = T->getCanonicalTypeUnqualified(); @@ -650,7 +675,6 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForBlock( DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForFunction(const FunctionDecl *Func) { DeclarationFragments Fragments; - // FIXME: Handle template specialization switch (Func->getStorageClass()) { case SC_None: case SC_PrivateExtern: @@ -952,27 +976,84 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateParameters( Fragments.append(",", DeclarationFragments::FragmentKind::Text) .appendSpace(); - const auto *TemplateParam = - dyn_cast<TemplateTypeParmDecl>(ParameterArray[i]); - if (!TemplateParam) - continue; - if (TemplateParam->hasTypeConstraint()) - Fragments.append(TemplateParam->getTypeConstraint() - ->getNamedConcept() - ->getName() - .str(), - DeclarationFragments::FragmentKind::TypeIdentifier); - else if (TemplateParam->wasDeclaredWithTypename()) - Fragments.append("typename", DeclarationFragments::FragmentKind::Keyword); - else - Fragments.append("class", DeclarationFragments::FragmentKind::Keyword); - - if (TemplateParam->isParameterPack()) - Fragments.append("...", DeclarationFragments::FragmentKind::Text); - - Fragments.appendSpace().append( - TemplateParam->getName(), - DeclarationFragments::FragmentKind::GenericParameter); + if (const auto *TemplateParam = + dyn_cast<TemplateTypeParmDecl>(ParameterArray[i])) { + if (TemplateParam->hasTypeConstraint()) + Fragments.append(TemplateParam->getTypeConstraint() + ->getNamedConcept() + ->getName() + .str(), + DeclarationFragments::FragmentKind::TypeIdentifier); + else if (TemplateParam->wasDeclaredWithTypename()) + Fragments.append("typename", + DeclarationFragments::FragmentKind::Keyword); + else + Fragments.append("class", DeclarationFragments::FragmentKind::Keyword); + + if (TemplateParam->isParameterPack()) + Fragments.append("...", DeclarationFragments::FragmentKind::Text); + + if (!TemplateParam->getName().empty()) + Fragments.appendSpace().append( + TemplateParam->getName(), + DeclarationFragments::FragmentKind::GenericParameter); + + if (TemplateParam->hasDefaultArgument()) { + DeclarationFragments After; + Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) + .append(getFragmentsForType(TemplateParam->getDefaultArgument(), + TemplateParam->getASTContext(), After)); + Fragments.append(std::move(After)); + } + } else if (const auto *NTP = + dyn_cast<NonTypeTemplateParmDecl>(ParameterArray[i])) { + DeclarationFragments After; + const auto TyFragments = + getFragmentsForType(NTP->getType(), NTP->getASTContext(), After); + Fragments.append(std::move(TyFragments)).append(std::move(After)); + + if (NTP->isParameterPack()) + Fragments.append("...", DeclarationFragments::FragmentKind::Text); + + if (!NTP->getName().empty()) + Fragments.appendSpace().append( + NTP->getName(), + DeclarationFragments::FragmentKind::GenericParameter); + + if (NTP->hasDefaultArgument()) { + SmallString<8> ExprStr; + raw_svector_ostream Output(ExprStr); + NTP->getDefaultArgument()->printPretty( + Output, nullptr, NTP->getASTContext().getPrintingPolicy()); + Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) + .append(ExprStr, DeclarationFragments::FragmentKind::Text); + } + } else if (const auto *TTP = + dyn_cast<TemplateTemplateParmDecl>(ParameterArray[i])) { + Fragments.append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() + .append("<", DeclarationFragments::FragmentKind::Text) + .append(getFragmentsForTemplateParameters( + TTP->getTemplateParameters()->asArray())) + .append(">", DeclarationFragments::FragmentKind::Text) + .appendSpace() + .append(TTP->wasDeclaredWithTypename() ? "typename" : "class", + DeclarationFragments::FragmentKind::Keyword); + + if (TTP->isParameterPack()) + Fragments.append("...", DeclarationFragments::FragmentKind::Text); + + if (!TTP->getName().empty()) + Fragments.appendSpace().append( + TTP->getName(), + DeclarationFragments::FragmentKind::GenericParameter); + if (TTP->hasDefaultArgument()) { + const auto Default = TTP->getDefaultArgument(); + Fragments.append(" = ", DeclarationFragments::FragmentKind::Text) + .append(getFragmentsForTemplateArguments( + {Default.getArgument()}, TTP->getASTContext(), {Default})); + } + } } return Fragments; } @@ -993,23 +1074,85 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateArguments( Fragments.append(",", DeclarationFragments::FragmentKind::Text) .appendSpace(); - std::string Type = TemplateArguments[i].getAsType().getAsString(); - DeclarationFragments After; - DeclarationFragments ArgumentFragment = - getFragmentsForType(TemplateArguments[i].getAsType(), Context, After); - - if (StringRef(ArgumentFragment.begin()->Spelling) - .starts_with("type-parameter")) { - std::string ProperArgName = TemplateArgumentLocs.value()[i] - .getTypeSourceInfo() - ->getType() - .getAsString(); - ArgumentFragment.begin()->Spelling.swap(ProperArgName); + const auto &CTA = TemplateArguments[i]; + switch (CTA.getKind()) { + case TemplateArgument::Type: { + DeclarationFragments After; + DeclarationFragments ArgumentFragment = + getFragmentsForType(CTA.getAsType(), Context, After); + + if (StringRef(ArgumentFragment.begin()->Spelling) + .starts_with("type-parameter")) { + std::string ProperArgName = TemplateArgumentLocs.value()[i] + .getTypeSourceInfo() + ->getType() + .getAsString(); + ArgumentFragment.begin()->Spelling.swap(ProperArgName); + } + Fragments.append(std::move(ArgumentFragment)); + break; } - Fragments.append(std::move(ArgumentFragment)); + case TemplateArgument::Declaration: { + const auto *VD = CTA.getAsDecl(); + SmallString<128> USR; + index::generateUSRForDecl(VD, USR); + Fragments.append(VD->getNameAsString(), + DeclarationFragments::FragmentKind::Identifier, USR); + break; + } + case TemplateArgument::NullPtr: + Fragments.append("nullptr", DeclarationFragments::FragmentKind::Keyword); + break; - if (TemplateArguments[i].isPackExpansion()) - Fragments.append("...", DeclarationFragments::FragmentKind::Text); + case TemplateArgument::Integral: { + SmallString<4> Str; + CTA.getAsIntegral().toString(Str); + Fragments.append(Str, DeclarationFragments::FragmentKind::Text); + break; + } + + case TemplateArgument::StructuralValue: { + const auto SVTy = CTA.getStructuralValueType(); + Fragments.append(CTA.getAsStructuralValue().getAsString(Context, SVTy), + DeclarationFragments::FragmentKind::Text); + break; + } + + case TemplateArgument::TemplateExpansion: + case TemplateArgument::Template: { + std::string Str; + raw_string_ostream Stream(Str); + CTA.getAsTemplate().print(Stream, Context.getPrintingPolicy()); + SmallString<64> USR(""); + if (const auto *TemplDecl = + CTA.getAsTemplateOrTemplatePattern().getAsTemplateDecl()) + index::generateUSRForDecl(TemplDecl, USR); + Fragments.append(Str, DeclarationFragments::FragmentKind::TypeIdentifier, + USR); + if (CTA.getKind() == TemplateArgument::TemplateExpansion) + Fragments.append("...", DeclarationFragments::FragmentKind::Text); + break; + } + + case TemplateArgument::Pack: + Fragments.append("<", DeclarationFragments::FragmentKind::Text) + .append(getFragmentsForTemplateArguments(CTA.pack_elements(), Context, + {})) + .append(">", DeclarationFragments::FragmentKind::Text); + break; + + case TemplateArgument::Expression: { + SmallString<8> ExprStr; + raw_svector_ostream Output(ExprStr); + CTA.getAsExpr()->printPretty(Output, nullptr, + Context.getPrintingPolicy()); + Fragments.append(ExprStr, DeclarationFragments::FragmentKind::Text); + break; + } + + case TemplateArgument::Null: + break; + } } return Fragments; } @@ -1019,10 +1162,12 @@ DeclarationFragments DeclarationFragmentsBuilder::getFragmentsForConcept( DeclarationFragments Fragments; return Fragments .append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<", DeclarationFragments::FragmentKind::Text) .append(getFragmentsForTemplateParameters( Concept->getTemplateParameters()->asArray())) .append("> ", DeclarationFragments::FragmentKind::Text) + .appendSpace() .append("concept", DeclarationFragments::FragmentKind::Keyword) .appendSpace() .append(Concept->getName().str(), @@ -1035,6 +1180,7 @@ DeclarationFragmentsBuilder::getFragmentsForRedeclarableTemplate( const RedeclarableTemplateDecl *RedeclarableTemplate) { DeclarationFragments Fragments; Fragments.append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<", DeclarationFragments::FragmentKind::Text) .append(getFragmentsForTemplateParameters( RedeclarableTemplate->getTemplateParameters()->asArray())) @@ -1057,6 +1203,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization( DeclarationFragments Fragments; return Fragments .append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<", DeclarationFragments::FragmentKind::Text) .append(">", DeclarationFragments::FragmentKind::Text) .appendSpace() @@ -1077,6 +1224,7 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplatePartialSpecialization( DeclarationFragments Fragments; return Fragments .append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<", DeclarationFragments::FragmentKind::Text) .append(getFragmentsForTemplateParameters( Decl->getTemplateParameters()->asArray())) @@ -1099,6 +1247,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization( DeclarationFragments Fragments; return Fragments .append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<", DeclarationFragments::FragmentKind::Text) .append(">", DeclarationFragments::FragmentKind::Text) .appendSpace() @@ -1118,6 +1267,7 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplatePartialSpecialization( DeclarationFragments Fragments; return Fragments .append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<", DeclarationFragments::FragmentKind::Text) // Partial specs may have new params. .append(getFragmentsForTemplateParameters( @@ -1140,6 +1290,7 @@ DeclarationFragmentsBuilder::getFragmentsForFunctionTemplate( DeclarationFragments Fragments; return Fragments .append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<", DeclarationFragments::FragmentKind::Text) // Partial specs may have new params. .append(getFragmentsForTemplateParameters( @@ -1156,6 +1307,7 @@ DeclarationFragmentsBuilder::getFragmentsForFunctionTemplateSpecialization( DeclarationFragments Fragments; return Fragments .append("template", DeclarationFragments::FragmentKind::Keyword) + .appendSpace() .append("<>", DeclarationFragments::FragmentKind::Text) .appendSpace() .append(DeclarationFragmentsBuilder::getFragmentsForFunction(Decl)); diff --git a/clang/test/ExtractAPI/class_template.cpp b/clang/test/ExtractAPI/class_template.cpp index 4f2670d7b6997..203d47394dd60 100644 --- a/clang/test/ExtractAPI/class_template.cpp +++ b/clang/test/ExtractAPI/class_template.cpp @@ -51,7 +51,7 @@ template<typename T> class Foo {}; }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/class_template_param_inheritance.cpp b/clang/test/ExtractAPI/class_template_param_inheritance.cpp index 3d7b09f93ed6d..53b331e0b460b 100644 --- a/clang/test/ExtractAPI/class_template_param_inheritance.cpp +++ b/clang/test/ExtractAPI/class_template_param_inheritance.cpp @@ -58,7 +58,7 @@ template<typename T> class Foo : public T {}; }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/class_template_partial_spec.cpp b/clang/test/ExtractAPI/class_template_partial_spec.cpp index c8d9cc78d41c5..7d244f49c7359 100644 --- a/clang/test/ExtractAPI/class_template_partial_spec.cpp +++ b/clang/test/ExtractAPI/class_template_partial_spec.cpp @@ -53,7 +53,7 @@ template<typename Z> class Foo<Z, int> {}; }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", @@ -161,7 +161,7 @@ template<typename Z> class Foo<Z, int> {}; }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/class_template_spec.cpp b/clang/test/ExtractAPI/class_template_spec.cpp index 06a95314dc4aa..9dbd887510c70 100644 --- a/clang/test/ExtractAPI/class_template_spec.cpp +++ b/clang/test/ExtractAPI/class_template_spec.cpp @@ -53,7 +53,7 @@ template<> class Foo<int> {}; }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", @@ -140,7 +140,7 @@ template<> class Foo<int> {}; }, { "kind": "text", - "spelling": "<> " + "spelling": " <> " }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/concept.cpp b/clang/test/ExtractAPI/concept.cpp index 443eac2971f0e..4396a39a63ef6 100644 --- a/clang/test/ExtractAPI/concept.cpp +++ b/clang/test/ExtractAPI/concept.cpp @@ -51,7 +51,7 @@ template<typename T> concept Foo = true; }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/field_template.cpp b/clang/test/ExtractAPI/field_template.cpp index 2058ed008cfe4..973a9de5c9986 100644 --- a/clang/test/ExtractAPI/field_template.cpp +++ b/clang/test/ExtractAPI/field_template.cpp @@ -114,7 +114,7 @@ class Foo { }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/global_func_template.cpp b/clang/test/ExtractAPI/global_func_template.cpp index f43a618ec0c36..044757c316d58 100644 --- a/clang/test/ExtractAPI/global_func_template.cpp +++ b/clang/test/ExtractAPI/global_func_template.cpp @@ -52,7 +52,7 @@ template<typename T> T Fizz(int Buzz); }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", @@ -186,7 +186,7 @@ template<typename T> T Fizz(int Buzz); }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/global_func_template_spec.cpp b/clang/test/ExtractAPI/global_func_template_spec.cpp index fe046e9c3b9da..b88063aacfedc 100644 --- a/clang/test/ExtractAPI/global_func_template_spec.cpp +++ b/clang/test/ExtractAPI/global_func_template_spec.cpp @@ -52,7 +52,7 @@ template<> void Foo<int>(int Bar); }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", @@ -186,7 +186,7 @@ template<> void Foo<int>(int Bar); }, { "kind": "text", - "spelling": "<> " + "spelling": " <> " }, { "kind": "typeIdentifier", diff --git a/clang/test/ExtractAPI/global_var_template.cpp b/clang/test/ExtractAPI/global_var_template.cpp index 94f3713cd3d31..5c9194141332b 100644 --- a/clang/test/ExtractAPI/global_var_template.cpp +++ b/clang/test/ExtractAPI/global_var_template.cpp @@ -50,7 +50,7 @@ template<typename T> T Foo = T(3.14); }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", diff --git a/clang/test/ExtractAPI/global_var_template_partial_spec.cpp b/clang/test/ExtractAPI/global_var_template_partial_spec.cpp index 91084f258878e..ffb1557fd7580 100644 --- a/clang/test/ExtractAPI/global_var_template_partial_spec.cpp +++ b/clang/test/ExtractAPI/global_var_template_partial_spec.cpp @@ -52,7 +52,7 @@ template<typename Z> int Foo<int, Z> = 0; }, { "kind": "text", - "spelling": "<" + "spelling": " <" }, { "kind": "keyword", @@ -161,7 +161,7 @@ template<typename Z> int Foo<... [truncated] `````````` </details> https://github.com/llvm/llvm-project/pull/91958 _______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits