[cfe-commits] r95887 - in /cfe/trunk: include/clang/AST/Expr.h lib/AST/Expr.cpp lib/CodeGen/CGExpr.cpp lib/CodeGen/CGVtable.cpp lib/Sema/SemaExpr.cpp lib/Sema/SemaTemplateInstantiate.cpp test/CodeGenCXX/vtable-layout.cpp
Anders Carlsson
andersca at mac.com
Thu Feb 11 10:20:29 PST 2010
Author: andersca
Date: Thu Feb 11 12:20:28 2010
New Revision: 95887
URL: http://llvm.org/viewvc/llvm-project?rev=95887&view=rev
Log:
More vtable layout dumper improvements. Handle destructors, dump the complete function type of the member functions (using PredefinedExpr::ComputeName.
Modified:
cfe/trunk/include/clang/AST/Expr.h
cfe/trunk/lib/AST/Expr.cpp
cfe/trunk/lib/CodeGen/CGExpr.cpp
cfe/trunk/lib/CodeGen/CGVtable.cpp
cfe/trunk/lib/Sema/SemaExpr.cpp
cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
Modified: cfe/trunk/include/clang/AST/Expr.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/Expr.h?rev=95887&r1=95886&r2=95887&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/Expr.h (original)
+++ cfe/trunk/include/clang/AST/Expr.h Thu Feb 11 12:20:28 2010
@@ -568,7 +568,10 @@
enum IdentType {
Func,
Function,
- PrettyFunction
+ PrettyFunction,
+ /// PrettyFunctionNoVirtual - The same as PrettyFunction, except that the
+ /// 'virtual' keyword is omitted for virtual member functions.
+ PrettyFunctionNoVirtual
};
private:
@@ -589,8 +592,7 @@
SourceLocation getLocation() const { return Loc; }
void setLocation(SourceLocation L) { Loc = L; }
- static std::string ComputeName(ASTContext &Context, IdentType IT,
- const Decl *CurrentDecl);
+ static std::string ComputeName(IdentType IT, const Decl *CurrentDecl);
virtual SourceRange getSourceRange() const { return SourceRange(Loc); }
Modified: cfe/trunk/lib/AST/Expr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/Expr.cpp?rev=95887&r1=95886&r2=95887&view=diff
==============================================================================
--- cfe/trunk/lib/AST/Expr.cpp (original)
+++ cfe/trunk/lib/AST/Expr.cpp Thu Feb 11 12:20:28 2010
@@ -163,17 +163,18 @@
// 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 ";
Modified: cfe/trunk/lib/CodeGen/CGExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGExpr.cpp?rev=95887&r1=95886&r2=95887&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGExpr.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGExpr.cpp Thu Feb 11 12:20:28 2010
@@ -1185,8 +1185,7 @@
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());
Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=95887&r1=95886&r2=95887&view=diff
==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Thu Feb 11 12:20:28 2010
@@ -32,7 +32,13 @@
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 @@
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 @@
}
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 @@
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 @@
}
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 @@
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 @@
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;
}
Modified: cfe/trunk/lib/Sema/SemaExpr.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaExpr.cpp?rev=95887&r1=95886&r2=95887&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaExpr.cpp (original)
+++ cfe/trunk/lib/Sema/SemaExpr.cpp Thu Feb 11 12:20:28 2010
@@ -1653,8 +1653,7 @@
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();
Modified: cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp?rev=95887&r1=95886&r2=95887&view=diff
==============================================================================
--- cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp (original)
+++ cfe/trunk/lib/Sema/SemaTemplateInstantiate.cpp Thu Feb 11 12:20:28 2010
@@ -687,8 +687,7 @@
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();
Modified: cfe/trunk/test/CodeGenCXX/vtable-layout.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/vtable-layout.cpp?rev=95887&r1=95886&r2=95887&view=diff
==============================================================================
--- cfe/trunk/test/CodeGenCXX/vtable-layout.cpp (original)
+++ cfe/trunk/test/CodeGenCXX/vtable-layout.cpp Thu Feb 11 12:20:28 2010
@@ -5,12 +5,36 @@
// CHECK-NEXT: 0 | offset_to_top (0)
// CHECK-NEXT: 1 | Test1::A RTTI
// CHECK-NEXT: -- (Test1::A, 0) vtable address --
-// CHECK-NEXT: 2 | Test1::A::f
+// CHECK-NEXT: 2 | void Test1::A::f()
struct A {
virtual void f();
};
void A::f() { }
-
}
+namespace Test2 {
+
+// This is a smoke test of the vtable dumper.
+// CHECK: Vtable for 'Test2::A' (8 entries).
+// CHECK-NEXT: 0 | offset_to_top (0)
+// CHECK-NEXT: 1 | Test2::A RTTI
+// CHECK-NEXT: -- (Test2::A, 0) vtable address --
+// CHECK-NEXT: 2 | void Test2::A::f()
+// CHECK-NEXT: 3 | void Test2::A::f() const
+// CHECK-NEXT: 4 | Test2::A *Test2::A::g(int)
+// CHECK-NEXT: 5 | Test2::A::~A() [complete]
+// CHECK-NEXT: 6 | Test2::A::~A() [deleting]
+// CHECK-NEXT: 7 | void Test2::A::h()
+struct A {
+ virtual void f();
+ virtual void f() const;
+
+ virtual A* g(int a);
+ virtual ~A();
+ virtual void h();
+};
+
+void A::f() { }
+
+}
More information about the cfe-commits
mailing list