diff options
Diffstat (limited to 'contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h')
-rw-r--r-- | contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h | 103 |
1 files changed, 103 insertions, 0 deletions
diff --git a/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h new file mode 100644 index 0000000..7c88956 --- /dev/null +++ b/contrib/llvm/include/llvm/DebugInfo/CodeView/CVSymbolVisitor.h @@ -0,0 +1,103 @@ +//===- CVSymbolVisitor.h ----------------------------------------*- C++ -*-===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H +#define LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H + +#include "llvm/DebugInfo/CodeView/CVRecord.h" +#include "llvm/DebugInfo/CodeView/CodeView.h" +#include "llvm/DebugInfo/CodeView/SymbolRecord.h" +#include "llvm/DebugInfo/CodeView/SymbolVisitorDelegate.h" +#include "llvm/Support/ErrorOr.h" + +namespace llvm { +namespace codeview { + +template <typename Derived> class CVSymbolVisitor { +public: + CVSymbolVisitor(SymbolVisitorDelegate *Delegate) : Delegate(Delegate) {} + + bool hadError() const { return HadError; } + + template <typename T> + bool consumeObject(ArrayRef<uint8_t> &Data, const T *&Res) { + if (Data.size() < sizeof(*Res)) { + HadError = true; + return false; + } + Res = reinterpret_cast<const T *>(Data.data()); + Data = Data.drop_front(sizeof(*Res)); + return true; + } + +/// Actions to take on known symbols. By default, they do nothing. Visit methods +/// for member records take the FieldData by non-const reference and are +/// expected to consume the trailing bytes used by the field. +/// FIXME: Make the visitor interpret the trailing bytes so that clients don't +/// need to. +#define SYMBOL_RECORD(EnumName, EnumVal, Name) \ + void visit##Name(SymbolRecordKind Kind, Name &Record) {} +#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) +#include "CVSymbolTypes.def" + + void visitSymbolRecord(const CVRecord<SymbolKind> &Record) { + ArrayRef<uint8_t> Data = Record.Data; + auto *DerivedThis = static_cast<Derived *>(this); + DerivedThis->visitSymbolBegin(Record.Type, Data); + uint32_t RecordOffset = Delegate ? Delegate->getRecordOffset(Data) : 0; + switch (Record.Type) { + default: + DerivedThis->visitUnknownSymbol(Record.Type, Data); + break; +#define SYMBOL_RECORD(EnumName, EnumVal, Name) \ + case EnumName: { \ + SymbolRecordKind RK = static_cast<SymbolRecordKind>(EnumName); \ + auto Result = Name::deserialize(RK, RecordOffset, Data); \ + if (Result.getError()) \ + return parseError(); \ + DerivedThis->visit##Name(Record.Type, *Result); \ + break; \ + } +#define SYMBOL_RECORD_ALIAS(EnumName, EnumVal, Name, AliasName) \ + SYMBOL_RECORD(EnumVal, EnumVal, AliasName) +#include "CVSymbolTypes.def" + } + DerivedThis->visitSymbolEnd(Record.Type, Record.Data); + } + + /// Visits the symbol records in Data. Sets the error flag on parse failures. + void visitSymbolStream(const CVSymbolArray &Symbols) { + for (const auto &I : Symbols) { + visitSymbolRecord(I); + if (hadError()) + break; + } + } + + /// Action to take on unknown symbols. By default, they are ignored. + void visitUnknownSymbol(SymbolKind Kind, ArrayRef<uint8_t> Data) {} + + /// Paired begin/end actions for all symbols. Receives all record data, + /// including the fixed-length record prefix. + void visitSymbolBegin(SymbolKind Leaf, ArrayRef<uint8_t> RecordData) {} + void visitSymbolEnd(SymbolKind Leaf, ArrayRef<uint8_t> OriginalSymData) {} + + /// Helper for returning from a void function when the stream is corrupted. + void parseError() { HadError = true; } + +private: + SymbolVisitorDelegate *Delegate; + /// Whether a symbol stream parsing error was encountered. + bool HadError = false; +}; + +} // end namespace codeview +} // end namespace llvm + +#endif // LLVM_DEBUGINFO_CODEVIEW_CVSYMBOLVISITOR_H |