/
dibuilder.h
193 lines (158 loc) · 5.87 KB
/
dibuilder.h
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
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
175
176
177
178
179
180
181
182
183
184
185
186
187
188
189
190
191
192
193
//===-- gen/dibuilder.h - Debug information builder -------------*- C++ -*-===//
//
// LDC – the LLVM D compiler
//
// This file is distributed under the BSD-style LDC license. See the LICENSE
// file for details.
//
//===----------------------------------------------------------------------===//
#ifndef LDC_GEN_DIBUILDER_H
#define LDC_GEN_DIBUILDER_H
#if LDC_LLVM_VER >= 303
#include "llvm/IR/Constants.h"
#include "llvm/IR/Type.h"
#include "llvm/IR/DataLayout.h"
#include "llvm/DebugInfo.h"
#include "llvm/DIBuilder.h"
#else
#if LDC_LLVM_VER == 302
#include "llvm/DataLayout.h"
#include "llvm/DebugInfo.h"
#include "llvm/DIBuilder.h"
#else
#include "llvm/Constants.h"
#include "llvm/Type.h"
#include "llvm/Analysis/DebugInfo.h"
#include "llvm/Analysis/DIBuilder.h"
#include "llvm/Target/TargetData.h"
#endif
#endif
#include "gen/tollvm.h"
#include "mars.h"
struct IRState;
struct ClassDeclaration;
struct Dsymbol;
struct FuncDeclaration;
struct Module;
struct Type;
struct VarDeclaration;
namespace llvm {
class GlobalVariable;
class StructType;
class LLVMContext;
// Only for the OpXXX templates, see below.
#if LDC_LLVM_VER >= 302
class DataLayout;
#else
class TargetData;
#endif
}
// Only for the OpXXX templates, see below.
#if LDC_LLVM_VER >= 302
extern const llvm::DataLayout* gDataLayout;
#else
extern const llvm::TargetData* gDataLayout;
#endif
namespace ldc {
#if LDC_LLVM_VER >= 304
typedef llvm::DICompositeType DIFunctionType;
#else
typedef llvm::DIType DIFunctionType;
#endif
class DIBuilder
{
IRState *const IR;
const llvm::MDNode *CUNode;
llvm::DIBuilder DBuilder;
const llvm::MDNode *GetCU()
{
return CUNode;
}
public:
DIBuilder(IRState *const IR, llvm::Module &M);
/// \brief Emit the Dwarf compile_unit global for a Module m.
/// \param m Module to emit as compile unit.
void EmitCompileUnit(Module *m);
/// \brief Emit the Dwarf subprogram global for a function declaration fd.
/// \param fd Function declaration to emit as subprogram.
/// \returns the Dwarf subprogram global.
llvm::DISubprogram EmitSubProgram(FuncDeclaration *fd); // FIXME
/// \brief Emit the Dwarf subprogram global for a internal function.
/// This is used for generated functions like moduleinfoctors,
/// module ctors/dtors and unittests.
/// \param prettyname The name as seen in the source.
/// \param mangledname The mangled name in the object file.
/// \returns the Dwarf subprogram global.
llvm::DISubprogram EmitSubProgramInternal(llvm::StringRef prettyname, llvm::StringRef mangledname); // FIXME
/// \brief Emits debug info for function start
void EmitFuncStart(FuncDeclaration *fd);
/// \brief Emits debug info for function end
void EmitFuncEnd(FuncDeclaration *fd);
/// \brief Emits debug info for block start
void EmitBlockStart(Loc loc);
/// \brief Emits debug info for block end
void EmitBlockEnd();
void EmitStopPoint(unsigned ln);
void EmitValue(llvm::Value *val, VarDeclaration* vd);
/// \brief Emits all things necessary for making debug info for a local variable vd.
/// \param ll LLVM Value of the variable.
/// \param vd Variable declaration to emit debug info for.
/// \param addr An array of complex address operations.
void EmitLocalVariable(llvm::Value *ll, VarDeclaration *vd,
llvm::ArrayRef<llvm::Value *> addr = llvm::ArrayRef<llvm::Value *>());
/// \brief Emits all things necessary for making debug info for a global variable vd.
/// \param ll LLVM global variable
/// \param vd Variable declaration to emit debug info for.
llvm::DIGlobalVariable EmitGlobalVariable(llvm::GlobalVariable *ll, VarDeclaration *vd); // FIXME
void EmitModuleEnd();
private:
llvm::LLVMContext &getContext();
Module *getDefinedModule(Dsymbol *s);
llvm::DIDescriptor GetCurrentScope();
void Declare(llvm::Value *var, llvm::DIVariable divar);
void AddBaseFields(ClassDeclaration *sd, llvm::DIFile file,
std::vector<llvm::Value*> &elems);
llvm::DIFile CreateFile(Loc loc);
llvm::DIType CreateBasicType(Type *type);
llvm::DIType CreateEnumType(Type *type);
llvm::DIType CreatePointerType(Type *type);
llvm::DIType CreateVectorType(Type *type);
llvm::DIType CreateMemberType(unsigned linnum, Type *type, llvm::DIFile file, const char* c_name, unsigned offset);
llvm::DIType CreateCompositeType(Type *type);
llvm::DIType CreateArrayType(Type *type);
llvm::DIType CreateSArrayType(Type *type);
llvm::DIType CreateAArrayType(Type *type);
DIFunctionType CreateFunctionType(Type *type);
DIFunctionType CreateDelegateType(Type *type);
llvm::DIType CreateTypeDescription(Type* type, const char* c_name, bool derefclass = false);
public:
template<typename T>
void OpOffset(T &addr, llvm::StructType *type, int index)
{
if (!global.params.symdebug)
return;
uint64_t offset = gDataLayout->getStructLayout(type)->getElementOffset(index);
llvm::Type *int64Ty = llvm::Type::getInt64Ty(getContext());
addr.push_back(llvm::ConstantInt::get(int64Ty, llvm::DIBuilder::OpPlus));
addr.push_back(llvm::ConstantInt::get(int64Ty, offset));
}
template<typename T>
void OpOffset(T &addr, llvm::Value *val, int index)
{
if (!global.params.symdebug)
return;
llvm::StructType *type = isaStruct(val->getType()->getContainedType(0));
assert(type);
OpOffset(addr, type, index);
}
template<typename T>
void OpDeref(T &addr)
{
if (!global.params.symdebug)
return;
llvm::Type *int64Ty = llvm::Type::getInt64Ty(getContext());
addr.push_back(llvm::ConstantInt::get(int64Ty, llvm::DIBuilder::OpDeref));
}
};
} // namespace ldc
#endif