]> granicus.if.org Git - clang/commitdiff
Store the key function of a record decl inside CGRecordLayout.
authorAnders Carlsson <andersca@mac.com>
Mon, 12 Oct 2009 21:16:22 +0000 (21:16 +0000)
committerAnders Carlsson <andersca@mac.com>
Mon, 12 Oct 2009 21:16:22 +0000 (21:16 +0000)
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@83900 91177308-0d34-0410-b5e6-96231b3b80d8

lib/CodeGen/CGRecordLayoutBuilder.cpp
lib/CodeGen/CodeGenTypes.h

index d26c7721da27af57ca249a2f6df84e2d035e42f7..7baf69d87689f1b368d5dff00880f9f78373f201 100644 (file)
@@ -326,6 +326,31 @@ void CGRecordLayoutBuilder::CheckForMemberPointer(const FieldDecl *FD) {
 
 }
 
+static const CXXMethodDecl *GetKeyFunction(const RecordDecl *D) {
+  const CXXRecordDecl *RD = dyn_cast<CXXRecordDecl>(D);
+  if (!RD || !RD->isDynamicClass())
+    return 0;
+  
+  for (CXXRecordDecl::method_iterator I = RD->method_begin(), 
+       E = RD->method_end(); I != E; ++I) {
+    const CXXMethodDecl *MD = *I;
+    
+    if (!MD->isVirtual())
+      continue;
+    
+    if (MD->isPure())
+      continue;
+
+    if (MD->getBody())
+      continue;
+
+    // We found it.
+    return MD;
+  }
+  
+  return 0;
+}
+
 CGRecordLayout *
 CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types,
                                      const RecordDecl *D) {
@@ -355,5 +380,7 @@ CGRecordLayoutBuilder::ComputeLayout(CodeGenTypes &Types,
     Types.addBitFieldInfo(Info.FD, Info.FieldNo, Info.Start, Info.Size);
   }
 
-  return new CGRecordLayout(Ty, Builder.ContainsMemberPointer);
+  const CXXMethodDecl *KeyFunction = GetKeyFunction(D);
+
+  return new CGRecordLayout(Ty, Builder.ContainsMemberPointer, KeyFunction);
 }
index ad71e0ad053ce417425229fd0eb68a5a4307f7fb..a92a019b988ecf191ed7d56d1c05c33a3f0b2fe2 100644 (file)
@@ -61,9 +61,17 @@ namespace CodeGen {
     /// is a member pointer, or a struct that contains a member pointer.
     bool ContainsMemberPointer;
 
+    /// KeyFunction - The key function of the record layout (if one exists),
+    /// which is the first non-pure virtual function that is not inline at the
+    /// point of class definition.
+    /// See http://www.codesourcery.com/public/cxx-abi/abi.html#vague-vtable.
+    const CXXMethodDecl *KeyFunction;
+    
   public:
-    CGRecordLayout(const llvm::Type *T, bool ContainsMemberPointer)
-      : LLVMType(T), ContainsMemberPointer(ContainsMemberPointer) { }
+    CGRecordLayout(const llvm::Type *T, bool ContainsMemberPointer,
+                   const CXXMethodDecl *KeyFunction)
+      : LLVMType(T), ContainsMemberPointer(ContainsMemberPointer),
+        KeyFunction(KeyFunction) { }
 
     /// getLLVMType - Return llvm type associated with this record.
     const llvm::Type *getLLVMType() const {
@@ -74,6 +82,9 @@ namespace CodeGen {
       return ContainsMemberPointer;
     }
 
+    const CXXMethodDecl *getKeyFunction() const {
+      return KeyFunction;
+    }
   };
 
 /// CodeGenTypes - This class organizes the cross-module state that is used