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