aboutsummaryrefslogtreecommitdiff
path: root/include/clang/Basic/TargetCXXABI.h
diff options
context:
space:
mode:
authorJohn McCall <rjmccall@apple.com>2013-01-25 22:31:03 +0000
committerJohn McCall <rjmccall@apple.com>2013-01-25 22:31:03 +0000
commitd5617eeafc93209a26b9f88276c88cf997c3a0a7 (patch)
tree43c9295b24bd0ef8787299fa08681e041ef4697b /include/clang/Basic/TargetCXXABI.h
parentb8b2c9da87e7d70a1679db026f40548b3192b705 (diff)
The standard ARM C++ ABI dictates that inline functions are
never key functions. We did not implement that rule for the iOS ABI, which was driven by what was implemented in gcc-4.2. However, implement it now for other ARM-based platforms. git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@173515 91177308-0d34-0410-b5e6-96231b3b80d8
Diffstat (limited to 'include/clang/Basic/TargetCXXABI.h')
-rw-r--r--include/clang/Basic/TargetCXXABI.h41
1 files changed, 41 insertions, 0 deletions
diff --git a/include/clang/Basic/TargetCXXABI.h b/include/clang/Basic/TargetCXXABI.h
index 2a8f5d0df5..1a8e62c16d 100644
--- a/include/clang/Basic/TargetCXXABI.h
+++ b/include/clang/Basic/TargetCXXABI.h
@@ -142,6 +142,47 @@ public:
return isItaniumFamily();
}
+ /// \brief Can an out-of-line inline function serve as a key function?
+ ///
+ /// This flag is only useful in ABIs where type data (for example,
+ /// v-tables and type_info objects) are emitted only after processing
+ /// the definition of a special "key" virtual function. (This is safe
+ /// because the ODR requires that every virtual function be defined
+ /// somewhere in a program.) This usually permits such data to be
+ /// emitted in only a single object file, as opposed to redundantly
+ /// in every object file that requires it.
+ ///
+ /// One simple and common definition of "key function" is the first
+ /// virtual function in the class definition which is not defined there.
+ /// This rule works very well when that function has a non-inline
+ /// definition in some non-header file. Unfortunately, when that
+ /// function is defined inline, this rule requires the type data
+ /// to be emitted weakly, as if there were no key function.
+ ///
+ /// The ARM ABI observes that the ODR provides an additional guarantee:
+ /// a virtual function is always ODR-used, so if it is defined inline,
+ /// that definition must appear in every translation unit that defines
+ /// the class. Therefore, there is no reason to allow such functions
+ /// to serve as key functions.
+ ///
+ /// Because this changes the rules for emitting type data,
+ /// it can cause type data to be emitted with both weak and strong
+ /// linkage, which is not allowed on all platforms. Therefore,
+ /// exploiting this observation requires an ABI break and cannot be
+ /// done on a generic Itanium platform.
+ bool canKeyFunctionBeInline() const {
+ switch (getKind()) {
+ case GenericARM:
+ return false;
+
+ case GenericItanium:
+ case iOS: // old iOS compilers did not follow this rule
+ case Microsoft:
+ return true;
+ }
+ llvm_unreachable("bad ABI kind");
+ }
+
/// Try to parse an ABI name, returning false on error.
bool tryParse(llvm::StringRef name);