@@ -67,60 +67,104 @@ class SwiftDispatcher {
67
67
// `swift::TypeBase*`)
68
68
TrapLabel<TypeTag> fetchLabel (swift::Type t) { return fetchLabel (t.getPointer ()); }
69
69
70
+ TrapLabel<AstNodeTag> fetchLabel (swift::ASTNode node) {
71
+ return fetchLabelFromUnion<AstNodeTag>(node);
72
+ }
73
+
70
74
// Due to the lazy emission approach, we must assign a label to a corresponding AST node before
71
75
// it actually gets emitted to handle recursive cases such as recursive calls, or recursive type
72
76
// declarations
73
77
template <typename E>
74
78
TrapLabelOf<E> assignNewLabel (E* e) {
75
79
assert (waitingForNewLabel == Store::Handle{e} && " assignNewLabel called on wrong entity" );
76
- auto label = getLabel<TrapTagOf<E>>();
77
- trap.assignStar (label);
80
+ auto label = createLabel<TrapTagOf<E>>();
78
81
store.insert (e, label);
79
82
waitingForNewLabel = std::monostate{};
80
83
return label;
81
84
}
82
85
83
86
template <typename Tag>
84
- TrapLabel<Tag> getLabel () {
85
- return arena.allocateLabel <Tag>();
87
+ TrapLabel<Tag> createLabel () {
88
+ auto ret = arena.allocateLabel <Tag>();
89
+ trap.assignStar (ret);
90
+ return ret;
91
+ }
92
+
93
+ template <typename Tag, typename ... Args>
94
+ TrapLabel<Tag> createLabel (Args&&... args) {
95
+ auto ret = arena.allocateLabel <Tag>();
96
+ trap.assignKey (ret, std::forward<Args>(args)...);
97
+ return ret;
86
98
}
87
99
88
100
template <typename Locatable>
89
101
void attachLocation (Locatable locatable, TrapLabel<LocatableTag> locatableLabel) {
90
102
attachLocation (&locatable, locatableLabel);
91
103
}
92
104
93
- // Emits a Location TRAP entry and attaches it to an AST node
105
+ // Emits a Location TRAP entry and attaches it to a `Locatable` trap label
94
106
template <typename Locatable>
95
107
void attachLocation (Locatable* locatable, TrapLabel<LocatableTag> locatableLabel) {
96
- auto start = locatable->getStartLoc ();
97
- auto end = locatable->getEndLoc ();
108
+ attachLocation (locatable->getStartLoc (), locatable->getEndLoc (), locatableLabel);
109
+ }
110
+
111
+ // Emits a Location TRAP entry for a list of swift entities and attaches it to a `Locatable` trap
112
+ // label
113
+ template <typename Locatable>
114
+ void attachLocation (llvm::MutableArrayRef<Locatable>* locatables,
115
+ TrapLabel<LocatableTag> locatableLabel) {
116
+ if (locatables->empty ()) {
117
+ return ;
118
+ }
119
+ attachLocation (locatables->front ().getStartLoc (), locatables->back ().getEndLoc (),
120
+ locatableLabel);
121
+ }
122
+
123
+ private:
124
+ // types to be supported by assignNewLabel/fetchLabel need to be listed here
125
+ using Store = TrapLabelStore<swift::Decl,
126
+ swift::Stmt,
127
+ swift::StmtCondition,
128
+ swift::CaseLabelItem,
129
+ swift::Expr,
130
+ swift::Pattern,
131
+ swift::TypeRepr,
132
+ swift::TypeBase>;
133
+
134
+ void attachLocation (swift::SourceLoc start,
135
+ swift::SourceLoc end,
136
+ TrapLabel<LocatableTag> locatableLabel) {
98
137
if (!start.isValid () || !end.isValid ()) {
99
138
// invalid locations seem to come from entities synthesized by the compiler
100
139
return ;
101
140
}
102
141
std::string filepath = getFilepath (start);
103
- auto fileLabel = arena.allocateLabel <FileTag>();
104
- trap.assignKey (fileLabel, filepath);
142
+ auto fileLabel = createLabel<FileTag>(filepath);
105
143
// TODO: do not emit duplicate trap entries for Files
106
144
trap.emit (FilesTrap{fileLabel, filepath});
107
145
auto [startLine, startColumn] = sourceManager.getLineAndColumnInBuffer (start);
108
146
auto [endLine, endColumn] = sourceManager.getLineAndColumnInBuffer (end);
109
- auto locLabel = arena.allocateLabel <LocationTag>();
110
- trap.assignKey (locLabel, ' {' , fileLabel, " }:" , startLine, ' :' , startColumn, ' :' , endLine, ' :' ,
111
- endColumn);
147
+ auto locLabel = createLabel<LocationTag>(' {' , fileLabel, " }:" , startLine, ' :' , startColumn, ' :' ,
148
+ endLine, ' :' , endColumn);
112
149
trap.emit (LocationsTrap{locLabel, fileLabel, startLine, startColumn, endLine, endColumn});
113
150
trap.emit (LocatablesTrap{locatableLabel, locLabel});
114
151
}
115
152
116
- private:
117
- // types to be supported by assignNewLabel/fetchLabel need to be listed here
118
- using Store = TrapLabelStore<swift::Decl,
119
- swift::Stmt,
120
- swift::Expr,
121
- swift::Pattern,
122
- swift::TypeRepr,
123
- swift::TypeBase>;
153
+ template <typename Tag, typename ... Ts>
154
+ TrapLabel<Tag> fetchLabelFromUnion (const llvm::PointerUnion<Ts...> u) {
155
+ TrapLabel<Tag> ret{};
156
+ assert ((... || fetchLabelFromUnionCase<Tag, Ts>(u, ret)) && " llvm::PointerUnion not set" );
157
+ return ret;
158
+ }
159
+
160
+ template <typename Tag, typename T, typename ... Ts>
161
+ bool fetchLabelFromUnionCase (const llvm::PointerUnion<Ts...> u, TrapLabel<Tag>& output) {
162
+ if (auto e = u.template dyn_cast <T>()) {
163
+ output = fetchLabel (e);
164
+ return true ;
165
+ }
166
+ return false ;
167
+ }
124
168
125
169
std::string getFilepath (swift::SourceLoc loc) {
126
170
// TODO: this needs more testing
@@ -139,6 +183,8 @@ class SwiftDispatcher {
139
183
// which are to be introduced in follow-up PRs
140
184
virtual void visit (swift::Decl* decl) = 0;
141
185
virtual void visit (swift::Stmt* stmt) = 0;
186
+ virtual void visit (swift::StmtCondition* cond) = 0;
187
+ virtual void visit (swift::CaseLabelItem* item) = 0;
142
188
virtual void visit (swift::Expr* expr) = 0;
143
189
virtual void visit (swift::Pattern* pattern) = 0;
144
190
virtual void visit (swift::TypeRepr* type) = 0;
0 commit comments