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