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