Skip to content

Commit ce6b4b3

Browse files
committed
Add -prefix-serialized-debugging-options
This commit adds the `-prefix-serialized-debugging-options` flag, which is used to apply the debug prefix map to serialized debugging options embedded in the swiftmodule files.
1 parent 58d67be commit ce6b4b3

File tree

7 files changed

+121
-28
lines changed

7 files changed

+121
-28
lines changed

include/swift/Frontend/FrontendOptions.h

Lines changed: 5 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -182,6 +182,11 @@ class FrontendOptions {
182182
/// module appears to not be a public module.
183183
Optional<bool> SerializeOptionsForDebugging;
184184

185+
/// When true the debug prefix map entries will be applied to debugging
186+
/// options before serialization. These can be reconstructed at debug time by
187+
/// applying the inverse map in SearchPathOptions.SearchPathRemapper.
188+
bool DebugPrefixSerializedDebuggingOptions = false;
189+
185190
/// When true, check if all required SwiftOnoneSupport symbols are present in
186191
/// the module.
187192
bool CheckOnoneSupportCompleteness = false;

include/swift/Option/Options.td

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -559,7 +559,7 @@ def disable_bridging_pch : Flag<["-"], "disable-bridging-pch">,
559559
def lto : Joined<["-"], "lto=">,
560560
Flags<[FrontendOption, NoInteractiveOption]>,
561561
HelpText<"Specify the LTO type to either 'llvm-thin' or 'llvm-full'">;
562-
562+
563563
def lto_library : Separate<["-"], "lto-library">,
564564
Flags<[FrontendOption, ArgumentIsPath, NoInteractiveOption]>,
565565
HelpText<"Perform LTO with <lto-library>">, MetaVarName<"<lto-library>">;
@@ -815,6 +815,10 @@ def debug_info_format : Joined<["-"], "debug-info-format=">,
815815
Flags<[FrontendOption]>,
816816
HelpText<"Specify the debug info format type to either 'dwarf' or 'codeview'">;
817817

818+
def prefix_serialized_debugging_options : Flag<["-"], "prefix-serialized-debugging-options">,
819+
Flags<[FrontendOption]>,
820+
HelpText<"Apply debug prefix mappings to serialized debug info in Swiftmodule files">;
821+
818822
// Verify debug info
819823
def verify_debug_info : Flag<["-"], "verify-debug-info">,
820824
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,

include/swift/Serialization/SerializationOptions.h

Lines changed: 5 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -14,6 +14,7 @@
1414
#define SWIFT_SERIALIZATION_SERIALIZATIONOPTIONS_H
1515

1616
#include "swift/Basic/LLVM.h"
17+
#include "swift/Basic/PathRemapper.h"
1718
#include "llvm/Support/VersionTuple.h"
1819

1920
namespace swift {
@@ -42,7 +43,10 @@ namespace swift {
4243
StringRef ImportedHeader;
4344
StringRef ModuleLinkName;
4445
StringRef ModuleInterface;
45-
ArrayRef<std::string> ExtraClangOptions;
46+
std::vector<std::string> ExtraClangOptions;
47+
48+
/// Path prefixes that should be rewritten in debug info.
49+
PathRemapper DebuggingOptionsPrefixMap;
4650

4751
/// Describes a single-file dependency for this module, along with the
4852
/// appropriate strategy for how to verify if it's up-to-date.

lib/Frontend/ArgsToFrontendOptionsConverter.cpp

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -258,6 +258,8 @@ bool ArgsToFrontendOptionsConverter::convert(
258258
A->getOption().matches(OPT_serialize_debugging_options);
259259
}
260260

261+
Opts.DebugPrefixSerializedDebuggingOptions |=
262+
Args.hasArg(OPT_prefix_serialized_debugging_options);
261263
Opts.EnableSourceImport |= Args.hasArg(OPT_enable_source_import);
262264
Opts.ImportUnderlyingModule |= Args.hasArg(OPT_import_underlying_module);
263265
Opts.EnableIncrementalDependencyVerifier |= Args.hasArg(OPT_verify_incremental_dependencies);

lib/Frontend/Frontend.cpp

Lines changed: 15 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -147,7 +147,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
147147
serializationOpts.ImportedHeader = opts.ImplicitObjCHeaderPath;
148148
serializationOpts.ModuleLinkName = opts.ModuleLinkName;
149149
serializationOpts.UserModuleVersion = opts.UserModuleVersion;
150-
serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs;
150+
151151
serializationOpts.PublicDependentLibraries =
152152
getIRGenOptions().PublicLinkLibraries;
153153
serializationOpts.SDKName = getLangOptions().SDKName;
@@ -176,6 +176,20 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
176176
opts.SerializeOptionsForDebugging.getValueOr(
177177
!module->isExternallyConsumed());
178178

179+
if (serializationOpts.SerializeOptionsForDebugging &&
180+
opts.DebugPrefixSerializedDebuggingOptions) {
181+
serializationOpts.DebuggingOptionsPrefixMap =
182+
getIRGenOptions().DebugPrefixMap;
183+
auto &remapper = serializationOpts.DebuggingOptionsPrefixMap;
184+
auto remapClangPaths = [&remapper](StringRef path) {
185+
return remapper.remapPath(path);
186+
};
187+
serializationOpts.ExtraClangOptions =
188+
getClangImporterOptions().getRemappedExtraArgs(remapClangPaths);
189+
} else {
190+
serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs;
191+
}
192+
179193
serializationOpts.DisableCrossModuleIncrementalInfo =
180194
opts.DisableCrossModuleIncrementalBuild;
181195

lib/Serialization/Serialization.cpp

Lines changed: 38 additions & 25 deletions
Original file line numberDiff line numberDiff line change
@@ -40,6 +40,7 @@
4040
#include "swift/Basic/Defer.h"
4141
#include "swift/Basic/Dwarf.h"
4242
#include "swift/Basic/FileSystem.h"
43+
#include "swift/Basic/PathRemapper.h"
4344
#include "swift/Basic/STLExtras.h"
4445
#include "swift/Basic/Version.h"
4546
#include "swift/ClangImporter/ClangImporter.h"
@@ -48,9 +49,9 @@
4849
#include "swift/Demangling/ManglingMacros.h"
4950
#include "swift/Serialization/SerializationOptions.h"
5051
#include "swift/Strings.h"
51-
#include "clang/AST/DeclTemplate.h"
52-
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
5352
#include "swift/SymbolGraphGen/SymbolGraphGen.h"
53+
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
54+
#include "clang/AST/DeclTemplate.h"
5455
#include "llvm/ADT/SmallSet.h"
5556
#include "llvm/ADT/SmallString.h"
5657
#include "llvm/ADT/StringExtras.h"
@@ -511,7 +512,7 @@ static uint8_t getRawOpaqueReadOwnership(swift::OpaqueReadOwnership ownership) {
511512
CASE(OwnedOrBorrowed)
512513
#undef CASE
513514
}
514-
llvm_unreachable("bad kind");
515+
llvm_unreachable("bad kind");
515516
}
516517

517518
static uint8_t getRawReadImplKind(swift::ReadImplKind kind) {
@@ -1058,25 +1059,35 @@ void Serializer::writeHeader(const SerializationOptions &options) {
10581059
options_block::SDKPathLayout SDKPath(Out);
10591060
options_block::XCCLayout XCC(Out);
10601061

1061-
SDKPath.emit(ScratchRecord, M->getASTContext().SearchPathOpts.SDKPath);
1062+
const auto &PathRemapper = options.DebuggingOptionsPrefixMap;
1063+
SDKPath.emit(
1064+
ScratchRecord,
1065+
PathRemapper.remapPath(M->getASTContext().SearchPathOpts.SDKPath));
10621066
auto &Opts = options.ExtraClangOptions;
1063-
for (auto Arg = Opts.begin(), E = Opts.end(); Arg != E; ++Arg) {
1064-
// FIXME: This is a hack and calls for a better design.
1065-
//
1066-
// Filter out any -ivfsoverlay options that include an
1067-
// unextended-module-overlay.yaml overlay. By convention the Xcode
1068-
// buildsystem uses these while *building* mixed Objective-C and Swift
1069-
// frameworks; but they should never be used to *import* the module
1070-
// defined in the framework.
1071-
if (StringRef(*Arg).startswith("-ivfsoverlay")) {
1067+
for (auto Arg = Opts.begin(), E = Opts.end(); Arg != E; ++Arg) {
1068+
StringRef arg(*Arg);
1069+
if (arg.startswith("-ivfsoverlay")) {
1070+
// FIXME: This is a hack and calls for a better design.
1071+
//
1072+
// Filter out any -ivfsoverlay options that include an
1073+
// unextended-module-overlay.yaml overlay. By convention the Xcode
1074+
// buildsystem uses these while *building* mixed Objective-C and
1075+
// Swift frameworks; but they should never be used to *import* the
1076+
// module defined in the framework.
10721077
auto Next = std::next(Arg);
10731078
if (Next != E &&
10741079
StringRef(*Next).endswith("unextended-module-overlay.yaml")) {
10751080
++Arg;
10761081
continue;
10771082
}
1083+
} else if (arg.startswith("-fdebug-prefix-map=")) {
1084+
// We don't serialize the debug prefix map flags as these
1085+
// contain absoute paths that are not usable on different
1086+
// machines. These flags are not necessary to compile the
1087+
// clang modules again so are safe to remove.
1088+
continue;
10781089
}
1079-
XCC.emit(ScratchRecord, *Arg);
1090+
XCC.emit(ScratchRecord, arg);
10801091
}
10811092
}
10821093
}
@@ -1127,14 +1138,16 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
11271138
input_block::ModuleInterfaceLayout ModuleInterface(Out);
11281139

11291140
if (options.SerializeOptionsForDebugging) {
1141+
const auto &PathMapper = options.DebuggingOptionsPrefixMap;
11301142
const SearchPathOptions &searchPathOpts = M->getASTContext().SearchPathOpts;
11311143
// Put the framework search paths first so that they'll be preferred upon
11321144
// deserialization.
11331145
for (auto &framepath : searchPathOpts.FrameworkSearchPaths)
11341146
SearchPath.emit(ScratchRecord, /*framework=*/true, framepath.IsSystem,
1135-
framepath.Path);
1147+
PathMapper.remapPath(framepath.Path));
11361148
for (auto &path : searchPathOpts.ImportSearchPaths)
1137-
SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false, path);
1149+
SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false,
1150+
PathMapper.remapPath(path));
11381151
}
11391152

11401153
// Note: We're not using StringMap here because we don't need to own the
@@ -1468,7 +1481,7 @@ void Serializer::writeASTBlockEntity(const SILLayout *layout) {
14681481
typeRef |= 0x80000000U;
14691482
data.push_back(typeRef);
14701483
}
1471-
1484+
14721485
unsigned abbrCode
14731486
= DeclTypeAbbrCodes[SILLayoutLayout::Code];
14741487

@@ -1703,7 +1716,7 @@ static bool shouldSerializeMember(Decl *D) {
17031716

17041717
case DeclKind::OpaqueType:
17051718
return true;
1706-
1719+
17071720
case DeclKind::EnumElement:
17081721
case DeclKind::Protocol:
17091722
case DeclKind::Constructor:
@@ -1801,14 +1814,14 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
18011814
if (auto opaque = dyn_cast<OpaqueTypeDecl>(generic)) {
18021815
if (!opaque->hasName()) {
18031816
abbrCode = DeclTypeAbbrCodes[XRefOpaqueReturnTypePathPieceLayout::Code];
1804-
1817+
18051818
XRefOpaqueReturnTypePathPieceLayout::emitRecord(Out, ScratchRecord,
18061819
abbrCode,
18071820
addDeclBaseNameRef(opaque->getOpaqueReturnTypeIdentifier()));
18081821
break;
18091822
}
18101823
}
1811-
1824+
18121825
assert(generic->hasName());
18131826

18141827
abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code];
@@ -1849,7 +1862,7 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
18491862
case DeclContextKind::SubscriptDecl: {
18501863
auto SD = cast<SubscriptDecl>(DC);
18511864
writeCrossReference(DC->getParent(), pathLen + 1);
1852-
1865+
18531866
Type ty = SD->getInterfaceType()->getCanonicalType();
18541867

18551868
abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code];
@@ -1860,7 +1873,7 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
18601873
SD->isStatic());
18611874
break;
18621875
}
1863-
1876+
18641877
case DeclContextKind::AbstractFunctionDecl: {
18651878
if (auto fn = dyn_cast<AccessorDecl>(DC)) {
18661879
auto storage = fn->getStorage();
@@ -1972,7 +1985,7 @@ void Serializer::writeCrossReference(const Decl *D) {
19721985
addDeclBaseNameRef(opaque->getOpaqueReturnTypeIdentifier()));
19731986
return;
19741987
}
1975-
1988+
19761989
if (auto genericParam = dyn_cast<GenericTypeParamDecl>(D)) {
19771990
assert(!D->getDeclContext()->isModuleScopeContext() &&
19781991
"Cannot cross reference a generic type decl at module scope.");
@@ -4673,7 +4686,7 @@ class ClangToSwiftBasicWriter :
46734686

46744687
Serializer &S;
46754688
SmallVectorImpl<uint64_t> &Record;
4676-
using TypeWriter =
4689+
using TypeWriter =
46774690
clang::serialization::AbstractTypeWriter<ClangToSwiftBasicWriter>;
46784691
TypeWriter Types;
46794692

@@ -5477,7 +5490,7 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
54775490
/*isLocal=*/true);
54785491
}
54795492
}
5480-
5493+
54815494
for (auto OTD : opaqueReturnTypeDecls) {
54825495
// FIXME: We should delay parsing function bodies so these type decls
54835496
// don't even get added to the file.
Lines changed: 51 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,51 @@
1+
// RUN: %empty-directory(%t)
2+
// RUN: %empty-directory(%t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule)
3+
// RUN: %target-swift-frontend -emit-module -o %t/Frameworks/has_alias.framework/Modules/has_alias.swiftmodule/%target-swiftmodule-name %S/Inputs/alias.swift -module-name has_alias
4+
// RUN: %empty-directory(%t/secret)
5+
// RUN: %target-swift-frontend -emit-module -o %t/secret %S/Inputs/struct_with_operators.swift
6+
// RUN: %target-swift-frontend -emit-module -o %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks %S/Inputs/has_xref.swift
7+
// RUN: %empty-directory(%t/workingdir)
8+
// RUN: cd %t/workingdir && %target-swift-frontend -sdk %t/sdk %s -emit-module -o %t/prefixed.swiftmodule \
9+
// RUN: -I %t -I %t/secret -F %t/Frameworks -Fsystem %t/SystemFrameworks \
10+
// RUN: -Xcc -I -Xcc %t/include -Xcc -isystem -Xcc %t/system -Xcc -F -Xcc %t/fw \
11+
// RUN: -Xcc -I%t/includejoined -Xcc -isystem%t/systemjoined -Xcc -F%t/fwjoined \
12+
// RUN: -Xcc -D -Xcc donotprefixme -prefix-serialized-debugging-options \
13+
// RUN: -debug-prefix-map %t/workingdir=WORKINGDIR -debug-prefix-map %t/sdk=SDKROOT -debug-prefix-map %t=SRC -debug-prefix-map donotprefixme=ERROR
14+
// RUN: llvm-bcanalyzer -dump %t/prefixed.swiftmodule | %FileCheck %s
15+
16+
import has_xref
17+
18+
numeric(42)
19+
20+
// CHECK-LABEL: <OPTIONS_BLOCK
21+
// CHECK: <SDK_PATH abbrevid={{[0-9]+}}/> blob data = 'SDKROOT'
22+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-working-directory'
23+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = 'WORKINGDIR'
24+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-I'
25+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = 'SRC/include'
26+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-isystem'
27+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = 'SRC/system'
28+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-F'
29+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = 'SRC/fw'
30+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-ISRC/includejoined'
31+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-isystemSRC/systemjoined'
32+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-FSRC/fwjoined'
33+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = '-D'
34+
// CHECK: <XCC abbrevid={{[0-9]+}}/> blob data = 'donotprefixme'
35+
// CHECK-NOT: <XCC abbrevid={{[0-9]+}}/> blob data = '-fdebug-prefix-map
36+
// CHECK: </OPTIONS_BLOCK>
37+
38+
// CHECK-LABEL: <INPUT_BLOCK
39+
// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=1 op1=0/> blob data = 'SRC/Frameworks'
40+
// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=1 op1=1/> blob data = 'SRC/SystemFrameworks'
41+
// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=0 op1=0/> blob data = 'SRC'
42+
// CHECK: <SEARCH_PATH abbrevid={{[0-9]+}} op0=0 op1=0/> blob data = 'SRC/secret'
43+
// CHECK: </INPUT_BLOCK>
44+
45+
// RUN: cd %t/workingdir && %target-swift-frontend -sdk %t/sdk %s -emit-module -o %t/unprefixed.swiftmodule \
46+
// RUN: -I %t -F %t/Frameworks \
47+
// RUN: -Xcc -I -Xcc %t/include \
48+
// RUN: -debug-prefix-map %t=TESTPREFIX
49+
// RUN: llvm-bcanalyzer -dump %t/unprefixed.swiftmodule | %FileCheck --check-prefix=UNPREFIXED %s
50+
51+
// UNPREFIXED-NOT: TESTPREFIX

0 commit comments

Comments
 (0)