Skip to content
Merged
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/lib/AST/ASTContext.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -927,6 +927,8 @@ ASTContext::getFeatureAvailInfo(Decl *D) const {
auto *Attr = VD->getAttr<AvailabilityDomainAttr>();
if (!Attr)
return {};
if (!VD->getInit())
Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

This is a drive-by fix for a compiler crash I encountered when testing an earlier version of this PR.

return {};
StringRef Name = Attr->getName()->getName();
auto *Init = cast<InitListExpr>(VD->getInit());
Expr::EvalResult Result;
Expand Down
1 change: 1 addition & 0 deletions clang/lib/Headers/CMakeLists.txt
Original file line number Diff line number Diff line change
Expand Up @@ -37,6 +37,7 @@ set(core_files
unwind.h
varargs.h
feature-availability.h
availability_domain.h
)

set(arm_common_files
Expand Down
53 changes: 53 additions & 0 deletions clang/lib/Headers/availability_domain.h
Original file line number Diff line number Diff line change
@@ -0,0 +1,53 @@
/*===---- availability_domain.h - Availability Domain -----------------------===
*
* 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
*
*===-----------------------------------------------------------------------===
*/

#ifndef __AVAILABILITY_DOMAIN_H
#define __AVAILABILITY_DOMAIN_H

#include <stdint.h>

#define __AVAILABILITY_DOMAIN_ENABLED 0
#define __AVAILABILITY_DOMAIN_DISABLED 1
#define __AVAILABILITY_DOMAIN_DYNAMIC 2

/// Describes the fields of a Clang availability domain. This struct is an
/// implementation detail of the compiler and is subject to change so don't
/// reference `__AvailabilityDomain` directly. Instead, use the provided macros:
///
/// CLANG_DYNAMIC_AVAILABILITY_DOMAIN(MyDomain, query);
///
struct __AvailabilityDomain {
/// The state of the domain (AVAILABLE, UNAVAILABLE, DYNAMIC, etc.).
intptr_t state;
/// An optional function pointer to call to query the availability of a domain
/// at runtime. This should only be non-null for domains in the DYNAMIC state.
int (*const runtimeQuery)(void);
};

#define CLANG_DYNAMIC_AVAILABILITY_DOMAIN(domain, query) \
static struct __AvailabilityDomain domain __attribute__(( \
availability_domain(domain))) = {__AVAILABILITY_DOMAIN_DYNAMIC, query}

#define CLANG_ENABLED_AVAILABILITY_DOMAIN(domain) \
static struct __AvailabilityDomain domain __attribute__(( \
availability_domain(domain))) = {__AVAILABILITY_DOMAIN_ENABLED, 0}

#define CLANG_DISABLED_AVAILABILITY_DOMAIN(domain) \
static struct __AvailabilityDomain domain __attribute__(( \
availability_domain(domain))) = {__AVAILABILITY_DOMAIN_DISABLED, 0}

#define CLANG_ALWAYS_ENABLED_AVAILABILITY_DOMAIN(domain) \
static struct __AvailabilityDomain domain __attribute__(( \
availability_domain(domain))) = {__AVAILABILITY_DOMAIN_ENABLED, 0}

#define CLANG_ALWAYS_DISABLED_AVAILABILITY_DOMAIN(domain) \
static struct __AvailabilityDomain domain __attribute__(( \
availability_domain(domain))) = {__AVAILABILITY_DOMAIN_DISABLED, 0}

#endif /* __AVAILABILITY_DOMAIN_H */
20 changes: 2 additions & 18 deletions clang/lib/Headers/feature-availability.h
Original file line number Diff line number Diff line change
Expand Up @@ -10,24 +10,8 @@
#ifndef __FEATURE_AVAILABILITY_H
#define __FEATURE_AVAILABILITY_H

#include <stdint.h>
// feature-availability.h is deprecated - use availability_domain.h instead.

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Should we turn this comment into a real warning using #warning?

Copy link
Author

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

I'd rather have a chance to move adopters off of it before it becomes a warning (although once adopters move off of it we should probably remove it entirely).


/// The possible availability domain states. These values are hardcoded in the
/// compiler and reproduced here for convenience when defining domains.

#define __AVAILABILITY_DOMAIN_ENABLED 0
#define __AVAILABILITY_DOMAIN_DISABLED 1
#define __AVAILABILITY_DOMAIN_DYNAMIC 2

/// A struct describing availability domain definitions. This struct definition
/// is just a convenience to ensure that a header defining an availability
/// domain can define it with the arguments that Clang expects at parse time.
struct __AvailabilityDomain {
/// The state of the domain (AVAILABLE, UNAVAILABLE, DYNAMIC, etc.).
intptr_t state;
/// An optional function pointer to call to query the availability of a domain
/// at runtime. This should only be non-null for domains in the DYNAMIC state.
int (*const runtimeQuery)(void);
};
#include <availability_domain.h>

#endif /* __FEATURE_AVAILABILITY_H */
5 changes: 5 additions & 0 deletions clang/lib/Headers/module.modulemap
Original file line number Diff line number Diff line change
Expand Up @@ -342,6 +342,11 @@ module feature_availability {
export *
}

module availability_domain {
header "availability_domain.h"
export *
}

/* TO_UPSTREAM(BoundsSafety) ON */
module ptrcheck {
header "ptrcheck.h"
Expand Down
8 changes: 4 additions & 4 deletions clang/test/CodeGen/feature-availability.c
Original file line number Diff line number Diff line change
Expand Up @@ -15,15 +15,15 @@
#ifndef HEADER
#define HEADER

#include <feature-availability.h>
#include <availability_domain.h>

#define AVAIL 0

#ifdef USE_DOMAIN
// DOMAIN: @g3 = extern_weak global i32, align 4

static struct __AvailabilityDomain feature1 __attribute__((availability_domain(feature1))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain feature2 __attribute__((availability_domain(feature2))) = {__AVAILABILITY_DOMAIN_DISABLED, 0};
CLANG_ENABLED_AVAILABILITY_DOMAIN(feature1);
CLANG_DISABLED_AVAILABILITY_DOMAIN(feature2);
#endif

__attribute__((availability(domain:feature1, AVAIL))) int func0(void);
Expand Down Expand Up @@ -94,7 +94,7 @@ void test3(struct S0 *s0) {
// DOMAIN-NEXT: ret void

int pred1(void);
static struct __AvailabilityDomain feature3 __attribute__((availability_domain(feature3))) = {__AVAILABILITY_DOMAIN_DYNAMIC, pred1};
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(feature3, pred1);
__attribute__((availability(domain:feature3, AVAIL))) int func3(void);
__attribute__((availability(domain:feature3, AVAIL))) extern int g3;

Expand Down
10 changes: 4 additions & 6 deletions clang/test/CodeGenObjC/feature-availability.m
Original file line number Diff line number Diff line change
@@ -1,16 +1,14 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx -fblocks -ffeature-availability=feature1:on -ffeature-availability=feature2:off -ffeature-availability=feature3:on -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-apple-macosx -fblocks -emit-llvm -o - -DUSE_DOMAIN %s | FileCheck %s

#include <feature-availability.h>
#include <availability_domain.h>

#define AVAIL 0

#ifdef USE_DOMAIN
int pred1(void);

static struct __AvailabilityDomain feature1 __attribute__((availability_domain(feature1))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain feature2 __attribute__((availability_domain(feature2))) = {__AVAILABILITY_DOMAIN_DISABLED, 0};
static struct __AvailabilityDomain feature3 __attribute__((availability_domain(feature3))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
CLANG_ENABLED_AVAILABILITY_DOMAIN(feature1);
CLANG_DISABLED_AVAILABILITY_DOMAIN(feature2);
CLANG_ENABLED_AVAILABILITY_DOMAIN(feature3);
#endif

// CHECK: @"OBJC_IVAR_$_C0._prop0" = hidden global i32 4, section "__DATA, __objc_ivar", align 4
Expand Down
4 changes: 2 additions & 2 deletions clang/test/Modules/Inputs/feature-availability/feature1.h
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
#ifndef FEATURE1_H
#define FEATURE1_H
#include <feature-availability.h>
#include <availability_domain.h>

static struct __AvailabilityDomain feature1 __attribute__((availability_domain(feature1))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
CLANG_ENABLED_AVAILABILITY_DOMAIN(feature1);

#endif
4 changes: 2 additions & 2 deletions clang/test/Modules/Inputs/feature-availability/feature2.h
Original file line number Diff line number Diff line change
@@ -1,8 +1,8 @@
#ifndef FEATURE2_H
#define FEATURE2_H
#include <feature-availability.h>
#include <availability_domain.h>
#include "feature1.h"

static struct __AvailabilityDomain feature2 __attribute__((availability_domain(feature2))) = {__AVAILABILITY_DOMAIN_DISABLED, 0};
CLANG_DISABLED_AVAILABILITY_DOMAIN(feature2);

#endif
4 changes: 2 additions & 2 deletions clang/test/Modules/feature-availability.c
Original file line number Diff line number Diff line change
Expand Up @@ -3,14 +3,14 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx -fmodules -fmodule-file=%t/feature2.pcm -I %S/Inputs/feature-availability -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple arm64-apple-macosx -fmodules -fimplicit-module-maps -fmodules-cache-path=%t -I %S/Inputs/feature-availability -Werror=non-modular-include-in-module -emit-llvm -o - %s | FileCheck %s

#include <feature-availability.h>
#include <availability_domain.h>
#include "feature2.h"

#define AVAIL 0
#define UNAVAIL 1

int pred1(void);
static struct __AvailabilityDomain feature3 __attribute__((availability_domain(feature3))) = {__AVAILABILITY_DOMAIN_DYNAMIC, pred1};
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(feature3, pred1);

void func0(void);
__attribute__((availability(domain:feature1, AVAIL))) void func1(void);
Expand Down
10 changes: 5 additions & 5 deletions clang/test/Sema/feature-availability.c
Original file line number Diff line number Diff line change
@@ -1,18 +1,18 @@
// RUN: %clang_cc1 -triple arm64-apple-macosx15 -fblocks -ffeature-availability=feature1:1 -ffeature-availability=feature2:0 -ffeature-availability=feature3:on -fsyntax-only -Wunreachable-code -verify %s
// RUN: %clang_cc1 -triple arm64-apple-macosx15 -fblocks -fsyntax-only -Wunreachable-code -verify -DUSE_DOMAIN %s

#include <feature-availability.h>
#include <availability_domain.h>

#define AVAIL 0
#define UNAVAIL 1
#define INVALID 2

#ifdef USE_DOMAIN
int pred1(void);
static struct __AvailabilityDomain __feature1 __attribute__((availability_domain(feature1))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain __feature2 __attribute__((availability_domain(feature2))) = {__AVAILABILITY_DOMAIN_DISABLED, 0};
static struct __AvailabilityDomain __feature3 __attribute__((availability_domain(feature3))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain __feature4 __attribute__((availability_domain(feature4))) = {__AVAILABILITY_DOMAIN_DYNAMIC, pred1};
CLANG_ENABLED_AVAILABILITY_DOMAIN(feature1);
CLANG_DISABLED_AVAILABILITY_DOMAIN(feature2);
CLANG_ENABLED_AVAILABILITY_DOMAIN(feature3);
CLANG_DYNAMIC_AVAILABILITY_DOMAIN(feature4, pred1);
#endif

__attribute__((availability(domain:feature1, AVAIL))) void func12(void);
Expand Down
7 changes: 3 additions & 4 deletions clang/test/SemaObjC/feature-availability.m
Original file line number Diff line number Diff line change
@@ -1,15 +1,14 @@
// RUN: %clang_cc1 -fblocks -ffeature-availability=feature1:ON -ffeature-availability=feature2:OFF -fsyntax-only -verify %s
// RUN: %clang_cc1 -fblocks -fsyntax-only -verify -DUSE_DOMAIN %s

#include <feature-availability.h>
#include <availability_domain.h>

#define AVAIL 0
#define UNAVAIL 1

#ifdef USE_DOMAIN
int pred1(void);
static struct __AvailabilityDomain feature1 __attribute__((availability_domain(feature1))) = {__AVAILABILITY_DOMAIN_ENABLED, 0};
static struct __AvailabilityDomain feature2 __attribute__((availability_domain(feature2))) = {__AVAILABILITY_DOMAIN_DISABLED, 0};
CLANG_ENABLED_AVAILABILITY_DOMAIN(feature1);
CLANG_DISABLED_AVAILABILITY_DOMAIN(feature2);
#endif

__attribute__((availability(domain:feature1, AVAIL))) int func1(void);
Expand Down