From ae8f9d8234f08b02417e4709d19c1079a9bc972d Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 29 Sep 2025 13:43:54 -0700 Subject: [PATCH 1/3] Add `-print-static-build-config` to print a static build conformance Introduce the ability to form a `StaticBuildConfiguration` from language options. Add a frontend option `-print-static-build-config` to then print that static build configuration as JSON in a manner that can be decoded into a `StaticBuildConfiguration`. Most of the change here is in sinking the bridged ASTContext queries of language options into a new BridgedLangOptions. The printing of the static build configuration only has a LangOptions (not an ASTContext), so this refactoring is required for printing. --- include/swift/AST/ASTBridging.h | 168 ++++++++----- include/swift/AST/ASTBridgingImpl.h | 11 + include/swift/Frontend/FrontendOptions.h | 4 + include/swift/Option/Options.td | 3 + lib/AST/Bridging/ASTContextBridging.cpp | 106 +------- lib/AST/Bridging/CMakeLists.txt | 1 + lib/AST/Bridging/LangOptionsBridging.cpp | 231 ++++++++++++++++++ lib/ASTGen/Sources/ASTGen/BuiltinPound.swift | 4 +- lib/ASTGen/Sources/ASTGen/CMakeLists.txt | 2 + .../ASTGen/CompilerBuildConfiguration.swift | 26 +- lib/ASTGen/Sources/ASTGen/DeclAttrs.swift | 4 +- lib/ASTGen/Sources/ASTGen/Decls.swift | 4 +- lib/ASTGen/Sources/ASTGen/SourceFile.swift | 2 +- .../StaticBuildConfiguration+ASTContext.swift | 133 ++++++++++ lib/Basic/LangOptions.cpp | 3 + lib/Driver/Driver.cpp | 21 ++ .../ArgsToFrontendOptionsConverter.cpp | 4 + lib/FrontendTool/CMakeLists.txt | 5 + lib/FrontendTool/FrontendTool.cpp | 21 ++ test/Frontend/print-static-build-config.swift | 10 + 20 files changed, 580 insertions(+), 183 deletions(-) create mode 100644 lib/AST/Bridging/LangOptionsBridging.cpp create mode 100644 lib/ASTGen/Sources/ASTGen/StaticBuildConfiguration+ASTContext.swift create mode 100644 test/Frontend/print-static-build-config.swift diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 99f9d05e0eef3..336aa0fafb2a6 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -58,6 +58,7 @@ class IfConfigClauseRangeInfo; class GenericSignature; class GenericSignatureImpl; struct LabeledStmtInfo; +class LangOptions; class LayoutConstraint; class LayoutConstraintInfo; struct LifetimeDescriptor; @@ -82,6 +83,7 @@ enum class RequirementReprKind : unsigned; struct BridgedASTType; class BridgedCanType; class BridgedASTContext; +class BridgedLangOptions; struct BridgedSubstitutionMap; struct BridgedGenericSignature; struct BridgedConformance; @@ -193,7 +195,7 @@ BridgedDeclNameLoc_createParsed(BridgedASTContext cContext, swift::SourceLoc baseNameLoc); //===----------------------------------------------------------------------===// -// MARK: ASTContext +// MARK: LangOptions //===----------------------------------------------------------------------===// enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedEndianness : size_t { @@ -201,30 +203,126 @@ enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedEndianness : size_t { EndianBig, }; -class BridgedASTContext { - swift::ASTContext * _Nonnull Ctx; +class BridgedLangOptions { + const swift::LangOptions * _Nonnull LangOpts; public: SWIFT_UNAVAILABLE("Use init(raw:) instead") - BRIDGED_INLINE BridgedASTContext(swift::ASTContext &ctx); + BRIDGED_INLINE BridgedLangOptions(const swift::LangOptions &langOpts); SWIFT_UNAVAILABLE("Use '.raw' instead") - BRIDGED_INLINE swift::ASTContext &unbridged() const; + BRIDGED_INLINE const swift::LangOptions &unbridged() const; SWIFT_COMPUTED_PROPERTY - void *_Nonnull getRaw() const { return Ctx; } + const void *_Nonnull getRaw() const { return LangOpts; } SWIFT_COMPUTED_PROPERTY unsigned getMajorLanguageVersion() const; SWIFT_COMPUTED_PROPERTY - unsigned getLangOptsTargetPointerBitWidth() const; + unsigned getTargetPointerBitWidth() const; + + SWIFT_COMPUTED_PROPERTY + BridgedEndianness getTargetEndianness() const; + + SWIFT_COMPUTED_PROPERTY + bool getAttachCommentsToDecls() const; +}; + +/// Key used when enumerating build configuration entries to the +/// StaticBuildConfiguration initializer for an ASTContext. +enum ENUM_EXTENSIBILITY_ATTR(closed) BuildConfigurationKey : size_t { + BCKCustomCondition, + BCKFeature, + BCKAttribute, + BCKTargetOSName, + BCKTargetArchitecture, + BCKTargetEnvironment, + BCKTargetRuntime, + BCKTargetPointerAuthenticationScheme, + BCKTargetObjectFileFormat +}; + +SWIFT_NAME("BridgedLangOptions.hasFeature(self:_:)") +bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts, + BridgedFeature feature); + +SWIFT_NAME("BridgedLangOptions.customConditionSet(self:_:)") +bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.hasFeatureNamed(self:_:)") +bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.hasAttributeNamed(self:_:)") +bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetOS(self:_:)") +bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetArchitecture(self:_:)") +bool BridgedLangOptions_isActiveTargetArchitecture(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetEnvironment(self:_:)") +bool BridgedLangOptions_isActiveTargetEnvironment(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetRuntime(self:_:)") +bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetPtrAuth(self:_:)") +bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.getTargetAtomicBitWidths(self:_:)") +SwiftInt BridgedLangOptions_getTargetAtomicBitWidths(BridgedLangOptions cLangOpts, + SwiftInt* _Nullable * _Nonnull cComponents); + +SWIFT_NAME("BridgedLangOptions.getLanguageVersion(self:_:)") +SwiftInt BridgedLangOptions_getLanguageVersion(BridgedLangOptions cLangOpts, + SwiftInt* _Nullable * _Nonnull cComponents); + +SWIFT_NAME("BridgedLangOptions.getCompilerVersion(self:_:)") +SwiftInt BridgedLangOptions_getCompilerVersion(BridgedLangOptions cLangOpts, + SwiftInt* _Nullable * _Nonnull cComponents); + +/* Deallocate an array of Swift int values that was allocated in C++. */ +void deallocateIntBuffer(SwiftInt * _Nullable cComponents); + +/// Enumerate all of the key/value pairs for the build configuration by calling +/// the given callback for each one. +SWIFT_NAME("BridgedLangOptions.enumerateBuildConfigurationEntries(self:callbackContext:callback:)") +void BridgedLangOptions_enumerateBuildConfigurationEntries( + BridgedLangOptions cLangOpts, + void * _Nonnull callbackContext, + void (* _Nonnull callback)( + BridgedLangOptions cLangOpts, void * _Nonnull callbackContext, + BuildConfigurationKey key, BridgedStringRef value)); + +//===----------------------------------------------------------------------===// +// MARK: ASTContext +//===----------------------------------------------------------------------===// + +class BridgedASTContext { + swift::ASTContext * _Nonnull Ctx; + +public: + SWIFT_UNAVAILABLE("Use init(raw:) instead") + BRIDGED_INLINE BridgedASTContext(swift::ASTContext &ctx); + + SWIFT_UNAVAILABLE("Use '.raw' instead") + BRIDGED_INLINE swift::ASTContext &unbridged() const; SWIFT_COMPUTED_PROPERTY - bool getLangOptsAttachCommentsToDecls() const; + void *_Nonnull getRaw() const { return Ctx; } SWIFT_COMPUTED_PROPERTY - BridgedEndianness getLangOptsTargetEndianness() const; + unsigned getMajorLanguageVersion() const; SWIFT_COMPUTED_PROPERTY BridgedAvailabilityMacroMap getAvailabilityMacroMap() const; @@ -259,56 +357,8 @@ SWIFT_NAME("BridgedASTContext.getDollarIdentifier(self:_:)") swift::Identifier BridgedASTContext_getDollarIdentifier(BridgedASTContext cContext, size_t idx); -SWIFT_NAME("BridgedASTContext.langOptsHasFeature(self:_:)") -bool BridgedASTContext_langOptsHasFeature(BridgedASTContext cContext, - BridgedFeature feature); - -SWIFT_NAME("BridgedASTContext.langOptsCustomConditionSet(self:_:)") -bool BridgedASTContext_langOptsCustomConditionSet(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsHasFeatureNamed(self:_:)") -bool BridgedASTContext_langOptsHasFeatureNamed(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsHasAttributeNamed(self:_:)") -bool BridgedASTContext_langOptsHasAttributeNamed(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsIsActiveTargetOS(self:_:)") -bool BridgedASTContext_langOptsIsActiveTargetOS(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsIsActiveTargetArchitecture(self:_:)") -bool BridgedASTContext_langOptsIsActiveTargetArchitecture(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsIsActiveTargetEnvironment(self:_:)") -bool BridgedASTContext_langOptsIsActiveTargetEnvironment(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsIsActiveTargetRuntime(self:_:)") -bool BridgedASTContext_langOptsIsActiveTargetRuntime(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsIsActiveTargetPtrAuth(self:_:)") -bool BridgedASTContext_langOptsIsActiveTargetPtrAuth(BridgedASTContext cContext, - BridgedStringRef cName); - -SWIFT_NAME("BridgedASTContext.langOptsGetTargetAtomicBitWidths(self:_:)") -SwiftInt BridgedASTContext_langOptsGetTargetAtomicBitWidths(BridgedASTContext cContext, - SwiftInt* _Nullable * _Nonnull cComponents); - -SWIFT_NAME("BridgedASTContext.langOptsGetLanguageVersion(self:_:)") -SwiftInt BridgedASTContext_langOptsGetLanguageVersion(BridgedASTContext cContext, - SwiftInt* _Nullable * _Nonnull cComponents); - -SWIFT_NAME("BridgedASTContext.langOptsGetCompilerVersion(self:_:)") -SwiftInt BridgedASTContext_langOptsGetCompilerVersion(BridgedASTContext cContext, - SwiftInt* _Nullable * _Nonnull cComponents); - -/* Deallocate an array of Swift int values that was allocated in C++. */ -void deallocateIntBuffer(SwiftInt * _Nullable cComponents); +SWIFT_NAME("getter:BridgedASTContext.langOpts(self:)") +BridgedLangOptions BridgedASTContext_langOpts(BridgedASTContext cContext); enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedCanImportVersion : size_t { CanImportUnversioned, diff --git a/include/swift/AST/ASTBridgingImpl.h b/include/swift/AST/ASTBridgingImpl.h index 3d8d55b673c87..b71a98e3b140d 100644 --- a/include/swift/AST/ASTBridgingImpl.h +++ b/include/swift/AST/ASTBridgingImpl.h @@ -66,6 +66,17 @@ swift::DeclNameLoc BridgedDeclNameLoc::unbridged() const { return swift::DeclNameLoc(LocationInfo, NumArgumentLabels); } +//===----------------------------------------------------------------------===// +// MARK: BridgedLangOptions +//===----------------------------------------------------------------------===// + +BridgedLangOptions::BridgedLangOptions(const swift::LangOptions &langOpts) + : LangOpts(&langOpts) { } + +const swift::LangOptions &BridgedLangOptions::unbridged() const { + return *LangOpts; +} + //===----------------------------------------------------------------------===// // MARK: BridgedASTContext //===----------------------------------------------------------------------===// diff --git a/include/swift/Frontend/FrontendOptions.h b/include/swift/Frontend/FrontendOptions.h index fcd6324279222..68101735374a6 100644 --- a/include/swift/Frontend/FrontendOptions.h +++ b/include/swift/Frontend/FrontendOptions.h @@ -326,6 +326,10 @@ class FrontendOptions { /// exit. bool PrintTargetInfo = false; + /// Indicates that the frontend should print the static build configuration + /// information as JSON. + bool PrintBuildConfig = false; + /// Indicates that the frontend should print the supported features and then /// exit. bool PrintSupportedFeatures = false; diff --git a/include/swift/Option/Options.td b/include/swift/Option/Options.td index e99cdc850671f..b25c87080876c 100644 --- a/include/swift/Option/Options.td +++ b/include/swift/Option/Options.td @@ -1542,6 +1542,9 @@ def target_legacy_spelling : Joined<["--"], "target=">, def print_target_info : Flag<["-"], "print-target-info">, Flags<[FrontendOption]>, HelpText<"Print target information for the given target , such as x86_64-apple-macos10.9">, MetaVarName<"">; +def print_static_build_config : Flag<["-"], "print-static-build-config">, + Flags<[FrontendOption]>, + HelpText<"Print static build configuration that can be used to evaluate #ifs in Swift source code">; def print_supported_features : Flag<["-"], "print-supported-features">, Flags<[FrontendOption]>, diff --git a/lib/AST/Bridging/ASTContextBridging.cpp b/lib/AST/Bridging/ASTContextBridging.cpp index 36ef1677768e2..8184929c84d30 100644 --- a/lib/AST/Bridging/ASTContextBridging.cpp +++ b/lib/AST/Bridging/ASTContextBridging.cpp @@ -36,116 +36,14 @@ Identifier BridgedASTContext_getDollarIdentifier(BridgedASTContext cContext, return cContext.unbridged().getDollarIdentifier(idx); } -bool BridgedASTContext_langOptsHasFeature(BridgedASTContext cContext, - BridgedFeature feature) { - return cContext.unbridged().LangOpts.hasFeature((Feature)feature); +BridgedLangOptions BridgedASTContext_langOpts(BridgedASTContext cContext) { + return cContext.unbridged().LangOpts; } unsigned BridgedASTContext::getMajorLanguageVersion() const { return unbridged().LangOpts.EffectiveLanguageVersion[0]; } -bool BridgedASTContext_langOptsCustomConditionSet(BridgedASTContext cContext, - BridgedStringRef cName) { - ASTContext &ctx = cContext.unbridged(); - auto name = cName.unbridged(); - if (name.starts_with("$") && ctx.LangOpts.hasFeature(name.drop_front())) - return true; - - return ctx.LangOpts.isCustomConditionalCompilationFlagSet(name); -} - -bool BridgedASTContext_langOptsHasFeatureNamed(BridgedASTContext cContext, - BridgedStringRef cName) { - return cContext.unbridged().LangOpts.hasFeature(cName.unbridged()); -} - -bool BridgedASTContext_langOptsHasAttributeNamed(BridgedASTContext cContext, - BridgedStringRef cName) { - return hasAttribute(cContext.unbridged().LangOpts, cName.unbridged()); -} - -bool BridgedASTContext_langOptsIsActiveTargetOS(BridgedASTContext cContext, - BridgedStringRef cName) { - return cContext.unbridged().LangOpts.checkPlatformCondition( - PlatformConditionKind::OS, cName.unbridged()); -} - -bool BridgedASTContext_langOptsIsActiveTargetArchitecture( - BridgedASTContext cContext, BridgedStringRef cName) { - return cContext.unbridged().LangOpts.checkPlatformCondition( - PlatformConditionKind::Arch, cName.unbridged()); -} - -bool BridgedASTContext_langOptsIsActiveTargetEnvironment( - BridgedASTContext cContext, BridgedStringRef cName) { - return cContext.unbridged().LangOpts.checkPlatformCondition( - PlatformConditionKind::TargetEnvironment, cName.unbridged()); -} - -bool BridgedASTContext_langOptsIsActiveTargetRuntime(BridgedASTContext cContext, - BridgedStringRef cName) { - return cContext.unbridged().LangOpts.checkPlatformCondition( - PlatformConditionKind::Runtime, cName.unbridged()); -} - -bool BridgedASTContext_langOptsIsActiveTargetPtrAuth(BridgedASTContext cContext, - BridgedStringRef cName) { - return cContext.unbridged().LangOpts.checkPlatformCondition( - PlatformConditionKind::PtrAuth, cName.unbridged()); -} - -unsigned BridgedASTContext::getLangOptsTargetPointerBitWidth() const { - return unbridged().LangOpts.Target.isArch64Bit() ? 64 - : unbridged().LangOpts.Target.isArch32Bit() ? 32 - : unbridged().LangOpts.Target.isArch16Bit() ? 16 - : 0; -} - -bool BridgedASTContext::getLangOptsAttachCommentsToDecls() const { - return unbridged().LangOpts.AttachCommentsToDecls; -} - -BridgedEndianness BridgedASTContext::getLangOptsTargetEndianness() const { - return unbridged().LangOpts.Target.isLittleEndian() ? EndianLittle - : EndianBig; -} - -/// Convert an array of numbers into a form we can use in Swift. -namespace { -template -SwiftInt convertArray(const Arr &array, SwiftInt **cElements) { - SwiftInt numElements = array.size(); - *cElements = (SwiftInt *)malloc(sizeof(SwiftInt) * numElements); - for (SwiftInt i = 0; i != numElements; ++i) - (*cElements)[i] = array[i]; - return numElements; -} -} // namespace - -void deallocateIntBuffer(SwiftInt *_Nullable cComponents) { free(cComponents); } - -SwiftInt -BridgedASTContext_langOptsGetLanguageVersion(BridgedASTContext cContext, - SwiftInt **cComponents) { - auto theVersion = cContext.unbridged().LangOpts.EffectiveLanguageVersion; - return convertArray(theVersion, cComponents); -} - -SWIFT_NAME("BridgedASTContext.langOptsGetCompilerVersion(self:_:)") -SwiftInt -BridgedASTContext_langOptsGetCompilerVersion(BridgedASTContext cContext, - SwiftInt **cComponents) { - auto theVersion = version::Version::getCurrentLanguageVersion(); - return convertArray(theVersion, cComponents); -} - -SwiftInt BridgedASTContext_langOptsGetTargetAtomicBitWidths( - BridgedASTContext cContext, SwiftInt *_Nullable *_Nonnull cElements) { - return convertArray(cContext.unbridged().LangOpts.getAtomicBitWidthValues(), - cElements); -} - bool BridgedASTContext_canImport(BridgedASTContext cContext, BridgedStringRef importPath, SourceLoc canImportLoc, diff --git a/lib/AST/Bridging/CMakeLists.txt b/lib/AST/Bridging/CMakeLists.txt index 277fdaca350a7..72e6c0fbdb9bd 100644 --- a/lib/AST/Bridging/CMakeLists.txt +++ b/lib/AST/Bridging/CMakeLists.txt @@ -7,6 +7,7 @@ target_sources(swiftAST PRIVATE DiagnosticsBridging.cpp ExprBridging.cpp GenericsBridging.cpp + LangOptionsBridging.cpp MiscBridging.cpp PatternBridging.cpp PluginBridging.cpp diff --git a/lib/AST/Bridging/LangOptionsBridging.cpp b/lib/AST/Bridging/LangOptionsBridging.cpp new file mode 100644 index 0000000000000..d407aede8a086 --- /dev/null +++ b/lib/AST/Bridging/LangOptionsBridging.cpp @@ -0,0 +1,231 @@ +//===--- Bridging/LangOptsBridging.cpp ------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022-2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#include "swift/AST/ASTBridging.h" + +#include "swift/Basic/LangOptions.h" + +using namespace swift; + +bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts, + BridgedFeature feature) { + return cLangOpts.unbridged().hasFeature((Feature)feature); +} + + +bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts, + BridgedStringRef cName) { + const LangOptions &langOpts = cLangOpts.unbridged(); + auto name = cName.unbridged(); + if (name.starts_with("$") && langOpts.hasFeature(name.drop_front())) + return true; + + return langOpts.isCustomConditionalCompilationFlagSet(name); +} + +bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts, + BridgedStringRef cName) { + return cLangOpts.unbridged().hasFeature(cName.unbridged()); +} + +bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts, + BridgedStringRef cName) { + return hasAttribute(cLangOpts.unbridged(), cName.unbridged()); +} + +bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts, + BridgedStringRef cName) { + return cLangOpts.unbridged().checkPlatformCondition( + PlatformConditionKind::OS, cName.unbridged()); +} + +bool BridgedLangOptions_isActiveTargetArchitecture( + BridgedLangOptions cLangOpts, BridgedStringRef cName) { + return cLangOpts.unbridged().checkPlatformCondition( + PlatformConditionKind::Arch, cName.unbridged()); +} + +bool BridgedLangOptions_isActiveTargetEnvironment( + BridgedLangOptions cLangOpts, BridgedStringRef cName) { + return cLangOpts.unbridged().checkPlatformCondition( + PlatformConditionKind::TargetEnvironment, cName.unbridged()); +} + +bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts, + BridgedStringRef cName) { + return cLangOpts.unbridged().checkPlatformCondition( + PlatformConditionKind::Runtime, cName.unbridged()); +} + +bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts, + BridgedStringRef cName) { + return cLangOpts.unbridged().checkPlatformCondition( + PlatformConditionKind::PtrAuth, cName.unbridged()); +} + +unsigned BridgedLangOptions::getTargetPointerBitWidth() const { + return unbridged().Target.isArch64Bit() ? 64 + : unbridged().Target.isArch32Bit() ? 32 + : unbridged().Target.isArch16Bit() ? 16 + : 0; +} + +BridgedEndianness BridgedLangOptions::getTargetEndianness() const { + return unbridged().Target.isLittleEndian() ? EndianLittle : EndianBig; +} + +bool BridgedLangOptions::getAttachCommentsToDecls() const { + return unbridged().AttachCommentsToDecls; +} + +/// Convert an array of numbers into a form we can use in Swift. +namespace { +template +SwiftInt convertArray(const Arr &array, SwiftInt **cElements) { + SwiftInt numElements = array.size(); + *cElements = (SwiftInt *)malloc(sizeof(SwiftInt) * numElements); + for (SwiftInt i = 0; i != numElements; ++i) + (*cElements)[i] = array[i]; + return numElements; +} +} // namespace + +void deallocateIntBuffer(SwiftInt *_Nullable cComponents) { free(cComponents); } + +SwiftInt +BridgedLangOptions_getLanguageVersion(BridgedLangOptions cLangOpts, + SwiftInt **cComponents) { + auto theVersion = cLangOpts.unbridged().EffectiveLanguageVersion; + return convertArray(theVersion, cComponents); +} + +SwiftInt +BridgedLangOptions_getCompilerVersion(BridgedLangOptions cLangOpts, + SwiftInt **cComponents) { + auto theVersion = version::Version::getCurrentLanguageVersion(); + return convertArray(theVersion, cComponents); +} + +SwiftInt BridgedLangOptions_getTargetAtomicBitWidths( + BridgedLangOptions cLangOpts, SwiftInt *_Nullable *_Nonnull cElements) { + return convertArray(cLangOpts.unbridged().getAtomicBitWidthValues(), + cElements); +} + +void BridgedLangOptions_enumerateBuildConfigurationEntries( + BridgedLangOptions cLangOpts, + void * _Nonnull callbackContext, + void (* _Nonnull callback)( + BridgedLangOptions cLangOpts, void * _Nonnull callbackContext, + BuildConfigurationKey key, BridgedStringRef value)) { + const LangOptions &langOpts = cLangOpts.unbridged(); + + // Enumerate custom conditions. + for (const auto &customCondition: langOpts.getCustomConditionalCompilationFlags()) { + callback(cLangOpts, callbackContext, BCKCustomCondition, + StringRef(customCondition)); + } + + // Enumerate features that are enabled. +#define LANGUAGE_FEATURE(FeatureName, SENumber, Description) \ + if (langOpts.hasFeature(Feature::FeatureName)) \ + callback(cLangOpts, callbackContext, BCKFeature, StringRef(#FeatureName)); +#include "swift/Basic/Features.def" + + // Enumerate attributes that are available. +#define DECL_ATTR(SPELLING, CLASS, REQUIREMENTS, BEHAVIORS, CODE) \ + if (hasAttribute(langOpts, #SPELLING)) \ + callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING)); +#include "swift/AST/DeclAttr.def" + +#define TYPE_ATTR(SPELLING, CLASS) \ + if (hasAttribute(langOpts, #SPELLING)) \ + callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING)); +#include "swift/AST/TypeAttr.def" + + // Deal with all of the target platform/architecture information. + for (const auto &[kind, value] : langOpts.getPlatformConditionValues()) { + switch (kind) { + case PlatformConditionKind::OS: + callback(cLangOpts, callbackContext, BCKTargetOSName, StringRef(value)); + + // Special case that macOS is an alias of OSX. + if (value == "OSX") { + callback(cLangOpts, callbackContext, BCKTargetOSName, + StringRef("macOS")); + } + break; + + case PlatformConditionKind::Arch: + callback(cLangOpts, callbackContext, BCKTargetArchitecture, StringRef(value)); + break; + + case PlatformConditionKind::Runtime: + callback(cLangOpts, callbackContext, BCKTargetRuntime, StringRef(value)); + break; + + case PlatformConditionKind::TargetEnvironment: + callback(cLangOpts, callbackContext, BCKTargetEnvironment, + StringRef(value)); + + // When compiling for iOS we consider "macCatalyst" to be a + // synonym of "macabi". This enables the use of + // #if targetEnvironment(macCatalyst) as a compilation + // condition for macCatalyst. + if (value == "macabi" && langOpts.Target.isiOS()) { + callback(cLangOpts, callbackContext, BCKTargetEnvironment, + StringRef("macCatalyst")); + } + break; + + case PlatformConditionKind::PtrAuth: + callback(cLangOpts, callbackContext, BCKTargetPointerAuthenticationScheme, + StringRef(value)); + break; + + case PlatformConditionKind::Endianness: + case PlatformConditionKind::PointerBitWidth: + case PlatformConditionKind::CanImport: + case PlatformConditionKind::HasAtomicBitWidth: + // Handled separately. + break; + } + } + + // Object file format. + llvm::Triple triple(langOpts.Target.getTriple()); + switch (triple.getObjectFormat()) { + case llvm::Triple::ObjectFormatType::COFF: + callback(cLangOpts, callbackContext, BCKTargetObjectFileFormat, + StringRef("COFF")); + break; + case llvm::Triple::ObjectFormatType::ELF: + callback(cLangOpts, callbackContext, BCKTargetObjectFileFormat, + StringRef("ELF")); + break; + case llvm::Triple::ObjectFormatType::MachO: + callback(cLangOpts, callbackContext, BCKTargetObjectFileFormat, + StringRef("MachO")); + break; + case llvm::Triple::ObjectFormatType::SPIRV: + callback(cLangOpts, callbackContext, BCKTargetObjectFileFormat, + StringRef("SPIRV")); + break; + case llvm::Triple::ObjectFormatType::Wasm: + callback(cLangOpts, callbackContext, BCKTargetObjectFileFormat, + StringRef("Wasm")); + break; + default: + // Ignore others. + break; + } +} diff --git a/lib/ASTGen/Sources/ASTGen/BuiltinPound.swift b/lib/ASTGen/Sources/ASTGen/BuiltinPound.swift index 8dbe88d23359b..93b6c367d7fd9 100644 --- a/lib/ASTGen/Sources/ASTGen/BuiltinPound.swift +++ b/lib/ASTGen/Sources/ASTGen/BuiltinPound.swift @@ -76,7 +76,7 @@ extension ASTGenVisitor { let keypathExpr = self.generateObjCKeyPathExpr(freestandingMacroExpansion: node) return .generated(.expr(keypathExpr)) - case .assert where ctx.langOptsHasFeature(.StaticAssert): + case .assert where ctx.langOpts.hasFeature(.StaticAssert): let assertStmtOpt = self.generatePoundAssertStmt(freestandingMacroExpansion: node) return .generated(assertStmtOpt.map({ .stmt($0.asStmt) })) @@ -143,7 +143,7 @@ extension ASTGenVisitor { } func generatePoundAssertStmt(freestandingMacroExpansion node: some FreestandingMacroExpansionSyntax) -> BridgedPoundAssertStmt? { - assert(self.ctx.langOptsHasFeature(.StaticAssert)) + assert(self.ctx.langOpts.hasFeature(.StaticAssert)) var args = node.arguments[...] let conditionExpr = self.generateConsumingAttrOption(args: &args, label: nil) { conditionNode in self.generate(expr: conditionNode) diff --git a/lib/ASTGen/Sources/ASTGen/CMakeLists.txt b/lib/ASTGen/Sources/ASTGen/CMakeLists.txt index 0094fbc0c3f28..971fca8d7c061 100644 --- a/lib/ASTGen/Sources/ASTGen/CMakeLists.txt +++ b/lib/ASTGen/Sources/ASTGen/CMakeLists.txt @@ -20,6 +20,7 @@ add_pure_swift_host_library(swiftASTGen STATIC CXX_INTEROP Regex.swift SourceFile.swift StableHasher.swift + StaticBuildConfiguration+ASTContext.swift Stmts.swift TypeAttrs.swift Types.swift @@ -27,6 +28,7 @@ add_pure_swift_host_library(swiftASTGen STATIC CXX_INTEROP DEPENDENCIES swiftAST SWIFT_DEPENDENCIES + _CompilerSwiftCompilerPluginMessageHandling _CompilerRegexParser _CompilerSwiftSyntax _CompilerSwiftIfConfig diff --git a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift index 257b02362f8f1..00a5c412470c4 100644 --- a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift +++ b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift @@ -30,21 +30,21 @@ struct CompilerBuildConfiguration: BuildConfiguration { func isCustomConditionSet(name: String) throws -> Bool { var name = name return name.withBridgedString { nameRef in - ctx.langOptsCustomConditionSet(nameRef) + ctx.langOpts.customConditionSet(nameRef) } } func hasFeature(name: String) throws -> Bool { var name = name return name.withBridgedString { nameRef in - ctx.langOptsHasFeatureNamed(nameRef) + ctx.langOpts.hasFeatureNamed(nameRef) } } func hasAttribute(name: String) throws -> Bool { var name = name return name.withBridgedString { nameRef in - ctx.langOptsHasAttributeNamed(nameRef) + ctx.langOpts.hasAttributeNamed(nameRef) } } @@ -89,21 +89,21 @@ struct CompilerBuildConfiguration: BuildConfiguration { func isActiveTargetOS(name: String) throws -> Bool { var name = name return name.withBridgedString { nameRef in - ctx.langOptsIsActiveTargetOS(nameRef) + ctx.langOpts.isActiveTargetOS(nameRef) } } func isActiveTargetArchitecture(name: String) throws -> Bool { var name = name return name.withBridgedString { nameRef in - ctx.langOptsIsActiveTargetArchitecture(nameRef) + ctx.langOpts.isActiveTargetArchitecture(nameRef) } } func isActiveTargetEnvironment(name: String) throws -> Bool { var name = name return name.withBridgedString { nameRef in - ctx.langOptsIsActiveTargetEnvironment(nameRef) + ctx.langOpts.isActiveTargetEnvironment(nameRef) } } @@ -117,31 +117,31 @@ struct CompilerBuildConfiguration: BuildConfiguration { } return name.withBridgedString { nameRef in - ctx.langOptsIsActiveTargetRuntime(nameRef) + ctx.langOpts.isActiveTargetRuntime(nameRef) } } func isActiveTargetPointerAuthentication(name: String) throws -> Bool { var name = name return name.withBridgedString { nameRef in - ctx.langOptsIsActiveTargetPtrAuth(nameRef) + ctx.langOpts.isActiveTargetPtrAuth(nameRef) } } var targetPointerBitWidth: Int { - Int(ctx.langOptsTargetPointerBitWidth) + Int(ctx.langOpts.targetPointerBitWidth) } var targetAtomicBitWidths: [Int] { var bitWidthsBuf: UnsafeMutablePointer? = nil - let count = ctx.langOptsGetTargetAtomicBitWidths(&bitWidthsBuf) + let count = ctx.langOpts.getTargetAtomicBitWidths(&bitWidthsBuf) let bitWidths = Array(UnsafeMutableBufferPointer(start: bitWidthsBuf, count: count)) deallocateIntBuffer(bitWidthsBuf); return bitWidths } var endianness: Endianness { - switch ctx.langOptsTargetEndianness { + switch ctx.langOpts.targetEndianness { case .EndianBig: return .big case .EndianLittle: return .little } @@ -149,7 +149,7 @@ struct CompilerBuildConfiguration: BuildConfiguration { var languageVersion: VersionTuple { var componentsBuf: UnsafeMutablePointer? = nil - let count = ctx.langOptsGetLanguageVersion(&componentsBuf) + let count = ctx.langOpts.getLanguageVersion(&componentsBuf) let version = VersionTuple( components: Array(UnsafeMutableBufferPointer(start: componentsBuf, count: count)) ) @@ -159,7 +159,7 @@ struct CompilerBuildConfiguration: BuildConfiguration { var compilerVersion: VersionTuple { var componentsBuf: UnsafeMutablePointer? = nil - let count = ctx.langOptsGetCompilerVersion(&componentsBuf) + let count = ctx.langOpts.getCompilerVersion(&componentsBuf) let version = VersionTuple( components: Array(UnsafeMutableBufferPointer(start: componentsBuf, count: count)) ) diff --git a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift index 50b26985daf02..d8f6c807c3940 100644 --- a/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift +++ b/lib/ASTGen/Sources/ASTGen/DeclAttrs.swift @@ -31,7 +31,7 @@ extension ASTGenVisitor { // Comments. COMMENT: if - self.ctx.langOptsAttachCommentsToDecls, + self.ctx.langOpts.attachCommentsToDecls, let firstTok = node.firstToken(viewMode: .sourceAccurate) { var pos = firstTok.position @@ -2228,7 +2228,7 @@ extension ASTGenVisitor { } func generateUnavailableInEmbeddedAttr(attribute node: AttributeSyntax) -> BridgedAvailableAttr? { - if ctx.langOptsHasFeature(.Embedded) { + if ctx.langOpts.hasFeature(.Embedded) { return BridgedAvailableAttr.createUnavailableInEmbedded( self.ctx, atLoc: self.generateSourceLoc(node.atSign), diff --git a/lib/ASTGen/Sources/ASTGen/Decls.swift b/lib/ASTGen/Sources/ASTGen/Decls.swift index 4fc9d279cdcd9..5d0b78fbc2ea7 100644 --- a/lib/ASTGen/Sources/ASTGen/Decls.swift +++ b/lib/ASTGen/Sources/ASTGen/Decls.swift @@ -396,10 +396,10 @@ extension ASTGenVisitor { case .`init`: return .Init case .read: - precondition(ctx.langOptsHasFeature(.CoroutineAccessors), "(compiler bug) 'read' accessor should only be parsed with 'CoroutineAccessors' feature") + precondition(ctx.langOpts.hasFeature(.CoroutineAccessors), "(compiler bug) 'read' accessor should only be parsed with 'CoroutineAccessors' feature") return .read case .modify: - precondition(ctx.langOptsHasFeature(.CoroutineAccessors), "(compiler bug) 'modify' accessor should only be parsed with 'CoroutineAccessors' feature") + precondition(ctx.langOpts.hasFeature(.CoroutineAccessors), "(compiler bug) 'modify' accessor should only be parsed with 'CoroutineAccessors' feature") return .modify default: self.diagnose(.unknownAccessorSpecifier(specifier)) diff --git a/lib/ASTGen/Sources/ASTGen/SourceFile.swift b/lib/ASTGen/Sources/ASTGen/SourceFile.swift index c9981bd320063..cfe23e0be7318 100644 --- a/lib/ASTGen/Sources/ASTGen/SourceFile.swift +++ b/lib/ASTGen/Sources/ASTGen/SourceFile.swift @@ -72,7 +72,7 @@ extension Parser.ExperimentalFeatures { guard let context = context else { return } func mapFeature(_ bridged: BridgedFeature, to feature: Self) { - if context.langOptsHasFeature(bridged) { + if context.langOpts.hasFeature(bridged) { insert(feature) } } diff --git a/lib/ASTGen/Sources/ASTGen/StaticBuildConfiguration+ASTContext.swift b/lib/ASTGen/Sources/ASTGen/StaticBuildConfiguration+ASTContext.swift new file mode 100644 index 0000000000000..c3e1d39750bf8 --- /dev/null +++ b/lib/ASTGen/Sources/ASTGen/StaticBuildConfiguration+ASTContext.swift @@ -0,0 +1,133 @@ +//===--- StaticBuildConfiguration+ASTContext.swift ------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022-2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import ASTBridging +@_spi(PluginMessage) import SwiftCompilerPluginMessageHandling +import SwiftDiagnostics +@_spi(Compiler) import SwiftIfConfig +@_spi(ExperimentalLanguageFeatures) import SwiftParser +@_spi(ExperimentalLanguageFeatures) import SwiftSyntax + +extension StaticBuildConfiguration { + /// Configuration entries captured in the initializer from a bridged context. + private struct ConfigurationEntries { + var customConditions: Set = [] + var features: Set = [] + var attributes: Set = [] + var targetOSNames: Set = [] + var targetArchitectures: Set = [] + var targetEnvironments: Set = [] + var targetRuntimes: Set = [] + var targetPointerAuthenticationSchemes: Set = [] + var targetObjectFileFormats: Set = [] + } + + /// Initialize a static build configuration for the given language options. + init(langOptions: BridgedLangOptions) { + var entries = ConfigurationEntries() + + langOptions.enumerateBuildConfigurationEntries(callbackContext: &entries) { cContext, entries, key, value in + let entries = entries.assumingMemoryBound(to: ConfigurationEntries.self) + switch key { + case .BCKAttribute: + entries.pointee.attributes.insert(String(bridged: value)) + case .BCKCustomCondition: + entries.pointee.customConditions.insert(String(bridged: value)) + case .BCKFeature: + entries.pointee.features.insert(String(bridged: value)) + case .BCKTargetOSName: + entries.pointee.targetOSNames.insert(String(bridged: value)) + case .BCKTargetArchitecture: + entries.pointee.targetArchitectures.insert(String(bridged: value)) + case .BCKTargetEnvironment: + entries.pointee.targetEnvironments.insert(String(bridged: value)) + case .BCKTargetRuntime: + entries.pointee.targetRuntimes.insert(String(bridged: value)) + case .BCKTargetPointerAuthenticationScheme: + entries.pointee.targetPointerAuthenticationSchemes.insert(String(bridged: value)) + case .BCKTargetObjectFileFormat: + entries.pointee.targetObjectFileFormats.insert(String(bridged: value)) + } + } + + let targetPointerBitWidth = Int(langOptions.targetPointerBitWidth) + + // Atomic bit widths. + let targetAtomicBitWidths: [Int] + do { + var bitWidthsBuf: UnsafeMutablePointer? = nil + let bitWidthsCount = langOptions.getTargetAtomicBitWidths(&bitWidthsBuf) + targetAtomicBitWidths = Array(UnsafeMutableBufferPointer(start: bitWidthsBuf, count: bitWidthsCount)) + deallocateIntBuffer(bitWidthsBuf); + } + + let endianness: Endianness + switch langOptions.targetEndianness { + case .EndianBig: endianness = .big + case .EndianLittle: endianness = .little + } + + let languageVersion = getVersionTuple { langOptions.getLanguageVersion(&$0) } + let compilerVersion = getVersionTuple { langOptions.getCompilerVersion(&$0) } + self.init( + customConditions: entries.customConditions, + features: entries.features, + attributes: entries.attributes, + targetOSs: entries.targetOSNames, + targetArchitectures: entries.targetArchitectures, + targetEnvironments: entries.targetEnvironments, + targetRuntimes: entries.targetRuntimes, + targetPointerAuthenticationSchemes: entries.targetPointerAuthenticationSchemes, + targetObjectFileFormats: entries.targetObjectFileFormats, + targetPointerBitWidth: targetPointerBitWidth, + targetAtomicBitWidths: targetAtomicBitWidths, + endianness: endianness, + languageVersion: languageVersion, + compilerVersion: compilerVersion + ) + } +} + +/// Get a version tuple from C++. +private func getVersionTuple( + body: (inout UnsafeMutablePointer?) -> Int +) -> VersionTuple { + var componentsBuf: UnsafeMutablePointer? = nil + let count = body(&componentsBuf) + let version = VersionTuple( + components: Array(UnsafeMutableBufferPointer(start: componentsBuf, count: count)) + ) + deallocateIntBuffer(componentsBuf); + return version +} + +@_cdecl("swift_ASTGen_printStaticBuildConfiguration") +public func printStaticBuildConfiguration( + langOptions: BridgedLangOptions +) -> BridgedStringRef { + let config = StaticBuildConfiguration(langOptions: langOptions) + let result = try? JSON.encode(config).withUnsafeBufferPointer { buffer in + let ptr = UnsafeMutablePointer.allocate( + capacity: buffer.count + 1 + ) + if let baseAddress = buffer.baseAddress { + ptr.initialize(from: baseAddress, count: buffer.count) + } + + // null terminate, for client's convenience. + ptr[buffer.count] = 0 + + return BridgedStringRef(data: ptr, count: buffer.count) + } + + return result ?? BridgedStringRef() +} diff --git a/lib/Basic/LangOptions.cpp b/lib/Basic/LangOptions.cpp index 7d6e0a1eafceb..114b81a20ae53 100644 --- a/lib/Basic/LangOptions.cpp +++ b/lib/Basic/LangOptions.cpp @@ -252,6 +252,9 @@ LangOptions::getPlatformConditionValue(PlatformConditionKind Kind) const { bool LangOptions:: checkPlatformCondition(PlatformConditionKind Kind, StringRef Value) const { + // Note: BridgedASTContext_enumerateBuildConfigurationEntries has a redundant + // copy of these special cases. + // Check a special case that "macOS" is an alias of "OSX". if (Kind == PlatformConditionKind::OS && Value == "macOS") return checkPlatformCondition(Kind, "OSX"); diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 60903dd63226d..fc81cd8dd8779 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -1985,6 +1985,27 @@ bool Driver::handleImmediateArgs(const ArgList &Args, const ToolChain &TC) { return false; } + if (Args.hasArg(options::OPT_print_static_build_config)) { + SmallVector commandLine; + commandLine.push_back("-frontend"); + commandLine.push_back("-print-static-build-config"); + + std::string executable = getSwiftProgramPath(); + + // FIXME(https://github.com/apple/swift/issues/54554): This bypasses + // mechanisms like -v and -###. + sys::TaskQueue queue; + queue.addTask(executable.c_str(), commandLine); + queue.execute(nullptr, + [](sys::ProcessId PID, int returnCode, StringRef output, + StringRef errors, sys::TaskProcessInformation ProcInfo, + void *unused) -> sys::TaskFinishedResponse { + llvm::outs() << output; + llvm::errs() << errors; + return sys::TaskFinishedResponse::ContinueExecution; + }); + return false; + } return true; } diff --git a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp index 84a7045a7d184..8e20de012dea8 100644 --- a/lib/Frontend/ArgsToFrontendOptionsConverter.cpp +++ b/lib/Frontend/ArgsToFrontendOptionsConverter.cpp @@ -210,6 +210,10 @@ bool ArgsToFrontendOptionsConverter::convert( Opts.PrintTargetInfo = true; } + if (Args.hasArg(OPT_print_static_build_config)) { + Opts.PrintBuildConfig = true; + } + if (Args.hasArg(OPT_print_supported_features)) { Opts.PrintSupportedFeatures = true; } diff --git a/lib/FrontendTool/CMakeLists.txt b/lib/FrontendTool/CMakeLists.txt index e21505a2d6c57..e5001cde931af 100644 --- a/lib/FrontendTool/CMakeLists.txt +++ b/lib/FrontendTool/CMakeLists.txt @@ -27,4 +27,9 @@ target_link_libraries(swiftFrontendTool PRIVATE swiftSILOptimizer swiftThreading) +if (SWIFT_BUILD_SWIFT_SYNTAX) + target_link_libraries(swiftFrontendTool PRIVATE + swiftASTGen) +endif() + set_swift_llvm_is_available(swiftFrontendTool) diff --git a/lib/FrontendTool/FrontendTool.cpp b/lib/FrontendTool/FrontendTool.cpp index 7544562cfe3d3..de7f4ada33625 100644 --- a/lib/FrontendTool/FrontendTool.cpp +++ b/lib/FrontendTool/FrontendTool.cpp @@ -23,6 +23,7 @@ #include "swift/FrontendTool/FrontendTool.h" #include "Dependencies.h" #include "TBD.h" +#include "swift/AST/ASTBridging.h" #include "swift/AST/ASTDumper.h" #include "swift/AST/ASTMangler.h" #include "swift/AST/AvailabilityScope.h" @@ -38,6 +39,7 @@ #include "swift/AST/NameLookup.h" #include "swift/AST/TBDGenRequests.h" #include "swift/Basic/Assertions.h" +#include "swift/Basic/BasicBridging.h" #include "swift/Basic/Defer.h" #include "swift/Basic/Edit.h" #include "swift/Basic/FileSystem.h" @@ -50,6 +52,7 @@ #include "swift/Basic/TargetInfo.h" #include "swift/Basic/UUID.h" #include "swift/Basic/Version.h" +#include "swift/Bridging/ASTGen.h" #include "swift/ConstExtract/ConstExtract.h" #include "swift/DependencyScan/ScanDependencies.h" #include "swift/Frontend/CachedDiagnostics.h" @@ -2255,6 +2258,14 @@ class PrettyStackTraceFrontend : public llvm::PrettyStackTraceEntry { }; }; +#if SWIFT_BUILD_SWIFT_SYNTAX +#pragma clang diagnostic push +#pragma clang diagnostic ignored "-Wreturn-type-c-linkage" +extern "C" BridgedStringRef +swift_ASTGen_printStaticBuildConfiguration(BridgedLangOptions cLangOpts); +#pragma clang diagnostic pop +#endif + int swift::performFrontend(ArrayRef Args, const char *Argv0, void *MainAddr, FrontendObserver *observer) { @@ -2385,6 +2396,16 @@ int swift::performFrontend(ArrayRef Args, return finishDiagProcessing(0, /*verifierEnabled*/ false); } + if (Invocation.getFrontendOptions().PrintBuildConfig) { +#if SWIFT_BUILD_SWIFT_SYNTAX + auto resultText = + swift_ASTGen_printStaticBuildConfiguration(Invocation.getLangOptions()); + llvm::outs() << resultText.unbridged(); + swift_ASTGen_freeBridgedString(resultText); +#endif + return finishDiagProcessing(0, /*verifierEnabled*/ false); + } + if (Invocation.getFrontendOptions().PrintSupportedFeatures) { swift::features::printSupportedFeatures(llvm::outs()); return finishDiagProcessing(0, /*verifierEnabled*/ false); diff --git a/test/Frontend/print-static-build-config.swift b/test/Frontend/print-static-build-config.swift new file mode 100644 index 0000000000000..70ac0c9a12fb4 --- /dev/null +++ b/test/Frontend/print-static-build-config.swift @@ -0,0 +1,10 @@ +// RUN: %target-swift-frontend -print-static-build-config -DSOMETHING | %FileCheck %s +// REQUIRES: swift_swift_parser + +// CHECK: "attributes": +// CHECK-SAME: "escaping" + +// CHECK-SAME: "customConditions":["SOMETHING"] + +// CHECK-SAME: "features": +// CHECK-SAME: "AttachedMacros" From 3082b04b7505f84005d597a048ca416165c2a078 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 29 Sep 2025 17:07:43 -0700 Subject: [PATCH 2/3] [Macros] Feed the static build configuration into macro expansions Thread the static build configuration (formed from language options) in to the macro plugin handler, which will serialize it for use in the macro implementation. test this with a simple macro that checks whether a particular custom configuration (set via `-D`) is enabled or not. This required some re-layering, sinking the logic for building a StaticBuildConfiguration from language options down into a new swiftBasicSwift library, which sits on top of the C++ swiftBasic and provides Swift functionality for it. That can be used by the C++ swiftAST to cache the StaticBuildConfiguration on the ASTContext, making it available for other parts of ASTGen. --- include/swift/AST/ASTBridging.h | 119 ++---------------- include/swift/AST/ASTContextGlobalCache.h | 4 + include/swift/Basic/BasicBridging.h | 107 ++++++++++++++++ include/swift/Bridging/BasicSwift.h | 32 +++++ include/swift/Bridging/MacroEvaluation.h | 5 +- lib/AST/Bridging/ASTContextBridging.cpp | 25 ++++ lib/AST/Bridging/CMakeLists.txt | 1 - lib/AST/CMakeLists.txt | 2 +- lib/ASTGen/Sources/ASTGen/Bridge.swift | 15 --- lib/ASTGen/Sources/ASTGen/CMakeLists.txt | 2 +- .../ASTGen/CompilerBuildConfiguration.swift | 11 ++ lib/ASTGen/Sources/ASTGen/Exprs.swift | 1 + lib/ASTGen/Sources/BasicSwift/CMakeLists.txt | 11 ++ ...taticBuildConfiguration+LangOptions.swift} | 16 +++ .../BasicSwift/String+BridgedString.swift | 28 +++++ lib/ASTGen/Sources/CMakeLists.txt | 1 + .../Sources/MacroEvaluation/Macros.swift | 67 +++++----- .../Sources/MacroEvaluation/PluginHost.swift | 4 +- .../MacroEvaluation/SourceManager.swift | 4 + lib/Basic/CMakeLists.txt | 1 + .../LangOptionsBridging.cpp | 95 ++++++++++++-- lib/Sema/TypeCheckMacros.cpp | 6 +- .../Inputs/syntax_macro_definitions.swift | 18 +++ test/Macros/macro_build_config.swift | 17 +++ test/Macros/macro_plugin_basic.swift | 4 +- test/Macros/macro_plugin_error.swift | 6 +- test/Macros/macro_plugin_server.swift | 10 +- 27 files changed, 432 insertions(+), 180 deletions(-) create mode 100644 include/swift/Bridging/BasicSwift.h create mode 100644 lib/ASTGen/Sources/BasicSwift/CMakeLists.txt rename lib/ASTGen/Sources/{ASTGen/StaticBuildConfiguration+ASTContext.swift => BasicSwift/StaticBuildConfiguration+LangOptions.swift} (88%) create mode 100644 lib/ASTGen/Sources/BasicSwift/String+BridgedString.swift rename lib/{AST/Bridging => Basic}/LangOptionsBridging.cpp (74%) create mode 100644 test/Macros/macro_build_config.swift diff --git a/include/swift/AST/ASTBridging.h b/include/swift/AST/ASTBridging.h index 336aa0fafb2a6..ec88cb660a4f0 100644 --- a/include/swift/AST/ASTBridging.h +++ b/include/swift/AST/ASTBridging.h @@ -194,115 +194,6 @@ BridgedDeclNameLoc_createParsed(BridgedASTContext cContext, swift::SourceLoc moduleSelectorLoc, swift::SourceLoc baseNameLoc); -//===----------------------------------------------------------------------===// -// MARK: LangOptions -//===----------------------------------------------------------------------===// - -enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedEndianness : size_t { - EndianLittle, - EndianBig, -}; - -class BridgedLangOptions { - const swift::LangOptions * _Nonnull LangOpts; - -public: - SWIFT_UNAVAILABLE("Use init(raw:) instead") - BRIDGED_INLINE BridgedLangOptions(const swift::LangOptions &langOpts); - - SWIFT_UNAVAILABLE("Use '.raw' instead") - BRIDGED_INLINE const swift::LangOptions &unbridged() const; - - SWIFT_COMPUTED_PROPERTY - const void *_Nonnull getRaw() const { return LangOpts; } - - SWIFT_COMPUTED_PROPERTY - unsigned getMajorLanguageVersion() const; - - SWIFT_COMPUTED_PROPERTY - unsigned getTargetPointerBitWidth() const; - - SWIFT_COMPUTED_PROPERTY - BridgedEndianness getTargetEndianness() const; - - SWIFT_COMPUTED_PROPERTY - bool getAttachCommentsToDecls() const; -}; - -/// Key used when enumerating build configuration entries to the -/// StaticBuildConfiguration initializer for an ASTContext. -enum ENUM_EXTENSIBILITY_ATTR(closed) BuildConfigurationKey : size_t { - BCKCustomCondition, - BCKFeature, - BCKAttribute, - BCKTargetOSName, - BCKTargetArchitecture, - BCKTargetEnvironment, - BCKTargetRuntime, - BCKTargetPointerAuthenticationScheme, - BCKTargetObjectFileFormat -}; - -SWIFT_NAME("BridgedLangOptions.hasFeature(self:_:)") -bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts, - BridgedFeature feature); - -SWIFT_NAME("BridgedLangOptions.customConditionSet(self:_:)") -bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.hasFeatureNamed(self:_:)") -bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.hasAttributeNamed(self:_:)") -bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetOS(self:_:)") -bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetArchitecture(self:_:)") -bool BridgedLangOptions_isActiveTargetArchitecture(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetEnvironment(self:_:)") -bool BridgedLangOptions_isActiveTargetEnvironment(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetRuntime(self:_:)") -bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetPtrAuth(self:_:)") -bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.getTargetAtomicBitWidths(self:_:)") -SwiftInt BridgedLangOptions_getTargetAtomicBitWidths(BridgedLangOptions cLangOpts, - SwiftInt* _Nullable * _Nonnull cComponents); - -SWIFT_NAME("BridgedLangOptions.getLanguageVersion(self:_:)") -SwiftInt BridgedLangOptions_getLanguageVersion(BridgedLangOptions cLangOpts, - SwiftInt* _Nullable * _Nonnull cComponents); - -SWIFT_NAME("BridgedLangOptions.getCompilerVersion(self:_:)") -SwiftInt BridgedLangOptions_getCompilerVersion(BridgedLangOptions cLangOpts, - SwiftInt* _Nullable * _Nonnull cComponents); - -/* Deallocate an array of Swift int values that was allocated in C++. */ -void deallocateIntBuffer(SwiftInt * _Nullable cComponents); - -/// Enumerate all of the key/value pairs for the build configuration by calling -/// the given callback for each one. -SWIFT_NAME("BridgedLangOptions.enumerateBuildConfigurationEntries(self:callbackContext:callback:)") -void BridgedLangOptions_enumerateBuildConfigurationEntries( - BridgedLangOptions cLangOpts, - void * _Nonnull callbackContext, - void (* _Nonnull callback)( - BridgedLangOptions cLangOpts, void * _Nonnull callbackContext, - BuildConfigurationKey key, BridgedStringRef value)); //===----------------------------------------------------------------------===// // MARK: ASTContext @@ -326,6 +217,9 @@ class BridgedASTContext { SWIFT_COMPUTED_PROPERTY BridgedAvailabilityMacroMap getAvailabilityMacroMap() const; + + SWIFT_COMPUTED_PROPERTY + BridgedDiagnosticEngine getDiags() const; }; #define IDENTIFIER_WITH_NAME(Name, _) \ @@ -360,6 +254,10 @@ BridgedASTContext_getDollarIdentifier(BridgedASTContext cContext, size_t idx); SWIFT_NAME("getter:BridgedASTContext.langOpts(self:)") BridgedLangOptions BridgedASTContext_langOpts(BridgedASTContext cContext); +SWIFT_NAME("BridgedLangOptions.hasAttributeNamed(self:_:)") +bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedCanImportVersion : size_t { CanImportUnversioned, CanImportVersion, @@ -374,6 +272,9 @@ bool BridgedASTContext_canImport(BridgedASTContext cContext, const SwiftInt *_Nullable versionComponents, SwiftInt numVersionComponents); +SWIFT_NAME("getter:BridgedASTContext.staticBuildConfigurationPtr(self:)") +void * _Nonnull BridgedASTContext_staticBuildConfiguration(BridgedASTContext cContext); + //===----------------------------------------------------------------------===// // MARK: AST nodes //===----------------------------------------------------------------------===// diff --git a/include/swift/AST/ASTContextGlobalCache.h b/include/swift/AST/ASTContextGlobalCache.h index a57e5bc249f66..e4aeb0415232f 100644 --- a/include/swift/AST/ASTContextGlobalCache.h +++ b/include/swift/AST/ASTContextGlobalCache.h @@ -84,6 +84,10 @@ struct ASTContext::GlobalCache { const NormalProtocolConformance *, std::vector > conformanceIsolationErrors; + + /// The static build configuration. This points to an instance of the Swift + /// StaticBuildConfiguration. + void *StaticBuildConfiguration = nullptr; }; } // end namespace diff --git a/include/swift/Basic/BasicBridging.h b/include/swift/Basic/BasicBridging.h index 0c7f3d20bab8d..ee696f09f09c4 100644 --- a/include/swift/Basic/BasicBridging.h +++ b/include/swift/Basic/BasicBridging.h @@ -61,6 +61,7 @@ class VersionTuple; } // end namespace llvm namespace swift { +class LangOptions; class SourceLoc; class SourceRange; class CharSourceRange; @@ -451,6 +452,112 @@ struct BridgedSwiftClosure { BRIDGED_INLINE void operator()(const void *_Nullable); }; +//===----------------------------------------------------------------------===// +// MARK: LangOptions +//===----------------------------------------------------------------------===// + +enum ENUM_EXTENSIBILITY_ATTR(closed) BridgedEndianness : size_t { + EndianLittle, + EndianBig, +}; + +class BridgedLangOptions { + const swift::LangOptions * _Nonnull LangOpts; + +public: + SWIFT_UNAVAILABLE("Use init(raw:) instead") + BRIDGED_INLINE BridgedLangOptions(const swift::LangOptions &langOpts); + + SWIFT_UNAVAILABLE("Use '.raw' instead") + BRIDGED_INLINE const swift::LangOptions &unbridged() const; + + SWIFT_COMPUTED_PROPERTY + const void *_Nonnull getRaw() const { return LangOpts; } + + SWIFT_COMPUTED_PROPERTY + unsigned getMajorLanguageVersion() const; + + SWIFT_COMPUTED_PROPERTY + unsigned getTargetPointerBitWidth() const; + + SWIFT_COMPUTED_PROPERTY + BridgedEndianness getTargetEndianness() const; + + SWIFT_COMPUTED_PROPERTY + bool getAttachCommentsToDecls() const; +}; + +/// Key used when enumerating build configuration entries to the +/// StaticBuildConfiguration initializer for an ASTContext. +enum ENUM_EXTENSIBILITY_ATTR(closed) BuildConfigurationKey : size_t { + BCKCustomCondition, + BCKFeature, + BCKAttribute, + BCKTargetOSName, + BCKTargetArchitecture, + BCKTargetEnvironment, + BCKTargetRuntime, + BCKTargetPointerAuthenticationScheme, + BCKTargetObjectFileFormat +}; + +SWIFT_NAME("BridgedLangOptions.hasFeature(self:_:)") +bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts, + BridgedFeature feature); + +SWIFT_NAME("BridgedLangOptions.customConditionSet(self:_:)") +bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.hasFeatureNamed(self:_:)") +bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetOS(self:_:)") +bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetArchitecture(self:_:)") +bool BridgedLangOptions_isActiveTargetArchitecture(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetEnvironment(self:_:)") +bool BridgedLangOptions_isActiveTargetEnvironment(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetRuntime(self:_:)") +bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.isActiveTargetPtrAuth(self:_:)") +bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts, + BridgedStringRef cName); + +SWIFT_NAME("BridgedLangOptions.getTargetAtomicBitWidths(self:_:)") +SwiftInt BridgedLangOptions_getTargetAtomicBitWidths(BridgedLangOptions cLangOpts, + SwiftInt* _Nullable * _Nonnull cComponents); + +SWIFT_NAME("BridgedLangOptions.getLanguageVersion(self:_:)") +SwiftInt BridgedLangOptions_getLanguageVersion(BridgedLangOptions cLangOpts, + SwiftInt* _Nullable * _Nonnull cComponents); + +SWIFT_NAME("BridgedLangOptions.getCompilerVersion(self:_:)") +SwiftInt BridgedLangOptions_getCompilerVersion(BridgedLangOptions cLangOpts, + SwiftInt* _Nullable * _Nonnull cComponents); + +/* Deallocate an array of Swift int values that was allocated in C++. */ +void deallocateIntBuffer(SwiftInt * _Nullable cComponents); + +/// Enumerate all of the key/value pairs for the build configuration by calling +/// the given callback for each one. +SWIFT_NAME("BridgedLangOptions.enumerateBuildConfigurationEntries(self:callbackContext:callback:)") +void BridgedLangOptions_enumerateBuildConfigurationEntries( + BridgedLangOptions cLangOpts, + void * _Nonnull callbackContext, + void (* _Nonnull callback)( + BridgedLangOptions cLangOpts, void * _Nonnull callbackContext, + BuildConfigurationKey key, BridgedStringRef value)); + SWIFT_END_NULLABILITY_ANNOTATIONS #ifndef PURE_BRIDGING_MODE diff --git a/include/swift/Bridging/BasicSwift.h b/include/swift/Bridging/BasicSwift.h new file mode 100644 index 0000000000000..a2cb3f8fea606 --- /dev/null +++ b/include/swift/Bridging/BasicSwift.h @@ -0,0 +1,32 @@ +//===--- BasicSwift.h -------------------------------------------*- C++ -*-===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2023 - 2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +#ifndef SWIFT_BRIDGING_BASICSWIFT_H +#define SWIFT_BRIDGING_BASICSWIFT_H + +#include "swift/Basic/BasicBridging.h" + +#ifdef __cplusplus +extern "C" { +#endif + +/// Create a new static build configuration for the given language options. +void * _Nonnull swift_Basic_createStaticBuildConfiguration(BridgedLangOptions cLangOpts); + +/// Free the given static build configuration. +void swift_Basic_freeStaticBuildConfiguration(void * _Nonnull staticBuildConfiguration); + +#ifdef __cplusplus +} +#endif + +#endif // SWIFT_BRIDGING_BASICSWIFT_H diff --git a/include/swift/Bridging/MacroEvaluation.h b/include/swift/Bridging/MacroEvaluation.h index 1df6e130ee1db..650accc61122c 100644 --- a/include/swift/Bridging/MacroEvaluation.h +++ b/include/swift/Bridging/MacroEvaluation.h @@ -14,6 +14,7 @@ #define SWIFT_BRIDGING_MACROS_H #include "swift/Basic/BasicBridging.h" +#include "swift/AST/ASTBridging.h" #ifdef __cplusplus extern "C" { @@ -40,13 +41,13 @@ void swift_Macros_freeExpansionReplacements( ptrdiff_t *_Nullable replacementsPtr, ptrdiff_t numReplacements); ptrdiff_t swift_Macros_expandFreestandingMacro( - void *_Nonnull diagEngine, const void *_Nonnull macro, + BridgedASTContext cContext, const void *_Nonnull macro, const char *_Nonnull discriminator, uint8_t rawMacroRole, void *_Nonnull sourceFile, const void *_Nullable sourceLocation, BridgedStringRef *_Nonnull evaluatedSourceOut); ptrdiff_t swift_Macros_expandAttachedMacro( - void *_Nonnull diagEngine, const void *_Nonnull macro, + BridgedASTContext cContext, const void *_Nonnull macro, const char *_Nonnull discriminator, const char *_Nonnull qualifiedType, const char *_Nonnull conformances, uint8_t rawMacroRole, void *_Nonnull customAttrSourceFile, diff --git a/lib/AST/Bridging/ASTContextBridging.cpp b/lib/AST/Bridging/ASTContextBridging.cpp index 8184929c84d30..94a6e4fa47b9b 100644 --- a/lib/AST/Bridging/ASTContextBridging.cpp +++ b/lib/AST/Bridging/ASTContextBridging.cpp @@ -13,7 +13,9 @@ #include "swift/AST/ASTBridging.h" #include "swift/AST/ASTContext.h" +#include "swift/AST/ASTContextGlobalCache.h" #include "swift/AST/AvailabilitySpec.h" +#include "swift/Bridging/BasicSwift.h" using namespace swift; @@ -44,6 +46,10 @@ unsigned BridgedASTContext::getMajorLanguageVersion() const { return unbridged().LangOpts.EffectiveLanguageVersion[0]; } +BridgedDiagnosticEngine BridgedASTContext::getDiags() const { + return &unbridged().Diags; +} + bool BridgedASTContext_canImport(BridgedASTContext cContext, BridgedStringRef importPath, SourceLoc canImportLoc, @@ -82,3 +88,22 @@ bool BridgedASTContext_canImport(BridgedASTContext cContext, BridgedAvailabilityMacroMap BridgedASTContext::getAvailabilityMacroMap() const { return &unbridged().getAvailabilityMacroMap(); } + +bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts, + BridgedStringRef cName) { + return hasAttribute(cLangOpts.unbridged(), cName.unbridged()); +} + +void *BridgedASTContext_staticBuildConfiguration(BridgedASTContext cContext) { + ASTContext &ctx = cContext.unbridged(); + void *staticBuildConfiguration = ctx.getGlobalCache().StaticBuildConfiguration; + if (!staticBuildConfiguration) { + staticBuildConfiguration = + swift_Basic_createStaticBuildConfiguration(ctx.LangOpts); + ctx.addCleanup([staticBuildConfiguration] { + swift_Basic_freeStaticBuildConfiguration(staticBuildConfiguration); + }); + } + + return staticBuildConfiguration; +} diff --git a/lib/AST/Bridging/CMakeLists.txt b/lib/AST/Bridging/CMakeLists.txt index 72e6c0fbdb9bd..277fdaca350a7 100644 --- a/lib/AST/Bridging/CMakeLists.txt +++ b/lib/AST/Bridging/CMakeLists.txt @@ -7,7 +7,6 @@ target_sources(swiftAST PRIVATE DiagnosticsBridging.cpp ExprBridging.cpp GenericsBridging.cpp - LangOptionsBridging.cpp MiscBridging.cpp PatternBridging.cpp PluginBridging.cpp diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index 586182c6cc9ce..17b748e1ee468 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -180,7 +180,7 @@ target_link_libraries(swiftAST if (SWIFT_BUILD_SWIFT_SYNTAX) target_link_libraries(swiftAST - PRIVATE swiftASTGen) + PRIVATE swiftASTGen swiftBasicSwift) endif() set_swift_llvm_is_available(swiftAST) diff --git a/lib/ASTGen/Sources/ASTGen/Bridge.swift b/lib/ASTGen/Sources/ASTGen/Bridge.swift index 7846b5245d126..257a4cca8642b 100644 --- a/lib/ASTGen/Sources/ASTGen/Bridge.swift +++ b/lib/ASTGen/Sources/ASTGen/Bridge.swift @@ -126,21 +126,6 @@ extension BridgedLabeledStmtInfo: /*@retroactive*/ Swift.ExpressibleByNilLiteral } } -extension String { - init(bridged: BridgedStringRef) { - self.init( - decoding: UnsafeBufferPointer(start: bridged.data, count: bridged.count), - as: UTF8.self - ) - } - - public mutating func withBridgedString(_ body: (BridgedStringRef) throws -> R) rethrows -> R { - try withUTF8 { buffer in - try body(BridgedStringRef(data: buffer.baseAddress, count: buffer.count)) - } - } -} - extension SyntaxText { var bridged: BridgedStringRef { BridgedStringRef(data: self.baseAddress, count: self.count) diff --git a/lib/ASTGen/Sources/ASTGen/CMakeLists.txt b/lib/ASTGen/Sources/ASTGen/CMakeLists.txt index 971fca8d7c061..678a23509cc43 100644 --- a/lib/ASTGen/Sources/ASTGen/CMakeLists.txt +++ b/lib/ASTGen/Sources/ASTGen/CMakeLists.txt @@ -20,7 +20,6 @@ add_pure_swift_host_library(swiftASTGen STATIC CXX_INTEROP Regex.swift SourceFile.swift StableHasher.swift - StaticBuildConfiguration+ASTContext.swift Stmts.swift TypeAttrs.swift Types.swift @@ -38,4 +37,5 @@ add_pure_swift_host_library(swiftASTGen STATIC CXX_INTEROP _CompilerSwiftParser _CompilerSwiftParserDiagnostics _CompilerSwiftDiagnostics + swiftBasicSwift ) diff --git a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift index 00a5c412470c4..f095fb2e5563e 100644 --- a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift +++ b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift @@ -10,12 +10,23 @@ // //===----------------------------------------------------------------------===// +import BasicBridging import ASTBridging +import swiftBasicSwift import SwiftDiagnostics @_spi(Compiler) import SwiftIfConfig @_spi(ExperimentalLanguageFeatures) import SwiftParser @_spi(ExperimentalLanguageFeatures) import SwiftSyntax +extension BridgedASTContext { + /// Retrieve the (cached) static build configuration for this ASTContext. + public var staticBuildConfiguration: StaticBuildConfiguration { + staticBuildConfigurationPtr.assumingMemoryBound( + to: StaticBuildConfiguration.self + ).pointee + } +} + /// A build configuration that uses the compiler's ASTContext to answer /// queries. struct CompilerBuildConfiguration: BuildConfiguration { diff --git a/lib/ASTGen/Sources/ASTGen/Exprs.swift b/lib/ASTGen/Sources/ASTGen/Exprs.swift index bd69b2b3a6054..c30c23e06fc50 100644 --- a/lib/ASTGen/Sources/ASTGen/Exprs.swift +++ b/lib/ASTGen/Sources/ASTGen/Exprs.swift @@ -11,6 +11,7 @@ //===----------------------------------------------------------------------===// import ASTBridging +import swiftBasicSwift import SwiftDiagnostics @_spi(Compiler) import SwiftParser @_spi(ExperimentalLanguageFeatures) @_spi(RawSyntax) import SwiftSyntax diff --git a/lib/ASTGen/Sources/BasicSwift/CMakeLists.txt b/lib/ASTGen/Sources/BasicSwift/CMakeLists.txt new file mode 100644 index 0000000000000..beeb67ef70cc2 --- /dev/null +++ b/lib/ASTGen/Sources/BasicSwift/CMakeLists.txt @@ -0,0 +1,11 @@ +add_pure_swift_host_library(swiftBasicSwift STATIC CXX_INTEROP + StaticBuildConfiguration+LangOptions.swift + String+BridgedString.swift + + DEPENDENCIES + swiftBasic + SWIFT_DEPENDENCIES + _CompilerSwiftCompilerPluginMessageHandling + _CompilerSwiftSyntax + _CompilerSwiftIfConfig +) diff --git a/lib/ASTGen/Sources/ASTGen/StaticBuildConfiguration+ASTContext.swift b/lib/ASTGen/Sources/BasicSwift/StaticBuildConfiguration+LangOptions.swift similarity index 88% rename from lib/ASTGen/Sources/ASTGen/StaticBuildConfiguration+ASTContext.swift rename to lib/ASTGen/Sources/BasicSwift/StaticBuildConfiguration+LangOptions.swift index c3e1d39750bf8..7bdd51e6ae3f3 100644 --- a/lib/ASTGen/Sources/ASTGen/StaticBuildConfiguration+ASTContext.swift +++ b/lib/ASTGen/Sources/BasicSwift/StaticBuildConfiguration+LangOptions.swift @@ -131,3 +131,19 @@ public func printStaticBuildConfiguration( return result ?? BridgedStringRef() } + +@_cdecl("swift_Basic_createStaticBuildConfiguration") +public func createStaticBuildConfiguration( + cLangOpts: BridgedLangOptions +) -> UnsafeMutableRawPointer { + let storage = UnsafeMutablePointer.allocate(capacity: 1) + storage.initialize(to: StaticBuildConfiguration(langOptions: cLangOpts)) + return UnsafeMutableRawPointer(storage) +} + +/// Free the given static build configuration. +@_cdecl("swift_Basic_freeStaticBuildConfiguration") +public func freeStaticBuildConfiguration(pointer: UnsafeMutableRawPointer) { + pointer.assumingMemoryBound(to: StaticBuildConfiguration.self) + .deinitialize(count: 1).deallocate() +} diff --git a/lib/ASTGen/Sources/BasicSwift/String+BridgedString.swift b/lib/ASTGen/Sources/BasicSwift/String+BridgedString.swift new file mode 100644 index 0000000000000..ef7fcdb4e6e5b --- /dev/null +++ b/lib/ASTGen/Sources/BasicSwift/String+BridgedString.swift @@ -0,0 +1,28 @@ +//===--- String+BridgedString.swift ---------------------------------------===// +// +// This source file is part of the Swift.org open source project +// +// Copyright (c) 2022-2025 Apple Inc. and the Swift project authors +// Licensed under Apache License v2.0 with Runtime Library Exception +// +// See https://swift.org/LICENSE.txt for license information +// See https://swift.org/CONTRIBUTORS.txt for the list of Swift project authors +// +//===----------------------------------------------------------------------===// + +import BasicBridging + +extension String { + public init(bridged: BridgedStringRef) { + self.init( + decoding: UnsafeBufferPointer(start: bridged.data, count: bridged.count), + as: UTF8.self + ) + } + + public mutating func withBridgedString(_ body: (BridgedStringRef) throws -> R) rethrows -> R { + try withUTF8 { buffer in + try body(BridgedStringRef(data: buffer.baseAddress, count: buffer.count)) + } + } +} diff --git a/lib/ASTGen/Sources/CMakeLists.txt b/lib/ASTGen/Sources/CMakeLists.txt index 57efe7eddacee..1e2f2816f2cbb 100644 --- a/lib/ASTGen/Sources/CMakeLists.txt +++ b/lib/ASTGen/Sources/CMakeLists.txt @@ -1,3 +1,4 @@ +add_subdirectory(BasicSwift) add_subdirectory(ASTGen) add_subdirectory(MacroEvaluation) add_subdirectory(SwiftIDEUtilsBridging) diff --git a/lib/ASTGen/Sources/MacroEvaluation/Macros.swift b/lib/ASTGen/Sources/MacroEvaluation/Macros.swift index 2845418be557a..91068283a0d0c 100644 --- a/lib/ASTGen/Sources/MacroEvaluation/Macros.swift +++ b/lib/ASTGen/Sources/MacroEvaluation/Macros.swift @@ -14,6 +14,7 @@ import ASTBridging import BasicBridging @_spi(PluginMessage) @_spi(ExperimentalLanguageFeature) import SwiftCompilerPluginMessageHandling import SwiftDiagnostics +import SwiftIfConfig import SwiftParser import SwiftSyntax @_spi(ExperimentalLanguageFeature) @_spi(Compiler) import SwiftSyntaxMacroExpansion @@ -419,7 +420,7 @@ func makeExpansionOutputResult( @_cdecl("swift_Macros_expandFreestandingMacro") @usableFromInline func expandFreestandingMacro( - diagEnginePtr: UnsafeMutableRawPointer, + cContext: BridgedASTContext, macroPtr: UnsafeRawPointer, discriminatorText: UnsafePointer, rawMacroRole: UInt8, @@ -461,7 +462,7 @@ func expandFreestandingMacro( let expandedSource: String? = expandFreestandingMacroImpl( macroPtr: macroPtr, macroRole: macroRole, - diagEnginePtr: diagEnginePtr, + cContext: cContext, expansionSyntax: expansion, sourceFilePtr: sourceFilePtr, discriminator: discriminator @@ -476,7 +477,7 @@ func expandFreestandingMacro( func expandFreestandingMacroImpl( macroPtr: UnsafeRawPointer, macroRole: MacroRole, - diagEnginePtr: UnsafeMutableRawPointer, + cContext: BridgedASTContext, expansionSyntax: FreestandingMacroExpansionSyntax, sourceFilePtr: UnsafePointer, discriminator: String @@ -505,14 +506,15 @@ func expandFreestandingMacroImpl( } // Send the message. - let message = HostToPluginMessage.expandFreestandingMacro( - macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName), - macroRole: pluginMacroRole, - discriminator: discriminator, - syntax: PluginMessage.Syntax(syntax: Syntax(expansionSyntax), in: sourceFilePtr)!, - lexicalContext: pluginLexicalContext(of: expansionSyntax) - ) do { + let message = HostToPluginMessage.expandFreestandingMacro( + macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName), + macroRole: pluginMacroRole, + discriminator: discriminator, + syntax: PluginMessage.Syntax(syntax: Syntax(expansionSyntax), in: sourceFilePtr)!, + lexicalContext: pluginLexicalContext(of: expansionSyntax), + staticBuildConfiguration: try cContext.staticBuildConfiguration.asJSON + ) let result = try macro.plugin.sendMessageAndWait(message) let expandedSource: String? let diagnostics: [PluginMessage.Diagnostic] @@ -527,14 +529,14 @@ func expandFreestandingMacroImpl( // Process the result. if !diagnostics.isEmpty { - let diagEngine = PluginDiagnosticsEngine(cxxDiagnosticEngine: diagEnginePtr) + let diagEngine = PluginDiagnosticsEngine(cContext: cContext) diagEngine.add(exportedSourceFile: sourceFilePtr) diagEngine.emit(diagnostics, messageSuffix: " (from macro '\(macroName)')") } return expandedSource } catch let error { - let srcMgr = SourceManager(cxxDiagnosticEngine: diagEnginePtr) + let srcMgr = SourceManager(cContext: cContext) srcMgr.insert(sourceFilePtr) srcMgr.diagnose( diagnostic: .init( @@ -552,7 +554,7 @@ func expandFreestandingMacroImpl( @_cdecl("swift_Macros_expandAttachedMacro") @usableFromInline func expandAttachedMacro( - diagEnginePtr: UnsafeMutableRawPointer, + cContext: BridgedASTContext, macroPtr: UnsafeRawPointer, discriminatorText: UnsafePointer, qualifiedTypeText: UnsafePointer, @@ -610,7 +612,7 @@ func expandAttachedMacro( let conformanceList = String(cString: conformanceListText) let expandedSource: String? = expandAttachedMacroImpl( - diagEnginePtr: diagEnginePtr, + cContext: cContext, macroPtr: macroPtr, rawMacroRole: rawMacroRole, discriminator: discriminator, @@ -645,7 +647,7 @@ private func pluginLexicalContext(of node: some SyntaxProtocol) -> [PluginMessag } func expandAttachedMacroImpl( - diagEnginePtr: UnsafeMutableRawPointer, + cContext: BridgedASTContext, macroPtr: UnsafeRawPointer, rawMacroRole: UInt8, discriminator: String, @@ -718,18 +720,19 @@ func expandAttachedMacroImpl( // Send the message. - let message = HostToPluginMessage.expandAttachedMacro( - macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName), - macroRole: macroRole, - discriminator: discriminator, - attributeSyntax: customAttributeSyntax, - declSyntax: declSyntax, - parentDeclSyntax: parentDeclSyntax, - extendedTypeSyntax: extendedTypeSyntax, - conformanceListSyntax: conformanceListSyntax, - lexicalContext: pluginLexicalContext(of: declarationNode) - ) do { + let message = HostToPluginMessage.expandAttachedMacro( + macro: .init(moduleName: macro.moduleName, typeName: macro.typeName, name: macroName), + macroRole: macroRole, + discriminator: discriminator, + attributeSyntax: customAttributeSyntax, + declSyntax: declSyntax, + parentDeclSyntax: parentDeclSyntax, + extendedTypeSyntax: extendedTypeSyntax, + conformanceListSyntax: conformanceListSyntax, + lexicalContext: pluginLexicalContext(of: declarationNode), + staticBuildConfiguration: try cContext.staticBuildConfiguration.asJSON + ) let expandedSource: String? let diagnostics: [PluginMessage.Diagnostic] switch try macro.plugin.sendMessageAndWait(message) { @@ -756,7 +759,7 @@ func expandAttachedMacroImpl( // Process the result. if !diagnostics.isEmpty { - let diagEngine = PluginDiagnosticsEngine(cxxDiagnosticEngine: diagEnginePtr) + let diagEngine = PluginDiagnosticsEngine(cContext: cContext) diagEngine.add(exportedSourceFile: customAttrSourceFilePtr) diagEngine.add(exportedSourceFile: declarationSourceFilePtr) if let parentDeclSourceFilePtr = parentDeclSourceFilePtr { @@ -767,7 +770,7 @@ func expandAttachedMacroImpl( return expandedSource } catch let error { - let srcMgr = SourceManager(cxxDiagnosticEngine: diagEnginePtr) + let srcMgr = SourceManager(cContext: cContext) srcMgr.insert(customAttrSourceFilePtr) srcMgr.insert(declarationSourceFilePtr) if let parentDeclSourceFilePtr = parentDeclSourceFilePtr { @@ -787,3 +790,11 @@ func expandAttachedMacroImpl( } } +extension StaticBuildConfiguration { + /// Form the JSON representation of this static build configuration. + var asJSON: String { + get throws { + try String(decoding: JSON.encode(self), as: UTF8.self) + } + } +} diff --git a/lib/ASTGen/Sources/MacroEvaluation/PluginHost.swift b/lib/ASTGen/Sources/MacroEvaluation/PluginHost.swift index f4d1b64f4bb19..85005e2f64fa9 100644 --- a/lib/ASTGen/Sources/MacroEvaluation/PluginHost.swift +++ b/lib/ASTGen/Sources/MacroEvaluation/PluginHost.swift @@ -201,8 +201,8 @@ class PluginDiagnosticsEngine { private let bridgedDiagEngine: BridgedDiagnosticEngine private var exportedSourceFileByName: [String: UnsafePointer] = [:] - init(cxxDiagnosticEngine: UnsafeMutableRawPointer) { - self.bridgedDiagEngine = BridgedDiagnosticEngine(raw: cxxDiagnosticEngine) + init(cContext: BridgedASTContext) { + self.bridgedDiagEngine = cContext.diags } /// Failable convenience initializer for optional cxx engine pointer. diff --git a/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift b/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift index df35475f5ae74..1011d2652419a 100644 --- a/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift +++ b/lib/ASTGen/Sources/MacroEvaluation/SourceManager.swift @@ -23,6 +23,10 @@ class SourceManager { self.bridgedDiagEngine = BridgedDiagnosticEngine(raw: cxxDiagnosticEngine) } + init(cContext: BridgedASTContext) { + self.bridgedDiagEngine = cContext.diags + } + /// The bridged diagnostic engine (just the wrapped C++ `DiagnosticEngine`). let bridgedDiagEngine: BridgedDiagnosticEngine diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt index 8dea0082b88fe..b75e0c8377121 100644 --- a/lib/Basic/CMakeLists.txt +++ b/lib/Basic/CMakeLists.txt @@ -59,6 +59,7 @@ add_swift_host_library(swiftBasic STATIC ParseableOutput.cpp JSONSerialization.cpp LangOptions.cpp + LangOptionsBridging.cpp LoadDynamicLibrary.cpp Located.cpp Mangler.cpp diff --git a/lib/AST/Bridging/LangOptionsBridging.cpp b/lib/Basic/LangOptionsBridging.cpp similarity index 74% rename from lib/AST/Bridging/LangOptionsBridging.cpp rename to lib/Basic/LangOptionsBridging.cpp index d407aede8a086..8c66476e38f83 100644 --- a/lib/AST/Bridging/LangOptionsBridging.cpp +++ b/lib/Basic/LangOptionsBridging.cpp @@ -37,11 +37,6 @@ bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts, return cLangOpts.unbridged().hasFeature(cName.unbridged()); } -bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts, - BridgedStringRef cName) { - return hasAttribute(cLangOpts.unbridged(), cName.unbridged()); -} - bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts, BridgedStringRef cName) { return cLangOpts.unbridged().checkPlatformCondition( @@ -121,6 +116,90 @@ SwiftInt BridgedLangOptions_getTargetAtomicBitWidths( cElements); } +namespace { + +/// Describe behaviors that should prevent an attribute from being shown. +/// +/// This is DeclAttrBehaviors, but with irrelevent values set to zero. +enum DeclAttrBehaviorsNotShown : uint64_t { + /// Whether this attribute is only valid when concurrency is enabled. + ConcurrencyOnly = 0, + + /// True if multiple instances of this attribute are allowed on a single + /// declaration. + AllowMultipleAttributes = 0, + + /// True if this is a decl modifier - i.e., that it should not be spelled + /// with an @. + DeclModifier = 1ull << 2, + + /// True if this is a long attribute that should be printed on its own line. + /// + /// Currently has no effect on DeclModifier attributes. + LongAttribute = 0, + + /// True if this shouldn't be serialized. + NotSerialized = 0, + + /// True if this attribute is only valid when parsing a .sil file. + SILOnly = 1ull << 5, + + /// The attribute should be reported by parser as unknown. + RejectByParser = 1ull << 6, + + /// Whether client code cannot use the attribute. Hides it in code completion. + UserInaccessible = 1ull << 7, + + /// Whether adding this attribute can break API + APIBreakingToAdd = 0, + + /// Whether removing this attribute can break API + APIBreakingToRemove = 0, + + /// Whether adding this attribute can break ABI + ABIBreakingToAdd = 0, + + /// Whether removing this attribute can break ABI + ABIBreakingToRemove = 0, + + /// The opposite of APIBreakingToAdd + APIStableToAdd = 0, + + /// The opposite of APIBreakingToRemove + APIStableToRemove = 0, + + /// The opposite of ABIBreakingToAdd + ABIStableToAdd = 0, + + /// The opposite of ABIBreakingToRemove + ABIStableToRemove = 0, + + /// Attribute should not be used in an \c \@abi attribute. Use for + /// attributes which cannot affect mangled names, even indirectly, and + /// which either don't affect ABI or where ABI-only declarations get their + /// behavior from their API counterpart. + ForbiddenInABIAttr = 0, + + /// Attribute can be used without restrictions in an \c \@abi attribute. + /// Use for attributes which affect mangled names but otherwise don't alter + /// the ABI, or ones where the \c ABIDeclChecker manually implements + /// special checking logic (e.g. because several different attributes + /// contribute to the same aspect of ABI in some complicated way). + UnconstrainedInABIAttr = 0, + + /// Attribute can be used in an \c \@abi attribute, but must match + /// equivalent on API decl. Use for attributes which affect both mangled + /// names and other parts of the ABI such that the declaration can only be + /// valid if they match. + EquivalentInABIAttr = 0, + + /// Use for attributes which are \em only valid on declarations that cannot + /// have an \c @abi attribute, such as \c ImportDecl . + UnreachableInABIAttr = 0, +}; + +} + void BridgedLangOptions_enumerateBuildConfigurationEntries( BridgedLangOptions cLangOpts, void * _Nonnull callbackContext, @@ -143,13 +222,13 @@ void BridgedLangOptions_enumerateBuildConfigurationEntries( // Enumerate attributes that are available. #define DECL_ATTR(SPELLING, CLASS, REQUIREMENTS, BEHAVIORS, CODE) \ - if (hasAttribute(langOpts, #SPELLING)) \ + if ((BEHAVIORS) == 0) \ callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING)); #include "swift/AST/DeclAttr.def" +#define SIL_TYPE_ATTR(X, C) #define TYPE_ATTR(SPELLING, CLASS) \ - if (hasAttribute(langOpts, #SPELLING)) \ - callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING)); + callback(cLangOpts, callbackContext, BCKAttribute, StringRef(#SPELLING)); #include "swift/AST/TypeAttr.def" // Deal with all of the target platform/architecture information. diff --git a/lib/Sema/TypeCheckMacros.cpp b/lib/Sema/TypeCheckMacros.cpp index bac848bc387be..6ed62e2974084 100644 --- a/lib/Sema/TypeCheckMacros.cpp +++ b/lib/Sema/TypeCheckMacros.cpp @@ -1217,7 +1217,7 @@ evaluateFreestandingMacro(FreestandingMacroExpansion *expansion, BridgedStringRef evaluatedSourceOut{nullptr, 0}; assert(!externalDef.isError()); swift_Macros_expandFreestandingMacro( - &ctx.Diags, externalDef.get(), discriminator->c_str(), + ctx, externalDef.get(), discriminator->c_str(), getRawMacroRole(macroRole), astGenSourceFile, expansion->getSourceRange().Start.getOpaquePointerValue(), &evaluatedSourceOut); @@ -1574,7 +1574,7 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, Decl *attachedTo, BridgedStringRef evaluatedSourceOut{nullptr, 0}; assert(!externalDef.isError()); swift_Macros_expandAttachedMacro( - &ctx.Diags, externalDef.get(), discriminator->c_str(), + ctx, externalDef.get(), discriminator->c_str(), extendedType.c_str(), conformanceList.c_str(), getRawMacroRole(role), astGenAttrSourceFile, attr->AtLoc.getOpaquePointerValue(), astGenDeclSourceFile, startLoc.getOpaquePointerValue(), @@ -1717,7 +1717,7 @@ static SourceFile *evaluateAttachedMacro(MacroDecl *macro, BridgedStringRef evaluatedSourceOut{nullptr, 0}; assert(!externalDef.isError()); swift_Macros_expandAttachedMacro( - &ctx.Diags, externalDef.get(), discriminator->c_str(), + ctx, externalDef.get(), discriminator->c_str(), "", "", getRawMacroRole(role), astGenAttrSourceFile, attr->AtLoc.getOpaquePointerValue(), astGenClosureSourceFile, startLoc.getOpaquePointerValue(), diff --git a/test/Macros/Inputs/syntax_macro_definitions.swift b/test/Macros/Inputs/syntax_macro_definitions.swift index 7eee73fb6ca2b..2dc4a73c70047 100644 --- a/test/Macros/Inputs/syntax_macro_definitions.swift +++ b/test/Macros/Inputs/syntax_macro_definitions.swift @@ -2980,3 +2980,21 @@ public struct BigEndianAccessorMacro: AccessorMacro { ] } } + +public struct CustomConditionCheckMacro: ExpressionMacro { + public static func expansion( + of node: some FreestandingMacroExpansionSyntax, + in context: some MacroExpansionContext + ) throws -> ExprSyntax { + guard let firstElement = node.arguments.first, + let stringLiteral = firstElement.expression + .as(StringLiteralExprSyntax.self), + stringLiteral.segments.count == 1, + case let .stringSegment(conditionName)? = stringLiteral.segments.first else { + throw CustomError.message("macro requires a string literal containing the name of a custom condition") + } + + let isSet = try context.buildConfiguration?.isCustomConditionSet(name: conditionName.content.text) ?? false + return "\(literal: isSet)" + } +} diff --git a/test/Macros/macro_build_config.swift b/test/Macros/macro_build_config.swift new file mode 100644 index 0000000000000..2a1083ef3fb9d --- /dev/null +++ b/test/Macros/macro_build_config.swift @@ -0,0 +1,17 @@ +// REQUIRES: swift_swift_parser, executable_test + +// RUN: %empty-directory(%t) +// RUN: %host-build-swift -swift-version 5 -emit-library -o %t/%target-library-name(MacroDefinition) -module-name=MacroDefinition %S/Inputs/syntax_macro_definitions.swift + +// Execution testing +// RUN: %target-build-swift -swift-version 5 -g -load-plugin-library %t/%target-library-name(MacroDefinition) %s -o %t/main -module-name MacroUser -Xfrontend -emit-dependencies-path -Xfrontend %t/main.d -Xfrontend -emit-reference-dependencies-path -Xfrontend %t/main.swiftdeps -DDEBUG +// RUN: %target-codesign %t/main +// RUN: %target-run %t/main | %FileCheck %s + +@freestanding(expression) macro isCustomConditionSet(_ name: String) -> Bool = #externalMacro(module: "MacroDefinition", type: "CustomConditionCheckMacro") + +// CHECK: Release = false +print("Release = \(#isCustomConditionSet("RELEASE"))") + +// CHECK: Debug = true +print("Debug = \(#isCustomConditionSet("DEBUG"))") diff --git a/test/Macros/macro_plugin_basic.swift b/test/Macros/macro_plugin_basic.swift index 3208b0e73fed9..b85c90a7e89c8 100644 --- a/test/Macros/macro_plugin_basic.swift +++ b/test/Macros/macro_plugin_basic.swift @@ -30,9 +30,9 @@ // CHECK: ->(plugin:[[#PID:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION:]]}}} // CHECK: <-(plugin:[[#PID]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}} -// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}func test{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testString","typeName":"TestStringMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":5,"offset":301},"source":"#testString(123)"}}} +// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}func test{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testString","typeName":"TestStringMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":5,"offset":301},"source":"#testString(123)"}}} // CHECK: <-(plugin:[[#PID]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"\"123\"\n + \"foo \""}} -// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testStringWithError","typeName":"TestStringWithErrorMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":6,"offset":336},"source":"#testStringWithError(321)"}}} +// CHECK: ->(plugin:[[#PID]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"testStringWithError","typeName":"TestStringWithErrorMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":6,"offset":336},"source":"#testStringWithError(321)"}}} // CHECK: <-(plugin:[[#PID]]) {"expandFreestandingMacroResult":{"diagnostics":[{"fixIts":[],"highlights":[],"message":"message from plugin","notes":[],"position":{"fileName":"{{.*}}test.swift","offset":336},"severity":"error"}],"expandedSource":"\"bar\""}} //--- test.swift diff --git a/test/Macros/macro_plugin_error.swift b/test/Macros/macro_plugin_error.swift index a4d6bd3865df3..becbcda13afcc 100644 --- a/test/Macros/macro_plugin_error.swift +++ b/test/Macros/macro_plugin_error.swift @@ -18,14 +18,14 @@ // CHECK: ->(plugin:[[#PID1:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION:]]}}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":7,"offset":[[#]]},"source":"#fooMacro(1)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":7,"offset":[[#]]},"source":"#fooMacro(1)"}}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"invalidResponse":{}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":9,"offset":[[#]]},"source":"#fooMacro(2)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":9,"offset":[[#]]},"source":"#fooMacro(2)"}}} // ^ This messages causes the mock plugin exit because there's no matching expected message. // CHECK: ->(plugin:[[#PID2:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION]]}}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"getCapabilityResult":{"capability":{"protocolVersion":1}}} -// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":11,"offset":[[#]]},"source":"#fooMacro(3)"}}} +// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"$s{{.+}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"TestPlugin","name":"fooMacro","typeName":"FooMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{"column":19,"fileID":"MyApp/test.swift","fileName":"{{.+}}test.swift","line":11,"offset":[[#]]},"source":"#fooMacro(3)"}}} // CHECK-NEXT: <-(plugin:[[#PID2:]]) {"expandFreestandingMacroResult":{"diagnostics":[],"expandedSource":"3.description"}} //--- test.swift diff --git a/test/Macros/macro_plugin_server.swift b/test/Macros/macro_plugin_server.swift index 673bf64311f5b..fa9e20574aec6 100644 --- a/test/Macros/macro_plugin_server.swift +++ b/test/Macros/macro_plugin_server.swift @@ -71,9 +71,9 @@ // CHECK-NEXT: <-(plugin:[[#PID1]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} // CHECK-NEXT: ->(plugin:[[#PID1]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros.{{dylib|so|dll}}","moduleName":"EvilMacros"}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(a + b)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(a + b)"}}} // CHECK-NEXT: <-(plugin:[[#PID1]]) {"expandMacroResult":{"diagnostics":[],"expandedSource":"(a + b, \"a + b\")"}} -// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"EvilMacros","name":"evil","typeName":"CrashingMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#evil(42)"}}} +// CHECK-NEXT: ->(plugin:[[#PID1]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"EvilMacros","name":"evil","typeName":"CrashingMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#evil(42)"}}} // ^ This crashes the plugin server. // CHECK: ->(plugin:[[#PID2:]]) {"getCapability":{"capability":{"protocolVersion":[[#PROTOCOL_VERSION]]}}} @@ -82,12 +82,12 @@ // CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} // CHECK-NEXT: ->(plugin:[[#PID2]]) {"loadPluginLibrary":{"libraryPath":"{{.*}}EvilMacros.{{dylib|so|dll}}","moduleName":"EvilMacros"}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"loadPluginLibraryResult":{"diagnostics":[],"loaded":true}} -// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(b + a)"}}} +// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"stringify","typeName":"StringifyMacro"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{{.+}}},"source":"#stringify(b + a)"}}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"expandMacroResult":{"diagnostics":[],"expandedSource":"(b + a, \"b + a\")"}} -// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"missing","typeName":"TypeDoesNotExist"},"macroRole":"expression","syntax":{"kind":"expression","location":{{({.+})}},"source":"#missing()"}}} +// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"missing","typeName":"TypeDoesNotExist"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{({.+})}},"source":"#missing()"}}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"expandMacroResult":{"diagnostics":[{"fixIts":[],"highlights":[{{{.*}}}],"message":"type 'MacroDefinition.TypeDoesNotExist' could not be found in library plugin '{{.*}}MacroDefinition.{{dylib|so|dll}}'","notes":[],"position":{{{.*}}},"severity":"error"}]}} -// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"notMacro","typeName":"NotMacroStruct"},"macroRole":"expression","syntax":{"kind":"expression","location":{{({.+})}},"source":"#notMacro()"}}} +// CHECK-NEXT: ->(plugin:[[#PID2]]) {"expandFreestandingMacro":{"discriminator":"${{.*}}","lexicalContext":[{{.*}}],"macro":{"moduleName":"MacroDefinition","name":"notMacro","typeName":"NotMacroStruct"},"macroRole":"expression","staticBuildConfiguration"{{.*}},"syntax":{"kind":"expression","location":{{({.+})}},"source":"#notMacro()"}}} // CHECK-NEXT: <-(plugin:[[#PID2]]) {"expandMacroResult":{"diagnostics":[{"fixIts":[],"highlights":[{{{.*}}}],"message":"type 'MacroDefinition.NotMacroStruct' is not a valid macro implementation type in library plugin '{{.*}}MacroDefinition.{{dylib|so|dll}}'","notes":[],"position":{{{.*}}},"severity":"error"}]}} @freestanding(expression) macro stringify(_ value: T) -> (T, String) = #externalMacro(module: "MacroDefinition", type: "StringifyMacro") From 2a469165369df9dd03eb597fb3d478a4afc2dbe9 Mon Sep 17 00:00:00 2001 From: Doug Gregor Date: Mon, 29 Sep 2025 18:39:29 -0700 Subject: [PATCH 3/3] Reseat CompilerBuildConfiguration on top of StaticBuildConfiguration Now that we have a per-ASTContext StaticBuildConfiguration, reimplement (almost) everything in CompilerBuildConfiguration to sit on top of it. Only canImport requires the full ASTContext, so that gets its own implementation, as does one other operation that can produce an error. Aside from more code sharing, this provides additional validation that the StaticBuildConfiguration we build is complete and accurate. --- include/swift/Basic/BasicBridging.h | 28 ------ lib/AST/Bridging/ASTContextBridging.cpp | 5 - .../ASTGen/CompilerBuildConfiguration.swift | 92 +++++-------------- .../Sources/ASTGen/EmbeddedSupport.swift | 28 +++--- lib/Basic/LangOptionsBridging.cpp | 45 --------- 5 files changed, 39 insertions(+), 159 deletions(-) diff --git a/include/swift/Basic/BasicBridging.h b/include/swift/Basic/BasicBridging.h index ee696f09f09c4..f0b1073e51b0b 100644 --- a/include/swift/Basic/BasicBridging.h +++ b/include/swift/Basic/BasicBridging.h @@ -505,34 +505,6 @@ SWIFT_NAME("BridgedLangOptions.hasFeature(self:_:)") bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts, BridgedFeature feature); -SWIFT_NAME("BridgedLangOptions.customConditionSet(self:_:)") -bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.hasFeatureNamed(self:_:)") -bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetOS(self:_:)") -bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetArchitecture(self:_:)") -bool BridgedLangOptions_isActiveTargetArchitecture(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetEnvironment(self:_:)") -bool BridgedLangOptions_isActiveTargetEnvironment(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetRuntime(self:_:)") -bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - -SWIFT_NAME("BridgedLangOptions.isActiveTargetPtrAuth(self:_:)") -bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts, - BridgedStringRef cName); - SWIFT_NAME("BridgedLangOptions.getTargetAtomicBitWidths(self:_:)") SwiftInt BridgedLangOptions_getTargetAtomicBitWidths(BridgedLangOptions cLangOpts, SwiftInt* _Nullable * _Nonnull cComponents); diff --git a/lib/AST/Bridging/ASTContextBridging.cpp b/lib/AST/Bridging/ASTContextBridging.cpp index 94a6e4fa47b9b..18eaf236ebc81 100644 --- a/lib/AST/Bridging/ASTContextBridging.cpp +++ b/lib/AST/Bridging/ASTContextBridging.cpp @@ -89,11 +89,6 @@ BridgedAvailabilityMacroMap BridgedASTContext::getAvailabilityMacroMap() const { return &unbridged().getAvailabilityMacroMap(); } -bool BridgedLangOptions_hasAttributeNamed(BridgedLangOptions cLangOpts, - BridgedStringRef cName) { - return hasAttribute(cLangOpts.unbridged(), cName.unbridged()); -} - void *BridgedASTContext_staticBuildConfiguration(BridgedASTContext cContext) { ASTContext &ctx = cContext.unbridged(); void *staticBuildConfiguration = ctx.getGlobalCache().StaticBuildConfiguration; diff --git a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift index f095fb2e5563e..3dbc62d4d760a 100644 --- a/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift +++ b/lib/ASTGen/Sources/ASTGen/CompilerBuildConfiguration.swift @@ -31,32 +31,25 @@ extension BridgedASTContext { /// queries. struct CompilerBuildConfiguration: BuildConfiguration { let ctx: BridgedASTContext + let staticBuildConfiguration: StaticBuildConfiguration let sourceBuffer: UnsafeBufferPointer init(ctx: BridgedASTContext, sourceBuffer: UnsafeBufferPointer) { self.ctx = ctx + self.staticBuildConfiguration = ctx.staticBuildConfiguration self.sourceBuffer = sourceBuffer } - func isCustomConditionSet(name: String) throws -> Bool { - var name = name - return name.withBridgedString { nameRef in - ctx.langOpts.customConditionSet(nameRef) - } + func isCustomConditionSet(name: String) -> Bool { + staticBuildConfiguration.isCustomConditionSet(name: name) } - func hasFeature(name: String) throws -> Bool { - var name = name - return name.withBridgedString { nameRef in - ctx.langOpts.hasFeatureNamed(nameRef) - } + func hasFeature(name: String) -> Bool { + staticBuildConfiguration.hasFeature(name: name) } - func hasAttribute(name: String) throws -> Bool { - var name = name - return name.withBridgedString { nameRef in - ctx.langOpts.hasAttributeNamed(nameRef) - } + func hasAttribute(name: String) -> Bool { + staticBuildConfiguration.hasAttribute(name: name) } func canImport( @@ -97,85 +90,50 @@ struct CompilerBuildConfiguration: BuildConfiguration { } } - func isActiveTargetOS(name: String) throws -> Bool { - var name = name - return name.withBridgedString { nameRef in - ctx.langOpts.isActiveTargetOS(nameRef) - } + func isActiveTargetOS(name: String) -> Bool { + staticBuildConfiguration.isActiveTargetOS(name: name) } - func isActiveTargetArchitecture(name: String) throws -> Bool { - var name = name - return name.withBridgedString { nameRef in - ctx.langOpts.isActiveTargetArchitecture(nameRef) - } + func isActiveTargetArchitecture(name: String) -> Bool { + staticBuildConfiguration.isActiveTargetArchitecture(name: name) } - func isActiveTargetEnvironment(name: String) throws -> Bool { - var name = name - return name.withBridgedString { nameRef in - ctx.langOpts.isActiveTargetEnvironment(nameRef) - } + func isActiveTargetEnvironment(name: String) -> Bool { + staticBuildConfiguration.isActiveTargetEnvironment(name: name) } func isActiveTargetRuntime(name: String) throws -> Bool { - var name = name - // Complain if the provided runtime isn't one of the known values. switch name { case "_Native", "_ObjC", "_multithreaded": break default: throw IfConfigError.unexpectedRuntimeCondition } - return name.withBridgedString { nameRef in - ctx.langOpts.isActiveTargetRuntime(nameRef) - } + return staticBuildConfiguration.isActiveTargetRuntime(name: name) } - - func isActiveTargetPointerAuthentication(name: String) throws -> Bool { - var name = name - return name.withBridgedString { nameRef in - ctx.langOpts.isActiveTargetPtrAuth(nameRef) - } + + func isActiveTargetPointerAuthentication(name: String) -> Bool { + staticBuildConfiguration.isActiveTargetPointerAuthentication(name: name) } var targetPointerBitWidth: Int { - Int(ctx.langOpts.targetPointerBitWidth) + staticBuildConfiguration.targetPointerBitWidth } var targetAtomicBitWidths: [Int] { - var bitWidthsBuf: UnsafeMutablePointer? = nil - let count = ctx.langOpts.getTargetAtomicBitWidths(&bitWidthsBuf) - let bitWidths = Array(UnsafeMutableBufferPointer(start: bitWidthsBuf, count: count)) - deallocateIntBuffer(bitWidthsBuf); - return bitWidths + staticBuildConfiguration.targetAtomicBitWidths } var endianness: Endianness { - switch ctx.langOpts.targetEndianness { - case .EndianBig: return .big - case .EndianLittle: return .little - } + staticBuildConfiguration.endianness } - var languageVersion: VersionTuple { - var componentsBuf: UnsafeMutablePointer? = nil - let count = ctx.langOpts.getLanguageVersion(&componentsBuf) - let version = VersionTuple( - components: Array(UnsafeMutableBufferPointer(start: componentsBuf, count: count)) - ) - deallocateIntBuffer(componentsBuf); - return version + var languageVersion: VersionTuple { + staticBuildConfiguration.languageVersion } - var compilerVersion: VersionTuple { - var componentsBuf: UnsafeMutablePointer? = nil - let count = ctx.langOpts.getCompilerVersion(&componentsBuf) - let version = VersionTuple( - components: Array(UnsafeMutableBufferPointer(start: componentsBuf, count: count)) - ) - deallocateIntBuffer(componentsBuf); - return version + var compilerVersion: VersionTuple { + staticBuildConfiguration.compilerVersion } } diff --git a/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift b/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift index 3de35744eeb2f..0dfc9fa768fbe 100644 --- a/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift +++ b/lib/ASTGen/Sources/ASTGen/EmbeddedSupport.swift @@ -68,26 +68,26 @@ struct EmbeddedBuildConfiguration: BuildConfiguration { self.configuration = .init(ctx: ctx, sourceBuffer: sourceBuffer) } - func isCustomConditionSet(name: String) throws -> Bool { + func isCustomConditionSet(name: String) -> Bool { // $Embedded is set when building Embedded Swift if name == "$Embedded" { return true } - return try configuration.isCustomConditionSet(name: name) + return configuration.isCustomConditionSet(name: name) } - func hasFeature(name: String) throws -> Bool { + func hasFeature(name: String) -> Bool { // The "Embedded" feature is set when building Embedded Swift. if name == "Embedded" { return true } - return try configuration.hasFeature(name: name) + return configuration.hasFeature(name: name) } - func hasAttribute(name: String) throws -> Bool { - return try configuration.hasAttribute(name: name) + func hasAttribute(name: String) -> Bool { + return configuration.hasAttribute(name: name) } func canImport( @@ -100,24 +100,24 @@ struct EmbeddedBuildConfiguration: BuildConfiguration { return false } - func isActiveTargetOS(name: String) throws -> Bool { - return try configuration.isActiveTargetOS(name: name) + func isActiveTargetOS(name: String) -> Bool { + return configuration.isActiveTargetOS(name: name) } - func isActiveTargetArchitecture(name: String) throws -> Bool { - return try configuration.isActiveTargetArchitecture(name: name) + func isActiveTargetArchitecture(name: String) -> Bool { + return configuration.isActiveTargetArchitecture(name: name) } - func isActiveTargetEnvironment(name: String) throws -> Bool { - return try configuration.isActiveTargetEnvironment(name: name) + func isActiveTargetEnvironment(name: String) -> Bool { + return configuration.isActiveTargetEnvironment(name: name) } func isActiveTargetRuntime(name: String) throws -> Bool { return try configuration.isActiveTargetRuntime(name: name) } - func isActiveTargetPointerAuthentication(name: String) throws -> Bool { - return try configuration.isActiveTargetPointerAuthentication(name: name) + func isActiveTargetPointerAuthentication(name: String) -> Bool { + return configuration.isActiveTargetPointerAuthentication(name: name) } var targetPointerBitWidth: Int { diff --git a/lib/Basic/LangOptionsBridging.cpp b/lib/Basic/LangOptionsBridging.cpp index 8c66476e38f83..5ccc2a8ea1df0 100644 --- a/lib/Basic/LangOptionsBridging.cpp +++ b/lib/Basic/LangOptionsBridging.cpp @@ -22,51 +22,6 @@ bool BridgedLangOptions_hasFeature(BridgedLangOptions cLangOpts, } -bool BridgedLangOptions_customConditionSet(BridgedLangOptions cLangOpts, - BridgedStringRef cName) { - const LangOptions &langOpts = cLangOpts.unbridged(); - auto name = cName.unbridged(); - if (name.starts_with("$") && langOpts.hasFeature(name.drop_front())) - return true; - - return langOpts.isCustomConditionalCompilationFlagSet(name); -} - -bool BridgedLangOptions_hasFeatureNamed(BridgedLangOptions cLangOpts, - BridgedStringRef cName) { - return cLangOpts.unbridged().hasFeature(cName.unbridged()); -} - -bool BridgedLangOptions_isActiveTargetOS(BridgedLangOptions cLangOpts, - BridgedStringRef cName) { - return cLangOpts.unbridged().checkPlatformCondition( - PlatformConditionKind::OS, cName.unbridged()); -} - -bool BridgedLangOptions_isActiveTargetArchitecture( - BridgedLangOptions cLangOpts, BridgedStringRef cName) { - return cLangOpts.unbridged().checkPlatformCondition( - PlatformConditionKind::Arch, cName.unbridged()); -} - -bool BridgedLangOptions_isActiveTargetEnvironment( - BridgedLangOptions cLangOpts, BridgedStringRef cName) { - return cLangOpts.unbridged().checkPlatformCondition( - PlatformConditionKind::TargetEnvironment, cName.unbridged()); -} - -bool BridgedLangOptions_isActiveTargetRuntime(BridgedLangOptions cLangOpts, - BridgedStringRef cName) { - return cLangOpts.unbridged().checkPlatformCondition( - PlatformConditionKind::Runtime, cName.unbridged()); -} - -bool BridgedLangOptions_isActiveTargetPtrAuth(BridgedLangOptions cLangOpts, - BridgedStringRef cName) { - return cLangOpts.unbridged().checkPlatformCondition( - PlatformConditionKind::PtrAuth, cName.unbridged()); -} - unsigned BridgedLangOptions::getTargetPointerBitWidth() const { return unbridged().Target.isArch64Bit() ? 64 : unbridged().Target.isArch32Bit() ? 32