From 9b66c4bbbe23accc8c3b3b8cbacf7f093870f68f Mon Sep 17 00:00:00 2001 From: John McCall Date: Wed, 24 Nov 2010 11:21:45 +0000 Subject: [PATCH] Add -cc1 -ast-dump-xml, an excessively detailed XML dump of the internals of the ASTs. Only available in assertions builds. No stability guarantee. This is intended solely as a debugging tool. I'm not sure if the goals are sufficiently aligned with the XML printer to allow a common implementation. Currently just falls back on the StmtDumper to display statements, which means it doesn't produce valid XML in those cases. llvm-svn: 120088 --- clang/include/clang/AST/DeclBase.h | 2 ++ clang/include/clang/Driver/CC1Options.td | 2 ++ clang/include/clang/Frontend/ASTConsumers.h | 4 ++++ .../include/clang/Frontend/FrontendActions.h | 6 ++++++ .../include/clang/Frontend/FrontendOptions.h | 1 + clang/lib/AST/CMakeLists.txt | 1 + clang/lib/Frontend/ASTConsumers.cpp | 20 +++++++++++++++++++ clang/lib/Frontend/CompilerInvocation.cpp | 3 +++ clang/lib/Frontend/FrontendActions.cpp | 11 ++++++++++ .../ExecuteCompilerInvocation.cpp | 1 + 10 files changed, 51 insertions(+) diff --git a/clang/include/clang/AST/DeclBase.h b/clang/include/clang/AST/DeclBase.h index cc4e41abfe1e..9d49c1e642cd 100644 --- a/clang/include/clang/AST/DeclBase.h +++ b/clang/include/clang/AST/DeclBase.h @@ -622,6 +622,8 @@ public: llvm::raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); void dump() const; + void dumpXML() const; + void dumpXML(llvm::raw_ostream &OS) const; private: const Attr *getAttrsImpl() const; diff --git a/clang/include/clang/Driver/CC1Options.td b/clang/include/clang/Driver/CC1Options.td index 87a768045492..03a4dd97eba2 100644 --- a/clang/include/clang/Driver/CC1Options.td +++ b/clang/include/clang/Driver/CC1Options.td @@ -330,6 +330,8 @@ def ast_print_xml : Flag<"-ast-print-xml">, HelpText<"Build ASTs and then print them in XML format">; def ast_dump : Flag<"-ast-dump">, HelpText<"Build ASTs and then debug dump them">; +def ast_dump_xml : Flag<"-ast-dump-xml">, + HelpText<"Build ASTs and then debug dump them in a verbose XML format">; def ast_view : Flag<"-ast-view">, HelpText<"Build ASTs and view them with GraphViz">; def boostcon : Flag<"-boostcon">, diff --git a/clang/include/clang/Frontend/ASTConsumers.h b/clang/include/clang/Frontend/ASTConsumers.h index cca243d6cd71..6757a27ed1f1 100644 --- a/clang/include/clang/Frontend/ASTConsumers.h +++ b/clang/include/clang/Frontend/ASTConsumers.h @@ -48,6 +48,10 @@ ASTConsumer *CreateASTPrinterXML(llvm::raw_ostream *OS); // intended for debugging. ASTConsumer *CreateASTDumper(); +// AST XML-dumper: dumps out the AST to stderr in a very detailed XML +// format; this is intended for particularly intense debugging. +ASTConsumer *CreateASTDumperXML(llvm::raw_ostream &OS); + // Graphical AST viewer: for each function definition, creates a graph of // the AST and displays it with the graph viewer "dotty". Also outputs // function declarations to stderr. diff --git a/clang/include/clang/Frontend/FrontendActions.h b/clang/include/clang/Frontend/FrontendActions.h index 7b8063ce549c..9e68a3c95814 100644 --- a/clang/include/clang/Frontend/FrontendActions.h +++ b/clang/include/clang/Frontend/FrontendActions.h @@ -54,6 +54,12 @@ protected: llvm::StringRef InFile); }; +class ASTDumpXMLAction : public ASTFrontendAction { +protected: + virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile); +}; + class ASTViewAction : public ASTFrontendAction { protected: virtual ASTConsumer *CreateASTConsumer(CompilerInstance &CI, diff --git a/clang/include/clang/Frontend/FrontendOptions.h b/clang/include/clang/Frontend/FrontendOptions.h index b68e9913a6c6..bf249d205e6d 100644 --- a/clang/include/clang/Frontend/FrontendOptions.h +++ b/clang/include/clang/Frontend/FrontendOptions.h @@ -21,6 +21,7 @@ namespace clang { namespace frontend { enum ActionKind { ASTDump, ///< Parse ASTs and dump them. + ASTDumpXML, ///< Parse ASTs and dump them in XML. ASTPrint, ///< Parse ASTs and print them. ASTPrintXML, ///< Parse ASTs and print them in XML. ASTView, ///< Parse ASTs and view them in Graphviz. diff --git a/clang/lib/AST/CMakeLists.txt b/clang/lib/AST/CMakeLists.txt index f56e6c41b098..6fca4d7e732d 100644 --- a/clang/lib/AST/CMakeLists.txt +++ b/clang/lib/AST/CMakeLists.txt @@ -19,6 +19,7 @@ add_clang_library(clangAST DeclObjC.cpp DeclPrinter.cpp DeclTemplate.cpp + DumpXML.cpp Expr.cpp ExprClassification.cpp ExprConstant.cpp diff --git a/clang/lib/Frontend/ASTConsumers.cpp b/clang/lib/Frontend/ASTConsumers.cpp index eb7f270ae8fb..5c7c02da9b0f 100644 --- a/clang/lib/Frontend/ASTConsumers.cpp +++ b/clang/lib/Frontend/ASTConsumers.cpp @@ -449,3 +449,23 @@ public: ASTConsumer *clang::CreateInheritanceViewer(const std::string& clsname) { return new InheritanceViewer(clsname); } + +//===----------------------------------------------------------------------===// +/// ASTDumperXML - In-depth XML dumping. + +namespace { +class ASTDumpXML : public ASTConsumer { + llvm::raw_ostream &OS; + +public: + ASTDumpXML(llvm::raw_ostream &OS) : OS(OS) {} + + void HandleTranslationUnit(ASTContext &C) { + C.getTranslationUnitDecl()->dumpXML(OS); + } +}; +} + +ASTConsumer *clang::CreateASTDumperXML(llvm::raw_ostream &OS) { + return new ASTDumpXML(OS); +} diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index a0280e52c72b..80643b2d4bee 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -319,6 +319,7 @@ static const char *getActionName(frontend::ActionKind Kind) { llvm_unreachable("Invalid kind!"); case frontend::ASTDump: return "-ast-dump"; + case frontend::ASTDumpXML: return "-ast-dump-xml"; case frontend::ASTPrint: return "-ast-print"; case frontend::ASTPrintXML: return "-ast-print-xml"; case frontend::ASTView: return "-ast-view"; @@ -1003,6 +1004,8 @@ static InputKind ParseFrontendArgs(FrontendOptions &Opts, ArgList &Args, assert(0 && "Invalid option in group!"); case OPT_ast_dump: Opts.ProgramAction = frontend::ASTDump; break; + case OPT_ast_dump_xml: + Opts.ProgramAction = frontend::ASTDumpXML; break; case OPT_ast_print: Opts.ProgramAction = frontend::ASTPrint; break; case OPT_ast_print_xml: diff --git a/clang/lib/Frontend/FrontendActions.cpp b/clang/lib/Frontend/FrontendActions.cpp index d18baaa7e1e6..0ffc06a47720 100644 --- a/clang/lib/Frontend/FrontendActions.cpp +++ b/clang/lib/Frontend/FrontendActions.cpp @@ -59,6 +59,17 @@ ASTConsumer *ASTDumpAction::CreateASTConsumer(CompilerInstance &CI, return CreateASTDumper(); } +ASTConsumer *ASTDumpXMLAction::CreateASTConsumer(CompilerInstance &CI, + llvm::StringRef InFile) { + llvm::raw_ostream *OS; + if (CI.getFrontendOpts().OutputFile.empty()) + OS = &llvm::outs(); + else + OS = CI.createDefaultOutputFile(false, InFile); + if (!OS) return 0; + return CreateASTDumperXML(*OS); +} + ASTConsumer *ASTViewAction::CreateASTConsumer(CompilerInstance &CI, llvm::StringRef InFile) { return CreateASTViewer(); diff --git a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp index 861117fb30a5..711cbb640064 100644 --- a/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp +++ b/clang/lib/FrontendTool/ExecuteCompilerInvocation.cpp @@ -35,6 +35,7 @@ static FrontendAction *CreateFrontendBaseAction(CompilerInstance &CI) { llvm_unreachable("Invalid program action!"); case ASTDump: return new ASTDumpAction(); + case ASTDumpXML: return new ASTDumpXMLAction(); case ASTPrint: return new ASTPrintAction(); case ASTPrintXML: return new ASTPrintXMLAction(); case ASTView: return new ASTViewAction();