[cfe-commits] r89736 - in /cfe/trunk: lib/CodeGen/CGCall.cpp lib/CodeGen/CGVtable.cpp lib/CodeGen/CodeGenTypes.h test/CodeGenCXX/virtual-functions-incomplete-types.cpp

Anders Carlsson andersca at mac.com
Mon Nov 23 21:08:53 PST 2009


Author: andersca
Date: Mon Nov 23 23:08:52 2009
New Revision: 89736

URL: http://llvm.org/viewvc/llvm-project?rev=89736&view=rev
Log:
It is common for vtables to contain pointers to functions that have either incomplete return types or incomplete argument types.

Handle this by returning the llvm::OpaqueType for those cases, which CodeGenModule::GetOrCreateLLVMFunction knows about, and treats as being an "incomplete function".

Added:
    cfe/trunk/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
Modified:
    cfe/trunk/lib/CodeGen/CGCall.cpp
    cfe/trunk/lib/CodeGen/CGVtable.cpp
    cfe/trunk/lib/CodeGen/CodeGenTypes.h

Modified: cfe/trunk/lib/CodeGen/CGCall.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGCall.cpp?rev=89736&r1=89735&r2=89736&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGCall.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGCall.cpp Mon Nov 23 23:08:52 2009
@@ -418,6 +418,32 @@
   return llvm::FunctionType::get(ResultType, ArgTys, IsVariadic);
 }
 
+static bool HasIncompleteReturnTypeOrArgumentTypes(const FunctionProtoType *T) {
+  if (const TagType *TT = T->getResultType()->getAs<TagType>()) {
+    if (!TT->getDecl()->isDefinition())
+      return true;
+  }
+
+  for (unsigned i = 0, e = T->getNumArgs(); i != e; ++i) {
+    if (const TagType *TT = T->getArgType(i)->getAs<TagType>()) {
+      if (!TT->getDecl()->isDefinition())
+        return true;
+    }
+  }
+
+  return false;
+}
+
+const llvm::Type *
+CodeGenTypes::GetFunctionTypeForVtable(const CXXMethodDecl *MD) {
+  const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
+  
+  if (!HasIncompleteReturnTypeOrArgumentTypes(FPT))
+    return GetFunctionType(getFunctionInfo(MD), FPT->isVariadic());
+
+  return llvm::OpaqueType::get(getLLVMContext());
+}
+
 void CodeGenModule::ConstructAttributeList(const CGFunctionInfo &FI,
                                            const Decl *TargetDecl,
                                            AttributeListType &PAL, 

Modified: cfe/trunk/lib/CodeGen/CGVtable.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CGVtable.cpp?rev=89736&r1=89735&r2=89736&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CGVtable.cpp (original)
+++ cfe/trunk/lib/CodeGen/CGVtable.cpp Mon Nov 23 23:08:52 2009
@@ -367,10 +367,7 @@
     if (const CXXDestructorDecl *Dtor = dyn_cast<CXXDestructorDecl>(MD))
       return wrap(CGM.GetAddrOfCXXDestructor(Dtor, GD.getDtorType()));
 
-    const FunctionProtoType *FPT = MD->getType()->getAs<FunctionProtoType>();
-    const llvm::Type *Ty =
-      CGM.getTypes().GetFunctionType(CGM.getTypes().getFunctionInfo(MD),
-                                     FPT->isVariadic());
+    const llvm::Type *Ty = CGM.getTypes().GetFunctionTypeForVtable(MD);
 
     return wrap(CGM.GetAddrOfFunction(MD, Ty));
   }

Modified: cfe/trunk/lib/CodeGen/CodeGenTypes.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/CodeGen/CodeGenTypes.h?rev=89736&r1=89735&r2=89736&view=diff

==============================================================================
--- cfe/trunk/lib/CodeGen/CodeGenTypes.h (original)
+++ cfe/trunk/lib/CodeGen/CodeGenTypes.h Mon Nov 23 23:08:52 2009
@@ -173,6 +173,12 @@
   const llvm::FunctionType *GetFunctionType(const CGFunctionInfo &Info,
                                             bool IsVariadic);
 
+
+  /// GetFunctionTypeForVtable - Get the LLVM function type for use in a vtable,
+  /// given a CXXMethodDecl. If the method to has an incomplete return type, 
+  /// and/or incomplete argument types, this will return the opaque type.
+  const llvm::Type *GetFunctionTypeForVtable(const CXXMethodDecl *MD);
+                                                     
   const CGRecordLayout &getCGRecordLayout(const TagDecl*) const;
 
   /// getLLVMFieldNo - Return llvm::StructType element number

Added: cfe/trunk/test/CodeGenCXX/virtual-functions-incomplete-types.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/CodeGenCXX/virtual-functions-incomplete-types.cpp?rev=89736&view=auto

==============================================================================
--- cfe/trunk/test/CodeGenCXX/virtual-functions-incomplete-types.cpp (added)
+++ cfe/trunk/test/CodeGenCXX/virtual-functions-incomplete-types.cpp Mon Nov 23 23:08:52 2009
@@ -0,0 +1,30 @@
+// RUN: clang-cc %s -triple=x86_64-apple-darwin10 -emit-llvm -o - | FileCheck %s
+
+struct A;
+
+struct B {
+  virtual void f();
+  virtual A g();
+};
+
+void B::f() { }
+
+// CHECK: declare void @_ZN1B1gEv()
+
+struct C;
+
+struct D {
+  virtual void f();
+  virtual C g();
+};
+
+void D::f() { }
+
+struct C {
+  int a;
+};
+
+// CHECK: define i64 @_ZN1D1gEv(%struct.B* %this)
+C D::g() {
+  return C();
+}





More information about the cfe-commits mailing list