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