comparison gen/todebug.cpp @ 86:fd32135dca3e trunk

[svn r90] Major updates to the gen directory. Redesigned the 'elem' struct. Much more... !!! Lots of bugfixes. Added support for special foreach on strings. Added std.array, std.utf, std.ctype and std.uni to phobos. Changed all the .c files in the gen dir to .cpp (it *is* C++ after all)
author lindquist
date Sat, 03 Nov 2007 14:44:58 +0100
parents gen/todebug.c@d8dd47ef3973
children 61615fa85940
comparison
equal deleted inserted replaced
85:f869c636a113 86:fd32135dca3e
1 #include "gen/llvm.h"
2 #include "llvm/Support/Dwarf.h"
3 #include "llvm/CodeGen/MachineModuleInfo.h"
4
5 #include "declaration.h"
6 #include "module.h"
7 #include "mars.h"
8
9 #include "gen/todebug.h"
10 #include "gen/irstate.h"
11 #include "gen/tollvm.h"
12 #include "gen/logger.h"
13
14 using namespace llvm::dwarf;
15
16 static const llvm::PointerType* ptrTy(const llvm::Type* t)
17 {
18 return llvm::PointerType::get(t);
19 }
20
21 static const llvm::PointerType* dbgArrTy()
22 {
23 std::vector<const llvm::Type*> t;
24 return ptrTy(llvm::StructType::get(t));
25 }
26
27 static llvm::Constant* dbgToArrTy(llvm::Constant* c)
28 {
29 Logger::cout() << "casting: " << *c << '\n';
30 return llvm::ConstantExpr::getBitCast(c, dbgArrTy());
31 }
32
33 #define Ty(X) llvm::Type::X
34
35 //////////////////////////////////////////////////////////////////////////////////////////////////
36
37 static llvm::GlobalVariable* dbg_compile_units = 0;
38 static llvm::GlobalVariable* dbg_global_variables = 0;
39 static llvm::GlobalVariable* dbg_subprograms = 0;
40
41 const llvm::StructType* GetDwarfAnchorType()
42 {
43 /*
44 %llvm.dbg.anchor.type = type {
45 uint, ;; Tag = 0 + LLVMDebugVersion
46 uint ;; Tag of descriptors grouped by the anchor
47 }
48 */
49 std::vector<const llvm::Type*> elems(2, Ty(Int32Ty));
50 const llvm::StructType* t = llvm::cast<llvm::StructType>(gIR->module->getTypeByName("llvm.dbg.anchor.type"));
51
52 /*
53 %llvm.dbg.compile_units = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 17 } ;; DW_TAG_compile_unit
54 %llvm.dbg.global_variables = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 52 } ;; DW_TAG_variable
55 %llvm.dbg.subprograms = linkonce constant %llvm.dbg.anchor.type { uint 0, uint 46 } ;; DW_TAG_subprogram
56 */
57 if (!gIR->module->getNamedGlobal("llvm.dbg.compile_units")) {
58 std::vector<llvm::Constant*> vals;
59 vals.push_back(DtoConstUint(0));
60 vals.push_back(DtoConstUint(DW_TAG_compile_unit));
61 llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
62 dbg_compile_units = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.compile_units",gIR->module);
63 dbg_compile_units->setSection("llvm.metadata");
64 }
65 if (!gIR->module->getNamedGlobal("llvm.dbg.global_variables")) {
66 std::vector<llvm::Constant*> vals;
67 vals.push_back(DtoConstUint(0));
68 vals.push_back(DtoConstUint(DW_TAG_variable));
69 llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
70 dbg_global_variables = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.global_variables",gIR->module);
71 dbg_global_variables->setSection("llvm.metadata");
72 }
73 if (!gIR->module->getNamedGlobal("llvm.dbg.subprograms")) {
74 std::vector<llvm::Constant*> vals;
75 vals.push_back(DtoConstUint(0));
76 vals.push_back(DtoConstUint(DW_TAG_subprogram));
77 llvm::Constant* i = llvm::ConstantStruct::get(t, vals);
78 dbg_subprograms = new llvm::GlobalVariable(t,true,llvm::GlobalValue::LinkOnceLinkage,i,"llvm.dbg.subprograms",gIR->module);
79 dbg_subprograms->setSection("llvm.metadata");
80 }
81
82 return t;
83 }
84
85 llvm::Constant* GetDwarfAnchor(llvm::dwarf::dwarf_constants c)
86 {
87 GetDwarfAnchorType();
88 switch (c)
89 {
90 case DW_TAG_compile_unit:
91 return dbg_compile_units;
92 case DW_TAG_variable:
93 return dbg_global_variables;
94 case DW_TAG_subprogram:
95 return dbg_subprograms;
96 }
97 assert(0);
98 return 0;
99 }
100
101 //////////////////////////////////////////////////////////////////////////////////////////////////
102
103 const llvm::StructType* GetDwarfCompileUnitType() {
104 return llvm::cast<llvm::StructType>(gIR->module->getTypeByName("llvm.dbg.compile_unit.type"));
105 }
106
107 const llvm::StructType* GetDwarfSubProgramType() {
108 return llvm::cast<llvm::StructType>(gIR->module->getTypeByName("llvm.dbg.subprogram.type"));
109 }
110
111 //////////////////////////////////////////////////////////////////////////////////////////////////
112
113 llvm::GlobalVariable* DtoDwarfCompileUnit(Module* m)
114 {
115 std::vector<llvm::Constant*> vals;
116 vals.push_back(llvm::ConstantExpr::getAdd(
117 DtoConstUint(DW_TAG_compile_unit),
118 DtoConstUint(llvm::LLVMDebugVersion)));
119 vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_compile_unit)));
120
121 vals.push_back(DtoConstUint(DW_LANG_D));
122 vals.push_back(DtoConstStringPtr(m->srcfile->name->toChars(), "llvm.metadata"));
123 std::string srcpath(FileName::path(m->srcfile->name->toChars()));
124 srcpath.append("/");
125 vals.push_back(DtoConstStringPtr(srcpath.c_str(), "llvm.metadata"));
126 vals.push_back(DtoConstStringPtr("LLVMDC (http://www.dsource.org/projects/llvmdc)", "llvm.metadata"));
127
128 llvm::Constant* c = llvm::ConstantStruct::get(GetDwarfCompileUnitType(), vals);
129 llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.compile_unit", gIR->module);
130 gv->setSection("llvm.metadata");
131 return gv;
132 }
133
134 //////////////////////////////////////////////////////////////////////////////////////////////////
135
136 llvm::GlobalVariable* DtoDwarfSubProgram(FuncDeclaration* fd)
137 {
138 std::vector<llvm::Constant*> vals;
139 vals.push_back(llvm::ConstantExpr::getAdd(
140 DtoConstUint(DW_TAG_subprogram),
141 DtoConstUint(llvm::LLVMDebugVersion)));
142 vals.push_back(dbgToArrTy(GetDwarfAnchor(DW_TAG_subprogram)));
143
144 vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
145 vals.push_back(DtoConstStringPtr(fd->toPrettyChars(), "llvm.metadata"));
146 vals.push_back(DtoConstStringPtr(fd->mangle(), "llvm.metadata"));
147 vals.push_back(llvm::ConstantPointerNull::get(llvm::PointerType::get(llvm::Type::Int8Ty)));
148 vals.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
149 vals.push_back(DtoConstUint(fd->loc.linnum));
150 vals.push_back(llvm::ConstantPointerNull::get(dbgArrTy()));
151 vals.push_back(DtoConstBool(fd->protection == PROTprivate));
152 vals.push_back(DtoConstBool(fd->getModule() == gIR->dmodule));
153
154 llvm::Constant* c = llvm::ConstantStruct::get(GetDwarfSubProgramType(), vals);
155 llvm::GlobalVariable* gv = new llvm::GlobalVariable(c->getType(), true, llvm::GlobalValue::InternalLinkage, c, "llvm.dbg.subprogram", gIR->module);
156 gv->setSection("llvm.metadata");
157 return gv;
158 }
159
160 //////////////////////////////////////////////////////////////////////////////////////////////////
161
162 void DtoDwarfFuncStart(FuncDeclaration* fd)
163 {
164 assert(fd->llvmDwarfSubProgram);
165 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.func.start"), dbgToArrTy(fd->llvmDwarfSubProgram));
166 }
167
168 void DtoDwarfFuncEnd(FuncDeclaration* fd)
169 {
170 assert(fd->llvmDwarfSubProgram);
171 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.region.end"), dbgToArrTy(fd->llvmDwarfSubProgram));
172 }
173
174 //////////////////////////////////////////////////////////////////////////////////////////////////
175
176 void DtoDwarfStopPoint(unsigned ln)
177 {
178 std::vector<llvm::Value*> args;
179 args.push_back(DtoConstUint(ln));
180 args.push_back(DtoConstUint(0));
181 args.push_back(dbgToArrTy(gIR->dwarfCompileUnit));
182 gIR->ir->CreateCall(gIR->module->getFunction("llvm.dbg.stoppoint"), args.begin(), args.end());
183 }