1 //===-- LVScope.h -----------------------------------------------*- C++ -*-===// 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 file defines the LVScope class, which is used to describe a debug 10 // information scope. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H 15 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H 16 17 #include "llvm/DebugInfo/LogicalView/Core/LVElement.h" 18 #include "llvm/DebugInfo/LogicalView/Core/LVLocation.h" 19 #include "llvm/DebugInfo/LogicalView/Core/LVSort.h" 20 #include "llvm/Object/ObjectFile.h" 21 #include <list> 22 #include <map> 23 #include <set> 24 25 namespace llvm { 26 namespace logicalview { 27 28 // Name address, Code size. 29 using LVNameInfo = std::pair<LVAddress, uint64_t>; 30 using LVPublicNames = std::map<LVScope *, LVNameInfo>; 31 using LVPublicAddresses = std::map<LVAddress, LVNameInfo>; 32 33 class LVRange; 34 35 enum class LVScopeKind { 36 IsAggregate, 37 IsArray, 38 IsBlock, 39 IsCallSite, 40 IsCatchBlock, 41 IsClass, 42 IsCompileUnit, 43 IsEntryPoint, 44 IsEnumeration, 45 IsFunction, 46 IsFunctionType, 47 IsInlinedFunction, 48 IsLabel, 49 IsLexicalBlock, 50 IsMember, 51 IsNamespace, 52 IsRoot, 53 IsStructure, 54 IsSubprogram, 55 IsTemplate, 56 IsTemplateAlias, 57 IsTemplatePack, 58 IsTryBlock, 59 IsUnion, 60 LastEntry 61 }; 62 using LVScopeKindSet = std::set<LVScopeKind>; 63 using LVScopeDispatch = std::map<LVScopeKind, LVScopeGetFunction>; 64 using LVScopeRequest = std::vector<LVScopeGetFunction>; 65 66 using LVOffsetList = std::list<LVOffset>; 67 using LVOffsetElementMap = std::map<LVOffset, LVElement *>; 68 using LVOffsetLinesMap = std::map<LVOffset, LVLines *>; 69 using LVOffsetLocationsMap = std::map<LVOffset, LVLocations *>; 70 using LVOffsetSymbolMap = std::map<LVOffset, LVSymbol *>; 71 using LVTagOffsetsMap = std::map<dwarf::Tag, LVOffsetList *>; 72 73 // Class to represent a DWARF Scope. 74 class LVScope : public LVElement { 75 enum class Property { 76 HasDiscriminator, 77 CanHaveRanges, 78 CanHaveLines, 79 HasGlobals, 80 HasLocals, 81 HasLines, 82 HasScopes, 83 HasSymbols, 84 HasTypes, 85 IsComdat, 86 HasComdatScopes, // Compile Unit has comdat functions. 87 HasRanges, 88 AddedMissing, // Added missing referenced symbols. 89 LastEntry 90 }; 91 92 // Typed bitvector with kinds and properties for this scope. 93 LVProperties<LVScopeKind> Kinds; 94 LVProperties<Property> Properties; 95 static LVScopeDispatch Dispatch; 96 97 // Coverage factor in units (bytes). 98 unsigned CoverageFactor = 0; 99 100 // Calculate coverage factor. 101 void calculateCoverage() { 102 float CoveragePercentage = 0; 103 LVLocation::calculateCoverage(Ranges, CoverageFactor, CoveragePercentage); 104 } 105 106 // Decide if the scope will be printed, using some conditions given by: 107 // only-globals, only-locals, a-pattern. 108 bool resolvePrinting() const; 109 110 // Find the current scope in the given 'Targets'. 111 LVScope *findIn(const LVScopes *Targets) const; 112 113 // Traverse the scope parent tree, executing the given callback function 114 // on each scope. 115 void traverseParents(LVScopeGetFunction GetFunction, 116 LVScopeSetFunction SetFunction); 117 118 protected: 119 // Types, Symbols, Scopes, Lines, Locations in this scope. 120 LVAutoTypes *Types = nullptr; 121 LVAutoSymbols *Symbols = nullptr; 122 LVAutoScopes *Scopes = nullptr; 123 LVAutoLines *Lines = nullptr; 124 LVAutoLocations *Ranges = nullptr; 125 126 // Vector of elements (types, scopes and symbols). 127 // It is the union of (*Types, *Symbols and *Scopes) to be used for 128 // the following reasons: 129 // - Preserve the order the logical elements are read in. 130 // - To have a single container with all the logical elements, when 131 // the traversal does not require any specific element kind. 132 LVElements *Children = nullptr; 133 134 // Resolve the template parameters/arguments relationship. 135 void resolveTemplate(); 136 void printEncodedArgs(raw_ostream &OS, bool Full) const; 137 138 void printActiveRanges(raw_ostream &OS, bool Full = true) const; 139 virtual void printSizes(raw_ostream &OS) const {} 140 virtual void printSummary(raw_ostream &OS) const {} 141 142 // Encoded template arguments. 143 virtual StringRef getEncodedArgs() const { return StringRef(); } 144 virtual void setEncodedArgs(StringRef EncodedArgs) {} 145 146 public: 147 LVScope() : LVElement(LVSubclassID::LV_SCOPE) { 148 setIsScope(); 149 setIncludeInPrint(); 150 } 151 LVScope(const LVScope &) = delete; 152 LVScope &operator=(const LVScope &) = delete; 153 virtual ~LVScope(); 154 155 static bool classof(const LVElement *Element) { 156 return Element->getSubclassID() == LVSubclassID::LV_SCOPE; 157 } 158 159 KIND(LVScopeKind, IsAggregate); 160 KIND(LVScopeKind, IsArray); 161 KIND_2(LVScopeKind, IsBlock, CanHaveRanges, CanHaveLines); 162 KIND_1(LVScopeKind, IsCallSite, IsFunction); 163 KIND_1(LVScopeKind, IsCatchBlock, IsBlock); 164 KIND_1(LVScopeKind, IsClass, IsAggregate); 165 KIND_3(LVScopeKind, IsCompileUnit, CanHaveRanges, CanHaveLines, 166 TransformName); 167 KIND_1(LVScopeKind, IsEntryPoint, IsFunction); 168 KIND(LVScopeKind, IsEnumeration); 169 KIND_2(LVScopeKind, IsFunction, CanHaveRanges, CanHaveLines); 170 KIND_1(LVScopeKind, IsFunctionType, IsFunction); 171 KIND_2(LVScopeKind, IsInlinedFunction, IsFunction, IsInlined); 172 KIND_1(LVScopeKind, IsLabel, IsFunction); 173 KIND_1(LVScopeKind, IsLexicalBlock, IsBlock); 174 KIND(LVScopeKind, IsMember); 175 KIND(LVScopeKind, IsNamespace); 176 KIND_1(LVScopeKind, IsRoot, TransformName); 177 KIND_1(LVScopeKind, IsStructure, IsAggregate); 178 KIND_1(LVScopeKind, IsSubprogram, IsFunction); 179 KIND(LVScopeKind, IsTemplate); 180 KIND(LVScopeKind, IsTemplateAlias); 181 KIND(LVScopeKind, IsTemplatePack); 182 KIND_1(LVScopeKind, IsTryBlock, IsBlock); 183 KIND_1(LVScopeKind, IsUnion, IsAggregate); 184 185 PROPERTY(Property, HasDiscriminator); 186 PROPERTY(Property, CanHaveRanges); 187 PROPERTY(Property, CanHaveLines); 188 PROPERTY(Property, HasGlobals); 189 PROPERTY(Property, HasLocals); 190 PROPERTY(Property, HasLines); 191 PROPERTY(Property, HasScopes); 192 PROPERTY(Property, HasSymbols); 193 PROPERTY(Property, HasTypes); 194 PROPERTY(Property, IsComdat); 195 PROPERTY(Property, HasComdatScopes); 196 PROPERTY(Property, HasRanges); 197 PROPERTY(Property, AddedMissing); 198 199 bool isCompileUnit() const override { return getIsCompileUnit(); } 200 bool isRoot() const override { return getIsRoot(); } 201 202 const char *kind() const override; 203 204 // Get the specific children. 205 const LVLines *getLines() const { return Lines; } 206 const LVLocations *getRanges() const { return Ranges; } 207 const LVScopes *getScopes() const { return Scopes; } 208 const LVSymbols *getSymbols() const { return Symbols; } 209 const LVTypes *getTypes() const { return Types; } 210 const LVElements *getChildren() const { return Children; } 211 212 void addElement(LVElement *Element); 213 void addElement(LVLine *Line); 214 void addElement(LVScope *Scope); 215 void addElement(LVSymbol *Symbol); 216 void addElement(LVType *Type); 217 void addObject(LVLocation *Location); 218 void addObject(LVAddress LowerAddress, LVAddress UpperAddress); 219 void addToChildren(LVElement *Element); 220 221 // Add the missing elements from the given 'Reference', which is the 222 // scope associated with any DW_AT_specification, DW_AT_abstract_origin. 223 void addMissingElements(LVScope *Reference); 224 225 // Traverse the scope parent tree and the children, executing the given 226 // callback function on each element. 227 void traverseParentsAndChildren(LVObjectGetFunction GetFunction, 228 LVObjectSetFunction SetFunction); 229 230 // Get the size of specific children. 231 size_t lineCount() const { return Lines ? Lines->size() : 0; } 232 size_t rangeCount() const { return Ranges ? Ranges->size() : 0; } 233 size_t scopeCount() const { return Scopes ? Scopes->size() : 0; } 234 size_t symbolCount() const { return Symbols ? Symbols->size() : 0; } 235 size_t typeCount() const { return Types ? Types->size() : 0; } 236 237 // Find containing parent for the given address. 238 LVScope *outermostParent(LVAddress Address); 239 240 // Get all the locations associated with symbols. 241 void getLocations(LVLocations &LocationList, LVValidLocation ValidLocation, 242 bool RecordInvalid = false); 243 void getRanges(LVLocations &LocationList, LVValidLocation ValidLocation, 244 bool RecordInvalid = false); 245 void getRanges(LVRange &RangeList); 246 247 unsigned getCoverageFactor() const { return CoverageFactor; } 248 249 Error doPrint(bool Split, bool Match, bool Print, raw_ostream &OS, 250 bool Full = true) const override; 251 // Sort the logical elements using the criteria specified by the 252 // command line option '--output-sort'. 253 void sort(); 254 255 // Get template parameter types. 256 bool getTemplateParameterTypes(LVTypes &Params); 257 258 // DW_AT_specification, DW_AT_abstract_origin, DW_AT_extension. 259 virtual LVScope *getReference() const { return nullptr; } 260 261 LVScope *getCompileUnitParent() const override { 262 return LVElement::getCompileUnitParent(); 263 } 264 265 // Follow a chain of references given by DW_AT_abstract_origin and/or 266 // DW_AT_specification and update the scope name. 267 StringRef resolveReferencesChain(); 268 269 bool removeElement(LVElement *Element) override; 270 void updateLevel(LVScope *Parent, bool Moved) override; 271 272 void resolve() override; 273 void resolveName() override; 274 void resolveReferences() override; 275 276 // Return the chain of parents as a string. 277 void getQualifiedName(std::string &QualifiedName) const; 278 // Encode the template arguments. 279 void encodeTemplateArguments(std::string &Name) const; 280 void encodeTemplateArguments(std::string &Name, const LVTypes *Types) const; 281 282 void resolveElements(); 283 284 // Iterate through the 'References' set and check that all its elements 285 // are present in the 'Targets' set. For a missing element, mark its 286 // parents as missing. 287 static void markMissingParents(const LVScopes *References, 288 const LVScopes *Targets, 289 bool TraverseChildren); 290 291 // Checks if the current scope is contained within the target scope. 292 // Depending on the result, the callback may be performed. 293 virtual void markMissingParents(const LVScope *Target, bool TraverseChildren); 294 295 // Returns true if the current scope and the given 'Scope' have the 296 // same number of children. 297 virtual bool equalNumberOfChildren(const LVScope *Scope) const; 298 299 // Returns true if current scope is logically equal to the given 'Scope'. 300 virtual bool equals(const LVScope *Scope) const; 301 302 // Returns true if the given 'References' are logically equal to the 303 // given 'Targets'. 304 static bool equals(const LVScopes *References, const LVScopes *Targets); 305 306 // For the given 'Scopes' returns a scope that is logically equal 307 // to the current scope; otherwise 'nullptr'. 308 virtual LVScope *findEqualScope(const LVScopes *Scopes) const; 309 310 // Report the current scope as missing or added during comparison. 311 void report(LVComparePass Pass) override; 312 313 static LVScopeDispatch &getDispatch() { return Dispatch; } 314 315 void print(raw_ostream &OS, bool Full = true) const override; 316 void printExtra(raw_ostream &OS, bool Full = true) const override; 317 virtual void printWarnings(raw_ostream &OS, bool Full = true) const {} 318 virtual void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) {} 319 320 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) 321 void dump() const override { print(dbgs()); } 322 #endif 323 }; 324 325 // Class to represent a DWARF Union/Structure/Class. 326 class LVScopeAggregate final : public LVScope { 327 LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin. 328 size_t EncodedArgsIndex = 0; // Template encoded arguments. 329 330 public: 331 LVScopeAggregate() : LVScope() {} 332 LVScopeAggregate(const LVScopeAggregate &) = delete; 333 LVScopeAggregate &operator=(const LVScopeAggregate &) = delete; 334 ~LVScopeAggregate() = default; 335 336 // DW_AT_specification, DW_AT_abstract_origin. 337 LVScope *getReference() const override { return Reference; } 338 void setReference(LVScope *Scope) override { 339 Reference = Scope; 340 setHasReference(); 341 } 342 void setReference(LVElement *Element) override { 343 setReference(static_cast<LVScope *>(Element)); 344 } 345 346 StringRef getEncodedArgs() const override { 347 return getStringPool().getString(EncodedArgsIndex); 348 } 349 void setEncodedArgs(StringRef EncodedArgs) override { 350 EncodedArgsIndex = getStringPool().getIndex(EncodedArgs); 351 } 352 353 // Returns true if current scope is logically equal to the given 'Scope'. 354 bool equals(const LVScope *Scope) const override; 355 356 // For the given 'Scopes' returns a scope that is logically equal 357 // to the current scope; otherwise 'nullptr'. 358 LVScope *findEqualScope(const LVScopes *Scopes) const override; 359 360 void printExtra(raw_ostream &OS, bool Full = true) const override; 361 }; 362 363 // Class to represent a DWARF Template alias. 364 class LVScopeAlias final : public LVScope { 365 public: 366 LVScopeAlias() : LVScope() { 367 setIsTemplateAlias(); 368 setIsTemplate(); 369 } 370 LVScopeAlias(const LVScopeAlias &) = delete; 371 LVScopeAlias &operator=(const LVScopeAlias &) = delete; 372 ~LVScopeAlias() = default; 373 374 // Returns true if current scope is logically equal to the given 'Scope'. 375 bool equals(const LVScope *Scope) const override; 376 377 void printExtra(raw_ostream &OS, bool Full = true) const override; 378 }; 379 380 // Class to represent a DWARF array (DW_TAG_array_type). 381 class LVScopeArray final : public LVScope { 382 public: 383 LVScopeArray() : LVScope() { setIsArray(); } 384 LVScopeArray(const LVScopeArray &) = delete; 385 LVScopeArray &operator=(const LVScopeArray &) = delete; 386 ~LVScopeArray() = default; 387 388 void resolveExtra() override; 389 390 // Returns true if current scope is logically equal to the given 'Scope'. 391 bool equals(const LVScope *Scope) const override; 392 393 void printExtra(raw_ostream &OS, bool Full = true) const override; 394 }; 395 396 // Class to represent a DWARF Compilation Unit (CU). 397 class LVScopeCompileUnit final : public LVScope { 398 // Names (files and directories) used by the Compile Unit. 399 std::vector<size_t> Filenames; 400 401 // As the .debug_pubnames section has been removed in DWARF5, we have a 402 // similar functionality, which is used by the decoded functions. We use 403 // the low-pc and high-pc for those scopes that are marked as public, in 404 // order to support DWARF and CodeView. 405 LVPublicNames PublicNames; 406 407 // Toolchain producer. 408 size_t ProducerIndex = 0; 409 410 // Compilation directory name. 411 size_t CompilationDirectoryIndex = 0; 412 413 // Keep record of elements. They are needed at the compilation unit level 414 // to print the summary at the end of the printing. 415 LVCounter Allocated; 416 LVCounter Found; 417 LVCounter Printed; 418 419 // Elements that match a given command line pattern. 420 LVElements MatchedElements; 421 LVScopes MatchedScopes; 422 423 // It records the mapping between logical lines representing a debug line 424 // entry and its address in the text section. It is used to find a line 425 // giving its exact or closest address. To support comdat functions, all 426 // addresses for the same section are recorded in the same map. 427 using LVAddressToLine = std::map<LVAddress, LVLine *>; 428 LVDoubleMap<LVSectionIndex, LVAddress, LVLine *> SectionMappings; 429 430 // DWARF Tags (Tag, Element list). 431 LVTagOffsetsMap DebugTags; 432 433 // Offsets associated with objects being flagged as having invalid data 434 // (ranges, locations, lines zero or coverages). 435 LVOffsetElementMap WarningOffsets; 436 437 // Symbols with invalid locations. (Symbol, Location List). 438 LVOffsetLocationsMap InvalidLocations; 439 440 // Symbols with invalid coverage values. 441 LVOffsetSymbolMap InvalidCoverages; 442 443 // Scopes with invalid ranges (Scope, Range list). 444 LVOffsetLocationsMap InvalidRanges; 445 446 // Scopes with lines zero (Scope, Line list). 447 LVOffsetLinesMap LinesZero; 448 449 // Record scopes contribution in bytes to the debug information. 450 using LVSizesMap = std::map<const LVScope *, LVOffset>; 451 LVSizesMap Sizes; 452 LVOffset CUContributionSize = 0; 453 454 // Helper function to add an invalid location/range. 455 void addInvalidLocationOrRange(LVLocation *Location, LVElement *Element, 456 LVOffsetLocationsMap *Map) { 457 LVOffset Offset = Element->getOffset(); 458 addInvalidOffset(Offset, Element); 459 addItem<LVOffsetLocationsMap, LVLocations, LVOffset, LVLocation *>( 460 Map, Offset, Location); 461 } 462 463 // Record scope sizes indexed by lexical level. 464 // Setting an initial size that will cover a very deep nested scopes. 465 const size_t TotalInitialSize = 8; 466 using LVTotalsEntry = std::pair<unsigned, float>; 467 SmallVector<LVTotalsEntry> Totals; 468 // Maximum seen lexical level. It is used to control how many entries 469 // in the 'Totals' vector are valid values. 470 LVLevel MaxSeenLevel = 0; 471 472 // Get the line located at the given address. 473 LVLine *lineLowerBound(LVAddress Address, LVScope *Scope) const; 474 LVLine *lineUpperBound(LVAddress Address, LVScope *Scope) const; 475 476 void printScopeSize(const LVScope *Scope, raw_ostream &OS); 477 void printScopeSize(const LVScope *Scope, raw_ostream &OS) const { 478 (const_cast<LVScopeCompileUnit *>(this))->printScopeSize(Scope, OS); 479 } 480 void printTotals(raw_ostream &OS) const; 481 482 protected: 483 void printSizes(raw_ostream &OS) const override; 484 void printSummary(raw_ostream &OS) const override; 485 486 public: 487 LVScopeCompileUnit() : LVScope(), Totals(TotalInitialSize, {0, 0.0}) { 488 setIsCompileUnit(); 489 } 490 LVScopeCompileUnit(const LVScopeCompileUnit &) = delete; 491 LVScopeCompileUnit &operator=(const LVScopeCompileUnit &) = delete; 492 ~LVScopeCompileUnit() { 493 deleteList<LVTagOffsetsMap>(DebugTags); 494 deleteList<LVOffsetLocationsMap>(InvalidLocations); 495 deleteList<LVOffsetLocationsMap>(InvalidRanges); 496 deleteList<LVOffsetLinesMap>(LinesZero); 497 } 498 499 LVScope *getCompileUnitParent() const override { 500 return static_cast<LVScope *>(const_cast<LVScopeCompileUnit *>(this)); 501 } 502 503 // Add line to address mapping. 504 void addMapping(LVLine *Line, LVSectionIndex SectionIndex); 505 LVLineRange lineRange(LVLocation *Location) const; 506 507 LVNameInfo NameNone = {UINT64_MAX, 0}; 508 void addPublicName(LVScope *Scope, LVAddress LowPC, LVAddress HighPC) { 509 PublicNames.emplace(std::piecewise_construct, std::forward_as_tuple(Scope), 510 std::forward_as_tuple(LowPC, HighPC - LowPC)); 511 } 512 const LVNameInfo &findPublicName(LVScope *Scope) { 513 LVPublicNames::iterator Iter = PublicNames.find(Scope); 514 return (Iter != PublicNames.end()) ? Iter->second : NameNone; 515 } 516 const LVPublicNames &getPublicNames() const { return PublicNames; } 517 518 // The base address of the scope for any of the debugging information 519 // entries listed, is given by either the DW_AT_low_pc attribute or the 520 // first address in the first range entry in the list of ranges given by 521 // the DW_AT_ranges attribute. 522 LVAddress getBaseAddress() const { 523 return Ranges ? Ranges->front()->getLowerAddress() : 0; 524 } 525 526 StringRef getCompilationDirectory() const { 527 return getStringPool().getString(CompilationDirectoryIndex); 528 } 529 void setCompilationDirectory(StringRef CompilationDirectory) { 530 CompilationDirectoryIndex = getStringPool().getIndex(CompilationDirectory); 531 } 532 533 StringRef getFilename(size_t Index) const; 534 void addFilename(StringRef Name) { 535 Filenames.push_back(getStringPool().getIndex(Name)); 536 } 537 538 StringRef getProducer() const override { 539 return getStringPool().getString(ProducerIndex); 540 } 541 void setProducer(StringRef ProducerName) override { 542 ProducerIndex = getStringPool().getIndex(ProducerName); 543 } 544 545 // Record DWARF tags. 546 void addDebugTag(dwarf::Tag Target, LVOffset Offset); 547 // Record elements with invalid offsets. 548 void addInvalidOffset(LVOffset Offset, LVElement *Element); 549 // Record symbols with invalid coverage values. 550 void addInvalidCoverage(LVSymbol *Symbol); 551 // Record symbols with invalid locations. 552 void addInvalidLocation(LVLocation *Location); 553 // Record scopes with invalid ranges. 554 void addInvalidRange(LVLocation *Location); 555 // Record line zero. 556 void addLineZero(LVLine *Line); 557 558 const LVTagOffsetsMap &getDebugTags() const { return DebugTags; } 559 const LVOffsetElementMap &getWarningOffsets() const { return WarningOffsets; } 560 const LVOffsetLocationsMap &getInvalidLocations() const { 561 return InvalidLocations; 562 } 563 const LVOffsetSymbolMap &getInvalidCoverages() const { 564 return InvalidCoverages; 565 } 566 const LVOffsetLocationsMap &getInvalidRanges() const { return InvalidRanges; } 567 const LVOffsetLinesMap &getLinesZero() const { return LinesZero; } 568 569 // Process ranges, locations and calculate coverage. 570 void processRangeLocationCoverage( 571 LVValidLocation ValidLocation = &LVLocation::validateRanges); 572 573 // Add matched element. 574 void addMatched(LVElement *Element) { MatchedElements.push_back(Element); } 575 void addMatched(LVScope *Scope) { MatchedScopes.push_back(Scope); } 576 void propagatePatternMatch(); 577 578 const LVElements &getMatchedElements() const { return MatchedElements; } 579 const LVScopes &getMatchedScopes() const { return MatchedScopes; } 580 581 void printLocalNames(raw_ostream &OS, bool Full = true) const; 582 void printSummary(raw_ostream &OS, const LVCounter &Counter, 583 const char *Header) const; 584 585 void incrementPrintedLines(); 586 void incrementPrintedScopes(); 587 void incrementPrintedSymbols(); 588 void incrementPrintedTypes(); 589 590 // Values are used by '--summary' option (allocated). 591 void increment(LVLine *Line); 592 void increment(LVScope *Scope); 593 void increment(LVSymbol *Symbol); 594 void increment(LVType *Type); 595 596 // A new element has been added to the scopes tree. Take the following steps: 597 // Increase the added element counters, for printing summary. 598 // During comparison notify the Reader of the new element. 599 void addedElement(LVLine *Line); 600 void addedElement(LVScope *Scope); 601 void addedElement(LVSymbol *Symbol); 602 void addedElement(LVType *Type); 603 604 void addSize(LVScope *Scope, LVOffset Lower, LVOffset Upper); 605 606 // Returns true if current scope is logically equal to the given 'Scope'. 607 bool equals(const LVScope *Scope) const override; 608 609 void print(raw_ostream &OS, bool Full = true) const override; 610 void printExtra(raw_ostream &OS, bool Full = true) const override; 611 void printWarnings(raw_ostream &OS, bool Full = true) const override; 612 void printMatchedElements(raw_ostream &OS, bool UseMatchedElements) override; 613 }; 614 615 // Class to represent a DWARF enumerator (DW_TAG_enumeration_type). 616 class LVScopeEnumeration final : public LVScope { 617 public: 618 LVScopeEnumeration() : LVScope() { setIsEnumeration(); } 619 LVScopeEnumeration(const LVScopeEnumeration &) = delete; 620 LVScopeEnumeration &operator=(const LVScopeEnumeration &) = delete; 621 ~LVScopeEnumeration() = default; 622 623 // Returns true if current scope is logically equal to the given 'Scope'. 624 bool equals(const LVScope *Scope) const override; 625 626 void printExtra(raw_ostream &OS, bool Full = true) const override; 627 }; 628 629 // Class to represent a DWARF formal parameter pack 630 // (DW_TAG_GNU_formal_parameter_pack). 631 class LVScopeFormalPack final : public LVScope { 632 public: 633 LVScopeFormalPack() : LVScope() { setIsTemplatePack(); } 634 LVScopeFormalPack(const LVScopeFormalPack &) = delete; 635 LVScopeFormalPack &operator=(const LVScopeFormalPack &) = delete; 636 ~LVScopeFormalPack() = default; 637 638 // Returns true if current scope is logically equal to the given 'Scope'. 639 bool equals(const LVScope *Scope) const override; 640 641 void printExtra(raw_ostream &OS, bool Full = true) const override; 642 }; 643 644 // Class to represent a DWARF Function. 645 class LVScopeFunction : public LVScope { 646 LVScope *Reference = nullptr; // DW_AT_specification, DW_AT_abstract_origin. 647 size_t LinkageNameIndex = 0; // Function DW_AT_linkage_name attribute. 648 size_t EncodedArgsIndex = 0; // Template encoded arguments. 649 650 public: 651 LVScopeFunction() : LVScope() {} 652 LVScopeFunction(const LVScopeFunction &) = delete; 653 LVScopeFunction &operator=(const LVScopeFunction &) = delete; 654 virtual ~LVScopeFunction() = default; 655 656 // DW_AT_specification, DW_AT_abstract_origin. 657 LVScope *getReference() const override { return Reference; } 658 void setReference(LVScope *Scope) override { 659 Reference = Scope; 660 setHasReference(); 661 } 662 void setReference(LVElement *Element) override { 663 setReference(static_cast<LVScope *>(Element)); 664 } 665 666 StringRef getEncodedArgs() const override { 667 return getStringPool().getString(EncodedArgsIndex); 668 } 669 void setEncodedArgs(StringRef EncodedArgs) override { 670 EncodedArgsIndex = getStringPool().getIndex(EncodedArgs); 671 } 672 673 void setLinkageName(StringRef LinkageName) override { 674 LinkageNameIndex = getStringPool().getIndex(LinkageName); 675 } 676 StringRef getLinkageName() const override { 677 return getStringPool().getString(LinkageNameIndex); 678 } 679 size_t getLinkageNameIndex() const override { return LinkageNameIndex; } 680 681 void setName(StringRef ObjectName) override; 682 683 void resolveExtra() override; 684 void resolveReferences() override; 685 686 // Returns true if current scope is logically equal to the given 'Scope'. 687 bool equals(const LVScope *Scope) const override; 688 689 // For the given 'Scopes' returns a scope that is logically equal 690 // to the current scope; otherwise 'nullptr'. 691 LVScope *findEqualScope(const LVScopes *Scopes) const override; 692 693 void printExtra(raw_ostream &OS, bool Full = true) const override; 694 }; 695 696 // Class to represent a DWARF inlined function. 697 class LVScopeFunctionInlined final : public LVScopeFunction { 698 size_t CallFilenameIndex = 0; 699 uint32_t CallLineNumber = 0; 700 uint32_t Discriminator = 0; 701 702 public: 703 LVScopeFunctionInlined() : LVScopeFunction() { setIsInlinedFunction(); } 704 LVScopeFunctionInlined(const LVScopeFunctionInlined &) = delete; 705 LVScopeFunctionInlined &operator=(const LVScopeFunctionInlined &) = delete; 706 ~LVScopeFunctionInlined() = default; 707 708 uint32_t getDiscriminator() const override { return Discriminator; } 709 void setDiscriminator(uint32_t Value) override { 710 Discriminator = Value; 711 setHasDiscriminator(); 712 } 713 714 uint32_t getCallLineNumber() const override { return CallLineNumber; } 715 void setCallLineNumber(uint32_t Number) override { CallLineNumber = Number; } 716 size_t getCallFilenameIndex() const override { return CallFilenameIndex; } 717 void setCallFilenameIndex(size_t Index) override { 718 CallFilenameIndex = Index; 719 } 720 721 // Line number for display; in the case of Inlined Functions, we use the 722 // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute. 723 std::string lineNumberAsString(bool ShowZero = false) const override { 724 return lineAsString(getCallLineNumber(), getDiscriminator(), ShowZero); 725 } 726 727 void resolveExtra() override; 728 729 // Returns true if current scope is logically equal to the given 'Scope'. 730 bool equals(const LVScope *Scope) const override; 731 732 // For the given 'Scopes' returns a scope that is logically equal 733 // to the current scope; otherwise 'nullptr'. 734 LVScope *findEqualScope(const LVScopes *Scopes) const override; 735 736 void printExtra(raw_ostream &OS, bool Full = true) const override; 737 }; 738 739 // Class to represent a DWARF subroutine type. 740 class LVScopeFunctionType final : public LVScopeFunction { 741 public: 742 LVScopeFunctionType() : LVScopeFunction() { setIsFunctionType(); } 743 LVScopeFunctionType(const LVScopeFunctionType &) = delete; 744 LVScopeFunctionType &operator=(const LVScopeFunctionType &) = delete; 745 ~LVScopeFunctionType() = default; 746 747 void resolveExtra() override; 748 }; 749 750 // Class to represent a DWARF Namespace. 751 class LVScopeNamespace final : public LVScope { 752 LVScope *Reference = nullptr; // Reference to DW_AT_extension attribute. 753 754 public: 755 LVScopeNamespace() : LVScope() { setIsNamespace(); } 756 LVScopeNamespace(const LVScopeNamespace &) = delete; 757 LVScopeNamespace &operator=(const LVScopeNamespace &) = delete; 758 ~LVScopeNamespace() = default; 759 760 // Access DW_AT_extension reference. 761 LVScope *getReference() const override { return Reference; } 762 void setReference(LVScope *Scope) override { 763 Reference = Scope; 764 setHasReference(); 765 } 766 void setReference(LVElement *Element) override { 767 setReference(static_cast<LVScope *>(Element)); 768 } 769 770 // Returns true if current scope is logically equal to the given 'Scope'. 771 bool equals(const LVScope *Scope) const override; 772 773 // For the given 'Scopes' returns a scope that is logically equal 774 // to the current scope; otherwise 'nullptr'. 775 LVScope *findEqualScope(const LVScopes *Scopes) const override; 776 777 void printExtra(raw_ostream &OS, bool Full = true) const override; 778 }; 779 780 // Class to represent the binary file being analyzed. 781 class LVScopeRoot final : public LVScope { 782 size_t FileFormatNameIndex = 0; 783 784 public: 785 LVScopeRoot() : LVScope() { setIsRoot(); } 786 LVScopeRoot(const LVScopeRoot &) = delete; 787 LVScopeRoot &operator=(const LVScopeRoot &) = delete; 788 ~LVScopeRoot() = default; 789 790 StringRef getFileFormatName() const { 791 return getStringPool().getString(FileFormatNameIndex); 792 } 793 void setFileFormatName(StringRef FileFormatName) { 794 FileFormatNameIndex = getStringPool().getIndex(FileFormatName); 795 } 796 797 // Process the collected location, ranges and calculate coverage. 798 void processRangeInformation(); 799 800 // Returns true if current scope is logically equal to the given 'Scope'. 801 bool equals(const LVScope *Scope) const override; 802 803 void print(raw_ostream &OS, bool Full = true) const override; 804 void printExtra(raw_ostream &OS, bool Full = true) const override; 805 Error doPrintMatches(bool Split, raw_ostream &OS, 806 bool UseMatchedElements) const; 807 }; 808 809 // Class to represent a DWARF template parameter pack 810 // (DW_TAG_GNU_template_parameter_pack). 811 class LVScopeTemplatePack final : public LVScope { 812 public: 813 LVScopeTemplatePack() : LVScope() { setIsTemplatePack(); } 814 LVScopeTemplatePack(const LVScopeTemplatePack &) = delete; 815 LVScopeTemplatePack &operator=(const LVScopeTemplatePack &) = delete; 816 ~LVScopeTemplatePack() = default; 817 818 // Returns true if current scope is logically equal to the given 'Scope'. 819 bool equals(const LVScope *Scope) const override; 820 821 void printExtra(raw_ostream &OS, bool Full = true) const override; 822 }; 823 824 } // end namespace logicalview 825 } // end namespace llvm 826 827 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVSCOPE_H 828