1 //===- NativeSymbolEnumerator.cpp - info about enumerators ------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 
10 #include "llvm/DebugInfo/PDB/Native/NativeSymbolEnumerator.h"
11 
12 #include "llvm/DebugInfo/CodeView/SymbolRecord.h"
13 #include "llvm/DebugInfo/PDB/Native/NativeTypeBuiltin.h"
14 #include "llvm/DebugInfo/PDB/Native/NativeTypeEnum.h"
15 
16 using namespace llvm;
17 using namespace llvm::codeview;
18 using namespace llvm::pdb;
19 
20 NativeSymbolEnumerator::NativeSymbolEnumerator(
21     NativeSession &Session, SymIndexId Id, const NativeTypeEnum &Parent,
22     codeview::EnumeratorRecord Record)
23     : NativeRawSymbol(Session, PDB_SymType::Data, Id), Parent(Parent),
24       Record(std::move(Record)) {}
25 
26 NativeSymbolEnumerator::~NativeSymbolEnumerator() {}
27 
28 void NativeSymbolEnumerator::dump(raw_ostream &OS, int Indent) const {
29   NativeRawSymbol::dump(OS, Indent);
30   dumpSymbolField(OS, "classParentId", getClassParentId(), Indent);
31   dumpSymbolField(OS, "lexicalParentId", getLexicalParentId(), Indent);
32   dumpSymbolField(OS, "name", getName(), Indent);
33   dumpSymbolField(OS, "typeId", getTypeId(), Indent);
34   dumpSymbolField(OS, "dataKind", getDataKind(), Indent);
35   dumpSymbolField(OS, "locationType", getLocationType(), Indent);
36   dumpSymbolField(OS, "constType", isConstType(), Indent);
37   dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
38   dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
39   dumpSymbolField(OS, "value", getValue(), Indent);
40 }
41 
42 SymIndexId NativeSymbolEnumerator::getClassParentId() const {
43   return Parent.getSymIndexId();
44 }
45 
46 SymIndexId NativeSymbolEnumerator::getLexicalParentId() const { return 0; }
47 
48 std::string NativeSymbolEnumerator::getName() const { return Record.Name; }
49 
50 SymIndexId NativeSymbolEnumerator::getTypeId() const {
51   return Parent.getTypeId();
52 }
53 
54 PDB_DataKind NativeSymbolEnumerator::getDataKind() const {
55   return PDB_DataKind::Constant;
56 }
57 
58 PDB_LocType NativeSymbolEnumerator::getLocationType() const {
59   return PDB_LocType::Constant;
60 }
61 
62 bool NativeSymbolEnumerator::isConstType() const { return false; }
63 
64 bool NativeSymbolEnumerator::isVolatileType() const { return false; }
65 
66 bool NativeSymbolEnumerator::isUnalignedType() const { return false; }
67 
68 Variant NativeSymbolEnumerator::getValue() const {
69   const NativeTypeBuiltin &BT = Parent.getUnderlyingBuiltinType();
70 
71   switch (BT.getBuiltinType()) {
72   case PDB_BuiltinType::Int:
73   case PDB_BuiltinType::Long:
74   case PDB_BuiltinType::Char: {
75     assert(Record.Value.isSignedIntN(BT.getLength() * 8));
76     int64_t N = Record.Value.getSExtValue();
77     switch (BT.getLength()) {
78     case 1:
79       return Variant{static_cast<int8_t>(N)};
80     case 2:
81       return Variant{static_cast<int16_t>(N)};
82     case 4:
83       return Variant{static_cast<int32_t>(N)};
84     case 8:
85       return Variant{static_cast<int64_t>(N)};
86     }
87     break;
88   }
89   case PDB_BuiltinType::UInt:
90   case PDB_BuiltinType::ULong: {
91     assert(Record.Value.isIntN(BT.getLength() * 8));
92     uint64_t U = Record.Value.getZExtValue();
93     switch (BT.getLength()) {
94     case 1:
95       return Variant{static_cast<uint8_t>(U)};
96     case 2:
97       return Variant{static_cast<uint16_t>(U)};
98     case 4:
99       return Variant{static_cast<uint32_t>(U)};
100     case 8:
101       return Variant{static_cast<uint64_t>(U)};
102     }
103     break;
104   }
105   case PDB_BuiltinType::Bool: {
106     assert(Record.Value.isIntN(BT.getLength() * 8));
107     uint64_t U = Record.Value.getZExtValue();
108     return Variant{static_cast<bool>(U)};
109   }
110   default:
111     assert(false && "Invalid enumeration type");
112     break;
113   }
114 
115   return Variant{Record.Value.getSExtValue()};
116 }
117