Skip to content
Open
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
2 changes: 2 additions & 0 deletions clang/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -376,6 +376,8 @@ if (APPLE AND NOT CMAKE_LINKER MATCHES ".*lld.*")
endif()

include(AddClang)
include(AddDarwinPlatform)
clang_add_additional_platform()

set(CMAKE_INCLUDE_CURRENT_DIR ON)

Expand Down
23 changes: 23 additions & 0 deletions clang/cmake/modules/AddDarwinPlatform.cmake
Original file line number Diff line number Diff line change
@@ -0,0 +1,23 @@
# FIXME: How to generalize this to be driven by discovered SDKs?
function(clang_add_additional_platform)
# Add a platform.
set(name "xros")
set(CLANG_PLATFORM_${name}_PLATFORM_AVAILABILITY_NAME "xros" PARENT_SCOPE)
set(platformFallBack "iphoneos")

if (NOT "${platformFallBack}" STREQUAL "")
set(fallbackTripleName "${platformFallBack}")
# FIXME: we need a generic platform -> triple mapping.
if ("${fallbackTripleName}" STREQUAL "iphoneos")
set(fallbackTripleName "ios")
endif()

message(STATUS "Platform ${name} has fallback platform - ${fallbackTripleName}")
set(CLANG_PLATFORM_${name}_FALLBACK_PLATFORM_AVAILABILITY_NAME "${fallbackTripleName}" PARENT_SCOPE)

# FIXME: This is a hack for xrOS, but should be in the SDKSettings too.
set(CLANG_PLATFORM_${name}_INFER_UNAVAILABLE 1 PARENT_SCOPE)
set(CLANG_PLATFORM_${name}_PLATFORM_TRIPLE_OS_VALUE "XROS" PARENT_SCOPE)
set(CLANG_PLATFORM_${name}_FALLBACK_PLATFORM_TRIPLE_OS_VALUE "IOS" PARENT_SCOPE)
endif()
endfunction()
33 changes: 33 additions & 0 deletions clang/lib/Sema/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -13,6 +13,38 @@ clang_tablegen(OpenCLBuiltins.inc -gen-clang-opencl-builtins
TARGET ClangOpenCLBuiltinsImpl
)

# Configure additional platform-specific code that controls things like
# availability attributes.
set(TEMPLATE_INCLUDES_INFER_AVAILABILITY_ATTRIBUTE "")

foreach(supported_platform ${LLVM_SUPPORTED_PLATFORMS})
if (${CLANG_PLATFORM_${supported_platform}_INFER_UNAVAILABLE})
# Generate code that infers availability(unavailable) attribute if a platform
# requires that.
set(output_file_name "InferUnavailableAvailabilityFromFallbackPlatform_${supported_platform}.def")
message(STATUS "Adding platform specific availability attribute code - ${output_file_name}")

set(PLATFORM_TRIPLE_OS_VALUE
"${CLANG_PLATFORM_${supported_platform}_PLATFORM_TRIPLE_OS_VALUE}")
set(FALLBACK_PLATFORM_TRIPLE_OS_VALUE
"${CLANG_PLATFORM_${supported_platform}_FALLBACK_PLATFORM_TRIPLE_OS_VALUE}")
set(PLATFORM_AVAILABILITY_NAME
"${CLANG_PLATFORM_${supported_platform}_PLATFORM_AVAILABILITY_NAME}")
set(FALLBACK_PLATFORM_AVAILABILITY_NAME
"${CLANG_PLATFORM_${supported_platform}_FALLBACK_PLATFORM_AVAILABILITY_NAME}")
configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/PlatformTemplates/InferUnavailableAvailabilityFromFallbackPlatform.def.in
${CMAKE_CURRENT_BINARY_DIR}/PlatformTemplates/${output_file_name}
)
set(TEMPLATE_INCLUDES_INFER_AVAILABILITY_ATTRIBUTE "${TEMPLATE_INCLUDES_INFER_AVAILABILITY_ATTRIBUTE}\n#include \"PlatformTemplates/${output_file_name}\"")
endif()
endforeach()

configure_file(
${CMAKE_CURRENT_SOURCE_DIR}/InferAvailabilityAttribute.cpp.in
${CMAKE_CURRENT_BINARY_DIR}/InferAvailabilityAttribute.cpp
)

add_clang_library(clangSema
AnalysisBasedWarnings.cpp
# TO_UPSTREAM(BoundsSafety) ON
Expand Down Expand Up @@ -108,6 +140,7 @@ add_clang_library(clangSema
SemaWasm.cpp
SemaX86.cpp
TypeLocBuilder.cpp
${CMAKE_CURRENT_BINARY_DIR}/InferAvailabilityAttribute.cpp

DEPENDS
ClangOpenCLBuiltinsImpl
Expand Down
47 changes: 47 additions & 0 deletions clang/lib/Sema/InferAvailabilityAttribute.cpp.in
Original file line number Diff line number Diff line change
@@ -0,0 +1,47 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//

#include "clang/AST/ASTContext.h"
#include "clang/Basic/DarwinSDKInfo.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/LLVM.h"
#include "llvm/Support/VersionTuple.h"
#include "llvm/TargetParser/Triple.h"

namespace clang {

/// Returns true if the given availability attribute should be inferred, and
/// adjusts the value of the attribute as necessary to facilitate that.
bool shouldInferAvailabilityAttribute(const llvm::Triple &TT,
const DarwinSDKInfo *SDKInfo,
const ASTContext &Context,
IdentifierInfo *&II,
bool &IsUnavailable,
VersionTuple &Introduced,
VersionTuple &Deprecated,
VersionTuple &Obsolete) {
for (const auto &f : {
// function ptr promotion
+([] (const llvm::Triple &TT,
const DarwinSDKInfo *SDKInfo,
const ASTContext &Context,
IdentifierInfo *&II,
bool &IsUnavailable,
VersionTuple &Introduced,
VersionTuple &Deprecated,
VersionTuple &Obsolete) -> bool { return false; }),
@TEMPLATE_INCLUDES_INFER_AVAILABILITY_ATTRIBUTE@
}) {
if (f(TT, SDKInfo, Context, II, IsUnavailable, Introduced, Deprecated,
Obsolete))
return true;
}
return false;
}

} // end namespace clang
Original file line number Diff line number Diff line change
@@ -0,0 +1,108 @@
//===----------------------------------------------------------------------===//
//
// Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
// See https://llvm.org/LICENSE.txt for license information.
// SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
//
//===----------------------------------------------------------------------===//
//
// This platform-specific template implements inferral of
// __attribute__((availability(platform, unavailable))) from a base platform
// attribute __attribute__((availability(fallback platform, unavailable))).
//
// INPUTS:
// PLATFORM_TRIPLE_OS_VALUE - the name of the target OS enum in the Triple.
// FALLBACK_PLATFORM_TRIPLE_OS_VALUE - the name of the fallback target OS
// enum in the Triple.
// PLATFORM_AVAILABILITY_NAME - the name of availability platform.
// FALLBACK_PLATFORM_AVAILABILITY_NAME - the name of availability for the
// fallback platform.
//
//===----------------------------------------------------------------------===//

// FIXME: This is now doing more than 'unavailable', the docs have to be updated.

// x introduced := map(ios introduced, 1.0, None)
// None -> x unavailable
// <version> -> x introduced <version>

// x deprecated := map(ios deprecated, 1.0, MaximumDeploymentVersion)
// None -> None
// <version> -> x deprecated <version>

// x obsoleted := map(ios obsoleted, 1.0, MaximumDeploymentVersion)
// None -> x unavailable
// <version> -> x obsoleted <version>

/// Returns true if the given availability attribute should be inferred.
+([] (const llvm::Triple &TT,
const DarwinSDKInfo *SDKInfo,
const ASTContext &Context,
IdentifierInfo *&II,
bool &IsUnavailable,
VersionTuple &Introduced,
VersionTuple &Deprecated,
VersionTuple &Obsolete) -> bool {
if (TT.getOS() != llvm::Triple::@PLATFORM_TRIPLE_OS_VALUE@)
return false;
IdentifierInfo *NewII = nullptr;
if (II->getName() == "@FALLBACK_PLATFORM_AVAILABILITY_NAME@")
NewII = &Context.Idents.get("@PLATFORM_AVAILABILITY_NAME@");
else if (II->getName() == "@FALLBACK_PLATFORM_AVAILABILITY_NAME@_app_extension")
NewII = &Context.Idents.get("@PLATFORM_AVAILABILITY_NAME@_app_extension");
if (!NewII)
return false;
II = NewII;

auto MakeUnavailable = [&]() {
IsUnavailable = true;
// Reset introduced, deprecated, obsoleted.
Introduced = VersionTuple();
Deprecated = VersionTuple();
Obsolete = VersionTuple();
};

if (!SDKInfo) {
MakeUnavailable();
return true;
}
// Map from the fallback platform availability to the current platform
// availability.
const auto *Mapping = SDKInfo->getVersionMapping(
DarwinSDKInfo::OSEnvPair(
llvm::Triple::@FALLBACK_PLATFORM_TRIPLE_OS_VALUE@,
llvm::Triple::UnknownEnvironment,
llvm::Triple::@PLATFORM_TRIPLE_OS_VALUE@,
llvm::Triple::UnknownEnvironment));
if (!Mapping) {
MakeUnavailable();
return true;
}

if (Introduced) {
auto NewIntroduced = Mapping->mapIntroducedAvailabilityVersion(Introduced);
if (!NewIntroduced) {
MakeUnavailable();
return true;
}
Introduced = *NewIntroduced;
}

if (Obsolete) {
auto NewObsolete =
Mapping->mapDeprecatedObsoletedAvailabilityVersion(Obsolete);
if (!NewObsolete) {
MakeUnavailable();
return true;
}
Obsolete = *NewObsolete;
}

if (Deprecated) {
auto NewDeprecated =
Mapping->mapDeprecatedObsoletedAvailabilityVersion(Deprecated);
Deprecated = NewDeprecated ? *NewDeprecated : VersionTuple();
}

return true;
}),
37 changes: 37 additions & 0 deletions clang/lib/Sema/SemaDeclAttr.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -2453,6 +2453,17 @@ AvailabilityAttr *Sema::mergeAvailabilityAttr(
return nullptr;
}

namespace clang {

/// Returns true if the given availability attribute should be inferred, and
/// adjusts the value of the attribute as necessary to facilitate that.
bool shouldInferAvailabilityAttribute(
const llvm::Triple &TT, const DarwinSDKInfo *SDKInfo,
const ASTContext &Context, IdentifierInfo *&II, bool &IsUnavailable,
VersionTuple &Introduced, VersionTuple &Deprecated, VersionTuple &Obsolete);

} // end namespace clang

static void handleFeatureAvailabilityAttr(Sema &S, Decl *D,
const ParsedAttr &AL) {
if (S.getLangOpts().CPlusPlus) {
Expand Down Expand Up @@ -2634,6 +2645,32 @@ static void handleAvailabilityAttr(Sema &S, Decl *D, const ParsedAttr &AL) {
if (NewAttr)
D->addAttr(NewAttr);

/* TO_UPSTREAM(XROS) ON */
if (S.Context.getTargetInfo().getTriple().getOS() == llvm::Triple::XROS) {
// Infer availability attributes using platform-specific logic, driven by
// the SDKSettings if necessary.
IdentifierInfo *NewII = II;
bool NewIsUnavailable = IsUnavailable;
VersionTuple NewIntroduced = Introduced.Version;
VersionTuple NewDeprecated = Deprecated.Version;
VersionTuple NewObsoleted = Obsoleted.Version;
if (shouldInferAvailabilityAttribute(S.Context.getTargetInfo().getTriple(),
S.getDarwinSDKInfoForAvailabilityChecking(AL.getRange().getBegin(), "ios"),
S.Context, NewII,
NewIsUnavailable, NewIntroduced,
NewDeprecated, NewObsoleted)) {
AvailabilityAttr *NewAttr = S.mergeAvailabilityAttr(
ND, AL, NewII, true /*Implicit*/, NewIntroduced, NewDeprecated,
NewObsoleted, NewIsUnavailable, Str, IsStrict, Replacement,
AvailabilityMergeKind::None, PriorityModifier + Sema::AP_InferredFromOtherPlatform,
IIEnvironment);
if (NewAttr)
D->addAttr(NewAttr);
}
}

/* TO_UPSTREAM(XROS) OFF */

// Transcribe "ios" to "watchos" (and add a new attribute) if the versioning
// matches before the start of the watchOS platform.
if (S.Context.getTargetInfo().getTriple().isWatchOS()) {
Expand Down
Original file line number Diff line number Diff line change
@@ -0,0 +1,9 @@
{
"DefaultVariant": "xrOS", "DisplayName": "xrOS",
"Version": "1.0",
"CanonicalName": "xros1.0",
"MaximumDeploymentTarget": "1.0.99",
"VersionMap": {
"iOS_xrOS":{"15.0":"1.0"}
}
}
Loading