blob: fb4d66cde10b3c7746e53377594cf323bc059d4c [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.
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000171 DIE *TheDIE;
Bill Wendling2f921f82009-05-15 09:23:25 +0000172public:
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +0000173 // AbsVar may be NULL.
Devang Patele1c53f22010-05-20 16:36:41 +0000174 DbgVariable(DIVariable V) : Var(V), TheDIE(0) {}
Bill Wendling2f921f82009-05-15 09:23:25 +0000175
176 // Accessors.
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000177 DIVariable getVariable() const { return Var; }
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000178 void setDIE(DIE *D) { TheDIE = D; }
179 DIE *getDIE() const { return TheDIE; }
Bill Wendling2f921f82009-05-15 09:23:25 +0000180};
181
182//===----------------------------------------------------------------------===//
Devang Patel6c74a872010-04-27 19:46:33 +0000183/// DbgRange - This is used to track range of instructions with identical
184/// debug info scope.
185///
186typedef std::pair<const MachineInstr *, const MachineInstr *> DbgRange;
187
188//===----------------------------------------------------------------------===//
Bill Wendling2f921f82009-05-15 09:23:25 +0000189/// DbgScope - This class is used to track scope information.
190///
Devang Patelf3d7c082009-11-16 21:53:40 +0000191class DbgScope {
Bill Wendling2f921f82009-05-15 09:23:25 +0000192 DbgScope *Parent; // Parent to this scope.
Jim Grosbach042483e2009-11-21 23:12:12 +0000193 DIDescriptor Desc; // Debug info descriptor for scope.
Devang Patel1973df22010-01-26 21:39:14 +0000194 // Location at which this scope is inlined.
Devang Patel32cc43c2010-05-07 20:54:48 +0000195 AssertingVH<const MDNode> InlinedAtLocation;
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000196 bool AbstractScope; // Abstract Scope
Devang Patel787f94c2009-10-01 18:25:23 +0000197 const MachineInstr *LastInsn; // Last instruction of this scope.
198 const MachineInstr *FirstInsn; // First instruction of this scope.
Devang Patel6c74a872010-04-27 19:46:33 +0000199 unsigned DFSIn, DFSOut;
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +0000200 // Scopes defined in scope. Contents not owned.
201 SmallVector<DbgScope *, 4> Scopes;
202 // Variables declared in scope. Contents owned.
203 SmallVector<DbgVariable *, 8> Variables;
Devang Patel6c74a872010-04-27 19:46:33 +0000204 SmallVector<DbgRange, 4> Ranges;
Owen Anderson9becc182009-06-24 22:53:20 +0000205 // Private state for dump()
206 mutable unsigned IndentLevel;
Bill Wendling2f921f82009-05-15 09:23:25 +0000207public:
Devang Patel32cc43c2010-05-07 20:54:48 +0000208 DbgScope(DbgScope *P, DIDescriptor D, const MDNode *I = 0)
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000209 : Parent(P), Desc(D), InlinedAtLocation(I), AbstractScope(false),
Devang Patel6c74a872010-04-27 19:46:33 +0000210 LastInsn(0), FirstInsn(0),
211 DFSIn(0), DFSOut(0), IndentLevel(0) {}
Bill Wendling2f921f82009-05-15 09:23:25 +0000212 virtual ~DbgScope();
213
214 // Accessors.
215 DbgScope *getParent() const { return Parent; }
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000216 void setParent(DbgScope *P) { Parent = P; }
Bill Wendling2f921f82009-05-15 09:23:25 +0000217 DIDescriptor getDesc() const { return Desc; }
Devang Patel32cc43c2010-05-07 20:54:48 +0000218 const MDNode *getInlinedAt() const { return InlinedAtLocation; }
219 const MDNode *getScopeNode() const { return Desc; }
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +0000220 const SmallVector<DbgScope *, 4> &getScopes() { return Scopes; }
221 const SmallVector<DbgVariable *, 8> &getVariables() { return Variables; }
Devang Patel6c74a872010-04-27 19:46:33 +0000222 const SmallVector<DbgRange, 4> &getRanges() { return Ranges; }
223
224 /// openInsnRange - This scope covers instruction range starting from MI.
225 void openInsnRange(const MachineInstr *MI) {
226 if (!FirstInsn)
227 FirstInsn = MI;
228
229 if (Parent)
230 Parent->openInsnRange(MI);
231 }
232
233 /// extendInsnRange - Extend the current instruction range covered by
234 /// this scope.
235 void extendInsnRange(const MachineInstr *MI) {
236 assert (FirstInsn && "MI Range is not open!");
237 LastInsn = MI;
238 if (Parent)
239 Parent->extendInsnRange(MI);
240 }
241
242 /// closeInsnRange - Create a range based on FirstInsn and LastInsn collected
243 /// until now. This is used when a new scope is encountered while walking
244 /// machine instructions.
245 void closeInsnRange(DbgScope *NewScope = NULL) {
246 assert (LastInsn && "Last insn missing!");
247 Ranges.push_back(DbgRange(FirstInsn, LastInsn));
248 FirstInsn = NULL;
249 LastInsn = NULL;
250 // If Parent dominates NewScope then do not close Parent's instruction
251 // range.
252 if (Parent && (!NewScope || !Parent->dominates(NewScope)))
253 Parent->closeInsnRange(NewScope);
254 }
255
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000256 void setAbstractScope() { AbstractScope = true; }
257 bool isAbstractScope() const { return AbstractScope; }
Devang Patel6c74a872010-04-27 19:46:33 +0000258
259 // Depth First Search support to walk and mainpluate DbgScope hierarchy.
260 unsigned getDFSOut() const { return DFSOut; }
261 void setDFSOut(unsigned O) { DFSOut = O; }
262 unsigned getDFSIn() const { return DFSIn; }
263 void setDFSIn(unsigned I) { DFSIn = I; }
264 bool dominates(const DbgScope *S) {
265 if (S == this)
266 return true;
267 if (DFSIn < S->getDFSIn() && DFSOut > S->getDFSOut())
268 return true;
269 return false;
270 }
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000271
Devang Patel930143b2009-11-21 02:48:08 +0000272 /// addScope - Add a scope to the scope.
Bill Wendling2f921f82009-05-15 09:23:25 +0000273 ///
Devang Patel930143b2009-11-21 02:48:08 +0000274 void addScope(DbgScope *S) { Scopes.push_back(S); }
Bill Wendling2f921f82009-05-15 09:23:25 +0000275
Devang Patel930143b2009-11-21 02:48:08 +0000276 /// addVariable - Add a variable to the scope.
Bill Wendling2f921f82009-05-15 09:23:25 +0000277 ///
Devang Patel930143b2009-11-21 02:48:08 +0000278 void addVariable(DbgVariable *V) { Variables.push_back(V); }
Bill Wendling2f921f82009-05-15 09:23:25 +0000279
Bill Wendling2f921f82009-05-15 09:23:25 +0000280#ifndef NDEBUG
281 void dump() const;
282#endif
283};
Devang Patel6c74a872010-04-27 19:46:33 +0000284
Chris Lattnerf5d06362010-04-05 04:09:20 +0000285} // end llvm namespace
Bill Wendling2f921f82009-05-15 09:23:25 +0000286
287#ifndef NDEBUG
288void DbgScope::dump() const {
David Greenec230cb92009-12-24 00:31:35 +0000289 raw_ostream &err = dbgs();
Chris Lattner81e8e022009-08-23 00:51:00 +0000290 err.indent(IndentLevel);
Devang Patel32cc43c2010-05-07 20:54:48 +0000291 const MDNode *N = Desc;
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000292 N->dump();
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000293 if (AbstractScope)
294 err << "Abstract Scope\n";
Bill Wendling2f921f82009-05-15 09:23:25 +0000295
296 IndentLevel += 2;
Devang Patelf6eeaeb2009-11-10 23:06:00 +0000297 if (!Scopes.empty())
298 err << "Children ...\n";
Bill Wendling2f921f82009-05-15 09:23:25 +0000299 for (unsigned i = 0, e = Scopes.size(); i != e; ++i)
300 if (Scopes[i] != this)
301 Scopes[i]->dump();
302
303 IndentLevel -= 2;
304}
305#endif
306
Bill Wendling2f921f82009-05-15 09:23:25 +0000307DbgScope::~DbgScope() {
Bill Wendling2f921f82009-05-15 09:23:25 +0000308 for (unsigned j = 0, M = Variables.size(); j < M; ++j)
309 delete Variables[j];
Bill Wendling2f921f82009-05-15 09:23:25 +0000310}
311
Chris Lattnerf0d6bd32010-04-05 05:11:15 +0000312DwarfDebug::DwarfDebug(AsmPrinter *A, Module *M)
Devang Patel1a0df9a2010-05-10 22:49:55 +0000313 : Asm(A), MMI(Asm->MMI), FirstCU(0),
Chris Lattner196dbdc2010-04-05 03:52:55 +0000314 AbbreviationsSet(InitAbbreviationsSetSize),
Devang Patel12563b32010-04-16 23:33:45 +0000315 CurrentFnDbgScope(0), PrevLabel(NULL) {
Chris Lattnerb7aa9522010-03-13 02:17:42 +0000316 NextStringPoolNumber = 0;
Chris Lattner6629ca92010-04-04 22:59:04 +0000317
Chris Lattnere58b5472010-04-04 23:10:38 +0000318 DwarfFrameSectionSym = DwarfInfoSectionSym = DwarfAbbrevSectionSym = 0;
319 DwarfStrSectionSym = TextSectionSym = 0;
Devang Patel6c74a872010-04-27 19:46:33 +0000320 DwarfDebugRangeSectionSym = 0;
321 FunctionBeginSym = 0;
Torok Edwinf8dba242010-04-07 10:44:46 +0000322 if (TimePassesIsEnabled) {
323 NamedRegionTimer T(DbgTimerName, DWARFGroupName);
324 beginModule(M);
325 } else {
326 beginModule(M);
327 }
Bill Wendling2f921f82009-05-15 09:23:25 +0000328}
329DwarfDebug::~DwarfDebug() {
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000330 for (unsigned j = 0, M = DIEBlocks.size(); j < M; ++j)
331 DIEBlocks[j]->~DIEBlock();
Bill Wendling2f921f82009-05-15 09:23:25 +0000332}
333
Chris Lattnerb7aa9522010-03-13 02:17:42 +0000334MCSymbol *DwarfDebug::getStringPoolEntry(StringRef Str) {
335 std::pair<MCSymbol*, unsigned> &Entry = StringPool[Str];
336 if (Entry.first) return Entry.first;
337
338 Entry.second = NextStringPoolNumber++;
Chris Lattnera179b522010-04-04 19:25:43 +0000339 return Entry.first = Asm->GetTempSymbol("string", Entry.second);
Chris Lattnerb7aa9522010-03-13 02:17:42 +0000340}
341
342
Devang Patel930143b2009-11-21 02:48:08 +0000343/// assignAbbrevNumber - Define a unique number for the abbreviation.
Bill Wendling2f921f82009-05-15 09:23:25 +0000344///
Devang Patel930143b2009-11-21 02:48:08 +0000345void DwarfDebug::assignAbbrevNumber(DIEAbbrev &Abbrev) {
Bill Wendling2f921f82009-05-15 09:23:25 +0000346 // Profile the node so that we can make it unique.
347 FoldingSetNodeID ID;
348 Abbrev.Profile(ID);
349
350 // Check the set for priors.
351 DIEAbbrev *InSet = AbbreviationsSet.GetOrInsertNode(&Abbrev);
352
353 // If it's newly added.
354 if (InSet == &Abbrev) {
355 // Add to abbreviation list.
356 Abbreviations.push_back(&Abbrev);
357
358 // Assign the vector position + 1 as its number.
359 Abbrev.setNumber(Abbreviations.size());
360 } else {
361 // Assign existing abbreviation number.
362 Abbrev.setNumber(InSet->getNumber());
363 }
364}
365
Devang Patel930143b2009-11-21 02:48:08 +0000366/// createDIEEntry - Creates a new DIEEntry to be a proxy for a debug
Bill Wendlingbcad77a2009-05-20 23:24:48 +0000367/// information entry.
Devang Patel930143b2009-11-21 02:48:08 +0000368DIEEntry *DwarfDebug::createDIEEntry(DIE *Entry) {
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000369 DIEEntry *Value = new (DIEValueAllocator) DIEEntry(Entry);
Bill Wendling2f921f82009-05-15 09:23:25 +0000370 return Value;
371}
372
Devang Patel930143b2009-11-21 02:48:08 +0000373/// addUInt - Add an unsigned integer attribute data and value.
Bill Wendling2f921f82009-05-15 09:23:25 +0000374///
Devang Patel930143b2009-11-21 02:48:08 +0000375void DwarfDebug::addUInt(DIE *Die, unsigned Attribute,
Bill Wendling2f921f82009-05-15 09:23:25 +0000376 unsigned Form, uint64_t Integer) {
377 if (!Form) Form = DIEInteger::BestForm(false, Integer);
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000378 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel930143b2009-11-21 02:48:08 +0000379 Die->addValue(Attribute, Form, Value);
Bill Wendling2f921f82009-05-15 09:23:25 +0000380}
381
Devang Patel930143b2009-11-21 02:48:08 +0000382/// addSInt - Add an signed integer attribute data and value.
Bill Wendling2f921f82009-05-15 09:23:25 +0000383///
Devang Patel930143b2009-11-21 02:48:08 +0000384void DwarfDebug::addSInt(DIE *Die, unsigned Attribute,
Bill Wendling2f921f82009-05-15 09:23:25 +0000385 unsigned Form, int64_t Integer) {
386 if (!Form) Form = DIEInteger::BestForm(true, Integer);
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000387 DIEValue *Value = new (DIEValueAllocator) DIEInteger(Integer);
Devang Patel930143b2009-11-21 02:48:08 +0000388 Die->addValue(Attribute, Form, Value);
Bill Wendling2f921f82009-05-15 09:23:25 +0000389}
390
Devang Patel8c339592009-12-02 15:25:16 +0000391/// addString - Add a string attribute data and value. DIEString only
392/// keeps string reference.
Devang Patel930143b2009-11-21 02:48:08 +0000393void DwarfDebug::addString(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerc3f23b82010-01-23 03:11:46 +0000394 StringRef String) {
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000395 DIEValue *Value = new (DIEValueAllocator) DIEString(String);
Devang Patel930143b2009-11-21 02:48:08 +0000396 Die->addValue(Attribute, Form, Value);
Bill Wendling2f921f82009-05-15 09:23:25 +0000397}
398
Devang Patel930143b2009-11-21 02:48:08 +0000399/// addLabel - Add a Dwarf label attribute data and value.
Bill Wendling2f921f82009-05-15 09:23:25 +0000400///
Devang Patel930143b2009-11-21 02:48:08 +0000401void DwarfDebug::addLabel(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerbc9210c2010-03-08 22:23:36 +0000402 const MCSymbol *Label) {
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000403 DIEValue *Value = new (DIEValueAllocator) DIELabel(Label);
Devang Patel930143b2009-11-21 02:48:08 +0000404 Die->addValue(Attribute, Form, Value);
Bill Wendling2f921f82009-05-15 09:23:25 +0000405}
406
Devang Patel930143b2009-11-21 02:48:08 +0000407/// addDelta - Add a label delta attribute data and value.
Bill Wendling2f921f82009-05-15 09:23:25 +0000408///
Devang Patel930143b2009-11-21 02:48:08 +0000409void DwarfDebug::addDelta(DIE *Die, unsigned Attribute, unsigned Form,
Chris Lattnerbc9210c2010-03-08 22:23:36 +0000410 const MCSymbol *Hi, const MCSymbol *Lo) {
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000411 DIEValue *Value = new (DIEValueAllocator) DIEDelta(Hi, Lo);
Devang Patel930143b2009-11-21 02:48:08 +0000412 Die->addValue(Attribute, Form, Value);
Bill Wendling2f921f82009-05-15 09:23:25 +0000413}
414
Chris Lattner3f3fb972010-04-05 05:24:55 +0000415/// addDIEEntry - Add a DIE attribute data and value.
416///
417void DwarfDebug::addDIEEntry(DIE *Die, unsigned Attribute, unsigned Form,
418 DIE *Entry) {
419 Die->addValue(Attribute, Form, createDIEEntry(Entry));
420}
421
422
Devang Patel930143b2009-11-21 02:48:08 +0000423/// addBlock - Add block data.
Bill Wendling2f921f82009-05-15 09:23:25 +0000424///
Devang Patel930143b2009-11-21 02:48:08 +0000425void DwarfDebug::addBlock(DIE *Die, unsigned Attribute, unsigned Form,
Bill Wendling2f921f82009-05-15 09:23:25 +0000426 DIEBlock *Block) {
Chris Lattner5a00dea2010-04-05 00:18:22 +0000427 Block->ComputeSize(Asm);
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000428 DIEBlocks.push_back(Block); // Memoize so we can call the destructor later on.
Devang Patel930143b2009-11-21 02:48:08 +0000429 Die->addValue(Attribute, Block->BestForm(), Block);
Bill Wendling2f921f82009-05-15 09:23:25 +0000430}
431
Devang Patel930143b2009-11-21 02:48:08 +0000432/// addSourceLine - Add location information to specified debug information
Bill Wendling2f921f82009-05-15 09:23:25 +0000433/// entry.
Devang Patel930143b2009-11-21 02:48:08 +0000434void DwarfDebug::addSourceLine(DIE *Die, const DIVariable *V) {
Devang Patel0625af22010-05-07 23:33:41 +0000435 // Verify variable.
436 if (!V->Verify())
Bill Wendling2f921f82009-05-15 09:23:25 +0000437 return;
438
439 unsigned Line = V->getLineNumber();
Devang Patel8119fe872010-03-08 22:02:50 +0000440 unsigned FileID = GetOrCreateSourceID(V->getContext().getDirectory(),
441 V->getContext().getFilename());
Bill Wendling2f921f82009-05-15 09:23:25 +0000442 assert(FileID && "Invalid file id");
Devang Patel930143b2009-11-21 02:48:08 +0000443 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
444 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling2f921f82009-05-15 09:23:25 +0000445}
446
Devang Patel930143b2009-11-21 02:48:08 +0000447/// addSourceLine - Add location information to specified debug information
Bill Wendling2f921f82009-05-15 09:23:25 +0000448/// entry.
Devang Patelcbe7a852010-05-07 23:19:07 +0000449void DwarfDebug::addSourceLine(DIE *Die, const DIGlobalVariable *G) {
Devang Patel0625af22010-05-07 23:33:41 +0000450 // Verify global variable.
451 if (!G->Verify())
Bill Wendling2f921f82009-05-15 09:23:25 +0000452 return;
453
454 unsigned Line = G->getLineNumber();
Devang Patel8119fe872010-03-08 22:02:50 +0000455 unsigned FileID = GetOrCreateSourceID(G->getContext().getDirectory(),
456 G->getContext().getFilename());
Bill Wendling2f921f82009-05-15 09:23:25 +0000457 assert(FileID && "Invalid file id");
Devang Patel930143b2009-11-21 02:48:08 +0000458 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
459 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling2f921f82009-05-15 09:23:25 +0000460}
Devang Patelb2de5fa2009-08-31 22:47:13 +0000461
Devang Patel930143b2009-11-21 02:48:08 +0000462/// addSourceLine - Add location information to specified debug information
Devang Patelb2de5fa2009-08-31 22:47:13 +0000463/// entry.
Devang Patel930143b2009-11-21 02:48:08 +0000464void DwarfDebug::addSourceLine(DIE *Die, const DISubprogram *SP) {
Devang Patel0625af22010-05-07 23:33:41 +0000465 // Verify subprogram.
466 if (!SP->Verify())
Devang Patelb2de5fa2009-08-31 22:47:13 +0000467 return;
Caroline Tice183a5192009-09-11 18:25:54 +0000468 // If the line number is 0, don't add it.
469 if (SP->getLineNumber() == 0)
470 return;
471
Devang Patelb2de5fa2009-08-31 22:47:13 +0000472 unsigned Line = SP->getLineNumber();
Devang Patel8119fe872010-03-08 22:02:50 +0000473 if (!SP->getContext().Verify())
474 return;
Devang Patel834392f2010-03-24 21:30:35 +0000475 unsigned FileID = GetOrCreateSourceID(SP->getDirectory(),
476 SP->getFilename());
Devang Patelb2de5fa2009-08-31 22:47:13 +0000477 assert(FileID && "Invalid file id");
Devang Patel930143b2009-11-21 02:48:08 +0000478 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
479 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Devang Patelb2de5fa2009-08-31 22:47:13 +0000480}
481
Devang Patel930143b2009-11-21 02:48:08 +0000482/// addSourceLine - Add location information to specified debug information
Devang Patelb2de5fa2009-08-31 22:47:13 +0000483/// entry.
Devang Patel930143b2009-11-21 02:48:08 +0000484void DwarfDebug::addSourceLine(DIE *Die, const DIType *Ty) {
Devang Patel0625af22010-05-07 23:33:41 +0000485 // Verify type.
486 if (!Ty->Verify())
Bill Wendling2f921f82009-05-15 09:23:25 +0000487 return;
488
489 unsigned Line = Ty->getLineNumber();
Devang Patel8119fe872010-03-08 22:02:50 +0000490 if (!Ty->getContext().Verify())
491 return;
492 unsigned FileID = GetOrCreateSourceID(Ty->getContext().getDirectory(),
493 Ty->getContext().getFilename());
Bill Wendling2f921f82009-05-15 09:23:25 +0000494 assert(FileID && "Invalid file id");
Devang Patel930143b2009-11-21 02:48:08 +0000495 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
496 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
Bill Wendling2f921f82009-05-15 09:23:25 +0000497}
498
Devang Patel1f4690c2009-12-15 19:16:48 +0000499/// addSourceLine - Add location information to specified debug information
500/// entry.
501void DwarfDebug::addSourceLine(DIE *Die, const DINameSpace *NS) {
Devang Patel0625af22010-05-07 23:33:41 +0000502 // Verify namespace.
503 if (!NS->Verify())
Devang Patel1f4690c2009-12-15 19:16:48 +0000504 return;
505
506 unsigned Line = NS->getLineNumber();
507 StringRef FN = NS->getFilename();
508 StringRef Dir = NS->getDirectory();
509
510 unsigned FileID = GetOrCreateSourceID(Dir, FN);
511 assert(FileID && "Invalid file id");
512 addUInt(Die, dwarf::DW_AT_decl_file, 0, FileID);
513 addUInt(Die, dwarf::DW_AT_decl_line, 0, Line);
514}
515
Caroline Ticec87c1e22009-08-31 21:19:37 +0000516/* Byref variables, in Blocks, are declared by the programmer as
517 "SomeType VarName;", but the compiler creates a
518 __Block_byref_x_VarName struct, and gives the variable VarName
519 either the struct, or a pointer to the struct, as its type. This
520 is necessary for various behind-the-scenes things the compiler
521 needs to do with by-reference variables in blocks.
522
523 However, as far as the original *programmer* is concerned, the
524 variable should still have type 'SomeType', as originally declared.
525
526 The following function dives into the __Block_byref_x_VarName
527 struct to find the original type of the variable. This will be
528 passed back to the code generating the type for the Debug
529 Information Entry for the variable 'VarName'. 'VarName' will then
530 have the original type 'SomeType' in its debug information.
531
532 The original type 'SomeType' will be the type of the field named
533 'VarName' inside the __Block_byref_x_VarName struct.
534
535 NOTE: In order for this to not completely fail on the debugger
536 side, the Debug Information Entry for the variable VarName needs to
537 have a DW_AT_location that tells the debugger how to unwind through
538 the pointers and __Block_byref_x_VarName struct to find the actual
Devang Patel930143b2009-11-21 02:48:08 +0000539 value of the variable. The function addBlockByrefType does this. */
Caroline Ticec87c1e22009-08-31 21:19:37 +0000540
541/// Find the type the programmer originally declared the variable to be
542/// and return that type.
543///
Devang Patel930143b2009-11-21 02:48:08 +0000544DIType DwarfDebug::getBlockByrefType(DIType Ty, std::string Name) {
Caroline Ticec87c1e22009-08-31 21:19:37 +0000545
546 DIType subType = Ty;
547 unsigned tag = Ty.getTag();
548
549 if (tag == dwarf::DW_TAG_pointer_type) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000550 DIDerivedType DTy = DIDerivedType(Ty);
Caroline Ticec87c1e22009-08-31 21:19:37 +0000551 subType = DTy.getTypeDerivedFrom();
552 }
553
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000554 DICompositeType blockStruct = DICompositeType(subType);
Caroline Ticec87c1e22009-08-31 21:19:37 +0000555 DIArray Elements = blockStruct.getTypeArray();
556
Caroline Ticec87c1e22009-08-31 21:19:37 +0000557 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
558 DIDescriptor Element = Elements.getElement(i);
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000559 DIDerivedType DT = DIDerivedType(Element);
Devang Patel2d9caf92009-11-25 17:36:49 +0000560 if (Name == DT.getName())
Caroline Ticec87c1e22009-08-31 21:19:37 +0000561 return (DT.getTypeDerivedFrom());
562 }
563
564 return Ty;
565}
566
Devang Patel930143b2009-11-21 02:48:08 +0000567/// addComplexAddress - Start with the address based on the location provided,
Mike Stump14cf8ec2009-09-30 00:08:22 +0000568/// and generate the DWARF information necessary to find the actual variable
569/// given the extra address information encoded in the DIVariable, starting from
570/// the starting location. Add the DWARF information to the die.
571///
Devang Patel930143b2009-11-21 02:48:08 +0000572void DwarfDebug::addComplexAddress(DbgVariable *&DV, DIE *Die,
Mike Stump14cf8ec2009-09-30 00:08:22 +0000573 unsigned Attribute,
574 const MachineLocation &Location) {
575 const DIVariable &VD = DV->getVariable();
576 DIType Ty = VD.getType();
577
578 // Decode the original location, and use that as the start of the byref
579 // variable's location.
Chris Lattner3a383cb2010-04-05 00:13:49 +0000580 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Mike Stump14cf8ec2009-09-30 00:08:22 +0000581 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000582 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Mike Stump14cf8ec2009-09-30 00:08:22 +0000583
584 if (Location.isReg()) {
585 if (Reg < 32) {
Devang Patel930143b2009-11-21 02:48:08 +0000586 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Mike Stump14cf8ec2009-09-30 00:08:22 +0000587 } else {
588 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel930143b2009-11-21 02:48:08 +0000589 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
590 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump14cf8ec2009-09-30 00:08:22 +0000591 }
592 } else {
593 if (Reg < 32)
Devang Patel930143b2009-11-21 02:48:08 +0000594 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Mike Stump14cf8ec2009-09-30 00:08:22 +0000595 else {
Devang Patel930143b2009-11-21 02:48:08 +0000596 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
597 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Mike Stump14cf8ec2009-09-30 00:08:22 +0000598 }
599
Devang Patel930143b2009-11-21 02:48:08 +0000600 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Mike Stump14cf8ec2009-09-30 00:08:22 +0000601 }
602
603 for (unsigned i = 0, N = VD.getNumAddrElements(); i < N; ++i) {
604 uint64_t Element = VD.getAddrElement(i);
605
606 if (Element == DIFactory::OpPlus) {
Devang Patel930143b2009-11-21 02:48:08 +0000607 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
608 addUInt(Block, 0, dwarf::DW_FORM_udata, VD.getAddrElement(++i));
Mike Stump14cf8ec2009-09-30 00:08:22 +0000609 } else if (Element == DIFactory::OpDeref) {
Devang Patel930143b2009-11-21 02:48:08 +0000610 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Mike Stump14cf8ec2009-09-30 00:08:22 +0000611 } else llvm_unreachable("unknown DIFactory Opcode");
612 }
613
614 // Now attach the location information to the DIE.
Devang Patel930143b2009-11-21 02:48:08 +0000615 addBlock(Die, Attribute, 0, Block);
Mike Stump14cf8ec2009-09-30 00:08:22 +0000616}
617
Caroline Ticec87c1e22009-08-31 21:19:37 +0000618/* Byref variables, in Blocks, are declared by the programmer as "SomeType
619 VarName;", but the compiler creates a __Block_byref_x_VarName struct, and
620 gives the variable VarName either the struct, or a pointer to the struct, as
621 its type. This is necessary for various behind-the-scenes things the
622 compiler needs to do with by-reference variables in Blocks.
623
624 However, as far as the original *programmer* is concerned, the variable
625 should still have type 'SomeType', as originally declared.
626
Devang Patel930143b2009-11-21 02:48:08 +0000627 The function getBlockByrefType dives into the __Block_byref_x_VarName
Caroline Ticec87c1e22009-08-31 21:19:37 +0000628 struct to find the original type of the variable, which is then assigned to
629 the variable's Debug Information Entry as its real type. So far, so good.
630 However now the debugger will expect the variable VarName to have the type
631 SomeType. So we need the location attribute for the variable to be an
Daniel Dunbarc418d6b2009-09-19 20:40:05 +0000632 expression that explains to the debugger how to navigate through the
Caroline Ticec87c1e22009-08-31 21:19:37 +0000633 pointers and struct to find the actual variable of type SomeType.
634
635 The following function does just that. We start by getting
636 the "normal" location for the variable. This will be the location
637 of either the struct __Block_byref_x_VarName or the pointer to the
638 struct __Block_byref_x_VarName.
639
640 The struct will look something like:
641
642 struct __Block_byref_x_VarName {
643 ... <various fields>
644 struct __Block_byref_x_VarName *forwarding;
645 ... <various other fields>
646 SomeType VarName;
647 ... <maybe more fields>
648 };
649
650 If we are given the struct directly (as our starting point) we
651 need to tell the debugger to:
652
653 1). Add the offset of the forwarding field.
654
Dan Gohman4a618822010-02-10 16:03:48 +0000655 2). Follow that pointer to get the real __Block_byref_x_VarName
Caroline Ticec87c1e22009-08-31 21:19:37 +0000656 struct to use (the real one may have been copied onto the heap).
657
658 3). Add the offset for the field VarName, to find the actual variable.
659
660 If we started with a pointer to the struct, then we need to
661 dereference that pointer first, before the other steps.
662 Translating this into DWARF ops, we will need to append the following
663 to the current location description for the variable:
664
665 DW_OP_deref -- optional, if we start with a pointer
666 DW_OP_plus_uconst <forward_fld_offset>
667 DW_OP_deref
668 DW_OP_plus_uconst <varName_fld_offset>
669
670 That is what this function does. */
671
Devang Patel930143b2009-11-21 02:48:08 +0000672/// addBlockByrefAddress - Start with the address based on the location
Caroline Ticec87c1e22009-08-31 21:19:37 +0000673/// provided, and generate the DWARF information necessary to find the
674/// actual Block variable (navigating the Block struct) based on the
675/// starting location. Add the DWARF information to the die. For
676/// more information, read large comment just above here.
677///
Devang Patel930143b2009-11-21 02:48:08 +0000678void DwarfDebug::addBlockByrefAddress(DbgVariable *&DV, DIE *Die,
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000679 unsigned Attribute,
680 const MachineLocation &Location) {
Caroline Ticec87c1e22009-08-31 21:19:37 +0000681 const DIVariable &VD = DV->getVariable();
682 DIType Ty = VD.getType();
683 DIType TmpTy = Ty;
684 unsigned Tag = Ty.getTag();
685 bool isPointer = false;
686
Devang Patel2d9caf92009-11-25 17:36:49 +0000687 StringRef varName = VD.getName();
Caroline Ticec87c1e22009-08-31 21:19:37 +0000688
689 if (Tag == dwarf::DW_TAG_pointer_type) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000690 DIDerivedType DTy = DIDerivedType(Ty);
Caroline Ticec87c1e22009-08-31 21:19:37 +0000691 TmpTy = DTy.getTypeDerivedFrom();
692 isPointer = true;
693 }
694
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000695 DICompositeType blockStruct = DICompositeType(TmpTy);
Caroline Ticec87c1e22009-08-31 21:19:37 +0000696
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000697 // Find the __forwarding field and the variable field in the __Block_byref
698 // struct.
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000699 DIArray Fields = blockStruct.getTypeArray();
700 DIDescriptor varField = DIDescriptor();
701 DIDescriptor forwardingField = DIDescriptor();
Caroline Ticec87c1e22009-08-31 21:19:37 +0000702
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000703 for (unsigned i = 0, N = Fields.getNumElements(); i < N; ++i) {
704 DIDescriptor Element = Fields.getElement(i);
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000705 DIDerivedType DT = DIDerivedType(Element);
Devang Patel2d9caf92009-11-25 17:36:49 +0000706 StringRef fieldName = DT.getName();
707 if (fieldName == "__forwarding")
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000708 forwardingField = Element;
Devang Patel2d9caf92009-11-25 17:36:49 +0000709 else if (fieldName == varName)
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000710 varField = Element;
711 }
Daniel Dunbarc418d6b2009-09-19 20:40:05 +0000712
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000713 // Get the offsets for the forwarding field and the variable field.
Chris Lattner71696ef2010-03-31 06:06:37 +0000714 unsigned forwardingFieldOffset =
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000715 DIDerivedType(forwardingField).getOffsetInBits() >> 3;
Chris Lattner71696ef2010-03-31 06:06:37 +0000716 unsigned varFieldOffset =
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000717 DIDerivedType(varField).getOffsetInBits() >> 3;
Caroline Ticec87c1e22009-08-31 21:19:37 +0000718
Mike Stump944fa252009-09-24 23:21:26 +0000719 // Decode the original location, and use that as the start of the byref
720 // variable's location.
Chris Lattner3a383cb2010-04-05 00:13:49 +0000721 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000722 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000723 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Caroline Ticec87c1e22009-08-31 21:19:37 +0000724
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000725 if (Location.isReg()) {
726 if (Reg < 32)
Devang Patel930143b2009-11-21 02:48:08 +0000727 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000728 else {
729 Reg = Reg - dwarf::DW_OP_reg0;
Devang Patel930143b2009-11-21 02:48:08 +0000730 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
731 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000732 }
733 } else {
734 if (Reg < 32)
Devang Patel930143b2009-11-21 02:48:08 +0000735 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000736 else {
Devang Patel930143b2009-11-21 02:48:08 +0000737 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
738 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000739 }
Caroline Ticec87c1e22009-08-31 21:19:37 +0000740
Devang Patel930143b2009-11-21 02:48:08 +0000741 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000742 }
Caroline Ticec87c1e22009-08-31 21:19:37 +0000743
Mike Stump944fa252009-09-24 23:21:26 +0000744 // If we started with a pointer to the __Block_byref... struct, then
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000745 // the first thing we need to do is dereference the pointer (DW_OP_deref).
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000746 if (isPointer)
Devang Patel930143b2009-11-21 02:48:08 +0000747 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticec87c1e22009-08-31 21:19:37 +0000748
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000749 // Next add the offset for the '__forwarding' field:
750 // DW_OP_plus_uconst ForwardingFieldOffset. Note there's no point in
751 // adding the offset if it's 0.
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000752 if (forwardingFieldOffset > 0) {
Devang Patel930143b2009-11-21 02:48:08 +0000753 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
754 addUInt(Block, 0, dwarf::DW_FORM_udata, forwardingFieldOffset);
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000755 }
Caroline Ticec87c1e22009-08-31 21:19:37 +0000756
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000757 // Now dereference the __forwarding field to get to the real __Block_byref
758 // struct: DW_OP_deref.
Devang Patel930143b2009-11-21 02:48:08 +0000759 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
Caroline Ticec87c1e22009-08-31 21:19:37 +0000760
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000761 // Now that we've got the real __Block_byref... struct, add the offset
762 // for the variable's field to get to the location of the actual variable:
763 // DW_OP_plus_uconst varFieldOffset. Again, don't add if it's 0.
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000764 if (varFieldOffset > 0) {
Devang Patel930143b2009-11-21 02:48:08 +0000765 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
766 addUInt(Block, 0, dwarf::DW_FORM_udata, varFieldOffset);
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000767 }
Caroline Ticec87c1e22009-08-31 21:19:37 +0000768
Daniel Dunbarbe22ec42009-09-19 20:40:14 +0000769 // Now attach the location information to the DIE.
Devang Patel930143b2009-11-21 02:48:08 +0000770 addBlock(Die, Attribute, 0, Block);
Caroline Ticec87c1e22009-08-31 21:19:37 +0000771}
772
Devang Patel930143b2009-11-21 02:48:08 +0000773/// addAddress - Add an address attribute to a die based on the location
Bill Wendling2f921f82009-05-15 09:23:25 +0000774/// provided.
Devang Patel930143b2009-11-21 02:48:08 +0000775void DwarfDebug::addAddress(DIE *Die, unsigned Attribute,
Bill Wendling2f921f82009-05-15 09:23:25 +0000776 const MachineLocation &Location) {
Chris Lattner3a383cb2010-04-05 00:13:49 +0000777 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling2f921f82009-05-15 09:23:25 +0000778 unsigned Reg = RI->getDwarfRegNum(Location.getReg(), false);
Benjamin Kramer74729ae2010-03-31 19:34:01 +0000779 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Bill Wendling2f921f82009-05-15 09:23:25 +0000780
781 if (Location.isReg()) {
782 if (Reg < 32) {
Devang Patel930143b2009-11-21 02:48:08 +0000783 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_reg0 + Reg);
Bill Wendling2f921f82009-05-15 09:23:25 +0000784 } else {
Devang Patel930143b2009-11-21 02:48:08 +0000785 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_regx);
786 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling2f921f82009-05-15 09:23:25 +0000787 }
788 } else {
789 if (Reg < 32) {
Devang Patel930143b2009-11-21 02:48:08 +0000790 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_breg0 + Reg);
Bill Wendling2f921f82009-05-15 09:23:25 +0000791 } else {
Devang Patel930143b2009-11-21 02:48:08 +0000792 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_bregx);
793 addUInt(Block, 0, dwarf::DW_FORM_udata, Reg);
Bill Wendling2f921f82009-05-15 09:23:25 +0000794 }
795
Devang Patel930143b2009-11-21 02:48:08 +0000796 addUInt(Block, 0, dwarf::DW_FORM_sdata, Location.getOffset());
Bill Wendling2f921f82009-05-15 09:23:25 +0000797 }
798
Devang Patel930143b2009-11-21 02:48:08 +0000799 addBlock(Die, Attribute, 0, Block);
Bill Wendling2f921f82009-05-15 09:23:25 +0000800}
801
Devang Patel173b2b92010-04-28 01:03:09 +0000802/// addRegisterAddress - Add register location entry in variable DIE.
Devang Patele1c53f22010-05-20 16:36:41 +0000803bool DwarfDebug::addRegisterAddress(DIE *Die, const MCSymbol *VS,
Devang Patel173b2b92010-04-28 01:03:09 +0000804 const MachineOperand &MO) {
805 assert (MO.isReg() && "Invalid machine operand!");
806 if (!MO.getReg())
807 return false;
808 MachineLocation Location;
809 Location.set(MO.getReg());
810 addAddress(Die, dwarf::DW_AT_location, Location);
Devang Patele1c53f22010-05-20 16:36:41 +0000811 if (VS)
Devang Patel173b2b92010-04-28 01:03:09 +0000812 addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
813 return true;
814}
815
816/// addConstantValue - Add constant value entry in variable DIE.
Devang Patele1c53f22010-05-20 16:36:41 +0000817bool DwarfDebug::addConstantValue(DIE *Die, const MCSymbol *VS,
Devang Patel173b2b92010-04-28 01:03:09 +0000818 const MachineOperand &MO) {
819 assert (MO.isImm() && "Invalid machine operand!");
820 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
821 unsigned Imm = MO.getImm();
822 addUInt(Block, 0, dwarf::DW_FORM_udata, Imm);
823 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
Devang Patele1c53f22010-05-20 16:36:41 +0000824 if (VS)
Devang Patel173b2b92010-04-28 01:03:09 +0000825 addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
826 return true;
827}
828
829/// addConstantFPValue - Add constant value entry in variable DIE.
Devang Patele1c53f22010-05-20 16:36:41 +0000830bool DwarfDebug::addConstantFPValue(DIE *Die, const MCSymbol *VS,
Devang Patel173b2b92010-04-28 01:03:09 +0000831 const MachineOperand &MO) {
832 assert (MO.isFPImm() && "Invalid machine operand!");
833 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
834 APFloat FPImm = MO.getFPImm()->getValueAPF();
835
836 // Get the raw data form of the floating point.
837 const APInt FltVal = FPImm.bitcastToAPInt();
838 const char *FltPtr = (const char*)FltVal.getRawData();
839
840 int NumBytes = FltVal.getBitWidth() / 8; // 8 bits per byte.
841 bool LittleEndian = Asm->getTargetData().isLittleEndian();
842 int Incr = (LittleEndian ? 1 : -1);
843 int Start = (LittleEndian ? 0 : NumBytes - 1);
844 int Stop = (LittleEndian ? NumBytes : -1);
845
846 // Output the constant to DWARF one byte at a time.
847 for (; Start != Stop; Start += Incr)
848 addUInt(Block, 0, dwarf::DW_FORM_data1,
849 (unsigned char)0xFF & FltPtr[Start]);
850
851 addBlock(Die, dwarf::DW_AT_const_value, 0, Block);
Devang Patele1c53f22010-05-20 16:36:41 +0000852 if (VS)
853 addLabel(Die, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr, VS);
Devang Patel173b2b92010-04-28 01:03:09 +0000854 return true;
855}
856
857
Devang Patel2b75ed22009-12-10 19:14:49 +0000858/// addToContextOwner - Add Die into the list of its context owner's children.
859void DwarfDebug::addToContextOwner(DIE *Die, DIDescriptor Context) {
Devang Patel3b548aa2010-03-08 20:52:55 +0000860 if (Context.isType()) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000861 DIE *ContextDIE = getOrCreateTypeDIE(DIType(Context));
Devang Patel2b75ed22009-12-10 19:14:49 +0000862 ContextDIE->addChild(Die);
Devang Patel1f4690c2009-12-15 19:16:48 +0000863 } else if (Context.isNameSpace()) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000864 DIE *ContextDIE = getOrCreateNameSpace(DINameSpace(Context));
Devang Patel1f4690c2009-12-15 19:16:48 +0000865 ContextDIE->addChild(Die);
Devang Patel1a0df9a2010-05-10 22:49:55 +0000866 } else if (DIE *ContextDIE = getCompileUnit(Context)->getDIE(Context))
Devang Patel2b75ed22009-12-10 19:14:49 +0000867 ContextDIE->addChild(Die);
868 else
Devang Patel1a0df9a2010-05-10 22:49:55 +0000869 getCompileUnit(Context)->addDie(Die);
Devang Patel2b75ed22009-12-10 19:14:49 +0000870}
871
Devang Patelb5b60ea2009-12-10 18:05:33 +0000872/// getOrCreateTypeDIE - Find existing DIE or create new DIE for the
873/// given DIType.
874DIE *DwarfDebug::getOrCreateTypeDIE(DIType Ty) {
Devang Patel1a0df9a2010-05-10 22:49:55 +0000875 CompileUnit *TypeCU = getCompileUnit(Ty);
876 DIE *TyDIE = TypeCU->getDIE(Ty);
Devang Patelb5b60ea2009-12-10 18:05:33 +0000877 if (TyDIE)
878 return TyDIE;
879
880 // Create new type.
881 TyDIE = new DIE(dwarf::DW_TAG_base_type);
Devang Patel1a0df9a2010-05-10 22:49:55 +0000882 TypeCU->insertDIE(Ty, TyDIE);
Devang Patelb5b60ea2009-12-10 18:05:33 +0000883 if (Ty.isBasicType())
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000884 constructTypeDIE(*TyDIE, DIBasicType(Ty));
Devang Patelb5b60ea2009-12-10 18:05:33 +0000885 else if (Ty.isCompositeType())
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000886 constructTypeDIE(*TyDIE, DICompositeType(Ty));
Devang Patelb5b60ea2009-12-10 18:05:33 +0000887 else {
888 assert(Ty.isDerivedType() && "Unknown kind of DIType");
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000889 constructTypeDIE(*TyDIE, DIDerivedType(Ty));
Devang Patelb5b60ea2009-12-10 18:05:33 +0000890 }
891
Devang Patel2b75ed22009-12-10 19:14:49 +0000892 addToContextOwner(TyDIE, Ty.getContext());
Devang Patelb5b60ea2009-12-10 18:05:33 +0000893 return TyDIE;
894}
895
Devang Patel930143b2009-11-21 02:48:08 +0000896/// addType - Add a new type attribute to the specified entity.
Devang Patel9ccfb642009-12-09 18:24:21 +0000897void DwarfDebug::addType(DIE *Entity, DIType Ty) {
Devang Patel8d6a2b72010-05-07 21:45:47 +0000898 if (!Ty.Verify())
Bill Wendling2f921f82009-05-15 09:23:25 +0000899 return;
900
901 // Check for pre-existence.
Devang Patel1a0df9a2010-05-10 22:49:55 +0000902 CompileUnit *TypeCU = getCompileUnit(Ty);
903 DIEEntry *Entry = TypeCU->getDIEEntry(Ty);
Bill Wendling2f921f82009-05-15 09:23:25 +0000904 // If it exists then use the existing value.
Devang Patel930143b2009-11-21 02:48:08 +0000905 if (Entry) {
906 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling2f921f82009-05-15 09:23:25 +0000907 return;
908 }
909
Bill Wendling2f921f82009-05-15 09:23:25 +0000910 // Construct type.
Devang Patelb5b60ea2009-12-10 18:05:33 +0000911 DIE *Buffer = getOrCreateTypeDIE(Ty);
Bill Wendling2f921f82009-05-15 09:23:25 +0000912
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +0000913 // Set up proxy.
914 Entry = createDIEEntry(Buffer);
Devang Patel1a0df9a2010-05-10 22:49:55 +0000915 TypeCU->insertDIEEntry(Ty, Entry);
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +0000916
Devang Patel930143b2009-11-21 02:48:08 +0000917 Entity->addValue(dwarf::DW_AT_type, dwarf::DW_FORM_ref4, Entry);
Bill Wendling2f921f82009-05-15 09:23:25 +0000918}
919
Devang Patel930143b2009-11-21 02:48:08 +0000920/// constructTypeDIE - Construct basic type die from DIBasicType.
Devang Patel9ccfb642009-12-09 18:24:21 +0000921void DwarfDebug::constructTypeDIE(DIE &Buffer, DIBasicType BTy) {
Bill Wendling2f921f82009-05-15 09:23:25 +0000922 // Get core information.
Devang Patel2d9caf92009-11-25 17:36:49 +0000923 StringRef Name = BTy.getName();
Bill Wendling2f921f82009-05-15 09:23:25 +0000924 Buffer.setTag(dwarf::DW_TAG_base_type);
Devang Patel930143b2009-11-21 02:48:08 +0000925 addUInt(&Buffer, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Bill Wendling2f921f82009-05-15 09:23:25 +0000926 BTy.getEncoding());
927
928 // Add name if not anonymous or intermediate type.
Devang Patel2d9caf92009-11-25 17:36:49 +0000929 if (!Name.empty())
Devang Patel930143b2009-11-21 02:48:08 +0000930 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling2f921f82009-05-15 09:23:25 +0000931 uint64_t Size = BTy.getSizeInBits() >> 3;
Devang Patel930143b2009-11-21 02:48:08 +0000932 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling2f921f82009-05-15 09:23:25 +0000933}
934
Devang Patel930143b2009-11-21 02:48:08 +0000935/// constructTypeDIE - Construct derived type die from DIDerivedType.
Devang Patel9ccfb642009-12-09 18:24:21 +0000936void DwarfDebug::constructTypeDIE(DIE &Buffer, DIDerivedType DTy) {
Bill Wendling2f921f82009-05-15 09:23:25 +0000937 // Get core information.
Devang Patel2d9caf92009-11-25 17:36:49 +0000938 StringRef Name = DTy.getName();
Bill Wendling2f921f82009-05-15 09:23:25 +0000939 uint64_t Size = DTy.getSizeInBits() >> 3;
940 unsigned Tag = DTy.getTag();
941
942 // FIXME - Workaround for templates.
943 if (Tag == dwarf::DW_TAG_inheritance) Tag = dwarf::DW_TAG_reference_type;
944
945 Buffer.setTag(Tag);
946
947 // Map to main type, void will not have a type.
948 DIType FromTy = DTy.getTypeDerivedFrom();
Devang Patel9ccfb642009-12-09 18:24:21 +0000949 addType(&Buffer, FromTy);
Bill Wendling2f921f82009-05-15 09:23:25 +0000950
951 // Add name if not anonymous or intermediate type.
Devang Patelae466ef2009-11-30 23:56:56 +0000952 if (!Name.empty())
Devang Patel930143b2009-11-21 02:48:08 +0000953 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling2f921f82009-05-15 09:23:25 +0000954
955 // Add size if non-zero (derived types might be zero-sized.)
956 if (Size)
Devang Patel930143b2009-11-21 02:48:08 +0000957 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling2f921f82009-05-15 09:23:25 +0000958
959 // Add source line info if available and TyDesc is not a forward declaration.
Devang Patelb5b51592009-11-23 18:43:37 +0000960 if (!DTy.isForwardDecl())
Devang Patel930143b2009-11-21 02:48:08 +0000961 addSourceLine(&Buffer, &DTy);
Bill Wendling2f921f82009-05-15 09:23:25 +0000962}
963
Devang Patel930143b2009-11-21 02:48:08 +0000964/// constructTypeDIE - Construct type DIE from DICompositeType.
Devang Patel9ccfb642009-12-09 18:24:21 +0000965void DwarfDebug::constructTypeDIE(DIE &Buffer, DICompositeType CTy) {
Bill Wendling2f921f82009-05-15 09:23:25 +0000966 // Get core information.
Devang Patel2d9caf92009-11-25 17:36:49 +0000967 StringRef Name = CTy.getName();
Bill Wendling2f921f82009-05-15 09:23:25 +0000968
969 uint64_t Size = CTy.getSizeInBits() >> 3;
970 unsigned Tag = CTy.getTag();
971 Buffer.setTag(Tag);
972
973 switch (Tag) {
974 case dwarf::DW_TAG_vector_type:
975 case dwarf::DW_TAG_array_type:
Devang Patel9ccfb642009-12-09 18:24:21 +0000976 constructArrayTypeDIE(Buffer, &CTy);
Bill Wendling2f921f82009-05-15 09:23:25 +0000977 break;
978 case dwarf::DW_TAG_enumeration_type: {
979 DIArray Elements = CTy.getTypeArray();
980
981 // Add enumerators to enumeration type.
982 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
983 DIE *ElemDie = NULL;
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000984 DIDescriptor Enum(Elements.getElement(i));
Devang Patel3b548aa2010-03-08 20:52:55 +0000985 if (Enum.isEnumerator()) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000986 ElemDie = constructEnumTypeDIE(DIEnumerator(Enum));
Devang Patel930143b2009-11-21 02:48:08 +0000987 Buffer.addChild(ElemDie);
Devang Patelfafa1fe2009-10-09 17:51:49 +0000988 }
Bill Wendling2f921f82009-05-15 09:23:25 +0000989 }
990 }
991 break;
992 case dwarf::DW_TAG_subroutine_type: {
993 // Add return type.
994 DIArray Elements = CTy.getTypeArray();
995 DIDescriptor RTy = Elements.getElement(0);
Devang Patelcfa8e9d2010-05-07 18:11:54 +0000996 addType(&Buffer, DIType(RTy));
Bill Wendling2f921f82009-05-15 09:23:25 +0000997
998 // Add prototype flag.
Devang Patel930143b2009-11-21 02:48:08 +0000999 addUInt(&Buffer, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling2f921f82009-05-15 09:23:25 +00001000
1001 // Add arguments.
1002 for (unsigned i = 1, N = Elements.getNumElements(); i < N; ++i) {
1003 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
1004 DIDescriptor Ty = Elements.getElement(i);
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001005 addType(Arg, DIType(Ty));
Devang Patel930143b2009-11-21 02:48:08 +00001006 Buffer.addChild(Arg);
Bill Wendling2f921f82009-05-15 09:23:25 +00001007 }
1008 }
1009 break;
1010 case dwarf::DW_TAG_structure_type:
1011 case dwarf::DW_TAG_union_type:
1012 case dwarf::DW_TAG_class_type: {
1013 // Add elements to structure type.
1014 DIArray Elements = CTy.getTypeArray();
1015
1016 // A forward struct declared type may not have elements available.
Devang Patel3b548aa2010-03-08 20:52:55 +00001017 unsigned N = Elements.getNumElements();
1018 if (N == 0)
Bill Wendling2f921f82009-05-15 09:23:25 +00001019 break;
1020
1021 // Add elements to structure type.
Devang Patel3b548aa2010-03-08 20:52:55 +00001022 for (unsigned i = 0; i < N; ++i) {
Bill Wendling2f921f82009-05-15 09:23:25 +00001023 DIDescriptor Element = Elements.getElement(i);
1024 DIE *ElemDie = NULL;
Devang Patel3b548aa2010-03-08 20:52:55 +00001025 if (Element.isSubprogram())
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001026 ElemDie = createSubprogramDIE(DISubprogram(Element));
Devang Patel3b548aa2010-03-08 20:52:55 +00001027 else if (Element.isVariable()) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001028 DIVariable DV(Element);
Devang Patel160c92d2010-01-30 01:08:30 +00001029 ElemDie = new DIE(dwarf::DW_TAG_variable);
1030 addString(ElemDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
1031 DV.getName());
1032 addType(ElemDie, DV.getType());
1033 addUInt(ElemDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1034 addUInt(ElemDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1035 addSourceLine(ElemDie, &DV);
Devang Patel3b548aa2010-03-08 20:52:55 +00001036 } else if (Element.isDerivedType())
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001037 ElemDie = createMemberDIE(DIDerivedType(Element));
Devang Patel3b548aa2010-03-08 20:52:55 +00001038 else
1039 continue;
Devang Patel930143b2009-11-21 02:48:08 +00001040 Buffer.addChild(ElemDie);
Bill Wendling2f921f82009-05-15 09:23:25 +00001041 }
1042
Devang Patel3082c012009-08-27 23:51:51 +00001043 if (CTy.isAppleBlockExtension())
Devang Patel930143b2009-11-21 02:48:08 +00001044 addUInt(&Buffer, dwarf::DW_AT_APPLE_block, dwarf::DW_FORM_flag, 1);
Bill Wendling2f921f82009-05-15 09:23:25 +00001045
1046 unsigned RLang = CTy.getRunTimeLang();
1047 if (RLang)
Devang Patel930143b2009-11-21 02:48:08 +00001048 addUInt(&Buffer, dwarf::DW_AT_APPLE_runtime_class,
Bill Wendling2f921f82009-05-15 09:23:25 +00001049 dwarf::DW_FORM_data1, RLang);
Devang Patel303a1be2010-01-26 21:16:06 +00001050
1051 DICompositeType ContainingType = CTy.getContainingType();
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001052 if (DIDescriptor(ContainingType).isCompositeType())
Devang Patel303a1be2010-01-26 21:16:06 +00001053 addDIEEntry(&Buffer, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4,
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001054 getOrCreateTypeDIE(DIType(ContainingType)));
Bill Wendling2f921f82009-05-15 09:23:25 +00001055 break;
1056 }
1057 default:
1058 break;
1059 }
1060
1061 // Add name if not anonymous or intermediate type.
Devang Patel2d9caf92009-11-25 17:36:49 +00001062 if (!Name.empty())
Devang Patel930143b2009-11-21 02:48:08 +00001063 addString(&Buffer, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Bill Wendling2f921f82009-05-15 09:23:25 +00001064
Devang Patelaedd6f52010-01-29 18:34:58 +00001065 if (Tag == dwarf::DW_TAG_enumeration_type || Tag == dwarf::DW_TAG_class_type ||
Bill Wendling2f921f82009-05-15 09:23:25 +00001066 Tag == dwarf::DW_TAG_structure_type || Tag == dwarf::DW_TAG_union_type) {
1067 // Add size if non-zero (derived types might be zero-sized.)
1068 if (Size)
Devang Patel930143b2009-11-21 02:48:08 +00001069 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, Size);
Bill Wendling2f921f82009-05-15 09:23:25 +00001070 else {
1071 // Add zero size if it is not a forward declaration.
1072 if (CTy.isForwardDecl())
Devang Patel930143b2009-11-21 02:48:08 +00001073 addUInt(&Buffer, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling2f921f82009-05-15 09:23:25 +00001074 else
Devang Patel930143b2009-11-21 02:48:08 +00001075 addUInt(&Buffer, dwarf::DW_AT_byte_size, 0, 0);
Bill Wendling2f921f82009-05-15 09:23:25 +00001076 }
1077
1078 // Add source line info if available.
1079 if (!CTy.isForwardDecl())
Devang Patel930143b2009-11-21 02:48:08 +00001080 addSourceLine(&Buffer, &CTy);
Bill Wendling2f921f82009-05-15 09:23:25 +00001081 }
1082}
1083
Devang Patel930143b2009-11-21 02:48:08 +00001084/// constructSubrangeDIE - Construct subrange DIE from DISubrange.
1085void DwarfDebug::constructSubrangeDIE(DIE &Buffer, DISubrange SR, DIE *IndexTy){
Bill Wendling2f921f82009-05-15 09:23:25 +00001086 int64_t L = SR.getLo();
1087 int64_t H = SR.getHi();
1088 DIE *DW_Subrange = new DIE(dwarf::DW_TAG_subrange_type);
1089
Devang Patel930143b2009-11-21 02:48:08 +00001090 addDIEEntry(DW_Subrange, dwarf::DW_AT_type, dwarf::DW_FORM_ref4, IndexTy);
Devang Patelf691df32009-08-14 20:59:16 +00001091 if (L)
Devang Patel930143b2009-11-21 02:48:08 +00001092 addSInt(DW_Subrange, dwarf::DW_AT_lower_bound, 0, L);
Devang Patel8f046022009-12-04 23:10:24 +00001093 addSInt(DW_Subrange, dwarf::DW_AT_upper_bound, 0, H);
Bill Wendling2f921f82009-05-15 09:23:25 +00001094
Devang Patel930143b2009-11-21 02:48:08 +00001095 Buffer.addChild(DW_Subrange);
Bill Wendling2f921f82009-05-15 09:23:25 +00001096}
1097
Devang Patel930143b2009-11-21 02:48:08 +00001098/// constructArrayTypeDIE - Construct array type DIE from DICompositeType.
Devang Patel9ccfb642009-12-09 18:24:21 +00001099void DwarfDebug::constructArrayTypeDIE(DIE &Buffer,
Bill Wendling2f921f82009-05-15 09:23:25 +00001100 DICompositeType *CTy) {
1101 Buffer.setTag(dwarf::DW_TAG_array_type);
1102 if (CTy->getTag() == dwarf::DW_TAG_vector_type)
Devang Patel930143b2009-11-21 02:48:08 +00001103 addUInt(&Buffer, dwarf::DW_AT_GNU_vector, dwarf::DW_FORM_flag, 1);
Bill Wendling2f921f82009-05-15 09:23:25 +00001104
1105 // Emit derived type.
Devang Patel9ccfb642009-12-09 18:24:21 +00001106 addType(&Buffer, CTy->getTypeDerivedFrom());
Bill Wendling2f921f82009-05-15 09:23:25 +00001107 DIArray Elements = CTy->getTypeArray();
1108
Devang Patel92e8c652009-11-21 00:31:03 +00001109 // Get an anonymous type for index type.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001110 CompileUnit *TheCU = getCompileUnit(*CTy);
1111 DIE *IdxTy = TheCU->getIndexTyDie();
Devang Patel92e8c652009-11-21 00:31:03 +00001112 if (!IdxTy) {
1113 // Construct an anonymous type for index type.
1114 IdxTy = new DIE(dwarf::DW_TAG_base_type);
Devang Patel930143b2009-11-21 02:48:08 +00001115 addUInt(IdxTy, dwarf::DW_AT_byte_size, 0, sizeof(int32_t));
1116 addUInt(IdxTy, dwarf::DW_AT_encoding, dwarf::DW_FORM_data1,
Devang Patel92e8c652009-11-21 00:31:03 +00001117 dwarf::DW_ATE_signed);
Devang Patel1a0df9a2010-05-10 22:49:55 +00001118 TheCU->addDie(IdxTy);
1119 TheCU->setIndexTyDie(IdxTy);
Devang Patel92e8c652009-11-21 00:31:03 +00001120 }
Bill Wendling2f921f82009-05-15 09:23:25 +00001121
1122 // Add subranges to array type.
1123 for (unsigned i = 0, N = Elements.getNumElements(); i < N; ++i) {
1124 DIDescriptor Element = Elements.getElement(i);
1125 if (Element.getTag() == dwarf::DW_TAG_subrange_type)
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001126 constructSubrangeDIE(Buffer, DISubrange(Element), IdxTy);
Bill Wendling2f921f82009-05-15 09:23:25 +00001127 }
1128}
1129
Devang Patel930143b2009-11-21 02:48:08 +00001130/// constructEnumTypeDIE - Construct enum type DIE from DIEnumerator.
Devang Patel3b548aa2010-03-08 20:52:55 +00001131DIE *DwarfDebug::constructEnumTypeDIE(DIEnumerator ETy) {
Bill Wendling2f921f82009-05-15 09:23:25 +00001132 DIE *Enumerator = new DIE(dwarf::DW_TAG_enumerator);
Devang Patel3b548aa2010-03-08 20:52:55 +00001133 StringRef Name = ETy.getName();
Devang Patel930143b2009-11-21 02:48:08 +00001134 addString(Enumerator, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel3b548aa2010-03-08 20:52:55 +00001135 int64_t Value = ETy.getEnumValue();
Devang Patel930143b2009-11-21 02:48:08 +00001136 addSInt(Enumerator, dwarf::DW_AT_const_value, dwarf::DW_FORM_sdata, Value);
Bill Wendling2f921f82009-05-15 09:23:25 +00001137 return Enumerator;
1138}
1139
Devang Patel43ef34d2010-01-05 01:46:14 +00001140/// getRealLinkageName - If special LLVM prefix that is used to inform the asm
1141/// printer to not emit usual symbol prefix before the symbol name is used then
1142/// return linkage name after skipping this special LLVM prefix.
1143static StringRef getRealLinkageName(StringRef LinkageName) {
1144 char One = '\1';
1145 if (LinkageName.startswith(StringRef(&One, 1)))
1146 return LinkageName.substr(1);
1147 return LinkageName;
1148}
1149
Devang Patel930143b2009-11-21 02:48:08 +00001150/// createGlobalVariableDIE - Create new DIE using GV.
Devang Patel9ccfb642009-12-09 18:24:21 +00001151DIE *DwarfDebug::createGlobalVariableDIE(const DIGlobalVariable &GV) {
Jim Grosbach00e9c612009-11-22 19:20:36 +00001152 // If the global variable was optmized out then no need to create debug info
1153 // entry.
Devang Patelcc11371b2009-11-06 17:58:12 +00001154 if (!GV.getGlobal()) return NULL;
Devang Patel2d9caf92009-11-25 17:36:49 +00001155 if (GV.getDisplayName().empty()) return NULL;
Devang Patel06ce6502009-11-06 01:30:04 +00001156
Bill Wendling2f921f82009-05-15 09:23:25 +00001157 DIE *GVDie = new DIE(dwarf::DW_TAG_variable);
Jim Grosbach042483e2009-11-21 23:12:12 +00001158 addString(GVDie, dwarf::DW_AT_name, dwarf::DW_FORM_string,
Devang Patelb2969422009-09-29 18:40:58 +00001159 GV.getDisplayName());
1160
Devang Patel2d9caf92009-11-25 17:36:49 +00001161 StringRef LinkageName = GV.getLinkageName();
Devang Patel43ef34d2010-01-05 01:46:14 +00001162 if (!LinkageName.empty())
Devang Patel930143b2009-11-21 02:48:08 +00001163 addString(GVDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel43ef34d2010-01-05 01:46:14 +00001164 getRealLinkageName(LinkageName));
1165
Devang Patel9ccfb642009-12-09 18:24:21 +00001166 addType(GVDie, GV.getType());
Bill Wendling2f921f82009-05-15 09:23:25 +00001167 if (!GV.isLocalToUnit())
Devang Patel930143b2009-11-21 02:48:08 +00001168 addUInt(GVDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
1169 addSourceLine(GVDie, &GV);
Devang Patel4144a822009-10-05 23:22:08 +00001170
Bill Wendling2f921f82009-05-15 09:23:25 +00001171 return GVDie;
1172}
1173
Devang Patel930143b2009-11-21 02:48:08 +00001174/// createMemberDIE - Create new member DIE.
Devang Patel9ccfb642009-12-09 18:24:21 +00001175DIE *DwarfDebug::createMemberDIE(const DIDerivedType &DT) {
Bill Wendling2f921f82009-05-15 09:23:25 +00001176 DIE *MemberDie = new DIE(DT.getTag());
Devang Patel2d9caf92009-11-25 17:36:49 +00001177 StringRef Name = DT.getName();
1178 if (!Name.empty())
Devang Patel930143b2009-11-21 02:48:08 +00001179 addString(MemberDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
Devang Patel2d9caf92009-11-25 17:36:49 +00001180
Devang Patel9ccfb642009-12-09 18:24:21 +00001181 addType(MemberDie, DT.getTypeDerivedFrom());
Bill Wendling2f921f82009-05-15 09:23:25 +00001182
Devang Patel930143b2009-11-21 02:48:08 +00001183 addSourceLine(MemberDie, &DT);
Bill Wendling2f921f82009-05-15 09:23:25 +00001184
Benjamin Kramer74729ae2010-03-31 19:34:01 +00001185 DIEBlock *MemLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Patel930143b2009-11-21 02:48:08 +00001186 addUInt(MemLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus_uconst);
Devang Patel67f56f02009-11-04 22:06:12 +00001187
Bill Wendling2f921f82009-05-15 09:23:25 +00001188 uint64_t Size = DT.getSizeInBits();
Devang Patelf05d5722009-11-04 23:48:00 +00001189 uint64_t FieldSize = DT.getOriginalTypeSize();
Bill Wendling2f921f82009-05-15 09:23:25 +00001190
1191 if (Size != FieldSize) {
1192 // Handle bitfield.
Devang Patel930143b2009-11-21 02:48:08 +00001193 addUInt(MemberDie, dwarf::DW_AT_byte_size, 0, DT.getOriginalTypeSize()>>3);
1194 addUInt(MemberDie, dwarf::DW_AT_bit_size, 0, DT.getSizeInBits());
Bill Wendling2f921f82009-05-15 09:23:25 +00001195
1196 uint64_t Offset = DT.getOffsetInBits();
Bill Wendling2f921f82009-05-15 09:23:25 +00001197 uint64_t AlignMask = ~(DT.getAlignInBits() - 1);
1198 uint64_t HiMark = (Offset + FieldSize) & AlignMask;
Benjamin Kramer2b459982010-01-07 17:50:57 +00001199 uint64_t FieldOffset = (HiMark - FieldSize);
Bill Wendling2f921f82009-05-15 09:23:25 +00001200 Offset -= FieldOffset;
1201
1202 // Maybe we need to work from the other end.
Chris Lattner3a383cb2010-04-05 00:13:49 +00001203 if (Asm->getTargetData().isLittleEndian())
1204 Offset = FieldSize - (Offset + Size);
Devang Patel930143b2009-11-21 02:48:08 +00001205 addUInt(MemberDie, dwarf::DW_AT_bit_offset, 0, Offset);
Bill Wendling2f921f82009-05-15 09:23:25 +00001206
Devang Patel67f56f02009-11-04 22:06:12 +00001207 // Here WD_AT_data_member_location points to the anonymous
1208 // field that includes this bit field.
Devang Patel930143b2009-11-21 02:48:08 +00001209 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, FieldOffset >> 3);
Devang Patel67f56f02009-11-04 22:06:12 +00001210
1211 } else
1212 // This is not a bitfield.
Devang Patel930143b2009-11-21 02:48:08 +00001213 addUInt(MemLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits() >> 3);
Devang Patel67f56f02009-11-04 22:06:12 +00001214
Devang Pateld2316892010-02-03 20:08:48 +00001215 if (DT.getTag() == dwarf::DW_TAG_inheritance
1216 && DT.isVirtual()) {
1217
1218 // For C++, virtual base classes are not at fixed offset. Use following
1219 // expression to extract appropriate offset from vtable.
1220 // BaseAddr = ObAddr + *((*ObAddr) - Offset)
1221
Benjamin Kramer74729ae2010-03-31 19:34:01 +00001222 DIEBlock *VBaseLocationDie = new (DIEValueAllocator) DIEBlock();
Devang Pateld2316892010-02-03 20:08:48 +00001223 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_dup);
1224 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1225 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1226 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_udata, DT.getOffsetInBits());
1227 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_minus);
1228 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_deref);
1229 addUInt(VBaseLocationDie, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_plus);
1230
1231 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0,
1232 VBaseLocationDie);
1233 } else
1234 addBlock(MemberDie, dwarf::DW_AT_data_member_location, 0, MemLocationDie);
Bill Wendling2f921f82009-05-15 09:23:25 +00001235
1236 if (DT.isProtected())
Devang Pateleb57c592009-12-03 19:11:07 +00001237 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling2f921f82009-05-15 09:23:25 +00001238 dwarf::DW_ACCESS_protected);
1239 else if (DT.isPrivate())
Devang Pateleb57c592009-12-03 19:11:07 +00001240 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
Bill Wendling2f921f82009-05-15 09:23:25 +00001241 dwarf::DW_ACCESS_private);
Devang Pateleb57c592009-12-03 19:11:07 +00001242 else if (DT.getTag() == dwarf::DW_TAG_inheritance)
1243 addUInt(MemberDie, dwarf::DW_AT_accessibility, dwarf::DW_FORM_flag,
1244 dwarf::DW_ACCESS_public);
1245 if (DT.isVirtual())
1246 addUInt(MemberDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag,
1247 dwarf::DW_VIRTUALITY_virtual);
Bill Wendling2f921f82009-05-15 09:23:25 +00001248 return MemberDie;
1249}
1250
Devang Patel525dda02009-12-14 16:18:45 +00001251/// createSubprogramDIE - Create new DIE using SP.
1252DIE *DwarfDebug::createSubprogramDIE(const DISubprogram &SP, bool MakeDecl) {
Devang Patel1a0df9a2010-05-10 22:49:55 +00001253 CompileUnit *SPCU = getCompileUnit(SP);
1254 DIE *SPDie = SPCU->getDIE(SP);
Devang Patel525dda02009-12-14 16:18:45 +00001255 if (SPDie)
1256 return SPDie;
1257
1258 SPDie = new DIE(dwarf::DW_TAG_subprogram);
Devang Patelf200b392010-03-02 17:58:15 +00001259 // Constructors and operators for anonymous aggregates do not have names.
Devang Pateld0fa3042010-03-02 01:26:20 +00001260 if (!SP.getName().empty())
1261 addString(SPDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, SP.getName());
Bill Wendling2f921f82009-05-15 09:23:25 +00001262
Devang Patel2d9caf92009-11-25 17:36:49 +00001263 StringRef LinkageName = SP.getLinkageName();
Devang Patel43ef34d2010-01-05 01:46:14 +00001264 if (!LinkageName.empty())
Devang Patel930143b2009-11-21 02:48:08 +00001265 addString(SPDie, dwarf::DW_AT_MIPS_linkage_name, dwarf::DW_FORM_string,
Devang Patel43ef34d2010-01-05 01:46:14 +00001266 getRealLinkageName(LinkageName));
1267
Devang Patel930143b2009-11-21 02:48:08 +00001268 addSourceLine(SPDie, &SP);
Bill Wendling2f921f82009-05-15 09:23:25 +00001269
Bill Wendling2f921f82009-05-15 09:23:25 +00001270 // Add prototyped tag, if C or ObjC.
1271 unsigned Lang = SP.getCompileUnit().getLanguage();
1272 if (Lang == dwarf::DW_LANG_C99 || Lang == dwarf::DW_LANG_C89 ||
1273 Lang == dwarf::DW_LANG_ObjC)
Devang Patel930143b2009-11-21 02:48:08 +00001274 addUInt(SPDie, dwarf::DW_AT_prototyped, dwarf::DW_FORM_flag, 1);
Bill Wendling2f921f82009-05-15 09:23:25 +00001275
1276 // Add Return Type.
Devang Patel236526d2009-12-03 01:25:38 +00001277 DICompositeType SPTy = SP.getType();
1278 DIArray Args = SPTy.getTypeArray();
Bill Wendling2f921f82009-05-15 09:23:25 +00001279 unsigned SPTag = SPTy.getTag();
Devang Pateleb57c592009-12-03 19:11:07 +00001280
Devang Patel3b548aa2010-03-08 20:52:55 +00001281 if (Args.getNumElements() == 0 || SPTag != dwarf::DW_TAG_subroutine_type)
Devang Patel9ccfb642009-12-09 18:24:21 +00001282 addType(SPDie, SPTy);
Devang Patel236526d2009-12-03 01:25:38 +00001283 else
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001284 addType(SPDie, DIType(Args.getElement(0)));
Devang Patel236526d2009-12-03 01:25:38 +00001285
Devang Pateleb57c592009-12-03 19:11:07 +00001286 unsigned VK = SP.getVirtuality();
1287 if (VK) {
1288 addUInt(SPDie, dwarf::DW_AT_virtuality, dwarf::DW_FORM_flag, VK);
Benjamin Kramer74729ae2010-03-31 19:34:01 +00001289 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Pateleb57c592009-12-03 19:11:07 +00001290 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_constu);
1291 addUInt(Block, 0, dwarf::DW_FORM_data1, SP.getVirtualIndex());
1292 addBlock(SPDie, dwarf::DW_AT_vtable_elem_location, 0, Block);
Devang Patel018b29b2010-01-19 06:19:05 +00001293 ContainingTypeMap.insert(std::make_pair(SPDie,
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001294 SP.getContainingType()));
Devang Pateleb57c592009-12-03 19:11:07 +00001295 }
1296
Devang Patel525dda02009-12-14 16:18:45 +00001297 if (MakeDecl || !SP.isDefinition()) {
Devang Patel930143b2009-11-21 02:48:08 +00001298 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Bill Wendling2f921f82009-05-15 09:23:25 +00001299
1300 // Add arguments. Do not add arguments for subprogram definition. They will
Devang Patel236526d2009-12-03 01:25:38 +00001301 // be handled while processing variables.
1302 DICompositeType SPTy = SP.getType();
1303 DIArray Args = SPTy.getTypeArray();
1304 unsigned SPTag = SPTy.getTag();
1305
Bill Wendling2f921f82009-05-15 09:23:25 +00001306 if (SPTag == dwarf::DW_TAG_subroutine_type)
1307 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1308 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001309 DIType ATy = DIType(DIType(Args.getElement(i)));
Devang Patel6efc8e52010-02-06 01:02:37 +00001310 addType(Arg, ATy);
1311 if (ATy.isArtificial())
1312 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patel930143b2009-11-21 02:48:08 +00001313 SPDie->addChild(Arg);
Bill Wendling2f921f82009-05-15 09:23:25 +00001314 }
1315 }
1316
Devang Patel999b4992010-02-03 19:57:19 +00001317 if (SP.isArtificial())
1318 addUInt(SPDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1319
Devang Patelb4e3b902010-04-30 19:38:23 +00001320 if (!SP.isLocalToUnit())
1321 addUInt(SPDie, dwarf::DW_AT_external, dwarf::DW_FORM_flag, 1);
Devang Patel61880932010-04-19 19:14:02 +00001322
Devang Patelb4e3b902010-04-30 19:38:23 +00001323 if (SP.isOptimized())
1324 addUInt(SPDie, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
1325
Devang Patelb4e3b902010-04-30 19:38:23 +00001326 // DW_TAG_inlined_subroutine may refer to this DIE.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001327 SPCU->insertDIE(SP, SPDie);
Devang Patelb4e3b902010-04-30 19:38:23 +00001328
Bill Wendling2f921f82009-05-15 09:23:25 +00001329 return SPDie;
1330}
1331
Devang Patel32cc43c2010-05-07 20:54:48 +00001332DbgScope *DwarfDebug::getOrCreateAbstractScope(const MDNode *N) {
Chris Lattner8d2fe282010-03-31 05:36:29 +00001333 assert(N && "Invalid Scope encoding!");
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001334
1335 DbgScope *AScope = AbstractScopes.lookup(N);
1336 if (AScope)
1337 return AScope;
Jim Grosbach042483e2009-11-21 23:12:12 +00001338
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001339 DbgScope *Parent = NULL;
1340
1341 DIDescriptor Scope(N);
1342 if (Scope.isLexicalBlock()) {
1343 DILexicalBlock DB(N);
1344 DIDescriptor ParentDesc = DB.getContext();
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001345 Parent = getOrCreateAbstractScope(ParentDesc);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001346 }
1347
1348 AScope = new DbgScope(Parent, DIDescriptor(N), NULL);
1349
1350 if (Parent)
Devang Patel930143b2009-11-21 02:48:08 +00001351 Parent->addScope(AScope);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001352 AScope->setAbstractScope();
1353 AbstractScopes[N] = AScope;
1354 if (DIDescriptor(N).isSubprogram())
1355 AbstractScopesList.push_back(AScope);
1356 return AScope;
1357}
Devang Patel75cc16c2009-10-01 20:31:14 +00001358
Devang Patel019922d2010-04-06 23:53:48 +00001359/// isSubprogramContext - Return true if Context is either a subprogram
1360/// or another context nested inside a subprogram.
Devang Patel32cc43c2010-05-07 20:54:48 +00001361static bool isSubprogramContext(const MDNode *Context) {
Devang Patel019922d2010-04-06 23:53:48 +00001362 if (!Context)
1363 return false;
1364 DIDescriptor D(Context);
1365 if (D.isSubprogram())
1366 return true;
1367 if (D.isType())
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001368 return isSubprogramContext(DIType(Context).getContext());
Devang Patel019922d2010-04-06 23:53:48 +00001369 return false;
1370}
1371
Jim Grosbach042483e2009-11-21 23:12:12 +00001372/// updateSubprogramScopeDIE - Find DIE for the given subprogram and
Devang Patel930143b2009-11-21 02:48:08 +00001373/// attach appropriate DW_AT_low_pc and DW_AT_high_pc attributes.
1374/// If there are global variables in this scope then create and insert
1375/// DIEs for these variables.
Devang Patel32cc43c2010-05-07 20:54:48 +00001376DIE *DwarfDebug::updateSubprogramScopeDIE(const MDNode *SPNode) {
Devang Patel1a0df9a2010-05-10 22:49:55 +00001377 CompileUnit *SPCU = getCompileUnit(SPNode);
1378 DIE *SPDie = SPCU->getDIE(SPNode);
Chris Lattner3a383cb2010-04-05 00:13:49 +00001379 assert(SPDie && "Unable to find subprogram DIE!");
1380 DISubprogram SP(SPNode);
Chris Lattner2c3f4782010-03-13 07:26:18 +00001381
Chris Lattner3a383cb2010-04-05 00:13:49 +00001382 // There is not any need to generate specification DIE for a function
1383 // defined at compile unit level. If a function is defined inside another
1384 // function then gdb prefers the definition at top level and but does not
1385 // expect specification DIE in parent function. So avoid creating
1386 // specification DIE for a function defined inside a function.
1387 if (SP.isDefinition() && !SP.getContext().isCompileUnit() &&
Devang Patel019922d2010-04-06 23:53:48 +00001388 !SP.getContext().isFile() &&
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001389 !isSubprogramContext(SP.getContext())) {
Chris Lattner3a383cb2010-04-05 00:13:49 +00001390 addUInt(SPDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
1391
1392 // Add arguments.
1393 DICompositeType SPTy = SP.getType();
1394 DIArray Args = SPTy.getTypeArray();
1395 unsigned SPTag = SPTy.getTag();
1396 if (SPTag == dwarf::DW_TAG_subroutine_type)
1397 for (unsigned i = 1, N = Args.getNumElements(); i < N; ++i) {
1398 DIE *Arg = new DIE(dwarf::DW_TAG_formal_parameter);
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001399 DIType ATy = DIType(DIType(Args.getElement(i)));
Chris Lattner3a383cb2010-04-05 00:13:49 +00001400 addType(Arg, ATy);
1401 if (ATy.isArtificial())
1402 addUInt(Arg, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
1403 SPDie->addChild(Arg);
1404 }
1405 DIE *SPDeclDie = SPDie;
1406 SPDie = new DIE(dwarf::DW_TAG_subprogram);
1407 addDIEEntry(SPDie, dwarf::DW_AT_specification, dwarf::DW_FORM_ref4,
1408 SPDeclDie);
Devang Patel1a0df9a2010-05-10 22:49:55 +00001409 SPCU->addDie(SPDie);
Chris Lattner3a383cb2010-04-05 00:13:49 +00001410 }
1411
1412 addLabel(SPDie, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr,
1413 Asm->GetTempSymbol("func_begin", Asm->getFunctionNumber()));
1414 addLabel(SPDie, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr,
1415 Asm->GetTempSymbol("func_end", Asm->getFunctionNumber()));
1416 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
1417 MachineLocation Location(RI->getFrameRegister(*Asm->MF));
1418 addAddress(SPDie, dwarf::DW_AT_frame_base, Location);
Devang Patel6efc8e52010-02-06 01:02:37 +00001419
Chris Lattner3a383cb2010-04-05 00:13:49 +00001420 return SPDie;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001421}
1422
Jim Grosbach042483e2009-11-21 23:12:12 +00001423/// constructLexicalScope - Construct new DW_TAG_lexical_block
Devang Patel930143b2009-11-21 02:48:08 +00001424/// for this scope and attach DW_AT_low_pc/DW_AT_high_pc labels.
1425DIE *DwarfDebug::constructLexicalScopeDIE(DbgScope *Scope) {
Devang Patel6c74a872010-04-27 19:46:33 +00001426
1427 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_lexical_block);
1428 if (Scope->isAbstractScope())
1429 return ScopeDIE;
1430
1431 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1432 if (Ranges.empty())
1433 return 0;
1434
1435 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1436 if (Ranges.size() > 1) {
1437 // .debug_range section has not been laid out yet. Emit offset in
1438 // .debug_range as a uint, size 4, for now. emitDIE will handle
1439 // DW_AT_ranges appropriately.
1440 addUInt(ScopeDIE, dwarf::DW_AT_ranges, dwarf::DW_FORM_data4,
1441 DebugRangeSymbols.size() * Asm->getTargetData().getPointerSize());
1442 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
1443 RE = Ranges.end(); RI != RE; ++RI) {
1444 DebugRangeSymbols.push_back(LabelsBeforeInsn.lookup(RI->first));
1445 DebugRangeSymbols.push_back(LabelsAfterInsn.lookup(RI->second));
1446 }
1447 DebugRangeSymbols.push_back(NULL);
1448 DebugRangeSymbols.push_back(NULL);
1449 return ScopeDIE;
1450 }
1451
1452 MCSymbol *Start = LabelsBeforeInsn.lookup(RI->first);
1453 MCSymbol *End = LabelsAfterInsn.lookup(RI->second);
1454
Devang Patel23b2ae62010-03-29 22:59:58 +00001455 if (Start == 0 || End == 0) return 0;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001456
Chris Lattnere13c3722010-03-09 01:58:53 +00001457 assert(Start->isDefined() && "Invalid starting label for an inlined scope!");
1458 assert(End->isDefined() && "Invalid end label for an inlined scope!");
Chris Lattnerc3b70f62010-03-09 01:51:43 +00001459
Devang Patel6c74a872010-04-27 19:46:33 +00001460 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, Start);
1461 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, End);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001462
1463 return ScopeDIE;
1464}
1465
Devang Patel930143b2009-11-21 02:48:08 +00001466/// constructInlinedScopeDIE - This scope represents inlined body of
1467/// a function. Construct DIE to represent this concrete inlined copy
1468/// of the function.
1469DIE *DwarfDebug::constructInlinedScopeDIE(DbgScope *Scope) {
Devang Patel6c74a872010-04-27 19:46:33 +00001470
1471 const SmallVector<DbgRange, 4> &Ranges = Scope->getRanges();
1472 assert (Ranges.empty() == false
1473 && "DbgScope does not have instruction markers!");
1474
1475 // FIXME : .debug_inlined section specification does not clearly state how
1476 // to emit inlined scope that is split into multiple instruction ranges.
1477 // For now, use first instruction range and emit low_pc/high_pc pair and
1478 // corresponding .debug_inlined section entry for this pair.
1479 SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin();
1480 MCSymbol *StartLabel = LabelsBeforeInsn.lookup(RI->first);
1481 MCSymbol *EndLabel = LabelsAfterInsn.lookup(RI->second);
1482
1483 if (StartLabel == 0 || EndLabel == 0) {
1484 assert (0 && "Unexpected Start and End labels for a inlined scope!");
1485 return 0;
1486 }
Chris Lattnere13c3722010-03-09 01:58:53 +00001487 assert(StartLabel->isDefined() &&
Chris Lattnerc3b70f62010-03-09 01:51:43 +00001488 "Invalid starting label for an inlined scope!");
Chris Lattnere13c3722010-03-09 01:58:53 +00001489 assert(EndLabel->isDefined() &&
Chris Lattnerc3b70f62010-03-09 01:51:43 +00001490 "Invalid end label for an inlined scope!");
Devang Patel6c74a872010-04-27 19:46:33 +00001491
Devang Patel3b548aa2010-03-08 20:52:55 +00001492 if (!Scope->getScopeNode())
Devang Patelbc97f6b2010-03-08 19:20:38 +00001493 return NULL;
Devang Patel3b548aa2010-03-08 20:52:55 +00001494 DIScope DS(Scope->getScopeNode());
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001495 DIE *ScopeDIE = new DIE(dwarf::DW_TAG_inlined_subroutine);
1496
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001497 DISubprogram InlinedSP = getDISubprogram(DS);
Devang Patel1a0df9a2010-05-10 22:49:55 +00001498 CompileUnit *TheCU = getCompileUnit(InlinedSP);
1499 DIE *OriginDIE = TheCU->getDIE(InlinedSP);
Chris Lattner8d2fe282010-03-31 05:36:29 +00001500 assert(OriginDIE && "Unable to find Origin DIE!");
Devang Patel930143b2009-11-21 02:48:08 +00001501 addDIEEntry(ScopeDIE, dwarf::DW_AT_abstract_origin,
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001502 dwarf::DW_FORM_ref4, OriginDIE);
1503
Chris Lattner085b6522010-03-09 00:31:02 +00001504 addLabel(ScopeDIE, dwarf::DW_AT_low_pc, dwarf::DW_FORM_addr, StartLabel);
Chris Lattnere13c3722010-03-09 01:58:53 +00001505 addLabel(ScopeDIE, dwarf::DW_AT_high_pc, dwarf::DW_FORM_addr, EndLabel);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001506
1507 InlinedSubprogramDIEs.insert(OriginDIE);
1508
1509 // Track the start label for this inlined function.
Devang Patel32cc43c2010-05-07 20:54:48 +00001510 DenseMap<const MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001511 I = InlineInfo.find(InlinedSP);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001512
1513 if (I == InlineInfo.end()) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001514 InlineInfo[InlinedSP].push_back(std::make_pair(StartLabel,
Jim Grosbach00e9c612009-11-22 19:20:36 +00001515 ScopeDIE));
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001516 InlinedSPNodes.push_back(InlinedSP);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001517 } else
Chris Lattner085b6522010-03-09 00:31:02 +00001518 I->second.push_back(std::make_pair(StartLabel, ScopeDIE));
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001519
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001520 DILocation DL(Scope->getInlinedAt());
Devang Patel1a0df9a2010-05-10 22:49:55 +00001521 addUInt(ScopeDIE, dwarf::DW_AT_call_file, 0, TheCU->getID());
Devang Patel930143b2009-11-21 02:48:08 +00001522 addUInt(ScopeDIE, dwarf::DW_AT_call_line, 0, DL.getLineNumber());
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001523
1524 return ScopeDIE;
1525}
1526
Devang Patel930143b2009-11-21 02:48:08 +00001527
1528/// constructVariableDIE - Construct a DIE for the given DbgVariable.
Devang Patel9ccfb642009-12-09 18:24:21 +00001529DIE *DwarfDebug::constructVariableDIE(DbgVariable *DV, DbgScope *Scope) {
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001530 // Get the descriptor.
1531 const DIVariable &VD = DV->getVariable();
Devang Patel2d9caf92009-11-25 17:36:49 +00001532 StringRef Name = VD.getName();
1533 if (Name.empty())
Devang Patel97f99fa2009-11-13 02:25:26 +00001534 return NULL;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001535
1536 // Translate tag to proper Dwarf tag. The result variable is dropped for
1537 // now.
1538 unsigned Tag;
1539 switch (VD.getTag()) {
1540 case dwarf::DW_TAG_return_variable:
1541 return NULL;
1542 case dwarf::DW_TAG_arg_variable:
1543 Tag = dwarf::DW_TAG_formal_parameter;
1544 break;
1545 case dwarf::DW_TAG_auto_variable: // fall thru
1546 default:
1547 Tag = dwarf::DW_TAG_variable;
1548 break;
1549 }
1550
1551 // Define variable debug information entry.
1552 DIE *VariableDie = new DIE(Tag);
1553
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001554 DIE *AbsDIE = NULL;
Devang Patele1c53f22010-05-20 16:36:41 +00001555 DenseMap<const DbgVariable *, const DbgVariable *>::iterator
1556 V2AVI = VarToAbstractVarMap.find(DV);
1557 if (V2AVI != VarToAbstractVarMap.end())
1558 AbsDIE = V2AVI->second->getDIE();
Jim Grosbach042483e2009-11-21 23:12:12 +00001559
Devang Patele1c53f22010-05-20 16:36:41 +00001560 if (AbsDIE)
Devang Patel930143b2009-11-21 02:48:08 +00001561 addDIEEntry(VariableDie, dwarf::DW_AT_abstract_origin,
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001562 dwarf::DW_FORM_ref4, AbsDIE);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001563 else {
Devang Patel930143b2009-11-21 02:48:08 +00001564 addString(VariableDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, Name);
1565 addSourceLine(VariableDie, &VD);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001566
1567 // Add variable type.
Jim Grosbach042483e2009-11-21 23:12:12 +00001568 // FIXME: isBlockByrefVariable should be reformulated in terms of complex
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001569 // addresses instead.
1570 if (VD.isBlockByrefVariable())
Devang Patel9ccfb642009-12-09 18:24:21 +00001571 addType(VariableDie, getBlockByrefType(VD.getType(), Name));
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001572 else
Devang Patel9ccfb642009-12-09 18:24:21 +00001573 addType(VariableDie, VD.getType());
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001574 }
1575
1576 // Add variable address.
1577 if (!Scope->isAbstractScope()) {
Devang Patela3e9c9c2010-03-15 18:33:46 +00001578 // Check if variable is described by DBG_VALUE instruction.
Devang Patele1c53f22010-05-20 16:36:41 +00001579 DenseMap<const DbgVariable *, const MachineInstr *>::iterator DVI =
1580 DbgVariableToDbgInstMap.find(DV);
1581 if (DVI != DbgVariableToDbgInstMap.end()) {
1582 const MachineInstr *DVInsn = DVI->second;
1583 const MCSymbol *DVLabel = findVariableLabel(DV);
Devang Patel173b2b92010-04-28 01:03:09 +00001584 bool updated = false;
1585 // FIXME : Handle getNumOperands != 3
1586 if (DVInsn->getNumOperands() == 3) {
1587 if (DVInsn->getOperand(0).isReg())
Devang Patele1c53f22010-05-20 16:36:41 +00001588 updated = addRegisterAddress(VariableDie, DVLabel, DVInsn->getOperand(0));
Devang Patel173b2b92010-04-28 01:03:09 +00001589 else if (DVInsn->getOperand(0).isImm())
Devang Patele1c53f22010-05-20 16:36:41 +00001590 updated = addConstantValue(VariableDie, DVLabel, DVInsn->getOperand(0));
Devang Patel173b2b92010-04-28 01:03:09 +00001591 else if (DVInsn->getOperand(0).isFPImm())
Devang Patele1c53f22010-05-20 16:36:41 +00001592 updated = addConstantFPValue(VariableDie, DVLabel, DVInsn->getOperand(0));
Devang Patel50c94312010-04-28 01:39:28 +00001593 } else {
1594 MachineLocation Location = Asm->getDebugValueLocation(DVInsn);
1595 if (Location.getReg()) {
1596 addAddress(VariableDie, dwarf::DW_AT_location, Location);
Devang Patele1c53f22010-05-20 16:36:41 +00001597 if (DVLabel)
Devang Patel50c94312010-04-28 01:39:28 +00001598 addLabel(VariableDie, dwarf::DW_AT_start_scope, dwarf::DW_FORM_addr,
Devang Patele1c53f22010-05-20 16:36:41 +00001599 DVLabel);
Devang Patel50c94312010-04-28 01:39:28 +00001600 updated = true;
1601 }
Devang Patel173b2b92010-04-28 01:03:09 +00001602 }
1603 if (!updated) {
1604 // If variableDie is not updated then DBG_VALUE instruction does not
1605 // have valid variable info.
1606 delete VariableDie;
1607 return NULL;
1608 }
1609 }
1610 else {
Devang Patela3e9c9c2010-03-15 18:33:46 +00001611 MachineLocation Location;
1612 unsigned FrameReg;
Chris Lattner3a383cb2010-04-05 00:13:49 +00001613 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Devang Patele1c53f22010-05-20 16:36:41 +00001614 int FI = 0;
1615 if (findVariableFrameIndex(DV, &FI)) {
1616 int Offset = RI->getFrameIndexReference(*Asm->MF, FI, FrameReg);
Devang Patele0a94bf2010-05-14 21:01:35 +00001617 Location.set(FrameReg, Offset);
1618
1619 if (VD.hasComplexAddress())
1620 addComplexAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1621 else if (VD.isBlockByrefVariable())
1622 addBlockByrefAddress(DV, VariableDie, dwarf::DW_AT_location, Location);
1623 else
1624 addAddress(VariableDie, dwarf::DW_AT_location, Location);
1625 }
Devang Patela3e9c9c2010-03-15 18:33:46 +00001626 }
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001627 }
Devang Patel6efc8e52010-02-06 01:02:37 +00001628
1629 if (Tag == dwarf::DW_TAG_formal_parameter && VD.getType().isArtificial())
1630 addUInt(VariableDie, dwarf::DW_AT_artificial, dwarf::DW_FORM_flag, 1);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001631 DV->setDIE(VariableDie);
1632 return VariableDie;
1633
1634}
Devang Patel930143b2009-11-21 02:48:08 +00001635
Devang Patel04d2f2d2009-11-24 01:14:22 +00001636void DwarfDebug::addPubTypes(DISubprogram SP) {
1637 DICompositeType SPTy = SP.getType();
1638 unsigned SPTag = SPTy.getTag();
1639 if (SPTag != dwarf::DW_TAG_subroutine_type)
1640 return;
1641
1642 DIArray Args = SPTy.getTypeArray();
Devang Patel04d2f2d2009-11-24 01:14:22 +00001643 for (unsigned i = 0, e = Args.getNumElements(); i != e; ++i) {
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001644 DIType ATy(Args.getElement(i));
Devang Patel8d6a2b72010-05-07 21:45:47 +00001645 if (!ATy.Verify())
Devang Patel04d2f2d2009-11-24 01:14:22 +00001646 continue;
1647 DICompositeType CATy = getDICompositeType(ATy);
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001648 if (DIDescriptor(CATy).Verify() && !CATy.getName().empty()
Devang Patel12d150e2010-04-13 20:35:04 +00001649 && !CATy.isForwardDecl()) {
Devang Patel1a0df9a2010-05-10 22:49:55 +00001650 CompileUnit *TheCU = getCompileUnit(CATy);
1651 if (DIEEntry *Entry = TheCU->getDIEEntry(CATy))
1652 TheCU->addGlobalType(CATy.getName(), Entry->getEntry());
Devang Patel04d2f2d2009-11-24 01:14:22 +00001653 }
1654 }
1655}
1656
Devang Patel930143b2009-11-21 02:48:08 +00001657/// constructScopeDIE - Construct a DIE for this scope.
1658DIE *DwarfDebug::constructScopeDIE(DbgScope *Scope) {
Devang Patel3b548aa2010-03-08 20:52:55 +00001659 if (!Scope || !Scope->getScopeNode())
1660 return NULL;
1661
1662 DIScope DS(Scope->getScopeNode());
1663 DIE *ScopeDIE = NULL;
1664 if (Scope->getInlinedAt())
1665 ScopeDIE = constructInlinedScopeDIE(Scope);
1666 else if (DS.isSubprogram()) {
1667 if (Scope->isAbstractScope())
Devang Patel1a0df9a2010-05-10 22:49:55 +00001668 ScopeDIE = getCompileUnit(DS)->getDIE(DS);
Devang Patel3b548aa2010-03-08 20:52:55 +00001669 else
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001670 ScopeDIE = updateSubprogramScopeDIE(DS);
Devang Patel3b548aa2010-03-08 20:52:55 +00001671 }
Devang Patel23b2ae62010-03-29 22:59:58 +00001672 else
Devang Patel3b548aa2010-03-08 20:52:55 +00001673 ScopeDIE = constructLexicalScopeDIE(Scope);
Devang Patel23b2ae62010-03-29 22:59:58 +00001674 if (!ScopeDIE) return NULL;
Devang Patel3b548aa2010-03-08 20:52:55 +00001675
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001676 // Add variables to scope.
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +00001677 const SmallVector<DbgVariable *, 8> &Variables = Scope->getVariables();
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001678 for (unsigned i = 0, N = Variables.size(); i < N; ++i) {
Devang Patel9ccfb642009-12-09 18:24:21 +00001679 DIE *VariableDIE = constructVariableDIE(Variables[i], Scope);
Jim Grosbach042483e2009-11-21 23:12:12 +00001680 if (VariableDIE)
Devang Patel930143b2009-11-21 02:48:08 +00001681 ScopeDIE->addChild(VariableDIE);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001682 }
1683
1684 // Add nested scopes.
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +00001685 const SmallVector<DbgScope *, 4> &Scopes = Scope->getScopes();
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001686 for (unsigned j = 0, M = Scopes.size(); j < M; ++j) {
1687 // Define the Scope debug information entry.
Devang Patel930143b2009-11-21 02:48:08 +00001688 DIE *NestedDIE = constructScopeDIE(Scopes[j]);
Jim Grosbach042483e2009-11-21 23:12:12 +00001689 if (NestedDIE)
Devang Patel930143b2009-11-21 02:48:08 +00001690 ScopeDIE->addChild(NestedDIE);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001691 }
Devang Patel04d2f2d2009-11-24 01:14:22 +00001692
1693 if (DS.isSubprogram())
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001694 addPubTypes(DISubprogram(DS));
Devang Patel04d2f2d2009-11-24 01:14:22 +00001695
1696 return ScopeDIE;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001697}
1698
Bill Wendling2b128d72009-05-20 23:19:06 +00001699/// GetOrCreateSourceID - Look up the source id with the given directory and
1700/// source file names. If none currently exists, create a new id and insert it
1701/// in the SourceIds map. This can update DirectoryNames and SourceFileNames
1702/// maps as well.
Chris Lattner71696ef2010-03-31 06:06:37 +00001703unsigned DwarfDebug::GetOrCreateSourceID(StringRef DirName, StringRef FileName){
Bill Wendling2b128d72009-05-20 23:19:06 +00001704 unsigned DId;
1705 StringMap<unsigned>::iterator DI = DirectoryIdMap.find(DirName);
1706 if (DI != DirectoryIdMap.end()) {
1707 DId = DI->getValue();
1708 } else {
1709 DId = DirectoryNames.size() + 1;
1710 DirectoryIdMap[DirName] = DId;
1711 DirectoryNames.push_back(DirName);
1712 }
1713
1714 unsigned FId;
1715 StringMap<unsigned>::iterator FI = SourceFileIdMap.find(FileName);
1716 if (FI != SourceFileIdMap.end()) {
1717 FId = FI->getValue();
1718 } else {
1719 FId = SourceFileNames.size() + 1;
1720 SourceFileIdMap[FileName] = FId;
1721 SourceFileNames.push_back(FileName);
1722 }
1723
1724 DenseMap<std::pair<unsigned, unsigned>, unsigned>::iterator SI =
1725 SourceIdMap.find(std::make_pair(DId, FId));
1726 if (SI != SourceIdMap.end())
1727 return SI->second;
1728
1729 unsigned SrcId = SourceIds.size() + 1; // DW_AT_decl_file cannot be 0.
1730 SourceIdMap[std::make_pair(DId, FId)] = SrcId;
1731 SourceIds.push_back(std::make_pair(DId, FId));
1732
1733 return SrcId;
1734}
1735
Devang Patel1f4690c2009-12-15 19:16:48 +00001736/// getOrCreateNameSpace - Create a DIE for DINameSpace.
1737DIE *DwarfDebug::getOrCreateNameSpace(DINameSpace NS) {
Devang Patel1a0df9a2010-05-10 22:49:55 +00001738 CompileUnit *TheCU = getCompileUnit(NS);
1739 DIE *NDie = TheCU->getDIE(NS);
Devang Patel1f4690c2009-12-15 19:16:48 +00001740 if (NDie)
1741 return NDie;
1742 NDie = new DIE(dwarf::DW_TAG_namespace);
Devang Patel1a0df9a2010-05-10 22:49:55 +00001743 TheCU->insertDIE(NS, NDie);
Devang Patel1f4690c2009-12-15 19:16:48 +00001744 if (!NS.getName().empty())
1745 addString(NDie, dwarf::DW_AT_name, dwarf::DW_FORM_string, NS.getName());
1746 addSourceLine(NDie, &NS);
1747 addToContextOwner(NDie, NS.getContext());
1748 return NDie;
1749}
1750
Devang Patel1a0df9a2010-05-10 22:49:55 +00001751/// constructCompileUnit - Create new CompileUnit for the given
1752/// metadata node with tag DW_TAG_compile_unit.
Devang Patel32cc43c2010-05-07 20:54:48 +00001753void DwarfDebug::constructCompileUnit(const MDNode *N) {
Devang Patel80ae3492009-08-28 23:24:31 +00001754 DICompileUnit DIUnit(N);
Devang Patel2d9caf92009-11-25 17:36:49 +00001755 StringRef FN = DIUnit.getFilename();
1756 StringRef Dir = DIUnit.getDirectory();
Devang Patelb2969422009-09-29 18:40:58 +00001757 unsigned ID = GetOrCreateSourceID(Dir, FN);
Bill Wendling2b128d72009-05-20 23:19:06 +00001758
1759 DIE *Die = new DIE(dwarf::DW_TAG_compile_unit);
Devang Patel930143b2009-11-21 02:48:08 +00001760 addString(Die, dwarf::DW_AT_producer, dwarf::DW_FORM_string,
Devang Patelb2969422009-09-29 18:40:58 +00001761 DIUnit.getProducer());
Devang Patel930143b2009-11-21 02:48:08 +00001762 addUInt(Die, dwarf::DW_AT_language, dwarf::DW_FORM_data1,
Bill Wendling2b128d72009-05-20 23:19:06 +00001763 DIUnit.getLanguage());
Devang Patel930143b2009-11-21 02:48:08 +00001764 addString(Die, dwarf::DW_AT_name, dwarf::DW_FORM_string, FN);
Devang Patelbd798ce2010-04-26 22:54:28 +00001765 // Use DW_AT_entry_pc instead of DW_AT_low_pc/DW_AT_high_pc pair. This
1766 // simplifies debug range entries.
1767 addUInt(Die, dwarf::DW_AT_entry_pc, dwarf::DW_FORM_data4, 0);
Devang Pateld22ed622010-03-22 23:11:36 +00001768 // DW_AT_stmt_list is a offset of line number information for this
1769 // compile unit in debug_line section. It is always zero when only one
1770 // compile unit is emitted in one object file.
1771 addUInt(Die, dwarf::DW_AT_stmt_list, dwarf::DW_FORM_data4, 0);
Bill Wendling2b128d72009-05-20 23:19:06 +00001772
Devang Patel2d9caf92009-11-25 17:36:49 +00001773 if (!Dir.empty())
Devang Patel930143b2009-11-21 02:48:08 +00001774 addString(Die, dwarf::DW_AT_comp_dir, dwarf::DW_FORM_string, Dir);
Bill Wendling2b128d72009-05-20 23:19:06 +00001775 if (DIUnit.isOptimized())
Devang Patel930143b2009-11-21 02:48:08 +00001776 addUInt(Die, dwarf::DW_AT_APPLE_optimized, dwarf::DW_FORM_flag, 1);
Bill Wendling2b128d72009-05-20 23:19:06 +00001777
Devang Patel2d9caf92009-11-25 17:36:49 +00001778 StringRef Flags = DIUnit.getFlags();
1779 if (!Flags.empty())
Devang Patel930143b2009-11-21 02:48:08 +00001780 addString(Die, dwarf::DW_AT_APPLE_flags, dwarf::DW_FORM_string, Flags);
Bill Wendling2b128d72009-05-20 23:19:06 +00001781
1782 unsigned RVer = DIUnit.getRunTimeVersion();
1783 if (RVer)
Devang Patel930143b2009-11-21 02:48:08 +00001784 addUInt(Die, dwarf::DW_AT_APPLE_major_runtime_vers,
Bill Wendling2b128d72009-05-20 23:19:06 +00001785 dwarf::DW_FORM_data1, RVer);
1786
Devang Patel1a0df9a2010-05-10 22:49:55 +00001787 CompileUnit *NewCU = new CompileUnit(ID, Die);
1788 if (!FirstCU)
1789 FirstCU = NewCU;
1790 CUMap.insert(std::make_pair(N, NewCU));
Bill Wendling2b128d72009-05-20 23:19:06 +00001791}
1792
Devang Patel1a0df9a2010-05-10 22:49:55 +00001793/// getCompielUnit - Get CompileUnit DIE.
1794CompileUnit *DwarfDebug::getCompileUnit(const MDNode *N) const {
1795 assert (N && "Invalid DwarfDebug::getCompileUnit argument!");
1796 DIDescriptor D(N);
1797 const MDNode *CUNode = NULL;
1798 if (D.isCompileUnit())
1799 CUNode = N;
1800 else if (D.isSubprogram())
1801 CUNode = DISubprogram(N).getCompileUnit();
1802 else if (D.isType())
1803 CUNode = DIType(N).getCompileUnit();
1804 else if (D.isGlobalVariable())
1805 CUNode = DIGlobalVariable(N).getCompileUnit();
1806 else if (D.isVariable())
1807 CUNode = DIVariable(N).getCompileUnit();
1808 else if (D.isNameSpace())
1809 CUNode = DINameSpace(N).getCompileUnit();
1810 else if (D.isFile())
1811 CUNode = DIFile(N).getCompileUnit();
1812 else
1813 return FirstCU;
1814
1815 DenseMap<const MDNode *, CompileUnit *>::const_iterator I
1816 = CUMap.find(CUNode);
1817 if (I == CUMap.end())
1818 return FirstCU;
1819 return I->second;
1820}
1821
1822
1823/// constructGlobalVariableDIE - Construct global variable DIE.
Devang Patel32cc43c2010-05-07 20:54:48 +00001824void DwarfDebug::constructGlobalVariableDIE(const MDNode *N) {
Devang Patel80ae3492009-08-28 23:24:31 +00001825 DIGlobalVariable DI_GV(N);
Daniel Dunbarc418d6b2009-09-19 20:40:05 +00001826
Devang Patelf5d53602009-09-04 23:59:07 +00001827 // If debug information is malformed then ignore it.
1828 if (DI_GV.Verify() == false)
1829 return;
Bill Wendling2b128d72009-05-20 23:19:06 +00001830
1831 // Check for pre-existence.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001832 CompileUnit *TheCU = getCompileUnit(N);
1833 if (TheCU->getDIE(DI_GV))
Devang Patel0751a282009-06-26 01:49:18 +00001834 return;
Bill Wendling2b128d72009-05-20 23:19:06 +00001835
Devang Patel9ccfb642009-12-09 18:24:21 +00001836 DIE *VariableDie = createGlobalVariableDIE(DI_GV);
Devang Patel2eec32d2009-12-10 23:25:41 +00001837 if (!VariableDie)
1838 return;
Bill Wendling2b128d72009-05-20 23:19:06 +00001839
Bill Wendling2b128d72009-05-20 23:19:06 +00001840 // Add to map.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001841 TheCU->insertDIE(N, VariableDie);
Bill Wendling2b128d72009-05-20 23:19:06 +00001842
1843 // Add to context owner.
Devang Patel89880c82010-01-15 01:12:22 +00001844 DIDescriptor GVContext = DI_GV.getContext();
1845 // Do not create specification DIE if context is either compile unit
1846 // or a subprogram.
Chris Lattner71696ef2010-03-31 06:06:37 +00001847 if (DI_GV.isDefinition() && !GVContext.isCompileUnit() &&
Devang Patel019922d2010-04-06 23:53:48 +00001848 !GVContext.isFile() &&
Devang Patelcfa8e9d2010-05-07 18:11:54 +00001849 !isSubprogramContext(GVContext)) {
Devang Patel1f4690c2009-12-15 19:16:48 +00001850 // Create specification DIE.
1851 DIE *VariableSpecDIE = new DIE(dwarf::DW_TAG_variable);
1852 addDIEEntry(VariableSpecDIE, dwarf::DW_AT_specification,
1853 dwarf::DW_FORM_ref4, VariableDie);
Benjamin Kramer74729ae2010-03-31 19:34:01 +00001854 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel1f4690c2009-12-15 19:16:48 +00001855 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner8dcf41e2010-03-08 22:31:46 +00001856 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattner9e4cafe2010-03-12 21:09:07 +00001857 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel1f4690c2009-12-15 19:16:48 +00001858 addBlock(VariableSpecDIE, dwarf::DW_AT_location, 0, Block);
Devang Patelce25dd72010-02-09 01:58:33 +00001859 addUInt(VariableDie, dwarf::DW_AT_declaration, dwarf::DW_FORM_flag, 1);
Devang Patel1a0df9a2010-05-10 22:49:55 +00001860 TheCU->addDie(VariableSpecDIE);
Devang Patel1f4690c2009-12-15 19:16:48 +00001861 } else {
Benjamin Kramer74729ae2010-03-31 19:34:01 +00001862 DIEBlock *Block = new (DIEValueAllocator) DIEBlock();
Devang Patel1f4690c2009-12-15 19:16:48 +00001863 addUInt(Block, 0, dwarf::DW_FORM_data1, dwarf::DW_OP_addr);
Chris Lattner8dcf41e2010-03-08 22:31:46 +00001864 addLabel(Block, 0, dwarf::DW_FORM_udata,
Chris Lattner9e4cafe2010-03-12 21:09:07 +00001865 Asm->Mang->getSymbol(DI_GV.getGlobal()));
Devang Patel1f4690c2009-12-15 19:16:48 +00001866 addBlock(VariableDie, dwarf::DW_AT_location, 0, Block);
1867 }
Devang Patel89880c82010-01-15 01:12:22 +00001868 addToContextOwner(VariableDie, GVContext);
Devang Patel2b75ed22009-12-10 19:14:49 +00001869
Bill Wendling2b128d72009-05-20 23:19:06 +00001870 // Expose as global. FIXME - need to check external flag.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001871 TheCU->addGlobal(DI_GV.getName(), VariableDie);
Devang Patel04d2f2d2009-11-24 01:14:22 +00001872
1873 DIType GTy = DI_GV.getType();
Devang Patel12d150e2010-04-13 20:35:04 +00001874 if (GTy.isCompositeType() && !GTy.getName().empty()
1875 && !GTy.isForwardDecl()) {
Devang Patel1a0df9a2010-05-10 22:49:55 +00001876 DIEEntry *Entry = TheCU->getDIEEntry(GTy);
Chris Lattner8d2fe282010-03-31 05:36:29 +00001877 assert(Entry && "Missing global type!");
Devang Patel1a0df9a2010-05-10 22:49:55 +00001878 TheCU->addGlobalType(GTy.getName(), Entry->getEntry());
Devang Patel04d2f2d2009-11-24 01:14:22 +00001879 }
Devang Patel0751a282009-06-26 01:49:18 +00001880 return;
Bill Wendling2b128d72009-05-20 23:19:06 +00001881}
1882
Devang Patel1a0df9a2010-05-10 22:49:55 +00001883/// construct SubprogramDIE - Construct subprogram DIE.
Devang Patel32cc43c2010-05-07 20:54:48 +00001884void DwarfDebug::constructSubprogramDIE(const MDNode *N) {
Devang Patel80ae3492009-08-28 23:24:31 +00001885 DISubprogram SP(N);
Bill Wendling2b128d72009-05-20 23:19:06 +00001886
Stuart Hastings4bd3dd92010-04-06 21:38:29 +00001887 // Check for pre-existence.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001888 CompileUnit *TheCU = getCompileUnit(N);
1889 if (TheCU->getDIE(N))
Stuart Hastings4bd3dd92010-04-06 21:38:29 +00001890 return;
1891
Bill Wendling2b128d72009-05-20 23:19:06 +00001892 if (!SP.isDefinition())
1893 // This is a method declaration which will be handled while constructing
1894 // class type.
Devang Patel0751a282009-06-26 01:49:18 +00001895 return;
Bill Wendling2b128d72009-05-20 23:19:06 +00001896
Stuart Hastings4bd3dd92010-04-06 21:38:29 +00001897 DIE *SubprogramDie = createSubprogramDIE(SP);
1898
1899 // Add to map.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001900 TheCU->insertDIE(N, SubprogramDie);
Bill Wendling2b128d72009-05-20 23:19:06 +00001901
1902 // Add to context owner.
Devang Patel1f4690c2009-12-15 19:16:48 +00001903 addToContextOwner(SubprogramDie, SP.getContext());
Devang Patel512001a2009-12-08 23:21:45 +00001904
Bill Wendling2b128d72009-05-20 23:19:06 +00001905 // Expose as global.
Devang Patel1a0df9a2010-05-10 22:49:55 +00001906 TheCU->addGlobal(SP.getName(), SubprogramDie);
Devang Patel04d2f2d2009-11-24 01:14:22 +00001907
Devang Patel0751a282009-06-26 01:49:18 +00001908 return;
Bill Wendling2b128d72009-05-20 23:19:06 +00001909}
1910
Devang Patel930143b2009-11-21 02:48:08 +00001911/// beginModule - Emit all Dwarf sections that should come prior to the
Daniel Dunbarbe22ec42009-09-19 20:40:14 +00001912/// content. Create global DIEs and emit initial debug info sections.
1913/// This is inovked by the target AsmPrinter.
Chris Lattner11980022010-04-04 07:48:20 +00001914void DwarfDebug::beginModule(Module *M) {
Devang Patel6c74a872010-04-27 19:46:33 +00001915 if (DisableDebugInfoPrinting)
1916 return;
1917
Devang Patel63524442009-07-30 18:56:46 +00001918 DebugInfoFinder DbgFinder;
1919 DbgFinder.processModule(*M);
Devang Patel0751a282009-06-26 01:49:18 +00001920
Chris Lattner7cfa70e2010-04-05 02:19:28 +00001921 bool HasDebugInfo = false;
1922
1923 // Scan all the compile-units to see if there are any marked as the main unit.
1924 // if not, we do not generate debug info.
1925 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1926 E = DbgFinder.compile_unit_end(); I != E; ++I) {
1927 if (DICompileUnit(*I).isMain()) {
1928 HasDebugInfo = true;
1929 break;
1930 }
1931 }
1932
1933 if (!HasDebugInfo) return;
1934
1935 // Tell MMI that we have debug info.
1936 MMI->setDebugInfoAvailability(true);
1937
Chris Lattnerd442aa32010-04-04 23:17:54 +00001938 // Emit initial sections.
Chris Lattner7cfa70e2010-04-05 02:19:28 +00001939 EmitSectionLabels();
Chris Lattnerd442aa32010-04-04 23:17:54 +00001940
Bill Wendling2b128d72009-05-20 23:19:06 +00001941 // Create all the compile unit DIEs.
Devang Patel63524442009-07-30 18:56:46 +00001942 for (DebugInfoFinder::iterator I = DbgFinder.compile_unit_begin(),
1943 E = DbgFinder.compile_unit_end(); I != E; ++I)
Devang Patel930143b2009-11-21 02:48:08 +00001944 constructCompileUnit(*I);
Bill Wendling2b128d72009-05-20 23:19:06 +00001945
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001946 // Create DIEs for each subprogram.
Devang Patel63524442009-07-30 18:56:46 +00001947 for (DebugInfoFinder::iterator I = DbgFinder.subprogram_begin(),
1948 E = DbgFinder.subprogram_end(); I != E; ++I)
Devang Patel930143b2009-11-21 02:48:08 +00001949 constructSubprogramDIE(*I);
Devang Patel0751a282009-06-26 01:49:18 +00001950
Devang Patel2b75ed22009-12-10 19:14:49 +00001951 // Create DIEs for each global variable.
1952 for (DebugInfoFinder::iterator I = DbgFinder.global_variable_begin(),
1953 E = DbgFinder.global_variable_end(); I != E; ++I)
1954 constructGlobalVariableDIE(*I);
1955
Bill Wendling2b128d72009-05-20 23:19:06 +00001956 // Prime section data.
Chris Lattner5e693ed2009-07-28 03:13:23 +00001957 SectionMap.insert(Asm->getObjFileLowering().getTextSection());
Bill Wendling2b128d72009-05-20 23:19:06 +00001958
1959 // Print out .file directives to specify files for .loc directives. These are
1960 // printed out early so that they precede any .loc directives.
Chris Lattner3a383cb2010-04-05 00:13:49 +00001961 if (Asm->MAI->hasDotLocAndDotFile()) {
Bill Wendling2b128d72009-05-20 23:19:06 +00001962 for (unsigned i = 1, e = getNumSourceIds()+1; i != e; ++i) {
1963 // Remember source id starts at 1.
1964 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(i);
Chris Lattnerf5c834f2010-01-22 22:09:00 +00001965 // FIXME: don't use sys::path for this! This should not depend on the
1966 // host.
Bill Wendling2b128d72009-05-20 23:19:06 +00001967 sys::Path FullPath(getSourceDirectoryName(Id.first));
1968 bool AppendOk =
1969 FullPath.appendComponent(getSourceFileName(Id.second));
1970 assert(AppendOk && "Could not append filename to directory!");
1971 AppendOk = false;
Chris Lattner601ef332010-01-25 18:58:59 +00001972 Asm->OutStreamer.EmitDwarfFileDirective(i, FullPath.str());
Bill Wendling2b128d72009-05-20 23:19:06 +00001973 }
1974 }
Bill Wendling2b128d72009-05-20 23:19:06 +00001975}
1976
Devang Patel930143b2009-11-21 02:48:08 +00001977/// endModule - Emit all Dwarf sections that should come after the content.
Bill Wendling2b128d72009-05-20 23:19:06 +00001978///
Devang Patel930143b2009-11-21 02:48:08 +00001979void DwarfDebug::endModule() {
Devang Patel1a0df9a2010-05-10 22:49:55 +00001980 if (!FirstCU) return;
Bill Wendling2b128d72009-05-20 23:19:06 +00001981
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001982 // Attach DW_AT_inline attribute with inlined subprogram DIEs.
1983 for (SmallPtrSet<DIE *, 4>::iterator AI = InlinedSubprogramDIEs.begin(),
1984 AE = InlinedSubprogramDIEs.end(); AI != AE; ++AI) {
1985 DIE *ISP = *AI;
Devang Patel930143b2009-11-21 02:48:08 +00001986 addUInt(ISP, dwarf::DW_AT_inline, 0, dwarf::DW_INL_inlined);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00001987 }
1988
Devang Patel32cc43c2010-05-07 20:54:48 +00001989 for (DenseMap<DIE *, const MDNode *>::iterator CI = ContainingTypeMap.begin(),
Devang Pateleb57c592009-12-03 19:11:07 +00001990 CE = ContainingTypeMap.end(); CI != CE; ++CI) {
1991 DIE *SPDie = CI->first;
Devang Patel32cc43c2010-05-07 20:54:48 +00001992 const MDNode *N = dyn_cast_or_null<MDNode>(CI->second);
Devang Pateleb57c592009-12-03 19:11:07 +00001993 if (!N) continue;
Devang Patel1a0df9a2010-05-10 22:49:55 +00001994 DIE *NDie = getCompileUnit(N)->getDIE(N);
Devang Pateleb57c592009-12-03 19:11:07 +00001995 if (!NDie) continue;
1996 addDIEEntry(SPDie, dwarf::DW_AT_containing_type, dwarf::DW_FORM_ref4, NDie);
Devang Pateleb57c592009-12-03 19:11:07 +00001997 }
1998
Bill Wendling2b128d72009-05-20 23:19:06 +00001999 // Standard sections final addresses.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00002000 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getTextSection());
Chris Lattnera179b522010-04-04 19:25:43 +00002001 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("text_end"));
Chris Lattner4b7dadb2009-08-19 05:49:37 +00002002 Asm->OutStreamer.SwitchSection(Asm->getObjFileLowering().getDataSection());
Chris Lattnera179b522010-04-04 19:25:43 +00002003 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("data_end"));
Bill Wendling2b128d72009-05-20 23:19:06 +00002004
2005 // End text sections.
2006 for (unsigned i = 1, N = SectionMap.size(); i <= N; ++i) {
Chris Lattner4b7dadb2009-08-19 05:49:37 +00002007 Asm->OutStreamer.SwitchSection(SectionMap[i]);
Chris Lattnera179b522010-04-04 19:25:43 +00002008 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("section_end", i));
Bill Wendling2b128d72009-05-20 23:19:06 +00002009 }
2010
2011 // Emit common frame information.
Devang Patel930143b2009-11-21 02:48:08 +00002012 emitCommonDebugFrame();
Bill Wendling2b128d72009-05-20 23:19:06 +00002013
2014 // Emit function debug frame information
2015 for (std::vector<FunctionDebugFrameInfo>::iterator I = DebugFrames.begin(),
2016 E = DebugFrames.end(); I != E; ++I)
Devang Patel930143b2009-11-21 02:48:08 +00002017 emitFunctionDebugFrame(*I);
Bill Wendling2b128d72009-05-20 23:19:06 +00002018
2019 // Compute DIE offsets and sizes.
Devang Patel930143b2009-11-21 02:48:08 +00002020 computeSizeAndOffsets();
Bill Wendling2b128d72009-05-20 23:19:06 +00002021
2022 // Emit all the DIEs into a debug info section
Devang Patel930143b2009-11-21 02:48:08 +00002023 emitDebugInfo();
Bill Wendling2b128d72009-05-20 23:19:06 +00002024
2025 // Corresponding abbreviations into a abbrev section.
Devang Patel930143b2009-11-21 02:48:08 +00002026 emitAbbreviations();
Bill Wendling2b128d72009-05-20 23:19:06 +00002027
2028 // Emit source line correspondence into a debug line section.
Devang Patel930143b2009-11-21 02:48:08 +00002029 emitDebugLines();
Bill Wendling2b128d72009-05-20 23:19:06 +00002030
2031 // Emit info into a debug pubnames section.
Devang Patel930143b2009-11-21 02:48:08 +00002032 emitDebugPubNames();
Bill Wendling2b128d72009-05-20 23:19:06 +00002033
Devang Patel04d2f2d2009-11-24 01:14:22 +00002034 // Emit info into a debug pubtypes section.
2035 emitDebugPubTypes();
2036
Bill Wendling2b128d72009-05-20 23:19:06 +00002037 // Emit info into a debug loc section.
Devang Patel930143b2009-11-21 02:48:08 +00002038 emitDebugLoc();
Bill Wendling2b128d72009-05-20 23:19:06 +00002039
2040 // Emit info into a debug aranges section.
2041 EmitDebugARanges();
2042
2043 // Emit info into a debug ranges section.
Devang Patel930143b2009-11-21 02:48:08 +00002044 emitDebugRanges();
Bill Wendling2b128d72009-05-20 23:19:06 +00002045
2046 // Emit info into a debug macinfo section.
Devang Patel930143b2009-11-21 02:48:08 +00002047 emitDebugMacInfo();
Bill Wendling2b128d72009-05-20 23:19:06 +00002048
2049 // Emit inline info.
Devang Patel930143b2009-11-21 02:48:08 +00002050 emitDebugInlineInfo();
Bill Wendling2b128d72009-05-20 23:19:06 +00002051
Chris Lattnerb7aa9522010-03-13 02:17:42 +00002052 // Emit info into a debug str section.
2053 emitDebugStr();
2054
Devang Patel1a0df9a2010-05-10 22:49:55 +00002055 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
2056 E = CUMap.end(); I != E; ++I)
2057 delete I->second;
2058 FirstCU = NULL; // Reset for the next Module, if any.
Bill Wendling2b128d72009-05-20 23:19:06 +00002059}
2060
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002061/// findAbstractVariable - Find abstract variable, if any, associated with Var.
Devang Patele1c53f22010-05-20 16:36:41 +00002062DbgVariable *DwarfDebug::findAbstractVariable(DIVariable &Var,
Chris Lattner915c5f92010-04-02 19:42:39 +00002063 DebugLoc ScopeLoc) {
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002064
Devang Patelcfa8e9d2010-05-07 18:11:54 +00002065 DbgVariable *AbsDbgVariable = AbstractVariables.lookup(Var);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002066 if (AbsDbgVariable)
2067 return AbsDbgVariable;
2068
Devang Patelcfa8e9d2010-05-07 18:11:54 +00002069 LLVMContext &Ctx = Var->getContext();
Chris Lattner915c5f92010-04-02 19:42:39 +00002070 DbgScope *Scope = AbstractScopes.lookup(ScopeLoc.getScope(Ctx));
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002071 if (!Scope)
2072 return NULL;
2073
Devang Patele1c53f22010-05-20 16:36:41 +00002074 AbsDbgVariable = new DbgVariable(Var);
Devang Patel930143b2009-11-21 02:48:08 +00002075 Scope->addVariable(AbsDbgVariable);
Devang Patelcfa8e9d2010-05-07 18:11:54 +00002076 AbstractVariables[Var] = AbsDbgVariable;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002077 return AbsDbgVariable;
2078}
2079
Devang Patel930143b2009-11-21 02:48:08 +00002080/// collectVariableInfo - Populate DbgScope entries with variables' info.
Devang Patele0a94bf2010-05-14 21:01:35 +00002081void DwarfDebug::collectVariableInfo(const MachineFunction *MF) {
Chris Lattner3a383cb2010-04-05 00:13:49 +00002082 const LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
Devang Patele0a94bf2010-05-14 21:01:35 +00002083 SmallPtrSet<const MDNode *, 16> Processed;
Devang Patel475d32a2009-10-06 01:26:37 +00002084 MachineModuleInfo::VariableDbgInfoMapTy &VMap = MMI->getVariableDbgInfo();
2085 for (MachineModuleInfo::VariableDbgInfoMapTy::iterator VI = VMap.begin(),
2086 VE = VMap.end(); VI != VE; ++VI) {
Devang Patel32cc43c2010-05-07 20:54:48 +00002087 const MDNode *Var = VI->first;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002088 if (!Var) continue;
Devang Patele0a94bf2010-05-14 21:01:35 +00002089 Processed.insert(Var);
Chris Lattner915c5f92010-04-02 19:42:39 +00002090 DIVariable DV(Var);
2091 const std::pair<unsigned, DebugLoc> &VP = VI->second;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002092
Chris Lattner915c5f92010-04-02 19:42:39 +00002093 DbgScope *Scope = 0;
Devang Patel32cc43c2010-05-07 20:54:48 +00002094 if (const MDNode *IA = VP.second.getInlinedAt(Ctx))
Chris Lattner915c5f92010-04-02 19:42:39 +00002095 Scope = ConcreteScopes.lookup(IA);
2096 if (Scope == 0)
2097 Scope = DbgScopeMap.lookup(VP.second.getScope(Ctx));
2098
Devang Patelcdb7d442009-11-10 23:20:04 +00002099 // If variable scope is not found then skip this variable.
Chris Lattner915c5f92010-04-02 19:42:39 +00002100 if (Scope == 0)
Devang Patelcdb7d442009-11-10 23:20:04 +00002101 continue;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002102
Devang Patele1c53f22010-05-20 16:36:41 +00002103 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, VP.second);
2104 DbgVariable *RegVar = new DbgVariable(DV);
2105 recordVariableFrameIndex(RegVar, VP.first);
Devang Patel930143b2009-11-21 02:48:08 +00002106 Scope->addVariable(RegVar);
Devang Patele1c53f22010-05-20 16:36:41 +00002107 if (AbsDbgVariable) {
2108 recordVariableFrameIndex(AbsDbgVariable, VP.first);
2109 VarToAbstractVarMap[RegVar] = AbsDbgVariable;
2110 }
Devang Patel475d32a2009-10-06 01:26:37 +00002111 }
Devang Patela3e9c9c2010-03-15 18:33:46 +00002112
2113 // Collect variable information from DBG_VALUE machine instructions;
Chris Lattner3a383cb2010-04-05 00:13:49 +00002114 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patela3e9c9c2010-03-15 18:33:46 +00002115 I != E; ++I) {
2116 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2117 II != IE; ++II) {
2118 const MachineInstr *MInsn = II;
Chris Lattner848c7d22010-03-31 05:39:57 +00002119 if (!MInsn->isDebugValue())
Devang Patela3e9c9c2010-03-15 18:33:46 +00002120 continue;
Devang Patel23b2ae62010-03-29 22:59:58 +00002121
Devang Patel1a0bbe22010-04-27 20:54:45 +00002122 // Ignore Undef values.
Devang Patelcfc76fd2010-04-27 22:04:41 +00002123 if (MInsn->getOperand(0).isReg() && !MInsn->getOperand(0).getReg())
Devang Patel1a0bbe22010-04-27 20:54:45 +00002124 continue;
2125
Dan Gohman88f7f6a2010-04-17 16:43:55 +00002126 DIVariable DV(
Devang Patel32cc43c2010-05-07 20:54:48 +00002127 const_cast<const MDNode *>(MInsn->getOperand(MInsn->getNumOperands() - 1)
Dan Gohman88f7f6a2010-04-17 16:43:55 +00002128 .getMetadata()));
Devang Patela3e9c9c2010-03-15 18:33:46 +00002129 if (DV.getTag() == dwarf::DW_TAG_arg_variable) {
2130 // FIXME Handle inlined subroutine arguments.
Devang Patele1c53f22010-05-20 16:36:41 +00002131 DbgVariable *ArgVar = new DbgVariable(DV);
Devang Patela3e9c9c2010-03-15 18:33:46 +00002132 CurrentFnDbgScope->addVariable(ArgVar);
Devang Patel23b2ae62010-03-29 22:59:58 +00002133 DbgValueStartMap[MInsn] = ArgVar;
Devang Patele1c53f22010-05-20 16:36:41 +00002134 DbgVariableToDbgInstMap[ArgVar] = MInsn;
Devang Patel36debf82010-05-14 21:55:50 +00002135 Processed.insert(DV);
Devang Patela3e9c9c2010-03-15 18:33:46 +00002136 continue;
2137 }
2138
2139 DebugLoc DL = MInsn->getDebugLoc();
2140 if (DL.isUnknown()) continue;
Chris Lattner915c5f92010-04-02 19:42:39 +00002141 DbgScope *Scope = 0;
Devang Patel32cc43c2010-05-07 20:54:48 +00002142 if (const MDNode *IA = DL.getInlinedAt(Ctx))
Chris Lattner915c5f92010-04-02 19:42:39 +00002143 Scope = ConcreteScopes.lookup(IA);
2144 if (Scope == 0)
2145 Scope = DbgScopeMap.lookup(DL.getScope(Ctx));
2146
Devang Patela3e9c9c2010-03-15 18:33:46 +00002147 // If variable scope is not found then skip this variable.
Chris Lattner915c5f92010-04-02 19:42:39 +00002148 if (Scope == 0)
Devang Patela3e9c9c2010-03-15 18:33:46 +00002149 continue;
2150
Devang Patele0a94bf2010-05-14 21:01:35 +00002151 Processed.insert(DV);
Devang Patele1c53f22010-05-20 16:36:41 +00002152 DbgVariable *AbsDbgVariable = findAbstractVariable(DV, DL);
2153 DbgVariable *RegVar = new DbgVariable(DV);
Devang Patel23b2ae62010-03-29 22:59:58 +00002154 DbgValueStartMap[MInsn] = RegVar;
Devang Patele1c53f22010-05-20 16:36:41 +00002155 DbgVariableToDbgInstMap[RegVar] = MInsn;
Devang Patela3e9c9c2010-03-15 18:33:46 +00002156 Scope->addVariable(RegVar);
Devang Patele1c53f22010-05-20 16:36:41 +00002157 if (AbsDbgVariable) {
2158 DbgVariableToDbgInstMap[AbsDbgVariable] = MInsn;
2159 VarToAbstractVarMap[RegVar] = AbsDbgVariable;
2160 }
Devang Patela3e9c9c2010-03-15 18:33:46 +00002161 }
2162 }
Devang Patele0a94bf2010-05-14 21:01:35 +00002163
2164 // Collect info for variables that were optimized out.
2165 if (NamedMDNode *NMD =
2166 MF->getFunction()->getParent()->getNamedMetadata("llvm.dbg.lv")) {
2167 for (unsigned i = 0, e = NMD->getNumOperands(); i != e; ++i) {
2168 DIVariable DV(cast_or_null<MDNode>(NMD->getOperand(i)));
2169 if (!Processed.insert(DV))
2170 continue;
2171 DbgScope *Scope = DbgScopeMap.lookup(DV.getContext());
2172 if (Scope)
Devang Patele1c53f22010-05-20 16:36:41 +00002173 Scope->addVariable(new DbgVariable(DV));
Devang Patele0a94bf2010-05-14 21:01:35 +00002174 }
2175 }
2176
Devang Patel475d32a2009-10-06 01:26:37 +00002177}
2178
Devang Patelbd477be2010-03-29 17:20:31 +00002179/// beginScope - Process beginning of a scope.
2180void DwarfDebug::beginScope(const MachineInstr *MI) {
Devang Patelbd477be2010-03-29 17:20:31 +00002181 // Check location.
2182 DebugLoc DL = MI->getDebugLoc();
Dan Gohman50849c62010-05-05 23:41:32 +00002183 if (DL.isUnknown()) {
Dan Gohman7421ae42010-05-07 01:08:53 +00002184 if (UnknownLocations) {
2185 // This instruction has no debug location. If the preceding instruction
2186 // did, emit debug location information to indicate that the debug
2187 // location is now unknown.
2188 MCSymbol *Label = NULL;
2189 if (DL == PrevInstLoc)
2190 Label = PrevLabel;
2191 else {
2192 Label = recordSourceLine(DL.getLine(), DL.getCol(), 0);
2193 PrevInstLoc = DL;
2194 PrevLabel = Label;
Devang Patel0fe341e2010-05-19 21:26:53 +00002195 }
Devang Patela0813082010-05-19 21:58:28 +00002196
Devang Patele1c53f22010-05-20 16:36:41 +00002197 // If this instruction begins a scope then note down corresponding label
2198 // even if previous label is reused.
Devang Patela0813082010-05-19 21:58:28 +00002199 if (InsnsBeginScopeSet.count(MI) != 0)
2200 LabelsBeforeInsn[MI] = Label;
Dan Gohman7421ae42010-05-07 01:08:53 +00002201 }
Dan Gohman47d04e32010-05-06 00:29:41 +00002202
Devang Patelbd477be2010-03-29 17:20:31 +00002203 return;
Dan Gohman50849c62010-05-05 23:41:32 +00002204 }
Devang Patelbd477be2010-03-29 17:20:31 +00002205
Devang Patel32cc43c2010-05-07 20:54:48 +00002206 const MDNode *Scope = DL.getScope(Asm->MF->getFunction()->getContext());
Chris Lattner915c5f92010-04-02 19:42:39 +00002207
2208 // FIXME: Should only verify each scope once!
2209 if (!DIScope(Scope).Verify())
Devang Patelbd477be2010-03-29 17:20:31 +00002210 return;
Devang Patelbd477be2010-03-29 17:20:31 +00002211
Devang Patel23b2ae62010-03-29 22:59:58 +00002212 // DBG_VALUE instruction establishes new value.
Chris Lattner848c7d22010-03-31 05:39:57 +00002213 if (MI->isDebugValue()) {
Devang Patel23b2ae62010-03-29 22:59:58 +00002214 DenseMap<const MachineInstr *, DbgVariable *>::iterator DI
2215 = DbgValueStartMap.find(MI);
2216 if (DI != DbgValueStartMap.end()) {
Devang Patel6c74a872010-04-27 19:46:33 +00002217 MCSymbol *Label = NULL;
2218 if (DL == PrevInstLoc)
2219 Label = PrevLabel;
2220 else {
2221 Label = recordSourceLine(DL.getLine(), DL.getCol(), Scope);
2222 PrevInstLoc = DL;
2223 PrevLabel = Label;
2224 }
Devang Patele1c53f22010-05-20 16:36:41 +00002225 DbgVariableLabelsMap[DI->second] = Label;
Devang Patel23b2ae62010-03-29 22:59:58 +00002226 }
Devang Patel67d94ab2010-03-30 18:07:00 +00002227 return;
Devang Patel23b2ae62010-03-29 22:59:58 +00002228 }
2229
Devang Patelbd477be2010-03-29 17:20:31 +00002230 // Emit a label to indicate location change. This is used for line
Devang Patel6c74a872010-04-27 19:46:33 +00002231 // table even if this instruction does not start a new scope.
2232 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 Patelbd477be2010-03-29 17:20:31 +00002240
Devang Patele1c53f22010-05-20 16:36:41 +00002241 // If this instruction begins a scope then note down corresponding label
2242 // even if previous label is reused.
Devang Patela0813082010-05-19 21:58:28 +00002243 if (InsnsBeginScopeSet.count(MI) != 0)
2244 LabelsBeforeInsn[MI] = Label;
Devang Patel8db360d2009-10-06 01:50:42 +00002245}
2246
Devang Patel930143b2009-11-21 02:48:08 +00002247/// endScope - Process end of a scope.
2248void DwarfDebug::endScope(const MachineInstr *MI) {
Devang Patel3ebd8932010-04-08 16:50:29 +00002249 if (InsnsEndScopeSet.count(MI) != 0) {
2250 // Emit a label if this instruction ends a scope.
2251 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
2252 Asm->OutStreamer.EmitLabel(Label);
Devang Patel6c74a872010-04-27 19:46:33 +00002253 LabelsAfterInsn[MI] = Label;
Devang Patel3ebd8932010-04-08 16:50:29 +00002254 }
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002255}
2256
Devang Patel6c74a872010-04-27 19:46:33 +00002257/// getOrCreateDbgScope - Create DbgScope for the scope.
Devang Patel32cc43c2010-05-07 20:54:48 +00002258DbgScope *DwarfDebug::getOrCreateDbgScope(const MDNode *Scope, const MDNode *InlinedAt) {
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002259 if (!InlinedAt) {
2260 DbgScope *WScope = DbgScopeMap.lookup(Scope);
2261 if (WScope)
Devang Patel6c74a872010-04-27 19:46:33 +00002262 return WScope;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002263 WScope = new DbgScope(NULL, DIDescriptor(Scope), NULL);
2264 DbgScopeMap.insert(std::make_pair(Scope, WScope));
Devang Patel6c74a872010-04-27 19:46:33 +00002265 if (DIDescriptor(Scope).isLexicalBlock()) {
2266 DbgScope *Parent =
Devang Patelcfa8e9d2010-05-07 18:11:54 +00002267 getOrCreateDbgScope(DILexicalBlock(Scope).getContext(), NULL);
Devang Patel6c74a872010-04-27 19:46:33 +00002268 WScope->setParent(Parent);
2269 Parent->addScope(WScope);
2270 }
2271
2272 if (!WScope->getParent()) {
2273 StringRef SPName = DISubprogram(Scope).getLinkageName();
2274 if (SPName == Asm->MF->getFunction()->getName())
2275 CurrentFnDbgScope = WScope;
2276 }
2277
2278 return WScope;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002279 }
2280
2281 DbgScope *WScope = DbgScopeMap.lookup(InlinedAt);
2282 if (WScope)
Devang Patel6c74a872010-04-27 19:46:33 +00002283 return WScope;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002284
2285 WScope = new DbgScope(NULL, DIDescriptor(Scope), InlinedAt);
2286 DbgScopeMap.insert(std::make_pair(InlinedAt, WScope));
2287 DILocation DL(InlinedAt);
Devang Patel6c74a872010-04-27 19:46:33 +00002288 DbgScope *Parent =
Devang Patelcfa8e9d2010-05-07 18:11:54 +00002289 getOrCreateDbgScope(DL.getScope(), DL.getOrigLocation());
Devang Patel6c74a872010-04-27 19:46:33 +00002290 WScope->setParent(Parent);
2291 Parent->addScope(WScope);
2292
2293 ConcreteScopes[InlinedAt] = WScope;
2294 getOrCreateAbstractScope(Scope);
2295
2296 return WScope;
Devang Patel8db360d2009-10-06 01:50:42 +00002297}
2298
Devang Patel6c74a872010-04-27 19:46:33 +00002299/// hasValidLocation - Return true if debug location entry attached with
2300/// machine instruction encodes valid location info.
2301static bool hasValidLocation(LLVMContext &Ctx,
2302 const MachineInstr *MInsn,
Devang Patel32cc43c2010-05-07 20:54:48 +00002303 const MDNode *&Scope, const MDNode *&InlinedAt) {
Devang Patel6c74a872010-04-27 19:46:33 +00002304 if (MInsn->isDebugValue())
2305 return false;
2306 DebugLoc DL = MInsn->getDebugLoc();
2307 if (DL.isUnknown()) return false;
2308
Devang Patel32cc43c2010-05-07 20:54:48 +00002309 const MDNode *S = DL.getScope(Ctx);
Devang Patel6c74a872010-04-27 19:46:33 +00002310
2311 // There is no need to create another DIE for compile unit. For all
2312 // other scopes, create one DbgScope now. This will be translated
2313 // into a scope DIE at the end.
2314 if (DIScope(S).isCompileUnit()) return false;
2315
2316 Scope = S;
2317 InlinedAt = DL.getInlinedAt(Ctx);
2318 return true;
2319}
2320
2321/// calculateDominanceGraph - Calculate dominance graph for DbgScope
2322/// hierarchy.
2323static void calculateDominanceGraph(DbgScope *Scope) {
2324 assert (Scope && "Unable to calculate scop edominance graph!");
2325 SmallVector<DbgScope *, 4> WorkStack;
2326 WorkStack.push_back(Scope);
2327 unsigned Counter = 0;
2328 while (!WorkStack.empty()) {
2329 DbgScope *WS = WorkStack.back();
2330 const SmallVector<DbgScope *, 4> &Children = WS->getScopes();
2331 bool visitedChildren = false;
2332 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
2333 SE = Children.end(); SI != SE; ++SI) {
2334 DbgScope *ChildScope = *SI;
2335 if (!ChildScope->getDFSOut()) {
2336 WorkStack.push_back(ChildScope);
2337 visitedChildren = true;
2338 ChildScope->setDFSIn(++Counter);
2339 break;
2340 }
2341 }
2342 if (!visitedChildren) {
2343 WorkStack.pop_back();
2344 WS->setDFSOut(++Counter);
2345 }
2346 }
2347}
2348
2349/// printDbgScopeInfo - Print DbgScope info for each machine instruction.
2350static
2351void printDbgScopeInfo(LLVMContext &Ctx, const MachineFunction *MF,
2352 DenseMap<const MachineInstr *, DbgScope *> &MI2ScopeMap)
2353{
2354#ifndef NDEBUG
2355 unsigned PrevDFSIn = 0;
2356 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2357 I != E; ++I) {
2358 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2359 II != IE; ++II) {
2360 const MachineInstr *MInsn = II;
Devang Patel32cc43c2010-05-07 20:54:48 +00002361 const MDNode *Scope = NULL;
2362 const MDNode *InlinedAt = NULL;
Devang Patel6c74a872010-04-27 19:46:33 +00002363
2364 // Check if instruction has valid location information.
2365 if (hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2366 dbgs() << " [ ";
2367 if (InlinedAt)
2368 dbgs() << "*";
2369 DenseMap<const MachineInstr *, DbgScope *>::iterator DI =
2370 MI2ScopeMap.find(MInsn);
2371 if (DI != MI2ScopeMap.end()) {
2372 DbgScope *S = DI->second;
2373 dbgs() << S->getDFSIn();
2374 PrevDFSIn = S->getDFSIn();
2375 } else
2376 dbgs() << PrevDFSIn;
2377 } else
2378 dbgs() << " [ x" << PrevDFSIn;
2379 dbgs() << " ]";
2380 MInsn->dump();
2381 }
2382 dbgs() << "\n";
2383 }
2384#endif
2385}
Devang Patel930143b2009-11-21 02:48:08 +00002386/// extractScopeInformation - Scan machine instructions in this function
Chris Lattner848c7d22010-03-31 05:39:57 +00002387/// and collect DbgScopes. Return true, if at least one scope was found.
Chris Lattner76555b52010-01-26 23:18:02 +00002388bool DwarfDebug::extractScopeInformation() {
Devang Patel75cc16c2009-10-01 20:31:14 +00002389 // If scope information was extracted using .dbg intrinsics then there is not
2390 // any need to extract these information by scanning each instruction.
2391 if (!DbgScopeMap.empty())
2392 return false;
2393
Dan Gohmane9135cb2010-04-23 01:18:53 +00002394 // Scan each instruction and create scopes. First build working set of scopes.
Devang Patel6c74a872010-04-27 19:46:33 +00002395 LLVMContext &Ctx = Asm->MF->getFunction()->getContext();
2396 SmallVector<DbgRange, 4> MIRanges;
2397 DenseMap<const MachineInstr *, DbgScope *> MI2ScopeMap;
Devang Patel32cc43c2010-05-07 20:54:48 +00002398 const MDNode *PrevScope = NULL;
2399 const MDNode *PrevInlinedAt = NULL;
Devang Patel6c74a872010-04-27 19:46:33 +00002400 const MachineInstr *RangeBeginMI = NULL;
2401 const MachineInstr *PrevMI = NULL;
Chris Lattner3a383cb2010-04-05 00:13:49 +00002402 for (MachineFunction::const_iterator I = Asm->MF->begin(), E = Asm->MF->end();
Devang Patel75cc16c2009-10-01 20:31:14 +00002403 I != E; ++I) {
2404 for (MachineBasicBlock::const_iterator II = I->begin(), IE = I->end();
2405 II != IE; ++II) {
2406 const MachineInstr *MInsn = II;
Devang Patel32cc43c2010-05-07 20:54:48 +00002407 const MDNode *Scope = NULL;
2408 const MDNode *InlinedAt = NULL;
Devang Patel6c74a872010-04-27 19:46:33 +00002409
2410 // Check if instruction has valid location information.
2411 if (!hasValidLocation(Ctx, MInsn, Scope, InlinedAt)) {
2412 PrevMI = MInsn;
2413 continue;
2414 }
Chris Lattner915c5f92010-04-02 19:42:39 +00002415
Devang Patel6c74a872010-04-27 19:46:33 +00002416 // If scope has not changed then skip this instruction.
2417 if (Scope == PrevScope && PrevInlinedAt == InlinedAt) {
2418 PrevMI = MInsn;
2419 continue;
2420 }
2421
2422 if (RangeBeginMI) {
2423 // If we have alread seen a beginning of a instruction range and
2424 // current instruction scope does not match scope of first instruction
2425 // in this range then create a new instruction range.
2426 DbgRange R(RangeBeginMI, PrevMI);
2427 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
2428 MIRanges.push_back(R);
2429 }
2430
2431 // This is a beginning of a new instruction range.
2432 RangeBeginMI = MInsn;
Chris Lattner915c5f92010-04-02 19:42:39 +00002433
Devang Patel6c74a872010-04-27 19:46:33 +00002434 // Reset previous markers.
2435 PrevMI = MInsn;
2436 PrevScope = Scope;
2437 PrevInlinedAt = InlinedAt;
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002438 }
2439 }
2440
Devang Patel6c74a872010-04-27 19:46:33 +00002441 // Create last instruction range.
2442 if (RangeBeginMI && PrevMI && PrevScope) {
2443 DbgRange R(RangeBeginMI, PrevMI);
2444 MIRanges.push_back(R);
2445 MI2ScopeMap[RangeBeginMI] = getOrCreateDbgScope(PrevScope, PrevInlinedAt);
Devang Patel75cc16c2009-10-01 20:31:14 +00002446 }
Devang Patel6c74a872010-04-27 19:46:33 +00002447
Devang Patel530a0752010-01-04 20:44:00 +00002448 if (!CurrentFnDbgScope)
2449 return false;
2450
Devang Patel6c74a872010-04-27 19:46:33 +00002451 calculateDominanceGraph(CurrentFnDbgScope);
2452 if (PrintDbgScope)
2453 printDbgScopeInfo(Ctx, Asm->MF, MI2ScopeMap);
2454
2455 // Find ranges of instructions covered by each DbgScope;
2456 DbgScope *PrevDbgScope = NULL;
2457 for (SmallVector<DbgRange, 4>::const_iterator RI = MIRanges.begin(),
2458 RE = MIRanges.end(); RI != RE; ++RI) {
2459 const DbgRange &R = *RI;
2460 DbgScope *S = MI2ScopeMap.lookup(R.first);
2461 assert (S && "Lost DbgScope for a machine instruction!");
2462 if (PrevDbgScope && !PrevDbgScope->dominates(S))
2463 PrevDbgScope->closeInsnRange(S);
2464 S->openInsnRange(R.first);
2465 S->extendInsnRange(R.second);
2466 PrevDbgScope = S;
2467 }
2468
2469 if (PrevDbgScope)
2470 PrevDbgScope->closeInsnRange();
Devang Patel75cc16c2009-10-01 20:31:14 +00002471
Devang Patel359b0132010-04-08 18:43:56 +00002472 identifyScopeMarkers();
Devang Patelf1d5a1e2010-04-08 15:37:09 +00002473
2474 return !DbgScopeMap.empty();
2475}
2476
Devang Patel6c74a872010-04-27 19:46:33 +00002477/// identifyScopeMarkers() -
2478/// Each DbgScope has first instruction and last instruction to mark beginning
2479/// and end of a scope respectively. Create an inverse map that list scopes
2480/// starts (and ends) with an instruction. One instruction may start (or end)
2481/// multiple scopes. Ignore scopes that are not reachable.
Devang Patel359b0132010-04-08 18:43:56 +00002482void DwarfDebug::identifyScopeMarkers() {
Devang Patel7771b7c2010-01-20 02:05:23 +00002483 SmallVector<DbgScope *, 4> WorkList;
2484 WorkList.push_back(CurrentFnDbgScope);
2485 while (!WorkList.empty()) {
Chris Lattner848c7d22010-03-31 05:39:57 +00002486 DbgScope *S = WorkList.pop_back_val();
Devang Patel6c74a872010-04-27 19:46:33 +00002487
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +00002488 const SmallVector<DbgScope *, 4> &Children = S->getScopes();
Devang Patel7771b7c2010-01-20 02:05:23 +00002489 if (!Children.empty())
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +00002490 for (SmallVector<DbgScope *, 4>::const_iterator SI = Children.begin(),
Devang Patel7771b7c2010-01-20 02:05:23 +00002491 SE = Children.end(); SI != SE; ++SI)
2492 WorkList.push_back(*SI);
2493
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002494 if (S->isAbstractScope())
2495 continue;
Devang Patel6c74a872010-04-27 19:46:33 +00002496
2497 const SmallVector<DbgRange, 4> &Ranges = S->getRanges();
2498 if (Ranges.empty())
2499 continue;
2500 for (SmallVector<DbgRange, 4>::const_iterator RI = Ranges.begin(),
2501 RE = Ranges.end(); RI != RE; ++RI) {
Devang Patela0813082010-05-19 21:58:28 +00002502 assert(RI->first && "DbgRange does not have first instruction!");
2503 assert(RI->second && "DbgRange does not have second instruction!");
2504 InsnsBeginScopeSet.insert(RI->first);
Devang Patel6c74a872010-04-27 19:46:33 +00002505 InsnsEndScopeSet.insert(RI->second);
2506 }
Devang Patel75cc16c2009-10-01 20:31:14 +00002507 }
Devang Patel75cc16c2009-10-01 20:31:14 +00002508}
2509
Dan Gohman3df671a2010-04-20 00:37:27 +00002510/// FindFirstDebugLoc - Find the first debug location in the function. This
2511/// is intended to be an approximation for the source position of the
2512/// beginning of the function.
2513static DebugLoc FindFirstDebugLoc(const MachineFunction *MF) {
2514 for (MachineFunction::const_iterator I = MF->begin(), E = MF->end();
2515 I != E; ++I)
2516 for (MachineBasicBlock::const_iterator MBBI = I->begin(), MBBE = I->end();
2517 MBBI != MBBE; ++MBBI) {
2518 DebugLoc DL = MBBI->getDebugLoc();
2519 if (!DL.isUnknown())
2520 return DL;
2521 }
2522 return DebugLoc();
2523}
2524
Devang Patel930143b2009-11-21 02:48:08 +00002525/// beginFunction - Gather pre-function debug information. Assumes being
Bill Wendling2b128d72009-05-20 23:19:06 +00002526/// emitted immediately after the function entry point.
Chris Lattner76555b52010-01-26 23:18:02 +00002527void DwarfDebug::beginFunction(const MachineFunction *MF) {
Chris Lattner196dbdc2010-04-05 03:52:55 +00002528 if (!MMI->hasDebugInfo()) return;
Bill Wendlingfcc14142010-04-07 09:28:04 +00002529 if (!extractScopeInformation()) return;
Chris Lattner47879752010-03-29 20:38:20 +00002530
Devang Patele0a94bf2010-05-14 21:01:35 +00002531 collectVariableInfo(MF);
Devang Patel4598eb62009-10-06 18:37:31 +00002532
Devang Patel6c74a872010-04-27 19:46:33 +00002533 FunctionBeginSym = Asm->GetTempSymbol("func_begin",
2534 Asm->getFunctionNumber());
Bill Wendling2b128d72009-05-20 23:19:06 +00002535 // Assumes in correct section after the entry point.
Devang Patel6c74a872010-04-27 19:46:33 +00002536 Asm->OutStreamer.EmitLabel(FunctionBeginSym);
Bill Wendling2b128d72009-05-20 23:19:06 +00002537
2538 // Emit label for the implicitly defined dbg.stoppoint at the start of the
2539 // function.
Dan Gohman3df671a2010-04-20 00:37:27 +00002540 DebugLoc FDL = FindFirstDebugLoc(MF);
Chris Lattner915c5f92010-04-02 19:42:39 +00002541 if (FDL.isUnknown()) return;
2542
Devang Patel32cc43c2010-05-07 20:54:48 +00002543 const MDNode *Scope = FDL.getScope(MF->getFunction()->getContext());
Chris Lattner915c5f92010-04-02 19:42:39 +00002544
2545 DISubprogram SP = getDISubprogram(Scope);
2546 unsigned Line, Col;
2547 if (SP.Verify()) {
2548 Line = SP.getLineNumber();
2549 Col = 0;
2550 } else {
2551 Line = FDL.getLine();
2552 Col = FDL.getCol();
Bill Wendling2b128d72009-05-20 23:19:06 +00002553 }
Chris Lattner915c5f92010-04-02 19:42:39 +00002554
2555 recordSourceLine(Line, Col, Scope);
Bill Wendling2b128d72009-05-20 23:19:06 +00002556}
2557
Devang Patel930143b2009-11-21 02:48:08 +00002558/// endFunction - Gather and emit post-function debug information.
Bill Wendling2b128d72009-05-20 23:19:06 +00002559///
Chris Lattner76555b52010-01-26 23:18:02 +00002560void DwarfDebug::endFunction(const MachineFunction *MF) {
Bill Wendlingfcc14142010-04-07 09:28:04 +00002561 if (!MMI->hasDebugInfo() || DbgScopeMap.empty()) return;
Devang Patel2904aa92009-11-12 19:02:56 +00002562
Devang Patel530a0752010-01-04 20:44:00 +00002563 if (CurrentFnDbgScope) {
2564 // Define end label for subprogram.
Chris Lattner3a383cb2010-04-05 00:13:49 +00002565 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("func_end",
2566 Asm->getFunctionNumber()));
Devang Patel530a0752010-01-04 20:44:00 +00002567
2568 // Get function line info.
2569 if (!Lines.empty()) {
2570 // Get section line info.
2571 unsigned ID = SectionMap.insert(Asm->getCurrentSection());
2572 if (SectionSourceLines.size() < ID) SectionSourceLines.resize(ID);
2573 std::vector<SrcLineInfo> &SectionLineInfos = SectionSourceLines[ID-1];
2574 // Append the function info to section info.
2575 SectionLineInfos.insert(SectionLineInfos.end(),
2576 Lines.begin(), Lines.end());
2577 }
2578
2579 // Construct abstract scopes.
2580 for (SmallVector<DbgScope *, 4>::iterator AI = AbstractScopesList.begin(),
2581 AE = AbstractScopesList.end(); AI != AE; ++AI)
2582 constructScopeDIE(*AI);
2583
Devang Patel075e9b52010-05-04 06:15:30 +00002584 DIE *CurFnDIE = constructScopeDIE(CurrentFnDbgScope);
Devang Patel530a0752010-01-04 20:44:00 +00002585
Devang Patel075e9b52010-05-04 06:15:30 +00002586 if (!DisableFramePointerElim(*MF))
2587 addUInt(CurFnDIE, dwarf::DW_AT_APPLE_omit_frame_ptr,
2588 dwarf::DW_FORM_flag, 1);
2589
2590
Chris Lattner3a383cb2010-04-05 00:13:49 +00002591 DebugFrames.push_back(FunctionDebugFrameInfo(Asm->getFunctionNumber(),
Devang Patel530a0752010-01-04 20:44:00 +00002592 MMI->getFrameMoves()));
Bill Wendling2b128d72009-05-20 23:19:06 +00002593 }
2594
Bill Wendling2b128d72009-05-20 23:19:06 +00002595 // Clear debug info
Devang Patelfe189e62010-01-19 01:26:02 +00002596 CurrentFnDbgScope = NULL;
Devang Patele1c53f22010-05-20 16:36:41 +00002597 DbgVariableToFrameIndexMap.clear();
2598 VarToAbstractVarMap.clear();
2599 DbgVariableToDbgInstMap.clear();
2600 DbgVariableLabelsMap.clear();
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +00002601 DeleteContainerSeconds(DbgScopeMap);
Devang Patela0813082010-05-19 21:58:28 +00002602 InsnsBeginScopeSet.clear();
Devang Patel541019d2010-04-09 16:04:20 +00002603 InsnsEndScopeSet.clear();
Devang Patel23b2ae62010-03-29 22:59:58 +00002604 DbgValueStartMap.clear();
Devang Patelfe189e62010-01-19 01:26:02 +00002605 ConcreteScopes.clear();
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +00002606 DeleteContainerSeconds(AbstractScopes);
Devang Patelfe189e62010-01-19 01:26:02 +00002607 AbstractScopesList.clear();
Jeffrey Yasskin35b4e4f2010-03-12 17:45:06 +00002608 AbstractVariables.clear();
Devang Patel6c74a872010-04-27 19:46:33 +00002609 LabelsBeforeInsn.clear();
2610 LabelsAfterInsn.clear();
Bill Wendling2b128d72009-05-20 23:19:06 +00002611 Lines.clear();
Devang Patel12563b32010-04-16 23:33:45 +00002612 PrevLabel = NULL;
Bill Wendling2b128d72009-05-20 23:19:06 +00002613}
2614
Devang Patele1c53f22010-05-20 16:36:41 +00002615/// recordVariableFrameIndex - Record a variable's index.
2616void DwarfDebug::recordVariableFrameIndex(const DbgVariable *V, int Index) {
2617 assert (V && "Invalid DbgVariable!");
2618 DbgVariableToFrameIndexMap[V] = Index;
2619}
2620
2621/// findVariableFrameIndex - Return true if frame index for the variable
2622/// is found. Update FI to hold value of the index.
2623bool DwarfDebug::findVariableFrameIndex(const DbgVariable *V, int *FI) {
2624 assert (V && "Invalid DbgVariable!");
2625 DenseMap<const DbgVariable *, int>::iterator I =
2626 DbgVariableToFrameIndexMap.find(V);
2627 if (I == DbgVariableToFrameIndexMap.end())
2628 return false;
2629 *FI = I->second;
2630 return true;
2631}
2632
2633/// findVariableLabel - Find MCSymbol for the variable.
2634const MCSymbol *DwarfDebug::findVariableLabel(const DbgVariable *V) {
2635 DenseMap<const DbgVariable *, const MCSymbol *>::iterator I
2636 = DbgVariableLabelsMap.find(V);
2637 if (I == DbgVariableLabelsMap.end())
2638 return NULL;
2639 else return I->second;
2640}
2641
Chris Lattnerba35a672010-03-09 04:54:43 +00002642/// recordSourceLine - Register a source line with debug info. Returns the
2643/// unique label that was emitted and which provides correspondence to
2644/// the source line list.
Devang Patel32cc43c2010-05-07 20:54:48 +00002645MCSymbol *DwarfDebug::recordSourceLine(unsigned Line, unsigned Col, const MDNode *S) {
Devang Patel2d9caf92009-11-25 17:36:49 +00002646 StringRef Dir;
2647 StringRef Fn;
Devang Patel2089d162009-10-05 18:03:19 +00002648
Dan Gohman50849c62010-05-05 23:41:32 +00002649 unsigned Src = 1;
2650 if (S) {
2651 DIDescriptor Scope(S);
Devang Patel2089d162009-10-05 18:03:19 +00002652
Dan Gohman50849c62010-05-05 23:41:32 +00002653 if (Scope.isCompileUnit()) {
2654 DICompileUnit CU(S);
2655 Dir = CU.getDirectory();
2656 Fn = CU.getFilename();
2657 } else if (Scope.isSubprogram()) {
2658 DISubprogram SP(S);
2659 Dir = SP.getDirectory();
2660 Fn = SP.getFilename();
2661 } else if (Scope.isLexicalBlock()) {
2662 DILexicalBlock DB(S);
2663 Dir = DB.getDirectory();
2664 Fn = DB.getFilename();
2665 } else
2666 assert(0 && "Unexpected scope info");
2667
2668 Src = GetOrCreateSourceID(Dir, Fn);
2669 }
2670
Chris Lattner6e52e9d2010-03-14 08:36:50 +00002671 MCSymbol *Label = MMI->getContext().CreateTempSymbol();
Chris Lattnerb4666f42010-03-14 08:15:55 +00002672 Lines.push_back(SrcLineInfo(Line, Col, Src, Label));
Bill Wendling2b128d72009-05-20 23:19:06 +00002673
Chris Lattnerba35a672010-03-09 04:54:43 +00002674 Asm->OutStreamer.EmitLabel(Label);
2675 return Label;
Bill Wendling2b128d72009-05-20 23:19:06 +00002676}
2677
Bill Wendling806535f2009-05-20 23:22:40 +00002678//===----------------------------------------------------------------------===//
2679// Emit Methods
2680//===----------------------------------------------------------------------===//
2681
Devang Patel930143b2009-11-21 02:48:08 +00002682/// computeSizeAndOffset - Compute the size and offset of a DIE.
Bill Wendling480ff322009-05-20 23:21:38 +00002683///
Jim Grosbach00e9c612009-11-22 19:20:36 +00002684unsigned
2685DwarfDebug::computeSizeAndOffset(DIE *Die, unsigned Offset, bool Last) {
Bill Wendling480ff322009-05-20 23:21:38 +00002686 // Get the children.
2687 const std::vector<DIE *> &Children = Die->getChildren();
2688
2689 // If not last sibling and has children then add sibling offset attribute.
Jeffrey Yasskin54ebc982010-03-22 18:47:14 +00002690 if (!Last && !Children.empty())
Benjamin Kramer74729ae2010-03-31 19:34:01 +00002691 Die->addSiblingOffset(DIEValueAllocator);
Bill Wendling480ff322009-05-20 23:21:38 +00002692
2693 // Record the abbreviation.
Devang Patel930143b2009-11-21 02:48:08 +00002694 assignAbbrevNumber(Die->getAbbrev());
Bill Wendling480ff322009-05-20 23:21:38 +00002695
2696 // Get the abbreviation for this DIE.
2697 unsigned AbbrevNumber = Die->getAbbrevNumber();
2698 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2699
2700 // Set DIE offset
2701 Die->setOffset(Offset);
2702
2703 // Start the size with the size of abbreviation code.
Chris Lattner7b26fce2009-08-22 20:48:53 +00002704 Offset += MCAsmInfo::getULEB128Size(AbbrevNumber);
Bill Wendling480ff322009-05-20 23:21:38 +00002705
2706 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
2707 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2708
2709 // Size the DIE attribute values.
2710 for (unsigned i = 0, N = Values.size(); i < N; ++i)
2711 // Size attribute value.
Chris Lattner5a00dea2010-04-05 00:18:22 +00002712 Offset += Values[i]->SizeOf(Asm, AbbrevData[i].getForm());
Bill Wendling480ff322009-05-20 23:21:38 +00002713
2714 // Size the DIE children if any.
2715 if (!Children.empty()) {
2716 assert(Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes &&
2717 "Children flag not set");
2718
2719 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel930143b2009-11-21 02:48:08 +00002720 Offset = computeSizeAndOffset(Children[j], Offset, (j + 1) == M);
Bill Wendling480ff322009-05-20 23:21:38 +00002721
2722 // End of children marker.
2723 Offset += sizeof(int8_t);
2724 }
2725
2726 Die->setSize(Offset - Die->getOffset());
2727 return Offset;
2728}
2729
Devang Patel930143b2009-11-21 02:48:08 +00002730/// computeSizeAndOffsets - Compute the size and offset of all the DIEs.
Bill Wendling480ff322009-05-20 23:21:38 +00002731///
Devang Patel930143b2009-11-21 02:48:08 +00002732void DwarfDebug::computeSizeAndOffsets() {
Devang Patel1a0df9a2010-05-10 22:49:55 +00002733 unsigned PrevOffset = 0;
2734 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
2735 E = CUMap.end(); I != E; ++I) {
2736 // Compute size of compile unit header.
2737 static unsigned Offset = PrevOffset +
2738 sizeof(int32_t) + // Length of Compilation Unit Info
2739 sizeof(int16_t) + // DWARF version number
2740 sizeof(int32_t) + // Offset Into Abbrev. Section
2741 sizeof(int8_t); // Pointer Size (in bytes)
2742 computeSizeAndOffset(I->second->getCUDie(), Offset, true);
2743 PrevOffset = Offset;
2744 }
Bill Wendling480ff322009-05-20 23:21:38 +00002745}
2746
Chris Lattner1fbf53b2010-04-04 23:02:02 +00002747/// EmitSectionSym - Switch to the specified MCSection and emit an assembler
2748/// temporary label to it if SymbolStem is specified.
Chris Lattner6629ca92010-04-04 22:59:04 +00002749static MCSymbol *EmitSectionSym(AsmPrinter *Asm, const MCSection *Section,
Chris Lattner1fbf53b2010-04-04 23:02:02 +00002750 const char *SymbolStem = 0) {
Chris Lattner6629ca92010-04-04 22:59:04 +00002751 Asm->OutStreamer.SwitchSection(Section);
Chris Lattner1fbf53b2010-04-04 23:02:02 +00002752 if (!SymbolStem) return 0;
2753
Chris Lattner6629ca92010-04-04 22:59:04 +00002754 MCSymbol *TmpSym = Asm->GetTempSymbol(SymbolStem);
2755 Asm->OutStreamer.EmitLabel(TmpSym);
2756 return TmpSym;
2757}
2758
2759/// EmitSectionLabels - Emit initial Dwarf sections with a label at
2760/// the start of each one.
Chris Lattner46355d82010-04-04 22:33:59 +00002761void DwarfDebug::EmitSectionLabels() {
Chris Lattner4b7dadb2009-08-19 05:49:37 +00002762 const TargetLoweringObjectFile &TLOF = Asm->getObjFileLowering();
Daniel Dunbarc418d6b2009-09-19 20:40:05 +00002763
Bill Wendling480ff322009-05-20 23:21:38 +00002764 // Dwarf sections base addresses.
Chris Lattner3a383cb2010-04-05 00:13:49 +00002765 if (Asm->MAI->doesDwarfRequireFrameSection()) {
Chris Lattner6629ca92010-04-04 22:59:04 +00002766 DwarfFrameSectionSym =
2767 EmitSectionSym(Asm, TLOF.getDwarfFrameSection(), "section_debug_frame");
2768 }
Bill Wendling480ff322009-05-20 23:21:38 +00002769
Chris Lattner6629ca92010-04-04 22:59:04 +00002770 DwarfInfoSectionSym =
2771 EmitSectionSym(Asm, TLOF.getDwarfInfoSection(), "section_info");
2772 DwarfAbbrevSectionSym =
2773 EmitSectionSym(Asm, TLOF.getDwarfAbbrevSection(), "section_abbrev");
Chris Lattner1fbf53b2010-04-04 23:02:02 +00002774 EmitSectionSym(Asm, TLOF.getDwarfARangesSection());
Chris Lattner6629ca92010-04-04 22:59:04 +00002775
2776 if (const MCSection *MacroInfo = TLOF.getDwarfMacroInfoSection())
Chris Lattner1fbf53b2010-04-04 23:02:02 +00002777 EmitSectionSym(Asm, MacroInfo);
Bill Wendling480ff322009-05-20 23:21:38 +00002778
Chris Lattner1fbf53b2010-04-04 23:02:02 +00002779 EmitSectionSym(Asm, TLOF.getDwarfLineSection());
2780 EmitSectionSym(Asm, TLOF.getDwarfLocSection());
2781 EmitSectionSym(Asm, TLOF.getDwarfPubNamesSection());
2782 EmitSectionSym(Asm, TLOF.getDwarfPubTypesSection());
Chris Lattner6629ca92010-04-04 22:59:04 +00002783 DwarfStrSectionSym =
2784 EmitSectionSym(Asm, TLOF.getDwarfStrSection(), "section_str");
Devang Patel12563b32010-04-16 23:33:45 +00002785 DwarfDebugRangeSectionSym = EmitSectionSym(Asm, TLOF.getDwarfRangesSection(),
2786 "debug_range");
Bill Wendling480ff322009-05-20 23:21:38 +00002787
Chris Lattner6629ca92010-04-04 22:59:04 +00002788 TextSectionSym = EmitSectionSym(Asm, TLOF.getTextSection(), "text_begin");
Chris Lattnere58b5472010-04-04 23:10:38 +00002789 EmitSectionSym(Asm, TLOF.getDataSection());
Bill Wendling480ff322009-05-20 23:21:38 +00002790}
2791
Devang Patel930143b2009-11-21 02:48:08 +00002792/// emitDIE - Recusively Emits a debug information entry.
Bill Wendling480ff322009-05-20 23:21:38 +00002793///
Devang Patel930143b2009-11-21 02:48:08 +00002794void DwarfDebug::emitDIE(DIE *Die) {
Bill Wendling480ff322009-05-20 23:21:38 +00002795 // Get the abbreviation for this DIE.
2796 unsigned AbbrevNumber = Die->getAbbrevNumber();
2797 const DIEAbbrev *Abbrev = Abbreviations[AbbrevNumber - 1];
2798
Bill Wendling480ff322009-05-20 23:21:38 +00002799 // Emit the code (index) for the abbreviation.
Chris Lattner7bde8c02010-04-04 18:52:31 +00002800 if (Asm->isVerbose())
Chris Lattnerfa823552010-01-22 23:18:42 +00002801 Asm->OutStreamer.AddComment("Abbrev [" + Twine(AbbrevNumber) + "] 0x" +
2802 Twine::utohexstr(Die->getOffset()) + ":0x" +
2803 Twine::utohexstr(Die->getSize()) + " " +
2804 dwarf::TagString(Abbrev->getTag()));
Chris Lattner9efd1182010-04-04 19:09:29 +00002805 Asm->EmitULEB128(AbbrevNumber);
Bill Wendling480ff322009-05-20 23:21:38 +00002806
Jeffrey Yasskin54ebc982010-03-22 18:47:14 +00002807 const SmallVector<DIEValue*, 32> &Values = Die->getValues();
Bill Wendling480ff322009-05-20 23:21:38 +00002808 const SmallVector<DIEAbbrevData, 8> &AbbrevData = Abbrev->getData();
2809
2810 // Emit the DIE attribute values.
2811 for (unsigned i = 0, N = Values.size(); i < N; ++i) {
2812 unsigned Attr = AbbrevData[i].getAttribute();
2813 unsigned Form = AbbrevData[i].getForm();
2814 assert(Form && "Too many attributes for DIE (check abbreviation)");
2815
Chris Lattner7bde8c02010-04-04 18:52:31 +00002816 if (Asm->isVerbose())
Chris Lattner5adf9872010-01-24 18:54:17 +00002817 Asm->OutStreamer.AddComment(dwarf::AttributeString(Attr));
2818
Bill Wendling480ff322009-05-20 23:21:38 +00002819 switch (Attr) {
2820 case dwarf::DW_AT_sibling:
Devang Patel930143b2009-11-21 02:48:08 +00002821 Asm->EmitInt32(Die->getSiblingOffset());
Bill Wendling480ff322009-05-20 23:21:38 +00002822 break;
2823 case dwarf::DW_AT_abstract_origin: {
2824 DIEEntry *E = cast<DIEEntry>(Values[i]);
2825 DIE *Origin = E->getEntry();
Devang Patelf6eeaeb2009-11-10 23:06:00 +00002826 unsigned Addr = Origin->getOffset();
Bill Wendling480ff322009-05-20 23:21:38 +00002827 Asm->EmitInt32(Addr);
2828 break;
2829 }
Devang Patel12563b32010-04-16 23:33:45 +00002830 case dwarf::DW_AT_ranges: {
2831 // DW_AT_range Value encodes offset in debug_range section.
2832 DIEInteger *V = cast<DIEInteger>(Values[i]);
2833 Asm->EmitLabelOffsetDifference(DwarfDebugRangeSectionSym,
2834 V->getValue(),
2835 DwarfDebugRangeSectionSym,
2836 4);
2837 break;
2838 }
Bill Wendling480ff322009-05-20 23:21:38 +00002839 default:
2840 // Emit an attribute using the defined form.
Chris Lattner3a383cb2010-04-05 00:13:49 +00002841 Values[i]->EmitValue(Asm, Form);
Bill Wendling480ff322009-05-20 23:21:38 +00002842 break;
2843 }
Bill Wendling480ff322009-05-20 23:21:38 +00002844 }
2845
2846 // Emit the DIE children if any.
2847 if (Abbrev->getChildrenFlag() == dwarf::DW_CHILDREN_yes) {
2848 const std::vector<DIE *> &Children = Die->getChildren();
2849
2850 for (unsigned j = 0, M = Children.size(); j < M; ++j)
Devang Patel930143b2009-11-21 02:48:08 +00002851 emitDIE(Children[j]);
Bill Wendling480ff322009-05-20 23:21:38 +00002852
Chris Lattner7bde8c02010-04-04 18:52:31 +00002853 if (Asm->isVerbose())
Chris Lattner566cae92010-03-09 23:52:58 +00002854 Asm->OutStreamer.AddComment("End Of Children Mark");
2855 Asm->EmitInt8(0);
Bill Wendling480ff322009-05-20 23:21:38 +00002856 }
2857}
2858
Devang Patel9ccfb642009-12-09 18:24:21 +00002859/// emitDebugInfo - Emit the debug info section.
Bill Wendling480ff322009-05-20 23:21:38 +00002860///
Devang Patel9ccfb642009-12-09 18:24:21 +00002861void DwarfDebug::emitDebugInfo() {
2862 // Start debug info section.
2863 Asm->OutStreamer.SwitchSection(
2864 Asm->getObjFileLowering().getDwarfInfoSection());
Devang Patel1a0df9a2010-05-10 22:49:55 +00002865 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
2866 E = CUMap.end(); I != E; ++I) {
2867 CompileUnit *TheCU = I->second;
2868 DIE *Die = TheCU->getCUDie();
2869
2870 // Emit the compile units header.
2871 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_begin",
2872 TheCU->getID()));
2873
2874 // Emit size of content not including length itself
2875 unsigned ContentSize = Die->getSize() +
2876 sizeof(int16_t) + // DWARF version number
2877 sizeof(int32_t) + // Offset Into Abbrev. Section
2878 sizeof(int8_t) + // Pointer Size (in bytes)
2879 sizeof(int32_t); // FIXME - extra pad for gdb bug.
2880
2881 Asm->OutStreamer.AddComment("Length of Compilation Unit Info");
2882 Asm->EmitInt32(ContentSize);
2883 Asm->OutStreamer.AddComment("DWARF version number");
2884 Asm->EmitInt16(dwarf::DWARF_VERSION);
2885 Asm->OutStreamer.AddComment("Offset Into Abbrev. Section");
2886 Asm->EmitSectionOffset(Asm->GetTempSymbol("abbrev_begin"),
2887 DwarfAbbrevSectionSym);
2888 Asm->OutStreamer.AddComment("Address Size (in bytes)");
2889 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
2890
2891 emitDIE(Die);
2892 // FIXME - extra padding for gdb bug.
2893 Asm->OutStreamer.AddComment("4 extra padding bytes for GDB");
2894 Asm->EmitInt8(0);
2895 Asm->EmitInt8(0);
2896 Asm->EmitInt8(0);
2897 Asm->EmitInt8(0);
2898 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("info_end", TheCU->getID()));
2899 }
Bill Wendling480ff322009-05-20 23:21:38 +00002900}
2901
Devang Patel930143b2009-11-21 02:48:08 +00002902/// emitAbbreviations - Emit the abbreviation section.
Bill Wendling480ff322009-05-20 23:21:38 +00002903///
Devang Patel930143b2009-11-21 02:48:08 +00002904void DwarfDebug::emitAbbreviations() const {
Bill Wendling480ff322009-05-20 23:21:38 +00002905 // Check to see if it is worth the effort.
2906 if (!Abbreviations.empty()) {
2907 // Start the debug abbrev section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00002908 Asm->OutStreamer.SwitchSection(
2909 Asm->getObjFileLowering().getDwarfAbbrevSection());
Bill Wendling480ff322009-05-20 23:21:38 +00002910
Chris Lattnera179b522010-04-04 19:25:43 +00002911 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_begin"));
Bill Wendling480ff322009-05-20 23:21:38 +00002912
2913 // For each abbrevation.
2914 for (unsigned i = 0, N = Abbreviations.size(); i < N; ++i) {
2915 // Get abbreviation data
2916 const DIEAbbrev *Abbrev = Abbreviations[i];
2917
2918 // Emit the abbrevations code (base 1 index.)
Chris Lattner9efd1182010-04-04 19:09:29 +00002919 Asm->EmitULEB128(Abbrev->getNumber(), "Abbreviation Code");
Bill Wendling480ff322009-05-20 23:21:38 +00002920
2921 // Emit the abbreviations data.
Chris Lattner3a383cb2010-04-05 00:13:49 +00002922 Abbrev->Emit(Asm);
Bill Wendling480ff322009-05-20 23:21:38 +00002923 }
2924
2925 // Mark end of abbreviations.
Chris Lattner9efd1182010-04-04 19:09:29 +00002926 Asm->EmitULEB128(0, "EOM(3)");
Bill Wendling480ff322009-05-20 23:21:38 +00002927
Chris Lattnera179b522010-04-04 19:25:43 +00002928 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("abbrev_end"));
Bill Wendling480ff322009-05-20 23:21:38 +00002929 }
2930}
2931
Devang Patel930143b2009-11-21 02:48:08 +00002932/// emitEndOfLineMatrix - Emit the last address of the section and the end of
Bill Wendling480ff322009-05-20 23:21:38 +00002933/// the line matrix.
2934///
Devang Patel930143b2009-11-21 02:48:08 +00002935void DwarfDebug::emitEndOfLineMatrix(unsigned SectionEnd) {
Bill Wendling480ff322009-05-20 23:21:38 +00002936 // Define last address of section.
Chris Lattner566cae92010-03-09 23:52:58 +00002937 Asm->OutStreamer.AddComment("Extended Op");
2938 Asm->EmitInt8(0);
2939
2940 Asm->OutStreamer.AddComment("Op size");
Chris Lattner3a383cb2010-04-05 00:13:49 +00002941 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner566cae92010-03-09 23:52:58 +00002942 Asm->OutStreamer.AddComment("DW_LNE_set_address");
2943 Asm->EmitInt8(dwarf::DW_LNE_set_address);
2944
2945 Asm->OutStreamer.AddComment("Section end label");
Chris Lattnerb245dfb2010-03-10 01:17:49 +00002946
Chris Lattnera179b522010-04-04 19:25:43 +00002947 Asm->OutStreamer.EmitSymbolValue(Asm->GetTempSymbol("section_end",SectionEnd),
Chris Lattner3a383cb2010-04-05 00:13:49 +00002948 Asm->getTargetData().getPointerSize(),
2949 0/*AddrSpace*/);
Bill Wendling480ff322009-05-20 23:21:38 +00002950
2951 // Mark end of matrix.
Chris Lattner566cae92010-03-09 23:52:58 +00002952 Asm->OutStreamer.AddComment("DW_LNE_end_sequence");
2953 Asm->EmitInt8(0);
Chris Lattnerf5c834f2010-01-22 22:09:00 +00002954 Asm->EmitInt8(1);
Chris Lattnerfa823552010-01-22 23:18:42 +00002955 Asm->EmitInt8(1);
Bill Wendling480ff322009-05-20 23:21:38 +00002956}
2957
Devang Patel930143b2009-11-21 02:48:08 +00002958/// emitDebugLines - Emit source line information.
Bill Wendling480ff322009-05-20 23:21:38 +00002959///
Devang Patel930143b2009-11-21 02:48:08 +00002960void DwarfDebug::emitDebugLines() {
Bill Wendling480ff322009-05-20 23:21:38 +00002961 // If the target is using .loc/.file, the assembler will be emitting the
2962 // .debug_line table automatically.
Chris Lattner3a383cb2010-04-05 00:13:49 +00002963 if (Asm->MAI->hasDotLocAndDotFile())
Bill Wendling480ff322009-05-20 23:21:38 +00002964 return;
2965
2966 // Minimum line delta, thus ranging from -10..(255-10).
2967 const int MinLineDelta = -(dwarf::DW_LNS_fixed_advance_pc + 1);
2968 // Maximum line delta, thus ranging from -10..(255-10).
2969 const int MaxLineDelta = 255 + MinLineDelta;
2970
2971 // Start the dwarf line section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00002972 Asm->OutStreamer.SwitchSection(
2973 Asm->getObjFileLowering().getDwarfLineSection());
Bill Wendling480ff322009-05-20 23:21:38 +00002974
2975 // Construct the section header.
Chris Lattner566cae92010-03-09 23:52:58 +00002976 Asm->OutStreamer.AddComment("Length of Source Line Info");
Chris Lattnerf1429f12010-04-04 19:58:12 +00002977 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_end"),
2978 Asm->GetTempSymbol("line_begin"), 4);
Chris Lattnera179b522010-04-04 19:25:43 +00002979 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_begin"));
Bill Wendling480ff322009-05-20 23:21:38 +00002980
Chris Lattner566cae92010-03-09 23:52:58 +00002981 Asm->OutStreamer.AddComment("DWARF version number");
2982 Asm->EmitInt16(dwarf::DWARF_VERSION);
Bill Wendling480ff322009-05-20 23:21:38 +00002983
Chris Lattner566cae92010-03-09 23:52:58 +00002984 Asm->OutStreamer.AddComment("Prolog Length");
Chris Lattnerf1429f12010-04-04 19:58:12 +00002985 Asm->EmitLabelDifference(Asm->GetTempSymbol("line_prolog_end"),
2986 Asm->GetTempSymbol("line_prolog_begin"), 4);
Chris Lattnera179b522010-04-04 19:25:43 +00002987 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_begin"));
Bill Wendling480ff322009-05-20 23:21:38 +00002988
Chris Lattner566cae92010-03-09 23:52:58 +00002989 Asm->OutStreamer.AddComment("Minimum Instruction Length");
2990 Asm->EmitInt8(1);
2991 Asm->OutStreamer.AddComment("Default is_stmt_start flag");
2992 Asm->EmitInt8(1);
2993 Asm->OutStreamer.AddComment("Line Base Value (Special Opcodes)");
2994 Asm->EmitInt8(MinLineDelta);
2995 Asm->OutStreamer.AddComment("Line Range Value (Special Opcodes)");
2996 Asm->EmitInt8(MaxLineDelta);
2997 Asm->OutStreamer.AddComment("Special Opcode Base");
2998 Asm->EmitInt8(-MinLineDelta);
Bill Wendling480ff322009-05-20 23:21:38 +00002999
3000 // Line number standard opcode encodings argument count
Chris Lattner566cae92010-03-09 23:52:58 +00003001 Asm->OutStreamer.AddComment("DW_LNS_copy arg count");
3002 Asm->EmitInt8(0);
3003 Asm->OutStreamer.AddComment("DW_LNS_advance_pc arg count");
3004 Asm->EmitInt8(1);
3005 Asm->OutStreamer.AddComment("DW_LNS_advance_line arg count");
3006 Asm->EmitInt8(1);
3007 Asm->OutStreamer.AddComment("DW_LNS_set_file arg count");
3008 Asm->EmitInt8(1);
3009 Asm->OutStreamer.AddComment("DW_LNS_set_column arg count");
3010 Asm->EmitInt8(1);
3011 Asm->OutStreamer.AddComment("DW_LNS_negate_stmt arg count");
3012 Asm->EmitInt8(0);
3013 Asm->OutStreamer.AddComment("DW_LNS_set_basic_block arg count");
3014 Asm->EmitInt8(0);
3015 Asm->OutStreamer.AddComment("DW_LNS_const_add_pc arg count");
3016 Asm->EmitInt8(0);
3017 Asm->OutStreamer.AddComment("DW_LNS_fixed_advance_pc arg count");
3018 Asm->EmitInt8(1);
Bill Wendling480ff322009-05-20 23:21:38 +00003019
3020 // Emit directories.
3021 for (unsigned DI = 1, DE = getNumSourceDirectories()+1; DI != DE; ++DI) {
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003022 const std::string &Dir = getSourceDirectoryName(DI);
Chris Lattner7bde8c02010-04-04 18:52:31 +00003023 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Directory");
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003024 Asm->OutStreamer.EmitBytes(StringRef(Dir.c_str(), Dir.size()+1), 0);
Bill Wendling480ff322009-05-20 23:21:38 +00003025 }
3026
Chris Lattner566cae92010-03-09 23:52:58 +00003027 Asm->OutStreamer.AddComment("End of directories");
3028 Asm->EmitInt8(0);
Bill Wendling480ff322009-05-20 23:21:38 +00003029
3030 // Emit files.
3031 for (unsigned SI = 1, SE = getNumSourceIds()+1; SI != SE; ++SI) {
3032 // Remember source id starts at 1.
3033 std::pair<unsigned, unsigned> Id = getSourceDirectoryAndFileIds(SI);
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003034 const std::string &FN = getSourceFileName(Id.second);
Chris Lattner7bde8c02010-04-04 18:52:31 +00003035 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("Source");
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003036 Asm->OutStreamer.EmitBytes(StringRef(FN.c_str(), FN.size()+1), 0);
3037
Chris Lattner9efd1182010-04-04 19:09:29 +00003038 Asm->EmitULEB128(Id.first, "Directory #");
3039 Asm->EmitULEB128(0, "Mod date");
3040 Asm->EmitULEB128(0, "File size");
Bill Wendling480ff322009-05-20 23:21:38 +00003041 }
3042
Chris Lattner566cae92010-03-09 23:52:58 +00003043 Asm->OutStreamer.AddComment("End of files");
3044 Asm->EmitInt8(0);
Bill Wendling480ff322009-05-20 23:21:38 +00003045
Chris Lattnera179b522010-04-04 19:25:43 +00003046 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_prolog_end"));
Bill Wendling480ff322009-05-20 23:21:38 +00003047
3048 // A sequence for each text section.
3049 unsigned SecSrcLinesSize = SectionSourceLines.size();
3050
3051 for (unsigned j = 0; j < SecSrcLinesSize; ++j) {
3052 // Isolate current sections line info.
3053 const std::vector<SrcLineInfo> &LineInfos = SectionSourceLines[j];
3054
Bill Wendling480ff322009-05-20 23:21:38 +00003055 // Dwarf assumes we start with first line of first source file.
3056 unsigned Source = 1;
3057 unsigned Line = 1;
3058
3059 // Construct rows of the address, source, line, column matrix.
3060 for (unsigned i = 0, N = LineInfos.size(); i < N; ++i) {
3061 const SrcLineInfo &LineInfo = LineInfos[i];
Chris Lattnerb4666f42010-03-14 08:15:55 +00003062 MCSymbol *Label = LineInfo.getLabel();
Chris Lattneree95d4c2010-03-14 02:20:58 +00003063 if (!Label->isDefined()) continue; // Not emitted, in dead code.
Bill Wendling480ff322009-05-20 23:21:38 +00003064
Chris Lattner3d72a672010-03-09 23:38:23 +00003065 if (Asm->isVerbose()) {
Chris Lattner7e998b72010-03-10 01:04:13 +00003066 std::pair<unsigned, unsigned> SrcID =
Bill Wendling480ff322009-05-20 23:21:38 +00003067 getSourceDirectoryAndFileIds(LineInfo.getSourceID());
Chris Lattner7e998b72010-03-10 01:04:13 +00003068 Asm->OutStreamer.AddComment(Twine(getSourceDirectoryName(SrcID.first)) +
Chris Lattnera26fbe42010-03-10 02:29:31 +00003069 "/" +
3070 Twine(getSourceFileName(SrcID.second)) +
Chris Lattner7e998b72010-03-10 01:04:13 +00003071 ":" + Twine(LineInfo.getLine()));
Bill Wendling480ff322009-05-20 23:21:38 +00003072 }
3073
3074 // Define the line address.
Chris Lattner566cae92010-03-09 23:52:58 +00003075 Asm->OutStreamer.AddComment("Extended Op");
3076 Asm->EmitInt8(0);
3077 Asm->OutStreamer.AddComment("Op size");
Chris Lattner3a383cb2010-04-05 00:13:49 +00003078 Asm->EmitInt8(Asm->getTargetData().getPointerSize() + 1);
Chris Lattner566cae92010-03-09 23:52:58 +00003079
3080 Asm->OutStreamer.AddComment("DW_LNE_set_address");
3081 Asm->EmitInt8(dwarf::DW_LNE_set_address);
3082
3083 Asm->OutStreamer.AddComment("Location label");
Chris Lattner3a383cb2010-04-05 00:13:49 +00003084 Asm->OutStreamer.EmitSymbolValue(Label,
3085 Asm->getTargetData().getPointerSize(),
Chris Lattneree95d4c2010-03-14 02:20:58 +00003086 0/*AddrSpace*/);
Chris Lattnerb245dfb2010-03-10 01:17:49 +00003087
Bill Wendling480ff322009-05-20 23:21:38 +00003088 // If change of source, then switch to the new source.
3089 if (Source != LineInfo.getSourceID()) {
3090 Source = LineInfo.getSourceID();
Chris Lattner566cae92010-03-09 23:52:58 +00003091 Asm->OutStreamer.AddComment("DW_LNS_set_file");
3092 Asm->EmitInt8(dwarf::DW_LNS_set_file);
Chris Lattner9efd1182010-04-04 19:09:29 +00003093 Asm->EmitULEB128(Source, "New Source");
Bill Wendling480ff322009-05-20 23:21:38 +00003094 }
3095
3096 // If change of line.
3097 if (Line != LineInfo.getLine()) {
3098 // Determine offset.
3099 int Offset = LineInfo.getLine() - Line;
3100 int Delta = Offset - MinLineDelta;
3101
3102 // Update line.
3103 Line = LineInfo.getLine();
3104
3105 // If delta is small enough and in range...
3106 if (Delta >= 0 && Delta < (MaxLineDelta - 1)) {
3107 // ... then use fast opcode.
Chris Lattner566cae92010-03-09 23:52:58 +00003108 Asm->OutStreamer.AddComment("Line Delta");
3109 Asm->EmitInt8(Delta - MinLineDelta);
Bill Wendling480ff322009-05-20 23:21:38 +00003110 } else {
3111 // ... otherwise use long hand.
Chris Lattner566cae92010-03-09 23:52:58 +00003112 Asm->OutStreamer.AddComment("DW_LNS_advance_line");
Bill Wendling480ff322009-05-20 23:21:38 +00003113 Asm->EmitInt8(dwarf::DW_LNS_advance_line);
Chris Lattner9efd1182010-04-04 19:09:29 +00003114 Asm->EmitSLEB128(Offset, "Line Offset");
Chris Lattner566cae92010-03-09 23:52:58 +00003115 Asm->OutStreamer.AddComment("DW_LNS_copy");
3116 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling480ff322009-05-20 23:21:38 +00003117 }
3118 } else {
3119 // Copy the previous row (different address or source)
Chris Lattner566cae92010-03-09 23:52:58 +00003120 Asm->OutStreamer.AddComment("DW_LNS_copy");
3121 Asm->EmitInt8(dwarf::DW_LNS_copy);
Bill Wendling480ff322009-05-20 23:21:38 +00003122 }
3123 }
3124
Devang Patel930143b2009-11-21 02:48:08 +00003125 emitEndOfLineMatrix(j + 1);
Bill Wendling480ff322009-05-20 23:21:38 +00003126 }
3127
3128 if (SecSrcLinesSize == 0)
3129 // Because we're emitting a debug_line section, we still need a line
3130 // table. The linker and friends expect it to exist. If there's nothing to
3131 // put into it, emit an empty table.
Devang Patel930143b2009-11-21 02:48:08 +00003132 emitEndOfLineMatrix(1);
Bill Wendling480ff322009-05-20 23:21:38 +00003133
Chris Lattnera179b522010-04-04 19:25:43 +00003134 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("line_end"));
Bill Wendling480ff322009-05-20 23:21:38 +00003135}
3136
Devang Patel930143b2009-11-21 02:48:08 +00003137/// emitCommonDebugFrame - Emit common frame info into a debug frame section.
Bill Wendling480ff322009-05-20 23:21:38 +00003138///
Devang Patel930143b2009-11-21 02:48:08 +00003139void DwarfDebug::emitCommonDebugFrame() {
Chris Lattner3a383cb2010-04-05 00:13:49 +00003140 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling480ff322009-05-20 23:21:38 +00003141 return;
3142
Chris Lattner3a383cb2010-04-05 00:13:49 +00003143 int stackGrowth = Asm->getTargetData().getPointerSize();
3144 if (Asm->TM.getFrameInfo()->getStackGrowthDirection() ==
3145 TargetFrameInfo::StackGrowsDown)
3146 stackGrowth *= -1;
Bill Wendling480ff322009-05-20 23:21:38 +00003147
3148 // Start the dwarf frame section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003149 Asm->OutStreamer.SwitchSection(
3150 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling480ff322009-05-20 23:21:38 +00003151
Chris Lattnera179b522010-04-04 19:25:43 +00003152 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common"));
Chris Lattner566cae92010-03-09 23:52:58 +00003153 Asm->OutStreamer.AddComment("Length of Common Information Entry");
Chris Lattnerf1429f12010-04-04 19:58:12 +00003154 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_frame_common_end"),
3155 Asm->GetTempSymbol("debug_frame_common_begin"), 4);
Bill Wendling480ff322009-05-20 23:21:38 +00003156
Chris Lattnera179b522010-04-04 19:25:43 +00003157 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_begin"));
Chris Lattner566cae92010-03-09 23:52:58 +00003158 Asm->OutStreamer.AddComment("CIE Identifier Tag");
Bill Wendling480ff322009-05-20 23:21:38 +00003159 Asm->EmitInt32((int)dwarf::DW_CIE_ID);
Chris Lattner566cae92010-03-09 23:52:58 +00003160 Asm->OutStreamer.AddComment("CIE Version");
Bill Wendling480ff322009-05-20 23:21:38 +00003161 Asm->EmitInt8(dwarf::DW_CIE_VERSION);
Chris Lattner566cae92010-03-09 23:52:58 +00003162 Asm->OutStreamer.AddComment("CIE Augmentation");
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003163 Asm->OutStreamer.EmitIntValue(0, 1, /*addrspace*/0); // nul terminator.
Chris Lattner9efd1182010-04-04 19:09:29 +00003164 Asm->EmitULEB128(1, "CIE Code Alignment Factor");
3165 Asm->EmitSLEB128(stackGrowth, "CIE Data Alignment Factor");
Chris Lattner566cae92010-03-09 23:52:58 +00003166 Asm->OutStreamer.AddComment("CIE RA Column");
Chris Lattner3a383cb2010-04-05 00:13:49 +00003167 const TargetRegisterInfo *RI = Asm->TM.getRegisterInfo();
Bill Wendling480ff322009-05-20 23:21:38 +00003168 Asm->EmitInt8(RI->getDwarfRegNum(RI->getRARegister(), false));
Bill Wendling480ff322009-05-20 23:21:38 +00003169
3170 std::vector<MachineMove> Moves;
3171 RI->getInitialFrameState(Moves);
3172
Chris Lattneraabc6042010-04-04 23:41:46 +00003173 Asm->EmitFrameMoves(Moves, 0, false);
Bill Wendling480ff322009-05-20 23:21:38 +00003174
Chris Lattner9e06e532010-04-28 01:05:45 +00003175 Asm->EmitAlignment(2);
Chris Lattnera179b522010-04-04 19:25:43 +00003176 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_frame_common_end"));
Bill Wendling480ff322009-05-20 23:21:38 +00003177}
3178
Devang Patel930143b2009-11-21 02:48:08 +00003179/// emitFunctionDebugFrame - Emit per function frame info into a debug frame
Bill Wendling480ff322009-05-20 23:21:38 +00003180/// section.
Chris Lattner2c3f4782010-03-13 07:26:18 +00003181void DwarfDebug::
3182emitFunctionDebugFrame(const FunctionDebugFrameInfo &DebugFrameInfo) {
Chris Lattner3a383cb2010-04-05 00:13:49 +00003183 if (!Asm->MAI->doesDwarfRequireFrameSection())
Bill Wendling480ff322009-05-20 23:21:38 +00003184 return;
3185
3186 // Start the dwarf frame section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003187 Asm->OutStreamer.SwitchSection(
3188 Asm->getObjFileLowering().getDwarfFrameSection());
Bill Wendling480ff322009-05-20 23:21:38 +00003189
Chris Lattner566cae92010-03-09 23:52:58 +00003190 Asm->OutStreamer.AddComment("Length of Frame Information Entry");
Chris Lattner2c3f4782010-03-13 07:26:18 +00003191 MCSymbol *DebugFrameBegin =
Chris Lattnera179b522010-04-04 19:25:43 +00003192 Asm->GetTempSymbol("debug_frame_begin", DebugFrameInfo.Number);
Chris Lattner2c3f4782010-03-13 07:26:18 +00003193 MCSymbol *DebugFrameEnd =
Chris Lattnera179b522010-04-04 19:25:43 +00003194 Asm->GetTempSymbol("debug_frame_end", DebugFrameInfo.Number);
Chris Lattnerf1429f12010-04-04 19:58:12 +00003195 Asm->EmitLabelDifference(DebugFrameEnd, DebugFrameBegin, 4);
Bill Wendling480ff322009-05-20 23:21:38 +00003196
Chris Lattner2c3f4782010-03-13 07:26:18 +00003197 Asm->OutStreamer.EmitLabel(DebugFrameBegin);
Bill Wendling480ff322009-05-20 23:21:38 +00003198
Chris Lattner566cae92010-03-09 23:52:58 +00003199 Asm->OutStreamer.AddComment("FDE CIE offset");
Chris Lattner70a4fce2010-04-04 23:25:33 +00003200 Asm->EmitSectionOffset(Asm->GetTempSymbol("debug_frame_common"),
3201 DwarfFrameSectionSym);
Bill Wendling480ff322009-05-20 23:21:38 +00003202
Chris Lattner566cae92010-03-09 23:52:58 +00003203 Asm->OutStreamer.AddComment("FDE initial location");
Chris Lattnera179b522010-04-04 19:25:43 +00003204 MCSymbol *FuncBeginSym =
3205 Asm->GetTempSymbol("func_begin", DebugFrameInfo.Number);
Chris Lattner8811e122010-03-13 07:40:56 +00003206 Asm->OutStreamer.EmitSymbolValue(FuncBeginSym,
Chris Lattner3a383cb2010-04-05 00:13:49 +00003207 Asm->getTargetData().getPointerSize(),
3208 0/*AddrSpace*/);
Chris Lattnerb245dfb2010-03-10 01:17:49 +00003209
3210
Chris Lattner566cae92010-03-09 23:52:58 +00003211 Asm->OutStreamer.AddComment("FDE address range");
Chris Lattnerf1429f12010-04-04 19:58:12 +00003212 Asm->EmitLabelDifference(Asm->GetTempSymbol("func_end",DebugFrameInfo.Number),
Chris Lattner3a383cb2010-04-05 00:13:49 +00003213 FuncBeginSym, Asm->getTargetData().getPointerSize());
Bill Wendling480ff322009-05-20 23:21:38 +00003214
Chris Lattneraabc6042010-04-04 23:41:46 +00003215 Asm->EmitFrameMoves(DebugFrameInfo.Moves, FuncBeginSym, false);
Bill Wendling480ff322009-05-20 23:21:38 +00003216
Chris Lattner9e06e532010-04-28 01:05:45 +00003217 Asm->EmitAlignment(2);
Chris Lattner2c3f4782010-03-13 07:26:18 +00003218 Asm->OutStreamer.EmitLabel(DebugFrameEnd);
Bill Wendling480ff322009-05-20 23:21:38 +00003219}
3220
Devang Patel9ccfb642009-12-09 18:24:21 +00003221/// emitDebugPubNames - Emit visible names into a debug pubnames section.
3222///
3223void DwarfDebug::emitDebugPubNames() {
Devang Patel1a0df9a2010-05-10 22:49:55 +00003224 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
3225 E = CUMap.end(); I != E; ++I) {
3226 CompileUnit *TheCU = I->second;
3227 // Start the dwarf pubnames section.
3228 Asm->OutStreamer.SwitchSection(
3229 Asm->getObjFileLowering().getDwarfPubNamesSection());
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003230
Devang Patel1a0df9a2010-05-10 22:49:55 +00003231 Asm->OutStreamer.AddComment("Length of Public Names Info");
3232 Asm->EmitLabelDifference(
3233 Asm->GetTempSymbol("pubnames_end", TheCU->getID()),
3234 Asm->GetTempSymbol("pubnames_begin", TheCU->getID()), 4);
3235
3236 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_begin",
3237 TheCU->getID()));
3238
3239 Asm->OutStreamer.AddComment("DWARF Version");
3240 Asm->EmitInt16(dwarf::DWARF_VERSION);
3241
3242 Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
3243 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", TheCU->getID()),
3244 DwarfInfoSectionSym);
3245
3246 Asm->OutStreamer.AddComment("Compilation Unit Length");
3247 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", TheCU->getID()),
3248 Asm->GetTempSymbol("info_begin", TheCU->getID()),
3249 4);
3250
3251 const StringMap<DIE*> &Globals = TheCU->getGlobals();
3252 for (StringMap<DIE*>::const_iterator
3253 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3254 const char *Name = GI->getKeyData();
3255 DIE *Entity = GI->second;
3256
3257 Asm->OutStreamer.AddComment("DIE offset");
3258 Asm->EmitInt32(Entity->getOffset());
3259
3260 if (Asm->isVerbose())
3261 Asm->OutStreamer.AddComment("External Name");
3262 Asm->OutStreamer.EmitBytes(StringRef(Name, strlen(Name)+1), 0);
3263 }
3264
3265 Asm->OutStreamer.AddComment("End Mark");
3266 Asm->EmitInt32(0);
3267 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubnames_end",
3268 TheCU->getID()));
Bill Wendling480ff322009-05-20 23:21:38 +00003269 }
Bill Wendling480ff322009-05-20 23:21:38 +00003270}
3271
Devang Patel04d2f2d2009-11-24 01:14:22 +00003272void DwarfDebug::emitDebugPubTypes() {
Devang Patel1a0df9a2010-05-10 22:49:55 +00003273 for (DenseMap<const MDNode *, CompileUnit *>::iterator I = CUMap.begin(),
3274 E = CUMap.end(); I != E; ++I) {
3275 CompileUnit *TheCU = I->second;
3276 // Start the dwarf pubnames section.
3277 Asm->OutStreamer.SwitchSection(
3278 Asm->getObjFileLowering().getDwarfPubTypesSection());
3279 Asm->OutStreamer.AddComment("Length of Public Types Info");
3280 Asm->EmitLabelDifference(
3281 Asm->GetTempSymbol("pubtypes_end", TheCU->getID()),
3282 Asm->GetTempSymbol("pubtypes_begin", TheCU->getID()), 4);
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003283
Devang Patel1a0df9a2010-05-10 22:49:55 +00003284 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_begin",
3285 TheCU->getID()));
3286
3287 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DWARF Version");
3288 Asm->EmitInt16(dwarf::DWARF_VERSION);
3289
3290 Asm->OutStreamer.AddComment("Offset of Compilation Unit Info");
3291 Asm->EmitSectionOffset(Asm->GetTempSymbol("info_begin", TheCU->getID()),
3292 DwarfInfoSectionSym);
3293
3294 Asm->OutStreamer.AddComment("Compilation Unit Length");
3295 Asm->EmitLabelDifference(Asm->GetTempSymbol("info_end", TheCU->getID()),
3296 Asm->GetTempSymbol("info_begin", TheCU->getID()),
3297 4);
3298
3299 const StringMap<DIE*> &Globals = TheCU->getGlobalTypes();
3300 for (StringMap<DIE*>::const_iterator
3301 GI = Globals.begin(), GE = Globals.end(); GI != GE; ++GI) {
3302 const char *Name = GI->getKeyData();
3303 DIE * Entity = GI->second;
3304
3305 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
3306 Asm->EmitInt32(Entity->getOffset());
3307
3308 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("External Name");
3309 Asm->OutStreamer.EmitBytes(StringRef(Name, GI->getKeyLength()+1), 0);
3310 }
3311
3312 Asm->OutStreamer.AddComment("End Mark");
3313 Asm->EmitInt32(0);
3314 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("pubtypes_end",
3315 TheCU->getID()));
Devang Patel04d2f2d2009-11-24 01:14:22 +00003316 }
Devang Patel04d2f2d2009-11-24 01:14:22 +00003317}
3318
Devang Patel930143b2009-11-21 02:48:08 +00003319/// emitDebugStr - Emit visible names into a debug str section.
Bill Wendling480ff322009-05-20 23:21:38 +00003320///
Devang Patel930143b2009-11-21 02:48:08 +00003321void DwarfDebug::emitDebugStr() {
Bill Wendling480ff322009-05-20 23:21:38 +00003322 // Check to see if it is worth the effort.
Chris Lattner3d72a672010-03-09 23:38:23 +00003323 if (StringPool.empty()) return;
3324
3325 // Start the dwarf str section.
3326 Asm->OutStreamer.SwitchSection(
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003327 Asm->getObjFileLowering().getDwarfStrSection());
Bill Wendling480ff322009-05-20 23:21:38 +00003328
Chris Lattnerb7aa9522010-03-13 02:17:42 +00003329 // Get all of the string pool entries and put them in an array by their ID so
3330 // we can sort them.
3331 SmallVector<std::pair<unsigned,
3332 StringMapEntry<std::pair<MCSymbol*, unsigned> >*>, 64> Entries;
3333
3334 for (StringMap<std::pair<MCSymbol*, unsigned> >::iterator
3335 I = StringPool.begin(), E = StringPool.end(); I != E; ++I)
3336 Entries.push_back(std::make_pair(I->second.second, &*I));
3337
3338 array_pod_sort(Entries.begin(), Entries.end());
3339
3340 for (unsigned i = 0, e = Entries.size(); i != e; ++i) {
Chris Lattner3d72a672010-03-09 23:38:23 +00003341 // Emit a label for reference from debug information entries.
Chris Lattnerb7aa9522010-03-13 02:17:42 +00003342 Asm->OutStreamer.EmitLabel(Entries[i].second->getValue().first);
Chris Lattner3d72a672010-03-09 23:38:23 +00003343
3344 // Emit the string itself.
Chris Lattnerb7aa9522010-03-13 02:17:42 +00003345 Asm->OutStreamer.EmitBytes(Entries[i].second->getKey(), 0/*addrspace*/);
Bill Wendling480ff322009-05-20 23:21:38 +00003346 }
3347}
3348
Devang Patel930143b2009-11-21 02:48:08 +00003349/// emitDebugLoc - Emit visible names into a debug loc section.
Bill Wendling480ff322009-05-20 23:21:38 +00003350///
Devang Patel930143b2009-11-21 02:48:08 +00003351void DwarfDebug::emitDebugLoc() {
Bill Wendling480ff322009-05-20 23:21:38 +00003352 // Start the dwarf loc section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003353 Asm->OutStreamer.SwitchSection(
3354 Asm->getObjFileLowering().getDwarfLocSection());
Bill Wendling480ff322009-05-20 23:21:38 +00003355}
3356
3357/// EmitDebugARanges - Emit visible names into a debug aranges section.
3358///
3359void DwarfDebug::EmitDebugARanges() {
3360 // Start the dwarf aranges section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003361 Asm->OutStreamer.SwitchSection(
3362 Asm->getObjFileLowering().getDwarfARangesSection());
Bill Wendling480ff322009-05-20 23:21:38 +00003363}
3364
Devang Patel930143b2009-11-21 02:48:08 +00003365/// emitDebugRanges - Emit visible names into a debug ranges section.
Bill Wendling480ff322009-05-20 23:21:38 +00003366///
Devang Patel930143b2009-11-21 02:48:08 +00003367void DwarfDebug::emitDebugRanges() {
Bill Wendling480ff322009-05-20 23:21:38 +00003368 // Start the dwarf ranges section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003369 Asm->OutStreamer.SwitchSection(
Devang Patel12563b32010-04-16 23:33:45 +00003370 Asm->getObjFileLowering().getDwarfRangesSection());
Devang Patel6c74a872010-04-27 19:46:33 +00003371 unsigned char Size = Asm->getTargetData().getPointerSize();
3372 for (SmallVector<const MCSymbol *, 8>::iterator
3373 I = DebugRangeSymbols.begin(), E = DebugRangeSymbols.end();
3374 I != E; ++I) {
3375 if (*I)
3376 Asm->OutStreamer.EmitSymbolValue(const_cast<MCSymbol*>(*I), Size, 0);
Devang Patel12563b32010-04-16 23:33:45 +00003377 else
Devang Patel6c74a872010-04-27 19:46:33 +00003378 Asm->OutStreamer.EmitIntValue(0, Size, /*addrspace*/0);
Devang Patel12563b32010-04-16 23:33:45 +00003379 }
Bill Wendling480ff322009-05-20 23:21:38 +00003380}
3381
Devang Patel930143b2009-11-21 02:48:08 +00003382/// emitDebugMacInfo - Emit visible names into a debug macinfo section.
Bill Wendling480ff322009-05-20 23:21:38 +00003383///
Devang Patel930143b2009-11-21 02:48:08 +00003384void DwarfDebug::emitDebugMacInfo() {
Daniel Dunbarc418d6b2009-09-19 20:40:05 +00003385 if (const MCSection *LineInfo =
Chris Lattner1472cf52009-08-02 07:24:22 +00003386 Asm->getObjFileLowering().getDwarfMacroInfoSection()) {
Bill Wendling480ff322009-05-20 23:21:38 +00003387 // Start the dwarf macinfo section.
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003388 Asm->OutStreamer.SwitchSection(LineInfo);
Bill Wendling480ff322009-05-20 23:21:38 +00003389 }
3390}
3391
Devang Patel930143b2009-11-21 02:48:08 +00003392/// emitDebugInlineInfo - Emit inline info using following format.
Bill Wendling480ff322009-05-20 23:21:38 +00003393/// Section Header:
3394/// 1. length of section
3395/// 2. Dwarf version number
3396/// 3. address size.
3397///
3398/// Entries (one "entry" for each function that was inlined):
3399///
3400/// 1. offset into __debug_str section for MIPS linkage name, if exists;
3401/// otherwise offset into __debug_str for regular function name.
3402/// 2. offset into __debug_str section for regular function name.
3403/// 3. an unsigned LEB128 number indicating the number of distinct inlining
3404/// instances for the function.
3405///
3406/// The rest of the entry consists of a {die_offset, low_pc} pair for each
3407/// inlined instance; the die_offset points to the inlined_subroutine die in the
3408/// __debug_info section, and the low_pc is the starting address for the
3409/// inlining instance.
Devang Patel930143b2009-11-21 02:48:08 +00003410void DwarfDebug::emitDebugInlineInfo() {
Chris Lattner3a383cb2010-04-05 00:13:49 +00003411 if (!Asm->MAI->doesDwarfUsesInlineInfoSection())
Bill Wendling480ff322009-05-20 23:21:38 +00003412 return;
3413
Devang Patel1a0df9a2010-05-10 22:49:55 +00003414 if (!FirstCU)
Bill Wendling480ff322009-05-20 23:21:38 +00003415 return;
3416
Chris Lattner4b7dadb2009-08-19 05:49:37 +00003417 Asm->OutStreamer.SwitchSection(
3418 Asm->getObjFileLowering().getDwarfDebugInlineSection());
Chris Lattnerf5c834f2010-01-22 22:09:00 +00003419
Chris Lattner566cae92010-03-09 23:52:58 +00003420 Asm->OutStreamer.AddComment("Length of Debug Inlined Information Entry");
Chris Lattnerf1429f12010-04-04 19:58:12 +00003421 Asm->EmitLabelDifference(Asm->GetTempSymbol("debug_inlined_end", 1),
3422 Asm->GetTempSymbol("debug_inlined_begin", 1), 4);
Bill Wendling480ff322009-05-20 23:21:38 +00003423
Chris Lattnera179b522010-04-04 19:25:43 +00003424 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_begin", 1));
Bill Wendling480ff322009-05-20 23:21:38 +00003425
Chris Lattner566cae92010-03-09 23:52:58 +00003426 Asm->OutStreamer.AddComment("Dwarf Version");
3427 Asm->EmitInt16(dwarf::DWARF_VERSION);
3428 Asm->OutStreamer.AddComment("Address Size (in bytes)");
Chris Lattner3a383cb2010-04-05 00:13:49 +00003429 Asm->EmitInt8(Asm->getTargetData().getPointerSize());
Bill Wendling480ff322009-05-20 23:21:38 +00003430
Devang Patel32cc43c2010-05-07 20:54:48 +00003431 for (SmallVector<const MDNode *, 4>::iterator I = InlinedSPNodes.begin(),
Devang Patelf6eeaeb2009-11-10 23:06:00 +00003432 E = InlinedSPNodes.end(); I != E; ++I) {
Jim Grosbach042483e2009-11-21 23:12:12 +00003433
Devang Patel32cc43c2010-05-07 20:54:48 +00003434 const MDNode *Node = *I;
3435 DenseMap<const MDNode *, SmallVector<InlineInfoLabels, 4> >::iterator II
Jim Grosbach00e9c612009-11-22 19:20:36 +00003436 = InlineInfo.find(Node);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00003437 SmallVector<InlineInfoLabels, 4> &Labels = II->second;
Devang Patel80ae3492009-08-28 23:24:31 +00003438 DISubprogram SP(Node);
Devang Patel2d9caf92009-11-25 17:36:49 +00003439 StringRef LName = SP.getLinkageName();
3440 StringRef Name = SP.getName();
Bill Wendling480ff322009-05-20 23:21:38 +00003441
Chris Lattner566cae92010-03-09 23:52:58 +00003442 Asm->OutStreamer.AddComment("MIPS linkage name");
Chris Lattnerc3f23b82010-01-23 03:11:46 +00003443 if (LName.empty()) {
3444 Asm->OutStreamer.EmitBytes(Name, 0);
3445 Asm->OutStreamer.EmitIntValue(0, 1, 0); // nul terminator.
3446 } else
Chris Lattner70a4fce2010-04-04 23:25:33 +00003447 Asm->EmitSectionOffset(getStringPoolEntry(getRealLinkageName(LName)),
3448 DwarfStrSectionSym);
Devang Patelf6eeaeb2009-11-10 23:06:00 +00003449
Chris Lattner566cae92010-03-09 23:52:58 +00003450 Asm->OutStreamer.AddComment("Function name");
Chris Lattner70a4fce2010-04-04 23:25:33 +00003451 Asm->EmitSectionOffset(getStringPoolEntry(Name), DwarfStrSectionSym);
Chris Lattner9efd1182010-04-04 19:09:29 +00003452 Asm->EmitULEB128(Labels.size(), "Inline count");
Bill Wendling480ff322009-05-20 23:21:38 +00003453
Devang Patelf6eeaeb2009-11-10 23:06:00 +00003454 for (SmallVector<InlineInfoLabels, 4>::iterator LI = Labels.begin(),
Bill Wendling480ff322009-05-20 23:21:38 +00003455 LE = Labels.end(); LI != LE; ++LI) {
Chris Lattner7bde8c02010-04-04 18:52:31 +00003456 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("DIE offset");
Chris Lattner085b6522010-03-09 00:31:02 +00003457 Asm->EmitInt32(LI->second->getOffset());
Bill Wendling480ff322009-05-20 23:21:38 +00003458
Chris Lattner7bde8c02010-04-04 18:52:31 +00003459 if (Asm->isVerbose()) Asm->OutStreamer.AddComment("low_pc");
Chris Lattner3a383cb2010-04-05 00:13:49 +00003460 Asm->OutStreamer.EmitSymbolValue(LI->first,
3461 Asm->getTargetData().getPointerSize(),0);
Bill Wendling480ff322009-05-20 23:21:38 +00003462 }
3463 }
3464
Chris Lattnera179b522010-04-04 19:25:43 +00003465 Asm->OutStreamer.EmitLabel(Asm->GetTempSymbol("debug_inlined_end", 1));
Bill Wendling480ff322009-05-20 23:21:38 +00003466}