Skip to content

Commit 8c12e44

Browse files
committed
[lldb] handle relative working directories in swiftmodule debug info
This change makes it possible to use relative working directories. Prior to this change the `path::append` will put a / between the `clang_argument` and the `cur_working_dir`, which will not correctly resolve if `cur_working_dir` is relative. This change joins the path components separately.
1 parent 341fda9 commit 8c12e44

File tree

3 files changed

+80
-28
lines changed

3 files changed

+80
-28
lines changed

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.cpp

Lines changed: 29 additions & 27 deletions
Original file line numberDiff line numberDiff line change
@@ -142,7 +142,7 @@
142142
if (HasFatalErrors()) { \
143143
return; \
144144
} \
145-
} while (0);
145+
} while (0);
146146
#define VALID_OR_RETURN_CHECK_TYPE(type, value) \
147147
do { \
148148
if (HasFatalErrors() || !type) { \
@@ -1414,29 +1414,6 @@ bool ConsumeIncludeOption(StringRef &arg, StringRef &prefix) {
14141414
return false;
14151415
}
14161416

1417-
/// Turn relative paths in clang options into absolute paths based on
1418-
/// \c cur_working_dir.
1419-
template <typename SmallString>
1420-
void ApplyWorkingDir(SmallString &clang_argument, StringRef cur_working_dir) {
1421-
StringRef arg = clang_argument.str();
1422-
StringRef prefix;
1423-
if (ConsumeIncludeOption(arg, prefix)) {
1424-
// Ignore the option part of a double-arg include option.
1425-
if (arg.empty())
1426-
return;
1427-
} else if (arg.startswith("-")) {
1428-
// Assume this is a compiler arg and not a path starting with "-".
1429-
return;
1430-
}
1431-
// There is most probably a path in arg now.
1432-
if (!llvm::sys::path::is_relative(arg))
1433-
return;
1434-
SmallString rel_path = arg;
1435-
clang_argument = prefix;
1436-
llvm::sys::path::append(clang_argument, cur_working_dir, rel_path);
1437-
llvm::sys::path::remove_dots(clang_argument);
1438-
}
1439-
14401417
std::array<StringRef, 2> macro_flags = { "-D", "-U" };
14411418
std::array<StringRef, 5> multi_arg_flags =
14421419
{ "-D", "-U", "-I", "-F", "-working-directory" };
@@ -1529,6 +1506,31 @@ void SwiftASTContext::AddUserClangArgs(TargetProperties &props) {
15291506
AddExtraClangArgs(user_clang_flags);
15301507
}
15311508

1509+
/// Turn relative paths in clang options into absolute paths based on
1510+
/// \c cur_working_dir.
1511+
void SwiftASTContext::ApplyWorkingDir(
1512+
llvm::SmallVectorImpl<char> &clang_argument, StringRef cur_working_dir) {
1513+
StringRef arg = StringRef(clang_argument.data(), clang_argument.size());
1514+
StringRef prefix;
1515+
if (ConsumeIncludeOption(arg, prefix)) {
1516+
// Ignore the option part of a double-arg include option.
1517+
if (arg.empty())
1518+
return;
1519+
} else if (arg.startswith("-")) {
1520+
// Assume this is a compiler arg and not a path starting with "-".
1521+
return;
1522+
}
1523+
// There is most probably a path in arg now.
1524+
if (!llvm::sys::path::is_relative(arg))
1525+
return;
1526+
1527+
llvm::SmallString<128> joined_path;
1528+
llvm::sys::path::append(joined_path, cur_working_dir, arg);
1529+
llvm::sys::path::remove_dots(joined_path);
1530+
clang_argument.resize(prefix.size());
1531+
clang_argument.append(joined_path.begin(), joined_path.end());
1532+
}
1533+
15321534
void SwiftASTContext::RemapClangImporterOptions(
15331535
const PathMappingList &path_map) {
15341536
auto &options = GetClangImporterOptions();
@@ -4592,7 +4594,7 @@ llvm::Optional<SwiftASTContext::TypeOrDecl>
45924594
SwiftASTContext::FindTypeOrDecl(const char *name,
45934595
swift::ModuleDecl *swift_module) {
45944596
VALID_OR_RETURN(llvm::Optional<SwiftASTContext::TypeOrDecl>());
4595-
4597+
45964598
TypesOrDecls search_results;
45974599

45984600
FindTypesOrDecls(name, swift_module, search_results, false);
@@ -5772,7 +5774,7 @@ SwiftASTContext::GetArrayElementType(opaque_compiler_type_t type,
57725774
}
57735775
}
57745776
}
5775-
5777+
57765778
return element_type;
57775779
}
57785780

@@ -5847,7 +5849,7 @@ size_t SwiftASTContext::GetNumMemberFunctions(opaque_compiler_type_t type) {
58475849
}
58485850
}
58495851
}
5850-
5852+
58515853
return num_functions;
58525854
}
58535855

lldb/source/Plugins/TypeSystem/Swift/SwiftASTContext.h

Lines changed: 6 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -20,6 +20,7 @@
2020
#include "lldb/Core/ThreadSafeDenseMap.h"
2121
#include "lldb/Core/ThreadSafeDenseSet.h"
2222
#include "lldb/Utility/Either.h"
23+
#include "llvm/ADT/SmallVector.h"
2324
#include "llvm/ADT/StringRef.h"
2425
#include "llvm/Target/TargetOptions.h"
2526

@@ -166,7 +167,7 @@ class SwiftASTContext : public TypeSystemSwift {
166167
Target *target = nullptr);
167168

168169
SwiftASTContext(const SwiftASTContext &rhs) = delete;
169-
170+
170171
TypeSystemSwiftTypeRef &GetTypeSystemSwiftTypeRef() override {
171172
return m_typeref_typesystem;
172173
}
@@ -552,6 +553,9 @@ class SwiftASTContext : public TypeSystemSwift {
552553
const CompilerType &type, NonTriviallyManagedReferenceStrategy &strategy,
553554
CompilerType *underlying_type = nullptr);
554555

556+
static void ApplyWorkingDir(llvm::SmallVectorImpl<char> &clang_argument,
557+
llvm::StringRef cur_working_dir);
558+
555559
// AST related queries
556560

557561
uint32_t GetPointerByteSize() override;
@@ -981,4 +985,5 @@ class SwiftASTContextForExpressions : public SwiftASTContext {
981985
};
982986

983987
} // namespace lldb_private
988+
984989
#endif // #ifndef liblldb_SwiftASTContext_h_

lldb/unittests/Symbol/TestSwiftASTContext.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -220,6 +220,51 @@ TEST_F(TestSwiftASTContext, SwiftFriendlyTriple) {
220220
llvm::Triple("aarch64-unknown-linux-gnu"));
221221
}
222222

223+
TEST_F(TestSwiftASTContext, ApplyWorkingDir) {
224+
std::string abs_working_dir = "/abs/dir";
225+
std::string rel_working_dir = "rel/dir";
226+
227+
// non-include option should not apply working dir
228+
llvm::SmallString<128> non_include_flag("-non-include-flag");
229+
SwiftASTContext::ApplyWorkingDir(non_include_flag, abs_working_dir);
230+
EXPECT_EQ(non_include_flag, llvm::SmallString<128>("-non-include-flag"));
231+
232+
// absolute paths should not apply working dir
233+
llvm::SmallString<128> abs_path("/abs/path");
234+
SwiftASTContext::ApplyWorkingDir(abs_path, abs_working_dir);
235+
EXPECT_EQ(abs_path, llvm::SmallString<128>("/abs/path"));
236+
237+
llvm::SmallString<128> single_arg_abs_path(
238+
"-fmodule-map-file=/module/map/path");
239+
SwiftASTContext::ApplyWorkingDir(single_arg_abs_path, abs_working_dir);
240+
EXPECT_EQ(single_arg_abs_path,
241+
llvm::SmallString<128>("-fmodule-map-file=/module/map/path"));
242+
243+
// relative paths apply working dir
244+
llvm::SmallString<128> rel_path("rel/path");
245+
SwiftASTContext::ApplyWorkingDir(rel_path, abs_working_dir);
246+
EXPECT_EQ(rel_path, llvm::SmallString<128>("/abs/dir/rel/path"));
247+
248+
rel_path = llvm::SmallString<128>("rel/path");
249+
SwiftASTContext::ApplyWorkingDir(rel_path, rel_working_dir);
250+
EXPECT_EQ(rel_path, llvm::SmallString<128>("rel/dir/rel/path"));
251+
252+
// single arg include option applies working dir
253+
llvm::SmallString<128> single_arg_rel_path(
254+
"-fmodule-map-file=module.modulemap");
255+
SwiftASTContext::ApplyWorkingDir(single_arg_rel_path, abs_working_dir);
256+
EXPECT_EQ(
257+
single_arg_rel_path,
258+
llvm::SmallString<128>("-fmodule-map-file=/abs/dir/module.modulemap"));
259+
260+
single_arg_rel_path =
261+
llvm::SmallString<128>("-fmodule-map-file=module.modulemap");
262+
SwiftASTContext::ApplyWorkingDir(single_arg_rel_path, rel_working_dir);
263+
EXPECT_EQ(
264+
single_arg_rel_path,
265+
llvm::SmallString<128>("-fmodule-map-file=rel/dir/module.modulemap"));
266+
}
267+
223268
namespace {
224269
const std::vector<std::string> duplicated_flags = {
225270
"-DMACRO1", "-D", "MACRO1", "-UMACRO2", "-U", "MACRO2",

0 commit comments

Comments
 (0)