Skip to content

Commit

Permalink
Properly print unnamed TagDecl objects in diagnostics
Browse files Browse the repository at this point in the history
The diagnostics engine is very smart about being passed a NamedDecl to
print as part of a diagnostic; it gets the "right" form of the name,
quotes it properly, etc. However, the result of using an unnamed tag
declaration was to print '' instead of anything useful.

This patch causes us to print the same information we'd have gotten if
we had printed the type of the declaration rather than the name of it,
as that's the most relevant information we can display.

Differential Revision: https://reviews.llvm.org/D134813
  • Loading branch information
AaronBallman committed Oct 14, 2022
1 parent ce4d5ae commit 19e984e
Show file tree
Hide file tree
Showing 32 changed files with 125 additions and 92 deletions.
2 changes: 1 addition & 1 deletion clang-tools-extra/clangd/unittests/FindTargetTests.cpp
Expand Up @@ -1640,7 +1640,7 @@ TEST_F(FindExplicitReferencesTest, All) {
int (*$2^fptr)(int $3^a, int) = nullptr;
}
)cpp",
"0: targets = {}\n"
"0: targets = {(unnamed)}\n"
"1: targets = {x}, decl\n"
"2: targets = {fptr}, decl\n"
"3: targets = {a}, decl\n"},
Expand Down
6 changes: 5 additions & 1 deletion clang/include/clang/AST/Decl.h
Expand Up @@ -291,7 +291,9 @@ class NamedDecl : public Decl {

/// Pretty-print the unqualified name of this declaration. Can be overloaded
/// by derived classes to provide a more user-friendly name when appropriate.
virtual void printName(raw_ostream &os) const;
virtual void printName(raw_ostream &OS, const PrintingPolicy &Policy) const;
/// Calls printName() with the ASTContext printing policy from the decl.
void printName(raw_ostream &OS) const;

/// Get the actual, stored name of the declaration, which may be a special
/// name.
Expand Down Expand Up @@ -3654,6 +3656,8 @@ class TagDecl : public TypeDecl,
return getExtInfo()->TemplParamLists[i];
}

void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;

void setTemplateParameterListsInfo(ASTContext &Context,
ArrayRef<TemplateParameterList *> TPLists);

Expand Down
8 changes: 5 additions & 3 deletions clang/include/clang/AST/DeclCXX.h
Expand Up @@ -4100,7 +4100,7 @@ class DecompositionDecl final
return llvm::makeArrayRef(getTrailingObjects<BindingDecl *>(), NumBindings);
}

void printName(raw_ostream &os) const override;
void printName(raw_ostream &OS, const PrintingPolicy &Policy) const override;

static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == Decomposition; }
Expand Down Expand Up @@ -4213,7 +4213,8 @@ class MSGuidDecl : public ValueDecl,

public:
/// Print this UUID in a human-readable format.
void printName(llvm::raw_ostream &OS) const override;
void printName(llvm::raw_ostream &OS,
const PrintingPolicy &Policy) const override;

/// Get the decomposed parts of this declaration.
Parts getParts() const { return PartVal; }
Expand Down Expand Up @@ -4266,7 +4267,8 @@ class UnnamedGlobalConstantDecl : public ValueDecl,

public:
/// Print this in a human-readable format.
void printName(llvm::raw_ostream &OS) const override;
void printName(llvm::raw_ostream &OS,
const PrintingPolicy &Policy) const override;

const APValue &getValue() const { return Value; }

Expand Down
3 changes: 2 additions & 1 deletion clang/include/clang/AST/DeclTemplate.h
Expand Up @@ -3343,7 +3343,8 @@ class TemplateParamObjectDecl : public ValueDecl,

public:
/// Print this template parameter object in a human-readable format.
void printName(llvm::raw_ostream &OS) const override;
void printName(llvm::raw_ostream &OS,
const PrintingPolicy &Policy) const override;

/// Print this object as an equivalent expression.
void printAsExpr(llvm::raw_ostream &OS) const;
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/ASTDiagnostic.cpp
Expand Up @@ -1893,7 +1893,7 @@ class TemplateDiff {
TPO->printAsInit(OS, Policy);
return;
}
VD->printName(OS);
VD->printName(OS, Policy);
return;
}

Expand Down
31 changes: 26 additions & 5 deletions clang/lib/AST/Decl.cpp
Expand Up @@ -1602,8 +1602,12 @@ Module *Decl::getOwningModuleForLinkage(bool IgnoreLinkage) const {
llvm_unreachable("unknown module kind");
}

void NamedDecl::printName(raw_ostream &os) const {
os << Name;
void NamedDecl::printName(raw_ostream &OS, const PrintingPolicy&) const {
OS << Name;
}

void NamedDecl::printName(raw_ostream &OS) const {
printName(OS, getASTContext().getPrintingPolicy());
}

std::string NamedDecl::getQualifiedNameAsString() const {
Expand All @@ -1621,7 +1625,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
const PrintingPolicy &P) const {
if (getDeclContext()->isFunctionOrMethod()) {
// We do not print '(anonymous)' for function parameters without name.
printName(OS);
printName(OS, P);
return;
}
printNestedNameSpecifier(OS, P);
Expand All @@ -1632,7 +1636,7 @@ void NamedDecl::printQualifiedName(raw_ostream &OS,
// fall back to "(anonymous)".
SmallString<64> NameBuffer;
llvm::raw_svector_ostream NameOS(NameBuffer);
printName(NameOS);
printName(NameOS, P);
if (NameBuffer.empty())
OS << "(anonymous)";
else
Expand Down Expand Up @@ -1755,7 +1759,7 @@ void NamedDecl::getNameForDiagnostic(raw_ostream &OS,
if (Qualified)
printQualifiedName(OS, Policy);
else
printName(OS);
printName(OS, Policy);
}

template<typename T> static bool isRedeclarableImpl(Redeclarable<T> *) {
Expand Down Expand Up @@ -4470,6 +4474,23 @@ void TagDecl::setQualifierInfo(NestedNameSpecifierLoc QualifierLoc) {
}
}

void TagDecl::printName(raw_ostream &OS, const PrintingPolicy &Policy) const {
DeclarationName Name = getDeclName();
// If the name is supposed to have an identifier but does not have one, then
// the tag is anonymous and we should print it differently.
if (Name.isIdentifier() && !Name.getAsIdentifierInfo()) {
// If the caller wanted to print a qualified name, they've already printed
// the scope. And if the caller doesn't want that, the scope information
// is already printed as part of the type.
PrintingPolicy Copy(Policy);
Copy.SuppressScope = true;
getASTContext().getTagDeclType(this).print(OS, Copy);
return;
}
// Otherwise, do the normal printing.
Name.print(OS, Policy);
}

void TagDecl::setTemplateParameterListsInfo(
ASTContext &Context, ArrayRef<TemplateParameterList *> TPLists) {
assert(!TPLists.empty());
Expand Down
17 changes: 10 additions & 7 deletions clang/lib/AST/DeclCXX.cpp
Expand Up @@ -3269,16 +3269,17 @@ DecompositionDecl *DecompositionDecl::CreateDeserialized(ASTContext &C,
return Result;
}

void DecompositionDecl::printName(llvm::raw_ostream &os) const {
os << '[';
void DecompositionDecl::printName(llvm::raw_ostream &OS,
const PrintingPolicy &Policy) const {
OS << '[';
bool Comma = false;
for (const auto *B : bindings()) {
if (Comma)
os << ", ";
B->printName(os);
OS << ", ";
B->printName(OS, Policy);
Comma = true;
}
os << ']';
OS << ']';
}

void MSPropertyDecl::anchor() {}
Expand Down Expand Up @@ -3314,7 +3315,8 @@ MSGuidDecl *MSGuidDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return new (C, ID) MSGuidDecl(nullptr, QualType(), Parts());
}

void MSGuidDecl::printName(llvm::raw_ostream &OS) const {
void MSGuidDecl::printName(llvm::raw_ostream &OS,
const PrintingPolicy &) const {
OS << llvm::format("GUID{%08" PRIx32 "-%04" PRIx16 "-%04" PRIx16 "-",
PartVal.Part1, PartVal.Part2, PartVal.Part3);
unsigned I = 0;
Expand Down Expand Up @@ -3423,7 +3425,8 @@ UnnamedGlobalConstantDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
UnnamedGlobalConstantDecl(C, nullptr, QualType(), APValue());
}

void UnnamedGlobalConstantDecl::printName(llvm::raw_ostream &OS) const {
void UnnamedGlobalConstantDecl::printName(llvm::raw_ostream &OS,
const PrintingPolicy &) const {
OS << "unnamed-global-constant";
}

Expand Down
4 changes: 2 additions & 2 deletions clang/lib/AST/DeclPrinter.cpp
Expand Up @@ -1711,7 +1711,7 @@ void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
Out << OpName;
} else {
assert(D->getDeclName().isIdentifier());
D->printName(Out);
D->printName(Out, Policy);
}
Out << " : ";
D->getType().print(Out, Policy);
Expand Down Expand Up @@ -1741,7 +1741,7 @@ void DeclPrinter::VisitOMPDeclareReductionDecl(OMPDeclareReductionDecl *D) {
void DeclPrinter::VisitOMPDeclareMapperDecl(OMPDeclareMapperDecl *D) {
if (!D->isInvalidDecl()) {
Out << "#pragma omp declare mapper (";
D->printName(Out);
D->printName(Out, Policy);
Out << " : ";
D->getType().print(Out, Policy);
Out << " ";
Expand Down
5 changes: 3 additions & 2 deletions clang/lib/AST/DeclTemplate.cpp
Expand Up @@ -1532,9 +1532,10 @@ TemplateParamObjectDecl::CreateDeserialized(ASTContext &C, unsigned ID) {
return TPOD;
}

void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS) const {
void TemplateParamObjectDecl::printName(llvm::raw_ostream &OS,
const PrintingPolicy &Policy) const {
OS << "<template param ";
printAsExpr(OS);
printAsExpr(OS, Policy);
OS << ">";
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/NestedNameSpecifier.cpp
Expand Up @@ -287,7 +287,7 @@ void NestedNameSpecifier::print(raw_ostream &OS, const PrintingPolicy &Policy,
dyn_cast_or_null<ClassTemplateSpecializationDecl>(getAsRecordDecl());
if (ResolveTemplateArguments && Record) {
// Print the type trait with resolved template parameters.
Record->printName(OS);
Record->printName(OS, Policy);
printTemplateArgumentList(
OS, Record->getTemplateArgs().asArray(), Policy,
Record->getSpecializedTemplate()->getTemplateParameters());
Expand Down
2 changes: 1 addition & 1 deletion clang/lib/AST/TemplateName.cpp
Expand Up @@ -304,7 +304,7 @@ void TemplateName::print(raw_ostream &OS, const PrintingPolicy &Policy,
} else {
assert(getKind() == TemplateName::OverloadedTemplate);
OverloadedTemplateStorage *OTS = getAsOverloadedTemplate();
(*OTS->begin())->printName(OS);
(*OTS->begin())->printName(OS, Policy);
}
}

Expand Down
2 changes: 1 addition & 1 deletion clang/lib/CodeGen/CodeGenTypes.cpp
Expand Up @@ -67,7 +67,7 @@ void CodeGenTypes::addRecordTypeName(const RecordDecl *RD,
if (RD->getDeclContext())
RD->printQualifiedName(OS, Policy);
else
RD->printName(OS);
RD->printName(OS, Policy);
} else if (const TypedefNameDecl *TDD = RD->getTypedefNameForAnonDecl()) {
// FIXME: We should not have to check for a null decl context here.
// Right now we do it because the implicit Obj-C decls don't have one.
Expand Down
6 changes: 3 additions & 3 deletions clang/lib/Sema/SemaTemplateInstantiate.cpp
Expand Up @@ -718,7 +718,7 @@ void Sema::PrintInstantiationStack() {
TemplateDecl *Template = cast<TemplateDecl>(Active->Template);
SmallString<128> TemplateArgsStr;
llvm::raw_svector_ostream OS(TemplateArgsStr);
Template->printName(OS);
Template->printName(OS, getPrintingPolicy());
printTemplateArgumentList(OS, Active->template_arguments(),
getPrintingPolicy());
Diags.Report(Active->PointOfInstantiation,
Expand Down Expand Up @@ -784,7 +784,7 @@ void Sema::PrintInstantiationStack() {

SmallString<128> TemplateArgsStr;
llvm::raw_svector_ostream OS(TemplateArgsStr);
FD->printName(OS);
FD->printName(OS, getPrintingPolicy());
printTemplateArgumentList(OS, Active->template_arguments(),
getPrintingPolicy());
Diags.Report(Active->PointOfInstantiation,
Expand Down Expand Up @@ -949,7 +949,7 @@ void Sema::PrintInstantiationStack() {
}
SmallString<128> TemplateArgsStr;
llvm::raw_svector_ostream OS(TemplateArgsStr);
cast<NamedDecl>(Active->Entity)->printName(OS);
cast<NamedDecl>(Active->Entity)->printName(OS, getPrintingPolicy());
if (!isa<FunctionDecl>(Active->Entity)) {
printTemplateArgumentList(OS, Active->template_arguments(),
getPrintingPolicy());
Expand Down
4 changes: 2 additions & 2 deletions clang/test/AST/ast-dump-record-definition-data-json.cpp
Expand Up @@ -323,7 +323,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "isReferenced": true,
// CHECK-NEXT: "name": "~",
// CHECK-NEXT: "name": "~(lambda at {{.*}})",
// CHECK-NEXT: "mangledName": "_ZZ1fvEN3$_0D1Ev",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "void () noexcept"
Expand Down Expand Up @@ -708,7 +708,7 @@ struct DoesNotAllowConstDefaultInit {
// CHECK-NEXT: },
// CHECK-NEXT: "isImplicit": true,
// CHECK-NEXT: "isReferenced": true,
// CHECK-NEXT: "name": "~",
// CHECK-NEXT: "name": "~(lambda at {{.*}})",
// CHECK-NEXT: "mangledName": "_ZZ1fvEN3$_1D1Ev",
// CHECK-NEXT: "type": {
// CHECK-NEXT: "qualType": "void () noexcept"
Expand Down
16 changes: 8 additions & 8 deletions clang/test/ExtractAPI/enum.c
Expand Up @@ -694,13 +694,13 @@ enum {
"navigator": [
{
"kind": "identifier",
"spelling": "(anonymous)"
"spelling": "enum (unnamed)"
}
],
"title": "(anonymous)"
"title": "enum (unnamed)"
},
"pathComponents": [
"(anonymous)"
"enum (unnamed)"
]
},
{
Expand Down Expand Up @@ -742,7 +742,7 @@ enum {
"title": "Constant"
},
"pathComponents": [
"(anonymous)",
"enum (unnamed)",
"Constant"
]
},
Expand Down Expand Up @@ -782,13 +782,13 @@ enum {
"navigator": [
{
"kind": "identifier",
"spelling": "(anonymous)"
"spelling": "enum (unnamed)"
}
],
"title": "(anonymous)"
"title": "enum (unnamed)"
},
"pathComponents": [
"(anonymous)"
"enum (unnamed)"
]
},
{
Expand Down Expand Up @@ -830,7 +830,7 @@ enum {
"title": "OtherConstant"
},
"pathComponents": [
"(anonymous)",
"enum (unnamed)",
"OtherConstant"
]
}
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Index/annotate-comments-typedef.m
Expand Up @@ -36,7 +36,7 @@
int iii;
} Foo;
// CHECK: TypedefDecl=Foo:[[@LINE-1]]:11 (Definition) {{.*}} FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] FullCommentAsXML=[<Typedef file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-1]]" column="11"><Name>Foo</Name><USR>c:@T@Foo</USR><Declaration>typedef struct Foo Foo</Declaration><Abstract><Para> Comment about Foo </Para></Abstract></Typedef>]
// CHECK: StructDecl=:[[@LINE-4]]:9 (Definition) {{.*}} BriefComment=[Comment about Foo] FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-4]]" column="9"><Name>&lt;anonymous&gt;</Name><USR>c:@SA@Foo</USR><Declaration>struct {}</Declaration><Abstract><Para> Comment about Foo </Para></Abstract></Class>]
// CHECK: StructDecl=Foo:[[@LINE-4]]:9 (Definition) {{.*}} BriefComment=[Comment about Foo] FullCommentAsHTML=[<p class="para-brief"> Comment about Foo </p>] FullCommentAsXML=[<Class file="{{[^"]+}}annotate-comments-typedef.m" line="[[@LINE-4]]" column="9"><Name>&lt;anonymous&gt;</Name><USR>c:@SA@Foo</USR><Declaration>struct {}</Declaration><Abstract><Para> Comment about Foo </Para></Abstract></Class>]


struct Foo1 {
Expand Down
2 changes: 1 addition & 1 deletion clang/test/Index/c-index-api-loadTU-test.m
Expand Up @@ -105,7 +105,7 @@ @interface TestAttributes()
// CHECK: c-index-api-loadTU-test.m:35:9: ObjCIvarDecl=_anIVar:35:9 (Definition) Extent=[35:5 - 35:16]
// CHECK: c-index-api-loadTU-test.m:38:11: ObjCInstanceMethodDecl=bazMethod:38:11 Extent=[38:1 - 38:21]
// CHECK: c-index-api-loadTU-test.m:38:4: ObjCClassRef=Foo:4:12 Extent=[38:4 - 38:7]
// CHECK: c-index-api-loadTU-test.m:42:1: EnumDecl=:42:1 (Definition) Extent=[42:1 - 44:2]
// CHECK: c-index-api-loadTU-test.m:42:1: EnumDecl=enum (unnamed at {{.*}}):42:1 (Definition) Extent=[42:1 - 44:2]
// CHECK: c-index-api-loadTU-test.m:43:3: EnumConstantDecl=someEnum:43:3 (Definition) Extent=[43:3 - 43:11]
// CHECK: c-index-api-loadTU-test.m:46:5: FunctionDecl=main:46:5 (Definition) Extent=[46:1 - 55:2]
// CHECK: c-index-api-loadTU-test.m:46:15: ParmDecl=argc:46:15 (Definition) Extent=[46:11 - 46:19]
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Index/c-index-getCursor-test.m
Expand Up @@ -102,9 +102,9 @@ void f() {
// CHECK: [36:7 - 36:21] ObjCInstanceMethodDecl=bazMethod:36:1
// CHECK: [36:21 - 38:5] ObjCInterfaceDecl=Baz:31:12
// CHECK: [38:5 - 40:1] Invalid Cursor => NoDeclFound
// CHECK: [40:1 - 41:3] EnumDecl=:40:1 (Definition)
// CHECK: [40:1 - 41:3] EnumDecl=enum (unnamed at {{.*}}):40:1 (Definition)
// CHECK: [41:3 - 41:11] EnumConstantDecl=someEnum:41:3 (Definition)
// CHECK: [41:11 - 42:2] EnumDecl=:40:1 (Definition)
// CHECK: [41:11 - 42:2] EnumDecl=enum (unnamed at {{.*}}):40:1 (Definition)
// CHECK: [42:2 - 44:1] Invalid Cursor => NoDeclFound
// CHECK: [44:1 - 44:11] FunctionDecl=main:44:5 (Definition)
// CHECK: [44:11 - 44:19] ParmDecl=argc:44:15 (Definition)
Expand Down
8 changes: 4 additions & 4 deletions clang/test/Index/print-type.c
Expand Up @@ -69,10 +69,10 @@ _Atomic(unsigned long) aul;
// CHECK: StructDecl=Struct:16:8 (Definition) [type=struct Struct] [typekind=Record] [isPOD=1]
// CHECK: FunctionDecl=elaboratedStructType:16:32 [type=struct Struct ()] [typekind=FunctionNoProto] [canonicaltype=struct Struct ()] [canonicaltypekind=FunctionNoProto] [resulttype=struct Struct] [resulttypekind=Elaborated] [isPOD=0]
// CHECK: TypeRef=struct Struct:16:8 [type=struct Struct] [typekind=Record] [isPOD=1]
// CHECK: StructDecl=:18:1 (Definition) [type=struct (unnamed at {{.*}}print-type.c:18:1)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
// CHECK: StructDecl=:23:1 (Definition) [type=struct (unnamed at {{.*}}print-type.c:23:1)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] [isAnonRecDecl=0]
// CHECK: StructDecl=:24:3 (Definition) [type=struct (anonymous at {{.*}}print-type.c:24:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=1]
// CHECK: StructDecl=struct (unnamed at {{.*}}):18:1 (Definition) [type=struct (unnamed at {{.*}}print-type.c:18:1)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
// CHECK: StructDecl=struct (unnamed at {{.*}}):23:1 (Definition) [type=struct (unnamed at {{.*}}print-type.c:23:1)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1] [isAnonRecDecl=0]
// CHECK: StructDecl=struct (anonymous at {{.*}}):24:3 (Definition) [type=struct (anonymous at {{.*}}print-type.c:24:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=1]
// CHECK: FieldDecl=x:25:17 (Definition) [type=_Atomic(int)] [typekind=Atomic] [valuetype=int] [valuetypekind=Int] [isPOD=0] [isAnonRecDecl=0]
// CHECK: FieldDecl=y:26:9 (Definition) [type=int] [typekind=Int] [isPOD=1] [isAnonRecDecl=0]
// CHECK: StructDecl=:30:10 (Definition) [type=struct (unnamed at {{.*}}print-type.c:30:10)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
// CHECK: StructDecl=struct (unnamed at {{.*}}):30:10 (Definition) [type=struct (unnamed at {{.*}}print-type.c:30:10)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1] [isAnonRecDecl=0]
// CHECK: VarDecl=aul:32:24 [type=_Atomic(unsigned long)] [typekind=Atomic] [valuetype=unsigned long] [valuetypekind=ULong] [isPOD=0] [isAnonRecDecl=0]
8 changes: 4 additions & 4 deletions clang/test/Index/print-type.cpp
Expand Up @@ -201,9 +201,9 @@ inline namespace InlineNS {}
// CHECK: TypeAliasDecl=baz:76:7 (Definition) [type=baz] [typekind=Typedef] [templateargs/1= [type=A<void>] [typekind=Elaborated]] [canonicaltype=A<void>] [canonicaltypekind=Record] [canonicaltemplateargs/1= [type=void] [typekind=Void]] [isPOD=0]
// CHECK: VarDecl=autoTemplPointer:78:6 (Definition) [type=Specialization<Specialization<bool> &> *] [typekind=Auto] [canonicaltype=Specialization<Specialization<bool> &> *] [canonicaltypekind=Pointer] [isPOD=1] [pointeetype=Specialization<Specialization<bool> &>] [pointeekind=Auto]
// CHECK: CallExpr=Bar:17:3 [type=outer::inner::Bar] [typekind=Elaborated] [canonicaltype=outer::inner::Bar] [canonicaltypekind=Record] [args= [outer::Foo<bool> *] [Pointer]] [isPOD=0] [nbFields=3]
// CHECK: StructDecl=:84:3 (Definition) [type=X::(anonymous struct at {{.*}}print-type.cpp:84:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
// CHECK: ClassDecl=:85:3 (Definition) [type=X::(anonymous class at {{.*}}print-type.cpp:85:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
// CHECK: UnionDecl=:86:3 (Definition) [type=X::(anonymous union at {{.*}}print-type.cpp:86:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1]
// CHECK: EnumDecl=:87:3 (Definition) [type=X::(unnamed enum at {{.*}}print-type.cpp:87:3)] [typekind=Enum] [isPOD=1] [isAnon=1]
// CHECK: StructDecl=(anonymous struct at {{.*}}):84:3 (Definition) [type=X::(anonymous struct at {{.*}}print-type.cpp:84:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
// CHECK: ClassDecl=(anonymous class at {{.*}}:85:3 (Definition) [type=X::(anonymous class at {{.*}}print-type.cpp:85:3)] [typekind=Record] [isPOD=1] [nbFields=1] [isAnon=1]
// CHECK: UnionDecl=(anonymous union at {{.*}}:86:3 (Definition) [type=X::(anonymous union at {{.*}}print-type.cpp:86:3)] [typekind=Record] [isPOD=1] [nbFields=2] [isAnon=1]
// CHECK: EnumDecl=(unnamed enum at {{.*}}:87:3 (Definition) [type=X::(unnamed enum at {{.*}}print-type.cpp:87:3)] [typekind=Enum] [isPOD=1] [isAnon=1]
// CHECK: Namespace=:90:11 (Definition) [type=] [typekind=Invalid] [isPOD=0] [isAnon=1]
// CHECK: Namespace=InlineNS:94:18 (Definition) [type=] [typekind=Invalid] [isPOD=0] [isAnonRecDecl=0] [isInlineNamespace=1]

0 comments on commit 19e984e

Please sign in to comment.