2 //===-- PIC16DebugInfo.cpp - Implementation for PIC16 Debug Information ======//
4 // The LLVM Compiler Infrastructure
6 // This file is distributed under the University of Illinois Open Source
7 // License. See LICENSE.TXT for details.
9 //===----------------------------------------------------------------------===//
11 // This file contains the helper functions for representing debug information.
13 //===----------------------------------------------------------------------===//
16 #include "PIC16DebugInfo.h"
17 #include "llvm/GlobalVariable.h"
18 #include "llvm/CodeGen/MachineFunction.h"
19 #include "llvm/MC/MCAsmInfo.h"
20 #include "llvm/Support/DebugLoc.h"
21 #include "llvm/Support/FormattedStream.h"
22 #include "llvm/ADT/SmallString.h"
26 /// PopulateDebugInfo - Populate the TypeNo, Aux[] and TagName from Ty.
28 void PIC16DbgInfo::PopulateDebugInfo (DIType Ty
, unsigned short &TypeNo
,
29 bool &HasAux
, int Aux
[],
30 std::string
&TagName
) {
32 PopulateBasicTypeInfo (Ty
, TypeNo
);
33 else if (Ty
.isDerivedType())
34 PopulateDerivedTypeInfo (Ty
, TypeNo
, HasAux
, Aux
, TagName
);
35 else if (Ty
.isCompositeType())
36 PopulateCompositeTypeInfo (Ty
, TypeNo
, HasAux
, Aux
, TagName
);
38 TypeNo
= PIC16Dbg::T_NULL
;
44 /// PopulateBasicTypeInfo- Populate TypeNo for basic type from Ty.
46 void PIC16DbgInfo::PopulateBasicTypeInfo (DIType Ty
, unsigned short &TypeNo
) {
47 std::string Name
= "";
49 unsigned short BaseTy
= GetTypeDebugNumber(Name
);
50 TypeNo
= TypeNo
<< PIC16Dbg::S_BASIC
;
51 TypeNo
= TypeNo
| (0xffff & BaseTy
);
54 /// PopulateDerivedTypeInfo - Populate TypeNo, Aux[], TagName for derived type
55 /// from Ty. Derived types are mostly pointers.
57 void PIC16DbgInfo::PopulateDerivedTypeInfo (DIType Ty
, unsigned short &TypeNo
,
58 bool &HasAux
, int Aux
[],
59 std::string
&TagName
) {
63 case dwarf::DW_TAG_pointer_type
:
64 TypeNo
= TypeNo
<< PIC16Dbg::S_DERIVED
;
65 TypeNo
= TypeNo
| PIC16Dbg::DT_PTR
;
68 TypeNo
= TypeNo
<< PIC16Dbg::S_DERIVED
;
71 // We also need to encode the the information about the base type of
73 DIType BaseType
= DIDerivedType(Ty
.getNode()).getTypeDerivedFrom();
74 PopulateDebugInfo(BaseType
, TypeNo
, HasAux
, Aux
, TagName
);
77 /// PopulateArrayTypeInfo - Populate TypeNo, Aux[] for array from Ty.
78 void PIC16DbgInfo::PopulateArrayTypeInfo (DIType Ty
, unsigned short &TypeNo
,
79 bool &HasAux
, int Aux
[],
80 std::string
&TagName
) {
82 DICompositeType CTy
= DICompositeType(Ty
.getNode());
83 DIArray Elements
= CTy
.getTypeArray();
84 unsigned short size
= 1;
85 unsigned short Dimension
[4]={0,0,0,0};
86 for (unsigned i
= 0, N
= Elements
.getNumElements(); i
< N
; ++i
) {
87 DIDescriptor Element
= Elements
.getElement(i
);
88 if (Element
.getTag() == dwarf::DW_TAG_subrange_type
) {
89 TypeNo
= TypeNo
<< PIC16Dbg::S_DERIVED
;
90 TypeNo
= TypeNo
| PIC16Dbg::DT_ARY
;
91 DISubrange SubRange
= DISubrange(Element
.getNode());
92 Dimension
[i
] = SubRange
.getHi() - SubRange
.getLo() + 1;
93 // Each dimension is represented by 2 bytes starting at byte 9.
94 Aux
[8+i
*2+0] = Dimension
[i
];
95 Aux
[8+i
*2+1] = Dimension
[i
] >> 8;
96 size
= size
* Dimension
[i
];
100 // In auxillary entry for array, 7th and 8th byte represent array size.
101 Aux
[6] = size
& 0xff;
103 DIType BaseType
= CTy
.getTypeDerivedFrom();
104 PopulateDebugInfo(BaseType
, TypeNo
, HasAux
, Aux
, TagName
);
107 /// PopulateStructOrUnionTypeInfo - Populate TypeNo, Aux[] , TagName for
108 /// structure or union.
110 void PIC16DbgInfo::PopulateStructOrUnionTypeInfo (DIType Ty
,
111 unsigned short &TypeNo
,
112 bool &HasAux
, int Aux
[],
113 std::string
&TagName
) {
114 DICompositeType CTy
= DICompositeType(Ty
.getNode());
115 TypeNo
= TypeNo
<< PIC16Dbg::S_BASIC
;
116 if (Ty
.getTag() == dwarf::DW_TAG_structure_type
)
117 TypeNo
= TypeNo
| PIC16Dbg::T_STRUCT
;
119 TypeNo
= TypeNo
| PIC16Dbg::T_UNION
;
120 CTy
.getName(TagName
);
121 // UniqueSuffix is .number where number is obtained from
122 // llvm.dbg.composite<number>.
123 // FIXME: This will break when composite type is not represented by
124 // llvm.dbg.composite* global variable. Since we need to revisit
125 // PIC16DebugInfo implementation anyways after the MDNodes based
126 // framework is done, let us continue with the way it is.
127 std::string UniqueSuffix
= "." + Ty
.getNode()->getNameStr().substr(18);
128 TagName
+= UniqueSuffix
;
129 unsigned short size
= CTy
.getSizeInBits()/8;
130 // 7th and 8th byte represent size.
132 Aux
[6] = size
& 0xff;
136 /// PopulateEnumTypeInfo - Populate TypeNo for enum from Ty.
137 void PIC16DbgInfo::PopulateEnumTypeInfo (DIType Ty
, unsigned short &TypeNo
) {
138 TypeNo
= TypeNo
<< PIC16Dbg::S_BASIC
;
139 TypeNo
= TypeNo
| PIC16Dbg::T_ENUM
;
142 /// PopulateCompositeTypeInfo - Populate TypeNo, Aux[] and TagName for
143 /// composite types from Ty.
145 void PIC16DbgInfo::PopulateCompositeTypeInfo (DIType Ty
, unsigned short &TypeNo
,
146 bool &HasAux
, int Aux
[],
147 std::string
&TagName
) {
148 switch (Ty
.getTag()) {
149 case dwarf::DW_TAG_array_type
: {
150 PopulateArrayTypeInfo (Ty
, TypeNo
, HasAux
, Aux
, TagName
);
153 case dwarf:: DW_TAG_union_type
:
154 case dwarf::DW_TAG_structure_type
: {
155 PopulateStructOrUnionTypeInfo (Ty
, TypeNo
, HasAux
, Aux
, TagName
);
158 case dwarf::DW_TAG_enumeration_type
: {
159 PopulateEnumTypeInfo (Ty
, TypeNo
);
163 TypeNo
= TypeNo
<< PIC16Dbg::S_DERIVED
;
167 /// GetTypeDebugNumber - Get debug type number for given type.
169 unsigned PIC16DbgInfo::GetTypeDebugNumber(std::string
&type
) {
171 return PIC16Dbg::T_CHAR
;
172 else if (type
== "short")
173 return PIC16Dbg::T_SHORT
;
174 else if (type
== "int")
175 return PIC16Dbg::T_INT
;
176 else if (type
== "long")
177 return PIC16Dbg::T_LONG
;
178 else if (type
== "unsigned char")
179 return PIC16Dbg::T_UCHAR
;
180 else if (type
== "unsigned short")
181 return PIC16Dbg::T_USHORT
;
182 else if (type
== "unsigned int")
183 return PIC16Dbg::T_UINT
;
184 else if (type
== "unsigned long")
185 return PIC16Dbg::T_ULONG
;
190 /// GetStorageClass - Get storage class for give debug variable.
192 short PIC16DbgInfo::getStorageClass(DIGlobalVariable DIGV
) {
194 if (PAN::isLocalName(DIGV
.getGlobal()->getName())) {
195 // Generating C_AUTO here fails due to error in linker. Change it once
197 ClassNo
= PIC16Dbg::C_STAT
;
199 else if (DIGV
.isLocalToUnit())
200 ClassNo
= PIC16Dbg::C_STAT
;
202 ClassNo
= PIC16Dbg::C_EXT
;
206 /// BeginModule - Emit necessary debug info to start a Module and do other
207 /// required initializations.
208 void PIC16DbgInfo::BeginModule(Module
&M
) {
209 // Emit file directive for module.
210 DebugInfoFinder DbgFinder
;
211 DbgFinder
.processModule(M
);
212 if (DbgFinder
.compile_unit_count() != 0) {
213 // FIXME : What if more then one CUs are present in a module ?
214 MDNode
*CU
= *DbgFinder
.compile_unit_begin();
215 EmitDebugDirectives
= true;
218 // Emit debug info for decls of composite types.
219 EmitCompositeTypeDecls(M
);
222 /// Helper to find first valid debug loc for a function.
224 static const DebugLoc
GetDebugLocForFunction(const MachineFunction
&MF
) {
226 for (MachineFunction::const_iterator I
= MF
.begin(), E
= MF
.end();
228 for (MachineBasicBlock::const_iterator II
= I
->begin(), E
= I
->end();
230 DL
= II
->getDebugLoc();
238 /// BeginFunction - Emit necessary debug info to start a function.
240 void PIC16DbgInfo::BeginFunction(const MachineFunction
&MF
) {
241 if (! EmitDebugDirectives
) return;
243 // Retreive the first valid debug Loc and process it.
244 const DebugLoc
&DL
= GetDebugLocForFunction(MF
);
245 // Emit debug info only if valid debug info is available.
246 if (!DL
.isUnknown()) {
247 ChangeDebugLoc(MF
, DL
, true);
248 EmitFunctBeginDI(MF
.getFunction());
250 // Set current line to 0 so that.line directive is genearted after .bf.
254 /// ChangeDebugLoc - Take necessary steps when DebugLoc changes.
255 /// CurFile and CurLine may change as a result of this.
257 void PIC16DbgInfo::ChangeDebugLoc(const MachineFunction
&MF
,
258 const DebugLoc
&DL
, bool IsInBeginFunction
) {
259 if (! EmitDebugDirectives
) return;
260 assert (! DL
.isUnknown() && "can't change to invalid debug loc");
262 MDNode
*CU
= MF
.getDebugLocTuple(DL
).CompileUnit
;
263 unsigned line
= MF
.getDebugLocTuple(DL
).Line
;
266 SwitchToLine(line
, IsInBeginFunction
);
269 /// SwitchToLine - Emit line directive for a new line.
271 void PIC16DbgInfo::SwitchToLine(unsigned Line
, bool IsInBeginFunction
) {
272 if (CurLine
== Line
) return;
273 if (!IsInBeginFunction
) O
<< "\n\t.line " << Line
<< "\n";
277 /// EndFunction - Emit .ef for end of function.
279 void PIC16DbgInfo::EndFunction(const MachineFunction
&MF
) {
280 if (! EmitDebugDirectives
) return;
281 const DebugLoc
&DL
= GetDebugLocForFunction(MF
);
282 // Emit debug info only if valid debug info is available.
284 EmitFunctEndDI(MF
.getFunction(), CurLine
);
287 /// EndModule - Emit .eof for end of module.
289 void PIC16DbgInfo::EndModule(Module
&M
) {
290 if (! EmitDebugDirectives
) return;
292 if (CurFile
!= "") O
<< "\n\t.eof";
295 /// EmitCompositeTypeElements - Emit debug information for members of a
298 void PIC16DbgInfo::EmitCompositeTypeElements (DICompositeType CTy
,
299 std::string SuffixNo
) {
300 unsigned long Value
= 0;
301 DIArray Elements
= CTy
.getTypeArray();
302 for (unsigned i
= 0, N
= Elements
.getNumElements(); i
< N
; i
++) {
303 DIDescriptor Element
= Elements
.getElement(i
);
304 unsigned short TypeNo
= 0;
306 int ElementAux
[PIC16Dbg::AuxSize
] = { 0 };
307 std::string TagName
= "";
308 std::string ElementName
;
309 DIDerivedType
DITy(Element
.getNode());
310 DITy
.getName(ElementName
);
311 unsigned short ElementSize
= DITy
.getSizeInBits()/8;
312 // Get mangleddd name for this structure/union element.
313 std::string MangMemName
= ElementName
+ SuffixNo
;
314 PopulateDebugInfo(DITy
, TypeNo
, HasAux
, ElementAux
, TagName
);
316 if( CTy
.getTag() == dwarf::DW_TAG_union_type
)
317 Class
= PIC16Dbg::C_MOU
;
318 else if (CTy
.getTag() == dwarf::DW_TAG_structure_type
)
319 Class
= PIC16Dbg::C_MOS
;
320 EmitSymbol(MangMemName
.c_str(), Class
, TypeNo
, Value
);
321 if (CTy
.getTag() == dwarf::DW_TAG_structure_type
)
322 Value
+= ElementSize
;
324 EmitAuxEntry(MangMemName
.c_str(), ElementAux
, PIC16Dbg::AuxSize
, TagName
);
328 /// EmitCompositeTypeDecls - Emit composite type declarations like structure
329 /// and union declarations.
331 void PIC16DbgInfo::EmitCompositeTypeDecls(Module
&M
) {
332 DebugInfoFinder DbgFinder
;
333 DbgFinder
.processModule(M
);
334 for (DebugInfoFinder::iterator I
= DbgFinder
.type_begin(),
335 E
= DbgFinder
.type_end(); I
!= E
; ++I
) {
336 DICompositeType
CTy(*I
);
339 if (CTy
.getTag() == dwarf::DW_TAG_union_type
||
340 CTy
.getTag() == dwarf::DW_TAG_structure_type
) {
343 // Get the number after llvm.dbg.composite and make UniqueSuffix from
345 std::string DIVar
= CTy
.getNode()->getNameStr();
346 std::string UniqueSuffix
= "." + DIVar
.substr(18);
347 std::string MangledCTyName
= Name
+ UniqueSuffix
;
348 unsigned short size
= CTy
.getSizeInBits()/8;
349 int Aux
[PIC16Dbg::AuxSize
] = {0};
350 // 7th and 8th byte represent size of structure/union.
351 Aux
[6] = size
& 0xff;
353 // Emit .def for structure/union tag.
354 if( CTy
.getTag() == dwarf::DW_TAG_union_type
)
355 EmitSymbol(MangledCTyName
.c_str(), PIC16Dbg::C_UNTAG
);
356 else if (CTy
.getTag() == dwarf::DW_TAG_structure_type
)
357 EmitSymbol(MangledCTyName
.c_str(), PIC16Dbg::C_STRTAG
);
359 // Emit auxiliary debug information for structure/union tag.
360 EmitAuxEntry(MangledCTyName
.c_str(), Aux
, PIC16Dbg::AuxSize
);
363 EmitCompositeTypeElements (CTy
, UniqueSuffix
);
365 // Emit mangled Symbol for end of structure/union.
366 std::string EOSSymbol
= ".eos" + UniqueSuffix
;
367 EmitSymbol(EOSSymbol
.c_str(), PIC16Dbg::C_EOS
);
368 EmitAuxEntry(EOSSymbol
.c_str(), Aux
, PIC16Dbg::AuxSize
,
369 MangledCTyName
.c_str());
375 /// EmitFunctBeginDI - Emit .bf for function.
377 void PIC16DbgInfo::EmitFunctBeginDI(const Function
*F
) {
378 std::string FunctName
= F
->getName();
379 if (EmitDebugDirectives
) {
380 std::string FunctBeginSym
= ".bf." + FunctName
;
381 std::string BlockBeginSym
= ".bb." + FunctName
;
383 int BFAux
[PIC16Dbg::AuxSize
] = {0};
385 BFAux
[5] = CurLine
>> 8;
387 // Emit debug directives for beginning of function.
388 EmitSymbol(FunctBeginSym
, PIC16Dbg::C_FCN
);
389 EmitAuxEntry(FunctBeginSym
, BFAux
, PIC16Dbg::AuxSize
);
391 EmitSymbol(BlockBeginSym
, PIC16Dbg::C_BLOCK
);
392 EmitAuxEntry(BlockBeginSym
, BFAux
, PIC16Dbg::AuxSize
);
396 /// EmitFunctEndDI - Emit .ef for function end.
398 void PIC16DbgInfo::EmitFunctEndDI(const Function
*F
, unsigned Line
) {
399 std::string FunctName
= F
->getName();
400 if (EmitDebugDirectives
) {
401 std::string FunctEndSym
= ".ef." + FunctName
;
402 std::string BlockEndSym
= ".eb." + FunctName
;
404 // Emit debug directives for end of function.
405 EmitSymbol(BlockEndSym
, PIC16Dbg::C_BLOCK
);
406 int EFAux
[PIC16Dbg::AuxSize
] = {0};
407 // 5th and 6th byte stand for line number.
409 EFAux
[5] = CurLine
>> 8;
410 EmitAuxEntry(BlockEndSym
, EFAux
, PIC16Dbg::AuxSize
);
411 EmitSymbol(FunctEndSym
, PIC16Dbg::C_FCN
);
412 EmitAuxEntry(FunctEndSym
, EFAux
, PIC16Dbg::AuxSize
);
416 /// EmitAuxEntry - Emit Auxiliary debug information.
418 void PIC16DbgInfo::EmitAuxEntry(const std::string VarName
, int Aux
[], int Num
,
419 std::string TagName
) {
420 O
<< "\n\t.dim " << VarName
<< ", 1" ;
421 // TagName is emitted in case of structure/union objects.
423 O
<< ", " << TagName
;
424 for (int i
= 0; i
<Num
; i
++)
428 /// EmitSymbol - Emit .def for a symbol. Value is offset for the member.
430 void PIC16DbgInfo::EmitSymbol(std::string Name
, short Class
, unsigned short
431 Type
, unsigned long Value
) {
432 O
<< "\n\t" << ".def "<< Name
<< ", type = " << Type
<< ", class = "
435 O
<< ", value = " << Value
;
438 /// EmitVarDebugInfo - Emit debug information for all variables.
440 void PIC16DbgInfo::EmitVarDebugInfo(Module
&M
) {
441 DebugInfoFinder DbgFinder
;
442 DbgFinder
.processModule(M
);
444 for (DebugInfoFinder::iterator I
= DbgFinder
.global_variable_begin(),
445 E
= DbgFinder
.global_variable_end(); I
!= E
; ++I
) {
446 DIGlobalVariable
DIGV(*I
);
447 DIType Ty
= DIGV
.getType();
448 unsigned short TypeNo
= 0;
450 int Aux
[PIC16Dbg::AuxSize
] = { 0 };
451 std::string TagName
= "";
452 std::string VarName
= MAI
->getGlobalPrefix()+DIGV
.getGlobal()->getNameStr();
453 PopulateDebugInfo(Ty
, TypeNo
, HasAux
, Aux
, TagName
);
454 // Emit debug info only if type information is availaible.
455 if (TypeNo
!= PIC16Dbg::T_NULL
) {
456 O
<< "\n\t.type " << VarName
<< ", " << TypeNo
;
457 short ClassNo
= getStorageClass(DIGV
);
458 O
<< "\n\t.class " << VarName
<< ", " << ClassNo
;
460 EmitAuxEntry(VarName
, Aux
, PIC16Dbg::AuxSize
, TagName
);
466 /// SwitchToCU - Switch to a new compilation unit.
468 void PIC16DbgInfo::SwitchToCU(MDNode
*CU
) {
469 // Get the file path from CU.
470 DICompileUnit
cu(CU
);
471 std::string DirName
, FileName
;
472 std::string FilePath
= cu
.getDirectory(DirName
) + "/" +
473 cu
.getFilename(FileName
);
475 // Nothing to do if source file is still same.
476 if ( FilePath
== CurFile
) return;
478 // Else, close the current one and start a new.
479 if (CurFile
!= "") O
<< "\n\t.eof";
480 O
<< "\n\t.file\t\"" << FilePath
<< "\"\n" ;
485 /// EmitEOF - Emit .eof for end of file.
487 void PIC16DbgInfo::EmitEOF() {