diff options
author | Anders Carlsson <andersca@mac.com> | 2010-02-11 18:20:28 +0000 |
---|---|---|
committer | Anders Carlsson <andersca@mac.com> | 2010-02-11 18:20:28 +0000 |
commit | 848fa64143fbe5ae62a601ad61277f741e54dfab (patch) | |
tree | bc0dedaa6e2d1dba6c8d194763c36182530a83a9 /lib | |
parent | b203c9ee39be3170a7d545db057de8ea62959259 (diff) |
More vtable layout dumper improvements. Handle destructors, dump the complete function type of the member functions (using PredefinedExpr::ComputeName.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@95887 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'lib')
-rw-r--r-- | lib/AST/Expr.cpp | 9 | ||||
-rw-r--r-- | lib/CodeGen/CGExpr.cpp | 3 | ||||
-rw-r--r-- | lib/CodeGen/CGVtable.cpp | 73 | ||||
-rw-r--r-- | lib/Sema/SemaExpr.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaTemplateInstantiate.cpp | 3 |
5 files changed, 69 insertions, 22 deletions
diff --git a/lib/AST/Expr.cpp b/lib/AST/Expr.cpp index 1af4bf8773..73f6a2c915 100644 --- a/lib/AST/Expr.cpp +++ b/lib/AST/Expr.cpp @@ -163,17 +163,18 @@ SourceRange DeclRefExpr::getSourceRange() const { // FIXME: Maybe this should use DeclPrinter with a special "print predefined // expr" policy instead. -std::string PredefinedExpr::ComputeName(ASTContext &Context, IdentType IT, - const Decl *CurrentDecl) { +std::string PredefinedExpr::ComputeName(IdentType IT, const Decl *CurrentDecl) { + ASTContext &Context = CurrentDecl->getASTContext(); + if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(CurrentDecl)) { - if (IT != PrettyFunction) + if (IT != PrettyFunction && IT != PrettyFunctionNoVirtual) return FD->getNameAsString(); llvm::SmallString<256> Name; llvm::raw_svector_ostream Out(Name); if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) { - if (MD->isVirtual()) + if (MD->isVirtual() && IT != PrettyFunctionNoVirtual) Out << "virtual "; if (MD->isStatic()) Out << "static "; diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp index bb74f9b2f5..ad4fd63cbf 100644 --- a/lib/CodeGen/CGExpr.cpp +++ b/lib/CodeGen/CGExpr.cpp @@ -1185,8 +1185,7 @@ LValue CodeGenFunction::EmitPredefinedFunctionName(unsigned Type) { GlobalVarName += FnName; std::string FunctionName = - PredefinedExpr::ComputeName(getContext(), (PredefinedExpr::IdentType)Type, - CurCodeDecl); + PredefinedExpr::ComputeName((PredefinedExpr::IdentType)Type, CurCodeDecl); llvm::Constant *C = CGM.GetAddrOfConstantCString(FunctionName, GlobalVarName.c_str()); diff --git a/lib/CodeGen/CGVtable.cpp b/lib/CodeGen/CGVtable.cpp index d2b6c08712..93e2cb7fc6 100644 --- a/lib/CodeGen/CGVtable.cpp +++ b/lib/CodeGen/CGVtable.cpp @@ -32,7 +32,13 @@ public: CK_VBaseOffset, CK_OffsetToTop, CK_RTTI, - CK_VFunctionPointer + CK_FunctionPointer, + + /// CK_CompleteDtorPointer - A pointer to the complete destructor. + CK_CompleteDtorPointer, + + /// CK_DeletingDtorPointer - A pointer to the deleting destructor. + CK_DeletingDtorPointer }; /// dump - Dump the contents of this component to the given stream. @@ -48,12 +54,22 @@ public: static VtableComponent MakeFunction(const CXXMethodDecl *MD) { assert(!isa<CXXDestructorDecl>(MD) && - "Don't know how to handle dtors yet!"); + "Don't use MakeFunction with destructors!"); - return VtableComponent(CK_VFunctionPointer, + return VtableComponent(CK_FunctionPointer, reinterpret_cast<uintptr_t>(MD)); } + static VtableComponent MakeCompleteDtor(const CXXDestructorDecl *DD) { + return VtableComponent(CK_CompleteDtorPointer, + reinterpret_cast<uintptr_t>(DD)); + } + + static VtableComponent MakeDeletingDtor(const CXXDestructorDecl *DD) { + return VtableComponent(CK_DeletingDtorPointer, + reinterpret_cast<uintptr_t>(DD)); + } + /// getKind - Get the kind of this vtable component. Kind getKind() const { return (Kind)(Value & 0x7); @@ -72,11 +88,18 @@ public: } const CXXMethodDecl *getFunctionDecl() const { - assert(getKind() == CK_VFunctionPointer); + assert(getKind() == CK_FunctionPointer); return reinterpret_cast<CXXMethodDecl *>(getPointer()); } - + + const CXXDestructorDecl *getDestructorDecl() const { + assert((getKind() == CK_CompleteDtorPointer || + getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); + + return reinterpret_cast<CXXDestructorDecl *>(getPointer()); + } + private: VtableComponent(Kind ComponentKind, int64_t Offset) { assert((ComponentKind == CK_VCallOffset || @@ -89,7 +112,9 @@ private: VtableComponent(Kind ComponentKind, uintptr_t Ptr) { assert((ComponentKind == CK_RTTI || - ComponentKind == CK_VFunctionPointer) && + ComponentKind == CK_FunctionPointer || + ComponentKind == CK_CompleteDtorPointer || + ComponentKind == CK_DeletingDtorPointer) && "Invalid component kind!"); assert((Ptr & 7) == 0 && "Pointer not sufficiently aligned!"); @@ -105,9 +130,11 @@ private: } uintptr_t getPointer() const { - assert((getKind() == CK_RTTI || getKind() == CK_VFunctionPointer) && + assert((getKind() == CK_RTTI || + getKind() == CK_FunctionPointer || + getKind() == CK_CompleteDtorPointer || + getKind() == CK_DeletingDtorPointer) && "Invalid component kind!"); - return static_cast<uintptr_t>(Value & ~7ULL); } @@ -173,8 +200,14 @@ void VtableBuilder::layoutSimpleVtable(const CXXRecordDecl *RD) { if (!MD->isVirtual()) continue; - // Add the function. - Components.push_back(VtableComponent::MakeFunction(MD)); + if (const CXXDestructorDecl *DD = dyn_cast<CXXDestructorDecl>(MD)) { + // Add both the complete destructor and the deleting destructor. + Components.push_back(VtableComponent::MakeCompleteDtor(DD)); + Components.push_back(VtableComponent::MakeDeletingDtor(DD)); + } else { + // Add the function. + Components.push_back(VtableComponent::MakeFunction(MD)); + } } } @@ -229,11 +262,27 @@ void VtableBuilder::dumpLayout(llvm::raw_ostream& Out) { Out << Component.getRTTIDecl()->getQualifiedNameAsString() << " RTTI"; break; - case VtableComponent::CK_VFunctionPointer: { + case VtableComponent::CK_FunctionPointer: { const CXXMethodDecl *MD = Component.getFunctionDecl(); - Out << MD->getQualifiedNameAsString(); + std::string Str = + PredefinedExpr::ComputeName(PredefinedExpr::PrettyFunctionNoVirtual, + MD); + Out << Str; + break; + } + case VtableComponent::CK_CompleteDtorPointer: { + const CXXDestructorDecl *DD = Component.getDestructorDecl(); + + Out << DD->getQualifiedNameAsString() << "() [complete]"; + break; + } + + case VtableComponent::CK_DeletingDtorPointer: { + const CXXDestructorDecl *DD = Component.getDestructorDecl(); + + Out << DD->getQualifiedNameAsString() << "() [deleting]"; break; } diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp index 22856433f3..3ce3c28058 100644 --- a/lib/Sema/SemaExpr.cpp +++ b/lib/Sema/SemaExpr.cpp @@ -1653,8 +1653,7 @@ Sema::OwningExprResult Sema::ActOnPredefinedExpr(SourceLocation Loc, if (cast<DeclContext>(currentDecl)->isDependentContext()) { ResTy = Context.DependentTy; } else { - unsigned Length = - PredefinedExpr::ComputeName(Context, IT, currentDecl).length(); + unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length(); llvm::APInt LengthI(32, Length + 1); ResTy = Context.CharTy.withConst(); diff --git a/lib/Sema/SemaTemplateInstantiate.cpp b/lib/Sema/SemaTemplateInstantiate.cpp index 0dd7990f50..2d354575f0 100644 --- a/lib/Sema/SemaTemplateInstantiate.cpp +++ b/lib/Sema/SemaTemplateInstantiate.cpp @@ -687,8 +687,7 @@ TemplateInstantiator::TransformPredefinedExpr(PredefinedExpr *E) { PredefinedExpr::IdentType IT = E->getIdentType(); - unsigned Length = - PredefinedExpr::ComputeName(getSema().Context, IT, currentDecl).length(); + unsigned Length = PredefinedExpr::ComputeName(IT, currentDecl).length(); llvm::APInt LengthI(32, Length + 1); QualType ResTy = getSema().Context.CharTy.withConst(); |