Skip to content

Commit dd900e6

Browse files
authored
Merge pull request #9107 from redsun82/swift-arena
Swift: `TrapOutput`
2 parents 234a36f + ddb567b commit dd900e6

File tree

4 files changed

+90
-9
lines changed

4 files changed

+90
-9
lines changed

swift/extractor/SwiftExtractor.cpp

Lines changed: 15 additions & 9 deletions
Original file line numberDiff line numberDiff line change
@@ -13,6 +13,8 @@
1313
#include <llvm/Support/Path.h>
1414

1515
#include "swift/extractor/trap/TrapClasses.h"
16+
#include "swift/extractor/trap/TrapArena.h"
17+
#include "swift/extractor/trap/TrapOutput.h"
1618

1719
using namespace codeql;
1820

@@ -61,24 +63,28 @@ static void extractFile(const SwiftExtractorConfiguration& config, swift::Source
6163
return;
6264
}
6365

64-
std::ofstream trap(tempTrapPath.str().str());
65-
if (!trap) {
66+
std::ofstream trapStream(tempTrapPath.str().str());
67+
if (!trapStream) {
6668
std::error_code ec;
6769
ec.assign(errno, std::generic_category());
6870
std::cerr << "Cannot create temp trap file '" << tempTrapPath.str().str()
6971
<< "': " << ec.message() << "\n";
7072
return;
7173
}
72-
trap << "// extractor-args: ";
74+
trapStream << "// extractor-args: ";
7375
for (auto opt : config.frontendOptions) {
74-
trap << std::quoted(opt) << " ";
76+
trapStream << std::quoted(opt) << " ";
7577
}
76-
trap << "\n\n";
77-
78-
File f;
79-
f.id = TrapLabel<FileTag>{};
78+
trapStream << "\n\n";
79+
80+
TrapOutput trap{trapStream};
81+
TrapArena arena{};
82+
auto label = arena.allocateLabel<FileTag>();
83+
trap.assignStar(label);
84+
File f{};
85+
f.id = label;
8086
f.name = srcFilePath.str().str();
81-
trap << f.id << "=*\n" << f;
87+
trap.emit(f);
8288

8389
// TODO: Pick a better name to avoid collisions
8490
std::string trapName = file.getFilename().str() + ".trap";

swift/extractor/trap/TrapArena.h

Lines changed: 23 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,23 @@
1+
#pragma once
2+
3+
#include <iostream>
4+
#include <sstream>
5+
#include <vector>
6+
7+
#include "swift/extractor/trap/TrapLabel.h"
8+
9+
namespace codeql {
10+
11+
// TrapArena has the responsibilities to allocate distinct trap #-labels
12+
// TODO this is now a small functionality that will be moved to code upcoming from other PRs
13+
class TrapArena {
14+
uint64_t id_{0};
15+
16+
public:
17+
template <typename Tag>
18+
TrapLabel<Tag> allocateLabel() {
19+
return TrapLabel<Tag>::unsafeCreateFromExplicitId(id_++);
20+
}
21+
};
22+
23+
} // namespace codeql

swift/extractor/trap/TrapLabel.h

Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -39,6 +39,9 @@ class TrapLabel : public UntypedTrapLabel {
3939

4040
TrapLabel() = default;
4141

42+
// The caller is responsible for ensuring ID uniqueness.
43+
static TrapLabel unsafeCreateFromExplicitId(uint64_t id) { return {id}; }
44+
4245
template <typename OtherTag>
4346
TrapLabel(const TrapLabel<OtherTag>& other) : UntypedTrapLabel(other) {
4447
// we temporarily need to bypass the label type system for unknown AST nodes and types

swift/extractor/trap/TrapOutput.h

Lines changed: 49 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,49 @@
1+
#pragma once
2+
3+
#include <memory>
4+
#include "swift/extractor/trap/TrapLabel.h"
5+
6+
namespace codeql {
7+
8+
// Sink for trap emissions and label assignments. This abstracts away `ofstream` operations
9+
// like `ofstream`, an explicit bool operator is provided, that return false if something
10+
// went wrong
11+
// TODO better error handling
12+
class TrapOutput {
13+
std::ostream& out_;
14+
15+
public:
16+
explicit TrapOutput(std::ostream& out) : out_{out} {}
17+
18+
template <typename Tag>
19+
void assignStar(TrapLabel<Tag> label) {
20+
print(label, "=*");
21+
}
22+
23+
template <typename Tag>
24+
void assignKey(TrapLabel<Tag> label, const std::string& key) {
25+
// prefix the key with the id to guarantee the same key is not used wrongly with different tags
26+
auto prefixed = std::string(Tag::prefix) + '_' + key;
27+
print(label, "=@", trapQuoted(prefixed));
28+
}
29+
30+
template <typename Tag, typename... Args>
31+
void assignKey(TrapLabel<Tag> label, const Args&... keyParts) {
32+
std::ostringstream oss;
33+
(oss << ... << keyParts);
34+
assignKey(label, oss.str());
35+
}
36+
37+
template <typename Entry>
38+
void emit(const Entry& e) {
39+
print(e);
40+
}
41+
42+
private:
43+
template <typename... Args>
44+
void print(const Args&... args) {
45+
(out_ << ... << args) << '\n';
46+
}
47+
};
48+
49+
} // namespace codeql

0 commit comments

Comments
 (0)