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