1 //===- NativeTypeFunctionSig.cpp - info about function signature -*- C++-*-===//
3 // The LLVM Compiler Infrastructure
5 // This file is distributed under the University of Illinois Open Source
6 // License. See LICENSE.TXT for details.
8 //===----------------------------------------------------------------------===//
10 #include "llvm/DebugInfo/PDB/Native/NativeTypeFunctionSig.h"
12 #include "llvm/DebugInfo/CodeView/LazyRandomTypeCollection.h"
13 #include "llvm/DebugInfo/PDB/Native/NativeEnumTypes.h"
14 #include "llvm/DebugInfo/PDB/PDBExtras.h"
15 #include "llvm/DebugInfo/PDB/Native/PDBFile.h"
16 #include "llvm/DebugInfo/PDB/Native/TpiStream.h"
19 using namespace llvm::codeview;
20 using namespace llvm::pdb;
23 // This is kind of a silly class, hence why we keep it private to the file.
24 // It's only purpose is to wrap the real type record. I guess this is so that
25 // we can have the lexical parent point to the function instead of the global
27 class NativeTypeFunctionArg : public NativeRawSymbol {
29 NativeTypeFunctionArg(NativeSession &Session,
30 std::unique_ptr<PDBSymbol> RealType)
31 : NativeRawSymbol(Session, PDB_SymType::FunctionArg, 0),
32 RealType(std::move(RealType)) {}
34 void dump(raw_ostream &OS, int Indent, PdbSymbolIdField ShowIdFields,
35 PdbSymbolIdField RecurseIdFields) const override {
36 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
38 dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
39 PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
42 SymIndexId getTypeId() const override { return RealType->getSymIndexId(); }
44 std::unique_ptr<PDBSymbol> RealType;
47 class NativeEnumFunctionArgs : public IPDBEnumChildren<PDBSymbol> {
49 NativeEnumFunctionArgs(NativeSession &Session,
50 std::unique_ptr<NativeEnumTypes> TypeEnumerator)
51 : Session(Session), TypeEnumerator(std::move(TypeEnumerator)) {}
53 uint32_t getChildCount() const override {
54 return TypeEnumerator->getChildCount();
56 std::unique_ptr<PDBSymbol> getChildAtIndex(uint32_t Index) const override {
57 return wrap(TypeEnumerator->getChildAtIndex(Index));
59 std::unique_ptr<PDBSymbol> getNext() override {
60 return wrap(TypeEnumerator->getNext());
63 void reset() override { TypeEnumerator->reset(); }
66 std::unique_ptr<PDBSymbol> wrap(std::unique_ptr<PDBSymbol> S) const {
69 auto NTFA = llvm::make_unique<NativeTypeFunctionArg>(Session, std::move(S));
70 return PDBSymbol::create(Session, std::move(NTFA));
72 NativeSession &Session;
73 std::unique_ptr<NativeEnumTypes> TypeEnumerator;
77 NativeTypeFunctionSig::NativeTypeFunctionSig(NativeSession &Session,
79 codeview::TypeIndex Index,
80 codeview::ProcedureRecord Proc)
81 : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
82 Proc(std::move(Proc)), Index(Index), IsMemberFunction(false) {}
84 NativeTypeFunctionSig::NativeTypeFunctionSig(
85 NativeSession &Session, SymIndexId Id, codeview::TypeIndex Index,
86 codeview::MemberFunctionRecord MemberFunc)
87 : NativeRawSymbol(Session, PDB_SymType::FunctionSig, Id),
88 MemberFunc(std::move(MemberFunc)), Index(Index), IsMemberFunction(true) {}
90 void NativeTypeFunctionSig::initialize() {
91 if (IsMemberFunction) {
93 Session.getSymbolCache().findSymbolByTypeIndex(MemberFunc.ClassType);
94 initializeArgList(MemberFunc.ArgumentList);
96 initializeArgList(Proc.ArgumentList);
100 NativeTypeFunctionSig::~NativeTypeFunctionSig() {}
102 void NativeTypeFunctionSig::initializeArgList(codeview::TypeIndex ArgListTI) {
103 TpiStream &Tpi = cantFail(Session.getPDBFile().getPDBTpiStream());
104 CVType CVT = Tpi.typeCollection().getType(ArgListTI);
106 cantFail(TypeDeserializer::deserializeAs<ArgListRecord>(CVT, ArgList));
109 void NativeTypeFunctionSig::dump(raw_ostream &OS, int Indent,
110 PdbSymbolIdField ShowIdFields,
111 PdbSymbolIdField RecurseIdFields) const {
113 NativeRawSymbol::dump(OS, Indent, ShowIdFields, RecurseIdFields);
115 dumpSymbolIdField(OS, "lexicalParentId", 0, Indent, Session,
116 PdbSymbolIdField::LexicalParent, ShowIdFields,
119 dumpSymbolField(OS, "callingConvention", getCallingConvention(), Indent);
120 dumpSymbolField(OS, "count", getCount(), Indent);
121 dumpSymbolIdField(OS, "typeId", getTypeId(), Indent, Session,
122 PdbSymbolIdField::Type, ShowIdFields, RecurseIdFields);
123 if (IsMemberFunction)
124 dumpSymbolField(OS, "thisAdjust", getThisAdjust(), Indent);
125 dumpSymbolField(OS, "constructor", hasConstructor(), Indent);
126 dumpSymbolField(OS, "constType", isConstType(), Indent);
127 dumpSymbolField(OS, "isConstructorVirtualBase", isConstructorVirtualBase(),
129 dumpSymbolField(OS, "isCxxReturnUdt", isCxxReturnUdt(), Indent);
130 dumpSymbolField(OS, "unalignedType", isUnalignedType(), Indent);
131 dumpSymbolField(OS, "volatileType", isVolatileType(), Indent);
134 std::unique_ptr<IPDBEnumSymbols>
135 NativeTypeFunctionSig::findChildren(PDB_SymType Type) const {
136 if (Type != PDB_SymType::FunctionArg)
137 return llvm::make_unique<NullEnumerator<PDBSymbol>>();
139 auto NET = llvm::make_unique<NativeEnumTypes>(Session,
140 /* copy */ ArgList.ArgIndices);
141 return std::unique_ptr<IPDBEnumSymbols>(
142 new NativeEnumFunctionArgs(Session, std::move(NET)));
145 SymIndexId NativeTypeFunctionSig::getClassParentId() const {
146 if (!IsMemberFunction)
149 return ClassParentId;
152 PDB_CallingConv NativeTypeFunctionSig::getCallingConvention() const {
153 return IsMemberFunction ? MemberFunc.CallConv : Proc.CallConv;
156 uint32_t NativeTypeFunctionSig::getCount() const {
157 return IsMemberFunction ? (1 + MemberFunc.getParameterCount())
158 : Proc.getParameterCount();
161 SymIndexId NativeTypeFunctionSig::getTypeId() const {
163 IsMemberFunction ? MemberFunc.getReturnType() : Proc.getReturnType();
165 SymIndexId Result = Session.getSymbolCache().findSymbolByTypeIndex(ReturnTI);
169 int32_t NativeTypeFunctionSig::getThisAdjust() const {
170 return IsMemberFunction ? MemberFunc.getThisPointerAdjustment() : 0;
173 bool NativeTypeFunctionSig::hasConstructor() const {
174 if (!IsMemberFunction)
177 return (MemberFunc.getOptions() & FunctionOptions::Constructor) !=
178 FunctionOptions::None;
181 bool NativeTypeFunctionSig::isConstType() const { return false; }
183 bool NativeTypeFunctionSig::isConstructorVirtualBase() const {
184 if (!IsMemberFunction)
187 return (MemberFunc.getOptions() &
188 FunctionOptions::ConstructorWithVirtualBases) !=
189 FunctionOptions::None;
192 bool NativeTypeFunctionSig::isCxxReturnUdt() const {
193 FunctionOptions Options =
194 IsMemberFunction ? MemberFunc.getOptions() : Proc.getOptions();
195 return (Options & FunctionOptions::CxxReturnUdt) != FunctionOptions::None;
198 bool NativeTypeFunctionSig::isUnalignedType() const { return false; }
200 bool NativeTypeFunctionSig::isVolatileType() const { return false; }