Switch from \- to `- for the last child.
Removed parentheses.
Added a space at the beginning of the node.
http://llvm-reviews.chandlerc.com/D281
CHANGE SINCE LAST DIFF
http://llvm-reviews.chandlerc.com/D281?vs=693&id=752#toc
Files:
lib/AST/ASTDumper.cpp
test/CodeGen/bitfield-2.c
test/Tooling/clang-check-ast-dump.cpp
test/Sema/implicit-cast-dump.c
test/Misc/ast-dump-stmt.c
test/Misc/ast-dump-wchar.cpp
test/Misc/ast-dump-decl.c
test/Misc/ast-dump-attr.cpp
utils/TableGen/ClangAttrEmitter.cpp
Index: lib/AST/ASTDumper.cpp
===================================================================
--- lib/AST/ASTDumper.cpp
+++ lib/AST/ASTDumper.cpp
@@ -32,9 +32,20 @@
: public DeclVisitor<ASTDumper>, public StmtVisitor<ASTDumper> {
SourceManager *SM;
raw_ostream &OS;
- unsigned IndentLevel;
bool IsFirstLine;
+ // Indicates whether more child are expected at the current tree depth
+ enum IndentType { IT_Child, IT_LastChild };
+
+ /// Indents - Indents[i] indicates if another child exists at level i.
+ /// Used by Indent() to print the tree structure.
+ llvm::SmallVector<IndentType, 32> Indents;
+
+ /// MoreChildren - Indicates that more children will be needed at this
+ /// indent level. If true, prevents lastChild() from marking the node
+ /// as the last child.
+ 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;
@@ -42,18 +53,23 @@
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();
}
};
public:
ASTDumper(SourceManager *SM, raw_ostream &OS)
- : SM(SM), OS(OS), IndentLevel(0), IsFirstLine(true),
+ : SM(SM), OS(OS), IsFirstLine(true), MoreChildren(false),
LastLocFilename(""), LastLocLine(~0U) { }
~ASTDumper() {
@@ -63,9 +79,14 @@
void dumpDecl(Decl *D);
void dumpStmt(Stmt *S);
- // 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);
@@ -74,6 +95,7 @@
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);
@@ -195,21 +217,68 @@
// 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++;
+
+ for (llvm::SmallVector<IndentType, 32>::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");
+ }
+ }
+ OS << " ";
+ 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) {
OS << ' ' << Ptr;
}
@@ -303,12 +372,24 @@
OS << ' ' << ND->getNameAsString();
}
+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) {
@@ -367,8 +448,11 @@
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) {
@@ -392,10 +476,12 @@
break;
case TemplateArgument::Type:
OS << " type";
+ lastChild();
dumpType(A.getAsType());
break;
case TemplateArgument::Declaration:
OS << " decl";
+ lastChild();
dumpDeclRef(A.getAsDecl());
break;
case TemplateArgument::NullPtr:
@@ -414,13 +500,17 @@
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;
}
}
@@ -431,7 +521,6 @@
void ASTDumper::dumpDecl(Decl *D) {
IndentScope Indent(*this);
-
if (!D) {
OS << "<<<NULL>>>";
return;
@@ -440,14 +529,26 @@
OS << D->getDeclKindName() << "Decl";
dumpPointer(D);
dumpSourceRange(D->getSourceRange());
+
+ bool HasAttrs = D->hasAttrs() && D->getAttrs().begin() != D->getAttrs().end();
+ bool HasDeclContext = !isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D) &&
+ hasNodes(dyn_cast<DeclContext>(D));
+
+ setMoreChildren(HasAttrs || HasDeclContext);
DeclVisitor<ASTDumper>::Visit(D);
- if (D->hasAttrs()) {
+
+ setMoreChildren(HasDeclContext);
+ if (HasAttrs) {
for (AttrVec::const_iterator I = D->getAttrs().begin(),
- E = D->getAttrs().end(); I != E; ++I)
+ E = D->getAttrs().end(); I != E; ++I) {
+ if (I + 1 == E)
+ lastChild();
dumpAttr(*I);
+ }
}
// Decls within functions are visited by the body
- if (!isa<FunctionDecl>(*D) && !isa<ObjCMethodDecl>(*D))
+ setMoreChildren(false);
+ if (HasDeclContext)
dumpDeclContext(dyn_cast<DeclContext>(D));
}
@@ -486,16 +587,21 @@
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) {
@@ -517,26 +623,60 @@
else if (D->isDeletedAsWritten())
OS << " delete";
- if (const FunctionTemplateSpecializationInfo *FTSI =
- D->getTemplateSpecializationInfo())
+ 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<CXXConstructorDecl>(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 (llvm::ArrayRef<NamedDecl*>::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<CXXConstructorDecl>(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) {
@@ -546,10 +686,22 @@
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) {
@@ -564,11 +716,14 @@
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());
}
@@ -628,6 +783,7 @@
void ASTDumper::VisitStaticAssertDecl(StaticAssertDecl *D) {
dumpStmt(D->getAssertExpr());
+ lastChild();
dumpStmt(D->getMessage());
}
@@ -637,6 +793,10 @@
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:
@@ -654,9 +814,16 @@
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:
@@ -801,66 +968,99 @@
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());
}
@@ -895,10 +1095,15 @@
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");
+ }
}
}
@@ -909,6 +1114,7 @@
else
OS << " dynamic";
dumpDeclRef(D->getPropertyDecl());
+ lastChild();
dumpDeclRef(D->getPropertyIvarDecl());
}
@@ -941,7 +1147,7 @@
if (I->hasCopyExpr())
dumpStmt(I->getCopyExpr());
}
-
+ lastChild();
dumpStmt(D->getBody());
}
@@ -962,9 +1168,16 @@
return;
}
+ setMoreChildren(S->children());
StmtVisitor<ASTDumper>::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) {
@@ -976,15 +1189,21 @@
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<const Attr*>::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) {
@@ -1193,6 +1412,7 @@
void ASTDumper::VisitOpaqueValueExpr(OpaqueValueExpr *Node) {
VisitExpr(Node);
+ lastChild();
if (Expr *Source = Node->getSourceExpr())
dumpStmt(Source);
}
Index: test/CodeGen/bitfield-2.c
===================================================================
--- test/CodeGen/bitfield-2.c
+++ 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: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s0 = type <{ [3 x i8] }>
// CHECK-RECORD: IsZeroInitializable:1
@@ -49,7 +49,7 @@
// PR5591
// CHECK-RECORD: *** Dumping IRgen Record Layout
-// CHECK-RECORD: Record: (RecordDecl{{.*}}s1
+// CHECK-RECORD: Record: RecordDecl{{.*}}s1
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s1 = type <{ [3 x i8] }>
// CHECK-RECORD: IsZeroInitializable:1
@@ -97,7 +97,7 @@
// PR5567
// CHECK-RECORD: *** Dumping IRgen Record Layout
-// CHECK-RECORD: Record: (RecordDecl{{.*}}u2
+// CHECK-RECORD: Record: RecordDecl{{.*}}u2
// CHECK-RECORD: Layout: <CGRecordLayout
// CHECK-RECORD: LLVMType:%union.u2 = type <{ i8 }>
// CHECK-RECORD: IsZeroInitializable:1
@@ -269,7 +269,7 @@
// 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: <CGRecordLayout
// CHECK-RECORD: LLVMType:%struct.s7 = type { i32, i32, i32, i8, [3 x i8], [4 x i8], [12 x i8] }
// CHECK-RECORD: IsZeroInitializable:1
Index: test/Tooling/clang-check-ast-dump.cpp
===================================================================
--- test/Tooling/clang-check-ast-dump.cpp
+++ 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
Index: test/Sema/implicit-cast-dump.c
===================================================================
--- test/Sema/implicit-cast-dump.c
+++ test/Sema/implicit-cast-dump.c
@@ -5,11 +5,11 @@
void bar() {
- // CHECK: (FunctionDecl {{.*}} <line:{{.*}}, line:{{.*}}> bar 'void ()'
+ // CHECK: FunctionDecl {{.*}} <line:{{.*}}, line:{{.*}}> bar 'void ()'
foo1(0);
- // CHECK: (ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer>
+ // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer>
foo2(0);
- // CHECK: (ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer>
+ // CHECK: ImplicitCastExpr {{.*}} <col:{{.*}}> 'void *' <NullToPointer>
}
Index: test/Misc/ast-dump-stmt.c
===================================================================
--- test/Misc/ast-dump-stmt.c
+++ test/Misc/ast-dump-stmt.c
@@ -6,10 +6,10 @@
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;
Index: test/Misc/ast-dump-wchar.cpp
===================================================================
--- test/Misc/ast-dump-wchar.cpp
+++ 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"
Index: test/Misc/ast-dump-decl.c
===================================================================
--- test/Misc/ast-dump-decl.c
+++ test/Misc/ast-dump-decl.c
@@ -7,8 +7,8 @@
struct TestIndent {
int x;
};
-// CHECK: {{^\(RecordDecl.*TestIndent[^()]*$}}
-// CHECK-NEXT: {{^ \(FieldDecl.*x[^()]*\)\)$}}
+// CHECK: {{^}} RecordDecl{{.*TestIndent[^()]*$}}
+// CHECK-NEXT: {{^}}`- FieldDecl{{.*x[^()]*$}}
struct TestChildren {
int x;
Index: test/Misc/ast-dump-attr.cpp
===================================================================
--- test/Misc/ast-dump-attr.cpp
+++ test/Misc/ast-dump-attr.cpp
@@ -7,8 +7,8 @@
int TestIndent
__attribute__((unused));
-// CHECK: {{^\(VarDecl.*TestIndent[^()]*$}}
-// CHECK-NEXT: {{^ \(UnusedAttr[^()]*\)\)$}}
+// CHECK: {{^}} VarDecl{{.*TestIndent[^()]*$}}
+// CHECK-NEXT: {{^}}`- UnusedAttr{{[^()]*$}}
void TestAttributedStmt() {
switch (1) {
Index: utils/TableGen/ClangAttrEmitter.cpp
===================================================================
--- utils/TableGen/ClangAttrEmitter.cpp
+++ utils/TableGen/ClangAttrEmitter.cpp
@@ -127,6 +127,7 @@
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 @@
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 @@
}
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,9 +683,17 @@
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()";
+ }
};
}
@@ -1256,9 +1271,27 @@
for (std::vector<Record*>::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<Record*>::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<Record*>::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"
_______________________________________________
cfe-commits mailing list
[email protected]
http://lists.cs.uiuc.edu/mailman/listinfo/cfe-commits