[llvm-branch-commits] [clang] [lldb] Backport: [clang] fix P3310 overload resolution flag propagation (#125791) (PR #127831)
via llvm-branch-commits
llvm-branch-commits at lists.llvm.org
Wed Feb 19 09:12:16 PST 2025
llvmbot wrote:
<!--LLVM PR SUMMARY COMMENT-->
@llvm/pr-subscribers-clang-modules
Author: Matheus Izvekov (mizvekov)
<details>
<summary>Changes</summary>
Class templates might be only instantiated when they are required to be complete, but checking the template args against the primary template is immediate.
This result is cached so that later when the class is instantiated, checking against the primary template is not repeated.
The 'MatchedPackOnParmToNonPackOnArg' flag is also produced upon checking against the primary template, so it needs to be cached in the specialziation as well.
This fixes a bug which has not been in any release, so there are no release notes.
Fixes #<!-- -->125290
---
Patch is 232.71 KiB, truncated to 20.00 KiB below, full version: https://github.com/llvm/llvm-project/pull/127831.diff
16 Files Affected:
- (modified) clang/include/clang/AST/DeclTemplate.h (+14-2)
- (modified) clang/include/clang/Sema/Sema.h (+2-2)
- (modified) clang/lib/AST/ASTImporter.cpp (+3-3)
- (modified) clang/lib/AST/DeclTemplate.cpp (+24-23)
- (modified) clang/lib/AST/JSONNodeDumper.cpp (+5)
- (modified) clang/lib/AST/TextNodeDumper.cpp (+4-1)
- (modified) clang/lib/Sema/SemaTemplate.cpp (+5-3)
- (modified) clang/lib/Sema/SemaTemplateDeduction.cpp (-2)
- (modified) clang/lib/Sema/SemaTemplateInstantiateDecl.cpp (+1-1)
- (modified) clang/lib/Sema/SemaType.cpp (+2-1)
- (modified) clang/lib/Serialization/ASTReaderDecl.cpp (+1)
- (modified) clang/lib/Serialization/ASTWriterDecl.cpp (+1)
- (modified) clang/test/AST/ast-dump-templates.cpp (+6045-2)
- (modified) clang/test/AST/gen_ast_dump_json_test.py (+17-4)
- (modified) clang/test/SemaTemplate/cwg2398.cpp (+20)
- (modified) lldb/source/Plugins/ExpressionParser/Clang/CxxModuleHandler.cpp (+2-1)
``````````diff
diff --git a/clang/include/clang/AST/DeclTemplate.h b/clang/include/clang/AST/DeclTemplate.h
index 9ecff2c898acd..03c43765206b1 100644
--- a/clang/include/clang/AST/DeclTemplate.h
+++ b/clang/include/clang/AST/DeclTemplate.h
@@ -1841,15 +1841,23 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
LLVM_PREFERRED_TYPE(TemplateSpecializationKind)
unsigned SpecializationKind : 3;
+ /// Indicate that we have matched a parameter pack with a non pack
+ /// argument, when the opposite match is also allowed (strict pack match).
+ /// This needs to be cached as deduction is performed during declaration,
+ /// and we need the information to be preserved so that it is consistent
+ /// during instantiation.
+ bool MatchedPackOnParmToNonPackOnArg : 1;
+
protected:
ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
DeclContext *DC, SourceLocation StartLoc,
SourceLocation IdLoc,
ClassTemplateDecl *SpecializedTemplate,
ArrayRef<TemplateArgument> Args,
+ bool MatchedPackOnParmToNonPackOnArg,
ClassTemplateSpecializationDecl *PrevDecl);
- explicit ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
+ ClassTemplateSpecializationDecl(ASTContext &C, Kind DK);
public:
friend class ASTDeclReader;
@@ -1859,7 +1867,7 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
Create(ASTContext &Context, TagKind TK, DeclContext *DC,
SourceLocation StartLoc, SourceLocation IdLoc,
ClassTemplateDecl *SpecializedTemplate,
- ArrayRef<TemplateArgument> Args,
+ ArrayRef<TemplateArgument> Args, bool MatchedPackOnParmToNonPackOnArg,
ClassTemplateSpecializationDecl *PrevDecl);
static ClassTemplateSpecializationDecl *CreateDeserialized(ASTContext &C,
GlobalDeclID ID);
@@ -1930,6 +1938,10 @@ class ClassTemplateSpecializationDecl : public CXXRecordDecl,
SpecializationKind = TSK;
}
+ bool hasMatchedPackOnParmToNonPackOnArg() const {
+ return MatchedPackOnParmToNonPackOnArg;
+ }
+
/// Get the point of instantiation (if any), or null if none.
SourceLocation getPointOfInstantiation() const {
return PointOfInstantiation;
diff --git a/clang/include/clang/Sema/Sema.h b/clang/include/clang/Sema/Sema.h
index eb82d1b978e94..a30a7076ea5d4 100644
--- a/clang/include/clang/Sema/Sema.h
+++ b/clang/include/clang/Sema/Sema.h
@@ -13491,8 +13491,8 @@ class Sema final : public SemaBase {
bool InstantiateClassTemplateSpecialization(
SourceLocation PointOfInstantiation,
ClassTemplateSpecializationDecl *ClassTemplateSpec,
- TemplateSpecializationKind TSK, bool Complain = true,
- bool PrimaryHasMatchedPackOnParmToNonPackOnArg = false);
+ TemplateSpecializationKind TSK, bool Complain,
+ bool PrimaryHasMatchedPackOnParmToNonPackOnArg);
/// Instantiates the definitions of all of the member
/// of the given class, which is an instantiation of a class template
diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp
index 09fa10f716ec1..13e7f93233a7f 100644
--- a/clang/lib/AST/ASTImporter.cpp
+++ b/clang/lib/AST/ASTImporter.cpp
@@ -6321,9 +6321,9 @@ ExpectedDecl ASTNodeImporter::VisitClassTemplateSpecializationDecl(
updateLookupTableForTemplateParameters(*ToTPList);
} else { // Not a partial specialization.
if (GetImportedOrCreateDecl(
- D2, D, Importer.getToContext(), D->getTagKind(), DC,
- *BeginLocOrErr, *IdLocOrErr, ClassTemplate, TemplateArgs,
- PrevDecl))
+ D2, D, Importer.getToContext(), D->getTagKind(), DC, *BeginLocOrErr,
+ *IdLocOrErr, ClassTemplate, TemplateArgs,
+ D->hasMatchedPackOnParmToNonPackOnArg(), PrevDecl))
return D2;
// Update InsertPos, because preceding import calls may have invalidated
diff --git a/clang/lib/AST/DeclTemplate.cpp b/clang/lib/AST/DeclTemplate.cpp
index 2e1ed9e10713a..fe8734d262a96 100644
--- a/clang/lib/AST/DeclTemplate.cpp
+++ b/clang/lib/AST/DeclTemplate.cpp
@@ -957,18 +957,20 @@ FunctionTemplateSpecializationInfo *FunctionTemplateSpecializationInfo::Create(
// ClassTemplateSpecializationDecl Implementation
//===----------------------------------------------------------------------===//
-ClassTemplateSpecializationDecl::
-ClassTemplateSpecializationDecl(ASTContext &Context, Kind DK, TagKind TK,
- DeclContext *DC, SourceLocation StartLoc,
- SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- ArrayRef<TemplateArgument> Args,
- ClassTemplateSpecializationDecl *PrevDecl)
+ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(
+ ASTContext &Context, Kind DK, TagKind TK, DeclContext *DC,
+ SourceLocation StartLoc, SourceLocation IdLoc,
+ ClassTemplateDecl *SpecializedTemplate, ArrayRef<TemplateArgument> Args,
+ bool MatchedPackOnParmToNonPackOnArg,
+ ClassTemplateSpecializationDecl *PrevDecl)
: CXXRecordDecl(DK, TK, Context, DC, StartLoc, IdLoc,
SpecializedTemplate->getIdentifier(), PrevDecl),
- SpecializedTemplate(SpecializedTemplate),
- TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
- SpecializationKind(TSK_Undeclared) {
+ SpecializedTemplate(SpecializedTemplate),
+ TemplateArgs(TemplateArgumentList::CreateCopy(Context, Args)),
+ SpecializationKind(TSK_Undeclared),
+ MatchedPackOnParmToNonPackOnArg(MatchedPackOnParmToNonPackOnArg) {
+ assert(DK == Kind::ClassTemplateSpecialization ||
+ MatchedPackOnParmToNonPackOnArg == false);
}
ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
@@ -977,18 +979,14 @@ ClassTemplateSpecializationDecl::ClassTemplateSpecializationDecl(ASTContext &C,
SourceLocation(), nullptr, nullptr),
SpecializationKind(TSK_Undeclared) {}
-ClassTemplateSpecializationDecl *
-ClassTemplateSpecializationDecl::Create(ASTContext &Context, TagKind TK,
- DeclContext *DC,
- SourceLocation StartLoc,
- SourceLocation IdLoc,
- ClassTemplateDecl *SpecializedTemplate,
- ArrayRef<TemplateArgument> Args,
- ClassTemplateSpecializationDecl *PrevDecl) {
- auto *Result =
- new (Context, DC) ClassTemplateSpecializationDecl(
- Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
- SpecializedTemplate, Args, PrevDecl);
+ClassTemplateSpecializationDecl *ClassTemplateSpecializationDecl::Create(
+ ASTContext &Context, TagKind TK, DeclContext *DC, SourceLocation StartLoc,
+ SourceLocation IdLoc, ClassTemplateDecl *SpecializedTemplate,
+ ArrayRef<TemplateArgument> Args, bool MatchedPackOnParmToNonPackOnArg,
+ ClassTemplateSpecializationDecl *PrevDecl) {
+ auto *Result = new (Context, DC) ClassTemplateSpecializationDecl(
+ Context, ClassTemplateSpecialization, TK, DC, StartLoc, IdLoc,
+ SpecializedTemplate, Args, MatchedPackOnParmToNonPackOnArg, PrevDecl);
Result->setMayHaveOutOfDateDef(false);
// If the template decl is incomplete, copy the external lexical storage from
@@ -1175,7 +1173,10 @@ ClassTemplatePartialSpecializationDecl::ClassTemplatePartialSpecializationDecl(
ClassTemplatePartialSpecializationDecl *PrevDecl)
: ClassTemplateSpecializationDecl(
Context, ClassTemplatePartialSpecialization, TK, DC, StartLoc, IdLoc,
- SpecializedTemplate, Args, PrevDecl),
+ // Tracking MatchedPackOnParmToNonPackOnArg for Partial
+ // Specializations is not needed.
+ SpecializedTemplate, Args, /*MatchedPackOnParmToNonPackOnArg=*/false,
+ PrevDecl),
TemplateParams(Params), InstantiatedFromMember(nullptr, false) {
if (AdoptTemplateParameterList(Params, this))
setInvalidDecl();
diff --git a/clang/lib/AST/JSONNodeDumper.cpp b/clang/lib/AST/JSONNodeDumper.cpp
index 36ef1fc8c79db..4ab0e7cb5815b 100644
--- a/clang/lib/AST/JSONNodeDumper.cpp
+++ b/clang/lib/AST/JSONNodeDumper.cpp
@@ -1003,6 +1003,11 @@ void JSONNodeDumper::VisitRecordDecl(const RecordDecl *RD) {
void JSONNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *RD) {
VisitRecordDecl(RD);
+ if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(RD)) {
+ if (CTSD->hasMatchedPackOnParmToNonPackOnArg())
+ JOS.attribute("strict-pack-match", true);
+ }
+
// All other information requires a complete definition.
if (!RD->isCompleteDefinition())
return;
diff --git a/clang/lib/AST/TextNodeDumper.cpp b/clang/lib/AST/TextNodeDumper.cpp
index a57cba9597482..7f5a825b68798 100644
--- a/clang/lib/AST/TextNodeDumper.cpp
+++ b/clang/lib/AST/TextNodeDumper.cpp
@@ -2525,8 +2525,11 @@ void TextNodeDumper::VisitCXXRecordDecl(const CXXRecordDecl *D) {
OS << " instantiated_from";
dumpPointer(Instance);
}
- if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D))
+ if (const auto *CTSD = dyn_cast<ClassTemplateSpecializationDecl>(D)) {
dumpTemplateSpecializationKind(CTSD->getSpecializationKind());
+ if (CTSD->hasMatchedPackOnParmToNonPackOnArg())
+ OS << " strict-pack-match";
+ }
dumpNestedNameSpecifier(D->getQualifier());
diff --git a/clang/lib/Sema/SemaTemplate.cpp b/clang/lib/Sema/SemaTemplate.cpp
index 3944c4f67bab9..51e7001ba6ca2 100644
--- a/clang/lib/Sema/SemaTemplate.cpp
+++ b/clang/lib/Sema/SemaTemplate.cpp
@@ -3651,7 +3651,7 @@ QualType Sema::CheckTemplateIdType(TemplateName Name,
ClassTemplate->getDeclContext(),
ClassTemplate->getTemplatedDecl()->getBeginLoc(),
ClassTemplate->getLocation(), ClassTemplate, CTAI.CanonicalConverted,
- nullptr);
+ CTAI.MatchedPackOnParmToNonPackOnArg, nullptr);
ClassTemplate->AddSpecialization(Decl, InsertPos);
if (ClassTemplate->isOutOfLine())
Decl->setLexicalDeclContext(ClassTemplate->getLexicalDeclContext());
@@ -8566,7 +8566,8 @@ DeclResult Sema::ActOnClassTemplateSpecialization(
// this explicit specialization or friend declaration.
Specialization = ClassTemplateSpecializationDecl::Create(
Context, Kind, DC, KWLoc, TemplateNameLoc, ClassTemplate,
- CTAI.CanonicalConverted, PrevDecl);
+ CTAI.CanonicalConverted, CTAI.MatchedPackOnParmToNonPackOnArg,
+ PrevDecl);
Specialization->setTemplateArgsAsWritten(TemplateArgs);
SetNestedNameSpecifier(*this, Specialization, SS);
if (TemplateParameterLists.size() > 0) {
@@ -9909,7 +9910,8 @@ DeclResult Sema::ActOnExplicitInstantiation(
// this explicit specialization.
Specialization = ClassTemplateSpecializationDecl::Create(
Context, Kind, ClassTemplate->getDeclContext(), KWLoc, TemplateNameLoc,
- ClassTemplate, CTAI.CanonicalConverted, PrevDecl);
+ ClassTemplate, CTAI.CanonicalConverted,
+ CTAI.MatchedPackOnParmToNonPackOnArg, PrevDecl);
SetNestedNameSpecifier(*this, Specialization, SS);
// A MSInheritanceAttr attached to the previous declaration must be
diff --git a/clang/lib/Sema/SemaTemplateDeduction.cpp b/clang/lib/Sema/SemaTemplateDeduction.cpp
index 137942f0c30bf..425c41f0f6236 100644
--- a/clang/lib/Sema/SemaTemplateDeduction.cpp
+++ b/clang/lib/Sema/SemaTemplateDeduction.cpp
@@ -3341,8 +3341,6 @@ FinishTemplateArgumentDeduction(
return ConstraintsNotSatisfied
? TemplateDeductionResult::ConstraintsNotSatisfied
: TemplateDeductionResult::SubstitutionFailure;
- if (InstCTAI.MatchedPackOnParmToNonPackOnArg)
- Info.setMatchedPackOnParmToNonPackOnArg();
TemplateParameterList *TemplateParams = Template->getTemplateParameters();
for (unsigned I = 0, E = TemplateParams->size(); I != E; ++I) {
diff --git a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 131f5c8ad1a09..b4f4469ed4e48 100644
--- a/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/clang/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -4007,7 +4007,7 @@ TemplateDeclInstantiator::VisitClassTemplateSpecializationDecl(
ClassTemplateSpecializationDecl::Create(
SemaRef.Context, D->getTagKind(), Owner, D->getBeginLoc(),
D->getLocation(), InstClassTemplate, CTAI.CanonicalConverted,
- PrevDecl);
+ CTAI.MatchedPackOnParmToNonPackOnArg, PrevDecl);
InstD->setTemplateArgsAsWritten(InstTemplateArgs);
// Add this partial specialization to the set of class template partial
diff --git a/clang/lib/Sema/SemaType.cpp b/clang/lib/Sema/SemaType.cpp
index 1fa5239a597c8..77b52b832d771 100644
--- a/clang/lib/Sema/SemaType.cpp
+++ b/clang/lib/Sema/SemaType.cpp
@@ -9399,7 +9399,8 @@ bool Sema::RequireCompleteTypeImpl(SourceLocation Loc, QualType T,
runWithSufficientStackSpace(Loc, [&] {
Diagnosed = InstantiateClassTemplateSpecialization(
Loc, ClassTemplateSpec, TSK_ImplicitInstantiation,
- /*Complain=*/Diagnoser);
+ /*Complain=*/Diagnoser,
+ ClassTemplateSpec->hasMatchedPackOnParmToNonPackOnArg());
});
Instantiated = true;
}
diff --git a/clang/lib/Serialization/ASTReaderDecl.cpp b/clang/lib/Serialization/ASTReaderDecl.cpp
index 8fbb0a8d3edd8..8921b92178ee2 100644
--- a/clang/lib/Serialization/ASTReaderDecl.cpp
+++ b/clang/lib/Serialization/ASTReaderDecl.cpp
@@ -2532,6 +2532,7 @@ RedeclarableResult ASTDeclReader::VisitClassTemplateSpecializationDeclImpl(
D->TemplateArgs = TemplateArgumentList::CreateCopy(C, TemplArgs);
D->PointOfInstantiation = readSourceLocation();
D->SpecializationKind = (TemplateSpecializationKind)Record.readInt();
+ D->MatchedPackOnParmToNonPackOnArg = Record.readBool();
bool writtenAsCanonicalDecl = Record.readInt();
if (writtenAsCanonicalDecl) {
diff --git a/clang/lib/Serialization/ASTWriterDecl.cpp b/clang/lib/Serialization/ASTWriterDecl.cpp
index fa2294da95de8..3505db441e829 100644
--- a/clang/lib/Serialization/ASTWriterDecl.cpp
+++ b/clang/lib/Serialization/ASTWriterDecl.cpp
@@ -1843,6 +1843,7 @@ void ASTDeclWriter::VisitClassTemplateSpecializationDecl(
Record.AddTemplateArgumentList(&D->getTemplateArgs());
Record.AddSourceLocation(D->getPointOfInstantiation());
Record.push_back(D->getSpecializationKind());
+ Record.push_back(D->hasMatchedPackOnParmToNonPackOnArg());
Record.push_back(D->isCanonicalDecl());
if (D->isCanonicalDecl()) {
diff --git a/clang/test/AST/ast-dump-templates.cpp b/clang/test/AST/ast-dump-templates.cpp
index 9fcafbcbcc46b..86af8c50f3174 100644
--- a/clang/test/AST/ast-dump-templates.cpp
+++ b/clang/test/AST/ast-dump-templates.cpp
@@ -1,7 +1,15 @@
-// RUN: %clang_cc1 -std=c++1z -ast-print %s > %t
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump=json %s | FileCheck --check-prefix=JSON %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-print %s > %t
// RUN: FileCheck < %t %s -check-prefix=CHECK1
// RUN: FileCheck < %t %s -check-prefix=CHECK2
-// RUN: %clang_cc1 -std=c++1z -ast-dump %s | FileCheck --check-prefix=DUMP %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -ast-dump %s | FileCheck --check-prefix=DUMP %s
+
+// Test with serialization:
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -std=c++17 -emit-pch -o %t %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -x c++ -std=c++17 -include-pch %t \
+// RUN: -ast-dump-all /dev/null \
+// RUN: | sed -e "s/ <undeserialized declarations>//" -e "s/ imported//" \
+// RUN: | FileCheck --strict-whitespace --check-prefix=DUMP %s
template <int X, typename Y, int Z = 5>
struct foo {
@@ -118,3 +126,6038 @@ void func() {
// DUMP-NEXT: `-TemplateTypeParm {{.*}} 'Key'
}
}
+
+namespace test7 {
+ template <template<class> class TT> struct A {};
+ template <class...> class B {};
+ template struct A<B>;
+// DUMP-LABEL: NamespaceDecl {{.*}} test7{{$}}
+// DUMP: ClassTemplateSpecializationDecl {{.*}} struct A definition explicit_instantiation_definition strict-pack-match{{$}}
+} // namespce test7
+
+// NOTE: CHECK lines have been autogenerated by gen_ast_dump_json_test.py
+
+
+// JSON-NOT: {{^}}Dumping
+// JSON: "kind": "TranslationUnitDecl",
+// JSON-NEXT: "loc": {},
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {},
+// JSON-NEXT: "end": {}
+// JSON-NEXT: },
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TypedefDecl",
+// JSON-NEXT: "loc": {},
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {},
+// JSON-NEXT: "end": {}
+// JSON-NEXT: },
+// JSON-NEXT: "isImplicit": true,
+// JSON-NEXT: "name": "__int128_t",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "__int128"
+// JSON-NEXT: },
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "BuiltinType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "__int128"
+// JSON-NEXT: }
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TypedefDecl",
+// JSON-NEXT: "loc": {},
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {},
+// JSON-NEXT: "end": {}
+// JSON-NEXT: },
+// JSON-NEXT: "isImplicit": true,
+// JSON-NEXT: "name": "__uint128_t",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "unsigned __int128"
+// JSON-NEXT: },
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "BuiltinType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "unsigned __int128"
+// JSON-NEXT: }
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TypedefDecl",
+// JSON-NEXT: "loc": {},
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {},
+// JSON-NEXT: "end": {}
+// JSON-NEXT: },
+// JSON-NEXT: "isImplicit": true,
+// JSON-NEXT: "name": "__NSConstantString",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "__NSConstantString_tag"
+// JSON-NEXT: },
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "RecordType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "__NSConstantString_tag"
+// JSON-NEXT: },
+// JSON-NEXT: "decl": {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "CXXRecordDecl",
+// JSON-NEXT: "name": "__NSConstantString_tag"
+// JSON-NEXT: }
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TypedefDecl",
+// JSON-NEXT: "loc": {},
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {},
+// JSON-NEXT: "end": {}
+// JSON-NEXT: },
+// JSON-NEXT: "isImplicit": true,
+// JSON-NEXT: "name": "__builtin_ms_va_list",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "char *"
+// JSON-NEXT: },
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "PointerType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "char *"
+// JSON-NEXT: },
+// JSON-NEXT: "inner": [
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "BuiltinType",
+// JSON-NEXT: "type": {
+// JSON-NEXT: "qualType": "char"
+// JSON-NEXT: }
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: }
+// JSON-NEXT: ]
+// JSON-NEXT: },
+// JSON-NEXT: {
+// JSON-NEXT: "id": "0x{{.*}}",
+// JSON-NEXT: "kind": "TypedefDecl",
+// JSON-NEXT: "loc": {},
+// JSON-NEXT: "range": {
+// JSON-NEXT: "begin": {},
+// JSON-NEXT: "end": {}
+// JSON-NEXT: },
+// JSON-NEXT: "isImplicit": true,
+// JSON-NE...
[truncated]
``````````
</details>
https://github.com/llvm/llvm-project/pull/127831
More information about the llvm-branch-commits
mailing list