[clang] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (PR #93205)
Daniel Grumberg via cfe-commits
cfe-commits at lists.llvm.org
Thu May 23 08:10:00 PDT 2024
https://github.com/daniel-grumberg created https://github.com/llvm/llvm-project/pull/93205
None
>From d4e7e838fcbdf1645e5e31cefb462d53e59361d4 Mon Sep 17 00:00:00 2001
From: Daniel Grumberg <dgrumberg at apple.com>
Date: Thu, 23 May 2024 15:24:53 +0100
Subject: [PATCH] [clang][ExtractAPI] Ensure TemplateArgumentLocations are only
accessed if available
---
clang/lib/ExtractAPI/DeclarationFragments.cpp | 32 +++++++++-----
clang/test/ExtractAPI/non_type_template.cpp | 44 +++++++++++++++++++
2 files changed, 65 insertions(+), 11 deletions(-)
diff --git a/clang/lib/ExtractAPI/DeclarationFragments.cpp b/clang/lib/ExtractAPI/DeclarationFragments.cpp
index 904b9315f26ef..8c7c0f8a14726 100644
--- a/clang/lib/ExtractAPI/DeclarationFragments.cpp
+++ b/clang/lib/ExtractAPI/DeclarationFragments.cpp
@@ -1084,12 +1084,22 @@ DeclarationFragmentsBuilder::getFragmentsForTemplateArguments(
if (StringRef(ArgumentFragment.begin()->Spelling)
.starts_with("type-parameter")) {
- std::string ProperArgName = TemplateArgumentLocs.value()[i]
- .getTypeSourceInfo()
- ->getType()
- .getAsString();
- ArgumentFragment.begin()->Spelling.swap(ProperArgName);
+ if (TemplateArgumentLocs.has_value() &&
+ TemplateArgumentLocs->size() > i) {
+ std::string ProperArgName = TemplateArgumentLocs.value()[i]
+ .getTypeSourceInfo()
+ ->getType()
+ .getAsString();
+ ArgumentFragment.begin()->Spelling.swap(ProperArgName);
+ } else {
+ auto &Spelling = ArgumentFragment.begin()->Spelling;
+ Spelling.clear();
+ raw_string_ostream OutStream(Spelling);
+ CTA.print(Context.getPrintingPolicy(), OutStream, false);
+ OutStream.flush();
+ }
}
+
Fragments.append(std::move(ArgumentFragment));
break;
}
@@ -1212,9 +1222,9 @@ DeclarationFragmentsBuilder::getFragmentsForClassTemplateSpecialization(
cast<CXXRecordDecl>(Decl)))
.pop_back() // there is an extra semicolon now
.append("<", DeclarationFragments::FragmentKind::Text)
- .append(
- getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
- Decl->getASTContext(), std::nullopt))
+ .append(getFragmentsForTemplateArguments(
+ Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
+ Decl->getTemplateArgsAsWritten()->arguments()))
.append(">", DeclarationFragments::FragmentKind::Text)
.appendSemicolon();
}
@@ -1255,9 +1265,9 @@ DeclarationFragmentsBuilder::getFragmentsForVarTemplateSpecialization(
.append(DeclarationFragmentsBuilder::getFragmentsForVarTemplate(Decl))
.pop_back() // there is an extra semicolon now
.append("<", DeclarationFragments::FragmentKind::Text)
- .append(
- getFragmentsForTemplateArguments(Decl->getTemplateArgs().asArray(),
- Decl->getASTContext(), std::nullopt))
+ .append(getFragmentsForTemplateArguments(
+ Decl->getTemplateArgs().asArray(), Decl->getASTContext(),
+ Decl->getTemplateArgsAsWritten()->arguments()))
.append(">", DeclarationFragments::FragmentKind::Text)
.appendSemicolon();
}
diff --git a/clang/test/ExtractAPI/non_type_template.cpp b/clang/test/ExtractAPI/non_type_template.cpp
index 4e65eb790ca11..85f38e39c82bc 100644
--- a/clang/test/ExtractAPI/non_type_template.cpp
+++ b/clang/test/ExtractAPI/non_type_template.cpp
@@ -310,4 +310,48 @@ NestedTemplateTemplateParamPack<Bar, Bar> var;
// VAR-NEXT: }
// VAR-NEXT: ]
+template <typename T>
+class TypeContainer {
+ public:
+ // RUN: FileCheck %s --input-file %t/output.symbols.json --check-prefix TYPE
+ typedef Foo<T> Type;
+// TYPE-LABEL: "!testLabel": "c:non_type_template.cpp at ST>1#T at TypeContainer@T at Type",
+// TYPE: "declarationFragments": [
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "keyword",
+// TYPE-NEXT: "spelling": "typedef"
+// TYPE-NEXT: },
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "text",
+// TYPE-NEXT: "spelling": " "
+// TYPE-NEXT: },
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "typeIdentifier",
+// TYPE-NEXT: "preciseIdentifier": "c:@ST>2#T#NI at Foo",
+// TYPE-NEXT: "spelling": "Foo"
+// TYPE-NEXT: },
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "text",
+// TYPE-NEXT: "spelling": "<"
+// TYPE-NEXT: },
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "typeIdentifier",
+// TYPE-NEXT: "preciseIdentifier": "c:t0.0",
+// TYPE-NEXT: "spelling": "T"
+// TYPE-NEXT: },
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "text",
+// TYPE-NEXT: "spelling": "> "
+// TYPE-NEXT: },
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "identifier",
+// TYPE-NEXT: "spelling": "Type"
+// TYPE-NEXT: },
+// TYPE-NEXT: {
+// TYPE-NEXT: "kind": "text",
+// TYPE-NEXT: "spelling": ";"
+// TYPE-NEXT: }
+// TYPE-NEXT: ]
+};
+
// expected-no-diagnostics
More information about the cfe-commits
mailing list