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