From 585c84c5afd91f57b84b0236aa28620438cfe636 Mon Sep 17 00:00:00 2001 From: Benjamin Kramer Date: Mon, 16 Sep 2013 16:31:49 +0000 Subject: [PATCH] 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! git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@190791 91177308-0d34-0410-b5e6-96231b3b80d8 --- docs/LanguageExtensions.rst | 17 ----------------- lib/Basic/ObjCRuntime.cpp | 8 ++++++-- lib/Frontend/InitPreprocessor.cpp | 16 ++++++++++++++++ lib/Lex/PPMacroExpansion.cpp | 1 - test/CodeGenObjC/stret_lookup.m | 4 ++-- 5 files changed, 24 insertions(+), 22 deletions(-) diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 917be93109..44f2f8dbea 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -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)``, ``__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 ========================= diff --git a/lib/Basic/ObjCRuntime.cpp b/lib/Basic/ObjCRuntime.cpp index 9bd433a064..be50fc4fe2 100644 --- a/lib/Basic/ObjCRuntime.cpp +++ b/lib/Basic/ObjCRuntime.cpp @@ -71,16 +71,20 @@ bool ObjCRuntime::tryParse(StringRef input) { kind = ObjCRuntime::GCC; } else if (runtimeName == "objfw") { kind = ObjCRuntime::ObjFW; + Version = VersionTuple(0, 8); } else { return true; } TheKind = kind; - + if (dash != StringRef::npos) { StringRef verString = input.substr(dash + 1); - if (Version.tryParse(verString)) + if (Version.tryParse(verString)) return true; } + if (kind == ObjCRuntime::ObjFW && Version > VersionTuple(0, 8)) + Version = VersionTuple(0, 8); + return false; } diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 0d76069a84..8703a67a6f 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -408,6 +408,22 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.ObjCRuntime.isNeXTFamily()) 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("IBOutletCollection(ClassName)", "__attribute__((iboutletcollection(ClassName)))"); diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index 0a4610d06c..8b81d5943b 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -920,7 +920,6 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { .Case("objc_nonfragile_abi", LangOpts.ObjCRuntime.isNonFragile()) .Case("objc_property_explicit_atomic", true) // Does clang support explicit "atomic" keyword? .Case("objc_weak_class", LangOpts.ObjCRuntime.hasWeakClassImport()) - .Case("objc_msg_lookup_stret", LangOpts.ObjCRuntime.getKind() == ObjCRuntime::ObjFW) .Case("ownership_holds", true) .Case("ownership_returns", true) .Case("ownership_takes", true) diff --git a/test/CodeGenObjC/stret_lookup.m b/test/CodeGenObjC/stret_lookup.m index 3f7303d4ad..6682fac7ae 100644 --- a/test/CodeGenObjC/stret_lookup.m +++ b/test/CodeGenObjC/stret_lookup.m @@ -11,8 +11,8 @@ struct test { @end void test0(void) { struct test t; -#if (defined(STRET) && __has_feature(objc_msg_lookup_stret)) || \ - (!defined(STRET) && !__has_feature(objc_msg_lookup_stret)) +#if (defined(STRET) && defined(__OBJFW_RUNTIME_ABI__)) || \ + (!defined(STRET) && !defined(__OBJFW_RUNTIME_ABI__)) t = [Test0 test]; #endif (void)t; -- 2.40.0