forked from OSchip/llvm-project
Add a define for the ObjFW runtime ABI version.
This removes __has_feature(objc_msg_lookup_stret), as it is not required anymore after this patch. Patch by Jonathan Schleifer! llvm-svn: 190791
This commit is contained in:
parent
53e622cef4
commit
4d6efbb28a
|
@ -1255,23 +1255,6 @@ Further examples of these attributes are available in the static analyzer's `lis
|
||||||
Query for these features with ``__has_attribute(ns_consumed)``,
|
Query for these features with ``__has_attribute(ns_consumed)``,
|
||||||
``__has_attribute(ns_returns_retained)``, etc.
|
``__has_attribute(ns_returns_retained)``, etc.
|
||||||
|
|
||||||
objc_msg_lookup_stret
|
|
||||||
---------------------
|
|
||||||
|
|
||||||
Traditionally, if a runtime is used that follows the GNU Objective-C ABI, a
|
|
||||||
call to objc_msg_lookup() would be emitted for each message send, which would
|
|
||||||
return a pointer to the actual implementation of the method. However,
|
|
||||||
objc_msg_lookup() has no information at all about the method signature of the
|
|
||||||
actual method. Therefore, certain features like forwarding messages cannot be
|
|
||||||
correctly implemented for methods returning structs using objc_msg_lookup(), as
|
|
||||||
methods returning structs use a slightly different calling convention.
|
|
||||||
|
|
||||||
To work around this, Clang emits calls to objc_msg_lookup_stret() instead for
|
|
||||||
methods that return structs if the runtime supports this, allowing the runtime
|
|
||||||
to use a different forwarding handler for methods returning structs.
|
|
||||||
|
|
||||||
To check if Clang emits calls to objc_msg_lookup_stret(),
|
|
||||||
__has_feature(objc_msg_lookup_stret) can be used.
|
|
||||||
|
|
||||||
Function Overloading in C
|
Function Overloading in C
|
||||||
=========================
|
=========================
|
||||||
|
|
|
@ -71,16 +71,20 @@ bool ObjCRuntime::tryParse(StringRef input) {
|
||||||
kind = ObjCRuntime::GCC;
|
kind = ObjCRuntime::GCC;
|
||||||
} else if (runtimeName == "objfw") {
|
} else if (runtimeName == "objfw") {
|
||||||
kind = ObjCRuntime::ObjFW;
|
kind = ObjCRuntime::ObjFW;
|
||||||
|
Version = VersionTuple(0, 8);
|
||||||
} else {
|
} else {
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
TheKind = kind;
|
TheKind = kind;
|
||||||
|
|
||||||
if (dash != StringRef::npos) {
|
if (dash != StringRef::npos) {
|
||||||
StringRef verString = input.substr(dash + 1);
|
StringRef verString = input.substr(dash + 1);
|
||||||
if (Version.tryParse(verString))
|
if (Version.tryParse(verString))
|
||||||
return true;
|
return true;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8))
|
||||||
|
Version = VersionTuple(0, 8);
|
||||||
|
|
||||||
return false;
|
return false;
|
||||||
}
|
}
|
||||||
|
|
|
@ -408,6 +408,22 @@ static void InitializePredefinedMacros(const TargetInfo &TI,
|
||||||
if (LangOpts.ObjCRuntime.isNeXTFamily())
|
if (LangOpts.ObjCRuntime.isNeXTFamily())
|
||||||
Builder.defineMacro("__NEXT_RUNTIME__");
|
Builder.defineMacro("__NEXT_RUNTIME__");
|
||||||
|
|
||||||
|
if (LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW) {
|
||||||
|
VersionTuple tuple = LangOpts.ObjCRuntime.getVersion();
|
||||||
|
|
||||||
|
unsigned minor = 0;
|
||||||
|
if (tuple.getMinor().hasValue())
|
||||||
|
minor = tuple.getMinor().getValue();
|
||||||
|
|
||||||
|
unsigned subminor = 0;
|
||||||
|
if (tuple.getSubminor().hasValue())
|
||||||
|
subminor = tuple.getSubminor().getValue();
|
||||||
|
|
||||||
|
Builder.defineMacro("__OBJFW_RUNTIME_ABI__",
|
||||||
|
Twine(tuple.getMajor() * 10000 + minor * 100 +
|
||||||
|
subminor));
|
||||||
|
}
|
||||||
|
|
||||||
Builder.defineMacro("IBOutlet", "__attribute__((iboutlet))");
|
Builder.defineMacro("IBOutlet", "__attribute__((iboutlet))");
|
||||||
Builder.defineMacro("IBOutletCollection(ClassName)",
|
Builder.defineMacro("IBOutletCollection(ClassName)",
|
||||||
"__attribute__((iboutletcollection(ClassName)))");
|
"__attribute__((iboutletcollection(ClassName)))");
|
||||||
|
|
|
@ -920,7 +920,6 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
|
||||||
.Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
|
.Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile())
|
||||||
.Case("objc_property_explicit_atomic", true) // Does clang support explicit "atomic" keyword?
|
.Case("objc_property_explicit_atomic", true) // Does clang support explicit "atomic" keyword?
|
||||||
.Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
|
.Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport())
|
||||||
.Case("objc_msg_lookup_stret", LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW)
|
|
||||||
.Case("ownership_holds", true)
|
.Case("ownership_holds", true)
|
||||||
.Case("ownership_returns", true)
|
.Case("ownership_returns", true)
|
||||||
.Case("ownership_takes", true)
|
.Case("ownership_takes", true)
|
||||||
|
|
|
@ -11,8 +11,8 @@ struct test {
|
||||||
@end
|
@end
|
||||||
void test0(void) {
|
void test0(void) {
|
||||||
struct test t;
|
struct test t;
|
||||||
#if (defined(STRET) && __has_feature(objc_msg_lookup_stret)) || \
|
#if (defined(STRET) && defined(__OBJFW_RUNTIME_ABI__)) || \
|
||||||
(!defined(STRET) && !__has_feature(objc_msg_lookup_stret))
|
(!defined(STRET) && !defined(__OBJFW_RUNTIME_ABI__))
|
||||||
t = [Test0 test];
|
t = [Test0 test];
|
||||||
#endif
|
#endif
|
||||||
(void)t;
|
(void)t;
|
||||||
|
|
Loading…
Reference in New Issue