[cfe-commits] r62136 - in /cfe/trunk/Driver: ASTConsumers.cpp ASTConsumers.h clang.cpp
Zhongxing Xu
xuzhongxing at gmail.com
Mon Jan 12 17:29:25 PST 2009
Author: zhongxingxu
Date: Mon Jan 12 19:29:24 2009
New Revision: 62136
URL: http://llvm.org/viewvc/llvm-project?rev=62136&view=rev
Log:
Add an initial framework of a DeclContextPrinter. It can print DeclContext and
its Decls in indented format. An Example:
$ cat t.cpp
class A {
int a;
void f();
};
void A::f() {
a = 3;
}
$ clang -print-decl-contexts t.cpp
[translation unit] 0x9754d7c
<typedef> __builtin_va_list
[class] A 0x9753310
<class> A 0x975ce20
<field> a
<c++ method> f
<c++ ctor> A
<c++ ctor> A
<c++ method> operator=
<c++ dtor> ~A
[c++ method] f [[0x9753310]]
Some comments: '<>' indicates a declaration, '[]' indicates a definition, '[[
]]' displays the semantic DeclContext which is different from the lexical
DeclContext. The symbols printed can definitely be changed in the future.
Modified:
cfe/trunk/Driver/ASTConsumers.cpp
cfe/trunk/Driver/ASTConsumers.h
cfe/trunk/Driver/clang.cpp
Modified: cfe/trunk/Driver/ASTConsumers.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.cpp?rev=62136&r1=62135&r2=62136&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTConsumers.cpp (original)
+++ cfe/trunk/Driver/ASTConsumers.cpp Mon Jan 12 19:29:24 2009
@@ -555,6 +555,225 @@
ASTConsumer *clang::CreateASTViewer() { return new ASTViewer(); }
//===----------------------------------------------------------------------===//
+/// DeclContextPrinter - Decl and DeclContext Visualization
+
+namespace {
+
+class DeclContextPrinter : public ASTConsumer {
+ llvm::raw_ostream& Out;
+public:
+ DeclContextPrinter() : Out(llvm::errs()) {}
+
+ void HandleTranslationUnit(TranslationUnit& TU) {
+ TranslationUnitDecl* TUD = TU.getContext().getTranslationUnitDecl();
+ PrintDeclContext(TUD, 4);
+ }
+
+ void PrintDeclContext(const DeclContext* DC, unsigned Indentation);
+};
+
+void DeclContextPrinter::PrintDeclContext(const DeclContext* DC,
+ unsigned Indentation) {
+ // Print DeclContext name.
+ Decl::Kind DK = DeclContext::KindTrait<DeclContext>::getKind(DC);
+ switch (DK) {
+ case Decl::TranslationUnit:
+ Out << "[translation unit] " << DC;
+ break;
+ case Decl::Namespace: {
+ Out << "[namespace] ";
+ NamespaceDecl* ND = NamespaceDecl::castFromDeclContext(DC);
+ Out << ND->getNameAsString();
+ break;
+ }
+ case Decl::Enum:
+ Out << "[enum]";
+ break;
+ case Decl::Record: {
+ RecordDecl* RD = RecordDecl::castFromDeclContext(DC);
+ if (RD->isDefinition())
+ Out << "[struct] ";
+ else
+ Out << "<struct> ";
+ Out << RD->getNameAsString();
+ break;
+ }
+ case Decl::CXXRecord: {
+ CXXRecordDecl* RD = CXXRecordDecl::castFromDeclContext(DC);
+ if (RD->isDefinition())
+ Out << "[class] ";
+ else
+ Out << "<class> ";
+ Out << RD->getNameAsString() << " " << DC;
+ break;
+ }
+ case Decl::ObjCMethod:
+ Out << "[objc method]";
+ break;
+ case Decl::ObjCInterface:
+ Out << "[objc interface]";
+ break;
+ case Decl::ObjCCategory:
+ Out << "[objc category]";
+ break;
+ case Decl::ObjCProtocol:
+ Out << "[objc protocol]";
+ break;
+ case Decl::ObjCImplementation:
+ Out << "[objc implementation]";
+ break;
+ case Decl::ObjCCategoryImpl:
+ Out << "[objc categoryimpl]";
+ break;
+ case Decl::LinkageSpec:
+ Out << "[linkage spec]";
+ break;
+ case Decl::Block:
+ Out << "[block]";
+ break;
+ case Decl::Function: {
+ FunctionDecl* FD = FunctionDecl::castFromDeclContext(DC);
+ if (FD->isThisDeclarationADefinition())
+ Out << "[function] ";
+ else
+ Out << "<function> ";
+ Out << FD->getNameAsString();
+ break;
+ }
+ case Decl::CXXMethod: {
+ CXXMethodDecl* CMD = CXXMethodDecl::castFromDeclContext(DC);
+ if (CMD->isOutOfLineDefinition())
+ Out << "[c++ method] ";
+ else
+ Out << "<c++ method> ";
+ Out << CMD->getNameAsString();
+
+ // Check the semantic DeclContext.
+ DeclContext* SemaDC = CMD->getDeclContext();
+ DeclContext* LexicalDC = CMD->getLexicalDeclContext();
+ if (SemaDC != LexicalDC) {
+ Out << " [[" << SemaDC << "]]";
+ }
+ break;
+ }
+ case Decl::CXXConstructor: {
+ CXXConstructorDecl* CMD = CXXConstructorDecl::castFromDeclContext(DC);
+ if (CMD->isOutOfLineDefinition())
+ Out << "[c++ ctor] ";
+ else
+ Out << "<c++ ctor> ";
+ Out << CMD->getNameAsString();
+ break;
+ }
+ case Decl::CXXDestructor: {
+ CXXDestructorDecl* CMD = CXXDestructorDecl::castFromDeclContext(DC);
+ if (CMD->isOutOfLineDefinition())
+ Out << "[c++ dtor] ";
+ else
+ Out << "<c++ dtor> ";
+ Out << CMD->getNameAsString();
+ break;
+ }
+ case Decl::CXXConversion: {
+ CXXConversionDecl* CMD = CXXConversionDecl::castFromDeclContext(DC);
+ if (CMD->isOutOfLineDefinition())
+ Out << "[c++ conversion] ";
+ else
+ Out << "<c++ conversion> ";
+ Out << CMD->getNameAsString();
+ break;
+ }
+
+ default:
+ assert(0 && "a decl that inherits DeclContext isn't handled");
+ }
+
+ Out << "\n";
+
+ // Print decls in the DeclContext.
+ for (DeclContext::decl_iterator I = DC->decls_begin(), E = DC->decls_end();
+ I != E; ++I) {
+ for (unsigned i = 0; i < Indentation; ++i)
+ Out << " ";
+
+ Decl::Kind DK = I->getKind();
+ switch (DK) {
+ case Decl::Namespace:
+ case Decl::Enum:
+ case Decl::Record:
+ case Decl::CXXRecord:
+ case Decl::ObjCMethod:
+ case Decl::ObjCInterface:
+ case Decl::ObjCCategory:
+ case Decl::ObjCProtocol:
+ case Decl::ObjCImplementation:
+ case Decl::ObjCCategoryImpl:
+ case Decl::LinkageSpec:
+ case Decl::Block:
+ case Decl::Function:
+ case Decl::CXXMethod:
+ case Decl::CXXConstructor:
+ case Decl::CXXDestructor:
+ case Decl::CXXConversion:
+ {
+ DeclContext* DC = Decl::castToDeclContext(*I);
+ PrintDeclContext(DC, Indentation+4);
+ break;
+ }
+ case Decl::Field: {
+ FieldDecl* FD = cast<FieldDecl>(*I);
+ Out << "<field> " << FD->getNameAsString() << "\n";
+ break;
+ }
+ case Decl::Typedef: {
+ TypedefDecl* TD = cast<TypedefDecl>(*I);
+ Out << "<typedef> " << TD->getNameAsString() << "\n";
+ break;
+ }
+ case Decl::EnumConstant: {
+ EnumConstantDecl* ECD = cast<EnumConstantDecl>(*I);
+ Out << "<enum constant> " << ECD->getNameAsString() << "\n";
+ break;
+ }
+ case Decl::Var: {
+ VarDecl* VD = cast<VarDecl>(*I);
+ Out << "<var> " << VD->getNameAsString() << "\n";
+ break;
+ }
+ case Decl::ImplicitParam: {
+ ImplicitParamDecl* IPD = cast<ImplicitParamDecl>(*I);
+ Out << "<implicit parameter> " << IPD->getNameAsString() << "\n";
+ break;
+ }
+ case Decl::CXXClassVar: {
+ CXXClassVarDecl* CVD = cast<CXXClassVarDecl>(*I);
+ Out << "<static member var> " << CVD->getNameAsString() << "\n";
+ break;
+ }
+ case Decl::ParmVar: {
+ ParmVarDecl* PVD = cast<ParmVarDecl>(*I);
+ Out << "<parameter> " << PVD->getNameAsString() << "\n";
+ break;
+ }
+ case Decl::ObjCProperty: {
+ ObjCPropertyDecl* OPD = cast<ObjCPropertyDecl>(*I);
+ Out << "<objc property> " << OPD->getNameAsString() << "\n";
+ break;
+ }
+ default:
+ fprintf(stderr, "DeclKind: %d\n", DK);
+ assert(0 && "decl unhandled");
+ }
+ }
+}
+
+}
+
+ASTConsumer *clang::CreateDeclContextPrinter() {
+ return new DeclContextPrinter();
+}
+
+//===----------------------------------------------------------------------===//
/// InheritanceViewer - C++ Inheritance Visualization
namespace {
Modified: cfe/trunk/Driver/ASTConsumers.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/ASTConsumers.h?rev=62136&r1=62135&r2=62136&view=diff
==============================================================================
--- cfe/trunk/Driver/ASTConsumers.h (original)
+++ cfe/trunk/Driver/ASTConsumers.h Mon Jan 12 19:29:24 2009
@@ -38,6 +38,8 @@
ASTConsumer *CreateASTViewer();
+ASTConsumer *CreateDeclContextPrinter();
+
ASTConsumer *CreateCodeRewriterTest(const std::string& InFile,
const std::string& OutFile,
Diagnostic &Diags,
Modified: cfe/trunk/Driver/clang.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/Driver/clang.cpp?rev=62136&r1=62135&r2=62136&view=diff
==============================================================================
--- cfe/trunk/Driver/clang.cpp (original)
+++ cfe/trunk/Driver/clang.cpp Mon Jan 12 19:29:24 2009
@@ -83,6 +83,7 @@
ASTPrint, // Parse ASTs and print them.
ASTDump, // Parse ASTs and dump them.
ASTView, // Parse ASTs and view them in Graphviz.
+ PrintDeclContext, // Print DeclContext and their Decls.
TestSerialization, // Run experimental serialization code.
ParsePrintCallbacks, // Parse and print each callback.
ParseSyntaxOnly, // Parse and perform semantic analysis.
@@ -122,6 +123,8 @@
"Build ASTs and then debug dump them"),
clEnumValN(ASTView, "ast-view",
"Build ASTs and view them with GraphViz"),
+ clEnumValN(PrintDeclContext, "print-decl-contexts",
+ "Print DeclContexts and their Decls."),
clEnumValN(TestSerialization, "test-pickling",
"Run prototype serialization code"),
clEnumValN(EmitAssembly, "S",
@@ -1245,6 +1248,9 @@
case ASTView:
return CreateASTViewer();
+
+ case PrintDeclContext:
+ return CreateDeclContextPrinter();
case EmitHTML:
return CreateHTMLPrinter(OutputFile, Diag, PP, PPF);
More information about the cfe-commits
mailing list