Skip to content

Commit fd16dee

Browse files
committed
Introduce checking for language features via "#if $FeatureName"
Introduce some basic support for defining specific language features that can be checked by name, e.g., #if $AsyncAwait // use the feature #endif For backward compatibility with older compilers, to actually prevent the parser from parsing, one will have to do a Swift compiler version check, even though the version number doesn't matter. For example: #if compiler(>=5.3) && $AsyncAwait // use the feature #endif
1 parent bcd6416 commit fd16dee

File tree

3 files changed

+63
-1
lines changed

3 files changed

+63
-1
lines changed

include/swift/Basic/Features.def

Lines changed: 41 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,41 @@
1+
//===--- Features.def - Swift Features Metaprogramming ----------*- C++ -*-===//
2+
//
3+
// This source file is part of the Swift.org open source project
4+
//
5+
// Copyright (c) 2014 - 2017 Apple Inc. and the Swift project authors
6+
// Licensed under Apache License v2.0 with Runtime Library Exception
7+
//
8+
// See https://swift.org/LICENSE.txt for license information
9+
// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors
10+
//
11+
//===----------------------------------------------------------------------===//
12+
//
13+
// This file defines macros used for macro-metaprogramming with language
14+
// features.
15+
//
16+
//
17+
// FEATURE(FeatureName, SENumber, Description, Option)
18+
//
19+
// The FEATURE macro describes each named feature that is introduced in
20+
// Swift. It allows Swift code to check for a particular feature with
21+
// "#if $FeatureName" in source code.
22+
//
23+
// FeatureName: The name given to this feature to be used in source code,
24+
// e.g., AsyncAwait.
25+
// SENumber: The number assigned to this feature in the Swift Evolution
26+
// process, or 0 if there isn't one.
27+
// Description: A string literal describing the feature.
28+
// Option: either a reference to a language option in the form
29+
// "langOpts.<option name>" or "true" to indicate that it's always
30+
// enabled.
31+
//===----------------------------------------------------------------------===//
32+
33+
#ifndef LANGUAGE_FEATURE
34+
# error define LANGUAGE_FEATURE before including Features.def
35+
#endif
36+
37+
LANGUAGE_FEATURE(StaticAssert, 0, "#assert", langOpts.EnableExperimentalStaticAssert)
38+
LANGUAGE_FEATURE(AsyncAwait, 296, "async/await", true)
39+
LANGUAGE_FEATURE(Actors, 0, "actors", langOpts.EnableExperimentalConcurrency)
40+
41+
#undef LANGUAGE_FEATURE

lib/Parse/ParseIfConfig.cpp

Lines changed: 13 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -407,7 +407,19 @@ class EvaluateIfConfigCondition :
407407

408408
bool visitUnresolvedDeclRefExpr(UnresolvedDeclRefExpr *E) {
409409
auto Name = getDeclRefStr(E);
410-
return Ctx.LangOpts.isCustomConditionalCompilationFlagSet(Name);
410+
411+
// Check whether this is any one of the known compiler features.
412+
const auto &langOpts = Ctx.LangOpts;
413+
bool isKnownFeature = llvm::StringSwitch<bool>(Name)
414+
#define LANGUAGE_FEATURE(FeatureName, SENumber, Description, Option) \
415+
.Case("$" #FeatureName, Option)
416+
#include "swift/Basic/Features.def"
417+
.Default(false);
418+
419+
if (isKnownFeature)
420+
return true;
421+
422+
return langOpts.isCustomConditionalCompilationFlagSet(Name);
411423
}
412424

413425
bool visitCallExpr(CallExpr *E) {

test/Parse/features.swift

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: not %target-swift-frontend -typecheck %s 2>&1 | %FileCheck --check-prefix=CHECK-WITHOUT %s
2+
// RUN: %target-typecheck-verify-swift -enable-experimental-static-assert
3+
4+
#if compiler(>=5.3) && $StaticAssert
5+
#assert(true)
6+
#else
7+
// CHECK-WITHOUT: cannot find 'complete' in scope
8+
complete junk
9+
#endif

0 commit comments

Comments
 (0)