summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorBob Wilson <bob.wilson@apple.com>2015-03-02 19:01:14 +0000
committerBob Wilson <bob.wilson@apple.com>2015-03-02 19:01:14 +0000
commitb111ec94b3474c4eff15b19a74cd815cdb469aaa (patch)
treeb08c0df24e8e846e1e0a2d7f6a7ec618fd64087e
parenta57d588cb7109c45b63a46ef6598f03745486f98 (diff)
downloadbcm5719-llvm-b111ec94b3474c4eff15b19a74cd815cdb469aaa.tar.gz
bcm5719-llvm-b111ec94b3474c4eff15b19a74cd815cdb469aaa.zip
Add clang support for Objective-C application extensions.
This adds the -fapplication-extension option, along with the ios_app_extension and macosx_app_extension availability attributes. Patch by Ted Kremenek llvm-svn: 230989
-rw-r--r--clang/include/clang/Basic/Attr.td2
-rw-r--r--clang/include/clang/Basic/LangOptions.def1
-rw-r--r--clang/include/clang/Driver/Options.td5
-rw-r--r--clang/lib/AST/DeclBase.cpp30
-rw-r--r--clang/lib/Driver/Tools.cpp10
-rw-r--r--clang/lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--clang/lib/Lex/PPMacroExpansion.cpp1
-rw-r--r--clang/test/Sema/attr-availability-app-extensions.c18
8 files changed, 60 insertions, 8 deletions
diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td
index 48e04beeaa4..fb49132b7e9 100644
--- a/clang/include/clang/Basic/Attr.td
+++ b/clang/include/clang/Basic/Attr.td
@@ -442,6 +442,8 @@ def Availability : InheritableAttr {
return llvm::StringSwitch<llvm::StringRef>(Platform)
.Case("ios", "iOS")
.Case("macosx", "OS X")
+ .Case("ios_app_extension", "iOS (App Extension)")
+ .Case("macosx_app_extension", "OS X (App Extension)")
.Default(llvm::StringRef());
} }];
let HasCustomParsing = 1;
diff --git a/clang/include/clang/Basic/LangOptions.def b/clang/include/clang/Basic/LangOptions.def
index fb398872588..21de1e3370b 100644
--- a/clang/include/clang/Basic/LangOptions.def
+++ b/clang/include/clang/Basic/LangOptions.def
@@ -84,6 +84,7 @@ BENIGN_LANGOPT(EncodeExtendedBlockSig , 1, 0,
"Encoding extended block type signature")
BENIGN_LANGOPT(ObjCInferRelatedResultType , 1, 1,
"Objective-C related result type inference")
+LANGOPT(AppExt , 1, 0, "Objective-C App Extension")
LANGOPT(Trigraphs , 1, 0,"trigraphs")
LANGOPT(LineComment , 1, 0, "'//' comments")
LANGOPT(Bool , 1, 0, "bool, true, and false keywords")
diff --git a/clang/include/clang/Driver/Options.td b/clang/include/clang/Driver/Options.td
index 6b7a47c1bb6..bcc4393e5c6 100644
--- a/clang/include/clang/Driver/Options.td
+++ b/clang/include/clang/Driver/Options.td
@@ -819,6 +819,11 @@ def fobjc_atdefs : Flag<["-"], "fobjc-atdefs">, Group<clang_ignored_f_Group>;
def fobjc_call_cxx_cdtors : Flag<["-"], "fobjc-call-cxx-cdtors">, Group<clang_ignored_f_Group>;
def fobjc_exceptions: Flag<["-"], "fobjc-exceptions">, Group<f_Group>,
HelpText<"Enable Objective-C exceptions">, Flags<[CC1Option]>;
+def fapplication_extension : Flag<["-"], "fapplication-extension">,
+ Group<f_Group>, Flags<[CC1Option]>,
+ HelpText<"Restrict code to those available for App Extensions">;
+def fno_application_extension : Flag<["-"], "fno-application-extension">,
+ Group<f_Group>;
def fobjc_gc_only : Flag<["-"], "fobjc-gc-only">, Group<f_Group>, Flags<[CC1Option]>,
HelpText<"Use GC exclusively for Objective-C related memory management">;
diff --git a/clang/lib/AST/DeclBase.cpp b/clang/lib/AST/DeclBase.cpp
index 75a219a4370..0390d81263a 100644
--- a/clang/lib/AST/DeclBase.cpp
+++ b/clang/lib/AST/DeclBase.cpp
@@ -336,20 +336,34 @@ bool Decl::isReferenced() const {
static AvailabilityResult CheckAvailability(ASTContext &Context,
const AvailabilityAttr *A,
std::string *Message) {
- StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
- StringRef PrettyPlatformName
- = AvailabilityAttr::getPrettyPlatformName(TargetPlatform);
- if (PrettyPlatformName.empty())
- PrettyPlatformName = TargetPlatform;
+ VersionTuple TargetMinVersion =
+ Context.getTargetInfo().getPlatformMinVersion();
- VersionTuple TargetMinVersion = Context.getTargetInfo().getPlatformMinVersion();
if (TargetMinVersion.empty())
return AR_Available;
+ // Check if this is an App Extension "platform", and if so chop off
+ // the suffix for matching with the actual platform.
+ StringRef ActualPlatform = A->getPlatform()->getName();
+ StringRef RealizedPlatform = ActualPlatform;
+ if (Context.getLangOpts().AppExt) {
+ size_t suffix = RealizedPlatform.rfind("_app_extension");
+ if (suffix != StringRef::npos)
+ RealizedPlatform = RealizedPlatform.slice(0, suffix);
+ }
+
+ StringRef TargetPlatform = Context.getTargetInfo().getPlatformName();
+
// Match the platform name.
- if (A->getPlatform()->getName() != TargetPlatform)
+ if (RealizedPlatform != TargetPlatform)
return AR_Available;
-
+
+ StringRef PrettyPlatformName
+ = AvailabilityAttr::getPrettyPlatformName(ActualPlatform);
+
+ if (PrettyPlatformName.empty())
+ PrettyPlatformName = ActualPlatform;
+
std::string HintMessage;
if (!A->getMessage().empty()) {
HintMessage = " - ";
diff --git a/clang/lib/Driver/Tools.cpp b/clang/lib/Driver/Tools.cpp
index de3d5a6af5c..eff0ca759a4 100644
--- a/clang/lib/Driver/Tools.cpp
+++ b/clang/lib/Driver/Tools.cpp
@@ -4216,6 +4216,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
}
}
+ if (Args.hasFlag(options::OPT_fapplication_extension,
+ options::OPT_fno_application_extension, false))
+ CmdArgs.push_back("-fapplication-extension");
+
// Handle GCC-style exception args.
if (!C.getDriver().IsCLMode())
addExceptionArgs(Args, InputType, getToolChain(), KernelOrKext,
@@ -5811,6 +5815,12 @@ void darwin::Link::AddLinkArgs(Compilation &C,
if (Args.hasArg(options::OPT_rdynamic) && Version[0] >= 137)
CmdArgs.push_back("-export_dynamic");
+ // If we are using App Extension restrictions, pass a flag to the linker
+ // telling it that the compiled code has been audited.
+ if (Args.hasFlag(options::OPT_fapplication_extension,
+ options::OPT_fno_application_extension, false))
+ CmdArgs.push_back("-application_extension");
+
// If we are using LTO, then automatically create a temporary file path for
// the linker to use, so that it's lifetime will extend past a possible
// dsymutil step.
diff --git a/clang/lib/Frontend/CompilerInvocation.cpp b/clang/lib/Frontend/CompilerInvocation.cpp
index 2098dec1729..962e8e10df7 100644
--- a/clang/lib/Frontend/CompilerInvocation.cpp
+++ b/clang/lib/Frontend/CompilerInvocation.cpp
@@ -1578,6 +1578,7 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK,
Opts.DebuggerObjCLiteral = Args.hasArg(OPT_fdebugger_objc_literal);
Opts.ApplePragmaPack = Args.hasArg(OPT_fapple_pragma_pack);
Opts.CurrentModule = Args.getLastArgValue(OPT_fmodule_name);
+ Opts.AppExt = Args.hasArg(OPT_fapplication_extension);
Opts.ImplementationOfModule =
Args.getLastArgValue(OPT_fmodule_implementation_of);
Opts.ModuleFeatures = Args.getAllArgValues(OPT_fmodule_feature);
diff --git a/clang/lib/Lex/PPMacroExpansion.cpp b/clang/lib/Lex/PPMacroExpansion.cpp
index b986ada05a9..80ec3c45ce6 100644
--- a/clang/lib/Lex/PPMacroExpansion.cpp
+++ b/clang/lib/Lex/PPMacroExpansion.cpp
@@ -868,6 +868,7 @@ static bool HasFeature(const Preprocessor &PP, const IdentifierInfo *II) {
.Case("attribute_analyzer_noreturn", true)
.Case("attribute_availability", true)
.Case("attribute_availability_with_message", true)
+ .Case("attribute_availability_app_extension", true)
.Case("attribute_cf_returns_not_retained", true)
.Case("attribute_cf_returns_retained", true)
.Case("attribute_deprecated_with_message", true)
diff --git a/clang/test/Sema/attr-availability-app-extensions.c b/clang/test/Sema/attr-availability-app-extensions.c
new file mode 100644
index 00000000000..a8470928193
--- /dev/null
+++ b/clang/test/Sema/attr-availability-app-extensions.c
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -triple x86_64-apple-macosx10.9.0 -fsyntax-only -fapplication-extension %s -verify
+// RUN: %clang_cc1 -triple armv7-apple-ios9.0 -fsyntax-only -fapplication-extension %s -verify
+
+#if __has_feature(attribute_availability_app_extension)
+ __attribute__((availability(macosx_app_extension,unavailable)))
+ __attribute__((availability(ios_app_extension,unavailable)))
+#endif
+void f0(int); // expected-note {{'f0' has been explicitly marked unavailable here}}
+
+__attribute__((availability(macosx,unavailable)))
+__attribute__((availability(ios,unavailable)))
+void f1(int); // expected-note {{'f1' has been explicitly marked unavailable here}}
+
+void test() {
+ f0(1); // expected-error {{'f0' is unavailable: not available on}}
+ f1(1); // expected-error {{'f1' is unavailable}}
+}
+
OpenPOWER on IntegriCloud