[clang][ExtractAPI] Ensure TemplateArgumentLocations are only accessed if available (#93205)

This commit is contained in:
Daniel Grumberg
2024-05-24 16:32:25 +01:00
committed by GitHub
parent 8178a3ad1b
commit ab7e6b66fd
2 changed files with 65 additions and 11 deletions

View File

@@ -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();
}

View File

@@ -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@ST>1#T@TypeContainer@T@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@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