Skip to content

Commit c6a5292

Browse files
Merge remote-tracking branch 'apple/release/5.3' into katei-merge-5.3
2 parents 0535399 + 89edca6 commit c6a5292

31 files changed

+347
-48
lines changed

include/swift/AST/DiagnosticsFrontend.def

+3
Original file line numberDiff line numberDiff line change
@@ -301,6 +301,9 @@ ERROR(error_optimization_remark_pattern, none, "%0 in '%1'",
301301
ERROR(error_invalid_debug_prefix_map, none,
302302
"invalid argument '%0' to -debug-prefix-map; it must be of the form "
303303
"'original=remapped'", (StringRef))
304+
ERROR(error_invalid_coverage_prefix_map, none,
305+
"invalid argument '%0' to -coverage-prefix-map; it must be of the form "
306+
"'original=remapped'", (StringRef))
304307

305308

306309
ERROR(error_unable_to_write_swift_ranges_file, none,

include/swift/AST/IRGenOptions.h

+3
Original file line numberDiff line numberDiff line change
@@ -169,6 +169,9 @@ class IRGenOptions {
169169
/// Path prefixes that should be rewritten in debug info.
170170
PathRemapper DebugPrefixMap;
171171

172+
/// Path prefixes that should be rewritten in coverage info.
173+
PathRemapper CoveragePrefixMap;
174+
172175
/// What level of debug info to generate.
173176
IRGenDebugInfoLevel DebugInfoLevel : 2;
174177

include/swift/Option/Options.td

+3
Original file line numberDiff line numberDiff line change
@@ -708,6 +708,9 @@ def gdwarf_types : Flag<["-"], "gdwarf-types">,
708708
def debug_prefix_map : Separate<["-"], "debug-prefix-map">,
709709
Flags<[FrontendOption]>,
710710
HelpText<"Remap source paths in debug info">;
711+
def coverage_prefix_map : Separate<["-"], "coverage-prefix-map">,
712+
Flags<[FrontendOption]>,
713+
HelpText<"Remap source paths in coverage info">;
711714

712715
def debug_info_format : Joined<["-"], "debug-info-format=">,
713716
Flags<[FrontendOption]>,

lib/AST/Type.cpp

+2-2
Original file line numberDiff line numberDiff line change
@@ -3059,8 +3059,8 @@ operator()(SubstitutableType *maybeOpaqueType) const {
30593059
}))
30603060
return maybeOpaqueType;
30613061

3062-
// If the type still contains opaque types, recur.
3063-
if (substTy->hasOpaqueArchetype()) {
3062+
// If the type changed, but still contains opaque types, recur.
3063+
if (!substTy->isEqual(maybeOpaqueType) && substTy->hasOpaqueArchetype()) {
30643064
return ::substOpaqueTypesWithUnderlyingTypes(
30653065
substTy, inContext, contextExpansion, isContextWholeModule);
30663066
}

lib/Driver/Driver.cpp

+6
Original file line numberDiff line numberDiff line change
@@ -179,6 +179,12 @@ static void validateDebugInfoArgs(DiagnosticEngine &diags,
179179
for (auto A : args.getAllArgValues(options::OPT_debug_prefix_map))
180180
if (A.find('=') == StringRef::npos)
181181
diags.diagnose(SourceLoc(), diag::error_invalid_debug_prefix_map, A);
182+
183+
// Check for any -coverage-prefix-map options that aren't of the form
184+
// 'original=remapped' (either side can be empty, however).
185+
for (auto A : args.getAllArgValues(options::OPT_coverage_prefix_map))
186+
if (A.find('=') == StringRef::npos)
187+
diags.diagnose(SourceLoc(), diag::error_invalid_coverage_prefix_map, A);
182188
}
183189

184190
static void validateVerifyIncrementalDependencyArgs(DiagnosticEngine &diags,

lib/Driver/ToolChains.cpp

+1
Original file line numberDiff line numberDiff line change
@@ -265,6 +265,7 @@ void ToolChain::addCommonFrontendArgs(const OutputInfo &OI,
265265

266266
// Pass on file paths that should be remapped in debug info.
267267
inputArgs.AddAllArgs(arguments, options::OPT_debug_prefix_map);
268+
inputArgs.AddAllArgs(arguments, options::OPT_coverage_prefix_map);
268269

269270
// Pass through the values passed to -Xfrontend.
270271
inputArgs.AddAllArgValues(arguments, options::OPT_Xfrontend);

lib/Frontend/CompilerInvocation.cpp

+5
Original file line numberDiff line numberDiff line change
@@ -1267,6 +1267,11 @@ static bool ParseIRGenArgs(IRGenOptions &Opts, ArgList &Args,
12671267
Opts.DebugPrefixMap.addMapping(SplitMap.first, SplitMap.second);
12681268
}
12691269

1270+
for (auto A : Args.getAllArgValues(options::OPT_coverage_prefix_map)) {
1271+
auto SplitMap = StringRef(A).split('=');
1272+
Opts.CoveragePrefixMap.addMapping(SplitMap.first, SplitMap.second);
1273+
}
1274+
12701275
for (const Arg *A : Args.filtered(OPT_Xcc)) {
12711276
StringRef Opt = A->getValue();
12721277
if (Opt.startswith("-D") || Opt.startswith("-U"))

lib/IRGen/GenClangDecl.cpp

+37-10
Original file line numberDiff line numberDiff line change
@@ -34,18 +34,43 @@ class ClangDeclRefFinder
3434
return true;
3535
}
3636
};
37+
38+
// If any (re)declaration of `decl` contains executable code, returns that
39+
// redeclaration; otherwise, returns nullptr.
40+
// In the case of a function, executable code is contained in the function
41+
// definition. In the case of a variable, executable code can be contained in
42+
// the initializer of the variable.
43+
clang::Decl *getDeclWithExecutableCode(clang::Decl *decl) {
44+
if (auto fd = dyn_cast<clang::FunctionDecl>(decl)) {
45+
const clang::FunctionDecl *definition;
46+
if (fd->hasBody(definition)) {
47+
return const_cast<clang::FunctionDecl *>(definition);
48+
}
49+
} else if (auto vd = dyn_cast<clang::VarDecl>(decl)) {
50+
clang::VarDecl *initializingDecl = vd->getInitializingDeclaration();
51+
if (initializingDecl) {
52+
return initializingDecl;
53+
}
54+
}
55+
56+
return nullptr;
57+
}
58+
3759
} // end anonymous namespace
3860

3961
void IRGenModule::emitClangDecl(const clang::Decl *decl) {
40-
auto valueDecl = dyn_cast<clang::ValueDecl>(decl);
41-
if (!valueDecl || valueDecl->isExternallyVisible()) {
62+
// Ignore this decl if we've seen it before.
63+
if (!GlobalClangDecls.insert(decl->getCanonicalDecl()).second)
64+
return;
65+
66+
// Fast path for the case where `decl` doesn't contain executable code, so it
67+
// can't reference any other declarations that we would need to emit.
68+
if (getDeclWithExecutableCode(const_cast<clang::Decl *>(decl)) == nullptr) {
4269
ClangCodeGen->HandleTopLevelDecl(
4370
clang::DeclGroupRef(const_cast<clang::Decl*>(decl)));
4471
return;
4572
}
4673

47-
if (!GlobalClangDecls.insert(decl->getCanonicalDecl()).second)
48-
return;
4974
SmallVector<const clang::Decl *, 8> stack;
5075
stack.push_back(decl);
5176

@@ -69,13 +94,15 @@ void IRGenModule::emitClangDecl(const clang::Decl *decl) {
6994

7095
while (!stack.empty()) {
7196
auto *next = const_cast<clang::Decl *>(stack.pop_back_val());
72-
if (auto fn = dyn_cast<clang::FunctionDecl>(next)) {
73-
const clang::FunctionDecl *definition;
74-
if (fn->hasBody(definition)) {
75-
refFinder.TraverseDecl(const_cast<clang::FunctionDecl *>(definition));
76-
next = const_cast<clang::FunctionDecl *>(definition);
77-
}
97+
if (clang::Decl *executableDecl = getDeclWithExecutableCode(next)) {
98+
refFinder.TraverseDecl(executableDecl);
99+
next = executableDecl;
78100
}
101+
102+
if (auto var = dyn_cast<clang::VarDecl>(next))
103+
if (!var->isFileVarDecl())
104+
continue;
105+
79106
ClangCodeGen->HandleTopLevelDecl(clang::DeclGroupRef(next));
80107
}
81108
}

lib/IRGen/GenCoverage.cpp

+3-1
Original file line numberDiff line numberDiff line change
@@ -18,6 +18,7 @@
1818
#include "IRGenModule.h"
1919
#include "SwiftTargetInfo.h"
2020

21+
#include "swift/AST/IRGenOptions.h"
2122
#include "swift/SIL/SILModule.h"
2223
#include "llvm/IR/Constants.h"
2324
#include "llvm/IR/Module.h"
@@ -60,6 +61,7 @@ void IRGenModule::emitCoverageMapping() {
6061
if (std::find(Files.begin(), Files.end(), M->getFile()) == Files.end())
6162
Files.push_back(M->getFile());
6263

64+
auto remapper = getOptions().CoveragePrefixMap;
6365
// Awkwardly munge absolute filenames into a vector of StringRefs.
6466
// TODO: This is heinous - the same thing is happening in clang, but the API
6567
// really needs to be cleaned up for both.
@@ -68,7 +70,7 @@ void IRGenModule::emitCoverageMapping() {
6870
for (StringRef Name : Files) {
6971
llvm::SmallString<256> Path(Name);
7072
llvm::sys::fs::make_absolute(Path);
71-
FilenameStrs.push_back(std::string(Path.begin(), Path.end()));
73+
FilenameStrs.push_back(remapper.remapPath(Path));
7274
FilenameRefs.push_back(FilenameStrs.back());
7375
}
7476

lib/IRGen/GenDecl.cpp

+5-2
Original file line numberDiff line numberDiff line change
@@ -1104,8 +1104,11 @@ void IRGenerator::emitGlobalTopLevel(llvm::StringSet<> *linkerDirectives) {
11041104
IGM->emitSILDifferentiabilityWitness(&dw);
11051105
}
11061106

1107-
// Emit code coverage mapping data.
1108-
PrimaryIGM->emitCoverageMapping();
1107+
// Emit code coverage mapping data for all modules
1108+
for (auto Iter : *this) {
1109+
IRGenModule *IGM = Iter.second;
1110+
IGM->emitCoverageMapping();
1111+
}
11091112

11101113
for (auto Iter : *this) {
11111114
IRGenModule *IGM = Iter.second;

test/Driver/coverage-prefix-map.swift

+9
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,9 @@
1+
// RUN: not %target-swiftc_driver -coverage-prefix-map old %s 2>&1 | %FileCheck %s -check-prefix CHECK-INVALID
2+
// RUN: %target-swiftc_driver -### -coverage-prefix-map old=new %s 2>&1 | %FileCheck %s -check-prefix CHECK-SIMPLE
3+
// RUN: %target-swiftc_driver -### -coverage-prefix-map old=n=ew %s 2>&1 | %FileCheck %s -check-prefix CHECK-COMPLEX
4+
// RUN: %target-swiftc_driver -### -coverage-prefix-map old= %s 2>&1 | %FileCheck %s -check-prefix CHECK-EMPTY
5+
6+
// CHECK-INVALID: error: invalid argument 'old' to -coverage-prefix-map
7+
// CHECK-SIMPLE: coverage-prefix-map old=new
8+
// CHECK-COMPLEX: coverage-prefix-map old=n=ew
9+
// CHECK-EMPTY: coverage-prefix-map old=

test/IRGen/Inputs/local_extern.h

+21
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,21 @@
1+
static inline int _no_prior_var() {
2+
extern int var;
3+
return var;
4+
}
5+
6+
static inline int _no_prior_func() {
7+
extern int func();
8+
return func();
9+
}
10+
11+
static int prior_var = 1;
12+
static inline int _prior_var() {
13+
extern int prior_var;
14+
return prior_var;
15+
}
16+
17+
static inline int prior_func() { return 1; }
18+
static inline int _prior_func() {
19+
extern int prior_func();
20+
return prior_func();
21+
}

test/IRGen/local_extern.swift

+10
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,10 @@
1+
// RUN: %target-swift-frontend -import-objc-header %S/Inputs/local_extern.h %s -emit-ir | %FileCheck %s
2+
// CHECK: @var = external {{(dso_local )?}}global i32
3+
// CHECK: @prior_var = internal global i32
4+
// CHECK: declare {{(dso_local )?}}i32 @func
5+
// CHECK: define internal i32 @prior_func
6+
7+
print("\(_no_prior_var())")
8+
print("\(_no_prior_func())")
9+
print("\(_prior_var())")
10+
print("\(_prior_func())")
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#ifdef __cplusplus
2+
#define INLINE inline
3+
#else
4+
// When compiling as C, make the functions `static inline`. This is the flavor
5+
// of inline functions for which we require the behavior checked by this test.
6+
// Non-static C inline functions don't require Swift to emit LLVM IR for them
7+
// because the idea is that there will we one `.c` file that declares them
8+
// `extern inline`, causing an out-of-line definition to be emitted to the
9+
// corresponding .o file.
10+
#define INLINE static inline
11+
#endif
12+
13+
INLINE int notCalled() {
14+
return 42;
15+
}
16+
17+
INLINE int calledTransitively() {
18+
return 42;
19+
}
20+
21+
#ifdef __cplusplus
22+
class C {
23+
public:
24+
int memberFunctionCalledTransitively() {
25+
return 42;
26+
}
27+
};
28+
29+
inline int calledTransitivelyFromVarInit() {
30+
return 42;
31+
}
32+
33+
inline int varUsedFromSwift = calledTransitivelyFromVarInit();
34+
#else
35+
// C only allows constant initializers for variables with static storage
36+
// duration, so there's no way to initialize this with the result of a call to
37+
// an inline method. Just provide _some_ definition of `varImportedToSwift` so
38+
// we can import it in the test.
39+
static int varUsedFromSwift = 42;
40+
#endif
41+
42+
INLINE int calledFromSwift() {
43+
#ifdef __cplusplus
44+
C c;
45+
return calledTransitively() + c.memberFunctionCalledTransitively();
46+
#else
47+
return calledTransitively();
48+
#endif
49+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,4 @@
1+
module EmitCalledInlineFunction {
2+
header "emit-called-inline-function.h"
3+
export *
4+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
// Test that we emit LLVM IR for inline functions that are called directly or
2+
// transitively from Swift.
3+
//
4+
// Test that we don't emit LLVM IR for inline functions that are not called from
5+
// Swift.
6+
7+
// RUN: %empty-directory(%t)
8+
// RUN: %target-swift-frontend %s -I %S/Inputs -Xcc -std=c99 -emit-ir -o - | %FileCheck %s -check-prefix C99 --implicit-check-not notCalled
9+
// RUN: %target-swift-frontend %s -I %S/Inputs -enable-cxx-interop -emit-ir -o - | %FileCheck %s -check-prefix CXX --implicit-check-not notCalled
10+
11+
import EmitCalledInlineFunction
12+
13+
// C99-DAG: define internal i32 @calledFromSwift()
14+
// C99-DAG: define internal i32 @calledTransitively()
15+
16+
// CXX-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z15calledFromSwiftv|"\?calledFromSwift@@YAHXZ"}}()
17+
// CXX-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z18calledTransitivelyv|"\?calledTransitively@@YAHXZ"}}()
18+
// CXX-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_ZN1C32memberFunctionCalledTransitivelyEv|"\?memberFunctionCalledTransitively@C@@QEAAHXZ"}}(%class.C* %this)
19+
// CXX-DAG: define linkonce_odr{{( dso_local)?}} i32 @{{_Z29calledTransitivelyFromVarInitv|"\?calledTransitivelyFromVarInit@@YAHXZ"}}()
20+
21+
calledFromSwift()
22+
23+
let _ = varUsedFromSwift
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
func func1() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1 @@
1+
func func2() {}
+13
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,13 @@
1+
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -num-threads 0 -emit-ir %S/Inputs/coverage_num_threads1.swift | %FileCheck %s -check-prefix=SINGLE-SOURCE --implicit-check-not="llvm_coverage_mapping ="
2+
3+
// SINGLE-SOURCE: llvm_coverage_mapping =
4+
5+
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -num-threads 0 -emit-ir %S/Inputs/coverage_num_threads1.swift %S/Inputs/coverage_num_threads2.swift | %FileCheck %s -check-prefix=SINGLE-OBJECT --implicit-check-not="llvm_coverage_mapping ="
6+
7+
// SINGLE-OBJECT: llvm_coverage_mapping =
8+
9+
// Using 1 goes down the multithreaded codepath but only operates with a single thread to work around an issue on Windows where the output of both IR modules is interleaved and therefore the output is invalid
10+
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -num-threads 1 -emit-ir %S/Inputs/coverage_num_threads1.swift %S/Inputs/coverage_num_threads2.swift | %FileCheck %s -check-prefix=MULTIPLE-OBJECTS --implicit-check-not="llvm_coverage_mapping ="
11+
12+
// MULTIPLE-OBJECTS: llvm_coverage_mapping =
13+
// MULTIPLE-OBJECTS: llvm_coverage_mapping =
+16
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,16 @@
1+
// %s expands to an absolute path, so to test relative paths we need to create a
2+
// clean directory, put the source there, and cd into it.
3+
// RUN: rm -rf %t
4+
// RUN: mkdir -p %t/foo/bar/baz
5+
// RUN: echo "func coverage() {}" > %t/foo/bar/baz/coverage_relative_path.swift
6+
// RUN: cd %t/foo/bar
7+
8+
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -Xllvm -enable-name-compression=false -emit-ir %/t/foo/bar/baz/coverage_relative_path.swift | %FileCheck -check-prefix=ABSOLUTE %s
9+
//
10+
// ABSOLUTE: @__llvm_coverage_mapping = {{.*"\\01.*foo.*bar.*baz.*coverage_relative_path\.swift}}
11+
12+
// RUN: %target-swift-frontend -profile-generate -profile-coverage-mapping -Xllvm -enable-name-compression=false -coverage-prefix-map %/t/foo/bar=. -emit-ir %/t/foo/bar/baz/coverage_relative_path.swift | %FileCheck -check-prefix=RELATIVE %s
13+
//
14+
// RELATIVE: @__llvm_coverage_mapping = {{.*"\\01[^/]*}}.{{/|\\}}baz{{.*coverage_relative_path\.swift}}
15+
16+
func coverage() {}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,11 @@
1+
public protocol Gesture {
2+
associatedtype Body: Gesture
3+
var body: Body { get }
4+
5+
associatedtype Value
6+
var value: Value { get }
7+
}
8+
9+
extension Gesture {
10+
public var value: Body.Value { return body.value }
11+
}
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,14 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %target-swift-frontend -disable-availability-checking -emit-module-path %t/replace_opaque_type_public_assoc_type_m.swiftmodule %S/Inputs/replace_opaque_type_public_assoc_type_m.swift
3+
// RUN: %target-swift-emit-silgen -disable-availability-checking -I %t %s -verify
4+
5+
import replace_opaque_type_public_assoc_type_m
6+
7+
struct PiggyBack: Gesture {
8+
var action: () -> Void
9+
10+
var body: some Gesture {
11+
action()
12+
return self
13+
}
14+
}

utils/build-presets.ini

+8
Original file line numberDiff line numberDiff line change
@@ -1214,13 +1214,21 @@ compiler-vendor=apple
12141214

12151215
dash-dash
12161216

1217+
# Cross compile for Apple Silicon
1218+
cross-compile-hosts=macosx-arm64
1219+
12171220
lldb-no-debugserver
12181221
lldb-use-system-debugserver
12191222
lldb-build-type=Release
12201223
verbose-build
12211224
build-ninja
12221225
build-swift-stdlib-unittest-extra
12231226

1227+
# When producing a package, don't copy the Swift Resource/ directory.
1228+
# This is mainly a space optimization.
1229+
extra-cmake-options=
1230+
-DLLDB_FRAMEWORK_COPY_SWIFT_RESOURCES=0
1231+
12241232
install-swift
12251233
install-lldb
12261234
install-llbuild

0 commit comments

Comments
 (0)