summaryrefslogtreecommitdiffstats
path: root/clang/lib/CodeGen
diff options
context:
space:
mode:
authorAnders Carlsson <andersca@mac.com>2009-10-12 21:16:22 +0000
committerAnders Carlsson <andersca@mac.com>2009-10-12 21:16:22 +0000
commit1d116976b4d6357b2c3be099fbf5d718b1d5cea7 (patch)
tree6fbf87acc8a9d9dd6dd890333197d8957159120f /clang/lib/CodeGen
parent289ae4f454ae22e8ff8f49ae8660794368c1a496 (diff)
downloadbcm5719-llvm-1d116976b4d6357b2c3be099fbf5d718b1d5cea7.tar.gz
bcm5719-llvm-1d116976b4d6357b2c3be099fbf5d718b1d5cea7.zip
Store the key function of a record decl inside CGRecordLayout.
llvm-svn: 83900
Diffstat (limited to 'clang/lib/CodeGen')
-rw-r--r--clang/lib/CodeGen/CGRecordLayoutBuilder.cpp29
-rw-r--r--clang/lib/CodeGen/CodeGenTypes.h15
2 files changed, 41 insertions, 3 deletions
diff --git a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
index d26c7721da2..7baf69d8768 100644
--- a/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
+++ b/clang/lib/CodeGen/CGRecordLayoutBuilder.cpp
@@ -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);
}
diff --git a/clang/lib/CodeGen/CodeGenTypes.h b/clang/lib/CodeGen/CodeGenTypes.h
index ad71e0ad053..a92a019b988 100644
--- a/clang/lib/CodeGen/CodeGenTypes.h
+++ b/clang/lib/CodeGen/CodeGenTypes.h
@@ -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
OpenPOWER on IntegriCloud