Wiki Roadmap Timeline Tickets New Ticket Source Search Help / Guide About Trac Login

root/gen/todebug.cpp

Revision 1650:40bd4a0d4870, 20.2 kB (checked in by Tomas Lindquist Olsen, 2 years ago)

Update to work with LLVM 2.7.

Removed use of dyn_cast, llvm no compiles
without exceptions and rtti by
default. We do need exceptions for the libconfig stuff, but rtti isn't
necessary (anymore).

Debug info needs to be rewritten, as in LLVM 2.7 the format has
completely changed. To have something to look at while rewriting, the
old code has been wrapped inside #ifndef DISABLE_DEBUG_INFO , this means
that you have to define this to compile at the moment.

Updated tango 0.99.9 patch to include updated EH runtime code, which is
needed for LLVM 2.7 as well.

Line 
1 #include "gen/llvm.h"
2 #include "llvm/Support/Dwarf.h"
3 #include "llvm/CodeGen/MachineModuleInfo.h"
4 #include "llvm/System/Path.h"
5
6 #include "declaration.h"
7 #include "module.h"
8 #include "mars.h"
9
10 #include "gen/todebug.h"
11 #include "gen/irstate.h"
12 #include "gen/tollvm.h"
13 #include "gen/logger.h"
14 #include "gen/llvmhelpers.h"
15 #include "gen/linkage.h"
16 #include "gen/utils.h"
17
18 #include "ir/irmodule.h"
19
20 using namespace llvm::dwarf;
21
22 #ifndef DISABLE_DEBUG_INFO
23
24 #define DBG_NULL    ( LLConstant::getNullValue(DBG_TYPE) )
25 #define DBG_TYPE    ( getPtrToType(llvm::StructType::get(gIR->context(),NULL,NULL)) )
26 #define DBG_CAST(X) ( llvm::ConstantExpr::getBitCast(X, DBG_TYPE) )
27
28 #define DBG_TAG(X)  ( llvm::ConstantExpr::getAdd( DtoConstUint( X ), DtoConstUint( llvm::LLVMDebugVersion ) ) )
29
30 //////////////////////////////////////////////////////////////////////////////////////////////////
31
32 /**
33  * Emits a global variable, LLVM Dwarf style, only declares.
34  * @param type Type of variable.
35  * @param name Name.
36  * @return The global variable.
37  */
38 static LLGlobalVariable* emitDwarfGlobalDecl(const LLStructType* type, const char* name, bool linkonce=false)
39 {
40     LLGlobalValue::LinkageTypes linkage = linkonce
41         ? DEBUGINFO_LINKONCE_LINKAGE_TYPE
42         : LLGlobalValue::InternalLinkage;
43     LLGlobalVariable* gv = new LLGlobalVariable(*gIR->module, type, true, linkage, NULL, name);
44     gv->setSection("llvm.metadata");
45     return gv;
46 }
47
48 //////////////////////////////////////////////////////////////////////////////////////////////////
49
50 static const llvm::StructType* getDwarfCompileUnitType() {
51     return isaStruct(gIR->module->getTypeByName("llvm.dbg.compile_unit.type"));
52 }
53
54 static const llvm::StructType* getDwarfSubProgramType() {
55     return isaStruct(gIR->module->getTypeByName("llvm.dbg.subprogram.type"));
56 }
57
58 static const llvm::StructType* getDwarfVariableType() {
59     return isaStruct(gIR->module->getTypeByName("llvm.dbg.variable.type"));
60 }
61
62 static const llvm::StructType* getDwarfDerivedTypeType() {
63     return isaStruct(gIR->module->getTypeByName("llvm.dbg.derivedtype.type"));
64 }
65
66 static const llvm::StructType* getDwarfBasicTypeType() {
67     return isaStruct(gIR->module->getTypeByName("llvm.dbg.basictype.type"));
68 }
69
70 static const llvm::StructType* getDwarfCompositeTypeType() {
71     return isaStruct(gIR->module->getTypeByName("llvm.dbg.compositetype.type"));
72 }
73
74 static const llvm::StructType* getDwarfGlobalVariableType() {
75     return isaStruct(gIR->module->getTypeByName("llvm.dbg.global_variable.type"));
76 }
77
78 //////////////////////////////////////////////////////////////////////////////////////////////////
79
80 // get the module the symbol is in, or - for template instances - the current module
81 static Module* getDefinedModule(Dsymbol* s)
82 {
83     // templates are defined in current module
84     if (DtoIsTemplateInstance(s))
85     {
86         return gIR->dmodule;
87     }
88     // array operations as well
89     else if (FuncDeclaration* fd = s->isFuncDeclaration())
90     {
91         if (fd->isArrayOp)
92             return gIR->dmodule;
93     }
94     // otherwise use the symbol's module
95     return s->getModule();
96 }
97
98 //////////////////////////////////////////////////////////////////////////////////////////////////
99
100 static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name);
101 static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name);
102
103 //////////////////////////////////////////////////////////////////////////////////////////////////
104
105 static llvm::DIBasicType dwarfBasicType(Type* type, llvm::DICompileUnit compileUnit)
106 {
107     Type* t = type->toBasetype();
108     const LLType* T = DtoType(type);
109
110     // find encoding
111     unsigned id;
112     if (t->isintegral())
113     {
114         if (type->isunsigned())
115             id = DW_ATE_unsigned;
116         else
117             id = DW_ATE_signed;
118     }
119     else if (t->isfloating())
120     {
121         id = DW_ATE_float;
122     }
123     else
124     {
125         assert(0 && "unsupported basictype for debug info");
126     }
127
128     return gIR->difactory.CreateBasicType(
129         compileUnit, // context
130         type->toChars(), // name
131         llvm::DICompileUnit(NULL), // compile unit
132         0, // line number
133         getTypeBitSize(T), // size (bits)
134         getABITypeAlign(T)*8, // align (bits)
135         0, // offset (bits)
136 //FIXME: need flags?
137         0, // flags
138         id // encoding
139     );
140 }
141
142 //////////////////////////////////////////////////////////////////////////////////////////////////
143
144 static llvm::DIDerivedType dwarfDerivedType(Type* type, llvm::DICompileUnit compileUnit)
145 {
146     const LLType* T = DtoType(type);
147     Type* t = type->toBasetype();
148
149     assert(t->ty == Tpointer && "unsupported derivedtype for debug info, only pointers allowed");
150
151     // find base type
152     llvm::DIType basetype;
153     Type* nt = t->nextOf();
154     basetype = dwarfTypeDescription_impl(nt, compileUnit, NULL);
155     if (nt->ty == Tvoid)
156         basetype = llvm::DIType(NULL);
157
158     return gIR->difactory.CreateDerivedType(
159         DW_TAG_pointer_type, // tag
160         compileUnit, // context
161         "", // name
162         llvm::DICompileUnit(NULL), // compile unit
163         0, // line number
164         getTypeBitSize(T), // size (bits)
165         getABITypeAlign(T)*8, // align (bits)
166         0, // offset (bits)
167 //FIXME: need flags?
168         0, // flags
169         basetype // derived from
170     );
171 }
172
173 //////////////////////////////////////////////////////////////////////////////////////////////////
174
175 static llvm::DIDerivedType dwarfMemberType(unsigned linnum, Type* type, llvm::DICompileUnit compileUnit, llvm::DICompileUnit definedCU, const char* c_name, unsigned offset)
176 {
177     const LLType* T = DtoType(type);
178     Type* t = type->toBasetype();
179
180     // find base type
181     llvm::DIType basetype;
182     basetype = dwarfTypeDescription(t, compileUnit, NULL);
183     if (t->ty == Tvoid)
184         basetype = llvm::DIType(NULL);
185
186     return gIR->difactory.CreateDerivedType(
187         DW_TAG_member, // tag
188         compileUnit, // context
189         c_name, // name
190         definedCU, // compile unit
191         linnum, // line number
192         getTypeBitSize(T), // size (bits)
193         getABITypeAlign(T)*8, // align (bits)
194         offset*8, // offset (bits)
195 //FIXME: need flags?
196         0, // flags
197         basetype // derived from
198     );
199 }
200
201 //////////////////////////////////////////////////////////////////////////////////////////////////
202
203 static void add_base_fields(
204     ClassDeclaration* sd,
205     llvm::DICompileUnit compileUnit,
206     llvm::DICompileUnit definedCU,
207     std::vector<LLConstant*>& elems)
208 {
209     if (sd->baseClass)
210     {
211         add_base_fields(sd->baseClass, compileUnit, definedCU, elems);
212     }
213
214     ArrayIter<VarDeclaration> it(sd->fields);
215     size_t narr = sd->fields.dim;
216     elems.reserve(narr);
217     for (; !it.done(); it.next())
218     {
219         VarDeclaration* vd = it.get();
220         LLGlobalVariable* ptr = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, definedCU, vd->toChars(), vd->offset).getGV();
221         elems.push_back(DBG_CAST(ptr));
222     }
223 }
224
225 //FIXME: This does not use llvm's DIFactory as it can't
226 //   handle recursive types properly.
227 static llvm::DICompositeType dwarfCompositeType(Type* type, llvm::DICompileUnit compileUnit)
228 {
229     const LLType* T = DtoType(type);
230     Type* t = type->toBasetype();
231
232     // defaults
233     LLConstant* name = getNullPtr(getVoidPtrType());
234     LLGlobalVariable* members = NULL;
235     unsigned linnum = 0;
236     llvm::DICompileUnit definedCU;
237
238     // prepare tag and members
239     unsigned tag;
240
241     // declare final global variable
242     LLGlobalVariable* gv = NULL;
243
244     // dynamic array
245     if (t->ty == Tarray)
246     {
247         tag = DW_TAG_structure_type;
248
249         LLGlobalVariable* len = dwarfMemberType(0, Type::tsize_t, compileUnit, llvm::DICompileUnit(NULL), "length", 0).getGV();
250         assert(len);
251         LLGlobalVariable* ptr = dwarfMemberType(0, t->nextOf()->pointerTo(), compileUnit, llvm::DICompileUnit(NULL), "ptr", global.params.is64bit?8:4).getGV();
252         assert(ptr);
253
254         const LLArrayType* at = LLArrayType::get(DBG_TYPE, 2);
255
256         std::vector<LLConstant*> elems(2);
257         elems[0] = DBG_CAST(len);
258         elems[1] = DBG_CAST(ptr);
259
260         LLConstant* ca = LLConstantArray::get(at, elems);
261         members = new LLGlobalVariable(*gIR->module, ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array");
262         members->setSection("llvm.metadata");
263
264         name = DtoConstStringPtr(t->toChars(), "llvm.metadata");
265     }
266
267     // struct/class
268     else if (t->ty == Tstruct || t->ty == Tclass)
269     {
270         AggregateDeclaration* sd;
271         if (t->ty == Tstruct)
272         {
273             TypeStruct* ts = (TypeStruct*)t;
274             sd = ts->sym;
275         }
276         else
277         {
278             TypeClass* tc = (TypeClass*)t;
279             sd = tc->sym;
280         }
281         assert(sd);
282
283         // make sure it's resolved
284         sd->codegen(Type::sir);
285
286         // if we don't know the aggregate's size, we don't know enough about it
287         // to provide debug info. probably a forward-declared struct?
288         if (sd->sizeok == 0)
289             return llvm::DICompositeType(NULL);
290
291         IrStruct* ir = sd->ir.irStruct;
292         assert(ir);
293         if (!ir->diCompositeType.isNull())
294             return ir->diCompositeType;
295
296         // set to handle recursive types properly
297         gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype");
298         // set bogus initializer to satisfy asserts in DICompositeType constructor
299         std::vector<LLConstant*> initvals(11);
300         initvals[0] = DBG_TAG(DW_TAG_structure_type);
301         for (int i = 1; i < initvals.size(); ++i)
302             initvals[i] = LLConstant::getNullValue(getDwarfCompositeTypeType()->getContainedType(i));
303         gv->setInitializer(LLConstantStruct::get(getDwarfCompositeTypeType(), initvals));
304         ir->diCompositeType = llvm::DICompositeType(gv);
305
306         tag = DW_TAG_structure_type;
307
308         name = DtoConstStringPtr(sd->toChars(), "llvm.metadata");
309         linnum = sd->loc.linnum;
310         definedCU = DtoDwarfCompileUnit(getDefinedModule(sd));
311
312         std::vector<LLConstant*> elems;
313         if (!ir->aggrdecl->isInterfaceDeclaration()) // plain interfaces don't have one
314         {
315             if (t->ty == Tstruct)
316             {
317                 ArrayIter<VarDeclaration> it(sd->fields);
318                 size_t narr = sd->fields.dim;
319                 elems.reserve(narr);
320                 for (; !it.done(); it.next())
321                 {
322                     VarDeclaration* vd = it.get();
323                     LLGlobalVariable* ptr = dwarfMemberType(vd->loc.linnum, vd->type, compileUnit, definedCU, vd->toChars(), vd->offset).getGV();
324                     elems.push_back(DBG_CAST(ptr));
325                 }
326             }
327             else
328             {
329                 add_base_fields(ir->aggrdecl->isClassDeclaration(), compileUnit, definedCU, elems);
330             }
331         }
332
333         const LLArrayType* at = LLArrayType::get(DBG_TYPE, elems.size());
334         LLConstant* ca = LLConstantArray::get(at, elems);
335         members = new LLGlobalVariable(*gIR->module, ca->getType(), true, LLGlobalValue::InternalLinkage, ca, ".array");
336         members->setSection("llvm.metadata");
337     }
338
339     // unsupported composite type
340     else
341     {
342         assert(0 && "unsupported compositetype for debug info");
343     }
344
345     std::vector<LLConstant*> vals(11);
346
347     // tag
348     vals[0] = DBG_TAG(tag);
349
350     // context
351     vals[1] = DBG_CAST(compileUnit.getGV());
352
353     // name
354     vals[2] = name;
355
356     // compile unit where defined
357     if (definedCU.getGV())
358         vals[3] = DBG_CAST(definedCU.getGV());
359     else
360         vals[3] = DBG_NULL;
361
362     // line number where defined
363     vals[4] = DtoConstInt(linnum);
364
365     // size in bits
366     vals[5] = LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getTypeBitSize(T), false);
367
368     // alignment in bits
369     vals[6] = LLConstantInt::get(LLType::getInt64Ty(gIR->context()), getABITypeAlign(T)*8, false);
370
371     // offset in bits
372     vals[7] = LLConstantInt::get(LLType::getInt64Ty(gIR->context()), 0, false);
373
374     // FIXME: dont know what this is
375     vals[8] = DtoConstUint(0);
376
377     // FIXME: ditto
378     vals[9] = DBG_NULL;
379
380     // members array
381     if (members)
382         vals[10] = DBG_CAST(members);
383     else
384         vals[10] = DBG_NULL;
385
386     // set initializer
387     if (!gv)
388         gv = emitDwarfGlobalDecl(getDwarfCompositeTypeType(), "llvm.dbg.compositetype");
389     LLConstant* initia = LLConstantStruct::get(getDwarfCompositeTypeType(), vals);
390     gv->setInitializer(initia);
391
392     return llvm::DICompositeType(gv);
393 }
394
395 //////////////////////////////////////////////////////////////////////////////////////////////////
396
397 static llvm::DIGlobalVariable dwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd)
398 {
399 #if DMDV2
400     assert(vd->isDataseg() || (vd->storage_class & (STCconst | STCimmutable) && vd->init));
401 #else
402     assert(vd->isDataseg());
403 #endif
404     llvm::DICompileUnit compileUnit = DtoDwarfCompileUnit(gIR->dmodule);
405
406     return gIR->difactory.CreateGlobalVariable(
407         compileUnit, // context
408         vd->mangle(), // name
409         vd->toPrettyChars(), // displayname
410         vd->toChars(), // linkage name
411         DtoDwarfCompileUnit(getDefinedModule(vd)), // compile unit
412         vd->loc.linnum, // line num
413         dwarfTypeDescription_impl(vd->type, compileUnit, NULL), // type
414         vd->protection == PROTprivate, // is local to unit
415         getDefinedModule(vd) == gIR->dmodule, // is definition
416         ll // value
417     );
418 }
419
420 //////////////////////////////////////////////////////////////////////////////////////////////////
421
422 static llvm::DIVariable dwarfVariable(VarDeclaration* vd, llvm::DIType type)
423 {
424     assert(!vd->isDataseg() && "static variable");
425
426     unsigned tag;
427     if (vd->isParameter())
428         tag = DW_TAG_arg_variable;
429     else
430         tag = DW_TAG_auto_variable;
431
432     return gIR->difactory.CreateVariable(
433         tag, // tag
434         gIR->func()->diSubprogram, // context
435         vd->toChars(), // name
436         DtoDwarfCompileUnit(getDefinedModule(vd)), // compile unit
437         vd->loc.linnum, // line num
438         type // type
439     );
440 }
441
442 //////////////////////////////////////////////////////////////////////////////////////////////////
443
444 static void dwarfDeclare(LLValue* var, llvm::DIVariable divar)
445 {
446     gIR->difactory.InsertDeclare(var, divar, gIR->scopebb());
447 }
448
449 //////////////////////////////////////////////////////////////////////////////////////////////////
450
451 static llvm::DIType dwarfTypeDescription_impl(Type* type, llvm::DICompileUnit cu, const char* c_name)
452 {
453     Type* t = type->toBasetype();
454     if (t->ty == Tvoid)
455         return llvm::DIType(NULL);
456     else if (t->isintegral() || t->isfloating())
457         return dwarfBasicType(type, cu);
458     else if (t->ty == Tpointer)
459         return dwarfDerivedType(type, cu);
460     else if (t->ty == Tarray || t->ty == Tstruct || t->ty == Tclass)
461         return dwarfCompositeType(type, cu);
462
463     return llvm::DIType(NULL);
464 }
465
466 static llvm::DIType dwarfTypeDescription(Type* type, llvm::DICompileUnit cu, const char* c_name)
467 {
468     Type* t = type->toBasetype();
469     if (t->ty == Tclass)
470         return dwarfTypeDescription_impl(type->pointerTo(), cu, c_name);
471     else
472         return dwarfTypeDescription_impl(type, cu, c_name);
473 }
474
475 //////////////////////////////////////////////////////////////////////////////////////////////////
476
477 void DtoDwarfLocalVariable(LLValue* ll, VarDeclaration* vd)
478 {
479     Logger::println("D to dwarf local variable");
480     LOG_SCOPE;
481
482     // get compile units
483     llvm::DICompileUnit thisCU = DtoDwarfCompileUnit(gIR->dmodule);
484     llvm::DICompileUnit varCU = DtoDwarfCompileUnit(getDefinedModule(vd));
485
486     // get type description
487     llvm::DIType TD = dwarfTypeDescription(vd->type, thisCU, NULL);
488     if (TD.isNull())
489         return; // unsupported
490
491     // get variable description
492     llvm::DIVariable VD = dwarfVariable(vd, TD);
493
494     // declare
495     dwarfDeclare(ll, VD);
496 }
497
498 //////////////////////////////////////////////////////////////////////////////////////////////////
499
500 llvm::DICompileUnit DtoDwarfCompileUnit(Module* m)
501 {
502     Logger::println("D to dwarf compile_unit");
503     LOG_SCOPE;
504
505     // we might be generating for an import
506     IrModule* irmod = getIrModule(m);
507
508     if (!irmod->diCompileUnit.isNull())
509     {
510         assert (irmod->diCompileUnit.getGV()->getParent() == gIR->module
511             && "debug info compile unit belongs to incorrect llvm module!");
512         return irmod->diCompileUnit;
513     }
514
515     // prepare srcpath
516     std::string srcpath(FileName::path(m->srcfile->name->toChars()));
517     if (!FileName::absolute(srcpath.c_str())) {
518         llvm::sys::Path tmp = llvm::sys::Path::GetCurrentDirectory();
519         tmp.appendComponent(srcpath);
520         srcpath = tmp.toString();
521         if (!srcpath.empty() && *srcpath.rbegin() != '/' && *srcpath.rbegin() != '\\')
522             srcpath = srcpath + '/';
523     }
524
525     // make compile unit
526     irmod->diCompileUnit = gIR->difactory.CreateCompileUnit(
527         global.params.symdebug == 2 ? DW_LANG_C : DW_LANG_D,
528         m->srcfile->name->toChars(),
529         srcpath,
530         "LDC (http://www.dsource.org/projects/ldc)",
531 //FIXME: What do these two mean?
532         false, // isMain,
533         false // isOptimized
534     );
535
536     // if the linkage stays internal, we can't llvm-link the generated modules together:
537     // llvm's DwarfWriter uses path and filename to determine the symbol name and we'd
538     // end up with duplicate symbols
539     irmod->diCompileUnit.getGV()->setLinkage(DEBUGINFO_LINKONCE_LINKAGE_TYPE);
540     irmod->diCompileUnit.getGV()->setName(std::string("llvm.dbg.compile_unit_") + srcpath + m->srcfile->name->toChars());
541
542     return irmod->diCompileUnit;
543 }
544
545 //////////////////////////////////////////////////////////////////////////////////////////////////
546
547 llvm::DISubprogram DtoDwarfSubProgram(FuncDeclaration* fd)
548 {
549     Logger::println("D to dwarf subprogram");
550     LOG_SCOPE;
551
552     llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule);
553     llvm::DICompileUnit definition = DtoDwarfCompileUnit(getDefinedModule(fd));
554
555     // FIXME: duplicates ?
556     return gIR->difactory.CreateSubprogram(
557         context, // context
558         fd->toPrettyChars(), // name
559         fd->toPrettyChars(), // display name
560         fd->mangle(), // linkage name
561         definition, // compile unit
562         fd->loc.linnum, // line no
563 //FIXME: what's this type for?
564         llvm::DIType(NULL), // type
565         fd->protection == PROTprivate, // is local to unit
566         context.getGV() == definition.getGV() // isdefinition
567     );
568 }
569
570 //////////////////////////////////////////////////////////////////////////////////////////////////
571
572 llvm::DISubprogram DtoDwarfSubProgramInternal(const char* prettyname, const char* mangledname)
573 {
574     Logger::println("D to dwarf subprogram");
575     LOG_SCOPE;
576
577     llvm::DICompileUnit context = DtoDwarfCompileUnit(gIR->dmodule);
578
579     // FIXME: duplicates ?
580     return gIR->difactory.CreateSubprogram(
581         context, // context
582         prettyname, // name
583         prettyname, // display name
584         mangledname, // linkage name
585         context, // compile unit
586         0, // line no
587 //FIXME: what's this type for?
588         llvm::DIType(NULL), // type
589         true, // is local to unit
590         true // isdefinition
591     );
592 }
593
594 //////////////////////////////////////////////////////////////////////////////////////////////////
595
596 llvm::DIGlobalVariable DtoDwarfGlobalVariable(LLGlobalVariable* ll, VarDeclaration* vd)
597 {
598     Logger::println("D to dwarf global_variable");
599     LOG_SCOPE;
600
601     // FIXME: duplicates ?
602     return dwarfGlobalVariable(ll, vd);
603 }
604
605 //////////////////////////////////////////////////////////////////////////////////////////////////
606
607 void DtoDwarfFuncStart(FuncDeclaration* fd)
608 {
609     Logger::println("D to dwarf funcstart");
610     LOG_SCOPE;
611
612     assert(!fd->ir.irFunc->diSubprogram.isNull());
613     gIR->difactory.InsertSubprogramStart(fd->ir.irFunc->diSubprogram, gIR->scopebb());
614 }
615
616 //////////////////////////////////////////////////////////////////////////////////////////////////
617
618 void DtoDwarfFuncEnd(FuncDeclaration* fd)
619 {
620     Logger::println("D to dwarf funcend");
621     LOG_SCOPE;
622
623     assert(!fd->ir.irFunc->diSubprogram.isNull());
624     gIR->difactory.InsertRegionEnd(fd->ir.irFunc->diSubprogram, gIR->scopebb());
625 }
626
627 //////////////////////////////////////////////////////////////////////////////////////////////////
628
629 void DtoDwarfStopPoint(unsigned ln)
630 {
631     Logger::println("D to dwarf stoppoint at line %u", ln);
632     LOG_SCOPE;
633
634     gIR->difactory.InsertStopPoint(
635         DtoDwarfCompileUnit(getDefinedModule(gIR->func()->decl)), // compile unit
636         ln, // line no
637         0, // col no
638         gIR->scopebb()
639     );
640 }
641
642 #endif
Note: See TracBrowser for help on using the browser.
Copyright © 2008, LDC Development Team.