mirror of
https://github.com/apple/swift.git
synced 2025-12-14 20:36:38 +01:00
Frontend: Add language mode and enabled features to .SWIFT_TRACE.
To allow tooling to analyze use of language mode and experimental/upcoming features, add that information to the `.SWIFT_TRACE` file. Resolves rdar://152673681.
This commit is contained in:
@@ -65,6 +65,8 @@ struct LoadedModuleTraceFormat {
|
||||
unsigned Version;
|
||||
Identifier Name;
|
||||
std::string Arch;
|
||||
std::string LanguageMode;
|
||||
std::vector<StringRef> EnabledLanguageFeatures;
|
||||
bool StrictMemorySafety;
|
||||
std::vector<SwiftModuleTraceInfo> SwiftModules;
|
||||
std::vector<SwiftMacroTraceInfo> SwiftMacros;
|
||||
@@ -107,6 +109,11 @@ template <> struct ObjectTraits<LoadedModuleTraceFormat> {
|
||||
|
||||
out.mapRequired("arch", contents.Arch);
|
||||
|
||||
out.mapRequired("languageMode", contents.LanguageMode);
|
||||
|
||||
out.mapRequired("enabledLanguageFeatures",
|
||||
contents.EnabledLanguageFeatures);
|
||||
|
||||
out.mapRequired("strictMemorySafety", contents.StrictMemorySafety);
|
||||
|
||||
// The 'swiftmodules' key is kept for backwards compatibility.
|
||||
@@ -723,6 +730,38 @@ computeSwiftMacroTraceInfo(ASTContext &ctx, const DependencyTracker &depTracker,
|
||||
});
|
||||
}
|
||||
|
||||
static void computeEnabledFeatures(ASTContext &ctx,
|
||||
std::vector<StringRef> &enabledFeatures) {
|
||||
struct FeatureAndName {
|
||||
Feature feature;
|
||||
StringRef name;
|
||||
};
|
||||
|
||||
static const FeatureAndName features[] = {
|
||||
#define FEATURE_ENTRY(FeatureName) {Feature::FeatureName, #FeatureName},
|
||||
#define LANGUAGE_FEATURE(FeatureName, SENumber, Version)
|
||||
#define EXPERIMENTAL_FEATURE(FeatureName, AvailableInProd) \
|
||||
FEATURE_ENTRY(FeatureName)
|
||||
#define UPCOMING_FEATURE(FeatureName, SENumber, Version) \
|
||||
FEATURE_ENTRY(FeatureName)
|
||||
#define OPTIONAL_LANGUAGE_FEATURE(FeatureName, SENumber, Version) \
|
||||
FEATURE_ENTRY(FeatureName)
|
||||
#include "swift/Basic/Features.def"
|
||||
};
|
||||
|
||||
for (auto &featureAndName : features) {
|
||||
if (ctx.LangOpts.hasFeature(featureAndName.feature))
|
||||
enabledFeatures.push_back(featureAndName.name);
|
||||
}
|
||||
|
||||
// FIXME: It would be nice if the features were added in sorted order instead.
|
||||
// However, std::sort is not constexpr until C++20.
|
||||
std::sort(enabledFeatures.begin(), enabledFeatures.end(),
|
||||
[](const StringRef &lhs, const StringRef &rhs) -> bool {
|
||||
return lhs.compare(rhs) < 0;
|
||||
});
|
||||
}
|
||||
|
||||
// [NOTE: Bailing-vs-crashing-in-trace-emission] There are certain edge cases
|
||||
// in trace emission where an invariant that you think should hold does not hold
|
||||
// in practice. For example, sometimes we have seen modules without any
|
||||
@@ -785,12 +824,18 @@ bool swift::emitLoadedModuleTraceIfNeeded(ModuleDecl *mainModule,
|
||||
std::vector<SwiftMacroTraceInfo> swiftMacros;
|
||||
computeSwiftMacroTraceInfo(ctxt, *depTracker, swiftMacros);
|
||||
|
||||
std::vector<StringRef> enabledFeatures;
|
||||
computeEnabledFeatures(ctxt, enabledFeatures);
|
||||
|
||||
LoadedModuleTraceFormat trace = {
|
||||
/*version=*/LoadedModuleTraceFormat::CurrentVersion,
|
||||
/*name=*/mainModule->getName(),
|
||||
/*arch=*/ctxt.LangOpts.Target.getArchName().str(),
|
||||
ctxt.LangOpts.EffectiveLanguageVersion.asAPINotesVersionString(),
|
||||
enabledFeatures,
|
||||
mainModule ? mainModule->strictMemorySafety() : false,
|
||||
swiftModules, swiftMacros};
|
||||
swiftModules,
|
||||
swiftMacros};
|
||||
|
||||
// raw_fd_ostream is unbuffered, and we may have multiple processes writing,
|
||||
// so first write to memory and then dump the buffer to the trace file.
|
||||
|
||||
@@ -12,6 +12,7 @@
|
||||
// CHECK: "version":2
|
||||
// CHECK: "name":"loaded_module_trace"
|
||||
// CHECK: "arch":"{{[^"]*}}"
|
||||
// CHECK: "languageMode":"4"
|
||||
// CHECK: "strictMemorySafety":false
|
||||
// CHECK: "swiftmodules":[
|
||||
// CHECK-DAG: "{{[^"]*\\[/\\]}}Module2.swiftmodule"
|
||||
|
||||
83
test/Driver/loaded_module_trace_enabled_features.swift
Normal file
83
test/Driver/loaded_module_trace_enabled_features.swift
Normal file
@@ -0,0 +1,83 @@
|
||||
// RUN: %empty-directory(%t)
|
||||
|
||||
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 4 \
|
||||
// RUN: -emit-loaded-module-trace-path %t/swift4.trace.json
|
||||
// RUN: %FileCheck -check-prefix=CHECK-SWIFT4 %s < %t/swift4.trace.json
|
||||
|
||||
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 5 \
|
||||
// RUN: -emit-loaded-module-trace-path %t/swift5.trace.json
|
||||
// RUN: %FileCheck -check-prefix=CHECK-SWIFT5 %s < %t/swift5.trace.json
|
||||
|
||||
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 5 \
|
||||
// RUN: -emit-loaded-module-trace-path %t/swift5_and_features.trace.json \
|
||||
// RUN: -enable-experimental-feature ParserValidation \
|
||||
// RUN: -enable-upcoming-feature RegionBasedIsolation \
|
||||
// RUN: -strict-memory-safety
|
||||
// RUN: %FileCheck -check-prefix=CHECK-SWIFT5-PLUS %s < %t/swift5_and_features.trace.json
|
||||
|
||||
// RUN: %target-swift-frontend %s -emit-module -o /dev/null -swift-version 6 \
|
||||
// RUN: -emit-loaded-module-trace-path %t/swift6.trace.json
|
||||
// RUN: %FileCheck -check-prefix=CHECK-SWIFT6 %s < %t/swift6.trace.json
|
||||
|
||||
// NOTE: The matching of the enabledLanguageFeatures lists below is
|
||||
// intentionally inexact. There are few experimental features (ParserRoundTrip,
|
||||
// ParserValidation) that are enabled by default in asserts compilers but
|
||||
// otherwise disabled, so the enabled feature lists will sometimes contain
|
||||
// additional entries.
|
||||
|
||||
// REQUIRES: swift_feature_ParserValidation
|
||||
// REQUIRES: swift_feature_RegionBasedIsolation
|
||||
|
||||
// CHECK-SWIFT4: {
|
||||
// CHECK-SWIFT4: "version":2
|
||||
// CHECK-SWIFT4: "arch":"{{[^"]*}}"
|
||||
// CHECK-SWIFT4: "languageMode":"4"
|
||||
// CHECK-SWIFT4: "enabledLanguageFeatures":[
|
||||
// CHECK-SWIFT4: ]
|
||||
// CHECK-SWIFT4: "strictMemorySafety":false
|
||||
|
||||
// CHECK-SWIFT5: {
|
||||
// CHECK-SWIFT5: "version":2
|
||||
// CHECK-SWIFT5: "arch":"{{[^"]*}}"
|
||||
// CHECK-SWIFT5: "languageMode":"5"
|
||||
// CHECK-SWIFT5: "enabledLanguageFeatures":[
|
||||
// CHECK-SWIFT5: "NonfrozenEnumExhaustivity"
|
||||
// CHECK-SWIFT5: ]
|
||||
// CHECK-SWIFT5: "strictMemorySafety":false
|
||||
|
||||
// CHECK-SWIFT5-PLUS: {
|
||||
// CHECK-SWIFT5-PLUS: "version":2
|
||||
// CHECK-SWIFT5-PLUS: "arch":"{{[^"]*}}"
|
||||
// CHECK-SWIFT5-PLUS: "languageMode":"5"
|
||||
// CHECK-SWIFT5-PLUS: "enabledLanguageFeatures":[
|
||||
// CHECK-SWIFT5-PLUS: "NonfrozenEnumExhaustivity",
|
||||
// CHECK-SWIFT5-PLUS: "ParserValidation",
|
||||
// CHECK-SWIFT5-PLUS: "RegionBasedIsolation",
|
||||
// CHECK-SWIFT5-PLUS: "StrictMemorySafety"
|
||||
// CHECK-SWIFT5-PLUS: ]
|
||||
// CHECK-SWIFT5-PLUS: "strictMemorySafety":true
|
||||
|
||||
// CHECK-SWIFT6: {
|
||||
// CHECK-SWIFT6: "version":2
|
||||
// CHECK-SWIFT6: "arch":"{{[^"]*}}"
|
||||
// CHECK-SWIFT6: "languageMode":"6"
|
||||
// CHECK-SWIFT6: "enabledLanguageFeatures":[
|
||||
// CHECK-SWIFT6: "BareSlashRegexLiterals",
|
||||
// CHECK-SWIFT6: "ConciseMagicFile",
|
||||
// CHECK-SWIFT6: "DeprecateApplicationMain",
|
||||
// CHECK-SWIFT6: "DisableOutwardActorInference",
|
||||
// CHECK-SWIFT6: "DynamicActorIsolation",
|
||||
// CHECK-SWIFT6: "ForwardTrailingClosures",
|
||||
// CHECK-SWIFT6: "GlobalActorIsolatedTypesUsability",
|
||||
// CHECK-SWIFT6: "GlobalConcurrency",
|
||||
// CHECK-SWIFT6: "ImplicitOpenExistentials",
|
||||
// CHECK-SWIFT6: "ImportObjcForwardDeclarations",
|
||||
// CHECK-SWIFT6: "InferSendableFromCaptures",
|
||||
// CHECK-SWIFT6: "IsolatedDefaultValues",
|
||||
// CHECK-SWIFT6: "NonfrozenEnumExhaustivity",
|
||||
// CHECK-SWIFT6: "RegionBasedIsolation",
|
||||
// CHECK-SWIFT6: "StrictConcurrency"
|
||||
// CHECK-SWIFT6: ]
|
||||
// CHECK-SWIFT6: "strictMemorySafety":false
|
||||
|
||||
import Swift
|
||||
@@ -14,6 +14,9 @@
|
||||
// CHECK: "version":2
|
||||
// CHECK: "name":"loaded_module_trace_multifile"
|
||||
// CHECK: "arch":"{{[^"]*}}"
|
||||
// CHECK: "languageMode":"4"
|
||||
// CHECK: "enabledLanguageFeatures":[
|
||||
// CHECK: ]
|
||||
// CHECK: "swiftmodules":[
|
||||
// CHECK-DAG: "{{[^"]*\\[/\\]}}Module2.swiftmodule"
|
||||
// CHECK-DAG: "{{[^"]*\\[/\\]}}Swift.swiftmodule{{(\\[/\\][^"]+[.]swiftmodule)?}}"
|
||||
|
||||
Reference in New Issue
Block a user