blob: 7588bbb9301a39ea45fd9329734ae8743d9bf31a [file] [log] [blame]
Bill Wendling0310d762009-05-15 09:23:25 +00001//===-- llvm/CodeGen/DwarfDebug.cpp - Dwarf Debug Framework ---------------===//
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 support for writing dwarf debug info into asm files.
11//
12//===----------------------------------------------------------------------===//
Chris Lattner6cde3e62010-03-09 00:39:24 +000013
Devang Patele4b27562009-08-28 23:24:31 +000014#define DEBUG_TYPE "dwarfdebug"
Bill Wendling0310d762009-05-15 09:23:25 +000015#include "DwarfDebug.h"
Chris Lattner74e41f92010-04-05 05:24:55 +000016#include "DIE.h"
Bill Wendling57fbba42010-04-05 22:59:21 +000017#include "llvm/Constants.h"
Bill Wendling0310d762009-05-15 09:23:25 +000018#include "llvm/Module.h"
David Greeneb2c66fc2009-08-19 21:52:55 +000019#include "llvm/CodeGen/MachineFunction.h"
Bill Wendling0310d762009-05-15 09:23:25 +000020#include "llvm/CodeGen/MachineModuleInfo.h"
Chris Lattnerb7db7332010-03-09 01:58:53 +000021#include "llvm/MC/MCAsmInfo.h"
Chris Lattnera87dea42009-07-31 18:48:30 +000022#include "llvm/MC/MCSection.h"
Chris Lattner6c2f9e12009-08-19 05:49:37 +000023#include "llvm/MC/MCStreamer.h"
Chris Lattnerb7db7332010-03-09 01:58:53 +000024#include "llvm/MC/MCSymbol.h"
Chris Lattner45111d12010-01-16 21:57:06 +000025#include "llvm/Target/Mangler.h"
Bill Wendling0310d762009-05-15 09:23:25 +000026#include "llvm/Target/TargetData.h"
27#include "llvm/Target/TargetFrameInfo.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000028#include "llvm/Target/TargetLoweringObjectFile.h"
Chris Lattner9d1c1ad2010-04-04 18:06:11 +000029#include "llvm/Target/TargetMachine.h"
Chris Lattnerf0144122009-07-28 03:13:23 +000030#include "llvm/Target/TargetRegisterInfo.h"
Devang Patel2a4a3b72010-04-19 19:14:02 +000031#include "llvm/Target/TargetOptions.h"
Chris Lattner74e41f92010-04-05 05:24:55 +000032#include "llvm/Analysis/DebugInfo.h"
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +000033#include "llvm/ADT/STLExtras.h"
Chris Lattner23132b12009-08-24 03:52:50 +000034#include "llvm/ADT/StringExtras.h"
Devang Patel9cdb4102010-04-21 16:32:19 +000035#include "llvm/Support/CommandLine.h"
Daniel Dunbar6e4bdfc2009-10-13 06:47:08 +000036#include "llvm/Support/Debug.h"
37#include "llvm/Support/ErrorHandling.h"
Devang Patel3139fcf2010-01-26 21:39:14 +000038#include "llvm/Support/ValueHandle.h"
Chris Lattner0ad9c912010-01-22 22:09:00 +000039#include "llvm/Support/FormattedStream.h"
Chris Lattnera87dea42009-07-31 18:48:30 +000040#include "llvm/Support/Timer.h"
41#include "llvm/System/Path.h"
Bill Wendling0310d762009-05-15 09:23:25 +000042using namespace llvm;
43
Devang Patel9cdb4102010-04-21 16:32:19 +000044static cl::opt<bool> PrintDbgScope("print-dbgscope", cl::Hidden,
45 cl::desc("Print DbgScope information for each machine instruction"));
46
Bill Wendling5f017e82010-04-07 09:28:04 +000047namespace {
48 const char *DWARFGroupName = "DWARF Emission";
49 const char *DbgTimerName = "DWARF Debug Writer";
50} // end anonymous namespace
51
Bill Wendling0310d762009-05-15 09:23:25 +000052//===----------------------------------------------------------------------===//
53
54/// Configuration values for initial hash set sizes (log2).
55///
Bill Wendling0310d762009-05-15 09:23:25 +000056static const unsigned InitAbbreviationsSetSize = 9; // log2(512)
Bill Wendling0310d762009-05-15 09:23:25 +000057
58namespace llvm {
59
60//===----------------------------------------------------------------------===//
61/// CompileUnit - This dwarf writer support class manages information associate
62/// with a source file.
Nick Lewycky5f9843f2009-11-17 08:11:44 +000063class CompileUnit {
Bill Wendling0310d762009-05-15 09:23:25 +000064 /// ID - File identifier for source.
65 ///
66 unsigned ID;
67
68 /// Die - Compile unit debug information entry.
69 ///
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +000070 const OwningPtr<DIE> CUDie;
Bill Wendling0310d762009-05-15 09:23:25 +000071
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +000072 /// IndexTyDie - An anonymous type for index type. Owned by CUDie.
Devang Patel6f01d9c2009-11-21 00:31:03 +000073 DIE *IndexTyDie;
74
Bill Wendling0310d762009-05-15 09:23:25 +000075 /// GVToDieMap - Tracks the mapping of unit level debug informaton
76 /// variables to debug information entries.
Devang Patele4b27562009-08-28 23:24:31 +000077 /// FIXME : Rename GVToDieMap -> NodeToDieMap
Devang Patel622b0262010-01-19 06:19:05 +000078 DenseMap<MDNode *, DIE *> GVToDieMap;
Bill Wendling0310d762009-05-15 09:23:25 +000079
80 /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
81 /// descriptors to debug information entries using a DIEEntry proxy.
Devang Patele4b27562009-08-28 23:24:31 +000082 /// FIXME : Rename
Devang Patel622b0262010-01-19 06:19:05 +000083 DenseMap<MDNode *, DIEEntry *> GVToDIEEntryMap;
Bill Wendling0310d762009-05-15 09:23:25 +000084
85 /// Globals - A map of globally visible named entities for this unit.
86 ///
87 StringMap<DIE*> Globals;
88
Devang Patel193f7202009-11-24 01:14:22 +000089 /// GlobalTypes - A map of globally visible types for this unit.
90 ///
91 StringMap<DIE*> GlobalTypes;
92
Bill Wendling0310d762009-05-15 09:23:25 +000093public:
94 CompileUnit(unsigned I, DIE *D)
Devang Patel2c4ceb12009-11-21 02:48:08 +000095 : ID(I), CUDie(D), IndexTyDie(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +000096
97 // Accessors.
Devang Patel193f7202009-11-24 01:14:22 +000098 unsigned getID() const { return ID; }
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +000099 DIE* getCUDie() const { return CUDie.get(); }
Devang Patel193f7202009-11-24 01:14:22 +0000100 const StringMap<DIE*> &getGlobals() const { return Globals; }
101 const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; }
Bill Wendling0310d762009-05-15 09:23:25 +0000102
103 /// hasContent - Return true if this compile unit has something to write out.
104 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000105 bool hasContent() const { return !CUDie->getChildren().empty(); }
Bill Wendling0310d762009-05-15 09:23:25 +0000106
Devang Patel2c4ceb12009-11-21 02:48:08 +0000107 /// addGlobal - Add a new global entity to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000108 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000109 void addGlobal(StringRef Name, DIE *Die) { Globals[Name] = Die; }
Bill Wendling0310d762009-05-15 09:23:25 +0000110
Devang Patel193f7202009-11-24 01:14:22 +0000111 /// addGlobalType - Add a new global type to the compile unit.
112 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000113 void addGlobalType(StringRef Name, DIE *Die) {
Devang Patel193f7202009-11-24 01:14:22 +0000114 GlobalTypes[Name] = Die;
115 }
116
Devang Patel017d1212009-11-20 21:37:22 +0000117 /// getDIE - Returns the debug information entry map slot for the
Bill Wendling0310d762009-05-15 09:23:25 +0000118 /// specified debug variable.
Devang Patel017d1212009-11-20 21:37:22 +0000119 DIE *getDIE(MDNode *N) { return GVToDieMap.lookup(N); }
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000120
Devang Patel017d1212009-11-20 21:37:22 +0000121 /// insertDIE - Insert DIE into the map.
122 void insertDIE(MDNode *N, DIE *D) {
123 GVToDieMap.insert(std::make_pair(N, D));
124 }
Bill Wendling0310d762009-05-15 09:23:25 +0000125
Devang Patel017d1212009-11-20 21:37:22 +0000126 /// getDIEEntry - Returns the debug information entry for the speciefied
127 /// debug variable.
Devang Patel6404e4e2009-12-15 19:16:48 +0000128 DIEEntry *getDIEEntry(MDNode *N) {
Devang Patel622b0262010-01-19 06:19:05 +0000129 DenseMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
Devang Patel6404e4e2009-12-15 19:16:48 +0000130 if (I == GVToDIEEntryMap.end())
131 return NULL;
132 return I->second;
133 }
Devang Patel017d1212009-11-20 21:37:22 +0000134
135 /// insertDIEEntry - Insert debug information entry into the map.
136 void insertDIEEntry(MDNode *N, DIEEntry *E) {
137 GVToDIEEntryMap.insert(std::make_pair(N, E));
Bill Wendling0310d762009-05-15 09:23:25 +0000138 }
139
Devang Patel2c4ceb12009-11-21 02:48:08 +0000140 /// addDie - Adds or interns the DIE to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000141 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000142 void addDie(DIE *Buffer) {
143 this->CUDie->addChild(Buffer);
Bill Wendling0310d762009-05-15 09:23:25 +0000144 }
Devang Patel6f01d9c2009-11-21 00:31:03 +0000145
146 // getIndexTyDie - Get an anonymous type for index type.
147 DIE *getIndexTyDie() {
148 return IndexTyDie;
149 }
150
Jim Grosbach7ab38df2009-11-22 19:20:36 +0000151 // setIndexTyDie - Set D as anonymous type for index which can be reused
152 // later.
Devang Patel6f01d9c2009-11-21 00:31:03 +0000153 void setIndexTyDie(DIE *D) {
154 IndexTyDie = D;
155 }
156
Bill Wendling0310d762009-05-15 09:23:25 +0000157};
158
159//===----------------------------------------------------------------------===//
160/// DbgVariable - This class is used to track local variable information.
161///
Devang Patelf76a3d62009-11-16 21:53:40 +0000162class DbgVariable {
Bill Wendling0310d762009-05-15 09:23:25 +0000163 DIVariable Var; // Variable Descriptor.
164 unsigned FrameIndex; // Variable frame index.
Devang Patel90a48ad2010-03-15 18:33:46 +0000165 const MachineInstr *DbgValueMInsn; // DBG_VALUE
Devang Patelaead63c2010-03-29 22:59:58 +0000166 // DbgValueLabel - DBG_VALUE is effective from this label.
167 MCSymbol *DbgValueLabel;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000168 DbgVariable *const AbstractVar; // Abstract variable for this variable.
Devang Patel53bb5c92009-11-10 23:06:00 +0000169 DIE *TheDIE;
Bill Wendling0310d762009-05-15 09:23:25 +0000170public:
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000171 // AbsVar may be NULL.
172 DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000173 : Var(V), FrameIndex(I), DbgValueMInsn(0),
174 DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
Devang Patel90a48ad2010-03-15 18:33:46 +0000175 DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000176 : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
177 AbstractVar(AbsVar), TheDIE(0)
Devang Patel90a48ad2010-03-15 18:33:46 +0000178 {}
Bill Wendling0310d762009-05-15 09:23:25 +0000179
180 // Accessors.
Devang Patel53bb5c92009-11-10 23:06:00 +0000181 DIVariable getVariable() const { return Var; }
182 unsigned getFrameIndex() const { return FrameIndex; }
Devang Patel90a48ad2010-03-15 18:33:46 +0000183 const MachineInstr *getDbgValue() const { return DbgValueMInsn; }
Devang Patelaead63c2010-03-29 22:59:58 +0000184 MCSymbol *getDbgValueLabel() const { return DbgValueLabel; }
185 void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000186 DbgVariable *getAbstractVariable() const { return AbstractVar; }
187 void setDIE(DIE *D) { TheDIE = D; }
188 DIE *getDIE() const { return TheDIE; }
Bill Wendling0310d762009-05-15 09:23:25 +0000189};
190
191//===----------------------------------------------------------------------===//
Devang Patel9cdb4102010-04-21 16:32:19 +0000192/// DbgRange - This is used to track range of instructions with identical
193/// debug info scope.
194///
195typedef std::pair<const MachineInstr *, const MachineInstr *> DbgRange;
196
197//===----------------------------------------------------------------------===//
Bill Wendling0310d762009-05-15 09:23:25 +0000198/// DbgScope - This class is used to track scope information.
199///
Devang Patelf76a3d62009-11-16 21:53:40 +0000200class DbgScope {
Bill Wendling0310d762009-05-15 09:23:25 +0000201 DbgScope *Parent; // Parent to this scope.
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000202 DIDescriptor Desc; // Debug info descriptor for scope.
Devang Patel3139fcf2010-01-26 21:39:14 +0000203 // Location at which this scope is inlined.
204 AssertingVH<MDNode> InlinedAtLocation;
Devang Patel53bb5c92009-11-10 23:06:00 +0000205 bool AbstractScope; // Abstract Scope
Devang Pateld38dd112009-10-01 18:25:23 +0000206 const MachineInstr *LastInsn; // Last instruction of this scope.
207 const MachineInstr *FirstInsn; // First instruction of this scope.
Devang Patel9cdb4102010-04-21 16:32:19 +0000208 unsigned DFSIn, DFSOut;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000209 // Scopes defined in scope. Contents not owned.
210 SmallVector<DbgScope *, 4> Scopes;
211 // Variables declared in scope. Contents owned.
212 SmallVector<DbgVariable *, 8> Variables;
Devang Patel9cdb4102010-04-21 16:32:19 +0000213 SmallVector<DbgRange, 4> Ranges;
Owen Anderson04c05f72009-06-24 22:53:20 +0000214 // Private state for dump()
215 mutable unsigned IndentLevel;
Bill Wendling0310d762009-05-15 09:23:25 +0000216public:
Devang Patelc90aefe2009-10-14 21:08:09 +0000217 DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0)
Devang Patel53bb5c92009-11-10 23:06:00 +0000218 : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
Devang Patel9cdb4102010-04-21 16:32:19 +0000219 LastInsn(0), FirstInsn(0),
220 DFSIn(0), DFSOut(0), IndentLevel(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +0000221 virtual ~DbgScope();
222
223 // Accessors.
224 DbgScope *getParent() const { return Parent; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000225 void setParent(DbgScope *P) { Parent = P; }
Bill Wendling0310d762009-05-15 09:23:25 +0000226 DIDescriptor getDesc() const { return Desc; }
Chris Lattnerbc733f52010-03-13 02:17:42 +0000227 MDNode *getInlinedAt() const { return InlinedAtLocation; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000228 MDNode *getScopeNode() const { return Desc.getNode(); }
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000229 const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
230 const SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
Devang Patel9cdb4102010-04-21 16:32:19 +0000231 const SmallVector<DbgRange, 4> &getRanges() { return Ranges; }
232
233 /// openInsnRange - This scope covers instruction range starting from MI.
234 void openInsnRange(const MachineInstr *MI) {
235 if (!FirstInsn)
236 FirstInsn = MI;
237
238 if (Parent)
239 Parent->openInsnRange(MI);
240 }
241
242 /// extendInsnRange - Extend the current instruction range covered by
243 /// this scope.
244 void extendInsnRange(const MachineInstr *MI) {
245 assert (FirstInsn && "MI Range is not open!");
246 LastInsn = MI;
247 if (Parent)
248 Parent->extendInsnRange(MI);
249 }
250
251 /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
252 /// until now. This is used when a new scope is encountered while walking
253 /// machine instructions.
254 void closeInsnRange(DbgScope *NewScope = NULL) {
255 assert (LastInsn && "Last insn missing!");
256 Ranges.push_back(DbgRange(FirstInsn, LastInsn));
257 FirstInsn = NULL;
258 LastInsn = NULL;
259 // If Parent dominates NewScope then do not close Parent's instruction
260 // range.
261 if (Parent && (!NewScope || !Parent->dominates(NewScope)))
262 Parent->closeInsnRange(NewScope);
263 }
264
Devang Patel53bb5c92009-11-10 23:06:00 +0000265 void setAbstractScope() { AbstractScope = true; }
266 bool isAbstractScope() const { return AbstractScope; }
Devang Patel9cdb4102010-04-21 16:32:19 +0000267
268 // Depth First Search support to walk and mainpluate DbgScope hierarchy.
269 unsigned getDFSOut() const { return DFSOut; }
270 void setDFSOut(unsigned O) { DFSOut = O; }
271 unsigned getDFSIn() const { return DFSIn; }
272 void setDFSIn(unsigned I) { DFSIn = I; }
273 bool dominates(const DbgScope *S) {
274 if (S == this)
275 return true;
276 if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
277 return true;
278 return false;
279 }
Devang Patel53bb5c92009-11-10 23:06:00 +0000280
Devang Patel2c4ceb12009-11-21 02:48:08 +0000281 /// addScope - Add a scope to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000282 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000283 void addScope(DbgScope *S) { Scopes.push_back(S); }
Bill Wendling0310d762009-05-15 09:23:25 +0000284
Devang Patel2c4ceb12009-11-21 02:48:08 +0000285 /// addVariable - Add a variable to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000286 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000287 void addVariable(DbgVariable *V) { Variables.push_back(V); }
Bill Wendling0310d762009-05-15 09:23:25 +0000288
Bill Wendling0310d762009-05-15 09:23:25 +0000289#ifndef NDEBUG
290 void dump() const;
291#endif
292};
Devang Patel9cdb4102010-04-21 16:32:19 +0000293
Chris Lattnerea761862010-04-05 04:09:20 +0000294} // end llvm namespace
Bill Wendling0310d762009-05-15 09:23:25 +0000295
296#ifndef NDEBUG
297void DbgScope::dump() const {
David Greenef83adbc2009-12-24 00:31:35 +0000298 raw_ostream &err = dbgs();
Chris Lattnerc281de12009-08-23 00:51:00 +0000299 err.indent(IndentLevel);
Devang Patel53bb5c92009-11-10 23:06:00 +0000300 MDNode *N = Desc.getNode();
301 N->dump();
Devang Patel53bb5c92009-11-10 23:06:00 +0000302 if (AbstractScope)
303 err << "Abstract Scope\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000304
305 IndentLevel += 2;
Devang Patel53bb5c92009-11-10 23:06:00 +0000306 if (!Scopes.empty())
307 err << "Children ...\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000308 for (unsigned i = 0, e = Scopes.size(); i != e; ++i)
309 if (Scopes[i] != this)
310 Scopes[i]->dump();
311
312 IndentLevel -= 2;
313}
314#endif
315
Bill Wendling0310d762009-05-15 09:23:25 +0000316DbgScope::~DbgScope() {
Bill Wendling0310d762009-05-15 09:23:25 +0000317 for (unsigned j = 0, M = Variables.size(); j < M; ++j)
318 delete Variables[j];
Bill Wendling0310d762009-05-15 09:23:25 +0000319}
320
Chris Lattner49cd6642010-04-05 05:11:15 +0000321DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
Chris Lattnerd38fee82010-04-05 00:13:49 +0000322 : Asm(A), MMI(Asm->MMI), ModuleCU(0),
Chris Lattner994cb122010-04-05 03:52:55 +0000323 AbbreviationsSet(InitAbbreviationsSetSize),
Devang Patelf2548ca2010-04-16 23:33:45 +0000324 CurrentFnDbgScope(0), PrevLabel(NULL) {
Chris Lattnerbc733f52010-03-13 02:17:42 +0000325 NextStringPoolNumber = 0;
Chris Lattner9c69e285532010-04-04 22:59:04 +0000326
Chris Lattner4ad1efe2010-04-04 23:10:38 +0000327 DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
328 DwarfStrSectionSym = TextSectionSym = 0;
Devang Patel9cdb4102010-04-21 16:32:19 +0000329 DwarfDebugRangeSectionSym = 0;
Torok Edwin9c421072010-04-07 10:44:46 +0000330 if (TimePassesIsEnabled) {
331 NamedRegionTimer T(DbgTimerName, DWARFGroupName);
332 beginModule(M);
333 } else {
334 beginModule(M);
335 }
Bill Wendling0310d762009-05-15 09:23:25 +0000336}
337DwarfDebug::~DwarfDebug() {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000338 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
339 DIEBlocks[j]->~DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000340}
341
Chris Lattnerbc733f52010-03-13 02:17:42 +0000342MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
343 std::pair<MCSymbol*, unsigned> &Entry = StringPool[Str];
344 if (Entry.first) return Entry.first;
345
346 Entry.second = NextStringPoolNumber++;
Chris Lattnerc0215722010-04-04 19:25:43 +0000347 return Entry.first = Asm->GetTempSymbol("string", Entry.second);
Chris Lattnerbc733f52010-03-13 02:17:42 +0000348}
349
350
Devang Patel2c4ceb12009-11-21 02:48:08 +0000351/// assignAbbrevNumber - Define a unique number for the abbreviation.
Bill Wendling0310d762009-05-15 09:23:25 +0000352///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000353void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {
Bill Wendling0310d762009-05-15 09:23:25 +0000354 // Profile the node so that we can make it unique.
355 FoldingSetNodeID ID;
356 Abbrev.Profile(ID);
357
358 // Check the set for priors.
359 DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev);
360
361 // If it's newly added.
362 if (InSet == &Abbrev) {
363 // Add to abbreviation list.
364 Abbreviations.push_back(&Abbrev);
365
366 // Assign the vector position + 1 as its number.
367 Abbrev.setNumber(Abbreviations.size());
368 } else {
369 // Assign existing abbreviation number.
370 Abbrev.setNumber(InSet->getNumber());
371 }
372}
373
Devang Patel2c4ceb12009-11-21 02:48:08 +0000374/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
Bill Wendling995f80a2009-05-20 23:24:48 +0000375/// information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000376DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000377 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000378 return Value;
379}
380
Devang Patel2c4ceb12009-11-21 02:48:08 +0000381/// addUInt - Add an unsigned integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000382///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000383void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000384 unsigned Form, uint64_t Integer) {
385 if (!Form) Form = DIEInteger::BestForm(false, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000386 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000387 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000388}
389
Devang Patel2c4ceb12009-11-21 02:48:08 +0000390/// addSInt - Add an signed integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000391///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000392void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000393 unsigned Form, int64_t Integer) {
394 if (!Form) Form = DIEInteger::BestForm(true, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000395 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000396 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000397}
398
Devang Patel69f57b12009-12-02 15:25:16 +0000399/// addString - Add a string attribute data and value. DIEString only
400/// keeps string reference.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000401void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattner4cf202b2010-01-23 03:11:46 +0000402 StringRef String) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000403 DIEValue *Value = new (DIEValueAllocator) DIEString(String);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000404 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000405}
406
Devang Patel2c4ceb12009-11-21 02:48:08 +0000407/// addLabel - Add a Dwarf label attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000408///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000409void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000410 const MCSymbol *Label) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000411 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000412 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000413}
414
Devang Patel2c4ceb12009-11-21 02:48:08 +0000415/// addDelta - Add a label delta attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000416///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000417void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000418 const MCSymbol *Hi, const MCSymbol *Lo) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000419 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000420 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000421}
422
Chris Lattner74e41f92010-04-05 05:24:55 +0000423/// addDIEEntry - Add a DIE attribute data and value.
424///
425void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
426 DIE *Entry) {
427 Die->addValue(Attribute, Form, createDIEEntry(Entry));
428}
429
430
Devang Patel2c4ceb12009-11-21 02:48:08 +0000431/// addBlock - Add block data.
Bill Wendling0310d762009-05-15 09:23:25 +0000432///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000433void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
Bill Wendling0310d762009-05-15 09:23:25 +0000434 DIEBlock *Block) {
Chris Lattnera37d5382010-04-05 00:18:22 +0000435 Block->ComputeSize(Asm);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000436 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000437 Die->addValue(Attribute, Block->BestForm(), Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000438}
439
Devang Patel2c4ceb12009-11-21 02:48:08 +0000440/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000441/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000442void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
Bill Wendling0310d762009-05-15 09:23:25 +0000443 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000444 if (!V->getCompileUnit().Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000445 return;
446
447 unsigned Line = V->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000448 unsigned FileID = GetOrCreateSourceID(V->getContext().getDirectory(),
449 V->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000450 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000451 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
452 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000453}
454
Devang Patel2c4ceb12009-11-21 02:48:08 +0000455/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000456/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000457void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) {
Bill Wendling0310d762009-05-15 09:23:25 +0000458 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000459 if (!G->getCompileUnit().Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000460 return;
461
462 unsigned Line = G->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000463 unsigned FileID = GetOrCreateSourceID(G->getContext().getDirectory(),
464 G->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000465 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000466 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
467 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000468}
Devang Patel82dfc0c2009-08-31 22:47:13 +0000469
Devang Patel2c4ceb12009-11-21 02:48:08 +0000470/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000471/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000472void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
Devang Patel82dfc0c2009-08-31 22:47:13 +0000473 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000474 if (!SP->getCompileUnit().Verify())
Devang Patel82dfc0c2009-08-31 22:47:13 +0000475 return;
Caroline Ticec6f9d622009-09-11 18:25:54 +0000476 // If the line number is 0, don't add it.
477 if (SP->getLineNumber() == 0)
478 return;
479
Devang Patel82dfc0c2009-08-31 22:47:13 +0000480 unsigned Line = SP->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000481 if (!SP->getContext().Verify())
482 return;
Devang Patel9bb59a22010-03-24 21:30:35 +0000483 unsigned FileID = GetOrCreateSourceID(SP->getDirectory(),
484 SP->getFilename());
Devang Patel82dfc0c2009-08-31 22:47:13 +0000485 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000486 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
487 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Devang Patel82dfc0c2009-08-31 22:47:13 +0000488}
489
Devang Patel2c4ceb12009-11-21 02:48:08 +0000490/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000491/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000492void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
Bill Wendling0310d762009-05-15 09:23:25 +0000493 // If there is no compile unit specified, don't add a line #.
494 DICompileUnit CU = Ty->getCompileUnit();
Devang Patel3c91b052010-03-08 20:52:55 +0000495 if (!CU.Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000496 return;
497
498 unsigned Line = Ty->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000499 if (!Ty->getContext().Verify())
500 return;
501 unsigned FileID = GetOrCreateSourceID(Ty->getContext().getDirectory(),
502 Ty->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000503 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000504 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
505 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000506}
507
Devang Patel6404e4e2009-12-15 19:16:48 +0000508/// addSourceLine - Add location information to specified debug information
509/// entry.
510void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) {
511 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000512 if (!NS->getCompileUnit().Verify())
Devang Patel6404e4e2009-12-15 19:16:48 +0000513 return;
514
515 unsigned Line = NS->getLineNumber();
516 StringRef FN = NS->getFilename();
517 StringRef Dir = NS->getDirectory();
518
519 unsigned FileID = GetOrCreateSourceID(Dir, FN);
520 assert(FileID && "Invalid file id");
521 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
522 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
523}
524
Caroline Ticedc8f6042009-08-31 21:19:37 +0000525/* Byref variables, in Blocks, are declared by the programmer as
526 "SomeType VarName;", but the compiler creates a
527 __Block_byref_x_VarName struct, and gives the variable VarName
528 either the struct, or a pointer to the struct, as its type. This
529 is necessary for various behind-the-scenes things the compiler
530 needs to do with by-reference variables in blocks.
531
532 However, as far as the original *programmer* is concerned, the
533 variable should still have type 'SomeType', as originally declared.
534
535 The following function dives into the __Block_byref_x_VarName
536 struct to find the original type of the variable. This will be
537 passed back to the code generating the type for the Debug
538 Information Entry for the variable 'VarName'. 'VarName' will then
539 have the original type 'SomeType' in its debug information.
540
541 The original type 'SomeType' will be the type of the field named
542 'VarName' inside the __Block_byref_x_VarName struct.
543
544 NOTE: In order for this to not completely fail on the debugger
545 side, the Debug Information Entry for the variable VarName needs to
546 have a DW_AT_location that tells the debugger how to unwind through
547 the pointers and __Block_byref_x_VarName struct to find the actual
Devang Patel2c4ceb12009-11-21 02:48:08 +0000548 value of the variable. The function addBlockByrefType does this. */
Caroline Ticedc8f6042009-08-31 21:19:37 +0000549
550/// Find the type the programmer originally declared the variable to be
551/// and return that type.
552///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000553DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000554
555 DIType subType = Ty;
556 unsigned tag = Ty.getTag();
557
558 if (tag == dwarf::DW_TAG_pointer_type) {
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000559 DIDerivedType DTy = DIDerivedType(Ty.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000560 subType = DTy.getTypeDerivedFrom();
561 }
562
563 DICompositeType blockStruct = DICompositeType(subType.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000564 DIArray Elements = blockStruct.getTypeArray();
565
Caroline Ticedc8f6042009-08-31 21:19:37 +0000566 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
567 DIDescriptor Element = Elements.getElement(i);
568 DIDerivedType DT = DIDerivedType(Element.getNode());
Devang Patel65dbc902009-11-25 17:36:49 +0000569 if (Name == DT.getName())
Caroline Ticedc8f6042009-08-31 21:19:37 +0000570 return (DT.getTypeDerivedFrom());
571 }
572
573 return Ty;
574}
575
Devang Patel2c4ceb12009-11-21 02:48:08 +0000576/// addComplexAddress - Start with the address based on the location provided,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000577/// and generate the DWARF information necessary to find the actual variable
578/// given the extra address information encoded in the DIVariable, starting from
579/// the starting location. Add the DWARF information to the die.
580///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000581void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000582 unsigned Attribute,
583 const MachineLocation &Location) {
584 const DIVariable &VD = DV->getVariable();
585 DIType Ty = VD.getType();
586
587 // Decode the original location, and use that as the start of the byref
588 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000589 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000590 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000591 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000592
593 if (Location.isReg()) {
594 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000595 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000596 } else {
597 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000598 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
599 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000600 }
601 } else {
602 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000603 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000604 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000605 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
606 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000607 }
608
Devang Patel2c4ceb12009-11-21 02:48:08 +0000609 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000610 }
611
612 for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) {
613 uint64_t Element = VD.getAddrElement(i);
614
615 if (Element == DIFactory::OpPlus) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000616 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
617 addUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i));
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000618 } else if (Element == DIFactory::OpDeref) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000619 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000620 } else llvm_unreachable("unknown DIFactory Opcode");
621 }
622
623 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000624 addBlock(Die, Attribute, 0, Block);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000625}
626
Caroline Ticedc8f6042009-08-31 21:19:37 +0000627/* Byref variables, in Blocks, are declared by the programmer as "SomeType
628 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
629 gives the variable VarName either the struct, or a pointer to the struct, as
630 its type. This is necessary for various behind-the-scenes things the
631 compiler needs to do with by-reference variables in Blocks.
632
633 However, as far as the original *programmer* is concerned, the variable
634 should still have type 'SomeType', as originally declared.
635
Devang Patel2c4ceb12009-11-21 02:48:08 +0000636 The function getBlockByrefType dives into the __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000637 struct to find the original type of the variable, which is then assigned to
638 the variable's Debug Information Entry as its real type. So far, so good.
639 However now the debugger will expect the variable VarName to have the type
640 SomeType. So we need the location attribute for the variable to be an
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000641 expression that explains to the debugger how to navigate through the
Caroline Ticedc8f6042009-08-31 21:19:37 +0000642 pointers and struct to find the actual variable of type SomeType.
643
644 The following function does just that. We start by getting
645 the "normal" location for the variable. This will be the location
646 of either the struct __Block_byref_x_VarName or the pointer to the
647 struct __Block_byref_x_VarName.
648
649 The struct will look something like:
650
651 struct __Block_byref_x_VarName {
652 ... <various fields>
653 struct __Block_byref_x_VarName *forwarding;
654 ... <various other fields>
655 SomeType VarName;
656 ... <maybe more fields>
657 };
658
659 If we are given the struct directly (as our starting point) we
660 need to tell the debugger to:
661
662 1). Add the offset of the forwarding field.
663
Dan Gohmanf451cb82010-02-10 16:03:48 +0000664 2). Follow that pointer to get the real __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000665 struct to use (the real one may have been copied onto the heap).
666
667 3). Add the offset for the field VarName, to find the actual variable.
668
669 If we started with a pointer to the struct, then we need to
670 dereference that pointer first, before the other steps.
671 Translating this into DWARF ops, we will need to append the following
672 to the current location description for the variable:
673
674 DW_OP_deref -- optional, if we start with a pointer
675 DW_OP_plus_uconst <forward_fld_offset>
676 DW_OP_deref
677 DW_OP_plus_uconst <varName_fld_offset>
678
679 That is what this function does. */
680
Devang Patel2c4ceb12009-11-21 02:48:08 +0000681/// addBlockByrefAddress - Start with the address based on the location
Caroline Ticedc8f6042009-08-31 21:19:37 +0000682/// provided, and generate the DWARF information necessary to find the
683/// actual Block variable (navigating the Block struct) based on the
684/// starting location. Add the DWARF information to the die. For
685/// more information, read large comment just above here.
686///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000687void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
Daniel Dunbar00564992009-09-19 20:40:14 +0000688 unsigned Attribute,
689 const MachineLocation &Location) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000690 const DIVariable &VD = DV->getVariable();
691 DIType Ty = VD.getType();
692 DIType TmpTy = Ty;
693 unsigned Tag = Ty.getTag();
694 bool isPointer = false;
695
Devang Patel65dbc902009-11-25 17:36:49 +0000696 StringRef varName = VD.getName();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000697
698 if (Tag == dwarf::DW_TAG_pointer_type) {
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000699 DIDerivedType DTy = DIDerivedType(Ty.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000700 TmpTy = DTy.getTypeDerivedFrom();
701 isPointer = true;
702 }
703
704 DICompositeType blockStruct = DICompositeType(TmpTy.getNode());
705
Daniel Dunbar00564992009-09-19 20:40:14 +0000706 // Find the __forwarding field and the variable field in the __Block_byref
707 // struct.
Daniel Dunbar00564992009-09-19 20:40:14 +0000708 DIArray Fields = blockStruct.getTypeArray();
709 DIDescriptor varField = DIDescriptor();
710 DIDescriptor forwardingField = DIDescriptor();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000711
Daniel Dunbar00564992009-09-19 20:40:14 +0000712 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
713 DIDescriptor Element = Fields.getElement(i);
714 DIDerivedType DT = DIDerivedType(Element.getNode());
Devang Patel65dbc902009-11-25 17:36:49 +0000715 StringRef fieldName = DT.getName();
716 if (fieldName == "__forwarding")
Daniel Dunbar00564992009-09-19 20:40:14 +0000717 forwardingField = Element;
Devang Patel65dbc902009-11-25 17:36:49 +0000718 else if (fieldName == varName)
Daniel Dunbar00564992009-09-19 20:40:14 +0000719 varField = Element;
720 }
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000721
Daniel Dunbar00564992009-09-19 20:40:14 +0000722 // Get the offsets for the forwarding field and the variable field.
Chris Lattner1d65ba72010-03-31 06:06:37 +0000723 unsigned forwardingFieldOffset =
Daniel Dunbar00564992009-09-19 20:40:14 +0000724 DIDerivedType(forwardingField.getNode()).getOffsetInBits() >> 3;
Chris Lattner1d65ba72010-03-31 06:06:37 +0000725 unsigned varFieldOffset =
Daniel Dunbar00564992009-09-19 20:40:14 +0000726 DIDerivedType(varField.getNode()).getOffsetInBits() >> 3;
Caroline Ticedc8f6042009-08-31 21:19:37 +0000727
Mike Stump7e3720d2009-09-24 23:21:26 +0000728 // Decode the original location, and use that as the start of the byref
729 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000730 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Daniel Dunbar00564992009-09-19 20:40:14 +0000731 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000732 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000733
Daniel Dunbar00564992009-09-19 20:40:14 +0000734 if (Location.isReg()) {
735 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000736 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000737 else {
738 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000739 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
740 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000741 }
742 } else {
743 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000744 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000745 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000746 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
747 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000748 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000749
Devang Patel2c4ceb12009-11-21 02:48:08 +0000750 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Daniel Dunbar00564992009-09-19 20:40:14 +0000751 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000752
Mike Stump7e3720d2009-09-24 23:21:26 +0000753 // If we started with a pointer to the __Block_byref... struct, then
Daniel Dunbar00564992009-09-19 20:40:14 +0000754 // the first thing we need to do is dereference the pointer (DW_OP_deref).
Daniel Dunbar00564992009-09-19 20:40:14 +0000755 if (isPointer)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000756 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000757
Daniel Dunbar00564992009-09-19 20:40:14 +0000758 // Next add the offset for the '__forwarding' field:
759 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
760 // adding the offset if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000761 if (forwardingFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000762 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
763 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000764 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000765
Daniel Dunbar00564992009-09-19 20:40:14 +0000766 // Now dereference the __forwarding field to get to the real __Block_byref
767 // struct: DW_OP_deref.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000768 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000769
Daniel Dunbar00564992009-09-19 20:40:14 +0000770 // Now that we've got the real __Block_byref... struct, add the offset
771 // for the variable's field to get to the location of the actual variable:
772 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000773 if (varFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000774 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
775 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000776 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000777
Daniel Dunbar00564992009-09-19 20:40:14 +0000778 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000779 addBlock(Die, Attribute, 0, Block);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000780}
781
Devang Patel2c4ceb12009-11-21 02:48:08 +0000782/// addAddress - Add an address attribute to a die based on the location
Bill Wendling0310d762009-05-15 09:23:25 +0000783/// provided.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000784void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000785 const MachineLocation &Location) {
Chris Lattnerd38fee82010-04-05 00:13:49 +0000786 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling0310d762009-05-15 09:23:25 +0000787 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000788 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000789
790 if (Location.isReg()) {
791 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000792 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000793 } else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000794 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
795 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000796 }
797 } else {
798 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000799 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000800 } else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000801 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
802 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000803 }
804
Devang Patel2c4ceb12009-11-21 02:48:08 +0000805 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Bill Wendling0310d762009-05-15 09:23:25 +0000806 }
807
Devang Patel2c4ceb12009-11-21 02:48:08 +0000808 addBlock(Die, Attribute, 0, Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000809}
810
Devang Patelc366f832009-12-10 19:14:49 +0000811/// addToContextOwner - Add Die into the list of its context owner's children.
812void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
Devang Patel3c91b052010-03-08 20:52:55 +0000813 if (Context.isType()) {
Devang Patelc366f832009-12-10 19:14:49 +0000814 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode()));
815 ContextDIE->addChild(Die);
Devang Patel6404e4e2009-12-15 19:16:48 +0000816 } else if (Context.isNameSpace()) {
817 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context.getNode()));
818 ContextDIE->addChild(Die);
Devang Patelc366f832009-12-10 19:14:49 +0000819 } else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
820 ContextDIE->addChild(Die);
821 else
822 ModuleCU->addDie(Die);
823}
824
Devang Patel16ced732009-12-10 18:05:33 +0000825/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
826/// given DIType.
827DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
828 DIE *TyDIE = ModuleCU->getDIE(Ty.getNode());
829 if (TyDIE)
830 return TyDIE;
831
832 // Create new type.
833 TyDIE = new DIE(dwarf::DW_TAG_base_type);
834 ModuleCU->insertDIE(Ty.getNode(), TyDIE);
835 if (Ty.isBasicType())
836 constructTypeDIE(*TyDIE, DIBasicType(Ty.getNode()));
837 else if (Ty.isCompositeType())
838 constructTypeDIE(*TyDIE, DICompositeType(Ty.getNode()));
839 else {
840 assert(Ty.isDerivedType() && "Unknown kind of DIType");
841 constructTypeDIE(*TyDIE, DIDerivedType(Ty.getNode()));
842 }
843
Devang Patelc366f832009-12-10 19:14:49 +0000844 addToContextOwner(TyDIE, Ty.getContext());
Devang Patel16ced732009-12-10 18:05:33 +0000845 return TyDIE;
846}
847
Devang Patel2c4ceb12009-11-21 02:48:08 +0000848/// addType - Add a new type attribute to the specified entity.
Devang Patel8a241142009-12-09 18:24:21 +0000849void DwarfDebug::addType(DIE *Entity, DIType Ty) {
Devang Patel3c91b052010-03-08 20:52:55 +0000850 if (!Ty.isValid())
Bill Wendling0310d762009-05-15 09:23:25 +0000851 return;
852
853 // Check for pre-existence.
Devang Patel8a241142009-12-09 18:24:21 +0000854 DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode());
Bill Wendling0310d762009-05-15 09:23:25 +0000855 // If it exists then use the existing value.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000856 if (Entry) {
857 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000858 return;
859 }
860
Bill Wendling0310d762009-05-15 09:23:25 +0000861 // Construct type.
Devang Patel16ced732009-12-10 18:05:33 +0000862 DIE *Buffer = getOrCreateTypeDIE(Ty);
Bill Wendling0310d762009-05-15 09:23:25 +0000863
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000864 // Set up proxy.
865 Entry = createDIEEntry(Buffer);
866 ModuleCU->insertDIEEntry(Ty.getNode(), Entry);
867
Devang Patel2c4ceb12009-11-21 02:48:08 +0000868 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000869}
870
Devang Patel2c4ceb12009-11-21 02:48:08 +0000871/// constructTypeDIE - Construct basic type die from DIBasicType.
Devang Patel8a241142009-12-09 18:24:21 +0000872void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000873 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000874 StringRef Name = BTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000875 Buffer.setTag(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000876 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Bill Wendling0310d762009-05-15 09:23:25 +0000877 BTy.getEncoding());
878
879 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +0000880 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000881 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000882 uint64_t Size = BTy.getSizeInBits() >> 3;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000883 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000884}
885
Devang Patel2c4ceb12009-11-21 02:48:08 +0000886/// constructTypeDIE - Construct derived type die from DIDerivedType.
Devang Patel8a241142009-12-09 18:24:21 +0000887void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000888 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000889 StringRef Name = DTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000890 uint64_t Size = DTy.getSizeInBits() >> 3;
891 unsigned Tag = DTy.getTag();
892
893 // FIXME - Workaround for templates.
894 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
895
896 Buffer.setTag(Tag);
897
898 // Map to main type, void will not have a type.
899 DIType FromTy = DTy.getTypeDerivedFrom();
Devang Patel8a241142009-12-09 18:24:21 +0000900 addType(&Buffer, FromTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000901
902 // Add name if not anonymous or intermediate type.
Devang Pateldeea5642009-11-30 23:56:56 +0000903 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000904 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000905
906 // Add size if non-zero (derived types might be zero-sized.)
907 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000908 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000909
910 // Add source line info if available and TyDesc is not a forward declaration.
Devang Patel05f6fa82009-11-23 18:43:37 +0000911 if (!DTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000912 addSourceLine(&Buffer, &DTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000913}
914
Devang Patel2c4ceb12009-11-21 02:48:08 +0000915/// constructTypeDIE - Construct type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +0000916void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000917 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000918 StringRef Name = CTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000919
920 uint64_t Size = CTy.getSizeInBits() >> 3;
921 unsigned Tag = CTy.getTag();
922 Buffer.setTag(Tag);
923
924 switch (Tag) {
925 case dwarf::DW_TAG_vector_type:
926 case dwarf::DW_TAG_array_type:
Devang Patel8a241142009-12-09 18:24:21 +0000927 constructArrayTypeDIE(Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000928 break;
929 case dwarf::DW_TAG_enumeration_type: {
930 DIArray Elements = CTy.getTypeArray();
931
932 // Add enumerators to enumeration type.
933 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
934 DIE *ElemDie = NULL;
Devang Patel3c91b052010-03-08 20:52:55 +0000935 DIDescriptor Enum(Elements.getElement(i).getNode());
936 if (Enum.isEnumerator()) {
937 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum.getNode()));
Devang Patel2c4ceb12009-11-21 02:48:08 +0000938 Buffer.addChild(ElemDie);
Devang Patelc5254722009-10-09 17:51:49 +0000939 }
Bill Wendling0310d762009-05-15 09:23:25 +0000940 }
941 }
942 break;
943 case dwarf::DW_TAG_subroutine_type: {
944 // Add return type.
945 DIArray Elements = CTy.getTypeArray();
946 DIDescriptor RTy = Elements.getElement(0);
Devang Patel8a241142009-12-09 18:24:21 +0000947 addType(&Buffer, DIType(RTy.getNode()));
Bill Wendling0310d762009-05-15 09:23:25 +0000948
949 // Add prototype flag.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000950 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +0000951
952 // Add arguments.
953 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
954 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
955 DIDescriptor Ty = Elements.getElement(i);
Devang Patel8a241142009-12-09 18:24:21 +0000956 addType(Arg, DIType(Ty.getNode()));
Devang Patel2c4ceb12009-11-21 02:48:08 +0000957 Buffer.addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +0000958 }
959 }
960 break;
961 case dwarf::DW_TAG_structure_type:
962 case dwarf::DW_TAG_union_type:
963 case dwarf::DW_TAG_class_type: {
964 // Add elements to structure type.
965 DIArray Elements = CTy.getTypeArray();
966
967 // A forward struct declared type may not have elements available.
Devang Patel3c91b052010-03-08 20:52:55 +0000968 unsigned N = Elements.getNumElements();
969 if (N == 0)
Bill Wendling0310d762009-05-15 09:23:25 +0000970 break;
971
972 // Add elements to structure type.
Devang Patel3c91b052010-03-08 20:52:55 +0000973 for (unsigned i = 0; i < N; ++i) {
Bill Wendling0310d762009-05-15 09:23:25 +0000974 DIDescriptor Element = Elements.getElement(i);
975 DIE *ElemDie = NULL;
Devang Patel3c91b052010-03-08 20:52:55 +0000976 if (Element.isSubprogram())
Devang Patelffe966c2009-12-14 16:18:45 +0000977 ElemDie = createSubprogramDIE(DISubprogram(Element.getNode()));
Devang Patel3c91b052010-03-08 20:52:55 +0000978 else if (Element.isVariable()) {
Devang Patel1ee0cb92010-01-30 01:08:30 +0000979 DIVariable DV(Element.getNode());
980 ElemDie = new DIE(dwarf::DW_TAG_variable);
981 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
982 DV.getName());
983 addType(ElemDie, DV.getType());
984 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
985 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
986 addSourceLine(ElemDie, &DV);
Devang Patel3c91b052010-03-08 20:52:55 +0000987 } else if (Element.isDerivedType())
Devang Patel8a241142009-12-09 18:24:21 +0000988 ElemDie = createMemberDIE(DIDerivedType(Element.getNode()));
Devang Patel3c91b052010-03-08 20:52:55 +0000989 else
990 continue;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000991 Buffer.addChild(ElemDie);
Bill Wendling0310d762009-05-15 09:23:25 +0000992 }
993
Devang Patela1ba2692009-08-27 23:51:51 +0000994 if (CTy.isAppleBlockExtension())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000995 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +0000996
997 unsigned RLang = CTy.getRunTimeLang();
998 if (RLang)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000999 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
Bill Wendling0310d762009-05-15 09:23:25 +00001000 dwarf::DW_FORM_data1, RLang);
Devang Patelb5544992010-01-26 21:16:06 +00001001
1002 DICompositeType ContainingType = CTy.getContainingType();
Devang Patel3c91b052010-03-08 20:52:55 +00001003 if (DIDescriptor(ContainingType.getNode()).isCompositeType())
Devang Patelb5544992010-01-26 21:16:06 +00001004 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
1005 getOrCreateTypeDIE(DIType(ContainingType.getNode())));
Bill Wendling0310d762009-05-15 09:23:25 +00001006 break;
1007 }
1008 default:
1009 break;
1010 }
1011
1012 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +00001013 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001014 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +00001015
Devang Patel8cbb6122010-01-29 18:34:58 +00001016 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type ||
Bill Wendling0310d762009-05-15 09:23:25 +00001017 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
1018 // Add size if non-zero (derived types might be zero-sized.)
1019 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001020 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +00001021 else {
1022 // Add zero size if it is not a forward declaration.
1023 if (CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001024 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001025 else
Devang Patel2c4ceb12009-11-21 02:48:08 +00001026 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
Bill Wendling0310d762009-05-15 09:23:25 +00001027 }
1028
1029 // Add source line info if available.
1030 if (!CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001031 addSourceLine(&Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001032 }
1033}
1034
Devang Patel2c4ceb12009-11-21 02:48:08 +00001035/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1036void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
Bill Wendling0310d762009-05-15 09:23:25 +00001037 int64_t L = SR.getLo();
1038 int64_t H = SR.getHi();
1039 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1040
Devang Patel2c4ceb12009-11-21 02:48:08 +00001041 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patel6325a532009-08-14 20:59:16 +00001042 if (L)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001043 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
Devang Pateld55224c2009-12-04 23:10:24 +00001044 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Bill Wendling0310d762009-05-15 09:23:25 +00001045
Devang Patel2c4ceb12009-11-21 02:48:08 +00001046 Buffer.addChild(DW_Subrange);
Bill Wendling0310d762009-05-15 09:23:25 +00001047}
1048
Devang Patel2c4ceb12009-11-21 02:48:08 +00001049/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +00001050void DwarfDebug::constructArrayTypeDIE(DIE &Buffer,
Bill Wendling0310d762009-05-15 09:23:25 +00001051 DICompositeType *CTy) {
1052 Buffer.setTag(dwarf::DW_TAG_array_type);
1053 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001054 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001055
1056 // Emit derived type.
Devang Patel8a241142009-12-09 18:24:21 +00001057 addType(&Buffer, CTy->getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001058 DIArray Elements = CTy->getTypeArray();
1059
Devang Patel6f01d9c2009-11-21 00:31:03 +00001060 // Get an anonymous type for index type.
Devang Patel8a241142009-12-09 18:24:21 +00001061 DIE *IdxTy = ModuleCU->getIndexTyDie();
Devang Patel6f01d9c2009-11-21 00:31:03 +00001062 if (!IdxTy) {
1063 // Construct an anonymous type for index type.
1064 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001065 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1066 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel6f01d9c2009-11-21 00:31:03 +00001067 dwarf::DW_ATE_signed);
Devang Patel8a241142009-12-09 18:24:21 +00001068 ModuleCU->addDie(IdxTy);
1069 ModuleCU->setIndexTyDie(IdxTy);
Devang Patel6f01d9c2009-11-21 00:31:03 +00001070 }
Bill Wendling0310d762009-05-15 09:23:25 +00001071
1072 // Add subranges to array type.
1073 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1074 DIDescriptor Element = Elements.getElement(i);
1075 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001076 constructSubrangeDIE(Buffer, DISubrange(Element.getNode()), IdxTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001077 }
1078}
1079
Devang Patel2c4ceb12009-11-21 02:48:08 +00001080/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
Devang Patel3c91b052010-03-08 20:52:55 +00001081DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) {
Bill Wendling0310d762009-05-15 09:23:25 +00001082 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
Devang Patel3c91b052010-03-08 20:52:55 +00001083 StringRef Name = ETy.getName();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001084 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel3c91b052010-03-08 20:52:55 +00001085 int64_t Value = ETy.getEnumValue();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001086 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
Bill Wendling0310d762009-05-15 09:23:25 +00001087 return Enumerator;
1088}
1089
Devang Patel351ca332010-01-05 01:46:14 +00001090/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1091/// printer to not emit usual symbol prefix before the symbol name is used then
1092/// return linkage name after skipping this special LLVM prefix.
1093static StringRef getRealLinkageName(StringRef LinkageName) {
1094 char One = '\1';
1095 if (LinkageName.startswith(StringRef(&One, 1)))
1096 return LinkageName.substr(1);
1097 return LinkageName;
1098}
1099
Devang Patel2c4ceb12009-11-21 02:48:08 +00001100/// createGlobalVariableDIE - Create new DIE using GV.
Devang Patel8a241142009-12-09 18:24:21 +00001101DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001102 // If the global variable was optmized out then no need to create debug info
1103 // entry.
Devang Patel84c73e92009-11-06 17:58:12 +00001104 if (!GV.getGlobal()) return NULL;
Devang Patel65dbc902009-11-25 17:36:49 +00001105 if (GV.getDisplayName().empty()) return NULL;
Devang Patel465c3be2009-11-06 01:30:04 +00001106
Bill Wendling0310d762009-05-15 09:23:25 +00001107 DIE *GVDie = new DIE(dwarf::DW_TAG_variable);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001108 addString(GVDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001109 GV.getDisplayName());
1110
Devang Patel65dbc902009-11-25 17:36:49 +00001111 StringRef LinkageName = GV.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001112 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001113 addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001114 getRealLinkageName(LinkageName));
1115
Devang Patel8a241142009-12-09 18:24:21 +00001116 addType(GVDie, GV.getType());
Bill Wendling0310d762009-05-15 09:23:25 +00001117 if (!GV.isLocalToUnit())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001118 addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1119 addSourceLine(GVDie, &GV);
Devang Patelb71a16d2009-10-05 23:22:08 +00001120
Bill Wendling0310d762009-05-15 09:23:25 +00001121 return GVDie;
1122}
1123
Devang Patel2c4ceb12009-11-21 02:48:08 +00001124/// createMemberDIE - Create new member DIE.
Devang Patel8a241142009-12-09 18:24:21 +00001125DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
Bill Wendling0310d762009-05-15 09:23:25 +00001126 DIE *MemberDie = new DIE(DT.getTag());
Devang Patel65dbc902009-11-25 17:36:49 +00001127 StringRef Name = DT.getName();
1128 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001129 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel65dbc902009-11-25 17:36:49 +00001130
Devang Patel8a241142009-12-09 18:24:21 +00001131 addType(MemberDie, DT.getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001132
Devang Patel2c4ceb12009-11-21 02:48:08 +00001133 addSourceLine(MemberDie, &DT);
Bill Wendling0310d762009-05-15 09:23:25 +00001134
Benjamin Kramer345ef342010-03-31 19:34:01 +00001135 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001136 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
Devang Patel33db5082009-11-04 22:06:12 +00001137
Bill Wendling0310d762009-05-15 09:23:25 +00001138 uint64_t Size = DT.getSizeInBits();
Devang Patel61ecbd12009-11-04 23:48:00 +00001139 uint64_t FieldSize = DT.getOriginalTypeSize();
Bill Wendling0310d762009-05-15 09:23:25 +00001140
1141 if (Size != FieldSize) {
1142 // Handle bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001143 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1144 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
Bill Wendling0310d762009-05-15 09:23:25 +00001145
1146 uint64_t Offset = DT.getOffsetInBits();
Bill Wendling0310d762009-05-15 09:23:25 +00001147 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1148 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
Benjamin Kramer3d594fd2010-01-07 17:50:57 +00001149 uint64_t FieldOffset = (HiMark - FieldSize);
Bill Wendling0310d762009-05-15 09:23:25 +00001150 Offset -= FieldOffset;
1151
1152 // Maybe we need to work from the other end.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001153 if (Asm->getTargetData().isLittleEndian())
1154 Offset = FieldSize - (Offset + Size);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001155 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
Bill Wendling0310d762009-05-15 09:23:25 +00001156
Devang Patel33db5082009-11-04 22:06:12 +00001157 // Here WD_AT_data_member_location points to the anonymous
1158 // field that includes this bit field.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001159 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001160
1161 } else
1162 // This is not a bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001163 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001164
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001165 if (DT.getTag() == dwarf::DW_TAG_inheritance
1166 && DT.isVirtual()) {
1167
1168 // For C++, virtual base classes are not at fixed offset. Use following
1169 // expression to extract appropriate offset from vtable.
1170 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1171
Benjamin Kramer345ef342010-03-31 19:34:01 +00001172 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001173 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1174 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1175 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1176 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1177 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1178 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1179 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1180
1181 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1182 VBaseLocationDie);
1183 } else
1184 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
Bill Wendling0310d762009-05-15 09:23:25 +00001185
1186 if (DT.isProtected())
Devang Patel5d11eb02009-12-03 19:11:07 +00001187 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001188 dwarf::DW_ACCESS_protected);
1189 else if (DT.isPrivate())
Devang Patel5d11eb02009-12-03 19:11:07 +00001190 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001191 dwarf::DW_ACCESS_private);
Devang Patel5d11eb02009-12-03 19:11:07 +00001192 else if (DT.getTag() == dwarf::DW_TAG_inheritance)
1193 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1194 dwarf::DW_ACCESS_public);
1195 if (DT.isVirtual())
1196 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1197 dwarf::DW_VIRTUALITY_virtual);
Bill Wendling0310d762009-05-15 09:23:25 +00001198 return MemberDie;
1199}
1200
Devang Patelffe966c2009-12-14 16:18:45 +00001201/// createSubprogramDIE - Create new DIE using SP.
1202DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
1203 DIE *SPDie = ModuleCU->getDIE(SP.getNode());
1204 if (SPDie)
1205 return SPDie;
1206
1207 SPDie = new DIE(dwarf::DW_TAG_subprogram);
Devang Patel1eac3e72010-03-02 17:58:15 +00001208 // Constructors and operators for anonymous aggregates do not have names.
Devang Patel6b506cb2010-03-02 01:26:20 +00001209 if (!SP.getName().empty())
1210 addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
Bill Wendling0310d762009-05-15 09:23:25 +00001211
Devang Patel65dbc902009-11-25 17:36:49 +00001212 StringRef LinkageName = SP.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001213 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001214 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001215 getRealLinkageName(LinkageName));
1216
Devang Patel2c4ceb12009-11-21 02:48:08 +00001217 addSourceLine(SPDie, &SP);
Bill Wendling0310d762009-05-15 09:23:25 +00001218
Bill Wendling0310d762009-05-15 09:23:25 +00001219 // Add prototyped tag, if C or ObjC.
1220 unsigned Lang = SP.getCompileUnit().getLanguage();
1221 if (Lang == dwarf::DW_LANG_C99 || Lang == dwarf::DW_LANG_C89 ||
1222 Lang == dwarf::DW_LANG_ObjC)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001223 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001224
1225 // Add Return Type.
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001226 DICompositeType SPTy = SP.getType();
1227 DIArray Args = SPTy.getTypeArray();
Bill Wendling0310d762009-05-15 09:23:25 +00001228 unsigned SPTag = SPTy.getTag();
Devang Patel5d11eb02009-12-03 19:11:07 +00001229
Devang Patel3c91b052010-03-08 20:52:55 +00001230 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
Devang Patel8a241142009-12-09 18:24:21 +00001231 addType(SPDie, SPTy);
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001232 else
Devang Patel8a241142009-12-09 18:24:21 +00001233 addType(SPDie, DIType(Args.getElement(0).getNode()));
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001234
Devang Patel5d11eb02009-12-03 19:11:07 +00001235 unsigned VK = SP.getVirtuality();
1236 if (VK) {
1237 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001238 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel5d11eb02009-12-03 19:11:07 +00001239 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1240 addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
1241 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
Devang Patel622b0262010-01-19 06:19:05 +00001242 ContainingTypeMap.insert(std::make_pair(SPDie,
1243 SP.getContainingType().getNode()));
Devang Patel5d11eb02009-12-03 19:11:07 +00001244 }
1245
Devang Patelffe966c2009-12-14 16:18:45 +00001246 if (MakeDecl || !SP.isDefinition()) {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001247 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001248
1249 // Add arguments. Do not add arguments for subprogram definition. They will
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001250 // be handled while processing variables.
1251 DICompositeType SPTy = SP.getType();
1252 DIArray Args = SPTy.getTypeArray();
1253 unsigned SPTag = SPTy.getTag();
1254
Bill Wendling0310d762009-05-15 09:23:25 +00001255 if (SPTag == dwarf::DW_TAG_subroutine_type)
1256 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1257 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Devang Patelb4645642010-02-06 01:02:37 +00001258 DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
1259 addType(Arg, ATy);
1260 if (ATy.isArtificial())
1261 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001262 SPDie->addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +00001263 }
1264 }
1265
Devang Patel4e0d19d2010-02-03 19:57:19 +00001266 if (SP.isArtificial())
1267 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1268
Bill Wendling0310d762009-05-15 09:23:25 +00001269 // DW_TAG_inlined_subroutine may refer to this DIE.
Devang Patel8a241142009-12-09 18:24:21 +00001270 ModuleCU->insertDIE(SP.getNode(), SPDie);
Devang Patel2a4a3b72010-04-19 19:14:02 +00001271
Evan Chenge5667632010-04-21 03:18:23 +00001272 if (!DisableFramePointerElim(*Asm->MF))
Devang Patel2a4a3b72010-04-19 19:14:02 +00001273 addUInt(SPDie, dwarf::DW_AT_APPLE_omit_frame_ptr, dwarf::DW_FORM_flag, 1);
1274
Bill Wendling0310d762009-05-15 09:23:25 +00001275 return SPDie;
1276}
1277
Devang Patel53bb5c92009-11-10 23:06:00 +00001278DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
Chris Lattnered7a77b2010-03-31 05:36:29 +00001279 assert(N && "Invalid Scope encoding!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001280
1281 DbgScope *AScope = AbstractScopes.lookup(N);
1282 if (AScope)
1283 return AScope;
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001284
Devang Patel53bb5c92009-11-10 23:06:00 +00001285 DbgScope *Parent = NULL;
1286
1287 DIDescriptor Scope(N);
1288 if (Scope.isLexicalBlock()) {
1289 DILexicalBlock DB(N);
1290 DIDescriptor ParentDesc = DB.getContext();
Devang Patel3c91b052010-03-08 20:52:55 +00001291 Parent = getOrCreateAbstractScope(ParentDesc.getNode());
Devang Patel53bb5c92009-11-10 23:06:00 +00001292 }
1293
1294 AScope = new DbgScope(Parent, DIDescriptor(N), NULL);
1295
1296 if (Parent)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001297 Parent->addScope(AScope);
Devang Patel53bb5c92009-11-10 23:06:00 +00001298 AScope->setAbstractScope();
1299 AbstractScopes[N] = AScope;
1300 if (DIDescriptor(N).isSubprogram())
1301 AbstractScopesList.push_back(AScope);
1302 return AScope;
1303}
Devang Patelaf9e8472009-10-01 20:31:14 +00001304
Devang Patel5f094002010-04-06 23:53:48 +00001305/// isSubprogramContext - Return true if Context is either a subprogram
1306/// or another context nested inside a subprogram.
Dan Gohmanb3579832010-04-15 17:08:50 +00001307static bool isSubprogramContext(MDNode *Context) {
Devang Patel5f094002010-04-06 23:53:48 +00001308 if (!Context)
1309 return false;
1310 DIDescriptor D(Context);
1311 if (D.isSubprogram())
1312 return true;
1313 if (D.isType())
1314 return isSubprogramContext(DIType(Context).getContext().getNode());
1315 return false;
1316}
1317
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001318/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
Devang Patel2c4ceb12009-11-21 02:48:08 +00001319/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
1320/// If there are global variables in this scope then create and insert
1321/// DIEs for these variables.
1322DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00001323 DIE *SPDie = ModuleCU->getDIE(SPNode);
1324 assert(SPDie && "Unable to find subprogram DIE!");
1325 DISubprogram SP(SPNode);
Chris Lattner206d61e2010-03-13 07:26:18 +00001326
Chris Lattnerd38fee82010-04-05 00:13:49 +00001327 // There is not any need to generate specification DIE for a function
1328 // defined at compile unit level. If a function is defined inside another
1329 // function then gdb prefers the definition at top level and but does not
1330 // expect specification DIE in parent function. So avoid creating
1331 // specification DIE for a function defined inside a function.
1332 if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001333 !SP.getContext().isFile() &&
1334 !isSubprogramContext(SP.getContext().getNode())) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00001335 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1336
1337 // Add arguments.
1338 DICompositeType SPTy = SP.getType();
1339 DIArray Args = SPTy.getTypeArray();
1340 unsigned SPTag = SPTy.getTag();
1341 if (SPTag == dwarf::DW_TAG_subroutine_type)
1342 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1343 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1344 DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
1345 addType(Arg, ATy);
1346 if (ATy.isArtificial())
1347 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1348 SPDie->addChild(Arg);
1349 }
1350 DIE *SPDeclDie = SPDie;
1351 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1352 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1353 SPDeclDie);
1354 ModuleCU->addDie(SPDie);
1355 }
1356
1357 addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1358 Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
1359 addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
1360 Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
1361 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1362 MachineLocation Location(RI->getFrameRegister(*Asm->MF));
1363 addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
Devang Patelb4645642010-02-06 01:02:37 +00001364
Chris Lattnerd38fee82010-04-05 00:13:49 +00001365 if (!DISubprogram(SPNode).isLocalToUnit())
1366 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1367
1368 return SPDie;
Devang Patel53bb5c92009-11-10 23:06:00 +00001369}
1370
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001371/// constructLexicalScope - Construct new DW_TAG_lexical_block
Devang Patel2c4ceb12009-11-21 02:48:08 +00001372/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
1373DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
Devang Patel9cdb4102010-04-21 16:32:19 +00001374
1375 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
1376 if (Scope->isAbstractScope())
1377 return ScopeDIE;
1378
1379 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1380 if (Ranges.empty())
1381 return 0;
1382
1383 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1384 if (Ranges.size() > 1) {
1385 // .debug_range section has not been laid out yet. Emit offset in
1386 // .debug_range as a uint, size 4, for now. emitDIE will handle
1387 // DW_AT_ranges appropriately.
1388 addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
1389 DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());
1390 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
1391 RE = Ranges.end(); RI != RE; ++RI) {
1392 DebugRangeSymbols.push_back(InsnBeforeLabelMap.lookup(RI->first));
1393 DebugRangeSymbols.push_back(InsnAfterLabelMap.lookup(RI->second));
1394 }
1395 DebugRangeSymbols.push_back(NULL);
1396 DebugRangeSymbols.push_back(NULL);
1397 return ScopeDIE;
1398 }
1399
1400 MCSymbol *Start = InsnBeforeLabelMap.lookup(RI->first);
1401 MCSymbol *End = InsnAfterLabelMap.lookup(RI->second);
1402
Devang Patelaead63c2010-03-29 22:59:58 +00001403 if (Start == 0 || End == 0) return 0;
Devang Patel53bb5c92009-11-10 23:06:00 +00001404
Chris Lattnerb7db7332010-03-09 01:58:53 +00001405 assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
1406 assert(End->isDefined() && "Invalid end label for an inlined scope!");
Chris Lattnera34ec2292010-03-09 01:51:43 +00001407
Devang Patel2c4ceb12009-11-21 02:48:08 +00001408 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
Chris Lattnerd38fee82010-04-05 00:13:49 +00001409 Start ? Start : Asm->GetTempSymbol("func_begin",
1410 Asm->getFunctionNumber()));
Devang Patel2c4ceb12009-11-21 02:48:08 +00001411 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
Chris Lattnerd38fee82010-04-05 00:13:49 +00001412 End ? End : Asm->GetTempSymbol("func_end",Asm->getFunctionNumber()));
Devang Patel53bb5c92009-11-10 23:06:00 +00001413
1414 return ScopeDIE;
1415}
1416
Devang Patel2c4ceb12009-11-21 02:48:08 +00001417/// constructInlinedScopeDIE - This scope represents inlined body of
1418/// a function. Construct DIE to represent this concrete inlined copy
1419/// of the function.
1420DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
Devang Patel9cdb4102010-04-21 16:32:19 +00001421
1422 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1423 assert (Ranges.empty() == false
1424 && "DbgScope does not have instruction markers!");
1425
1426 // FIXME : .debug_inlined section specification does not clearly state how
1427 // to emit inlined scope that is split into multiple instruction ranges.
1428 // For now, use first instruction range and emit low_pc/high_pc pair and
1429 // corresponding .debug_inlined section entry for this pair.
1430 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1431 MCSymbol *StartLabel = InsnBeforeLabelMap.lookup(RI->first);
1432 MCSymbol *EndLabel = InsnAfterLabelMap.lookup(RI->second);
1433
1434 if (StartLabel == 0 || EndLabel == 0) {
1435 assert (0 && "Unexpected Start and End labels for a inlined scope!");
1436 return 0;
1437 }
Chris Lattnerb7db7332010-03-09 01:58:53 +00001438 assert(StartLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001439 "Invalid starting label for an inlined scope!");
Chris Lattnerb7db7332010-03-09 01:58:53 +00001440 assert(EndLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001441 "Invalid end label for an inlined scope!");
Devang Patel9cdb4102010-04-21 16:32:19 +00001442
Devang Patel3c91b052010-03-08 20:52:55 +00001443 if (!Scope->getScopeNode())
Devang Patel0ef3fa62010-03-08 19:20:38 +00001444 return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001445 DIScope DS(Scope->getScopeNode());
Devang Patel53bb5c92009-11-10 23:06:00 +00001446 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
1447
1448 DISubprogram InlinedSP = getDISubprogram(DS.getNode());
Devang Patel017d1212009-11-20 21:37:22 +00001449 DIE *OriginDIE = ModuleCU->getDIE(InlinedSP.getNode());
Chris Lattnered7a77b2010-03-31 05:36:29 +00001450 assert(OriginDIE && "Unable to find Origin DIE!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001451 addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001452 dwarf::DW_FORM_ref4, OriginDIE);
1453
Chris Lattner6ed0f902010-03-09 00:31:02 +00001454 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel);
Chris Lattnerb7db7332010-03-09 01:58:53 +00001455 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel);
Devang Patel53bb5c92009-11-10 23:06:00 +00001456
1457 InlinedSubprogramDIEs.insert(OriginDIE);
1458
1459 // Track the start label for this inlined function.
Devang Patel622b0262010-01-19 06:19:05 +00001460 DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
Devang Patel53bb5c92009-11-10 23:06:00 +00001461 I = InlineInfo.find(InlinedSP.getNode());
1462
1463 if (I == InlineInfo.end()) {
Chris Lattner6ed0f902010-03-09 00:31:02 +00001464 InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartLabel,
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001465 ScopeDIE));
Devang Patel53bb5c92009-11-10 23:06:00 +00001466 InlinedSPNodes.push_back(InlinedSP.getNode());
1467 } else
Chris Lattner6ed0f902010-03-09 00:31:02 +00001468 I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
Devang Patel53bb5c92009-11-10 23:06:00 +00001469
Devang Patel53bb5c92009-11-10 23:06:00 +00001470 DILocation DL(Scope->getInlinedAt());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001471 addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID());
1472 addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
Devang Patel53bb5c92009-11-10 23:06:00 +00001473
1474 return ScopeDIE;
1475}
1476
Devang Patel2c4ceb12009-11-21 02:48:08 +00001477
1478/// constructVariableDIE - Construct a DIE for the given DbgVariable.
Devang Patel8a241142009-12-09 18:24:21 +00001479DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
Devang Patel53bb5c92009-11-10 23:06:00 +00001480 // Get the descriptor.
1481 const DIVariable &VD = DV->getVariable();
Devang Patel65dbc902009-11-25 17:36:49 +00001482 StringRef Name = VD.getName();
1483 if (Name.empty())
Devang Patel3fb6bd62009-11-13 02:25:26 +00001484 return NULL;
Devang Patel53bb5c92009-11-10 23:06:00 +00001485
1486 // Translate tag to proper Dwarf tag. The result variable is dropped for
1487 // now.
1488 unsigned Tag;
1489 switch (VD.getTag()) {
1490 case dwarf::DW_TAG_return_variable:
1491 return NULL;
1492 case dwarf::DW_TAG_arg_variable:
1493 Tag = dwarf::DW_TAG_formal_parameter;
1494 break;
1495 case dwarf::DW_TAG_auto_variable: // fall thru
1496 default:
1497 Tag = dwarf::DW_TAG_variable;
1498 break;
1499 }
1500
1501 // Define variable debug information entry.
1502 DIE *VariableDie = new DIE(Tag);
1503
1504
1505 DIE *AbsDIE = NULL;
1506 if (DbgVariable *AV = DV->getAbstractVariable())
1507 AbsDIE = AV->getDIE();
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001508
Devang Patel53bb5c92009-11-10 23:06:00 +00001509 if (AbsDIE) {
1510 DIScope DS(Scope->getScopeNode());
1511 DISubprogram InlinedSP = getDISubprogram(DS.getNode());
Devang Patel017d1212009-11-20 21:37:22 +00001512 DIE *OriginSPDIE = ModuleCU->getDIE(InlinedSP.getNode());
Daniel Dunbarc0326792009-11-11 03:09:50 +00001513 (void) OriginSPDIE;
Chris Lattnered7a77b2010-03-31 05:36:29 +00001514 assert(OriginSPDIE && "Unable to find Origin DIE for the SP!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001515 DIE *AbsDIE = DV->getAbstractVariable()->getDIE();
Chris Lattnered7a77b2010-03-31 05:36:29 +00001516 assert(AbsDIE && "Unable to find Origin DIE for the Variable!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001517 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001518 dwarf::DW_FORM_ref4, AbsDIE);
1519 }
1520 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001521 addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
1522 addSourceLine(VariableDie, &VD);
Devang Patel53bb5c92009-11-10 23:06:00 +00001523
1524 // Add variable type.
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001525 // FIXME: isBlockByrefVariable should be reformulated in terms of complex
Devang Patel53bb5c92009-11-10 23:06:00 +00001526 // addresses instead.
1527 if (VD.isBlockByrefVariable())
Devang Patel8a241142009-12-09 18:24:21 +00001528 addType(VariableDie, getBlockByrefType(VD.getType(), Name));
Devang Patel53bb5c92009-11-10 23:06:00 +00001529 else
Devang Patel8a241142009-12-09 18:24:21 +00001530 addType(VariableDie, VD.getType());
Devang Patel53bb5c92009-11-10 23:06:00 +00001531 }
1532
1533 // Add variable address.
1534 if (!Scope->isAbstractScope()) {
Devang Patel90a48ad2010-03-15 18:33:46 +00001535 // Check if variable is described by DBG_VALUE instruction.
1536 if (const MachineInstr *DbgValueInsn = DV->getDbgValue()) {
1537 if (DbgValueInsn->getNumOperands() == 3) {
1538 // FIXME : Handle getNumOperands != 3
1539 if (DbgValueInsn->getOperand(0).getType()
1540 == MachineOperand::MO_Register
1541 && DbgValueInsn->getOperand(0).getReg()) {
1542 MachineLocation Location;
1543 Location.set(DbgValueInsn->getOperand(0).getReg());
1544 addAddress(VariableDie, dwarf::DW_AT_location, Location);
Devang Patelaead63c2010-03-29 22:59:58 +00001545 if (MCSymbol *VS = DV->getDbgValueLabel())
1546 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1547 VS);
Devang Patel90a48ad2010-03-15 18:33:46 +00001548 } else if (DbgValueInsn->getOperand(0).getType() ==
1549 MachineOperand::MO_Immediate) {
Benjamin Kramer345ef342010-03-31 19:34:01 +00001550 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel90a48ad2010-03-15 18:33:46 +00001551 unsigned Imm = DbgValueInsn->getOperand(0).getImm();
1552 addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
1553 addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
Devang Patelaead63c2010-03-29 22:59:58 +00001554 if (MCSymbol *VS = DV->getDbgValueLabel())
1555 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1556 VS);
Bill Wendling57fbba42010-04-05 22:59:21 +00001557 } else if (DbgValueInsn->getOperand(0).getType() ==
1558 MachineOperand::MO_FPImmediate) {
1559 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1560 APFloat FPImm = DbgValueInsn->getOperand(0).getFPImm()->getValueAPF();
1561
1562 // Get the raw data form of the floating point.
1563 const APInt FltVal = FPImm.bitcastToAPInt();
1564 const char *FltPtr = (const char*)FltVal.getRawData();
1565
John McCall795ee9d2010-04-06 23:35:53 +00001566 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
Bill Wendling57fbba42010-04-05 22:59:21 +00001567 bool LittleEndian = Asm->getTargetData().isLittleEndian();
1568 int Incr = (LittleEndian ? 1 : -1);
1569 int Start = (LittleEndian ? 0 : NumBytes - 1);
1570 int Stop = (LittleEndian ? NumBytes : -1);
1571
1572 // Output the constant to DWARF one byte at a time.
1573 for (; Start != Stop; Start += Incr)
1574 addUInt(Block, 0, dwarf::DW_FORM_data1,
1575 (unsigned char)0xFF & FltPtr[Start]);
1576
1577 addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
1578
1579 if (MCSymbol *VS = DV->getDbgValueLabel())
1580 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1581 VS);
Devang Patel90a48ad2010-03-15 18:33:46 +00001582 } else {
1583 //FIXME : Handle other operand types.
1584 delete VariableDie;
1585 return NULL;
1586 }
1587 }
1588 } else {
1589 MachineLocation Location;
1590 unsigned FrameReg;
Chris Lattnerd38fee82010-04-05 00:13:49 +00001591 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1592 int Offset = RI->getFrameIndexReference(*Asm->MF, DV->getFrameIndex(),
Chris Lattner1d65ba72010-03-31 06:06:37 +00001593 FrameReg);
Devang Patel90a48ad2010-03-15 18:33:46 +00001594 Location.set(FrameReg, Offset);
1595
1596 if (VD.hasComplexAddress())
1597 addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1598 else if (VD.isBlockByrefVariable())
1599 addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1600 else
1601 addAddress(VariableDie, dwarf::DW_AT_location, Location);
1602 }
Devang Patel53bb5c92009-11-10 23:06:00 +00001603 }
Devang Patelb4645642010-02-06 01:02:37 +00001604
1605 if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
1606 addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel53bb5c92009-11-10 23:06:00 +00001607 DV->setDIE(VariableDie);
1608 return VariableDie;
1609
1610}
Devang Patel2c4ceb12009-11-21 02:48:08 +00001611
Devang Patel193f7202009-11-24 01:14:22 +00001612void DwarfDebug::addPubTypes(DISubprogram SP) {
1613 DICompositeType SPTy = SP.getType();
1614 unsigned SPTag = SPTy.getTag();
1615 if (SPTag != dwarf::DW_TAG_subroutine_type)
1616 return;
1617
1618 DIArray Args = SPTy.getTypeArray();
Devang Patel193f7202009-11-24 01:14:22 +00001619 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
1620 DIType ATy(Args.getElement(i).getNode());
Devang Patel3c91b052010-03-08 20:52:55 +00001621 if (!ATy.isValid())
Devang Patel193f7202009-11-24 01:14:22 +00001622 continue;
1623 DICompositeType CATy = getDICompositeType(ATy);
Devang Patel50d80e32010-04-13 20:35:04 +00001624 if (DIDescriptor(CATy.getNode()).Verify() && !CATy.getName().empty()
1625 && !CATy.isForwardDecl()) {
Devang Patel193f7202009-11-24 01:14:22 +00001626 if (DIEEntry *Entry = ModuleCU->getDIEEntry(CATy.getNode()))
1627 ModuleCU->addGlobalType(CATy.getName(), Entry->getEntry());
1628 }
1629 }
1630}
1631
Devang Patel2c4ceb12009-11-21 02:48:08 +00001632/// constructScopeDIE - Construct a DIE for this scope.
1633DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
Devang Patel3c91b052010-03-08 20:52:55 +00001634 if (!Scope || !Scope->getScopeNode())
1635 return NULL;
1636
1637 DIScope DS(Scope->getScopeNode());
1638 DIE *ScopeDIE = NULL;
1639 if (Scope->getInlinedAt())
1640 ScopeDIE = constructInlinedScopeDIE(Scope);
1641 else if (DS.isSubprogram()) {
1642 if (Scope->isAbstractScope())
1643 ScopeDIE = ModuleCU->getDIE(DS.getNode());
1644 else
1645 ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
1646 }
Devang Patelaead63c2010-03-29 22:59:58 +00001647 else
Devang Patel3c91b052010-03-08 20:52:55 +00001648 ScopeDIE = constructLexicalScopeDIE(Scope);
Devang Patelaead63c2010-03-29 22:59:58 +00001649 if (!ScopeDIE) return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001650
Devang Patel53bb5c92009-11-10 23:06:00 +00001651 // Add variables to scope.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001652 const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
Devang Patel53bb5c92009-11-10 23:06:00 +00001653 for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
Devang Patel8a241142009-12-09 18:24:21 +00001654 DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001655 if (VariableDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001656 ScopeDIE->addChild(VariableDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001657 }
1658
1659 // Add nested scopes.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001660 const SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes();
Devang Patel53bb5c92009-11-10 23:06:00 +00001661 for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
1662 // Define the Scope debug information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001663 DIE *NestedDIE = constructScopeDIE(Scopes[j]);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001664 if (NestedDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001665 ScopeDIE->addChild(NestedDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001666 }
Devang Patel193f7202009-11-24 01:14:22 +00001667
1668 if (DS.isSubprogram())
1669 addPubTypes(DISubprogram(DS.getNode()));
1670
1671 return ScopeDIE;
Devang Patel53bb5c92009-11-10 23:06:00 +00001672}
1673
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001674/// GetOrCreateSourceID - Look up the source id with the given directory and
1675/// source file names. If none currently exists, create a new id and insert it
1676/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
1677/// maps as well.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001678unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName){
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001679 unsigned DId;
1680 StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
1681 if (DI != DirectoryIdMap.end()) {
1682 DId = DI->getValue();
1683 } else {
1684 DId = DirectoryNames.size() + 1;
1685 DirectoryIdMap[DirName] = DId;
1686 DirectoryNames.push_back(DirName);
1687 }
1688
1689 unsigned FId;
1690 StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
1691 if (FI != SourceFileIdMap.end()) {
1692 FId = FI->getValue();
1693 } else {
1694 FId = SourceFileNames.size() + 1;
1695 SourceFileIdMap[FileName] = FId;
1696 SourceFileNames.push_back(FileName);
1697 }
1698
1699 DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
1700 SourceIdMap.find(std::make_pair(DId, FId));
1701 if (SI != SourceIdMap.end())
1702 return SI->second;
1703
1704 unsigned SrcId = SourceIds.size() + 1; // DW_AT_decl_file cannot be 0.
1705 SourceIdMap[std::make_pair(DId, FId)] = SrcId;
1706 SourceIds.push_back(std::make_pair(DId, FId));
1707
1708 return SrcId;
1709}
1710
Devang Patel6404e4e2009-12-15 19:16:48 +00001711/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1712DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace NS) {
1713 DIE *NDie = ModuleCU->getDIE(NS.getNode());
1714 if (NDie)
1715 return NDie;
1716 NDie = new DIE(dwarf::DW_TAG_namespace);
1717 ModuleCU->insertDIE(NS.getNode(), NDie);
1718 if (!NS.getName().empty())
1719 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
1720 addSourceLine(NDie, &NS);
1721 addToContextOwner(NDie, NS.getContext());
1722 return NDie;
1723}
1724
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001725void DwarfDebug::constructCompileUnit(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001726 DICompileUnit DIUnit(N);
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001727 // Use first compile unit marked as isMain as the compile unit for this
1728 // module.
1729 if (ModuleCU || !DIUnit.isMain())
1730 return;
Devang Patel65dbc902009-11-25 17:36:49 +00001731 StringRef FN = DIUnit.getFilename();
1732 StringRef Dir = DIUnit.getDirectory();
Devang Patel5ccdd102009-09-29 18:40:58 +00001733 unsigned ID = GetOrCreateSourceID(Dir, FN);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001734
1735 DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001736 addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001737 DIUnit.getProducer());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001738 addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001739 DIUnit.getLanguage());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001740 addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
Chris Lattner9c69e285532010-04-04 22:59:04 +00001741 addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, TextSectionSym);
Devang Patel4a602ca2010-03-22 23:11:36 +00001742 addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
Chris Lattnerc0215722010-04-04 19:25:43 +00001743 Asm->GetTempSymbol("text_end"));
Devang Patel4a602ca2010-03-22 23:11:36 +00001744 // DW_AT_stmt_list is a offset of line number information for this
1745 // compile unit in debug_line section. It is always zero when only one
1746 // compile unit is emitted in one object file.
1747 addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001748
Devang Patel65dbc902009-11-25 17:36:49 +00001749 if (!Dir.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001750 addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001751 if (DIUnit.isOptimized())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001752 addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001753
Devang Patel65dbc902009-11-25 17:36:49 +00001754 StringRef Flags = DIUnit.getFlags();
1755 if (!Flags.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001756 addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001757
1758 unsigned RVer = DIUnit.getRunTimeVersion();
1759 if (RVer)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001760 addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001761 dwarf::DW_FORM_data1, RVer);
1762
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001763 assert(!ModuleCU &&
1764 "ModuleCU assigned since the top of constructCompileUnit");
1765 ModuleCU = new CompileUnit(ID, Die);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001766}
1767
Devang Patel2c4ceb12009-11-21 02:48:08 +00001768void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001769 DIGlobalVariable DI_GV(N);
Daniel Dunbarf612ff62009-09-19 20:40:05 +00001770
Devang Patel905cf5e2009-09-04 23:59:07 +00001771 // If debug information is malformed then ignore it.
1772 if (DI_GV.Verify() == false)
1773 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001774
1775 // Check for pre-existence.
Devang Patel017d1212009-11-20 21:37:22 +00001776 if (ModuleCU->getDIE(DI_GV.getNode()))
Devang Patel13e16b62009-06-26 01:49:18 +00001777 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001778
Devang Patel8a241142009-12-09 18:24:21 +00001779 DIE *VariableDie = createGlobalVariableDIE(DI_GV);
Devang Pateledb45632009-12-10 23:25:41 +00001780 if (!VariableDie)
1781 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001782
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001783 // Add to map.
Devang Patel017d1212009-11-20 21:37:22 +00001784 ModuleCU->insertDIE(N, VariableDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001785
1786 // Add to context owner.
Devang Patelc9b16cc2010-01-15 01:12:22 +00001787 DIDescriptor GVContext = DI_GV.getContext();
1788 // Do not create specification DIE if context is either compile unit
1789 // or a subprogram.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001790 if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001791 !GVContext.isFile() &&
1792 !isSubprogramContext(GVContext.getNode())) {
Devang Patel6404e4e2009-12-15 19:16:48 +00001793 // Create specification DIE.
1794 DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
1795 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1796 dwarf::DW_FORM_ref4, VariableDie);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001797 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001798 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001799 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001800 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001801 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Devang Patel8581e012010-02-09 01:58:33 +00001802 addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Devang Patel6404e4e2009-12-15 19:16:48 +00001803 ModuleCU->addDie(VariableSpecDIE);
1804 } else {
Benjamin Kramer345ef342010-03-31 19:34:01 +00001805 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001806 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001807 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001808 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001809 addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
1810 }
Devang Patelc9b16cc2010-01-15 01:12:22 +00001811 addToContextOwner(VariableDie, GVContext);
Devang Patelc366f832009-12-10 19:14:49 +00001812
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001813 // Expose as global. FIXME - need to check external flag.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001814 ModuleCU->addGlobal(DI_GV.getName(), VariableDie);
Devang Patel193f7202009-11-24 01:14:22 +00001815
1816 DIType GTy = DI_GV.getType();
Devang Patel50d80e32010-04-13 20:35:04 +00001817 if (GTy.isCompositeType() && !GTy.getName().empty()
1818 && !GTy.isForwardDecl()) {
Devang Patel193f7202009-11-24 01:14:22 +00001819 DIEEntry *Entry = ModuleCU->getDIEEntry(GTy.getNode());
Chris Lattnered7a77b2010-03-31 05:36:29 +00001820 assert(Entry && "Missing global type!");
Devang Patel193f7202009-11-24 01:14:22 +00001821 ModuleCU->addGlobalType(GTy.getName(), Entry->getEntry());
1822 }
Devang Patel13e16b62009-06-26 01:49:18 +00001823 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001824}
1825
Devang Patel2c4ceb12009-11-21 02:48:08 +00001826void DwarfDebug::constructSubprogramDIE(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001827 DISubprogram SP(N);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001828
Stuart Hastings639336e2010-04-06 21:38:29 +00001829 // Check for pre-existence.
1830 if (ModuleCU->getDIE(N))
1831 return;
1832
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001833 if (!SP.isDefinition())
1834 // This is a method declaration which will be handled while constructing
1835 // class type.
Devang Patel13e16b62009-06-26 01:49:18 +00001836 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001837
Stuart Hastings639336e2010-04-06 21:38:29 +00001838 DIE *SubprogramDie = createSubprogramDIE(SP);
1839
1840 // Add to map.
1841 ModuleCU->insertDIE(N, SubprogramDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001842
1843 // Add to context owner.
Devang Patel6404e4e2009-12-15 19:16:48 +00001844 addToContextOwner(SubprogramDie, SP.getContext());
Devang Patel0000fad2009-12-08 23:21:45 +00001845
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001846 // Expose as global.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001847 ModuleCU->addGlobal(SP.getName(), SubprogramDie);
Devang Patel193f7202009-11-24 01:14:22 +00001848
Devang Patel13e16b62009-06-26 01:49:18 +00001849 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001850}
1851
Devang Patel2c4ceb12009-11-21 02:48:08 +00001852/// beginModule - Emit all Dwarf sections that should come prior to the
Daniel Dunbar00564992009-09-19 20:40:14 +00001853/// content. Create global DIEs and emit initial debug info sections.
1854/// This is inovked by the target AsmPrinter.
Chris Lattner75f50722010-04-04 07:48:20 +00001855void DwarfDebug::beginModule(Module *M) {
Devang Patel78ab9e22009-07-30 18:56:46 +00001856 DebugInfoFinder DbgFinder;
1857 DbgFinder.processModule(*M);
Devang Patel13e16b62009-06-26 01:49:18 +00001858
Chris Lattnerd850ac72010-04-05 02:19:28 +00001859 bool HasDebugInfo = false;
1860
1861 // Scan all the compile-units to see if there are any marked as the main unit.
1862 // if not, we do not generate debug info.
1863 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1864 E = DbgFinder.compile_unit_end(); I != E; ++I) {
1865 if (DICompileUnit(*I).isMain()) {
1866 HasDebugInfo = true;
1867 break;
1868 }
1869 }
1870
1871 if (!HasDebugInfo) return;
1872
1873 // Tell MMI that we have debug info.
1874 MMI->setDebugInfoAvailability(true);
1875
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001876 // Emit initial sections.
Chris Lattnerd850ac72010-04-05 02:19:28 +00001877 EmitSectionLabels();
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001878
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001879 // Create all the compile unit DIEs.
Devang Patel78ab9e22009-07-30 18:56:46 +00001880 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1881 E = DbgFinder.compile_unit_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001882 constructCompileUnit(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001883
Devang Patel53bb5c92009-11-10 23:06:00 +00001884 // Create DIEs for each subprogram.
Devang Patel78ab9e22009-07-30 18:56:46 +00001885 for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
1886 E = DbgFinder.subprogram_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001887 constructSubprogramDIE(*I);
Devang Patel13e16b62009-06-26 01:49:18 +00001888
Devang Patelc366f832009-12-10 19:14:49 +00001889 // Create DIEs for each global variable.
1890 for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
1891 E = DbgFinder.global_variable_end(); I != E; ++I)
1892 constructGlobalVariableDIE(*I);
1893
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001894 // Prime section data.
Chris Lattnerf0144122009-07-28 03:13:23 +00001895 SectionMap.insert(Asm->getObjFileLowering().getTextSection());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001896
1897 // Print out .file directives to specify files for .loc directives. These are
1898 // printed out early so that they precede any .loc directives.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001899 if (Asm->MAI->hasDotLocAndDotFile()) {
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001900 for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
1901 // Remember source id starts at 1.
1902 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
Chris Lattner0ad9c912010-01-22 22:09:00 +00001903 // FIXME: don't use sys::path for this! This should not depend on the
1904 // host.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001905 sys::Path FullPath(getSourceDirectoryName(Id.first));
1906 bool AppendOk =
1907 FullPath.appendComponent(getSourceFileName(Id.second));
1908 assert(AppendOk && "Could not append filename to directory!");
1909 AppendOk = false;
Chris Lattnera6594fc2010-01-25 18:58:59 +00001910 Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001911 }
1912 }
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001913}
1914
Devang Patel2c4ceb12009-11-21 02:48:08 +00001915/// endModule - Emit all Dwarf sections that should come after the content.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001916///
Devang Patel2c4ceb12009-11-21 02:48:08 +00001917void DwarfDebug::endModule() {
Bill Wendling5f017e82010-04-07 09:28:04 +00001918 if (!ModuleCU) return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001919
Devang Patel53bb5c92009-11-10 23:06:00 +00001920 // Attach DW_AT_inline attribute with inlined subprogram DIEs.
1921 for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
1922 AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) {
1923 DIE *ISP = *AI;
Devang Patel2c4ceb12009-11-21 02:48:08 +00001924 addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
Devang Patel53bb5c92009-11-10 23:06:00 +00001925 }
1926
Devang Patel622b0262010-01-19 06:19:05 +00001927 for (DenseMap<DIE *, MDNode *>::iterator CI = ContainingTypeMap.begin(),
Devang Patel5d11eb02009-12-03 19:11:07 +00001928 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1929 DIE *SPDie = CI->first;
1930 MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
1931 if (!N) continue;
1932 DIE *NDie = ModuleCU->getDIE(N);
1933 if (!NDie) continue;
1934 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
Devang Patel5d11eb02009-12-03 19:11:07 +00001935 }
1936
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001937 // Standard sections final addresses.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001938 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00001939 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001940 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00001941 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001942
1943 // End text sections.
1944 for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001945 Asm->OutStreamer.SwitchSection(SectionMap[i]);
Chris Lattnerc0215722010-04-04 19:25:43 +00001946 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", i));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001947 }
1948
1949 // Emit common frame information.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001950 emitCommonDebugFrame();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001951
1952 // Emit function debug frame information
1953 for (std::vector<FunctionDebugFrameInfo>::iterator I = DebugFrames.begin(),
1954 E = DebugFrames.end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001955 emitFunctionDebugFrame(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001956
1957 // Compute DIE offsets and sizes.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001958 computeSizeAndOffsets();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001959
1960 // Emit all the DIEs into a debug info section
Devang Patel2c4ceb12009-11-21 02:48:08 +00001961 emitDebugInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001962
1963 // Corresponding abbreviations into a abbrev section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001964 emitAbbreviations();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001965
1966 // Emit source line correspondence into a debug line section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001967 emitDebugLines();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001968
1969 // Emit info into a debug pubnames section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001970 emitDebugPubNames();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001971
Devang Patel193f7202009-11-24 01:14:22 +00001972 // Emit info into a debug pubtypes section.
1973 emitDebugPubTypes();
1974
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001975 // Emit info into a debug loc section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001976 emitDebugLoc();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001977
1978 // Emit info into a debug aranges section.
1979 EmitDebugARanges();
1980
1981 // Emit info into a debug ranges section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001982 emitDebugRanges();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001983
1984 // Emit info into a debug macinfo section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001985 emitDebugMacInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001986
1987 // Emit inline info.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001988 emitDebugInlineInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001989
Chris Lattnerbc733f52010-03-13 02:17:42 +00001990 // Emit info into a debug str section.
1991 emitDebugStr();
1992
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001993 delete ModuleCU;
1994 ModuleCU = NULL; // Reset for the next Module, if any.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001995}
1996
Devang Patel53bb5c92009-11-10 23:06:00 +00001997/// findAbstractVariable - Find abstract variable, if any, associated with Var.
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001998DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
1999 unsigned FrameIdx,
Chris Lattnerde4845c2010-04-02 19:42:39 +00002000 DebugLoc ScopeLoc) {
Devang Patel53bb5c92009-11-10 23:06:00 +00002001
2002 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
2003 if (AbsDbgVariable)
2004 return AbsDbgVariable;
2005
Chris Lattnerde4845c2010-04-02 19:42:39 +00002006 LLVMContext &Ctx = Var.getNode()->getContext();
2007 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel53bb5c92009-11-10 23:06:00 +00002008 if (!Scope)
2009 return NULL;
2010
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002011 AbsDbgVariable = new DbgVariable(Var, FrameIdx,
2012 NULL /* No more-abstract variable*/);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002013 Scope->addVariable(AbsDbgVariable);
Devang Patel53bb5c92009-11-10 23:06:00 +00002014 AbstractVariables[Var.getNode()] = AbsDbgVariable;
2015 return AbsDbgVariable;
2016}
2017
Devang Patel90a48ad2010-03-15 18:33:46 +00002018/// findAbstractVariable - Find abstract variable, if any, associated with Var.
2019/// FIXME : Refactor findAbstractVariable.
2020DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
2021 const MachineInstr *MI,
Chris Lattnerde4845c2010-04-02 19:42:39 +00002022 DebugLoc ScopeLoc) {
Devang Patel90a48ad2010-03-15 18:33:46 +00002023
2024 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
2025 if (AbsDbgVariable)
2026 return AbsDbgVariable;
2027
Chris Lattnerde4845c2010-04-02 19:42:39 +00002028 LLVMContext &Ctx = Var.getNode()->getContext();
2029 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel90a48ad2010-03-15 18:33:46 +00002030 if (!Scope)
2031 return NULL;
2032
Devang Patelaead63c2010-03-29 22:59:58 +00002033 AbsDbgVariable = new DbgVariable(Var, MI,
Devang Patel90a48ad2010-03-15 18:33:46 +00002034 NULL /* No more-abstract variable*/);
2035 Scope->addVariable(AbsDbgVariable);
2036 AbstractVariables[Var.getNode()] = AbsDbgVariable;
Devang Patelaead63c2010-03-29 22:59:58 +00002037 DbgValueStartMap[MI] = AbsDbgVariable;
Devang Patel90a48ad2010-03-15 18:33:46 +00002038 return AbsDbgVariable;
2039}
2040
Devang Patel2c4ceb12009-11-21 02:48:08 +00002041/// collectVariableInfo - Populate DbgScope entries with variables' info.
2042void DwarfDebug::collectVariableInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00002043 const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002044
Devang Patele717faa2009-10-06 01:26:37 +00002045 MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
2046 for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
2047 VE = VMap.end(); VI != VE; ++VI) {
Devang Patelbc5201f2010-01-22 22:52:10 +00002048 MDNode *Var = VI->first;
Devang Patel53bb5c92009-11-10 23:06:00 +00002049 if (!Var) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002050 DIVariable DV(Var);
2051 const std::pair<unsigned, DebugLoc> &VP = VI->second;
Devang Patel53bb5c92009-11-10 23:06:00 +00002052
Chris Lattnerde4845c2010-04-02 19:42:39 +00002053 DbgScope *Scope = 0;
2054 if (MDNode *IA = VP.second.getInlinedAt(Ctx))
2055 Scope = ConcreteScopes.lookup(IA);
2056 if (Scope == 0)
2057 Scope = DbgScopeMap.lookup(VP.second.getScope(Ctx));
2058
Devang Patelfb0ee432009-11-10 23:20:04 +00002059 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002060 if (Scope == 0)
Devang Patelfb0ee432009-11-10 23:20:04 +00002061 continue;
Devang Patel53bb5c92009-11-10 23:06:00 +00002062
Chris Lattnerde4845c2010-04-02 19:42:39 +00002063 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, VP.second);
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002064 DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002065 Scope->addVariable(RegVar);
Devang Patele717faa2009-10-06 01:26:37 +00002066 }
Devang Patel90a48ad2010-03-15 18:33:46 +00002067
2068 // Collect variable information from DBG_VALUE machine instructions;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002069 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patel90a48ad2010-03-15 18:33:46 +00002070 I != E; ++I) {
2071 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2072 II != IE; ++II) {
2073 const MachineInstr *MInsn = II;
Chris Lattner14d750d2010-03-31 05:39:57 +00002074 if (!MInsn->isDebugValue())
Devang Patel90a48ad2010-03-15 18:33:46 +00002075 continue;
Devang Patelaead63c2010-03-29 22:59:58 +00002076
Devang Patel90a48ad2010-03-15 18:33:46 +00002077 // FIXME : Lift this restriction.
2078 if (MInsn->getNumOperands() != 3)
2079 continue;
Dan Gohman82d5eaf2010-04-17 16:43:55 +00002080 DIVariable DV(
2081 const_cast<MDNode *>(MInsn->getOperand(MInsn->getNumOperands() - 1)
2082 .getMetadata()));
Devang Patel90a48ad2010-03-15 18:33:46 +00002083 if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
2084 // FIXME Handle inlined subroutine arguments.
2085 DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
2086 CurrentFnDbgScope->addVariable(ArgVar);
Devang Patelaead63c2010-03-29 22:59:58 +00002087 DbgValueStartMap[MInsn] = ArgVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002088 continue;
2089 }
2090
2091 DebugLoc DL = MInsn->getDebugLoc();
2092 if (DL.isUnknown()) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002093 DbgScope *Scope = 0;
2094 if (MDNode *IA = DL.getInlinedAt(Ctx))
2095 Scope = ConcreteScopes.lookup(IA);
2096 if (Scope == 0)
2097 Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
2098
Devang Patel90a48ad2010-03-15 18:33:46 +00002099 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002100 if (Scope == 0)
Devang Patel90a48ad2010-03-15 18:33:46 +00002101 continue;
2102
Chris Lattnerde4845c2010-04-02 19:42:39 +00002103 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, DL);
Devang Patel90a48ad2010-03-15 18:33:46 +00002104 DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
Devang Patelaead63c2010-03-29 22:59:58 +00002105 DbgValueStartMap[MInsn] = RegVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002106 Scope->addVariable(RegVar);
2107 }
2108 }
Devang Patele717faa2009-10-06 01:26:37 +00002109}
2110
Devang Patel553881b2010-03-29 17:20:31 +00002111/// beginScope - Process beginning of a scope.
2112void DwarfDebug::beginScope(const MachineInstr *MI) {
Devang Patel553881b2010-03-29 17:20:31 +00002113 // Check location.
2114 DebugLoc DL = MI->getDebugLoc();
2115 if (DL.isUnknown())
2116 return;
Devang Patel553881b2010-03-29 17:20:31 +00002117
Chris Lattnerd38fee82010-04-05 00:13:49 +00002118 MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
Chris Lattnerde4845c2010-04-02 19:42:39 +00002119
2120 // FIXME: Should only verify each scope once!
2121 if (!DIScope(Scope).Verify())
Devang Patel553881b2010-03-29 17:20:31 +00002122 return;
Devang Patel553881b2010-03-29 17:20:31 +00002123
Devang Patelaead63c2010-03-29 22:59:58 +00002124 // DBG_VALUE instruction establishes new value.
Chris Lattner14d750d2010-03-31 05:39:57 +00002125 if (MI->isDebugValue()) {
Devang Patelaead63c2010-03-29 22:59:58 +00002126 DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
2127 = DbgValueStartMap.find(MI);
2128 if (DI != DbgValueStartMap.end()) {
Devang Patel9cdb4102010-04-21 16:32:19 +00002129 MCSymbol *Label = NULL;
2130 if (DL == PrevInstLoc)
2131 Label = PrevLabel;
2132 else {
2133 Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2134 PrevInstLoc = DL;
2135 PrevLabel = Label;
2136 }
Devang Patelaead63c2010-03-29 22:59:58 +00002137 DI->second->setDbgValueLabel(Label);
2138 }
Devang Patel7ed63112010-03-30 18:07:00 +00002139 return;
Devang Patelaead63c2010-03-29 22:59:58 +00002140 }
2141
Devang Patel553881b2010-03-29 17:20:31 +00002142 // Emit a label to indicate location change. This is used for line
Devang Patel9cdb4102010-04-21 16:32:19 +00002143 // table even if this instruction does not start a new scope.
2144 MCSymbol *Label = NULL;
2145 if (DL == PrevInstLoc)
2146 Label = PrevLabel;
2147 else {
2148 Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2149 PrevInstLoc = DL;
2150 PrevLabel = Label;
2151 }
Devang Patel553881b2010-03-29 17:20:31 +00002152
Devang Patel1c246352010-04-08 16:50:29 +00002153 // If this instruction begins a scope then note down corresponding label.
2154 if (InsnsBeginScopeSet.count(MI) != 0)
2155 InsnBeforeLabelMap[MI] = Label;
Devang Patel0d20ac82009-10-06 01:50:42 +00002156}
2157
Devang Patel2c4ceb12009-11-21 02:48:08 +00002158/// endScope - Process end of a scope.
2159void DwarfDebug::endScope(const MachineInstr *MI) {
Devang Patel1c246352010-04-08 16:50:29 +00002160 if (InsnsEndScopeSet.count(MI) != 0) {
2161 // Emit a label if this instruction ends a scope.
2162 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
2163 Asm->OutStreamer.EmitLabel(Label);
2164 InsnAfterLabelMap[MI] = Label;
2165 }
Devang Patel53bb5c92009-11-10 23:06:00 +00002166}
2167
Devang Patel9cdb4102010-04-21 16:32:19 +00002168/// getOrCreateDbgScope - Create DbgScope for the scope.
2169DbgScope *DwarfDebug::getOrCreateDbgScope(MDNode *Scope, MDNode *InlinedAt) {
Devang Patel53bb5c92009-11-10 23:06:00 +00002170 if (!InlinedAt) {
2171 DbgScope *WScope = DbgScopeMap.lookup(Scope);
2172 if (WScope)
Devang Patel9cdb4102010-04-21 16:32:19 +00002173 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002174 WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL);
2175 DbgScopeMap.insert(std::make_pair(Scope, WScope));
Devang Patel9cdb4102010-04-21 16:32:19 +00002176 if (DIDescriptor(Scope).isLexicalBlock()) {
2177 DbgScope *Parent =
2178 getOrCreateDbgScope(DILexicalBlock(Scope).getContext().getNode(), NULL);
2179 WScope->setParent(Parent);
2180 Parent->addScope(WScope);
2181 }
2182
2183 if (!WScope->getParent()) {
2184 StringRef SPName = DISubprogram(Scope).getLinkageName();
2185 if (SPName == Asm->MF->getFunction()->getName())
2186 CurrentFnDbgScope = WScope;
2187 }
2188
2189 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002190 }
2191
2192 DbgScope *WScope = DbgScopeMap.lookup(InlinedAt);
2193 if (WScope)
Devang Patel9cdb4102010-04-21 16:32:19 +00002194 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002195
2196 WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt);
2197 DbgScopeMap.insert(std::make_pair(InlinedAt, WScope));
2198 DILocation DL(InlinedAt);
Devang Patel9cdb4102010-04-21 16:32:19 +00002199 DbgScope *Parent =
2200 getOrCreateDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode());
2201 WScope->setParent(Parent);
2202 Parent->addScope(WScope);
2203
2204 ConcreteScopes[InlinedAt] = WScope;
2205 getOrCreateAbstractScope(Scope);
2206
2207 return WScope;
Devang Patel0d20ac82009-10-06 01:50:42 +00002208}
2209
Devang Patel9cdb4102010-04-21 16:32:19 +00002210/// hasValidLocation - Return true if debug location entry attached with
2211/// machine instruction encodes valid location info.
2212static bool hasValidLocation(LLVMContext &Ctx,
2213 const MachineInstr *MInsn,
2214 MDNode *&Scope, MDNode *&InlinedAt) {
2215 if (MInsn->isDebugValue())
2216 return false;
2217 DebugLoc DL = MInsn->getDebugLoc();
2218 if (DL.isUnknown()) return false;
2219
2220 MDNode *S = DL.getScope(Ctx);
2221
2222 // There is no need to create another DIE for compile unit. For all
2223 // other scopes, create one DbgScope now. This will be translated
2224 // into a scope DIE at the end.
2225 if (DIScope(S).isCompileUnit()) return false;
2226
2227 Scope = S;
2228 InlinedAt = DL.getInlinedAt(Ctx);
2229 return true;
2230}
2231
2232/// calculateDominanceGraph - Calculate dominance graph for DbgScope
2233/// hierarchy.
2234static void calculateDominanceGraph(DbgScope *Scope) {
2235 assert (Scope && "Unable to calculate scop edominance graph!");
2236 SmallVector<DbgScope *, 4> WorkStack;
2237 WorkStack.push_back(Scope);
2238 unsigned Counter = 0;
2239 while (!WorkStack.empty()) {
2240 DbgScope *WS = WorkStack.back();
2241 const SmallVector<DbgScope *, 4> &Children = WS->getScopes();
2242 bool visitedChildren = false;
2243 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
2244 SE = Children.end(); SI != SE; ++SI) {
2245 DbgScope *ChildScope = *SI;
2246 if (!ChildScope->getDFSOut()) {
2247 WorkStack.push_back(ChildScope);
2248 visitedChildren = true;
2249 ChildScope->setDFSIn(++Counter);
2250 break;
2251 }
2252 }
2253 if (!visitedChildren) {
2254 WorkStack.pop_back();
2255 WS->setDFSOut(++Counter);
2256 }
2257 }
2258}
2259
2260/// printDbgScopeInfo - Print DbgScope info for each machine instruction.
2261static
2262void printDbgScopeInfo(LLVMContext &Ctx, const MachineFunction *MF,
2263 DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap)
2264{
2265#ifndef NDEBUG
2266 unsigned PrevDFSIn = 0;
2267 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2268 I != E; ++I) {
2269 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2270 II != IE; ++II) {
2271 const MachineInstr *MInsn = II;
2272 MDNode *Scope = NULL;
2273 MDNode *InlinedAt = NULL;
2274
2275 // Check if instruction has valid location information.
2276 if (hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2277 dbgs() << " [ ";
2278 if (InlinedAt)
2279 dbgs() << "*";
2280 DenseMap<const MachineInstr *, DbgScope *>::iterator DI =
2281 MI2ScopeMap.find(MInsn);
2282 if (DI != MI2ScopeMap.end()) {
2283 DbgScope *S = DI->second;
2284 dbgs() << S->getDFSIn();
2285 PrevDFSIn = S->getDFSIn();
2286 } else
2287 dbgs() << PrevDFSIn;
2288 } else
2289 dbgs() << " [ x" << PrevDFSIn;
2290 dbgs() << " ]";
2291 MInsn->dump();
2292 }
2293 dbgs() << "\n";
2294 }
2295#endif
2296}
Devang Patel2c4ceb12009-11-21 02:48:08 +00002297/// extractScopeInformation - Scan machine instructions in this function
Chris Lattner14d750d2010-03-31 05:39:57 +00002298/// and collect DbgScopes. Return true, if at least one scope was found.
Chris Lattnereec791a2010-01-26 23:18:02 +00002299bool DwarfDebug::extractScopeInformation() {
Devang Patelaf9e8472009-10-01 20:31:14 +00002300 // If scope information was extracted using .dbg intrinsics then there is not
2301 // any need to extract these information by scanning each instruction.
2302 if (!DbgScopeMap.empty())
2303 return false;
2304
Devang Patel53bb5c92009-11-10 23:06:00 +00002305 // Scan each instruction and create scopes. First build working set of scopes.
Devang Patel9cdb4102010-04-21 16:32:19 +00002306 LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
2307 SmallVector<DbgRange, 4> MIRanges;
2308 DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap;
2309 MDNode *PrevScope = NULL;
2310 MDNode *PrevInlinedAt = NULL;
2311 const MachineInstr *RangeBeginMI = NULL;
2312 const MachineInstr *PrevMI = NULL;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002313 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patelaf9e8472009-10-01 20:31:14 +00002314 I != E; ++I) {
2315 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2316 II != IE; ++II) {
2317 const MachineInstr *MInsn = II;
Devang Patel9cdb4102010-04-21 16:32:19 +00002318 MDNode *Scope = NULL;
2319 MDNode *InlinedAt = NULL;
2320
2321 // Check if instruction has valid location information.
2322 if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2323 PrevMI = MInsn;
2324 continue;
2325 }
Chris Lattnerde4845c2010-04-02 19:42:39 +00002326
Devang Patel9cdb4102010-04-21 16:32:19 +00002327 // If scope has not changed then skip this instruction.
2328 if (Scope == PrevScope && PrevInlinedAt == InlinedAt) {
2329 PrevMI = MInsn;
2330 continue;
2331 }
2332
2333 if (RangeBeginMI) {
2334 // If we have alread seen a beginning of a instruction range and
2335 // current instruction scope does not match scope of first instruction
2336 // in this range then create a new instruction range.
2337 DbgRange R(RangeBeginMI, PrevMI);
2338 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
2339 MIRanges.push_back(R);
2340 }
2341
2342 // This is a beginning of a new instruction range.
2343 RangeBeginMI = MInsn;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002344
Devang Patel9cdb4102010-04-21 16:32:19 +00002345 // Reset previous markers.
2346 PrevMI = MInsn;
2347 PrevScope = Scope;
2348 PrevInlinedAt = InlinedAt;
Devang Patel53bb5c92009-11-10 23:06:00 +00002349 }
2350 }
2351
Devang Patel9cdb4102010-04-21 16:32:19 +00002352 // Create last instruction range.
2353 if (RangeBeginMI && PrevMI && PrevScope) {
2354 DbgRange R(RangeBeginMI, PrevMI);
2355 MIRanges.push_back(R);
2356 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
Devang Patelaf9e8472009-10-01 20:31:14 +00002357 }
Devang Patel9cdb4102010-04-21 16:32:19 +00002358
Devang Patel344130e2010-01-04 20:44:00 +00002359 if (!CurrentFnDbgScope)
2360 return false;
2361
Devang Patel9cdb4102010-04-21 16:32:19 +00002362 calculateDominanceGraph(CurrentFnDbgScope);
2363 if (PrintDbgScope)
2364 printDbgScopeInfo(Ctx, Asm->MF, MI2ScopeMap);
2365
2366 // Find ranges of instructions covered by each DbgScope;
2367 DbgScope *PrevDbgScope = NULL;
2368 for (SmallVector<DbgRange, 4>::const_iterator RI = MIRanges.begin(),
2369 RE = MIRanges.end(); RI != RE; ++RI) {
2370 const DbgRange &R = *RI;
2371 DbgScope *S = MI2ScopeMap.lookup(R.first);
2372 assert (S && "Lost DbgScope for a machine instruction!");
2373 if (PrevDbgScope && !PrevDbgScope->dominates(S))
2374 PrevDbgScope->closeInsnRange(S);
2375 S->openInsnRange(R.first);
2376 S->extendInsnRange(R.second);
2377 PrevDbgScope = S;
2378 }
2379
2380 if (PrevDbgScope)
2381 PrevDbgScope->closeInsnRange();
Devang Patelaf9e8472009-10-01 20:31:14 +00002382
Devang Patele37b0c62010-04-08 18:43:56 +00002383 identifyScopeMarkers();
Devang Patel6122a4d2010-04-08 15:37:09 +00002384
2385 return !DbgScopeMap.empty();
2386}
2387
Devang Patel9cdb4102010-04-21 16:32:19 +00002388/// identifyScopeMarkers() -
2389/// Each DbgScope has first instruction and last instruction to mark beginning
2390/// and end of a scope respectively. Create an inverse map that list scopes
2391/// starts (and ends) with an instruction. One instruction may start (or end)
2392/// multiple scopes. Ignore scopes that are not reachable.
Devang Patele37b0c62010-04-08 18:43:56 +00002393void DwarfDebug::identifyScopeMarkers() {
Devang Patel42aafd72010-01-20 02:05:23 +00002394 SmallVector<DbgScope *, 4> WorkList;
2395 WorkList.push_back(CurrentFnDbgScope);
2396 while (!WorkList.empty()) {
Chris Lattner14d750d2010-03-31 05:39:57 +00002397 DbgScope *S = WorkList.pop_back_val();
Devang Patel9cdb4102010-04-21 16:32:19 +00002398
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002399 const SmallVector<DbgScope *, 4> &Children = S->getScopes();
Devang Patel42aafd72010-01-20 02:05:23 +00002400 if (!Children.empty())
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002401 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
Devang Patel42aafd72010-01-20 02:05:23 +00002402 SE = Children.end(); SI != SE; ++SI)
2403 WorkList.push_back(*SI);
2404
Devang Patel53bb5c92009-11-10 23:06:00 +00002405 if (S->isAbstractScope())
2406 continue;
Devang Patel9cdb4102010-04-21 16:32:19 +00002407
2408 const SmallVector<DbgRange, 4> &Ranges = S->getRanges();
2409 if (Ranges.empty())
2410 continue;
2411 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
2412 RE = Ranges.end(); RI != RE; ++RI) {
2413 assert(RI->first && "DbgRange does not have first instruction!");
2414 assert(RI->second && "DbgRange does not have second instruction!");
2415 InsnsBeginScopeSet.insert(RI->first);
2416 InsnsEndScopeSet.insert(RI->second);
2417 }
Devang Patelaf9e8472009-10-01 20:31:14 +00002418 }
Devang Patelaf9e8472009-10-01 20:31:14 +00002419}
2420
Dan Gohman084751c2010-04-20 00:37:27 +00002421/// FindFirstDebugLoc - Find the first debug location in the function. This
2422/// is intended to be an approximation for the source position of the
2423/// beginning of the function.
2424static DebugLoc FindFirstDebugLoc(const MachineFunction *MF) {
2425 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2426 I != E; ++I)
2427 for (MachineBasicBlock::const_iterator MBBI = I->begin(), MBBE = I->end();
2428 MBBI != MBBE; ++MBBI) {
2429 DebugLoc DL = MBBI->getDebugLoc();
2430 if (!DL.isUnknown())
2431 return DL;
2432 }
2433 return DebugLoc();
2434}
2435
Devang Patel2c4ceb12009-11-21 02:48:08 +00002436/// beginFunction - Gather pre-function debug information. Assumes being
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002437/// emitted immediately after the function entry point.
Chris Lattnereec791a2010-01-26 23:18:02 +00002438void DwarfDebug::beginFunction(const MachineFunction *MF) {
Chris Lattner994cb122010-04-05 03:52:55 +00002439 if (!MMI->hasDebugInfo()) return;
Bill Wendling5f017e82010-04-07 09:28:04 +00002440 if (!extractScopeInformation()) return;
Chris Lattnera909d662010-03-29 20:38:20 +00002441
Devang Patel2c4ceb12009-11-21 02:48:08 +00002442 collectVariableInfo();
Devang Patel60b35bd2009-10-06 18:37:31 +00002443
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002444 // Assumes in correct section after the entry point.
Chris Lattnerc0215722010-04-04 19:25:43 +00002445 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_begin",
Chris Lattnerd38fee82010-04-05 00:13:49 +00002446 Asm->getFunctionNumber()));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002447
2448 // Emit label for the implicitly defined dbg.stoppoint at the start of the
2449 // function.
Dan Gohman084751c2010-04-20 00:37:27 +00002450 DebugLoc FDL = FindFirstDebugLoc(MF);
Chris Lattnerde4845c2010-04-02 19:42:39 +00002451 if (FDL.isUnknown()) return;
2452
2453 MDNode *Scope = FDL.getScope(MF->getFunction()->getContext());
2454
2455 DISubprogram SP = getDISubprogram(Scope);
2456 unsigned Line, Col;
2457 if (SP.Verify()) {
2458 Line = SP.getLineNumber();
2459 Col = 0;
2460 } else {
2461 Line = FDL.getLine();
2462 Col = FDL.getCol();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002463 }
Chris Lattnerde4845c2010-04-02 19:42:39 +00002464
2465 recordSourceLine(Line, Col, Scope);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002466}
2467
Devang Patel2c4ceb12009-11-21 02:48:08 +00002468/// endFunction - Gather and emit post-function debug information.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002469///
Chris Lattnereec791a2010-01-26 23:18:02 +00002470void DwarfDebug::endFunction(const MachineFunction *MF) {
Bill Wendling5f017e82010-04-07 09:28:04 +00002471 if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return;
Devang Patel70d75ca2009-11-12 19:02:56 +00002472
Devang Patel344130e2010-01-04 20:44:00 +00002473 if (CurrentFnDbgScope) {
2474 // Define end label for subprogram.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002475 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
2476 Asm->getFunctionNumber()));
Devang Patel344130e2010-01-04 20:44:00 +00002477
2478 // Get function line info.
2479 if (!Lines.empty()) {
2480 // Get section line info.
2481 unsigned ID = SectionMap.insert(Asm->getCurrentSection());
2482 if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
2483 std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
2484 // Append the function info to section info.
2485 SectionLineInfos.insert(SectionLineInfos.end(),
2486 Lines.begin(), Lines.end());
2487 }
2488
2489 // Construct abstract scopes.
2490 for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
2491 AE = AbstractScopesList.end(); AI != AE; ++AI)
2492 constructScopeDIE(*AI);
2493
2494 constructScopeDIE(CurrentFnDbgScope);
2495
Chris Lattnerd38fee82010-04-05 00:13:49 +00002496 DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
Devang Patel344130e2010-01-04 20:44:00 +00002497 MMI->getFrameMoves()));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002498 }
2499
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002500 // Clear debug info
Devang Patelf54b8522010-01-19 01:26:02 +00002501 CurrentFnDbgScope = NULL;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002502 DeleteContainerSeconds(DbgScopeMap);
Devang Patel51424712010-04-09 16:04:20 +00002503 InsnsBeginScopeSet.clear();
2504 InsnsEndScopeSet.clear();
Devang Patelaead63c2010-03-29 22:59:58 +00002505 DbgValueStartMap.clear();
Devang Patelf54b8522010-01-19 01:26:02 +00002506 ConcreteScopes.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002507 DeleteContainerSeconds(AbstractScopes);
Devang Patelf54b8522010-01-19 01:26:02 +00002508 AbstractScopesList.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002509 AbstractVariables.clear();
Devang Patel1d526c32010-04-14 01:18:28 +00002510 InsnBeforeLabelMap.clear();
2511 InsnAfterLabelMap.clear();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002512 Lines.clear();
Devang Patelf2548ca2010-04-16 23:33:45 +00002513 PrevLabel = NULL;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002514}
2515
Chris Lattnerc6087842010-03-09 04:54:43 +00002516/// recordSourceLine - Register a source line with debug info. Returns the
2517/// unique label that was emitted and which provides correspondence to
2518/// the source line list.
2519MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
Devang Patel65dbc902009-11-25 17:36:49 +00002520 StringRef Dir;
2521 StringRef Fn;
Devang Patelf84548d2009-10-05 18:03:19 +00002522
2523 DIDescriptor Scope(S);
2524 if (Scope.isCompileUnit()) {
2525 DICompileUnit CU(S);
2526 Dir = CU.getDirectory();
2527 Fn = CU.getFilename();
2528 } else if (Scope.isSubprogram()) {
2529 DISubprogram SP(S);
2530 Dir = SP.getDirectory();
2531 Fn = SP.getFilename();
2532 } else if (Scope.isLexicalBlock()) {
2533 DILexicalBlock DB(S);
2534 Dir = DB.getDirectory();
2535 Fn = DB.getFilename();
2536 } else
Chris Lattner206d61e2010-03-13 07:26:18 +00002537 assert(0 && "Unexpected scope info");
Devang Patelf84548d2009-10-05 18:03:19 +00002538
2539 unsigned Src = GetOrCreateSourceID(Dir, Fn);
Chris Lattner63d78362010-03-14 08:36:50 +00002540 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Chris Lattner25b68c62010-03-14 08:15:55 +00002541 Lines.push_back(SrcLineInfo(Line, Col, Src, Label));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002542
Chris Lattnerc6087842010-03-09 04:54:43 +00002543 Asm->OutStreamer.EmitLabel(Label);
2544 return Label;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002545}
2546
Bill Wendling829e67b2009-05-20 23:22:40 +00002547//===----------------------------------------------------------------------===//
2548// Emit Methods
2549//===----------------------------------------------------------------------===//
2550
Devang Patel2c4ceb12009-11-21 02:48:08 +00002551/// computeSizeAndOffset - Compute the size and offset of a DIE.
Bill Wendling94d04b82009-05-20 23:21:38 +00002552///
Jim Grosbach7ab38df2009-11-22 19:20:36 +00002553unsigned
2554DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002555 // Get the children.
2556 const std::vector<DIE *> &Children = Die->getChildren();
2557
2558 // If not last sibling and has children then add sibling offset attribute.
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002559 if (!Last && !Children.empty())
Benjamin Kramer345ef342010-03-31 19:34:01 +00002560 Die->addSiblingOffset(DIEValueAllocator);
Bill Wendling94d04b82009-05-20 23:21:38 +00002561
2562 // Record the abbreviation.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002563 assignAbbrevNumber(Die->getAbbrev());
Bill Wendling94d04b82009-05-20 23:21:38 +00002564
2565 // Get the abbreviation for this DIE.
2566 unsigned AbbrevNumber = Die->getAbbrevNumber();
2567 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2568
2569 // Set DIE offset
2570 Die->setOffset(Offset);
2571
2572 // Start the size with the size of abbreviation code.
Chris Lattneraf76e592009-08-22 20:48:53 +00002573 Offset += MCAsmInfo::getULEB128Size(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002574
2575 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
2576 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2577
2578 // Size the DIE attribute values.
2579 for (unsigned i = 0, N = Values.size(); i < N; ++i)
2580 // Size attribute value.
Chris Lattnera37d5382010-04-05 00:18:22 +00002581 Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
Bill Wendling94d04b82009-05-20 23:21:38 +00002582
2583 // Size the DIE children if any.
2584 if (!Children.empty()) {
2585 assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes &&
2586 "Children flag not set");
2587
2588 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002589 Offset = computeSizeAndOffset(Children[j], Offset, (j + 1) == M);
Bill Wendling94d04b82009-05-20 23:21:38 +00002590
2591 // End of children marker.
2592 Offset += sizeof(int8_t);
2593 }
2594
2595 Die->setSize(Offset - Die->getOffset());
2596 return Offset;
2597}
2598
Devang Patel2c4ceb12009-11-21 02:48:08 +00002599/// computeSizeAndOffsets - Compute the size and offset of all the DIEs.
Bill Wendling94d04b82009-05-20 23:21:38 +00002600///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002601void DwarfDebug::computeSizeAndOffsets() {
Bill Wendling94d04b82009-05-20 23:21:38 +00002602 // Compute size of compile unit header.
2603 static unsigned Offset =
2604 sizeof(int32_t) + // Length of Compilation Unit Info
2605 sizeof(int16_t) + // DWARF version number
2606 sizeof(int32_t) + // Offset Into Abbrev. Section
2607 sizeof(int8_t); // Pointer Size (in bytes)
2608
Devang Patel2c4ceb12009-11-21 02:48:08 +00002609 computeSizeAndOffset(ModuleCU->getCUDie(), Offset, true);
Bill Wendling94d04b82009-05-20 23:21:38 +00002610}
2611
Chris Lattner11b8f302010-04-04 23:02:02 +00002612/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
2613/// temporary label to it if SymbolStem is specified.
Chris Lattner9c69e285532010-04-04 22:59:04 +00002614static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
Chris Lattner11b8f302010-04-04 23:02:02 +00002615 const char *SymbolStem = 0) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002616 Asm->OutStreamer.SwitchSection(Section);
Chris Lattner11b8f302010-04-04 23:02:02 +00002617 if (!SymbolStem) return 0;
2618
Chris Lattner9c69e285532010-04-04 22:59:04 +00002619 MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
2620 Asm->OutStreamer.EmitLabel(TmpSym);
2621 return TmpSym;
2622}
2623
2624/// EmitSectionLabels - Emit initial Dwarf sections with a label at
2625/// the start of each one.
Chris Lattnerfa070b02010-04-04 22:33:59 +00002626void DwarfDebug::EmitSectionLabels() {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002627 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
Daniel Dunbarf612ff62009-09-19 20:40:05 +00002628
Bill Wendling94d04b82009-05-20 23:21:38 +00002629 // Dwarf sections base addresses.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002630 if (Asm->MAI->doesDwarfRequireFrameSection()) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002631 DwarfFrameSectionSym =
2632 EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
2633 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002634
Chris Lattner9c69e285532010-04-04 22:59:04 +00002635 DwarfInfoSectionSym =
2636 EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
2637 DwarfAbbrevSectionSym =
2638 EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
Chris Lattner11b8f302010-04-04 23:02:02 +00002639 EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002640
2641 if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
Chris Lattner11b8f302010-04-04 23:02:02 +00002642 EmitSectionSym(Asm, MacroInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00002643
Chris Lattner11b8f302010-04-04 23:02:02 +00002644 EmitSectionSym(Asm, TLOF.getDwarfLineSection());
2645 EmitSectionSym(Asm, TLOF.getDwarfLocSection());
2646 EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
2647 EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002648 DwarfStrSectionSym =
2649 EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
Devang Patelf2548ca2010-04-16 23:33:45 +00002650 DwarfDebugRangeSectionSym = EmitSectionSym(Asm, TLOF.getDwarfRangesSection(),
2651 "debug_range");
Bill Wendling94d04b82009-05-20 23:21:38 +00002652
Chris Lattner9c69e285532010-04-04 22:59:04 +00002653 TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
Chris Lattner4ad1efe2010-04-04 23:10:38 +00002654 EmitSectionSym(Asm, TLOF.getDataSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002655}
2656
Devang Patel2c4ceb12009-11-21 02:48:08 +00002657/// emitDIE - Recusively Emits a debug information entry.
Bill Wendling94d04b82009-05-20 23:21:38 +00002658///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002659void DwarfDebug::emitDIE(DIE *Die) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002660 // Get the abbreviation for this DIE.
2661 unsigned AbbrevNumber = Die->getAbbrevNumber();
2662 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2663
Bill Wendling94d04b82009-05-20 23:21:38 +00002664 // Emit the code (index) for the abbreviation.
Chris Lattner3f53c832010-04-04 18:52:31 +00002665 if (Asm->isVerbose())
Chris Lattner894d75a2010-01-22 23:18:42 +00002666 Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
2667 Twine::utohexstr(Die->getOffset()) + ":0x" +
2668 Twine::utohexstr(Die->getSize()) + " " +
2669 dwarf::TagString(Abbrev->getTag()));
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002670 Asm->EmitULEB128(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002671
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002672 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
Bill Wendling94d04b82009-05-20 23:21:38 +00002673 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2674
2675 // Emit the DIE attribute values.
2676 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
2677 unsigned Attr = AbbrevData[i].getAttribute();
2678 unsigned Form = AbbrevData[i].getForm();
2679 assert(Form && "Too many attributes for DIE (check abbreviation)");
2680
Chris Lattner3f53c832010-04-04 18:52:31 +00002681 if (Asm->isVerbose())
Chris Lattnera8013622010-01-24 18:54:17 +00002682 Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
2683
Bill Wendling94d04b82009-05-20 23:21:38 +00002684 switch (Attr) {
2685 case dwarf::DW_AT_sibling:
Devang Patel2c4ceb12009-11-21 02:48:08 +00002686 Asm->EmitInt32(Die->getSiblingOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00002687 break;
2688 case dwarf::DW_AT_abstract_origin: {
2689 DIEEntry *E = cast<DIEEntry>(Values[i]);
2690 DIE *Origin = E->getEntry();
Devang Patel53bb5c92009-11-10 23:06:00 +00002691 unsigned Addr = Origin->getOffset();
Bill Wendling94d04b82009-05-20 23:21:38 +00002692 Asm->EmitInt32(Addr);
2693 break;
2694 }
Devang Patelf2548ca2010-04-16 23:33:45 +00002695 case dwarf::DW_AT_ranges: {
2696 // DW_AT_range Value encodes offset in debug_range section.
2697 DIEInteger *V = cast<DIEInteger>(Values[i]);
2698 Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym,
2699 V->getValue(),
2700 DwarfDebugRangeSectionSym,
2701 4);
2702 break;
2703 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002704 default:
2705 // Emit an attribute using the defined form.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002706 Values[i]->EmitValue(Asm, Form);
Bill Wendling94d04b82009-05-20 23:21:38 +00002707 break;
2708 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002709 }
2710
2711 // Emit the DIE children if any.
2712 if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) {
2713 const std::vector<DIE *> &Children = Die->getChildren();
2714
2715 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002716 emitDIE(Children[j]);
Bill Wendling94d04b82009-05-20 23:21:38 +00002717
Chris Lattner3f53c832010-04-04 18:52:31 +00002718 if (Asm->isVerbose())
Chris Lattner233f52b2010-03-09 23:52:58 +00002719 Asm->OutStreamer.AddComment("End Of Children Mark");
2720 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002721 }
2722}
2723
Devang Patel8a241142009-12-09 18:24:21 +00002724/// emitDebugInfo - Emit the debug info section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002725///
Devang Patel8a241142009-12-09 18:24:21 +00002726void DwarfDebug::emitDebugInfo() {
2727 // Start debug info section.
2728 Asm->OutStreamer.SwitchSection(
2729 Asm->getObjFileLowering().getDwarfInfoSection());
2730 DIE *Die = ModuleCU->getCUDie();
Bill Wendling94d04b82009-05-20 23:21:38 +00002731
2732 // Emit the compile units header.
Chris Lattnerc0215722010-04-04 19:25:43 +00002733 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin",
2734 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002735
2736 // Emit size of content not including length itself
2737 unsigned ContentSize = Die->getSize() +
2738 sizeof(int16_t) + // DWARF version number
2739 sizeof(int32_t) + // Offset Into Abbrev. Section
2740 sizeof(int8_t) + // Pointer Size (in bytes)
2741 sizeof(int32_t); // FIXME - extra pad for gdb bug.
2742
Chris Lattner233f52b2010-03-09 23:52:58 +00002743 Asm->OutStreamer.AddComment("Length of Compilation Unit Info");
2744 Asm->EmitInt32(ContentSize);
2745 Asm->OutStreamer.AddComment("DWARF version number");
2746 Asm->EmitInt16(dwarf::DWARF_VERSION);
2747 Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
Chris Lattner6189ed12010-04-04 23:25:33 +00002748 Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
2749 DwarfAbbrevSectionSym);
Chris Lattner233f52b2010-03-09 23:52:58 +00002750 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002751 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00002752
Devang Patel2c4ceb12009-11-21 02:48:08 +00002753 emitDIE(Die);
Bill Wendling94d04b82009-05-20 23:21:38 +00002754 // FIXME - extra padding for gdb bug.
Chris Lattner233f52b2010-03-09 23:52:58 +00002755 Asm->OutStreamer.AddComment("4 extra padding bytes for GDB");
2756 Asm->EmitInt8(0);
2757 Asm->EmitInt8(0);
2758 Asm->EmitInt8(0);
2759 Asm->EmitInt8(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00002760 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002761}
2762
Devang Patel2c4ceb12009-11-21 02:48:08 +00002763/// emitAbbreviations - Emit the abbreviation section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002764///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002765void DwarfDebug::emitAbbreviations() const {
Bill Wendling94d04b82009-05-20 23:21:38 +00002766 // Check to see if it is worth the effort.
2767 if (!Abbreviations.empty()) {
2768 // Start the debug abbrev section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002769 Asm->OutStreamer.SwitchSection(
2770 Asm->getObjFileLowering().getDwarfAbbrevSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002771
Chris Lattnerc0215722010-04-04 19:25:43 +00002772 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002773
2774 // For each abbrevation.
2775 for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
2776 // Get abbreviation data
2777 const DIEAbbrev *Abbrev = Abbreviations[i];
2778
2779 // Emit the abbrevations code (base 1 index.)
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002780 Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
Bill Wendling94d04b82009-05-20 23:21:38 +00002781
2782 // Emit the abbreviations data.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002783 Abbrev->Emit(Asm);
Bill Wendling94d04b82009-05-20 23:21:38 +00002784 }
2785
2786 // Mark end of abbreviations.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002787 Asm->EmitULEB128(0, "EOM(3)");
Bill Wendling94d04b82009-05-20 23:21:38 +00002788
Chris Lattnerc0215722010-04-04 19:25:43 +00002789 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002790 }
2791}
2792
Devang Patel2c4ceb12009-11-21 02:48:08 +00002793/// emitEndOfLineMatrix - Emit the last address of the section and the end of
Bill Wendling94d04b82009-05-20 23:21:38 +00002794/// the line matrix.
2795///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002796void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002797 // Define last address of section.
Chris Lattner233f52b2010-03-09 23:52:58 +00002798 Asm->OutStreamer.AddComment("Extended Op");
2799 Asm->EmitInt8(0);
2800
2801 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002802 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00002803 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2804 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2805
2806 Asm->OutStreamer.AddComment("Section end label");
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002807
Chris Lattnerc0215722010-04-04 19:25:43 +00002808 Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
Chris Lattnerd38fee82010-04-05 00:13:49 +00002809 Asm->getTargetData().getPointerSize(),
2810 0/*AddrSpace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00002811
2812 // Mark end of matrix.
Chris Lattner233f52b2010-03-09 23:52:58 +00002813 Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
2814 Asm->EmitInt8(0);
Chris Lattner0ad9c912010-01-22 22:09:00 +00002815 Asm->EmitInt8(1);
Chris Lattner894d75a2010-01-22 23:18:42 +00002816 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002817}
2818
Devang Patel2c4ceb12009-11-21 02:48:08 +00002819/// emitDebugLines - Emit source line information.
Bill Wendling94d04b82009-05-20 23:21:38 +00002820///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002821void DwarfDebug::emitDebugLines() {
Bill Wendling94d04b82009-05-20 23:21:38 +00002822 // If the target is using .loc/.file, the assembler will be emitting the
2823 // .debug_line table automatically.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002824 if (Asm->MAI->hasDotLocAndDotFile())
Bill Wendling94d04b82009-05-20 23:21:38 +00002825 return;
2826
2827 // Minimum line delta, thus ranging from -10..(255-10).
2828 const int MinLineDelta = -(dwarf::DW_LNS_fixed_advance_pc + 1);
2829 // Maximum line delta, thus ranging from -10..(255-10).
2830 const int MaxLineDelta = 255 + MinLineDelta;
2831
2832 // Start the dwarf line section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002833 Asm->OutStreamer.SwitchSection(
2834 Asm->getObjFileLowering().getDwarfLineSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002835
2836 // Construct the section header.
Chris Lattner233f52b2010-03-09 23:52:58 +00002837 Asm->OutStreamer.AddComment("Length of Source Line Info");
Chris Lattnera6437182010-04-04 19:58:12 +00002838 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_end"),
2839 Asm->GetTempSymbol("line_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002840 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002841
Chris Lattner233f52b2010-03-09 23:52:58 +00002842 Asm->OutStreamer.AddComment("DWARF version number");
2843 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling94d04b82009-05-20 23:21:38 +00002844
Chris Lattner233f52b2010-03-09 23:52:58 +00002845 Asm->OutStreamer.AddComment("Prolog Length");
Chris Lattnera6437182010-04-04 19:58:12 +00002846 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_prolog_end"),
2847 Asm->GetTempSymbol("line_prolog_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002848 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002849
Chris Lattner233f52b2010-03-09 23:52:58 +00002850 Asm->OutStreamer.AddComment("Minimum Instruction Length");
2851 Asm->EmitInt8(1);
2852 Asm->OutStreamer.AddComment("Default is_stmt_start flag");
2853 Asm->EmitInt8(1);
2854 Asm->OutStreamer.AddComment("Line Base Value (Special Opcodes)");
2855 Asm->EmitInt8(MinLineDelta);
2856 Asm->OutStreamer.AddComment("Line Range Value (Special Opcodes)");
2857 Asm->EmitInt8(MaxLineDelta);
2858 Asm->OutStreamer.AddComment("Special Opcode Base");
2859 Asm->EmitInt8(-MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00002860
2861 // Line number standard opcode encodings argument count
Chris Lattner233f52b2010-03-09 23:52:58 +00002862 Asm->OutStreamer.AddComment("DW_LNS_copy arg count");
2863 Asm->EmitInt8(0);
2864 Asm->OutStreamer.AddComment("DW_LNS_advance_pc arg count");
2865 Asm->EmitInt8(1);
2866 Asm->OutStreamer.AddComment("DW_LNS_advance_line arg count");
2867 Asm->EmitInt8(1);
2868 Asm->OutStreamer.AddComment("DW_LNS_set_file arg count");
2869 Asm->EmitInt8(1);
2870 Asm->OutStreamer.AddComment("DW_LNS_set_column arg count");
2871 Asm->EmitInt8(1);
2872 Asm->OutStreamer.AddComment("DW_LNS_negate_stmt arg count");
2873 Asm->EmitInt8(0);
2874 Asm->OutStreamer.AddComment("DW_LNS_set_basic_block arg count");
2875 Asm->EmitInt8(0);
2876 Asm->OutStreamer.AddComment("DW_LNS_const_add_pc arg count");
2877 Asm->EmitInt8(0);
2878 Asm->OutStreamer.AddComment("DW_LNS_fixed_advance_pc arg count");
2879 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002880
2881 // Emit directories.
2882 for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
Chris Lattner4cf202b2010-01-23 03:11:46 +00002883 const std::string &Dir = getSourceDirectoryName(DI);
Chris Lattner3f53c832010-04-04 18:52:31 +00002884 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Directory");
Chris Lattner4cf202b2010-01-23 03:11:46 +00002885 Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002886 }
2887
Chris Lattner233f52b2010-03-09 23:52:58 +00002888 Asm->OutStreamer.AddComment("End of directories");
2889 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002890
2891 // Emit files.
2892 for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
2893 // Remember source id starts at 1.
2894 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
Chris Lattner4cf202b2010-01-23 03:11:46 +00002895 const std::string &FN = getSourceFileName(Id.second);
Chris Lattner3f53c832010-04-04 18:52:31 +00002896 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Source");
Chris Lattner4cf202b2010-01-23 03:11:46 +00002897 Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0);
2898
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002899 Asm->EmitULEB128(Id.first, "Directory #");
2900 Asm->EmitULEB128(0, "Mod date");
2901 Asm->EmitULEB128(0, "File size");
Bill Wendling94d04b82009-05-20 23:21:38 +00002902 }
2903
Chris Lattner233f52b2010-03-09 23:52:58 +00002904 Asm->OutStreamer.AddComment("End of files");
2905 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002906
Chris Lattnerc0215722010-04-04 19:25:43 +00002907 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002908
2909 // A sequence for each text section.
2910 unsigned SecSrcLinesSize = SectionSourceLines.size();
2911
2912 for (unsigned j = 0; j < SecSrcLinesSize; ++j) {
2913 // Isolate current sections line info.
2914 const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j];
2915
Bill Wendling94d04b82009-05-20 23:21:38 +00002916 // Dwarf assumes we start with first line of first source file.
2917 unsigned Source = 1;
2918 unsigned Line = 1;
2919
2920 // Construct rows of the address, source, line, column matrix.
2921 for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
2922 const SrcLineInfo &LineInfo = LineInfos[i];
Chris Lattner25b68c62010-03-14 08:15:55 +00002923 MCSymbol *Label = LineInfo.getLabel();
Chris Lattnerb9130602010-03-14 02:20:58 +00002924 if (!Label->isDefined()) continue; // Not emitted, in dead code.
Bill Wendling94d04b82009-05-20 23:21:38 +00002925
Caroline Ticec6f9d622009-09-11 18:25:54 +00002926 if (LineInfo.getLine() == 0) continue;
2927
Chris Lattner0d9d70f2010-03-09 23:38:23 +00002928 if (Asm->isVerbose()) {
Chris Lattner188a87d2010-03-10 01:04:13 +00002929 std::pair<unsigned, unsigned> SrcID =
Bill Wendling94d04b82009-05-20 23:21:38 +00002930 getSourceDirectoryAndFileIds(LineInfo.getSourceID());
Chris Lattner188a87d2010-03-10 01:04:13 +00002931 Asm->OutStreamer.AddComment(Twine(getSourceDirectoryName(SrcID.first)) +
Chris Lattner49f618a2010-03-10 02:29:31 +00002932 "/" +
2933 Twine(getSourceFileName(SrcID.second)) +
Chris Lattner188a87d2010-03-10 01:04:13 +00002934 ":" + Twine(LineInfo.getLine()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002935 }
2936
2937 // Define the line address.
Chris Lattner233f52b2010-03-09 23:52:58 +00002938 Asm->OutStreamer.AddComment("Extended Op");
2939 Asm->EmitInt8(0);
2940 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002941 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00002942
2943 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2944 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2945
2946 Asm->OutStreamer.AddComment("Location label");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002947 Asm->OutStreamer.EmitSymbolValue(Label,
2948 Asm->getTargetData().getPointerSize(),
Chris Lattnerb9130602010-03-14 02:20:58 +00002949 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002950
Bill Wendling94d04b82009-05-20 23:21:38 +00002951 // If change of source, then switch to the new source.
2952 if (Source != LineInfo.getSourceID()) {
2953 Source = LineInfo.getSourceID();
Chris Lattner233f52b2010-03-09 23:52:58 +00002954 Asm->OutStreamer.AddComment("DW_LNS_set_file");
2955 Asm->EmitInt8(dwarf::DW_LNS_set_file);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002956 Asm->EmitULEB128(Source, "New Source");
Bill Wendling94d04b82009-05-20 23:21:38 +00002957 }
2958
2959 // If change of line.
2960 if (Line != LineInfo.getLine()) {
2961 // Determine offset.
2962 int Offset = LineInfo.getLine() - Line;
2963 int Delta = Offset - MinLineDelta;
2964
2965 // Update line.
2966 Line = LineInfo.getLine();
2967
2968 // If delta is small enough and in range...
2969 if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
2970 // ... then use fast opcode.
Chris Lattner233f52b2010-03-09 23:52:58 +00002971 Asm->OutStreamer.AddComment("Line Delta");
2972 Asm->EmitInt8(Delta - MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00002973 } else {
2974 // ... otherwise use long hand.
Chris Lattner233f52b2010-03-09 23:52:58 +00002975 Asm->OutStreamer.AddComment("DW_LNS_advance_line");
Bill Wendling94d04b82009-05-20 23:21:38 +00002976 Asm->EmitInt8(dwarf::DW_LNS_advance_line);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002977 Asm->EmitSLEB128(Offset, "Line Offset");
Chris Lattner233f52b2010-03-09 23:52:58 +00002978 Asm->OutStreamer.AddComment("DW_LNS_copy");
2979 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00002980 }
2981 } else {
2982 // Copy the previous row (different address or source)
Chris Lattner233f52b2010-03-09 23:52:58 +00002983 Asm->OutStreamer.AddComment("DW_LNS_copy");
2984 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00002985 }
2986 }
2987
Devang Patel2c4ceb12009-11-21 02:48:08 +00002988 emitEndOfLineMatrix(j + 1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002989 }
2990
2991 if (SecSrcLinesSize == 0)
2992 // Because we're emitting a debug_line section, we still need a line
2993 // table. The linker and friends expect it to exist. If there's nothing to
2994 // put into it, emit an empty table.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002995 emitEndOfLineMatrix(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002996
Chris Lattnerc0215722010-04-04 19:25:43 +00002997 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002998}
2999
Devang Patel2c4ceb12009-11-21 02:48:08 +00003000/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003001///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003002void DwarfDebug::emitCommonDebugFrame() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003003 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003004 return;
3005
Chris Lattnerd38fee82010-04-05 00:13:49 +00003006 int stackGrowth = Asm->getTargetData().getPointerSize();
3007 if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
3008 TargetFrameInfo::StackGrowsDown)
3009 stackGrowth *= -1;
Bill Wendling94d04b82009-05-20 23:21:38 +00003010
3011 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003012 Asm->OutStreamer.SwitchSection(
3013 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003014
Chris Lattnerc0215722010-04-04 19:25:43 +00003015 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common"));
Chris Lattner233f52b2010-03-09 23:52:58 +00003016 Asm->OutStreamer.AddComment("Length of Common Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00003017 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_frame_common_end"),
3018 Asm->GetTempSymbol("debug_frame_common_begin"), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003019
Chris Lattnerc0215722010-04-04 19:25:43 +00003020 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_begin"));
Chris Lattner233f52b2010-03-09 23:52:58 +00003021 Asm->OutStreamer.AddComment("CIE Identifier Tag");
Bill Wendling94d04b82009-05-20 23:21:38 +00003022 Asm->EmitInt32((int)dwarf::DW_CIE_ID);
Chris Lattner233f52b2010-03-09 23:52:58 +00003023 Asm->OutStreamer.AddComment("CIE Version");
Bill Wendling94d04b82009-05-20 23:21:38 +00003024 Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Chris Lattner233f52b2010-03-09 23:52:58 +00003025 Asm->OutStreamer.AddComment("CIE Augmentation");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003026 Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003027 Asm->EmitULEB128(1, "CIE Code Alignment Factor");
3028 Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Chris Lattner233f52b2010-03-09 23:52:58 +00003029 Asm->OutStreamer.AddComment("CIE RA Column");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003030 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling94d04b82009-05-20 23:21:38 +00003031 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
Bill Wendling94d04b82009-05-20 23:21:38 +00003032
3033 std::vector<MachineMove> Moves;
3034 RI->getInitialFrameState(Moves);
3035
Chris Lattner02b86b92010-04-04 23:41:46 +00003036 Asm->EmitFrameMoves(Moves, 0, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00003037
3038 Asm->EmitAlignment(2, 0, 0, false);
Chris Lattnerc0215722010-04-04 19:25:43 +00003039 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00003040}
3041
Devang Patel2c4ceb12009-11-21 02:48:08 +00003042/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
Bill Wendling94d04b82009-05-20 23:21:38 +00003043/// section.
Chris Lattner206d61e2010-03-13 07:26:18 +00003044void DwarfDebug::
3045emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003046 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003047 return;
3048
3049 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003050 Asm->OutStreamer.SwitchSection(
3051 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003052
Chris Lattner233f52b2010-03-09 23:52:58 +00003053 Asm->OutStreamer.AddComment("Length of Frame Information Entry");
Chris Lattner206d61e2010-03-13 07:26:18 +00003054 MCSymbol *DebugFrameBegin =
Chris Lattnerc0215722010-04-04 19:25:43 +00003055 Asm->GetTempSymbol("debug_frame_begin", DebugFrameInfo.Number);
Chris Lattner206d61e2010-03-13 07:26:18 +00003056 MCSymbol *DebugFrameEnd =
Chris Lattnerc0215722010-04-04 19:25:43 +00003057 Asm->GetTempSymbol("debug_frame_end", DebugFrameInfo.Number);
Chris Lattnera6437182010-04-04 19:58:12 +00003058 Asm->EmitLabelDifference(DebugFrameEnd, DebugFrameBegin, 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003059
Chris Lattner206d61e2010-03-13 07:26:18 +00003060 Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Bill Wendling94d04b82009-05-20 23:21:38 +00003061
Chris Lattner233f52b2010-03-09 23:52:58 +00003062 Asm->OutStreamer.AddComment("FDE CIE offset");
Chris Lattner6189ed12010-04-04 23:25:33 +00003063 Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
3064 DwarfFrameSectionSym);
Bill Wendling94d04b82009-05-20 23:21:38 +00003065
Chris Lattner233f52b2010-03-09 23:52:58 +00003066 Asm->OutStreamer.AddComment("FDE initial location");
Chris Lattnerc0215722010-04-04 19:25:43 +00003067 MCSymbol *FuncBeginSym =
3068 Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Chris Lattnerfb658072010-03-13 07:40:56 +00003069 Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
Chris Lattnerd38fee82010-04-05 00:13:49 +00003070 Asm->getTargetData().getPointerSize(),
3071 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00003072
3073
Chris Lattner233f52b2010-03-09 23:52:58 +00003074 Asm->OutStreamer.AddComment("FDE address range");
Chris Lattnera6437182010-04-04 19:58:12 +00003075 Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
Chris Lattnerd38fee82010-04-05 00:13:49 +00003076 FuncBeginSym, Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00003077
Chris Lattner02b86b92010-04-04 23:41:46 +00003078 Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00003079
3080 Asm->EmitAlignment(2, 0, 0, false);
Chris Lattner206d61e2010-03-13 07:26:18 +00003081 Asm->OutStreamer.EmitLabel(DebugFrameEnd);
Bill Wendling94d04b82009-05-20 23:21:38 +00003082}
3083
Devang Patel8a241142009-12-09 18:24:21 +00003084/// emitDebugPubNames - Emit visible names into a debug pubnames section.
3085///
3086void DwarfDebug::emitDebugPubNames() {
3087 // Start the dwarf pubnames section.
3088 Asm->OutStreamer.SwitchSection(
3089 Asm->getObjFileLowering().getDwarfPubNamesSection());
3090
Chris Lattner233f52b2010-03-09 23:52:58 +00003091 Asm->OutStreamer.AddComment("Length of Public Names Info");
Chris Lattnera6437182010-04-04 19:58:12 +00003092 Asm->EmitLabelDifference(
3093 Asm->GetTempSymbol("pubnames_end", ModuleCU->getID()),
3094 Asm->GetTempSymbol("pubnames_begin", ModuleCU->getID()), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003095
Chris Lattnerc0215722010-04-04 19:25:43 +00003096 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin",
3097 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00003098
Chris Lattner233f52b2010-03-09 23:52:58 +00003099 Asm->OutStreamer.AddComment("DWARF Version");
3100 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling94d04b82009-05-20 23:21:38 +00003101
Chris Lattner233f52b2010-03-09 23:52:58 +00003102 Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
Chris Lattner6189ed12010-04-04 23:25:33 +00003103 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3104 DwarfInfoSectionSym);
Bill Wendling94d04b82009-05-20 23:21:38 +00003105
Chris Lattner233f52b2010-03-09 23:52:58 +00003106 Asm->OutStreamer.AddComment("Compilation Unit Length");
Chris Lattnera6437182010-04-04 19:58:12 +00003107 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
3108 Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3109 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003110
Devang Patel8a241142009-12-09 18:24:21 +00003111 const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
Bill Wendling94d04b82009-05-20 23:21:38 +00003112 for (StringMap<DIE*>::const_iterator
3113 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3114 const char *Name = GI->getKeyData();
Chris Lattner233f52b2010-03-09 23:52:58 +00003115 DIE *Entity = GI->second;
Bill Wendling94d04b82009-05-20 23:21:38 +00003116
Chris Lattner233f52b2010-03-09 23:52:58 +00003117 Asm->OutStreamer.AddComment("DIE offset");
3118 Asm->EmitInt32(Entity->getOffset());
Chris Lattner4cf202b2010-01-23 03:11:46 +00003119
Chris Lattner3f53c832010-04-04 18:52:31 +00003120 if (Asm->isVerbose())
Chris Lattner4cf202b2010-01-23 03:11:46 +00003121 Asm->OutStreamer.AddComment("External Name");
3122 Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003123 }
3124
Chris Lattner233f52b2010-03-09 23:52:58 +00003125 Asm->OutStreamer.AddComment("End Mark");
3126 Asm->EmitInt32(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00003127 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end",
3128 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00003129}
3130
Devang Patel193f7202009-11-24 01:14:22 +00003131void DwarfDebug::emitDebugPubTypes() {
Devang Patelf3a03762009-11-24 19:18:41 +00003132 // Start the dwarf pubnames section.
3133 Asm->OutStreamer.SwitchSection(
3134 Asm->getObjFileLowering().getDwarfPubTypesSection());
Chris Lattner233f52b2010-03-09 23:52:58 +00003135 Asm->OutStreamer.AddComment("Length of Public Types Info");
Chris Lattnera6437182010-04-04 19:58:12 +00003136 Asm->EmitLabelDifference(
3137 Asm->GetTempSymbol("pubtypes_end", ModuleCU->getID()),
3138 Asm->GetTempSymbol("pubtypes_begin", ModuleCU->getID()), 4);
Devang Patel193f7202009-11-24 01:14:22 +00003139
Chris Lattnerc0215722010-04-04 19:25:43 +00003140 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_begin",
3141 ModuleCU->getID()));
Devang Patel193f7202009-11-24 01:14:22 +00003142
Chris Lattner3f53c832010-04-04 18:52:31 +00003143 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version");
Devang Patele3d6d222010-02-02 03:47:27 +00003144 Asm->EmitInt16(dwarf::DWARF_VERSION);
Devang Patel193f7202009-11-24 01:14:22 +00003145
Chris Lattner233f52b2010-03-09 23:52:58 +00003146 Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info");
Chris Lattner6189ed12010-04-04 23:25:33 +00003147 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3148 DwarfInfoSectionSym);
Devang Patel193f7202009-11-24 01:14:22 +00003149
Chris Lattner233f52b2010-03-09 23:52:58 +00003150 Asm->OutStreamer.AddComment("Compilation ModuleCU Length");
Chris Lattnera6437182010-04-04 19:58:12 +00003151 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
3152 Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
3153 4);
Devang Patel193f7202009-11-24 01:14:22 +00003154
3155 const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes();
3156 for (StringMap<DIE*>::const_iterator
3157 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3158 const char *Name = GI->getKeyData();
3159 DIE * Entity = GI->second;
3160
Chris Lattner3f53c832010-04-04 18:52:31 +00003161 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Devang Patele3d6d222010-02-02 03:47:27 +00003162 Asm->EmitInt32(Entity->getOffset());
Chris Lattner4cf202b2010-01-23 03:11:46 +00003163
Chris Lattner3f53c832010-04-04 18:52:31 +00003164 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
Devang Patel31acb892010-02-02 03:37:03 +00003165 Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
Devang Patel193f7202009-11-24 01:14:22 +00003166 }
3167
Chris Lattner233f52b2010-03-09 23:52:58 +00003168 Asm->OutStreamer.AddComment("End Mark");
3169 Asm->EmitInt32(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00003170 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
3171 ModuleCU->getID()));
Devang Patel193f7202009-11-24 01:14:22 +00003172}
3173
Devang Patel2c4ceb12009-11-21 02:48:08 +00003174/// emitDebugStr - Emit visible names into a debug str section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003175///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003176void DwarfDebug::emitDebugStr() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003177 // Check to see if it is worth the effort.
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003178 if (StringPool.empty()) return;
3179
3180 // Start the dwarf str section.
3181 Asm->OutStreamer.SwitchSection(
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003182 Asm->getObjFileLowering().getDwarfStrSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003183
Chris Lattnerbc733f52010-03-13 02:17:42 +00003184 // Get all of the string pool entries and put them in an array by their ID so
3185 // we can sort them.
3186 SmallVector<std::pair<unsigned,
3187 StringMapEntry<std::pair<MCSymbol*, unsigned> >*>, 64> Entries;
3188
3189 for (StringMap<std::pair<MCSymbol*, unsigned> >::iterator
3190 I = StringPool.begin(), E = StringPool.end(); I != E; ++I)
3191 Entries.push_back(std::make_pair(I->second.second, &*I));
3192
3193 array_pod_sort(Entries.begin(), Entries.end());
3194
3195 for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003196 // Emit a label for reference from debug information entries.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003197 Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first);
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003198
3199 // Emit the string itself.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003200 Asm->OutStreamer.EmitBytes(Entries[i].second->getKey(), 0/*addrspace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00003201 }
3202}
3203
Devang Patel2c4ceb12009-11-21 02:48:08 +00003204/// emitDebugLoc - Emit visible names into a debug loc section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003205///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003206void DwarfDebug::emitDebugLoc() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003207 // Start the dwarf loc section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003208 Asm->OutStreamer.SwitchSection(
3209 Asm->getObjFileLowering().getDwarfLocSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003210}
3211
3212/// EmitDebugARanges - Emit visible names into a debug aranges section.
3213///
3214void DwarfDebug::EmitDebugARanges() {
3215 // Start the dwarf aranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003216 Asm->OutStreamer.SwitchSection(
3217 Asm->getObjFileLowering().getDwarfARangesSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003218}
3219
Devang Patel2c4ceb12009-11-21 02:48:08 +00003220/// emitDebugRanges - Emit visible names into a debug ranges section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003221///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003222void DwarfDebug::emitDebugRanges() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003223 // Start the dwarf ranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003224 Asm->OutStreamer.SwitchSection(
Devang Patelf2548ca2010-04-16 23:33:45 +00003225 Asm->getObjFileLowering().getDwarfRangesSection());
3226 for (SmallVector<const MCSymbol *, 8>::const_iterator I = DebugRangeSymbols.begin(),
3227 E = DebugRangeSymbols.end(); I != E; ++I) {
3228 if (*I)
3229 Asm->EmitLabelDifference(*I, TextSectionSym,
3230 Asm->getTargetData().getPointerSize());
3231 else
3232 Asm->OutStreamer.EmitIntValue(0, Asm->getTargetData().getPointerSize(),
3233 /*addrspace*/0);
3234 }
Bill Wendling94d04b82009-05-20 23:21:38 +00003235}
3236
Devang Patel2c4ceb12009-11-21 02:48:08 +00003237/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003238///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003239void DwarfDebug::emitDebugMacInfo() {
Daniel Dunbarf612ff62009-09-19 20:40:05 +00003240 if (const MCSection *LineInfo =
Chris Lattner18a4c162009-08-02 07:24:22 +00003241 Asm->getObjFileLowering().getDwarfMacroInfoSection()) {
Bill Wendling94d04b82009-05-20 23:21:38 +00003242 // Start the dwarf macinfo section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003243 Asm->OutStreamer.SwitchSection(LineInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00003244 }
3245}
3246
Devang Patel2c4ceb12009-11-21 02:48:08 +00003247/// emitDebugInlineInfo - Emit inline info using following format.
Bill Wendling94d04b82009-05-20 23:21:38 +00003248/// Section Header:
3249/// 1. length of section
3250/// 2. Dwarf version number
3251/// 3. address size.
3252///
3253/// Entries (one "entry" for each function that was inlined):
3254///
3255/// 1. offset into __debug_str section for MIPS linkage name, if exists;
3256/// otherwise offset into __debug_str for regular function name.
3257/// 2. offset into __debug_str section for regular function name.
3258/// 3. an unsigned LEB128 number indicating the number of distinct inlining
3259/// instances for the function.
3260///
3261/// The rest of the entry consists of a {die_offset, low_pc} pair for each
3262/// inlined instance; the die_offset points to the inlined_subroutine die in the
3263/// __debug_info section, and the low_pc is the starting address for the
3264/// inlining instance.
Devang Patel2c4ceb12009-11-21 02:48:08 +00003265void DwarfDebug::emitDebugInlineInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003266 if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003267 return;
3268
Devang Patel1dbc7712009-06-29 20:45:18 +00003269 if (!ModuleCU)
Bill Wendling94d04b82009-05-20 23:21:38 +00003270 return;
3271
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003272 Asm->OutStreamer.SwitchSection(
3273 Asm->getObjFileLowering().getDwarfDebugInlineSection());
Chris Lattner0ad9c912010-01-22 22:09:00 +00003274
Chris Lattner233f52b2010-03-09 23:52:58 +00003275 Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00003276 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
3277 Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003278
Chris Lattnerc0215722010-04-04 19:25:43 +00003279 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003280
Chris Lattner233f52b2010-03-09 23:52:58 +00003281 Asm->OutStreamer.AddComment("Dwarf Version");
3282 Asm->EmitInt16(dwarf::DWARF_VERSION);
3283 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003284 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00003285
Devang Patel53bb5c92009-11-10 23:06:00 +00003286 for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
3287 E = InlinedSPNodes.end(); I != E; ++I) {
Jim Grosbach31ef40e2009-11-21 23:12:12 +00003288
Devang Patel53bb5c92009-11-10 23:06:00 +00003289 MDNode *Node = *I;
Devang Patel622b0262010-01-19 06:19:05 +00003290 DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
Jim Grosbach7ab38df2009-11-22 19:20:36 +00003291 = InlineInfo.find(Node);
Devang Patel53bb5c92009-11-10 23:06:00 +00003292 SmallVector<InlineInfoLabels, 4> &Labels = II->second;
Devang Patele4b27562009-08-28 23:24:31 +00003293 DISubprogram SP(Node);
Devang Patel65dbc902009-11-25 17:36:49 +00003294 StringRef LName = SP.getLinkageName();
3295 StringRef Name = SP.getName();
Bill Wendling94d04b82009-05-20 23:21:38 +00003296
Chris Lattner233f52b2010-03-09 23:52:58 +00003297 Asm->OutStreamer.AddComment("MIPS linkage name");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003298 if (LName.empty()) {
3299 Asm->OutStreamer.EmitBytes(Name, 0);
3300 Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
3301 } else
Chris Lattner6189ed12010-04-04 23:25:33 +00003302 Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
3303 DwarfStrSectionSym);
Devang Patel53bb5c92009-11-10 23:06:00 +00003304
Chris Lattner233f52b2010-03-09 23:52:58 +00003305 Asm->OutStreamer.AddComment("Function name");
Chris Lattner6189ed12010-04-04 23:25:33 +00003306 Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003307 Asm->EmitULEB128(Labels.size(), "Inline count");
Bill Wendling94d04b82009-05-20 23:21:38 +00003308
Devang Patel53bb5c92009-11-10 23:06:00 +00003309 for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
Bill Wendling94d04b82009-05-20 23:21:38 +00003310 LE = Labels.end(); LI != LE; ++LI) {
Chris Lattner3f53c832010-04-04 18:52:31 +00003311 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Chris Lattner6ed0f902010-03-09 00:31:02 +00003312 Asm->EmitInt32(LI->second->getOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00003313
Chris Lattner3f53c832010-04-04 18:52:31 +00003314 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003315 Asm->OutStreamer.EmitSymbolValue(LI->first,
3316 Asm->getTargetData().getPointerSize(),0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003317 }
3318 }
3319
Chris Lattnerc0215722010-04-04 19:25:43 +00003320 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003321}