File tree Expand file tree Collapse file tree 4 files changed +90
-9
lines changed Expand file tree Collapse file tree 4 files changed +90
-9
lines changed Original file line number Diff line number Diff line change 13
13
#include < llvm/Support/Path.h>
14
14
15
15
#include " swift/extractor/trap/TrapClasses.h"
16
+ #include " swift/extractor/trap/TrapArena.h"
17
+ #include " swift/extractor/trap/TrapOutput.h"
16
18
17
19
using namespace codeql ;
18
20
@@ -61,24 +63,28 @@ static void extractFile(const SwiftExtractorConfiguration& config, swift::Source
61
63
return ;
62
64
}
63
65
64
- std::ofstream trap (tempTrapPath.str ().str ());
65
- if (!trap ) {
66
+ std::ofstream trapStream (tempTrapPath.str ().str ());
67
+ if (!trapStream ) {
66
68
std::error_code ec;
67
69
ec.assign (errno, std::generic_category ());
68
70
std::cerr << " Cannot create temp trap file '" << tempTrapPath.str ().str ()
69
71
<< " ': " << ec.message () << " \n " ;
70
72
return ;
71
73
}
72
- trap << " // extractor-args: " ;
74
+ trapStream << " // extractor-args: " ;
73
75
for (auto opt : config.frontendOptions ) {
74
- trap << std::quoted (opt) << " " ;
76
+ trapStream << std::quoted (opt) << " " ;
75
77
}
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;
80
86
f.name = srcFilePath.str ().str ();
81
- trap << f. id << " =* \n " << f ;
87
+ trap. emit (f) ;
82
88
83
89
// TODO: Pick a better name to avoid collisions
84
90
std::string trapName = file.getFilename ().str () + " .trap" ;
Original file line number Diff line number Diff line change
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
Original file line number Diff line number Diff line change @@ -39,6 +39,9 @@ class TrapLabel : public UntypedTrapLabel {
39
39
40
40
TrapLabel () = default ;
41
41
42
+ // The caller is responsible for ensuring ID uniqueness.
43
+ static TrapLabel unsafeCreateFromExplicitId (uint64_t id) { return {id}; }
44
+
42
45
template <typename OtherTag>
43
46
TrapLabel (const TrapLabel<OtherTag>& other) : UntypedTrapLabel(other) {
44
47
// we temporarily need to bypass the label type system for unknown AST nodes and types
Original file line number Diff line number Diff line change
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
You can’t perform that action at this time.
0 commit comments