}
+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) {
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);
}
/// 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 {
return ContainsMemberPointer;
}
+ const CXXMethodDecl *getKeyFunction() const {
+ return KeyFunction;
+ }
};
/// CodeGenTypes - This class organizes the cross-module state that is used