Details | Last modification | View Log | RSS feed
Rev | Author | Line No. | Line |
---|---|---|---|
14 | pmbaty | 1 | //===-- LVOptions.h ---------------------------------------------*- C++ -*-===// |
2 | // |
||
3 | // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. |
||
4 | // See https://llvm.org/LICENSE.txt for license information. |
||
5 | // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception |
||
6 | // |
||
7 | //===----------------------------------------------------------------------===// |
||
8 | // |
||
9 | // This file defines the LVOptions class, which is used to record the command |
||
10 | // line options. |
||
11 | // |
||
12 | //===----------------------------------------------------------------------===// |
||
13 | |||
14 | #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOPTIONS_H |
||
15 | #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOPTIONS_H |
||
16 | |||
17 | #include "llvm/ADT/StringSet.h" |
||
18 | #include "llvm/DebugInfo/LogicalView/Core/LVLine.h" |
||
19 | #include "llvm/DebugInfo/LogicalView/Core/LVScope.h" |
||
20 | #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h" |
||
21 | #include "llvm/DebugInfo/LogicalView/Core/LVType.h" |
||
22 | #include "llvm/Support/Regex.h" |
||
23 | #include <set> |
||
24 | #include <string> |
||
25 | |||
26 | namespace llvm { |
||
27 | namespace logicalview { |
||
28 | |||
29 | // Generate get and set 'bool' functions. |
||
30 | #define BOOL_FUNCTION(FAMILY, FIELD) \ |
||
31 | bool get##FAMILY##FIELD() const { return FAMILY.FIELD; } \ |
||
32 | void set##FAMILY##FIELD() { FAMILY.FIELD = true; } \ |
||
33 | void reset##FAMILY##FIELD() { FAMILY.FIELD = false; } |
||
34 | |||
35 | // Generate get and set 'unsigned' functions. |
||
36 | #define UNSIGNED_FUNCTION(FAMILY, FIELD) \ |
||
37 | unsigned get##FAMILY##FIELD() const { return FAMILY.FIELD; } \ |
||
38 | void set##FAMILY##FIELD(unsigned Value) { FAMILY.FIELD = Value; } \ |
||
39 | void reset##FAMILY##FIELD() { FAMILY.FIELD = -1U; } |
||
40 | |||
41 | // Generate get and set 'std::string' functions. |
||
42 | #define STD_STRING_FUNCTION(FAMILY, FIELD) \ |
||
43 | std::string get##FAMILY##FIELD() const { return FAMILY.FIELD; } \ |
||
44 | void set##FAMILY##FIELD(std::string FIELD) { FAMILY.FIELD = FIELD; } \ |
||
45 | void reset##FAMILY##FIELD() { FAMILY.FIELD = ""; } |
||
46 | |||
47 | // Generate get and set 'std::set' functions. |
||
48 | #define STDSET_FUNCTION_4(FAMILY, FIELD, TYPE, SET) \ |
||
49 | bool get##FAMILY##FIELD() const { \ |
||
50 | return FAMILY.SET.find(TYPE::FIELD) != FAMILY.SET.end(); \ |
||
51 | } \ |
||
52 | void set##FAMILY##FIELD() { FAMILY.SET.insert(TYPE::FIELD); } \ |
||
53 | void reset##FAMILY##FIELD() { \ |
||
54 | std::set<TYPE>::iterator Iter = FAMILY.SET.find(TYPE::FIELD); \ |
||
55 | if (Iter != FAMILY.SET.end()) \ |
||
56 | FAMILY.SET.erase(Iter); \ |
||
57 | } |
||
58 | |||
59 | #define STDSET_FUNCTION_5(FAMILY, FIELD, ENTRY, TYPE, SET) \ |
||
60 | bool get##FAMILY##FIELD##ENTRY() const { \ |
||
61 | return FAMILY.SET.find(TYPE::ENTRY) != FAMILY.SET.end(); \ |
||
62 | } \ |
||
63 | void set##FAMILY##FIELD##ENTRY() { FAMILY.SET.insert(TYPE::ENTRY); } |
||
64 | |||
65 | // Generate get and set functions for '--attribute' |
||
66 | #define ATTRIBUTE_OPTION(FIELD) \ |
||
67 | STDSET_FUNCTION_4(Attribute, FIELD, LVAttributeKind, Kinds) |
||
68 | |||
69 | // Generate get and set functions for '--output' |
||
70 | #define OUTPUT_OPTION(FIELD) \ |
||
71 | STDSET_FUNCTION_4(Output, FIELD, LVOutputKind, Kinds) |
||
72 | |||
73 | // Generate get and set functions for '--print' |
||
74 | #define PRINT_OPTION(FIELD) STDSET_FUNCTION_4(Print, FIELD, LVPrintKind, Kinds) |
||
75 | |||
76 | // Generate get and set functions for '--warning' |
||
77 | #define WARNING_OPTION(FIELD) \ |
||
78 | STDSET_FUNCTION_4(Warning, FIELD, LVWarningKind, Kinds) |
||
79 | |||
80 | // Generate get and set functions for '--compare' |
||
81 | #define COMPARE_OPTION(FIELD) \ |
||
82 | STDSET_FUNCTION_4(Compare, FIELD, LVCompareKind, Elements) |
||
83 | |||
84 | // Generate get and set functions for '--report' |
||
85 | #define REPORT_OPTION(FIELD) \ |
||
86 | STDSET_FUNCTION_4(Report, FIELD, LVReportKind, Kinds) |
||
87 | |||
88 | // Generate get and set functions for '--internal' |
||
89 | #define INTERNAL_OPTION(FIELD) \ |
||
90 | STDSET_FUNCTION_4(Internal, FIELD, LVInternalKind, Kinds) |
||
91 | |||
92 | using LVOffsetSet = std::set<uint64_t>; |
||
93 | |||
94 | enum class LVAttributeKind { |
||
95 | All, // --attribute=all |
||
96 | Argument, // --attribute=argument |
||
97 | Base, // --attribute=base |
||
98 | Coverage, // --attribute=coverage |
||
99 | Directories, // --attribute=directories |
||
100 | Discarded, // --attribute=discarded |
||
101 | Discriminator, // --attribute=discriminator |
||
102 | Encoded, // --attribute=encoded |
||
103 | Extended, // --attribute=extended |
||
104 | Filename, // --attribute=filename |
||
105 | Files, // --attribute=files |
||
106 | Format, // --attribute=format |
||
107 | Gaps, // --attribute=gaps |
||
108 | Generated, // --attribute=generated |
||
109 | Global, // --attribute=global |
||
110 | Inserted, // --attribute=inserted |
||
111 | Level, // --attribute=level |
||
112 | Linkage, // --attribute=linkage |
||
113 | Local, // --attribute=local |
||
114 | Location, // --attribute=location |
||
115 | Offset, // --attribute=offset |
||
116 | Pathname, // --attribute=pathname |
||
117 | Producer, // --attribute=producer |
||
118 | Publics, // --attribute=publics |
||
119 | Qualified, // --attribute=qualified |
||
120 | Qualifier, // --attribute=qualifier |
||
121 | Range, // --attribute=range |
||
122 | Reference, // --attribute=reference |
||
123 | Register, // --attribute=register |
||
124 | Standard, // --attribute=standard |
||
125 | Subrange, // --attribute=subrange |
||
126 | System, // --attribute=system |
||
127 | Typename, // --attribute=typename |
||
128 | Underlying, // --attribute=underlying |
||
129 | Zero // --attribute=zero |
||
130 | }; |
||
131 | using LVAttributeKindSet = std::set<LVAttributeKind>; |
||
132 | |||
133 | enum class LVCompareKind { |
||
134 | All, // --compare=all |
||
135 | Lines, // --compare=lines |
||
136 | Scopes, // --compare=scopes |
||
137 | Symbols, // --compare=symbols |
||
138 | Types // --compare=types |
||
139 | }; |
||
140 | using LVCompareKindSet = std::set<LVCompareKind>; |
||
141 | |||
142 | enum class LVOutputKind { |
||
143 | All, // --output=all |
||
144 | Split, // --output=split |
||
145 | Json, // --output=json |
||
146 | Text // --output=text |
||
147 | }; |
||
148 | using LVOutputKindSet = std::set<LVOutputKind>; |
||
149 | |||
150 | enum class LVPrintKind { |
||
151 | All, // --print=all |
||
152 | Elements, // --print=elements |
||
153 | Instructions, // --print=instructions |
||
154 | Lines, // --print=lines |
||
155 | Scopes, // --print=scopes |
||
156 | Sizes, // --print=sizes |
||
157 | Symbols, // --print=symbols |
||
158 | Summary, // --print=summary |
||
159 | Types, // --print=types |
||
160 | Warnings // --print=warnings |
||
161 | }; |
||
162 | using LVPrintKindSet = std::set<LVPrintKind>; |
||
163 | |||
164 | enum class LVReportKind { |
||
165 | All, // --report=all |
||
166 | Children, // --report=children |
||
167 | List, // --report=list |
||
168 | Parents, // --report=parents |
||
169 | View // --report=view |
||
170 | }; |
||
171 | using LVReportKindSet = std::set<LVReportKind>; |
||
172 | |||
173 | enum class LVWarningKind { |
||
174 | All, // --warning=all |
||
175 | Coverages, // --warning=coverages |
||
176 | Lines, // --warning=lines |
||
177 | Locations, // --warning=locations |
||
178 | Ranges // --warning=ranges |
||
179 | }; |
||
180 | using LVWarningKindSet = std::set<LVWarningKind>; |
||
181 | |||
182 | enum class LVInternalKind { |
||
183 | All, // --internal=all |
||
184 | Cmdline, // --internal=cmdline |
||
185 | ID, // --internal=id |
||
186 | Integrity, // --internal=integrity |
||
187 | None, // --internal=none |
||
188 | Tag // --internal=tag |
||
189 | }; |
||
190 | using LVInternalKindSet = std::set<LVInternalKind>; |
||
191 | |||
192 | // The 'Kinds' members are a one-to-one mapping to the associated command |
||
193 | // options that supports comma separated values. There are other 'bool' |
||
194 | // members that in very few cases point to a command option (see associated |
||
195 | // comment). Other cases for 'bool' refers to internal values derivated from |
||
196 | // the command options. |
||
197 | class LVOptions { |
||
198 | class LVAttribute { |
||
199 | public: |
||
200 | LVAttributeKindSet Kinds; // --attribute=<Kind> |
||
201 | bool Added = false; // Added elements found during comparison. |
||
202 | bool AnyLocation = false; // Any kind of location information. |
||
203 | bool AnySource = false; // Any kind of source information. |
||
204 | bool Missing = false; // Missing elements found during comparison. |
||
205 | }; |
||
206 | |||
207 | class LVCompare { |
||
208 | public: |
||
209 | LVCompareKindSet Elements; // --compare=<kind> |
||
210 | bool Context = false; // --compare-context |
||
211 | bool Execute = false; // Compare requested. |
||
212 | bool Print = false; // Enable any printing. |
||
213 | }; |
||
214 | |||
215 | class LVPrint { |
||
216 | public: |
||
217 | LVPrintKindSet Kinds; // --print=<Kind> |
||
218 | bool AnyElement = false; // Request to print any element. |
||
219 | bool AnyLine = false; // Print 'lines' or 'instructions'. |
||
220 | bool Execute = false; // Print requested. |
||
221 | bool Formatting = true; // Disable formatting during printing. |
||
222 | bool Offset = false; // Print offsets while formatting is disabled. |
||
223 | bool SizesSummary = false; // Print 'sizes' or 'summary'. |
||
224 | }; |
||
225 | |||
226 | class LVReport { |
||
227 | public: |
||
228 | LVReportKindSet Kinds; // --report=<kind> |
||
229 | bool AnyView = false; // View, Parents or Children. |
||
230 | bool Execute = false; // Report requested. |
||
231 | }; |
||
232 | |||
233 | class LVSelect { |
||
234 | public: |
||
235 | bool IgnoreCase = false; // --select-ignore-case |
||
236 | bool UseRegex = false; // --select-use-regex |
||
237 | bool Execute = false; // Select requested. |
||
238 | bool GenericKind = false; // We have collected generic kinds. |
||
239 | bool GenericPattern = false; // We have collected generic patterns. |
||
240 | bool OffsetPattern = false; // We have collected offset patterns. |
||
241 | StringSet<> Generic; // --select=<Pattern> |
||
242 | LVOffsetSet Offsets; // --select-offset=<Offset> |
||
243 | LVElementKindSet Elements; // --select-elements=<Kind> |
||
244 | LVLineKindSet Lines; // --select-lines=<Kind> |
||
245 | LVScopeKindSet Scopes; // --select-scopes=<Kind> |
||
246 | LVSymbolKindSet Symbols; // --select-symbols=<Kind> |
||
247 | LVTypeKindSelection Types; // --select-types=<Kind> |
||
248 | }; |
||
249 | |||
250 | class LVOutput { |
||
251 | public: |
||
252 | LVOutputKindSet Kinds; // --output=<kind> |
||
253 | LVSortMode SortMode = LVSortMode::None; // --output-sort=<SortMode> |
||
254 | std::string Folder; // --output-folder=<Folder> |
||
255 | unsigned Level = -1U; // --output-level=<level> |
||
256 | }; |
||
257 | |||
258 | class LVWarning { |
||
259 | public: |
||
260 | LVWarningKindSet Kinds; // --warning=<Kind> |
||
261 | }; |
||
262 | |||
263 | class LVInternal { |
||
264 | public: |
||
265 | LVInternalKindSet Kinds; // --internal=<Kind> |
||
266 | }; |
||
267 | |||
268 | class LVGeneral { |
||
269 | public: |
||
270 | bool CollectRanges = false; // Collect ranges information. |
||
271 | }; |
||
272 | |||
273 | // Filters the output of the filename associated with the element being |
||
274 | // printed in order to see clearly which logical elements belongs to |
||
275 | // a particular filename. It is value is reset after the element |
||
276 | // that represents the Compile Unit is printed. |
||
277 | size_t LastFilenameIndex = 0; |
||
278 | |||
279 | // Controls the amount of additional spaces to insert when printing |
||
280 | // object attributes, in order to get a consistent printing layout. |
||
281 | size_t IndentationSize = 0; |
||
282 | |||
283 | // Calculate the indentation size, so we can use that value when printing |
||
284 | // additional attributes to objects, such as location. |
||
285 | void calculateIndentationSize(); |
||
286 | |||
287 | public: |
||
288 | void resetFilenameIndex() { LastFilenameIndex = 0; } |
||
289 | bool changeFilenameIndex(size_t Index) { |
||
290 | bool IndexChanged = (Index != LastFilenameIndex); |
||
291 | if (IndexChanged) |
||
292 | LastFilenameIndex = Index; |
||
293 | return IndexChanged; |
||
294 | } |
||
295 | |||
296 | // Access to command line options, pattern and printing information. |
||
297 | static LVOptions *getOptions(); |
||
298 | static void setOptions(LVOptions *Options); |
||
299 | |||
300 | LVOptions() = default; |
||
301 | LVOptions(const LVOptions &) = default; |
||
302 | LVOptions &operator=(const LVOptions &) = default; |
||
303 | ~LVOptions() = default; |
||
304 | |||
305 | // Some command line options support shortcuts. For example: |
||
306 | // The command line option '--print=elements' is a shortcut for: |
||
307 | // '--print=instructions,lines,scopes,symbols,types'. |
||
308 | // In the case of logical view comparison, some options related to |
||
309 | // attributes must be set or reset for a proper comparison. |
||
310 | // Resolve any dependencies between command line options. |
||
311 | void resolveDependencies(); |
||
312 | size_t indentationSize() const { return IndentationSize; } |
||
313 | |||
314 | LVAttribute Attribute; |
||
315 | LVCompare Compare; |
||
316 | LVOutput Output; |
||
317 | LVPrint Print; |
||
318 | LVReport Report; |
||
319 | LVSelect Select; |
||
320 | LVWarning Warning; |
||
321 | LVInternal Internal; |
||
322 | LVGeneral General; |
||
323 | |||
324 | // --attribute. |
||
325 | ATTRIBUTE_OPTION(All); |
||
326 | ATTRIBUTE_OPTION(Argument); |
||
327 | ATTRIBUTE_OPTION(Base); |
||
328 | ATTRIBUTE_OPTION(Coverage); |
||
329 | ATTRIBUTE_OPTION(Directories); |
||
330 | ATTRIBUTE_OPTION(Discarded); |
||
331 | ATTRIBUTE_OPTION(Discriminator); |
||
332 | ATTRIBUTE_OPTION(Encoded); |
||
333 | ATTRIBUTE_OPTION(Extended); |
||
334 | ATTRIBUTE_OPTION(Filename); |
||
335 | ATTRIBUTE_OPTION(Files); |
||
336 | ATTRIBUTE_OPTION(Format); |
||
337 | ATTRIBUTE_OPTION(Gaps); |
||
338 | ATTRIBUTE_OPTION(Generated); |
||
339 | ATTRIBUTE_OPTION(Global); |
||
340 | ATTRIBUTE_OPTION(Inserted); |
||
341 | ATTRIBUTE_OPTION(Level); |
||
342 | ATTRIBUTE_OPTION(Linkage); |
||
343 | ATTRIBUTE_OPTION(Location); |
||
344 | ATTRIBUTE_OPTION(Local); |
||
345 | ATTRIBUTE_OPTION(Offset); |
||
346 | ATTRIBUTE_OPTION(Pathname); |
||
347 | ATTRIBUTE_OPTION(Producer); |
||
348 | ATTRIBUTE_OPTION(Publics); |
||
349 | ATTRIBUTE_OPTION(Qualified); |
||
350 | ATTRIBUTE_OPTION(Qualifier); |
||
351 | ATTRIBUTE_OPTION(Range); |
||
352 | ATTRIBUTE_OPTION(Reference); |
||
353 | ATTRIBUTE_OPTION(Register); |
||
354 | ATTRIBUTE_OPTION(Standard); |
||
355 | ATTRIBUTE_OPTION(Subrange); |
||
356 | ATTRIBUTE_OPTION(System); |
||
357 | ATTRIBUTE_OPTION(Typename); |
||
358 | ATTRIBUTE_OPTION(Underlying); |
||
359 | ATTRIBUTE_OPTION(Zero); |
||
360 | BOOL_FUNCTION(Attribute, Added); |
||
361 | BOOL_FUNCTION(Attribute, AnyLocation); |
||
362 | BOOL_FUNCTION(Attribute, AnySource); |
||
363 | BOOL_FUNCTION(Attribute, Missing); |
||
364 | |||
365 | // --compare. |
||
366 | COMPARE_OPTION(All); |
||
367 | COMPARE_OPTION(Lines); |
||
368 | COMPARE_OPTION(Scopes); |
||
369 | COMPARE_OPTION(Symbols); |
||
370 | COMPARE_OPTION(Types); |
||
371 | BOOL_FUNCTION(Compare, Context); |
||
372 | BOOL_FUNCTION(Compare, Execute); |
||
373 | BOOL_FUNCTION(Compare, Print); |
||
374 | |||
375 | // --output. |
||
376 | OUTPUT_OPTION(All); |
||
377 | OUTPUT_OPTION(Split); |
||
378 | OUTPUT_OPTION(Text); |
||
379 | OUTPUT_OPTION(Json); |
||
380 | STD_STRING_FUNCTION(Output, Folder); |
||
381 | UNSIGNED_FUNCTION(Output, Level); |
||
382 | LVSortMode getSortMode() const { return Output.SortMode; } |
||
383 | void setSortMode(LVSortMode SortMode) { Output.SortMode = SortMode; } |
||
384 | |||
385 | // --print. |
||
386 | PRINT_OPTION(All); |
||
387 | PRINT_OPTION(Elements); |
||
388 | PRINT_OPTION(Instructions); |
||
389 | PRINT_OPTION(Lines); |
||
390 | PRINT_OPTION(Scopes); |
||
391 | PRINT_OPTION(Sizes); |
||
392 | PRINT_OPTION(Symbols); |
||
393 | PRINT_OPTION(Summary); |
||
394 | PRINT_OPTION(Types); |
||
395 | PRINT_OPTION(Warnings); |
||
396 | BOOL_FUNCTION(Print, AnyElement); |
||
397 | BOOL_FUNCTION(Print, AnyLine); |
||
398 | BOOL_FUNCTION(Print, Execute); |
||
399 | BOOL_FUNCTION(Print, Formatting); |
||
400 | BOOL_FUNCTION(Print, Offset); |
||
401 | BOOL_FUNCTION(Print, SizesSummary); |
||
402 | |||
403 | // --report. |
||
404 | REPORT_OPTION(All); |
||
405 | REPORT_OPTION(Children); |
||
406 | REPORT_OPTION(List); |
||
407 | REPORT_OPTION(Parents); |
||
408 | REPORT_OPTION(View); |
||
409 | BOOL_FUNCTION(Report, AnyView); |
||
410 | BOOL_FUNCTION(Report, Execute); |
||
411 | |||
412 | // --select. |
||
413 | BOOL_FUNCTION(Select, IgnoreCase); |
||
414 | BOOL_FUNCTION(Select, UseRegex); |
||
415 | BOOL_FUNCTION(Select, Execute); |
||
416 | BOOL_FUNCTION(Select, GenericKind); |
||
417 | BOOL_FUNCTION(Select, GenericPattern); |
||
418 | BOOL_FUNCTION(Select, OffsetPattern); |
||
419 | |||
420 | // --warning. |
||
421 | WARNING_OPTION(All); |
||
422 | WARNING_OPTION(Coverages); |
||
423 | WARNING_OPTION(Lines); |
||
424 | WARNING_OPTION(Locations); |
||
425 | WARNING_OPTION(Ranges); |
||
426 | |||
427 | // --internal. |
||
428 | INTERNAL_OPTION(All); |
||
429 | INTERNAL_OPTION(Cmdline); |
||
430 | INTERNAL_OPTION(ID); |
||
431 | INTERNAL_OPTION(Integrity); |
||
432 | INTERNAL_OPTION(None); |
||
433 | INTERNAL_OPTION(Tag); |
||
434 | |||
435 | // General shortcuts to some combinations. |
||
436 | BOOL_FUNCTION(General, CollectRanges); |
||
437 | |||
438 | void print(raw_ostream &OS) const; |
||
439 | |||
440 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
||
441 | void dump() const { print(dbgs()); } |
||
442 | #endif |
||
443 | }; |
||
444 | |||
445 | inline LVOptions &options() { return (*LVOptions::getOptions()); } |
||
446 | inline void setOptions(LVOptions *Options) { LVOptions::setOptions(Options); } |
||
447 | |||
448 | class LVPatterns final { |
||
449 | // Pattern Mode. |
||
450 | enum class LVMatchMode { |
||
451 | None = 0, // No given pattern. |
||
452 | Match, // Perfect match. |
||
453 | NoCase, // Ignore case. |
||
454 | Regex // Regular expression. |
||
455 | }; |
||
456 | |||
457 | // Keep the search pattern information. |
||
458 | struct LVMatch { |
||
459 | std::string Pattern; // Normal pattern. |
||
460 | std::shared_ptr<Regex> RE; // Regular Expression Pattern. |
||
461 | LVMatchMode Mode = LVMatchMode::None; // Match mode. |
||
462 | }; |
||
463 | |||
464 | using LVMatchInfo = std::vector<LVMatch>; |
||
465 | LVMatchInfo GenericMatchInfo; |
||
466 | using LVMatchOffsets = std::vector<uint64_t>; |
||
467 | LVMatchOffsets OffsetMatchInfo; |
||
468 | |||
469 | // Element selection. |
||
470 | LVElementDispatch ElementDispatch; |
||
471 | LVLineDispatch LineDispatch; |
||
472 | LVScopeDispatch ScopeDispatch; |
||
473 | LVSymbolDispatch SymbolDispatch; |
||
474 | LVTypeDispatch TypeDispatch; |
||
475 | |||
476 | // Element selection request. |
||
477 | LVElementRequest ElementRequest; |
||
478 | LVLineRequest LineRequest; |
||
479 | LVScopeRequest ScopeRequest; |
||
480 | LVSymbolRequest SymbolRequest; |
||
481 | LVTypeRequest TypeRequest; |
||
482 | |||
483 | // Check an element printing Request. |
||
484 | template <typename T, typename U> |
||
485 | bool checkElementRequest(const T *Element, const U &Requests) const { |
||
486 | assert(Element && "Element must not be nullptr"); |
||
487 | for (const auto &Request : Requests) |
||
488 | if ((Element->*Request)()) |
||
489 | return true; |
||
490 | // Check generic element requests. |
||
491 | for (const LVElementGetFunction &Request : ElementRequest) |
||
492 | if ((Element->*Request)()) |
||
493 | return true; |
||
494 | return false; |
||
495 | } |
||
496 | |||
497 | // Add an element printing request based on its kind. |
||
498 | template <typename T, typename U, typename V> |
||
499 | void addRequest(const T &Selection, const U &Dispatch, V &Request) const { |
||
500 | for (const auto &Entry : Selection) { |
||
501 | // Find target function to fullfit request. |
||
502 | typename U::const_iterator Iter = Dispatch.find(Entry); |
||
503 | if (Iter != Dispatch.end()) |
||
504 | Request.push_back(Iter->second); |
||
505 | } |
||
506 | } |
||
507 | |||
508 | void addElement(LVElement *Element); |
||
509 | |||
510 | template <typename T, typename U> |
||
511 | void resolveGenericPatternMatch(T *Element, const U &Requests) { |
||
512 | assert(Element && "Element must not be nullptr"); |
||
513 | auto CheckPattern = [=]() -> bool { |
||
514 | return (Element->isNamed() && matchGenericPattern(Element->getName())) || |
||
515 | (Element->isTyped() && |
||
516 | matchGenericPattern(Element->getTypeName())); |
||
517 | }; |
||
518 | auto CheckOffset = [=]() -> bool { |
||
519 | return matchOffsetPattern(Element->getOffset()); |
||
520 | }; |
||
521 | if ((options().getSelectGenericPattern() && CheckPattern()) || |
||
522 | (options().getSelectOffsetPattern() && CheckOffset()) || |
||
523 | ((Requests.size() || ElementRequest.size()) && |
||
524 | checkElementRequest(Element, Requests))) |
||
525 | addElement(Element); |
||
526 | } |
||
527 | |||
528 | template <typename U> |
||
529 | void resolveGenericPatternMatch(LVLine *Line, const U &Requests) { |
||
530 | assert(Line && "Line must not be nullptr"); |
||
531 | auto CheckPattern = [=]() -> bool { |
||
532 | return matchGenericPattern(Line->lineNumberAsStringStripped()) || |
||
533 | matchGenericPattern(Line->getName()) || |
||
534 | matchGenericPattern(Line->getPathname()); |
||
535 | }; |
||
536 | auto CheckOffset = [=]() -> bool { |
||
537 | return matchOffsetPattern(Line->getAddress()); |
||
538 | }; |
||
539 | if ((options().getSelectGenericPattern() && CheckPattern()) || |
||
540 | (options().getSelectOffsetPattern() && CheckOffset()) || |
||
541 | (Requests.size() && checkElementRequest(Line, Requests))) |
||
542 | addElement(Line); |
||
543 | } |
||
544 | |||
545 | Error createMatchEntry(LVMatchInfo &Filters, StringRef Pattern, |
||
546 | bool IgnoreCase, bool UseRegex); |
||
547 | |||
548 | public: |
||
549 | static LVPatterns *getPatterns(); |
||
550 | |||
551 | LVPatterns() { |
||
552 | ElementDispatch = LVElement::getDispatch(); |
||
553 | LineDispatch = LVLine::getDispatch(); |
||
554 | ScopeDispatch = LVScope::getDispatch(); |
||
555 | SymbolDispatch = LVSymbol::getDispatch(); |
||
556 | TypeDispatch = LVType::getDispatch(); |
||
557 | } |
||
558 | LVPatterns(const LVPatterns &) = delete; |
||
559 | LVPatterns &operator=(const LVPatterns &) = delete; |
||
560 | ~LVPatterns() = default; |
||
561 | |||
562 | // Clear any existing patterns. |
||
563 | void clear() { |
||
564 | GenericMatchInfo.clear(); |
||
565 | OffsetMatchInfo.clear(); |
||
566 | ElementRequest.clear(); |
||
567 | LineRequest.clear(); |
||
568 | ScopeRequest.clear(); |
||
569 | SymbolRequest.clear(); |
||
570 | TypeRequest.clear(); |
||
571 | |||
572 | options().resetSelectGenericKind(); |
||
573 | options().resetSelectGenericPattern(); |
||
574 | options().resetSelectOffsetPattern(); |
||
575 | } |
||
576 | |||
577 | void addRequest(LVElementKindSet &Selection) { |
||
578 | addRequest(Selection, ElementDispatch, ElementRequest); |
||
579 | } |
||
580 | void addRequest(LVLineKindSet &Selection) { |
||
581 | addRequest(Selection, LineDispatch, LineRequest); |
||
582 | } |
||
583 | void addRequest(LVScopeKindSet &Selection) { |
||
584 | addRequest(Selection, ScopeDispatch, ScopeRequest); |
||
585 | } |
||
586 | void addRequest(LVSymbolKindSet &Selection) { |
||
587 | addRequest(Selection, SymbolDispatch, SymbolRequest); |
||
588 | } |
||
589 | void addRequest(LVTypeKindSelection &Selection) { |
||
590 | addRequest(Selection, TypeDispatch, TypeRequest); |
||
591 | } |
||
592 | |||
593 | void updateReportOptions(); |
||
594 | |||
595 | bool matchPattern(StringRef Input, const LVMatchInfo &MatchInfo); |
||
596 | // Match a pattern (--select='pattern'). |
||
597 | bool matchGenericPattern(StringRef Input) { |
||
598 | return matchPattern(Input, GenericMatchInfo); |
||
599 | } |
||
600 | bool matchOffsetPattern(LVOffset Offset) { |
||
601 | return llvm::is_contained(OffsetMatchInfo, Offset); |
||
602 | } |
||
603 | |||
604 | void resolvePatternMatch(LVLine *Line) { |
||
605 | resolveGenericPatternMatch(Line, LineRequest); |
||
606 | } |
||
607 | |||
608 | void resolvePatternMatch(LVScope *Scope) { |
||
609 | resolveGenericPatternMatch(Scope, ScopeRequest); |
||
610 | } |
||
611 | |||
612 | void resolvePatternMatch(LVSymbol *Symbol) { |
||
613 | resolveGenericPatternMatch(Symbol, SymbolRequest); |
||
614 | } |
||
615 | |||
616 | void resolvePatternMatch(LVType *Type) { |
||
617 | resolveGenericPatternMatch(Type, TypeRequest); |
||
618 | } |
||
619 | |||
620 | void addPatterns(StringSet<> &Patterns, LVMatchInfo &Filters); |
||
621 | |||
622 | // Add generic and offset patterns info. |
||
623 | void addGenericPatterns(StringSet<> &Patterns); |
||
624 | void addOffsetPatterns(const LVOffsetSet &Patterns); |
||
625 | |||
626 | // Conditions to print an object. |
||
627 | bool printElement(const LVLine *Line) const; |
||
628 | bool printObject(const LVLocation *Location) const; |
||
629 | bool printElement(const LVScope *Scope) const; |
||
630 | bool printElement(const LVSymbol *Symbol) const; |
||
631 | bool printElement(const LVType *Type) const; |
||
632 | |||
633 | void print(raw_ostream &OS) const; |
||
634 | |||
635 | #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) |
||
636 | void dump() const { print(dbgs()); } |
||
637 | #endif |
||
638 | }; |
||
639 | |||
640 | inline LVPatterns &patterns() { return *LVPatterns::getPatterns(); } |
||
641 | |||
642 | } // namespace logicalview |
||
643 | } // namespace llvm |
||
644 | |||
645 | #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVOPTIONS_H |