Mercurial > projects > ldc
comparison gen/todebug.cpp @ 250:fc9c1a0eabbd trunk
[svn r267] Fixed debug info for global variables.
Cleaned up the debug info code in general.
author | lindquist |
---|---|
date | Wed, 11 Jun 2008 20:53:26 +0200 |
parents | 56199753e637 |
children | e3355ce5444b |
comparison
equal
deleted
inserted
replaced
249:fa9fef362a98 | 250:fc9c1a0eabbd |
---|---|
17 | 17 |
18 #define DBG_NULL ( LLConstant::getNullValue(DBG_TYPE) ) | 18 #define DBG_NULL ( LLConstant::getNullValue(DBG_TYPE) ) |
19 #define DBG_TYPE ( getPtrToType(llvm::StructType::get(NULL,NULL)) ) | 19 #define DBG_TYPE ( getPtrToType(llvm::StructType::get(NULL,NULL)) ) |
20 #define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) | 20 #define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) ) |
21 | 21 |
22 #define DBG_TAG(X) ( llvm::ConstantExpr::getAdd( DtoConstUint( X ), DtoConstUint( llvm::LLVMDebugVersion ) ) ) | |
23 | |
24 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
25 | |
26 /** | |
27 * Emits a global variable, LLVM Dwarf style. | |
28 * @param type Type of variable. | |
29 * @param values Initializers. | |
30 * @param name Name. | |
31 * @return The global variable. | |
32 */ | |
33 static LLGlobalVariable* emitDwarfGlobal(const LLStructType* type, const std::vector<LLConstant*> values, const char* name, bool linkonce=false) | |
34 { | |
35 LLConstant* c = llvm::ConstantStruct::get(type, values); | |
36 LLGlobalValue::LinkageTypes linkage = linkonce ? LLGlobalValue::LinkOnceLinkage : LLGlobalValue::InternalLinkage; | |
37 LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, linkage, c, name, gIR->module); | |
38 gv->setSection("llvm.metadata"); | |
39 return gv; | |
40 } | |
41 | |
22 ////////////////////////////////////////////////////////////////////////////////////////////////// | 42 ////////////////////////////////////////////////////////////////////////////////////////////////// |
23 | 43 |
24 static llvm::GlobalVariable* dbg_compile_units = 0; | 44 static llvm::GlobalVariable* dbg_compile_units = 0; |
25 static llvm::GlobalVariable* dbg_global_variables = 0; | 45 static llvm::GlobalVariable* dbg_global_variables = 0; |
26 static llvm::GlobalVariable* dbg_subprograms = 0; | 46 static llvm::GlobalVariable* dbg_subprograms = 0; |
27 | 47 |
28 const llvm::StructType* GetDwarfAnchorType() | 48 /** |
29 { | 49 * Emits the Dwarf anchors that are used repeatedly by LLVM debug info. |
30 /* | 50 */ |
31 %llvm.dbg.anchor.type = type { | 51 static void emitDwarfAnchors() |
32 uint, ;; Tag = 0 + LLVMDebugVersion | 52 { |
33 uint ;; Tag of descriptors grouped by the anchor | 53 const llvm::StructType* anchorTy = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type")); |
34 } | 54 std::vector<LLConstant*> vals(2); |
35 */ | 55 |
36 | |
37 const llvm::StructType* t = isaStruct(gIR->module->getTypeByName("llvm.dbg.anchor.type")); | |
38 | |
39 /* | |
40 %llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 17 } ;; DW_TAG_compile_unit | |
41 %llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 52 } ;; DW_TAG_variable | |
42 %llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 46 } ;; DW_TAG_subprogram | |
43 */ | |
44 if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) { | 56 if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) { |
45 std::vector<LLConstant*> vals; | 57 vals[0] = DtoConstUint(llvm::LLVMDebugVersion); |
46 vals.push_back(DtoConstUint(llvm::LLVMDebugVersion)); | 58 vals[1] = DtoConstUint(DW_TAG_compile_unit); |
47 vals.push_back(DtoConstUint(DW_TAG_compile_unit)); | 59 dbg_compile_units = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.compile_units", true); |
48 LLConstant* i = llvm::ConstantStruct::get(t, vals); | |
49 dbg_compile_units = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.compile_units",gIR->module); | |
50 dbg_compile_units->setSection("llvm.metadata"); | |
51 } | 60 } |
52 if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) { | 61 if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) { |
53 std::vector<LLConstant*> vals; | 62 vals[0] = DtoConstUint(llvm::LLVMDebugVersion); |
54 vals.push_back(DtoConstUint(llvm::LLVMDebugVersion)); | 63 vals[1] = DtoConstUint(DW_TAG_variable); |
55 vals.push_back(DtoConstUint(DW_TAG_variable)); | 64 dbg_global_variables = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.global_variables", true); |
56 LLConstant* i = llvm::ConstantStruct::get(t, vals); | |
57 dbg_global_variables = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.global_variables",gIR->module); | |
58 dbg_global_variables->setSection("llvm.metadata"); | |
59 } | 65 } |
60 if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) { | 66 if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) { |
61 std::vector<LLConstant*> vals; | 67 vals[0] = DtoConstUint(llvm::LLVMDebugVersion); |
62 vals.push_back(DtoConstUint(llvm::LLVMDebugVersion)); | 68 vals[1] = DtoConstUint(DW_TAG_subprogram); |
63 vals.push_back(DtoConstUint(DW_TAG_subprogram)); | 69 dbg_subprograms = emitDwarfGlobal(anchorTy, vals, "llvm.dbg.subprograms", true); |
64 LLConstant* i = llvm::ConstantStruct::get(t, vals); | 70 } |
65 dbg_subprograms = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.subprograms",gIR->module); | 71 } |
66 dbg_subprograms->setSection("llvm.metadata"); | 72 |
67 } | 73 static LLConstant* getDwarfAnchor(dwarf_constants c) |
68 | 74 { |
69 return t; | 75 emitDwarfAnchors(); |
70 } | |
71 | |
72 LLConstant* GetDwarfAnchor(llvm::dwarf::dwarf_constants c) | |
73 { | |
74 GetDwarfAnchorType(); | |
75 switch (c) | 76 switch (c) |
76 { | 77 { |
77 case DW_TAG_compile_unit: | 78 case DW_TAG_compile_unit: |
78 return dbg_compile_units; | 79 return dbg_compile_units; |
79 case DW_TAG_variable: | 80 case DW_TAG_variable: |
80 return dbg_global_variables; | 81 return dbg_global_variables; |
81 case DW_TAG_subprogram: | 82 case DW_TAG_subprogram: |
82 return dbg_subprograms; | 83 return dbg_subprograms; |
83 } | 84 default: |
84 assert(0); | 85 assert(0); |
85 return 0; | 86 } |
86 } | 87 } |
87 | 88 |
88 ////////////////////////////////////////////////////////////////////////////////////////////////// | 89 ////////////////////////////////////////////////////////////////////////////////////////////////// |
89 | 90 |
90 static const llvm::StructType* getDwarfCompileUnitType() { | 91 static const llvm::StructType* getDwarfCompileUnitType() { |
115 return isaStruct(gIR->module->getTypeByName("llvm.dbg.global_variable.type")); | 116 return isaStruct(gIR->module->getTypeByName("llvm.dbg.global_variable.type")); |
116 } | 117 } |
117 | 118 |
118 ////////////////////////////////////////////////////////////////////////////////////////////////// | 119 ////////////////////////////////////////////////////////////////////////////////////////////////// |
119 | 120 |
120 LLGlobalVariable* DtoDwarfCompileUnit(Module* m) | 121 static LLGlobalVariable* dwarfCompileUnit(Module* m) |
121 { | 122 { |
122 if (!m->ir.irModule) | 123 std::vector<LLConstant*> vals; |
123 m->ir.irModule = new IrModule(m); | 124 vals.push_back(DBG_TAG(DW_TAG_compile_unit)); |
124 else if (m->ir.irModule->dwarfCompileUnit) | 125 vals.push_back(DBG_CAST(getDwarfAnchor(DW_TAG_compile_unit))); |
125 { | |
126 if (m->ir.irModule->dwarfCompileUnit->getParent() == gIR->module) | |
127 return m->ir.irModule->dwarfCompileUnit; | |
128 } | |
129 | |
130 // create a valid compile unit constant for the current module | |
131 | |
132 LLConstant* c = NULL; | |
133 | |
134 std::vector<LLConstant*> vals; | |
135 vals.push_back(llvm::ConstantExpr::getAdd( | |
136 DtoConstUint(DW_TAG_compile_unit), | |
137 DtoConstUint(llvm::LLVMDebugVersion))); | |
138 vals.push_back(DBG_CAST(GetDwarfAnchor(DW_TAG_compile_unit))); | |
139 | 126 |
140 vals.push_back(DtoConstUint(DW_LANG_C));// _D)); // doesn't seem to work | 127 vals.push_back(DtoConstUint(DW_LANG_C));// _D)); // doesn't seem to work |
141 vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata")); | 128 vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata")); |
142 std::string srcpath(FileName::path(m->srcfile->name->toChars())); | 129 std::string srcpath(FileName::path(m->srcfile->name->toChars())); |
143 if (srcpath.empty()) { | 130 if (srcpath.empty()) { |
146 srcpath = str; | 133 srcpath = str; |
147 } | 134 } |
148 vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata")); | 135 vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata")); |
149 vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata")); | 136 vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata")); |
150 | 137 |
151 c = llvm::ConstantStruct::get(getDwarfCompileUnitType(), vals); | 138 LLGlobalVariable* gv = emitDwarfGlobal(getDwarfCompileUnitType(), vals, "llvm.dbg.compile_unit"); |
152 | |
153 llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module); | |
154 gv->setSection("llvm.metadata"); | |
155 | |
156 m->ir.irModule->dwarfCompileUnit = gv; | 139 m->ir.irModule->dwarfCompileUnit = gv; |
157 return gv; | 140 return gv; |
158 } | 141 } |
159 | 142 |
160 ////////////////////////////////////////////////////////////////////////////////////////////////// | 143 ////////////////////////////////////////////////////////////////////////////////////////////////// |
161 | 144 |
162 LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit) | 145 static LLGlobalVariable* dwarfSubProgram(FuncDeclaration* fd, llvm::GlobalVariable* compileUnit) |
163 { | 146 { |
164 std::vector<LLConstant*> vals; | 147 std::vector<LLConstant*> vals; |
165 vals.push_back(llvm::ConstantExpr::getAdd( | 148 vals.push_back(DBG_TAG(DW_TAG_subprogram)); |
166 DtoConstUint(DW_TAG_subprogram), | 149 vals.push_back(DBG_CAST(getDwarfAnchor(DW_TAG_subprogram))); |
167 DtoConstUint(llvm::LLVMDebugVersion))); | |
168 vals.push_back(DBG_CAST(GetDwarfAnchor(DW_TAG_subprogram))); | |
169 | 150 |
170 vals.push_back(DBG_CAST(compileUnit)); | 151 vals.push_back(DBG_CAST(compileUnit)); |
171 vals.push_back(DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata")); | 152 vals.push_back(DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata")); |
172 vals.push_back(vals.back()); | 153 vals.push_back(vals.back()); |
173 vals.push_back(DtoConstStringPtr(fd->mangle(), "llvm.metadata")); | 154 vals.push_back(DtoConstStringPtr(fd->mangle(), "llvm.metadata")); |
174 vals.push_back(DBG_CAST(compileUnit)); | 155 vals.push_back(DBG_CAST( DtoDwarfCompileUnit(fd->getModule()) )); |
175 vals.push_back(DtoConstUint(fd->loc.linnum)); | 156 vals.push_back(DtoConstUint(fd->loc.linnum)); |
176 vals.push_back(DBG_NULL); | 157 vals.push_back(DBG_NULL); |
177 vals.push_back(DtoConstBool(fd->protection == PROTprivate)); | 158 vals.push_back(DtoConstBool(fd->protection == PROTprivate)); |
178 vals.push_back(DtoConstBool(fd->getModule() == gIR->dmodule)); | 159 vals.push_back(DtoConstBool(fd->getModule() == gIR->dmodule)); |
179 | 160 |
180 LLConstant* c = llvm::ConstantStruct::get(getDwarfSubProgramType(), vals); | 161 return emitDwarfGlobal(getDwarfSubProgramType(), vals, "llvm.dbg.subprogram"); |
181 llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.subprogram", gIR->module); | |
182 gv->setSection("llvm.metadata"); | |
183 return gv; | |
184 } | |
185 | |
186 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
187 | |
188 void DtoDwarfFuncStart(FuncDeclaration* fd) | |
189 { | |
190 assert(fd->ir.irFunc->dwarfSubProg); | |
191 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); | |
192 } | |
193 | |
194 void DtoDwarfFuncEnd(FuncDeclaration* fd) | |
195 { | |
196 assert(fd->ir.irFunc->dwarfSubProg); | |
197 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); | |
198 } | |
199 | |
200 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
201 | |
202 void DtoDwarfStopPoint(unsigned ln) | |
203 { | |
204 LLSmallVector<LLValue*,3> args; | |
205 args.push_back(DtoConstUint(ln)); | |
206 args.push_back(DtoConstUint(0)); | |
207 FuncDeclaration* fd = gIR->func()->decl; | |
208 args.push_back(DBG_CAST(DtoDwarfCompileUnit(fd->getModule()))); | |
209 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end()); | |
210 } | 162 } |
211 | 163 |
212 ////////////////////////////////////////////////////////////////////////////////////////////////// | 164 ////////////////////////////////////////////////////////////////////////////////////////////////// |
213 | 165 |
214 static LLGlobalVariable* dwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu, const char* c_name); | 166 static LLGlobalVariable* dwarfTypeDescription(Loc loc, Type* type, LLGlobalVariable* cu, const char* c_name); |
222 const LLType* T = DtoType(type); | 174 const LLType* T = DtoType(type); |
223 | 175 |
224 std::vector<LLConstant*> vals; | 176 std::vector<LLConstant*> vals; |
225 | 177 |
226 // tag | 178 // tag |
227 vals.push_back(llvm::ConstantExpr::getAdd( | 179 vals.push_back(DBG_TAG(DW_TAG_base_type)); |
228 DtoConstUint(DW_TAG_base_type), | |
229 DtoConstUint(llvm::LLVMDebugVersion))); | |
230 | 180 |
231 // context | 181 // context |
232 vals.push_back(DBG_CAST(compileUnit)); | 182 vals.push_back(DBG_CAST(compileUnit)); |
233 | 183 |
234 // name | 184 // name |
255 // dwarf type | 205 // dwarf type |
256 unsigned id; | 206 unsigned id; |
257 if (t->isintegral()) | 207 if (t->isintegral()) |
258 { | 208 { |
259 if (type->isunsigned()) | 209 if (type->isunsigned()) |
260 id = llvm::dwarf::DW_ATE_unsigned; | 210 id = DW_ATE_unsigned; |
261 else | 211 else |
262 id = llvm::dwarf::DW_ATE_signed; | 212 id = DW_ATE_signed; |
263 } | 213 } |
264 else if (t->isfloating()) | 214 else if (t->isfloating()) |
265 { | 215 { |
266 id = llvm::dwarf::DW_ATE_float; | 216 id = DW_ATE_float; |
267 } | 217 } |
268 else | 218 else |
269 { | 219 { |
270 assert(0 && "unsupported basictype for debug info"); | 220 assert(0 && "unsupported basictype for debug info"); |
271 } | 221 } |
272 vals.push_back(DtoConstUint(id)); | 222 vals.push_back(DtoConstUint(id)); |
273 | 223 |
274 LLConstant* c = llvm::ConstantStruct::get(getDwarfBasicTypeType(), vals); | 224 return emitDwarfGlobal(getDwarfBasicTypeType(), vals, "llvm.dbg.basictype"); |
275 LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.basictype", gIR->module); | |
276 gv->setSection("llvm.metadata"); | |
277 return gv; | |
278 } | 225 } |
279 | 226 |
280 ////////////////////////////////////////////////////////////////////////////////////////////////// | 227 ////////////////////////////////////////////////////////////////////////////////////////////////// |
281 | 228 |
282 static LLGlobalVariable* dwarfDerivedType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit) | 229 static LLGlobalVariable* dwarfDerivedType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit) |
289 | 236 |
290 // find tag | 237 // find tag |
291 unsigned tag; | 238 unsigned tag; |
292 if (t->ty == Tpointer) | 239 if (t->ty == Tpointer) |
293 { | 240 { |
294 tag = llvm::dwarf::DW_TAG_pointer_type; | 241 tag = DW_TAG_pointer_type; |
295 } | 242 } |
296 else | 243 else |
297 { | 244 { |
298 assert(0 && "unsupported derivedtype for debug info"); | 245 assert(0 && "unsupported derivedtype for debug info"); |
299 } | 246 } |
300 | 247 |
301 std::vector<LLConstant*> vals; | 248 std::vector<LLConstant*> vals; |
302 | 249 |
303 // tag | 250 // tag |
304 vals.push_back(llvm::ConstantExpr::getAdd( | 251 vals.push_back(DBG_TAG(tag)); |
305 DtoConstUint(tag), | |
306 DtoConstUint(llvm::LLVMDebugVersion))); | |
307 | 252 |
308 // context | 253 // context |
309 vals.push_back(DBG_CAST(compileUnit)); | 254 vals.push_back(DBG_CAST(compileUnit)); |
310 | 255 |
311 // name | 256 // name |
335 if (nt->ty == Tvoid || !nTD) | 280 if (nt->ty == Tvoid || !nTD) |
336 vals.push_back(DBG_NULL); | 281 vals.push_back(DBG_NULL); |
337 else | 282 else |
338 vals.push_back(DBG_CAST(nTD)); | 283 vals.push_back(DBG_CAST(nTD)); |
339 | 284 |
340 LLConstant* c = llvm::ConstantStruct::get(getDwarfDerivedTypeType(), vals); | 285 return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype"); |
341 LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.derivedtype", gIR->module); | |
342 gv->setSection("llvm.metadata"); | |
343 return gv; | |
344 } | 286 } |
345 | 287 |
346 ////////////////////////////////////////////////////////////////////////////////////////////////// | 288 ////////////////////////////////////////////////////////////////////////////////////////////////// |
347 | 289 |
348 static LLGlobalVariable* dwarfMemberType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit, const char* c_name, unsigned offset) | 290 static LLGlobalVariable* dwarfMemberType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit, const char* c_name, unsigned offset) |
358 name = getNullPtr(getVoidPtrType()); | 300 name = getNullPtr(getVoidPtrType()); |
359 | 301 |
360 std::vector<LLConstant*> vals; | 302 std::vector<LLConstant*> vals; |
361 | 303 |
362 // tag | 304 // tag |
363 vals.push_back(llvm::ConstantExpr::getAdd( | 305 vals.push_back(DBG_TAG(DW_TAG_member)); |
364 DtoConstUint(llvm::dwarf::DW_TAG_member), | |
365 DtoConstUint(llvm::LLVMDebugVersion))); | |
366 | 306 |
367 // context | 307 // context |
368 vals.push_back(DBG_CAST(compileUnit)); | 308 vals.push_back(DBG_CAST(compileUnit)); |
369 | 309 |
370 // name | 310 // name |
393 if (t->ty == Tvoid || !nTD) | 333 if (t->ty == Tvoid || !nTD) |
394 vals.push_back(DBG_NULL); | 334 vals.push_back(DBG_NULL); |
395 else | 335 else |
396 vals.push_back(DBG_CAST(nTD)); | 336 vals.push_back(DBG_CAST(nTD)); |
397 | 337 |
398 LLConstant* c = llvm::ConstantStruct::get(getDwarfDerivedTypeType(), vals); | 338 return emitDwarfGlobal(getDwarfDerivedTypeType(), vals, "llvm.dbg.derivedtype"); |
399 LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.derivedtype", gIR->module); | |
400 gv->setSection("llvm.metadata"); | |
401 return gv; | |
402 } | 339 } |
403 | 340 |
404 ////////////////////////////////////////////////////////////////////////////////////////////////// | 341 ////////////////////////////////////////////////////////////////////////////////////////////////// |
405 | 342 |
406 static LLGlobalVariable* dwarfCompositeType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit) | 343 static LLGlobalVariable* dwarfCompositeType(Loc loc, Type* type, llvm::GlobalVariable* compileUnit) |
410 | 347 |
411 // defaults | 348 // defaults |
412 LLConstant* name = getNullPtr(getVoidPtrType()); | 349 LLConstant* name = getNullPtr(getVoidPtrType()); |
413 LLGlobalVariable* members = NULL; | 350 LLGlobalVariable* members = NULL; |
414 | 351 |
415 // find tag | 352 // prepare tag and members |
416 unsigned tag; | 353 unsigned tag; |
417 if (t->ty == Tarray) | 354 if (t->ty == Tarray) |
418 { | 355 { |
419 tag = llvm::dwarf::DW_TAG_structure_type; | 356 tag = DW_TAG_structure_type; |
420 | 357 |
421 LLGlobalVariable* len = dwarfMemberType(loc, Type::tsize_t, compileUnit, "length", 0); | 358 LLGlobalVariable* len = dwarfMemberType(loc, Type::tsize_t, compileUnit, "length", 0); |
422 assert(len); | 359 assert(len); |
423 LLGlobalVariable* ptr = dwarfMemberType(loc, t->nextOf()->pointerTo(), compileUnit, "ptr", global.params.is64bit?8:4); | 360 LLGlobalVariable* ptr = dwarfMemberType(loc, t->nextOf()->pointerTo(), compileUnit, "ptr", global.params.is64bit?8:4); |
424 assert(ptr); | 361 assert(ptr); |
443 } | 380 } |
444 | 381 |
445 std::vector<LLConstant*> vals; | 382 std::vector<LLConstant*> vals; |
446 | 383 |
447 // tag | 384 // tag |
448 vals.push_back(llvm::ConstantExpr::getAdd( | 385 vals.push_back(DBG_TAG(tag)); |
449 DtoConstUint(tag), | |
450 DtoConstUint(llvm::LLVMDebugVersion))); | |
451 | 386 |
452 // context | 387 // context |
453 vals.push_back(DBG_CAST(compileUnit)); | 388 vals.push_back(DBG_CAST(compileUnit)); |
454 | 389 |
455 // name | 390 // name |
480 if (members) | 415 if (members) |
481 vals.push_back(DBG_CAST(members)); | 416 vals.push_back(DBG_CAST(members)); |
482 else | 417 else |
483 vals.push_back(DBG_NULL); | 418 vals.push_back(DBG_NULL); |
484 | 419 |
485 LLConstant* c = llvm::ConstantStruct::get(getDwarfCompositeTypeType(), vals); | 420 return emitDwarfGlobal(getDwarfCompositeTypeType(), vals, "llvm.dbg.compositetype"); |
486 LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.compositetype", gIR->module); | 421 } |
487 gv->setSection("llvm.metadata"); | 422 |
488 return gv; | 423 ////////////////////////////////////////////////////////////////////////////////////////////////// |
489 } | 424 |
490 | 425 static LLGlobalVariable* dwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) |
491 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
492 | |
493 LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) | |
494 { | 426 { |
495 assert(vd->isDataseg()); | 427 assert(vd->isDataseg()); |
496 llvm::GlobalVariable* compileUnit = DtoDwarfCompileUnit(gIR->dmodule); | 428 LLGlobalVariable* compileUnit = DtoDwarfCompileUnit(gIR->dmodule); |
497 | 429 |
498 std::vector<LLConstant*> vals; | 430 std::vector<LLConstant*> vals; |
499 vals.push_back(llvm::ConstantExpr::getAdd( | 431 vals.push_back(DBG_TAG(DW_TAG_variable)); |
500 DtoConstUint(DW_TAG_variable), | 432 vals.push_back(DBG_CAST(getDwarfAnchor(DW_TAG_variable))); |
501 DtoConstUint(llvm::LLVMDebugVersion))); | |
502 vals.push_back(DBG_CAST(GetDwarfAnchor(DW_TAG_variable))); | |
503 | 433 |
504 vals.push_back(DBG_CAST(compileUnit)); | 434 vals.push_back(DBG_CAST(compileUnit)); |
505 | 435 |
506 vals.push_back(DtoConstStringPtr(vd->mangle(), "llvm.metadata")); | 436 vals.push_back(DtoConstStringPtr(vd->mangle(), "llvm.metadata")); |
507 vals.push_back(DtoConstStringPtr(vd->toPrettyChars(), "llvm.metadata")); | 437 vals.push_back(DtoConstStringPtr(vd->toPrettyChars(), "llvm.metadata")); |
515 vals.push_back(DtoConstBool(vd->protection == PROTprivate)); | 445 vals.push_back(DtoConstBool(vd->protection == PROTprivate)); |
516 vals.push_back(DtoConstBool(vd->getModule() == gIR->dmodule)); | 446 vals.push_back(DtoConstBool(vd->getModule() == gIR->dmodule)); |
517 | 447 |
518 vals.push_back(DBG_CAST(ll)); | 448 vals.push_back(DBG_CAST(ll)); |
519 | 449 |
520 LLConstant* c = llvm::ConstantStruct::get(getDwarfGlobalVariableType(), vals); | 450 return emitDwarfGlobal(getDwarfGlobalVariableType(), vals, "llvm.dbg.global_variable"); |
521 llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.global_variable", gIR->module); | 451 } |
522 gv->setSection("llvm.metadata"); | |
523 return gv; | |
524 } | |
525 | |
526 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
527 | 452 |
528 static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr) | 453 static LLGlobalVariable* dwarfVariable(VarDeclaration* vd, LLGlobalVariable* typeDescr) |
529 { | 454 { |
455 assert(!vd->isDataseg() && "static variable"); | |
456 | |
530 unsigned tag; | 457 unsigned tag; |
531 if (vd->isParameter()) | 458 if (vd->isParameter()) |
532 tag = DW_TAG_arg_variable; | 459 tag = DW_TAG_arg_variable; |
533 else if (vd->isDataseg()) | |
534 assert(0 && "a static variable"); | |
535 else | 460 else |
536 tag = DW_TAG_auto_variable; | 461 tag = DW_TAG_auto_variable; |
537 | 462 |
538 std::vector<LLConstant*> vals; | 463 std::vector<LLConstant*> vals(6); |
539 // tag | 464 // tag |
540 vals.push_back(llvm::ConstantExpr::getAdd( | 465 vals[0] = DBG_TAG(tag); |
541 DtoConstUint(tag), | |
542 DtoConstUint(llvm::LLVMDebugVersion))); | |
543 // context | 466 // context |
544 vals.push_back(DBG_CAST(gIR->func()->dwarfSubProg)); | 467 vals[1] = DBG_CAST(gIR->func()->dwarfSubProg); |
545 // name | 468 // name |
546 vals.push_back(DtoConstStringPtr(vd->toChars(), "llvm.metadata")); | 469 vals[2] = DtoConstStringPtr(vd->toChars(), "llvm.metadata"); |
547 // compile unit where defined | 470 // compile unit where defined |
548 vals.push_back(DBG_CAST(DtoDwarfCompileUnit(vd->getModule()))); | 471 vals[3] = DBG_CAST(DtoDwarfCompileUnit(vd->getModule())); |
549 // line number where defined | 472 // line number where defined |
550 vals.push_back(DtoConstUint(vd->loc.linnum)); | 473 vals[4] = DtoConstUint(vd->loc.linnum); |
551 // type descriptor | 474 // type descriptor |
552 vals.push_back(DBG_CAST(typeDescr)); | 475 vals[5] = DBG_CAST(typeDescr); |
553 | 476 |
554 LLConstant* c = llvm::ConstantStruct::get(getDwarfVariableType(), vals); | 477 return emitDwarfGlobal(getDwarfVariableType(), vals, "llvm.dbg.variable"); |
555 LLGlobalVariable* gv = new LLGlobalVariable(c->getType(), true, LLGlobalValue::InternalLinkage, c, "llvm.dbg.variable", gIR->module); | |
556 gv->setSection("llvm.metadata"); | |
557 return gv; | |
558 } | 478 } |
559 | 479 |
560 ////////////////////////////////////////////////////////////////////////////////////////////////// | 480 ////////////////////////////////////////////////////////////////////////////////////////////////// |
561 | 481 |
562 static void dwarfDeclare(LLValue* var, LLGlobalVariable* varDescr) | 482 static void dwarfDeclare(LLValue* var, LLGlobalVariable* varDescr) |
608 | 528 |
609 // declare | 529 // declare |
610 dwarfDeclare(ll, VD); | 530 dwarfDeclare(ll, VD); |
611 } | 531 } |
612 | 532 |
613 | 533 ////////////////////////////////////////////////////////////////////////////////////////////////// |
614 | 534 |
615 | 535 LLGlobalVariable* DtoDwarfCompileUnit(Module* m) |
616 | 536 { |
617 | 537 // we might be generating for an import |
618 | 538 if (!m->ir.irModule) |
619 | 539 m->ir.irModule = new IrModule(m); |
620 | 540 else if (m->ir.irModule->dwarfCompileUnit) |
621 | 541 { |
622 | 542 if (m->ir.irModule->dwarfCompileUnit->getParent() == gIR->module) |
623 | 543 return m->ir.irModule->dwarfCompileUnit; |
624 | 544 } |
625 | 545 |
546 LLGlobalVariable* gv = dwarfCompileUnit(m); | |
547 m->ir.irModule->dwarfCompileUnit = gv; | |
548 return gv; | |
549 } | |
550 | |
551 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
552 | |
553 LLGlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd) | |
554 { | |
555 // FIXME: duplicates ? | |
556 return dwarfSubProgram(fd, DtoDwarfCompileUnit(gIR->dmodule)); | |
557 } | |
558 | |
559 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
560 | |
561 LLGlobalVariable* DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd) | |
562 { | |
563 // FIXME: duplicates ? | |
564 return dwarfGlobalVariable(ll, vd); | |
565 } | |
566 | |
567 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
568 | |
569 void DtoDwarfFuncStart(FuncDeclaration* fd) | |
570 { | |
571 assert(fd->ir.irFunc->dwarfSubProg); | |
572 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); | |
573 } | |
574 | |
575 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
576 | |
577 void DtoDwarfFuncEnd(FuncDeclaration* fd) | |
578 { | |
579 assert(fd->ir.irFunc->dwarfSubProg); | |
580 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), DBG_CAST(fd->ir.irFunc->dwarfSubProg)); | |
581 } | |
582 | |
583 ////////////////////////////////////////////////////////////////////////////////////////////////// | |
584 | |
585 void DtoDwarfStopPoint(unsigned ln) | |
586 { | |
587 LLSmallVector<LLValue*,3> args; | |
588 args.push_back(DtoConstUint(ln)); | |
589 args.push_back(DtoConstUint(0)); | |
590 FuncDeclaration* fd = gIR->func()->decl; | |
591 args.push_back(DBG_CAST(DtoDwarfCompileUnit(fd->getModule()))); | |
592 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end()); | |
593 } |