- //===- DebugLinesSubsection.h -----------------------------------*- C++ -*-===// 
- // 
- // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions. 
- // See https://llvm.org/LICENSE.txt for license information. 
- // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception 
- // 
- //===----------------------------------------------------------------------===// 
-   
- #ifndef LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H 
- #define LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H 
-   
- #include "llvm/ADT/StringRef.h" 
- #include "llvm/DebugInfo/CodeView/CodeView.h" 
- #include "llvm/DebugInfo/CodeView/DebugSubsection.h" 
- #include "llvm/DebugInfo/CodeView/Line.h" 
- #include "llvm/Support/BinaryStreamArray.h" 
- #include "llvm/Support/BinaryStreamRef.h" 
- #include "llvm/Support/Endian.h" 
- #include "llvm/Support/Error.h" 
- #include <cstdint> 
- #include <vector> 
-   
- namespace llvm { 
- class BinaryStreamReader; 
- class BinaryStreamWriter; 
- namespace codeview { 
-   
- class DebugChecksumsSubsection; 
- class DebugStringTableSubsection; 
-   
- // Corresponds to the `CV_DebugSLinesHeader_t` structure. 
- struct LineFragmentHeader { 
-   support::ulittle32_t RelocOffset;  // Code offset of line contribution. 
-   support::ulittle16_t RelocSegment; // Code segment of line contribution. 
-   support::ulittle16_t Flags;        // See LineFlags enumeration. 
-   support::ulittle32_t CodeSize;     // Code size of this line contribution. 
- }; 
-   
- // Corresponds to the `CV_DebugSLinesFileBlockHeader_t` structure. 
- struct LineBlockFragmentHeader { 
-   support::ulittle32_t NameIndex; // Offset of FileChecksum entry in File 
-                                   // checksums buffer.  The checksum entry then 
-                                   // contains another offset into the string 
-                                   // table of the actual name. 
-   support::ulittle32_t NumLines;  // Number of lines 
-   support::ulittle32_t BlockSize; // Code size of block, in bytes. 
-   // The following two variable length arrays appear immediately after the 
-   // header.  The structure definitions follow. 
-   // LineNumberEntry   Lines[NumLines]; 
-   // ColumnNumberEntry Columns[NumLines]; 
- }; 
-   
- // Corresponds to `CV_Line_t` structure 
- struct LineNumberEntry { 
-   support::ulittle32_t Offset; // Offset to start of code bytes for line number 
-   support::ulittle32_t Flags;  // Start:24, End:7, IsStatement:1 
- }; 
-   
- // Corresponds to `CV_Column_t` structure 
- struct ColumnNumberEntry { 
-   support::ulittle16_t StartColumn; 
-   support::ulittle16_t EndColumn; 
- }; 
-   
- struct LineColumnEntry { 
-   support::ulittle32_t NameIndex; 
-   FixedStreamArray<LineNumberEntry> LineNumbers; 
-   FixedStreamArray<ColumnNumberEntry> Columns; 
- }; 
-   
- class LineColumnExtractor { 
- public: 
-   Error operator()(BinaryStreamRef Stream, uint32_t &Len, 
-                    LineColumnEntry &Item); 
-   
-   const LineFragmentHeader *Header = nullptr; 
- }; 
-   
- class DebugLinesSubsectionRef final : public DebugSubsectionRef { 
-   friend class LineColumnExtractor; 
-   
-   using LineInfoArray = VarStreamArray<LineColumnEntry, LineColumnExtractor>; 
-   using Iterator = LineInfoArray::Iterator; 
-   
- public: 
-   DebugLinesSubsectionRef(); 
-   
-   static bool classof(const DebugSubsectionRef *S) { 
-     return S->kind() == DebugSubsectionKind::Lines; 
-   } 
-   
-   Error initialize(BinaryStreamReader Reader); 
-   
-   Iterator begin() const { return LinesAndColumns.begin(); } 
-   Iterator end() const { return LinesAndColumns.end(); } 
-   
-   const LineFragmentHeader *header() const { return Header; } 
-   
-   bool hasColumnInfo() const; 
-   
- private: 
-   const LineFragmentHeader *Header = nullptr; 
-   LineInfoArray LinesAndColumns; 
- }; 
-   
- class DebugLinesSubsection final : public DebugSubsection { 
-   struct Block { 
-     Block(uint32_t ChecksumBufferOffset) 
-         : ChecksumBufferOffset(ChecksumBufferOffset) {} 
-   
-     uint32_t ChecksumBufferOffset; 
-     std::vector<LineNumberEntry> Lines; 
-     std::vector<ColumnNumberEntry> Columns; 
-   }; 
-   
- public: 
-   DebugLinesSubsection(DebugChecksumsSubsection &Checksums, 
-                        DebugStringTableSubsection &Strings); 
-   
-   static bool classof(const DebugSubsection *S) { 
-     return S->kind() == DebugSubsectionKind::Lines; 
-   } 
-   
-   void createBlock(StringRef FileName); 
-   void addLineInfo(uint32_t Offset, const LineInfo &Line); 
-   void addLineAndColumnInfo(uint32_t Offset, const LineInfo &Line, 
-                             uint32_t ColStart, uint32_t ColEnd); 
-   
-   uint32_t calculateSerializedSize() const override; 
-   Error commit(BinaryStreamWriter &Writer) const override; 
-   
-   void setRelocationAddress(uint16_t Segment, uint32_t Offset); 
-   void setCodeSize(uint32_t Size); 
-   void setFlags(LineFlags Flags); 
-   
-   bool hasColumnInfo() const; 
-   
- private: 
-   DebugChecksumsSubsection &Checksums; 
-   uint32_t RelocOffset = 0; 
-   uint16_t RelocSegment = 0; 
-   uint32_t CodeSize = 0; 
-   LineFlags Flags = LF_None; 
-   std::vector<Block> Blocks; 
- }; 
-   
- } // end namespace codeview 
- } // end namespace llvm 
-   
- #endif // LLVM_DEBUGINFO_CODEVIEW_DEBUGLINESSUBSECTION_H 
-