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