File: CVSymbolVisitor.h

package info (click to toggle)
llvm-toolchain-3.9 1%3A3.9.1-8
  • links: PTS, VCS
  • area: main
  • in suites: stretch
  • size: 441,060 kB
  • ctags: 428,777
  • sloc: cpp: 2,546,577; ansic: 538,318; asm: 119,677; objc: 103,316; python: 102,148; sh: 27,847; pascal: 5,626; ml: 5,510; perl: 5,293; lisp: 4,801; makefile: 2,177; xml: 686; cs: 362; php: 212; csh: 117
file content (103 lines) | stat: -rw-r--r-- 4,033 bytes parent folder | download | duplicates (2)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
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