From: Anders Carlsson Date: Thu, 24 Sep 2009 18:54:49 +0000 (+0000) Subject: Add a -dump-record-layouts argument to clang-cc. X-Git-Url: https://granicus.if.org/sourcecode?a=commitdiff_plain;h=78762ebb9ad71d681110d4bada4b0575eaadfebe;p=clang Add a -dump-record-layouts argument to clang-cc. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82703 91177308-0d34-0410-b5e6-96231b3b80d8 --- diff --git a/clang.xcodeproj/project.pbxproj b/clang.xcodeproj/project.pbxproj index cf8bec0085..de2392fd10 100644 --- a/clang.xcodeproj/project.pbxproj +++ b/clang.xcodeproj/project.pbxproj @@ -342,7 +342,7 @@ 1A2193CC0F45EEB700C0713D /* Mangle.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = Mangle.cpp; path = lib/CodeGen/Mangle.cpp; sourceTree = ""; tabWidth = 2; }; 1A2193CD0F45EEB700C0713D /* Mangle.h */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.c.h; name = Mangle.h; path = lib/CodeGen/Mangle.h; sourceTree = ""; tabWidth = 2; }; 1A2A54A40FD1DD1C00F4CE45 /* AnalysisConsumer.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = AnalysisConsumer.cpp; path = lib/Frontend/AnalysisConsumer.cpp; sourceTree = ""; }; - 1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumers.cpp; path = lib/Frontend/ASTConsumers.cpp; sourceTree = ""; }; + 1A2A54A50FD1DD1C00F4CE45 /* ASTConsumers.cpp */ = {isa = PBXFileReference; fileEncoding = 4; indentWidth = 2; lastKnownFileType = sourcecode.cpp.cpp; name = ASTConsumers.cpp; path = lib/Frontend/ASTConsumers.cpp; sourceTree = ""; tabWidth = 2; }; 1A2A54A60FD1DD1C00F4CE45 /* Backend.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = Backend.cpp; path = lib/Frontend/Backend.cpp; sourceTree = ""; }; 1A2A54A70FD1DD1C00F4CE45 /* CacheTokens.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = CacheTokens.cpp; path = lib/Frontend/CacheTokens.cpp; sourceTree = ""; }; 1A2A54A80FD1DD1C00F4CE45 /* DependencyFile.cpp */ = {isa = PBXFileReference; fileEncoding = 4; lastKnownFileType = sourcecode.cpp.cpp; name = DependencyFile.cpp; path = lib/Frontend/DependencyFile.cpp; sourceTree = ""; }; diff --git a/include/clang/Frontend/ASTConsumers.h b/include/clang/Frontend/ASTConsumers.h index fc89e95cd7..f59a0a7d48 100644 --- a/include/clang/Frontend/ASTConsumers.h +++ b/include/clang/Frontend/ASTConsumers.h @@ -57,6 +57,10 @@ ASTConsumer *CreateASTViewer(); // to stderr; this is intended for debugging. ASTConsumer *CreateDeclContextPrinter(); +// RecordLayout dumper: prints out the record layout information for all records +// in the translation unit; this is intended for debugging. +ASTConsumer *CreateRecordLayoutDumper(); + // ObjC rewriter: attempts tp rewrite ObjC constructs into pure C code. // This is considered experimental, and only works with Apple's ObjC runtime. ASTConsumer *CreateObjCRewriter(const std::string &InFile, diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp index 3abd2b36e6..aec68f3e11 100644 --- a/lib/Frontend/ASTConsumers.cpp +++ b/lib/Frontend/ASTConsumers.cpp @@ -20,6 +20,7 @@ #include "clang/AST/AST.h" #include "clang/AST/ASTConsumer.h" #include "clang/AST/ASTContext.h" +#include "clang/AST/RecordLayout.h" #include "clang/AST/PrettyPrinter.h" #include "clang/CodeGen/ModuleBuilder.h" #include "llvm/Module.h" @@ -418,6 +419,55 @@ ASTConsumer *clang::CreateDeclContextPrinter() { return new DeclContextPrinter(); } +//===----------------------------------------------------------------------===// +/// RecordLayoutDumper - C++ Record Layout Dumping. +namespace { +class RecordLayoutDumper : public ASTConsumer { + llvm::raw_ostream& Out; + + // FIXME: Maybe this be useful in ASTContext.cpp. + void DumpRecordLayout(const CXXRecordDecl *RD, ASTContext &C) { + const ASTRecordLayout &Info = C.getASTRecordLayout(RD); + + Out << RD->getKindName() << ' ' << RD->getQualifiedNameAsString() << '\n'; + Out << " sizeof=" << Info.getSize() / 8; + Out << ", dsize=" << Info.getDataSize() / 8; + Out << ", align=" << Info.getAlignment() / 8 << '\n'; + Out << " nvsize=" << Info.getNonVirtualSize() / 8; + Out << ", nvalign=" << Info.getNonVirtualAlign() / 8 << '\n'; + Out << '\n'; + } + +public: + RecordLayoutDumper() : Out(llvm::errs()) {} + + void HandleTranslationUnit(ASTContext &C) { + for (ASTContext::type_iterator I = C.types_begin(), E = C.types_end(); + I != E; ++I) { + const RecordType *RT = dyn_cast(*I); + if (!RT) + continue; + + const CXXRecordDecl *RD = dyn_cast(RT->getDecl()); + if (!RD) + continue; + + if (RD->isImplicit()) + continue; + + // FIXME: Do we really need to hard code this? + if (RD->getQualifiedNameAsString() == "__va_list_tag") + continue; + + DumpRecordLayout(RD, C); + } + } +}; +} // end anonymous namespace +ASTConsumer *clang::CreateRecordLayoutDumper() { + return new RecordLayoutDumper(); +} + //===----------------------------------------------------------------------===// /// InheritanceViewer - C++ Inheritance Visualization diff --git a/tools/clang-cc/clang-cc.cpp b/tools/clang-cc/clang-cc.cpp index d6c536e0cc..6a92a28402 100644 --- a/tools/clang-cc/clang-cc.cpp +++ b/tools/clang-cc/clang-cc.cpp @@ -138,6 +138,7 @@ enum ProgActions { ASTDump, // Parse ASTs and dump them. ASTView, // Parse ASTs and view them in Graphviz. PrintDeclContext, // Print DeclContext and their Decls. + DumpRecordLayouts, // Dump record layout information. ParsePrintCallbacks, // Parse and print each callback. ParseSyntaxOnly, // Parse and perform semantic analysis. ParseNoop, // Parse with noop callbacks. @@ -183,6 +184,8 @@ ProgAction(llvm::cl::desc("Choose output type:"), llvm::cl::ZeroOrMore, "Build ASTs and view them with GraphViz"), clEnumValN(PrintDeclContext, "print-decl-contexts", "Print DeclContexts and their Decls"), + clEnumValN(DumpRecordLayouts, "dump-record-layouts", + "Dump record layout information"), clEnumValN(GeneratePTH, "emit-pth", "Generate pre-tokenized header file"), clEnumValN(GeneratePCH, "emit-pch", @@ -1774,6 +1777,9 @@ static ASTConsumer *CreateConsumerAction(Preprocessor &PP, case PrintDeclContext: return CreateDeclContextPrinter(); + case DumpRecordLayouts: + return CreateRecordLayoutDumper(); + case InheritanceView: return CreateInheritanceViewer(InheritanceViewCls);