@@ -35,6 +35,18 @@ class SwiftDispatcher {
3535 trap.emit (entry);
3636 }
3737
38+ template <typename Entry>
39+ void emit (const std::optional<Entry>& entry) {
40+ if (entry) {
41+ emit (*entry);
42+ }
43+ }
44+
45+ template <typename ... Cases>
46+ void emit (const std::variant<Cases...>& entry) {
47+ std::visit ([this ](const auto & e) { this ->emit (e); }, entry);
48+ }
49+
3850 // This is a helper method to emit TRAP entries for AST nodes that we don't fully support yet.
3951 template <typename E>
4052 void emitUnknown (E* entity) {
@@ -92,6 +104,11 @@ class SwiftDispatcher {
92104 return label;
93105 }
94106
107+ template <typename E, typename ... Args, std::enable_if_t <!std::is_pointer_v<E>>* = nullptr >
108+ TrapLabelOf<E> assignNewLabel (const E& e, Args&&... args) {
109+ return assignNewLabel (&e, std::forward<Args>(args)...);
110+ }
111+
95112 template <typename Tag>
96113 TrapLabel<Tag> createLabel () {
97114 auto ret = arena.allocateLabel <Tag>();
@@ -129,6 +146,30 @@ class SwiftDispatcher {
129146 locatableLabel);
130147 }
131148
149+ // return `std::optional(fetchLabel(arg))` if arg converts to true, otherwise std::nullopt
150+ // universal reference `Arg&&` is used to catch both temporary and non-const references, not
151+ // for perfect forwarding
152+ template <typename Arg>
153+ auto fetchOptionalLabel (Arg&& arg) -> std::optional<decltype(fetchLabel(arg))> {
154+ if (arg) {
155+ return fetchLabel (arg);
156+ }
157+ return std::nullopt ;
158+ }
159+
160+ // map `fetchLabel` on the iterable `arg`, returning a vector of all labels
161+ // universal reference `Arg&&` is used to catch both temporary and non-const references, not
162+ // for perfect forwarding
163+ template <typename Iterable>
164+ auto fetchRepeatedLabels (Iterable&& arg) {
165+ std::vector<decltype (fetchLabel (*arg.begin ()))> ret;
166+ ret.reserve (arg.size ());
167+ for (auto && e : arg) {
168+ ret.push_back (fetchLabel (e));
169+ }
170+ return ret;
171+ }
172+
132173 // In order to not emit duplicated entries for declarations, we restrict emission to only
133174 // Decls declared within the current "scope".
134175 // Depending on the whether we are extracting a primary source file or not the scope is defined as
@@ -138,14 +179,14 @@ class SwiftDispatcher {
138179 // - extracting a primary source file: in this mode, we extract several files belonging to the
139180 // same module one by one. In this mode, we restrict emission only to the same file ignoring
140181 // all the other files.
141- bool shouldEmitDeclBody (swift::Decl* decl) {
142- if (decl-> getModuleContext () != ¤tModule) {
182+ bool shouldEmitDeclBody (const swift::Decl& decl) {
183+ if (decl. getModuleContext () != ¤tModule) {
143184 return false ;
144185 }
145186 if (!currentPrimarySourceFile) {
146187 return true ;
147188 }
148- if (auto context = decl-> getDeclContext ()) {
189+ if (auto context = decl. getDeclContext ()) {
149190 return currentPrimarySourceFile == context->getParentSourceFile ();
150191 }
151192 return false ;
@@ -178,7 +219,7 @@ class SwiftDispatcher {
178219 auto locLabel = createLabel<LocationTag>(' {' , fileLabel, " }:" , startLine, ' :' , startColumn, ' :' ,
179220 endLine, ' :' , endColumn);
180221 trap.emit (LocationsTrap{locLabel, fileLabel, startLine, startColumn, endLine, endColumn});
181- trap.emit (LocatablesTrap {locatableLabel, locLabel});
222+ trap.emit (LocatableLocationsTrap {locatableLabel, locLabel});
182223 }
183224
184225 template <typename Tag, typename ... Ts>
0 commit comments