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