Emit file directives correctly in case of a .bc is generated by llvm-ld after linking...
[oota-llvm.git] / lib / Target / PIC16 / PIC16DebugInfo.cpp
1 //===-- PIC16DebugInfo.cpp - Implementation for PIC16 Debug Information ======//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file is distributed under the University of Illinois Open Source 
6 // License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // This file contains the helper functions for representing debug information.
11 //
12 //===----------------------------------------------------------------------===//
13
14 #include "PIC16.h"
15 #include "PIC16DebugInfo.h" 
16 #include "llvm/GlobalVariable.h"
17 #include "llvm/Support/raw_ostream.h"
18
19 using namespace llvm;
20
21 PIC16DbgInfo::~PIC16DbgInfo() {
22   for(std::map<std::string, DISubprogram *>::iterator i = FunctNameMap.begin();
23       i!=FunctNameMap.end(); i++) 
24     delete i->second;
25   FunctNameMap.clear();
26 }
27
28 void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo,
29                                      bool &HasAux, int Aux[], 
30                                      std::string &TypeName) {
31   if (Ty.isBasicType(Ty.getTag())) {
32     std::string Name = "";
33     Ty.getName(Name);
34     unsigned short BaseTy = GetTypeDebugNumber(Name);
35     TypeNo = TypeNo << PIC16Dbg::S_BASIC;
36     TypeNo = TypeNo | (0xffff & BaseTy);
37   }
38   else if (Ty.isDerivedType(Ty.getTag())) {
39     switch(Ty.getTag())
40     {
41       case dwarf::DW_TAG_pointer_type:
42         TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
43         TypeNo = TypeNo | PIC16Dbg::DT_PTR;
44         break;
45       default:
46         TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
47     }
48     DIType BaseType = DIDerivedType(Ty.getGV()).getTypeDerivedFrom();
49     PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName);
50   }
51   else if (Ty.isCompositeType(Ty.getTag())) {
52     switch (Ty.getTag()) {
53       case dwarf::DW_TAG_array_type: {
54         DICompositeType CTy = DICompositeType(Ty.getGV());
55         DIArray Elements = CTy.getTypeArray();
56         unsigned short size = 1;
57         unsigned short Dimension[4]={0,0,0,0};
58         for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
59           DIDescriptor Element = Elements.getElement(i);
60           if (Element.getTag() == dwarf::DW_TAG_subrange_type) {
61             TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
62             TypeNo = TypeNo | PIC16Dbg::DT_ARY;
63             DISubrange SubRange = DISubrange(Element.getGV());
64             Dimension[i] = SubRange.getHi() - SubRange.getLo() + 1;
65             // Each dimension is represented by 2 bytes starting at byte 9.
66             Aux[8+i*2+0] = Dimension[i];
67             Aux[8+i*2+1] = Dimension[i] >> 8;
68             size = size * Dimension[i];
69           }
70         }
71         HasAux = true;
72         // In auxillary entry for array, 7th and 8th byte represent array size.
73         Aux[6] = size;
74         Aux[7] = size >> 8;
75         DIType BaseType = CTy.getTypeDerivedFrom();
76         PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName);
77
78         break;
79       }
80       case dwarf:: DW_TAG_union_type:
81       case dwarf::DW_TAG_structure_type: {
82         DICompositeType CTy = DICompositeType(Ty.getGV());
83         TypeNo = TypeNo << PIC16Dbg::S_BASIC;
84         if (Ty.getTag() == dwarf::DW_TAG_structure_type)
85           TypeNo = TypeNo | PIC16Dbg::T_STRUCT;
86         else
87           TypeNo = TypeNo | PIC16Dbg::T_UNION;
88         CTy.getName(TypeName);
89         unsigned size = CTy.getSizeInBits()/8;
90         // 7th and 8th byte represent size.   
91         HasAux = true;
92         Aux[6] = size;
93         Aux[7] = size >> 8;
94         break;
95       }
96       case dwarf::DW_TAG_enumeration_type: {
97         TypeNo = TypeNo << PIC16Dbg::S_BASIC;
98         TypeNo = TypeNo | PIC16Dbg::T_ENUM;
99         break;
100       }
101       default:
102         TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
103     }
104   }
105   else {
106     TypeNo = PIC16Dbg::T_NULL;
107     HasAux = false;
108   }
109   return;
110 }
111
112
113 unsigned PIC16DbgInfo::GetTypeDebugNumber(std::string &type)  {
114   if (type == "char")
115     return PIC16Dbg::T_CHAR;
116   else if (type == "short")
117     return PIC16Dbg::T_SHORT;
118   else if (type == "int")
119     return PIC16Dbg::T_INT;
120   else if (type == "long")
121     return PIC16Dbg::T_LONG;
122   else if (type == "unsigned char")
123     return PIC16Dbg::T_UCHAR;
124   else if (type == "unsigned short")
125     return PIC16Dbg::T_USHORT;
126   else if (type == "unsigned int")
127     return PIC16Dbg::T_UINT;
128   else if (type == "unsigned long")
129     return PIC16Dbg::T_ULONG;
130   else
131     return 0;
132 }
133
134 short PIC16DbgInfo::getClass(DIGlobalVariable DIGV) {
135   short ClassNo;
136   if (PAN::isLocalName(DIGV.getGlobal()->getName())) {
137     // Generating C_AUTO here fails due to error in linker. Change it once
138     // linker is fixed.
139     ClassNo = PIC16Dbg::C_STAT;
140   }
141   else if (DIGV.isLocalToUnit())
142     ClassNo = PIC16Dbg::C_STAT;
143   else
144     ClassNo = PIC16Dbg::C_EXT;
145   return ClassNo;
146 }
147
148 void PIC16DbgInfo::PopulateFunctsDI(Module &M) {
149   GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.subprograms");
150   if (!Root)
151     return;
152   Constant *RootC = cast<Constant>(*Root->use_begin());
153
154   for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
155        UI != UE; ++UI)
156     for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
157          UUI != UUE; ++UUI) {
158       GlobalVariable *GVSP = cast<GlobalVariable>(*UUI);
159       DISubprogram *SP = new DISubprogram(GVSP);
160       std::string Name;
161       SP->getLinkageName(Name);
162       FunctNameMap[Name] = SP; 
163     }
164   return;
165 }
166
167 DISubprogram* PIC16DbgInfo::getFunctDI(std::string FunctName) {
168   return FunctNameMap[FunctName];
169 }
170
171 void PIC16DbgInfo::EmitFunctBeginDI(const Function *F) {
172   std::string FunctName = F->getName();
173   DISubprogram *SP = getFunctDI(FunctName);
174   if (SP) {
175     std::string FunctBeginSym = ".bf." + FunctName;
176     std::string BlockBeginSym = ".bb." + FunctName;
177
178     int FunctBeginLine = SP->getLineNumber();
179     int BFAux[PIC16Dbg::AuxSize] = {0};
180     BFAux[4] = FunctBeginLine;
181     BFAux[5] = FunctBeginLine >> 8;
182     // Emit debug directives for beginning of function.
183     EmitSymbol(FunctBeginSym, PIC16Dbg::C_FCN);
184     EmitAuxEntry(FunctBeginSym, BFAux, PIC16Dbg::AuxSize);
185     EmitSymbol(BlockBeginSym, PIC16Dbg::C_BLOCK);
186     EmitAuxEntry(BlockBeginSym, BFAux, PIC16Dbg::AuxSize);
187   }
188 }
189
190 void PIC16DbgInfo::EmitFunctEndDI(const Function *F, unsigned Line) {
191   std::string FunctName = F->getName();
192   DISubprogram *SP = getFunctDI(FunctName);
193   if (SP) {
194     std::string FunctEndSym = ".ef." + FunctName;
195     std::string BlockEndSym = ".eb." + FunctName;
196
197     // Emit debug directives for end of function.
198     EmitSymbol(BlockEndSym, PIC16Dbg::C_BLOCK);
199     int EFAux[PIC16Dbg::AuxSize] = {0};
200     // 5th and 6th byte stand for line number.
201     EFAux[4] = Line;
202     EFAux[5] = Line >> 8;
203     EmitAuxEntry(BlockEndSym, EFAux, PIC16Dbg::AuxSize);
204     EmitSymbol(FunctEndSym, PIC16Dbg::C_FCN);
205     EmitAuxEntry(FunctEndSym, EFAux, PIC16Dbg::AuxSize);
206   }
207 }
208
209 /// EmitAuxEntry - Emit Auxiliary debug information.
210 ///
211 void PIC16DbgInfo::EmitAuxEntry(const std::string VarName, int Aux[], int num) {
212   O << "\n\t.dim " << VarName << ", 1" ;
213   for (int i = 0; i<num; i++)
214     O << "," << Aux[i];
215 }
216
217 void PIC16DbgInfo::EmitSymbol(std::string Name, int Class) {
218   O << "\n\t" << ".def "<< Name << ", debug, class = " << Class;
219 }
220
221 void PIC16DbgInfo::EmitVarDebugInfo(Module &M) {
222   GlobalVariable *Root = M.getGlobalVariable("llvm.dbg.global_variables");
223   if (!Root)
224     return;
225
226   Constant *RootC = cast<Constant>(*Root->use_begin());
227   for (Value::use_iterator UI = RootC->use_begin(), UE = Root->use_end();
228        UI != UE; ++UI) {
229     for (Value::use_iterator UUI = UI->use_begin(), UUE = UI->use_end();
230          UUI != UUE; ++UUI) {
231       DIGlobalVariable DIGV(cast<GlobalVariable>(*UUI));
232       DIType Ty = DIGV.getType();
233       unsigned short TypeNo = 0;
234       bool HasAux = false;
235       int Aux[PIC16Dbg::AuxSize] = { 0 };
236       std::string TypeName = "";
237       std::string VarName = TAI->getGlobalPrefix()+DIGV.getGlobal()->getName();
238       PopulateDebugInfo(Ty, TypeNo, HasAux, Aux, TypeName);
239       // Emit debug info only if type information is availaible.
240       if (TypeNo != PIC16Dbg::T_NULL) {
241         O << "\n\t.type " << VarName << ", " << TypeNo;
242         short ClassNo = getClass(DIGV);
243         O << "\n\t.class " << VarName << ", " << ClassNo;
244         if (HasAux) {
245           if (TypeName != "") {
246            // Emit debug info for structure and union objects after
247            // .dim directive supports structure/union tag name in aux entry.
248            /* O << "\n\t.dim " << VarName << ", 1," << TypeName;
249             for (int i = 0; i<PIC16Dbg::AuxSize; i++)
250               O << "," << Aux[i];*/
251          }
252           else {
253             EmitAuxEntry(VarName, Aux, PIC16Dbg::AuxSize);
254           }
255         }
256       }
257     }
258   }
259   O << "\n";
260 }
261
262 void PIC16DbgInfo::EmitFileDirective(Module &M) {
263   GlobalVariable *CU = M.getNamedGlobal("llvm.dbg.compile_unit");
264   if (CU) {
265     DICompileUnit DIUnit(CU);
266     std::string Dir, FN;
267     std::string File = DIUnit.getDirectory(Dir) + "/" + DIUnit.getFilename(FN);
268     O << "\n\t.file\t\"" << File << "\"\n" ;
269     CurFile = File;
270   }
271 }
272
273 void PIC16DbgInfo::EmitFileDirective(const Function *F) {
274   std::string FunctName = F->getName();
275   DISubprogram *SP = getFunctDI(FunctName);
276   if (SP) {
277     std::string Dir, FN;
278     DICompileUnit CU = SP->getCompileUnit();
279     std::string File = CU.getDirectory(Dir) + "/" + CU.getFilename(FN);
280     if ( File != CurFile) {
281       EmitEOF();
282       O << "\n\t.file\t\"" << File << "\"\n" ;
283       CurFile = File;
284     }
285   }
286 }
287
288 void PIC16DbgInfo::EmitEOF() {
289   if (CurFile != "")
290     O << "\n\t.EOF";
291 }
292