Back to home page

EIC code displayed by LXR

 
 

    


File indexing completed on 2026-05-10 08:43:43

0001 //===-- LVReader.h ----------------------------------------------*- C++ -*-===//
0002 //
0003 // Part of the LLVM Project, under the Apache License v2.0 with LLVM Exceptions.
0004 // See https://llvm.org/LICENSE.txt for license information.
0005 // SPDX-License-Identifier: Apache-2.0 WITH LLVM-exception
0006 //
0007 //===----------------------------------------------------------------------===//
0008 //
0009 // This file defines the LVReader class, which is used to describe a debug
0010 // information reader.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVREADER_H
0015 #define LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVREADER_H
0016 
0017 #include "llvm/DebugInfo/LogicalView/Core/LVOptions.h"
0018 #include "llvm/DebugInfo/LogicalView/Core/LVRange.h"
0019 #include "llvm/Support/Errc.h"
0020 #include "llvm/Support/Error.h"
0021 #include "llvm/Support/ScopedPrinter.h"
0022 #include "llvm/Support/ToolOutputFile.h"
0023 #include <map>
0024 
0025 namespace llvm {
0026 namespace logicalview {
0027 
0028 constexpr LVSectionIndex UndefinedSectionIndex = 0;
0029 
0030 class LVScopeCompileUnit;
0031 class LVObject;
0032 
0033 class LVSplitContext final {
0034   std::unique_ptr<ToolOutputFile> OutputFile;
0035   std::string Location;
0036 
0037 public:
0038   LVSplitContext() = default;
0039   LVSplitContext(const LVSplitContext &) = delete;
0040   LVSplitContext &operator=(const LVSplitContext &) = delete;
0041   ~LVSplitContext() = default;
0042 
0043   Error createSplitFolder(StringRef Where);
0044   std::error_code open(std::string Name, std::string Extension,
0045                        raw_ostream &OS);
0046   void close() {
0047     if (OutputFile) {
0048       OutputFile->os().close();
0049       OutputFile = nullptr;
0050     }
0051   }
0052 
0053   std::string getLocation() const { return Location; }
0054   raw_fd_ostream &os() { return OutputFile->os(); }
0055 };
0056 
0057 /// The logical reader owns of all the logical elements created during
0058 /// the debug information parsing. For its creation it uses a specific
0059 ///  bump allocator for each type of logical element.
0060 class LVReader {
0061   LVBinaryType BinaryType;
0062 
0063   // Context used by '--output=split' command line option.
0064   LVSplitContext SplitContext;
0065 
0066   // Compile Units DIE Offset => Scope.
0067   using LVCompileUnits = std::map<LVOffset, LVScopeCompileUnit *>;
0068   LVCompileUnits CompileUnits;
0069 
0070   // Added elements to be used during elements comparison.
0071   LVLines Lines;
0072   LVScopes Scopes;
0073   LVSymbols Symbols;
0074   LVTypes Types;
0075 
0076   // Create split folder.
0077   Error createSplitFolder();
0078   bool OutputSplit = false;
0079 
0080 // Define a specific bump allocator for the given KIND.
0081 #define LV_OBJECT_ALLOCATOR(KIND)                                              \
0082   llvm::SpecificBumpPtrAllocator<LV##KIND> Allocated##KIND;
0083 
0084   // Lines allocator.
0085   LV_OBJECT_ALLOCATOR(Line)
0086   LV_OBJECT_ALLOCATOR(LineDebug)
0087   LV_OBJECT_ALLOCATOR(LineAssembler)
0088 
0089   // Locations allocator.
0090   LV_OBJECT_ALLOCATOR(Location)
0091   LV_OBJECT_ALLOCATOR(LocationSymbol)
0092 
0093   // Operations allocator.
0094   LV_OBJECT_ALLOCATOR(Operation)
0095 
0096   // Scopes allocator.
0097   LV_OBJECT_ALLOCATOR(Scope)
0098   LV_OBJECT_ALLOCATOR(ScopeAggregate)
0099   LV_OBJECT_ALLOCATOR(ScopeAlias)
0100   LV_OBJECT_ALLOCATOR(ScopeArray)
0101   LV_OBJECT_ALLOCATOR(ScopeCompileUnit)
0102   LV_OBJECT_ALLOCATOR(ScopeEnumeration)
0103   LV_OBJECT_ALLOCATOR(ScopeFormalPack)
0104   LV_OBJECT_ALLOCATOR(ScopeFunction)
0105   LV_OBJECT_ALLOCATOR(ScopeFunctionInlined)
0106   LV_OBJECT_ALLOCATOR(ScopeFunctionType)
0107   LV_OBJECT_ALLOCATOR(ScopeNamespace)
0108   LV_OBJECT_ALLOCATOR(ScopeRoot)
0109   LV_OBJECT_ALLOCATOR(ScopeTemplatePack)
0110 
0111   // Symbols allocator.
0112   LV_OBJECT_ALLOCATOR(Symbol)
0113 
0114   // Types allocator.
0115   LV_OBJECT_ALLOCATOR(Type)
0116   LV_OBJECT_ALLOCATOR(TypeDefinition)
0117   LV_OBJECT_ALLOCATOR(TypeEnumerator)
0118   LV_OBJECT_ALLOCATOR(TypeImport)
0119   LV_OBJECT_ALLOCATOR(TypeParam)
0120   LV_OBJECT_ALLOCATOR(TypeSubrange)
0121 
0122 #undef LV_OBJECT_ALLOCATOR
0123 
0124 protected:
0125   LVScopeRoot *Root = nullptr;
0126   std::string InputFilename;
0127   std::string FileFormatName;
0128   ScopedPrinter &W;
0129   raw_ostream &OS;
0130   LVScopeCompileUnit *CompileUnit = nullptr;
0131 
0132   // Only for ELF format. The CodeView is handled in a different way.
0133   LVSectionIndex DotTextSectionIndex = UndefinedSectionIndex;
0134 
0135   // Record Compilation Unit entry.
0136   void addCompileUnitOffset(LVOffset Offset, LVScopeCompileUnit *CompileUnit) {
0137     CompileUnits.emplace(Offset, CompileUnit);
0138   }
0139 
0140   // Create the Scope Root.
0141   virtual Error createScopes() {
0142     Root = createScopeRoot();
0143     Root->setName(getFilename());
0144     if (options().getAttributeFormat())
0145       Root->setFileFormatName(FileFormatName);
0146     return Error::success();
0147   }
0148 
0149   // Return a pathname composed by: parent_path(InputFilename)/filename(From).
0150   // This is useful when a type server (PDB file associated with an object
0151   // file or a precompiled header file) or a DWARF split object have been
0152   // moved from their original location. That is the case when running
0153   // regression tests, where object files are created in one location and
0154   // executed in a different location.
0155   std::string createAlternativePath(StringRef From) {
0156     // During the reader initialization, any backslashes in 'InputFilename'
0157     // are converted to forward slashes.
0158     SmallString<128> Path;
0159     sys::path::append(Path, sys::path::Style::posix,
0160                       sys::path::parent_path(InputFilename),
0161                       sys::path::filename(sys::path::convert_to_slash(
0162                           From, sys::path::Style::windows)));
0163     return std::string(Path);
0164   }
0165 
0166   virtual Error printScopes();
0167   virtual Error printMatchedElements(bool UseMatchedElements);
0168   virtual void sortScopes() {}
0169 
0170 public:
0171   LVReader() = delete;
0172   LVReader(StringRef InputFilename, StringRef FileFormatName, ScopedPrinter &W,
0173            LVBinaryType BinaryType = LVBinaryType::NONE)
0174       : BinaryType(BinaryType), OutputSplit(options().getOutputSplit()),
0175         InputFilename(InputFilename), FileFormatName(FileFormatName), W(W),
0176         OS(W.getOStream()) {}
0177   LVReader(const LVReader &) = delete;
0178   LVReader &operator=(const LVReader &) = delete;
0179   virtual ~LVReader() = default;
0180 
0181 // Creates a logical object of the given KIND. The signature for the created
0182 // functions looks like:
0183 //   ...
0184 //   LVScope *createScope()
0185 //   LVScopeRoot *creatScopeRoot()
0186 //   LVType *createType();
0187 //   ...
0188 #define LV_CREATE_OBJECT(KIND)                                                 \
0189   LV##KIND *create##KIND() {                                                   \
0190     return new (Allocated##KIND.Allocate()) LV##KIND();                        \
0191   }
0192 
0193   // Lines creation.
0194   LV_CREATE_OBJECT(Line)
0195   LV_CREATE_OBJECT(LineDebug)
0196   LV_CREATE_OBJECT(LineAssembler)
0197 
0198   // Locations creation.
0199   LV_CREATE_OBJECT(Location)
0200   LV_CREATE_OBJECT(LocationSymbol)
0201 
0202   // Scopes creation.
0203   LV_CREATE_OBJECT(Scope)
0204   LV_CREATE_OBJECT(ScopeAggregate)
0205   LV_CREATE_OBJECT(ScopeAlias)
0206   LV_CREATE_OBJECT(ScopeArray)
0207   LV_CREATE_OBJECT(ScopeCompileUnit)
0208   LV_CREATE_OBJECT(ScopeEnumeration)
0209   LV_CREATE_OBJECT(ScopeFormalPack)
0210   LV_CREATE_OBJECT(ScopeFunction)
0211   LV_CREATE_OBJECT(ScopeFunctionInlined)
0212   LV_CREATE_OBJECT(ScopeFunctionType)
0213   LV_CREATE_OBJECT(ScopeNamespace)
0214   LV_CREATE_OBJECT(ScopeRoot)
0215   LV_CREATE_OBJECT(ScopeTemplatePack)
0216 
0217   // Symbols creation.
0218   LV_CREATE_OBJECT(Symbol)
0219 
0220   // Types creation.
0221   LV_CREATE_OBJECT(Type)
0222   LV_CREATE_OBJECT(TypeDefinition)
0223   LV_CREATE_OBJECT(TypeEnumerator)
0224   LV_CREATE_OBJECT(TypeImport)
0225   LV_CREATE_OBJECT(TypeParam)
0226   LV_CREATE_OBJECT(TypeSubrange)
0227 
0228 #undef LV_CREATE_OBJECT
0229 
0230   // Operations creation.
0231   LVOperation *createOperation(LVSmall OpCode, ArrayRef<LVUnsigned> Operands) {
0232     return new (AllocatedOperation.Allocate()) LVOperation(OpCode, Operands);
0233   }
0234 
0235   StringRef getFilename(LVObject *Object, size_t Index) const;
0236   StringRef getFilename() const { return InputFilename; }
0237   void setFilename(std::string Name) { InputFilename = std::move(Name); }
0238   StringRef getFileFormatName() const { return FileFormatName; }
0239 
0240   raw_ostream &outputStream() { return OS; }
0241 
0242   bool isBinaryTypeNone() const { return BinaryType == LVBinaryType::NONE; }
0243   bool isBinaryTypeELF() const { return BinaryType == LVBinaryType::ELF; }
0244   bool isBinaryTypeCOFF() const { return BinaryType == LVBinaryType::COFF; }
0245 
0246   LVScopeCompileUnit *getCompileUnit() const { return CompileUnit; }
0247   void setCompileUnit(LVScope *Scope) {
0248     assert(Scope && Scope->isCompileUnit() && "Scope is not a compile unit");
0249     CompileUnit = static_cast<LVScopeCompileUnit *>(Scope);
0250   }
0251   void setCompileUnitCPUType(codeview::CPUType Type) {
0252     CompileUnit->setCPUType(Type);
0253   }
0254   codeview::CPUType getCompileUnitCPUType() {
0255     return CompileUnit->getCPUType();
0256   }
0257 
0258   // Access to the scopes root.
0259   LVScopeRoot *getScopesRoot() const { return Root; }
0260 
0261   Error doPrint();
0262   Error doLoad();
0263 
0264   virtual std::string getRegisterName(LVSmall Opcode,
0265                                       ArrayRef<uint64_t> Operands) {
0266     llvm_unreachable("Invalid instance reader.");
0267     return {};
0268   }
0269 
0270   LVSectionIndex getDotTextSectionIndex() const { return DotTextSectionIndex; }
0271   virtual LVSectionIndex getSectionIndex(LVScope *Scope) {
0272     return getDotTextSectionIndex();
0273   }
0274 
0275   virtual bool isSystemEntry(LVElement *Element, StringRef Name = {}) const {
0276     return false;
0277   };
0278 
0279   // Access to split context.
0280   LVSplitContext &getSplitContext() { return SplitContext; }
0281 
0282   // In the case of element comparison, register that added element.
0283   void notifyAddedElement(LVLine *Line) {
0284     if (!options().getCompareContext() && options().getCompareLines())
0285       Lines.push_back(Line);
0286   }
0287   void notifyAddedElement(LVScope *Scope) {
0288     if (!options().getCompareContext() && options().getCompareScopes())
0289       Scopes.push_back(Scope);
0290   }
0291   void notifyAddedElement(LVSymbol *Symbol) {
0292     if (!options().getCompareContext() && options().getCompareSymbols())
0293       Symbols.push_back(Symbol);
0294   }
0295   void notifyAddedElement(LVType *Type) {
0296     if (!options().getCompareContext() && options().getCompareTypes())
0297       Types.push_back(Type);
0298   }
0299 
0300   const LVLines &getLines() const { return Lines; }
0301   const LVScopes &getScopes() const { return Scopes; }
0302   const LVSymbols &getSymbols() const { return Symbols; }
0303   const LVTypes &getTypes() const { return Types; }
0304 
0305   // Conditions to print an object.
0306   bool doPrintLine(const LVLine *Line) const {
0307     return patterns().printElement(Line);
0308   }
0309   bool doPrintLocation(const LVLocation *Location) const {
0310     return patterns().printObject(Location);
0311   }
0312   bool doPrintScope(const LVScope *Scope) const {
0313     return patterns().printElement(Scope);
0314   }
0315   bool doPrintSymbol(const LVSymbol *Symbol) const {
0316     return patterns().printElement(Symbol);
0317   }
0318   bool doPrintType(const LVType *Type) const {
0319     return patterns().printElement(Type);
0320   }
0321 
0322   static LVReader &getInstance();
0323   static void setInstance(LVReader *Reader);
0324 
0325   void print(raw_ostream &OS) const;
0326   virtual void printRecords(raw_ostream &OS) const {}
0327 
0328 #if !defined(NDEBUG) || defined(LLVM_ENABLE_DUMP)
0329   void dump() const { print(dbgs()); }
0330 #endif
0331 };
0332 
0333 inline LVReader &getReader() { return LVReader::getInstance(); }
0334 inline LVSplitContext &getReaderSplitContext() {
0335   return getReader().getSplitContext();
0336 }
0337 inline LVScopeCompileUnit *getReaderCompileUnit() {
0338   return getReader().getCompileUnit();
0339 }
0340 
0341 } // end namespace logicalview
0342 } // end namespace llvm
0343 
0344 #endif // LLVM_DEBUGINFO_LOGICALVIEW_CORE_LVREADER_H