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