From e8d411997899a87e1a9f63ad3f52b38e7931687c Mon Sep 17 00:00:00 2001 From: Richard Trieu Date: Thu, 31 Jan 2013 01:44:26 +0000 Subject: [PATCH] Add indents to AST dumping and removed parenthesis from AST nodes. Indents were given the color blue when outputting with color. AST dumping now looks like this: Node |-Node | `-Node `-Node `-Node Compared to the previous: (Node (Node (Node)) (Node (Node))) git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174022 91177308-0d34-0410-b5e6-96231b3b80d8 --- lib/AST/ASTDumper.cpp | 334 ++++++++++++++++++++++---- test/CodeGen/bitfield-2.c | 8 +- test/Misc/ast-dump-attr.cpp | 4 +- test/Misc/ast-dump-color.cpp | 118 ++++----- test/Misc/ast-dump-comment.cpp | 4 +- test/Misc/ast-dump-decl.c | 4 +- test/Misc/ast-dump-stmt.c | 8 +- test/Misc/ast-dump-wchar.cpp | 8 +- test/Sema/implicit-cast-dump.c | 6 +- test/Tooling/clang-check-ast-dump.cpp | 30 +-- utils/TableGen/ClangAttrEmitter.cpp | 41 +++- 11 files changed, 417 insertions(+), 148 deletions(-) diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp index 6248da045a..5291c8bc42 100644 --- a/lib/AST/ASTDumper.cpp +++ b/lib/AST/ASTDumper.cpp @@ -70,6 +70,9 @@ namespace { // Decl names static const TerminalColor DeclNameColor = { raw_ostream::CYAN, true }; + // Indents ( `, -. | ) + static const TerminalColor IndentColor = { raw_ostream::BLUE, false }; + class ASTDumper : public DeclVisitor, public StmtVisitor, public ConstCommentVisitor { @@ -79,6 +82,19 @@ namespace { unsigned IndentLevel; bool IsFirstLine; + // Indicates whether more child are expected at the current tree depth + enum IndentType { IT_Child, IT_LastChild }; + + /// Indents[i] indicates if another child exists at level i. + /// Used by Indent() to print the tree structure. + llvm::SmallVector Indents; + + /// Indicates that more children will be needed at this indent level. + /// If true, prevents lastChild() from marking the node as the last child. + /// This is used when there are multiple collections of children to be + /// dumped as well as during conditional node dumping. + bool MoreChildren; + /// Keep track of the last location we print out so that we can /// print out deltas from then on out. const char *LastLocFilename; @@ -91,11 +107,16 @@ namespace { class IndentScope { ASTDumper &Dumper; + // Preserve the Dumper's MoreChildren value from the previous IndentScope + bool MoreChildren; public: IndentScope(ASTDumper &Dumper) : Dumper(Dumper) { + MoreChildren = Dumper.hasMoreChildren(); + Dumper.setMoreChildren(false); Dumper.indent(); } ~IndentScope() { + Dumper.setMoreChildren(MoreChildren); Dumper.unindent(); } }; @@ -118,13 +139,14 @@ namespace { ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM) : OS(OS), Traits(Traits), SM(SM), IndentLevel(0), IsFirstLine(true), - LastLocFilename(""), LastLocLine(~0U), FC(0), + MoreChildren(false), LastLocFilename(""), LastLocLine(~0U), FC(0), ShowColors(SM && SM->getDiagnostics().getShowColors()) { } ASTDumper(raw_ostream &OS, const CommandTraits *Traits, const SourceManager *SM, bool ShowColors) : OS(OS), Traits(Traits), SM(SM), IndentLevel(0), IsFirstLine(true), - LastLocFilename(""), LastLocLine(~0U), ShowColors(ShowColors) { } + MoreChildren(false), LastLocFilename(""), LastLocLine(~0U), + ShowColors(ShowColors) { } ~ASTDumper() { OS << "\n"; @@ -134,9 +156,14 @@ namespace { void dumpStmt(Stmt *S); void dumpFullComment(const FullComment *C); - // Utilities + // Formatting void indent(); void unindent(); + void lastChild(); + bool hasMoreChildren(); + void setMoreChildren(bool Value); + + // Utilities void dumpPointer(const void *Ptr); void dumpSourceRange(SourceRange R); void dumpLocation(SourceLocation Loc); @@ -145,6 +172,7 @@ namespace { void dumpBareDeclRef(const Decl *Node); void dumpDeclRef(const Decl *Node, const char *Label = 0); void dumpName(const NamedDecl *D); + bool hasNodes(const DeclContext *DC); void dumpDeclContext(const DeclContext *DC); void dumpAttr(const Attr *A); @@ -284,19 +312,66 @@ namespace { // Utilities //===----------------------------------------------------------------------===// +// Print out the appropriate tree structure using the Indents vector. +// Example of tree and the Indents vector at each level. +// A { } +// |-B { IT_Child } +// | `-C { IT_Child, IT_LastChild } +// `-D { IT_LastChild } +// |-E { IT_LastChild, IT_Child } +// `-F { IT_LastChild, IT_LastChild } +// Type non-last element, last element +// IT_Child "| " "|-" +// IT_LastChild " " "`-" void ASTDumper::indent() { if (IsFirstLine) IsFirstLine = false; else OS << "\n"; - OS.indent(IndentLevel * 2); - OS << "("; - IndentLevel++; + + ColorScope Color(*this, IndentColor); + for (llvm::SmallVector::const_iterator I = + Indents.begin(), E = Indents.end(); + I != E; ++I) { + switch (*I) { + case IT_Child: + if (I == E - 1) + OS << "|-"; + else + OS << "| "; + break; + case IT_LastChild: + if (I == E - 1) + OS << "`-"; + else + OS << " "; + break; + default: + llvm_unreachable("Invalid IndentType"); + } + } + Indents.push_back(IT_Child); } void ASTDumper::unindent() { - OS << ")"; - IndentLevel--; + Indents.pop_back(); +} + +// Call before each potential last child node is to be dumped. If MoreChildren +// is false, then this is the last child, otherwise treat as a regular node. +void ASTDumper::lastChild() { + if (!hasMoreChildren()) + Indents.back() = IT_LastChild; +} + +// MoreChildren should be set before calling another function that may print +// additional nodes to prevent conflicting final child nodes. +bool ASTDumper::hasMoreChildren() { + return MoreChildren; +} + +void ASTDumper::setMoreChildren(bool Value) { + MoreChildren = Value; } void ASTDumper::dumpPointer(const void *Ptr) { @@ -402,12 +477,24 @@ void ASTDumper::dumpName(const NamedDecl *ND) { } } +bool ASTDumper::hasNodes(const DeclContext *DC) { + if (!DC) + return false; + + return DC->decls_begin() != DC->decls_end(); +} + void ASTDumper::dumpDeclContext(const DeclContext *DC) { if (!DC) return; for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end(); - I != E; ++I) + I != E; ++I) { + DeclContext::decl_iterator Next = I; + ++Next; + if (Next == E) + lastChild(); dumpDecl(*I); + } } void ASTDumper::dumpAttr(const Attr *A) { @@ -469,8 +556,11 @@ void ASTDumper::dumpTemplateParameters(const TemplateParameterList *TPL) { void ASTDumper::dumpTemplateArgumentListInfo( const TemplateArgumentListInfo &TALI) { - for (unsigned i = 0, e = TALI.size(); i < e; ++i) + for (unsigned i = 0, e = TALI.size(); i < e; ++i) { + if (i + 1 == e) + lastChild(); dumpTemplateArgumentLoc(TALI[i]); + } } void ASTDumper::dumpTemplateArgumentLoc(const TemplateArgumentLoc &A) { @@ -494,10 +584,12 @@ void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { break; case TemplateArgument::Type: OS << " type"; + lastChild(); dumpType(A.getAsType()); break; case TemplateArgument::Declaration: OS << " decl"; + lastChild(); dumpDeclRef(A.getAsDecl()); break; case TemplateArgument::NullPtr: @@ -516,13 +608,17 @@ void ASTDumper::dumpTemplateArgument(const TemplateArgument &A, SourceRange R) { break; case TemplateArgument::Expression: OS << " expr"; + lastChild(); dumpStmt(A.getAsExpr()); break; case TemplateArgument::Pack: OS << " pack"; for (TemplateArgument::pack_iterator I = A.pack_begin(), E = A.pack_end(); - I != E; ++I) + I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpTemplateArgument(*I); + } break; } } @@ -546,15 +642,32 @@ void ASTDumper::dumpDecl(Decl *D) { } dumpPointer(D); dumpSourceRange(D->getSourceRange()); - DeclVisitor::Visit(D); - if (D->hasAttrs()) { - for (AttrVec::const_iterator I = D->getAttrs().begin(), - E = D->getAttrs().end(); I != E; ++I) - dumpAttr(*I); - } - dumpFullComment(D->getASTContext().getCommentForDecl(D, 0)); + + bool HasAttrs = D->hasAttrs() && D->getAttrs().begin() != D->getAttrs().end(); + bool HasComment = D->getASTContext().getCommentForDecl(D, 0); // Decls within functions are visited by the body - if (!isa(*D) && !isa(*D)) + bool HasDeclContext = !isa(*D) && !isa(*D) && + hasNodes(dyn_cast(D)); + + setMoreChildren(HasAttrs || HasComment || HasDeclContext); + DeclVisitor::Visit(D); + + setMoreChildren(HasComment || HasDeclContext); + if (HasAttrs) { + for (AttrVec::const_iterator I = D->getAttrs().begin(), + E = D->getAttrs().end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); + dumpAttr(*I); + } + } + + setMoreChildren(HasDeclContext); + lastChild(); + dumpFullComment(D->getASTContext().getCommentForDecl(D, 0)); + + setMoreChildren(false); + if (HasDeclContext) dumpDeclContext(dyn_cast(D)); } @@ -593,16 +706,21 @@ void ASTDumper::VisitRecordDecl(RecordDecl *D) { void ASTDumper::VisitEnumConstantDecl(EnumConstantDecl *D) { dumpName(D); dumpType(D->getType()); - if (Expr *Init = D->getInitExpr()) + if (Expr *Init = D->getInitExpr()) { + lastChild(); dumpStmt(Init); + } } void ASTDumper::VisitIndirectFieldDecl(IndirectFieldDecl *D) { dumpName(D); dumpType(D->getType()); for (IndirectFieldDecl::chain_iterator I = D->chain_begin(), - E = D->chain_end(); I != E; ++I) + E = D->chain_end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDeclRef(*I); + } } void ASTDumper::VisitFunctionDecl(FunctionDecl *D) { @@ -624,26 +742,60 @@ void ASTDumper::VisitFunctionDecl(FunctionDecl *D) { else if (D->isDeletedAsWritten()) OS << " delete"; - if (const FunctionTemplateSpecializationInfo *FTSI = - D->getTemplateSpecializationInfo()) - dumpTemplateArgumentList(*FTSI->TemplateArguments); + bool OldMoreChildren = hasMoreChildren(); + const FunctionTemplateSpecializationInfo *FTSI = + D->getTemplateSpecializationInfo(); + bool HasTemplateSpecialization = FTSI; + bool HasNamedDecls = D->getDeclsInPrototypeScope().begin() != + D->getDeclsInPrototypeScope().end(); + + bool HasFunctionDecls = D->param_begin() != D->param_end(); + + CXXConstructorDecl *C = dyn_cast(D); + bool HasCtorInitializers = C && C->init_begin() != C->init_end(); + + bool HasDeclarationBody = D->doesThisDeclarationHaveABody(); + + setMoreChildren(OldMoreChildren || HasNamedDecls || HasFunctionDecls || + HasCtorInitializers || HasDeclarationBody); + if (HasTemplateSpecialization) { + lastChild(); + dumpTemplateArgumentList(*FTSI->TemplateArguments); + } + + setMoreChildren(OldMoreChildren || HasFunctionDecls || + HasCtorInitializers || HasDeclarationBody); for (ArrayRef::iterator I = D->getDeclsInPrototypeScope().begin(), - E = D->getDeclsInPrototypeScope().end(); I != E; ++I) + E = D->getDeclsInPrototypeScope().end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDecl(*I); + } + setMoreChildren(OldMoreChildren || HasCtorInitializers || HasDeclarationBody); for (FunctionDecl::param_iterator I = D->param_begin(), E = D->param_end(); - I != E; ++I) + I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDecl(*I); - - if (CXXConstructorDecl *C = dyn_cast(D)) + } + + setMoreChildren(OldMoreChildren || HasDeclarationBody); + if (HasCtorInitializers) for (CXXConstructorDecl::init_const_iterator I = C->init_begin(), - E = C->init_end(); I != E; ++I) + E = C->init_end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpCXXCtorInitializer(*I); + } - if (D->doesThisDeclarationHaveABody()) + setMoreChildren(OldMoreChildren); + if (HasDeclarationBody) { + lastChild(); dumpStmt(D->getBody()); + } } void ASTDumper::VisitFieldDecl(FieldDecl *D) { @@ -653,10 +805,22 @@ void ASTDumper::VisitFieldDecl(FieldDecl *D) { OS << " mutable"; if (D->isModulePrivate()) OS << " __module_private__"; - if (D->isBitField()) + + bool OldMoreChildren = hasMoreChildren(); + bool IsBitField = D->isBitField(); + Expr *Init = D->getInClassInitializer(); + bool HasInit = Init; + + setMoreChildren(OldMoreChildren || HasInit); + if (IsBitField) { + lastChild(); dumpStmt(D->getBitWidth()); - if (Expr *Init = D->getInClassInitializer()) + } + setMoreChildren(OldMoreChildren); + if (HasInit) { + lastChild(); dumpStmt(Init); + } } void ASTDumper::VisitVarDecl(VarDecl *D) { @@ -671,11 +835,14 @@ void ASTDumper::VisitVarDecl(VarDecl *D) { OS << " __module_private__"; if (D->isNRVOVariable()) OS << " nrvo"; - if (D->hasInit()) + if (D->hasInit()) { + lastChild(); dumpStmt(D->getInit()); + } } void ASTDumper::VisitFileScopeAsmDecl(FileScopeAsmDecl *D) { + lastChild(); dumpStmt(D->getAsmString()); } @@ -735,6 +902,7 @@ void ASTDumper::VisitCXXRecordDecl(CXXRecordDecl *D) { void ASTDumper::VisitStaticAssertDecl(StaticAssertDecl *D) { dumpStmt(D->getAssertExpr()); + lastChild(); dumpStmt(D->getMessage()); } @@ -744,6 +912,10 @@ void ASTDumper::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { dumpDecl(D->getTemplatedDecl()); for (FunctionTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); I != E; ++I) { + FunctionTemplateDecl::spec_iterator Next = I; + ++Next; + if (Next == E) + lastChild(); switch (I->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ImplicitInstantiation: @@ -761,9 +933,16 @@ void ASTDumper::VisitFunctionTemplateDecl(FunctionTemplateDecl *D) { void ASTDumper::VisitClassTemplateDecl(ClassTemplateDecl *D) { dumpName(D); dumpTemplateParameters(D->getTemplateParameters()); + + if (D->spec_begin() == D->spec_end()) + lastChild(); dumpDecl(D->getTemplatedDecl()); for (ClassTemplateDecl::spec_iterator I = D->spec_begin(), E = D->spec_end(); I != E; ++I) { + ClassTemplateDecl::spec_iterator Next = I; + ++Next; + if (Next == E) + lastChild(); switch (I->getTemplateSpecializationKind()) { case TSK_Undeclared: case TSK_ImplicitInstantiation: @@ -908,66 +1087,99 @@ void ASTDumper::VisitObjCMethodDecl(ObjCMethodDecl *D) { dumpName(D); dumpType(D->getResultType()); - if (D->isThisDeclarationADefinition()) + bool OldMoreChildren = hasMoreChildren(); + bool IsVariadic = D->isVariadic(); + bool HasBody = D->hasBody(); + + setMoreChildren(OldMoreChildren || IsVariadic || HasBody); + if (D->isThisDeclarationADefinition()) { + lastChild(); dumpDeclContext(D); - else { + } else { for (ObjCMethodDecl::param_iterator I = D->param_begin(), E = D->param_end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDecl(*I); } } - if (D->isVariadic()) { + setMoreChildren(OldMoreChildren || HasBody); + if (IsVariadic) { + lastChild(); IndentScope Indent(*this); OS << "..."; } - if (D->hasBody()) + setMoreChildren(OldMoreChildren); + if (HasBody) { + lastChild(); dumpStmt(D->getBody()); + } } void ASTDumper::VisitObjCCategoryDecl(ObjCCategoryDecl *D) { dumpName(D); dumpDeclRef(D->getClassInterface()); + if (D->protocol_begin() == D->protocol_end()) + lastChild(); dumpDeclRef(D->getImplementation()); for (ObjCCategoryDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); I != E; ++I) + E = D->protocol_end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDeclRef(*I); + } } void ASTDumper::VisitObjCCategoryImplDecl(ObjCCategoryImplDecl *D) { dumpName(D); dumpDeclRef(D->getClassInterface()); + lastChild(); dumpDeclRef(D->getCategoryDecl()); } void ASTDumper::VisitObjCProtocolDecl(ObjCProtocolDecl *D) { dumpName(D); for (ObjCProtocolDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); I != E; ++I) + E = D->protocol_end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDeclRef(*I); + } } void ASTDumper::VisitObjCInterfaceDecl(ObjCInterfaceDecl *D) { dumpName(D); dumpDeclRef(D->getSuperClass(), "super"); + if (D->protocol_begin() == D->protocol_end()) + lastChild(); dumpDeclRef(D->getImplementation()); for (ObjCInterfaceDecl::protocol_iterator I = D->protocol_begin(), - E = D->protocol_end(); I != E; ++I) + E = D->protocol_end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDeclRef(*I); + } } void ASTDumper::VisitObjCImplementationDecl(ObjCImplementationDecl *D) { dumpName(D); dumpDeclRef(D->getSuperClass(), "super"); + if (D->init_begin() == D->init_end()) + lastChild(); dumpDeclRef(D->getClassInterface()); for (ObjCImplementationDecl::init_iterator I = D->init_begin(), - E = D->init_end(); I != E; ++I) + E = D->init_end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpCXXCtorInitializer(*I); + } } void ASTDumper::VisitObjCCompatibleAliasDecl(ObjCCompatibleAliasDecl *D) { dumpName(D); + lastChild(); dumpDeclRef(D->getClassInterface()); } @@ -1002,10 +1214,15 @@ void ASTDumper::VisitObjCPropertyDecl(ObjCPropertyDecl *D) { OS << " strong"; if (Attrs & ObjCPropertyDecl::OBJC_PR_unsafe_unretained) OS << " unsafe_unretained"; - if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) + if (Attrs & ObjCPropertyDecl::OBJC_PR_getter) { + if (!(Attrs & ObjCPropertyDecl::OBJC_PR_setter)) + lastChild(); dumpDeclRef(D->getGetterMethodDecl(), "getter"); - if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) + } + if (Attrs & ObjCPropertyDecl::OBJC_PR_setter) { + lastChild(); dumpDeclRef(D->getSetterMethodDecl(), "setter"); + } } } @@ -1016,6 +1233,7 @@ void ASTDumper::VisitObjCPropertyImplDecl(ObjCPropertyImplDecl *D) { else OS << " dynamic"; dumpDeclRef(D->getPropertyDecl()); + lastChild(); dumpDeclRef(D->getPropertyIvarDecl()); } @@ -1048,7 +1266,7 @@ void ASTDumper::VisitBlockDecl(BlockDecl *D) { if (I->hasCopyExpr()) dumpStmt(I->getCopyExpr()); } - + lastChild(); dumpStmt(D->getBody()); } @@ -1070,9 +1288,16 @@ void ASTDumper::dumpStmt(Stmt *S) { return; } + setMoreChildren(S->children()); StmtVisitor::Visit(S); - for (Stmt::child_range CI = S->children(); CI; ++CI) + setMoreChildren(false); + for (Stmt::child_range CI = S->children(); CI; ++CI) { + Stmt::child_range Next = CI; + ++Next; + if (!Next) + lastChild(); dumpStmt(*CI); + } } void ASTDumper::VisitStmt(Stmt *Node) { @@ -1087,15 +1312,21 @@ void ASTDumper::VisitStmt(Stmt *Node) { void ASTDumper::VisitDeclStmt(DeclStmt *Node) { VisitStmt(Node); for (DeclStmt::decl_iterator I = Node->decl_begin(), E = Node->decl_end(); - I != E; ++I) + I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpDecl(*I); + } } void ASTDumper::VisitAttributedStmt(AttributedStmt *Node) { VisitStmt(Node); for (ArrayRef::iterator I = Node->getAttrs().begin(), - E = Node->getAttrs().end(); I != E; ++I) + E = Node->getAttrs().end(); I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpAttr(*I); + } } void ASTDumper::VisitLabelStmt(LabelStmt *Node) { @@ -1321,8 +1552,10 @@ void ASTDumper::VisitBlockExpr(BlockExpr *Node) { void ASTDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) { VisitExpr(Node); - if (Expr *Source = Node->getSourceExpr()) + if (Expr *Source = Node->getSourceExpr()) { + lastChild(); dumpStmt(Source); + } } // GNU extensions. @@ -1542,8 +1775,11 @@ void ASTDumper::dumpComment(const Comment *C) { dumpSourceRange(C->getSourceRange()); ConstCommentVisitor::visit(C); for (Comment::child_iterator I = C->child_begin(), E = C->child_end(); - I != E; ++I) + I != E; ++I) { + if (I + 1 == E) + lastChild(); dumpComment(*I); + } } void ASTDumper::visitTextComment(const TextComment *C) { diff --git a/test/CodeGen/bitfield-2.c b/test/CodeGen/bitfield-2.c index 867ed8c2ce..bec55ffa75 100644 --- a/test/CodeGen/bitfield-2.c +++ b/test/CodeGen/bitfield-2.c @@ -9,7 +9,7 @@ // PR6176 // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: (RecordDecl{{.*}}s0 +// CHECK-RECORD: Record: RecordDecl{{.*}}s0 // CHECK-RECORD: Layout: // CHECK-RECORD: IsZeroInitializable:1 @@ -49,7 +49,7 @@ unsigned long long test_0() { // PR5591 // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: (RecordDecl{{.*}}s1 +// CHECK-RECORD: Record: RecordDecl{{.*}}s1 // CHECK-RECORD: Layout: // CHECK-RECORD: IsZeroInitializable:1 @@ -97,7 +97,7 @@ unsigned long long test_1() { // PR5567 // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: (RecordDecl{{.*}}u2 +// CHECK-RECORD: Record: RecordDecl{{.*}}u2 // CHECK-RECORD: Layout: // CHECK-RECORD: IsZeroInitializable:1 @@ -269,7 +269,7 @@ _Bool test_6() { // Check that we compute the best alignment possible for each access. // // CHECK-RECORD: *** Dumping IRgen Record Layout -// CHECK-RECORD: Record: (RecordDecl{{.*}}s7 +// CHECK-RECORD: Record: RecordDecl{{.*}}s7 // CHECK-RECORD: Layout: [[RESET]]>{{$}} -//CHECK: {{^}} ([[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]][[RESET]]>[[CYAN:.\[0;1;36m]] __int128_t[[RESET]] [[Green:.\[0;32m]]'__int128'[[RESET]]){{$}} -//CHECK: {{^}} ([[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]][[RESET]]>[[CYAN]] __uint128_t[[RESET]] [[Green]]'unsigned __int128'[[RESET]]){{$}} -//CHECK: {{^}} ([[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]][[RESET]]>[[CYAN]] __builtin_va_list[[RESET]] [[Green]]'__va_list_tag [1]'[[RESET]]){{$}} -//CHECK: {{^}} ([[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]{{.*}}ast-dump-color.cpp:6:1[[RESET]], [[Yellow]]col:5[[RESET]]>[[CYAN]] Test[[RESET]] [[Green]]'int'[[RESET]]{{$}} -//CHECK: {{^}} ([[BLUE:.\[0;1;34m]]UnusedAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:25[[RESET]]>){{$}} -//CHECK: {{^}} ([[YELLOW:.\[0;1;33m]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]]> Text=" "){{$}} -//CHECK: {{^}} ([[YELLOW]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:7[[RESET]]> Name="a"){{$}} -//CHECK: {{^}} ([[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]], [[Yellow]]col:12[[RESET]]> Text="Hello"){{$}} -//CHECK: {{^}} ([[YELLOW]]HTMLEndTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:13[[RESET]], [[Yellow]]col:16[[RESET]]> Name="a"){{$}} -//CHECK: {{^}} ([[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:5:4[[RESET]]> Text=" "){{$}} -//CHECK: {{^}} ([[YELLOW]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:8[[RESET]]> Name="br" SelfClosing)))){{$}} -//CHECK: {{^}} ([[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]>[[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void (void)'[[RESET]]{{$}} -//CHECK: {{^}} ([[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}} -//CHECK: {{^}} ([[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} -//CHECK: {{^}} ([[Blue:.\[0;34m]]<<>>[[RESET]]){{$}} -//CHECK: {{^}} ([[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]){{$}} -//CHECK: {{^}} ([[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} -//CHECK: {{^}} ([[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}} -//CHECK: {{^}} ([[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]){{$}} -//CHECK: {{^}} ([[Blue]]<<>>[[RESET]]){{$}} -//CHECK: {{^}} ([[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}} -//CHECK: {{^}} ([[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>){{$}} -//CHECK: {{^}} ([[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>))){{$}} -//CHECK: {{^}} ([[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}} -//CHECK: {{^}} ([[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]){{$}} -//CHECK: {{^}} ([[Blue]]<<>>[[RESET]]){{$}} -//CHECK: {{^}} ([[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>))))){{$}} -//CHECK: {{^}} ([[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]> Text=" Comment")))){{$}} -//CHECK: {{^}} ([[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:1[[RESET]]> class[[CYAN]] Mutex[[RESET]]{{$}} -//CHECK: {{^}} ([[BLUE]]LockableAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:22[[RESET]]>){{$}} -//CHECK: {{^}} ([[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:33[[RESET]]> class[[CYAN]] Mutex[[RESET]]){{$}} -//CHECK: {{^}} ([[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:20:3[[RESET]], [[Yellow]]col:7[[RESET]]>[[CYAN]] var1[[RESET]] [[Green]]'int'[[RESET]]{{$}} -//CHECK: {{^}} ([[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:19:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]> Text=" A variable")))){{$}} -//CHECK: {{^}} ([[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:24:3[[RESET]], [[Yellow]]col:7[[RESET]]>[[CYAN]] var2[[RESET]] [[Green]]'int'[[RESET]]{{$}} -//CHECK: {{^}} ([[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]line:23:44[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]col:22[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:22[[RESET]]> Text=" Another variable")){{$}} -//CHECK: {{^}} ([[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:23:6[[RESET]], [[Yellow]]col:44[[RESET]]>{{$}} -//CHECK: {{^}} ([[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:44[[RESET]]> Text=" Like the other variable, but different")))){{$}} -//CHECK: {{^}} ([[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (void)'[[RESET]] inline{{$}} -//CHECK: {{^}} ([[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>)){{$}} -//CHECK: {{^}} ([[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (const class Mutex &)'[[RESET]] inline{{$}} -//CHECK: {{^}} ([[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Green]]'const class Mutex &'[[RESET]])){{$}} -//CHECK: {{^}} ([[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (class Mutex &&)'[[RESET]] inline{{$}} -//CHECK: {{^}} ([[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Green]]'class Mutex &&'[[RESET]]))){{$}} -//CHECK: {{^}} ([[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]>[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}} -//CHECK: {{^}} ([[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]])){{$}} -//CHECK: {{^}} ([[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]>[[CYAN]] mu2[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}} -//CHECK: {{^}} ([[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]])){{$}} -//CHECK: {{^}} ([[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]>[[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]]{{$}} -//CHECK: {{^}} ([[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]]>{{$}} -//CHECK: {{^}} ([[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]])))){{$}} +//CHECK: {{^}}[[Blue:.\[0;34m]][[RESET:.\[0m]][[GREEN:.\[0;1;32m]]TranslationUnitDecl[[RESET]][[Yellow:.\[0;33m]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]][[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]][[RESET]]>[[CYAN:.\[0;1;36m]] __int128_t[[RESET]] [[Green:.\[0;32m]]'__int128'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]][[RESET]]>[[CYAN]] __uint128_t[[RESET]] [[Green]]'unsigned __int128'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]TypedefDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]][[RESET]]>[[CYAN]] __builtin_va_list[[RESET]] [[Green]]'__va_list_tag [1]'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]{{.*}}ast-dump-color.cpp:6:1[[RESET]], [[Yellow]]col:5[[RESET]]>[[CYAN]] Test[[RESET]] [[Green]]'int'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[BLUE:.\[0;1;34m]]UnusedAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:25[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW:.\[0;1;33m]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]], [[Yellow]]line:5:8[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:4:4[[RESET]]> Text=" "{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[YELLOW]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:7[[RESET]]> Name="a"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]], [[Yellow]]col:12[[RESET]]> Text="Hello"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[YELLOW]]HTMLEndTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:13[[RESET]], [[Yellow]]col:16[[RESET]]> Name="a"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:5:4[[RESET]]> Text=" "{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW]]HTMLStartTagComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:5[[RESET]], [[Yellow]]col:8[[RESET]]> Name="br" SelfClosing{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]FunctionDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:1[[RESET]], [[Yellow]]line:16:1[[RESET]]>[[CYAN]] TestAttributedStmt[[RESET]] [[Green]]'void (void)'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[MAGENTA:.\[0;1;35m]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:9:27[[RESET]], [[Yellow]]line:16:1[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]SwitchStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:3[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[Blue:.\[0;34m]]<<>>[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:10:11[[RESET]]> [[Green]]'int'[[RESET]][[Cyan:.\[0;36m]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:14[[RESET]], [[Yellow]]line:15:3[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:3[[RESET]], [[Yellow]]line:12:27[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:11:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 1[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]AttributedStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:12:5[[RESET]], [[Yellow]]col:27[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | |-[[RESET]][[BLUE]]FallThroughAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:7[[RESET]], [[Yellow]]col:14[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:27[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CaseStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:3[[RESET]], [[Yellow]]line:14:5[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[MAGENTA]]IntegerLiteral[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:13:8[[RESET]]> [[Green]]'int'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]][[CYAN]] 2[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[Blue]]<<>>[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]NullStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:14:5[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:8:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:4[[RESET]], [[Yellow]]col:11[[RESET]]> Text=" Comment"{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:1[[RESET]]> class[[CYAN]] Mutex[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[BLUE]]LockableAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:22[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXRecordDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]col:33[[RESET]]> class[[CYAN]] Mutex[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:20:3[[RESET]], [[Yellow]]col:7[[RESET]]>[[CYAN]] var1[[RESET]] [[Green]]'int'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:19:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:16[[RESET]]> Text=" A variable"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]FieldDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:24:3[[RESET]], [[Yellow]]col:7[[RESET]]>[[CYAN]] var2[[RESET]] [[Green]]'int'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]FullComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]line:23:44[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | |-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:21:6[[RESET]], [[Yellow]]col:22[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | | `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:22[[RESET]]> Text=" Another variable"{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]ParagraphComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:23:6[[RESET]], [[Yellow]]col:44[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[YELLOW]]TextComment[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:6[[RESET]], [[Yellow]]col:44[[RESET]]> Text=" Like the other variable, but different"{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (void)'[[RESET]] inline{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[MAGENTA]]CompoundStmt[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]]| |-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (const class Mutex &)'[[RESET]] inline{{$}} +//CHECK: {{^}}[[Blue]]| | `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Green]]'const class Mutex &'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]CXXConstructorDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]>[[CYAN]] Mutex[[RESET]] [[Green]]'void (class Mutex &&)'[[RESET]] inline{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[GREEN]]ParmVarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:33[[RESET]]> [[Green]]'class Mutex &&'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:1[[RESET]], [[Yellow]]line:25:3[[RESET]]>[[CYAN]] mu1[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:3[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]|-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:18:1[[RESET]], [[Yellow]]line:25:8[[RESET]]>[[CYAN]] mu2[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]| `-[[RESET]][[MAGENTA]]CXXConstructExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:8[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]][[RESET]][[Cyan]][[RESET]] [[Green]]'void (void)'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]]`-[[RESET]][[GREEN]]VarDecl[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]line:26:1[[RESET]], [[Yellow]]col:5[[RESET]]>[[CYAN]] TestExpr[[RESET]] [[Green]]'int'[[RESET]]{{$}} +//CHECK: {{^}}[[Blue]] `-[[RESET]][[BLUE]]GuardedByAttr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:29[[RESET]]>{{$}} +//CHECK: {{^}}[[Blue]] `-[[RESET]][[MAGENTA]]DeclRefExpr[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]] <[[Yellow]]col:40[[RESET]]> [[Green]]'class Mutex':'class Mutex'[[RESET]][[Cyan]] lvalue[[RESET]][[Cyan]][[RESET]] [[GREEN]]Var[[RESET]][[Yellow]] 0x{{[0-9a-fA-F]*}}[[RESET]][[CYAN]] 'mu1'[[RESET]] [[Green]]'class Mutex':'class Mutex'[[RESET]]{{$}} diff --git a/test/Misc/ast-dump-comment.cpp b/test/Misc/ast-dump-comment.cpp index 072348ca84..4e84af01a5 100644 --- a/test/Misc/ast-dump-comment.cpp +++ b/test/Misc/ast-dump-comment.cpp @@ -7,8 +7,8 @@ int TestLocation; /// int TestIndent; -// CHECK: {{^\(VarDecl.*TestIndent[^()]*$}} -// CHECK-NEXT: {{^ \(FullComment.*>\)\)$}} +// CHECK: {{^VarDecl.*TestIndent[^()]*$}} +// CHECK-NEXT: {{^`-FullComment.*>$}} /// Aaa int Test_TextComment; diff --git a/test/Misc/ast-dump-decl.c b/test/Misc/ast-dump-decl.c index 71b4578add..c74da29f6d 100644 --- a/test/Misc/ast-dump-decl.c +++ b/test/Misc/ast-dump-decl.c @@ -7,8 +7,8 @@ int TestLocation; struct TestIndent { int x; }; -// CHECK: {{^\(RecordDecl.*TestIndent[^()]*$}} -// CHECK-NEXT: {{^ \(FieldDecl.*x[^()]*\)\)$}} +// CHECK: {{^}}RecordDecl{{.*TestIndent[^()]*$}} +// CHECK-NEXT: {{^}}`-FieldDecl{{.*x[^()]*$}} struct TestChildren { int x; diff --git a/test/Misc/ast-dump-stmt.c b/test/Misc/ast-dump-stmt.c index 0df236edfc..1f21cf03f6 100644 --- a/test/Misc/ast-dump-stmt.c +++ b/test/Misc/ast-dump-stmt.c @@ -6,10 +6,10 @@ int TestLocation = 0; int TestIndent = 1 + (1); // CHECK: VarDecl{{.*}}TestIndent -// CHECK-NEXT: {{^ \(BinaryOperator[^()]*$}} -// CHECK-NEXT: {{^ \(IntegerLiteral.*0[^()]*\)$}} -// CHECK-NEXT: {{^ \(ParenExpr.*0[^()]*$}} -// CHECK-NEXT: {{^ \(IntegerLiteral.*0[^()]*\)\)\)\)$}} +// CHECK-NEXT: {{^}}`-BinaryOperator{{[^()]*$}} +// CHECK-NEXT: {{^}} |-IntegerLiteral{{.*0[^()]*$}} +// CHECK-NEXT: {{^}} `-ParenExpr{{.*0[^()]*$}} +// CHECK-NEXT: {{^}} `-IntegerLiteral{{.*0[^()]*$}} void TestDeclStmt() { int x = 0; diff --git a/test/Misc/ast-dump-wchar.cpp b/test/Misc/ast-dump-wchar.cpp index 1dca83c47b..9768bc8900 100644 --- a/test/Misc/ast-dump-wchar.cpp +++ b/test/Misc/ast-dump-wchar.cpp @@ -1,13 +1,13 @@ // RUN: %clang_cc1 -std=c++11 -ast-dump %s -triple x86_64-linux-gnu | FileCheck %s char c8[] = u8"test\0\\\"\t\a\b\234"; -// CHECK: (StringLiteral {{.*}} lvalue u8"test\000\\\"\t\a\b\234") +// CHECK: StringLiteral {{.*}} lvalue u8"test\000\\\"\t\a\b\234" char16_t c16[] = u"test\0\\\"\t\a\b\234\u1234"; -// CHECK: (StringLiteral {{.*}} lvalue u"test\000\\\"\t\a\b\234\u1234") +// CHECK: StringLiteral {{.*}} lvalue u"test\000\\\"\t\a\b\234\u1234" char32_t c32[] = U"test\0\\\"\t\a\b\234\u1234\U0010ffff"; // \ -// CHECK: (StringLiteral {{.*}} lvalue U"test\000\\\"\t\a\b\234\u1234\U0010FFFF") +// CHECK: StringLiteral {{.*}} lvalue U"test\000\\\"\t\a\b\234\u1234\U0010FFFF" wchar_t wc[] = L"test\0\\\"\t\a\b\234\u1234\xffffffff"; // \ -// CHECK: (StringLiteral {{.*}} lvalue L"test\000\\\"\t\a\b\234\x1234\xFFFFFFFF") +// CHECK: StringLiteral {{.*}} lvalue L"test\000\\\"\t\a\b\234\x1234\xFFFFFFFF" diff --git a/test/Sema/implicit-cast-dump.c b/test/Sema/implicit-cast-dump.c index f2e208dca6..87f15d0cf6 100644 --- a/test/Sema/implicit-cast-dump.c +++ b/test/Sema/implicit-cast-dump.c @@ -5,11 +5,11 @@ void foo2(void* const); void bar() { - // CHECK: (FunctionDecl {{.*}} bar 'void ()' + // CHECK: FunctionDecl {{.*}} bar 'void ()' foo1(0); - // CHECK: (ImplicitCastExpr {{.*}} 'void *' + // CHECK: ImplicitCastExpr {{.*}} 'void *' foo2(0); - // CHECK: (ImplicitCastExpr {{.*}} 'void *' + // CHECK: ImplicitCastExpr {{.*}} 'void *' } diff --git a/test/Tooling/clang-check-ast-dump.cpp b/test/Tooling/clang-check-ast-dump.cpp index 7425b7f875..d8643c7942 100644 --- a/test/Tooling/clang-check-ast-dump.cpp +++ b/test/Tooling/clang-check-ast-dump.cpp @@ -1,21 +1,21 @@ // RUN: clang-check -ast-dump "%s" -- 2>&1 | FileCheck %s -// CHECK: (NamespaceDecl{{.*}}test_namespace -// CHECK-NEXT: (CXXRecordDecl{{.*}}TheClass -// CHECK: (CXXMethodDecl{{.*}}theMethod -// CHECK-NEXT: (ParmVarDecl{{.*}}x -// CHECK-NEXT: (CompoundStmt -// CHECK-NEXT: (ReturnStmt -// CHECK-NEXT: (BinaryOperator +// CHECK: NamespaceDecl{{.*}}test_namespace +// CHECK-NEXT: CXXRecordDecl{{.*}}TheClass +// CHECK: CXXMethodDecl{{.*}}theMethod +// CHECK-NEXT: ParmVarDecl{{.*}}x +// CHECK-NEXT: CompoundStmt +// CHECK-NEXT: ReturnStmt +// CHECK-NEXT: BinaryOperator // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::theMethod "%s" -- 2>&1 | FileCheck -check-prefix CHECK-FILTER %s // CHECK-FILTER-NOT: NamespaceDecl // CHECK-FILTER-NOT: CXXRecordDecl // CHECK-FILTER: {{^}}Dumping test_namespace::TheClass::theMethod -// CHECK-FILTER-NEXT: {{^}}(CXXMethodDecl{{.*}}theMethod -// CHECK-FILTER-NEXT: (ParmVarDecl{{.*}}x -// CHECK-FILTER-NEXT: (CompoundStmt -// CHECK-FILTER-NEXT: (ReturnStmt -// CHECK-FILTER-NEXT: (BinaryOperator +// CHECK-FILTER-NEXT: {{^}}CXXMethodDecl{{.*}}theMethod +// CHECK-FILTER-NEXT: ParmVarDecl{{.*}}x +// CHECK-FILTER-NEXT: CompoundStmt +// CHECK-FILTER-NEXT: ReturnStmt +// CHECK-FILTER-NEXT: BinaryOperator // // RUN: clang-check -ast-print "%s" -- 2>&1 | FileCheck -check-prefix CHECK-PRINT %s // CHECK-PRINT: namespace test_namespace @@ -30,9 +30,9 @@ // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::TheClass::n "%s" -- 2>&1 | FileCheck -check-prefix CHECK-ATTR %s // CHECK-ATTR: test_namespace -// CHECK-ATTR-NEXT: (FieldDecl{{.*}}n -// CHECK-ATTR-NEXT: (AlignedAttr -// CHECK-ATTR-NEXT: (BinaryOperator +// CHECK-ATTR-NEXT: FieldDecl{{.*}}n +// CHECK-ATTR-NEXT: AlignedAttr +// CHECK-ATTR-NEXT: BinaryOperator // // RUN: clang-check -ast-dump -ast-dump-filter test_namespace::AfterNullNode "%s" -- 2>&1 | FileCheck -check-prefix CHECK-AFTER-NULL %s // CHECK-AFTER-NULL: class AfterNullNode diff --git a/utils/TableGen/ClangAttrEmitter.cpp b/utils/TableGen/ClangAttrEmitter.cpp index 97f4403f96..65a009c214 100644 --- a/utils/TableGen/ClangAttrEmitter.cpp +++ b/utils/TableGen/ClangAttrEmitter.cpp @@ -127,6 +127,7 @@ namespace { virtual void writeValue(raw_ostream &OS) const = 0; virtual void writeDump(raw_ostream &OS) const = 0; virtual void writeDumpChildren(raw_ostream &OS) const {} + virtual void writeHasChildren(raw_ostream &OS) const { OS << "false"; } }; class SimpleArgument : public Argument { @@ -384,12 +385,16 @@ namespace { void writeDump(raw_ostream &OS) const { } void writeDumpChildren(raw_ostream &OS) const { - OS << " if (SA->is" << getUpperName() << "Expr())\n"; + OS << " if (SA->is" << getUpperName() << "Expr()) {\n"; + OS << " lastChild();\n"; OS << " dumpStmt(SA->get" << getUpperName() << "Expr());\n"; - OS << " else\n"; + OS << " } else\n"; OS << " dumpType(SA->get" << getUpperName() << "Type()->getType());\n"; } + void writeHasChildren(raw_ostream &OS) const { + OS << "SA->is" << getUpperName() << "Expr()"; + } }; class VariadicArgument : public Argument { @@ -635,8 +640,10 @@ namespace { } void writeDumpChildren(raw_ostream &OS) const { + OS << " lastChild();\n"; OS << " dumpStmt(SA->get" << getUpperName() << "());\n"; } + void writeHasChildren(raw_ostream &OS) const { OS << "true"; } }; class VariadicExprArgument : public VariadicArgument { @@ -676,8 +683,16 @@ namespace { void writeDumpChildren(raw_ostream &OS) const { OS << " for (" << getAttrName() << "Attr::" << getLowerName() << "_iterator I = SA->" << getLowerName() << "_begin(), E = SA->" - << getLowerName() << "_end(); I != E; ++I)\n"; + << getLowerName() << "_end(); I != E; ++I) {\n"; + OS << " if (I + 1 == E)\n"; + OS << " lastChild();\n"; OS << " dumpStmt(*I);\n"; + OS << " }\n"; + } + + void writeHasChildren(raw_ostream &OS) const { + OS << "SA->" << getLowerName() << "_begin() != " + << "SA->" << getLowerName() << "_end()"; } }; } @@ -1386,9 +1401,27 @@ void EmitClangAttrDump(RecordKeeper &Records, raw_ostream &OS) { for (std::vector::iterator I = Args.begin(), E = Args.end(); I != E; ++I) createArgument(**I, R.getName())->writeDump(OS); + + // Code for detecting the last child. + OS << " bool OldMoreChildren = hasMoreChildren();\n"; + OS << " bool MoreChildren = OldMoreChildren;\n"; + for (std::vector::iterator I = Args.begin(), E = Args.end(); - I != E; ++I) + I != E; ++I) { + // More code for detecting the last child. + OS << " MoreChildren = OldMoreChildren"; + for (std::vector::iterator Next = I + 1; Next != E; ++Next) { + OS << " || "; + createArgument(**Next, R.getName())->writeHasChildren(OS); + } + OS << ";\n"; + OS << " setMoreChildren(MoreChildren);\n"; + createArgument(**I, R.getName())->writeDumpChildren(OS); + } + + // Reset the last child. + OS << " setMoreChildren(OldMoreChildren);\n"; } OS << " break;\n"