diff options
Diffstat (limited to 'clang/lib/Frontend')
-rw-r--r-- | clang/lib/Frontend/CompilerInvocation.cpp | 26 | ||||
-rw-r--r-- | clang/lib/Frontend/InitPreprocessor.cpp | 48 |
2 files changed, 48 insertions, 26 deletions
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp index 71ee7e47149..99963bab09c 100644 --- a/clang/lib/Frontend/CompilerInvocation.cpp +++ b/clang/lib/Frontend/CompilerInvocation.cpp @@ -1421,12 +1421,28 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, Opts.ObjCAutoRefCount = 1; 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(); + // ObjCWeakRuntime tracks whether the runtime supports __weak, not + // whether the feature is actually enabled. This is predominantly + // determined by -fobjc-runtime, but we allow it to be overridden + // from the command line for testing purposes. + if (Args.hasArg(OPT_fobjc_runtime_has_weak)) + Opts.ObjCWeakRuntime = 1; + else + Opts.ObjCWeakRuntime = Opts.ObjCRuntime.allowsWeak(); + + // ObjCWeak determines whether __weak is actually enabled. + if (Opts.ObjCAutoRefCount) { + Opts.ObjCWeak = Opts.ObjCWeakRuntime; + } else if (Args.hasArg(OPT_fobjc_weak)) { + if (Opts.getGC() != LangOptions::NonGC) { + Diags.Report(diag::err_objc_weak_with_gc); + } else if (Opts.ObjCWeakRuntime) { + Opts.ObjCWeak = true; + } else { + Diags.Report(diag::err_objc_weak_unsupported); + } } if (Args.hasArg(OPT_fno_objc_infer_related_result_type)) diff --git a/clang/lib/Frontend/InitPreprocessor.cpp b/clang/lib/Frontend/InitPreprocessor.cpp index dc075793ac8..3d62d88917b 100644 --- a/clang/lib/Frontend/InitPreprocessor.cpp +++ b/clang/lib/Frontend/InitPreprocessor.cpp @@ -323,15 +323,17 @@ static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts, Out << "template<typename _Tp> struct __is_scalar;\n" << "\n"; + + if (LangOpts.ObjCAutoRefCount) { + Out << "template<typename _Tp>\n" + << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n" + << " enum { __value = 0 };\n" + << " typedef __false_type __type;\n" + << "};\n" + << "\n"; + } - Out << "template<typename _Tp>\n" - << "struct __is_scalar<__attribute__((objc_ownership(strong))) _Tp> {\n" - << " enum { __value = 0 };\n" - << " typedef __false_type __type;\n" - << "};\n" - << "\n"; - - if (LangOpts.ObjCARCWeak) { + if (LangOpts.ObjCWeak) { Out << "template<typename _Tp>\n" << "struct __is_scalar<__attribute__((objc_ownership(weak))) _Tp> {\n" << " enum { __value = 0 };\n" @@ -340,13 +342,15 @@ static void AddObjCXXARCLibstdcxxDefines(const LangOptions &LangOpts, << "\n"; } - Out << "template<typename _Tp>\n" - << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))" - << " _Tp> {\n" - << " enum { __value = 0 };\n" - << " typedef __false_type __type;\n" - << "};\n" - << "\n"; + if (LangOpts.ObjCAutoRefCount) { + Out << "template<typename _Tp>\n" + << "struct __is_scalar<__attribute__((objc_ownership(autoreleasing)))" + << " _Tp> {\n" + << " enum { __value = 0 };\n" + << " typedef __false_type __type;\n" + << "};\n" + << "\n"; + } Out << "}\n"; } @@ -851,9 +855,6 @@ static void InitializePredefinedMacros(const TargetInfo &TI, else if (LangOpts.getStackProtector() == LangOptions::SSPReq) Builder.defineMacro("__SSP_ALL__", "3"); - if (FEOpts.ProgramAction == frontend::RewriteObjC) - Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); - // Define a macro that exists only when using the static analyzer. if (FEOpts.ProgramAction == frontend::RunAnalysis) Builder.defineMacro("__clang_analyzer__"); @@ -861,7 +862,11 @@ static void InitializePredefinedMacros(const TargetInfo &TI, if (LangOpts.FastRelaxedMath) Builder.defineMacro("__FAST_RELAXED_MATH__"); - if (LangOpts.ObjCAutoRefCount) { + if (FEOpts.ProgramAction == frontend::RewriteObjC || + LangOpts.getGC() != LangOptions::NonGC) { + Builder.defineMacro("__weak", "__attribute__((objc_gc(weak)))"); + Builder.defineMacro("__strong", "__attribute__((objc_gc(strong)))"); + } else if (LangOpts.ObjC1) { Builder.defineMacro("__weak", "__attribute__((objc_ownership(weak)))"); Builder.defineMacro("__strong", "__attribute__((objc_ownership(strong)))"); Builder.defineMacro("__autoreleasing", @@ -928,10 +933,11 @@ void clang::InitializePreprocessor( // Install definitions to make Objective-C++ ARC work well with various // C++ Standard Library implementations. - if (LangOpts.ObjC1 && LangOpts.CPlusPlus && LangOpts.ObjCAutoRefCount) { + if (LangOpts.ObjC1 && LangOpts.CPlusPlus && + (LangOpts.ObjCAutoRefCount || LangOpts.ObjCWeak)) { switch (InitOpts.ObjCXXARCStandardLibrary) { case ARCXX_nolib: - case ARCXX_libcxx: + case ARCXX_libcxx: break; case ARCXX_libstdcxx: |