Emit debug information for globals (which include automatic variables as well because...
[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
18 using namespace llvm;
19
20 void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo,
21                                      bool &HasAux, int Aux[], 
22                                      std::string &TypeName) {
23   if (Ty.isBasicType(Ty.getTag())) {
24     std::string Name = "";
25     Ty.getName(Name);
26     unsigned short BaseTy = GetTypeDebugNumber(Name);
27     TypeNo = TypeNo << PIC16Dbg::S_BASIC;
28     TypeNo = TypeNo | (0xffff & BaseTy);
29   }
30   else if (Ty.isDerivedType(Ty.getTag())) {
31     switch(Ty.getTag())
32     {
33       case dwarf::DW_TAG_pointer_type:
34         TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
35         TypeNo = TypeNo | PIC16Dbg::DT_PTR;
36         break;
37       default:
38         TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
39     }
40     DIType BaseType = DIDerivedType(Ty.getGV()).getTypeDerivedFrom();
41     PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName);
42   }
43   else if (Ty.isCompositeType(Ty.getTag())) {
44     switch (Ty.getTag()) {
45       case dwarf::DW_TAG_array_type: {
46         DICompositeType CTy = DICompositeType(Ty.getGV());
47         DIArray Elements = CTy.getTypeArray();
48         unsigned short size = 1;
49         unsigned short Dimension[4]={0,0,0,0};
50         for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
51           DIDescriptor Element = Elements.getElement(i);
52           if (Element.getTag() == dwarf::DW_TAG_subrange_type) {
53             TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
54             TypeNo = TypeNo | PIC16Dbg::DT_ARY;
55             DISubrange SubRange = DISubrange(Element.getGV());
56             Dimension[i] = SubRange.getHi() - SubRange.getLo() + 1;
57             // Each dimension is represented by 2 bytes starting at byte 9.
58             Aux[8+i*2+0] = Dimension[i];
59             Aux[8+i*2+1] = Dimension[i] >> 8;
60             size = size * Dimension[i];
61           }
62         }
63         HasAux = true;
64         // In auxillary entry for array, 7th and 8th byte represent array size.
65         Aux[6] = size;
66         Aux[7] = size >> 8;
67         DIType BaseType = CTy.getTypeDerivedFrom();
68         PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName);
69
70         break;
71       }
72       case dwarf:: DW_TAG_union_type:
73       case dwarf::DW_TAG_structure_type: {
74         DICompositeType CTy = DICompositeType(Ty.getGV());
75         TypeNo = TypeNo << PIC16Dbg::S_BASIC;
76         if (Ty.getTag() == dwarf::DW_TAG_structure_type)
77           TypeNo = TypeNo | PIC16Dbg::T_STRUCT;
78         else
79           TypeNo = TypeNo | PIC16Dbg::T_UNION;
80         CTy.getName(TypeName);
81         unsigned size = CTy.getSizeInBits()/8;
82         // 7th and 8th byte represent size.   
83         HasAux = true;
84         Aux[6] = size;
85         Aux[7] = size >> 8;
86         break;
87       }
88       case dwarf::DW_TAG_enumeration_type: {
89         TypeNo = TypeNo << PIC16Dbg::S_BASIC;
90         TypeNo = TypeNo | PIC16Dbg::T_ENUM;
91         break;
92       }
93       default:
94         TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
95     }
96   }
97   else {
98     TypeNo = PIC16Dbg::T_NULL;
99     HasAux = false;
100   }
101   return;
102 }
103
104
105 unsigned PIC16DbgInfo::GetTypeDebugNumber(std::string &type)  {
106   if (type == "char")
107     return PIC16Dbg::T_CHAR;
108   else if (type == "short")
109     return PIC16Dbg::T_SHORT;
110   else if (type == "int")
111     return PIC16Dbg::T_INT;
112   else if (type == "long")
113     return PIC16Dbg::T_LONG;
114   else if (type == "unsigned char")
115     return PIC16Dbg::T_UCHAR;
116   else if (type == "unsigned short")
117     return PIC16Dbg::T_USHORT;
118   else if (type == "unsigned int")
119     return PIC16Dbg::T_UINT;
120   else if (type == "unsigned long")
121     return PIC16Dbg::T_ULONG;
122   else
123     return 0;
124 }
125
126 short PIC16DbgInfo::getClass(DIGlobalVariable DIGV) {
127   short ClassNo;
128   if (PAN::isLocalName(DIGV.getGlobal()->getName())) {
129     // Generating C_AUTO here fails due to error in linker. Change it once
130     // linker is fixed.
131     ClassNo = PIC16Dbg::C_STAT;
132   }
133   else if (DIGV.isLocalToUnit())
134     ClassNo = PIC16Dbg::C_STAT;
135   else
136     ClassNo = PIC16Dbg::C_EXT;
137   return ClassNo;
138 }