diff options
author | John McCall <rjmccall@apple.com> | 2012-08-21 02:47:43 +0000 |
---|---|---|
committer | John McCall <rjmccall@apple.com> | 2012-08-21 02:47:43 +0000 |
commit | 0a7dd788dbef975f35f273c7ab913f480f7edd60 (patch) | |
tree | 4ff726c6ed21d7c822a307b124bf4fec48ffc89a | |
parent | eb8f2efb17c74620510a38cb437e792ea9c76021 (diff) |
Screw around with ObjCRuntime some more, changing the
diagnostics for bad deployment targets and adding a few
more predicates. Includes a patch by Jonathan Schleifer
to enable ARC for ObjFW.
git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@162252 91177308-0d34-0410-b5e6-96231b3b80d8
-rw-r--r-- | include/clang/Basic/DiagnosticDriverKinds.td | 8 | ||||
-rw-r--r-- | include/clang/Basic/LangOptions.def | 2 | ||||
-rw-r--r-- | include/clang/Basic/ObjCRuntime.h | 30 | ||||
-rw-r--r-- | include/clang/Driver/ToolChain.h | 4 | ||||
-rw-r--r-- | lib/ARCMigrate/ARCMT.cpp | 2 | ||||
-rw-r--r-- | lib/ARCMigrate/Transforms.cpp | 2 | ||||
-rw-r--r-- | lib/CodeGen/CGObjC.cpp | 4 | ||||
-rw-r--r-- | lib/CodeGen/CGObjCGNU.cpp | 47 | ||||
-rw-r--r-- | lib/Driver/ToolChains.cpp | 7 | ||||
-rw-r--r-- | lib/Driver/ToolChains.h | 2 | ||||
-rw-r--r-- | lib/Driver/Tools.cpp | 5 | ||||
-rw-r--r-- | lib/Frontend/CompilerInvocation.cpp | 16 | ||||
-rw-r--r-- | lib/Frontend/InitPreprocessor.cpp | 2 | ||||
-rw-r--r-- | lib/Lex/PPMacroExpansion.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaCodeComplete.cpp | 3 | ||||
-rw-r--r-- | lib/Sema/SemaObjCProperty.cpp | 2 | ||||
-rw-r--r-- | lib/Sema/SemaType.cpp | 2 | ||||
-rw-r--r-- | test/Driver/arc.c | 6 |
18 files changed, 102 insertions, 45 deletions
diff --git a/include/clang/Basic/DiagnosticDriverKinds.td b/include/clang/Basic/DiagnosticDriverKinds.td index 583b2345c9..a2e15395d6 100644 --- a/include/clang/Basic/DiagnosticDriverKinds.td +++ b/include/clang/Basic/DiagnosticDriverKinds.td @@ -91,10 +91,10 @@ def err_drv_invalid_arch_for_deployment_target : Error< "invalid architecture '%0' for deployment target '%1'">; def err_drv_objc_gc_arr : Error< "cannot specify both '-fobjc-arc' and '%0'">; -def err_arc_nonfragile_abi : Error< - "-fobjc-arc is not supported with legacy abi">; -def err_arc_unsupported : Error< - "-fobjc-arc is not supported on current deployment target">; +def err_arc_unsupported_on_runtime : Error< + "-fobjc-arc is not supported on platforms using the legacy runtime">; +def err_arc_unsupported_on_toolchain : Error< + "-fobjc-arc is not supported on %select{versions of Mac OS prior to 10.6}0">; def err_drv_mg_requires_m_or_mm : Error< "option '-MG' requires '-M' or '-MM'">; def err_drv_asan_android_requires_pie : Error< diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def index fab17a2fe5..3c70028ee3 100644 --- a/include/clang/Basic/LangOptions.def +++ b/include/clang/Basic/LangOptions.def @@ -135,7 +135,7 @@ LANGOPT(DefaultFPContract , 1, 0, "FP_CONTRACT") LANGOPT(NoBitFieldTypeAlign , 1, 0, "bit-field type alignment") LANGOPT(HexagonQdsp6Compat , 1, 0, "hexagon-qdsp6 backward compatibility") LANGOPT(ObjCAutoRefCount , 1, 0, "Objective-C automated reference counting") -LANGOPT(ObjCRuntimeHasWeak , 1, 0, "__weak support in the ARC runtime") +LANGOPT(ObjCARCWeak , 1, 0, "__weak support in the ARC runtime") LANGOPT(FakeAddressSpaceMap , 1, 0, "OpenCL fake address space map") LANGOPT(MRTD , 1, 0, "-mrtd calling convention") diff --git a/include/clang/Basic/ObjCRuntime.h b/include/clang/Basic/ObjCRuntime.h index b24fe7cd91..2ca421bb57 100644 --- a/include/clang/Basic/ObjCRuntime.h +++ b/include/clang/Basic/ObjCRuntime.h @@ -126,12 +126,25 @@ public: return !isGNUFamily(); } + /// \brief Does this runtime allow ARC at all? + bool allowsARC() const { + switch (getKind()) { + case FragileMacOSX: return false; + case MacOSX: return true; + case iOS: return true; + case GCC: return false; + case GNUstep: return true; + case ObjFW: return true; + } + llvm_unreachable("bad kind"); + } + /// \brief Does this runtime natively provide the ARC entrypoints? /// /// ARC cannot be directly supported on a platform that does not provide /// these entrypoints, although it may be supportable via a stub /// library. - bool hasARC() const { + bool hasNativeARC() const { switch (getKind()) { case FragileMacOSX: return false; case MacOSX: return getVersion() >= VersionTuple(10, 7); @@ -139,16 +152,22 @@ public: case GCC: return false; case GNUstep: return getVersion() >= VersionTuple(1, 6); - case ObjFW: return false; // XXX: this will change soon + case ObjFW: return true; } llvm_unreachable("bad kind"); } + /// Does this runtime allow the use of __weak? + bool allowsWeak() const { + return hasNativeWeak(); + } + /// \brief Does this runtime natively provide ARC-compliant 'weak' /// entrypoints? - bool hasWeak() const { - // Right now, this is always equivalent to the ARC decision. - return hasARC(); + bool hasNativeWeak() const { + // Right now, this is always equivalent to whether the runtime + // natively supports ARC decision. + return hasNativeARC(); } /// \brief Does this runtime directly support the subscripting methods? @@ -226,6 +245,7 @@ public: } llvm_unreachable("bad kind"); } + /// \brief Does this runtime use zero-cost exceptions? bool hasUnwindExceptions() const { switch (getKind()) { diff --git a/include/clang/Driver/ToolChain.h b/include/clang/Driver/ToolChain.h index ab417bb577..bc6331e897 100644 --- a/include/clang/Driver/ToolChain.h +++ b/include/clang/Driver/ToolChain.h @@ -183,8 +183,8 @@ public: /// Does this tool chain support Objective-C garbage collection. virtual bool SupportsObjCGC() const { return true; } - /// Does this tool chain support Objective-C ARC. - virtual bool SupportsObjCARC() const { return true; } + /// Complain if this tool chain doesn't support Objective-C ARC. + virtual void CheckObjCARC() const {} /// UseDwarfDebugFlags - Embed the compile options to clang into the Dwarf /// compile unit information. diff --git a/lib/ARCMigrate/ARCMT.cpp b/lib/ARCMigrate/ARCMT.cpp index f291dec21f..14e13ba58c 100644 --- a/lib/ARCMigrate/ARCMT.cpp +++ b/lib/ARCMigrate/ARCMT.cpp @@ -237,7 +237,7 @@ createInvocationForMigration(CompilerInvocation &origCI) { WarnOpts.push_back("error=arc-unsafe-retained-assign"); CInvok->getDiagnosticOpts().Warnings = llvm_move(WarnOpts); - CInvok->getLangOpts()->ObjCRuntimeHasWeak = HasARCRuntime(origCI); + CInvok->getLangOpts()->ObjCARCWeak = HasARCRuntime(origCI); return CInvok.take(); } diff --git a/lib/ARCMigrate/Transforms.cpp b/lib/ARCMigrate/Transforms.cpp index 1175c36316..f01dfa9c15 100644 --- a/lib/ARCMigrate/Transforms.cpp +++ b/lib/ARCMigrate/Transforms.cpp @@ -40,7 +40,7 @@ bool MigrationPass::CFBridgingFunctionsDefined() { bool trans::canApplyWeak(ASTContext &Ctx, QualType type, bool AllowOnUnknownClass) { - if (!Ctx.getLangOpts().ObjCRuntimeHasWeak) + if (!Ctx.getLangOpts().ObjCARCWeak) return false; QualType T = type; diff --git a/lib/CodeGen/CGObjC.cpp b/lib/CodeGen/CGObjC.cpp index e0762846dc..4a8a07994a 100644 --- a/lib/CodeGen/CGObjC.cpp +++ b/lib/CodeGen/CGObjC.cpp @@ -1706,7 +1706,7 @@ static llvm::Constant *createARCRuntimeFunction(CodeGenModule &CGM, // references to the runtime support library. We don't really // permit this to fail, but we need a particular relocation style. if (llvm::Function *f = dyn_cast<llvm::Function>(fn)) { - if (!CGM.getLangOpts().ObjCRuntime.hasARC()) + if (!CGM.getLangOpts().ObjCRuntime.hasNativeARC()) f->setLinkage(llvm::Function::ExternalWeakLinkage); // set nonlazybind attribute for these APIs for performance. if (fnName == "objc_retain" || fnName == "objc_release") @@ -2739,7 +2739,7 @@ void CodeGenFunction::EmitObjCAutoreleasePoolStmt( // Keep track of the current cleanup stack depth. RunCleanupsScope Scope(*this); - if (CGM.getLangOpts().ObjCRuntime.hasARC()) { + if (CGM.getLangOpts().ObjCRuntime.hasNativeARC()) { llvm::Value *token = EmitObjCAutoreleasePoolPush(); EHStack.pushCleanup<CallObjCAutoreleasePoolObject>(NormalCleanup, token); } else { diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp index 6d129d02a5..f1c5f19ffa 100644 --- a/lib/CodeGen/CGObjCGNU.cpp +++ b/lib/CodeGen/CGObjCGNU.cpp @@ -653,11 +653,40 @@ class CGObjCGNUstep : public CGObjCGNU { } }; -/// The ObjFW runtime, which closely follows the GCC runtime's -/// compiler ABI. Support here is due to Jonathan Schleifer, the -/// ObjFW maintainer. -class CGObjCObjFW : public CGObjCGCC { - /// Emit class references unconditionally as direct symbol references. +/// Support for the ObjFW runtime. Support here is due to +/// Jonathan Schleifer <js@webkeks.org>, the ObjFW maintainer. +class CGObjCObjFW: public CGObjCGNU { +protected: + /// The GCC ABI message lookup function. Returns an IMP pointing to the + /// method implementation for this message. + LazyRuntimeFunction MsgLookupFn; + /// The GCC ABI superclass message lookup function. Takes a pointer to a + /// structure describing the receiver and the class, and a selector as + /// arguments. Returns the IMP for the corresponding method. + LazyRuntimeFunction MsgLookupSuperFn; + + virtual llvm::Value *LookupIMP(CodeGenFunction &CGF, + llvm::Value *&Receiver, + llvm::Value *cmd, + llvm::MDNode *node) { + CGBuilderTy &Builder = CGF.Builder; + llvm::Value *args[] = { + EnforceType(Builder, Receiver, IdTy), + EnforceType(Builder, cmd, SelectorTy) }; + llvm::CallSite imp = CGF.EmitCallOrInvoke(MsgLookupFn, args); + imp->setMetadata(msgSendMDKind, node); + return imp.getInstruction(); + } + + virtual llvm::Value *LookupIMPSuper(CodeGenFunction &CGF, + llvm::Value *ObjCSuper, + llvm::Value *cmd) { + CGBuilderTy &Builder = CGF.Builder; + llvm::Value *lookupArgs[] = {EnforceType(Builder, ObjCSuper, + PtrToObjCSuperTy), cmd}; + return Builder.CreateCall(MsgLookupSuperFn, lookupArgs); + } + virtual llvm::Value *GetClassNamed(CGBuilderTy &Builder, const std::string &Name, bool isWeak) { if (isWeak) @@ -678,7 +707,13 @@ class CGObjCObjFW : public CGObjCGCC { } public: - CGObjCObjFW(CodeGenModule &Mod): CGObjCGCC(Mod) {} + CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) { + // IMP objc_msg_lookup(id, SEL); + MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, NULL); + // IMP objc_msg_lookup_super(struct objc_super*, SEL); + MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy, + PtrToObjCSuperTy, SelectorTy, NULL); + } }; } // end anonymous namespace diff --git a/lib/Driver/ToolChains.cpp b/lib/Driver/ToolChains.cpp index 5cf97b702b..46259139cd 100644 --- a/lib/Driver/ToolChains.cpp +++ b/lib/Driver/ToolChains.cpp @@ -951,8 +951,11 @@ bool Darwin::SupportsObjCGC() const { return !isTargetIPhoneOS(); } -bool Darwin::SupportsObjCARC() const { - return isTargetIPhoneOS() || !isMacosxVersionLT(10, 6); +void Darwin::CheckObjCARC() const { + if (isTargetIPhoneOS() || !isMacosxVersionLT(10, 6)) + return; + getDriver().Diag(diag::err_arc_unsupported_on_toolchain) + << 0; // "versions of Mac OS X prior to 10.6" } std::string diff --git a/lib/Driver/ToolChains.h b/lib/Driver/ToolChains.h index 95a11beea1..752cdfdcaa 100644 --- a/lib/Driver/ToolChains.h +++ b/lib/Driver/ToolChains.h @@ -354,7 +354,7 @@ public: virtual bool SupportsObjCGC() const; - virtual bool SupportsObjCARC() const; + virtual void CheckObjCARC() const; virtual bool UseDwarfDebugFlags() const; diff --git a/lib/Driver/Tools.cpp b/lib/Driver/Tools.cpp index ed67f7b9a1..e9f1aab90b 100644 --- a/lib/Driver/Tools.cpp +++ b/lib/Driver/Tools.cpp @@ -2541,8 +2541,7 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, // NOTE: This logic is duplicated in ToolChains.cpp. bool ARC = isObjCAutoRefCount(Args); if (ARC) { - if (!getToolChain().SupportsObjCARC()) - D.Diag(diag::err_arc_unsupported); + getToolChain().CheckObjCARC(); CmdArgs.push_back("-fobjc-arc"); @@ -4481,7 +4480,7 @@ void darwin::Link::ConstructJob(Compilation &C, const JobAction &JA, ObjCRuntime runtime = getDarwinToolChain().getDefaultObjCRuntime(/*nonfragile*/ true); // We use arclite library for both ARC and subscripting support. - if ((!runtime.hasARC() && isObjCAutoRefCount(Args)) || + if ((!runtime.hasNativeARC() && isObjCAutoRefCount(Args)) || !runtime.hasSubscripting()) getDarwinToolChain().AddLinkARCArgs(Args, CmdArgs); } diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index d39679caf1..d90bd92b9d 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -812,7 +812,7 @@ static void LangOptsToArgs(const LangOptions &Opts, ToArgsList &Res) { Res.push_back("-fobjc-runtime=" + Opts.ObjCRuntime.getAsString()); if (Opts.ObjCAutoRefCount) Res.push_back("-fobjc-arc"); - if (Opts.ObjCRuntimeHasWeak) + if (Opts.ObjCARCWeak) Res.push_back("-fobjc-runtime-has-weak"); if (!Opts.ObjCInferRelatedResultType) Res.push_back("-fno-objc-infer-related-result-type"); @@ -1941,14 +1941,16 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.setGC(LangOptions::HybridGC); else if (Args.hasArg(OPT_fobjc_arc)) { Opts.ObjCAutoRefCount = 1; - if (!Opts.ObjCRuntime.isNonFragile()) - Diags.Report(diag::err_arc_nonfragile_abi); + if (!Opts.ObjCRuntime.allowsARC()) + Diags.Report(diag::err_arc_unsupported_on_runtime); + + // Only set ObjCARCWeak if ARC is enabled. + if (Args.hasArg(OPT_fobjc_runtime_has_weak)) + Opts.ObjCARCWeak = 1; + else + Opts.ObjCARCWeak = Opts.ObjCRuntime.allowsWeak(); } - Opts.ObjCRuntimeHasWeak = Opts.ObjCRuntime.hasWeak(); - if (Args.hasArg(OPT_fobjc_runtime_has_weak)) - Opts.ObjCRuntimeHasWeak = 1; - if (Args.hasArg(OPT_fno_objc_infer_related_result_type)) Opts.ObjCInferRelatedResultType = 0; } diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp index 1440da6e37..edb0710534 100644 --- a/lib/Frontend/InitPreprocessor.cpp +++ b/lib/Frontend/InitPreprocessor.cpp @@ -247,7 +247,7 @@ static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts, << "};\n" << "\n"; - if (LangOpts.ObjCRuntimeHasWeak) { + if (LangOpts.ObjCARCWeak) { Out << "template<typename _Tp>\n" << "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n" << " enum { __value = 0 };\n" diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index ebdb6446d1..96d6b2c729 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -641,8 +641,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) { // Objective-C features .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? .Case("objc_arc", LangOpts.ObjCAutoRefCount) - .Case("objc_arc_weak", LangOpts.ObjCAutoRefCount && - LangOpts.ObjCRuntimeHasWeak) + .Case("objc_arc_weak", LangOpts.ObjCARCWeak) .Case("objc_default_synthesize_properties", LangOpts.ObjC2) .Case("objc_fixed_enum", LangOpts.ObjC2) .Case("objc_instancetype", LangOpts.ObjC2) diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index eb03d253a5..6c140ac692 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -4649,8 +4649,7 @@ void Sema::CodeCompleteObjCPropertyFlags(Scope *S, ObjCDeclSpec &ODS) { Results.AddResult(CodeCompletionResult("atomic")); // Only suggest "weak" if we're compiling for ARC-with-weak-references or GC. - if ((getLangOpts().ObjCAutoRefCount && getLangOpts().ObjCRuntimeHasWeak) || - getLangOpts().getGC() != LangOptions::NonGC) + if (getLangOpts().ObjCARCWeak || getLangOpts().getGC() != LangOptions::NonGC) if (!ObjCPropertyFlagConflicts(Attributes, ObjCDeclSpec::DQ_PR_weak)) Results.AddResult(CodeCompletionResult("weak")); diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp index 8a8927d362..6aa59229fa 100644 --- a/lib/Sema/SemaObjCProperty.cpp +++ b/lib/Sema/SemaObjCProperty.cpp @@ -880,7 +880,7 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S, Diag(property->getLocation(), diag::note_property_declare); err = true; } - if (!err && !getLangOpts().ObjCRuntimeHasWeak) { + if (!err && !getLangOpts().ObjCARCWeak) { Diag(PropertyDiagLoc, diag::err_arc_weak_no_runtime); Diag(property->getLocation(), diag::note_property_declare); } diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp index 54f8dbaf01..3e72c2d06f 100644 --- a/lib/Sema/SemaType.cpp +++ b/lib/Sema/SemaType.cpp @@ -3588,7 +3588,7 @@ static bool handleObjCOwnershipTypeAttr(TypeProcessingState &state, // Forbid __weak if the runtime doesn't support it. if (lifetime == Qualifiers::OCL_Weak && - !S.getLangOpts().ObjCRuntimeHasWeak && !NonObjCPointer) { + !S.getLangOpts().ObjCARCWeak && !NonObjCPointer) { // Actually, delay this until we know what we're parsing. if (S.DelayedDiagnostics.shouldDelayDiagnostics()) { diff --git a/test/Driver/arc.c b/test/Driver/arc.c index 5a5720c04a..1072e6b7bb 100644 --- a/test/Driver/arc.c +++ b/test/Driver/arc.c @@ -8,10 +8,10 @@ // Just to test clang is working. # foo -// CHECK: error: -fobjc-arc is not supported with legacy abi +// CHECK: error: -fobjc-arc is not supported on platforms using the legacy runtime // CHECK-NOT: invalid preprocessing directive -// NOTOBJC-NOT: error: -fobjc-arc is not supported with legacy abi +// NOTOBJC-NOT: error: -fobjc-arc is not supported on platforms using the legacy runtime // NOTOBJC: invalid preprocessing directive -// UNSUPPORTED: error: -fobjc-arc is not supported on current deployment target +// UNSUPPORTED: error: -fobjc-arc is not supported on versions of Mac OS prior to 10.6 |