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