[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