aboutsummaryrefslogtreecommitdiff
diff options
context:
space:
mode:
authorRichard Smith <richard-llvm@metafoo.co.uk>2013-02-07 01:35:44 +0000
committerRichard Smith <richard-llvm@metafoo.co.uk>2013-02-07 01:35:44 +0000
commit4a19052fe91c988885c722252ef03ce5f762a73c (patch)
treef3ee986f2db4ae2b77df427436365edfcb47bab6
parent005d51bc4f16a7b330e13082d186b72953bde581 (diff)
AST dumping: indicate the previous declaration for a redeclaration, and
indicate the semantic DC if it's not the lexical DC. In passing, correct the ascii-art child marker for a child of a FriendDecl. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@174570 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r--lib/AST/ASTDumper.cpp28
-rw-r--r--test/Misc/ast-dump-decl.cpp13
2 files changed, 40 insertions, 1 deletions
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 646cb16dd8..3f221a7cde 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -511,6 +511,27 @@ void ASTDumper::dumpAttr(const Attr *A) {
#include "clang/AST/AttrDump.inc"
}
+static Decl *getPreviousDeclImpl(...) {
+ return 0;
+}
+
+template<typename T>
+static const Decl *getPreviousDeclImpl(const Redeclarable<T> *D) {
+ return D->getPreviousDecl();
+}
+
+/// Get the previous declaration in the redeclaration chain for a declaration.
+static const Decl *getPreviousDecl(const Decl *D) {
+ switch (D->getKind()) {
+#define DECL(DERIVED, BASE) \
+ case Decl::DERIVED: \
+ return getPreviousDeclImpl(cast<DERIVED##Decl>(D));
+#define ABSTRACT_DECL(DECL)
+#include "clang/AST/DeclNodes.inc"
+ }
+ llvm_unreachable("Decl that isn't part of DeclNodes.inc!");
+}
+
//===----------------------------------------------------------------------===//
// C++ Utilities
//===----------------------------------------------------------------------===//
@@ -639,6 +660,10 @@ void ASTDumper::dumpDecl(const Decl *D) {
OS << D->getDeclKindName() << "Decl";
}
dumpPointer(D);
+ if (D->getLexicalDeclContext() != D->getDeclContext())
+ OS << " parent " << cast<Decl>(D->getDeclContext());
+ if (const Decl *Prev = getPreviousDecl(D))
+ OS << " prev " << Prev;
dumpSourceRange(D->getSourceRange());
bool HasAttrs = D->attr_begin() != D->attr_end();
@@ -664,7 +689,7 @@ void ASTDumper::dumpDecl(const Decl *D) {
setMoreChildren(false);
if (HasDeclContext)
- dumpDeclContext(dyn_cast<DeclContext>(D));
+ dumpDeclContext(cast<DeclContext>(D));
}
void ASTDumper::VisitLabelDecl(const LabelDecl *D) {
@@ -1049,6 +1074,7 @@ void ASTDumper::VisitAccessSpecDecl(const AccessSpecDecl *D) {
}
void ASTDumper::VisitFriendDecl(const FriendDecl *D) {
+ lastChild();
if (TypeSourceInfo *T = D->getFriendType())
dumpType(T->getType());
else
diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp
index ab847cac6f..d8072b727a 100644
--- a/test/Misc/ast-dump-decl.cpp
+++ b/test/Misc/ast-dump-decl.cpp
@@ -403,3 +403,16 @@ namespace TestFileScopeAsmDecl {
// CHECK: NamespaceDecl{{.*}} TestFileScopeAsmDecl{{$}}
// CHECK: FileScopeAsmDecl{{.*>$}}
// CHECK-NEXT: StringLiteral
+
+namespace TestFriendDecl2 {
+ void f();
+ struct S {
+ friend void f();
+ };
+}
+// CHECK: NamespaceDecl [[TestFriendDecl2:0x.*]] <{{.*}}> TestFriendDecl2
+// CHECK: |-FunctionDecl [[TestFriendDecl2_f:0x.*]] <{{.*}}> f 'void (void)'
+// CHECK: `-CXXRecordDecl {{.*}} struct S
+// CHECK: |-CXXRecordDecl {{.*}} struct S
+// CHECK: `-FriendDecl
+// CHECK: `-FunctionDecl {{.*}} parent [[TestFriendDecl2]] prev [[TestFriendDecl2_f]] <{{.*}}> f 'void (void)'