blob: 917bd9d2d58e4bf84dd1af0bc9a4aa81b0af7d9c [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"
Chris Lattner74e41f92010-04-05 05:24:55 +000031#include "llvm/Analysis/DebugInfo.h"
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +000032#include "llvm/ADT/STLExtras.h"
Chris Lattner23132b12009-08-24 03:52:50 +000033#include "llvm/ADT/StringExtras.h"
Daniel Dunbar6e4bdfc2009-10-13 06:47:08 +000034#include "llvm/Support/Debug.h"
35#include "llvm/Support/ErrorHandling.h"
Devang Patel3139fcf2010-01-26 21:39:14 +000036#include "llvm/Support/ValueHandle.h"
Chris Lattner0ad9c912010-01-22 22:09:00 +000037#include "llvm/Support/FormattedStream.h"
Chris Lattnera87dea42009-07-31 18:48:30 +000038#include "llvm/Support/Timer.h"
39#include "llvm/System/Path.h"
Bill Wendling0310d762009-05-15 09:23:25 +000040using namespace llvm;
41
Bill Wendling5f017e82010-04-07 09:28:04 +000042namespace {
43 const char *DWARFGroupName = "DWARF Emission";
44 const char *DbgTimerName = "DWARF Debug Writer";
45} // end anonymous namespace
46
Bill Wendling0310d762009-05-15 09:23:25 +000047//===----------------------------------------------------------------------===//
48
49/// Configuration values for initial hash set sizes (log2).
50///
Bill Wendling0310d762009-05-15 09:23:25 +000051static const unsigned InitAbbreviationsSetSize = 9; // log2(512)
Bill Wendling0310d762009-05-15 09:23:25 +000052
53namespace llvm {
54
55//===----------------------------------------------------------------------===//
56/// CompileUnit - This dwarf writer support class manages information associate
57/// with a source file.
Nick Lewycky5f9843f2009-11-17 08:11:44 +000058class CompileUnit {
Bill Wendling0310d762009-05-15 09:23:25 +000059 /// ID - File identifier for source.
60 ///
61 unsigned ID;
62
63 /// Die - Compile unit debug information entry.
64 ///
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +000065 const OwningPtr<DIE> CUDie;
Bill Wendling0310d762009-05-15 09:23:25 +000066
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +000067 /// IndexTyDie - An anonymous type for index type. Owned by CUDie.
Devang Patel6f01d9c2009-11-21 00:31:03 +000068 DIE *IndexTyDie;
69
Bill Wendling0310d762009-05-15 09:23:25 +000070 /// GVToDieMap - Tracks the mapping of unit level debug informaton
71 /// variables to debug information entries.
Devang Patele4b27562009-08-28 23:24:31 +000072 /// FIXME : Rename GVToDieMap -> NodeToDieMap
Devang Patel622b0262010-01-19 06:19:05 +000073 DenseMap<MDNode *, DIE *> GVToDieMap;
Bill Wendling0310d762009-05-15 09:23:25 +000074
75 /// GVToDIEEntryMap - Tracks the mapping of unit level debug informaton
76 /// descriptors to debug information entries using a DIEEntry proxy.
Devang Patele4b27562009-08-28 23:24:31 +000077 /// FIXME : Rename
Devang Patel622b0262010-01-19 06:19:05 +000078 DenseMap<MDNode *, DIEEntry *> GVToDIEEntryMap;
Bill Wendling0310d762009-05-15 09:23:25 +000079
80 /// Globals - A map of globally visible named entities for this unit.
81 ///
82 StringMap<DIE*> Globals;
83
Devang Patel193f7202009-11-24 01:14:22 +000084 /// GlobalTypes - A map of globally visible types for this unit.
85 ///
86 StringMap<DIE*> GlobalTypes;
87
Bill Wendling0310d762009-05-15 09:23:25 +000088public:
89 CompileUnit(unsigned I, DIE *D)
Devang Patel2c4ceb12009-11-21 02:48:08 +000090 : ID(I), CUDie(D), IndexTyDie(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +000091
92 // Accessors.
Devang Patel193f7202009-11-24 01:14:22 +000093 unsigned getID() const { return ID; }
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +000094 DIE* getCUDie() const { return CUDie.get(); }
Devang Patel193f7202009-11-24 01:14:22 +000095 const StringMap<DIE*> &getGlobals() const { return Globals; }
96 const StringMap<DIE*> &getGlobalTypes() const { return GlobalTypes; }
Bill Wendling0310d762009-05-15 09:23:25 +000097
98 /// hasContent - Return true if this compile unit has something to write out.
99 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000100 bool hasContent() const { return !CUDie->getChildren().empty(); }
Bill Wendling0310d762009-05-15 09:23:25 +0000101
Devang Patel2c4ceb12009-11-21 02:48:08 +0000102 /// addGlobal - Add a new global entity to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000103 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000104 void addGlobal(StringRef Name, DIE *Die) { Globals[Name] = Die; }
Bill Wendling0310d762009-05-15 09:23:25 +0000105
Devang Patel193f7202009-11-24 01:14:22 +0000106 /// addGlobalType - Add a new global type to the compile unit.
107 ///
Benjamin Kramerbbb88db2010-03-31 20:15:45 +0000108 void addGlobalType(StringRef Name, DIE *Die) {
Devang Patel193f7202009-11-24 01:14:22 +0000109 GlobalTypes[Name] = Die;
110 }
111
Devang Patel017d1212009-11-20 21:37:22 +0000112 /// getDIE - Returns the debug information entry map slot for the
Bill Wendling0310d762009-05-15 09:23:25 +0000113 /// specified debug variable.
Devang Patel017d1212009-11-20 21:37:22 +0000114 DIE *getDIE(MDNode *N) { return GVToDieMap.lookup(N); }
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000115
Devang Patel017d1212009-11-20 21:37:22 +0000116 /// insertDIE - Insert DIE into the map.
117 void insertDIE(MDNode *N, DIE *D) {
118 GVToDieMap.insert(std::make_pair(N, D));
119 }
Bill Wendling0310d762009-05-15 09:23:25 +0000120
Devang Patel017d1212009-11-20 21:37:22 +0000121 /// getDIEEntry - Returns the debug information entry for the speciefied
122 /// debug variable.
Devang Patel6404e4e2009-12-15 19:16:48 +0000123 DIEEntry *getDIEEntry(MDNode *N) {
Devang Patel622b0262010-01-19 06:19:05 +0000124 DenseMap<MDNode *, DIEEntry *>::iterator I = GVToDIEEntryMap.find(N);
Devang Patel6404e4e2009-12-15 19:16:48 +0000125 if (I == GVToDIEEntryMap.end())
126 return NULL;
127 return I->second;
128 }
Devang Patel017d1212009-11-20 21:37:22 +0000129
130 /// insertDIEEntry - Insert debug information entry into the map.
131 void insertDIEEntry(MDNode *N, DIEEntry *E) {
132 GVToDIEEntryMap.insert(std::make_pair(N, E));
Bill Wendling0310d762009-05-15 09:23:25 +0000133 }
134
Devang Patel2c4ceb12009-11-21 02:48:08 +0000135 /// addDie - Adds or interns the DIE to the compile unit.
Bill Wendling0310d762009-05-15 09:23:25 +0000136 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000137 void addDie(DIE *Buffer) {
138 this->CUDie->addChild(Buffer);
Bill Wendling0310d762009-05-15 09:23:25 +0000139 }
Devang Patel6f01d9c2009-11-21 00:31:03 +0000140
141 // getIndexTyDie - Get an anonymous type for index type.
142 DIE *getIndexTyDie() {
143 return IndexTyDie;
144 }
145
Jim Grosbach7ab38df2009-11-22 19:20:36 +0000146 // setIndexTyDie - Set D as anonymous type for index which can be reused
147 // later.
Devang Patel6f01d9c2009-11-21 00:31:03 +0000148 void setIndexTyDie(DIE *D) {
149 IndexTyDie = D;
150 }
151
Bill Wendling0310d762009-05-15 09:23:25 +0000152};
153
154//===----------------------------------------------------------------------===//
155/// DbgVariable - This class is used to track local variable information.
156///
Devang Patelf76a3d62009-11-16 21:53:40 +0000157class DbgVariable {
Bill Wendling0310d762009-05-15 09:23:25 +0000158 DIVariable Var; // Variable Descriptor.
159 unsigned FrameIndex; // Variable frame index.
Devang Patel90a48ad2010-03-15 18:33:46 +0000160 const MachineInstr *DbgValueMInsn; // DBG_VALUE
Devang Patelaead63c2010-03-29 22:59:58 +0000161 // DbgValueLabel - DBG_VALUE is effective from this label.
162 MCSymbol *DbgValueLabel;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000163 DbgVariable *const AbstractVar; // Abstract variable for this variable.
Devang Patel53bb5c92009-11-10 23:06:00 +0000164 DIE *TheDIE;
Bill Wendling0310d762009-05-15 09:23:25 +0000165public:
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000166 // AbsVar may be NULL.
167 DbgVariable(DIVariable V, unsigned I, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000168 : Var(V), FrameIndex(I), DbgValueMInsn(0),
169 DbgValueLabel(0), AbstractVar(AbsVar), TheDIE(0) {}
Devang Patel90a48ad2010-03-15 18:33:46 +0000170 DbgVariable(DIVariable V, const MachineInstr *MI, DbgVariable *AbsVar)
Devang Patelaead63c2010-03-29 22:59:58 +0000171 : Var(V), FrameIndex(0), DbgValueMInsn(MI), DbgValueLabel(0),
172 AbstractVar(AbsVar), TheDIE(0)
Devang Patel90a48ad2010-03-15 18:33:46 +0000173 {}
Bill Wendling0310d762009-05-15 09:23:25 +0000174
175 // Accessors.
Devang Patel53bb5c92009-11-10 23:06:00 +0000176 DIVariable getVariable() const { return Var; }
177 unsigned getFrameIndex() const { return FrameIndex; }
Devang Patel90a48ad2010-03-15 18:33:46 +0000178 const MachineInstr *getDbgValue() const { return DbgValueMInsn; }
Devang Patelaead63c2010-03-29 22:59:58 +0000179 MCSymbol *getDbgValueLabel() const { return DbgValueLabel; }
180 void setDbgValueLabel(MCSymbol *L) { DbgValueLabel = L; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000181 DbgVariable *getAbstractVariable() const { return AbstractVar; }
182 void setDIE(DIE *D) { TheDIE = D; }
183 DIE *getDIE() const { return TheDIE; }
Bill Wendling0310d762009-05-15 09:23:25 +0000184};
185
186//===----------------------------------------------------------------------===//
187/// DbgScope - This class is used to track scope information.
188///
Devang Patelf76a3d62009-11-16 21:53:40 +0000189class DbgScope {
Bill Wendling0310d762009-05-15 09:23:25 +0000190 DbgScope *Parent; // Parent to this scope.
Jim Grosbach31ef40e2009-11-21 23:12:12 +0000191 DIDescriptor Desc; // Debug info descriptor for scope.
Devang Patel3139fcf2010-01-26 21:39:14 +0000192 // Location at which this scope is inlined.
193 AssertingVH<MDNode> InlinedAtLocation;
Devang Patel53bb5c92009-11-10 23:06:00 +0000194 bool AbstractScope; // Abstract Scope
Devang Pateld38dd112009-10-01 18:25:23 +0000195 const MachineInstr *LastInsn; // Last instruction of this scope.
196 const MachineInstr *FirstInsn; // First instruction of this scope.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000197 // Scopes defined in scope. Contents not owned.
198 SmallVector<DbgScope *, 4> Scopes;
199 // Variables declared in scope. Contents owned.
200 SmallVector<DbgVariable *, 8> Variables;
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000201
Owen Anderson04c05f72009-06-24 22:53:20 +0000202 // Private state for dump()
203 mutable unsigned IndentLevel;
Bill Wendling0310d762009-05-15 09:23:25 +0000204public:
Devang Patelc90aefe2009-10-14 21:08:09 +0000205 DbgScope(DbgScope *P, DIDescriptor D, MDNode *I = 0)
Devang Patel53bb5c92009-11-10 23:06:00 +0000206 : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
Devang Patelc90aefe2009-10-14 21:08:09 +0000207 LastInsn(0), FirstInsn(0), IndentLevel(0) {}
Bill Wendling0310d762009-05-15 09:23:25 +0000208 virtual ~DbgScope();
209
210 // Accessors.
211 DbgScope *getParent() const { return Parent; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000212 void setParent(DbgScope *P) { Parent = P; }
Bill Wendling0310d762009-05-15 09:23:25 +0000213 DIDescriptor getDesc() const { return Desc; }
Chris Lattnerbc733f52010-03-13 02:17:42 +0000214 MDNode *getInlinedAt() const { return InlinedAtLocation; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000215 MDNode *getScopeNode() const { return Desc.getNode(); }
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000216 const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
217 const SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
Devang Pateld38dd112009-10-01 18:25:23 +0000218 void setLastInsn(const MachineInstr *MI) { LastInsn = MI; }
219 const MachineInstr *getLastInsn() { return LastInsn; }
220 void setFirstInsn(const MachineInstr *MI) { FirstInsn = MI; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000221 void setAbstractScope() { AbstractScope = true; }
222 bool isAbstractScope() const { return AbstractScope; }
Devang Pateld38dd112009-10-01 18:25:23 +0000223 const MachineInstr *getFirstInsn() { return FirstInsn; }
Devang Patel53bb5c92009-11-10 23:06:00 +0000224
Devang Patel2c4ceb12009-11-21 02:48:08 +0000225 /// addScope - Add a scope to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000226 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000227 void addScope(DbgScope *S) { Scopes.push_back(S); }
Bill Wendling0310d762009-05-15 09:23:25 +0000228
Devang Patel2c4ceb12009-11-21 02:48:08 +0000229 /// addVariable - Add a variable to the scope.
Bill Wendling0310d762009-05-15 09:23:25 +0000230 ///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000231 void addVariable(DbgVariable *V) { Variables.push_back(V); }
Bill Wendling0310d762009-05-15 09:23:25 +0000232
Devang Patel344130e2010-01-04 20:44:00 +0000233 void fixInstructionMarkers(DenseMap<const MachineInstr *,
234 unsigned> &MIIndexMap) {
Chris Lattnered7a77b2010-03-31 05:36:29 +0000235 assert(getFirstInsn() && "First instruction is missing!");
Devang Patel344130e2010-01-04 20:44:00 +0000236
237 // Use the end of last child scope as end of this scope.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000238 const SmallVector<DbgScope *, 4> &Scopes = getScopes();
Devang Patelee890ed2010-01-05 16:59:17 +0000239 const MachineInstr *LastInsn = getFirstInsn();
Devang Patel344130e2010-01-04 20:44:00 +0000240 unsigned LIndex = 0;
241 if (Scopes.empty()) {
Chris Lattnered7a77b2010-03-31 05:36:29 +0000242 assert(getLastInsn() && "Inner most scope does not have last insn!");
Devang Patel344130e2010-01-04 20:44:00 +0000243 return;
244 }
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000245 for (SmallVector<DbgScope *, 4>::const_iterator SI = Scopes.begin(),
Devang Patel344130e2010-01-04 20:44:00 +0000246 SE = Scopes.end(); SI != SE; ++SI) {
247 DbgScope *DS = *SI;
248 DS->fixInstructionMarkers(MIIndexMap);
249 const MachineInstr *DSLastInsn = DS->getLastInsn();
250 unsigned DSI = MIIndexMap[DSLastInsn];
251 if (DSI > LIndex) {
252 LastInsn = DSLastInsn;
253 LIndex = DSI;
254 }
255 }
Devang Patel22fb4b22010-02-17 02:20:34 +0000256
257 unsigned CurrentLastInsnIndex = 0;
258 if (const MachineInstr *CL = getLastInsn())
259 CurrentLastInsnIndex = MIIndexMap[CL];
260 unsigned FIndex = MIIndexMap[getFirstInsn()];
261
262 // Set LastInsn as the last instruction for this scope only if
263 // it follows
264 // 1) this scope's first instruction and
265 // 2) current last instruction for this scope, if any.
266 if (LIndex >= CurrentLastInsnIndex && LIndex >= FIndex)
267 setLastInsn(LastInsn);
Devang Patelaf9e8472009-10-01 20:31:14 +0000268 }
269
Bill Wendling0310d762009-05-15 09:23:25 +0000270#ifndef NDEBUG
271 void dump() const;
272#endif
273};
Chris Lattnerea761862010-04-05 04:09:20 +0000274
275} // end llvm namespace
Bill Wendling0310d762009-05-15 09:23:25 +0000276
277#ifndef NDEBUG
278void DbgScope::dump() const {
David Greenef83adbc2009-12-24 00:31:35 +0000279 raw_ostream &err = dbgs();
Chris Lattnerc281de12009-08-23 00:51:00 +0000280 err.indent(IndentLevel);
Devang Patel53bb5c92009-11-10 23:06:00 +0000281 MDNode *N = Desc.getNode();
282 N->dump();
Devang Patel53bb5c92009-11-10 23:06:00 +0000283 if (AbstractScope)
284 err << "Abstract Scope\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000285
286 IndentLevel += 2;
Devang Patel53bb5c92009-11-10 23:06:00 +0000287 if (!Scopes.empty())
288 err << "Children ...\n";
Bill Wendling0310d762009-05-15 09:23:25 +0000289 for (unsigned i = 0, e = Scopes.size(); i != e; ++i)
290 if (Scopes[i] != this)
291 Scopes[i]->dump();
292
293 IndentLevel -= 2;
294}
295#endif
296
Bill Wendling0310d762009-05-15 09:23:25 +0000297DbgScope::~DbgScope() {
Bill Wendling0310d762009-05-15 09:23:25 +0000298 for (unsigned j = 0, M = Variables.size(); j < M; ++j)
299 delete Variables[j];
Bill Wendling0310d762009-05-15 09:23:25 +0000300}
301
Chris Lattner49cd6642010-04-05 05:11:15 +0000302DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
Chris Lattnerd38fee82010-04-05 00:13:49 +0000303 : Asm(A), MMI(Asm->MMI), ModuleCU(0),
Chris Lattner994cb122010-04-05 03:52:55 +0000304 AbbreviationsSet(InitAbbreviationsSetSize),
Bill Wendling5f017e82010-04-07 09:28:04 +0000305 CurrentFnDbgScope(0) {
Chris Lattnerbc733f52010-03-13 02:17:42 +0000306 NextStringPoolNumber = 0;
Chris Lattner9c69e285532010-04-04 22:59:04 +0000307
Chris Lattner4ad1efe2010-04-04 23:10:38 +0000308 DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
309 DwarfStrSectionSym = TextSectionSym = 0;
Torok Edwin9c421072010-04-07 10:44:46 +0000310
311 if (TimePassesIsEnabled) {
312 NamedRegionTimer T(DbgTimerName, DWARFGroupName);
313 beginModule(M);
314 } else {
315 beginModule(M);
316 }
Bill Wendling0310d762009-05-15 09:23:25 +0000317}
318DwarfDebug::~DwarfDebug() {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000319 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
320 DIEBlocks[j]->~DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000321}
322
Chris Lattnerbc733f52010-03-13 02:17:42 +0000323MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
324 std::pair<MCSymbol*, unsigned> &Entry = StringPool[Str];
325 if (Entry.first) return Entry.first;
326
327 Entry.second = NextStringPoolNumber++;
Chris Lattnerc0215722010-04-04 19:25:43 +0000328 return Entry.first = Asm->GetTempSymbol("string", Entry.second);
Chris Lattnerbc733f52010-03-13 02:17:42 +0000329}
330
331
Devang Patel2c4ceb12009-11-21 02:48:08 +0000332/// assignAbbrevNumber - Define a unique number for the abbreviation.
Bill Wendling0310d762009-05-15 09:23:25 +0000333///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000334void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {
Bill Wendling0310d762009-05-15 09:23:25 +0000335 // Profile the node so that we can make it unique.
336 FoldingSetNodeID ID;
337 Abbrev.Profile(ID);
338
339 // Check the set for priors.
340 DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev);
341
342 // If it's newly added.
343 if (InSet == &Abbrev) {
344 // Add to abbreviation list.
345 Abbreviations.push_back(&Abbrev);
346
347 // Assign the vector position + 1 as its number.
348 Abbrev.setNumber(Abbreviations.size());
349 } else {
350 // Assign existing abbreviation number.
351 Abbrev.setNumber(InSet->getNumber());
352 }
353}
354
Devang Patel2c4ceb12009-11-21 02:48:08 +0000355/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
Bill Wendling995f80a2009-05-20 23:24:48 +0000356/// information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000357DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000358 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000359 return Value;
360}
361
Devang Patel2c4ceb12009-11-21 02:48:08 +0000362/// addUInt - Add an unsigned integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000363///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000364void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000365 unsigned Form, uint64_t Integer) {
366 if (!Form) Form = DIEInteger::BestForm(false, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000367 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000368 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000369}
370
Devang Patel2c4ceb12009-11-21 02:48:08 +0000371/// addSInt - Add an signed integer attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000372///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000373void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000374 unsigned Form, int64_t Integer) {
375 if (!Form) Form = DIEInteger::BestForm(true, Integer);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000376 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000377 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000378}
379
Devang Patel69f57b12009-12-02 15:25:16 +0000380/// addString - Add a string attribute data and value. DIEString only
381/// keeps string reference.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000382void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattner4cf202b2010-01-23 03:11:46 +0000383 StringRef String) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000384 DIEValue *Value = new (DIEValueAllocator) DIEString(String);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000385 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000386}
387
Devang Patel2c4ceb12009-11-21 02:48:08 +0000388/// addLabel - Add a Dwarf label attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000389///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000390void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000391 const MCSymbol *Label) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000392 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000393 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000394}
395
Devang Patel2c4ceb12009-11-21 02:48:08 +0000396/// addDelta - Add a label delta attribute data and value.
Bill Wendling0310d762009-05-15 09:23:25 +0000397///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000398void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerb98b1bf2010-03-08 22:23:36 +0000399 const MCSymbol *Hi, const MCSymbol *Lo) {
Benjamin Kramer345ef342010-03-31 19:34:01 +0000400 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000401 Die->addValue(Attribute, Form, Value);
Bill Wendling0310d762009-05-15 09:23:25 +0000402}
403
Chris Lattner74e41f92010-04-05 05:24:55 +0000404/// addDIEEntry - Add a DIE attribute data and value.
405///
406void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
407 DIE *Entry) {
408 Die->addValue(Attribute, Form, createDIEEntry(Entry));
409}
410
411
Devang Patel2c4ceb12009-11-21 02:48:08 +0000412/// addBlock - Add block data.
Bill Wendling0310d762009-05-15 09:23:25 +0000413///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000414void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
Bill Wendling0310d762009-05-15 09:23:25 +0000415 DIEBlock *Block) {
Chris Lattnera37d5382010-04-05 00:18:22 +0000416 Block->ComputeSize(Asm);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000417 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000418 Die->addValue(Attribute, Block->BestForm(), Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000419}
420
Devang Patel2c4ceb12009-11-21 02:48:08 +0000421/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000422/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000423void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
Bill Wendling0310d762009-05-15 09:23:25 +0000424 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000425 if (!V->getCompileUnit().Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000426 return;
427
428 unsigned Line = V->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000429 unsigned FileID = GetOrCreateSourceID(V->getContext().getDirectory(),
430 V->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000431 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000432 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
433 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000434}
435
Devang Patel2c4ceb12009-11-21 02:48:08 +0000436/// addSourceLine - Add location information to specified debug information
Bill Wendling0310d762009-05-15 09:23:25 +0000437/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000438void DwarfDebug::addSourceLine(DIE *Die, const DIGlobal *G) {
Bill Wendling0310d762009-05-15 09:23:25 +0000439 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000440 if (!G->getCompileUnit().Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000441 return;
442
443 unsigned Line = G->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000444 unsigned FileID = GetOrCreateSourceID(G->getContext().getDirectory(),
445 G->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000446 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000447 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
448 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000449}
Devang Patel82dfc0c2009-08-31 22:47:13 +0000450
Devang Patel2c4ceb12009-11-21 02:48:08 +0000451/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000452/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000453void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
Devang Patel82dfc0c2009-08-31 22:47:13 +0000454 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000455 if (!SP->getCompileUnit().Verify())
Devang Patel82dfc0c2009-08-31 22:47:13 +0000456 return;
Caroline Ticec6f9d622009-09-11 18:25:54 +0000457 // If the line number is 0, don't add it.
458 if (SP->getLineNumber() == 0)
459 return;
460
Devang Patel82dfc0c2009-08-31 22:47:13 +0000461 unsigned Line = SP->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000462 if (!SP->getContext().Verify())
463 return;
Devang Patel9bb59a22010-03-24 21:30:35 +0000464 unsigned FileID = GetOrCreateSourceID(SP->getDirectory(),
465 SP->getFilename());
Devang Patel82dfc0c2009-08-31 22:47:13 +0000466 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000467 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
468 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Devang Patel82dfc0c2009-08-31 22:47:13 +0000469}
470
Devang Patel2c4ceb12009-11-21 02:48:08 +0000471/// addSourceLine - Add location information to specified debug information
Devang Patel82dfc0c2009-08-31 22:47:13 +0000472/// entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000473void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
Bill Wendling0310d762009-05-15 09:23:25 +0000474 // If there is no compile unit specified, don't add a line #.
475 DICompileUnit CU = Ty->getCompileUnit();
Devang Patel3c91b052010-03-08 20:52:55 +0000476 if (!CU.Verify())
Bill Wendling0310d762009-05-15 09:23:25 +0000477 return;
478
479 unsigned Line = Ty->getLineNumber();
Devang Patel77bf2952010-03-08 22:02:50 +0000480 if (!Ty->getContext().Verify())
481 return;
482 unsigned FileID = GetOrCreateSourceID(Ty->getContext().getDirectory(),
483 Ty->getContext().getFilename());
Bill Wendling0310d762009-05-15 09:23:25 +0000484 assert(FileID && "Invalid file id");
Devang Patel2c4ceb12009-11-21 02:48:08 +0000485 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
486 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling0310d762009-05-15 09:23:25 +0000487}
488
Devang Patel6404e4e2009-12-15 19:16:48 +0000489/// addSourceLine - Add location information to specified debug information
490/// entry.
491void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) {
492 // If there is no compile unit specified, don't add a line #.
Devang Patel3c91b052010-03-08 20:52:55 +0000493 if (!NS->getCompileUnit().Verify())
Devang Patel6404e4e2009-12-15 19:16:48 +0000494 return;
495
496 unsigned Line = NS->getLineNumber();
497 StringRef FN = NS->getFilename();
498 StringRef Dir = NS->getDirectory();
499
500 unsigned FileID = GetOrCreateSourceID(Dir, FN);
501 assert(FileID && "Invalid file id");
502 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
503 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
504}
505
Caroline Ticedc8f6042009-08-31 21:19:37 +0000506/* Byref variables, in Blocks, are declared by the programmer as
507 "SomeType VarName;", but the compiler creates a
508 __Block_byref_x_VarName struct, and gives the variable VarName
509 either the struct, or a pointer to the struct, as its type. This
510 is necessary for various behind-the-scenes things the compiler
511 needs to do with by-reference variables in blocks.
512
513 However, as far as the original *programmer* is concerned, the
514 variable should still have type 'SomeType', as originally declared.
515
516 The following function dives into the __Block_byref_x_VarName
517 struct to find the original type of the variable. This will be
518 passed back to the code generating the type for the Debug
519 Information Entry for the variable 'VarName'. 'VarName' will then
520 have the original type 'SomeType' in its debug information.
521
522 The original type 'SomeType' will be the type of the field named
523 'VarName' inside the __Block_byref_x_VarName struct.
524
525 NOTE: In order for this to not completely fail on the debugger
526 side, the Debug Information Entry for the variable VarName needs to
527 have a DW_AT_location that tells the debugger how to unwind through
528 the pointers and __Block_byref_x_VarName struct to find the actual
Devang Patel2c4ceb12009-11-21 02:48:08 +0000529 value of the variable. The function addBlockByrefType does this. */
Caroline Ticedc8f6042009-08-31 21:19:37 +0000530
531/// Find the type the programmer originally declared the variable to be
532/// and return that type.
533///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000534DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000535
536 DIType subType = Ty;
537 unsigned tag = Ty.getTag();
538
539 if (tag == dwarf::DW_TAG_pointer_type) {
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000540 DIDerivedType DTy = DIDerivedType(Ty.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000541 subType = DTy.getTypeDerivedFrom();
542 }
543
544 DICompositeType blockStruct = DICompositeType(subType.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000545 DIArray Elements = blockStruct.getTypeArray();
546
Caroline Ticedc8f6042009-08-31 21:19:37 +0000547 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
548 DIDescriptor Element = Elements.getElement(i);
549 DIDerivedType DT = DIDerivedType(Element.getNode());
Devang Patel65dbc902009-11-25 17:36:49 +0000550 if (Name == DT.getName())
Caroline Ticedc8f6042009-08-31 21:19:37 +0000551 return (DT.getTypeDerivedFrom());
552 }
553
554 return Ty;
555}
556
Devang Patel2c4ceb12009-11-21 02:48:08 +0000557/// addComplexAddress - Start with the address based on the location provided,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000558/// and generate the DWARF information necessary to find the actual variable
559/// given the extra address information encoded in the DIVariable, starting from
560/// the starting location. Add the DWARF information to the die.
561///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000562void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000563 unsigned Attribute,
564 const MachineLocation &Location) {
565 const DIVariable &VD = DV->getVariable();
566 DIType Ty = VD.getType();
567
568 // Decode the original location, and use that as the start of the byref
569 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000570 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000571 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000572 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000573
574 if (Location.isReg()) {
575 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000576 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000577 } else {
578 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000579 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
580 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000581 }
582 } else {
583 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000584 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000585 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000586 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
587 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000588 }
589
Devang Patel2c4ceb12009-11-21 02:48:08 +0000590 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000591 }
592
593 for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) {
594 uint64_t Element = VD.getAddrElement(i);
595
596 if (Element == DIFactory::OpPlus) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000597 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
598 addUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i));
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000599 } else if (Element == DIFactory::OpDeref) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000600 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000601 } else llvm_unreachable("unknown DIFactory Opcode");
602 }
603
604 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000605 addBlock(Die, Attribute, 0, Block);
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000606}
607
Caroline Ticedc8f6042009-08-31 21:19:37 +0000608/* Byref variables, in Blocks, are declared by the programmer as "SomeType
609 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
610 gives the variable VarName either the struct, or a pointer to the struct, as
611 its type. This is necessary for various behind-the-scenes things the
612 compiler needs to do with by-reference variables in Blocks.
613
614 However, as far as the original *programmer* is concerned, the variable
615 should still have type 'SomeType', as originally declared.
616
Devang Patel2c4ceb12009-11-21 02:48:08 +0000617 The function getBlockByrefType dives into the __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000618 struct to find the original type of the variable, which is then assigned to
619 the variable's Debug Information Entry as its real type. So far, so good.
620 However now the debugger will expect the variable VarName to have the type
621 SomeType. So we need the location attribute for the variable to be an
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000622 expression that explains to the debugger how to navigate through the
Caroline Ticedc8f6042009-08-31 21:19:37 +0000623 pointers and struct to find the actual variable of type SomeType.
624
625 The following function does just that. We start by getting
626 the "normal" location for the variable. This will be the location
627 of either the struct __Block_byref_x_VarName or the pointer to the
628 struct __Block_byref_x_VarName.
629
630 The struct will look something like:
631
632 struct __Block_byref_x_VarName {
633 ... <various fields>
634 struct __Block_byref_x_VarName *forwarding;
635 ... <various other fields>
636 SomeType VarName;
637 ... <maybe more fields>
638 };
639
640 If we are given the struct directly (as our starting point) we
641 need to tell the debugger to:
642
643 1). Add the offset of the forwarding field.
644
Dan Gohmanf451cb82010-02-10 16:03:48 +0000645 2). Follow that pointer to get the real __Block_byref_x_VarName
Caroline Ticedc8f6042009-08-31 21:19:37 +0000646 struct to use (the real one may have been copied onto the heap).
647
648 3). Add the offset for the field VarName, to find the actual variable.
649
650 If we started with a pointer to the struct, then we need to
651 dereference that pointer first, before the other steps.
652 Translating this into DWARF ops, we will need to append the following
653 to the current location description for the variable:
654
655 DW_OP_deref -- optional, if we start with a pointer
656 DW_OP_plus_uconst <forward_fld_offset>
657 DW_OP_deref
658 DW_OP_plus_uconst <varName_fld_offset>
659
660 That is what this function does. */
661
Devang Patel2c4ceb12009-11-21 02:48:08 +0000662/// addBlockByrefAddress - Start with the address based on the location
Caroline Ticedc8f6042009-08-31 21:19:37 +0000663/// provided, and generate the DWARF information necessary to find the
664/// actual Block variable (navigating the Block struct) based on the
665/// starting location. Add the DWARF information to the die. For
666/// more information, read large comment just above here.
667///
Devang Patel2c4ceb12009-11-21 02:48:08 +0000668void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
Daniel Dunbar00564992009-09-19 20:40:14 +0000669 unsigned Attribute,
670 const MachineLocation &Location) {
Caroline Ticedc8f6042009-08-31 21:19:37 +0000671 const DIVariable &VD = DV->getVariable();
672 DIType Ty = VD.getType();
673 DIType TmpTy = Ty;
674 unsigned Tag = Ty.getTag();
675 bool isPointer = false;
676
Devang Patel65dbc902009-11-25 17:36:49 +0000677 StringRef varName = VD.getName();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000678
679 if (Tag == dwarf::DW_TAG_pointer_type) {
Mike Stump3e4c9bd2009-09-30 00:08:22 +0000680 DIDerivedType DTy = DIDerivedType(Ty.getNode());
Caroline Ticedc8f6042009-08-31 21:19:37 +0000681 TmpTy = DTy.getTypeDerivedFrom();
682 isPointer = true;
683 }
684
685 DICompositeType blockStruct = DICompositeType(TmpTy.getNode());
686
Daniel Dunbar00564992009-09-19 20:40:14 +0000687 // Find the __forwarding field and the variable field in the __Block_byref
688 // struct.
Daniel Dunbar00564992009-09-19 20:40:14 +0000689 DIArray Fields = blockStruct.getTypeArray();
690 DIDescriptor varField = DIDescriptor();
691 DIDescriptor forwardingField = DIDescriptor();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000692
Daniel Dunbar00564992009-09-19 20:40:14 +0000693 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
694 DIDescriptor Element = Fields.getElement(i);
695 DIDerivedType DT = DIDerivedType(Element.getNode());
Devang Patel65dbc902009-11-25 17:36:49 +0000696 StringRef fieldName = DT.getName();
697 if (fieldName == "__forwarding")
Daniel Dunbar00564992009-09-19 20:40:14 +0000698 forwardingField = Element;
Devang Patel65dbc902009-11-25 17:36:49 +0000699 else if (fieldName == varName)
Daniel Dunbar00564992009-09-19 20:40:14 +0000700 varField = Element;
701 }
Daniel Dunbarf612ff62009-09-19 20:40:05 +0000702
Daniel Dunbar00564992009-09-19 20:40:14 +0000703 // Get the offsets for the forwarding field and the variable field.
Chris Lattner1d65ba72010-03-31 06:06:37 +0000704 unsigned forwardingFieldOffset =
Daniel Dunbar00564992009-09-19 20:40:14 +0000705 DIDerivedType(forwardingField.getNode()).getOffsetInBits() >> 3;
Chris Lattner1d65ba72010-03-31 06:06:37 +0000706 unsigned varFieldOffset =
Daniel Dunbar00564992009-09-19 20:40:14 +0000707 DIDerivedType(varField.getNode()).getOffsetInBits() >> 3;
Caroline Ticedc8f6042009-08-31 21:19:37 +0000708
Mike Stump7e3720d2009-09-24 23:21:26 +0000709 // Decode the original location, and use that as the start of the byref
710 // variable's location.
Chris Lattnerd38fee82010-04-05 00:13:49 +0000711 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Daniel Dunbar00564992009-09-19 20:40:14 +0000712 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000713 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Caroline Ticedc8f6042009-08-31 21:19:37 +0000714
Daniel Dunbar00564992009-09-19 20:40:14 +0000715 if (Location.isReg()) {
716 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000717 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000718 else {
719 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000720 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
721 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000722 }
723 } else {
724 if (Reg < 32)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000725 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000726 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000727 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
728 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbar00564992009-09-19 20:40:14 +0000729 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000730
Devang Patel2c4ceb12009-11-21 02:48:08 +0000731 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Daniel Dunbar00564992009-09-19 20:40:14 +0000732 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000733
Mike Stump7e3720d2009-09-24 23:21:26 +0000734 // If we started with a pointer to the __Block_byref... struct, then
Daniel Dunbar00564992009-09-19 20:40:14 +0000735 // the first thing we need to do is dereference the pointer (DW_OP_deref).
Daniel Dunbar00564992009-09-19 20:40:14 +0000736 if (isPointer)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000737 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000738
Daniel Dunbar00564992009-09-19 20:40:14 +0000739 // Next add the offset for the '__forwarding' field:
740 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
741 // adding the offset if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000742 if (forwardingFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000743 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
744 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000745 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000746
Daniel Dunbar00564992009-09-19 20:40:14 +0000747 // Now dereference the __forwarding field to get to the real __Block_byref
748 // struct: DW_OP_deref.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000749 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000750
Daniel Dunbar00564992009-09-19 20:40:14 +0000751 // Now that we've got the real __Block_byref... struct, add the offset
752 // for the variable's field to get to the location of the actual variable:
753 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
Daniel Dunbar00564992009-09-19 20:40:14 +0000754 if (varFieldOffset > 0) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000755 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
756 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
Daniel Dunbar00564992009-09-19 20:40:14 +0000757 }
Caroline Ticedc8f6042009-08-31 21:19:37 +0000758
Daniel Dunbar00564992009-09-19 20:40:14 +0000759 // Now attach the location information to the DIE.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000760 addBlock(Die, Attribute, 0, Block);
Caroline Ticedc8f6042009-08-31 21:19:37 +0000761}
762
Devang Patel2c4ceb12009-11-21 02:48:08 +0000763/// addAddress - Add an address attribute to a die based on the location
Bill Wendling0310d762009-05-15 09:23:25 +0000764/// provided.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000765void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
Bill Wendling0310d762009-05-15 09:23:25 +0000766 const MachineLocation &Location) {
Chris Lattnerd38fee82010-04-05 00:13:49 +0000767 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling0310d762009-05-15 09:23:25 +0000768 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer345ef342010-03-31 19:34:01 +0000769 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Bill Wendling0310d762009-05-15 09:23:25 +0000770
771 if (Location.isReg()) {
772 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000773 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000774 } else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000775 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
776 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000777 }
778 } else {
779 if (Reg < 32) {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000780 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000781 } else {
Devang Patel2c4ceb12009-11-21 02:48:08 +0000782 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
783 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling0310d762009-05-15 09:23:25 +0000784 }
785
Devang Patel2c4ceb12009-11-21 02:48:08 +0000786 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Bill Wendling0310d762009-05-15 09:23:25 +0000787 }
788
Devang Patel2c4ceb12009-11-21 02:48:08 +0000789 addBlock(Die, Attribute, 0, Block);
Bill Wendling0310d762009-05-15 09:23:25 +0000790}
791
Devang Patelc366f832009-12-10 19:14:49 +0000792/// addToContextOwner - Add Die into the list of its context owner's children.
793void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
Devang Patel3c91b052010-03-08 20:52:55 +0000794 if (Context.isType()) {
Devang Patelc366f832009-12-10 19:14:49 +0000795 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context.getNode()));
796 ContextDIE->addChild(Die);
Devang Patel6404e4e2009-12-15 19:16:48 +0000797 } else if (Context.isNameSpace()) {
798 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context.getNode()));
799 ContextDIE->addChild(Die);
Devang Patelc366f832009-12-10 19:14:49 +0000800 } else if (DIE *ContextDIE = ModuleCU->getDIE(Context.getNode()))
801 ContextDIE->addChild(Die);
802 else
803 ModuleCU->addDie(Die);
804}
805
Devang Patel16ced732009-12-10 18:05:33 +0000806/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
807/// given DIType.
808DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
809 DIE *TyDIE = ModuleCU->getDIE(Ty.getNode());
810 if (TyDIE)
811 return TyDIE;
812
813 // Create new type.
814 TyDIE = new DIE(dwarf::DW_TAG_base_type);
815 ModuleCU->insertDIE(Ty.getNode(), TyDIE);
816 if (Ty.isBasicType())
817 constructTypeDIE(*TyDIE, DIBasicType(Ty.getNode()));
818 else if (Ty.isCompositeType())
819 constructTypeDIE(*TyDIE, DICompositeType(Ty.getNode()));
820 else {
821 assert(Ty.isDerivedType() && "Unknown kind of DIType");
822 constructTypeDIE(*TyDIE, DIDerivedType(Ty.getNode()));
823 }
824
Devang Patelc366f832009-12-10 19:14:49 +0000825 addToContextOwner(TyDIE, Ty.getContext());
Devang Patel16ced732009-12-10 18:05:33 +0000826 return TyDIE;
827}
828
Devang Patel2c4ceb12009-11-21 02:48:08 +0000829/// addType - Add a new type attribute to the specified entity.
Devang Patel8a241142009-12-09 18:24:21 +0000830void DwarfDebug::addType(DIE *Entity, DIType Ty) {
Devang Patel3c91b052010-03-08 20:52:55 +0000831 if (!Ty.isValid())
Bill Wendling0310d762009-05-15 09:23:25 +0000832 return;
833
834 // Check for pre-existence.
Devang Patel8a241142009-12-09 18:24:21 +0000835 DIEEntry *Entry = ModuleCU->getDIEEntry(Ty.getNode());
Bill Wendling0310d762009-05-15 09:23:25 +0000836 // If it exists then use the existing value.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000837 if (Entry) {
838 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000839 return;
840 }
841
Bill Wendling0310d762009-05-15 09:23:25 +0000842 // Construct type.
Devang Patel16ced732009-12-10 18:05:33 +0000843 DIE *Buffer = getOrCreateTypeDIE(Ty);
Bill Wendling0310d762009-05-15 09:23:25 +0000844
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +0000845 // Set up proxy.
846 Entry = createDIEEntry(Buffer);
847 ModuleCU->insertDIEEntry(Ty.getNode(), Entry);
848
Devang Patel2c4ceb12009-11-21 02:48:08 +0000849 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling0310d762009-05-15 09:23:25 +0000850}
851
Devang Patel2c4ceb12009-11-21 02:48:08 +0000852/// constructTypeDIE - Construct basic type die from DIBasicType.
Devang Patel8a241142009-12-09 18:24:21 +0000853void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000854 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000855 StringRef Name = BTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000856 Buffer.setTag(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +0000857 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Bill Wendling0310d762009-05-15 09:23:25 +0000858 BTy.getEncoding());
859
860 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +0000861 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000862 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000863 uint64_t Size = BTy.getSizeInBits() >> 3;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000864 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000865}
866
Devang Patel2c4ceb12009-11-21 02:48:08 +0000867/// constructTypeDIE - Construct derived type die from DIDerivedType.
Devang Patel8a241142009-12-09 18:24:21 +0000868void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000869 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000870 StringRef Name = DTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000871 uint64_t Size = DTy.getSizeInBits() >> 3;
872 unsigned Tag = DTy.getTag();
873
874 // FIXME - Workaround for templates.
875 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
876
877 Buffer.setTag(Tag);
878
879 // Map to main type, void will not have a type.
880 DIType FromTy = DTy.getTypeDerivedFrom();
Devang Patel8a241142009-12-09 18:24:21 +0000881 addType(&Buffer, FromTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000882
883 // Add name if not anonymous or intermediate type.
Devang Pateldeea5642009-11-30 23:56:56 +0000884 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000885 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000886
887 // Add size if non-zero (derived types might be zero-sized.)
888 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000889 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +0000890
891 // Add source line info if available and TyDesc is not a forward declaration.
Devang Patel05f6fa82009-11-23 18:43:37 +0000892 if (!DTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000893 addSourceLine(&Buffer, &DTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000894}
895
Devang Patel2c4ceb12009-11-21 02:48:08 +0000896/// constructTypeDIE - Construct type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +0000897void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Bill Wendling0310d762009-05-15 09:23:25 +0000898 // Get core information.
Devang Patel65dbc902009-11-25 17:36:49 +0000899 StringRef Name = CTy.getName();
Bill Wendling0310d762009-05-15 09:23:25 +0000900
901 uint64_t Size = CTy.getSizeInBits() >> 3;
902 unsigned Tag = CTy.getTag();
903 Buffer.setTag(Tag);
904
905 switch (Tag) {
906 case dwarf::DW_TAG_vector_type:
907 case dwarf::DW_TAG_array_type:
Devang Patel8a241142009-12-09 18:24:21 +0000908 constructArrayTypeDIE(Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +0000909 break;
910 case dwarf::DW_TAG_enumeration_type: {
911 DIArray Elements = CTy.getTypeArray();
912
913 // Add enumerators to enumeration type.
914 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
915 DIE *ElemDie = NULL;
Devang Patel3c91b052010-03-08 20:52:55 +0000916 DIDescriptor Enum(Elements.getElement(i).getNode());
917 if (Enum.isEnumerator()) {
918 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum.getNode()));
Devang Patel2c4ceb12009-11-21 02:48:08 +0000919 Buffer.addChild(ElemDie);
Devang Patelc5254722009-10-09 17:51:49 +0000920 }
Bill Wendling0310d762009-05-15 09:23:25 +0000921 }
922 }
923 break;
924 case dwarf::DW_TAG_subroutine_type: {
925 // Add return type.
926 DIArray Elements = CTy.getTypeArray();
927 DIDescriptor RTy = Elements.getElement(0);
Devang Patel8a241142009-12-09 18:24:21 +0000928 addType(&Buffer, DIType(RTy.getNode()));
Bill Wendling0310d762009-05-15 09:23:25 +0000929
930 // Add prototype flag.
Devang Patel2c4ceb12009-11-21 02:48:08 +0000931 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +0000932
933 // Add arguments.
934 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
935 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
936 DIDescriptor Ty = Elements.getElement(i);
Devang Patel8a241142009-12-09 18:24:21 +0000937 addType(Arg, DIType(Ty.getNode()));
Devang Patel2c4ceb12009-11-21 02:48:08 +0000938 Buffer.addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +0000939 }
940 }
941 break;
942 case dwarf::DW_TAG_structure_type:
943 case dwarf::DW_TAG_union_type:
944 case dwarf::DW_TAG_class_type: {
945 // Add elements to structure type.
946 DIArray Elements = CTy.getTypeArray();
947
948 // A forward struct declared type may not have elements available.
Devang Patel3c91b052010-03-08 20:52:55 +0000949 unsigned N = Elements.getNumElements();
950 if (N == 0)
Bill Wendling0310d762009-05-15 09:23:25 +0000951 break;
952
953 // Add elements to structure type.
Devang Patel3c91b052010-03-08 20:52:55 +0000954 for (unsigned i = 0; i < N; ++i) {
Bill Wendling0310d762009-05-15 09:23:25 +0000955 DIDescriptor Element = Elements.getElement(i);
956 DIE *ElemDie = NULL;
Devang Patel3c91b052010-03-08 20:52:55 +0000957 if (Element.isSubprogram())
Devang Patelffe966c2009-12-14 16:18:45 +0000958 ElemDie = createSubprogramDIE(DISubprogram(Element.getNode()));
Devang Patel3c91b052010-03-08 20:52:55 +0000959 else if (Element.isVariable()) {
Devang Patel1ee0cb92010-01-30 01:08:30 +0000960 DIVariable DV(Element.getNode());
961 ElemDie = new DIE(dwarf::DW_TAG_variable);
962 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
963 DV.getName());
964 addType(ElemDie, DV.getType());
965 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
966 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
967 addSourceLine(ElemDie, &DV);
Devang Patel3c91b052010-03-08 20:52:55 +0000968 } else if (Element.isDerivedType())
Devang Patel8a241142009-12-09 18:24:21 +0000969 ElemDie = createMemberDIE(DIDerivedType(Element.getNode()));
Devang Patel3c91b052010-03-08 20:52:55 +0000970 else
971 continue;
Devang Patel2c4ceb12009-11-21 02:48:08 +0000972 Buffer.addChild(ElemDie);
Bill Wendling0310d762009-05-15 09:23:25 +0000973 }
974
Devang Patela1ba2692009-08-27 23:51:51 +0000975 if (CTy.isAppleBlockExtension())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000976 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +0000977
978 unsigned RLang = CTy.getRunTimeLang();
979 if (RLang)
Devang Patel2c4ceb12009-11-21 02:48:08 +0000980 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
Bill Wendling0310d762009-05-15 09:23:25 +0000981 dwarf::DW_FORM_data1, RLang);
Devang Patelb5544992010-01-26 21:16:06 +0000982
983 DICompositeType ContainingType = CTy.getContainingType();
Devang Patel3c91b052010-03-08 20:52:55 +0000984 if (DIDescriptor(ContainingType.getNode()).isCompositeType())
Devang Patelb5544992010-01-26 21:16:06 +0000985 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
986 getOrCreateTypeDIE(DIType(ContainingType.getNode())));
Bill Wendling0310d762009-05-15 09:23:25 +0000987 break;
988 }
989 default:
990 break;
991 }
992
993 // Add name if not anonymous or intermediate type.
Devang Patel65dbc902009-11-25 17:36:49 +0000994 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +0000995 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling0310d762009-05-15 09:23:25 +0000996
Devang Patel8cbb6122010-01-29 18:34:58 +0000997 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type ||
Bill Wendling0310d762009-05-15 09:23:25 +0000998 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
999 // Add size if non-zero (derived types might be zero-sized.)
1000 if (Size)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001001 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling0310d762009-05-15 09:23:25 +00001002 else {
1003 // Add zero size if it is not a forward declaration.
1004 if (CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001005 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001006 else
Devang Patel2c4ceb12009-11-21 02:48:08 +00001007 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
Bill Wendling0310d762009-05-15 09:23:25 +00001008 }
1009
1010 // Add source line info if available.
1011 if (!CTy.isForwardDecl())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001012 addSourceLine(&Buffer, &CTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001013 }
1014}
1015
Devang Patel2c4ceb12009-11-21 02:48:08 +00001016/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1017void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
Bill Wendling0310d762009-05-15 09:23:25 +00001018 int64_t L = SR.getLo();
1019 int64_t H = SR.getHi();
1020 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1021
Devang Patel2c4ceb12009-11-21 02:48:08 +00001022 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patel6325a532009-08-14 20:59:16 +00001023 if (L)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001024 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
Devang Pateld55224c2009-12-04 23:10:24 +00001025 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Bill Wendling0310d762009-05-15 09:23:25 +00001026
Devang Patel2c4ceb12009-11-21 02:48:08 +00001027 Buffer.addChild(DW_Subrange);
Bill Wendling0310d762009-05-15 09:23:25 +00001028}
1029
Devang Patel2c4ceb12009-11-21 02:48:08 +00001030/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
Devang Patel8a241142009-12-09 18:24:21 +00001031void DwarfDebug::constructArrayTypeDIE(DIE &Buffer,
Bill Wendling0310d762009-05-15 09:23:25 +00001032 DICompositeType *CTy) {
1033 Buffer.setTag(dwarf::DW_TAG_array_type);
1034 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001035 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001036
1037 // Emit derived type.
Devang Patel8a241142009-12-09 18:24:21 +00001038 addType(&Buffer, CTy->getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001039 DIArray Elements = CTy->getTypeArray();
1040
Devang Patel6f01d9c2009-11-21 00:31:03 +00001041 // Get an anonymous type for index type.
Devang Patel8a241142009-12-09 18:24:21 +00001042 DIE *IdxTy = ModuleCU->getIndexTyDie();
Devang Patel6f01d9c2009-11-21 00:31:03 +00001043 if (!IdxTy) {
1044 // Construct an anonymous type for index type.
1045 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001046 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1047 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel6f01d9c2009-11-21 00:31:03 +00001048 dwarf::DW_ATE_signed);
Devang Patel8a241142009-12-09 18:24:21 +00001049 ModuleCU->addDie(IdxTy);
1050 ModuleCU->setIndexTyDie(IdxTy);
Devang Patel6f01d9c2009-11-21 00:31:03 +00001051 }
Bill Wendling0310d762009-05-15 09:23:25 +00001052
1053 // Add subranges to array type.
1054 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1055 DIDescriptor Element = Elements.getElement(i);
1056 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001057 constructSubrangeDIE(Buffer, DISubrange(Element.getNode()), IdxTy);
Bill Wendling0310d762009-05-15 09:23:25 +00001058 }
1059}
1060
Devang Patel2c4ceb12009-11-21 02:48:08 +00001061/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
Devang Patel3c91b052010-03-08 20:52:55 +00001062DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) {
Bill Wendling0310d762009-05-15 09:23:25 +00001063 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
Devang Patel3c91b052010-03-08 20:52:55 +00001064 StringRef Name = ETy.getName();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001065 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel3c91b052010-03-08 20:52:55 +00001066 int64_t Value = ETy.getEnumValue();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001067 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
Bill Wendling0310d762009-05-15 09:23:25 +00001068 return Enumerator;
1069}
1070
Devang Patel351ca332010-01-05 01:46:14 +00001071/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1072/// printer to not emit usual symbol prefix before the symbol name is used then
1073/// return linkage name after skipping this special LLVM prefix.
1074static StringRef getRealLinkageName(StringRef LinkageName) {
1075 char One = '\1';
1076 if (LinkageName.startswith(StringRef(&One, 1)))
1077 return LinkageName.substr(1);
1078 return LinkageName;
1079}
1080
Devang Patel2c4ceb12009-11-21 02:48:08 +00001081/// createGlobalVariableDIE - Create new DIE using GV.
Devang Patel8a241142009-12-09 18:24:21 +00001082DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001083 // If the global variable was optmized out then no need to create debug info
1084 // entry.
Devang Patel84c73e92009-11-06 17:58:12 +00001085 if (!GV.getGlobal()) return NULL;
Devang Patel65dbc902009-11-25 17:36:49 +00001086 if (GV.getDisplayName().empty()) return NULL;
Devang Patel465c3be2009-11-06 01:30:04 +00001087
Bill Wendling0310d762009-05-15 09:23:25 +00001088 DIE *GVDie = new DIE(dwarf::DW_TAG_variable);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001089 addString(GVDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001090 GV.getDisplayName());
1091
Devang Patel65dbc902009-11-25 17:36:49 +00001092 StringRef LinkageName = GV.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001093 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001094 addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001095 getRealLinkageName(LinkageName));
1096
Devang Patel8a241142009-12-09 18:24:21 +00001097 addType(GVDie, GV.getType());
Bill Wendling0310d762009-05-15 09:23:25 +00001098 if (!GV.isLocalToUnit())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001099 addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1100 addSourceLine(GVDie, &GV);
Devang Patelb71a16d2009-10-05 23:22:08 +00001101
Bill Wendling0310d762009-05-15 09:23:25 +00001102 return GVDie;
1103}
1104
Devang Patel2c4ceb12009-11-21 02:48:08 +00001105/// createMemberDIE - Create new member DIE.
Devang Patel8a241142009-12-09 18:24:21 +00001106DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
Bill Wendling0310d762009-05-15 09:23:25 +00001107 DIE *MemberDie = new DIE(DT.getTag());
Devang Patel65dbc902009-11-25 17:36:49 +00001108 StringRef Name = DT.getName();
1109 if (!Name.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001110 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel65dbc902009-11-25 17:36:49 +00001111
Devang Patel8a241142009-12-09 18:24:21 +00001112 addType(MemberDie, DT.getTypeDerivedFrom());
Bill Wendling0310d762009-05-15 09:23:25 +00001113
Devang Patel2c4ceb12009-11-21 02:48:08 +00001114 addSourceLine(MemberDie, &DT);
Bill Wendling0310d762009-05-15 09:23:25 +00001115
Benjamin Kramer345ef342010-03-31 19:34:01 +00001116 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patel2c4ceb12009-11-21 02:48:08 +00001117 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
Devang Patel33db5082009-11-04 22:06:12 +00001118
Bill Wendling0310d762009-05-15 09:23:25 +00001119 uint64_t Size = DT.getSizeInBits();
Devang Patel61ecbd12009-11-04 23:48:00 +00001120 uint64_t FieldSize = DT.getOriginalTypeSize();
Bill Wendling0310d762009-05-15 09:23:25 +00001121
1122 if (Size != FieldSize) {
1123 // Handle bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001124 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1125 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
Bill Wendling0310d762009-05-15 09:23:25 +00001126
1127 uint64_t Offset = DT.getOffsetInBits();
Bill Wendling0310d762009-05-15 09:23:25 +00001128 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1129 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
Benjamin Kramer3d594fd2010-01-07 17:50:57 +00001130 uint64_t FieldOffset = (HiMark - FieldSize);
Bill Wendling0310d762009-05-15 09:23:25 +00001131 Offset -= FieldOffset;
1132
1133 // Maybe we need to work from the other end.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001134 if (Asm->getTargetData().isLittleEndian())
1135 Offset = FieldSize - (Offset + Size);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001136 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
Bill Wendling0310d762009-05-15 09:23:25 +00001137
Devang Patel33db5082009-11-04 22:06:12 +00001138 // Here WD_AT_data_member_location points to the anonymous
1139 // field that includes this bit field.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001140 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001141
1142 } else
1143 // This is not a bitfield.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001144 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
Devang Patel33db5082009-11-04 22:06:12 +00001145
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001146 if (DT.getTag() == dwarf::DW_TAG_inheritance
1147 && DT.isVirtual()) {
1148
1149 // For C++, virtual base classes are not at fixed offset. Use following
1150 // expression to extract appropriate offset from vtable.
1151 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1152
Benjamin Kramer345ef342010-03-31 19:34:01 +00001153 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patelc1dc8ff2010-02-03 20:08:48 +00001154 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1155 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1156 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1157 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1158 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1159 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1160 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1161
1162 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1163 VBaseLocationDie);
1164 } else
1165 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
Bill Wendling0310d762009-05-15 09:23:25 +00001166
1167 if (DT.isProtected())
Devang Patel5d11eb02009-12-03 19:11:07 +00001168 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001169 dwarf::DW_ACCESS_protected);
1170 else if (DT.isPrivate())
Devang Patel5d11eb02009-12-03 19:11:07 +00001171 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling0310d762009-05-15 09:23:25 +00001172 dwarf::DW_ACCESS_private);
Devang Patel5d11eb02009-12-03 19:11:07 +00001173 else if (DT.getTag() == dwarf::DW_TAG_inheritance)
1174 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1175 dwarf::DW_ACCESS_public);
1176 if (DT.isVirtual())
1177 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1178 dwarf::DW_VIRTUALITY_virtual);
Bill Wendling0310d762009-05-15 09:23:25 +00001179 return MemberDie;
1180}
1181
Devang Patelffe966c2009-12-14 16:18:45 +00001182/// createSubprogramDIE - Create new DIE using SP.
1183DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
1184 DIE *SPDie = ModuleCU->getDIE(SP.getNode());
1185 if (SPDie)
1186 return SPDie;
1187
1188 SPDie = new DIE(dwarf::DW_TAG_subprogram);
Devang Patel1eac3e72010-03-02 17:58:15 +00001189 // Constructors and operators for anonymous aggregates do not have names.
Devang Patel6b506cb2010-03-02 01:26:20 +00001190 if (!SP.getName().empty())
1191 addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
Bill Wendling0310d762009-05-15 09:23:25 +00001192
Devang Patel65dbc902009-11-25 17:36:49 +00001193 StringRef LinkageName = SP.getLinkageName();
Devang Patel351ca332010-01-05 01:46:14 +00001194 if (!LinkageName.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001195 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel351ca332010-01-05 01:46:14 +00001196 getRealLinkageName(LinkageName));
1197
Devang Patel2c4ceb12009-11-21 02:48:08 +00001198 addSourceLine(SPDie, &SP);
Bill Wendling0310d762009-05-15 09:23:25 +00001199
Bill Wendling0310d762009-05-15 09:23:25 +00001200 // Add prototyped tag, if C or ObjC.
1201 unsigned Lang = SP.getCompileUnit().getLanguage();
1202 if (Lang == dwarf::DW_LANG_C99 || Lang == dwarf::DW_LANG_C89 ||
1203 Lang == dwarf::DW_LANG_ObjC)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001204 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001205
1206 // Add Return Type.
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001207 DICompositeType SPTy = SP.getType();
1208 DIArray Args = SPTy.getTypeArray();
Bill Wendling0310d762009-05-15 09:23:25 +00001209 unsigned SPTag = SPTy.getTag();
Devang Patel5d11eb02009-12-03 19:11:07 +00001210
Devang Patel3c91b052010-03-08 20:52:55 +00001211 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
Devang Patel8a241142009-12-09 18:24:21 +00001212 addType(SPDie, SPTy);
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001213 else
Devang Patel8a241142009-12-09 18:24:21 +00001214 addType(SPDie, DIType(Args.getElement(0).getNode()));
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001215
Devang Patel5d11eb02009-12-03 19:11:07 +00001216 unsigned VK = SP.getVirtuality();
1217 if (VK) {
1218 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001219 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel5d11eb02009-12-03 19:11:07 +00001220 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1221 addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
1222 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
Devang Patel622b0262010-01-19 06:19:05 +00001223 ContainingTypeMap.insert(std::make_pair(SPDie,
1224 SP.getContainingType().getNode()));
Devang Patel5d11eb02009-12-03 19:11:07 +00001225 }
1226
Devang Patelffe966c2009-12-14 16:18:45 +00001227 if (MakeDecl || !SP.isDefinition()) {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001228 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling0310d762009-05-15 09:23:25 +00001229
1230 // Add arguments. Do not add arguments for subprogram definition. They will
Devang Patel1d5cc1d2009-12-03 01:25:38 +00001231 // be handled while processing variables.
1232 DICompositeType SPTy = SP.getType();
1233 DIArray Args = SPTy.getTypeArray();
1234 unsigned SPTag = SPTy.getTag();
1235
Bill Wendling0310d762009-05-15 09:23:25 +00001236 if (SPTag == dwarf::DW_TAG_subroutine_type)
1237 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1238 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Devang Patelb4645642010-02-06 01:02:37 +00001239 DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
1240 addType(Arg, ATy);
1241 if (ATy.isArtificial())
1242 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001243 SPDie->addChild(Arg);
Bill Wendling0310d762009-05-15 09:23:25 +00001244 }
1245 }
1246
Devang Patel4e0d19d2010-02-03 19:57:19 +00001247 if (SP.isArtificial())
1248 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1249
Bill Wendling0310d762009-05-15 09:23:25 +00001250 // DW_TAG_inlined_subroutine may refer to this DIE.
Devang Patel8a241142009-12-09 18:24:21 +00001251 ModuleCU->insertDIE(SP.getNode(), SPDie);
Bill Wendling0310d762009-05-15 09:23:25 +00001252 return SPDie;
1253}
1254
Devang Patel8935d902010-04-01 17:16:48 +00001255/// getUpdatedDbgScope - Find DbgScope assicated with the instruction.
1256/// Update scope hierarchy. Create abstract scope if required.
Devang Patel53bb5c92009-11-10 23:06:00 +00001257DbgScope *DwarfDebug::getUpdatedDbgScope(MDNode *N, const MachineInstr *MI,
Chris Lattnered7a77b2010-03-31 05:36:29 +00001258 MDNode *InlinedAt) {
1259 assert(N && "Invalid Scope encoding!");
1260 assert(MI && "Missing machine instruction!");
Devang Patel8935d902010-04-01 17:16:48 +00001261 bool isAConcreteScope = InlinedAt != 0;
Devang Patel53bb5c92009-11-10 23:06:00 +00001262
1263 DbgScope *NScope = NULL;
1264
1265 if (InlinedAt)
1266 NScope = DbgScopeMap.lookup(InlinedAt);
1267 else
1268 NScope = DbgScopeMap.lookup(N);
Chris Lattnered7a77b2010-03-31 05:36:29 +00001269 assert(NScope && "Unable to find working scope!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001270
1271 if (NScope->getFirstInsn())
1272 return NScope;
Devang Patelaf9e8472009-10-01 20:31:14 +00001273
1274 DbgScope *Parent = NULL;
Devang Patel8935d902010-04-01 17:16:48 +00001275 if (isAConcreteScope) {
Devang Patelc90aefe2009-10-14 21:08:09 +00001276 DILocation IL(InlinedAt);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001277 Parent = getUpdatedDbgScope(IL.getScope().getNode(), MI,
Devang Patel53bb5c92009-11-10 23:06:00 +00001278 IL.getOrigLocation().getNode());
Chris Lattnered7a77b2010-03-31 05:36:29 +00001279 assert(Parent && "Unable to find Parent scope!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001280 NScope->setParent(Parent);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001281 Parent->addScope(NScope);
Devang Patel53bb5c92009-11-10 23:06:00 +00001282 } else if (DIDescriptor(N).isLexicalBlock()) {
1283 DILexicalBlock DB(N);
Devang Patel3c91b052010-03-08 20:52:55 +00001284 Parent = getUpdatedDbgScope(DB.getContext().getNode(), MI, InlinedAt);
1285 NScope->setParent(Parent);
1286 Parent->addScope(NScope);
Devang Patelc90aefe2009-10-14 21:08:09 +00001287 }
Devang Patelaf9e8472009-10-01 20:31:14 +00001288
Devang Patelbdf45cb2009-10-27 20:47:17 +00001289 NScope->setFirstInsn(MI);
Devang Patelaf9e8472009-10-01 20:31:14 +00001290
Devang Patel53bb5c92009-11-10 23:06:00 +00001291 if (!Parent && !InlinedAt) {
Devang Patel39ae3ff2009-11-11 00:31:36 +00001292 StringRef SPName = DISubprogram(N).getLinkageName();
Chris Lattnerd38fee82010-04-05 00:13:49 +00001293 if (SPName == Asm->MF->getFunction()->getName())
Devang Patel39ae3ff2009-11-11 00:31:36 +00001294 CurrentFnDbgScope = NScope;
Devang Patel53bb5c92009-11-10 23:06:00 +00001295 }
Devang Patelaf9e8472009-10-01 20:31:14 +00001296
Devang Patel8935d902010-04-01 17:16:48 +00001297 if (isAConcreteScope) {
Devang Patel53bb5c92009-11-10 23:06:00 +00001298 ConcreteScopes[InlinedAt] = NScope;
1299 getOrCreateAbstractScope(N);
1300 }
1301
Devang Patelbdf45cb2009-10-27 20:47:17 +00001302 return NScope;
Devang Patelaf9e8472009-10-01 20:31:14 +00001303}
1304
Devang Patel53bb5c92009-11-10 23:06:00 +00001305DbgScope *DwarfDebug::getOrCreateAbstractScope(MDNode *N) {
Chris Lattnered7a77b2010-03-31 05:36:29 +00001306 assert(N && "Invalid Scope encoding!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001307
1308 DbgScope *AScope = AbstractScopes.lookup(N);
1309 if (AScope)
1310 return AScope;
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001311
Devang Patel53bb5c92009-11-10 23:06:00 +00001312 DbgScope *Parent = NULL;
1313
1314 DIDescriptor Scope(N);
1315 if (Scope.isLexicalBlock()) {
1316 DILexicalBlock DB(N);
1317 DIDescriptor ParentDesc = DB.getContext();
Devang Patel3c91b052010-03-08 20:52:55 +00001318 Parent = getOrCreateAbstractScope(ParentDesc.getNode());
Devang Patel53bb5c92009-11-10 23:06:00 +00001319 }
1320
1321 AScope = new DbgScope(Parent, DIDescriptor(N), NULL);
1322
1323 if (Parent)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001324 Parent->addScope(AScope);
Devang Patel53bb5c92009-11-10 23:06:00 +00001325 AScope->setAbstractScope();
1326 AbstractScopes[N] = AScope;
1327 if (DIDescriptor(N).isSubprogram())
1328 AbstractScopesList.push_back(AScope);
1329 return AScope;
1330}
Devang Patelaf9e8472009-10-01 20:31:14 +00001331
Devang Patel5f094002010-04-06 23:53:48 +00001332/// isSubprogramContext - Return true if Context is either a subprogram
1333/// or another context nested inside a subprogram.
1334bool isSubprogramContext(MDNode *Context) {
1335 if (!Context)
1336 return false;
1337 DIDescriptor D(Context);
1338 if (D.isSubprogram())
1339 return true;
1340 if (D.isType())
1341 return isSubprogramContext(DIType(Context).getContext().getNode());
1342 return false;
1343}
1344
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001345/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
Devang Patel2c4ceb12009-11-21 02:48:08 +00001346/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
1347/// If there are global variables in this scope then create and insert
1348/// DIEs for these variables.
1349DIE *DwarfDebug::updateSubprogramScopeDIE(MDNode *SPNode) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00001350 DIE *SPDie = ModuleCU->getDIE(SPNode);
1351 assert(SPDie && "Unable to find subprogram DIE!");
1352 DISubprogram SP(SPNode);
Chris Lattner206d61e2010-03-13 07:26:18 +00001353
Chris Lattnerd38fee82010-04-05 00:13:49 +00001354 // There is not any need to generate specification DIE for a function
1355 // defined at compile unit level. If a function is defined inside another
1356 // function then gdb prefers the definition at top level and but does not
1357 // expect specification DIE in parent function. So avoid creating
1358 // specification DIE for a function defined inside a function.
1359 if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001360 !SP.getContext().isFile() &&
1361 !isSubprogramContext(SP.getContext().getNode())) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00001362 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1363
1364 // Add arguments.
1365 DICompositeType SPTy = SP.getType();
1366 DIArray Args = SPTy.getTypeArray();
1367 unsigned SPTag = SPTy.getTag();
1368 if (SPTag == dwarf::DW_TAG_subroutine_type)
1369 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1370 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1371 DIType ATy = DIType(DIType(Args.getElement(i).getNode()));
1372 addType(Arg, ATy);
1373 if (ATy.isArtificial())
1374 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1375 SPDie->addChild(Arg);
1376 }
1377 DIE *SPDeclDie = SPDie;
1378 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1379 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1380 SPDeclDie);
1381 ModuleCU->addDie(SPDie);
1382 }
1383
1384 addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1385 Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
1386 addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
1387 Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
1388 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1389 MachineLocation Location(RI->getFrameRegister(*Asm->MF));
1390 addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
Devang Patelb4645642010-02-06 01:02:37 +00001391
Chris Lattnerd38fee82010-04-05 00:13:49 +00001392 if (!DISubprogram(SPNode).isLocalToUnit())
1393 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1394
1395 return SPDie;
Devang Patel53bb5c92009-11-10 23:06:00 +00001396}
1397
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001398/// constructLexicalScope - Construct new DW_TAG_lexical_block
Devang Patel2c4ceb12009-11-21 02:48:08 +00001399/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
1400DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
Devang Patel1c246352010-04-08 16:50:29 +00001401
1402 MCSymbol *Start = InsnBeforeLabelMap.lookup(Scope->getFirstInsn());
1403 MCSymbol *End = InsnAfterLabelMap.lookup(Scope->getLastInsn());
Devang Patelaead63c2010-03-29 22:59:58 +00001404 if (Start == 0 || End == 0) return 0;
Devang Patel53bb5c92009-11-10 23:06:00 +00001405
Chris Lattnerb7db7332010-03-09 01:58:53 +00001406 assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
1407 assert(End->isDefined() && "Invalid end label for an inlined scope!");
Chris Lattnera34ec2292010-03-09 01:51:43 +00001408
Devang Patel53bb5c92009-11-10 23:06:00 +00001409 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
1410 if (Scope->isAbstractScope())
1411 return ScopeDIE;
1412
Devang Patel2c4ceb12009-11-21 02:48:08 +00001413 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
Chris Lattnerd38fee82010-04-05 00:13:49 +00001414 Start ? Start : Asm->GetTempSymbol("func_begin",
1415 Asm->getFunctionNumber()));
Devang Patel2c4ceb12009-11-21 02:48:08 +00001416 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
Chris Lattnerd38fee82010-04-05 00:13:49 +00001417 End ? End : Asm->GetTempSymbol("func_end",Asm->getFunctionNumber()));
Devang Patel53bb5c92009-11-10 23:06:00 +00001418
1419 return ScopeDIE;
1420}
1421
Devang Patel2c4ceb12009-11-21 02:48:08 +00001422/// constructInlinedScopeDIE - This scope represents inlined body of
1423/// a function. Construct DIE to represent this concrete inlined copy
1424/// of the function.
1425DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
Devang Patel1c246352010-04-08 16:50:29 +00001426 MCSymbol *StartLabel = InsnBeforeLabelMap.lookup(Scope->getFirstInsn());
1427 MCSymbol *EndLabel = InsnAfterLabelMap.lookup(Scope->getLastInsn());
Devang Patelaead63c2010-03-29 22:59:58 +00001428 if (StartLabel == 0 || EndLabel == 0) return 0;
Chris Lattner6c7dfc02010-03-09 04:48:35 +00001429
Chris Lattnerb7db7332010-03-09 01:58:53 +00001430 assert(StartLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001431 "Invalid starting label for an inlined scope!");
Chris Lattnerb7db7332010-03-09 01:58:53 +00001432 assert(EndLabel->isDefined() &&
Chris Lattnera34ec2292010-03-09 01:51:43 +00001433 "Invalid end label for an inlined scope!");
Devang Patel3c91b052010-03-08 20:52:55 +00001434 if (!Scope->getScopeNode())
Devang Patel0ef3fa62010-03-08 19:20:38 +00001435 return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001436 DIScope DS(Scope->getScopeNode());
Devang Patel53bb5c92009-11-10 23:06:00 +00001437 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
1438
1439 DISubprogram InlinedSP = getDISubprogram(DS.getNode());
Devang Patel017d1212009-11-20 21:37:22 +00001440 DIE *OriginDIE = ModuleCU->getDIE(InlinedSP.getNode());
Chris Lattnered7a77b2010-03-31 05:36:29 +00001441 assert(OriginDIE && "Unable to find Origin DIE!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001442 addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001443 dwarf::DW_FORM_ref4, OriginDIE);
1444
Chris Lattner6ed0f902010-03-09 00:31:02 +00001445 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel);
Chris Lattnerb7db7332010-03-09 01:58:53 +00001446 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel);
Devang Patel53bb5c92009-11-10 23:06:00 +00001447
1448 InlinedSubprogramDIEs.insert(OriginDIE);
1449
1450 // Track the start label for this inlined function.
Devang Patel622b0262010-01-19 06:19:05 +00001451 DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
Devang Patel53bb5c92009-11-10 23:06:00 +00001452 I = InlineInfo.find(InlinedSP.getNode());
1453
1454 if (I == InlineInfo.end()) {
Chris Lattner6ed0f902010-03-09 00:31:02 +00001455 InlineInfo[InlinedSP.getNode()].push_back(std::make_pair(StartLabel,
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001456 ScopeDIE));
Devang Patel53bb5c92009-11-10 23:06:00 +00001457 InlinedSPNodes.push_back(InlinedSP.getNode());
1458 } else
Chris Lattner6ed0f902010-03-09 00:31:02 +00001459 I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
Devang Patel53bb5c92009-11-10 23:06:00 +00001460
Devang Patel53bb5c92009-11-10 23:06:00 +00001461 DILocation DL(Scope->getInlinedAt());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001462 addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, ModuleCU->getID());
1463 addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
Devang Patel53bb5c92009-11-10 23:06:00 +00001464
1465 return ScopeDIE;
1466}
1467
Devang Patel2c4ceb12009-11-21 02:48:08 +00001468
1469/// constructVariableDIE - Construct a DIE for the given DbgVariable.
Devang Patel8a241142009-12-09 18:24:21 +00001470DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
Devang Patel53bb5c92009-11-10 23:06:00 +00001471 // Get the descriptor.
1472 const DIVariable &VD = DV->getVariable();
Devang Patel65dbc902009-11-25 17:36:49 +00001473 StringRef Name = VD.getName();
1474 if (Name.empty())
Devang Patel3fb6bd62009-11-13 02:25:26 +00001475 return NULL;
Devang Patel53bb5c92009-11-10 23:06:00 +00001476
1477 // Translate tag to proper Dwarf tag. The result variable is dropped for
1478 // now.
1479 unsigned Tag;
1480 switch (VD.getTag()) {
1481 case dwarf::DW_TAG_return_variable:
1482 return NULL;
1483 case dwarf::DW_TAG_arg_variable:
1484 Tag = dwarf::DW_TAG_formal_parameter;
1485 break;
1486 case dwarf::DW_TAG_auto_variable: // fall thru
1487 default:
1488 Tag = dwarf::DW_TAG_variable;
1489 break;
1490 }
1491
1492 // Define variable debug information entry.
1493 DIE *VariableDie = new DIE(Tag);
1494
1495
1496 DIE *AbsDIE = NULL;
1497 if (DbgVariable *AV = DV->getAbstractVariable())
1498 AbsDIE = AV->getDIE();
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001499
Devang Patel53bb5c92009-11-10 23:06:00 +00001500 if (AbsDIE) {
1501 DIScope DS(Scope->getScopeNode());
1502 DISubprogram InlinedSP = getDISubprogram(DS.getNode());
Devang Patel017d1212009-11-20 21:37:22 +00001503 DIE *OriginSPDIE = ModuleCU->getDIE(InlinedSP.getNode());
Daniel Dunbarc0326792009-11-11 03:09:50 +00001504 (void) OriginSPDIE;
Chris Lattnered7a77b2010-03-31 05:36:29 +00001505 assert(OriginSPDIE && "Unable to find Origin DIE for the SP!");
Devang Patel53bb5c92009-11-10 23:06:00 +00001506 DIE *AbsDIE = DV->getAbstractVariable()->getDIE();
Chris Lattnered7a77b2010-03-31 05:36:29 +00001507 assert(AbsDIE && "Unable to find Origin DIE for the Variable!");
Devang Patel2c4ceb12009-11-21 02:48:08 +00001508 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
Devang Patel53bb5c92009-11-10 23:06:00 +00001509 dwarf::DW_FORM_ref4, AbsDIE);
1510 }
1511 else {
Devang Patel2c4ceb12009-11-21 02:48:08 +00001512 addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
1513 addSourceLine(VariableDie, &VD);
Devang Patel53bb5c92009-11-10 23:06:00 +00001514
1515 // Add variable type.
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001516 // FIXME: isBlockByrefVariable should be reformulated in terms of complex
Devang Patel53bb5c92009-11-10 23:06:00 +00001517 // addresses instead.
1518 if (VD.isBlockByrefVariable())
Devang Patel8a241142009-12-09 18:24:21 +00001519 addType(VariableDie, getBlockByrefType(VD.getType(), Name));
Devang Patel53bb5c92009-11-10 23:06:00 +00001520 else
Devang Patel8a241142009-12-09 18:24:21 +00001521 addType(VariableDie, VD.getType());
Devang Patel53bb5c92009-11-10 23:06:00 +00001522 }
1523
1524 // Add variable address.
1525 if (!Scope->isAbstractScope()) {
Devang Patel90a48ad2010-03-15 18:33:46 +00001526 // Check if variable is described by DBG_VALUE instruction.
1527 if (const MachineInstr *DbgValueInsn = DV->getDbgValue()) {
1528 if (DbgValueInsn->getNumOperands() == 3) {
1529 // FIXME : Handle getNumOperands != 3
1530 if (DbgValueInsn->getOperand(0).getType()
1531 == MachineOperand::MO_Register
1532 && DbgValueInsn->getOperand(0).getReg()) {
1533 MachineLocation Location;
1534 Location.set(DbgValueInsn->getOperand(0).getReg());
1535 addAddress(VariableDie, dwarf::DW_AT_location, Location);
Devang Patelaead63c2010-03-29 22:59:58 +00001536 if (MCSymbol *VS = DV->getDbgValueLabel())
1537 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1538 VS);
Devang Patel90a48ad2010-03-15 18:33:46 +00001539 } else if (DbgValueInsn->getOperand(0).getType() ==
1540 MachineOperand::MO_Immediate) {
Benjamin Kramer345ef342010-03-31 19:34:01 +00001541 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel90a48ad2010-03-15 18:33:46 +00001542 unsigned Imm = DbgValueInsn->getOperand(0).getImm();
1543 addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
1544 addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
Devang Patelaead63c2010-03-29 22:59:58 +00001545 if (MCSymbol *VS = DV->getDbgValueLabel())
1546 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1547 VS);
Bill Wendling57fbba42010-04-05 22:59:21 +00001548 } else if (DbgValueInsn->getOperand(0).getType() ==
1549 MachineOperand::MO_FPImmediate) {
1550 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
1551 APFloat FPImm = DbgValueInsn->getOperand(0).getFPImm()->getValueAPF();
1552
1553 // Get the raw data form of the floating point.
1554 const APInt FltVal = FPImm.bitcastToAPInt();
1555 const char *FltPtr = (const char*)FltVal.getRawData();
1556
John McCall795ee9d2010-04-06 23:35:53 +00001557 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
Bill Wendling57fbba42010-04-05 22:59:21 +00001558 bool LittleEndian = Asm->getTargetData().isLittleEndian();
1559 int Incr = (LittleEndian ? 1 : -1);
1560 int Start = (LittleEndian ? 0 : NumBytes - 1);
1561 int Stop = (LittleEndian ? NumBytes : -1);
1562
1563 // Output the constant to DWARF one byte at a time.
1564 for (; Start != Stop; Start += Incr)
1565 addUInt(Block, 0, dwarf::DW_FORM_data1,
1566 (unsigned char)0xFF & FltPtr[Start]);
1567
1568 addBlock(VariableDie, dwarf::DW_AT_const_value, 0, Block);
1569
1570 if (MCSymbol *VS = DV->getDbgValueLabel())
1571 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
1572 VS);
Devang Patel90a48ad2010-03-15 18:33:46 +00001573 } else {
1574 //FIXME : Handle other operand types.
1575 delete VariableDie;
1576 return NULL;
1577 }
1578 }
1579 } else {
1580 MachineLocation Location;
1581 unsigned FrameReg;
Chris Lattnerd38fee82010-04-05 00:13:49 +00001582 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1583 int Offset = RI->getFrameIndexReference(*Asm->MF, DV->getFrameIndex(),
Chris Lattner1d65ba72010-03-31 06:06:37 +00001584 FrameReg);
Devang Patel90a48ad2010-03-15 18:33:46 +00001585 Location.set(FrameReg, Offset);
1586
1587 if (VD.hasComplexAddress())
1588 addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1589 else if (VD.isBlockByrefVariable())
1590 addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1591 else
1592 addAddress(VariableDie, dwarf::DW_AT_location, Location);
1593 }
Devang Patel53bb5c92009-11-10 23:06:00 +00001594 }
Devang Patelb4645642010-02-06 01:02:37 +00001595
1596 if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
1597 addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel53bb5c92009-11-10 23:06:00 +00001598 DV->setDIE(VariableDie);
1599 return VariableDie;
1600
1601}
Devang Patel2c4ceb12009-11-21 02:48:08 +00001602
Devang Patel193f7202009-11-24 01:14:22 +00001603void DwarfDebug::addPubTypes(DISubprogram SP) {
1604 DICompositeType SPTy = SP.getType();
1605 unsigned SPTag = SPTy.getTag();
1606 if (SPTag != dwarf::DW_TAG_subroutine_type)
1607 return;
1608
1609 DIArray Args = SPTy.getTypeArray();
Devang Patel193f7202009-11-24 01:14:22 +00001610 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
1611 DIType ATy(Args.getElement(i).getNode());
Devang Patel3c91b052010-03-08 20:52:55 +00001612 if (!ATy.isValid())
Devang Patel193f7202009-11-24 01:14:22 +00001613 continue;
1614 DICompositeType CATy = getDICompositeType(ATy);
Devang Patel3c91b052010-03-08 20:52:55 +00001615 if (DIDescriptor(CATy.getNode()).Verify() && !CATy.getName().empty()) {
Devang Patel193f7202009-11-24 01:14:22 +00001616 if (DIEEntry *Entry = ModuleCU->getDIEEntry(CATy.getNode()))
1617 ModuleCU->addGlobalType(CATy.getName(), Entry->getEntry());
1618 }
1619 }
1620}
1621
Devang Patel2c4ceb12009-11-21 02:48:08 +00001622/// constructScopeDIE - Construct a DIE for this scope.
1623DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
Devang Patel3c91b052010-03-08 20:52:55 +00001624 if (!Scope || !Scope->getScopeNode())
1625 return NULL;
1626
1627 DIScope DS(Scope->getScopeNode());
1628 DIE *ScopeDIE = NULL;
1629 if (Scope->getInlinedAt())
1630 ScopeDIE = constructInlinedScopeDIE(Scope);
1631 else if (DS.isSubprogram()) {
1632 if (Scope->isAbstractScope())
1633 ScopeDIE = ModuleCU->getDIE(DS.getNode());
1634 else
1635 ScopeDIE = updateSubprogramScopeDIE(DS.getNode());
1636 }
Devang Patelaead63c2010-03-29 22:59:58 +00001637 else
Devang Patel3c91b052010-03-08 20:52:55 +00001638 ScopeDIE = constructLexicalScopeDIE(Scope);
Devang Patelaead63c2010-03-29 22:59:58 +00001639 if (!ScopeDIE) return NULL;
Devang Patel3c91b052010-03-08 20:52:55 +00001640
Devang Patel53bb5c92009-11-10 23:06:00 +00001641 // Add variables to scope.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001642 const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
Devang Patel53bb5c92009-11-10 23:06:00 +00001643 for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
Devang Patel8a241142009-12-09 18:24:21 +00001644 DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001645 if (VariableDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001646 ScopeDIE->addChild(VariableDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001647 }
1648
1649 // Add nested scopes.
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00001650 const SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes();
Devang Patel53bb5c92009-11-10 23:06:00 +00001651 for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
1652 // Define the Scope debug information entry.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001653 DIE *NestedDIE = constructScopeDIE(Scopes[j]);
Jim Grosbach31ef40e2009-11-21 23:12:12 +00001654 if (NestedDIE)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001655 ScopeDIE->addChild(NestedDIE);
Devang Patel53bb5c92009-11-10 23:06:00 +00001656 }
Devang Patel193f7202009-11-24 01:14:22 +00001657
1658 if (DS.isSubprogram())
1659 addPubTypes(DISubprogram(DS.getNode()));
1660
1661 return ScopeDIE;
Devang Patel53bb5c92009-11-10 23:06:00 +00001662}
1663
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001664/// GetOrCreateSourceID - Look up the source id with the given directory and
1665/// source file names. If none currently exists, create a new id and insert it
1666/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
1667/// maps as well.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001668unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName){
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001669 unsigned DId;
1670 StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
1671 if (DI != DirectoryIdMap.end()) {
1672 DId = DI->getValue();
1673 } else {
1674 DId = DirectoryNames.size() + 1;
1675 DirectoryIdMap[DirName] = DId;
1676 DirectoryNames.push_back(DirName);
1677 }
1678
1679 unsigned FId;
1680 StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
1681 if (FI != SourceFileIdMap.end()) {
1682 FId = FI->getValue();
1683 } else {
1684 FId = SourceFileNames.size() + 1;
1685 SourceFileIdMap[FileName] = FId;
1686 SourceFileNames.push_back(FileName);
1687 }
1688
1689 DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
1690 SourceIdMap.find(std::make_pair(DId, FId));
1691 if (SI != SourceIdMap.end())
1692 return SI->second;
1693
1694 unsigned SrcId = SourceIds.size() + 1; // DW_AT_decl_file cannot be 0.
1695 SourceIdMap[std::make_pair(DId, FId)] = SrcId;
1696 SourceIds.push_back(std::make_pair(DId, FId));
1697
1698 return SrcId;
1699}
1700
Devang Patel6404e4e2009-12-15 19:16:48 +00001701/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1702DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace NS) {
1703 DIE *NDie = ModuleCU->getDIE(NS.getNode());
1704 if (NDie)
1705 return NDie;
1706 NDie = new DIE(dwarf::DW_TAG_namespace);
1707 ModuleCU->insertDIE(NS.getNode(), NDie);
1708 if (!NS.getName().empty())
1709 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
1710 addSourceLine(NDie, &NS);
1711 addToContextOwner(NDie, NS.getContext());
1712 return NDie;
1713}
1714
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001715void DwarfDebug::constructCompileUnit(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001716 DICompileUnit DIUnit(N);
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001717 // Use first compile unit marked as isMain as the compile unit for this
1718 // module.
1719 if (ModuleCU || !DIUnit.isMain())
1720 return;
Devang Patel65dbc902009-11-25 17:36:49 +00001721 StringRef FN = DIUnit.getFilename();
1722 StringRef Dir = DIUnit.getDirectory();
Devang Patel5ccdd102009-09-29 18:40:58 +00001723 unsigned ID = GetOrCreateSourceID(Dir, FN);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001724
1725 DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
Devang Patel2c4ceb12009-11-21 02:48:08 +00001726 addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
Devang Patel5ccdd102009-09-29 18:40:58 +00001727 DIUnit.getProducer());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001728 addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001729 DIUnit.getLanguage());
Devang Patel2c4ceb12009-11-21 02:48:08 +00001730 addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
Chris Lattner9c69e285532010-04-04 22:59:04 +00001731 addLabel(Die, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, TextSectionSym);
Devang Patel4a602ca2010-03-22 23:11:36 +00001732 addLabel(Die, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
Chris Lattnerc0215722010-04-04 19:25:43 +00001733 Asm->GetTempSymbol("text_end"));
Devang Patel4a602ca2010-03-22 23:11:36 +00001734 // DW_AT_stmt_list is a offset of line number information for this
1735 // compile unit in debug_line section. It is always zero when only one
1736 // compile unit is emitted in one object file.
1737 addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001738
Devang Patel65dbc902009-11-25 17:36:49 +00001739 if (!Dir.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001740 addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001741 if (DIUnit.isOptimized())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001742 addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001743
Devang Patel65dbc902009-11-25 17:36:49 +00001744 StringRef Flags = DIUnit.getFlags();
1745 if (!Flags.empty())
Devang Patel2c4ceb12009-11-21 02:48:08 +00001746 addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001747
1748 unsigned RVer = DIUnit.getRunTimeVersion();
1749 if (RVer)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001750 addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001751 dwarf::DW_FORM_data1, RVer);
1752
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001753 assert(!ModuleCU &&
1754 "ModuleCU assigned since the top of constructCompileUnit");
1755 ModuleCU = new CompileUnit(ID, Die);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001756}
1757
Devang Patel2c4ceb12009-11-21 02:48:08 +00001758void DwarfDebug::constructGlobalVariableDIE(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001759 DIGlobalVariable DI_GV(N);
Daniel Dunbarf612ff62009-09-19 20:40:05 +00001760
Devang Patel905cf5e2009-09-04 23:59:07 +00001761 // If debug information is malformed then ignore it.
1762 if (DI_GV.Verify() == false)
1763 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001764
1765 // Check for pre-existence.
Devang Patel017d1212009-11-20 21:37:22 +00001766 if (ModuleCU->getDIE(DI_GV.getNode()))
Devang Patel13e16b62009-06-26 01:49:18 +00001767 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001768
Devang Patel8a241142009-12-09 18:24:21 +00001769 DIE *VariableDie = createGlobalVariableDIE(DI_GV);
Devang Pateledb45632009-12-10 23:25:41 +00001770 if (!VariableDie)
1771 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001772
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001773 // Add to map.
Devang Patel017d1212009-11-20 21:37:22 +00001774 ModuleCU->insertDIE(N, VariableDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001775
1776 // Add to context owner.
Devang Patelc9b16cc2010-01-15 01:12:22 +00001777 DIDescriptor GVContext = DI_GV.getContext();
1778 // Do not create specification DIE if context is either compile unit
1779 // or a subprogram.
Chris Lattner1d65ba72010-03-31 06:06:37 +00001780 if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel5f094002010-04-06 23:53:48 +00001781 !GVContext.isFile() &&
1782 !isSubprogramContext(GVContext.getNode())) {
Devang Patel6404e4e2009-12-15 19:16:48 +00001783 // Create specification DIE.
1784 DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
1785 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1786 dwarf::DW_FORM_ref4, VariableDie);
Benjamin Kramer345ef342010-03-31 19:34:01 +00001787 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001788 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001789 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001790 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001791 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Devang Patel8581e012010-02-09 01:58:33 +00001792 addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Devang Patel6404e4e2009-12-15 19:16:48 +00001793 ModuleCU->addDie(VariableSpecDIE);
1794 } else {
Benjamin Kramer345ef342010-03-31 19:34:01 +00001795 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel6404e4e2009-12-15 19:16:48 +00001796 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner4faf59a2010-03-08 22:31:46 +00001797 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattnerdeb0cba2010-03-12 21:09:07 +00001798 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel6404e4e2009-12-15 19:16:48 +00001799 addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
1800 }
Devang Patelc9b16cc2010-01-15 01:12:22 +00001801 addToContextOwner(VariableDie, GVContext);
Devang Patelc366f832009-12-10 19:14:49 +00001802
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001803 // Expose as global. FIXME - need to check external flag.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001804 ModuleCU->addGlobal(DI_GV.getName(), VariableDie);
Devang Patel193f7202009-11-24 01:14:22 +00001805
1806 DIType GTy = DI_GV.getType();
Devang Patel65dbc902009-11-25 17:36:49 +00001807 if (GTy.isCompositeType() && !GTy.getName().empty()) {
Devang Patel193f7202009-11-24 01:14:22 +00001808 DIEEntry *Entry = ModuleCU->getDIEEntry(GTy.getNode());
Chris Lattnered7a77b2010-03-31 05:36:29 +00001809 assert(Entry && "Missing global type!");
Devang Patel193f7202009-11-24 01:14:22 +00001810 ModuleCU->addGlobalType(GTy.getName(), Entry->getEntry());
1811 }
Devang Patel13e16b62009-06-26 01:49:18 +00001812 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001813}
1814
Devang Patel2c4ceb12009-11-21 02:48:08 +00001815void DwarfDebug::constructSubprogramDIE(MDNode *N) {
Devang Patele4b27562009-08-28 23:24:31 +00001816 DISubprogram SP(N);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001817
Stuart Hastings639336e2010-04-06 21:38:29 +00001818 // Check for pre-existence.
1819 if (ModuleCU->getDIE(N))
1820 return;
1821
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001822 if (!SP.isDefinition())
1823 // This is a method declaration which will be handled while constructing
1824 // class type.
Devang Patel13e16b62009-06-26 01:49:18 +00001825 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001826
Stuart Hastings639336e2010-04-06 21:38:29 +00001827 DIE *SubprogramDie = createSubprogramDIE(SP);
1828
1829 // Add to map.
1830 ModuleCU->insertDIE(N, SubprogramDie);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001831
1832 // Add to context owner.
Devang Patel6404e4e2009-12-15 19:16:48 +00001833 addToContextOwner(SubprogramDie, SP.getContext());
Devang Patel0000fad2009-12-08 23:21:45 +00001834
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001835 // Expose as global.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001836 ModuleCU->addGlobal(SP.getName(), SubprogramDie);
Devang Patel193f7202009-11-24 01:14:22 +00001837
Devang Patel13e16b62009-06-26 01:49:18 +00001838 return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001839}
1840
Devang Patel2c4ceb12009-11-21 02:48:08 +00001841/// beginModule - Emit all Dwarf sections that should come prior to the
Daniel Dunbar00564992009-09-19 20:40:14 +00001842/// content. Create global DIEs and emit initial debug info sections.
1843/// This is inovked by the target AsmPrinter.
Chris Lattner75f50722010-04-04 07:48:20 +00001844void DwarfDebug::beginModule(Module *M) {
Devang Patel78ab9e22009-07-30 18:56:46 +00001845 DebugInfoFinder DbgFinder;
1846 DbgFinder.processModule(*M);
Devang Patel13e16b62009-06-26 01:49:18 +00001847
Chris Lattnerd850ac72010-04-05 02:19:28 +00001848 bool HasDebugInfo = false;
1849
1850 // Scan all the compile-units to see if there are any marked as the main unit.
1851 // if not, we do not generate debug info.
1852 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1853 E = DbgFinder.compile_unit_end(); I != E; ++I) {
1854 if (DICompileUnit(*I).isMain()) {
1855 HasDebugInfo = true;
1856 break;
1857 }
1858 }
1859
1860 if (!HasDebugInfo) return;
1861
1862 // Tell MMI that we have debug info.
1863 MMI->setDebugInfoAvailability(true);
1864
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001865 // Emit initial sections.
Chris Lattnerd850ac72010-04-05 02:19:28 +00001866 EmitSectionLabels();
Chris Lattnerbe15beb2010-04-04 23:17:54 +00001867
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001868 // Create all the compile unit DIEs.
Devang Patel78ab9e22009-07-30 18:56:46 +00001869 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1870 E = DbgFinder.compile_unit_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001871 constructCompileUnit(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001872
Devang Patel53bb5c92009-11-10 23:06:00 +00001873 // Create DIEs for each subprogram.
Devang Patel78ab9e22009-07-30 18:56:46 +00001874 for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
1875 E = DbgFinder.subprogram_end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001876 constructSubprogramDIE(*I);
Devang Patel13e16b62009-06-26 01:49:18 +00001877
Devang Patelc366f832009-12-10 19:14:49 +00001878 // Create DIEs for each global variable.
1879 for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
1880 E = DbgFinder.global_variable_end(); I != E; ++I)
1881 constructGlobalVariableDIE(*I);
1882
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001883 // Prime section data.
Chris Lattnerf0144122009-07-28 03:13:23 +00001884 SectionMap.insert(Asm->getObjFileLowering().getTextSection());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001885
1886 // Print out .file directives to specify files for .loc directives. These are
1887 // printed out early so that they precede any .loc directives.
Chris Lattnerd38fee82010-04-05 00:13:49 +00001888 if (Asm->MAI->hasDotLocAndDotFile()) {
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001889 for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
1890 // Remember source id starts at 1.
1891 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
Chris Lattner0ad9c912010-01-22 22:09:00 +00001892 // FIXME: don't use sys::path for this! This should not depend on the
1893 // host.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001894 sys::Path FullPath(getSourceDirectoryName(Id.first));
1895 bool AppendOk =
1896 FullPath.appendComponent(getSourceFileName(Id.second));
1897 assert(AppendOk && "Could not append filename to directory!");
1898 AppendOk = false;
Chris Lattnera6594fc2010-01-25 18:58:59 +00001899 Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001900 }
1901 }
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001902}
1903
Devang Patel2c4ceb12009-11-21 02:48:08 +00001904/// endModule - Emit all Dwarf sections that should come after the content.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001905///
Devang Patel2c4ceb12009-11-21 02:48:08 +00001906void DwarfDebug::endModule() {
Bill Wendling5f017e82010-04-07 09:28:04 +00001907 if (!ModuleCU) return;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001908
Devang Patel53bb5c92009-11-10 23:06:00 +00001909 // Attach DW_AT_inline attribute with inlined subprogram DIEs.
1910 for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
1911 AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) {
1912 DIE *ISP = *AI;
Devang Patel2c4ceb12009-11-21 02:48:08 +00001913 addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
Devang Patel53bb5c92009-11-10 23:06:00 +00001914 }
1915
Devang Patel622b0262010-01-19 06:19:05 +00001916 for (DenseMap<DIE *, MDNode *>::iterator CI = ContainingTypeMap.begin(),
Devang Patel5d11eb02009-12-03 19:11:07 +00001917 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1918 DIE *SPDie = CI->first;
1919 MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
1920 if (!N) continue;
1921 DIE *NDie = ModuleCU->getDIE(N);
1922 if (!NDie) continue;
1923 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
Devang Patel5d11eb02009-12-03 19:11:07 +00001924 }
1925
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001926 // Standard sections final addresses.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001927 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00001928 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001929 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
Chris Lattnerc0215722010-04-04 19:25:43 +00001930 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001931
1932 // End text sections.
1933 for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00001934 Asm->OutStreamer.SwitchSection(SectionMap[i]);
Chris Lattnerc0215722010-04-04 19:25:43 +00001935 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", i));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001936 }
1937
1938 // Emit common frame information.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001939 emitCommonDebugFrame();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001940
1941 // Emit function debug frame information
1942 for (std::vector<FunctionDebugFrameInfo>::iterator I = DebugFrames.begin(),
1943 E = DebugFrames.end(); I != E; ++I)
Devang Patel2c4ceb12009-11-21 02:48:08 +00001944 emitFunctionDebugFrame(*I);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001945
1946 // Compute DIE offsets and sizes.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001947 computeSizeAndOffsets();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001948
1949 // Emit all the DIEs into a debug info section
Devang Patel2c4ceb12009-11-21 02:48:08 +00001950 emitDebugInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001951
1952 // Corresponding abbreviations into a abbrev section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001953 emitAbbreviations();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001954
1955 // Emit source line correspondence into a debug line section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001956 emitDebugLines();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001957
1958 // Emit info into a debug pubnames section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001959 emitDebugPubNames();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001960
Devang Patel193f7202009-11-24 01:14:22 +00001961 // Emit info into a debug pubtypes section.
1962 emitDebugPubTypes();
1963
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001964 // Emit info into a debug loc section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001965 emitDebugLoc();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001966
1967 // Emit info into a debug aranges section.
1968 EmitDebugARanges();
1969
1970 // Emit info into a debug ranges section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001971 emitDebugRanges();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001972
1973 // Emit info into a debug macinfo section.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001974 emitDebugMacInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001975
1976 // Emit inline info.
Devang Patel2c4ceb12009-11-21 02:48:08 +00001977 emitDebugInlineInfo();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001978
Chris Lattnerbc733f52010-03-13 02:17:42 +00001979 // Emit info into a debug str section.
1980 emitDebugStr();
1981
Jeffrey Yasskind0f393d2010-03-11 18:29:55 +00001982 delete ModuleCU;
1983 ModuleCU = NULL; // Reset for the next Module, if any.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00001984}
1985
Devang Patel53bb5c92009-11-10 23:06:00 +00001986/// findAbstractVariable - Find abstract variable, if any, associated with Var.
Jim Grosbach7ab38df2009-11-22 19:20:36 +00001987DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
1988 unsigned FrameIdx,
Chris Lattnerde4845c2010-04-02 19:42:39 +00001989 DebugLoc ScopeLoc) {
Devang Patel53bb5c92009-11-10 23:06:00 +00001990
1991 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
1992 if (AbsDbgVariable)
1993 return AbsDbgVariable;
1994
Chris Lattnerde4845c2010-04-02 19:42:39 +00001995 LLVMContext &Ctx = Var.getNode()->getContext();
1996 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel53bb5c92009-11-10 23:06:00 +00001997 if (!Scope)
1998 return NULL;
1999
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002000 AbsDbgVariable = new DbgVariable(Var, FrameIdx,
2001 NULL /* No more-abstract variable*/);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002002 Scope->addVariable(AbsDbgVariable);
Devang Patel53bb5c92009-11-10 23:06:00 +00002003 AbstractVariables[Var.getNode()] = AbsDbgVariable;
2004 return AbsDbgVariable;
2005}
2006
Devang Patel90a48ad2010-03-15 18:33:46 +00002007/// findAbstractVariable - Find abstract variable, if any, associated with Var.
2008/// FIXME : Refactor findAbstractVariable.
2009DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
2010 const MachineInstr *MI,
Chris Lattnerde4845c2010-04-02 19:42:39 +00002011 DebugLoc ScopeLoc) {
Devang Patel90a48ad2010-03-15 18:33:46 +00002012
2013 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var.getNode());
2014 if (AbsDbgVariable)
2015 return AbsDbgVariable;
2016
Chris Lattnerde4845c2010-04-02 19:42:39 +00002017 LLVMContext &Ctx = Var.getNode()->getContext();
2018 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patel90a48ad2010-03-15 18:33:46 +00002019 if (!Scope)
2020 return NULL;
2021
Devang Patelaead63c2010-03-29 22:59:58 +00002022 AbsDbgVariable = new DbgVariable(Var, MI,
Devang Patel90a48ad2010-03-15 18:33:46 +00002023 NULL /* No more-abstract variable*/);
2024 Scope->addVariable(AbsDbgVariable);
2025 AbstractVariables[Var.getNode()] = AbsDbgVariable;
Devang Patelaead63c2010-03-29 22:59:58 +00002026 DbgValueStartMap[MI] = AbsDbgVariable;
Devang Patel90a48ad2010-03-15 18:33:46 +00002027 return AbsDbgVariable;
2028}
2029
Devang Patel2c4ceb12009-11-21 02:48:08 +00002030/// collectVariableInfo - Populate DbgScope entries with variables' info.
2031void DwarfDebug::collectVariableInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00002032 const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002033
Devang Patele717faa2009-10-06 01:26:37 +00002034 MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
2035 for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
2036 VE = VMap.end(); VI != VE; ++VI) {
Devang Patelbc5201f2010-01-22 22:52:10 +00002037 MDNode *Var = VI->first;
Devang Patel53bb5c92009-11-10 23:06:00 +00002038 if (!Var) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002039 DIVariable DV(Var);
2040 const std::pair<unsigned, DebugLoc> &VP = VI->second;
Devang Patel53bb5c92009-11-10 23:06:00 +00002041
Chris Lattnerde4845c2010-04-02 19:42:39 +00002042 DbgScope *Scope = 0;
2043 if (MDNode *IA = VP.second.getInlinedAt(Ctx))
2044 Scope = ConcreteScopes.lookup(IA);
2045 if (Scope == 0)
2046 Scope = DbgScopeMap.lookup(VP.second.getScope(Ctx));
2047
Devang Patelfb0ee432009-11-10 23:20:04 +00002048 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002049 if (Scope == 0)
Devang Patelfb0ee432009-11-10 23:20:04 +00002050 continue;
Devang Patel53bb5c92009-11-10 23:06:00 +00002051
Chris Lattnerde4845c2010-04-02 19:42:39 +00002052 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.first, VP.second);
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002053 DbgVariable *RegVar = new DbgVariable(DV, VP.first, AbsDbgVariable);
Devang Patel2c4ceb12009-11-21 02:48:08 +00002054 Scope->addVariable(RegVar);
Devang Patele717faa2009-10-06 01:26:37 +00002055 }
Devang Patel90a48ad2010-03-15 18:33:46 +00002056
2057 // Collect variable information from DBG_VALUE machine instructions;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002058 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patel90a48ad2010-03-15 18:33:46 +00002059 I != E; ++I) {
2060 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2061 II != IE; ++II) {
2062 const MachineInstr *MInsn = II;
Chris Lattner14d750d2010-03-31 05:39:57 +00002063 if (!MInsn->isDebugValue())
Devang Patel90a48ad2010-03-15 18:33:46 +00002064 continue;
Devang Patelaead63c2010-03-29 22:59:58 +00002065
Devang Patel90a48ad2010-03-15 18:33:46 +00002066 // FIXME : Lift this restriction.
2067 if (MInsn->getNumOperands() != 3)
2068 continue;
Chris Lattner870cfcf2010-03-31 03:34:40 +00002069 DIVariable DV((MDNode*)(MInsn->getOperand(MInsn->getNumOperands()
2070 - 1).getMetadata()));
Devang Patel90a48ad2010-03-15 18:33:46 +00002071 if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
2072 // FIXME Handle inlined subroutine arguments.
2073 DbgVariable *ArgVar = new DbgVariable(DV, MInsn, NULL);
2074 CurrentFnDbgScope->addVariable(ArgVar);
Devang Patelaead63c2010-03-29 22:59:58 +00002075 DbgValueStartMap[MInsn] = ArgVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002076 continue;
2077 }
2078
2079 DebugLoc DL = MInsn->getDebugLoc();
2080 if (DL.isUnknown()) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002081 DbgScope *Scope = 0;
2082 if (MDNode *IA = DL.getInlinedAt(Ctx))
2083 Scope = ConcreteScopes.lookup(IA);
2084 if (Scope == 0)
2085 Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
2086
Devang Patel90a48ad2010-03-15 18:33:46 +00002087 // If variable scope is not found then skip this variable.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002088 if (Scope == 0)
Devang Patel90a48ad2010-03-15 18:33:46 +00002089 continue;
2090
Chris Lattnerde4845c2010-04-02 19:42:39 +00002091 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, MInsn, DL);
Devang Patel90a48ad2010-03-15 18:33:46 +00002092 DbgVariable *RegVar = new DbgVariable(DV, MInsn, AbsDbgVariable);
Devang Patelaead63c2010-03-29 22:59:58 +00002093 DbgValueStartMap[MInsn] = RegVar;
Devang Patel90a48ad2010-03-15 18:33:46 +00002094 Scope->addVariable(RegVar);
2095 }
2096 }
Devang Patele717faa2009-10-06 01:26:37 +00002097}
2098
Devang Patel553881b2010-03-29 17:20:31 +00002099/// beginScope - Process beginning of a scope.
2100void DwarfDebug::beginScope(const MachineInstr *MI) {
Devang Patel553881b2010-03-29 17:20:31 +00002101 // Check location.
2102 DebugLoc DL = MI->getDebugLoc();
2103 if (DL.isUnknown())
2104 return;
Devang Patel553881b2010-03-29 17:20:31 +00002105
2106 // Check and update last known location info.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002107 if (DL == PrevInstLoc)
2108 return;
2109
Chris Lattnerd38fee82010-04-05 00:13:49 +00002110 MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
Chris Lattnerde4845c2010-04-02 19:42:39 +00002111
2112 // FIXME: Should only verify each scope once!
2113 if (!DIScope(Scope).Verify())
Devang Patel553881b2010-03-29 17:20:31 +00002114 return;
Devang Patel553881b2010-03-29 17:20:31 +00002115
Devang Patelaead63c2010-03-29 22:59:58 +00002116 // DBG_VALUE instruction establishes new value.
Chris Lattner14d750d2010-03-31 05:39:57 +00002117 if (MI->isDebugValue()) {
Devang Patelaead63c2010-03-29 22:59:58 +00002118 DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
2119 = DbgValueStartMap.find(MI);
2120 if (DI != DbgValueStartMap.end()) {
Chris Lattnerde4845c2010-04-02 19:42:39 +00002121 MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2122 PrevInstLoc = DL;
Devang Patelaead63c2010-03-29 22:59:58 +00002123 DI->second->setDbgValueLabel(Label);
2124 }
Devang Patel7ed63112010-03-30 18:07:00 +00002125 return;
Devang Patelaead63c2010-03-29 22:59:58 +00002126 }
2127
Devang Patel553881b2010-03-29 17:20:31 +00002128 // Emit a label to indicate location change. This is used for line
2129 // table even if this instruction does start a new scope.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002130 MCSymbol *Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2131 PrevInstLoc = DL;
Devang Patel553881b2010-03-29 17:20:31 +00002132
Devang Patel1c246352010-04-08 16:50:29 +00002133 // If this instruction begins a scope then note down corresponding label.
2134 if (InsnsBeginScopeSet.count(MI) != 0)
2135 InsnBeforeLabelMap[MI] = Label;
Devang Patel0d20ac82009-10-06 01:50:42 +00002136}
2137
Devang Patel2c4ceb12009-11-21 02:48:08 +00002138/// endScope - Process end of a scope.
2139void DwarfDebug::endScope(const MachineInstr *MI) {
Devang Patel553881b2010-03-29 17:20:31 +00002140 // Ignore DBG_VALUE instruction.
Chris Lattner14d750d2010-03-31 05:39:57 +00002141 if (MI->isDebugValue())
Devang Patel553881b2010-03-29 17:20:31 +00002142 return;
2143
2144 // Check location.
2145 DebugLoc DL = MI->getDebugLoc();
2146 if (DL.isUnknown())
2147 return;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002148
Devang Patel1c246352010-04-08 16:50:29 +00002149 if (InsnsEndScopeSet.count(MI) != 0) {
2150 // Emit a label if this instruction ends a scope.
2151 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
2152 Asm->OutStreamer.EmitLabel(Label);
2153 InsnAfterLabelMap[MI] = Label;
2154 }
Devang Patel53bb5c92009-11-10 23:06:00 +00002155}
2156
2157/// createDbgScope - Create DbgScope for the scope.
2158void DwarfDebug::createDbgScope(MDNode *Scope, MDNode *InlinedAt) {
Devang Patel53bb5c92009-11-10 23:06:00 +00002159 if (!InlinedAt) {
2160 DbgScope *WScope = DbgScopeMap.lookup(Scope);
2161 if (WScope)
2162 return;
2163 WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL);
2164 DbgScopeMap.insert(std::make_pair(Scope, WScope));
Jim Grosbach31ef40e2009-11-21 23:12:12 +00002165 if (DIDescriptor(Scope).isLexicalBlock())
Devang Patel2f105c62009-11-11 00:18:40 +00002166 createDbgScope(DILexicalBlock(Scope).getContext().getNode(), NULL);
Devang Patel53bb5c92009-11-10 23:06:00 +00002167 return;
2168 }
2169
2170 DbgScope *WScope = DbgScopeMap.lookup(InlinedAt);
2171 if (WScope)
2172 return;
2173
2174 WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt);
2175 DbgScopeMap.insert(std::make_pair(InlinedAt, WScope));
2176 DILocation DL(InlinedAt);
2177 createDbgScope(DL.getScope().getNode(), DL.getOrigLocation().getNode());
Devang Patel0d20ac82009-10-06 01:50:42 +00002178}
2179
Devang Patel2c4ceb12009-11-21 02:48:08 +00002180/// extractScopeInformation - Scan machine instructions in this function
Chris Lattner14d750d2010-03-31 05:39:57 +00002181/// and collect DbgScopes. Return true, if at least one scope was found.
Chris Lattnereec791a2010-01-26 23:18:02 +00002182bool DwarfDebug::extractScopeInformation() {
Devang Patelaf9e8472009-10-01 20:31:14 +00002183 // If scope information was extracted using .dbg intrinsics then there is not
2184 // any need to extract these information by scanning each instruction.
2185 if (!DbgScopeMap.empty())
2186 return false;
2187
Devang Patel344130e2010-01-04 20:44:00 +00002188 DenseMap<const MachineInstr *, unsigned> MIIndexMap;
2189 unsigned MIIndex = 0;
Chris Lattnerd38fee82010-04-05 00:13:49 +00002190 LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002191
Devang Patel53bb5c92009-11-10 23:06:00 +00002192 // Scan each instruction and create scopes. First build working set of scopes.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002193 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patelaf9e8472009-10-01 20:31:14 +00002194 I != E; ++I) {
2195 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2196 II != IE; ++II) {
2197 const MachineInstr *MInsn = II;
Devang Patel90a48ad2010-03-15 18:33:46 +00002198 // FIXME : Remove DBG_VALUE check.
Chris Lattner14d750d2010-03-31 05:39:57 +00002199 if (MInsn->isDebugValue()) continue;
Devang Patel344130e2010-01-04 20:44:00 +00002200 MIIndexMap[MInsn] = MIIndex++;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002201
Devang Patelaf9e8472009-10-01 20:31:14 +00002202 DebugLoc DL = MInsn->getDebugLoc();
Devang Patel53bb5c92009-11-10 23:06:00 +00002203 if (DL.isUnknown()) continue;
Chris Lattnerde4845c2010-04-02 19:42:39 +00002204
2205 MDNode *Scope = DL.getScope(Ctx);
2206
Devang Patelaf9e8472009-10-01 20:31:14 +00002207 // There is no need to create another DIE for compile unit. For all
Jim Grosbach31ef40e2009-11-21 23:12:12 +00002208 // other scopes, create one DbgScope now. This will be translated
Devang Patelaf9e8472009-10-01 20:31:14 +00002209 // into a scope DIE at the end.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002210 if (DIScope(Scope).isCompileUnit()) continue;
2211 createDbgScope(Scope, DL.getInlinedAt(Ctx));
Devang Patel53bb5c92009-11-10 23:06:00 +00002212 }
2213 }
2214
Devang Patelc8e77642010-04-01 22:47:29 +00002215
Devang Patel53bb5c92009-11-10 23:06:00 +00002216 // Build scope hierarchy using working set of scopes.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002217 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patel53bb5c92009-11-10 23:06:00 +00002218 I != E; ++I) {
2219 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2220 II != IE; ++II) {
2221 const MachineInstr *MInsn = II;
Devang Patel90a48ad2010-03-15 18:33:46 +00002222 // FIXME : Remove DBG_VALUE check.
Chris Lattner14d750d2010-03-31 05:39:57 +00002223 if (MInsn->isDebugValue()) continue;
Devang Patel53bb5c92009-11-10 23:06:00 +00002224 DebugLoc DL = MInsn->getDebugLoc();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002225 if (DL.isUnknown()) continue;
2226
2227 MDNode *Scope = DL.getScope(Ctx);
2228 if (Scope == 0) continue;
2229
Devang Patel53bb5c92009-11-10 23:06:00 +00002230 // There is no need to create another DIE for compile unit. For all
Jim Grosbach31ef40e2009-11-21 23:12:12 +00002231 // other scopes, create one DbgScope now. This will be translated
Devang Patel53bb5c92009-11-10 23:06:00 +00002232 // into a scope DIE at the end.
Chris Lattnerde4845c2010-04-02 19:42:39 +00002233 if (DIScope(Scope).isCompileUnit()) continue;
2234 DbgScope *DScope = getUpdatedDbgScope(Scope, MInsn, DL.getInlinedAt(Ctx));
2235 DScope->setLastInsn(MInsn);
Devang Patelaf9e8472009-10-01 20:31:14 +00002236 }
2237 }
2238
Devang Patel344130e2010-01-04 20:44:00 +00002239 if (!CurrentFnDbgScope)
2240 return false;
2241
2242 CurrentFnDbgScope->fixInstructionMarkers(MIIndexMap);
Devang Patelaf9e8472009-10-01 20:31:14 +00002243
Devang Patel6122a4d2010-04-08 15:37:09 +00002244 populateDbgScopeInverseMaps();
2245
2246 return !DbgScopeMap.empty();
2247}
2248
2249/// populateDbgScopeInverseMaps() - Populate DbgScopeBeginMap and
2250/// DbgScopeEndMap. This maps are used to indentify debug scope started
2251/// and ended by an instruction.
2252void DwarfDebug::populateDbgScopeInverseMaps() {
2253
Devang Patelaf9e8472009-10-01 20:31:14 +00002254 // Each scope has first instruction and last instruction to mark beginning
2255 // and end of a scope respectively. Create an inverse map that list scopes
2256 // starts (and ends) with an instruction. One instruction may start (or end)
Devang Patel42aafd72010-01-20 02:05:23 +00002257 // multiple scopes. Ignore scopes that are not reachable.
2258 SmallVector<DbgScope *, 4> WorkList;
2259 WorkList.push_back(CurrentFnDbgScope);
2260 while (!WorkList.empty()) {
Chris Lattner14d750d2010-03-31 05:39:57 +00002261 DbgScope *S = WorkList.pop_back_val();
Devang Patel42aafd72010-01-20 02:05:23 +00002262
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002263 const SmallVector<DbgScope *, 4> &Children = S->getScopes();
Devang Patel42aafd72010-01-20 02:05:23 +00002264 if (!Children.empty())
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002265 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
Devang Patel42aafd72010-01-20 02:05:23 +00002266 SE = Children.end(); SI != SE; ++SI)
2267 WorkList.push_back(*SI);
2268
Devang Patel53bb5c92009-11-10 23:06:00 +00002269 if (S->isAbstractScope())
2270 continue;
Devang Patel1c246352010-04-08 16:50:29 +00002271 assert(S->getFirstInsn() && "DbgScope does not have first instruction!");
2272 InsnsBeginScopeSet.insert(S->getFirstInsn());
Devang Patelaf9e8472009-10-01 20:31:14 +00002273
Devang Patel1c246352010-04-08 16:50:29 +00002274 assert(S->getLastInsn() && "DbgScope does not have last instruction!");
2275 InsnsEndScopeSet.insert(S->getLastInsn());
Devang Patelaf9e8472009-10-01 20:31:14 +00002276 }
Devang Patelaf9e8472009-10-01 20:31:14 +00002277}
2278
Devang Patel2c4ceb12009-11-21 02:48:08 +00002279/// beginFunction - Gather pre-function debug information. Assumes being
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002280/// emitted immediately after the function entry point.
Chris Lattnereec791a2010-01-26 23:18:02 +00002281void DwarfDebug::beginFunction(const MachineFunction *MF) {
Chris Lattner994cb122010-04-05 03:52:55 +00002282 if (!MMI->hasDebugInfo()) return;
Bill Wendling5f017e82010-04-07 09:28:04 +00002283 if (!extractScopeInformation()) return;
Chris Lattnera909d662010-03-29 20:38:20 +00002284
Devang Patel2c4ceb12009-11-21 02:48:08 +00002285 collectVariableInfo();
Devang Patel60b35bd2009-10-06 18:37:31 +00002286
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002287 // Assumes in correct section after the entry point.
Chris Lattnerc0215722010-04-04 19:25:43 +00002288 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_begin",
Chris Lattnerd38fee82010-04-05 00:13:49 +00002289 Asm->getFunctionNumber()));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002290
2291 // Emit label for the implicitly defined dbg.stoppoint at the start of the
2292 // function.
Devang Patelac1ceb32009-10-09 22:42:28 +00002293 DebugLoc FDL = MF->getDefaultDebugLoc();
Chris Lattnerde4845c2010-04-02 19:42:39 +00002294 if (FDL.isUnknown()) return;
2295
2296 MDNode *Scope = FDL.getScope(MF->getFunction()->getContext());
2297
2298 DISubprogram SP = getDISubprogram(Scope);
2299 unsigned Line, Col;
2300 if (SP.Verify()) {
2301 Line = SP.getLineNumber();
2302 Col = 0;
2303 } else {
2304 Line = FDL.getLine();
2305 Col = FDL.getCol();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002306 }
Chris Lattnerde4845c2010-04-02 19:42:39 +00002307
2308 recordSourceLine(Line, Col, Scope);
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002309}
2310
Devang Patel2c4ceb12009-11-21 02:48:08 +00002311/// endFunction - Gather and emit post-function debug information.
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002312///
Chris Lattnereec791a2010-01-26 23:18:02 +00002313void DwarfDebug::endFunction(const MachineFunction *MF) {
Bill Wendling5f017e82010-04-07 09:28:04 +00002314 if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return;
Devang Patel70d75ca2009-11-12 19:02:56 +00002315
Devang Patel344130e2010-01-04 20:44:00 +00002316 if (CurrentFnDbgScope) {
2317 // Define end label for subprogram.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002318 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
2319 Asm->getFunctionNumber()));
Devang Patel344130e2010-01-04 20:44:00 +00002320
2321 // Get function line info.
2322 if (!Lines.empty()) {
2323 // Get section line info.
2324 unsigned ID = SectionMap.insert(Asm->getCurrentSection());
2325 if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
2326 std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
2327 // Append the function info to section info.
2328 SectionLineInfos.insert(SectionLineInfos.end(),
2329 Lines.begin(), Lines.end());
2330 }
2331
2332 // Construct abstract scopes.
2333 for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
2334 AE = AbstractScopesList.end(); AI != AE; ++AI)
2335 constructScopeDIE(*AI);
2336
2337 constructScopeDIE(CurrentFnDbgScope);
2338
Chris Lattnerd38fee82010-04-05 00:13:49 +00002339 DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
Devang Patel344130e2010-01-04 20:44:00 +00002340 MMI->getFrameMoves()));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002341 }
2342
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002343 // Clear debug info
Devang Patelf54b8522010-01-19 01:26:02 +00002344 CurrentFnDbgScope = NULL;
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002345 DeleteContainerSeconds(DbgScopeMap);
Devang Patelaead63c2010-03-29 22:59:58 +00002346 DbgValueStartMap.clear();
Devang Patelf54b8522010-01-19 01:26:02 +00002347 ConcreteScopes.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002348 DeleteContainerSeconds(AbstractScopes);
Devang Patelf54b8522010-01-19 01:26:02 +00002349 AbstractScopesList.clear();
Jeffrey Yasskin5c213dc2010-03-12 17:45:06 +00002350 AbstractVariables.clear();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002351 Lines.clear();
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002352}
2353
Chris Lattnerc6087842010-03-09 04:54:43 +00002354/// recordSourceLine - Register a source line with debug info. Returns the
2355/// unique label that was emitted and which provides correspondence to
2356/// the source line list.
2357MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, MDNode *S) {
Devang Patel65dbc902009-11-25 17:36:49 +00002358 StringRef Dir;
2359 StringRef Fn;
Devang Patelf84548d2009-10-05 18:03:19 +00002360
2361 DIDescriptor Scope(S);
2362 if (Scope.isCompileUnit()) {
2363 DICompileUnit CU(S);
2364 Dir = CU.getDirectory();
2365 Fn = CU.getFilename();
2366 } else if (Scope.isSubprogram()) {
2367 DISubprogram SP(S);
2368 Dir = SP.getDirectory();
2369 Fn = SP.getFilename();
2370 } else if (Scope.isLexicalBlock()) {
2371 DILexicalBlock DB(S);
2372 Dir = DB.getDirectory();
2373 Fn = DB.getFilename();
2374 } else
Chris Lattner206d61e2010-03-13 07:26:18 +00002375 assert(0 && "Unexpected scope info");
Devang Patelf84548d2009-10-05 18:03:19 +00002376
2377 unsigned Src = GetOrCreateSourceID(Dir, Fn);
Chris Lattner63d78362010-03-14 08:36:50 +00002378 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Chris Lattner25b68c62010-03-14 08:15:55 +00002379 Lines.push_back(SrcLineInfo(Line, Col, Src, Label));
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002380
Chris Lattnerc6087842010-03-09 04:54:43 +00002381 Asm->OutStreamer.EmitLabel(Label);
2382 return Label;
Bill Wendlingf0fb9872009-05-20 23:19:06 +00002383}
2384
Bill Wendling829e67b2009-05-20 23:22:40 +00002385//===----------------------------------------------------------------------===//
2386// Emit Methods
2387//===----------------------------------------------------------------------===//
2388
Devang Patel2c4ceb12009-11-21 02:48:08 +00002389/// computeSizeAndOffset - Compute the size and offset of a DIE.
Bill Wendling94d04b82009-05-20 23:21:38 +00002390///
Jim Grosbach7ab38df2009-11-22 19:20:36 +00002391unsigned
2392DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002393 // Get the children.
2394 const std::vector<DIE *> &Children = Die->getChildren();
2395
2396 // If not last sibling and has children then add sibling offset attribute.
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002397 if (!Last && !Children.empty())
Benjamin Kramer345ef342010-03-31 19:34:01 +00002398 Die->addSiblingOffset(DIEValueAllocator);
Bill Wendling94d04b82009-05-20 23:21:38 +00002399
2400 // Record the abbreviation.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002401 assignAbbrevNumber(Die->getAbbrev());
Bill Wendling94d04b82009-05-20 23:21:38 +00002402
2403 // Get the abbreviation for this DIE.
2404 unsigned AbbrevNumber = Die->getAbbrevNumber();
2405 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2406
2407 // Set DIE offset
2408 Die->setOffset(Offset);
2409
2410 // Start the size with the size of abbreviation code.
Chris Lattneraf76e592009-08-22 20:48:53 +00002411 Offset += MCAsmInfo::getULEB128Size(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002412
2413 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
2414 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2415
2416 // Size the DIE attribute values.
2417 for (unsigned i = 0, N = Values.size(); i < N; ++i)
2418 // Size attribute value.
Chris Lattnera37d5382010-04-05 00:18:22 +00002419 Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
Bill Wendling94d04b82009-05-20 23:21:38 +00002420
2421 // Size the DIE children if any.
2422 if (!Children.empty()) {
2423 assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes &&
2424 "Children flag not set");
2425
2426 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002427 Offset = computeSizeAndOffset(Children[j], Offset, (j + 1) == M);
Bill Wendling94d04b82009-05-20 23:21:38 +00002428
2429 // End of children marker.
2430 Offset += sizeof(int8_t);
2431 }
2432
2433 Die->setSize(Offset - Die->getOffset());
2434 return Offset;
2435}
2436
Devang Patel2c4ceb12009-11-21 02:48:08 +00002437/// computeSizeAndOffsets - Compute the size and offset of all the DIEs.
Bill Wendling94d04b82009-05-20 23:21:38 +00002438///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002439void DwarfDebug::computeSizeAndOffsets() {
Bill Wendling94d04b82009-05-20 23:21:38 +00002440 // Compute size of compile unit header.
2441 static unsigned Offset =
2442 sizeof(int32_t) + // Length of Compilation Unit Info
2443 sizeof(int16_t) + // DWARF version number
2444 sizeof(int32_t) + // Offset Into Abbrev. Section
2445 sizeof(int8_t); // Pointer Size (in bytes)
2446
Devang Patel2c4ceb12009-11-21 02:48:08 +00002447 computeSizeAndOffset(ModuleCU->getCUDie(), Offset, true);
Devang Patel1dbc7712009-06-29 20:45:18 +00002448 CompileUnitOffsets[ModuleCU] = 0;
Bill Wendling94d04b82009-05-20 23:21:38 +00002449}
2450
Chris Lattner11b8f302010-04-04 23:02:02 +00002451/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
2452/// temporary label to it if SymbolStem is specified.
Chris Lattner9c69e285532010-04-04 22:59:04 +00002453static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
Chris Lattner11b8f302010-04-04 23:02:02 +00002454 const char *SymbolStem = 0) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002455 Asm->OutStreamer.SwitchSection(Section);
Chris Lattner11b8f302010-04-04 23:02:02 +00002456 if (!SymbolStem) return 0;
2457
Chris Lattner9c69e285532010-04-04 22:59:04 +00002458 MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
2459 Asm->OutStreamer.EmitLabel(TmpSym);
2460 return TmpSym;
2461}
2462
2463/// EmitSectionLabels - Emit initial Dwarf sections with a label at
2464/// the start of each one.
Chris Lattnerfa070b02010-04-04 22:33:59 +00002465void DwarfDebug::EmitSectionLabels() {
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002466 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
Daniel Dunbarf612ff62009-09-19 20:40:05 +00002467
Bill Wendling94d04b82009-05-20 23:21:38 +00002468 // Dwarf sections base addresses.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002469 if (Asm->MAI->doesDwarfRequireFrameSection()) {
Chris Lattner9c69e285532010-04-04 22:59:04 +00002470 DwarfFrameSectionSym =
2471 EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
2472 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002473
Chris Lattner9c69e285532010-04-04 22:59:04 +00002474 DwarfInfoSectionSym =
2475 EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
2476 DwarfAbbrevSectionSym =
2477 EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
Chris Lattner11b8f302010-04-04 23:02:02 +00002478 EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002479
2480 if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
Chris Lattner11b8f302010-04-04 23:02:02 +00002481 EmitSectionSym(Asm, MacroInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00002482
Chris Lattner11b8f302010-04-04 23:02:02 +00002483 EmitSectionSym(Asm, TLOF.getDwarfLineSection());
2484 EmitSectionSym(Asm, TLOF.getDwarfLocSection());
2485 EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
2486 EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
Chris Lattner9c69e285532010-04-04 22:59:04 +00002487 DwarfStrSectionSym =
2488 EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
Chris Lattner11b8f302010-04-04 23:02:02 +00002489 EmitSectionSym(Asm, TLOF.getDwarfRangesSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002490
Chris Lattner9c69e285532010-04-04 22:59:04 +00002491 TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
Chris Lattner4ad1efe2010-04-04 23:10:38 +00002492 EmitSectionSym(Asm, TLOF.getDataSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002493}
2494
Devang Patel2c4ceb12009-11-21 02:48:08 +00002495/// emitDIE - Recusively Emits a debug information entry.
Bill Wendling94d04b82009-05-20 23:21:38 +00002496///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002497void DwarfDebug::emitDIE(DIE *Die) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002498 // Get the abbreviation for this DIE.
2499 unsigned AbbrevNumber = Die->getAbbrevNumber();
2500 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2501
Bill Wendling94d04b82009-05-20 23:21:38 +00002502 // Emit the code (index) for the abbreviation.
Chris Lattner3f53c832010-04-04 18:52:31 +00002503 if (Asm->isVerbose())
Chris Lattner894d75a2010-01-22 23:18:42 +00002504 Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
2505 Twine::utohexstr(Die->getOffset()) + ":0x" +
2506 Twine::utohexstr(Die->getSize()) + " " +
2507 dwarf::TagString(Abbrev->getTag()));
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002508 Asm->EmitULEB128(AbbrevNumber);
Bill Wendling94d04b82009-05-20 23:21:38 +00002509
Jeffrey Yasskin638fe8d2010-03-22 18:47:14 +00002510 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
Bill Wendling94d04b82009-05-20 23:21:38 +00002511 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2512
2513 // Emit the DIE attribute values.
2514 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
2515 unsigned Attr = AbbrevData[i].getAttribute();
2516 unsigned Form = AbbrevData[i].getForm();
2517 assert(Form && "Too many attributes for DIE (check abbreviation)");
2518
Chris Lattner3f53c832010-04-04 18:52:31 +00002519 if (Asm->isVerbose())
Chris Lattnera8013622010-01-24 18:54:17 +00002520 Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
2521
Bill Wendling94d04b82009-05-20 23:21:38 +00002522 switch (Attr) {
2523 case dwarf::DW_AT_sibling:
Devang Patel2c4ceb12009-11-21 02:48:08 +00002524 Asm->EmitInt32(Die->getSiblingOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00002525 break;
2526 case dwarf::DW_AT_abstract_origin: {
2527 DIEEntry *E = cast<DIEEntry>(Values[i]);
2528 DIE *Origin = E->getEntry();
Devang Patel53bb5c92009-11-10 23:06:00 +00002529 unsigned Addr = Origin->getOffset();
Bill Wendling94d04b82009-05-20 23:21:38 +00002530 Asm->EmitInt32(Addr);
2531 break;
2532 }
2533 default:
2534 // Emit an attribute using the defined form.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002535 Values[i]->EmitValue(Asm, Form);
Bill Wendling94d04b82009-05-20 23:21:38 +00002536 break;
2537 }
Bill Wendling94d04b82009-05-20 23:21:38 +00002538 }
2539
2540 // Emit the DIE children if any.
2541 if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) {
2542 const std::vector<DIE *> &Children = Die->getChildren();
2543
2544 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel2c4ceb12009-11-21 02:48:08 +00002545 emitDIE(Children[j]);
Bill Wendling94d04b82009-05-20 23:21:38 +00002546
Chris Lattner3f53c832010-04-04 18:52:31 +00002547 if (Asm->isVerbose())
Chris Lattner233f52b2010-03-09 23:52:58 +00002548 Asm->OutStreamer.AddComment("End Of Children Mark");
2549 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002550 }
2551}
2552
Devang Patel8a241142009-12-09 18:24:21 +00002553/// emitDebugInfo - Emit the debug info section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002554///
Devang Patel8a241142009-12-09 18:24:21 +00002555void DwarfDebug::emitDebugInfo() {
2556 // Start debug info section.
2557 Asm->OutStreamer.SwitchSection(
2558 Asm->getObjFileLowering().getDwarfInfoSection());
2559 DIE *Die = ModuleCU->getCUDie();
Bill Wendling94d04b82009-05-20 23:21:38 +00002560
2561 // Emit the compile units header.
Chris Lattnerc0215722010-04-04 19:25:43 +00002562 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin",
2563 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002564
2565 // Emit size of content not including length itself
2566 unsigned ContentSize = Die->getSize() +
2567 sizeof(int16_t) + // DWARF version number
2568 sizeof(int32_t) + // Offset Into Abbrev. Section
2569 sizeof(int8_t) + // Pointer Size (in bytes)
2570 sizeof(int32_t); // FIXME - extra pad for gdb bug.
2571
Chris Lattner233f52b2010-03-09 23:52:58 +00002572 Asm->OutStreamer.AddComment("Length of Compilation Unit Info");
2573 Asm->EmitInt32(ContentSize);
2574 Asm->OutStreamer.AddComment("DWARF version number");
2575 Asm->EmitInt16(dwarf::DWARF_VERSION);
2576 Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
Chris Lattner6189ed12010-04-04 23:25:33 +00002577 Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
2578 DwarfAbbrevSectionSym);
Chris Lattner233f52b2010-03-09 23:52:58 +00002579 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002580 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00002581
Devang Patel2c4ceb12009-11-21 02:48:08 +00002582 emitDIE(Die);
Bill Wendling94d04b82009-05-20 23:21:38 +00002583 // FIXME - extra padding for gdb bug.
Chris Lattner233f52b2010-03-09 23:52:58 +00002584 Asm->OutStreamer.AddComment("4 extra padding bytes for GDB");
2585 Asm->EmitInt8(0);
2586 Asm->EmitInt8(0);
2587 Asm->EmitInt8(0);
2588 Asm->EmitInt8(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00002589 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002590}
2591
Devang Patel2c4ceb12009-11-21 02:48:08 +00002592/// emitAbbreviations - Emit the abbreviation section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002593///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002594void DwarfDebug::emitAbbreviations() const {
Bill Wendling94d04b82009-05-20 23:21:38 +00002595 // Check to see if it is worth the effort.
2596 if (!Abbreviations.empty()) {
2597 // Start the debug abbrev section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002598 Asm->OutStreamer.SwitchSection(
2599 Asm->getObjFileLowering().getDwarfAbbrevSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002600
Chris Lattnerc0215722010-04-04 19:25:43 +00002601 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002602
2603 // For each abbrevation.
2604 for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
2605 // Get abbreviation data
2606 const DIEAbbrev *Abbrev = Abbreviations[i];
2607
2608 // Emit the abbrevations code (base 1 index.)
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002609 Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
Bill Wendling94d04b82009-05-20 23:21:38 +00002610
2611 // Emit the abbreviations data.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002612 Abbrev->Emit(Asm);
Bill Wendling94d04b82009-05-20 23:21:38 +00002613 }
2614
2615 // Mark end of abbreviations.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002616 Asm->EmitULEB128(0, "EOM(3)");
Bill Wendling94d04b82009-05-20 23:21:38 +00002617
Chris Lattnerc0215722010-04-04 19:25:43 +00002618 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002619 }
2620}
2621
Devang Patel2c4ceb12009-11-21 02:48:08 +00002622/// emitEndOfLineMatrix - Emit the last address of the section and the end of
Bill Wendling94d04b82009-05-20 23:21:38 +00002623/// the line matrix.
2624///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002625void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Bill Wendling94d04b82009-05-20 23:21:38 +00002626 // Define last address of section.
Chris Lattner233f52b2010-03-09 23:52:58 +00002627 Asm->OutStreamer.AddComment("Extended Op");
2628 Asm->EmitInt8(0);
2629
2630 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002631 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00002632 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2633 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2634
2635 Asm->OutStreamer.AddComment("Section end label");
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002636
Chris Lattnerc0215722010-04-04 19:25:43 +00002637 Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
Chris Lattnerd38fee82010-04-05 00:13:49 +00002638 Asm->getTargetData().getPointerSize(),
2639 0/*AddrSpace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00002640
2641 // Mark end of matrix.
Chris Lattner233f52b2010-03-09 23:52:58 +00002642 Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
2643 Asm->EmitInt8(0);
Chris Lattner0ad9c912010-01-22 22:09:00 +00002644 Asm->EmitInt8(1);
Chris Lattner894d75a2010-01-22 23:18:42 +00002645 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002646}
2647
Devang Patel2c4ceb12009-11-21 02:48:08 +00002648/// emitDebugLines - Emit source line information.
Bill Wendling94d04b82009-05-20 23:21:38 +00002649///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002650void DwarfDebug::emitDebugLines() {
Bill Wendling94d04b82009-05-20 23:21:38 +00002651 // If the target is using .loc/.file, the assembler will be emitting the
2652 // .debug_line table automatically.
Chris Lattnerd38fee82010-04-05 00:13:49 +00002653 if (Asm->MAI->hasDotLocAndDotFile())
Bill Wendling94d04b82009-05-20 23:21:38 +00002654 return;
2655
2656 // Minimum line delta, thus ranging from -10..(255-10).
2657 const int MinLineDelta = -(dwarf::DW_LNS_fixed_advance_pc + 1);
2658 // Maximum line delta, thus ranging from -10..(255-10).
2659 const int MaxLineDelta = 255 + MinLineDelta;
2660
2661 // Start the dwarf line section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002662 Asm->OutStreamer.SwitchSection(
2663 Asm->getObjFileLowering().getDwarfLineSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002664
2665 // Construct the section header.
Chris Lattner233f52b2010-03-09 23:52:58 +00002666 Asm->OutStreamer.AddComment("Length of Source Line Info");
Chris Lattnera6437182010-04-04 19:58:12 +00002667 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_end"),
2668 Asm->GetTempSymbol("line_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002669 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002670
Chris Lattner233f52b2010-03-09 23:52:58 +00002671 Asm->OutStreamer.AddComment("DWARF version number");
2672 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling94d04b82009-05-20 23:21:38 +00002673
Chris Lattner233f52b2010-03-09 23:52:58 +00002674 Asm->OutStreamer.AddComment("Prolog Length");
Chris Lattnera6437182010-04-04 19:58:12 +00002675 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_prolog_end"),
2676 Asm->GetTempSymbol("line_prolog_begin"), 4);
Chris Lattnerc0215722010-04-04 19:25:43 +00002677 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_begin"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002678
Chris Lattner233f52b2010-03-09 23:52:58 +00002679 Asm->OutStreamer.AddComment("Minimum Instruction Length");
2680 Asm->EmitInt8(1);
2681 Asm->OutStreamer.AddComment("Default is_stmt_start flag");
2682 Asm->EmitInt8(1);
2683 Asm->OutStreamer.AddComment("Line Base Value (Special Opcodes)");
2684 Asm->EmitInt8(MinLineDelta);
2685 Asm->OutStreamer.AddComment("Line Range Value (Special Opcodes)");
2686 Asm->EmitInt8(MaxLineDelta);
2687 Asm->OutStreamer.AddComment("Special Opcode Base");
2688 Asm->EmitInt8(-MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00002689
2690 // Line number standard opcode encodings argument count
Chris Lattner233f52b2010-03-09 23:52:58 +00002691 Asm->OutStreamer.AddComment("DW_LNS_copy arg count");
2692 Asm->EmitInt8(0);
2693 Asm->OutStreamer.AddComment("DW_LNS_advance_pc arg count");
2694 Asm->EmitInt8(1);
2695 Asm->OutStreamer.AddComment("DW_LNS_advance_line arg count");
2696 Asm->EmitInt8(1);
2697 Asm->OutStreamer.AddComment("DW_LNS_set_file arg count");
2698 Asm->EmitInt8(1);
2699 Asm->OutStreamer.AddComment("DW_LNS_set_column arg count");
2700 Asm->EmitInt8(1);
2701 Asm->OutStreamer.AddComment("DW_LNS_negate_stmt arg count");
2702 Asm->EmitInt8(0);
2703 Asm->OutStreamer.AddComment("DW_LNS_set_basic_block arg count");
2704 Asm->EmitInt8(0);
2705 Asm->OutStreamer.AddComment("DW_LNS_const_add_pc arg count");
2706 Asm->EmitInt8(0);
2707 Asm->OutStreamer.AddComment("DW_LNS_fixed_advance_pc arg count");
2708 Asm->EmitInt8(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002709
2710 // Emit directories.
2711 for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
Chris Lattner4cf202b2010-01-23 03:11:46 +00002712 const std::string &Dir = getSourceDirectoryName(DI);
Chris Lattner3f53c832010-04-04 18:52:31 +00002713 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Directory");
Chris Lattner4cf202b2010-01-23 03:11:46 +00002714 Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002715 }
2716
Chris Lattner233f52b2010-03-09 23:52:58 +00002717 Asm->OutStreamer.AddComment("End of directories");
2718 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002719
2720 // Emit files.
2721 for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
2722 // Remember source id starts at 1.
2723 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
Chris Lattner4cf202b2010-01-23 03:11:46 +00002724 const std::string &FN = getSourceFileName(Id.second);
Chris Lattner3f53c832010-04-04 18:52:31 +00002725 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Source");
Chris Lattner4cf202b2010-01-23 03:11:46 +00002726 Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0);
2727
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002728 Asm->EmitULEB128(Id.first, "Directory #");
2729 Asm->EmitULEB128(0, "Mod date");
2730 Asm->EmitULEB128(0, "File size");
Bill Wendling94d04b82009-05-20 23:21:38 +00002731 }
2732
Chris Lattner233f52b2010-03-09 23:52:58 +00002733 Asm->OutStreamer.AddComment("End of files");
2734 Asm->EmitInt8(0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002735
Chris Lattnerc0215722010-04-04 19:25:43 +00002736 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002737
2738 // A sequence for each text section.
2739 unsigned SecSrcLinesSize = SectionSourceLines.size();
2740
2741 for (unsigned j = 0; j < SecSrcLinesSize; ++j) {
2742 // Isolate current sections line info.
2743 const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j];
2744
Bill Wendling94d04b82009-05-20 23:21:38 +00002745 // Dwarf assumes we start with first line of first source file.
2746 unsigned Source = 1;
2747 unsigned Line = 1;
2748
2749 // Construct rows of the address, source, line, column matrix.
2750 for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
2751 const SrcLineInfo &LineInfo = LineInfos[i];
Chris Lattner25b68c62010-03-14 08:15:55 +00002752 MCSymbol *Label = LineInfo.getLabel();
Chris Lattnerb9130602010-03-14 02:20:58 +00002753 if (!Label->isDefined()) continue; // Not emitted, in dead code.
Bill Wendling94d04b82009-05-20 23:21:38 +00002754
Caroline Ticec6f9d622009-09-11 18:25:54 +00002755 if (LineInfo.getLine() == 0) continue;
2756
Chris Lattner0d9d70f2010-03-09 23:38:23 +00002757 if (Asm->isVerbose()) {
Chris Lattner188a87d2010-03-10 01:04:13 +00002758 std::pair<unsigned, unsigned> SrcID =
Bill Wendling94d04b82009-05-20 23:21:38 +00002759 getSourceDirectoryAndFileIds(LineInfo.getSourceID());
Chris Lattner188a87d2010-03-10 01:04:13 +00002760 Asm->OutStreamer.AddComment(Twine(getSourceDirectoryName(SrcID.first)) +
Chris Lattner49f618a2010-03-10 02:29:31 +00002761 "/" +
2762 Twine(getSourceFileName(SrcID.second)) +
Chris Lattner188a87d2010-03-10 01:04:13 +00002763 ":" + Twine(LineInfo.getLine()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002764 }
2765
2766 // Define the line address.
Chris Lattner233f52b2010-03-09 23:52:58 +00002767 Asm->OutStreamer.AddComment("Extended Op");
2768 Asm->EmitInt8(0);
2769 Asm->OutStreamer.AddComment("Op size");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002770 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner233f52b2010-03-09 23:52:58 +00002771
2772 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2773 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2774
2775 Asm->OutStreamer.AddComment("Location label");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002776 Asm->OutStreamer.EmitSymbolValue(Label,
2777 Asm->getTargetData().getPointerSize(),
Chris Lattnerb9130602010-03-14 02:20:58 +00002778 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002779
Bill Wendling94d04b82009-05-20 23:21:38 +00002780 // If change of source, then switch to the new source.
2781 if (Source != LineInfo.getSourceID()) {
2782 Source = LineInfo.getSourceID();
Chris Lattner233f52b2010-03-09 23:52:58 +00002783 Asm->OutStreamer.AddComment("DW_LNS_set_file");
2784 Asm->EmitInt8(dwarf::DW_LNS_set_file);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002785 Asm->EmitULEB128(Source, "New Source");
Bill Wendling94d04b82009-05-20 23:21:38 +00002786 }
2787
2788 // If change of line.
2789 if (Line != LineInfo.getLine()) {
2790 // Determine offset.
2791 int Offset = LineInfo.getLine() - Line;
2792 int Delta = Offset - MinLineDelta;
2793
2794 // Update line.
2795 Line = LineInfo.getLine();
2796
2797 // If delta is small enough and in range...
2798 if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
2799 // ... then use fast opcode.
Chris Lattner233f52b2010-03-09 23:52:58 +00002800 Asm->OutStreamer.AddComment("Line Delta");
2801 Asm->EmitInt8(Delta - MinLineDelta);
Bill Wendling94d04b82009-05-20 23:21:38 +00002802 } else {
2803 // ... otherwise use long hand.
Chris Lattner233f52b2010-03-09 23:52:58 +00002804 Asm->OutStreamer.AddComment("DW_LNS_advance_line");
Bill Wendling94d04b82009-05-20 23:21:38 +00002805 Asm->EmitInt8(dwarf::DW_LNS_advance_line);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002806 Asm->EmitSLEB128(Offset, "Line Offset");
Chris Lattner233f52b2010-03-09 23:52:58 +00002807 Asm->OutStreamer.AddComment("DW_LNS_copy");
2808 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00002809 }
2810 } else {
2811 // Copy the previous row (different address or source)
Chris Lattner233f52b2010-03-09 23:52:58 +00002812 Asm->OutStreamer.AddComment("DW_LNS_copy");
2813 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling94d04b82009-05-20 23:21:38 +00002814 }
2815 }
2816
Devang Patel2c4ceb12009-11-21 02:48:08 +00002817 emitEndOfLineMatrix(j + 1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002818 }
2819
2820 if (SecSrcLinesSize == 0)
2821 // Because we're emitting a debug_line section, we still need a line
2822 // table. The linker and friends expect it to exist. If there's nothing to
2823 // put into it, emit an empty table.
Devang Patel2c4ceb12009-11-21 02:48:08 +00002824 emitEndOfLineMatrix(1);
Bill Wendling94d04b82009-05-20 23:21:38 +00002825
Chris Lattnerc0215722010-04-04 19:25:43 +00002826 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002827}
2828
Devang Patel2c4ceb12009-11-21 02:48:08 +00002829/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
Bill Wendling94d04b82009-05-20 23:21:38 +00002830///
Devang Patel2c4ceb12009-11-21 02:48:08 +00002831void DwarfDebug::emitCommonDebugFrame() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00002832 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00002833 return;
2834
Chris Lattnerd38fee82010-04-05 00:13:49 +00002835 int stackGrowth = Asm->getTargetData().getPointerSize();
2836 if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
2837 TargetFrameInfo::StackGrowsDown)
2838 stackGrowth *= -1;
Bill Wendling94d04b82009-05-20 23:21:38 +00002839
2840 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002841 Asm->OutStreamer.SwitchSection(
2842 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002843
Chris Lattnerc0215722010-04-04 19:25:43 +00002844 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common"));
Chris Lattner233f52b2010-03-09 23:52:58 +00002845 Asm->OutStreamer.AddComment("Length of Common Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00002846 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_frame_common_end"),
2847 Asm->GetTempSymbol("debug_frame_common_begin"), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00002848
Chris Lattnerc0215722010-04-04 19:25:43 +00002849 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_begin"));
Chris Lattner233f52b2010-03-09 23:52:58 +00002850 Asm->OutStreamer.AddComment("CIE Identifier Tag");
Bill Wendling94d04b82009-05-20 23:21:38 +00002851 Asm->EmitInt32((int)dwarf::DW_CIE_ID);
Chris Lattner233f52b2010-03-09 23:52:58 +00002852 Asm->OutStreamer.AddComment("CIE Version");
Bill Wendling94d04b82009-05-20 23:21:38 +00002853 Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Chris Lattner233f52b2010-03-09 23:52:58 +00002854 Asm->OutStreamer.AddComment("CIE Augmentation");
Chris Lattner4cf202b2010-01-23 03:11:46 +00002855 Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
Chris Lattner7e1a8f82010-04-04 19:09:29 +00002856 Asm->EmitULEB128(1, "CIE Code Alignment Factor");
2857 Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Chris Lattner233f52b2010-03-09 23:52:58 +00002858 Asm->OutStreamer.AddComment("CIE RA Column");
Chris Lattnerd38fee82010-04-05 00:13:49 +00002859 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling94d04b82009-05-20 23:21:38 +00002860 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
Bill Wendling94d04b82009-05-20 23:21:38 +00002861
2862 std::vector<MachineMove> Moves;
2863 RI->getInitialFrameState(Moves);
2864
Chris Lattner02b86b92010-04-04 23:41:46 +00002865 Asm->EmitFrameMoves(Moves, 0, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00002866
2867 Asm->EmitAlignment(2, 0, 0, false);
Chris Lattnerc0215722010-04-04 19:25:43 +00002868 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
Bill Wendling94d04b82009-05-20 23:21:38 +00002869}
2870
Devang Patel2c4ceb12009-11-21 02:48:08 +00002871/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
Bill Wendling94d04b82009-05-20 23:21:38 +00002872/// section.
Chris Lattner206d61e2010-03-13 07:26:18 +00002873void DwarfDebug::
2874emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Chris Lattnerd38fee82010-04-05 00:13:49 +00002875 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00002876 return;
2877
2878 // Start the dwarf frame section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00002879 Asm->OutStreamer.SwitchSection(
2880 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00002881
Chris Lattner233f52b2010-03-09 23:52:58 +00002882 Asm->OutStreamer.AddComment("Length of Frame Information Entry");
Chris Lattner206d61e2010-03-13 07:26:18 +00002883 MCSymbol *DebugFrameBegin =
Chris Lattnerc0215722010-04-04 19:25:43 +00002884 Asm->GetTempSymbol("debug_frame_begin", DebugFrameInfo.Number);
Chris Lattner206d61e2010-03-13 07:26:18 +00002885 MCSymbol *DebugFrameEnd =
Chris Lattnerc0215722010-04-04 19:25:43 +00002886 Asm->GetTempSymbol("debug_frame_end", DebugFrameInfo.Number);
Chris Lattnera6437182010-04-04 19:58:12 +00002887 Asm->EmitLabelDifference(DebugFrameEnd, DebugFrameBegin, 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00002888
Chris Lattner206d61e2010-03-13 07:26:18 +00002889 Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Bill Wendling94d04b82009-05-20 23:21:38 +00002890
Chris Lattner233f52b2010-03-09 23:52:58 +00002891 Asm->OutStreamer.AddComment("FDE CIE offset");
Chris Lattner6189ed12010-04-04 23:25:33 +00002892 Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
2893 DwarfFrameSectionSym);
Bill Wendling94d04b82009-05-20 23:21:38 +00002894
Chris Lattner233f52b2010-03-09 23:52:58 +00002895 Asm->OutStreamer.AddComment("FDE initial location");
Chris Lattnerc0215722010-04-04 19:25:43 +00002896 MCSymbol *FuncBeginSym =
2897 Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Chris Lattnerfb658072010-03-13 07:40:56 +00002898 Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
Chris Lattnerd38fee82010-04-05 00:13:49 +00002899 Asm->getTargetData().getPointerSize(),
2900 0/*AddrSpace*/);
Chris Lattnerd85fc6e2010-03-10 01:17:49 +00002901
2902
Chris Lattner233f52b2010-03-09 23:52:58 +00002903 Asm->OutStreamer.AddComment("FDE address range");
Chris Lattnera6437182010-04-04 19:58:12 +00002904 Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
Chris Lattnerd38fee82010-04-05 00:13:49 +00002905 FuncBeginSym, Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00002906
Chris Lattner02b86b92010-04-04 23:41:46 +00002907 Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Bill Wendling94d04b82009-05-20 23:21:38 +00002908
2909 Asm->EmitAlignment(2, 0, 0, false);
Chris Lattner206d61e2010-03-13 07:26:18 +00002910 Asm->OutStreamer.EmitLabel(DebugFrameEnd);
Bill Wendling94d04b82009-05-20 23:21:38 +00002911}
2912
Devang Patel8a241142009-12-09 18:24:21 +00002913/// emitDebugPubNames - Emit visible names into a debug pubnames section.
2914///
2915void DwarfDebug::emitDebugPubNames() {
2916 // Start the dwarf pubnames section.
2917 Asm->OutStreamer.SwitchSection(
2918 Asm->getObjFileLowering().getDwarfPubNamesSection());
2919
Chris Lattner233f52b2010-03-09 23:52:58 +00002920 Asm->OutStreamer.AddComment("Length of Public Names Info");
Chris Lattnera6437182010-04-04 19:58:12 +00002921 Asm->EmitLabelDifference(
2922 Asm->GetTempSymbol("pubnames_end", ModuleCU->getID()),
2923 Asm->GetTempSymbol("pubnames_begin", ModuleCU->getID()), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00002924
Chris Lattnerc0215722010-04-04 19:25:43 +00002925 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin",
2926 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002927
Chris Lattner233f52b2010-03-09 23:52:58 +00002928 Asm->OutStreamer.AddComment("DWARF Version");
2929 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling94d04b82009-05-20 23:21:38 +00002930
Chris Lattner233f52b2010-03-09 23:52:58 +00002931 Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
Chris Lattner6189ed12010-04-04 23:25:33 +00002932 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
2933 DwarfInfoSectionSym);
Bill Wendling94d04b82009-05-20 23:21:38 +00002934
Chris Lattner233f52b2010-03-09 23:52:58 +00002935 Asm->OutStreamer.AddComment("Compilation Unit Length");
Chris Lattnera6437182010-04-04 19:58:12 +00002936 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
2937 Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
2938 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00002939
Devang Patel8a241142009-12-09 18:24:21 +00002940 const StringMap<DIE*> &Globals = ModuleCU->getGlobals();
Bill Wendling94d04b82009-05-20 23:21:38 +00002941 for (StringMap<DIE*>::const_iterator
2942 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
2943 const char *Name = GI->getKeyData();
Chris Lattner233f52b2010-03-09 23:52:58 +00002944 DIE *Entity = GI->second;
Bill Wendling94d04b82009-05-20 23:21:38 +00002945
Chris Lattner233f52b2010-03-09 23:52:58 +00002946 Asm->OutStreamer.AddComment("DIE offset");
2947 Asm->EmitInt32(Entity->getOffset());
Chris Lattner4cf202b2010-01-23 03:11:46 +00002948
Chris Lattner3f53c832010-04-04 18:52:31 +00002949 if (Asm->isVerbose())
Chris Lattner4cf202b2010-01-23 03:11:46 +00002950 Asm->OutStreamer.AddComment("External Name");
2951 Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
Bill Wendling94d04b82009-05-20 23:21:38 +00002952 }
2953
Chris Lattner233f52b2010-03-09 23:52:58 +00002954 Asm->OutStreamer.AddComment("End Mark");
2955 Asm->EmitInt32(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00002956 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end",
2957 ModuleCU->getID()));
Bill Wendling94d04b82009-05-20 23:21:38 +00002958}
2959
Devang Patel193f7202009-11-24 01:14:22 +00002960void DwarfDebug::emitDebugPubTypes() {
Devang Patelf3a03762009-11-24 19:18:41 +00002961 // Start the dwarf pubnames section.
2962 Asm->OutStreamer.SwitchSection(
2963 Asm->getObjFileLowering().getDwarfPubTypesSection());
Chris Lattner233f52b2010-03-09 23:52:58 +00002964 Asm->OutStreamer.AddComment("Length of Public Types Info");
Chris Lattnera6437182010-04-04 19:58:12 +00002965 Asm->EmitLabelDifference(
2966 Asm->GetTempSymbol("pubtypes_end", ModuleCU->getID()),
2967 Asm->GetTempSymbol("pubtypes_begin", ModuleCU->getID()), 4);
Devang Patel193f7202009-11-24 01:14:22 +00002968
Chris Lattnerc0215722010-04-04 19:25:43 +00002969 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_begin",
2970 ModuleCU->getID()));
Devang Patel193f7202009-11-24 01:14:22 +00002971
Chris Lattner3f53c832010-04-04 18:52:31 +00002972 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version");
Devang Patele3d6d222010-02-02 03:47:27 +00002973 Asm->EmitInt16(dwarf::DWARF_VERSION);
Devang Patel193f7202009-11-24 01:14:22 +00002974
Chris Lattner233f52b2010-03-09 23:52:58 +00002975 Asm->OutStreamer.AddComment("Offset of Compilation ModuleCU Info");
Chris Lattner6189ed12010-04-04 23:25:33 +00002976 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
2977 DwarfInfoSectionSym);
Devang Patel193f7202009-11-24 01:14:22 +00002978
Chris Lattner233f52b2010-03-09 23:52:58 +00002979 Asm->OutStreamer.AddComment("Compilation ModuleCU Length");
Chris Lattnera6437182010-04-04 19:58:12 +00002980 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", ModuleCU->getID()),
2981 Asm->GetTempSymbol("info_begin", ModuleCU->getID()),
2982 4);
Devang Patel193f7202009-11-24 01:14:22 +00002983
2984 const StringMap<DIE*> &Globals = ModuleCU->getGlobalTypes();
2985 for (StringMap<DIE*>::const_iterator
2986 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
2987 const char *Name = GI->getKeyData();
2988 DIE * Entity = GI->second;
2989
Chris Lattner3f53c832010-04-04 18:52:31 +00002990 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Devang Patele3d6d222010-02-02 03:47:27 +00002991 Asm->EmitInt32(Entity->getOffset());
Chris Lattner4cf202b2010-01-23 03:11:46 +00002992
Chris Lattner3f53c832010-04-04 18:52:31 +00002993 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
Devang Patel31acb892010-02-02 03:37:03 +00002994 Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
Devang Patel193f7202009-11-24 01:14:22 +00002995 }
2996
Chris Lattner233f52b2010-03-09 23:52:58 +00002997 Asm->OutStreamer.AddComment("End Mark");
2998 Asm->EmitInt32(0);
Chris Lattnerc0215722010-04-04 19:25:43 +00002999 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
3000 ModuleCU->getID()));
Devang Patel193f7202009-11-24 01:14:22 +00003001}
3002
Devang Patel2c4ceb12009-11-21 02:48:08 +00003003/// emitDebugStr - Emit visible names into a debug str section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003004///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003005void DwarfDebug::emitDebugStr() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003006 // Check to see if it is worth the effort.
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003007 if (StringPool.empty()) return;
3008
3009 // Start the dwarf str section.
3010 Asm->OutStreamer.SwitchSection(
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003011 Asm->getObjFileLowering().getDwarfStrSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003012
Chris Lattnerbc733f52010-03-13 02:17:42 +00003013 // Get all of the string pool entries and put them in an array by their ID so
3014 // we can sort them.
3015 SmallVector<std::pair<unsigned,
3016 StringMapEntry<std::pair<MCSymbol*, unsigned> >*>, 64> Entries;
3017
3018 for (StringMap<std::pair<MCSymbol*, unsigned> >::iterator
3019 I = StringPool.begin(), E = StringPool.end(); I != E; ++I)
3020 Entries.push_back(std::make_pair(I->second.second, &*I));
3021
3022 array_pod_sort(Entries.begin(), Entries.end());
3023
3024 for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003025 // Emit a label for reference from debug information entries.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003026 Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first);
Chris Lattner0d9d70f2010-03-09 23:38:23 +00003027
3028 // Emit the string itself.
Chris Lattnerbc733f52010-03-13 02:17:42 +00003029 Asm->OutStreamer.EmitBytes(Entries[i].second->getKey(), 0/*addrspace*/);
Bill Wendling94d04b82009-05-20 23:21:38 +00003030 }
3031}
3032
Devang Patel2c4ceb12009-11-21 02:48:08 +00003033/// emitDebugLoc - Emit visible names into a debug loc section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003034///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003035void DwarfDebug::emitDebugLoc() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003036 // Start the dwarf loc section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003037 Asm->OutStreamer.SwitchSection(
3038 Asm->getObjFileLowering().getDwarfLocSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003039}
3040
3041/// EmitDebugARanges - Emit visible names into a debug aranges section.
3042///
3043void DwarfDebug::EmitDebugARanges() {
3044 // Start the dwarf aranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003045 Asm->OutStreamer.SwitchSection(
3046 Asm->getObjFileLowering().getDwarfARangesSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003047}
3048
Devang Patel2c4ceb12009-11-21 02:48:08 +00003049/// emitDebugRanges - Emit visible names into a debug ranges section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003050///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003051void DwarfDebug::emitDebugRanges() {
Bill Wendling94d04b82009-05-20 23:21:38 +00003052 // Start the dwarf ranges section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003053 Asm->OutStreamer.SwitchSection(
3054 Asm->getObjFileLowering().getDwarfRangesSection());
Bill Wendling94d04b82009-05-20 23:21:38 +00003055}
3056
Devang Patel2c4ceb12009-11-21 02:48:08 +00003057/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
Bill Wendling94d04b82009-05-20 23:21:38 +00003058///
Devang Patel2c4ceb12009-11-21 02:48:08 +00003059void DwarfDebug::emitDebugMacInfo() {
Daniel Dunbarf612ff62009-09-19 20:40:05 +00003060 if (const MCSection *LineInfo =
Chris Lattner18a4c162009-08-02 07:24:22 +00003061 Asm->getObjFileLowering().getDwarfMacroInfoSection()) {
Bill Wendling94d04b82009-05-20 23:21:38 +00003062 // Start the dwarf macinfo section.
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003063 Asm->OutStreamer.SwitchSection(LineInfo);
Bill Wendling94d04b82009-05-20 23:21:38 +00003064 }
3065}
3066
Devang Patel2c4ceb12009-11-21 02:48:08 +00003067/// emitDebugInlineInfo - Emit inline info using following format.
Bill Wendling94d04b82009-05-20 23:21:38 +00003068/// Section Header:
3069/// 1. length of section
3070/// 2. Dwarf version number
3071/// 3. address size.
3072///
3073/// Entries (one "entry" for each function that was inlined):
3074///
3075/// 1. offset into __debug_str section for MIPS linkage name, if exists;
3076/// otherwise offset into __debug_str for regular function name.
3077/// 2. offset into __debug_str section for regular function name.
3078/// 3. an unsigned LEB128 number indicating the number of distinct inlining
3079/// instances for the function.
3080///
3081/// The rest of the entry consists of a {die_offset, low_pc} pair for each
3082/// inlined instance; the die_offset points to the inlined_subroutine die in the
3083/// __debug_info section, and the low_pc is the starting address for the
3084/// inlining instance.
Devang Patel2c4ceb12009-11-21 02:48:08 +00003085void DwarfDebug::emitDebugInlineInfo() {
Chris Lattnerd38fee82010-04-05 00:13:49 +00003086 if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
Bill Wendling94d04b82009-05-20 23:21:38 +00003087 return;
3088
Devang Patel1dbc7712009-06-29 20:45:18 +00003089 if (!ModuleCU)
Bill Wendling94d04b82009-05-20 23:21:38 +00003090 return;
3091
Chris Lattner6c2f9e12009-08-19 05:49:37 +00003092 Asm->OutStreamer.SwitchSection(
3093 Asm->getObjFileLowering().getDwarfDebugInlineSection());
Chris Lattner0ad9c912010-01-22 22:09:00 +00003094
Chris Lattner233f52b2010-03-09 23:52:58 +00003095 Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
Chris Lattnera6437182010-04-04 19:58:12 +00003096 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
3097 Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
Bill Wendling94d04b82009-05-20 23:21:38 +00003098
Chris Lattnerc0215722010-04-04 19:25:43 +00003099 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003100
Chris Lattner233f52b2010-03-09 23:52:58 +00003101 Asm->OutStreamer.AddComment("Dwarf Version");
3102 Asm->EmitInt16(dwarf::DWARF_VERSION);
3103 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003104 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling94d04b82009-05-20 23:21:38 +00003105
Devang Patel53bb5c92009-11-10 23:06:00 +00003106 for (SmallVector<MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
3107 E = InlinedSPNodes.end(); I != E; ++I) {
Jim Grosbach31ef40e2009-11-21 23:12:12 +00003108
Devang Patel53bb5c92009-11-10 23:06:00 +00003109 MDNode *Node = *I;
Devang Patel622b0262010-01-19 06:19:05 +00003110 DenseMap<MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
Jim Grosbach7ab38df2009-11-22 19:20:36 +00003111 = InlineInfo.find(Node);
Devang Patel53bb5c92009-11-10 23:06:00 +00003112 SmallVector<InlineInfoLabels, 4> &Labels = II->second;
Devang Patele4b27562009-08-28 23:24:31 +00003113 DISubprogram SP(Node);
Devang Patel65dbc902009-11-25 17:36:49 +00003114 StringRef LName = SP.getLinkageName();
3115 StringRef Name = SP.getName();
Bill Wendling94d04b82009-05-20 23:21:38 +00003116
Chris Lattner233f52b2010-03-09 23:52:58 +00003117 Asm->OutStreamer.AddComment("MIPS linkage name");
Chris Lattner4cf202b2010-01-23 03:11:46 +00003118 if (LName.empty()) {
3119 Asm->OutStreamer.EmitBytes(Name, 0);
3120 Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
3121 } else
Chris Lattner6189ed12010-04-04 23:25:33 +00003122 Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
3123 DwarfStrSectionSym);
Devang Patel53bb5c92009-11-10 23:06:00 +00003124
Chris Lattner233f52b2010-03-09 23:52:58 +00003125 Asm->OutStreamer.AddComment("Function name");
Chris Lattner6189ed12010-04-04 23:25:33 +00003126 Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
Chris Lattner7e1a8f82010-04-04 19:09:29 +00003127 Asm->EmitULEB128(Labels.size(), "Inline count");
Bill Wendling94d04b82009-05-20 23:21:38 +00003128
Devang Patel53bb5c92009-11-10 23:06:00 +00003129 for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
Bill Wendling94d04b82009-05-20 23:21:38 +00003130 LE = Labels.end(); LI != LE; ++LI) {
Chris Lattner3f53c832010-04-04 18:52:31 +00003131 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Chris Lattner6ed0f902010-03-09 00:31:02 +00003132 Asm->EmitInt32(LI->second->getOffset());
Bill Wendling94d04b82009-05-20 23:21:38 +00003133
Chris Lattner3f53c832010-04-04 18:52:31 +00003134 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
Chris Lattnerd38fee82010-04-05 00:13:49 +00003135 Asm->OutStreamer.EmitSymbolValue(LI->first,
3136 Asm->getTargetData().getPointerSize(),0);
Bill Wendling94d04b82009-05-20 23:21:38 +00003137 }
3138 }
3139
Chris Lattnerc0215722010-04-04 19:25:43 +00003140 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
Bill Wendling94d04b82009-05-20 23:21:38 +00003141}