diff --git a/clang/include/clang/Basic/Attr.td b/clang/include/clang/Basic/Attr.td --- a/clang/include/clang/Basic/Attr.td +++ b/clang/include/clang/Basic/Attr.td @@ -848,6 +848,7 @@ [{static llvm::StringRef getPrettyPlatformName(llvm::StringRef Platform) { return llvm::StringSwitch(Platform) .Case("android", "Android") + .Case("fuchsia", "Fuchsia") .Case("ios", "iOS") .Case("macos", "macOS") .Case("tvos", "tvOS") diff --git a/clang/include/clang/Basic/DiagnosticSemaKinds.td b/clang/include/clang/Basic/DiagnosticSemaKinds.td --- a/clang/include/clang/Basic/DiagnosticSemaKinds.td +++ b/clang/include/clang/Basic/DiagnosticSemaKinds.td @@ -3543,6 +3543,9 @@ InGroup; def note_protocol_method : Note< "protocol method is here">; +def warn_availability_fuchsia_unavailable_minor : Warning< + "Fuchsia versions only support 'major', not '.minor[.subminor]'">, + InGroup; def warn_unguarded_availability : Warning<"%0 is only available on %1 %2 or newer">, diff --git a/clang/lib/Basic/Targets/OSTargets.h b/clang/lib/Basic/Targets/OSTargets.h --- a/clang/lib/Basic/Targets/OSTargets.h +++ b/clang/lib/Basic/Targets/OSTargets.h @@ -885,6 +885,11 @@ // Required by the libc++ locale support. if (Opts.CPlusPlus) Builder.defineMacro("_GNU_SOURCE"); + + unsigned Maj, Min, Rev; + Triple.getOSVersion(Maj, Min, Rev); + this->PlatformName = "fuchsia"; + this->PlatformMinVersion = VersionTuple(Maj, Min, Rev); } public: diff --git a/clang/lib/Sema/SemaDeclAttr.cpp b/clang/lib/Sema/SemaDeclAttr.cpp --- a/clang/lib/Sema/SemaDeclAttr.cpp +++ b/clang/lib/Sema/SemaDeclAttr.cpp @@ -2488,6 +2488,15 @@ } } + if (II->isStr("fuchsia")) { + Optional Min, Sub; + if (((Min = Introduced.Version.getMinor()) && Min.getValue()) || + ((Sub = Introduced.Version.getSubminor()) && Sub.getValue())) { + S.Diag(AL.getLoc(), diag::warn_availability_fuchsia_unavailable_minor); + return; + } + } + int PriorityModifier = AL.isPragmaClangAttribute() ? Sema::AP_PragmaClangAttribute : Sema::AP_Explicit; diff --git a/clang/test/Sema/attr-availability-fuchsia.c b/clang/test/Sema/attr-availability-fuchsia.c new file mode 100644 --- /dev/null +++ b/clang/test/Sema/attr-availability-fuchsia.c @@ -0,0 +1,19 @@ +// RUN: %clang_cc1 "-triple" "x86_64-unknown-fuchsia16" -fsyntax-only -verify %s + +void f0(int) __attribute__((availability(fuchsia, introduced = 14, deprecated = 19))); +void f1(int) __attribute__((availability(fuchsia, introduced = 16))); +void f2(int) __attribute__((availability(fuchsia, introduced = 14, deprecated = 16))); // expected-note {{'f2' has been explicitly marked deprecated here}} +void f3(int) __attribute__((availability(fuchsia, introduced = 19))); +void f4(int) __attribute__((availability(fuchsia, introduced = 9, deprecated = 11, obsoleted = 16), availability(ios, introduced = 2.0, deprecated = 3.0))); // expected-note{{explicitly marked unavailable}} +void f5(int) __attribute__((availability(ios, introduced = 3.2), availability(fuchsia, unavailable))); // expected-note{{'f5' has been explicitly marked unavailable here}} +void f6(int) __attribute__((availability(fuchsia, introduced = 16.0))); +void f7(int) __attribute__((availability(fuchsia, introduced = 16.1))); // expected-warning {{Fuchsia versions only support 'major', not '.minor[.subminor]}} + +void test() { + f0(0); + f1(0); + f2(0); // expected-warning{{'f2' is deprecated: first deprecated in Fuchsia 16}} + f3(0); + f4(0); // expected-error{{f4' is unavailable: obsoleted in Fuchsia 16}} + f5(0); // expected-error{{'f5' is unavailable: not available on Fuchsia}} +}