Skip to content

Add -prefix-serialized-debugging-options #39138

New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

Merged
merged 3 commits into from
Sep 30, 2021
Merged
Show file tree
Hide file tree
Changes from all commits
Commits
File filter

Filter by extension

Filter by extension

Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
6 changes: 6 additions & 0 deletions include/swift/AST/SearchPathOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define SWIFT_AST_SEARCHPATHOPTIONS_H

#include "swift/Basic/ArrayRefView.h"
#include "swift/Basic/PathRemapper.h"
#include "llvm/ADT/Hashing.h"

#include <string>
Expand Down Expand Up @@ -97,6 +98,11 @@ class SearchPathOptions {

/// A file containing modules we should perform batch scanning.
std::string BatchScanInputFilePath;

/// Debug path mappings to apply to serialized search paths. These are
/// specified in LLDB from the target.source-map entries.
PathRemapper SearchPathRemapper;

private:
static StringRef
pathStringFromFrameworkSearchPath(const FrameworkSearchPath &next) {
Expand Down
3 changes: 3 additions & 0 deletions include/swift/Basic/LangOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -771,6 +771,9 @@ namespace swift {
DisableOverlayModules,
EnableClangSPI);
}

std::vector<std::string> getRemappedExtraArgs(
std::function<std::string(StringRef)> pathRemapCallback) const;
};

} // end namespace swift
Expand Down
5 changes: 5 additions & 0 deletions include/swift/Frontend/FrontendOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -182,6 +182,11 @@ class FrontendOptions {
/// module appears to not be a public module.
Optional<bool> SerializeOptionsForDebugging;

/// When true the debug prefix map entries will be applied to debugging
/// options before serialization. These can be reconstructed at debug time by
/// applying the inverse map in SearchPathOptions.SearchPathRemapper.
bool DebugPrefixSerializedDebuggingOptions = false;

/// When true, check if all required SwiftOnoneSupport symbols are present in
/// the module.
bool CheckOnoneSupportCompleteness = false;
Expand Down
6 changes: 5 additions & 1 deletion include/swift/Option/Options.td
Original file line number Diff line number Diff line change
Expand Up @@ -559,7 +559,7 @@ def disable_bridging_pch : Flag<["-"], "disable-bridging-pch">,
def lto : Joined<["-"], "lto=">,
Flags<[FrontendOption, NoInteractiveOption]>,
HelpText<"Specify the LTO type to either 'llvm-thin' or 'llvm-full'">;

def lto_library : Separate<["-"], "lto-library">,
Flags<[FrontendOption, ArgumentIsPath, NoInteractiveOption]>,
HelpText<"Perform LTO with <lto-library>">, MetaVarName<"<lto-library>">;
Expand Down Expand Up @@ -815,6 +815,10 @@ def debug_info_format : Joined<["-"], "debug-info-format=">,
Flags<[FrontendOption]>,
HelpText<"Specify the debug info format type to either 'dwarf' or 'codeview'">;

def prefix_serialized_debugging_options : Flag<["-"], "prefix-serialized-debugging-options">,
Flags<[FrontendOption]>,
HelpText<"Apply debug prefix mappings to serialized debug info in Swiftmodule files">;

// Verify debug info
def verify_debug_info : Flag<["-"], "verify-debug-info">,
Flags<[NoInteractiveOption, DoesNotAffectIncrementalBuild]>,
Expand Down
6 changes: 5 additions & 1 deletion include/swift/Serialization/SerializationOptions.h
Original file line number Diff line number Diff line change
Expand Up @@ -14,6 +14,7 @@
#define SWIFT_SERIALIZATION_SERIALIZATIONOPTIONS_H

#include "swift/Basic/LLVM.h"
#include "swift/Basic/PathRemapper.h"
#include "llvm/Support/VersionTuple.h"

namespace swift {
Expand Down Expand Up @@ -42,7 +43,10 @@ namespace swift {
StringRef ImportedHeader;
StringRef ModuleLinkName;
StringRef ModuleInterface;
ArrayRef<std::string> ExtraClangOptions;
std::vector<std::string> ExtraClangOptions;

/// Path prefixes that should be rewritten in debug info.
PathRemapper DebuggingOptionsPrefixMap;

/// Describes a single-file dependency for this module, along with the
/// appropriate strategy for how to verify if it's up-to-date.
Expand Down
53 changes: 53 additions & 0 deletions lib/Basic/LangOptions.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -408,3 +408,56 @@ DiagnosticBehavior LangOptions::getAccessNoteFailureLimit() const {
}
llvm_unreachable("covered switch");
}

std::vector<std::string> ClangImporterOptions::getRemappedExtraArgs(
std::function<std::string(StringRef)> pathRemapCallback) const {
auto consumeIncludeOption = [](StringRef &arg, StringRef &prefix) {
static StringRef options[] = {"-I",
"-F",
"-fmodule-map-file=",
"-iquote",
"-idirafter",
"-iframeworkwithsysroot",
"-iframework",
"-iprefix",
"-iwithprefixbefore",
"-iwithprefix",
"-isystemafter",
"-isystem",
"-isysroot",
"-ivfsoverlay",
"-working-directory=",
"-working-directory"};
for (StringRef &option : options)
if (arg.consume_front(option)) {
prefix = option;
return true;
}
return false;
};

// true if the previous argument was the dash-option of an option pair
bool remap_next = false;
std::vector<std::string> args;
for (auto A : ExtraArgs) {
StringRef prefix;
StringRef arg(A);

if (remap_next) {
remap_next = false;
args.push_back(pathRemapCallback(arg));
} else if (consumeIncludeOption(arg, prefix)) {
if (arg.empty()) {
// Option pair
remap_next = true;
args.push_back(prefix.str());
} else {
// Combine prefix with remapped path value
args.push_back(prefix.str() + pathRemapCallback(arg));
}
} else {
args.push_back(A);
}
}
return args;
}
2 changes: 2 additions & 0 deletions lib/Frontend/ArgsToFrontendOptionsConverter.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -258,6 +258,8 @@ bool ArgsToFrontendOptionsConverter::convert(
A->getOption().matches(OPT_serialize_debugging_options);
}

Opts.DebugPrefixSerializedDebuggingOptions |=
Args.hasArg(OPT_prefix_serialized_debugging_options);
Opts.EnableSourceImport |= Args.hasArg(OPT_enable_source_import);
Opts.ImportUnderlyingModule |= Args.hasArg(OPT_import_underlying_module);
Opts.EnableIncrementalDependencyVerifier |= Args.hasArg(OPT_verify_incremental_dependencies);
Expand Down
16 changes: 15 additions & 1 deletion lib/Frontend/Frontend.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -147,7 +147,7 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
serializationOpts.ImportedHeader = opts.ImplicitObjCHeaderPath;
serializationOpts.ModuleLinkName = opts.ModuleLinkName;
serializationOpts.UserModuleVersion = opts.UserModuleVersion;
serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs;

serializationOpts.PublicDependentLibraries =
getIRGenOptions().PublicLinkLibraries;
serializationOpts.SDKName = getLangOptions().SDKName;
Expand Down Expand Up @@ -176,6 +176,20 @@ SerializationOptions CompilerInvocation::computeSerializationOptions(
opts.SerializeOptionsForDebugging.getValueOr(
!module->isExternallyConsumed());

if (serializationOpts.SerializeOptionsForDebugging &&
opts.DebugPrefixSerializedDebuggingOptions) {
serializationOpts.DebuggingOptionsPrefixMap =
getIRGenOptions().DebugPrefixMap;
auto &remapper = serializationOpts.DebuggingOptionsPrefixMap;
auto remapClangPaths = [&remapper](StringRef path) {
return remapper.remapPath(path);
};
serializationOpts.ExtraClangOptions =
getClangImporterOptions().getRemappedExtraArgs(remapClangPaths);
} else {
serializationOpts.ExtraClangOptions = getClangImporterOptions().ExtraArgs;
}

serializationOpts.DisableCrossModuleIncrementalInfo =
opts.DisableCrossModuleIncrementalBuild;

Expand Down
8 changes: 5 additions & 3 deletions lib/Serialization/ModuleFile.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -158,9 +158,11 @@ Status ModuleFile::associateWithFileContext(FileUnit *file, SourceLoc diagLoc,
return error(status);
}

for (const auto &searchPath : Core->SearchPaths)
ctx.addSearchPath(searchPath.Path, searchPath.IsFramework,
searchPath.IsSystem);
for (const auto &searchPath : Core->SearchPaths) {
ctx.addSearchPath(
ctx.SearchPathOpts.SearchPathRemapper.remapPath(searchPath.Path),
searchPath.IsFramework, searchPath.IsSystem);
}

auto clangImporter = static_cast<ClangImporter *>(ctx.getClangModuleLoader());

Expand Down
63 changes: 38 additions & 25 deletions lib/Serialization/Serialization.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -40,6 +40,7 @@
#include "swift/Basic/Defer.h"
#include "swift/Basic/Dwarf.h"
#include "swift/Basic/FileSystem.h"
#include "swift/Basic/PathRemapper.h"
#include "swift/Basic/STLExtras.h"
#include "swift/Basic/Version.h"
#include "swift/ClangImporter/ClangImporter.h"
Expand All @@ -48,9 +49,9 @@
#include "swift/Demangling/ManglingMacros.h"
#include "swift/Serialization/SerializationOptions.h"
#include "swift/Strings.h"
#include "clang/AST/DeclTemplate.h"
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
#include "swift/SymbolGraphGen/SymbolGraphGen.h"
#include "swift/SymbolGraphGen/SymbolGraphOptions.h"
#include "clang/AST/DeclTemplate.h"
#include "llvm/ADT/SmallSet.h"
#include "llvm/ADT/SmallString.h"
#include "llvm/ADT/StringExtras.h"
Expand Down Expand Up @@ -511,7 +512,7 @@ static uint8_t getRawOpaqueReadOwnership(swift::OpaqueReadOwnership ownership) {
CASE(OwnedOrBorrowed)
#undef CASE
}
llvm_unreachable("bad kind");
llvm_unreachable("bad kind");
}

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

SDKPath.emit(ScratchRecord, M->getASTContext().SearchPathOpts.SDKPath);
const auto &PathRemapper = options.DebuggingOptionsPrefixMap;
SDKPath.emit(
ScratchRecord,
PathRemapper.remapPath(M->getASTContext().SearchPathOpts.SDKPath));
auto &Opts = options.ExtraClangOptions;
for (auto Arg = Opts.begin(), E = Opts.end(); Arg != E; ++Arg) {
// FIXME: This is a hack and calls for a better design.
//
// Filter out any -ivfsoverlay options that include an
// unextended-module-overlay.yaml overlay. By convention the Xcode
// buildsystem uses these while *building* mixed Objective-C and Swift
// frameworks; but they should never be used to *import* the module
// defined in the framework.
if (StringRef(*Arg).startswith("-ivfsoverlay")) {
for (auto Arg = Opts.begin(), E = Opts.end(); Arg != E; ++Arg) {
StringRef arg(*Arg);
if (arg.startswith("-ivfsoverlay")) {
// FIXME: This is a hack and calls for a better design.
//
// Filter out any -ivfsoverlay options that include an
// unextended-module-overlay.yaml overlay. By convention the Xcode
// buildsystem uses these while *building* mixed Objective-C and
// Swift frameworks; but they should never be used to *import* the
// module defined in the framework.
auto Next = std::next(Arg);
if (Next != E &&
StringRef(*Next).endswith("unextended-module-overlay.yaml")) {
++Arg;
continue;
}
} else if (arg.startswith("-fdebug-prefix-map=")) {
Copy link
Contributor

Choose a reason for hiding this comment

The reason will be displayed to describe this comment to others. Learn more.

Please add a brief comment to explain why we skip this flag.

// We don't serialize the debug prefix map flags as these
// contain absoute paths that are not usable on different
// machines. These flags are not necessary to compile the
// clang modules again so are safe to remove.
continue;
}
XCC.emit(ScratchRecord, *Arg);
XCC.emit(ScratchRecord, arg);
}
}
}
Expand Down Expand Up @@ -1127,14 +1138,16 @@ void Serializer::writeInputBlock(const SerializationOptions &options) {
input_block::ModuleInterfaceLayout ModuleInterface(Out);

if (options.SerializeOptionsForDebugging) {
const auto &PathMapper = options.DebuggingOptionsPrefixMap;
const SearchPathOptions &searchPathOpts = M->getASTContext().SearchPathOpts;
// Put the framework search paths first so that they'll be preferred upon
// deserialization.
for (auto &framepath : searchPathOpts.FrameworkSearchPaths)
SearchPath.emit(ScratchRecord, /*framework=*/true, framepath.IsSystem,
framepath.Path);
PathMapper.remapPath(framepath.Path));
for (auto &path : searchPathOpts.ImportSearchPaths)
SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false, path);
SearchPath.emit(ScratchRecord, /*framework=*/false, /*system=*/false,
PathMapper.remapPath(path));
}

// Note: We're not using StringMap here because we don't need to own the
Expand Down Expand Up @@ -1468,7 +1481,7 @@ void Serializer::writeASTBlockEntity(const SILLayout *layout) {
typeRef |= 0x80000000U;
data.push_back(typeRef);
}

unsigned abbrCode
= DeclTypeAbbrCodes[SILLayoutLayout::Code];

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

case DeclKind::OpaqueType:
return true;

case DeclKind::EnumElement:
case DeclKind::Protocol:
case DeclKind::Constructor:
Expand Down Expand Up @@ -1801,14 +1814,14 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
if (auto opaque = dyn_cast<OpaqueTypeDecl>(generic)) {
if (!opaque->hasName()) {
abbrCode = DeclTypeAbbrCodes[XRefOpaqueReturnTypePathPieceLayout::Code];

XRefOpaqueReturnTypePathPieceLayout::emitRecord(Out, ScratchRecord,
abbrCode,
addDeclBaseNameRef(opaque->getOpaqueReturnTypeIdentifier()));
break;
}
}

assert(generic->hasName());

abbrCode = DeclTypeAbbrCodes[XRefTypePathPieceLayout::Code];
Expand Down Expand Up @@ -1849,7 +1862,7 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
case DeclContextKind::SubscriptDecl: {
auto SD = cast<SubscriptDecl>(DC);
writeCrossReference(DC->getParent(), pathLen + 1);

Type ty = SD->getInterfaceType()->getCanonicalType();

abbrCode = DeclTypeAbbrCodes[XRefValuePathPieceLayout::Code];
Expand All @@ -1860,7 +1873,7 @@ void Serializer::writeCrossReference(const DeclContext *DC, uint32_t pathLen) {
SD->isStatic());
break;
}

case DeclContextKind::AbstractFunctionDecl: {
if (auto fn = dyn_cast<AccessorDecl>(DC)) {
auto storage = fn->getStorage();
Expand Down Expand Up @@ -1972,7 +1985,7 @@ void Serializer::writeCrossReference(const Decl *D) {
addDeclBaseNameRef(opaque->getOpaqueReturnTypeIdentifier()));
return;
}

if (auto genericParam = dyn_cast<GenericTypeParamDecl>(D)) {
assert(!D->getDeclContext()->isModuleScopeContext() &&
"Cannot cross reference a generic type decl at module scope.");
Expand Down Expand Up @@ -4673,7 +4686,7 @@ class ClangToSwiftBasicWriter :

Serializer &S;
SmallVectorImpl<uint64_t> &Record;
using TypeWriter =
using TypeWriter =
clang::serialization::AbstractTypeWriter<ClangToSwiftBasicWriter>;
TypeWriter Types;

Expand Down Expand Up @@ -5477,7 +5490,7 @@ void Serializer::writeAST(ModuleOrSourceFile DC) {
/*isLocal=*/true);
}
}

for (auto OTD : opaqueReturnTypeDecls) {
// FIXME: We should delay parsing function bodies so these type decls
// don't even get added to the file.
Expand Down
Loading