Skip to content

Commit f7a046c

Browse files
committed
Swift: add trap linkage awareness infrastructure
1 parent 5fdb093 commit f7a046c

File tree

9 files changed

+211
-15
lines changed

9 files changed

+211
-15
lines changed

swift/extractor/infra/TargetDomains.cpp

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#include "swift/extractor/infra/TargetDomains.h"
22
#include <iomanip>
3+
34
namespace codeql {
5+
46
static const char* typeToStr(TrapType type) {
57
switch (type) {
68
case TrapType::source:
@@ -9,6 +11,8 @@ static const char* typeToStr(TrapType type) {
911
return "modules";
1012
case TrapType::invocation:
1113
return "invocations";
14+
case TrapType::linkage:
15+
return "linkage";
1216
default:
1317
return "";
1418
}
@@ -42,4 +46,33 @@ std::optional<TrapDomain> createTargetTrapDomain(SwiftExtractorState& state,
4246
}
4347
return std::nullopt;
4448
}
49+
50+
std::optional<LinkDomain> createTargetLinkDomain(const SwiftExtractorState& state,
51+
const std::filesystem::path& target) {
52+
if (target.empty()) {
53+
return std::nullopt;
54+
}
55+
auto file = getRelativeTrapPath(target, TrapType::linkage, ".link");
56+
auto ret =
57+
TargetFile::create(file, state.configuration.trapDir, state.configuration.getTempTrapDir());
58+
if (ret) {
59+
return LinkDomain{*std::move(ret)};
60+
}
61+
return std::nullopt;
62+
}
63+
64+
std::optional<ObjectDomain> createTargetObjectDomain(const SwiftExtractorState& state,
65+
const std::filesystem::path& target) {
66+
if (target.empty()) {
67+
return std::nullopt;
68+
}
69+
auto file = getRelativeTrapPath(target, TrapType::linkage, ".odep");
70+
auto ret =
71+
TargetFile::create(file, state.configuration.trapDir, state.configuration.getTempTrapDir());
72+
if (ret) {
73+
return ObjectDomain{*std::move(ret)};
74+
}
75+
return std::nullopt;
76+
}
77+
4578
} // namespace codeql

swift/extractor/infra/TargetDomains.h

Lines changed: 9 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,6 +1,8 @@
11
#pragma once
22

33
#include "swift/extractor/trap/TrapDomain.h"
4+
#include "swift/extractor/trap/LinkDomain.h"
5+
#include "swift/extractor/trap/ObjectDomain.h"
46
#include "swift/extractor/config/SwiftExtractorState.h"
57

68
namespace codeql {
@@ -9,10 +11,17 @@ enum class TrapType {
911
source,
1012
module,
1113
invocation,
14+
linkage,
1215
};
1316

1417
std::optional<TrapDomain> createTargetTrapDomain(SwiftExtractorState& state,
1518
const std::filesystem::path& target,
1619
TrapType type);
1720

21+
std::optional<LinkDomain> createTargetLinkDomain(const SwiftExtractorState& state,
22+
const std::filesystem::path& target);
23+
24+
std::optional<ObjectDomain> createTargetObjectDomain(const SwiftExtractorState& state,
25+
const std::filesystem::path& target);
26+
1827
} // namespace codeql

swift/extractor/trap/BUILD.bazel

Lines changed: 4 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -30,7 +30,7 @@ filegroup(
3030

3131
swift_cc_library(
3232
name = "trap",
33-
srcs = [
33+
srcs = glob(["*.cpp"]) + [
3434
"generated/%s%s.cpp" % (dir, name)
3535
for dir in _dirs
3636
for name in ("TrapEntries", "TrapClasses")
@@ -43,4 +43,7 @@ swift_cc_library(
4343
for name in ("TrapEntries", "TrapClasses")
4444
],
4545
visibility = ["//visibility:public"],
46+
deps = [
47+
"//swift/extractor/infra/file",
48+
],
4649
)

swift/extractor/trap/LinkDomain.cpp

Lines changed: 37 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,37 @@
1+
#include "swift/extractor/trap/LinkDomain.h"
2+
3+
namespace codeql {
4+
LinkDomain::LinkDomain(TargetFile out) : out{std::move(out)} {
5+
this->out << "Linker invocation 1.0\n";
6+
}
7+
8+
void LinkDomain::emitTarget(const std::string& target) {
9+
ensurePhase(Phase::target);
10+
out << target << '\n';
11+
}
12+
13+
void LinkDomain::emitObjectDependency(const std::string& object) {
14+
ensurePhase(Phase::objects);
15+
out << object << '\n';
16+
}
17+
18+
void LinkDomain::ensurePhase(Phase phase) {
19+
assert(phase >= current && "wrong order in .link file attributes");
20+
21+
if (phase > current) {
22+
switch (phase) {
23+
case Phase::target:
24+
out << "TARGET\n";
25+
break;
26+
case Phase::objects:
27+
out << "OBJECTS\n";
28+
break;
29+
default:
30+
assert(false && "unexpected phase");
31+
break;
32+
}
33+
}
34+
current = phase;
35+
}
36+
37+
} // namespace codeql

swift/extractor/trap/LinkDomain.h

Lines changed: 30 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,30 @@
1+
#pragma once
2+
3+
#include <cassert>
4+
#include "swift/extractor/infra/file/TargetFile.h"
5+
6+
namespace codeql {
7+
8+
class LinkDomain {
9+
TargetFile out;
10+
11+
enum class Phase {
12+
header,
13+
target,
14+
objects,
15+
end,
16+
};
17+
18+
Phase current{Phase::header};
19+
20+
public:
21+
explicit LinkDomain(TargetFile out);
22+
23+
void emitTarget(const std::string& target);
24+
void emitObjectDependency(const std::string& object);
25+
26+
private:
27+
void ensurePhase(Phase phase);
28+
};
29+
30+
} // namespace codeql

swift/extractor/trap/ObjectDomain.cpp

Lines changed: 45 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,45 @@
1+
#include "swift/extractor/trap/ObjectDomain.h"
2+
3+
namespace codeql {
4+
ObjectDomain::ObjectDomain(TargetFile out) : out{std::move(out)} {
5+
this->out << "TRAP dependencies 1.2\n";
6+
}
7+
8+
void ObjectDomain::emitObject(const std::string& object) {
9+
ensurePhase(Phase::objects);
10+
out << object << '\n';
11+
}
12+
13+
void ObjectDomain::emitObjectDependency(const std::string& object) {
14+
ensurePhase(Phase::input_objects);
15+
out << object << '\n';
16+
}
17+
18+
void ObjectDomain::emitTrapDependency(const std::filesystem::path& trap) {
19+
ensurePhase(Phase::traps);
20+
out << trap.c_str() << '\n';
21+
}
22+
23+
void ObjectDomain::ensurePhase(Phase phase) {
24+
assert(phase >= current && "wrong order in .odep file attributes");
25+
26+
if (phase > current) {
27+
switch (phase) {
28+
case Phase::objects:
29+
out << "OBJECTS\n";
30+
break;
31+
case Phase::input_objects:
32+
out << "INPUT_OBJECTS\n";
33+
break;
34+
case Phase::traps:
35+
out << "TRAPS\n";
36+
break;
37+
default:
38+
assert(false && "unexpected phase");
39+
break;
40+
}
41+
}
42+
current = phase;
43+
}
44+
45+
} // namespace codeql

swift/extractor/trap/ObjectDomain.h

Lines changed: 33 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,33 @@
1+
#pragma once
2+
3+
#include <cassert>
4+
#include <filesystem>
5+
#include "swift/extractor/infra/file/TargetFile.h"
6+
7+
namespace codeql {
8+
9+
class ObjectDomain {
10+
TargetFile out;
11+
12+
enum class Phase {
13+
header,
14+
objects,
15+
input_objects,
16+
traps,
17+
end,
18+
};
19+
20+
Phase current{Phase::header};
21+
22+
public:
23+
explicit ObjectDomain(TargetFile out);
24+
25+
void emitObject(const std::string& object);
26+
void emitObjectDependency(const std::string& object);
27+
void emitTrapDependency(const std::filesystem::path& trap);
28+
29+
private:
30+
void ensurePhase(Phase phase);
31+
};
32+
33+
} // namespace codeql

swift/extractor/trap/TrapDomain.h

Lines changed: 19 additions & 13 deletions
Original file line numberDiff line numberDiff line change
@@ -10,34 +10,45 @@ namespace codeql {
1010

1111
// Abstracts a given trap output file, with its own universe of trap labels
1212
class TrapDomain {
13-
TargetFile out_;
13+
TargetFile out;
1414

1515
public:
16-
explicit TrapDomain(TargetFile&& out) : out_{std::move(out)} {}
16+
explicit TrapDomain(TargetFile&& out) : out{std::move(out)} {}
1717

1818
template <typename Entry>
1919
void emit(const Entry& e) {
20-
print(e);
20+
out << e << '\n';
2121
}
2222

2323
template <typename... Args>
2424
void debug(const Args&... args) {
25-
print("/* DEBUG:");
26-
print(args...);
27-
print("*/");
25+
out << "/* DEBUG:\n";
26+
(out << ... << args);
27+
out << "\n*/\n";
2828
}
2929

3030
template <typename Tag>
3131
TrapLabel<Tag> createLabel() {
3232
auto ret = allocateLabel<Tag>();
3333
assignStar(ret);
34+
out << '\n';
3435
return ret;
3536
}
3637

3738
template <typename Tag, typename... Args>
3839
TrapLabel<Tag> createLabel(Args&&... args) {
3940
auto ret = allocateLabel<Tag>();
4041
assignKey(ret, std::forward<Args>(args)...);
42+
out << '\n';
43+
return ret;
44+
}
45+
46+
template <typename Tag, typename... Args>
47+
TrapLabel<Tag> createLabelWithImplementationId(const std::string_view& implementationId,
48+
Args&&... args) {
49+
auto ret = allocateLabel<Tag>();
50+
assignKey(ret, std::forward<Args>(args)...);
51+
out << " .implementation " << trapQuoted(implementationId) << '\n';
4152
return ret;
4253
}
4354

@@ -49,21 +60,16 @@ class TrapDomain {
4960
return TrapLabel<Tag>::unsafeCreateFromExplicitId(id_++);
5061
}
5162

52-
template <typename... Args>
53-
void print(const Args&... args) {
54-
(out_ << ... << args) << '\n';
55-
}
56-
5763
template <typename Tag>
5864
void assignStar(TrapLabel<Tag> label) {
59-
print(label, "=*");
65+
out << label << "=*";
6066
}
6167

6268
template <typename Tag>
6369
void assignKey(TrapLabel<Tag> label, const std::string& key) {
6470
// prefix the key with the id to guarantee the same key is not used wrongly with different tags
6571
auto prefixed = std::string(Tag::prefix) + '_' + key;
66-
print(label, "=@", trapQuoted(prefixed));
72+
out << label << "=@" << trapQuoted(prefixed);
6773
}
6874

6975
template <typename Tag, typename... Args>

swift/extractor/trap/TrapLabel.h

Lines changed: 1 addition & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -86,7 +86,7 @@ struct TrapLabelVectorWrapper {
8686
}
8787
};
8888

89-
inline auto trapQuoted(const std::string& s) {
89+
inline auto trapQuoted(const std::string_view& s) {
9090
return std::quoted(s, '"', '"');
9191
}
9292

0 commit comments

Comments
 (0)