Back to home page

EIC code displayed by LXR

 
 

    


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

0001 //===-- LVCodeViewVisitor.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 LVCodeViewVisitor class, which is used to describe a
0010 // debug information (CodeView) visitor.
0011 //
0012 //===----------------------------------------------------------------------===//
0013 
0014 #ifndef LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWVISITOR_H
0015 #define LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWVISITOR_H
0016 
0017 #include "llvm/ADT/iterator.h"
0018 #include "llvm/DebugInfo/CodeView/SymbolDumpDelegate.h"
0019 #include "llvm/DebugInfo/CodeView/SymbolVisitorCallbacks.h"
0020 #include "llvm/DebugInfo/CodeView/TypeDeserializer.h"
0021 #include "llvm/DebugInfo/CodeView/TypeVisitorCallbacks.h"
0022 #include "llvm/DebugInfo/LogicalView/Readers/LVBinaryReader.h"
0023 #include "llvm/DebugInfo/PDB/Native/InputFile.h"
0024 #include "llvm/Object/Binary.h"
0025 #include "llvm/Object/ObjectFile.h"
0026 #include "llvm/Support/Error.h"
0027 #include <stack>
0028 #include <utility>
0029 
0030 namespace llvm {
0031 namespace logicalview {
0032 
0033 using namespace llvm::codeview;
0034 
0035 class LVCodeViewReader;
0036 class LVLogicalVisitor;
0037 struct LVShared;
0038 
0039 class LVTypeVisitor final : public TypeVisitorCallbacks {
0040   ScopedPrinter &W;
0041   LVLogicalVisitor *LogicalVisitor;
0042   LazyRandomTypeCollection &Types;
0043   LazyRandomTypeCollection &Ids;
0044   uint32_t StreamIdx;
0045   LVShared *Shared = nullptr;
0046 
0047   // In a PDB, a type index may refer to a type (TPI) or an item ID (IPI).
0048   // In a COFF or PDB (/Z7), the type index always refer to a type (TPI).
0049   // When creating logical elements, we must access the correct element
0050   // table, while searching for a type index.
0051   bool HasIds = false;
0052 
0053   // Current type index during the types traversal.
0054   TypeIndex CurrentTypeIndex = TypeIndex::None();
0055 
0056   void printTypeIndex(StringRef FieldName, TypeIndex TI,
0057                       uint32_t StreamIdx) const;
0058 
0059 public:
0060   LVTypeVisitor(ScopedPrinter &W, LVLogicalVisitor *LogicalVisitor,
0061                 LazyRandomTypeCollection &Types, LazyRandomTypeCollection &Ids,
0062                 uint32_t StreamIdx, LVShared *Shared)
0063       : TypeVisitorCallbacks(), W(W), LogicalVisitor(LogicalVisitor),
0064         Types(Types), Ids(Ids), StreamIdx(StreamIdx), Shared(Shared) {
0065     HasIds = &Types != &Ids;
0066   }
0067 
0068   Error visitTypeBegin(CVType &Record) override;
0069   Error visitTypeBegin(CVType &Record, TypeIndex TI) override;
0070   Error visitMemberBegin(CVMemberRecord &Record) override;
0071   Error visitMemberEnd(CVMemberRecord &Record) override;
0072   Error visitUnknownMember(CVMemberRecord &Record) override;
0073 
0074   Error visitKnownRecord(CVType &Record, BuildInfoRecord &Args) override;
0075   Error visitKnownRecord(CVType &Record, ClassRecord &Class) override;
0076   Error visitKnownRecord(CVType &Record, EnumRecord &Enum) override;
0077   Error visitKnownRecord(CVType &Record, FuncIdRecord &Func) override;
0078   Error visitKnownRecord(CVType &Record, ProcedureRecord &Proc) override;
0079   Error visitKnownRecord(CVType &Record, StringIdRecord &String) override;
0080   Error visitKnownRecord(CVType &Record, UdtSourceLineRecord &Line) override;
0081   Error visitKnownRecord(CVType &Record, UnionRecord &Union) override;
0082   Error visitUnknownType(CVType &Record) override;
0083 };
0084 
0085 class LVSymbolVisitorDelegate final : public SymbolVisitorDelegate {
0086   LVCodeViewReader *Reader;
0087   const llvm::object::coff_section *CoffSection;
0088   StringRef SectionContents;
0089 
0090 public:
0091   LVSymbolVisitorDelegate(LVCodeViewReader *Reader,
0092                           const llvm::object::SectionRef &Section,
0093                           const llvm::object::COFFObjectFile *Obj,
0094                           StringRef SectionContents)
0095       : Reader(Reader), SectionContents(SectionContents) {
0096     CoffSection = Obj->getCOFFSection(Section);
0097   }
0098 
0099   uint32_t getRecordOffset(BinaryStreamReader Reader) override {
0100     ArrayRef<uint8_t> Data;
0101     if (Error Err = Reader.readLongestContiguousChunk(Data)) {
0102       llvm::consumeError(std::move(Err));
0103       return 0;
0104     }
0105     return Data.data() - SectionContents.bytes_begin();
0106   }
0107 
0108   void printRelocatedField(StringRef Label, uint32_t RelocOffset,
0109                            uint32_t Offset, StringRef *RelocSym = nullptr);
0110 
0111   void getLinkageName(uint32_t RelocOffset, uint32_t Offset,
0112                       StringRef *RelocSym = nullptr);
0113 
0114   StringRef getFileNameForFileOffset(uint32_t FileOffset) override;
0115   DebugStringTableSubsectionRef getStringTable() override;
0116 };
0117 
0118 class LVElement;
0119 class LVScope;
0120 class LVSymbol;
0121 class LVType;
0122 
0123 // Visitor for CodeView symbol streams found in COFF object files and PDB files.
0124 class LVSymbolVisitor final : public SymbolVisitorCallbacks {
0125   LVCodeViewReader *Reader;
0126   ScopedPrinter &W;
0127   LVLogicalVisitor *LogicalVisitor;
0128   LazyRandomTypeCollection &Types;
0129   LazyRandomTypeCollection &Ids;
0130   LVSymbolVisitorDelegate *ObjDelegate;
0131   LVShared *Shared;
0132 
0133   // Symbol offset when processing PDB streams.
0134   uint32_t CurrentOffset = 0;
0135   // Current object name collected from S_OBJNAME.
0136   StringRef CurrentObjectName;
0137   // Last symbol processed by S_LOCAL.
0138   LVSymbol *LocalSymbol = nullptr;
0139 
0140   bool HasIds;
0141   bool InFunctionScope = false;
0142   bool IsCompileUnit = false;
0143 
0144   // Register for the locals and parameters symbols in the current frame.
0145   RegisterId LocalFrameRegister = RegisterId::NONE;
0146   RegisterId ParamFrameRegister = RegisterId::NONE;
0147 
0148   void printLocalVariableAddrRange(const LocalVariableAddrRange &Range,
0149                                    uint32_t RelocationOffset);
0150   void printLocalVariableAddrGap(ArrayRef<LocalVariableAddrGap> Gaps);
0151   void printTypeIndex(StringRef FieldName, TypeIndex TI) const;
0152 
0153   // Return true if this symbol is a Compile Unit.
0154   bool symbolIsCompileUnit(SymbolKind Kind) {
0155     switch (Kind) {
0156     case SymbolKind::S_COMPILE2:
0157     case SymbolKind::S_COMPILE3:
0158       return true;
0159     default:
0160       return false;
0161     }
0162   }
0163 
0164   // Determine symbol kind (local or parameter).
0165   void determineSymbolKind(LVSymbol *Symbol, RegisterId Register) {
0166     if (Register == LocalFrameRegister) {
0167       Symbol->setIsVariable();
0168       return;
0169     }
0170     if (Register == ParamFrameRegister) {
0171       Symbol->setIsParameter();
0172       return;
0173     }
0174     // Assume is a variable.
0175     Symbol->setIsVariable();
0176   }
0177 
0178 public:
0179   LVSymbolVisitor(LVCodeViewReader *Reader, ScopedPrinter &W,
0180                   LVLogicalVisitor *LogicalVisitor,
0181                   LazyRandomTypeCollection &Types,
0182                   LazyRandomTypeCollection &Ids,
0183                   LVSymbolVisitorDelegate *ObjDelegate, LVShared *Shared)
0184       : Reader(Reader), W(W), LogicalVisitor(LogicalVisitor), Types(Types),
0185         Ids(Ids), ObjDelegate(ObjDelegate), Shared(Shared) {
0186     HasIds = &Types != &Ids;
0187   }
0188 
0189   Error visitSymbolBegin(CVSymbol &Record) override;
0190   Error visitSymbolBegin(CVSymbol &Record, uint32_t Offset) override;
0191   Error visitSymbolEnd(CVSymbol &Record) override;
0192   Error visitUnknownSymbol(CVSymbol &Record) override;
0193 
0194   Error visitKnownRecord(CVSymbol &Record, BlockSym &Block) override;
0195   Error visitKnownRecord(CVSymbol &Record, BPRelativeSym &Local) override;
0196   Error visitKnownRecord(CVSymbol &Record, BuildInfoSym &BuildInfo) override;
0197   Error visitKnownRecord(CVSymbol &Record, Compile2Sym &Compile2) override;
0198   Error visitKnownRecord(CVSymbol &Record, Compile3Sym &Compile3) override;
0199   Error visitKnownRecord(CVSymbol &Record, ConstantSym &Constant) override;
0200   Error visitKnownRecord(CVSymbol &Record, DataSym &Data) override;
0201   Error visitKnownRecord(CVSymbol &Record,
0202                          DefRangeFramePointerRelFullScopeSym
0203                              &DefRangeFramePointerRelFullScope) override;
0204   Error visitKnownRecord(
0205       CVSymbol &Record,
0206       DefRangeFramePointerRelSym &DefRangeFramePointerRel) override;
0207   Error visitKnownRecord(CVSymbol &Record,
0208                          DefRangeRegisterRelSym &DefRangeRegisterRel) override;
0209   Error visitKnownRecord(CVSymbol &Record,
0210                          DefRangeRegisterSym &DefRangeRegister) override;
0211   Error visitKnownRecord(
0212       CVSymbol &Record,
0213       DefRangeSubfieldRegisterSym &DefRangeSubfieldRegister) override;
0214   Error visitKnownRecord(CVSymbol &Record,
0215                          DefRangeSubfieldSym &DefRangeSubfield) override;
0216   Error visitKnownRecord(CVSymbol &Record, DefRangeSym &DefRange) override;
0217   Error visitKnownRecord(CVSymbol &Record, FrameProcSym &FrameProc) override;
0218   Error visitKnownRecord(CVSymbol &Record, InlineSiteSym &InlineSite) override;
0219   Error visitKnownRecord(CVSymbol &Record, LocalSym &Local) override;
0220   Error visitKnownRecord(CVSymbol &Record, ObjNameSym &ObjName) override;
0221   Error visitKnownRecord(CVSymbol &Record, ProcSym &Proc) override;
0222   Error visitKnownRecord(CVSymbol &Record, RegRelativeSym &Local) override;
0223   Error visitKnownRecord(CVSymbol &Record, ScopeEndSym &ScopeEnd) override;
0224   Error visitKnownRecord(CVSymbol &Record, Thunk32Sym &Thunk) override;
0225   Error visitKnownRecord(CVSymbol &Record, UDTSym &UDT) override;
0226   Error visitKnownRecord(CVSymbol &Record, UsingNamespaceSym &UN) override;
0227   Error visitKnownRecord(CVSymbol &Record, JumpTableSym &JumpTable) override;
0228   Error visitKnownRecord(CVSymbol &Record, CallerSym &Caller) override;
0229 };
0230 
0231 // Visitor for CodeView types and symbols to populate elements.
0232 class LVLogicalVisitor final {
0233   LVCodeViewReader *Reader;
0234   ScopedPrinter &W;
0235 
0236   // Encapsulates access to the input file and any dependent type server,
0237   // including any precompiled header object.
0238   llvm::pdb::InputFile &Input;
0239   std::shared_ptr<llvm::pdb::InputFile> TypeServer = nullptr;
0240   std::shared_ptr<LazyRandomTypeCollection> PrecompHeader = nullptr;
0241 
0242   std::shared_ptr<LVShared> Shared;
0243 
0244   // Object files have only one type stream that contains both types and ids.
0245   // Precompiled header objects don't contain an IPI stream. Use the TPI.
0246   LazyRandomTypeCollection &types() {
0247     return TypeServer ? TypeServer->types()
0248                       : (PrecompHeader ? *PrecompHeader : Input.types());
0249   }
0250   LazyRandomTypeCollection &ids() {
0251     return TypeServer ? TypeServer->ids()
0252                       : (PrecompHeader ? *PrecompHeader : Input.ids());
0253   }
0254 
0255   using LVScopeStack = std::stack<LVScope *>;
0256   LVScopeStack ScopeStack;
0257   LVScope *ReaderParent = nullptr;
0258   LVScope *ReaderScope = nullptr;
0259   bool InCompileUnitScope = false;
0260 
0261   // Allow processing of argument list.
0262   bool ProcessArgumentList = false;
0263   StringRef OverloadedMethodName;
0264   std::string CompileUnitName;
0265 
0266   // Inlined functions source information.
0267   using LVInlineeEntry = std::pair<uint32_t, StringRef>;
0268   using LVInlineeInfo = std::map<TypeIndex, LVInlineeEntry>;
0269   LVInlineeInfo InlineeInfo;
0270 
0271   Error visitFieldListMemberStream(TypeIndex TI, LVElement *Element,
0272                                    ArrayRef<uint8_t> FieldList);
0273 
0274   LVType *createBaseType(TypeIndex TI, StringRef TypeName);
0275   LVType *createPointerType(TypeIndex TI, StringRef TypeName);
0276   LVSymbol *createParameter(TypeIndex TI, StringRef Name, LVScope *Parent);
0277   LVSymbol *createParameter(LVElement *Element, StringRef Name,
0278                             LVScope *Parent);
0279   void createDataMember(CVMemberRecord &Record, LVScope *Parent, StringRef Name,
0280                         TypeIndex Type, MemberAccess Access);
0281   void createParents(StringRef ScopedName, LVElement *Element);
0282 
0283 public:
0284   LVLogicalVisitor(LVCodeViewReader *Reader, ScopedPrinter &W,
0285                    llvm::pdb::InputFile &Input);
0286 
0287   // Current elements during the processing of a RecordType or RecordSymbol.
0288   // They are shared with the SymbolVisitor.
0289   LVElement *CurrentElement = nullptr;
0290   LVScope *CurrentScope = nullptr;
0291   LVSymbol *CurrentSymbol = nullptr;
0292   LVType *CurrentType = nullptr;
0293 
0294   // Input source in the case of type server or precompiled header.
0295   void setInput(std::shared_ptr<llvm::pdb::InputFile> TypeServer) {
0296     this->TypeServer = TypeServer;
0297   }
0298   void setInput(std::shared_ptr<LazyRandomTypeCollection> PrecompHeader) {
0299     this->PrecompHeader = PrecompHeader;
0300   }
0301 
0302   void addInlineeInfo(TypeIndex TI, uint32_t LineNumber, StringRef Filename) {
0303     InlineeInfo.emplace(std::piecewise_construct, std::forward_as_tuple(TI),
0304                         std::forward_as_tuple(LineNumber, Filename));
0305   }
0306 
0307   void printTypeIndex(StringRef FieldName, TypeIndex TI, uint32_t StreamIdx);
0308   void printMemberAttributes(MemberAttributes Attrs);
0309   void printMemberAttributes(MemberAccess Access, MethodKind Kind,
0310                              MethodOptions Options);
0311 
0312   LVElement *createElement(TypeLeafKind Kind);
0313   LVElement *createElement(SymbolKind Kind);
0314   LVElement *createElement(TypeIndex TI, TypeLeafKind Kind);
0315 
0316   // Break down the annotation byte code and calculate code and line offsets.
0317   Error inlineSiteAnnotation(LVScope *AbstractFunction,
0318                              LVScope *InlinedFunction,
0319                              InlineSiteSym &InlineSite);
0320 
0321   void pushScope(LVScope *Scope) {
0322     ScopeStack.push(ReaderParent);
0323     ReaderParent = ReaderScope;
0324     ReaderScope = Scope;
0325   }
0326   void popScope() {
0327     ReaderScope = ReaderParent;
0328     ReaderParent = ScopeStack.top();
0329     ScopeStack.pop();
0330   }
0331   void closeScope() {
0332     if (InCompileUnitScope) {
0333       InCompileUnitScope = false;
0334       popScope();
0335     }
0336   }
0337   void setRoot(LVScope *Root) { ReaderScope = Root; }
0338 
0339   void addElement(LVScope *Scope, bool IsCompileUnit);
0340   void addElement(LVSymbol *Symbol);
0341   void addElement(LVType *Type);
0342 
0343   std::string getCompileUnitName() { return CompileUnitName; }
0344   void setCompileUnitName(std::string Name) {
0345     CompileUnitName = std::move(Name);
0346   }
0347 
0348   LVElement *getElement(uint32_t StreamIdx, TypeIndex TI,
0349                         LVScope *Parent = nullptr);
0350   LVShared *getShared() { return Shared.get(); }
0351 
0352   LVScope *getReaderScope() const { return ReaderScope; }
0353 
0354   void printTypeBegin(CVType &Record, TypeIndex TI, LVElement *Element,
0355                       uint32_t StreamIdx);
0356   void printTypeEnd(CVType &Record);
0357   void printMemberBegin(CVMemberRecord &Record, TypeIndex TI,
0358                         LVElement *Element, uint32_t StreamIdx);
0359   void printMemberEnd(CVMemberRecord &Record);
0360 
0361   void startProcessArgumentList() { ProcessArgumentList = true; }
0362   void stopProcessArgumentList() { ProcessArgumentList = false; }
0363 
0364   void processFiles();
0365   void processLines();
0366   void processNamespaces();
0367 
0368   void printRecords(raw_ostream &OS) const;
0369 
0370   Error visitUnknownType(CVType &Record, TypeIndex TI);
0371   Error visitKnownRecord(CVType &Record, ArgListRecord &Args, TypeIndex TI,
0372                          LVElement *Element);
0373   Error visitKnownRecord(CVType &Record, ArrayRecord &AT, TypeIndex TI,
0374                          LVElement *Element);
0375   Error visitKnownRecord(CVType &Record, BitFieldRecord &BF, TypeIndex TI,
0376                          LVElement *Element);
0377   Error visitKnownRecord(CVType &Record, BuildInfoRecord &BI, TypeIndex TI,
0378                          LVElement *Element);
0379   Error visitKnownRecord(CVType &Record, ClassRecord &Class, TypeIndex TI,
0380                          LVElement *Element);
0381   Error visitKnownRecord(CVType &Record, EnumRecord &Enum, TypeIndex TI,
0382                          LVElement *Element);
0383   Error visitKnownRecord(CVType &Record, FieldListRecord &FieldList,
0384                          TypeIndex TI, LVElement *Element);
0385   Error visitKnownRecord(CVType &Record, FuncIdRecord &Func, TypeIndex TI,
0386                          LVElement *Element);
0387   Error visitKnownRecord(CVType &Record, LabelRecord &LR, TypeIndex TI,
0388                          LVElement *Element);
0389   Error visitKnownRecord(CVType &Record, ModifierRecord &Mod, TypeIndex TI,
0390                          LVElement *Element);
0391   Error visitKnownRecord(CVType &Record, MemberFuncIdRecord &Id, TypeIndex TI,
0392                          LVElement *Element);
0393   Error visitKnownRecord(CVType &Record, MemberFunctionRecord &MF, TypeIndex TI,
0394                          LVElement *Element);
0395   Error visitKnownRecord(CVType &Record, MethodOverloadListRecord &Overloads,
0396                          TypeIndex TI, LVElement *Element);
0397   Error visitKnownRecord(CVType &Record, PointerRecord &Ptr, TypeIndex TI,
0398                          LVElement *Element);
0399   Error visitKnownRecord(CVType &Record, ProcedureRecord &Proc, TypeIndex TI,
0400                          LVElement *Element);
0401   Error visitKnownRecord(CVType &Record, UnionRecord &Union, TypeIndex TI,
0402                          LVElement *Element);
0403   Error visitKnownRecord(CVType &Record, TypeServer2Record &TS, TypeIndex TI,
0404                          LVElement *Element);
0405   Error visitKnownRecord(CVType &Record, VFTableRecord &VFT, TypeIndex TI,
0406                          LVElement *Element);
0407   Error visitKnownRecord(CVType &Record, VFTableShapeRecord &Shape,
0408                          TypeIndex TI, LVElement *Element);
0409   Error visitKnownRecord(CVType &Record, StringListRecord &Strings,
0410                          TypeIndex TI, LVElement *Element);
0411   Error visitKnownRecord(CVType &Record, StringIdRecord &String, TypeIndex TI,
0412                          LVElement *Element);
0413   Error visitKnownRecord(CVType &Record, UdtSourceLineRecord &SourceLine,
0414                          TypeIndex TI, LVElement *Element);
0415   Error visitKnownRecord(CVType &Record, UdtModSourceLineRecord &ModSourceLine,
0416                          TypeIndex TI, LVElement *Element);
0417   Error visitKnownRecord(CVType &Record, PrecompRecord &Precomp, TypeIndex TI,
0418                          LVElement *Element);
0419   Error visitKnownRecord(CVType &Record, EndPrecompRecord &EndPrecomp,
0420                          TypeIndex TI, LVElement *Element);
0421 
0422   Error visitUnknownMember(CVMemberRecord &Record, TypeIndex TI);
0423   Error visitKnownMember(CVMemberRecord &Record, BaseClassRecord &Base,
0424                          TypeIndex TI, LVElement *Element);
0425   Error visitKnownMember(CVMemberRecord &Record, DataMemberRecord &Field,
0426                          TypeIndex TI, LVElement *Element);
0427   Error visitKnownMember(CVMemberRecord &Record, EnumeratorRecord &Enum,
0428                          TypeIndex TI, LVElement *Element);
0429   Error visitKnownMember(CVMemberRecord &Record, ListContinuationRecord &Cont,
0430                          TypeIndex TI, LVElement *Element);
0431   Error visitKnownMember(CVMemberRecord &Record, NestedTypeRecord &Nested,
0432                          TypeIndex TI, LVElement *Element);
0433   Error visitKnownMember(CVMemberRecord &Record, OneMethodRecord &Method,
0434                          TypeIndex TI, LVElement *Element);
0435   Error visitKnownMember(CVMemberRecord &Record, OverloadedMethodRecord &Method,
0436                          TypeIndex TI, LVElement *Element);
0437   Error visitKnownMember(CVMemberRecord &Record, StaticDataMemberRecord &Field,
0438                          TypeIndex TI, LVElement *Element);
0439   Error visitKnownMember(CVMemberRecord &Record, VFPtrRecord &VFTable,
0440                          TypeIndex TI, LVElement *Element);
0441   Error visitKnownMember(CVMemberRecord &Record, VirtualBaseClassRecord &Base,
0442                          TypeIndex TI, LVElement *Element);
0443 
0444   template <typename T>
0445   Error visitKnownMember(CVMemberRecord &Record,
0446                          TypeVisitorCallbacks &Callbacks, TypeIndex TI,
0447                          LVElement *Element) {
0448     TypeRecordKind RK = static_cast<TypeRecordKind>(Record.Kind);
0449     T KnownRecord(RK);
0450     if (Error Err = Callbacks.visitKnownMember(Record, KnownRecord))
0451       return Err;
0452     if (Error Err = visitKnownMember(Record, KnownRecord, TI, Element))
0453       return Err;
0454     return Error::success();
0455   }
0456 
0457   template <typename T>
0458   Error visitKnownRecord(CVType &Record, TypeIndex TI, LVElement *Element) {
0459     TypeRecordKind RK = static_cast<TypeRecordKind>(Record.kind());
0460     T KnownRecord(RK);
0461     if (Error Err = TypeDeserializer::deserializeAs(
0462             const_cast<CVType &>(Record), KnownRecord))
0463       return Err;
0464     if (Error Err = visitKnownRecord(Record, KnownRecord, TI, Element))
0465       return Err;
0466     return Error::success();
0467   }
0468 
0469   Error visitMemberRecord(CVMemberRecord &Record,
0470                           TypeVisitorCallbacks &Callbacks, TypeIndex TI,
0471                           LVElement *Element);
0472   Error finishVisitation(CVType &Record, TypeIndex TI, LVElement *Element);
0473 };
0474 
0475 } // namespace logicalview
0476 } // namespace llvm
0477 
0478 #endif // LLVM_DEBUGINFO_LOGICALVIEW_READERS_CODEVIEWVISITOR_H