aboutsummaryrefslogtreecommitdiffstats
path: root/lib/Target/PIC16/PIC16DebugInfo.cpp
blob: 166d96e9f65c17c0481e156ebaa1036bf5b6aa2c (plain)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
//===-- PIC16DebugInfo.cpp - Implementation for PIC16 Debug Information ======//
//
//                     The LLVM Compiler Infrastructure
//
// This file is distributed under the University of Illinois Open Source 
// License. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
//
// This file contains the helper functions for representing debug information.
//
//===----------------------------------------------------------------------===//

#include "PIC16.h"
#include "PIC16DebugInfo.h" 
#include "llvm/GlobalVariable.h"

using namespace llvm;

void PIC16DbgInfo::PopulateDebugInfo(DIType Ty, unsigned short &TypeNo,
                                     bool &HasAux, int Aux[], 
                                     std::string &TypeName) {
  if (Ty.isBasicType(Ty.getTag())) {
    std::string Name = "";
    Ty.getName(Name);
    unsigned short BaseTy = GetTypeDebugNumber(Name);
    TypeNo = TypeNo << PIC16Dbg::S_BASIC;
    TypeNo = TypeNo | (0xffff & BaseTy);
  }
  else if (Ty.isDerivedType(Ty.getTag())) {
    switch(Ty.getTag())
    {
      case dwarf::DW_TAG_pointer_type:
        TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
        TypeNo = TypeNo | PIC16Dbg::DT_PTR;
        break;
      default:
        TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
    }
    DIType BaseType = DIDerivedType(Ty.getGV()).getTypeDerivedFrom();
    PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName);
  }
  else if (Ty.isCompositeType(Ty.getTag())) {
    switch (Ty.getTag()) {
      case dwarf::DW_TAG_array_type: {
        DICompositeType CTy = DICompositeType(Ty.getGV());
        DIArray Elements = CTy.getTypeArray();
        unsigned short size = 1;
        unsigned short Dimension[4]={0,0,0,0};
        for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
          DIDescriptor Element = Elements.getElement(i);
          if (Element.getTag() == dwarf::DW_TAG_subrange_type) {
            TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
            TypeNo = TypeNo | PIC16Dbg::DT_ARY;
            DISubrange SubRange = DISubrange(Element.getGV());
            Dimension[i] = SubRange.getHi() - SubRange.getLo() + 1;
            // Each dimension is represented by 2 bytes starting at byte 9.
            Aux[8+i*2+0] = Dimension[i];
            Aux[8+i*2+1] = Dimension[i] >> 8;
            size = size * Dimension[i];
          }
        }
        HasAux = true;
        // In auxillary entry for array, 7th and 8th byte represent array size.
        Aux[6] = size;
        Aux[7] = size >> 8;
        DIType BaseType = CTy.getTypeDerivedFrom();
        PopulateDebugInfo(BaseType, TypeNo, HasAux, Aux, TypeName);

        break;
      }
      case dwarf:: DW_TAG_union_type:
      case dwarf::DW_TAG_structure_type: {
        DICompositeType CTy = DICompositeType(Ty.getGV());
        TypeNo = TypeNo << PIC16Dbg::S_BASIC;
        if (Ty.getTag() == dwarf::DW_TAG_structure_type)
          TypeNo = TypeNo | PIC16Dbg::T_STRUCT;
        else
          TypeNo = TypeNo | PIC16Dbg::T_UNION;
        CTy.getName(TypeName);
        unsigned size = CTy.getSizeInBits()/8;
        // 7th and 8th byte represent size.   
        HasAux = true;
        Aux[6] = size;
        Aux[7] = size >> 8;
        break;
      }
      case dwarf::DW_TAG_enumeration_type: {
        TypeNo = TypeNo << PIC16Dbg::S_BASIC;
        TypeNo = TypeNo | PIC16Dbg::T_ENUM;
        break;
      }
      default:
        TypeNo = TypeNo << PIC16Dbg::S_DERIVED;
    }
  }
  else {
    TypeNo = PIC16Dbg::T_NULL;
    HasAux = false;
  }
  return;
}


unsigned PIC16DbgInfo::GetTypeDebugNumber(std::string &type)  {
  if (type == "char")
    return PIC16Dbg::T_CHAR;
  else if (type == "short")
    return PIC16Dbg::T_SHORT;
  else if (type == "int")
    return PIC16Dbg::T_INT;
  else if (type == "long")
    return PIC16Dbg::T_LONG;
  else if (type == "unsigned char")
    return PIC16Dbg::T_UCHAR;
  else if (type == "unsigned short")
    return PIC16Dbg::T_USHORT;
  else if (type == "unsigned int")
    return PIC16Dbg::T_UINT;
  else if (type == "unsigned long")
    return PIC16Dbg::T_ULONG;
  else
    return 0;
}

short PIC16DbgInfo::getClass(DIGlobalVariable DIGV) {
  short ClassNo;
  if (PAN::isLocalName(DIGV.getGlobal()->getName())) {
    // Generating C_AUTO here fails due to error in linker. Change it once
    // linker is fixed.
    ClassNo = PIC16Dbg::C_STAT;
  }
  else if (DIGV.isLocalToUnit())
    ClassNo = PIC16Dbg::C_STAT;
  else
    ClassNo = PIC16Dbg::C_EXT;
  return ClassNo;
}