1 //===-- LVLine.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 LVLine class, which is used to describe a debug 10 // information line. 11 // 12 //===----------------------------------------------------------------------===// 13 14 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLINE_H 15 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLINE_H 16 17 #include "llvm/DebugInfo/LogicalView/Core/LVElement.h" 18 19 namespace llvm { 20 namespace logicalview { 21 22 enum class LVLineKind { 23 IsBasicBlock, 24 IsDiscriminator, 25 IsEndSequence, 26 IsEpilogueBegin, 27 IsLineDebug, 28 IsLineAssembler, 29 IsNewStatement, // Shared with CodeView 'IsStatement' flag. 30 IsPrologueEnd, 31 IsAlwaysStepInto, // CodeView 32 IsNeverStepInto, // CodeView 33 LastEntry 34 }; 35 using LVLineKindSet = std::set<LVLineKind>; 36 using LVLineDispatch = std::map<LVLineKind, LVLineGetFunction>; 37 using LVLineRequest = std::vector<LVLineGetFunction>; 38 39 // Class to represent a logical line. 40 class LVLine : public LVElement { 41 // Typed bitvector with kinds for this line. 42 LVProperties<LVLineKind> Kinds; 43 static LVLineDispatch Dispatch; 44 45 // Find the current line in the given 'Targets'. 46 LVLine *findIn(const LVLines *Targets) const; 47 48 public: LVLine()49 LVLine() : LVElement(LVSubclassID::LV_LINE) { 50 setIsLine(); 51 setIncludeInPrint(); 52 } 53 LVLine(const LVLine &) = delete; 54 LVLine &operator=(const LVLine &) = delete; 55 virtual ~LVLine() = default; 56 classof(const LVElement * Element)57 static bool classof(const LVElement *Element) { 58 return Element->getSubclassID() == LVSubclassID::LV_LINE; 59 } 60 61 KIND(LVLineKind, IsBasicBlock); 62 KIND(LVLineKind, IsDiscriminator); 63 KIND(LVLineKind, IsEndSequence); 64 KIND(LVLineKind, IsEpilogueBegin); 65 KIND(LVLineKind, IsLineDebug); 66 KIND(LVLineKind, IsLineAssembler); 67 KIND(LVLineKind, IsNewStatement); 68 KIND(LVLineKind, IsPrologueEnd); 69 KIND(LVLineKind, IsAlwaysStepInto); 70 KIND(LVLineKind, IsNeverStepInto); 71 72 const char *kind() const override; 73 74 // Use the offset to store the line address. getAddress()75 uint64_t getAddress() const { return getOffset(); } setAddress(uint64_t address)76 void setAddress(uint64_t address) { setOffset(address); } 77 78 // String used for printing objects with no line number. 79 std::string noLineAsString(bool ShowZero = false) const override; 80 81 // Line number for display; in the case of Inlined Functions, we use the 82 // DW_AT_call_line attribute; otherwise use DW_AT_decl_line attribute. 83 std::string lineNumberAsString(bool ShowZero = false) const override { 84 return lineAsString(getLineNumber(), getDiscriminator(), ShowZero); 85 } 86 getDispatch()87 static LVLineDispatch &getDispatch() { return Dispatch; } 88 89 // Iterate through the 'References' set and check that all its elements 90 // are present in the 'Targets' set. For a missing element, mark its 91 // parents as missing. 92 static void markMissingParents(const LVLines *References, 93 const LVLines *Targets); 94 95 // Returns true if current line is logically equal to the given 'Line'. 96 virtual bool equals(const LVLine *Line) const; 97 98 // Returns true if the given 'References' are logically equal to the 99 // given 'Targets'. 100 static bool equals(const LVLines *References, const LVLines *Targets); 101 102 // Report the current line as missing or added during comparison. 103 void report(LVComparePass Pass) override; 104 105 void print(raw_ostream &OS, bool Full = true) const override; 106 void printExtra(raw_ostream &OS, bool Full = true) const override {} 107 108 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP) dump()109 void dump() const override { print(dbgs()); } 110 #endif 111 }; 112 113 // Class to represent a DWARF line record object. 114 class LVLineDebug final : public LVLine { 115 // Discriminator value (DW_LNE_set_discriminator). The DWARF standard 116 // defines the discriminator as an unsigned LEB128 integer. 117 uint32_t Discriminator = 0; 118 119 public: LVLineDebug()120 LVLineDebug() : LVLine() { setIsLineDebug(); } 121 LVLineDebug(const LVLineDebug &) = delete; 122 LVLineDebug &operator=(const LVLineDebug &) = delete; 123 ~LVLineDebug() = default; 124 125 // Additional line information. It includes attributes that describes 126 // states in the machine instructions (basic block, end prologue, etc). 127 std::string statesInfo(bool Formatted) const; 128 129 // Access DW_LNE_set_discriminator attribute. getDiscriminator()130 uint32_t getDiscriminator() const override { return Discriminator; } setDiscriminator(uint32_t Value)131 void setDiscriminator(uint32_t Value) override { 132 Discriminator = Value; 133 setIsDiscriminator(); 134 } 135 136 // Returns true if current line is logically equal to the given 'Line'. 137 bool equals(const LVLine *Line) const override; 138 139 void printExtra(raw_ostream &OS, bool Full = true) const override; 140 }; 141 142 // Class to represent an assembler line extracted from the text section. 143 class LVLineAssembler final : public LVLine { 144 public: LVLineAssembler()145 LVLineAssembler() : LVLine() { setIsLineAssembler(); } 146 LVLineAssembler(const LVLineAssembler &) = delete; 147 LVLineAssembler &operator=(const LVLineAssembler &) = delete; 148 ~LVLineAssembler() = default; 149 150 // Print blanks as the line number. noLineAsString(bool ShowZero)151 std::string noLineAsString(bool ShowZero) const override { 152 return std::string(8, ' '); 153 }; 154 155 // Returns true if current line is logically equal to the given 'Line'. 156 bool equals(const LVLine *Line) const override; 157 158 void printExtra(raw_ostream &OS, bool Full = true) const override; 159 }; 160 161 } // end namespace logicalview 162 } // end namespace llvm 163 164 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVLINE_H 165