Changing model for the construction of debug information.
[oota-llvm.git] / include / llvm / CodeGen / MachineDebugInfo.h
1 //===-- llvm/CodeGen/MachineDebugInfo.h -------------------------*- C++ -*-===//
2 //
3 //                     The LLVM Compiler Infrastructure
4 //
5 // This file was developed by James M. Laskey and is distributed under
6 // the University of Illinois Open Source License. See LICENSE.TXT for details.
7 //
8 //===----------------------------------------------------------------------===//
9 //
10 // Collect debug information for a module.  This information should be in a
11 // neutral form that can be used by different debugging schemes.
12 //
13 // The organization of information is primarily clustered around the source
14 // compile units.  The main exception is source line coorespondence where
15 // inlining may interleave code from various compile units.
16 //
17 // The following information can be retrieved from the MachineDebugInfo.
18 //
19 //  -- Source directories - Directories are uniqued based on their canonical
20 //     string and assigned a sequential numeric ID (base 1.)
21 //  -- Source files - Files are also uniqued based on their name and directory
22 //     ID.  A file ID is sequential number (base 1.)
23 //  -- Source line coorespondence - A vector of file ID, line#, column# triples.
24 //     A DEBUG_LOCATION instruction is generated  by the DAG Legalizer
25 //     corresponding to each entry in the source line list.  This allows a debug
26 //     emitter to generate labels referenced by degug information tables.
27 //
28 //===----------------------------------------------------------------------===//
29
30 #ifndef LLVM_CODEGEN_MACHINEDEBUGINFO_H
31 #define LLVM_CODEGEN_MACHINEDEBUGINFO_H
32
33 #include "llvm/Support/Dwarf.h"
34 #include "llvm/ADT/UniqueVector.h"
35 #include "llvm/Pass.h"
36 #include "llvm/User.h"
37
38 #include <string>
39 #include <set>
40
41 namespace llvm {
42
43 //===----------------------------------------------------------------------===//
44 // Forward declarations.
45 class DebugInfoDesc;
46 class GlobalVariable;
47 class Module;
48 class PointerType;
49 class StructType;
50
51 //===----------------------------------------------------------------------===//
52 // Debug info constants.
53 enum {
54   LLVMDebugVersion = 1,                 // Current version of debug information.
55   DIInvalid = ~0U,                      // Invalid result indicator.
56   
57   // DebugInfoDesc type identifying tags.
58   // FIXME - Change over with gcc4.
59 #if 1
60   DI_TAG_compile_unit = DW_TAG_compile_unit,
61   DI_TAG_global_variable = DW_TAG_variable,
62   DI_TAG_subprogram = DW_TAG_subprogram
63 #else
64   DI_TAG_compile_unit = 1,
65   DI_TAG_global_variable,
66   DI_TAG_subprogram
67 #endif
68 };
69
70 //===----------------------------------------------------------------------===//
71 /// DIApplyManager - Subclasses of this class apply steps to each of the fields
72 /// in the supplied DebugInfoDesc.
73 class DIApplyManager {
74 public:
75   DIApplyManager() {}
76   virtual ~DIApplyManager() {}
77   
78   
79   /// ApplyToFields - Target the manager to each field of the debug information
80   /// descriptor.
81   void ApplyToFields(DebugInfoDesc *DD);
82   
83   /// Apply - Subclasses override each of these methods to perform the
84   /// appropriate action for the type of field.
85   virtual void Apply(int &Field) = 0;
86   virtual void Apply(unsigned &Field) = 0;
87   virtual void Apply(bool &Field) = 0;
88   virtual void Apply(std::string &Field) = 0;
89   virtual void Apply(DebugInfoDesc *&Field) = 0;
90   virtual void Apply(GlobalVariable *&Field) = 0;
91 };
92
93 //===----------------------------------------------------------------------===//
94 /// DebugInfoDesc - This class is the base class for debug info descriptors.
95 ///
96 class DebugInfoDesc {
97 private:
98   unsigned Tag;                         // Content indicator.  Dwarf values are
99                                         // used but that does not limit use to
100                                         // Dwarf writers.
101   
102 protected:
103   DebugInfoDesc(unsigned T) : Tag(T) {}
104   
105 public:
106   virtual ~DebugInfoDesc() {}
107
108   // Accessors
109   unsigned getTag()          const { return Tag; }
110   
111   /// TagFromGlobal - Returns the Tag number from a debug info descriptor
112   /// GlobalVariable.
113   static unsigned TagFromGlobal(GlobalVariable *GV, bool Checking = false);
114
115   /// DescFactory - Create an instance of debug info descriptor based on Tag.
116   /// Return NULL if not a recognized Tag.
117   static DebugInfoDesc *DescFactory(unsigned Tag);
118   
119   //===--------------------------------------------------------------------===//
120   // Subclasses should supply the following static methods.
121   
122   // Implement isa/cast/dyncast.
123   static bool classof(const DebugInfoDesc *)  { return true; }
124   
125   //===--------------------------------------------------------------------===//
126   // Subclasses should supply the following virtual methods.
127   
128   /// ApplyToFields - Target the apply manager to the fields of the descriptor.
129   ///
130   virtual void ApplyToFields(DIApplyManager *Mgr) = 0;
131
132   /// TypeString - Return a string used to compose globalnames and labels.
133   ///
134   virtual const char *TypeString() const = 0;
135   
136 #ifndef NDEBUG
137   virtual void dump() = 0;
138 #endif
139 };
140
141
142 //===----------------------------------------------------------------------===//
143 /// CompileUnitDesc - This class packages debug information associated with a 
144 /// source/header file.
145 class CompileUnitDesc : public DebugInfoDesc {
146 private:  
147   unsigned DebugVersion;                // LLVM debug version when produced.
148   unsigned Language;                    // Language number (ex. DW_LANG_C89.)
149   std::string FileName;                 // Source file name.
150   std::string Directory;                // Source file directory.
151   std::string Producer;                 // Compiler string.
152   GlobalVariable *TransUnit;            // Translation unit - ignored.
153   
154 public:
155   CompileUnitDesc()
156   : DebugInfoDesc(DI_TAG_compile_unit)
157   , DebugVersion(LLVMDebugVersion)
158   , Language(0)
159   , FileName("")
160   , Directory("")
161   , Producer("")
162   , TransUnit(NULL)
163   {}
164   
165   // Accessors
166   unsigned getDebugVersion()              const { return DebugVersion; }
167   unsigned getLanguage()                  const { return Language; }
168   const std::string &getFileName()        const { return FileName; }
169   const std::string &getDirectory()       const { return Directory; }
170   const std::string &getProducer()        const { return Producer; }
171   void setLanguage(unsigned L)                  { Language = L; }
172   void setFileName(const std::string &FN)       { FileName = FN; }
173   void setDirectory(const std::string &D)       { Directory = D; }
174   void setProducer(const std::string &P)        { Producer = P; }
175   // FIXME - Need translation unit getter/setter.
176
177   // Implement isa/cast/dyncast.
178   static bool classof(const CompileUnitDesc *) { return true; }
179   static bool classof(const DebugInfoDesc *D) {
180     return D->getTag() == DI_TAG_compile_unit;
181   }
182   
183   /// DebugVersionFromGlobal - Returns the version number from a compile unit
184   /// GlobalVariable.
185   static unsigned DebugVersionFromGlobal(GlobalVariable *GV,
186                                          bool Checking = false);
187   
188   /// ApplyToFields - Target the apply manager to the fields of the 
189   /// CompileUnitDesc.
190   virtual void ApplyToFields(DIApplyManager *Mgr);
191
192   /// TypeString - Return a string used to compose globalnames and labels.
193   ///
194   virtual const char *TypeString() const;
195     
196 #ifndef NDEBUG
197   virtual void dump();
198 #endif
199 };
200
201 //===----------------------------------------------------------------------===//
202 /// GlobalVariableDesc - This class packages debug information associated with a
203 /// GlobalVariable.
204 class GlobalVariableDesc : public DebugInfoDesc {
205 private:
206   DebugInfoDesc *Context;               // Context debug descriptor.
207   std::string Name;                     // Global name.
208   GlobalVariable *TransUnit;            // Translation unit - ignored.
209   // FIXME - Use a descriptor.
210   GlobalVariable *TyDesc;               // Type debug descriptor.
211   bool IsStatic;                        // Is the global a static.
212   bool IsDefinition;                    // Is the global defined in context.
213   GlobalVariable *Global;               // llvm global.
214   
215 public:
216   GlobalVariableDesc()
217   : DebugInfoDesc(DI_TAG_global_variable)
218   , Context(0)
219   , Name("")
220   , TransUnit(NULL)
221   , TyDesc(NULL)
222   , IsStatic(false)
223   , IsDefinition(false)
224   , Global(NULL)
225   {}
226   
227   // Accessors
228   DebugInfoDesc *getContext()                const { return Context; }
229   const std::string &getName()               const { return Name; }
230   bool isStatic()                            const { return IsStatic; }
231   bool isDefinition()                        const { return IsDefinition; }
232   GlobalVariable *getGlobalVariable()        const { return Global; }
233   void setName(const std::string &N)               { Name = N; }
234   void setIsStatic(bool IS)                        { IsStatic = IS; }
235   void setIsDefinition(bool ID)                    { IsDefinition = ID; }
236   void setGlobalVariable(GlobalVariable *GV)       { Global = GV; }
237   // FIXME - Other getters/setters.
238   
239   // Implement isa/cast/dyncast.
240   static bool classof(const GlobalVariableDesc *)  { return true; }
241   static bool classof(const DebugInfoDesc *D) {
242     return D->getTag() == DI_TAG_global_variable;
243   }
244   
245   /// ApplyToFields - Target the apply manager to the fields of the 
246   /// GlobalVariableDesc.
247   virtual void ApplyToFields(DIApplyManager *Mgr);
248
249   /// TypeString - Return a string used to compose globalnames and labels.
250   ///
251   virtual const char *TypeString() const;
252
253 #ifndef NDEBUG
254   virtual void dump();
255 #endif
256 };
257
258 //===----------------------------------------------------------------------===//
259 /// SubprogramDesc - This class packages debug information associated with a
260 /// subprogram/function.
261 class SubprogramDesc : public DebugInfoDesc {
262 private:
263   DebugInfoDesc *Context;               // Context debug descriptor.
264   std::string Name;                     // Subprogram name.
265   GlobalVariable *TransUnit;            // Translation unit - ignored.
266   // FIXME - Use a descriptor.
267   GlobalVariable *TyDesc;               // Type debug descriptor.
268   bool IsStatic;                        // Is the subprogram a static.
269   bool IsDefinition;                    // Is the subprogram defined in context.
270   
271 public:
272   SubprogramDesc()
273   : DebugInfoDesc(DI_TAG_subprogram)
274   , Context(0)
275   , Name("")
276   , TransUnit(NULL)
277   , TyDesc(NULL)
278   , IsStatic(false)
279   , IsDefinition(false)
280   {}
281   
282   // Accessors
283   DebugInfoDesc *getContext()                const { return Context; }
284   const std::string &getName()               const { return Name; }
285   bool isStatic()                            const { return IsStatic; }
286   bool isDefinition()                        const { return IsDefinition; }
287   void setName(const std::string &N)               { Name = N; }
288   void setIsStatic(bool IS)                        { IsStatic = IS; }
289   void setIsDefinition(bool ID)                    { IsDefinition = ID; }
290   // FIXME - Other getters/setters.
291   
292   // Implement isa/cast/dyncast.
293   static bool classof(const SubprogramDesc *)  { return true; }
294   static bool classof(const DebugInfoDesc *D) {
295     return D->getTag() == DI_TAG_subprogram;
296   }
297   
298   /// ApplyToFields - Target the apply manager to the fields of the 
299   /// SubprogramDesc.
300   virtual void ApplyToFields(DIApplyManager *Mgr);
301
302   /// TypeString - Return a string used to compose globalnames and labels.
303   ///
304   virtual const char *TypeString() const;
305
306 #ifndef NDEBUG
307   virtual void dump();
308 #endif
309 };
310
311 //===----------------------------------------------------------------------===//
312 /// DIDeserializer - This class is responsible for casting GlobalVariables
313 /// into DebugInfoDesc objects.
314 class DIDeserializer {
315 private:
316   Module *M;                            // Definition space module.
317   unsigned DebugVersion;                // Version of debug information in use.
318   std::map<GlobalVariable *, DebugInfoDesc *> GlobalDescs;
319                                         // Previously defined gloabls.
320   
321 public:
322   DIDeserializer() : M(NULL), DebugVersion(LLVMDebugVersion) {}
323   ~DIDeserializer() {}
324   
325   // Accessors
326   Module *getModule()        const { return M; };
327   void setModule(Module *module)   { M = module; }
328   unsigned getDebugVersion() const { return DebugVersion; }
329   
330   /// Deserialize - Reconstitute a GlobalVariable into it's component
331   /// DebugInfoDesc objects.
332   DebugInfoDesc *Deserialize(Value *V);
333   DebugInfoDesc *Deserialize(GlobalVariable *GV);
334 };
335
336 //===----------------------------------------------------------------------===//
337 /// DISerializer - This class is responsible for casting DebugInfoDesc objects
338 /// into GlobalVariables.
339 class DISerializer {
340 private:
341   Module *M;                            // Definition space module.
342   PointerType *StrPtrTy;                // A "sbyte *" type.  Created lazily.
343   PointerType *EmptyStructPtrTy;        // A "{ }*" type.  Created lazily.
344   std::map<unsigned, StructType *> TagTypes;
345                                         // Types per Tag.  Created lazily.
346   std::map<DebugInfoDesc *, GlobalVariable *> DescGlobals;
347                                         // Previously defined descriptors.
348   std::map<const std::string, GlobalVariable*> StringCache;
349                                         // Previously defined strings.
350 public:
351   DISerializer() : M(NULL) {}
352   ~DISerializer() {}
353   
354   // Accessors
355   Module *getModule()        const { return M; };
356   void setModule(Module *module)  { M = module; }
357
358   /// getStrPtrType - Return a "sbyte *" type.
359   ///
360   const PointerType *getStrPtrType();
361   
362   /// getEmptyStructPtrType - Return a "{ }*" type.
363   ///
364   const PointerType *getEmptyStructPtrType();
365   
366   /// getTagType - Return the type describing the specified descriptor (via
367   /// tag.)
368   const StructType *getTagType(DebugInfoDesc *DD);
369   
370   /// getString - Construct the string as constant string global.
371   ///
372   GlobalVariable *getString(const std::string &String);
373   
374   /// Serialize - Recursively cast the specified descriptor into a
375   /// GlobalVariable so that it can be serialized to a .bc or .ll file.
376   GlobalVariable *Serialize(DebugInfoDesc *DD);
377 };
378
379 //===----------------------------------------------------------------------===//
380 /// DIVerifier - This class is responsible for verifying the given network of
381 /// GlobalVariables are valid as DebugInfoDesc objects.
382 class DIVerifier {
383 private:
384   unsigned DebugVersion;                // Version of debug information in use.
385   std::set<GlobalVariable *> Visited;   // Tracks visits during recursion.
386   std::map<unsigned, unsigned> Counts;  // Count of fields per Tag type.
387
388   /// markVisited - Return true if the GlobalVariable hase been "seen" before.
389   /// Mark markVisited otherwise.
390   bool markVisited(GlobalVariable *GV);
391   
392 public:
393   DIVerifier() : DebugVersion(LLVMDebugVersion) {}
394   ~DIVerifier() {}
395   
396   /// Verify - Return true if the GlobalVariable appears to be a valid
397   /// serialization of a DebugInfoDesc.
398   bool Verify(GlobalVariable *GV);
399 };
400
401 //===----------------------------------------------------------------------===//
402 /// SourceLineInfo - This class is used to record source line correspondence.
403 ///
404 class SourceLineInfo {
405 private:
406   unsigned Line;                        // Source line number.
407   unsigned Column;                      // Source column.
408   unsigned SourceID;                    // Source ID number.
409
410 public:
411   SourceLineInfo(unsigned L, unsigned C, unsigned S)
412   : Line(L), Column(C), SourceID(S) {}
413   
414   // Accessors
415   unsigned getLine()     const { return Line; }
416   unsigned getColumn()   const { return Column; }
417   unsigned getSourceID() const { return SourceID; }
418 };
419
420 //===----------------------------------------------------------------------===//
421 /// SourceFileInfo - This class is used to track source information.
422 ///
423 class SourceFileInfo {
424 private:
425   unsigned DirectoryID;                 // Directory ID number.
426   std::string Name;                     // File name (not including directory.)
427   
428 public:
429   SourceFileInfo(unsigned D, const std::string &N) : DirectoryID(D), Name(N) {}
430             
431   // Accessors
432   unsigned getDirectoryID()    const { return DirectoryID; }
433   const std::string &getName() const { return Name; }
434
435   /// operator== - Used by UniqueVector to locate entry.
436   ///
437   bool operator==(const SourceFileInfo &SI) const {
438     return getDirectoryID() == SI.getDirectoryID() && getName() == SI.getName();
439   }
440
441   /// operator< - Used by UniqueVector to locate entry.
442   ///
443   bool operator<(const SourceFileInfo &SI) const {
444     return getDirectoryID() < SI.getDirectoryID() ||
445           (getDirectoryID() == SI.getDirectoryID() && getName() < SI.getName());
446   }
447 };
448
449 //===----------------------------------------------------------------------===//
450 /// MachineDebugInfo - This class contains debug information specific to a
451 /// module.  Queries can be made by different debugging schemes and reformated
452 /// for specific use.
453 ///
454 class MachineDebugInfo : public ImmutablePass {
455 private:
456   // Debug indforma
457   // Use the same serializer/deserializer/verifier for the module.
458   DISerializer SR;
459   DIDeserializer DR;
460   DIVerifier VR;
461
462   // CompileUnits - Uniquing vector for compile units.
463   UniqueVector<CompileUnitDesc *> CompileUnits;
464   
465   // Directories - Uniquing vector for directories.
466   UniqueVector<std::string> Directories;
467                                          
468   // SourceFiles - Uniquing vector for source files.
469   UniqueVector<SourceFileInfo> SourceFiles;
470
471   // Lines - List of of source line correspondence.
472   std::vector<SourceLineInfo *> Lines;
473
474 public:
475   MachineDebugInfo();
476   ~MachineDebugInfo();
477   
478   /// doInitialization - Initialize the debug state for a new module.
479   ///
480   bool doInitialization();
481   
482   /// doFinalization - Tear down the debug state after completion of a module.
483   ///
484   bool doFinalization();
485   
486   /// AnalyzeModule - Scan the module for global debug information.
487   ///
488   void AnalyzeModule(Module &M);
489   
490   /// hasInfo - Returns true if valid debug info is present.
491   ///
492   bool hasInfo() const { return !CompileUnits.empty(); }
493   
494   /// RecordLabel - Records location information and associates it with a
495   /// debug label.  Returns a unique label ID used to generate a label and 
496   /// provide correspondence to the source line list.
497   unsigned RecordLabel(unsigned Line, unsigned Column, unsigned Source) {
498     Lines.push_back(new SourceLineInfo(Line, Column, Source));
499     return Lines.size();
500   }
501   
502   /// RecordSource - Register a source file with debug info. Returns an source
503   /// ID.
504   unsigned RecordSource(const std::string &Directory,
505                                const std::string &Source) {
506     unsigned DirectoryID = Directories.insert(Directory);
507     return SourceFiles.insert(SourceFileInfo(DirectoryID, Source));
508   }
509   
510   /// getDirectories - Return the UniqueVector of std::string representing
511   /// directories.
512   const UniqueVector<std::string> &getDirectories() const {
513     return Directories;
514   }
515   
516   /// getSourceFiles - Return the UniqueVector of source files. 
517   ///
518   const UniqueVector<SourceFileInfo> &getSourceFiles() const {
519     return SourceFiles;
520   }
521   
522   /// getSourceLines - Return a vector of source lines.  Vector index + 1
523   /// equals label ID.
524   const std::vector<SourceLineInfo *> &getSourceLines() const {
525     return Lines;
526   }
527   
528   /// SetupCompileUnits - Set up the unique vector of compile units.
529   ///
530   void SetupCompileUnits(Module &M);
531
532   /// getCompileUnits - Return a vector of debug compile units.
533   ///
534   const UniqueVector<CompileUnitDesc *> getCompileUnits() const;
535
536   /// getGlobalVariables - Return a vector of debug GlobalVariables.
537   ///
538   std::vector<GlobalVariableDesc *> getGlobalVariables(Module &M);
539
540 }; // End class MachineDebugInfo
541
542 } // End llvm namespace
543
544 #endif