blob: 110e1cbcc6c63ec24e0c6d6ddc8b7d529d4e55bb [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 Pateleac9c072010-04-27 19:46:33 +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 Pateleac9c072010-04-27 19:46:33 +000044static cl::opt<bool> PrintDbgScope("print-dbgscope", cl::Hidden,
45 cl::desc("Print DbgScope information for each machine instruction"));
46
47static cl::opt<bool> DisableDebugInfoPrinting("disable-debug-info-print", cl::Hidden,
48 cl::desc("Disable debug info printing"));
49
Dan Gohman281d65d2010-05-07 01:08:53 +000050static cl::opt<bool> UnknownLocations("use-unknown-locations", cl::Hidden,
51 cl::desc("Make an absense of debug location information explicit."),
52 cl::init(false));
53
Bill Wendling5f017e82010-04-07 09:28:04 +000054namespace {
55 const char *DWARFGroupName = "DWARF Emission";
56 const char *DbgTimerName = "DWARF Debug Writer";
57} // end anonymous namespace
58
Bill Wendling0310d762009-05-15 09:23:25 +000059//===----------------------------------------------------------------------===//
60
61/// Configuration values for initial hash set sizes (log2).
62///
Bill Wendling0310d762009-05-15 09:23:25 +000063static const unsigned InitAbbreviationsSetSize = 9; // log2(512)
Bill Wendling0310d762009-05-15 09:23:25 +000064
65namespace llvm {
66
67//===----------------------------------------------------------------------===//
68/// CompileUnit - This dwarf writer support class manages information associate
69/// with a source file.
Nick Lewycky5f9843f2009-11-17 08:11:44 +000070class CompileUnit {
Bill Wendling0310d762009-05-15 09:23:25 +000071 /// ID - File identifier for source.
72 ///
73 unsigned ID;
74
75 /// Die - Compile unit debug information entry.
76 ///
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +000077 const OwningPtr<DIE> CUDie;
Bill Wendling0310d762009-05-15 09:23:25 +000078
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +000079 /// IndexTyDie - An anonymous type for index type. Owned by CUDie.
Devang Patel6f01d9c2009-11-21 00:31:03 +000080 DIE *IndexTyDie;
81
Bill Wendling0310d762009-05-15 09:23:25 +000082 /// GVToDieMap - Tracks the mapping of unit level debug informaton
83 /// variables to debug information entries.
Devang Patele4b27562009-08-28 23:24:31 +000084 /// FIXME : Rename GVToDieMap -> NodeToDieMap
Devang Patele9f8f5e2010-05-07 20:54:48 +000085 DenseMap<const MDNode *, DIE *> GVToDieMap;
Bill Wendling0310d762009-05-15 09:23:25 +000086
87 /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
88 /// descriptors to debug information entries using a DIEEntry proxy.
Devang Patele4b27562009-08-28 23:24:31 +000089 /// FIXME : Rename
Devang Patele9f8f5e2010-05-07 20:54:48 +000090 DenseMap<const MDNode *, DIEEntry *> GVToDIEEntryMap;
Bill Wendling0310d762009-05-15 09:23:25 +000091
92 /// Globals - A map of globally visible named entities for this unit.
93 ///
94 StringMap<DIE*> Globals;
95
Devang Patel193f7202009-11-24 01:14:22 +000096 /// GlobalTypes - A map of globally visible types for this unit.
97 ///
98 StringMap<DIE*> GlobalTypes;
99
Bill Wendling0310d762009-05-15 09:23:25 +0000100public:
101 CompileUnit(unsigned I, DIE *D)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000102 : ID(I), CUDie(D), IndexTyDie(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +0000103
104 // Accessors.
Devang Patel193f7202009-11-24 01:14:22 +0000105 unsigned getID() const { return ID; }
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +0000106 DIE* getCUDie() const { return CUDie.get(); }
Devang Patel193f7202009-11-24 01:14:22 +0000107 const StringMap<DIE*> &getGlobals() const { return Globals; }
108 const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; }
Bill Wendling0310d762009-05-15 09:23:25 +0000109
110 /// hasContent - Return true if this compile unit has something to write out.
111 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000112 bool hasContent() const { return !CUDie->getChildren().empty(); }
Bill Wendling0310d762009-05-15 09:23:25 +0000113
Devang Patel2c4ceb12009-11-21 02:48:08 +0000114 /// addGlobal - Add a new global entity to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000115 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000116 void addGlobal(StringRef Name, DIE *Die) { Globals[Name] = Die; }
Bill Wendling0310d762009-05-15 09:23:25 +0000117
Devang Patel193f7202009-11-24 01:14:22 +0000118 /// addGlobalType - Add a new global type to the compile unit.
119 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000120 void addGlobalType(StringRef Name, DIE *Die) {
Devang Patel193f7202009-11-24 01:14:22 +0000121 GlobalTypes[Name] = Die;
122 }
123
Devang Patel017d1212009-11-20 21:37:22 +0000124 /// getDIE - Returns the debug information entry map slot for the
Bill Wendling0310d762009-05-15 09:23:25 +0000125 /// specified debug variable.
Devang Patele9f8f5e2010-05-07 20:54:48 +0000126 DIE *getDIE(const MDNode *N) { return GVToDieMap.lookup(N); }
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000127
Devang Patel017d1212009-11-20 21:37:22 +0000128 /// insertDIE - Insert DIE into the map.
Devang Patele9f8f5e2010-05-07 20:54:48 +0000129 void insertDIE(const MDNode *N, DIE *D) {
Devang Patel017d1212009-11-20 21:37:22 +0000130 GVToDieMap.insert(std::make_pair(N, D));
131 }
Bill Wendling0310d762009-05-15 09:23:25 +0000132
Devang Patel017d1212009-11-20 21:37:22 +0000133 /// getDIEEntry - Returns the debug information entry for the speciefied
134 /// debug variable.
Devang Patele9f8f5e2010-05-07 20:54:48 +0000135 DIEEntry *getDIEEntry(const MDNode *N) {
136 DenseMap<const MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
Devang Patel6404e4e2009-12-15 19:16:48 +0000137 if (I == GVToDIEEntryMap.end())
138 return NULL;
139 return I->second;
140 }
Devang Patel017d1212009-11-20 21:37:22 +0000141
142 /// insertDIEEntry - Insert debug information entry into the map.
Devang Patele9f8f5e2010-05-07 20:54:48 +0000143 void insertDIEEntry(const MDNode *N, DIEEntry *E) {
Devang Patel017d1212009-11-20 21:37:22 +0000144 GVToDIEEntryMap.insert(std::make_pair(N, E));
Bill Wendling0310d762009-05-15 09:23:25 +0000145 }
146
Devang Patel2c4ceb12009-11-21 02:48:08 +0000147 /// addDie - Adds or interns the DIE to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000148 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000149 void addDie(DIE *Buffer) {
150 this->CUDie->addChild(Buffer);
Bill Wendling0310d762009-05-15 09:23:25 +0000151 }
Devang Patel6f01d9c2009-11-21 00:31:03 +0000152
153 // getIndexTyDie - Get an anonymous type for index type.
154 DIE *getIndexTyDie() {
155 return IndexTyDie;
156 }
157
Jim Grosbach7ab38df2009-11-22 19:20:36 +0000158 // setIndexTyDie - Set D as anonymous type for index which can be reused
159 // later.
Devang Patel6f01d9c2009-11-21 00:31:03 +0000160 void setIndexTyDie(DIE *D) {
161 IndexTyDie = D;
162 }
163
Bill Wendling0310d762009-05-15 09:23:25 +0000164};
165
166//===----------------------------------------------------------------------===//
167/// DbgVariable - This class is used to track local variable information.
168///
Devang Patelf76a3d62009-11-16 21:53:40 +0000169class DbgVariable {
Bill Wendling0310d762009-05-15 09:23:25 +0000170 DIVariable Var; // Variable Descriptor.
171 unsigned FrameIndex; // Variable frame index.
Devang Patel90a48ad2010-03-15 18:33:46 +0000172 const MachineInstr *DbgValueMInsn; // DBG_VALUE
Devang Patelaead63c2010-03-29 22:59:58 +0000173 // DbgValueLabel - DBG_VALUE is effective from this label.
174 MCSymbol *DbgValueLabel;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000175 DbgVariable *const AbstractVar; // Abstract variable for this variable.
Devang Patel53bb5c92009-11-10 23:06:00 +0000176 DIE *TheDIE;
Bill Wendling0310d762009-05-15 09:23:25 +0000177public:
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000178 // AbsVar may be NULL.
179 DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000180 : Var(V), FrameIndex(I), DbgValueMInsn(0),
181 DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
Devang Patel90a48ad2010-03-15 18:33:46 +0000182 DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000183 : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
184 AbstractVar(AbsVar), TheDIE(0)
Devang Patel90a48ad2010-03-15 18:33:46 +0000185 {}
Bill Wendling0310d762009-05-15 09:23:25 +0000186
187 // Accessors.
Devang Patel53bb5c92009-11-10 23:06:00 +0000188 DIVariable getVariable() const { return Var; }
189 unsigned getFrameIndex() const { return FrameIndex; }
Devang Patel90a48ad2010-03-15 18:33:46 +0000190 const MachineInstr *getDbgValue() const { return DbgValueMInsn; }
Devang Patelaead63c2010-03-29 22:59:58 +0000191 MCSymbol *getDbgValueLabel() const { return DbgValueLabel; }
192 void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000193 DbgVariable *getAbstractVariable() const { return AbstractVar; }
194 void setDIE(DIE *D) { TheDIE = D; }
195 DIE *getDIE() const { return TheDIE; }
Bill Wendling0310d762009-05-15 09:23:25 +0000196};
197
198//===----------------------------------------------------------------------===//
Devang Pateleac9c072010-04-27 19:46:33 +0000199/// DbgRange - This is used to track range of instructions with identical
200/// debug info scope.
201///
202typedef std::pair<const MachineInstr *, const MachineInstr *> DbgRange;
203
204//===----------------------------------------------------------------------===//
Bill Wendling0310d762009-05-15 09:23:25 +0000205/// DbgScope - This class is used to track scope information.
206///
Devang Patelf76a3d62009-11-16 21:53:40 +0000207class DbgScope {
Bill Wendling0310d762009-05-15 09:23:25 +0000208 DbgScope *Parent; // Parent to this scope.
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000209 DIDescriptor Desc; // Debug info descriptor for scope.
Devang Patel3139fcf2010-01-26 21:39:14 +0000210 // Location at which this scope is inlined.
Devang Patele9f8f5e2010-05-07 20:54:48 +0000211 AssertingVH<const MDNode> InlinedAtLocation;
Devang Patel53bb5c92009-11-10 23:06:00 +0000212 bool AbstractScope; // Abstract Scope
Devang Pateld38dd112009-10-01 18:25:23 +0000213 const MachineInstr *LastInsn; // Last instruction of this scope.
214 const MachineInstr *FirstInsn; // First instruction of this scope.
Devang Pateleac9c072010-04-27 19:46:33 +0000215 unsigned DFSIn, DFSOut;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000216 // Scopes defined in scope. Contents not owned.
217 SmallVector<DbgScope *, 4> Scopes;
218 // Variables declared in scope. Contents owned.
219 SmallVector<DbgVariable *, 8> Variables;
Devang Pateleac9c072010-04-27 19:46:33 +0000220 SmallVector<DbgRange, 4> Ranges;
Owen Anderson04c05f72009-06-24 22:53:20 +0000221 // Private state for dump()
222 mutable unsigned IndentLevel;
Bill Wendling0310d762009-05-15 09:23:25 +0000223public:
Devang Patele9f8f5e2010-05-07 20:54:48 +0000224 DbgScope(DbgScope *P, DIDescriptor D, const MDNode *I = 0)
Devang Patel53bb5c92009-11-10 23:06:00 +0000225 : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
Devang Pateleac9c072010-04-27 19:46:33 +0000226 LastInsn(0), FirstInsn(0),
227 DFSIn(0), DFSOut(0), IndentLevel(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +0000228 virtual ~DbgScope();
229
230 // Accessors.
231 DbgScope *getParent() const { return Parent; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000232 void setParent(DbgScope *P) { Parent = P; }
Bill Wendling0310d762009-05-15 09:23:25 +0000233 DIDescriptor getDesc() const { return Desc; }
Devang Patele9f8f5e2010-05-07 20:54:48 +0000234 const MDNode *getInlinedAt() const { return InlinedAtLocation; }
235 const MDNode *getScopeNode() const { return Desc; }
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000236 const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
237 const SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
Devang Pateleac9c072010-04-27 19:46:33 +0000238 const SmallVector<DbgRange, 4> &getRanges() { return Ranges; }
239
240 /// openInsnRange - This scope covers instruction range starting from MI.
241 void openInsnRange(const MachineInstr *MI) {
242 if (!FirstInsn)
243 FirstInsn = MI;
244
245 if (Parent)
246 Parent->openInsnRange(MI);
247 }
248
249 /// extendInsnRange - Extend the current instruction range covered by
250 /// this scope.
251 void extendInsnRange(const MachineInstr *MI) {
252 assert (FirstInsn && "MI Range is not open!");
253 LastInsn = MI;
254 if (Parent)
255 Parent->extendInsnRange(MI);
256 }
257
258 /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
259 /// until now. This is used when a new scope is encountered while walking
260 /// machine instructions.
261 void closeInsnRange(DbgScope *NewScope = NULL) {
262 assert (LastInsn && "Last insn missing!");
263 Ranges.push_back(DbgRange(FirstInsn, LastInsn));
264 FirstInsn = NULL;
265 LastInsn = NULL;
266 // If Parent dominates NewScope then do not close Parent's instruction
267 // range.
268 if (Parent && (!NewScope || !Parent->dominates(NewScope)))
269 Parent->closeInsnRange(NewScope);
270 }
271
Devang Patel53bb5c92009-11-10 23:06:00 +0000272 void setAbstractScope() { AbstractScope = true; }
273 bool isAbstractScope() const { return AbstractScope; }
Devang Pateleac9c072010-04-27 19:46:33 +0000274
275 // Depth First Search support to walk and mainpluate DbgScope hierarchy.
276 unsigned getDFSOut() const { return DFSOut; }
277 void setDFSOut(unsigned O) { DFSOut = O; }
278 unsigned getDFSIn() const { return DFSIn; }
279 void setDFSIn(unsigned I) { DFSIn = I; }
280 bool dominates(const DbgScope *S) {
281 if (S == this)
282 return true;
283 if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
284 return true;
285 return false;
286 }
Devang Patel53bb5c92009-11-10 23:06:00 +0000287
Devang Patel2c4ceb12009-11-21 02:48:08 +0000288 /// addScope - Add a scope to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000289 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000290 void addScope(DbgScope *S) { Scopes.push_back(S); }
Bill Wendling0310d762009-05-15 09:23:25 +0000291
Devang Patel2c4ceb12009-11-21 02:48:08 +0000292 /// addVariable - Add a variable to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000293 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000294 void addVariable(DbgVariable *V) { Variables.push_back(V); }
Bill Wendling0310d762009-05-15 09:23:25 +0000295
Bill Wendling0310d762009-05-15 09:23:25 +0000296#ifndef NDEBUG
297 void dump() const;
298#endif
299};
Devang Pateleac9c072010-04-27 19:46:33 +0000300
Chris Lattnerea761862010-04-05 04:09:20 +0000301} // end llvm namespace
Bill Wendling0310d762009-05-15 09:23:25 +0000302
303#ifndef NDEBUG
304void DbgScope::dump() const {
David Greenef83adbc2009-12-24 00:31:35 +0000305 raw_ostream &err = dbgs();
Chris Lattnerc281de12009-08-23 00:51:00 +0000306 err.indent(IndentLevel);
Devang Patele9f8f5e2010-05-07 20:54:48 +0000307 const MDNode *N = Desc;
Devang Patel53bb5c92009-11-10 23:06:00 +0000308 N->dump();
Devang Patel53bb5c92009-11-10 23:06:00 +0000309 if (AbstractScope)
310 err << "Abstract Scope\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000311
312 IndentLevel += 2;
Devang Patel53bb5c92009-11-10 23:06:00 +0000313 if (!Scopes.empty())
314 err << "Children ...\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000315 for (unsigned i = 0, e = Scopes.size(); i != e; ++i)
316 if (Scopes[i] != this)
317 Scopes[i]->dump();
318
319 IndentLevel -= 2;
320}
321#endif
322
Bill Wendling0310d762009-05-15 09:23:25 +0000323DbgScope::~DbgScope() {
Bill Wendling0310d762009-05-15 09:23:25 +0000324 for (unsigned j = 0, M = Variables.size(); j < M; ++j)
325 delete Variables[j];
Bill Wendling0310d762009-05-15 09:23:25 +0000326}
327
Chris Lattner49cd6642010-04-05 05:11:15 +0000328DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
Devang Patel163a9f72010-05-10 22:49:55 +0000329 : Asm(A), MMI(Asm->MMI), FirstCU(0),
Chris Lattner994cb122010-04-05 03:52:55 +0000330 AbbreviationsSet(InitAbbreviationsSetSize),
Devang Patelf2548ca2010-04-16 23:33:45 +0000331 CurrentFnDbgScope(0), PrevLabel(NULL) {
Chris Lattnerbc733f52010-03-13 02:17:42 +0000332 NextStringPoolNumber = 0;
Chris Lattner9c69e285532010-04-04 22:59:04 +0000333
Chris Lattner4ad1efe2010-04-04 23:10:38 +0000334 DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
335 DwarfStrSectionSym = TextSectionSym = 0;
Devang Pateleac9c072010-04-27 19:46:33 +0000336 DwarfDebugRangeSectionSym = 0;
337 FunctionBeginSym = 0;
Torok Edwin9c421072010-04-07 10:44:46 +0000338 if (TimePassesIsEnabled) {
339 NamedRegionTimer T(DbgTimerName, DWARFGroupName);
340 beginModule(M);
341 } else {
342 beginModule(M);
343 }
Bill Wendling0310d762009-05-15 09:23:25 +0000344}
345DwarfDebug::~DwarfDebug() {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000346 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
347 DIEBlocks[j]->~DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000348}
349
Chris Lattnerbc733f52010-03-13 02:17:42 +0000350MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
351 std::pair<MCSymbol*, unsigned> &Entry = StringPool[Str];
352 if (Entry.first) return Entry.first;
353
354 Entry.second = NextStringPoolNumber++;
Chris Lattnerc0215722010-04-04 19:25:43 +0000355 return Entry.first = Asm->GetTempSymbol("string", Entry.second);
Chris Lattnerbc733f52010-03-13 02:17:42 +0000356}
357
358
Devang Patel2c4ceb12009-11-21 02:48:08 +0000359/// assignAbbrevNumber - Define a unique number for the abbreviation.
Bill Wendling0310d762009-05-15 09:23:25 +0000360///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000361void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {
Bill Wendling0310d762009-05-15 09:23:25 +0000362 // Profile the node so that we can make it unique.
363 FoldingSetNodeID ID;
364 Abbrev.Profile(ID);
365
366 // Check the set for priors.
367 DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev);
368
369 // If it's newly added.
370 if (InSet == &Abbrev) {
371 // Add to abbreviation list.
372 Abbreviations.push_back(&Abbrev);
373
374 // Assign the vector position + 1 as its number.
375 Abbrev.setNumber(Abbreviations.size());
376 } else {
377 // Assign existing abbreviation number.
378 Abbrev.setNumber(InSet->getNumber());
379 }
380}
381
Devang Patel2c4ceb12009-11-21 02:48:08 +0000382/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
Bill Wendling995f80a2009-05-20 23:24:48 +0000383/// information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000384DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000385 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000386 return Value;
387}
388
Devang Patel2c4ceb12009-11-21 02:48:08 +0000389/// addUInt - Add an unsigned integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000390///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000391void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000392 unsigned Form, uint64_t Integer) {
393 if (!Form) Form = DIEInteger::BestForm(false, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000394 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000395 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000396}
397
Devang Patel2c4ceb12009-11-21 02:48:08 +0000398/// addSInt - Add an signed integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000399///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000400void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000401 unsigned Form, int64_t Integer) {
402 if (!Form) Form = DIEInteger::BestForm(true, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000403 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000404 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000405}
406
Devang Patel69f57b12009-12-02 15:25:16 +0000407/// addString - Add a string attribute data and value. DIEString only
408/// keeps string reference.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000409void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattner4cf202b2010-01-23 03:11:46 +0000410 StringRef String) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000411 DIEValue *Value = new (DIEValueAllocator) DIEString(String);
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/// addLabel - Add a Dwarf label attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000416///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000417void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000418 const MCSymbol *Label) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000419 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000420 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000421}
422
Devang Patel2c4ceb12009-11-21 02:48:08 +0000423/// addDelta - Add a label delta attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000424///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000425void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000426 const MCSymbol *Hi, const MCSymbol *Lo) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000427 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000428 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000429}
430
Chris Lattner74e41f92010-04-05 05:24:55 +0000431/// addDIEEntry - Add a DIE attribute data and value.
432///
433void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
434 DIE *Entry) {
435 Die->addValue(Attribute, Form, createDIEEntry(Entry));
436}
437
438
Devang Patel2c4ceb12009-11-21 02:48:08 +0000439/// addBlock - Add block data.
Bill Wendling0310d762009-05-15 09:23:25 +0000440///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000441void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
Bill Wendling0310d762009-05-15 09:23:25 +0000442 DIEBlock *Block) {
Chris Lattnera37d5382010-04-05 00:18:22 +0000443 Block->ComputeSize(Asm);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000444 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000445 Die->addValue(Attribute, Block->BestForm(), Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000446}
447
Devang Patel2c4ceb12009-11-21 02:48:08 +0000448/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000449/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000450void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
Devang Patelc665a512010-05-07 23:33:41 +0000451 // Verify variable.
452 if (!V->Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000453 return;
454
455 unsigned Line = V->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000456 unsigned FileID = GetOrCreateSourceID(V->getContext().getDirectory(),
457 V->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000458 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000459 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
460 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000461}
462
Devang Patel2c4ceb12009-11-21 02:48:08 +0000463/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000464/// entry.
Devang Patela49d8772010-05-07 23:19:07 +0000465void DwarfDebug::addSourceLine(DIE *Die, const DIGlobalVariable *G) {
Devang Patelc665a512010-05-07 23:33:41 +0000466 // Verify global variable.
467 if (!G->Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000468 return;
469
470 unsigned Line = G->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000471 unsigned FileID = GetOrCreateSourceID(G->getContext().getDirectory(),
472 G->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000473 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000474 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
475 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000476}
Devang Patel82dfc0c2009-08-31 22:47:13 +0000477
Devang Patel2c4ceb12009-11-21 02:48:08 +0000478/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000479/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000480void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
Devang Patelc665a512010-05-07 23:33:41 +0000481 // Verify subprogram.
482 if (!SP->Verify())
Devang Patel82dfc0c2009-08-31 22:47:13 +0000483 return;
Caroline Ticec6f9d622009-09-11 18:25:54 +0000484 // If the line number is 0, don't add it.
485 if (SP->getLineNumber() == 0)
486 return;
487
Devang Patel82dfc0c2009-08-31 22:47:13 +0000488 unsigned Line = SP->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000489 if (!SP->getContext().Verify())
490 return;
Devang Patel9bb59a22010-03-24 21:30:35 +0000491 unsigned FileID = GetOrCreateSourceID(SP->getDirectory(),
492 SP->getFilename());
Devang Patel82dfc0c2009-08-31 22:47:13 +0000493 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000494 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
495 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Devang Patel82dfc0c2009-08-31 22:47:13 +0000496}
497
Devang Patel2c4ceb12009-11-21 02:48:08 +0000498/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000499/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000500void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
Devang Patelc665a512010-05-07 23:33:41 +0000501 // Verify type.
502 if (!Ty->Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000503 return;
504
505 unsigned Line = Ty->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000506 if (!Ty->getContext().Verify())
507 return;
508 unsigned FileID = GetOrCreateSourceID(Ty->getContext().getDirectory(),
509 Ty->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000510 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000511 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
512 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000513}
514
Devang Patel6404e4e2009-12-15 19:16:48 +0000515/// addSourceLine - Add location information to specified debug information
516/// entry.
517void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) {
Devang Patelc665a512010-05-07 23:33:41 +0000518 // Verify namespace.
519 if (!NS->Verify())
Devang Patel6404e4e2009-12-15 19:16:48 +0000520 return;
521
522 unsigned Line = NS->getLineNumber();
523 StringRef FN = NS->getFilename();
524 StringRef Dir = NS->getDirectory();
525
526 unsigned FileID = GetOrCreateSourceID(Dir, FN);
527 assert(FileID && "Invalid file id");
528 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
529 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
530}
531
Caroline Ticedc8f6042009-08-31 21:19:37 +0000532/* Byref variables, in Blocks, are declared by the programmer as
533 "SomeType VarName;", but the compiler creates a
534 __Block_byref_x_VarName struct, and gives the variable VarName
535 either the struct, or a pointer to the struct, as its type. This
536 is necessary for various behind-the-scenes things the compiler
537 needs to do with by-reference variables in blocks.
538
539 However, as far as the original *programmer* is concerned, the
540 variable should still have type 'SomeType', as originally declared.
541
542 The following function dives into the __Block_byref_x_VarName
543 struct to find the original type of the variable. This will be
544 passed back to the code generating the type for the Debug
545 Information Entry for the variable 'VarName'. 'VarName' will then
546 have the original type 'SomeType' in its debug information.
547
548 The original type 'SomeType' will be the type of the field named
549 'VarName' inside the __Block_byref_x_VarName struct.
550
551 NOTE: In order for this to not completely fail on the debugger
552 side, the Debug Information Entry for the variable VarName needs to
553 have a DW_AT_location that tells the debugger how to unwind through
554 the pointers and __Block_byref_x_VarName struct to find the actual
Devang Patel2c4ceb12009-11-21 02:48:08 +0000555 value of the variable. The function addBlockByrefType does this. */
Caroline Ticedc8f6042009-08-31 21:19:37 +0000556
557/// Find the type the programmer originally declared the variable to be
558/// and return that type.
559///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000560DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000561
562 DIType subType = Ty;
563 unsigned tag = Ty.getTag();
564
565 if (tag == dwarf::DW_TAG_pointer_type) {
Devang Patel2db49d72010-05-07 18:11:54 +0000566 DIDerivedType DTy = DIDerivedType(Ty);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000567 subType = DTy.getTypeDerivedFrom();
568 }
569
Devang Patel2db49d72010-05-07 18:11:54 +0000570 DICompositeType blockStruct = DICompositeType(subType);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000571 DIArray Elements = blockStruct.getTypeArray();
572
Caroline Ticedc8f6042009-08-31 21:19:37 +0000573 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
574 DIDescriptor Element = Elements.getElement(i);
Devang Patel2db49d72010-05-07 18:11:54 +0000575 DIDerivedType DT = DIDerivedType(Element);
Devang Patel65dbc902009-11-25 17:36:49 +0000576 if (Name == DT.getName())
Caroline Ticedc8f6042009-08-31 21:19:37 +0000577 return (DT.getTypeDerivedFrom());
578 }
579
580 return Ty;
581}
582
Devang Patel2c4ceb12009-11-21 02:48:08 +0000583/// addComplexAddress - Start with the address based on the location provided,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000584/// and generate the DWARF information necessary to find the actual variable
585/// given the extra address information encoded in the DIVariable, starting from
586/// the starting location. Add the DWARF information to the die.
587///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000588void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000589 unsigned Attribute,
590 const MachineLocation &Location) {
591 const DIVariable &VD = DV->getVariable();
592 DIType Ty = VD.getType();
593
594 // Decode the original location, and use that as the start of the byref
595 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000596 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000597 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000598 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000599
600 if (Location.isReg()) {
601 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000602 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000603 } else {
604 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000605 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
606 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000607 }
608 } else {
609 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000610 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000611 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000612 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
613 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000614 }
615
Devang Patel2c4ceb12009-11-21 02:48:08 +0000616 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000617 }
618
619 for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) {
620 uint64_t Element = VD.getAddrElement(i);
621
622 if (Element == DIFactory::OpPlus) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000623 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
624 addUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i));
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000625 } else if (Element == DIFactory::OpDeref) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000626 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000627 } else llvm_unreachable("unknown DIFactory Opcode");
628 }
629
630 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000631 addBlock(Die, Attribute, 0, Block);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000632}
633
Caroline Ticedc8f6042009-08-31 21:19:37 +0000634/* Byref variables, in Blocks, are declared by the programmer as "SomeType
635 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
636 gives the variable VarName either the struct, or a pointer to the struct, as
637 its type. This is necessary for various behind-the-scenes things the
638 compiler needs to do with by-reference variables in Blocks.
639
640 However, as far as the original *programmer* is concerned, the variable
641 should still have type 'SomeType', as originally declared.
642
Devang Patel2c4ceb12009-11-21 02:48:08 +0000643 The function getBlockByrefType dives into the __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000644 struct to find the original type of the variable, which is then assigned to
645 the variable's Debug Information Entry as its real type. So far, so good.
646 However now the debugger will expect the variable VarName to have the type
647 SomeType. So we need the location attribute for the variable to be an
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000648 expression that explains to the debugger how to navigate through the
Caroline Ticedc8f6042009-08-31 21:19:37 +0000649 pointers and struct to find the actual variable of type SomeType.
650
651 The following function does just that. We start by getting
652 the "normal" location for the variable. This will be the location
653 of either the struct __Block_byref_x_VarName or the pointer to the
654 struct __Block_byref_x_VarName.
655
656 The struct will look something like:
657
658 struct __Block_byref_x_VarName {
659 ... <various fields>
660 struct __Block_byref_x_VarName *forwarding;
661 ... <various other fields>
662 SomeType VarName;
663 ... <maybe more fields>
664 };
665
666 If we are given the struct directly (as our starting point) we
667 need to tell the debugger to:
668
669 1). Add the offset of the forwarding field.
670
Dan Gohmanf451cb82010-02-10 16:03:48 +0000671 2). Follow that pointer to get the real __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000672 struct to use (the real one may have been copied onto the heap).
673
674 3). Add the offset for the field VarName, to find the actual variable.
675
676 If we started with a pointer to the struct, then we need to
677 dereference that pointer first, before the other steps.
678 Translating this into DWARF ops, we will need to append the following
679 to the current location description for the variable:
680
681 DW_OP_deref -- optional, if we start with a pointer
682 DW_OP_plus_uconst <forward_fld_offset>
683 DW_OP_deref
684 DW_OP_plus_uconst <varName_fld_offset>
685
686 That is what this function does. */
687
Devang Patel2c4ceb12009-11-21 02:48:08 +0000688/// addBlockByrefAddress - Start with the address based on the location
Caroline Ticedc8f6042009-08-31 21:19:37 +0000689/// provided, and generate the DWARF information necessary to find the
690/// actual Block variable (navigating the Block struct) based on the
691/// starting location. Add the DWARF information to the die. For
692/// more information, read large comment just above here.
693///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000694void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
Daniel Dunbar00564992009-09-19 20:40:14 +0000695 unsigned Attribute,
696 const MachineLocation &Location) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000697 const DIVariable &VD = DV->getVariable();
698 DIType Ty = VD.getType();
699 DIType TmpTy = Ty;
700 unsigned Tag = Ty.getTag();
701 bool isPointer = false;
702
Devang Patel65dbc902009-11-25 17:36:49 +0000703 StringRef varName = VD.getName();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000704
705 if (Tag == dwarf::DW_TAG_pointer_type) {
Devang Patel2db49d72010-05-07 18:11:54 +0000706 DIDerivedType DTy = DIDerivedType(Ty);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000707 TmpTy = DTy.getTypeDerivedFrom();
708 isPointer = true;
709 }
710
Devang Patel2db49d72010-05-07 18:11:54 +0000711 DICompositeType blockStruct = DICompositeType(TmpTy);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000712
Daniel Dunbar00564992009-09-19 20:40:14 +0000713 // Find the __forwarding field and the variable field in the __Block_byref
714 // struct.
Daniel Dunbar00564992009-09-19 20:40:14 +0000715 DIArray Fields = blockStruct.getTypeArray();
716 DIDescriptor varField = DIDescriptor();
717 DIDescriptor forwardingField = DIDescriptor();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000718
Daniel Dunbar00564992009-09-19 20:40:14 +0000719 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
720 DIDescriptor Element = Fields.getElement(i);
Devang Patel2db49d72010-05-07 18:11:54 +0000721 DIDerivedType DT = DIDerivedType(Element);
Devang Patel65dbc902009-11-25 17:36:49 +0000722 StringRef fieldName = DT.getName();
723 if (fieldName == "__forwarding")
Daniel Dunbar00564992009-09-19 20:40:14 +0000724 forwardingField = Element;
Devang Patel65dbc902009-11-25 17:36:49 +0000725 else if (fieldName == varName)
Daniel Dunbar00564992009-09-19 20:40:14 +0000726 varField = Element;
727 }
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000728
Daniel Dunbar00564992009-09-19 20:40:14 +0000729 // Get the offsets for the forwarding field and the variable field.
Chris Lattner1d65ba72010-03-31 06:06:37 +0000730 unsigned forwardingFieldOffset =
Devang Patel2db49d72010-05-07 18:11:54 +0000731 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
Chris Lattner1d65ba72010-03-31 06:06:37 +0000732 unsigned varFieldOffset =
Devang Patel2db49d72010-05-07 18:11:54 +0000733 DIDerivedType(varField).getOffsetInBits() >> 3;
Caroline Ticedc8f6042009-08-31 21:19:37 +0000734
Mike Stump7e3720d2009-09-24 23:21:26 +0000735 // Decode the original location, and use that as the start of the byref
736 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000737 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Daniel Dunbar00564992009-09-19 20:40:14 +0000738 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000739 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000740
Daniel Dunbar00564992009-09-19 20:40:14 +0000741 if (Location.isReg()) {
742 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000743 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000744 else {
745 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000746 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
747 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000748 }
749 } else {
750 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000751 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000752 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000753 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
754 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000755 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000756
Devang Patel2c4ceb12009-11-21 02:48:08 +0000757 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Daniel Dunbar00564992009-09-19 20:40:14 +0000758 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000759
Mike Stump7e3720d2009-09-24 23:21:26 +0000760 // If we started with a pointer to the __Block_byref... struct, then
Daniel Dunbar00564992009-09-19 20:40:14 +0000761 // the first thing we need to do is dereference the pointer (DW_OP_deref).
Daniel Dunbar00564992009-09-19 20:40:14 +0000762 if (isPointer)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000763 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000764
Daniel Dunbar00564992009-09-19 20:40:14 +0000765 // Next add the offset for the '__forwarding' field:
766 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
767 // adding the offset if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000768 if (forwardingFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000769 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
770 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000771 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000772
Daniel Dunbar00564992009-09-19 20:40:14 +0000773 // Now dereference the __forwarding field to get to the real __Block_byref
774 // struct: DW_OP_deref.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000775 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000776
Daniel Dunbar00564992009-09-19 20:40:14 +0000777 // Now that we've got the real __Block_byref... struct, add the offset
778 // for the variable's field to get to the location of the actual variable:
779 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000780 if (varFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000781 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
782 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000783 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000784
Daniel Dunbar00564992009-09-19 20:40:14 +0000785 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000786 addBlock(Die, Attribute, 0, Block);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000787}
788
Devang Patel2c4ceb12009-11-21 02:48:08 +0000789/// addAddress - Add an address attribute to a die based on the location
Bill Wendling0310d762009-05-15 09:23:25 +0000790/// provided.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000791void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000792 const MachineLocation &Location) {
Chris Lattnerd38fee82010-04-05 00:13:49 +0000793 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling0310d762009-05-15 09:23:25 +0000794 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000795 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000796
797 if (Location.isReg()) {
798 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000799 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + 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_regx);
802 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000803 }
804 } else {
805 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000806 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000807 } else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000808 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
809 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000810 }
811
Devang Patel2c4ceb12009-11-21 02:48:08 +0000812 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Bill Wendling0310d762009-05-15 09:23:25 +0000813 }
814
Devang Patel2c4ceb12009-11-21 02:48:08 +0000815 addBlock(Die, Attribute, 0, Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000816}
817
Devang Patela43098d2010-04-28 01:03:09 +0000818/// addRegisterAddress - Add register location entry in variable DIE.
819bool DwarfDebug::addRegisterAddress(DIE *Die, DbgVariable *DV,
820 const MachineOperand &MO) {
821 assert (MO.isReg() && "Invalid machine operand!");
822 if (!MO.getReg())
823 return false;
824 MachineLocation Location;
825 Location.set(MO.getReg());
826 addAddress(Die, dwarf::DW_AT_location, Location);
827 if (MCSymbol *VS = DV->getDbgValueLabel())
828 addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
829 return true;
830}
831
832/// addConstantValue - Add constant value entry in variable DIE.
833bool DwarfDebug::addConstantValue(DIE *Die, DbgVariable *DV,
834 const MachineOperand &MO) {
835 assert (MO.isImm() && "Invalid machine operand!");
836 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
837 unsigned Imm = MO.getImm();
838 addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
839 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
840 if (MCSymbol *VS = DV->getDbgValueLabel())
841 addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
842 return true;
843}
844
845/// addConstantFPValue - Add constant value entry in variable DIE.
846bool DwarfDebug::addConstantFPValue(DIE *Die, DbgVariable *DV,
847 const MachineOperand &MO) {
848 assert (MO.isFPImm() && "Invalid machine operand!");
849 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
850 APFloat FPImm = MO.getFPImm()->getValueAPF();
851
852 // Get the raw data form of the floating point.
853 const APInt FltVal = FPImm.bitcastToAPInt();
854 const char *FltPtr = (const char*)FltVal.getRawData();
855
856 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
857 bool LittleEndian = Asm->getTargetData().isLittleEndian();
858 int Incr = (LittleEndian ? 1 : -1);
859 int Start = (LittleEndian ? 0 : NumBytes - 1);
860 int Stop = (LittleEndian ? NumBytes : -1);
861
862 // Output the constant to DWARF one byte at a time.
863 for (; Start != Stop; Start += Incr)
864 addUInt(Block, 0, dwarf::DW_FORM_data1,
865 (unsigned char)0xFF & FltPtr[Start]);
866
867 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
868
869 if (MCSymbol *VS = DV->getDbgValueLabel())
870 addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
871 VS);
872 return true;
873}
874
875
Devang Patelc366f832009-12-10 19:14:49 +0000876/// addToContextOwner - Add Die into the list of its context owner's children.
877void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
Devang Patel3c91b052010-03-08 20:52:55 +0000878 if (Context.isType()) {
Devang Patel2db49d72010-05-07 18:11:54 +0000879 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
Devang Patelc366f832009-12-10 19:14:49 +0000880 ContextDIE->addChild(Die);
Devang Patel6404e4e2009-12-15 19:16:48 +0000881 } else if (Context.isNameSpace()) {
Devang Patel2db49d72010-05-07 18:11:54 +0000882 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
Devang Patel6404e4e2009-12-15 19:16:48 +0000883 ContextDIE->addChild(Die);
Devang Patel163a9f72010-05-10 22:49:55 +0000884 } else if (DIE *ContextDIE = getCompileUnit(Context)->getDIE(Context))
Devang Patelc366f832009-12-10 19:14:49 +0000885 ContextDIE->addChild(Die);
886 else
Devang Patel163a9f72010-05-10 22:49:55 +0000887 getCompileUnit(Context)->addDie(Die);
Devang Patelc366f832009-12-10 19:14:49 +0000888}
889
Devang Patel16ced732009-12-10 18:05:33 +0000890/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
891/// given DIType.
892DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
Devang Patel163a9f72010-05-10 22:49:55 +0000893 CompileUnit *TypeCU = getCompileUnit(Ty);
894 DIE *TyDIE = TypeCU->getDIE(Ty);
Devang Patel16ced732009-12-10 18:05:33 +0000895 if (TyDIE)
896 return TyDIE;
897
898 // Create new type.
899 TyDIE = new DIE(dwarf::DW_TAG_base_type);
Devang Patel163a9f72010-05-10 22:49:55 +0000900 TypeCU->insertDIE(Ty, TyDIE);
Devang Patel16ced732009-12-10 18:05:33 +0000901 if (Ty.isBasicType())
Devang Patel2db49d72010-05-07 18:11:54 +0000902 constructTypeDIE(*TyDIE, DIBasicType(Ty));
Devang Patel16ced732009-12-10 18:05:33 +0000903 else if (Ty.isCompositeType())
Devang Patel2db49d72010-05-07 18:11:54 +0000904 constructTypeDIE(*TyDIE, DICompositeType(Ty));
Devang Patel16ced732009-12-10 18:05:33 +0000905 else {
906 assert(Ty.isDerivedType() && "Unknown kind of DIType");
Devang Patel2db49d72010-05-07 18:11:54 +0000907 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
Devang Patel16ced732009-12-10 18:05:33 +0000908 }
909
Devang Patelc366f832009-12-10 19:14:49 +0000910 addToContextOwner(TyDIE, Ty.getContext());
Devang Patel16ced732009-12-10 18:05:33 +0000911 return TyDIE;
912}
913
Devang Patel2c4ceb12009-11-21 02:48:08 +0000914/// addType - Add a new type attribute to the specified entity.
Devang Patel8a241142009-12-09 18:24:21 +0000915void DwarfDebug::addType(DIE *Entity, DIType Ty) {
Devang Patel9c004872010-05-07 21:45:47 +0000916 if (!Ty.Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000917 return;
918
919 // Check for pre-existence.
Devang Patel163a9f72010-05-10 22:49:55 +0000920 CompileUnit *TypeCU = getCompileUnit(Ty);
921 DIEEntry *Entry = TypeCU->getDIEEntry(Ty);
Bill Wendling0310d762009-05-15 09:23:25 +0000922 // If it exists then use the existing value.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000923 if (Entry) {
924 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000925 return;
926 }
927
Bill Wendling0310d762009-05-15 09:23:25 +0000928 // Construct type.
Devang Patel16ced732009-12-10 18:05:33 +0000929 DIE *Buffer = getOrCreateTypeDIE(Ty);
Bill Wendling0310d762009-05-15 09:23:25 +0000930
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000931 // Set up proxy.
932 Entry = createDIEEntry(Buffer);
Devang Patel163a9f72010-05-10 22:49:55 +0000933 TypeCU->insertDIEEntry(Ty, Entry);
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000934
Devang Patel2c4ceb12009-11-21 02:48:08 +0000935 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000936}
937
Devang Patel2c4ceb12009-11-21 02:48:08 +0000938/// constructTypeDIE - Construct basic type die from DIBasicType.
Devang Patel8a241142009-12-09 18:24:21 +0000939void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000940 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000941 StringRef Name = BTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000942 Buffer.setTag(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000943 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Bill Wendling0310d762009-05-15 09:23:25 +0000944 BTy.getEncoding());
945
946 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +0000947 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000948 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000949 uint64_t Size = BTy.getSizeInBits() >> 3;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000950 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000951}
952
Devang Patel2c4ceb12009-11-21 02:48:08 +0000953/// constructTypeDIE - Construct derived type die from DIDerivedType.
Devang Patel8a241142009-12-09 18:24:21 +0000954void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000955 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000956 StringRef Name = DTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000957 uint64_t Size = DTy.getSizeInBits() >> 3;
958 unsigned Tag = DTy.getTag();
959
960 // FIXME - Workaround for templates.
961 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
962
963 Buffer.setTag(Tag);
964
965 // Map to main type, void will not have a type.
966 DIType FromTy = DTy.getTypeDerivedFrom();
Devang Patel8a241142009-12-09 18:24:21 +0000967 addType(&Buffer, FromTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000968
969 // Add name if not anonymous or intermediate type.
Devang Pateldeea5642009-11-30 23:56:56 +0000970 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000971 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000972
973 // Add size if non-zero (derived types might be zero-sized.)
974 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000975 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000976
977 // Add source line info if available and TyDesc is not a forward declaration.
Devang Patel05f6fa82009-11-23 18:43:37 +0000978 if (!DTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000979 addSourceLine(&Buffer, &DTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000980}
981
Devang Patel2c4ceb12009-11-21 02:48:08 +0000982/// constructTypeDIE - Construct type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +0000983void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000984 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000985 StringRef Name = CTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000986
987 uint64_t Size = CTy.getSizeInBits() >> 3;
988 unsigned Tag = CTy.getTag();
989 Buffer.setTag(Tag);
990
991 switch (Tag) {
992 case dwarf::DW_TAG_vector_type:
993 case dwarf::DW_TAG_array_type:
Devang Patel8a241142009-12-09 18:24:21 +0000994 constructArrayTypeDIE(Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000995 break;
996 case dwarf::DW_TAG_enumeration_type: {
997 DIArray Elements = CTy.getTypeArray();
998
999 // Add enumerators to enumeration type.
1000 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1001 DIE *ElemDie = NULL;
Devang Patel2db49d72010-05-07 18:11:54 +00001002 DIDescriptor Enum(Elements.getElement(i));
Devang Patel3c91b052010-03-08 20:52:55 +00001003 if (Enum.isEnumerator()) {
Devang Patel2db49d72010-05-07 18:11:54 +00001004 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
Devang Patel2c4ceb12009-11-21 02:48:08 +00001005 Buffer.addChild(ElemDie);
Devang Patelc5254722009-10-09 17:51:49 +00001006 }
Bill Wendling0310d762009-05-15 09:23:25 +00001007 }
1008 }
1009 break;
1010 case dwarf::DW_TAG_subroutine_type: {
1011 // Add return type.
1012 DIArray Elements = CTy.getTypeArray();
1013 DIDescriptor RTy = Elements.getElement(0);
Devang Patel2db49d72010-05-07 18:11:54 +00001014 addType(&Buffer, DIType(RTy));
Bill Wendling0310d762009-05-15 09:23:25 +00001015
1016 // Add prototype flag.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001017 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001018
1019 // Add arguments.
1020 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
1021 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1022 DIDescriptor Ty = Elements.getElement(i);
Devang Patel2db49d72010-05-07 18:11:54 +00001023 addType(Arg, DIType(Ty));
Devang Patel2c4ceb12009-11-21 02:48:08 +00001024 Buffer.addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +00001025 }
1026 }
1027 break;
1028 case dwarf::DW_TAG_structure_type:
1029 case dwarf::DW_TAG_union_type:
1030 case dwarf::DW_TAG_class_type: {
1031 // Add elements to structure type.
1032 DIArray Elements = CTy.getTypeArray();
1033
1034 // A forward struct declared type may not have elements available.
Devang Patel3c91b052010-03-08 20:52:55 +00001035 unsigned N = Elements.getNumElements();
1036 if (N == 0)
Bill Wendling0310d762009-05-15 09:23:25 +00001037 break;
1038
1039 // Add elements to structure type.
Devang Patel3c91b052010-03-08 20:52:55 +00001040 for (unsigned i = 0; i < N; ++i) {
Bill Wendling0310d762009-05-15 09:23:25 +00001041 DIDescriptor Element = Elements.getElement(i);
1042 DIE *ElemDie = NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001043 if (Element.isSubprogram())
Devang Patel2db49d72010-05-07 18:11:54 +00001044 ElemDie = createSubprogramDIE(DISubprogram(Element));
Devang Patel3c91b052010-03-08 20:52:55 +00001045 else if (Element.isVariable()) {
Devang Patel2db49d72010-05-07 18:11:54 +00001046 DIVariable DV(Element);
Devang Patel1ee0cb92010-01-30 01:08:30 +00001047 ElemDie = new DIE(dwarf::DW_TAG_variable);
1048 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
1049 DV.getName());
1050 addType(ElemDie, DV.getType());
1051 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1052 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1053 addSourceLine(ElemDie, &DV);
Devang Patel3c91b052010-03-08 20:52:55 +00001054 } else if (Element.isDerivedType())
Devang Patel2db49d72010-05-07 18:11:54 +00001055 ElemDie = createMemberDIE(DIDerivedType(Element));
Devang Patel3c91b052010-03-08 20:52:55 +00001056 else
1057 continue;
Devang Patel2c4ceb12009-11-21 02:48:08 +00001058 Buffer.addChild(ElemDie);
Bill Wendling0310d762009-05-15 09:23:25 +00001059 }
1060
Devang Patela1ba2692009-08-27 23:51:51 +00001061 if (CTy.isAppleBlockExtension())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001062 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001063
1064 unsigned RLang = CTy.getRunTimeLang();
1065 if (RLang)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001066 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
Bill Wendling0310d762009-05-15 09:23:25 +00001067 dwarf::DW_FORM_data1, RLang);
Devang Patelb5544992010-01-26 21:16:06 +00001068
1069 DICompositeType ContainingType = CTy.getContainingType();
Devang Patel2db49d72010-05-07 18:11:54 +00001070 if (DIDescriptor(ContainingType).isCompositeType())
Devang Patelb5544992010-01-26 21:16:06 +00001071 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
Devang Patel2db49d72010-05-07 18:11:54 +00001072 getOrCreateTypeDIE(DIType(ContainingType)));
Bill Wendling0310d762009-05-15 09:23:25 +00001073 break;
1074 }
1075 default:
1076 break;
1077 }
1078
1079 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +00001080 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001081 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +00001082
Devang Patel8cbb6122010-01-29 18:34:58 +00001083 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type ||
Bill Wendling0310d762009-05-15 09:23:25 +00001084 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
1085 // Add size if non-zero (derived types might be zero-sized.)
1086 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001087 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +00001088 else {
1089 // Add zero size if it is not a forward declaration.
1090 if (CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001091 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001092 else
Devang Patel2c4ceb12009-11-21 02:48:08 +00001093 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
Bill Wendling0310d762009-05-15 09:23:25 +00001094 }
1095
1096 // Add source line info if available.
1097 if (!CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001098 addSourceLine(&Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001099 }
1100}
1101
Devang Patel2c4ceb12009-11-21 02:48:08 +00001102/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1103void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
Bill Wendling0310d762009-05-15 09:23:25 +00001104 int64_t L = SR.getLo();
1105 int64_t H = SR.getHi();
1106 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1107
Devang Patel2c4ceb12009-11-21 02:48:08 +00001108 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patel6325a532009-08-14 20:59:16 +00001109 if (L)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001110 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
Devang Pateld55224c2009-12-04 23:10:24 +00001111 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Bill Wendling0310d762009-05-15 09:23:25 +00001112
Devang Patel2c4ceb12009-11-21 02:48:08 +00001113 Buffer.addChild(DW_Subrange);
Bill Wendling0310d762009-05-15 09:23:25 +00001114}
1115
Devang Patel2c4ceb12009-11-21 02:48:08 +00001116/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +00001117void DwarfDebug::constructArrayTypeDIE(DIE &Buffer,
Bill Wendling0310d762009-05-15 09:23:25 +00001118 DICompositeType *CTy) {
1119 Buffer.setTag(dwarf::DW_TAG_array_type);
1120 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001121 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001122
1123 // Emit derived type.
Devang Patel8a241142009-12-09 18:24:21 +00001124 addType(&Buffer, CTy->getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001125 DIArray Elements = CTy->getTypeArray();
1126
Devang Patel6f01d9c2009-11-21 00:31:03 +00001127 // Get an anonymous type for index type.
Devang Patel163a9f72010-05-10 22:49:55 +00001128 CompileUnit *TheCU = getCompileUnit(*CTy);
1129 DIE *IdxTy = TheCU->getIndexTyDie();
Devang Patel6f01d9c2009-11-21 00:31:03 +00001130 if (!IdxTy) {
1131 // Construct an anonymous type for index type.
1132 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001133 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1134 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel6f01d9c2009-11-21 00:31:03 +00001135 dwarf::DW_ATE_signed);
Devang Patel163a9f72010-05-10 22:49:55 +00001136 TheCU->addDie(IdxTy);
1137 TheCU->setIndexTyDie(IdxTy);
Devang Patel6f01d9c2009-11-21 00:31:03 +00001138 }
Bill Wendling0310d762009-05-15 09:23:25 +00001139
1140 // Add subranges to array type.
1141 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1142 DIDescriptor Element = Elements.getElement(i);
1143 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
Devang Patel2db49d72010-05-07 18:11:54 +00001144 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001145 }
1146}
1147
Devang Patel2c4ceb12009-11-21 02:48:08 +00001148/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
Devang Patel3c91b052010-03-08 20:52:55 +00001149DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) {
Bill Wendling0310d762009-05-15 09:23:25 +00001150 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
Devang Patel3c91b052010-03-08 20:52:55 +00001151 StringRef Name = ETy.getName();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001152 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel3c91b052010-03-08 20:52:55 +00001153 int64_t Value = ETy.getEnumValue();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001154 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
Bill Wendling0310d762009-05-15 09:23:25 +00001155 return Enumerator;
1156}
1157
Devang Patel351ca332010-01-05 01:46:14 +00001158/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1159/// printer to not emit usual symbol prefix before the symbol name is used then
1160/// return linkage name after skipping this special LLVM prefix.
1161static StringRef getRealLinkageName(StringRef LinkageName) {
1162 char One = '\1';
1163 if (LinkageName.startswith(StringRef(&One, 1)))
1164 return LinkageName.substr(1);
1165 return LinkageName;
1166}
1167
Devang Patel2c4ceb12009-11-21 02:48:08 +00001168/// createGlobalVariableDIE - Create new DIE using GV.
Devang Patel8a241142009-12-09 18:24:21 +00001169DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001170 // If the global variable was optmized out then no need to create debug info
1171 // entry.
Devang Patel84c73e92009-11-06 17:58:12 +00001172 if (!GV.getGlobal()) return NULL;
Devang Patel65dbc902009-11-25 17:36:49 +00001173 if (GV.getDisplayName().empty()) return NULL;
Devang Patel465c3be2009-11-06 01:30:04 +00001174
Bill Wendling0310d762009-05-15 09:23:25 +00001175 DIE *GVDie = new DIE(dwarf::DW_TAG_variable);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001176 addString(GVDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001177 GV.getDisplayName());
1178
Devang Patel65dbc902009-11-25 17:36:49 +00001179 StringRef LinkageName = GV.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001180 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001181 addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001182 getRealLinkageName(LinkageName));
1183
Devang Patel8a241142009-12-09 18:24:21 +00001184 addType(GVDie, GV.getType());
Bill Wendling0310d762009-05-15 09:23:25 +00001185 if (!GV.isLocalToUnit())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001186 addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1187 addSourceLine(GVDie, &GV);
Devang Patelb71a16d2009-10-05 23:22:08 +00001188
Bill Wendling0310d762009-05-15 09:23:25 +00001189 return GVDie;
1190}
1191
Devang Patel2c4ceb12009-11-21 02:48:08 +00001192/// createMemberDIE - Create new member DIE.
Devang Patel8a241142009-12-09 18:24:21 +00001193DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
Bill Wendling0310d762009-05-15 09:23:25 +00001194 DIE *MemberDie = new DIE(DT.getTag());
Devang Patel65dbc902009-11-25 17:36:49 +00001195 StringRef Name = DT.getName();
1196 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001197 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel65dbc902009-11-25 17:36:49 +00001198
Devang Patel8a241142009-12-09 18:24:21 +00001199 addType(MemberDie, DT.getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001200
Devang Patel2c4ceb12009-11-21 02:48:08 +00001201 addSourceLine(MemberDie, &DT);
Bill Wendling0310d762009-05-15 09:23:25 +00001202
Benjamin Kramer345ef342010-03-31 19:34:01 +00001203 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001204 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
Devang Patel33db5082009-11-04 22:06:12 +00001205
Bill Wendling0310d762009-05-15 09:23:25 +00001206 uint64_t Size = DT.getSizeInBits();
Devang Patel61ecbd12009-11-04 23:48:00 +00001207 uint64_t FieldSize = DT.getOriginalTypeSize();
Bill Wendling0310d762009-05-15 09:23:25 +00001208
1209 if (Size != FieldSize) {
1210 // Handle bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001211 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1212 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
Bill Wendling0310d762009-05-15 09:23:25 +00001213
1214 uint64_t Offset = DT.getOffsetInBits();
Bill Wendling0310d762009-05-15 09:23:25 +00001215 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1216 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
Benjamin Kramer3d594fd2010-01-07 17:50:57 +00001217 uint64_t FieldOffset = (HiMark - FieldSize);
Bill Wendling0310d762009-05-15 09:23:25 +00001218 Offset -= FieldOffset;
1219
1220 // Maybe we need to work from the other end.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001221 if (Asm->getTargetData().isLittleEndian())
1222 Offset = FieldSize - (Offset + Size);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001223 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
Bill Wendling0310d762009-05-15 09:23:25 +00001224
Devang Patel33db5082009-11-04 22:06:12 +00001225 // Here WD_AT_data_member_location points to the anonymous
1226 // field that includes this bit field.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001227 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001228
1229 } else
1230 // This is not a bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001231 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001232
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001233 if (DT.getTag() == dwarf::DW_TAG_inheritance
1234 && DT.isVirtual()) {
1235
1236 // For C++, virtual base classes are not at fixed offset. Use following
1237 // expression to extract appropriate offset from vtable.
1238 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1239
Benjamin Kramer345ef342010-03-31 19:34:01 +00001240 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001241 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1242 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1243 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1244 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1245 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1246 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1247 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1248
1249 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1250 VBaseLocationDie);
1251 } else
1252 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
Bill Wendling0310d762009-05-15 09:23:25 +00001253
1254 if (DT.isProtected())
Devang Patel5d11eb02009-12-03 19:11:07 +00001255 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001256 dwarf::DW_ACCESS_protected);
1257 else if (DT.isPrivate())
Devang Patel5d11eb02009-12-03 19:11:07 +00001258 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001259 dwarf::DW_ACCESS_private);
Devang Patel5d11eb02009-12-03 19:11:07 +00001260 else if (DT.getTag() == dwarf::DW_TAG_inheritance)
1261 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1262 dwarf::DW_ACCESS_public);
1263 if (DT.isVirtual())
1264 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1265 dwarf::DW_VIRTUALITY_virtual);
Bill Wendling0310d762009-05-15 09:23:25 +00001266 return MemberDie;
1267}
1268
Devang Patelffe966c2009-12-14 16:18:45 +00001269/// createSubprogramDIE - Create new DIE using SP.
1270DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
Devang Patel163a9f72010-05-10 22:49:55 +00001271 CompileUnit *SPCU = getCompileUnit(SP);
1272 DIE *SPDie = SPCU->getDIE(SP);
Devang Patelffe966c2009-12-14 16:18:45 +00001273 if (SPDie)
1274 return SPDie;
1275
1276 SPDie = new DIE(dwarf::DW_TAG_subprogram);
Devang Patel1eac3e72010-03-02 17:58:15 +00001277 // Constructors and operators for anonymous aggregates do not have names.
Devang Patel6b506cb2010-03-02 01:26:20 +00001278 if (!SP.getName().empty())
1279 addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
Bill Wendling0310d762009-05-15 09:23:25 +00001280
Devang Patel65dbc902009-11-25 17:36:49 +00001281 StringRef LinkageName = SP.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001282 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001283 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001284 getRealLinkageName(LinkageName));
1285
Devang Patel2c4ceb12009-11-21 02:48:08 +00001286 addSourceLine(SPDie, &SP);
Bill Wendling0310d762009-05-15 09:23:25 +00001287
Bill Wendling0310d762009-05-15 09:23:25 +00001288 // Add prototyped tag, if C or ObjC.
1289 unsigned Lang = SP.getCompileUnit().getLanguage();
1290 if (Lang == dwarf::DW_LANG_C99 || Lang == dwarf::DW_LANG_C89 ||
1291 Lang == dwarf::DW_LANG_ObjC)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001292 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001293
1294 // Add Return Type.
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001295 DICompositeType SPTy = SP.getType();
1296 DIArray Args = SPTy.getTypeArray();
Bill Wendling0310d762009-05-15 09:23:25 +00001297 unsigned SPTag = SPTy.getTag();
Devang Patel5d11eb02009-12-03 19:11:07 +00001298
Devang Patel3c91b052010-03-08 20:52:55 +00001299 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
Devang Patel8a241142009-12-09 18:24:21 +00001300 addType(SPDie, SPTy);
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001301 else
Devang Patel2db49d72010-05-07 18:11:54 +00001302 addType(SPDie, DIType(Args.getElement(0)));
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001303
Devang Patel5d11eb02009-12-03 19:11:07 +00001304 unsigned VK = SP.getVirtuality();
1305 if (VK) {
1306 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001307 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel5d11eb02009-12-03 19:11:07 +00001308 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1309 addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
1310 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
Devang Patel622b0262010-01-19 06:19:05 +00001311 ContainingTypeMap.insert(std::make_pair(SPDie,
Devang Patel2db49d72010-05-07 18:11:54 +00001312 SP.getContainingType()));
Devang Patel5d11eb02009-12-03 19:11:07 +00001313 }
1314
Devang Patelffe966c2009-12-14 16:18:45 +00001315 if (MakeDecl || !SP.isDefinition()) {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001316 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001317
1318 // Add arguments. Do not add arguments for subprogram definition. They will
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001319 // be handled while processing variables.
1320 DICompositeType SPTy = SP.getType();
1321 DIArray Args = SPTy.getTypeArray();
1322 unsigned SPTag = SPTy.getTag();
1323
Bill Wendling0310d762009-05-15 09:23:25 +00001324 if (SPTag == dwarf::DW_TAG_subroutine_type)
1325 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1326 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Devang Patel2db49d72010-05-07 18:11:54 +00001327 DIType ATy = DIType(DIType(Args.getElement(i)));
Devang Patelb4645642010-02-06 01:02:37 +00001328 addType(Arg, ATy);
1329 if (ATy.isArtificial())
1330 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001331 SPDie->addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +00001332 }
1333 }
1334
Devang Patel4e0d19d2010-02-03 19:57:19 +00001335 if (SP.isArtificial())
1336 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1337
Devang Patelccff8122010-04-30 19:38:23 +00001338 if (!SP.isLocalToUnit())
1339 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
Devang Patel2a4a3b72010-04-19 19:14:02 +00001340
Devang Patelccff8122010-04-30 19:38:23 +00001341 if (SP.isOptimized())
1342 addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
1343
Devang Patelccff8122010-04-30 19:38:23 +00001344 // DW_TAG_inlined_subroutine may refer to this DIE.
Devang Patel163a9f72010-05-10 22:49:55 +00001345 SPCU->insertDIE(SP, SPDie);
Devang Patelccff8122010-04-30 19:38:23 +00001346
Bill Wendling0310d762009-05-15 09:23:25 +00001347 return SPDie;
1348}
1349
Devang Patele9f8f5e2010-05-07 20:54:48 +00001350DbgScope *DwarfDebug::getOrCreateAbstractScope(const MDNode *N) {
Chris Lattnered7a77b2010-03-31 05:36:29 +00001351 assert(N && "Invalid Scope encoding!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001352
1353 DbgScope *AScope = AbstractScopes.lookup(N);
1354 if (AScope)
1355 return AScope;
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001356
Devang Patel53bb5c92009-11-10 23:06:00 +00001357 DbgScope *Parent = NULL;
1358
1359 DIDescriptor Scope(N);
1360 if (Scope.isLexicalBlock()) {
1361 DILexicalBlock DB(N);
1362 DIDescriptor ParentDesc = DB.getContext();
Devang Patel2db49d72010-05-07 18:11:54 +00001363 Parent = getOrCreateAbstractScope(ParentDesc);
Devang Patel53bb5c92009-11-10 23:06:00 +00001364 }
1365
1366 AScope = new DbgScope(Parent, DIDescriptor(N), NULL);
1367
1368 if (Parent)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001369 Parent->addScope(AScope);
Devang Patel53bb5c92009-11-10 23:06:00 +00001370 AScope->setAbstractScope();
1371 AbstractScopes[N] = AScope;
1372 if (DIDescriptor(N).isSubprogram())
1373 AbstractScopesList.push_back(AScope);
1374 return AScope;
1375}
Devang Patelaf9e8472009-10-01 20:31:14 +00001376
Devang Patel5f094002010-04-06 23:53:48 +00001377/// isSubprogramContext - Return true if Context is either a subprogram
1378/// or another context nested inside a subprogram.
Devang Patele9f8f5e2010-05-07 20:54:48 +00001379static bool isSubprogramContext(const MDNode *Context) {
Devang Patel5f094002010-04-06 23:53:48 +00001380 if (!Context)
1381 return false;
1382 DIDescriptor D(Context);
1383 if (D.isSubprogram())
1384 return true;
1385 if (D.isType())
Devang Patel2db49d72010-05-07 18:11:54 +00001386 return isSubprogramContext(DIType(Context).getContext());
Devang Patel5f094002010-04-06 23:53:48 +00001387 return false;
1388}
1389
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001390/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
Devang Patel2c4ceb12009-11-21 02:48:08 +00001391/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
1392/// If there are global variables in this scope then create and insert
1393/// DIEs for these variables.
Devang Patele9f8f5e2010-05-07 20:54:48 +00001394DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) {
Devang Patel163a9f72010-05-10 22:49:55 +00001395 CompileUnit *SPCU = getCompileUnit(SPNode);
1396 DIE *SPDie = SPCU->getDIE(SPNode);
Chris Lattnerd38fee82010-04-05 00:13:49 +00001397 assert(SPDie && "Unable to find subprogram DIE!");
1398 DISubprogram SP(SPNode);
Chris Lattner206d61e2010-03-13 07:26:18 +00001399
Chris Lattnerd38fee82010-04-05 00:13:49 +00001400 // There is not any need to generate specification DIE for a function
1401 // defined at compile unit level. If a function is defined inside another
1402 // function then gdb prefers the definition at top level and but does not
1403 // expect specification DIE in parent function. So avoid creating
1404 // specification DIE for a function defined inside a function.
1405 if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001406 !SP.getContext().isFile() &&
Devang Patel2db49d72010-05-07 18:11:54 +00001407 !isSubprogramContext(SP.getContext())) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00001408 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1409
1410 // Add arguments.
1411 DICompositeType SPTy = SP.getType();
1412 DIArray Args = SPTy.getTypeArray();
1413 unsigned SPTag = SPTy.getTag();
1414 if (SPTag == dwarf::DW_TAG_subroutine_type)
1415 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1416 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Devang Patel2db49d72010-05-07 18:11:54 +00001417 DIType ATy = DIType(DIType(Args.getElement(i)));
Chris Lattnerd38fee82010-04-05 00:13:49 +00001418 addType(Arg, ATy);
1419 if (ATy.isArtificial())
1420 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1421 SPDie->addChild(Arg);
1422 }
1423 DIE *SPDeclDie = SPDie;
1424 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1425 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1426 SPDeclDie);
Devang Patel163a9f72010-05-10 22:49:55 +00001427 SPCU->addDie(SPDie);
Chris Lattnerd38fee82010-04-05 00:13:49 +00001428 }
1429
1430 addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1431 Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
1432 addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
1433 Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
1434 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1435 MachineLocation Location(RI->getFrameRegister(*Asm->MF));
1436 addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
Devang Patelb4645642010-02-06 01:02:37 +00001437
Chris Lattnerd38fee82010-04-05 00:13:49 +00001438 return SPDie;
Devang Patel53bb5c92009-11-10 23:06:00 +00001439}
1440
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001441/// constructLexicalScope - Construct new DW_TAG_lexical_block
Devang Patel2c4ceb12009-11-21 02:48:08 +00001442/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
1443DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
Devang Pateleac9c072010-04-27 19:46:33 +00001444
1445 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
1446 if (Scope->isAbstractScope())
1447 return ScopeDIE;
1448
1449 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1450 if (Ranges.empty())
1451 return 0;
1452
1453 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1454 if (Ranges.size() > 1) {
1455 // .debug_range section has not been laid out yet. Emit offset in
1456 // .debug_range as a uint, size 4, for now. emitDIE will handle
1457 // DW_AT_ranges appropriately.
1458 addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
1459 DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());
1460 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
1461 RE = Ranges.end(); RI != RE; ++RI) {
1462 DebugRangeSymbols.push_back(LabelsBeforeInsn.lookup(RI->first));
1463 DebugRangeSymbols.push_back(LabelsAfterInsn.lookup(RI->second));
1464 }
1465 DebugRangeSymbols.push_back(NULL);
1466 DebugRangeSymbols.push_back(NULL);
1467 return ScopeDIE;
1468 }
1469
1470 MCSymbol *Start = LabelsBeforeInsn.lookup(RI->first);
1471 MCSymbol *End = LabelsAfterInsn.lookup(RI->second);
1472
Devang Patelaead63c2010-03-29 22:59:58 +00001473 if (Start == 0 || End == 0) return 0;
Devang Patel53bb5c92009-11-10 23:06:00 +00001474
Chris Lattnerb7db7332010-03-09 01:58:53 +00001475 assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
1476 assert(End->isDefined() && "Invalid end label for an inlined scope!");
Chris Lattnera34ec2292010-03-09 01:51:43 +00001477
Devang Pateleac9c072010-04-27 19:46:33 +00001478 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start);
1479 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End);
Devang Patel53bb5c92009-11-10 23:06:00 +00001480
1481 return ScopeDIE;
1482}
1483
Devang Patel2c4ceb12009-11-21 02:48:08 +00001484/// constructInlinedScopeDIE - This scope represents inlined body of
1485/// a function. Construct DIE to represent this concrete inlined copy
1486/// of the function.
1487DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
Devang Pateleac9c072010-04-27 19:46:33 +00001488
1489 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1490 assert (Ranges.empty() == false
1491 && "DbgScope does not have instruction markers!");
1492
1493 // FIXME : .debug_inlined section specification does not clearly state how
1494 // to emit inlined scope that is split into multiple instruction ranges.
1495 // For now, use first instruction range and emit low_pc/high_pc pair and
1496 // corresponding .debug_inlined section entry for this pair.
1497 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1498 MCSymbol *StartLabel = LabelsBeforeInsn.lookup(RI->first);
1499 MCSymbol *EndLabel = LabelsAfterInsn.lookup(RI->second);
1500
1501 if (StartLabel == 0 || EndLabel == 0) {
1502 assert (0 && "Unexpected Start and End labels for a inlined scope!");
1503 return 0;
1504 }
Chris Lattnerb7db7332010-03-09 01:58:53 +00001505 assert(StartLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001506 "Invalid starting label for an inlined scope!");
Chris Lattnerb7db7332010-03-09 01:58:53 +00001507 assert(EndLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001508 "Invalid end label for an inlined scope!");
Devang Pateleac9c072010-04-27 19:46:33 +00001509
Devang Patel3c91b052010-03-08 20:52:55 +00001510 if (!Scope->getScopeNode())
Devang Patel0ef3fa62010-03-08 19:20:38 +00001511 return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001512 DIScope DS(Scope->getScopeNode());
Devang Patel53bb5c92009-11-10 23:06:00 +00001513 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
1514
Devang Patel2db49d72010-05-07 18:11:54 +00001515 DISubprogram InlinedSP = getDISubprogram(DS);
Devang Patel163a9f72010-05-10 22:49:55 +00001516 CompileUnit *TheCU = getCompileUnit(InlinedSP);
1517 DIE *OriginDIE = TheCU->getDIE(InlinedSP);
Chris Lattnered7a77b2010-03-31 05:36:29 +00001518 assert(OriginDIE && "Unable to find Origin DIE!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001519 addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001520 dwarf::DW_FORM_ref4, OriginDIE);
1521
Chris Lattner6ed0f902010-03-09 00:31:02 +00001522 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel);
Chris Lattnerb7db7332010-03-09 01:58:53 +00001523 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel);
Devang Patel53bb5c92009-11-10 23:06:00 +00001524
1525 InlinedSubprogramDIEs.insert(OriginDIE);
1526
1527 // Track the start label for this inlined function.
Devang Patele9f8f5e2010-05-07 20:54:48 +00001528 DenseMap<const MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
Devang Patel2db49d72010-05-07 18:11:54 +00001529 I = InlineInfo.find(InlinedSP);
Devang Patel53bb5c92009-11-10 23:06:00 +00001530
1531 if (I == InlineInfo.end()) {
Devang Patel2db49d72010-05-07 18:11:54 +00001532 InlineInfo[InlinedSP].push_back(std::make_pair(StartLabel,
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001533 ScopeDIE));
Devang Patel2db49d72010-05-07 18:11:54 +00001534 InlinedSPNodes.push_back(InlinedSP);
Devang Patel53bb5c92009-11-10 23:06:00 +00001535 } else
Chris Lattner6ed0f902010-03-09 00:31:02 +00001536 I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
Devang Patel53bb5c92009-11-10 23:06:00 +00001537
Devang Patel53bb5c92009-11-10 23:06:00 +00001538 DILocation DL(Scope->getInlinedAt());
Devang Patel163a9f72010-05-10 22:49:55 +00001539 addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, TheCU->getID());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001540 addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
Devang Patel53bb5c92009-11-10 23:06:00 +00001541
1542 return ScopeDIE;
1543}
1544
Devang Patel2c4ceb12009-11-21 02:48:08 +00001545
1546/// constructVariableDIE - Construct a DIE for the given DbgVariable.
Devang Patel8a241142009-12-09 18:24:21 +00001547DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
Devang Patel53bb5c92009-11-10 23:06:00 +00001548 // Get the descriptor.
1549 const DIVariable &VD = DV->getVariable();
Devang Patel65dbc902009-11-25 17:36:49 +00001550 StringRef Name = VD.getName();
1551 if (Name.empty())
Devang Patel3fb6bd62009-11-13 02:25:26 +00001552 return NULL;
Devang Patel53bb5c92009-11-10 23:06:00 +00001553
1554 // Translate tag to proper Dwarf tag. The result variable is dropped for
1555 // now.
1556 unsigned Tag;
1557 switch (VD.getTag()) {
1558 case dwarf::DW_TAG_return_variable:
1559 return NULL;
1560 case dwarf::DW_TAG_arg_variable:
1561 Tag = dwarf::DW_TAG_formal_parameter;
1562 break;
1563 case dwarf::DW_TAG_auto_variable: // fall thru
1564 default:
1565 Tag = dwarf::DW_TAG_variable;
1566 break;
1567 }
1568
1569 // Define variable debug information entry.
1570 DIE *VariableDie = new DIE(Tag);
1571
1572
1573 DIE *AbsDIE = NULL;
1574 if (DbgVariable *AV = DV->getAbstractVariable())
1575 AbsDIE = AV->getDIE();
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001576
Devang Patel53bb5c92009-11-10 23:06:00 +00001577 if (AbsDIE) {
1578 DIScope DS(Scope->getScopeNode());
Devang Patel2db49d72010-05-07 18:11:54 +00001579 DISubprogram InlinedSP = getDISubprogram(DS);
Devang Patel163a9f72010-05-10 22:49:55 +00001580 DIE *OriginSPDIE = getCompileUnit(InlinedSP)->getDIE(InlinedSP);
Daniel Dunbarc0326792009-11-11 03:09:50 +00001581 (void) OriginSPDIE;
Chris Lattnered7a77b2010-03-31 05:36:29 +00001582 assert(OriginSPDIE && "Unable to find Origin DIE for the SP!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001583 DIE *AbsDIE = DV->getAbstractVariable()->getDIE();
Chris Lattnered7a77b2010-03-31 05:36:29 +00001584 assert(AbsDIE && "Unable to find Origin DIE for the Variable!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001585 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001586 dwarf::DW_FORM_ref4, AbsDIE);
1587 }
1588 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001589 addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
1590 addSourceLine(VariableDie, &VD);
Devang Patel53bb5c92009-11-10 23:06:00 +00001591
1592 // Add variable type.
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001593 // FIXME: isBlockByrefVariable should be reformulated in terms of complex
Devang Patel53bb5c92009-11-10 23:06:00 +00001594 // addresses instead.
1595 if (VD.isBlockByrefVariable())
Devang Patel8a241142009-12-09 18:24:21 +00001596 addType(VariableDie, getBlockByrefType(VD.getType(), Name));
Devang Patel53bb5c92009-11-10 23:06:00 +00001597 else
Devang Patel8a241142009-12-09 18:24:21 +00001598 addType(VariableDie, VD.getType());
Devang Patel53bb5c92009-11-10 23:06:00 +00001599 }
1600
1601 // Add variable address.
1602 if (!Scope->isAbstractScope()) {
Devang Patel90a48ad2010-03-15 18:33:46 +00001603 // Check if variable is described by DBG_VALUE instruction.
Devang Patela43098d2010-04-28 01:03:09 +00001604 if (const MachineInstr *DVInsn = DV->getDbgValue()) {
1605 bool updated = false;
1606 // FIXME : Handle getNumOperands != 3
1607 if (DVInsn->getNumOperands() == 3) {
1608 if (DVInsn->getOperand(0).isReg())
1609 updated = addRegisterAddress(VariableDie, DV, DVInsn->getOperand(0));
1610 else if (DVInsn->getOperand(0).isImm())
1611 updated = addConstantValue(VariableDie, DV, DVInsn->getOperand(0));
1612 else if (DVInsn->getOperand(0).isFPImm())
1613 updated = addConstantFPValue(VariableDie, DV, DVInsn->getOperand(0));
Devang Patel28ff35d2010-04-28 01:39:28 +00001614 } else {
1615 MachineLocation Location = Asm->getDebugValueLocation(DVInsn);
1616 if (Location.getReg()) {
1617 addAddress(VariableDie, dwarf::DW_AT_location, Location);
1618 if (MCSymbol *VS = DV->getDbgValueLabel())
1619 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1620 VS);
1621 updated = true;
1622 }
Devang Patela43098d2010-04-28 01:03:09 +00001623 }
1624 if (!updated) {
1625 // If variableDie is not updated then DBG_VALUE instruction does not
1626 // have valid variable info.
1627 delete VariableDie;
1628 return NULL;
1629 }
1630 }
1631 else {
Devang Patel90a48ad2010-03-15 18:33:46 +00001632 MachineLocation Location;
1633 unsigned FrameReg;
Chris Lattnerd38fee82010-04-05 00:13:49 +00001634 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1635 int Offset = RI->getFrameIndexReference(*Asm->MF, DV->getFrameIndex(),
Chris Lattner1d65ba72010-03-31 06:06:37 +00001636 FrameReg);
Devang Patel90a48ad2010-03-15 18:33:46 +00001637 Location.set(FrameReg, Offset);
1638
1639 if (VD.hasComplexAddress())
1640 addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1641 else if (VD.isBlockByrefVariable())
1642 addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1643 else
1644 addAddress(VariableDie, dwarf::DW_AT_location, Location);
1645 }
Devang Patel53bb5c92009-11-10 23:06:00 +00001646 }
Devang Patelb4645642010-02-06 01:02:37 +00001647
1648 if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
1649 addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel53bb5c92009-11-10 23:06:00 +00001650 DV->setDIE(VariableDie);
1651 return VariableDie;
1652
1653}
Devang Patel2c4ceb12009-11-21 02:48:08 +00001654
Devang Patel193f7202009-11-24 01:14:22 +00001655void DwarfDebug::addPubTypes(DISubprogram SP) {
1656 DICompositeType SPTy = SP.getType();
1657 unsigned SPTag = SPTy.getTag();
1658 if (SPTag != dwarf::DW_TAG_subroutine_type)
1659 return;
1660
1661 DIArray Args = SPTy.getTypeArray();
Devang Patel193f7202009-11-24 01:14:22 +00001662 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
Devang Patel2db49d72010-05-07 18:11:54 +00001663 DIType ATy(Args.getElement(i));
Devang Patel9c004872010-05-07 21:45:47 +00001664 if (!ATy.Verify())
Devang Patel193f7202009-11-24 01:14:22 +00001665 continue;
1666 DICompositeType CATy = getDICompositeType(ATy);
Devang Patel2db49d72010-05-07 18:11:54 +00001667 if (DIDescriptor(CATy).Verify() && !CATy.getName().empty()
Devang Patel50d80e32010-04-13 20:35:04 +00001668 && !CATy.isForwardDecl()) {
Devang Patel163a9f72010-05-10 22:49:55 +00001669 CompileUnit *TheCU = getCompileUnit(CATy);
1670 if (DIEEntry *Entry = TheCU->getDIEEntry(CATy))
1671 TheCU->addGlobalType(CATy.getName(), Entry->getEntry());
Devang Patel193f7202009-11-24 01:14:22 +00001672 }
1673 }
1674}
1675
Devang Patel2c4ceb12009-11-21 02:48:08 +00001676/// constructScopeDIE - Construct a DIE for this scope.
1677DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
Devang Patel3c91b052010-03-08 20:52:55 +00001678 if (!Scope || !Scope->getScopeNode())
1679 return NULL;
1680
1681 DIScope DS(Scope->getScopeNode());
1682 DIE *ScopeDIE = NULL;
1683 if (Scope->getInlinedAt())
1684 ScopeDIE = constructInlinedScopeDIE(Scope);
1685 else if (DS.isSubprogram()) {
1686 if (Scope->isAbstractScope())
Devang Patel163a9f72010-05-10 22:49:55 +00001687 ScopeDIE = getCompileUnit(DS)->getDIE(DS);
Devang Patel3c91b052010-03-08 20:52:55 +00001688 else
Devang Patel2db49d72010-05-07 18:11:54 +00001689 ScopeDIE = updateSubprogramScopeDIE(DS);
Devang Patel3c91b052010-03-08 20:52:55 +00001690 }
Devang Patelaead63c2010-03-29 22:59:58 +00001691 else
Devang Patel3c91b052010-03-08 20:52:55 +00001692 ScopeDIE = constructLexicalScopeDIE(Scope);
Devang Patelaead63c2010-03-29 22:59:58 +00001693 if (!ScopeDIE) return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001694
Devang Patel53bb5c92009-11-10 23:06:00 +00001695 // Add variables to scope.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001696 const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
Devang Patel53bb5c92009-11-10 23:06:00 +00001697 for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
Devang Patel8a241142009-12-09 18:24:21 +00001698 DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001699 if (VariableDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001700 ScopeDIE->addChild(VariableDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001701 }
1702
1703 // Add nested scopes.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001704 const SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes();
Devang Patel53bb5c92009-11-10 23:06:00 +00001705 for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
1706 // Define the Scope debug information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001707 DIE *NestedDIE = constructScopeDIE(Scopes[j]);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001708 if (NestedDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001709 ScopeDIE->addChild(NestedDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001710 }
Devang Patel193f7202009-11-24 01:14:22 +00001711
1712 if (DS.isSubprogram())
Devang Patel2db49d72010-05-07 18:11:54 +00001713 addPubTypes(DISubprogram(DS));
Devang Patel193f7202009-11-24 01:14:22 +00001714
1715 return ScopeDIE;
Devang Patel53bb5c92009-11-10 23:06:00 +00001716}
1717
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001718/// GetOrCreateSourceID - Look up the source id with the given directory and
1719/// source file names. If none currently exists, create a new id and insert it
1720/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
1721/// maps as well.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001722unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName){
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001723 unsigned DId;
1724 StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
1725 if (DI != DirectoryIdMap.end()) {
1726 DId = DI->getValue();
1727 } else {
1728 DId = DirectoryNames.size() + 1;
1729 DirectoryIdMap[DirName] = DId;
1730 DirectoryNames.push_back(DirName);
1731 }
1732
1733 unsigned FId;
1734 StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
1735 if (FI != SourceFileIdMap.end()) {
1736 FId = FI->getValue();
1737 } else {
1738 FId = SourceFileNames.size() + 1;
1739 SourceFileIdMap[FileName] = FId;
1740 SourceFileNames.push_back(FileName);
1741 }
1742
1743 DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
1744 SourceIdMap.find(std::make_pair(DId, FId));
1745 if (SI != SourceIdMap.end())
1746 return SI->second;
1747
1748 unsigned SrcId = SourceIds.size() + 1; // DW_AT_decl_file cannot be 0.
1749 SourceIdMap[std::make_pair(DId, FId)] = SrcId;
1750 SourceIds.push_back(std::make_pair(DId, FId));
1751
1752 return SrcId;
1753}
1754
Devang Patel6404e4e2009-12-15 19:16:48 +00001755/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1756DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace NS) {
Devang Patel163a9f72010-05-10 22:49:55 +00001757 CompileUnit *TheCU = getCompileUnit(NS);
1758 DIE *NDie = TheCU->getDIE(NS);
Devang Patel6404e4e2009-12-15 19:16:48 +00001759 if (NDie)
1760 return NDie;
1761 NDie = new DIE(dwarf::DW_TAG_namespace);
Devang Patel163a9f72010-05-10 22:49:55 +00001762 TheCU->insertDIE(NS, NDie);
Devang Patel6404e4e2009-12-15 19:16:48 +00001763 if (!NS.getName().empty())
1764 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
1765 addSourceLine(NDie, &NS);
1766 addToContextOwner(NDie, NS.getContext());
1767 return NDie;
1768}
1769
Devang Patel163a9f72010-05-10 22:49:55 +00001770/// constructCompileUnit - Create new CompileUnit for the given
1771/// metadata node with tag DW_TAG_compile_unit.
Devang Patele9f8f5e2010-05-07 20:54:48 +00001772void DwarfDebug::constructCompileUnit(const MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001773 DICompileUnit DIUnit(N);
Devang Patel65dbc902009-11-25 17:36:49 +00001774 StringRef FN = DIUnit.getFilename();
1775 StringRef Dir = DIUnit.getDirectory();
Devang Patel5ccdd102009-09-29 18:40:58 +00001776 unsigned ID = GetOrCreateSourceID(Dir, FN);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001777
1778 DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001779 addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001780 DIUnit.getProducer());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001781 addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001782 DIUnit.getLanguage());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001783 addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
Devang Patel5098da02010-04-26 22:54:28 +00001784 // Use DW_AT_entry_pc instead of DW_AT_low_pc/DW_AT_high_pc pair. This
1785 // simplifies debug range entries.
1786 addUInt(Die, dwarf::DW_AT_entry_pc, dwarf::DW_FORM_data4, 0);
Devang Patel4a602ca2010-03-22 23:11:36 +00001787 // DW_AT_stmt_list is a offset of line number information for this
1788 // compile unit in debug_line section. It is always zero when only one
1789 // compile unit is emitted in one object file.
1790 addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001791
Devang Patel65dbc902009-11-25 17:36:49 +00001792 if (!Dir.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001793 addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001794 if (DIUnit.isOptimized())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001795 addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001796
Devang Patel65dbc902009-11-25 17:36:49 +00001797 StringRef Flags = DIUnit.getFlags();
1798 if (!Flags.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001799 addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001800
1801 unsigned RVer = DIUnit.getRunTimeVersion();
1802 if (RVer)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001803 addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001804 dwarf::DW_FORM_data1, RVer);
1805
Devang Patel163a9f72010-05-10 22:49:55 +00001806 CompileUnit *NewCU = new CompileUnit(ID, Die);
1807 if (!FirstCU)
1808 FirstCU = NewCU;
1809 CUMap.insert(std::make_pair(N, NewCU));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001810}
1811
Devang Patel163a9f72010-05-10 22:49:55 +00001812/// getCompielUnit - Get CompileUnit DIE.
1813CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const {
1814 assert (N && "Invalid DwarfDebug::getCompileUnit argument!");
1815 DIDescriptor D(N);
1816 const MDNode *CUNode = NULL;
1817 if (D.isCompileUnit())
1818 CUNode = N;
1819 else if (D.isSubprogram())
1820 CUNode = DISubprogram(N).getCompileUnit();
1821 else if (D.isType())
1822 CUNode = DIType(N).getCompileUnit();
1823 else if (D.isGlobalVariable())
1824 CUNode = DIGlobalVariable(N).getCompileUnit();
1825 else if (D.isVariable())
1826 CUNode = DIVariable(N).getCompileUnit();
1827 else if (D.isNameSpace())
1828 CUNode = DINameSpace(N).getCompileUnit();
1829 else if (D.isFile())
1830 CUNode = DIFile(N).getCompileUnit();
1831 else
1832 return FirstCU;
1833
1834 DenseMap<const MDNode *, CompileUnit *>::const_iterator I
1835 = CUMap.find(CUNode);
1836 if (I == CUMap.end())
1837 return FirstCU;
1838 return I->second;
1839}
1840
1841
1842/// constructGlobalVariableDIE - Construct global variable DIE.
Devang Patele9f8f5e2010-05-07 20:54:48 +00001843void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001844 DIGlobalVariable DI_GV(N);
Daniel Dunbarf612ff62009-09-19 20:40:05 +00001845
Devang Patel905cf5e2009-09-04 23:59:07 +00001846 // If debug information is malformed then ignore it.
1847 if (DI_GV.Verify() == false)
1848 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001849
1850 // Check for pre-existence.
Devang Patel163a9f72010-05-10 22:49:55 +00001851 CompileUnit *TheCU = getCompileUnit(N);
1852 if (TheCU->getDIE(DI_GV))
Devang Patel13e16b62009-06-26 01:49:18 +00001853 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001854
Devang Patel8a241142009-12-09 18:24:21 +00001855 DIE *VariableDie = createGlobalVariableDIE(DI_GV);
Devang Pateledb45632009-12-10 23:25:41 +00001856 if (!VariableDie)
1857 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001858
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001859 // Add to map.
Devang Patel163a9f72010-05-10 22:49:55 +00001860 TheCU->insertDIE(N, VariableDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001861
1862 // Add to context owner.
Devang Patelc9b16cc2010-01-15 01:12:22 +00001863 DIDescriptor GVContext = DI_GV.getContext();
1864 // Do not create specification DIE if context is either compile unit
1865 // or a subprogram.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001866 if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001867 !GVContext.isFile() &&
Devang Patel2db49d72010-05-07 18:11:54 +00001868 !isSubprogramContext(GVContext)) {
Devang Patel6404e4e2009-12-15 19:16:48 +00001869 // Create specification DIE.
1870 DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
1871 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1872 dwarf::DW_FORM_ref4, VariableDie);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001873 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001874 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001875 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001876 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001877 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Devang Patel8581e012010-02-09 01:58:33 +00001878 addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Devang Patel163a9f72010-05-10 22:49:55 +00001879 TheCU->addDie(VariableSpecDIE);
Devang Patel6404e4e2009-12-15 19:16:48 +00001880 } else {
Benjamin Kramer345ef342010-03-31 19:34:01 +00001881 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001882 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001883 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001884 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001885 addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
1886 }
Devang Patelc9b16cc2010-01-15 01:12:22 +00001887 addToContextOwner(VariableDie, GVContext);
Devang Patelc366f832009-12-10 19:14:49 +00001888
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001889 // Expose as global. FIXME - need to check external flag.
Devang Patel163a9f72010-05-10 22:49:55 +00001890 TheCU->addGlobal(DI_GV.getName(), VariableDie);
Devang Patel193f7202009-11-24 01:14:22 +00001891
1892 DIType GTy = DI_GV.getType();
Devang Patel50d80e32010-04-13 20:35:04 +00001893 if (GTy.isCompositeType() && !GTy.getName().empty()
1894 && !GTy.isForwardDecl()) {
Devang Patel163a9f72010-05-10 22:49:55 +00001895 DIEEntry *Entry = TheCU->getDIEEntry(GTy);
Chris Lattnered7a77b2010-03-31 05:36:29 +00001896 assert(Entry && "Missing global type!");
Devang Patel163a9f72010-05-10 22:49:55 +00001897 TheCU->addGlobalType(GTy.getName(), Entry->getEntry());
Devang Patel193f7202009-11-24 01:14:22 +00001898 }
Devang Patel13e16b62009-06-26 01:49:18 +00001899 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001900}
1901
Devang Patel163a9f72010-05-10 22:49:55 +00001902/// construct SubprogramDIE - Construct subprogram DIE.
Devang Patele9f8f5e2010-05-07 20:54:48 +00001903void DwarfDebug::constructSubprogramDIE(const MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001904 DISubprogram SP(N);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001905
Stuart Hastings639336e2010-04-06 21:38:29 +00001906 // Check for pre-existence.
Devang Patel163a9f72010-05-10 22:49:55 +00001907 CompileUnit *TheCU = getCompileUnit(N);
1908 if (TheCU->getDIE(N))
Stuart Hastings639336e2010-04-06 21:38:29 +00001909 return;
1910
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001911 if (!SP.isDefinition())
1912 // This is a method declaration which will be handled while constructing
1913 // class type.
Devang Patel13e16b62009-06-26 01:49:18 +00001914 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001915
Stuart Hastings639336e2010-04-06 21:38:29 +00001916 DIE *SubprogramDie = createSubprogramDIE(SP);
1917
1918 // Add to map.
Devang Patel163a9f72010-05-10 22:49:55 +00001919 TheCU->insertDIE(N, SubprogramDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001920
1921 // Add to context owner.
Devang Patel6404e4e2009-12-15 19:16:48 +00001922 addToContextOwner(SubprogramDie, SP.getContext());
Devang Patel0000fad2009-12-08 23:21:45 +00001923
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001924 // Expose as global.
Devang Patel163a9f72010-05-10 22:49:55 +00001925 TheCU->addGlobal(SP.getName(), SubprogramDie);
Devang Patel193f7202009-11-24 01:14:22 +00001926
Devang Patel13e16b62009-06-26 01:49:18 +00001927 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001928}
1929
Devang Patel2c4ceb12009-11-21 02:48:08 +00001930/// beginModule - Emit all Dwarf sections that should come prior to the
Daniel Dunbar00564992009-09-19 20:40:14 +00001931/// content. Create global DIEs and emit initial debug info sections.
1932/// This is inovked by the target AsmPrinter.
Chris Lattner75f50722010-04-04 07:48:20 +00001933void DwarfDebug::beginModule(Module *M) {
Devang Pateleac9c072010-04-27 19:46:33 +00001934 if (DisableDebugInfoPrinting)
1935 return;
1936
Devang Patel78ab9e22009-07-30 18:56:46 +00001937 DebugInfoFinder DbgFinder;
1938 DbgFinder.processModule(*M);
Devang Patel13e16b62009-06-26 01:49:18 +00001939
Chris Lattnerd850ac72010-04-05 02:19:28 +00001940 bool HasDebugInfo = false;
1941
1942 // Scan all the compile-units to see if there are any marked as the main unit.
1943 // if not, we do not generate debug info.
1944 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1945 E = DbgFinder.compile_unit_end(); I != E; ++I) {
1946 if (DICompileUnit(*I).isMain()) {
1947 HasDebugInfo = true;
1948 break;
1949 }
1950 }
1951
1952 if (!HasDebugInfo) return;
1953
1954 // Tell MMI that we have debug info.
1955 MMI->setDebugInfoAvailability(true);
1956
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001957 // Emit initial sections.
Chris Lattnerd850ac72010-04-05 02:19:28 +00001958 EmitSectionLabels();
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001959
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001960 // Create all the compile unit DIEs.
Devang Patel78ab9e22009-07-30 18:56:46 +00001961 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1962 E = DbgFinder.compile_unit_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001963 constructCompileUnit(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001964
Devang Patel53bb5c92009-11-10 23:06:00 +00001965 // Create DIEs for each subprogram.
Devang Patel78ab9e22009-07-30 18:56:46 +00001966 for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
1967 E = DbgFinder.subprogram_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001968 constructSubprogramDIE(*I);
Devang Patel13e16b62009-06-26 01:49:18 +00001969
Devang Patelc366f832009-12-10 19:14:49 +00001970 // Create DIEs for each global variable.
1971 for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
1972 E = DbgFinder.global_variable_end(); I != E; ++I)
1973 constructGlobalVariableDIE(*I);
1974
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001975 // Prime section data.
Chris Lattnerf0144122009-07-28 03:13:23 +00001976 SectionMap.insert(Asm->getObjFileLowering().getTextSection());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001977
1978 // Print out .file directives to specify files for .loc directives. These are
1979 // printed out early so that they precede any .loc directives.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001980 if (Asm->MAI->hasDotLocAndDotFile()) {
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001981 for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
1982 // Remember source id starts at 1.
1983 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
Chris Lattner0ad9c912010-01-22 22:09:00 +00001984 // FIXME: don't use sys::path for this! This should not depend on the
1985 // host.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001986 sys::Path FullPath(getSourceDirectoryName(Id.first));
1987 bool AppendOk =
1988 FullPath.appendComponent(getSourceFileName(Id.second));
1989 assert(AppendOk && "Could not append filename to directory!");
1990 AppendOk = false;
Chris Lattnera6594fc2010-01-25 18:58:59 +00001991 Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001992 }
1993 }
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001994}
1995
Devang Patel2c4ceb12009-11-21 02:48:08 +00001996/// endModule - Emit all Dwarf sections that should come after the content.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001997///
Devang Patel2c4ceb12009-11-21 02:48:08 +00001998void DwarfDebug::endModule() {
Devang Patel163a9f72010-05-10 22:49:55 +00001999 if (!FirstCU) return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002000
Devang Patel53bb5c92009-11-10 23:06:00 +00002001 // Attach DW_AT_inline attribute with inlined subprogram DIEs.
2002 for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
2003 AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) {
2004 DIE *ISP = *AI;
Devang Patel2c4ceb12009-11-21 02:48:08 +00002005 addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
Devang Patel53bb5c92009-11-10 23:06:00 +00002006 }
2007
Devang Patele9f8f5e2010-05-07 20:54:48 +00002008 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
Devang Patel5d11eb02009-12-03 19:11:07 +00002009 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
2010 DIE *SPDie = CI->first;
Devang Patele9f8f5e2010-05-07 20:54:48 +00002011 const MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
Devang Patel5d11eb02009-12-03 19:11:07 +00002012 if (!N) continue;
Devang Patel163a9f72010-05-10 22:49:55 +00002013 DIE *NDie = getCompileUnit(N)->getDIE(N);
Devang Patel5d11eb02009-12-03 19:11:07 +00002014 if (!NDie) continue;
2015 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
Devang Patel5d11eb02009-12-03 19:11:07 +00002016 }
2017
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002018 // Standard sections final addresses.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002019 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00002020 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002021 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00002022 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002023
2024 // End text sections.
2025 for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002026 Asm->OutStreamer.SwitchSection(SectionMap[i]);
Chris Lattnerc0215722010-04-04 19:25:43 +00002027 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", i));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002028 }
2029
2030 // Emit common frame information.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002031 emitCommonDebugFrame();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002032
2033 // Emit function debug frame information
2034 for (std::vector<FunctionDebugFrameInfo>::iterator I = DebugFrames.begin(),
2035 E = DebugFrames.end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002036 emitFunctionDebugFrame(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002037
2038 // Compute DIE offsets and sizes.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002039 computeSizeAndOffsets();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002040
2041 // Emit all the DIEs into a debug info section
Devang Patel2c4ceb12009-11-21 02:48:08 +00002042 emitDebugInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002043
2044 // Corresponding abbreviations into a abbrev section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002045 emitAbbreviations();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002046
2047 // Emit source line correspondence into a debug line section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002048 emitDebugLines();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002049
2050 // Emit info into a debug pubnames section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002051 emitDebugPubNames();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002052
Devang Patel193f7202009-11-24 01:14:22 +00002053 // Emit info into a debug pubtypes section.
2054 emitDebugPubTypes();
2055
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002056 // Emit info into a debug loc section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002057 emitDebugLoc();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002058
2059 // Emit info into a debug aranges section.
2060 EmitDebugARanges();
2061
2062 // Emit info into a debug ranges section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002063 emitDebugRanges();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002064
2065 // Emit info into a debug macinfo section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002066 emitDebugMacInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002067
2068 // Emit inline info.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002069 emitDebugInlineInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002070
Chris Lattnerbc733f52010-03-13 02:17:42 +00002071 // Emit info into a debug str section.
2072 emitDebugStr();
2073
Devang Patel163a9f72010-05-10 22:49:55 +00002074 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
2075 E = CUMap.end(); I != E; ++I)
2076 delete I->second;
2077 FirstCU = NULL; // Reset for the next Module, if any.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002078}
2079
Devang Patel53bb5c92009-11-10 23:06:00 +00002080/// findAbstractVariable - Find abstract variable, if any, associated with Var.
Jim Grosbach7ab38df2009-11-22 19:20:36 +00002081DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
2082 unsigned FrameIdx,
Chris Lattnerde4845c2010-04-02 19:42:39 +00002083 DebugLoc ScopeLoc) {
Devang Patel53bb5c92009-11-10 23:06:00 +00002084
Devang Patel2db49d72010-05-07 18:11:54 +00002085 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var);
Devang Patel53bb5c92009-11-10 23:06:00 +00002086 if (AbsDbgVariable)
2087 return AbsDbgVariable;
2088
Devang Patel2db49d72010-05-07 18:11:54 +00002089 LLVMContext &Ctx = Var->getContext();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002090 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel53bb5c92009-11-10 23:06:00 +00002091 if (!Scope)
2092 return NULL;
2093
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002094 AbsDbgVariable = new DbgVariable(Var, FrameIdx,
2095 NULL /* No more-abstract variable*/);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002096 Scope->addVariable(AbsDbgVariable);
Devang Patel2db49d72010-05-07 18:11:54 +00002097 AbstractVariables[Var] = AbsDbgVariable;
Devang Patel53bb5c92009-11-10 23:06:00 +00002098 return AbsDbgVariable;
2099}
2100
Devang Patel90a48ad2010-03-15 18:33:46 +00002101/// findAbstractVariable - Find abstract variable, if any, associated with Var.
2102/// FIXME : Refactor findAbstractVariable.
2103DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
2104 const MachineInstr *MI,
Chris Lattnerde4845c2010-04-02 19:42:39 +00002105 DebugLoc ScopeLoc) {
Devang Patel90a48ad2010-03-15 18:33:46 +00002106
Devang Patel2db49d72010-05-07 18:11:54 +00002107 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var);
Devang Patel90a48ad2010-03-15 18:33:46 +00002108 if (AbsDbgVariable)
2109 return AbsDbgVariable;
2110
Devang Patel2db49d72010-05-07 18:11:54 +00002111 LLVMContext &Ctx = Var->getContext();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002112 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel90a48ad2010-03-15 18:33:46 +00002113 if (!Scope)
2114 return NULL;
2115
Devang Patelaead63c2010-03-29 22:59:58 +00002116 AbsDbgVariable = new DbgVariable(Var, MI,
Devang Patel90a48ad2010-03-15 18:33:46 +00002117 NULL /* No more-abstract variable*/);
2118 Scope->addVariable(AbsDbgVariable);
Devang Patel2db49d72010-05-07 18:11:54 +00002119 AbstractVariables[Var] = AbsDbgVariable;
Devang Patelaead63c2010-03-29 22:59:58 +00002120 DbgValueStartMap[MI] = AbsDbgVariable;
Devang Patel90a48ad2010-03-15 18:33:46 +00002121 return AbsDbgVariable;
2122}
2123
Devang Patel2c4ceb12009-11-21 02:48:08 +00002124/// collectVariableInfo - Populate DbgScope entries with variables' info.
2125void DwarfDebug::collectVariableInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00002126 const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002127
Devang Patele717faa2009-10-06 01:26:37 +00002128 MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
2129 for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
2130 VE = VMap.end(); VI != VE; ++VI) {
Devang Patele9f8f5e2010-05-07 20:54:48 +00002131 const MDNode *Var = VI->first;
Devang Patel53bb5c92009-11-10 23:06:00 +00002132 if (!Var) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002133 DIVariable DV(Var);
2134 const std::pair<unsigned, DebugLoc> &VP = VI->second;
Devang Patel53bb5c92009-11-10 23:06:00 +00002135
Chris Lattnerde4845c2010-04-02 19:42:39 +00002136 DbgScope *Scope = 0;
Devang Patele9f8f5e2010-05-07 20:54:48 +00002137 if (const MDNode *IA = VP.second.getInlinedAt(Ctx))
Chris Lattnerde4845c2010-04-02 19:42:39 +00002138 Scope = ConcreteScopes.lookup(IA);
2139 if (Scope == 0)
2140 Scope = DbgScopeMap.lookup(VP.second.getScope(Ctx));
2141
Devang Patelfb0ee432009-11-10 23:20:04 +00002142 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002143 if (Scope == 0)
Devang Patelfb0ee432009-11-10 23:20:04 +00002144 continue;
Devang Patel53bb5c92009-11-10 23:06:00 +00002145
Chris Lattnerde4845c2010-04-02 19:42:39 +00002146 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, VP.second);
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002147 DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002148 Scope->addVariable(RegVar);
Devang Patele717faa2009-10-06 01:26:37 +00002149 }
Devang Patel90a48ad2010-03-15 18:33:46 +00002150
2151 // Collect variable information from DBG_VALUE machine instructions;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002152 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patel90a48ad2010-03-15 18:33:46 +00002153 I != E; ++I) {
2154 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2155 II != IE; ++II) {
2156 const MachineInstr *MInsn = II;
Chris Lattner14d750d2010-03-31 05:39:57 +00002157 if (!MInsn->isDebugValue())
Devang Patel90a48ad2010-03-15 18:33:46 +00002158 continue;
Devang Patelaead63c2010-03-29 22:59:58 +00002159
Devang Patel0f9d9522010-04-27 20:54:45 +00002160 // Ignore Undef values.
Devang Patel97303ee2010-04-27 22:04:41 +00002161 if (MInsn->getOperand(0).isReg() && !MInsn->getOperand(0).getReg())
Devang Patel0f9d9522010-04-27 20:54:45 +00002162 continue;
2163
Dan Gohman82d5eaf2010-04-17 16:43:55 +00002164 DIVariable DV(
Devang Patele9f8f5e2010-05-07 20:54:48 +00002165 const_cast<const MDNode *>(MInsn->getOperand(MInsn->getNumOperands() - 1)
Dan Gohman82d5eaf2010-04-17 16:43:55 +00002166 .getMetadata()));
Devang Patel90a48ad2010-03-15 18:33:46 +00002167 if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
2168 // FIXME Handle inlined subroutine arguments.
2169 DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
2170 CurrentFnDbgScope->addVariable(ArgVar);
Devang Patelaead63c2010-03-29 22:59:58 +00002171 DbgValueStartMap[MInsn] = ArgVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002172 continue;
2173 }
2174
2175 DebugLoc DL = MInsn->getDebugLoc();
2176 if (DL.isUnknown()) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002177 DbgScope *Scope = 0;
Devang Patele9f8f5e2010-05-07 20:54:48 +00002178 if (const MDNode *IA = DL.getInlinedAt(Ctx))
Chris Lattnerde4845c2010-04-02 19:42:39 +00002179 Scope = ConcreteScopes.lookup(IA);
2180 if (Scope == 0)
2181 Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
2182
Devang Patel90a48ad2010-03-15 18:33:46 +00002183 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002184 if (Scope == 0)
Devang Patel90a48ad2010-03-15 18:33:46 +00002185 continue;
2186
Chris Lattnerde4845c2010-04-02 19:42:39 +00002187 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, DL);
Devang Patel90a48ad2010-03-15 18:33:46 +00002188 DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
Devang Patelaead63c2010-03-29 22:59:58 +00002189 DbgValueStartMap[MInsn] = RegVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002190 Scope->addVariable(RegVar);
2191 }
2192 }
Devang Patele717faa2009-10-06 01:26:37 +00002193}
2194
Devang Patel553881b2010-03-29 17:20:31 +00002195/// beginScope - Process beginning of a scope.
2196void DwarfDebug::beginScope(const MachineInstr *MI) {
Devang Patel553881b2010-03-29 17:20:31 +00002197 // Check location.
2198 DebugLoc DL = MI->getDebugLoc();
Dan Gohman1cc0d622010-05-05 23:41:32 +00002199 if (DL.isUnknown()) {
Dan Gohman281d65d2010-05-07 01:08:53 +00002200 if (UnknownLocations) {
2201 // This instruction has no debug location. If the preceding instruction
2202 // did, emit debug location information to indicate that the debug
2203 // location is now unknown.
2204 MCSymbol *Label = NULL;
2205 if (DL == PrevInstLoc)
2206 Label = PrevLabel;
2207 else {
2208 Label = recordSourceLine(DL.getLine(), DL.getCol(), 0);
2209 PrevInstLoc = DL;
2210 PrevLabel = Label;
2211 }
Dan Gohman75395842010-05-06 00:29:41 +00002212
Dan Gohman281d65d2010-05-07 01:08:53 +00002213 // If this instruction begins a scope then note down corresponding label.
2214 if (InsnsBeginScopeSet.count(MI) != 0)
2215 LabelsBeforeInsn[MI] = Label;
2216 }
Dan Gohman75395842010-05-06 00:29:41 +00002217
Devang Patel553881b2010-03-29 17:20:31 +00002218 return;
Dan Gohman1cc0d622010-05-05 23:41:32 +00002219 }
Devang Patel553881b2010-03-29 17:20:31 +00002220
Devang Patele9f8f5e2010-05-07 20:54:48 +00002221 const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
Chris Lattnerde4845c2010-04-02 19:42:39 +00002222
2223 // FIXME: Should only verify each scope once!
2224 if (!DIScope(Scope).Verify())
Devang Patel553881b2010-03-29 17:20:31 +00002225 return;
Devang Patel553881b2010-03-29 17:20:31 +00002226
Devang Patelaead63c2010-03-29 22:59:58 +00002227 // DBG_VALUE instruction establishes new value.
Chris Lattner14d750d2010-03-31 05:39:57 +00002228 if (MI->isDebugValue()) {
Devang Patelaead63c2010-03-29 22:59:58 +00002229 DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
2230 = DbgValueStartMap.find(MI);
2231 if (DI != DbgValueStartMap.end()) {
Devang Pateleac9c072010-04-27 19:46:33 +00002232 MCSymbol *Label = NULL;
2233 if (DL == PrevInstLoc)
2234 Label = PrevLabel;
2235 else {
2236 Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2237 PrevInstLoc = DL;
2238 PrevLabel = Label;
2239 }
Devang Patelaead63c2010-03-29 22:59:58 +00002240 DI->second->setDbgValueLabel(Label);
2241 }
Devang Patel7ed63112010-03-30 18:07:00 +00002242 return;
Devang Patelaead63c2010-03-29 22:59:58 +00002243 }
2244
Devang Patel553881b2010-03-29 17:20:31 +00002245 // Emit a label to indicate location change. This is used for line
Devang Pateleac9c072010-04-27 19:46:33 +00002246 // table even if this instruction does not start a new scope.
2247 MCSymbol *Label = NULL;
2248 if (DL == PrevInstLoc)
2249 Label = PrevLabel;
2250 else {
2251 Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2252 PrevInstLoc = DL;
2253 PrevLabel = Label;
2254 }
Devang Patel553881b2010-03-29 17:20:31 +00002255
Devang Patel1c246352010-04-08 16:50:29 +00002256 // If this instruction begins a scope then note down corresponding label.
2257 if (InsnsBeginScopeSet.count(MI) != 0)
Devang Pateleac9c072010-04-27 19:46:33 +00002258 LabelsBeforeInsn[MI] = Label;
Devang Patel0d20ac82009-10-06 01:50:42 +00002259}
2260
Devang Patel2c4ceb12009-11-21 02:48:08 +00002261/// endScope - Process end of a scope.
2262void DwarfDebug::endScope(const MachineInstr *MI) {
Devang Patel1c246352010-04-08 16:50:29 +00002263 if (InsnsEndScopeSet.count(MI) != 0) {
2264 // Emit a label if this instruction ends a scope.
2265 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
2266 Asm->OutStreamer.EmitLabel(Label);
Devang Pateleac9c072010-04-27 19:46:33 +00002267 LabelsAfterInsn[MI] = Label;
Devang Patel1c246352010-04-08 16:50:29 +00002268 }
Devang Patel53bb5c92009-11-10 23:06:00 +00002269}
2270
Devang Pateleac9c072010-04-27 19:46:33 +00002271/// getOrCreateDbgScope - Create DbgScope for the scope.
Devang Patele9f8f5e2010-05-07 20:54:48 +00002272DbgScope *DwarfDebug::getOrCreateDbgScope(const MDNode *Scope, const MDNode *InlinedAt) {
Devang Patel53bb5c92009-11-10 23:06:00 +00002273 if (!InlinedAt) {
2274 DbgScope *WScope = DbgScopeMap.lookup(Scope);
2275 if (WScope)
Devang Pateleac9c072010-04-27 19:46:33 +00002276 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002277 WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL);
2278 DbgScopeMap.insert(std::make_pair(Scope, WScope));
Devang Pateleac9c072010-04-27 19:46:33 +00002279 if (DIDescriptor(Scope).isLexicalBlock()) {
2280 DbgScope *Parent =
Devang Patel2db49d72010-05-07 18:11:54 +00002281 getOrCreateDbgScope(DILexicalBlock(Scope).getContext(), NULL);
Devang Pateleac9c072010-04-27 19:46:33 +00002282 WScope->setParent(Parent);
2283 Parent->addScope(WScope);
2284 }
2285
2286 if (!WScope->getParent()) {
2287 StringRef SPName = DISubprogram(Scope).getLinkageName();
2288 if (SPName == Asm->MF->getFunction()->getName())
2289 CurrentFnDbgScope = WScope;
2290 }
2291
2292 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002293 }
2294
2295 DbgScope *WScope = DbgScopeMap.lookup(InlinedAt);
2296 if (WScope)
Devang Pateleac9c072010-04-27 19:46:33 +00002297 return WScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00002298
2299 WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt);
2300 DbgScopeMap.insert(std::make_pair(InlinedAt, WScope));
2301 DILocation DL(InlinedAt);
Devang Pateleac9c072010-04-27 19:46:33 +00002302 DbgScope *Parent =
Devang Patel2db49d72010-05-07 18:11:54 +00002303 getOrCreateDbgScope(DL.getScope(), DL.getOrigLocation());
Devang Pateleac9c072010-04-27 19:46:33 +00002304 WScope->setParent(Parent);
2305 Parent->addScope(WScope);
2306
2307 ConcreteScopes[InlinedAt] = WScope;
2308 getOrCreateAbstractScope(Scope);
2309
2310 return WScope;
Devang Patel0d20ac82009-10-06 01:50:42 +00002311}
2312
Devang Pateleac9c072010-04-27 19:46:33 +00002313/// hasValidLocation - Return true if debug location entry attached with
2314/// machine instruction encodes valid location info.
2315static bool hasValidLocation(LLVMContext &Ctx,
2316 const MachineInstr *MInsn,
Devang Patele9f8f5e2010-05-07 20:54:48 +00002317 const MDNode *&Scope, const MDNode *&InlinedAt) {
Devang Pateleac9c072010-04-27 19:46:33 +00002318 if (MInsn->isDebugValue())
2319 return false;
2320 DebugLoc DL = MInsn->getDebugLoc();
2321 if (DL.isUnknown()) return false;
2322
Devang Patele9f8f5e2010-05-07 20:54:48 +00002323 const MDNode *S = DL.getScope(Ctx);
Devang Pateleac9c072010-04-27 19:46:33 +00002324
2325 // There is no need to create another DIE for compile unit. For all
2326 // other scopes, create one DbgScope now. This will be translated
2327 // into a scope DIE at the end.
2328 if (DIScope(S).isCompileUnit()) return false;
2329
2330 Scope = S;
2331 InlinedAt = DL.getInlinedAt(Ctx);
2332 return true;
2333}
2334
2335/// calculateDominanceGraph - Calculate dominance graph for DbgScope
2336/// hierarchy.
2337static void calculateDominanceGraph(DbgScope *Scope) {
2338 assert (Scope && "Unable to calculate scop edominance graph!");
2339 SmallVector<DbgScope *, 4> WorkStack;
2340 WorkStack.push_back(Scope);
2341 unsigned Counter = 0;
2342 while (!WorkStack.empty()) {
2343 DbgScope *WS = WorkStack.back();
2344 const SmallVector<DbgScope *, 4> &Children = WS->getScopes();
2345 bool visitedChildren = false;
2346 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
2347 SE = Children.end(); SI != SE; ++SI) {
2348 DbgScope *ChildScope = *SI;
2349 if (!ChildScope->getDFSOut()) {
2350 WorkStack.push_back(ChildScope);
2351 visitedChildren = true;
2352 ChildScope->setDFSIn(++Counter);
2353 break;
2354 }
2355 }
2356 if (!visitedChildren) {
2357 WorkStack.pop_back();
2358 WS->setDFSOut(++Counter);
2359 }
2360 }
2361}
2362
2363/// printDbgScopeInfo - Print DbgScope info for each machine instruction.
2364static
2365void printDbgScopeInfo(LLVMContext &Ctx, const MachineFunction *MF,
2366 DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap)
2367{
2368#ifndef NDEBUG
2369 unsigned PrevDFSIn = 0;
2370 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2371 I != E; ++I) {
2372 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2373 II != IE; ++II) {
2374 const MachineInstr *MInsn = II;
Devang Patele9f8f5e2010-05-07 20:54:48 +00002375 const MDNode *Scope = NULL;
2376 const MDNode *InlinedAt = NULL;
Devang Pateleac9c072010-04-27 19:46:33 +00002377
2378 // Check if instruction has valid location information.
2379 if (hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2380 dbgs() << " [ ";
2381 if (InlinedAt)
2382 dbgs() << "*";
2383 DenseMap<const MachineInstr *, DbgScope *>::iterator DI =
2384 MI2ScopeMap.find(MInsn);
2385 if (DI != MI2ScopeMap.end()) {
2386 DbgScope *S = DI->second;
2387 dbgs() << S->getDFSIn();
2388 PrevDFSIn = S->getDFSIn();
2389 } else
2390 dbgs() << PrevDFSIn;
2391 } else
2392 dbgs() << " [ x" << PrevDFSIn;
2393 dbgs() << " ]";
2394 MInsn->dump();
2395 }
2396 dbgs() << "\n";
2397 }
2398#endif
2399}
Devang Patel2c4ceb12009-11-21 02:48:08 +00002400/// extractScopeInformation - Scan machine instructions in this function
Chris Lattner14d750d2010-03-31 05:39:57 +00002401/// and collect DbgScopes. Return true, if at least one scope was found.
Chris Lattnereec791a2010-01-26 23:18:02 +00002402bool DwarfDebug::extractScopeInformation() {
Devang Patelaf9e8472009-10-01 20:31:14 +00002403 // If scope information was extracted using .dbg intrinsics then there is not
2404 // any need to extract these information by scanning each instruction.
2405 if (!DbgScopeMap.empty())
2406 return false;
2407
Dan Gohman314bf7c2010-04-23 01:18:53 +00002408 // Scan each instruction and create scopes. First build working set of scopes.
Devang Pateleac9c072010-04-27 19:46:33 +00002409 LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
2410 SmallVector<DbgRange, 4> MIRanges;
2411 DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap;
Devang Patele9f8f5e2010-05-07 20:54:48 +00002412 const MDNode *PrevScope = NULL;
2413 const MDNode *PrevInlinedAt = NULL;
Devang Pateleac9c072010-04-27 19:46:33 +00002414 const MachineInstr *RangeBeginMI = NULL;
2415 const MachineInstr *PrevMI = NULL;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002416 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patelaf9e8472009-10-01 20:31:14 +00002417 I != E; ++I) {
2418 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2419 II != IE; ++II) {
2420 const MachineInstr *MInsn = II;
Devang Patele9f8f5e2010-05-07 20:54:48 +00002421 const MDNode *Scope = NULL;
2422 const MDNode *InlinedAt = NULL;
Devang Pateleac9c072010-04-27 19:46:33 +00002423
2424 // Check if instruction has valid location information.
2425 if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2426 PrevMI = MInsn;
2427 continue;
2428 }
Chris Lattnerde4845c2010-04-02 19:42:39 +00002429
Devang Pateleac9c072010-04-27 19:46:33 +00002430 // If scope has not changed then skip this instruction.
2431 if (Scope == PrevScope && PrevInlinedAt == InlinedAt) {
2432 PrevMI = MInsn;
2433 continue;
2434 }
2435
2436 if (RangeBeginMI) {
2437 // If we have alread seen a beginning of a instruction range and
2438 // current instruction scope does not match scope of first instruction
2439 // in this range then create a new instruction range.
2440 DbgRange R(RangeBeginMI, PrevMI);
2441 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
2442 MIRanges.push_back(R);
2443 }
2444
2445 // This is a beginning of a new instruction range.
2446 RangeBeginMI = MInsn;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002447
Devang Pateleac9c072010-04-27 19:46:33 +00002448 // Reset previous markers.
2449 PrevMI = MInsn;
2450 PrevScope = Scope;
2451 PrevInlinedAt = InlinedAt;
Devang Patel53bb5c92009-11-10 23:06:00 +00002452 }
2453 }
2454
Devang Pateleac9c072010-04-27 19:46:33 +00002455 // Create last instruction range.
2456 if (RangeBeginMI && PrevMI && PrevScope) {
2457 DbgRange R(RangeBeginMI, PrevMI);
2458 MIRanges.push_back(R);
2459 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
Devang Patelaf9e8472009-10-01 20:31:14 +00002460 }
Devang Pateleac9c072010-04-27 19:46:33 +00002461
Devang Patel344130e2010-01-04 20:44:00 +00002462 if (!CurrentFnDbgScope)
2463 return false;
2464
Devang Pateleac9c072010-04-27 19:46:33 +00002465 calculateDominanceGraph(CurrentFnDbgScope);
2466 if (PrintDbgScope)
2467 printDbgScopeInfo(Ctx, Asm->MF, MI2ScopeMap);
2468
2469 // Find ranges of instructions covered by each DbgScope;
2470 DbgScope *PrevDbgScope = NULL;
2471 for (SmallVector<DbgRange, 4>::const_iterator RI = MIRanges.begin(),
2472 RE = MIRanges.end(); RI != RE; ++RI) {
2473 const DbgRange &R = *RI;
2474 DbgScope *S = MI2ScopeMap.lookup(R.first);
2475 assert (S && "Lost DbgScope for a machine instruction!");
2476 if (PrevDbgScope && !PrevDbgScope->dominates(S))
2477 PrevDbgScope->closeInsnRange(S);
2478 S->openInsnRange(R.first);
2479 S->extendInsnRange(R.second);
2480 PrevDbgScope = S;
2481 }
2482
2483 if (PrevDbgScope)
2484 PrevDbgScope->closeInsnRange();
Devang Patelaf9e8472009-10-01 20:31:14 +00002485
Devang Patele37b0c62010-04-08 18:43:56 +00002486 identifyScopeMarkers();
Devang Patel6122a4d2010-04-08 15:37:09 +00002487
2488 return !DbgScopeMap.empty();
2489}
2490
Devang Pateleac9c072010-04-27 19:46:33 +00002491/// identifyScopeMarkers() -
2492/// Each DbgScope has first instruction and last instruction to mark beginning
2493/// and end of a scope respectively. Create an inverse map that list scopes
2494/// starts (and ends) with an instruction. One instruction may start (or end)
2495/// multiple scopes. Ignore scopes that are not reachable.
Devang Patele37b0c62010-04-08 18:43:56 +00002496void DwarfDebug::identifyScopeMarkers() {
Devang Patel42aafd72010-01-20 02:05:23 +00002497 SmallVector<DbgScope *, 4> WorkList;
2498 WorkList.push_back(CurrentFnDbgScope);
2499 while (!WorkList.empty()) {
Chris Lattner14d750d2010-03-31 05:39:57 +00002500 DbgScope *S = WorkList.pop_back_val();
Devang Pateleac9c072010-04-27 19:46:33 +00002501
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002502 const SmallVector<DbgScope *, 4> &Children = S->getScopes();
Devang Patel42aafd72010-01-20 02:05:23 +00002503 if (!Children.empty())
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002504 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
Devang Patel42aafd72010-01-20 02:05:23 +00002505 SE = Children.end(); SI != SE; ++SI)
2506 WorkList.push_back(*SI);
2507
Devang Patel53bb5c92009-11-10 23:06:00 +00002508 if (S->isAbstractScope())
2509 continue;
Devang Pateleac9c072010-04-27 19:46:33 +00002510
2511 const SmallVector<DbgRange, 4> &Ranges = S->getRanges();
2512 if (Ranges.empty())
2513 continue;
2514 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
2515 RE = Ranges.end(); RI != RE; ++RI) {
2516 assert(RI->first && "DbgRange does not have first instruction!");
2517 assert(RI->second && "DbgRange does not have second instruction!");
2518 InsnsBeginScopeSet.insert(RI->first);
2519 InsnsEndScopeSet.insert(RI->second);
2520 }
Devang Patelaf9e8472009-10-01 20:31:14 +00002521 }
Devang Patelaf9e8472009-10-01 20:31:14 +00002522}
2523
Dan Gohman084751c2010-04-20 00:37:27 +00002524/// FindFirstDebugLoc - Find the first debug location in the function. This
2525/// is intended to be an approximation for the source position of the
2526/// beginning of the function.
2527static DebugLoc FindFirstDebugLoc(const MachineFunction *MF) {
2528 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2529 I != E; ++I)
2530 for (MachineBasicBlock::const_iterator MBBI = I->begin(), MBBE = I->end();
2531 MBBI != MBBE; ++MBBI) {
2532 DebugLoc DL = MBBI->getDebugLoc();
2533 if (!DL.isUnknown())
2534 return DL;
2535 }
2536 return DebugLoc();
2537}
2538
Devang Patel2c4ceb12009-11-21 02:48:08 +00002539/// beginFunction - Gather pre-function debug information. Assumes being
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002540/// emitted immediately after the function entry point.
Chris Lattnereec791a2010-01-26 23:18:02 +00002541void DwarfDebug::beginFunction(const MachineFunction *MF) {
Chris Lattner994cb122010-04-05 03:52:55 +00002542 if (!MMI->hasDebugInfo()) return;
Bill Wendling5f017e82010-04-07 09:28:04 +00002543 if (!extractScopeInformation()) return;
Chris Lattnera909d662010-03-29 20:38:20 +00002544
Devang Patel2c4ceb12009-11-21 02:48:08 +00002545 collectVariableInfo();
Devang Patel60b35bd2009-10-06 18:37:31 +00002546
Devang Pateleac9c072010-04-27 19:46:33 +00002547 FunctionBeginSym = Asm->GetTempSymbol("func_begin",
2548 Asm->getFunctionNumber());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002549 // Assumes in correct section after the entry point.
Devang Pateleac9c072010-04-27 19:46:33 +00002550 Asm->OutStreamer.EmitLabel(FunctionBeginSym);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002551
2552 // Emit label for the implicitly defined dbg.stoppoint at the start of the
2553 // function.
Dan Gohman084751c2010-04-20 00:37:27 +00002554 DebugLoc FDL = FindFirstDebugLoc(MF);
Chris Lattnerde4845c2010-04-02 19:42:39 +00002555 if (FDL.isUnknown()) return;
2556
Devang Patele9f8f5e2010-05-07 20:54:48 +00002557 const MDNode *Scope = FDL.getScope(MF->getFunction()->getContext());
Chris Lattnerde4845c2010-04-02 19:42:39 +00002558
2559 DISubprogram SP = getDISubprogram(Scope);
2560 unsigned Line, Col;
2561 if (SP.Verify()) {
2562 Line = SP.getLineNumber();
2563 Col = 0;
2564 } else {
2565 Line = FDL.getLine();
2566 Col = FDL.getCol();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002567 }
Chris Lattnerde4845c2010-04-02 19:42:39 +00002568
2569 recordSourceLine(Line, Col, Scope);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002570}
2571
Devang Patel2c4ceb12009-11-21 02:48:08 +00002572/// endFunction - Gather and emit post-function debug information.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002573///
Chris Lattnereec791a2010-01-26 23:18:02 +00002574void DwarfDebug::endFunction(const MachineFunction *MF) {
Bill Wendling5f017e82010-04-07 09:28:04 +00002575 if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return;
Devang Patel70d75ca2009-11-12 19:02:56 +00002576
Devang Patel344130e2010-01-04 20:44:00 +00002577 if (CurrentFnDbgScope) {
2578 // Define end label for subprogram.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002579 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
2580 Asm->getFunctionNumber()));
Devang Patel344130e2010-01-04 20:44:00 +00002581
2582 // Get function line info.
2583 if (!Lines.empty()) {
2584 // Get section line info.
2585 unsigned ID = SectionMap.insert(Asm->getCurrentSection());
2586 if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
2587 std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
2588 // Append the function info to section info.
2589 SectionLineInfos.insert(SectionLineInfos.end(),
2590 Lines.begin(), Lines.end());
2591 }
2592
2593 // Construct abstract scopes.
2594 for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
2595 AE = AbstractScopesList.end(); AI != AE; ++AI)
2596 constructScopeDIE(*AI);
2597
Devang Patel9c488372010-05-04 06:15:30 +00002598 DIE *CurFnDIE = constructScopeDIE(CurrentFnDbgScope);
Devang Patel344130e2010-01-04 20:44:00 +00002599
Devang Patel9c488372010-05-04 06:15:30 +00002600 if (!DisableFramePointerElim(*MF))
2601 addUInt(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr,
2602 dwarf::DW_FORM_flag, 1);
2603
2604
Chris Lattnerd38fee82010-04-05 00:13:49 +00002605 DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
Devang Patel344130e2010-01-04 20:44:00 +00002606 MMI->getFrameMoves()));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002607 }
2608
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002609 // Clear debug info
Devang Patelf54b8522010-01-19 01:26:02 +00002610 CurrentFnDbgScope = NULL;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002611 DeleteContainerSeconds(DbgScopeMap);
Devang Patel51424712010-04-09 16:04:20 +00002612 InsnsBeginScopeSet.clear();
2613 InsnsEndScopeSet.clear();
Devang Patelaead63c2010-03-29 22:59:58 +00002614 DbgValueStartMap.clear();
Devang Patelf54b8522010-01-19 01:26:02 +00002615 ConcreteScopes.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002616 DeleteContainerSeconds(AbstractScopes);
Devang Patelf54b8522010-01-19 01:26:02 +00002617 AbstractScopesList.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002618 AbstractVariables.clear();
Devang Pateleac9c072010-04-27 19:46:33 +00002619 LabelsBeforeInsn.clear();
2620 LabelsAfterInsn.clear();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002621 Lines.clear();
Devang Patelf2548ca2010-04-16 23:33:45 +00002622 PrevLabel = NULL;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002623}
2624
Chris Lattnerc6087842010-03-09 04:54:43 +00002625/// recordSourceLine - Register a source line with debug info. Returns the
2626/// unique label that was emitted and which provides correspondence to
2627/// the source line list.
Devang Patele9f8f5e2010-05-07 20:54:48 +00002628MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S) {
Devang Patel65dbc902009-11-25 17:36:49 +00002629 StringRef Dir;
2630 StringRef Fn;
Devang Patelf84548d2009-10-05 18:03:19 +00002631
Dan Gohman1cc0d622010-05-05 23:41:32 +00002632 unsigned Src = 1;
2633 if (S) {
2634 DIDescriptor Scope(S);
Devang Patelf84548d2009-10-05 18:03:19 +00002635
Dan Gohman1cc0d622010-05-05 23:41:32 +00002636 if (Scope.isCompileUnit()) {
2637 DICompileUnit CU(S);
2638 Dir = CU.getDirectory();
2639 Fn = CU.getFilename();
2640 } else if (Scope.isSubprogram()) {
2641 DISubprogram SP(S);
2642 Dir = SP.getDirectory();
2643 Fn = SP.getFilename();
2644 } else if (Scope.isLexicalBlock()) {
2645 DILexicalBlock DB(S);
2646 Dir = DB.getDirectory();
2647 Fn = DB.getFilename();
2648 } else
2649 assert(0 && "Unexpected scope info");
2650
2651 Src = GetOrCreateSourceID(Dir, Fn);
2652 }
2653
Chris Lattner63d78362010-03-14 08:36:50 +00002654 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Chris Lattner25b68c62010-03-14 08:15:55 +00002655 Lines.push_back(SrcLineInfo(Line, Col, Src, Label));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002656
Chris Lattnerc6087842010-03-09 04:54:43 +00002657 Asm->OutStreamer.EmitLabel(Label);
2658 return Label;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002659}
2660
Bill Wendling829e67b2009-05-20 23:22:40 +00002661//===----------------------------------------------------------------------===//
2662// Emit Methods
2663//===----------------------------------------------------------------------===//
2664
Devang Patel2c4ceb12009-11-21 02:48:08 +00002665/// computeSizeAndOffset - Compute the size and offset of a DIE.
Bill Wendling94d04b82009-05-20 23:21:38 +00002666///
Jim Grosbach7ab38df2009-11-22 19:20:36 +00002667unsigned
2668DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002669 // Get the children.
2670 const std::vector<DIE *> &Children = Die->getChildren();
2671
2672 // If not last sibling and has children then add sibling offset attribute.
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002673 if (!Last && !Children.empty())
Benjamin Kramer345ef342010-03-31 19:34:01 +00002674 Die->addSiblingOffset(DIEValueAllocator);
Bill Wendling94d04b82009-05-20 23:21:38 +00002675
2676 // Record the abbreviation.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002677 assignAbbrevNumber(Die->getAbbrev());
Bill Wendling94d04b82009-05-20 23:21:38 +00002678
2679 // Get the abbreviation for this DIE.
2680 unsigned AbbrevNumber = Die->getAbbrevNumber();
2681 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2682
2683 // Set DIE offset
2684 Die->setOffset(Offset);
2685
2686 // Start the size with the size of abbreviation code.
Chris Lattneraf76e592009-08-22 20:48:53 +00002687 Offset += MCAsmInfo::getULEB128Size(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002688
2689 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
2690 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2691
2692 // Size the DIE attribute values.
2693 for (unsigned i = 0, N = Values.size(); i < N; ++i)
2694 // Size attribute value.
Chris Lattnera37d5382010-04-05 00:18:22 +00002695 Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
Bill Wendling94d04b82009-05-20 23:21:38 +00002696
2697 // Size the DIE children if any.
2698 if (!Children.empty()) {
2699 assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes &&
2700 "Children flag not set");
2701
2702 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002703 Offset = computeSizeAndOffset(Children[j], Offset, (j + 1) == M);
Bill Wendling94d04b82009-05-20 23:21:38 +00002704
2705 // End of children marker.
2706 Offset += sizeof(int8_t);
2707 }
2708
2709 Die->setSize(Offset - Die->getOffset());
2710 return Offset;
2711}
2712
Devang Patel2c4ceb12009-11-21 02:48:08 +00002713/// computeSizeAndOffsets - Compute the size and offset of all the DIEs.
Bill Wendling94d04b82009-05-20 23:21:38 +00002714///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002715void DwarfDebug::computeSizeAndOffsets() {
Devang Patel163a9f72010-05-10 22:49:55 +00002716 unsigned PrevOffset = 0;
2717 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
2718 E = CUMap.end(); I != E; ++I) {
2719 // Compute size of compile unit header.
2720 static unsigned Offset = PrevOffset +
2721 sizeof(int32_t) + // Length of Compilation Unit Info
2722 sizeof(int16_t) + // DWARF version number
2723 sizeof(int32_t) + // Offset Into Abbrev. Section
2724 sizeof(int8_t); // Pointer Size (in bytes)
2725 computeSizeAndOffset(I->second->getCUDie(), Offset, true);
2726 PrevOffset = Offset;
2727 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002728}
2729
Chris Lattner11b8f302010-04-04 23:02:02 +00002730/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
2731/// temporary label to it if SymbolStem is specified.
Chris Lattner9c69e285532010-04-04 22:59:04 +00002732static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
Chris Lattner11b8f302010-04-04 23:02:02 +00002733 const char *SymbolStem = 0) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002734 Asm->OutStreamer.SwitchSection(Section);
Chris Lattner11b8f302010-04-04 23:02:02 +00002735 if (!SymbolStem) return 0;
2736
Chris Lattner9c69e285532010-04-04 22:59:04 +00002737 MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
2738 Asm->OutStreamer.EmitLabel(TmpSym);
2739 return TmpSym;
2740}
2741
2742/// EmitSectionLabels - Emit initial Dwarf sections with a label at
2743/// the start of each one.
Chris Lattnerfa070b02010-04-04 22:33:59 +00002744void DwarfDebug::EmitSectionLabels() {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002745 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
Daniel Dunbarf612ff62009-09-19 20:40:05 +00002746
Bill Wendling94d04b82009-05-20 23:21:38 +00002747 // Dwarf sections base addresses.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002748 if (Asm->MAI->doesDwarfRequireFrameSection()) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002749 DwarfFrameSectionSym =
2750 EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
2751 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002752
Chris Lattner9c69e285532010-04-04 22:59:04 +00002753 DwarfInfoSectionSym =
2754 EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
2755 DwarfAbbrevSectionSym =
2756 EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
Chris Lattner11b8f302010-04-04 23:02:02 +00002757 EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002758
2759 if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
Chris Lattner11b8f302010-04-04 23:02:02 +00002760 EmitSectionSym(Asm, MacroInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00002761
Chris Lattner11b8f302010-04-04 23:02:02 +00002762 EmitSectionSym(Asm, TLOF.getDwarfLineSection());
2763 EmitSectionSym(Asm, TLOF.getDwarfLocSection());
2764 EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
2765 EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002766 DwarfStrSectionSym =
2767 EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
Devang Patelf2548ca2010-04-16 23:33:45 +00002768 DwarfDebugRangeSectionSym = EmitSectionSym(Asm, TLOF.getDwarfRangesSection(),
2769 "debug_range");
Bill Wendling94d04b82009-05-20 23:21:38 +00002770
Chris Lattner9c69e285532010-04-04 22:59:04 +00002771 TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
Chris Lattner4ad1efe2010-04-04 23:10:38 +00002772 EmitSectionSym(Asm, TLOF.getDataSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002773}
2774
Devang Patel2c4ceb12009-11-21 02:48:08 +00002775/// emitDIE - Recusively Emits a debug information entry.
Bill Wendling94d04b82009-05-20 23:21:38 +00002776///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002777void DwarfDebug::emitDIE(DIE *Die) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002778 // Get the abbreviation for this DIE.
2779 unsigned AbbrevNumber = Die->getAbbrevNumber();
2780 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2781
Bill Wendling94d04b82009-05-20 23:21:38 +00002782 // Emit the code (index) for the abbreviation.
Chris Lattner3f53c832010-04-04 18:52:31 +00002783 if (Asm->isVerbose())
Chris Lattner894d75a2010-01-22 23:18:42 +00002784 Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
2785 Twine::utohexstr(Die->getOffset()) + ":0x" +
2786 Twine::utohexstr(Die->getSize()) + " " +
2787 dwarf::TagString(Abbrev->getTag()));
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002788 Asm->EmitULEB128(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002789
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002790 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
Bill Wendling94d04b82009-05-20 23:21:38 +00002791 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2792
2793 // Emit the DIE attribute values.
2794 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
2795 unsigned Attr = AbbrevData[i].getAttribute();
2796 unsigned Form = AbbrevData[i].getForm();
2797 assert(Form && "Too many attributes for DIE (check abbreviation)");
2798
Chris Lattner3f53c832010-04-04 18:52:31 +00002799 if (Asm->isVerbose())
Chris Lattnera8013622010-01-24 18:54:17 +00002800 Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
2801
Bill Wendling94d04b82009-05-20 23:21:38 +00002802 switch (Attr) {
2803 case dwarf::DW_AT_sibling:
Devang Patel2c4ceb12009-11-21 02:48:08 +00002804 Asm->EmitInt32(Die->getSiblingOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00002805 break;
2806 case dwarf::DW_AT_abstract_origin: {
2807 DIEEntry *E = cast<DIEEntry>(Values[i]);
2808 DIE *Origin = E->getEntry();
Devang Patel53bb5c92009-11-10 23:06:00 +00002809 unsigned Addr = Origin->getOffset();
Bill Wendling94d04b82009-05-20 23:21:38 +00002810 Asm->EmitInt32(Addr);
2811 break;
2812 }
Devang Patelf2548ca2010-04-16 23:33:45 +00002813 case dwarf::DW_AT_ranges: {
2814 // DW_AT_range Value encodes offset in debug_range section.
2815 DIEInteger *V = cast<DIEInteger>(Values[i]);
2816 Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym,
2817 V->getValue(),
2818 DwarfDebugRangeSectionSym,
2819 4);
2820 break;
2821 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002822 default:
2823 // Emit an attribute using the defined form.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002824 Values[i]->EmitValue(Asm, Form);
Bill Wendling94d04b82009-05-20 23:21:38 +00002825 break;
2826 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002827 }
2828
2829 // Emit the DIE children if any.
2830 if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) {
2831 const std::vector<DIE *> &Children = Die->getChildren();
2832
2833 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002834 emitDIE(Children[j]);
Bill Wendling94d04b82009-05-20 23:21:38 +00002835
Chris Lattner3f53c832010-04-04 18:52:31 +00002836 if (Asm->isVerbose())
Chris Lattner233f52b2010-03-09 23:52:58 +00002837 Asm->OutStreamer.AddComment("End Of Children Mark");
2838 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002839 }
2840}
2841
Devang Patel8a241142009-12-09 18:24:21 +00002842/// emitDebugInfo - Emit the debug info section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002843///
Devang Patel8a241142009-12-09 18:24:21 +00002844void DwarfDebug::emitDebugInfo() {
2845 // Start debug info section.
2846 Asm->OutStreamer.SwitchSection(
2847 Asm->getObjFileLowering().getDwarfInfoSection());
Devang Patel163a9f72010-05-10 22:49:55 +00002848 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
2849 E = CUMap.end(); I != E; ++I) {
2850 CompileUnit *TheCU = I->second;
2851 DIE *Die = TheCU->getCUDie();
2852
2853 // Emit the compile units header.
2854 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin",
2855 TheCU->getID()));
2856
2857 // Emit size of content not including length itself
2858 unsigned ContentSize = Die->getSize() +
2859 sizeof(int16_t) + // DWARF version number
2860 sizeof(int32_t) + // Offset Into Abbrev. Section
2861 sizeof(int8_t) + // Pointer Size (in bytes)
2862 sizeof(int32_t); // FIXME - extra pad for gdb bug.
2863
2864 Asm->OutStreamer.AddComment("Length of Compilation Unit Info");
2865 Asm->EmitInt32(ContentSize);
2866 Asm->OutStreamer.AddComment("DWARF version number");
2867 Asm->EmitInt16(dwarf::DWARF_VERSION);
2868 Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
2869 Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
2870 DwarfAbbrevSectionSym);
2871 Asm->OutStreamer.AddComment("Address Size (in bytes)");
2872 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
2873
2874 emitDIE(Die);
2875 // FIXME - extra padding for gdb bug.
2876 Asm->OutStreamer.AddComment("4 extra padding bytes for GDB");
2877 Asm->EmitInt8(0);
2878 Asm->EmitInt8(0);
2879 Asm->EmitInt8(0);
2880 Asm->EmitInt8(0);
2881 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", TheCU->getID()));
2882 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002883}
2884
Devang Patel2c4ceb12009-11-21 02:48:08 +00002885/// emitAbbreviations - Emit the abbreviation section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002886///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002887void DwarfDebug::emitAbbreviations() const {
Bill Wendling94d04b82009-05-20 23:21:38 +00002888 // Check to see if it is worth the effort.
2889 if (!Abbreviations.empty()) {
2890 // Start the debug abbrev section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002891 Asm->OutStreamer.SwitchSection(
2892 Asm->getObjFileLowering().getDwarfAbbrevSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002893
Chris Lattnerc0215722010-04-04 19:25:43 +00002894 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002895
2896 // For each abbrevation.
2897 for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
2898 // Get abbreviation data
2899 const DIEAbbrev *Abbrev = Abbreviations[i];
2900
2901 // Emit the abbrevations code (base 1 index.)
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002902 Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
Bill Wendling94d04b82009-05-20 23:21:38 +00002903
2904 // Emit the abbreviations data.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002905 Abbrev->Emit(Asm);
Bill Wendling94d04b82009-05-20 23:21:38 +00002906 }
2907
2908 // Mark end of abbreviations.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002909 Asm->EmitULEB128(0, "EOM(3)");
Bill Wendling94d04b82009-05-20 23:21:38 +00002910
Chris Lattnerc0215722010-04-04 19:25:43 +00002911 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002912 }
2913}
2914
Devang Patel2c4ceb12009-11-21 02:48:08 +00002915/// emitEndOfLineMatrix - Emit the last address of the section and the end of
Bill Wendling94d04b82009-05-20 23:21:38 +00002916/// the line matrix.
2917///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002918void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002919 // Define last address of section.
Chris Lattner233f52b2010-03-09 23:52:58 +00002920 Asm->OutStreamer.AddComment("Extended Op");
2921 Asm->EmitInt8(0);
2922
2923 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002924 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00002925 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2926 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2927
2928 Asm->OutStreamer.AddComment("Section end label");
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002929
Chris Lattnerc0215722010-04-04 19:25:43 +00002930 Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
Chris Lattnerd38fee82010-04-05 00:13:49 +00002931 Asm->getTargetData().getPointerSize(),
2932 0/*AddrSpace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00002933
2934 // Mark end of matrix.
Chris Lattner233f52b2010-03-09 23:52:58 +00002935 Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
2936 Asm->EmitInt8(0);
Chris Lattner0ad9c912010-01-22 22:09:00 +00002937 Asm->EmitInt8(1);
Chris Lattner894d75a2010-01-22 23:18:42 +00002938 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002939}
2940
Devang Patel2c4ceb12009-11-21 02:48:08 +00002941/// emitDebugLines - Emit source line information.
Bill Wendling94d04b82009-05-20 23:21:38 +00002942///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002943void DwarfDebug::emitDebugLines() {
Bill Wendling94d04b82009-05-20 23:21:38 +00002944 // If the target is using .loc/.file, the assembler will be emitting the
2945 // .debug_line table automatically.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002946 if (Asm->MAI->hasDotLocAndDotFile())
Bill Wendling94d04b82009-05-20 23:21:38 +00002947 return;
2948
2949 // Minimum line delta, thus ranging from -10..(255-10).
2950 const int MinLineDelta = -(dwarf::DW_LNS_fixed_advance_pc + 1);
2951 // Maximum line delta, thus ranging from -10..(255-10).
2952 const int MaxLineDelta = 255 + MinLineDelta;
2953
2954 // Start the dwarf line section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002955 Asm->OutStreamer.SwitchSection(
2956 Asm->getObjFileLowering().getDwarfLineSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002957
2958 // Construct the section header.
Chris Lattner233f52b2010-03-09 23:52:58 +00002959 Asm->OutStreamer.AddComment("Length of Source Line Info");
Chris Lattnera6437182010-04-04 19:58:12 +00002960 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_end"),
2961 Asm->GetTempSymbol("line_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002962 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002963
Chris Lattner233f52b2010-03-09 23:52:58 +00002964 Asm->OutStreamer.AddComment("DWARF version number");
2965 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling94d04b82009-05-20 23:21:38 +00002966
Chris Lattner233f52b2010-03-09 23:52:58 +00002967 Asm->OutStreamer.AddComment("Prolog Length");
Chris Lattnera6437182010-04-04 19:58:12 +00002968 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_prolog_end"),
2969 Asm->GetTempSymbol("line_prolog_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002970 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002971
Chris Lattner233f52b2010-03-09 23:52:58 +00002972 Asm->OutStreamer.AddComment("Minimum Instruction Length");
2973 Asm->EmitInt8(1);
2974 Asm->OutStreamer.AddComment("Default is_stmt_start flag");
2975 Asm->EmitInt8(1);
2976 Asm->OutStreamer.AddComment("Line Base Value (Special Opcodes)");
2977 Asm->EmitInt8(MinLineDelta);
2978 Asm->OutStreamer.AddComment("Line Range Value (Special Opcodes)");
2979 Asm->EmitInt8(MaxLineDelta);
2980 Asm->OutStreamer.AddComment("Special Opcode Base");
2981 Asm->EmitInt8(-MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00002982
2983 // Line number standard opcode encodings argument count
Chris Lattner233f52b2010-03-09 23:52:58 +00002984 Asm->OutStreamer.AddComment("DW_LNS_copy arg count");
2985 Asm->EmitInt8(0);
2986 Asm->OutStreamer.AddComment("DW_LNS_advance_pc arg count");
2987 Asm->EmitInt8(1);
2988 Asm->OutStreamer.AddComment("DW_LNS_advance_line arg count");
2989 Asm->EmitInt8(1);
2990 Asm->OutStreamer.AddComment("DW_LNS_set_file arg count");
2991 Asm->EmitInt8(1);
2992 Asm->OutStreamer.AddComment("DW_LNS_set_column arg count");
2993 Asm->EmitInt8(1);
2994 Asm->OutStreamer.AddComment("DW_LNS_negate_stmt arg count");
2995 Asm->EmitInt8(0);
2996 Asm->OutStreamer.AddComment("DW_LNS_set_basic_block arg count");
2997 Asm->EmitInt8(0);
2998 Asm->OutStreamer.AddComment("DW_LNS_const_add_pc arg count");
2999 Asm->EmitInt8(0);
3000 Asm->OutStreamer.AddComment("DW_LNS_fixed_advance_pc arg count");
3001 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00003002
3003 // Emit directories.
3004 for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
Chris Lattner4cf202b2010-01-23 03:11:46 +00003005 const std::string &Dir = getSourceDirectoryName(DI);
Chris Lattner3f53c832010-04-04 18:52:31 +00003006 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Directory");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003007 Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003008 }
3009
Chris Lattner233f52b2010-03-09 23:52:58 +00003010 Asm->OutStreamer.AddComment("End of directories");
3011 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003012
3013 // Emit files.
3014 for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
3015 // Remember source id starts at 1.
3016 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
Chris Lattner4cf202b2010-01-23 03:11:46 +00003017 const std::string &FN = getSourceFileName(Id.second);
Chris Lattner3f53c832010-04-04 18:52:31 +00003018 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Source");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003019 Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0);
3020
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003021 Asm->EmitULEB128(Id.first, "Directory #");
3022 Asm->EmitULEB128(0, "Mod date");
3023 Asm->EmitULEB128(0, "File size");
Bill Wendling94d04b82009-05-20 23:21:38 +00003024 }
3025
Chris Lattner233f52b2010-03-09 23:52:58 +00003026 Asm->OutStreamer.AddComment("End of files");
3027 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003028
Chris Lattnerc0215722010-04-04 19:25:43 +00003029 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00003030
3031 // A sequence for each text section.
3032 unsigned SecSrcLinesSize = SectionSourceLines.size();
3033
3034 for (unsigned j = 0; j < SecSrcLinesSize; ++j) {
3035 // Isolate current sections line info.
3036 const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j];
3037
Bill Wendling94d04b82009-05-20 23:21:38 +00003038 // Dwarf assumes we start with first line of first source file.
3039 unsigned Source = 1;
3040 unsigned Line = 1;
3041
3042 // Construct rows of the address, source, line, column matrix.
3043 for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
3044 const SrcLineInfo &LineInfo = LineInfos[i];
Chris Lattner25b68c62010-03-14 08:15:55 +00003045 MCSymbol *Label = LineInfo.getLabel();
Chris Lattnerb9130602010-03-14 02:20:58 +00003046 if (!Label->isDefined()) continue; // Not emitted, in dead code.
Bill Wendling94d04b82009-05-20 23:21:38 +00003047
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003048 if (Asm->isVerbose()) {
Chris Lattner188a87d2010-03-10 01:04:13 +00003049 std::pair<unsigned, unsigned> SrcID =
Bill Wendling94d04b82009-05-20 23:21:38 +00003050 getSourceDirectoryAndFileIds(LineInfo.getSourceID());
Chris Lattner188a87d2010-03-10 01:04:13 +00003051 Asm->OutStreamer.AddComment(Twine(getSourceDirectoryName(SrcID.first)) +
Chris Lattner49f618a2010-03-10 02:29:31 +00003052 "/" +
3053 Twine(getSourceFileName(SrcID.second)) +
Chris Lattner188a87d2010-03-10 01:04:13 +00003054 ":" + Twine(LineInfo.getLine()));
Bill Wendling94d04b82009-05-20 23:21:38 +00003055 }
3056
3057 // Define the line address.
Chris Lattner233f52b2010-03-09 23:52:58 +00003058 Asm->OutStreamer.AddComment("Extended Op");
3059 Asm->EmitInt8(0);
3060 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003061 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00003062
3063 Asm->OutStreamer.AddComment("DW_LNE_set_address");
3064 Asm->EmitInt8(dwarf::DW_LNE_set_address);
3065
3066 Asm->OutStreamer.AddComment("Location label");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003067 Asm->OutStreamer.EmitSymbolValue(Label,
3068 Asm->getTargetData().getPointerSize(),
Chris Lattnerb9130602010-03-14 02:20:58 +00003069 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00003070
Bill Wendling94d04b82009-05-20 23:21:38 +00003071 // If change of source, then switch to the new source.
3072 if (Source != LineInfo.getSourceID()) {
3073 Source = LineInfo.getSourceID();
Chris Lattner233f52b2010-03-09 23:52:58 +00003074 Asm->OutStreamer.AddComment("DW_LNS_set_file");
3075 Asm->EmitInt8(dwarf::DW_LNS_set_file);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003076 Asm->EmitULEB128(Source, "New Source");
Bill Wendling94d04b82009-05-20 23:21:38 +00003077 }
3078
3079 // If change of line.
3080 if (Line != LineInfo.getLine()) {
3081 // Determine offset.
3082 int Offset = LineInfo.getLine() - Line;
3083 int Delta = Offset - MinLineDelta;
3084
3085 // Update line.
3086 Line = LineInfo.getLine();
3087
3088 // If delta is small enough and in range...
3089 if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
3090 // ... then use fast opcode.
Chris Lattner233f52b2010-03-09 23:52:58 +00003091 Asm->OutStreamer.AddComment("Line Delta");
3092 Asm->EmitInt8(Delta - MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00003093 } else {
3094 // ... otherwise use long hand.
Chris Lattner233f52b2010-03-09 23:52:58 +00003095 Asm->OutStreamer.AddComment("DW_LNS_advance_line");
Bill Wendling94d04b82009-05-20 23:21:38 +00003096 Asm->EmitInt8(dwarf::DW_LNS_advance_line);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003097 Asm->EmitSLEB128(Offset, "Line Offset");
Chris Lattner233f52b2010-03-09 23:52:58 +00003098 Asm->OutStreamer.AddComment("DW_LNS_copy");
3099 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00003100 }
3101 } else {
3102 // Copy the previous row (different address or source)
Chris Lattner233f52b2010-03-09 23:52:58 +00003103 Asm->OutStreamer.AddComment("DW_LNS_copy");
3104 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00003105 }
3106 }
3107
Devang Patel2c4ceb12009-11-21 02:48:08 +00003108 emitEndOfLineMatrix(j + 1);
Bill Wendling94d04b82009-05-20 23:21:38 +00003109 }
3110
3111 if (SecSrcLinesSize == 0)
3112 // Because we're emitting a debug_line section, we still need a line
3113 // table. The linker and friends expect it to exist. If there's nothing to
3114 // put into it, emit an empty table.
Devang Patel2c4ceb12009-11-21 02:48:08 +00003115 emitEndOfLineMatrix(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00003116
Chris Lattnerc0215722010-04-04 19:25:43 +00003117 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00003118}
3119
Devang Patel2c4ceb12009-11-21 02:48:08 +00003120/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003121///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003122void DwarfDebug::emitCommonDebugFrame() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003123 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003124 return;
3125
Chris Lattnerd38fee82010-04-05 00:13:49 +00003126 int stackGrowth = Asm->getTargetData().getPointerSize();
3127 if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
3128 TargetFrameInfo::StackGrowsDown)
3129 stackGrowth *= -1;
Bill Wendling94d04b82009-05-20 23:21:38 +00003130
3131 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003132 Asm->OutStreamer.SwitchSection(
3133 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003134
Chris Lattnerc0215722010-04-04 19:25:43 +00003135 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common"));
Chris Lattner233f52b2010-03-09 23:52:58 +00003136 Asm->OutStreamer.AddComment("Length of Common Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00003137 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_frame_common_end"),
3138 Asm->GetTempSymbol("debug_frame_common_begin"), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003139
Chris Lattnerc0215722010-04-04 19:25:43 +00003140 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_begin"));
Chris Lattner233f52b2010-03-09 23:52:58 +00003141 Asm->OutStreamer.AddComment("CIE Identifier Tag");
Bill Wendling94d04b82009-05-20 23:21:38 +00003142 Asm->EmitInt32((int)dwarf::DW_CIE_ID);
Chris Lattner233f52b2010-03-09 23:52:58 +00003143 Asm->OutStreamer.AddComment("CIE Version");
Bill Wendling94d04b82009-05-20 23:21:38 +00003144 Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Chris Lattner233f52b2010-03-09 23:52:58 +00003145 Asm->OutStreamer.AddComment("CIE Augmentation");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003146 Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003147 Asm->EmitULEB128(1, "CIE Code Alignment Factor");
3148 Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Chris Lattner233f52b2010-03-09 23:52:58 +00003149 Asm->OutStreamer.AddComment("CIE RA Column");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003150 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling94d04b82009-05-20 23:21:38 +00003151 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
Bill Wendling94d04b82009-05-20 23:21:38 +00003152
3153 std::vector<MachineMove> Moves;
3154 RI->getInitialFrameState(Moves);
3155
Chris Lattner02b86b92010-04-04 23:41:46 +00003156 Asm->EmitFrameMoves(Moves, 0, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00003157
Chris Lattner059ea132010-04-28 01:05:45 +00003158 Asm->EmitAlignment(2);
Chris Lattnerc0215722010-04-04 19:25:43 +00003159 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00003160}
3161
Devang Patel2c4ceb12009-11-21 02:48:08 +00003162/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
Bill Wendling94d04b82009-05-20 23:21:38 +00003163/// section.
Chris Lattner206d61e2010-03-13 07:26:18 +00003164void DwarfDebug::
3165emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003166 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003167 return;
3168
3169 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003170 Asm->OutStreamer.SwitchSection(
3171 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003172
Chris Lattner233f52b2010-03-09 23:52:58 +00003173 Asm->OutStreamer.AddComment("Length of Frame Information Entry");
Chris Lattner206d61e2010-03-13 07:26:18 +00003174 MCSymbol *DebugFrameBegin =
Chris Lattnerc0215722010-04-04 19:25:43 +00003175 Asm->GetTempSymbol("debug_frame_begin", DebugFrameInfo.Number);
Chris Lattner206d61e2010-03-13 07:26:18 +00003176 MCSymbol *DebugFrameEnd =
Chris Lattnerc0215722010-04-04 19:25:43 +00003177 Asm->GetTempSymbol("debug_frame_end", DebugFrameInfo.Number);
Chris Lattnera6437182010-04-04 19:58:12 +00003178 Asm->EmitLabelDifference(DebugFrameEnd, DebugFrameBegin, 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003179
Chris Lattner206d61e2010-03-13 07:26:18 +00003180 Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Bill Wendling94d04b82009-05-20 23:21:38 +00003181
Chris Lattner233f52b2010-03-09 23:52:58 +00003182 Asm->OutStreamer.AddComment("FDE CIE offset");
Chris Lattner6189ed12010-04-04 23:25:33 +00003183 Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
3184 DwarfFrameSectionSym);
Bill Wendling94d04b82009-05-20 23:21:38 +00003185
Chris Lattner233f52b2010-03-09 23:52:58 +00003186 Asm->OutStreamer.AddComment("FDE initial location");
Chris Lattnerc0215722010-04-04 19:25:43 +00003187 MCSymbol *FuncBeginSym =
3188 Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Chris Lattnerfb658072010-03-13 07:40:56 +00003189 Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
Chris Lattnerd38fee82010-04-05 00:13:49 +00003190 Asm->getTargetData().getPointerSize(),
3191 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00003192
3193
Chris Lattner233f52b2010-03-09 23:52:58 +00003194 Asm->OutStreamer.AddComment("FDE address range");
Chris Lattnera6437182010-04-04 19:58:12 +00003195 Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
Chris Lattnerd38fee82010-04-05 00:13:49 +00003196 FuncBeginSym, Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00003197
Chris Lattner02b86b92010-04-04 23:41:46 +00003198 Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00003199
Chris Lattner059ea132010-04-28 01:05:45 +00003200 Asm->EmitAlignment(2);
Chris Lattner206d61e2010-03-13 07:26:18 +00003201 Asm->OutStreamer.EmitLabel(DebugFrameEnd);
Bill Wendling94d04b82009-05-20 23:21:38 +00003202}
3203
Devang Patel8a241142009-12-09 18:24:21 +00003204/// emitDebugPubNames - Emit visible names into a debug pubnames section.
3205///
3206void DwarfDebug::emitDebugPubNames() {
Devang Patel163a9f72010-05-10 22:49:55 +00003207 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
3208 E = CUMap.end(); I != E; ++I) {
3209 CompileUnit *TheCU = I->second;
3210 // Start the dwarf pubnames section.
3211 Asm->OutStreamer.SwitchSection(
3212 Asm->getObjFileLowering().getDwarfPubNamesSection());
Chris Lattner4cf202b2010-01-23 03:11:46 +00003213
Devang Patel163a9f72010-05-10 22:49:55 +00003214 Asm->OutStreamer.AddComment("Length of Public Names Info");
3215 Asm->EmitLabelDifference(
3216 Asm->GetTempSymbol("pubnames_end", TheCU->getID()),
3217 Asm->GetTempSymbol("pubnames_begin", TheCU->getID()), 4);
3218
3219 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin",
3220 TheCU->getID()));
3221
3222 Asm->OutStreamer.AddComment("DWARF Version");
3223 Asm->EmitInt16(dwarf::DWARF_VERSION);
3224
3225 Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
3226 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", TheCU->getID()),
3227 DwarfInfoSectionSym);
3228
3229 Asm->OutStreamer.AddComment("Compilation Unit Length");
3230 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", TheCU->getID()),
3231 Asm->GetTempSymbol("info_begin", TheCU->getID()),
3232 4);
3233
3234 const StringMap<DIE*> &Globals = TheCU->getGlobals();
3235 for (StringMap<DIE*>::const_iterator
3236 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3237 const char *Name = GI->getKeyData();
3238 DIE *Entity = GI->second;
3239
3240 Asm->OutStreamer.AddComment("DIE offset");
3241 Asm->EmitInt32(Entity->getOffset());
3242
3243 if (Asm->isVerbose())
3244 Asm->OutStreamer.AddComment("External Name");
3245 Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
3246 }
3247
3248 Asm->OutStreamer.AddComment("End Mark");
3249 Asm->EmitInt32(0);
3250 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end",
3251 TheCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00003252 }
Bill Wendling94d04b82009-05-20 23:21:38 +00003253}
3254
Devang Patel193f7202009-11-24 01:14:22 +00003255void DwarfDebug::emitDebugPubTypes() {
Devang Patel163a9f72010-05-10 22:49:55 +00003256 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
3257 E = CUMap.end(); I != E; ++I) {
3258 CompileUnit *TheCU = I->second;
3259 // Start the dwarf pubnames section.
3260 Asm->OutStreamer.SwitchSection(
3261 Asm->getObjFileLowering().getDwarfPubTypesSection());
3262 Asm->OutStreamer.AddComment("Length of Public Types Info");
3263 Asm->EmitLabelDifference(
3264 Asm->GetTempSymbol("pubtypes_end", TheCU->getID()),
3265 Asm->GetTempSymbol("pubtypes_begin", TheCU->getID()), 4);
Chris Lattner4cf202b2010-01-23 03:11:46 +00003266
Devang Patel163a9f72010-05-10 22:49:55 +00003267 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_begin",
3268 TheCU->getID()));
3269
3270 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version");
3271 Asm->EmitInt16(dwarf::DWARF_VERSION);
3272
3273 Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
3274 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", TheCU->getID()),
3275 DwarfInfoSectionSym);
3276
3277 Asm->OutStreamer.AddComment("Compilation Unit Length");
3278 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", TheCU->getID()),
3279 Asm->GetTempSymbol("info_begin", TheCU->getID()),
3280 4);
3281
3282 const StringMap<DIE*> &Globals = TheCU->getGlobalTypes();
3283 for (StringMap<DIE*>::const_iterator
3284 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3285 const char *Name = GI->getKeyData();
3286 DIE * Entity = GI->second;
3287
3288 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
3289 Asm->EmitInt32(Entity->getOffset());
3290
3291 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
3292 Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
3293 }
3294
3295 Asm->OutStreamer.AddComment("End Mark");
3296 Asm->EmitInt32(0);
3297 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
3298 TheCU->getID()));
Devang Patel193f7202009-11-24 01:14:22 +00003299 }
Devang Patel193f7202009-11-24 01:14:22 +00003300}
3301
Devang Patel2c4ceb12009-11-21 02:48:08 +00003302/// emitDebugStr - Emit visible names into a debug str section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003303///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003304void DwarfDebug::emitDebugStr() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003305 // Check to see if it is worth the effort.
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003306 if (StringPool.empty()) return;
3307
3308 // Start the dwarf str section.
3309 Asm->OutStreamer.SwitchSection(
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003310 Asm->getObjFileLowering().getDwarfStrSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003311
Chris Lattnerbc733f52010-03-13 02:17:42 +00003312 // Get all of the string pool entries and put them in an array by their ID so
3313 // we can sort them.
3314 SmallVector<std::pair<unsigned,
3315 StringMapEntry<std::pair<MCSymbol*, unsigned> >*>, 64> Entries;
3316
3317 for (StringMap<std::pair<MCSymbol*, unsigned> >::iterator
3318 I = StringPool.begin(), E = StringPool.end(); I != E; ++I)
3319 Entries.push_back(std::make_pair(I->second.second, &*I));
3320
3321 array_pod_sort(Entries.begin(), Entries.end());
3322
3323 for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003324 // Emit a label for reference from debug information entries.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003325 Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first);
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003326
3327 // Emit the string itself.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003328 Asm->OutStreamer.EmitBytes(Entries[i].second->getKey(), 0/*addrspace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00003329 }
3330}
3331
Devang Patel2c4ceb12009-11-21 02:48:08 +00003332/// emitDebugLoc - Emit visible names into a debug loc section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003333///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003334void DwarfDebug::emitDebugLoc() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003335 // Start the dwarf loc section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003336 Asm->OutStreamer.SwitchSection(
3337 Asm->getObjFileLowering().getDwarfLocSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003338}
3339
3340/// EmitDebugARanges - Emit visible names into a debug aranges section.
3341///
3342void DwarfDebug::EmitDebugARanges() {
3343 // Start the dwarf aranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003344 Asm->OutStreamer.SwitchSection(
3345 Asm->getObjFileLowering().getDwarfARangesSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003346}
3347
Devang Patel2c4ceb12009-11-21 02:48:08 +00003348/// emitDebugRanges - Emit visible names into a debug ranges section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003349///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003350void DwarfDebug::emitDebugRanges() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003351 // Start the dwarf ranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003352 Asm->OutStreamer.SwitchSection(
Devang Patelf2548ca2010-04-16 23:33:45 +00003353 Asm->getObjFileLowering().getDwarfRangesSection());
Devang Pateleac9c072010-04-27 19:46:33 +00003354 unsigned char Size = Asm->getTargetData().getPointerSize();
3355 for (SmallVector<const MCSymbol *, 8>::iterator
3356 I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end();
3357 I != E; ++I) {
3358 if (*I)
3359 Asm->OutStreamer.EmitSymbolValue(const_cast<MCSymbol*>(*I), Size, 0);
Devang Patelf2548ca2010-04-16 23:33:45 +00003360 else
Devang Pateleac9c072010-04-27 19:46:33 +00003361 Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
Devang Patelf2548ca2010-04-16 23:33:45 +00003362 }
Bill Wendling94d04b82009-05-20 23:21:38 +00003363}
3364
Devang Patel2c4ceb12009-11-21 02:48:08 +00003365/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003366///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003367void DwarfDebug::emitDebugMacInfo() {
Daniel Dunbarf612ff62009-09-19 20:40:05 +00003368 if (const MCSection *LineInfo =
Chris Lattner18a4c162009-08-02 07:24:22 +00003369 Asm->getObjFileLowering().getDwarfMacroInfoSection()) {
Bill Wendling94d04b82009-05-20 23:21:38 +00003370 // Start the dwarf macinfo section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003371 Asm->OutStreamer.SwitchSection(LineInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00003372 }
3373}
3374
Devang Patel2c4ceb12009-11-21 02:48:08 +00003375/// emitDebugInlineInfo - Emit inline info using following format.
Bill Wendling94d04b82009-05-20 23:21:38 +00003376/// Section Header:
3377/// 1. length of section
3378/// 2. Dwarf version number
3379/// 3. address size.
3380///
3381/// Entries (one "entry" for each function that was inlined):
3382///
3383/// 1. offset into __debug_str section for MIPS linkage name, if exists;
3384/// otherwise offset into __debug_str for regular function name.
3385/// 2. offset into __debug_str section for regular function name.
3386/// 3. an unsigned LEB128 number indicating the number of distinct inlining
3387/// instances for the function.
3388///
3389/// The rest of the entry consists of a {die_offset, low_pc} pair for each
3390/// inlined instance; the die_offset points to the inlined_subroutine die in the
3391/// __debug_info section, and the low_pc is the starting address for the
3392/// inlining instance.
Devang Patel2c4ceb12009-11-21 02:48:08 +00003393void DwarfDebug::emitDebugInlineInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003394 if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003395 return;
3396
Devang Patel163a9f72010-05-10 22:49:55 +00003397 if (!FirstCU)
Bill Wendling94d04b82009-05-20 23:21:38 +00003398 return;
3399
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003400 Asm->OutStreamer.SwitchSection(
3401 Asm->getObjFileLowering().getDwarfDebugInlineSection());
Chris Lattner0ad9c912010-01-22 22:09:00 +00003402
Chris Lattner233f52b2010-03-09 23:52:58 +00003403 Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00003404 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
3405 Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003406
Chris Lattnerc0215722010-04-04 19:25:43 +00003407 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003408
Chris Lattner233f52b2010-03-09 23:52:58 +00003409 Asm->OutStreamer.AddComment("Dwarf Version");
3410 Asm->EmitInt16(dwarf::DWARF_VERSION);
3411 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003412 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00003413
Devang Patele9f8f5e2010-05-07 20:54:48 +00003414 for (SmallVector<const MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
Devang Patel53bb5c92009-11-10 23:06:00 +00003415 E = InlinedSPNodes.end(); I != E; ++I) {
Jim Grosbach31ef40e2009-11-21 23:12:12 +00003416
Devang Patele9f8f5e2010-05-07 20:54:48 +00003417 const MDNode *Node = *I;
3418 DenseMap<const MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
Jim Grosbach7ab38df2009-11-22 19:20:36 +00003419 = InlineInfo.find(Node);
Devang Patel53bb5c92009-11-10 23:06:00 +00003420 SmallVector<InlineInfoLabels, 4> &Labels = II->second;
Devang Patele4b27562009-08-28 23:24:31 +00003421 DISubprogram SP(Node);
Devang Patel65dbc902009-11-25 17:36:49 +00003422 StringRef LName = SP.getLinkageName();
3423 StringRef Name = SP.getName();
Bill Wendling94d04b82009-05-20 23:21:38 +00003424
Chris Lattner233f52b2010-03-09 23:52:58 +00003425 Asm->OutStreamer.AddComment("MIPS linkage name");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003426 if (LName.empty()) {
3427 Asm->OutStreamer.EmitBytes(Name, 0);
3428 Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
3429 } else
Chris Lattner6189ed12010-04-04 23:25:33 +00003430 Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
3431 DwarfStrSectionSym);
Devang Patel53bb5c92009-11-10 23:06:00 +00003432
Chris Lattner233f52b2010-03-09 23:52:58 +00003433 Asm->OutStreamer.AddComment("Function name");
Chris Lattner6189ed12010-04-04 23:25:33 +00003434 Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003435 Asm->EmitULEB128(Labels.size(), "Inline count");
Bill Wendling94d04b82009-05-20 23:21:38 +00003436
Devang Patel53bb5c92009-11-10 23:06:00 +00003437 for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
Bill Wendling94d04b82009-05-20 23:21:38 +00003438 LE = Labels.end(); LI != LE; ++LI) {
Chris Lattner3f53c832010-04-04 18:52:31 +00003439 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Chris Lattner6ed0f902010-03-09 00:31:02 +00003440 Asm->EmitInt32(LI->second->getOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00003441
Chris Lattner3f53c832010-04-04 18:52:31 +00003442 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003443 Asm->OutStreamer.EmitSymbolValue(LI->first,
3444 Asm->getTargetData().getPointerSize(),0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003445 }
3446 }
3447
Chris Lattnerc0215722010-04-04 19:25:43 +00003448 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003449}