summaryrefslogtreecommitdiff
path: root/lib/Frontend/ASTConsumers.cpp
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-09-24 23:50:42 +0000
committerAnders Carlsson <andersca@mac.com>2009-09-24 23:50:42 +0000
commit8fdccd95fcc98956cddd9f10b4d72b0c01bf3eac (patch)
treec374b34f5691cd447f757f335089542451a53d0c /lib/Frontend/ASTConsumers.cpp
parent7dfd0fb08300b60a9657748bda7d8b3ceb07babe (diff)
downloadclang-8fdccd95fcc98956cddd9f10b4d72b0c01bf3eac.tar.gz
Improve the record layout dumper.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@82733 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib/Frontend/ASTConsumers.cpp')
-rw-r--r--lib/Frontend/ASTConsumers.cpp89
1 files changed, 87 insertions, 2 deletions
diff --git a/lib/Frontend/ASTConsumers.cpp b/lib/Frontend/ASTConsumers.cpp
index aec68f3e11..5ef5c0e6f0 100644
--- a/lib/Frontend/ASTConsumers.cpp
+++ b/lib/Frontend/ASTConsumers.cpp
@@ -24,6 +24,7 @@
#include "clang/AST/PrettyPrinter.h"
#include "clang/CodeGen/ModuleBuilder.h"
#include "llvm/Module.h"
+#include "llvm/Support/Format.h"
#include "llvm/Support/Timer.h"
#include "llvm/Support/raw_ostream.h"
#include "llvm/System/Path.h"
@@ -425,11 +426,95 @@ namespace {
class RecordLayoutDumper : public ASTConsumer {
llvm::raw_ostream& Out;
- // FIXME: Maybe this be useful in ASTContext.cpp.
+ void PrintOffset(uint64_t Offset, unsigned IndentLevel) {
+ Out << llvm::format("%4d | ", Offset);
+ for (unsigned I = 0; I < IndentLevel * 2; ++I) Out << ' ';
+ }
+
+ void DumpRecordLayoutOffsets(const CXXRecordDecl *RD, ASTContext &C,
+ uint64_t Offset,
+ unsigned IndentLevel, const char* Description,
+ bool IncludeVirtualBases) {
+ const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
+
+ PrintOffset(Offset, IndentLevel);
+ Out << C.getTypeDeclType((CXXRecordDecl *)RD).getAsString();
+ if (Description)
+ Out << ' ' << Description;
+ if (RD->isEmpty())
+ Out << " (empty)";
+ Out << '\n';
+
+ IndentLevel++;
+
+ const CXXRecordDecl *PrimaryBase = Info.getPrimaryBase();
+
+ // Vtable pointer.
+ if (RD->isDynamicClass() && !PrimaryBase) {
+ PrintOffset(Offset, IndentLevel);
+ Out << '(' << RD->getNameAsString() << " vtable pointer)\n";
+ }
+ // Dump (non-virtual) bases
+ for (CXXRecordDecl::base_class_const_iterator I = RD->bases_begin(),
+ E = RD->bases_end(); I != E; ++I) {
+ if (I->isVirtual())
+ continue;
+
+ const CXXRecordDecl *Base =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ uint64_t BaseOffset = Offset + Info.getBaseClassOffset(Base) / 8;
+
+ DumpRecordLayoutOffsets(Base, C, BaseOffset, IndentLevel,
+ Base == PrimaryBase ? "(primary base)" : "(base)",
+ /*IncludeVirtualBases=*/false);
+ }
+
+ // Dump fields.
+ uint64_t FieldNo = 0;
+ for (CXXRecordDecl::field_iterator I = RD->field_begin(),
+ E = RD->field_end(); I != E; ++I, ++FieldNo) {
+ const FieldDecl *Field = *I;
+ uint64_t FieldOffset = Offset + Info.getFieldOffset(FieldNo) / 8;
+
+ if (const RecordType *RT = Field->getType()->getAs<RecordType>()) {
+ if (const CXXRecordDecl *D = dyn_cast<CXXRecordDecl>(RT->getDecl())) {
+ DumpRecordLayoutOffsets(D, C, FieldOffset, IndentLevel,
+ Field->getNameAsCString(),
+ /*IncludeVirtualBases=*/true);
+ continue;
+ }
+ }
+
+ PrintOffset(FieldOffset, IndentLevel);
+ Out << Field->getType().getAsString() << ' ';
+ Out << Field->getNameAsString() << '\n';
+ }
+
+ if (!IncludeVirtualBases)
+ return;
+
+ // Dump virtual bases.
+ for (CXXRecordDecl::base_class_const_iterator I = RD->vbases_begin(),
+ E = RD->vbases_end(); I != E; ++I) {
+ assert(I->isVirtual() && "Found non-virtual class!");
+ const CXXRecordDecl *VBase =
+ cast<CXXRecordDecl>(I->getType()->getAs<RecordType>()->getDecl());
+
+ uint64_t VBaseOffset = Offset + Info.getVBaseClassOffset(VBase) / 8;
+ DumpRecordLayoutOffsets(VBase, C, VBaseOffset, IndentLevel,
+ VBase == PrimaryBase ?
+ "(primary virtual base)" : "(virtual base)",
+ /*IncludeVirtualBases=*/false);
+ }
+ }
+
+ // FIXME: Maybe this could be useful in ASTContext.cpp.
void DumpRecordLayout(const CXXRecordDecl *RD, ASTContext &C) {
const ASTRecordLayout &Info = C.getASTRecordLayout(RD);
- Out << RD->getKindName() << ' ' << RD->getQualifiedNameAsString() << '\n';
+ DumpRecordLayoutOffsets(RD, C, 0, 0, 0,
+ /*IncludeVirtualBases=*/true);
Out << " sizeof=" << Info.getSize() / 8;
Out << ", dsize=" << Info.getDataSize() / 8;
Out << ", align=" << Info.getAlignment() / 8 << '\n';