1*bdd1243dSDimitry Andric //===-- LVOptions.cpp -----------------------------------------------------===//
2*bdd1243dSDimitry Andric //
3*bdd1243dSDimitry Andric // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
4*bdd1243dSDimitry Andric // See https://llvm.org/LICENSE.txt for license information.
5*bdd1243dSDimitry Andric // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
6*bdd1243dSDimitry Andric //
7*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
8*bdd1243dSDimitry Andric //
9*bdd1243dSDimitry Andric // This implements the LVOptions class.
10*bdd1243dSDimitry Andric //
11*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
12*bdd1243dSDimitry Andric 
13*bdd1243dSDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVOptions.h"
14*bdd1243dSDimitry Andric #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
15*bdd1243dSDimitry Andric #include "llvm/Support/Errc.h"
16*bdd1243dSDimitry Andric 
17*bdd1243dSDimitry Andric using namespace llvm;
18*bdd1243dSDimitry Andric using namespace llvm::logicalview;
19*bdd1243dSDimitry Andric 
20*bdd1243dSDimitry Andric #define DEBUG_TYPE "Options"
21*bdd1243dSDimitry Andric 
22*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
23*bdd1243dSDimitry Andric // Options extracted from the command line.
24*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
25*bdd1243dSDimitry Andric static LVOptions Options;
getOptions()26*bdd1243dSDimitry Andric LVOptions *LVOptions::getOptions() { return &Options; }
setOptions(LVOptions * CmdOptions)27*bdd1243dSDimitry Andric void LVOptions::setOptions(LVOptions *CmdOptions) { Options = *CmdOptions; }
28*bdd1243dSDimitry Andric 
resolveDependencies()29*bdd1243dSDimitry Andric void LVOptions::resolveDependencies() {
30*bdd1243dSDimitry Andric   // Attributes that are classified as standard options.
31*bdd1243dSDimitry Andric   auto StandardAttributes = [&]() {
32*bdd1243dSDimitry Andric     // Set the 'standard' attribute to indicate its associated attributes.
33*bdd1243dSDimitry Andric     setAttributeStandard();
34*bdd1243dSDimitry Andric 
35*bdd1243dSDimitry Andric     setAttributeBase();
36*bdd1243dSDimitry Andric     setAttributeCoverage();
37*bdd1243dSDimitry Andric     setAttributeDirectories();
38*bdd1243dSDimitry Andric     setAttributeDiscriminator();
39*bdd1243dSDimitry Andric     setAttributeFilename();
40*bdd1243dSDimitry Andric     setAttributeFiles();
41*bdd1243dSDimitry Andric     setAttributeFormat();
42*bdd1243dSDimitry Andric     setAttributeLevel();
43*bdd1243dSDimitry Andric     setAttributeProducer();
44*bdd1243dSDimitry Andric     setAttributePublics();
45*bdd1243dSDimitry Andric     setAttributeRange();
46*bdd1243dSDimitry Andric     setAttributeReference();
47*bdd1243dSDimitry Andric     setAttributeZero();
48*bdd1243dSDimitry Andric   };
49*bdd1243dSDimitry Andric 
50*bdd1243dSDimitry Andric   // Attributes that are classified as extended options.
51*bdd1243dSDimitry Andric   auto ExtendedAttributes = [&]() {
52*bdd1243dSDimitry Andric     // Set the 'extended' attribute to indicate its associated attributes.
53*bdd1243dSDimitry Andric     setAttributeExtended();
54*bdd1243dSDimitry Andric 
55*bdd1243dSDimitry Andric     setAttributeArgument();
56*bdd1243dSDimitry Andric     setAttributeDiscarded();
57*bdd1243dSDimitry Andric     setAttributeEncoded();
58*bdd1243dSDimitry Andric     setAttributeGaps();
59*bdd1243dSDimitry Andric     setAttributeGenerated();
60*bdd1243dSDimitry Andric     setAttributeGlobal();
61*bdd1243dSDimitry Andric     setAttributeInserted();
62*bdd1243dSDimitry Andric     setAttributeLinkage();
63*bdd1243dSDimitry Andric     setAttributeLocal();
64*bdd1243dSDimitry Andric     setAttributeLocation();
65*bdd1243dSDimitry Andric     setAttributeOffset();
66*bdd1243dSDimitry Andric     setAttributePathname();
67*bdd1243dSDimitry Andric     setAttributeQualified();
68*bdd1243dSDimitry Andric     setAttributeQualifier();
69*bdd1243dSDimitry Andric     setAttributeRegister();
70*bdd1243dSDimitry Andric     setAttributeSubrange();
71*bdd1243dSDimitry Andric     setAttributeSystem();
72*bdd1243dSDimitry Andric     setAttributeTypename();
73*bdd1243dSDimitry Andric   };
74*bdd1243dSDimitry Andric 
75*bdd1243dSDimitry Andric   // '--Attribute=standard' settings.
76*bdd1243dSDimitry Andric   if (getAttributeStandard())
77*bdd1243dSDimitry Andric     StandardAttributes();
78*bdd1243dSDimitry Andric 
79*bdd1243dSDimitry Andric   // '--Attribute=extended' settings.
80*bdd1243dSDimitry Andric   if (getAttributeExtended())
81*bdd1243dSDimitry Andric     ExtendedAttributes();
82*bdd1243dSDimitry Andric 
83*bdd1243dSDimitry Andric   // '--Attribute=all' settings.
84*bdd1243dSDimitry Andric   if (getAttributeAll()) {
85*bdd1243dSDimitry Andric     StandardAttributes();
86*bdd1243dSDimitry Andric     ExtendedAttributes();
87*bdd1243dSDimitry Andric   }
88*bdd1243dSDimitry Andric 
89*bdd1243dSDimitry Andric   // '--attribute=pathname' supersedes '--attribute=filename'.
90*bdd1243dSDimitry Andric   if (getAttributePathname())
91*bdd1243dSDimitry Andric     resetAttributeFilename();
92*bdd1243dSDimitry Andric 
93*bdd1243dSDimitry Andric   // Assume '--output=text' as default
94*bdd1243dSDimitry Andric   if (!getOutputText() && !getOutputJson())
95*bdd1243dSDimitry Andric     setOutputText();
96*bdd1243dSDimitry Andric 
97*bdd1243dSDimitry Andric   // '--output=all' settings.
98*bdd1243dSDimitry Andric   if (getOutputAll()) {
99*bdd1243dSDimitry Andric     setOutputJson();
100*bdd1243dSDimitry Andric     setOutputSplit();
101*bdd1243dSDimitry Andric     setOutputText();
102*bdd1243dSDimitry Andric   }
103*bdd1243dSDimitry Andric 
104*bdd1243dSDimitry Andric   // A view split folder was specified.
105*bdd1243dSDimitry Andric   if (getOutputFolder().length())
106*bdd1243dSDimitry Andric     setOutputSplit();
107*bdd1243dSDimitry Andric 
108*bdd1243dSDimitry Andric   // Always use the full pathname with splitted output.
109*bdd1243dSDimitry Andric   if (getOutputSplit())
110*bdd1243dSDimitry Andric     setAttributePathname();
111*bdd1243dSDimitry Andric 
112*bdd1243dSDimitry Andric   // '--print=elements' settings.
113*bdd1243dSDimitry Andric   if (getPrintElements()) {
114*bdd1243dSDimitry Andric     setPrintInstructions();
115*bdd1243dSDimitry Andric     setPrintLines();
116*bdd1243dSDimitry Andric     setPrintScopes();
117*bdd1243dSDimitry Andric     setPrintSymbols();
118*bdd1243dSDimitry Andric     setPrintTypes();
119*bdd1243dSDimitry Andric   }
120*bdd1243dSDimitry Andric 
121*bdd1243dSDimitry Andric   // '--print=all' settings.
122*bdd1243dSDimitry Andric   if (getPrintAll()) {
123*bdd1243dSDimitry Andric     setPrintInstructions();
124*bdd1243dSDimitry Andric     setPrintLines();
125*bdd1243dSDimitry Andric     setPrintScopes();
126*bdd1243dSDimitry Andric     setPrintSizes();
127*bdd1243dSDimitry Andric     setPrintSymbols();
128*bdd1243dSDimitry Andric     setPrintSummary();
129*bdd1243dSDimitry Andric     setPrintTypes();
130*bdd1243dSDimitry Andric     setPrintWarnings();
131*bdd1243dSDimitry Andric   }
132*bdd1243dSDimitry Andric 
133*bdd1243dSDimitry Andric   // '--warning=all' settings.
134*bdd1243dSDimitry Andric   if (getWarningAll()) {
135*bdd1243dSDimitry Andric     setWarningCoverages();
136*bdd1243dSDimitry Andric     setWarningLines();
137*bdd1243dSDimitry Andric     setWarningLocations();
138*bdd1243dSDimitry Andric     setWarningRanges();
139*bdd1243dSDimitry Andric   }
140*bdd1243dSDimitry Andric 
141*bdd1243dSDimitry Andric   // '--internal=all' settings.
142*bdd1243dSDimitry Andric   if (getInternalAll()) {
143*bdd1243dSDimitry Andric     setInternalCmdline();
144*bdd1243dSDimitry Andric     setInternalID();
145*bdd1243dSDimitry Andric     setInternalIntegrity();
146*bdd1243dSDimitry Andric     setInternalNone();
147*bdd1243dSDimitry Andric     setInternalTag();
148*bdd1243dSDimitry Andric   }
149*bdd1243dSDimitry Andric 
150*bdd1243dSDimitry Andric   // '--compare=all' settings.
151*bdd1243dSDimitry Andric   if (getCompareAll()) {
152*bdd1243dSDimitry Andric     setCompareLines();
153*bdd1243dSDimitry Andric     setCompareScopes();
154*bdd1243dSDimitry Andric     setCompareSymbols();
155*bdd1243dSDimitry Andric     setCompareTypes();
156*bdd1243dSDimitry Andric   }
157*bdd1243dSDimitry Andric 
158*bdd1243dSDimitry Andric   // Compare the scopes if a request for compare symbols, types, lines.
159*bdd1243dSDimitry Andric   if (getCompareLines() || getCompareSymbols() || getCompareTypes())
160*bdd1243dSDimitry Andric     setCompareScopes();
161*bdd1243dSDimitry Andric 
162*bdd1243dSDimitry Andric   // Generic request for comparison.
163*bdd1243dSDimitry Andric   if (getCompareScopes())
164*bdd1243dSDimitry Andric     setCompareExecute();
165*bdd1243dSDimitry Andric 
166*bdd1243dSDimitry Andric   // Print any logical line (debug or instruction).
167*bdd1243dSDimitry Andric   if (getPrintInstructions() || getPrintLines())
168*bdd1243dSDimitry Andric     setPrintAnyLine();
169*bdd1243dSDimitry Andric 
170*bdd1243dSDimitry Andric   // Print any logical element (line, scope, symbol or type).
171*bdd1243dSDimitry Andric   if (getPrintAnyLine() || getPrintScopes() || getPrintSymbols() ||
172*bdd1243dSDimitry Andric       getPrintTypes())
173*bdd1243dSDimitry Andric     setPrintAnyElement();
174*bdd1243dSDimitry Andric 
175*bdd1243dSDimitry Andric   // Print 'sizes' or 'summary'.
176*bdd1243dSDimitry Andric   if (getPrintSizes() && getPrintSummary())
177*bdd1243dSDimitry Andric     setPrintSizesSummary();
178*bdd1243dSDimitry Andric 
179*bdd1243dSDimitry Andric   // Generic request for printing.
180*bdd1243dSDimitry Andric   if (getPrintAll() || getPrintAnyElement() || getPrintSizesSummary() ||
181*bdd1243dSDimitry Andric       getPrintWarnings())
182*bdd1243dSDimitry Andric     setPrintExecute();
183*bdd1243dSDimitry Andric 
184*bdd1243dSDimitry Andric   // '--reports=all' settings.
185*bdd1243dSDimitry Andric   if (getReportAll()) {
186*bdd1243dSDimitry Andric     setReportChildren();
187*bdd1243dSDimitry Andric     setReportList();
188*bdd1243dSDimitry Andric     setReportParents();
189*bdd1243dSDimitry Andric     setReportView();
190*bdd1243dSDimitry Andric   }
191*bdd1243dSDimitry Andric 
192*bdd1243dSDimitry Andric   // '--report=view' is a shortcut for '--report=parents,children'.
193*bdd1243dSDimitry Andric   if (getReportView()) {
194*bdd1243dSDimitry Andric     setReportChildren();
195*bdd1243dSDimitry Andric     setReportParents();
196*bdd1243dSDimitry Andric   }
197*bdd1243dSDimitry Andric 
198*bdd1243dSDimitry Andric   // The report will include: Parents or Children.
199*bdd1243dSDimitry Andric   if (getReportParents() || getReportChildren() || getReportView())
200*bdd1243dSDimitry Andric     setReportAnyView();
201*bdd1243dSDimitry Andric 
202*bdd1243dSDimitry Andric   // The report will include: List or Parents or Children.
203*bdd1243dSDimitry Andric   if (getReportList() || getReportAnyView())
204*bdd1243dSDimitry Andric     setReportExecute();
205*bdd1243dSDimitry Andric 
206*bdd1243dSDimitry Andric   // If a view or element comparison has been requested, the following options
207*bdd1243dSDimitry Andric   // must be set, in order to get a correct compare:
208*bdd1243dSDimitry Andric   // 1) Sort the CUs, to get a fast compare.
209*bdd1243dSDimitry Andric   // 2) Encode template instantiations, so the names include template
210*bdd1243dSDimitry Andric   //    parameter information.
211*bdd1243dSDimitry Andric   // 3) Include qualified types.
212*bdd1243dSDimitry Andric   // 4) Include any inserted abstract references.
213*bdd1243dSDimitry Andric   // 5) For added/missing elements add the '+' or '-' tags.
214*bdd1243dSDimitry Andric   if (getCompareExecute()) {
215*bdd1243dSDimitry Andric     resetPrintExecute();
216*bdd1243dSDimitry Andric     setComparePrint();
217*bdd1243dSDimitry Andric     setSortMode(LVSortMode::Line);
218*bdd1243dSDimitry Andric     setAttributeAdded();
219*bdd1243dSDimitry Andric     setAttributeArgument();
220*bdd1243dSDimitry Andric     setAttributeEncoded();
221*bdd1243dSDimitry Andric     setAttributeInserted();
222*bdd1243dSDimitry Andric     setAttributeMissing();
223*bdd1243dSDimitry Andric     setAttributeQualified();
224*bdd1243dSDimitry Andric   }
225*bdd1243dSDimitry Andric 
226*bdd1243dSDimitry Andric   // Enable formatting for printing (indentation, print children).
227*bdd1243dSDimitry Andric   setPrintFormatting();
228*bdd1243dSDimitry Andric 
229*bdd1243dSDimitry Andric   // These attributes are dependent on the capture of location information.
230*bdd1243dSDimitry Andric   if (getAttributeCoverage() || getAttributeGaps() || getAttributeRegister())
231*bdd1243dSDimitry Andric     setAttributeLocation();
232*bdd1243dSDimitry Andric 
233*bdd1243dSDimitry Andric   // Location information is only relevant when printing symbols.
234*bdd1243dSDimitry Andric   if (!getPrintSymbols()) {
235*bdd1243dSDimitry Andric     resetAttributeCoverage();
236*bdd1243dSDimitry Andric     resetAttributeGaps();
237*bdd1243dSDimitry Andric     resetAttributeLocation();
238*bdd1243dSDimitry Andric     resetAttributeRegister();
239*bdd1243dSDimitry Andric   }
240*bdd1243dSDimitry Andric 
241*bdd1243dSDimitry Andric   // Quick check for printing any element source information.
242*bdd1243dSDimitry Andric   if (getAttributeFilename() || getAttributePathname())
243*bdd1243dSDimitry Andric     setAttributeAnySource();
244*bdd1243dSDimitry Andric 
245*bdd1243dSDimitry Andric   // Quick check for printing any location information.
246*bdd1243dSDimitry Andric   if (getAttributeLocation() || getAttributeRange())
247*bdd1243dSDimitry Andric     setAttributeAnyLocation();
248*bdd1243dSDimitry Andric 
249*bdd1243dSDimitry Andric   if (getAttributeRange() || getPrintAnyLine())
250*bdd1243dSDimitry Andric     setGeneralCollectRanges();
251*bdd1243dSDimitry Andric 
252*bdd1243dSDimitry Andric   calculateIndentationSize();
253*bdd1243dSDimitry Andric 
254*bdd1243dSDimitry Andric   // Print collected command line options.
255*bdd1243dSDimitry Andric   LLVM_DEBUG({ dump(); });
256*bdd1243dSDimitry Andric }
257*bdd1243dSDimitry Andric 
calculateIndentationSize()258*bdd1243dSDimitry Andric void LVOptions::calculateIndentationSize() {
259*bdd1243dSDimitry Andric #ifndef NDEBUG
260*bdd1243dSDimitry Andric   if (getInternalID()) {
261*bdd1243dSDimitry Andric     std::string String = hexSquareString(0);
262*bdd1243dSDimitry Andric     IndentationSize += String.length();
263*bdd1243dSDimitry Andric   }
264*bdd1243dSDimitry Andric #endif
265*bdd1243dSDimitry Andric   if (getCompareExecute() && (getAttributeAdded() || getAttributeMissing()))
266*bdd1243dSDimitry Andric     ++IndentationSize;
267*bdd1243dSDimitry Andric   if (getAttributeOffset()) {
268*bdd1243dSDimitry Andric     std::string String = hexSquareString(0);
269*bdd1243dSDimitry Andric     IndentationSize += String.length();
270*bdd1243dSDimitry Andric   }
271*bdd1243dSDimitry Andric   if (getAttributeLevel()) {
272*bdd1243dSDimitry Andric     std::stringstream Stream;
273*bdd1243dSDimitry Andric     Stream.str(std::string());
274*bdd1243dSDimitry Andric     Stream << "[" << std::setfill('0') << std::setw(3) << 0 << "]";
275*bdd1243dSDimitry Andric     IndentationSize += Stream.tellp();
276*bdd1243dSDimitry Andric   }
277*bdd1243dSDimitry Andric   if (getAttributeGlobal())
278*bdd1243dSDimitry Andric     ++IndentationSize;
279*bdd1243dSDimitry Andric }
280*bdd1243dSDimitry Andric 
281*bdd1243dSDimitry Andric // Print the current values for all the options, after the dependencies
282*bdd1243dSDimitry Andric // has been resolved.
print(raw_ostream & OS) const283*bdd1243dSDimitry Andric void LVOptions::print(raw_ostream &OS) const {
284*bdd1243dSDimitry Andric   // --attribute
285*bdd1243dSDimitry Andric   OS << "** Attributes **\n"
286*bdd1243dSDimitry Andric      << "All:           " << getAttributeAll() << ", "
287*bdd1243dSDimitry Andric      << "Argument:      " << getAttributeArgument() << ", "
288*bdd1243dSDimitry Andric      << "Base:          " << getAttributeBase() << ", "
289*bdd1243dSDimitry Andric      << "Coverage:      " << getAttributeCoverage() << "\n"
290*bdd1243dSDimitry Andric      << "Directories:   " << getAttributeDirectories() << ", "
291*bdd1243dSDimitry Andric      << "Discarded:     " << getAttributeDiscarded() << ", "
292*bdd1243dSDimitry Andric      << "Discriminator: " << getAttributeDiscriminator() << ", "
293*bdd1243dSDimitry Andric      << "Encoded:       " << getAttributeEncoded() << "\n"
294*bdd1243dSDimitry Andric      << "Extended:      " << getAttributeExtended() << ", "
295*bdd1243dSDimitry Andric      << "Filename:      " << getAttributeFilename() << ", "
296*bdd1243dSDimitry Andric      << "Files:         " << getAttributeFiles() << ", "
297*bdd1243dSDimitry Andric      << "Format:        " << getAttributeFormat() << "\n"
298*bdd1243dSDimitry Andric      << "Gaps:          " << getAttributeGaps() << ", "
299*bdd1243dSDimitry Andric      << "Generated:     " << getAttributeGenerated() << ", "
300*bdd1243dSDimitry Andric      << "Global:        " << getAttributeGlobal() << ", "
301*bdd1243dSDimitry Andric      << "Inserted:      " << getAttributeInserted() << "\n"
302*bdd1243dSDimitry Andric      << "Level:         " << getAttributeLevel() << ", "
303*bdd1243dSDimitry Andric      << "Linkage:       " << getAttributeLinkage() << ", "
304*bdd1243dSDimitry Andric      << "Local:         " << getAttributeLocal() << ", "
305*bdd1243dSDimitry Andric      << "Location:      " << getAttributeLocation() << "\n"
306*bdd1243dSDimitry Andric      << "Offset:        " << getAttributeOffset() << ", "
307*bdd1243dSDimitry Andric      << "Pathname:      " << getAttributePathname() << ", "
308*bdd1243dSDimitry Andric      << "Producer:      " << getAttributeProducer() << ", "
309*bdd1243dSDimitry Andric      << "Publics:       " << getAttributePublics() << "\n"
310*bdd1243dSDimitry Andric      << "Qualified:     " << getAttributeQualified() << ", "
311*bdd1243dSDimitry Andric      << "Qualifier:     " << getAttributeQualifier() << ", "
312*bdd1243dSDimitry Andric      << "Range:         " << getAttributeRange() << ", "
313*bdd1243dSDimitry Andric      << "Reference:     " << getAttributeReference() << "\n"
314*bdd1243dSDimitry Andric      << "Register:      " << getAttributeRegister() << ", "
315*bdd1243dSDimitry Andric      << "Standard:      " << getAttributeStandard() << ", "
316*bdd1243dSDimitry Andric      << "Subrange:      " << getAttributeSubrange() << ", "
317*bdd1243dSDimitry Andric      << "System:        " << getAttributeSystem() << "\n"
318*bdd1243dSDimitry Andric      << "Typename:      " << getAttributeTypename() << ", "
319*bdd1243dSDimitry Andric      << "Underlying:    " << getAttributeUnderlying() << ", "
320*bdd1243dSDimitry Andric      << "Zero:          " << getAttributeZero() << "\n";
321*bdd1243dSDimitry Andric   OS << "Added:         " << getAttributeAdded() << ", "
322*bdd1243dSDimitry Andric      << "AnyLocation:   " << getAttributeAnyLocation() << ", "
323*bdd1243dSDimitry Andric      << "AnySource:     " << getAttributeAnySource() << ", "
324*bdd1243dSDimitry Andric      << "Missing:       " << getAttributeMissing() << "\n"
325*bdd1243dSDimitry Andric      << "\n";
326*bdd1243dSDimitry Andric 
327*bdd1243dSDimitry Andric   // --compare
328*bdd1243dSDimitry Andric   OS << "** Compare **\n"
329*bdd1243dSDimitry Andric      << "All:     " << getCompareAll() << ", "
330*bdd1243dSDimitry Andric      << "Lines:   " << getCompareLines() << ", "
331*bdd1243dSDimitry Andric      << "Scopes:  " << getCompareScopes() << ", "
332*bdd1243dSDimitry Andric      << "Symbols: " << getCompareSymbols() << ", "
333*bdd1243dSDimitry Andric      << "Types:   " << getCompareTypes() << "\n";
334*bdd1243dSDimitry Andric   OS << "Context: " << getCompareContext() << ", "
335*bdd1243dSDimitry Andric      << "Execute: " << getCompareExecute() << ", "
336*bdd1243dSDimitry Andric      << "Print:   " << getComparePrint() << "\n"
337*bdd1243dSDimitry Andric      << "\n";
338*bdd1243dSDimitry Andric 
339*bdd1243dSDimitry Andric   // --print
340*bdd1243dSDimitry Andric   OS << "** Print **\n"
341*bdd1243dSDimitry Andric      << "All:          " << getPrintAll() << ", "
342*bdd1243dSDimitry Andric      << "Elements:     " << getPrintElements() << ", "
343*bdd1243dSDimitry Andric      << "Instructions: " << getPrintInstructions() << ", "
344*bdd1243dSDimitry Andric      << "Lines:        " << getPrintLines() << "\n"
345*bdd1243dSDimitry Andric      << "Scopes:       " << getPrintScopes() << ", "
346*bdd1243dSDimitry Andric      << "Sizes:        " << getPrintSizes() << ", "
347*bdd1243dSDimitry Andric      << "Summary:      " << getPrintSummary() << ", "
348*bdd1243dSDimitry Andric      << "Symbols:      " << getPrintSymbols() << "\n"
349*bdd1243dSDimitry Andric      << "Types:        " << getPrintTypes() << ", "
350*bdd1243dSDimitry Andric      << "Warnings:     " << getPrintWarnings() << "\n";
351*bdd1243dSDimitry Andric   OS << "AnyElemeny:   " << getPrintAnyElement() << ", "
352*bdd1243dSDimitry Andric      << "AnyLine:      " << getPrintAnyLine() << ", "
353*bdd1243dSDimitry Andric      << "Execute:      " << getPrintExecute() << ", "
354*bdd1243dSDimitry Andric      << "Formatting:   " << getPrintFormatting() << "\n"
355*bdd1243dSDimitry Andric      << "Offset:       " << getPrintOffset() << ", "
356*bdd1243dSDimitry Andric      << "SizesSummary: " << getPrintSizesSummary() << "\n"
357*bdd1243dSDimitry Andric      << "\n";
358*bdd1243dSDimitry Andric 
359*bdd1243dSDimitry Andric   // --report
360*bdd1243dSDimitry Andric   OS << "** Report **\n"
361*bdd1243dSDimitry Andric      << "All:      " << getReportAll() << ", "
362*bdd1243dSDimitry Andric      << "Children: " << getReportChildren() << ", "
363*bdd1243dSDimitry Andric      << "List:     " << getReportList() << ", "
364*bdd1243dSDimitry Andric      << "Parents:  " << getReportParents() << ", "
365*bdd1243dSDimitry Andric      << "View:     " << getReportView() << "\n";
366*bdd1243dSDimitry Andric   OS << "AnyView:  " << getReportAnyView() << ", "
367*bdd1243dSDimitry Andric      << "Execute:  " << getReportExecute() << "\n"
368*bdd1243dSDimitry Andric      << "\n";
369*bdd1243dSDimitry Andric 
370*bdd1243dSDimitry Andric   // --select
371*bdd1243dSDimitry Andric   OS << "** Select **\n"
372*bdd1243dSDimitry Andric      << "IgnoreCase:     " << getSelectIgnoreCase() << ", "
373*bdd1243dSDimitry Andric      << "UseRegex:       " << getSelectUseRegex() << ", "
374*bdd1243dSDimitry Andric      << "Execute:        " << getSelectExecute() << ", "
375*bdd1243dSDimitry Andric      << "GenericKind:    " << getSelectGenericKind() << "\n"
376*bdd1243dSDimitry Andric      << "GenericPattern: " << getSelectGenericPattern() << ", "
377*bdd1243dSDimitry Andric      << "OffsetPattern:  " << getSelectOffsetPattern() << "\n"
378*bdd1243dSDimitry Andric      << "\n";
379*bdd1243dSDimitry Andric 
380*bdd1243dSDimitry Andric   // --warning
381*bdd1243dSDimitry Andric   OS << "** Warning **\n"
382*bdd1243dSDimitry Andric      << "All:       " << getWarningAll() << ", "
383*bdd1243dSDimitry Andric      << "Coverage:  " << getWarningCoverages() << ", "
384*bdd1243dSDimitry Andric      << "Lines:     " << getWarningLines() << ", "
385*bdd1243dSDimitry Andric      << "Locations: " << getWarningLocations() << ", "
386*bdd1243dSDimitry Andric      << "Ranges:    " << getWarningRanges() << "\n"
387*bdd1243dSDimitry Andric      << "\n";
388*bdd1243dSDimitry Andric 
389*bdd1243dSDimitry Andric   // --internal
390*bdd1243dSDimitry Andric   OS << "** Internal **\n"
391*bdd1243dSDimitry Andric      << "All:       " << Options.getInternalAll() << ", "
392*bdd1243dSDimitry Andric      << "Cmdline:   " << Options.getInternalCmdline() << ", "
393*bdd1243dSDimitry Andric      << "ID:        " << Options.getInternalID() << ", "
394*bdd1243dSDimitry Andric      << "Integrity: " << Options.getInternalIntegrity() << ", "
395*bdd1243dSDimitry Andric      << "None:      " << Options.getInternalNone() << "\n"
396*bdd1243dSDimitry Andric      << "Tag:       " << Options.getInternalTag() << "\n"
397*bdd1243dSDimitry Andric      << "\n";
398*bdd1243dSDimitry Andric }
399*bdd1243dSDimitry Andric 
400*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
401*bdd1243dSDimitry Andric // Logical element selection using patterns.
402*bdd1243dSDimitry Andric //===----------------------------------------------------------------------===//
getPatterns()403*bdd1243dSDimitry Andric LVPatterns *LVPatterns::getPatterns() {
404*bdd1243dSDimitry Andric   static LVPatterns Patterns;
405*bdd1243dSDimitry Andric   return &Patterns;
406*bdd1243dSDimitry Andric }
407*bdd1243dSDimitry Andric 
createMatchEntry(LVMatchInfo & Filters,StringRef Pattern,bool IgnoreCase,bool UseRegex)408*bdd1243dSDimitry Andric Error LVPatterns::createMatchEntry(LVMatchInfo &Filters, StringRef Pattern,
409*bdd1243dSDimitry Andric                                    bool IgnoreCase, bool UseRegex) {
410*bdd1243dSDimitry Andric   LVMatch Match;
411*bdd1243dSDimitry Andric   // Process pattern as regular expression.
412*bdd1243dSDimitry Andric   if (UseRegex) {
413*bdd1243dSDimitry Andric     Match.Pattern = std::string(Pattern);
414*bdd1243dSDimitry Andric     if (Pattern.size()) {
415*bdd1243dSDimitry Andric       Match.RE = std::make_shared<Regex>(Pattern, IgnoreCase ? Regex::IgnoreCase
416*bdd1243dSDimitry Andric                                                              : Regex::NoFlags);
417*bdd1243dSDimitry Andric       std::string Error;
418*bdd1243dSDimitry Andric       if (!Match.RE->isValid(Error))
419*bdd1243dSDimitry Andric         return createStringError(errc::invalid_argument,
420*bdd1243dSDimitry Andric                                  "Error in regular expression: %s",
421*bdd1243dSDimitry Andric                                  Error.c_str());
422*bdd1243dSDimitry Andric 
423*bdd1243dSDimitry Andric       Match.Mode = LVMatchMode::Regex;
424*bdd1243dSDimitry Andric       Filters.push_back(Match);
425*bdd1243dSDimitry Andric       return Error::success();
426*bdd1243dSDimitry Andric     }
427*bdd1243dSDimitry Andric   }
428*bdd1243dSDimitry Andric 
429*bdd1243dSDimitry Andric   // Process pattern as an exact string match, depending on the case.
430*bdd1243dSDimitry Andric   Match.Pattern = std::string(Pattern);
431*bdd1243dSDimitry Andric   if (Match.Pattern.size()) {
432*bdd1243dSDimitry Andric     Match.Mode = IgnoreCase ? LVMatchMode::NoCase : LVMatchMode::Match;
433*bdd1243dSDimitry Andric     Filters.push_back(Match);
434*bdd1243dSDimitry Andric   }
435*bdd1243dSDimitry Andric 
436*bdd1243dSDimitry Andric   return Error::success();
437*bdd1243dSDimitry Andric }
438*bdd1243dSDimitry Andric 
addGenericPatterns(StringSet<> & Patterns)439*bdd1243dSDimitry Andric void LVPatterns::addGenericPatterns(StringSet<> &Patterns) {
440*bdd1243dSDimitry Andric   addPatterns(Patterns, GenericMatchInfo);
441*bdd1243dSDimitry Andric   if (GenericMatchInfo.size()) {
442*bdd1243dSDimitry Andric     options().setSelectGenericPattern();
443*bdd1243dSDimitry Andric     options().setSelectExecute();
444*bdd1243dSDimitry Andric   }
445*bdd1243dSDimitry Andric }
446*bdd1243dSDimitry Andric 
addOffsetPatterns(const LVOffsetSet & Patterns)447*bdd1243dSDimitry Andric void LVPatterns::addOffsetPatterns(const LVOffsetSet &Patterns) {
448*bdd1243dSDimitry Andric   for (const LVOffset &Entry : Patterns)
449*bdd1243dSDimitry Andric     OffsetMatchInfo.push_back(Entry);
450*bdd1243dSDimitry Andric   if (OffsetMatchInfo.size()) {
451*bdd1243dSDimitry Andric     options().setSelectOffsetPattern();
452*bdd1243dSDimitry Andric     options().setSelectExecute();
453*bdd1243dSDimitry Andric   }
454*bdd1243dSDimitry Andric }
455*bdd1243dSDimitry Andric 
addPatterns(StringSet<> & Patterns,LVMatchInfo & Filters)456*bdd1243dSDimitry Andric void LVPatterns::addPatterns(StringSet<> &Patterns, LVMatchInfo &Filters) {
457*bdd1243dSDimitry Andric   bool IgnoreCase = options().getSelectIgnoreCase();
458*bdd1243dSDimitry Andric   bool UseRegex = options().getSelectUseRegex();
459*bdd1243dSDimitry Andric   for (const StringSet<>::value_type &Entry : Patterns) {
460*bdd1243dSDimitry Andric     StringRef Pattern = Entry.first();
461*bdd1243dSDimitry Andric     if (Error Err = createMatchEntry(Filters, Pattern, IgnoreCase, UseRegex))
462*bdd1243dSDimitry Andric       consumeError(std::move(Err));
463*bdd1243dSDimitry Andric   }
464*bdd1243dSDimitry Andric 
465*bdd1243dSDimitry Andric   LLVM_DEBUG({
466*bdd1243dSDimitry Andric     dbgs() << "\nPattern Information:\n";
467*bdd1243dSDimitry Andric     for (LVMatch &Match : Filters)
468*bdd1243dSDimitry Andric       dbgs() << "Mode: "
469*bdd1243dSDimitry Andric              << (Match.Mode == LVMatchMode::Match ? "Match" : "Regex")
470*bdd1243dSDimitry Andric              << " Pattern: '" << Match.Pattern << "'\n";
471*bdd1243dSDimitry Andric   });
472*bdd1243dSDimitry Andric }
473*bdd1243dSDimitry Andric 
addElement(LVElement * Element)474*bdd1243dSDimitry Andric void LVPatterns::addElement(LVElement *Element) {
475*bdd1243dSDimitry Andric   // Mark any element that matches a given pattern.
476*bdd1243dSDimitry Andric   Element->setIsMatched();
477*bdd1243dSDimitry Andric   options().setSelectExecute();
478*bdd1243dSDimitry Andric   if (options().getReportList())
479*bdd1243dSDimitry Andric     getReaderCompileUnit()->addMatched(Element);
480*bdd1243dSDimitry Andric   if (options().getReportAnyView()) {
481*bdd1243dSDimitry Andric     getReaderCompileUnit()->addMatched(Element->getIsScope()
482*bdd1243dSDimitry Andric                                            ? static_cast<LVScope *>(Element)
483*bdd1243dSDimitry Andric                                            : Element->getParentScope());
484*bdd1243dSDimitry Andric     // Mark element as matched.
485*bdd1243dSDimitry Andric     if (!Element->getIsScope())
486*bdd1243dSDimitry Andric       Element->setHasPattern();
487*bdd1243dSDimitry Andric   }
488*bdd1243dSDimitry Andric }
489*bdd1243dSDimitry Andric 
updateReportOptions()490*bdd1243dSDimitry Andric void LVPatterns::updateReportOptions() {
491*bdd1243dSDimitry Andric   if (ElementRequest.size() || LineRequest.size() || ScopeRequest.size() ||
492*bdd1243dSDimitry Andric       SymbolRequest.size() || TypeRequest.size()) {
493*bdd1243dSDimitry Andric     options().setSelectGenericKind();
494*bdd1243dSDimitry Andric     options().setSelectExecute();
495*bdd1243dSDimitry Andric   }
496*bdd1243dSDimitry Andric 
497*bdd1243dSDimitry Andric   // If we have selected requests and there are no specified report options,
498*bdd1243dSDimitry Andric   // assume the 'details' option.
499*bdd1243dSDimitry Andric   if (options().getSelectExecute() && !options().getReportExecute()) {
500*bdd1243dSDimitry Andric     options().setReportExecute();
501*bdd1243dSDimitry Andric     options().setReportList();
502*bdd1243dSDimitry Andric   }
503*bdd1243dSDimitry Andric }
504*bdd1243dSDimitry Andric 
505*bdd1243dSDimitry Andric // Match a general pattern.
matchPattern(StringRef Input,const LVMatchInfo & MatchInfo)506*bdd1243dSDimitry Andric bool LVPatterns::matchPattern(StringRef Input, const LVMatchInfo &MatchInfo) {
507*bdd1243dSDimitry Andric   bool Matched = false;
508*bdd1243dSDimitry Andric   // Do not match an empty 'Input'.
509*bdd1243dSDimitry Andric   if (Input.empty())
510*bdd1243dSDimitry Andric     return Matched;
511*bdd1243dSDimitry Andric   // Traverse all match specifications.
512*bdd1243dSDimitry Andric   for (const LVMatch &Match : MatchInfo) {
513*bdd1243dSDimitry Andric     switch (Match.Mode) {
514*bdd1243dSDimitry Andric     case LVMatchMode::Match:
515*bdd1243dSDimitry Andric       Matched = Input.equals(Match.Pattern);
516*bdd1243dSDimitry Andric       break;
517*bdd1243dSDimitry Andric     case LVMatchMode::NoCase:
518*bdd1243dSDimitry Andric       Matched = Input.equals_insensitive(Match.Pattern);
519*bdd1243dSDimitry Andric       break;
520*bdd1243dSDimitry Andric     case LVMatchMode::Regex:
521*bdd1243dSDimitry Andric       Matched = Match.RE->match(Input);
522*bdd1243dSDimitry Andric       break;
523*bdd1243dSDimitry Andric     default:
524*bdd1243dSDimitry Andric       break;
525*bdd1243dSDimitry Andric     }
526*bdd1243dSDimitry Andric     // Return if we have a match.
527*bdd1243dSDimitry Andric     if (Matched)
528*bdd1243dSDimitry Andric       return true;
529*bdd1243dSDimitry Andric   }
530*bdd1243dSDimitry Andric   return Matched;
531*bdd1243dSDimitry Andric }
532*bdd1243dSDimitry Andric 
printElement(const LVLine * Line) const533*bdd1243dSDimitry Andric bool LVPatterns::printElement(const LVLine *Line) const {
534*bdd1243dSDimitry Andric   return (options().getPrintLines() && Line->getIsLineDebug()) ||
535*bdd1243dSDimitry Andric          (options().getPrintInstructions() && Line->getIsLineAssembler());
536*bdd1243dSDimitry Andric }
537*bdd1243dSDimitry Andric 
printObject(const LVLocation * Location) const538*bdd1243dSDimitry Andric bool LVPatterns::printObject(const LVLocation *Location) const {
539*bdd1243dSDimitry Andric   if (options().getAttributeAll())
540*bdd1243dSDimitry Andric     return true;
541*bdd1243dSDimitry Andric   bool DoPrint = options().getAttributeAnyLocation();
542*bdd1243dSDimitry Andric   // Consider the case of filler locations.
543*bdd1243dSDimitry Andric   if (DoPrint && Location && Location->getIsGapEntry())
544*bdd1243dSDimitry Andric     DoPrint = options().getAttributeGaps();
545*bdd1243dSDimitry Andric   return DoPrint;
546*bdd1243dSDimitry Andric }
547*bdd1243dSDimitry Andric 
printElement(const LVScope * Scope) const548*bdd1243dSDimitry Andric bool LVPatterns::printElement(const LVScope *Scope) const {
549*bdd1243dSDimitry Andric   // A scope will be printed depending on the following rules:
550*bdd1243dSDimitry Andric   // - Request to print scopes.
551*bdd1243dSDimitry Andric   // - Request to print any of its children.
552*bdd1243dSDimitry Andric   // - If the scope is Root or CompileUnit:
553*bdd1243dSDimitry Andric   //     Request to print summary, sizes or warnings.
554*bdd1243dSDimitry Andric   return options().getPrintScopes() ||
555*bdd1243dSDimitry Andric          (options().getPrintSymbols() && Scope->getHasSymbols()) ||
556*bdd1243dSDimitry Andric          (options().getPrintAnyLine() && Scope->getHasLines()) ||
557*bdd1243dSDimitry Andric          (options().getPrintTypes() && Scope->getHasTypes()) ||
558*bdd1243dSDimitry Andric          ((options().getPrintSizesSummary() || options().getPrintWarnings()) &&
559*bdd1243dSDimitry Andric           (Scope->getIsRoot() || Scope->getIsCompileUnit()));
560*bdd1243dSDimitry Andric }
561*bdd1243dSDimitry Andric 
printElement(const LVSymbol * Symbol) const562*bdd1243dSDimitry Andric bool LVPatterns::printElement(const LVSymbol *Symbol) const {
563*bdd1243dSDimitry Andric   // Print compiler generated symbols only if command line option.
564*bdd1243dSDimitry Andric   if (Symbol->getIsArtificial())
565*bdd1243dSDimitry Andric     return options().getAttributeGenerated() && options().getPrintSymbols();
566*bdd1243dSDimitry Andric   return options().getPrintSymbols();
567*bdd1243dSDimitry Andric }
568*bdd1243dSDimitry Andric 
printElement(const LVType * Type) const569*bdd1243dSDimitry Andric bool LVPatterns::printElement(const LVType *Type) const {
570*bdd1243dSDimitry Andric   // Print array subranges only if print types is requested.
571*bdd1243dSDimitry Andric   if (Type->getIsSubrange())
572*bdd1243dSDimitry Andric     return options().getAttributeSubrange() && options().getPrintTypes();
573*bdd1243dSDimitry Andric   return options().getPrintTypes();
574*bdd1243dSDimitry Andric }
575*bdd1243dSDimitry Andric 
print(raw_ostream & OS) const576*bdd1243dSDimitry Andric void LVPatterns::print(raw_ostream &OS) const {
577*bdd1243dSDimitry Andric   OS << "LVPatterns\n";
578*bdd1243dSDimitry Andric   LLVM_DEBUG(dbgs() << "Print Patterns\n");
579*bdd1243dSDimitry Andric }
580