xref: /freebsd/contrib/llvm-project/llvm/lib/DebugInfo/LogicalView/Core/LVScope.cpp (revision 700637cbb5e582861067a11aaca4d053546871d2)
1 //===-- LVScope.cpp -------------------------------------------------------===//
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 implements the LVScope class.
10 //
11 //===----------------------------------------------------------------------===//
12 
13 #include "llvm/DebugInfo/LogicalView/Core/LVScope.h"
14 #include "llvm/DebugInfo/LogicalView/Core/LVCompare.h"
15 #include "llvm/DebugInfo/LogicalView/Core/LVLine.h"
16 #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h"
17 #include "llvm/DebugInfo/LogicalView/Core/LVRange.h"
18 #include "llvm/DebugInfo/LogicalView/Core/LVReader.h"
19 #include "llvm/DebugInfo/LogicalView/Core/LVSymbol.h"
20 #include "llvm/DebugInfo/LogicalView/Core/LVType.h"
21 
22 using namespace llvm;
23 using namespace llvm::logicalview;
24 
25 #define DEBUG_TYPE "Scope"
26 
27 namespace {
28 const char *const KindArray = "Array";
29 const char *const KindBlock = "Block";
30 const char *const KindCallSite = "CallSite";
31 const char *const KindClass = "Class";
32 const char *const KindCompileUnit = "CompileUnit";
33 const char *const KindEnumeration = "Enumeration";
34 const char *const KindFile = "File";
35 const char *const KindFunction = "Function";
36 const char *const KindInlinedFunction = "InlinedFunction";
37 const char *const KindModule = "Module";
38 const char *const KindNamespace = "Namespace";
39 const char *const KindStruct = "Struct";
40 const char *const KindTemplateAlias = "TemplateAlias";
41 const char *const KindTemplatePack = "TemplatePack";
42 const char *const KindUndefined = "Undefined";
43 const char *const KindUnion = "Union";
44 } // end anonymous namespace
45 
46 //===----------------------------------------------------------------------===//
47 // DWARF lexical block, such as: namespace, function, compile unit, module, etc.
48 //===----------------------------------------------------------------------===//
49 // Return a string representation for the scope kind.
kind() const50 const char *LVScope::kind() const {
51   const char *Kind = KindUndefined;
52   if (getIsArray())
53     Kind = KindArray;
54   else if (getIsModule())
55     Kind = KindModule;
56   else if (getIsBlock())
57     Kind = KindBlock;
58   else if (getIsCallSite())
59     Kind = KindCallSite;
60   else if (getIsCompileUnit())
61     Kind = KindCompileUnit;
62   else if (getIsEnumeration())
63     Kind = KindEnumeration;
64   else if (getIsInlinedFunction())
65     Kind = KindInlinedFunction;
66   else if (getIsNamespace())
67     Kind = KindNamespace;
68   else if (getIsTemplatePack())
69     Kind = KindTemplatePack;
70   else if (getIsRoot())
71     Kind = KindFile;
72   else if (getIsTemplateAlias())
73     Kind = KindTemplateAlias;
74   else if (getIsClass())
75     Kind = KindClass;
76   else if (getIsFunction())
77     Kind = KindFunction;
78   else if (getIsStructure())
79     Kind = KindStruct;
80   else if (getIsUnion())
81     Kind = KindUnion;
82   return Kind;
83 }
84 
85 LVScopeDispatch LVScope::Dispatch = {
86     {LVScopeKind::IsAggregate, &LVScope::getIsAggregate},
87     {LVScopeKind::IsArray, &LVScope::getIsArray},
88     {LVScopeKind::IsBlock, &LVScope::getIsBlock},
89     {LVScopeKind::IsCallSite, &LVScope::getIsCallSite},
90     {LVScopeKind::IsCatchBlock, &LVScope::getIsCatchBlock},
91     {LVScopeKind::IsClass, &LVScope::getIsClass},
92     {LVScopeKind::IsCompileUnit, &LVScope::getIsCompileUnit},
93     {LVScopeKind::IsEntryPoint, &LVScope::getIsEntryPoint},
94     {LVScopeKind::IsEnumeration, &LVScope::getIsEnumeration},
95     {LVScopeKind::IsFunction, &LVScope::getIsFunction},
96     {LVScopeKind::IsFunctionType, &LVScope::getIsFunctionType},
97     {LVScopeKind::IsInlinedFunction, &LVScope::getIsInlinedFunction},
98     {LVScopeKind::IsLabel, &LVScope::getIsLabel},
99     {LVScopeKind::IsLexicalBlock, &LVScope::getIsLexicalBlock},
100     {LVScopeKind::IsModule, &LVScope::getIsModule},
101     {LVScopeKind::IsNamespace, &LVScope::getIsNamespace},
102     {LVScopeKind::IsRoot, &LVScope::getIsRoot},
103     {LVScopeKind::IsStructure, &LVScope::getIsStructure},
104     {LVScopeKind::IsTemplate, &LVScope::getIsTemplate},
105     {LVScopeKind::IsTemplateAlias, &LVScope::getIsTemplateAlias},
106     {LVScopeKind::IsTemplatePack, &LVScope::getIsTemplatePack},
107     {LVScopeKind::IsTryBlock, &LVScope::getIsTryBlock},
108     {LVScopeKind::IsUnion, &LVScope::getIsUnion}};
109 
addToChildren(LVElement * Element)110 void LVScope::addToChildren(LVElement *Element) {
111   if (!Children)
112     Children = std::make_unique<LVElements>();
113   Children->push_back(Element);
114 }
115 
addElement(LVElement * Element)116 void LVScope::addElement(LVElement *Element) {
117   assert(Element && "Invalid element.");
118   if (Element->getIsType())
119     addElement(static_cast<LVType *>(Element));
120   else if (Element->getIsScope())
121     addElement(static_cast<LVScope *>(Element));
122   else if (Element->getIsSymbol())
123     addElement(static_cast<LVSymbol *>(Element));
124   else if (Element->getIsLine())
125     addElement(static_cast<LVLine *>(Element));
126   else
127     llvm_unreachable("Invalid Element.");
128 }
129 
130 // Adds the line info item to the ones stored in the scope.
addElement(LVLine * Line)131 void LVScope::addElement(LVLine *Line) {
132   assert(Line && "Invalid line.");
133   assert(!Line->getParent() && "Line already inserted");
134   if (!Lines)
135     Lines = std::make_unique<LVLines>();
136 
137   // Add it to parent.
138   Lines->push_back(Line);
139   Line->setParent(this);
140 
141   // Notify the reader about the new element being added.
142   getReaderCompileUnit()->addedElement(Line);
143 
144   // All logical elements added to the children, are sorted by any of the
145   // following criterias: offset, name, line number, kind.
146   // Do not add the line records to the children, as they represent the
147   // logical view for the text section and any sorting will not preserve
148   // the original sequence.
149 
150   // Indicate that this tree branch has lines.
151   traverseParents(&LVScope::getHasLines, &LVScope::setHasLines);
152 }
153 
154 // Add a location.
addObject(LVLocation * Location)155 void LVScope::addObject(LVLocation *Location) {
156   assert(Location && "Invalid location.");
157   assert(!Location->getParent() && "Location already inserted");
158   if (!Ranges)
159     Ranges = std::make_unique<LVLocations>();
160 
161   // Add it to parent.
162   Location->setParent(this);
163   Location->setOffset(getOffset());
164 
165   Ranges->push_back(Location);
166   setHasRanges();
167 }
168 
169 // Adds the scope to the child scopes and sets the parent in the child.
addElement(LVScope * Scope)170 void LVScope::addElement(LVScope *Scope) {
171   assert(Scope && "Invalid scope.");
172   assert(!Scope->getParent() && "Scope already inserted");
173   if (!Scopes)
174     Scopes = std::make_unique<LVScopes>();
175 
176   // Add it to parent.
177   Scopes->push_back(Scope);
178   addToChildren(Scope);
179   Scope->setParent(this);
180 
181   // Notify the reader about the new element being added.
182   getReaderCompileUnit()->addedElement(Scope);
183 
184   // If the element is a global reference, mark its parent as having global
185   // references; that information is used, to print only those branches
186   // with global references.
187   if (Scope->getIsGlobalReference())
188     traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);
189   else
190     traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);
191 
192   // Indicate that this tree branch has scopes.
193   traverseParents(&LVScope::getHasScopes, &LVScope::setHasScopes);
194 }
195 
196 // Adds a symbol to the ones stored in the scope.
addElement(LVSymbol * Symbol)197 void LVScope::addElement(LVSymbol *Symbol) {
198   assert(Symbol && "Invalid symbol.");
199   assert(!Symbol->getParent() && "Symbol already inserted");
200   if (!Symbols)
201     Symbols = std::make_unique<LVSymbols>();
202 
203   // Add it to parent.
204   Symbols->push_back(Symbol);
205   addToChildren(Symbol);
206   Symbol->setParent(this);
207 
208   // Notify the reader about the new element being added.
209   getReaderCompileUnit()->addedElement(Symbol);
210 
211   // If the element is a global reference, mark its parent as having global
212   // references; that information is used, to print only those branches
213   // with global references.
214   if (Symbol->getIsGlobalReference())
215     traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);
216   else
217     traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);
218 
219   // Indicate that this tree branch has symbols.
220   traverseParents(&LVScope::getHasSymbols, &LVScope::setHasSymbols);
221 }
222 
223 // Adds a type to the ones stored in the scope.
addElement(LVType * Type)224 void LVScope::addElement(LVType *Type) {
225   assert(Type && "Invalid type.");
226   assert(!Type->getParent() && "Type already inserted");
227   if (!Types)
228     Types = std::make_unique<LVTypes>();
229 
230   // Add it to parent.
231   Types->push_back(Type);
232   addToChildren(Type);
233   Type->setParent(this);
234 
235   // Notify the reader about the new element being added.
236   getReaderCompileUnit()->addedElement(Type);
237 
238   // If the element is a global reference, mark its parent as having global
239   // references; that information is used, to print only those branches
240   // with global references.
241   if (Type->getIsGlobalReference())
242     traverseParents(&LVScope::getHasGlobals, &LVScope::setHasGlobals);
243   else
244     traverseParents(&LVScope::getHasLocals, &LVScope::setHasLocals);
245 
246   // Indicate that this tree branch has types.
247   traverseParents(&LVScope::getHasTypes, &LVScope::setHasTypes);
248 }
249 
250 // Add a pair of ranges.
addObject(LVAddress LowerAddress,LVAddress UpperAddress)251 void LVScope::addObject(LVAddress LowerAddress, LVAddress UpperAddress) {
252   // Pack the ranges into a Location object.
253   LVLocation *Location = getReader().createLocation();
254   Location->setLowerAddress(LowerAddress);
255   Location->setUpperAddress(UpperAddress);
256   Location->setIsAddressRange();
257 
258   addObject(Location);
259 }
260 
removeElement(LVElement * Element)261 bool LVScope::removeElement(LVElement *Element) {
262   auto Predicate = [Element](LVElement *Item) -> bool {
263     return Item == Element;
264   };
265   auto RemoveElement = [Element, Predicate](auto &Container) -> bool {
266     auto Iter = std::remove_if(Container->begin(), Container->end(), Predicate);
267     if (Iter != Container->end()) {
268       Container->erase(Iter, Container->end());
269       Element->resetParent();
270       return true;
271     }
272     return false;
273   };
274 
275   // As 'children' contains only (scopes, symbols and types), check if the
276   // element we are deleting is a line.
277   if (Element->getIsLine())
278     return RemoveElement(Lines);
279 
280   if (RemoveElement(Children)) {
281     if (Element->getIsSymbol())
282       return RemoveElement(Symbols);
283     if (Element->getIsType())
284       return RemoveElement(Types);
285     if (Element->getIsScope())
286       return RemoveElement(Scopes);
287     llvm_unreachable("Invalid element.");
288   }
289 
290   return false;
291 }
292 
addMissingElements(LVScope * Reference)293 void LVScope::addMissingElements(LVScope *Reference) {
294   setAddedMissing();
295   if (!Reference)
296     return;
297 
298   // Get abstract symbols for the given scope reference.
299   const LVSymbols *ReferenceSymbols = Reference->getSymbols();
300   if (!ReferenceSymbols)
301     return;
302 
303   LVSymbols References;
304   References.append(ReferenceSymbols->begin(), ReferenceSymbols->end());
305 
306   // Erase abstract symbols already in this scope from the collection of
307   // symbols in the referenced scope.
308   if (getSymbols())
309     for (const LVSymbol *Symbol : *getSymbols())
310       if (Symbol->getHasReferenceAbstract())
311         llvm::erase(References, Symbol->getReference());
312 
313   // If we have elements left in 'References', those are the elements that
314   // need to be inserted in the current scope.
315   if (References.size()) {
316     LLVM_DEBUG({
317       dbgs() << "Insert Missing Inlined Elements\n"
318              << "Offset = " << hexSquareString(getOffset()) << " "
319              << "Abstract = " << hexSquareString(Reference->getOffset())
320              << "\n";
321     });
322     for (LVSymbol *Reference : References) {
323       LLVM_DEBUG({
324         dbgs() << "Missing Offset = " << hexSquareString(Reference->getOffset())
325                << "\n";
326       });
327       // We can't clone the abstract origin reference, as it contain extra
328       // information that is incorrect for the element to be inserted.
329       // As the symbol being added does not exist in the debug section,
330       // use its parent scope offset, to indicate its DIE location.
331       LVSymbol *Symbol = getReader().createSymbol();
332       addElement(Symbol);
333       Symbol->setOffset(getOffset());
334       Symbol->setIsOptimized();
335       Symbol->setReference(Reference);
336 
337       // The symbol can be a constant, parameter, variable or unspecified
338       // parameters (i.e. `...`).
339       if (Reference->getIsConstant())
340         Symbol->setIsConstant();
341       else if (Reference->getIsParameter())
342         Symbol->setIsParameter();
343       else if (Reference->getIsVariable())
344         Symbol->setIsVariable();
345       else if (Reference->getIsUnspecified())
346         Symbol->setIsUnspecified();
347       else
348         llvm_unreachable("Invalid symbol kind.");
349     }
350   }
351 }
352 
updateLevel(LVScope * Parent,bool Moved)353 void LVScope::updateLevel(LVScope *Parent, bool Moved) {
354   // Update the level for the element itself and all its children, using the
355   // given scope parent as reference.
356   setLevel(Parent->getLevel() + 1);
357 
358   // Update the children.
359   if (Children)
360     for (LVElement *Element : *Children)
361       Element->updateLevel(this, Moved);
362 
363   // Update any lines.
364   if (Lines)
365     for (LVLine *Line : *Lines)
366       Line->updateLevel(this, Moved);
367 }
368 
resolve()369 void LVScope::resolve() {
370   if (getIsResolved())
371     return;
372 
373   // Resolve the element itself.
374   LVElement::resolve();
375 
376   // Resolve the children.
377   if (Children)
378     for (LVElement *Element : *Children) {
379       if (getIsGlobalReference())
380         // If the scope is a global reference, mark all its children as well.
381         Element->setIsGlobalReference();
382       Element->resolve();
383     }
384 }
385 
resolveName()386 void LVScope::resolveName() {
387   if (getIsResolvedName())
388     return;
389   setIsResolvedName();
390 
391   // If the scope is a template, resolve the template parameters and get
392   // the name for the template with the encoded arguments.
393   if (getIsTemplate())
394     resolveTemplate();
395   else {
396     if (LVElement *BaseType = getType()) {
397       BaseType->resolveName();
398       resolveFullname(BaseType);
399     }
400   }
401 
402   // In the case of unnamed scopes, try to generate a name for it, using
403   // the parents name and the line information. In the case of compiler
404   // generated functions, use its linkage name if is available.
405   if (!isNamed()) {
406     if (getIsArtificial())
407       setName(getLinkageName());
408     else
409       generateName();
410   }
411 
412   LVElement::resolveName();
413 
414   // Resolve any given pattern.
415   patterns().resolvePatternMatch(this);
416 }
417 
resolveReferences()418 void LVScope::resolveReferences() {
419   // The scopes can have the following references to other elements:
420   //   A type:
421   //     DW_AT_type             ->  Type or Scope
422   //     DW_AT_import           ->  Type
423   //   A Reference:
424   //     DW_AT_specification    ->  Scope
425   //     DW_AT_abstract_origin  ->  Scope
426   //     DW_AT_extension        ->  Scope
427 
428   // Resolve any referenced scope.
429   LVScope *Reference = getReference();
430   if (Reference) {
431     Reference->resolve();
432     // Recursively resolve the scope names.
433     resolveReferencesChain();
434   }
435 
436   // Set the file/line information using the Debug Information entry.
437   setFile(Reference);
438 
439   // Resolve any referenced type or scope.
440   if (LVElement *Element = getType())
441     Element->resolve();
442 }
443 
resolveElements()444 void LVScope::resolveElements() {
445   // The current element represents the Root. Traverse each Compile Unit.
446   if (!Scopes)
447     return;
448 
449   for (LVScope *Scope : *Scopes) {
450     LVScopeCompileUnit *CompileUnit = static_cast<LVScopeCompileUnit *>(Scope);
451     getReader().setCompileUnit(CompileUnit);
452     CompileUnit->resolve();
453     // Propagate any matching information into the scopes tree.
454     CompileUnit->propagatePatternMatch();
455   }
456 }
457 
resolveReferencesChain()458 StringRef LVScope::resolveReferencesChain() {
459   // If the scope has a DW_AT_specification or DW_AT_abstract_origin,
460   // follow the chain to resolve the name from those references.
461   if (getHasReference() && !isNamed())
462     setName(getReference()->resolveReferencesChain());
463 
464   return getName();
465 }
466 
467 // Get template parameter types.
getTemplateParameterTypes(LVTypes & Params)468 bool LVScope::getTemplateParameterTypes(LVTypes &Params) {
469   // Traverse the scope types and populate the given container with those
470   // types that are template parameters; that container will be used by
471   // 'encodeTemplateArguments' to resolve them.
472   if (const LVTypes *Types = getTypes())
473     for (LVType *Type : *Types)
474       if (Type->getIsTemplateParam()) {
475         Type->resolve();
476         Params.push_back(Type);
477       }
478 
479   return !Params.empty();
480 }
481 
482 // Resolve the template parameters/arguments relationship.
resolveTemplate()483 void LVScope::resolveTemplate() {
484   if (getIsTemplateResolved())
485     return;
486   setIsTemplateResolved();
487 
488   // Check if we need to encode the template arguments.
489   if (options().getAttributeEncoded()) {
490     LVTypes Params;
491     if (getTemplateParameterTypes(Params)) {
492       std::string EncodedArgs;
493       // Encode the arguments as part of the template name and update the
494       // template name, to reflect the encoded parameters.
495       encodeTemplateArguments(EncodedArgs, &Params);
496       setEncodedArgs(EncodedArgs);
497     }
498   }
499 }
500 
501 // Get the qualified name for the template.
getQualifiedName(std::string & QualifiedName) const502 void LVScope::getQualifiedName(std::string &QualifiedName) const {
503   if (getIsRoot() || getIsCompileUnit())
504     return;
505 
506   if (LVScope *Parent = getParentScope())
507     Parent->getQualifiedName(QualifiedName);
508   if (!QualifiedName.empty())
509     QualifiedName.append("::");
510   QualifiedName.append(std::string(getName()));
511 }
512 
513 // Encode the template arguments as part of the template name.
encodeTemplateArguments(std::string & Name) const514 void LVScope::encodeTemplateArguments(std::string &Name) const {
515   // Qualify only when we are expanding parameters that are template
516   // instances; the debugger will assume the current scope symbol as
517   // the qualifying tag for the symbol being generated, which gives:
518   //   namespace std {
519   //     ...
520   //     set<float,std::less<float>,std::allocator<float>>
521   //     ...
522   //   }
523   // The 'set' symbol is assumed to have the qualified tag 'std'.
524 
525   // We are resolving a template parameter which is another template. If
526   // it is already resolved, just get the qualified name and return.
527   std::string BaseName;
528   getQualifiedName(BaseName);
529   if (getIsTemplateResolved())
530     Name.append(BaseName);
531 }
532 
encodeTemplateArguments(std::string & Name,const LVTypes * Types) const533 void LVScope::encodeTemplateArguments(std::string &Name,
534                                       const LVTypes *Types) const {
535   // The encoded string will start with the scope name.
536   Name.append("<");
537 
538   // The list of types are the template parameters.
539   if (Types) {
540     bool AddComma = false;
541     for (const LVType *Type : *Types) {
542       if (AddComma)
543         Name.append(", ");
544       Type->encodeTemplateArgument(Name);
545       AddComma = true;
546     }
547   }
548 
549   Name.append(">");
550 }
551 
resolvePrinting() const552 bool LVScope::resolvePrinting() const {
553   // The warnings collected during the scope creation as per compile unit.
554   // If there is a request for printing warnings, always print its associate
555   // Compile Unit.
556   if (options().getPrintWarnings() && (getIsRoot() || getIsCompileUnit()))
557     return true;
558 
559   // In selection mode, always print the root scope regardless of the
560   // number of matched elements. If no matches, the root by itself will
561   // indicate no matches.
562   if (options().getSelectExecute()) {
563     return getIsRoot() || getIsCompileUnit() || getHasPattern();
564   }
565 
566   bool Globals = options().getAttributeGlobal();
567   bool Locals = options().getAttributeLocal();
568   if ((Globals && Locals) || (!Globals && !Locals)) {
569     // Print both Global and Local.
570   } else {
571     // Check for Global or Local Objects.
572     if ((Globals && !(getHasGlobals() || getIsGlobalReference())) ||
573         (Locals && !(getHasLocals() || !getIsGlobalReference())))
574       return false;
575   }
576 
577   // For the case of functions, skip it if is compiler generated.
578   if (getIsFunction() && getIsArtificial() &&
579       !options().getAttributeGenerated())
580     return false;
581 
582   return true;
583 }
584 
doPrint(bool Split,bool Match,bool Print,raw_ostream & OS,bool Full) const585 Error LVScope::doPrint(bool Split, bool Match, bool Print, raw_ostream &OS,
586                        bool Full) const {
587   // During a view output splitting, use the output stream created by the
588   // split context, then switch to the reader output stream.
589   raw_ostream *StreamSplit = &OS;
590 
591   // Ignore the CU generated by the VS toolchain, when compiling to PDB.
592   if (getIsSystem() && !options().getAttributeSystem())
593     return Error::success();
594 
595   // If 'Split', we use the scope name (CU name) as the ouput file; the
596   // delimiters in the pathname, must be replaced by a normal character.
597   if (getIsCompileUnit()) {
598     getReader().setCompileUnit(const_cast<LVScope *>(this));
599     if (Split) {
600       std::string ScopeName(getName());
601       if (std::error_code EC =
602               getReaderSplitContext().open(ScopeName, ".txt", OS))
603         return createStringError(EC, "Unable to create split output file %s",
604                                  ScopeName.c_str());
605       StreamSplit = static_cast<raw_ostream *>(&getReaderSplitContext().os());
606     }
607   }
608 
609   // Ignore discarded or stripped scopes (functions).
610   bool DoPrint = (options().getAttributeDiscarded()) ? true : !getIsDiscarded();
611 
612   // If we are in compare mode, the only conditions are related to the
613   // element being missing. In the case of elements comparison, we print the
614   // augmented view, that includes added elements.
615   // In print mode, we check other conditions, such as local, global, etc.
616   if (DoPrint) {
617     DoPrint =
618         getIsInCompare() ? options().getReportExecute() : resolvePrinting();
619   }
620 
621   // At this point we have checked for very specific options, to decide if the
622   // element will be printed. Include the caller's test for element general
623   // print.
624   DoPrint = DoPrint && (Print || options().getOutputSplit());
625 
626   if (DoPrint) {
627     // Print the element itself.
628     print(*StreamSplit, Full);
629 
630     // Check if we have reached the requested lexical level specified in the
631     // command line options. Input file is level zero and the CU is level 1.
632     if ((getIsRoot() || options().getPrintAnyElement()) &&
633         options().getPrintFormatting() &&
634         getLevel() < options().getOutputLevel()) {
635       // Print the children.
636       if (Children)
637         for (const LVElement *Element : *Children) {
638           if (Match && !Element->getHasPattern())
639             continue;
640           if (Error Err =
641                   Element->doPrint(Split, Match, Print, *StreamSplit, Full))
642             return Err;
643         }
644 
645       // Print the line records.
646       if (Lines)
647         for (const LVLine *Line : *Lines) {
648           if (Match && !Line->getHasPattern())
649             continue;
650           if (Error Err =
651                   Line->doPrint(Split, Match, Print, *StreamSplit, Full))
652             return Err;
653         }
654 
655       // Print the warnings.
656       if (options().getPrintWarnings())
657         printWarnings(*StreamSplit, Full);
658     }
659   }
660 
661   // Done printing the compile unit. Print any requested summary and
662   // restore the original output context.
663   if (getIsCompileUnit()) {
664     if (options().getPrintSummary())
665       printSummary(*StreamSplit);
666     if (options().getPrintSizes())
667       printSizes(*StreamSplit);
668     if (Split) {
669       getReaderSplitContext().close();
670       StreamSplit = &getReader().outputStream();
671     }
672   }
673 
674   if (getIsRoot() && options().getPrintWarnings()) {
675     getReader().printRecords(*StreamSplit);
676   }
677 
678   return Error::success();
679 }
680 
sort()681 void LVScope::sort() {
682   // Preserve the lines order as they are associated with user code.
683   LVSortFunction SortFunction = getSortFunction();
684   if (SortFunction) {
685     std::function<void(LVScope * Parent, LVSortFunction SortFunction)> Sort =
686         [&](LVScope *Parent, LVSortFunction SortFunction) {
687           auto Traverse = [&](auto &Set, LVSortFunction SortFunction) {
688             if (Set)
689               llvm::stable_sort(*Set, SortFunction);
690           };
691           Traverse(Parent->Types, SortFunction);
692           Traverse(Parent->Symbols, SortFunction);
693           Traverse(Parent->Scopes, SortFunction);
694           Traverse(Parent->Ranges, compareRange);
695           Traverse(Parent->Children, SortFunction);
696 
697           if (Parent->Scopes)
698             for (LVScope *Scope : *Parent->Scopes)
699               Sort(Scope, SortFunction);
700         };
701 
702     // Start traversing the scopes root and transform the element name.
703     Sort(this, SortFunction);
704   }
705 }
706 
traverseParents(LVScopeGetFunction GetFunction,LVScopeSetFunction SetFunction)707 void LVScope::traverseParents(LVScopeGetFunction GetFunction,
708                               LVScopeSetFunction SetFunction) {
709   // Traverse the parent tree.
710   LVScope *Parent = this;
711   while (Parent) {
712     // Terminates if the 'SetFunction' has been already executed.
713     if ((Parent->*GetFunction)())
714       break;
715     (Parent->*SetFunction)();
716     Parent = Parent->getParentScope();
717   }
718 }
719 
traverseParentsAndChildren(LVObjectGetFunction GetFunction,LVObjectSetFunction SetFunction)720 void LVScope::traverseParentsAndChildren(LVObjectGetFunction GetFunction,
721                                          LVObjectSetFunction SetFunction) {
722   if (options().getReportParents()) {
723     // First traverse the parent tree.
724     LVScope *Parent = this;
725     while (Parent) {
726       // Terminates if the 'SetFunction' has been already executed.
727       if ((Parent->*GetFunction)())
728         break;
729       (Parent->*SetFunction)();
730       Parent = Parent->getParentScope();
731     }
732   }
733 
734   std::function<void(LVScope * Scope)> TraverseChildren = [&](LVScope *Scope) {
735     auto Traverse = [&](const auto *Set) {
736       if (Set)
737         for (const auto &Entry : *Set)
738           (Entry->*SetFunction)();
739     };
740 
741     (Scope->*SetFunction)();
742 
743     Traverse(Scope->getTypes());
744     Traverse(Scope->getSymbols());
745     Traverse(Scope->getLines());
746 
747     if (const LVScopes *Scopes = Scope->getScopes())
748       for (LVScope *Scope : *Scopes)
749         TraverseChildren(Scope);
750   };
751 
752   if (options().getReportChildren())
753     TraverseChildren(this);
754 }
755 
756 // Traverse the symbol location ranges and for each range:
757 // - Apply the 'ValidLocation' validation criteria.
758 // - Add any failed range to the 'LocationList'.
759 // - Calculate location coverage.
getLocations(LVLocations & LocationList,LVValidLocation ValidLocation,bool RecordInvalid)760 void LVScope::getLocations(LVLocations &LocationList,
761                            LVValidLocation ValidLocation, bool RecordInvalid) {
762   // Traverse scopes and symbols.
763   if (Symbols)
764     for (LVSymbol *Symbol : *Symbols)
765       Symbol->getLocations(LocationList, ValidLocation, RecordInvalid);
766   if (Scopes)
767     for (LVScope *Scope : *Scopes)
768       Scope->getLocations(LocationList, ValidLocation, RecordInvalid);
769 }
770 
771 // Traverse the scope ranges and for each range:
772 // - Apply the 'ValidLocation' validation criteria.
773 // - Add any failed range to the 'LocationList'.
774 // - Calculate location coverage.
getRanges(LVLocations & LocationList,LVValidLocation ValidLocation,bool RecordInvalid)775 void LVScope::getRanges(LVLocations &LocationList,
776                         LVValidLocation ValidLocation, bool RecordInvalid) {
777   // Ignore discarded or stripped scopes (functions).
778   if (getIsDiscarded())
779     return;
780 
781   // Process the ranges for current scope.
782   if (Ranges) {
783     for (LVLocation *Location : *Ranges) {
784       // Add the invalid location object.
785       if (!(Location->*ValidLocation)() && RecordInvalid)
786         LocationList.push_back(Location);
787     }
788 
789     // Calculate coverage factor.
790     calculateCoverage();
791   }
792 
793   // Traverse the scopes.
794   if (Scopes)
795     for (LVScope *Scope : *Scopes)
796       Scope->getRanges(LocationList, ValidLocation, RecordInvalid);
797 }
798 
799 // Get all the ranges associated with scopes.
getRanges(LVRange & RangeList)800 void LVScope::getRanges(LVRange &RangeList) {
801   // Ignore discarded or stripped scopes (functions).
802   if (getIsDiscarded())
803     return;
804 
805   if (Ranges)
806     RangeList.addEntry(this);
807   if (Scopes)
808     for (LVScope *Scope : *Scopes)
809       Scope->getRanges(RangeList);
810 }
811 
outermostParent(LVAddress Address)812 LVScope *LVScope::outermostParent(LVAddress Address) {
813   LVScope *Parent = this;
814   while (Parent) {
815     const LVLocations *ParentRanges = Parent->getRanges();
816     if (ParentRanges)
817       for (const LVLocation *Location : *ParentRanges)
818         if (Location->getLowerAddress() <= Address)
819           return Parent;
820     Parent = Parent->getParentScope();
821   }
822   return Parent;
823 }
824 
findIn(const LVScopes * Targets) const825 LVScope *LVScope::findIn(const LVScopes *Targets) const {
826   if (!Targets)
827     return nullptr;
828 
829   // In the case of overloaded functions, sometimes the DWARF used to
830   // describe them, does not give suficient information. Try to find a
831   // perfect match or mark them as possible conflicts.
832   LVScopes Candidates;
833   for (LVScope *Target : *Targets)
834     if (LVScope::equals(Target))
835       Candidates.push_back(Target);
836 
837   LLVM_DEBUG({
838     if (!Candidates.empty()) {
839       dbgs() << "\n[LVScope::findIn]\n"
840              << "Reference: "
841              << "Offset = " << hexSquareString(getOffset()) << ", "
842              << "Level = " << getLevel() << ", "
843              << "Kind = " << formattedKind(kind()) << ", "
844              << "Name = " << formattedName(getName()) << "\n";
845       for (const LVScope *Candidate : Candidates)
846         dbgs() << "Candidate: "
847                << "Offset = " << hexSquareString(Candidate->getOffset()) << ", "
848                << "Level = " << Candidate->getLevel() << ", "
849                << "Kind = " << formattedKind(Candidate->kind()) << ", "
850                << "Name = " << formattedName(Candidate->getName()) << "\n";
851     }
852   });
853 
854   if (!Candidates.empty())
855     return (Candidates.size() == 1)
856                ? (equals(Candidates[0]) ? Candidates[0] : nullptr)
857                : findEqualScope(&Candidates);
858 
859   return nullptr;
860 }
861 
equalNumberOfChildren(const LVScope * Scope) const862 bool LVScope::equalNumberOfChildren(const LVScope *Scope) const {
863   // Same number of children. Take into account which elements are requested
864   // to be included in the comparison.
865   return !(
866       (options().getCompareScopes() && scopeCount() != Scope->scopeCount()) ||
867       (options().getCompareSymbols() &&
868        symbolCount() != Scope->symbolCount()) ||
869       (options().getCompareTypes() && typeCount() != Scope->typeCount()) ||
870       (options().getCompareLines() && lineCount() != Scope->lineCount()));
871 }
872 
markMissingParents(const LVScope * Target,bool TraverseChildren)873 void LVScope::markMissingParents(const LVScope *Target, bool TraverseChildren) {
874   auto SetCompareState = [&](auto &Container) {
875     if (Container)
876       for (auto *Entry : *Container)
877         Entry->setIsInCompare();
878   };
879   SetCompareState(Types);
880   SetCompareState(Symbols);
881   SetCompareState(Lines);
882   SetCompareState(Scopes);
883 
884   // At this point, we are ready to start comparing the current scope, once
885   // the compare bits have been set.
886   if (options().getCompareTypes() && getTypes() && Target->getTypes())
887     LVType::markMissingParents(getTypes(), Target->getTypes());
888   if (options().getCompareSymbols() && getSymbols() && Target->getSymbols())
889     LVSymbol::markMissingParents(getSymbols(), Target->getSymbols());
890   if (options().getCompareLines() && getLines() && Target->getLines())
891     LVLine::markMissingParents(getLines(), Target->getLines());
892   if (getScopes() && Target->getScopes())
893     LVScope::markMissingParents(getScopes(), Target->getScopes(),
894                                 TraverseChildren);
895 }
896 
markMissingParents(const LVScopes * References,const LVScopes * Targets,bool TraverseChildren)897 void LVScope::markMissingParents(const LVScopes *References,
898                                  const LVScopes *Targets,
899                                  bool TraverseChildren) {
900   if (!(References && Targets))
901     return;
902 
903   LLVM_DEBUG({
904     dbgs() << "\n[LVScope::markMissingParents]\n";
905     for (const LVScope *Reference : *References)
906       dbgs() << "References: "
907              << "Offset = " << hexSquareString(Reference->getOffset()) << ", "
908              << "Level = " << Reference->getLevel() << ", "
909              << "Kind = " << formattedKind(Reference->kind()) << ", "
910              << "Name = " << formattedName(Reference->getName()) << "\n";
911     for (const LVScope *Target : *Targets)
912       dbgs() << "Targets   : "
913              << "Offset = " << hexSquareString(Target->getOffset()) << ", "
914              << "Level = " << Target->getLevel() << ", "
915              << "Kind = " << formattedKind(Target->kind()) << ", "
916              << "Name = " << formattedName(Target->getName()) << "\n";
917   });
918 
919   for (LVScope *Reference : *References) {
920     // Don't process 'Block' scopes, as we can't identify them.
921     if (Reference->getIsBlock() || Reference->getIsGeneratedName())
922       continue;
923 
924     LLVM_DEBUG({
925       dbgs() << "\nSearch Reference: "
926              << "Offset = " << hexSquareString(Reference->getOffset()) << " "
927              << "Name = " << formattedName(Reference->getName()) << "\n";
928     });
929     LVScope *Target = Reference->findIn(Targets);
930     if (Target) {
931       LLVM_DEBUG({
932         dbgs() << "\nFound Target: "
933                << "Offset = " << hexSquareString(Target->getOffset()) << " "
934                << "Name = " << formattedName(Target->getName()) << "\n";
935       });
936       if (TraverseChildren)
937         Reference->markMissingParents(Target, TraverseChildren);
938     } else {
939       LLVM_DEBUG({
940         dbgs() << "Missing Reference: "
941                << "Offset = " << hexSquareString(Reference->getOffset()) << " "
942                << "Name = " << formattedName(Reference->getName()) << "\n";
943       });
944       Reference->markBranchAsMissing();
945     }
946   }
947 }
948 
equals(const LVScope * Scope) const949 bool LVScope::equals(const LVScope *Scope) const {
950   if (!LVElement::equals(Scope))
951     return false;
952   // For lexical scopes, check if their parents are the same.
953   if (getIsLexicalBlock() && Scope->getIsLexicalBlock())
954     return getParentScope()->equals(Scope->getParentScope());
955   return true;
956 }
957 
findEqualScope(const LVScopes * Scopes) const958 LVScope *LVScope::findEqualScope(const LVScopes *Scopes) const {
959   assert(Scopes && "Scopes must not be nullptr");
960   for (LVScope *Scope : *Scopes)
961     if (equals(Scope))
962       return Scope;
963   return nullptr;
964 }
965 
equals(const LVScopes * References,const LVScopes * Targets)966 bool LVScope::equals(const LVScopes *References, const LVScopes *Targets) {
967   if (!References && !Targets)
968     return true;
969   if (References && Targets && References->size() == Targets->size()) {
970     for (const LVScope *Reference : *References)
971       if (!Reference->findIn(Targets))
972         return false;
973     return true;
974   }
975   return false;
976 }
977 
report(LVComparePass Pass)978 void LVScope::report(LVComparePass Pass) {
979   getComparator().printItem(this, Pass);
980   getComparator().push(this);
981   if (Children)
982     for (LVElement *Element : *Children)
983       Element->report(Pass);
984 
985   if (Lines)
986     for (LVLine *Line : *Lines)
987       Line->report(Pass);
988   getComparator().pop();
989 }
990 
printActiveRanges(raw_ostream & OS,bool Full) const991 void LVScope::printActiveRanges(raw_ostream &OS, bool Full) const {
992   if (options().getPrintFormatting() && options().getAttributeRange() &&
993       Ranges) {
994     for (const LVLocation *Location : *Ranges)
995       Location->print(OS, Full);
996   }
997 }
998 
printEncodedArgs(raw_ostream & OS,bool Full) const999 void LVScope::printEncodedArgs(raw_ostream &OS, bool Full) const {
1000   if (options().getPrintFormatting() && options().getAttributeEncoded())
1001     printAttributes(OS, Full, "{Encoded} ", const_cast<LVScope *>(this),
1002                     getEncodedArgs(), /*UseQuotes=*/false, /*PrintRef=*/false);
1003 }
1004 
print(raw_ostream & OS,bool Full) const1005 void LVScope::print(raw_ostream &OS, bool Full) const {
1006   if (getIncludeInPrint() && getReader().doPrintScope(this)) {
1007     // For a summary (printed elements), do not count the scope root.
1008     // For a summary (selected elements) do not count a compile unit.
1009     if (!(getIsRoot() || (getIsCompileUnit() && options().getSelectExecute())))
1010       getReaderCompileUnit()->incrementPrintedScopes();
1011     LVElement::print(OS, Full);
1012     printExtra(OS, Full);
1013   }
1014 }
1015 
printExtra(raw_ostream & OS,bool Full) const1016 void LVScope::printExtra(raw_ostream &OS, bool Full) const {
1017   OS << formattedKind(kind());
1018   // Do not print any type or name for a lexical block.
1019   if (!getIsBlock()) {
1020     OS << " " << formattedName(getName());
1021     if (!getIsAggregate()) {
1022       OS << " -> " << typeOffsetAsString()
1023          << formattedNames(getTypeQualifiedName(), typeAsString());
1024     }
1025     if (options().getAttributeSize())
1026       if (uint32_t Size = getStorageSizeInBytes())
1027         OS << " [Size = " << Size << "]";
1028   }
1029   OS << "\n";
1030 
1031   // Print any active ranges.
1032   if (Full && getIsBlock())
1033     printActiveRanges(OS, Full);
1034 }
1035 
1036 //===----------------------------------------------------------------------===//
1037 // DWARF Union/Structure/Class.
1038 //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1039 bool LVScopeAggregate::equals(const LVScope *Scope) const {
1040   if (!LVScope::equals(Scope))
1041     return false;
1042 
1043   if (!equalNumberOfChildren(Scope))
1044     return false;
1045 
1046   // Check if the parameters match in the case of templates.
1047   if (!LVType::parametersMatch(getTypes(), Scope->getTypes()))
1048     return false;
1049 
1050   if (!isNamed() && !Scope->isNamed())
1051     // In the case of unnamed union/structure/class compare the file name.
1052     if (getFilenameIndex() != Scope->getFilenameIndex())
1053       return false;
1054 
1055   return true;
1056 }
1057 
findEqualScope(const LVScopes * Scopes) const1058 LVScope *LVScopeAggregate::findEqualScope(const LVScopes *Scopes) const {
1059   assert(Scopes && "Scopes must not be nullptr");
1060   for (LVScope *Scope : *Scopes)
1061     if (equals(Scope))
1062       return Scope;
1063   return nullptr;
1064 }
1065 
printExtra(raw_ostream & OS,bool Full) const1066 void LVScopeAggregate::printExtra(raw_ostream &OS, bool Full) const {
1067   LVScope::printExtra(OS, Full);
1068   if (Full) {
1069     if (getIsTemplateResolved())
1070       printEncodedArgs(OS, Full);
1071     LVScope *Reference = getReference();
1072     if (Reference)
1073       Reference->printReference(OS, Full, const_cast<LVScopeAggregate *>(this));
1074   }
1075 }
1076 
1077 //===----------------------------------------------------------------------===//
1078 // DWARF Template alias.
1079 //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1080 bool LVScopeAlias::equals(const LVScope *Scope) const {
1081   if (!LVScope::equals(Scope))
1082     return false;
1083   return equalNumberOfChildren(Scope);
1084 }
1085 
printExtra(raw_ostream & OS,bool Full) const1086 void LVScopeAlias::printExtra(raw_ostream &OS, bool Full) const {
1087   OS << formattedKind(kind()) << " " << formattedName(getName()) << " -> "
1088      << typeOffsetAsString()
1089      << formattedNames(getTypeQualifiedName(), typeAsString()) << "\n";
1090 }
1091 
1092 //===----------------------------------------------------------------------===//
1093 // DWARF array (DW_TAG_array_type).
1094 //===----------------------------------------------------------------------===//
resolveExtra()1095 void LVScopeArray::resolveExtra() {
1096   // If the scope is an array, resolve the subrange entries and get those
1097   // values encoded and assigned to the scope type.
1098   // Encode the array subrange entries as part of the name.
1099   if (getIsArrayResolved())
1100     return;
1101   setIsArrayResolved();
1102 
1103   // There are 2 cases to represent the bounds information for an array:
1104   // 1) DW_TAG_array_type
1105   //      DW_AT_type --> ref_type
1106   //      DW_TAG_subrange_type
1107   //        DW_AT_type --> ref_type (type of object)
1108   //        DW_AT_count --> value (number of elements in subrange)
1109 
1110   // 2) DW_TAG_array_type
1111   //      DW_AT_type --> ref_type
1112   //        DW_TAG_subrange_type
1113   //          DW_AT_lower_bound --> value
1114   //          DW_AT_upper_bound --> value
1115 
1116   // The idea is to represent the bounds as a string, depending on the format:
1117   // 1) [count]
1118   // 2) [lower][upper]
1119 
1120   // Traverse scope types, looking for those types that are subranges.
1121   LVTypes Subranges;
1122   if (const LVTypes *Types = getTypes())
1123     for (LVType *Type : *Types)
1124       if (Type->getIsSubrange()) {
1125         Type->resolve();
1126         Subranges.push_back(Type);
1127       }
1128 
1129   // Use the subrange types to generate the high level name for the array.
1130   // Check the type has been fully resolved.
1131   if (LVElement *BaseType = getType()) {
1132     BaseType->resolveName();
1133     resolveFullname(BaseType);
1134   }
1135 
1136   // In 'resolveFullname' a check is done for double spaces in the type name.
1137   std::stringstream ArrayInfo;
1138   if (ElementType)
1139     ArrayInfo << getTypeName().str() << " ";
1140 
1141   for (const LVType *Type : Subranges) {
1142     if (Type->getIsSubrangeCount())
1143       // Check if we have DW_AT_count subrange style.
1144       ArrayInfo << "[" << Type->getCount() << "]";
1145     else {
1146       // Get lower and upper subrange values.
1147       unsigned LowerBound;
1148       unsigned UpperBound;
1149       std::tie(LowerBound, UpperBound) = Type->getBounds();
1150 
1151       // The representation depends on the bound values. If the lower value
1152       // is zero, treat the pair as the elements count. Otherwise, just use
1153       // the pair, as they are representing arrays in languages other than
1154       // C/C++ and the lower limit is not zero.
1155       if (LowerBound)
1156         ArrayInfo << "[" << LowerBound << ".." << UpperBound << "]";
1157       else
1158         ArrayInfo << "[" << UpperBound + 1 << "]";
1159     }
1160   }
1161 
1162   // Update the scope name, to reflect the encoded subranges.
1163   setName(ArrayInfo.str());
1164 }
1165 
equals(const LVScope * Scope) const1166 bool LVScopeArray::equals(const LVScope *Scope) const {
1167   if (!LVScope::equals(Scope))
1168     return false;
1169 
1170   if (!equalNumberOfChildren(Scope))
1171     return false;
1172 
1173   // Despite the arrays are encoded, to reflect the dimensions, we have to
1174   // check the subranges, in order to determine if they are the same.
1175   if (!LVType::equals(getTypes(), Scope->getTypes()))
1176     return false;
1177 
1178   return true;
1179 }
1180 
printExtra(raw_ostream & OS,bool Full) const1181 void LVScopeArray::printExtra(raw_ostream &OS, bool Full) const {
1182   OS << formattedKind(kind()) << " " << typeOffsetAsString()
1183      << formattedName(getName()) << "\n";
1184 }
1185 
1186 //===----------------------------------------------------------------------===//
1187 // An object file (single or multiple CUs).
1188 //===----------------------------------------------------------------------===//
addSize(LVScope * Scope,LVOffset Lower,LVOffset Upper)1189 void LVScopeCompileUnit::addSize(LVScope *Scope, LVOffset Lower,
1190                                  LVOffset Upper) {
1191   LLVM_DEBUG({
1192     dbgs() << format(
1193         "CU [0x%08" PRIx64 "], Scope [0x%08" PRIx64 "], Range [0x%08" PRIx64
1194         ":0x%08" PRIx64 "], Size = %" PRId64 "\n",
1195         getOffset(), Scope->getOffset(), Lower, Upper, Upper - Lower);
1196   });
1197 
1198   // There is no need to check for a previous entry, as we are traversing the
1199   // debug information in sequential order.
1200   LVOffset Size = Upper - Lower;
1201   Sizes[Scope] = Size;
1202   if (this == Scope)
1203     // Record contribution size for the compilation unit.
1204     CUContributionSize = Size;
1205 }
1206 
1207 // Update parents and children with pattern information.
propagatePatternMatch()1208 void LVScopeCompileUnit::propagatePatternMatch() {
1209   // At this stage, we have finished creating the Scopes tree and we have
1210   // a list of elements that match the pattern specified in the command line.
1211   // The pattern corresponds to a scope or element; mark parents and/or
1212   // children as having that pattern, before any printing is done.
1213   if (!options().getSelectExecute())
1214     return;
1215 
1216   if (MatchedScopes.size()) {
1217     for (LVScope *Scope : MatchedScopes)
1218       Scope->traverseParentsAndChildren(&LVScope::getHasPattern,
1219                                         &LVScope::setHasPattern);
1220   } else {
1221     // Mark the compile unit as having a pattern to enable any requests to
1222     // print sizes and summary as that information is recorded at that level.
1223     setHasPattern();
1224   }
1225 }
1226 
processRangeLocationCoverage(LVValidLocation ValidLocation)1227 void LVScopeCompileUnit::processRangeLocationCoverage(
1228     LVValidLocation ValidLocation) {
1229   if (options().getAttributeRange()) {
1230     // Traverse the scopes to get scopes that have invalid ranges.
1231     LVLocations Locations;
1232     bool RecordInvalid = options().getWarningRanges();
1233     getRanges(Locations, ValidLocation, RecordInvalid);
1234 
1235     // Validate ranges associated with scopes.
1236     if (RecordInvalid)
1237       for (LVLocation *Location : Locations)
1238         addInvalidRange(Location);
1239   }
1240 
1241   if (options().getAttributeLocation()) {
1242     // Traverse the scopes to get locations that have invalid ranges.
1243     LVLocations Locations;
1244     bool RecordInvalid = options().getWarningLocations();
1245     getLocations(Locations, ValidLocation, RecordInvalid);
1246 
1247     // Validate ranges associated with locations.
1248     if (RecordInvalid)
1249       for (LVLocation *Location : Locations)
1250         addInvalidLocation(Location);
1251   }
1252 }
1253 
addMapping(LVLine * Line,LVSectionIndex SectionIndex)1254 void LVScopeCompileUnit::addMapping(LVLine *Line, LVSectionIndex SectionIndex) {
1255   LVAddress Address = Line->getOffset();
1256   SectionMappings.add(SectionIndex, Address, Line);
1257 }
1258 
lineLowerBound(LVAddress Address,LVScope * Scope) const1259 LVLine *LVScopeCompileUnit::lineLowerBound(LVAddress Address,
1260                                            LVScope *Scope) const {
1261   LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope);
1262   LVAddressToLine *Map = SectionMappings.findMap(SectionIndex);
1263   if (!Map || Map->empty())
1264     return nullptr;
1265   LVAddressToLine::const_iterator Iter = Map->lower_bound(Address);
1266   return (Iter != Map->end()) ? Iter->second : nullptr;
1267 }
1268 
lineUpperBound(LVAddress Address,LVScope * Scope) const1269 LVLine *LVScopeCompileUnit::lineUpperBound(LVAddress Address,
1270                                            LVScope *Scope) const {
1271   LVSectionIndex SectionIndex = getReader().getSectionIndex(Scope);
1272   LVAddressToLine *Map = SectionMappings.findMap(SectionIndex);
1273   if (!Map || Map->empty())
1274     return nullptr;
1275   LVAddressToLine::const_iterator Iter = Map->upper_bound(Address);
1276   if (Iter != Map->begin())
1277     Iter = std::prev(Iter);
1278   return Iter->second;
1279 }
1280 
lineRange(LVLocation * Location) const1281 LVLineRange LVScopeCompileUnit::lineRange(LVLocation *Location) const {
1282   // The parent of a location can be a symbol or a scope.
1283   LVElement *Element = Location->getParent();
1284   LVScope *Parent = Element->getIsScope() ? static_cast<LVScope *>(Element)
1285                                           : Element->getParentScope();
1286   LVLine *LowLine = lineLowerBound(Location->getLowerAddress(), Parent);
1287   LVLine *HighLine = lineUpperBound(Location->getUpperAddress(), Parent);
1288   return LVLineRange(LowLine, HighLine);
1289 }
1290 
getFilename(size_t Index) const1291 StringRef LVScopeCompileUnit::getFilename(size_t Index) const {
1292   if (Index <= 0 || Index > Filenames.size())
1293     return StringRef();
1294   return getStringPool().getString(Filenames[Index - 1]);
1295 }
1296 
equals(const LVScope * Scope) const1297 bool LVScopeCompileUnit::equals(const LVScope *Scope) const {
1298   if (!LVScope::equals(Scope))
1299     return false;
1300 
1301   return getNameIndex() == Scope->getNameIndex();
1302 }
1303 
incrementPrintedLines()1304 void LVScopeCompileUnit::incrementPrintedLines() {
1305   options().getSelectExecute() ? ++Found.Lines : ++Printed.Lines;
1306 }
incrementPrintedScopes()1307 void LVScopeCompileUnit::incrementPrintedScopes() {
1308   options().getSelectExecute() ? ++Found.Scopes : ++Printed.Scopes;
1309 }
incrementPrintedSymbols()1310 void LVScopeCompileUnit::incrementPrintedSymbols() {
1311   options().getSelectExecute() ? ++Found.Symbols : ++Printed.Symbols;
1312 }
incrementPrintedTypes()1313 void LVScopeCompileUnit::incrementPrintedTypes() {
1314   options().getSelectExecute() ? ++Found.Types : ++Printed.Types;
1315 }
1316 
1317 // Values are used by '--summary' option (allocated).
increment(LVLine * Line)1318 void LVScopeCompileUnit::increment(LVLine *Line) {
1319   if (Line->getIncludeInPrint())
1320     ++Allocated.Lines;
1321 }
increment(LVScope * Scope)1322 void LVScopeCompileUnit::increment(LVScope *Scope) {
1323   if (Scope->getIncludeInPrint())
1324     ++Allocated.Scopes;
1325 }
increment(LVSymbol * Symbol)1326 void LVScopeCompileUnit::increment(LVSymbol *Symbol) {
1327   if (Symbol->getIncludeInPrint())
1328     ++Allocated.Symbols;
1329 }
increment(LVType * Type)1330 void LVScopeCompileUnit::increment(LVType *Type) {
1331   if (Type->getIncludeInPrint())
1332     ++Allocated.Types;
1333 }
1334 
1335 // A new element has been added to the scopes tree. Take the following steps:
1336 // Increase the added element counters, for printing summary.
1337 // During comparison notify the Reader of the new element.
addedElement(LVLine * Line)1338 void LVScopeCompileUnit::addedElement(LVLine *Line) {
1339   increment(Line);
1340   getReader().notifyAddedElement(Line);
1341 }
addedElement(LVScope * Scope)1342 void LVScopeCompileUnit::addedElement(LVScope *Scope) {
1343   increment(Scope);
1344   getReader().notifyAddedElement(Scope);
1345 }
addedElement(LVSymbol * Symbol)1346 void LVScopeCompileUnit::addedElement(LVSymbol *Symbol) {
1347   increment(Symbol);
1348   getReader().notifyAddedElement(Symbol);
1349 }
addedElement(LVType * Type)1350 void LVScopeCompileUnit::addedElement(LVType *Type) {
1351   increment(Type);
1352   getReader().notifyAddedElement(Type);
1353 }
1354 
1355 // Record unsuported DWARF tags.
addDebugTag(dwarf::Tag Target,LVOffset Offset)1356 void LVScopeCompileUnit::addDebugTag(dwarf::Tag Target, LVOffset Offset) {
1357   addItem<LVTagOffsetsMap, dwarf::Tag, LVOffset>(&DebugTags, Target, Offset);
1358 }
1359 
1360 // Record elements with invalid offsets.
addInvalidOffset(LVOffset Offset,LVElement * Element)1361 void LVScopeCompileUnit::addInvalidOffset(LVOffset Offset, LVElement *Element) {
1362   if (WarningOffsets.find(Offset) == WarningOffsets.end())
1363     WarningOffsets.emplace(Offset, Element);
1364 }
1365 
1366 // Record symbols with invalid coverage values.
addInvalidCoverage(LVSymbol * Symbol)1367 void LVScopeCompileUnit::addInvalidCoverage(LVSymbol *Symbol) {
1368   LVOffset Offset = Symbol->getOffset();
1369   if (InvalidCoverages.find(Offset) == InvalidCoverages.end())
1370     InvalidCoverages.emplace(Offset, Symbol);
1371 }
1372 
1373 // Record symbols with invalid locations.
addInvalidLocation(LVLocation * Location)1374 void LVScopeCompileUnit::addInvalidLocation(LVLocation *Location) {
1375   addInvalidLocationOrRange(Location, Location->getParentSymbol(),
1376                             &InvalidLocations);
1377 }
1378 
1379 // Record scopes with invalid ranges.
addInvalidRange(LVLocation * Location)1380 void LVScopeCompileUnit::addInvalidRange(LVLocation *Location) {
1381   addInvalidLocationOrRange(Location, Location->getParentScope(),
1382                             &InvalidRanges);
1383 }
1384 
1385 // Record line zero.
addLineZero(LVLine * Line)1386 void LVScopeCompileUnit::addLineZero(LVLine *Line) {
1387   LVScope *Scope = Line->getParentScope();
1388   LVOffset Offset = Scope->getOffset();
1389   addInvalidOffset(Offset, Scope);
1390   addItem<LVOffsetLinesMap, LVOffset, LVLine *>(&LinesZero, Offset, Line);
1391 }
1392 
printLocalNames(raw_ostream & OS,bool Full) const1393 void LVScopeCompileUnit::printLocalNames(raw_ostream &OS, bool Full) const {
1394   if (!options().getPrintFormatting())
1395     return;
1396 
1397   // Calculate an indentation value, to preserve a nice layout.
1398   size_t Indentation = options().indentationSize() +
1399                        lineNumberAsString().length() +
1400                        indentAsString(getLevel() + 1).length() + 3;
1401 
1402   enum class Option { Directory, File };
1403   auto PrintNames = [&](Option Action) {
1404     StringRef Kind = Action == Option::Directory ? "Directory" : "File";
1405     std::set<std::string> UniqueNames;
1406     for (size_t Index : Filenames) {
1407       // In the case of missing directory name in the .debug_line table,
1408       // the returned string has a leading '/'.
1409       StringRef Name = getStringPool().getString(Index);
1410       size_t Pos = Name.rfind('/');
1411       if (Pos != std::string::npos)
1412         Name = (Action == Option::File) ? Name.substr(Pos + 1)
1413                                         : Name.substr(0, Pos);
1414       // Collect only unique names.
1415       UniqueNames.insert(std::string(Name));
1416     }
1417     for (const std::string &Name : UniqueNames)
1418       OS << std::string(Indentation, ' ') << formattedKind(Kind) << " "
1419          << formattedName(Name) << "\n";
1420   };
1421 
1422   if (options().getAttributeDirectories())
1423     PrintNames(Option::Directory);
1424   if (options().getAttributeFiles())
1425     PrintNames(Option::File);
1426   if (options().getAttributePublics()) {
1427     StringRef Kind = "Public";
1428     // The public names are indexed by 'LVScope *'. We want to print
1429     // them by logical element address, to show the scopes layout.
1430     using OffsetSorted = std::map<LVAddress, LVPublicNames::const_iterator>;
1431     OffsetSorted SortedNames;
1432     for (LVPublicNames::const_iterator Iter = PublicNames.begin();
1433          Iter != PublicNames.end(); ++Iter)
1434       SortedNames.emplace(Iter->first->getOffset(), Iter);
1435 
1436     LVPublicNames::const_iterator Iter;
1437     for (OffsetSorted::reference Entry : SortedNames) {
1438       Iter = Entry.second;
1439       OS << std::string(Indentation, ' ') << formattedKind(Kind) << " "
1440          << formattedName((*Iter).first->getName());
1441       if (options().getAttributeOffset()) {
1442         LVAddress Address = (*Iter).second.first;
1443         size_t Size = (*Iter).second.second;
1444         OS << " [" << hexString(Address) << ":" << hexString(Address + Size)
1445            << "]";
1446       }
1447       OS << "\n";
1448     }
1449   }
1450 }
1451 
printWarnings(raw_ostream & OS,bool Full) const1452 void LVScopeCompileUnit::printWarnings(raw_ostream &OS, bool Full) const {
1453   auto PrintHeader = [&](const char *Header) { OS << "\n" << Header << ":\n"; };
1454   auto PrintFooter = [&](auto &Set) {
1455     if (Set.empty())
1456       OS << "None\n";
1457   };
1458   auto PrintOffset = [&](unsigned &Count, LVOffset Offset) {
1459     if (Count == 5) {
1460       Count = 0;
1461       OS << "\n";
1462     }
1463     ++Count;
1464     OS << hexSquareString(Offset) << " ";
1465   };
1466   auto PrintElement = [&](const LVOffsetElementMap &Map, LVOffset Offset) {
1467     LVOffsetElementMap::const_iterator Iter = Map.find(Offset);
1468     LVElement *Element = Iter != Map.end() ? Iter->second : nullptr;
1469     OS << "[" << hexString(Offset) << "]";
1470     if (Element)
1471       OS << " " << formattedKind(Element->kind()) << " "
1472          << formattedName(Element->getName());
1473     OS << "\n";
1474   };
1475   auto PrintInvalidLocations = [&](const LVOffsetLocationsMap &Map,
1476                                    const char *Header) {
1477     PrintHeader(Header);
1478     for (LVOffsetLocationsMap::const_reference Entry : Map) {
1479       PrintElement(WarningOffsets, Entry.first);
1480       for (const LVLocation *Location : Entry.second)
1481         OS << hexSquareString(Location->getOffset()) << " "
1482            << Location->getIntervalInfo() << "\n";
1483     }
1484     PrintFooter(Map);
1485   };
1486 
1487   if (options().getInternalTag() && getReader().isBinaryTypeELF()) {
1488     PrintHeader("Unsupported DWARF Tags");
1489     for (LVTagOffsetsMap::const_reference Entry : DebugTags) {
1490       OS << format("\n0x%02x", (unsigned)Entry.first) << ", "
1491          << dwarf::TagString(Entry.first) << "\n";
1492       unsigned Count = 0;
1493       for (const LVOffset &Offset : Entry.second)
1494         PrintOffset(Count, Offset);
1495       OS << "\n";
1496     }
1497     PrintFooter(DebugTags);
1498   }
1499 
1500   if (options().getWarningCoverages()) {
1501     PrintHeader("Symbols Invalid Coverages");
1502     for (LVOffsetSymbolMap::const_reference Entry : InvalidCoverages) {
1503       // Symbol basic information.
1504       LVSymbol *Symbol = Entry.second;
1505       OS << hexSquareString(Entry.first) << " {Coverage} "
1506          << format("%.2f%%", Symbol->getCoveragePercentage()) << " "
1507          << formattedKind(Symbol->kind()) << " "
1508          << formattedName(Symbol->getName()) << "\n";
1509     }
1510     PrintFooter(InvalidCoverages);
1511   }
1512 
1513   if (options().getWarningLines()) {
1514     PrintHeader("Lines Zero References");
1515     for (LVOffsetLinesMap::const_reference Entry : LinesZero) {
1516       PrintElement(WarningOffsets, Entry.first);
1517       unsigned Count = 0;
1518       for (const LVLine *Line : Entry.second)
1519         PrintOffset(Count, Line->getOffset());
1520       OS << "\n";
1521     }
1522     PrintFooter(LinesZero);
1523   }
1524 
1525   if (options().getWarningLocations())
1526     PrintInvalidLocations(InvalidLocations, "Invalid Location Ranges");
1527 
1528   if (options().getWarningRanges())
1529     PrintInvalidLocations(InvalidRanges, "Invalid Code Ranges");
1530 }
1531 
printTotals(raw_ostream & OS) const1532 void LVScopeCompileUnit::printTotals(raw_ostream &OS) const {
1533   OS << "\nTotals by lexical level:\n";
1534   for (size_t Index = 1; Index <= MaxSeenLevel; ++Index)
1535     OS << format("[%03d]: %10d (%6.2f%%)\n", Index, Totals[Index].first,
1536                  Totals[Index].second);
1537 }
1538 
printScopeSize(const LVScope * Scope,raw_ostream & OS)1539 void LVScopeCompileUnit::printScopeSize(const LVScope *Scope, raw_ostream &OS) {
1540   LVSizesMap::const_iterator Iter = Sizes.find(Scope);
1541   if (Iter != Sizes.end()) {
1542     LVOffset Size = Iter->second;
1543     assert(CUContributionSize && "Invalid CU contribution size.");
1544     // Get a percentage rounded to two decimal digits. This avoids
1545     // implementation-defined rounding inside printing functions.
1546     float Percentage =
1547         rint((float(Size) / CUContributionSize) * 100.0 * 100.0) / 100.0;
1548     OS << format("%10" PRId64 " (%6.2f%%) : ", Size, Percentage);
1549     Scope->print(OS);
1550 
1551     // Keep record of the total sizes at each lexical level.
1552     LVLevel Level = Scope->getLevel();
1553     if (Level > MaxSeenLevel)
1554       MaxSeenLevel = Level;
1555     if (Level >= Totals.size())
1556       Totals.resize(2 * Level);
1557     Totals[Level].first += Size;
1558     Totals[Level].second += Percentage;
1559   }
1560 }
1561 
printSizes(raw_ostream & OS) const1562 void LVScopeCompileUnit::printSizes(raw_ostream &OS) const {
1563   // Recursively print the contributions for each scope.
1564   std::function<void(const LVScope *Scope)> PrintScope =
1565       [&](const LVScope *Scope) {
1566         // If we have selection criteria, then use only the selected scopes.
1567         if (options().getSelectExecute() && options().getReportAnyView()) {
1568           for (const LVScope *Scope : MatchedScopes)
1569             if (Scope->getLevel() < options().getOutputLevel())
1570               printScopeSize(Scope, OS);
1571           return;
1572         }
1573         if (Scope->getLevel() < options().getOutputLevel()) {
1574           if (const LVScopes *Scopes = Scope->getScopes())
1575             for (const LVScope *Scope : *Scopes) {
1576               printScopeSize(Scope, OS);
1577               PrintScope(Scope);
1578             }
1579         }
1580       };
1581 
1582   bool PrintScopes = options().getPrintScopes();
1583   if (!PrintScopes)
1584     options().setPrintScopes();
1585   getReader().setCompileUnit(const_cast<LVScopeCompileUnit *>(this));
1586 
1587   OS << "\nScope Sizes:\n";
1588   options().resetPrintFormatting();
1589   options().setPrintOffset();
1590 
1591   // Print the scopes regardless if the user has requested any scopes
1592   // printing. Set the option just to allow printing the contributions.
1593   printScopeSize(this, OS);
1594   PrintScope(this);
1595 
1596   // Print total scope sizes by level.
1597   printTotals(OS);
1598 
1599   options().resetPrintOffset();
1600   options().setPrintFormatting();
1601 
1602   if (!PrintScopes)
1603     options().resetPrintScopes();
1604 }
1605 
printSummary(raw_ostream & OS) const1606 void LVScopeCompileUnit::printSummary(raw_ostream &OS) const {
1607   printSummary(OS, options().getSelectExecute() ? Found : Printed, "Printed");
1608 }
1609 
1610 // Print summary details for the scopes tree.
printSummary(raw_ostream & OS,const LVCounter & Counter,const char * Header) const1611 void LVScopeCompileUnit::printSummary(raw_ostream &OS, const LVCounter &Counter,
1612                                       const char *Header) const {
1613   std::string Separator = std::string(29, '-');
1614   auto PrintSeparator = [&]() { OS << Separator << "\n"; };
1615   auto PrintHeadingRow = [&](const char *T, const char *U, const char *V) {
1616     OS << format("%-9s%9s  %9s\n", T, U, V);
1617   };
1618   auto PrintDataRow = [&](const char *T, unsigned U, unsigned V) {
1619     OS << format("%-9s%9d  %9d\n", T, U, V);
1620   };
1621 
1622   OS << "\n";
1623   PrintSeparator();
1624   PrintHeadingRow("Element", "Total", Header);
1625   PrintSeparator();
1626   PrintDataRow("Scopes", Allocated.Scopes, Counter.Scopes);
1627   PrintDataRow("Symbols", Allocated.Symbols, Counter.Symbols);
1628   PrintDataRow("Types", Allocated.Types, Counter.Types);
1629   PrintDataRow("Lines", Allocated.Lines, Counter.Lines);
1630   PrintSeparator();
1631   PrintDataRow(
1632       "Total",
1633       Allocated.Scopes + Allocated.Symbols + Allocated.Lines + Allocated.Types,
1634       Counter.Scopes + Counter.Symbols + Counter.Lines + Counter.Types);
1635 }
1636 
printMatchedElements(raw_ostream & OS,bool UseMatchedElements)1637 void LVScopeCompileUnit::printMatchedElements(raw_ostream &OS,
1638                                               bool UseMatchedElements) {
1639   LVSortFunction SortFunction = getSortFunction();
1640   if (SortFunction)
1641     llvm::stable_sort(MatchedElements, SortFunction);
1642 
1643   // Check the type of elements required to be printed. 'MatchedElements'
1644   // contains generic elements (lines, scopes, symbols, types). If we have a
1645   // request to print any generic element, then allow the normal printing.
1646   if (options().getPrintAnyElement()) {
1647     if (UseMatchedElements)
1648       OS << "\n";
1649     print(OS);
1650 
1651     if (UseMatchedElements) {
1652       // Print the details for the matched elements.
1653       for (const LVElement *Element : MatchedElements)
1654         Element->print(OS);
1655     } else {
1656       // Print the view for the matched scopes.
1657       for (const LVScope *Scope : MatchedScopes) {
1658         Scope->print(OS);
1659         if (const LVElements *Elements = Scope->getChildren())
1660           for (LVElement *Element : *Elements)
1661             Element->print(OS);
1662       }
1663     }
1664 
1665     // Print any requested summary.
1666     if (options().getPrintSummary()) {
1667       // In the case of '--report=details' the matched elements are
1668       // already counted; just proceed to print any requested summary.
1669       // Otherwise, count them and print the summary.
1670       if (!options().getReportList()) {
1671         for (LVElement *Element : MatchedElements) {
1672           if (!Element->getIncludeInPrint())
1673             continue;
1674           if (Element->getIsType())
1675             ++Found.Types;
1676           else if (Element->getIsSymbol())
1677             ++Found.Symbols;
1678           else if (Element->getIsScope())
1679             ++Found.Scopes;
1680           else if (Element->getIsLine())
1681             ++Found.Lines;
1682           else
1683             assert(Element && "Invalid element.");
1684         }
1685       }
1686       printSummary(OS, Found, "Printed");
1687     }
1688   }
1689 
1690   // Check if we have a request to print sizes for the matched elements
1691   // that are scopes.
1692   if (options().getPrintSizes()) {
1693     OS << "\n";
1694     print(OS);
1695 
1696     OS << "\nScope Sizes:\n";
1697     printScopeSize(this, OS);
1698     for (LVElement *Element : MatchedElements)
1699       if (Element->getIsScope())
1700         // Print sizes only for scopes.
1701         printScopeSize(static_cast<LVScope *>(Element), OS);
1702 
1703     printTotals(OS);
1704   }
1705 }
1706 
print(raw_ostream & OS,bool Full) const1707 void LVScopeCompileUnit::print(raw_ostream &OS, bool Full) const {
1708   // Reset counters for printed and found elements.
1709   const_cast<LVScopeCompileUnit *>(this)->Found.reset();
1710   const_cast<LVScopeCompileUnit *>(this)->Printed.reset();
1711 
1712   if (getReader().doPrintScope(this) && options().getPrintFormatting())
1713     OS << "\n";
1714 
1715   LVScope::print(OS, Full);
1716 }
1717 
printExtra(raw_ostream & OS,bool Full) const1718 void LVScopeCompileUnit::printExtra(raw_ostream &OS, bool Full) const {
1719   OS << formattedKind(kind()) << " '" << getName() << "'\n";
1720   if (options().getPrintFormatting()) {
1721     if (options().getAttributeProducer())
1722       printAttributes(OS, Full, "{Producer} ",
1723                       const_cast<LVScopeCompileUnit *>(this), getProducer(),
1724                       /*UseQuotes=*/true,
1725                       /*PrintRef=*/false);
1726     if (options().getAttributeLanguage())
1727       if (auto SL = getSourceLanguage(); SL.isValid())
1728         printAttributes(OS, Full, "{Language} ",
1729                         const_cast<LVScopeCompileUnit *>(this), SL.getName(),
1730                         /*UseQuotes=*/true,
1731                         /*PrintRef=*/false);
1732   }
1733 
1734   // Reset file index, to allow its children to print the correct filename.
1735   options().resetFilenameIndex();
1736 
1737   // Print any files, directories, public names and active ranges.
1738   if (Full) {
1739     printLocalNames(OS, Full);
1740     printActiveRanges(OS, Full);
1741   }
1742 }
1743 
1744 //===----------------------------------------------------------------------===//
1745 // DWARF enumeration (DW_TAG_enumeration_type).
1746 //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1747 bool LVScopeEnumeration::equals(const LVScope *Scope) const {
1748   if (!LVScope::equals(Scope))
1749     return false;
1750   return equalNumberOfChildren(Scope);
1751 }
1752 
printExtra(raw_ostream & OS,bool Full) const1753 void LVScopeEnumeration::printExtra(raw_ostream &OS, bool Full) const {
1754   // Print the full type name.
1755   OS << formattedKind(kind()) << " " << (getIsEnumClass() ? "class " : "")
1756      << formattedName(getName());
1757   if (getHasType())
1758     OS << " -> " << typeOffsetAsString()
1759        << formattedNames(getTypeQualifiedName(), typeAsString());
1760   OS << "\n";
1761 }
1762 
1763 //===----------------------------------------------------------------------===//
1764 // DWARF formal parameter pack (DW_TAG_GNU_formal_parameter_pack).
1765 //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1766 bool LVScopeFormalPack::equals(const LVScope *Scope) const {
1767   if (!LVScope::equals(Scope))
1768     return false;
1769   return equalNumberOfChildren(Scope);
1770 }
1771 
printExtra(raw_ostream & OS,bool Full) const1772 void LVScopeFormalPack::printExtra(raw_ostream &OS, bool Full) const {
1773   OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
1774 }
1775 
1776 //===----------------------------------------------------------------------===//
1777 // DWARF function.
1778 //===----------------------------------------------------------------------===//
resolveReferences()1779 void LVScopeFunction::resolveReferences() {
1780   // Before we resolve any references to other elements, check if we have
1781   // to insert missing elements, that have been stripped, which will help
1782   // the logical view comparison.
1783   if (options().getAttributeInserted() && getHasReferenceAbstract() &&
1784       !getAddedMissing()) {
1785     // Add missing elements at the function scope.
1786     addMissingElements(getReference());
1787     if (Scopes)
1788       for (LVScope *Scope : *Scopes)
1789         if (Scope->getHasReferenceAbstract() && !Scope->getAddedMissing())
1790           Scope->addMissingElements(Scope->getReference());
1791   }
1792 
1793   LVScope::resolveReferences();
1794 
1795   // The DWARF 'extern' attribute is generated at the class level.
1796   // 0000003f DW_TAG_class_type "CLASS"
1797   //   00000048 DW_TAG_subprogram "bar"
1798   //	            DW_AT_external DW_FORM_flag_present
1799   // 00000070 DW_TAG_subprogram "bar"
1800   //   DW_AT_specification DW_FORM_ref4 0x00000048
1801   // CodeView does not include any information at the class level to
1802   // mark the member function as external.
1803   // If there is a reference linking the declaration and definition, mark
1804   // the definition as extern, to facilitate the logical view comparison.
1805   if (getHasReferenceSpecification()) {
1806     LVScope *Reference = getReference();
1807     if (Reference && Reference->getIsExternal()) {
1808       Reference->resetIsExternal();
1809       setIsExternal();
1810     }
1811   }
1812 
1813   // Resolve the function associated type.
1814   if (!getType())
1815     if (LVScope *Reference = getReference())
1816       setType(Reference->getType());
1817 }
1818 
setName(StringRef ObjectName)1819 void LVScopeFunction::setName(StringRef ObjectName) {
1820   LVScope::setName(ObjectName);
1821   // Check for system generated functions.
1822   getReader().isSystemEntry(this, ObjectName);
1823 }
1824 
resolveExtra()1825 void LVScopeFunction::resolveExtra() {
1826   // Check if we need to encode the template arguments.
1827   if (getIsTemplate())
1828     resolveTemplate();
1829 }
1830 
equals(const LVScope * Scope) const1831 bool LVScopeFunction::equals(const LVScope *Scope) const {
1832   if (!LVScope::equals(Scope))
1833     return false;
1834 
1835   // When comparing logical elements, ignore any difference in the children.
1836   if (options().getCompareContext() && !equalNumberOfChildren(Scope))
1837     return false;
1838 
1839   // Check if the linkage name matches.
1840   if (getLinkageNameIndex() != Scope->getLinkageNameIndex())
1841     return false;
1842 
1843   // Check if the parameters match in the case of templates.
1844   if (!LVType::parametersMatch(getTypes(), Scope->getTypes()))
1845     return false;
1846 
1847   // Check if the arguments match.
1848   if (!LVSymbol::parametersMatch(getSymbols(), Scope->getSymbols()))
1849     return false;
1850 
1851   // Check if the lines match.
1852   if (options().getCompareLines() &&
1853       !LVLine::equals(getLines(), Scope->getLines()))
1854     return false;
1855 
1856   // Check if any reference is the same.
1857   if (!referenceMatch(Scope))
1858     return false;
1859 
1860   if (getReference() && !getReference()->equals(Scope->getReference()))
1861     return false;
1862 
1863   return true;
1864 }
1865 
findEqualScope(const LVScopes * Scopes) const1866 LVScope *LVScopeFunction::findEqualScope(const LVScopes *Scopes) const {
1867   assert(Scopes && "Scopes must not be nullptr");
1868   // Go through candidates and try to find a best match.
1869   for (LVScope *Scope : *Scopes)
1870     // Match arguments, children, lines, references.
1871     if (equals(Scope))
1872       return Scope;
1873   return nullptr;
1874 }
1875 
printExtra(raw_ostream & OS,bool Full) const1876 void LVScopeFunction::printExtra(raw_ostream &OS, bool Full) const {
1877   LVScope *Reference = getReference();
1878 
1879   // Inline attributes based on the reference element.
1880   uint32_t InlineCode =
1881       Reference ? Reference->getInlineCode() : getInlineCode();
1882 
1883   // Accessibility depends on the parent (class, structure).
1884   uint32_t AccessCode = 0;
1885   if (getIsMember())
1886     AccessCode = getParentScope()->getIsClass() ? dwarf::DW_ACCESS_private
1887                                                 : dwarf::DW_ACCESS_public;
1888 
1889   std::string Attributes =
1890       getIsCallSite()
1891           ? ""
1892           : formatAttributes(externalString(), accessibilityString(AccessCode),
1893                              inlineCodeString(InlineCode), virtualityString());
1894 
1895   OS << formattedKind(kind()) << " " << Attributes << formattedName(getName())
1896      << discriminatorAsString() << " -> " << typeOffsetAsString()
1897      << formattedNames(getTypeQualifiedName(), typeAsString()) << "\n";
1898 
1899   // Print any active ranges.
1900   if (Full) {
1901     if (getIsTemplateResolved())
1902       printEncodedArgs(OS, Full);
1903     printActiveRanges(OS, Full);
1904     if (getLinkageNameIndex())
1905       printLinkageName(OS, Full, const_cast<LVScopeFunction *>(this),
1906                        const_cast<LVScopeFunction *>(this));
1907     if (Reference)
1908       Reference->printReference(OS, Full, const_cast<LVScopeFunction *>(this));
1909   }
1910 }
1911 
1912 //===----------------------------------------------------------------------===//
1913 // DWARF inlined function (DW_TAG_inlined_function).
1914 //===----------------------------------------------------------------------===//
resolveExtra()1915 void LVScopeFunctionInlined::resolveExtra() {
1916   // Check if we need to encode the template arguments.
1917   if (getIsTemplate())
1918     resolveTemplate();
1919 }
1920 
equals(const LVScope * Scope) const1921 bool LVScopeFunctionInlined::equals(const LVScope *Scope) const {
1922   if (!LVScopeFunction::equals(Scope))
1923     return false;
1924 
1925   // Check if any reference is the same.
1926   if (getHasDiscriminator() && Scope->getHasDiscriminator())
1927     if (getDiscriminator() != Scope->getDiscriminator())
1928       return false;
1929 
1930   // Check the call site information.
1931   if (getCallFilenameIndex() != Scope->getCallFilenameIndex() ||
1932       getCallLineNumber() != Scope->getCallLineNumber())
1933     return false;
1934 
1935   return true;
1936 }
1937 
findEqualScope(const LVScopes * Scopes) const1938 LVScope *LVScopeFunctionInlined::findEqualScope(const LVScopes *Scopes) const {
1939   return LVScopeFunction::findEqualScope(Scopes);
1940 }
1941 
printExtra(raw_ostream & OS,bool Full) const1942 void LVScopeFunctionInlined::printExtra(raw_ostream &OS, bool Full) const {
1943   LVScopeFunction::printExtra(OS, Full);
1944 }
1945 
1946 //===----------------------------------------------------------------------===//
1947 // DWARF subroutine type.
1948 //===----------------------------------------------------------------------===//
1949 // Resolve a Subroutine Type (Callback).
resolveExtra()1950 void LVScopeFunctionType::resolveExtra() {
1951   if (getIsMemberPointerResolved())
1952     return;
1953   setIsMemberPointerResolved();
1954 
1955   // The encoded string has the return type and the formal parameters type.
1956   std::string Name(typeAsString());
1957   Name.append(" (*)");
1958   Name.append("(");
1959 
1960   // Traverse the scope symbols, looking for those which are parameters.
1961   if (const LVSymbols *Symbols = getSymbols()) {
1962     bool AddComma = false;
1963     for (LVSymbol *Symbol : *Symbols)
1964       if (Symbol->getIsParameter()) {
1965         Symbol->resolve();
1966         if (LVElement *Type = Symbol->getType())
1967           Type->resolveName();
1968         if (AddComma)
1969           Name.append(", ");
1970         Name.append(std::string(Symbol->getTypeName()));
1971         AddComma = true;
1972       }
1973   }
1974 
1975   Name.append(")");
1976 
1977   // Update the scope name, to reflect the encoded parameters.
1978   setName(Name);
1979 }
1980 
1981 //===----------------------------------------------------------------------===//
1982 // DWARF module (DW_TAG_module).
1983 //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1984 bool LVScopeModule::equals(const LVScope *Scope) const {
1985   // For lexical blocks, LVScope::equals() compares the parent scope.
1986   return LVScope::equals(Scope) && (Scope->getName() == getName());
1987 }
1988 
printExtra(raw_ostream & OS,bool Full) const1989 void LVScopeModule::printExtra(raw_ostream &OS, bool Full) const {
1990   OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
1991 }
1992 
1993 //===----------------------------------------------------------------------===//
1994 // DWARF namespace (DW_TAG_namespace).
1995 //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const1996 bool LVScopeNamespace::equals(const LVScope *Scope) const {
1997   if (!LVScope::equals(Scope))
1998     return false;
1999 
2000   if (!equalNumberOfChildren(Scope))
2001     return false;
2002 
2003   // Check if any reference is the same.
2004   if (!referenceMatch(Scope))
2005     return false;
2006 
2007   if (getReference() && !getReference()->equals(Scope->getReference()))
2008     return false;
2009 
2010   return true;
2011 }
2012 
findEqualScope(const LVScopes * Scopes) const2013 LVScope *LVScopeNamespace::findEqualScope(const LVScopes *Scopes) const {
2014   assert(Scopes && "Scopes must not be nullptr");
2015   // Go through candidates and try to find a best match.
2016   for (LVScope *Scope : *Scopes)
2017     if (equals(Scope))
2018       return Scope;
2019   return nullptr;
2020 }
2021 
printExtra(raw_ostream & OS,bool Full) const2022 void LVScopeNamespace::printExtra(raw_ostream &OS, bool Full) const {
2023   OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
2024 
2025   // Print any active ranges.
2026   if (Full) {
2027     printActiveRanges(OS, Full);
2028 
2029     if (LVScope *Reference = getReference())
2030       Reference->printReference(OS, Full, const_cast<LVScopeNamespace *>(this));
2031   }
2032 }
2033 
2034 //===----------------------------------------------------------------------===//
2035 // An object file (single or multiple CUs).
2036 //===----------------------------------------------------------------------===//
processRangeInformation()2037 void LVScopeRoot::processRangeInformation() {
2038   if (!options().getAttributeAnyLocation())
2039     return;
2040 
2041   if (Scopes)
2042     for (LVScope *Scope : *Scopes) {
2043       LVScopeCompileUnit *CompileUnit =
2044           static_cast<LVScopeCompileUnit *>(Scope);
2045       getReader().setCompileUnit(CompileUnit);
2046       CompileUnit->processRangeLocationCoverage();
2047     }
2048 }
2049 
transformScopedName()2050 void LVScopeRoot::transformScopedName() {
2051   // Recursively transform all names.
2052   std::function<void(LVScope * Parent)> TraverseScope = [&](LVScope *Parent) {
2053     auto Traverse = [&](const auto *Set) {
2054       if (Set)
2055         for (const auto &Entry : *Set)
2056           Entry->setInnerComponent();
2057     };
2058     if (const LVScopes *Scopes = Parent->getScopes())
2059       for (LVScope *Scope : *Scopes) {
2060         Scope->setInnerComponent();
2061         TraverseScope(Scope);
2062       }
2063     Traverse(Parent->getSymbols());
2064     Traverse(Parent->getTypes());
2065     Traverse(Parent->getLines());
2066   };
2067 
2068   // Start traversing the scopes root and transform the element name.
2069   TraverseScope(this);
2070 }
2071 
equals(const LVScope * Scope) const2072 bool LVScopeRoot::equals(const LVScope *Scope) const {
2073   return LVScope::equals(Scope);
2074 }
2075 
print(raw_ostream & OS,bool Full) const2076 void LVScopeRoot::print(raw_ostream &OS, bool Full) const {
2077   OS << "\nLogical View:\n";
2078   LVScope::print(OS, Full);
2079 }
2080 
printExtra(raw_ostream & OS,bool Full) const2081 void LVScopeRoot::printExtra(raw_ostream &OS, bool Full) const {
2082   OS << formattedKind(kind()) << " " << formattedName(getName()) << "";
2083   if (options().getAttributeFormat())
2084     OS << " -> " << getFileFormatName();
2085   OS << "\n";
2086 }
2087 
doPrintMatches(bool Split,raw_ostream & OS,bool UseMatchedElements) const2088 Error LVScopeRoot::doPrintMatches(bool Split, raw_ostream &OS,
2089                                   bool UseMatchedElements) const {
2090   // During a view output splitting, use the output stream created by the
2091   // split context, then switch to the reader output stream.
2092   static raw_ostream *StreamSplit = &OS;
2093 
2094   if (Scopes) {
2095     if (UseMatchedElements)
2096       options().resetPrintFormatting();
2097     print(OS);
2098 
2099     for (LVScope *Scope : *Scopes) {
2100       getReader().setCompileUnit(Scope);
2101 
2102       // If 'Split', we use the scope name (CU name) as the ouput file; the
2103       // delimiters in the pathname, must be replaced by a normal character.
2104       if (Split) {
2105         std::string ScopeName(Scope->getName());
2106         if (std::error_code EC =
2107                 getReaderSplitContext().open(ScopeName, ".txt", OS))
2108           return createStringError(EC, "Unable to create split output file %s",
2109                                    ScopeName.c_str());
2110         StreamSplit = static_cast<raw_ostream *>(&getReaderSplitContext().os());
2111       }
2112 
2113       Scope->printMatchedElements(*StreamSplit, UseMatchedElements);
2114 
2115       // Done printing the compile unit. Restore the original output context.
2116       if (Split) {
2117         getReaderSplitContext().close();
2118         StreamSplit = &getReader().outputStream();
2119       }
2120     }
2121     if (UseMatchedElements)
2122       options().setPrintFormatting();
2123   }
2124 
2125   return Error::success();
2126 }
2127 
2128 //===----------------------------------------------------------------------===//
2129 // DWARF template parameter pack (DW_TAG_GNU_template_parameter_pack).
2130 //===----------------------------------------------------------------------===//
equals(const LVScope * Scope) const2131 bool LVScopeTemplatePack::equals(const LVScope *Scope) const {
2132   if (!LVScope::equals(Scope))
2133     return false;
2134   return equalNumberOfChildren(Scope);
2135 }
2136 
printExtra(raw_ostream & OS,bool Full) const2137 void LVScopeTemplatePack::printExtra(raw_ostream &OS, bool Full) const {
2138   OS << formattedKind(kind()) << " " << formattedName(getName()) << "\n";
2139 }
2140