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