1239310Sdim//===--- llvm/Analysis/DebugInfo.h - Debug Information Helpers --*- C++ -*-===//
2239310Sdim//
3239310Sdim//                     The LLVM Compiler Infrastructure
4239310Sdim//
5239310Sdim// This file is distributed under the University of Illinois Open Source
6239310Sdim// License. See LICENSE.TXT for details.
7239310Sdim//
8239310Sdim//===----------------------------------------------------------------------===//
9239310Sdim//
10239310Sdim// This file defines a bunch of datatypes that are useful for creating and
11239310Sdim// walking debug info in LLVM IR form. They essentially provide wrappers around
12239310Sdim// the information in the global variables that's needed when constructing the
13239310Sdim// DWARF information.
14239310Sdim//
15239310Sdim//===----------------------------------------------------------------------===//
16239310Sdim
17252723Sdim#ifndef LLVM_DEBUGINFO_H
18252723Sdim#define LLVM_DEBUGINFO_H
19239310Sdim
20263509Sdim#include "llvm/Support/Casting.h"
21263509Sdim#include "llvm/ADT/DenseMap.h"
22252723Sdim#include "llvm/ADT/SmallPtrSet.h"
23239310Sdim#include "llvm/ADT/SmallVector.h"
24239310Sdim#include "llvm/ADT/StringRef.h"
25263509Sdim#include "llvm/IR/Metadata.h"
26239310Sdim#include "llvm/Support/Dwarf.h"
27239310Sdim
28239310Sdimnamespace llvm {
29263509Sdimclass BasicBlock;
30263509Sdimclass Constant;
31263509Sdimclass Function;
32263509Sdimclass GlobalVariable;
33263509Sdimclass Module;
34263509Sdimclass Type;
35263509Sdimclass Value;
36263509Sdimclass DbgDeclareInst;
37263509Sdimclass DbgValueInst;
38263509Sdimclass Instruction;
39263509Sdimclass MDNode;
40263509Sdimclass MDString;
41263509Sdimclass NamedMDNode;
42263509Sdimclass LLVMContext;
43263509Sdimclass raw_ostream;
44239310Sdim
45263509Sdimclass DIFile;
46263509Sdimclass DISubprogram;
47263509Sdimclass DILexicalBlock;
48263509Sdimclass DILexicalBlockFile;
49263509Sdimclass DIVariable;
50263509Sdimclass DIType;
51263509Sdimclass DIScope;
52263509Sdimclass DIObjCProperty;
53239310Sdim
54263509Sdim/// Maps from type identifier to the actual MDNode.
55263509Sdimtypedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap;
56239310Sdim
57263509Sdim/// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
58263509Sdim/// This should not be stored in a container, because the underlying MDNode
59263509Sdim/// may change in certain situations.
60263509Sdimclass DIDescriptor {
61263509Sdim  // Befriends DIRef so DIRef can befriend the protected member
62263509Sdim  // function: getFieldAs<DIRef>.
63263509Sdim  template <typename T> friend class DIRef;
64239310Sdim
65263509Sdimpublic:
66263509Sdim  enum {
67263509Sdim    FlagPrivate = 1 << 0,
68263509Sdim    FlagProtected = 1 << 1,
69263509Sdim    FlagFwdDecl = 1 << 2,
70263509Sdim    FlagAppleBlock = 1 << 3,
71263509Sdim    FlagBlockByrefStruct = 1 << 4,
72263509Sdim    FlagVirtual = 1 << 5,
73263509Sdim    FlagArtificial = 1 << 6,
74263509Sdim    FlagExplicit = 1 << 7,
75263509Sdim    FlagPrototyped = 1 << 8,
76263509Sdim    FlagObjcClassComplete = 1 << 9,
77263509Sdim    FlagObjectPointer = 1 << 10,
78263509Sdim    FlagVector = 1 << 11,
79263509Sdim    FlagStaticMember = 1 << 12,
80263509Sdim    FlagIndirectVariable = 1 << 13
81263509Sdim  };
82239310Sdim
83263509Sdimprotected:
84263509Sdim  const MDNode *DbgNode;
85239310Sdim
86263509Sdim  StringRef getStringField(unsigned Elt) const;
87263509Sdim  unsigned getUnsignedField(unsigned Elt) const {
88263509Sdim    return (unsigned)getUInt64Field(Elt);
89263509Sdim  }
90263509Sdim  uint64_t getUInt64Field(unsigned Elt) const;
91263509Sdim  int64_t getInt64Field(unsigned Elt) const;
92263509Sdim  DIDescriptor getDescriptorField(unsigned Elt) const;
93239310Sdim
94263509Sdim  template <typename DescTy> DescTy getFieldAs(unsigned Elt) const {
95263509Sdim    return DescTy(getDescriptorField(Elt));
96263509Sdim  }
97239310Sdim
98263509Sdim  GlobalVariable *getGlobalVariableField(unsigned Elt) const;
99263509Sdim  Constant *getConstantField(unsigned Elt) const;
100263509Sdim  Function *getFunctionField(unsigned Elt) const;
101263509Sdim  void replaceFunctionField(unsigned Elt, Function *F);
102239310Sdim
103263509Sdimpublic:
104263509Sdim  explicit DIDescriptor(const MDNode *N = 0) : DbgNode(N) {}
105239310Sdim
106263509Sdim  bool Verify() const;
107239310Sdim
108263509Sdim  operator MDNode *() const { return const_cast<MDNode *>(DbgNode); }
109263509Sdim  MDNode *operator->() const { return const_cast<MDNode *>(DbgNode); }
110239310Sdim
111263509Sdim  // An explicit operator bool so that we can do testing of DI values
112263509Sdim  // easily.
113263509Sdim  // FIXME: This operator bool isn't actually protecting anything at the
114263509Sdim  // moment due to the conversion operator above making DIDescriptor nodes
115263509Sdim  // implicitly convertable to bool.
116263509Sdim  LLVM_EXPLICIT operator bool() const { return DbgNode != 0; }
117239310Sdim
118263509Sdim  bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; }
119263509Sdim  bool operator!=(DIDescriptor Other) const { return !operator==(Other); }
120239310Sdim
121263509Sdim  uint16_t getTag() const {
122263509Sdim    return getUnsignedField(0) & ~LLVMDebugVersionMask;
123263509Sdim  }
124239310Sdim
125263509Sdim  bool isDerivedType() const;
126263509Sdim  bool isCompositeType() const;
127263509Sdim  bool isBasicType() const;
128263509Sdim  bool isVariable() const;
129263509Sdim  bool isSubprogram() const;
130263509Sdim  bool isGlobalVariable() const;
131263509Sdim  bool isScope() const;
132263509Sdim  bool isFile() const;
133263509Sdim  bool isCompileUnit() const;
134263509Sdim  bool isNameSpace() const;
135263509Sdim  bool isLexicalBlockFile() const;
136263509Sdim  bool isLexicalBlock() const;
137263509Sdim  bool isSubrange() const;
138263509Sdim  bool isEnumerator() const;
139263509Sdim  bool isType() const;
140263509Sdim  bool isUnspecifiedParameter() const;
141263509Sdim  bool isTemplateTypeParameter() const;
142263509Sdim  bool isTemplateValueParameter() const;
143263509Sdim  bool isObjCProperty() const;
144263509Sdim  bool isImportedEntity() const;
145239310Sdim
146263509Sdim  /// print - print descriptor.
147263509Sdim  void print(raw_ostream &OS) const;
148239310Sdim
149263509Sdim  /// dump - print descriptor to dbgs() with a newline.
150263509Sdim  void dump() const;
151263509Sdim};
152239310Sdim
153263509Sdim/// DISubrange - This is used to represent ranges, for array bounds.
154263509Sdimclass DISubrange : public DIDescriptor {
155263509Sdim  friend class DIDescriptor;
156263509Sdim  void printInternal(raw_ostream &OS) const;
157239310Sdim
158263509Sdimpublic:
159263509Sdim  explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
160252723Sdim
161263509Sdim  int64_t getLo() const { return getInt64Field(1); }
162263509Sdim  int64_t getCount() const { return getInt64Field(2); }
163263509Sdim  bool Verify() const;
164263509Sdim};
165239310Sdim
166263509Sdim/// DIArray - This descriptor holds an array of descriptors.
167263509Sdimclass DIArray : public DIDescriptor {
168263509Sdimpublic:
169263509Sdim  explicit DIArray(const MDNode *N = 0) : DIDescriptor(N) {}
170239310Sdim
171263509Sdim  unsigned getNumElements() const;
172263509Sdim  DIDescriptor getElement(unsigned Idx) const {
173263509Sdim    return getDescriptorField(Idx);
174263509Sdim  }
175263509Sdim};
176239310Sdim
177263509Sdim/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
178263509Sdim/// FIXME: it seems strange that this doesn't have either a reference to the
179263509Sdim/// type/precision or a file/line pair for location info.
180263509Sdimclass DIEnumerator : public DIDescriptor {
181263509Sdim  friend class DIDescriptor;
182263509Sdim  void printInternal(raw_ostream &OS) const;
183239310Sdim
184263509Sdimpublic:
185263509Sdim  explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
186252723Sdim
187263509Sdim  StringRef getName() const { return getStringField(1); }
188263509Sdim  int64_t getEnumValue() const { return getInt64Field(2); }
189263509Sdim  bool Verify() const;
190263509Sdim};
191239310Sdim
192263509Sdimtemplate <typename T> class DIRef;
193263509Sdimtypedef DIRef<DIScope> DIScopeRef;
194263509Sdimtypedef DIRef<DIType> DITypeRef;
195239310Sdim
196263509Sdim/// DIScope - A base class for various scopes.
197263509Sdimclass DIScope : public DIDescriptor {
198263509Sdimprotected:
199263509Sdim  friend class DIDescriptor;
200263509Sdim  void printInternal(raw_ostream &OS) const;
201239310Sdim
202263509Sdimpublic:
203263509Sdim  explicit DIScope(const MDNode *N = 0) : DIDescriptor(N) {}
204239310Sdim
205263509Sdim  /// Gets the parent scope for this scope node or returns a
206263509Sdim  /// default constructed scope.
207263509Sdim  DIScopeRef getContext() const;
208263509Sdim  /// If the scope node has a name, return that, else return an empty string.
209263509Sdim  StringRef getName() const;
210263509Sdim  StringRef getFilename() const;
211263509Sdim  StringRef getDirectory() const;
212239310Sdim
213263509Sdim  /// Generate a reference to this DIScope. Uses the type identifier instead
214263509Sdim  /// of the actual MDNode if possible, to help type uniquing.
215263509Sdim  DIScopeRef getRef() const;
216263509Sdim};
217239310Sdim
218263509Sdim/// Represents reference to a DIDescriptor, abstracts over direct and
219263509Sdim/// identifier-based metadata references.
220263509Sdimtemplate <typename T> class DIRef {
221263509Sdim  template <typename DescTy>
222263509Sdim  friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
223263509Sdim  friend DIScopeRef DIScope::getContext() const;
224263509Sdim  friend DIScopeRef DIScope::getRef() const;
225239310Sdim
226263509Sdim  /// Val can be either a MDNode or a MDString, in the latter,
227263509Sdim  /// MDString specifies the type identifier.
228263509Sdim  const Value *Val;
229263509Sdim  explicit DIRef(const Value *V);
230239310Sdim
231263509Sdimpublic:
232263509Sdim  T resolve(const DITypeIdentifierMap &Map) const;
233263509Sdim  StringRef getName() const;
234263509Sdim  operator Value *() const { return const_cast<Value *>(Val); }
235263509Sdim};
236239310Sdim
237263509Sdimtemplate <typename T>
238263509SdimT DIRef<T>::resolve(const DITypeIdentifierMap &Map) const {
239263509Sdim  if (!Val)
240263509Sdim    return T();
241239310Sdim
242263509Sdim  if (const MDNode *MD = dyn_cast<MDNode>(Val))
243263509Sdim    return T(MD);
244239310Sdim
245263509Sdim  const MDString *MS = cast<MDString>(Val);
246263509Sdim  // Find the corresponding MDNode.
247263509Sdim  DITypeIdentifierMap::const_iterator Iter = Map.find(MS);
248263509Sdim  assert(Iter != Map.end() && "Identifier not in the type map?");
249263509Sdim  assert(DIDescriptor(Iter->second).isType() &&
250263509Sdim         "MDNode in DITypeIdentifierMap should be a DIType.");
251263509Sdim  return T(Iter->second);
252263509Sdim}
253239310Sdim
254263509Sdimtemplate <typename T> StringRef DIRef<T>::getName() const {
255263509Sdim  if (!Val)
256263509Sdim    return StringRef();
257239310Sdim
258263509Sdim  if (const MDNode *MD = dyn_cast<MDNode>(Val))
259263509Sdim    return T(MD).getName();
260239310Sdim
261263509Sdim  const MDString *MS = cast<MDString>(Val);
262263509Sdim  return MS->getString();
263263509Sdim}
264252723Sdim
265263509Sdim/// Specialize getFieldAs to handle fields that are references to DIScopes.
266263509Sdimtemplate <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
267263509Sdim/// Specialize DIRef constructor for DIScopeRef.
268263509Sdimtemplate <> DIRef<DIScope>::DIRef(const Value *V);
269239310Sdim
270263509Sdim/// Specialize getFieldAs to handle fields that are references to DITypes.
271263509Sdimtemplate <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
272263509Sdim/// Specialize DIRef constructor for DITypeRef.
273263509Sdimtemplate <> DIRef<DIType>::DIRef(const Value *V);
274239310Sdim
275263509Sdim/// DIType - This is a wrapper for a type.
276263509Sdim/// FIXME: Types should be factored much better so that CV qualifiers and
277263509Sdim/// others do not require a huge and empty descriptor full of zeros.
278263509Sdimclass DIType : public DIScope {
279263509Sdimprotected:
280263509Sdim  friend class DIDescriptor;
281263509Sdim  void printInternal(raw_ostream &OS) const;
282239310Sdim
283263509Sdimpublic:
284263509Sdim  explicit DIType(const MDNode *N = 0) : DIScope(N) {}
285239310Sdim
286263509Sdim  /// Verify - Verify that a type descriptor is well formed.
287263509Sdim  bool Verify() const;
288239310Sdim
289263509Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
290263509Sdim  StringRef getName() const { return getStringField(3); }
291263509Sdim  unsigned getLineNumber() const { return getUnsignedField(4); }
292263509Sdim  uint64_t getSizeInBits() const { return getUInt64Field(5); }
293263509Sdim  uint64_t getAlignInBits() const { return getUInt64Field(6); }
294263509Sdim  // FIXME: Offset is only used for DW_TAG_member nodes.  Making every type
295263509Sdim  // carry this is just plain insane.
296263509Sdim  uint64_t getOffsetInBits() const { return getUInt64Field(7); }
297263509Sdim  unsigned getFlags() const { return getUnsignedField(8); }
298263509Sdim  bool isPrivate() const { return (getFlags() & FlagPrivate) != 0; }
299263509Sdim  bool isProtected() const { return (getFlags() & FlagProtected) != 0; }
300263509Sdim  bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; }
301263509Sdim  // isAppleBlock - Return true if this is the Apple Blocks extension.
302263509Sdim  bool isAppleBlockExtension() const {
303263509Sdim    return (getFlags() & FlagAppleBlock) != 0;
304263509Sdim  }
305263509Sdim  bool isBlockByrefStruct() const {
306263509Sdim    return (getFlags() & FlagBlockByrefStruct) != 0;
307263509Sdim  }
308263509Sdim  bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; }
309263509Sdim  bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
310263509Sdim  bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; }
311263509Sdim  bool isObjcClassComplete() const {
312263509Sdim    return (getFlags() & FlagObjcClassComplete) != 0;
313263509Sdim  }
314263509Sdim  bool isVector() const { return (getFlags() & FlagVector) != 0; }
315263509Sdim  bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
316263509Sdim  bool isValid() const { return DbgNode && isType(); }
317239310Sdim
318263509Sdim  /// replaceAllUsesWith - Replace all uses of debug info referenced by
319263509Sdim  /// this descriptor.
320263509Sdim  void replaceAllUsesWith(DIDescriptor &D);
321263509Sdim  void replaceAllUsesWith(MDNode *D);
322263509Sdim};
323239310Sdim
324263509Sdim/// DIBasicType - A basic type, like 'int' or 'float'.
325263509Sdimclass DIBasicType : public DIType {
326263509Sdimpublic:
327263509Sdim  explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
328239310Sdim
329263509Sdim  unsigned getEncoding() const { return getUnsignedField(9); }
330239310Sdim
331263509Sdim  /// Verify - Verify that a basic type descriptor is well formed.
332263509Sdim  bool Verify() const;
333263509Sdim};
334239310Sdim
335263509Sdim/// DIDerivedType - A simple derived type, like a const qualified type,
336263509Sdim/// a typedef, a pointer or reference, et cetera.  Or, a data member of
337263509Sdim/// a class/struct/union.
338263509Sdimclass DIDerivedType : public DIType {
339263509Sdim  friend class DIDescriptor;
340263509Sdim  void printInternal(raw_ostream &OS) const;
341239310Sdim
342263509Sdimpublic:
343263509Sdim  explicit DIDerivedType(const MDNode *N = 0) : DIType(N) {}
344239310Sdim
345263509Sdim  DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(9); }
346239310Sdim
347263509Sdim  /// getObjCProperty - Return property node, if this ivar is
348263509Sdim  /// associated with one.
349263509Sdim  MDNode *getObjCProperty() const;
350239310Sdim
351263509Sdim  DITypeRef getClassType() const {
352263509Sdim    assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
353263509Sdim    return getFieldAs<DITypeRef>(10);
354263509Sdim  }
355239310Sdim
356263509Sdim  Constant *getConstant() const {
357263509Sdim    assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
358263509Sdim    return getConstantField(10);
359263509Sdim  }
360252723Sdim
361263509Sdim  /// Verify - Verify that a derived type descriptor is well formed.
362263509Sdim  bool Verify() const;
363263509Sdim};
364239310Sdim
365263509Sdim/// DICompositeType - This descriptor holds a type that can refer to multiple
366263509Sdim/// other types, like a function or struct.
367263509Sdim/// DICompositeType is derived from DIDerivedType because some
368263509Sdim/// composite types (such as enums) can be derived from basic types
369263509Sdim// FIXME: Make this derive from DIType directly & just store the
370263509Sdim// base type in a single DIType field.
371263509Sdimclass DICompositeType : public DIDerivedType {
372263509Sdim  friend class DIDescriptor;
373263509Sdim  void printInternal(raw_ostream &OS) const;
374239310Sdim
375263509Sdimpublic:
376263509Sdim  explicit DICompositeType(const MDNode *N = 0) : DIDerivedType(N) {}
377239310Sdim
378263509Sdim  DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
379263509Sdim  void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
380263509Sdim  void addMember(DIDescriptor D);
381263509Sdim  unsigned getRunTimeLang() const { return getUnsignedField(11); }
382263509Sdim  DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
383263509Sdim  void setContainingType(DICompositeType ContainingType);
384263509Sdim  DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
385263509Sdim  MDString *getIdentifier() const;
386239310Sdim
387263509Sdim  /// Verify - Verify that a composite type descriptor is well formed.
388263509Sdim  bool Verify() const;
389263509Sdim};
390239310Sdim
391263509Sdim/// DIFile - This is a wrapper for a file.
392263509Sdimclass DIFile : public DIScope {
393263509Sdim  friend class DIDescriptor;
394239310Sdim
395263509Sdimpublic:
396263509Sdim  explicit DIFile(const MDNode *N = 0) : DIScope(N) {}
397263509Sdim  MDNode *getFileNode() const;
398263509Sdim  bool Verify() const;
399263509Sdim};
400239310Sdim
401263509Sdim/// DICompileUnit - A wrapper for a compile unit.
402263509Sdimclass DICompileUnit : public DIScope {
403263509Sdim  friend class DIDescriptor;
404263509Sdim  void printInternal(raw_ostream &OS) const;
405239310Sdim
406263509Sdimpublic:
407263509Sdim  explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
408239310Sdim
409263509Sdim  unsigned getLanguage() const { return getUnsignedField(2); }
410263509Sdim  StringRef getProducer() const { return getStringField(3); }
411239310Sdim
412263509Sdim  bool isOptimized() const { return getUnsignedField(4) != 0; }
413263509Sdim  StringRef getFlags() const { return getStringField(5); }
414263509Sdim  unsigned getRunTimeVersion() const { return getUnsignedField(6); }
415239310Sdim
416263509Sdim  DIArray getEnumTypes() const;
417263509Sdim  DIArray getRetainedTypes() const;
418263509Sdim  DIArray getSubprograms() const;
419263509Sdim  DIArray getGlobalVariables() const;
420263509Sdim  DIArray getImportedEntities() const;
421239310Sdim
422263509Sdim  StringRef getSplitDebugFilename() const { return getStringField(12); }
423239310Sdim
424263509Sdim  /// Verify - Verify that a compile unit is well formed.
425263509Sdim  bool Verify() const;
426263509Sdim};
427252723Sdim
428263509Sdim/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
429263509Sdimclass DISubprogram : public DIScope {
430263509Sdim  friend class DIDescriptor;
431263509Sdim  void printInternal(raw_ostream &OS) const;
432239310Sdim
433263509Sdimpublic:
434263509Sdim  explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
435245431Sdim
436263509Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
437263509Sdim  StringRef getName() const { return getStringField(3); }
438263509Sdim  StringRef getDisplayName() const { return getStringField(4); }
439263509Sdim  StringRef getLinkageName() const { return getStringField(5); }
440263509Sdim  unsigned getLineNumber() const { return getUnsignedField(6); }
441263509Sdim  DICompositeType getType() const { return getFieldAs<DICompositeType>(7); }
442239310Sdim
443263509Sdim  /// isLocalToUnit - Return true if this subprogram is local to the current
444263509Sdim  /// compile unit, like 'static' in C.
445263509Sdim  unsigned isLocalToUnit() const { return getUnsignedField(8); }
446263509Sdim  unsigned isDefinition() const { return getUnsignedField(9); }
447239310Sdim
448263509Sdim  unsigned getVirtuality() const { return getUnsignedField(10); }
449263509Sdim  unsigned getVirtualIndex() const { return getUnsignedField(11); }
450239310Sdim
451263509Sdim  DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
452252723Sdim
453263509Sdim  unsigned getFlags() const { return getUnsignedField(13); }
454239310Sdim
455263509Sdim  unsigned isArtificial() const {
456263509Sdim    return (getUnsignedField(13) & FlagArtificial) != 0;
457263509Sdim  }
458263509Sdim  /// isPrivate - Return true if this subprogram has "private"
459263509Sdim  /// access specifier.
460263509Sdim  bool isPrivate() const { return (getUnsignedField(13) & FlagPrivate) != 0; }
461263509Sdim  /// isProtected - Return true if this subprogram has "protected"
462263509Sdim  /// access specifier.
463263509Sdim  bool isProtected() const {
464263509Sdim    return (getUnsignedField(13) & FlagProtected) != 0;
465263509Sdim  }
466263509Sdim  /// isExplicit - Return true if this subprogram is marked as explicit.
467263509Sdim  bool isExplicit() const { return (getUnsignedField(13) & FlagExplicit) != 0; }
468263509Sdim  /// isPrototyped - Return true if this subprogram is prototyped.
469263509Sdim  bool isPrototyped() const {
470263509Sdim    return (getUnsignedField(13) & FlagPrototyped) != 0;
471263509Sdim  }
472239310Sdim
473263509Sdim  unsigned isOptimized() const;
474239310Sdim
475263509Sdim  /// Verify - Verify that a subprogram descriptor is well formed.
476263509Sdim  bool Verify() const;
477239310Sdim
478263509Sdim  /// describes - Return true if this subprogram provides debugging
479263509Sdim  /// information for the function F.
480263509Sdim  bool describes(const Function *F);
481239310Sdim
482263509Sdim  Function *getFunction() const { return getFunctionField(15); }
483263509Sdim  void replaceFunction(Function *F) { replaceFunctionField(15, F); }
484263509Sdim  DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); }
485263509Sdim  DISubprogram getFunctionDeclaration() const {
486263509Sdim    return getFieldAs<DISubprogram>(17);
487263509Sdim  }
488263509Sdim  MDNode *getVariablesNodes() const;
489263509Sdim  DIArray getVariables() const;
490239310Sdim
491263509Sdim  /// getScopeLineNumber - Get the beginning of the scope of the
492263509Sdim  /// function, not necessarily where the name of the program
493263509Sdim  /// starts.
494263509Sdim  unsigned getScopeLineNumber() const { return getUnsignedField(19); }
495263509Sdim};
496239310Sdim
497263509Sdim/// DILexicalBlock - This is a wrapper for a lexical block.
498263509Sdimclass DILexicalBlock : public DIScope {
499263509Sdimpublic:
500263509Sdim  explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
501263509Sdim  DIScope getContext() const { return getFieldAs<DIScope>(2); }
502263509Sdim  unsigned getLineNumber() const { return getUnsignedField(3); }
503263509Sdim  unsigned getColumnNumber() const { return getUnsignedField(4); }
504263509Sdim  bool Verify() const;
505263509Sdim};
506239310Sdim
507263509Sdim/// DILexicalBlockFile - This is a wrapper for a lexical block with
508263509Sdim/// a filename change.
509263509Sdimclass DILexicalBlockFile : public DIScope {
510263509Sdimpublic:
511263509Sdim  explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
512263509Sdim  DIScope getContext() const {
513263509Sdim    if (getScope().isSubprogram())
514263509Sdim      return getScope();
515263509Sdim    return getScope().getContext();
516263509Sdim  }
517263509Sdim  unsigned getLineNumber() const { return getScope().getLineNumber(); }
518263509Sdim  unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
519263509Sdim  DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
520263509Sdim  bool Verify() const;
521263509Sdim};
522239310Sdim
523263509Sdim/// DINameSpace - A wrapper for a C++ style name space.
524263509Sdimclass DINameSpace : public DIScope {
525263509Sdim  friend class DIDescriptor;
526263509Sdim  void printInternal(raw_ostream &OS) const;
527239310Sdim
528263509Sdimpublic:
529263509Sdim  explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
530263509Sdim  DIScope getContext() const { return getFieldAs<DIScope>(2); }
531263509Sdim  StringRef getName() const { return getStringField(3); }
532263509Sdim  unsigned getLineNumber() const { return getUnsignedField(4); }
533263509Sdim  bool Verify() const;
534263509Sdim};
535239310Sdim
536263509Sdim/// DITemplateTypeParameter - This is a wrapper for template type parameter.
537263509Sdimclass DITemplateTypeParameter : public DIDescriptor {
538263509Sdimpublic:
539263509Sdim  explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
540239310Sdim
541263509Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
542263509Sdim  StringRef getName() const { return getStringField(2); }
543263509Sdim  DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
544263509Sdim  StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); }
545263509Sdim  StringRef getDirectory() const {
546263509Sdim    return getFieldAs<DIFile>(4).getDirectory();
547263509Sdim  }
548263509Sdim  unsigned getLineNumber() const { return getUnsignedField(5); }
549263509Sdim  unsigned getColumnNumber() const { return getUnsignedField(6); }
550263509Sdim  bool Verify() const;
551263509Sdim};
552239310Sdim
553263509Sdim/// DITemplateValueParameter - This is a wrapper for template value parameter.
554263509Sdimclass DITemplateValueParameter : public DIDescriptor {
555263509Sdimpublic:
556263509Sdim  explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
557239310Sdim
558263509Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
559263509Sdim  StringRef getName() const { return getStringField(2); }
560263509Sdim  DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
561263509Sdim  Value *getValue() const;
562263509Sdim  StringRef getFilename() const { return getFieldAs<DIFile>(5).getFilename(); }
563263509Sdim  StringRef getDirectory() const {
564263509Sdim    return getFieldAs<DIFile>(5).getDirectory();
565263509Sdim  }
566263509Sdim  unsigned getLineNumber() const { return getUnsignedField(6); }
567263509Sdim  unsigned getColumnNumber() const { return getUnsignedField(7); }
568263509Sdim  bool Verify() const;
569263509Sdim};
570252723Sdim
571263509Sdim/// DIGlobalVariable - This is a wrapper for a global variable.
572263509Sdimclass DIGlobalVariable : public DIDescriptor {
573263509Sdim  friend class DIDescriptor;
574263509Sdim  void printInternal(raw_ostream &OS) const;
575239310Sdim
576263509Sdimpublic:
577263509Sdim  explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
578239310Sdim
579263509Sdim  DIScope getContext() const { return getFieldAs<DIScope>(2); }
580263509Sdim  StringRef getName() const { return getStringField(3); }
581263509Sdim  StringRef getDisplayName() const { return getStringField(4); }
582263509Sdim  StringRef getLinkageName() const { return getStringField(5); }
583263509Sdim  StringRef getFilename() const { return getFieldAs<DIFile>(6).getFilename(); }
584263509Sdim  StringRef getDirectory() const {
585263509Sdim    return getFieldAs<DIFile>(6).getDirectory();
586263509Sdim  }
587239310Sdim
588263509Sdim  unsigned getLineNumber() const { return getUnsignedField(7); }
589263509Sdim  DIType getType() const { return getFieldAs<DIType>(8); }
590263509Sdim  unsigned isLocalToUnit() const { return getUnsignedField(9); }
591263509Sdim  unsigned isDefinition() const { return getUnsignedField(10); }
592239310Sdim
593263509Sdim  GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
594263509Sdim  Constant *getConstant() const { return getConstantField(11); }
595263509Sdim  DIDerivedType getStaticDataMemberDeclaration() const {
596263509Sdim    return getFieldAs<DIDerivedType>(12);
597263509Sdim  }
598239310Sdim
599263509Sdim  /// Verify - Verify that a global variable descriptor is well formed.
600263509Sdim  bool Verify() const;
601263509Sdim};
602239310Sdim
603263509Sdim/// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
604263509Sdim/// global etc).
605263509Sdimclass DIVariable : public DIDescriptor {
606263509Sdim  friend class DIDescriptor;
607263509Sdim  void printInternal(raw_ostream &OS) const;
608239310Sdim
609263509Sdimpublic:
610263509Sdim  explicit DIVariable(const MDNode *N = 0) : DIDescriptor(N) {}
611239310Sdim
612263509Sdim  DIScope getContext() const { return getFieldAs<DIScope>(1); }
613263509Sdim  StringRef getName() const { return getStringField(2); }
614263509Sdim  DIFile getFile() const { return getFieldAs<DIFile>(3); }
615263509Sdim  unsigned getLineNumber() const { return (getUnsignedField(4) << 8) >> 8; }
616263509Sdim  unsigned getArgNumber() const {
617263509Sdim    unsigned L = getUnsignedField(4);
618263509Sdim    return L >> 24;
619263509Sdim  }
620263509Sdim  DIType getType() const { return getFieldAs<DIType>(5); }
621239310Sdim
622263509Sdim  /// isArtificial - Return true if this variable is marked as "artificial".
623263509Sdim  bool isArtificial() const {
624263509Sdim    return (getUnsignedField(6) & FlagArtificial) != 0;
625263509Sdim  }
626239310Sdim
627263509Sdim  bool isObjectPointer() const {
628263509Sdim    return (getUnsignedField(6) & FlagObjectPointer) != 0;
629263509Sdim  }
630239310Sdim
631263509Sdim  /// \brief Return true if this variable is represented as a pointer.
632263509Sdim  bool isIndirect() const {
633263509Sdim    return (getUnsignedField(6) & FlagIndirectVariable) != 0;
634263509Sdim  }
635239310Sdim
636263509Sdim  /// getInlinedAt - If this variable is inlined then return inline location.
637263509Sdim  MDNode *getInlinedAt() const;
638239310Sdim
639263509Sdim  /// Verify - Verify that a variable descriptor is well formed.
640263509Sdim  bool Verify() const;
641239310Sdim
642263509Sdim  /// HasComplexAddr - Return true if the variable has a complex address.
643263509Sdim  bool hasComplexAddress() const { return getNumAddrElements() > 0; }
644239310Sdim
645263509Sdim  unsigned getNumAddrElements() const;
646239310Sdim
647263509Sdim  uint64_t getAddrElement(unsigned Idx) const {
648263509Sdim    return getUInt64Field(Idx + 8);
649263509Sdim  }
650239310Sdim
651263509Sdim  /// isBlockByrefVariable - Return true if the variable was declared as
652263509Sdim  /// a "__block" variable (Apple Blocks).
653263509Sdim  bool isBlockByrefVariable() const { return getType().isBlockByrefStruct(); }
654239310Sdim
655263509Sdim  /// isInlinedFnArgument - Return true if this variable provides debugging
656263509Sdim  /// information for an inlined function arguments.
657263509Sdim  bool isInlinedFnArgument(const Function *CurFn);
658239310Sdim
659263509Sdim  void printExtendedName(raw_ostream &OS) const;
660263509Sdim};
661263509Sdim
662263509Sdim/// DILocation - This object holds location information. This object
663263509Sdim/// is not associated with any DWARF tag.
664263509Sdimclass DILocation : public DIDescriptor {
665263509Sdimpublic:
666263509Sdim  explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
667263509Sdim
668263509Sdim  unsigned getLineNumber() const { return getUnsignedField(0); }
669263509Sdim  unsigned getColumnNumber() const { return getUnsignedField(1); }
670263509Sdim  DIScope getScope() const { return getFieldAs<DIScope>(2); }
671263509Sdim  DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
672263509Sdim  StringRef getFilename() const { return getScope().getFilename(); }
673263509Sdim  StringRef getDirectory() const { return getScope().getDirectory(); }
674263509Sdim  bool Verify() const;
675263509Sdim};
676263509Sdim
677263509Sdimclass DIObjCProperty : public DIDescriptor {
678263509Sdim  friend class DIDescriptor;
679263509Sdim  void printInternal(raw_ostream &OS) const;
680263509Sdim
681263509Sdimpublic:
682263509Sdim  explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {}
683263509Sdim
684263509Sdim  StringRef getObjCPropertyName() const { return getStringField(1); }
685263509Sdim  DIFile getFile() const { return getFieldAs<DIFile>(2); }
686263509Sdim  unsigned getLineNumber() const { return getUnsignedField(3); }
687263509Sdim
688263509Sdim  StringRef getObjCPropertyGetterName() const { return getStringField(4); }
689263509Sdim  StringRef getObjCPropertySetterName() const { return getStringField(5); }
690263509Sdim  bool isReadOnlyObjCProperty() const {
691263509Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
692263509Sdim  }
693263509Sdim  bool isReadWriteObjCProperty() const {
694263509Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
695263509Sdim  }
696263509Sdim  bool isAssignObjCProperty() const {
697263509Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
698263509Sdim  }
699263509Sdim  bool isRetainObjCProperty() const {
700263509Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
701263509Sdim  }
702263509Sdim  bool isCopyObjCProperty() const {
703263509Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
704263509Sdim  }
705263509Sdim  bool isNonAtomicObjCProperty() const {
706263509Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
707263509Sdim  }
708263509Sdim
709263509Sdim  DIType getType() const { return getFieldAs<DIType>(7); }
710263509Sdim
711263509Sdim  /// Verify - Verify that a derived type descriptor is well formed.
712263509Sdim  bool Verify() const;
713263509Sdim};
714263509Sdim
715263509Sdim/// \brief An imported module (C++ using directive or similar).
716263509Sdimclass DIImportedEntity : public DIDescriptor {
717263509Sdim  friend class DIDescriptor;
718263509Sdim  void printInternal(raw_ostream &OS) const;
719263509Sdim
720263509Sdimpublic:
721263509Sdim  explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
722263509Sdim  DIScope getContext() const { return getFieldAs<DIScope>(1); }
723263509Sdim  DIDescriptor getEntity() const { return getFieldAs<DIDescriptor>(2); }
724263509Sdim  unsigned getLineNumber() const { return getUnsignedField(3); }
725263509Sdim  StringRef getName() const { return getStringField(4); }
726263509Sdim  bool Verify() const;
727263509Sdim};
728263509Sdim
729263509Sdim/// getDISubprogram - Find subprogram that is enclosing this scope.
730263509SdimDISubprogram getDISubprogram(const MDNode *Scope);
731263509Sdim
732263509Sdim/// getDICompositeType - Find underlying composite type.
733263509SdimDICompositeType getDICompositeType(DIType T);
734263509Sdim
735263509Sdim/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
736263509Sdim/// to hold function specific information.
737263509SdimNamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
738263509Sdim
739263509Sdim/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
740263509Sdim/// suitable to hold function specific information.
741263509SdimNamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
742263509Sdim
743263509Sdim/// createInlinedVariable - Create a new inlined variable based on current
744263509Sdim/// variable.
745263509Sdim/// @param DV            Current Variable.
746263509Sdim/// @param InlinedScope  Location at current variable is inlined.
747263509SdimDIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
748263509Sdim                                 LLVMContext &VMContext);
749263509Sdim
750263509Sdim/// cleanseInlinedVariable - Remove inlined scope from the variable.
751263509SdimDIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
752263509Sdim
753263509Sdim/// Construct DITypeIdentifierMap by going through retained types of each CU.
754263509SdimDITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
755263509Sdim
756263509Sdim/// Strip debug info in the module if it exists.
757263509Sdim/// To do this, we remove all calls to the debugger intrinsics and any named
758263509Sdim/// metadata for debugging. We also remove debug locations for instructions.
759263509Sdim/// Return true if module is modified.
760263509Sdimbool StripDebugInfo(Module &M);
761263509Sdim
762263509Sdim/// Return Debug Info Metadata Version by checking module flags.
763263509Sdimunsigned getDebugMetadataVersionFromModule(const Module &M);
764263509Sdim
765263509Sdim/// DebugInfoFinder tries to list all debug info MDNodes used in a module. To
766263509Sdim/// list debug info MDNodes used by an instruction, DebugInfoFinder uses
767263509Sdim/// processDeclare, processValue and processLocation to handle DbgDeclareInst,
768263509Sdim/// DbgValueInst and DbgLoc attached to instructions. processModule will go
769263509Sdim/// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes
770263509Sdim/// used by the CUs.
771263509Sdimclass DebugInfoFinder {
772263509Sdimpublic:
773263509Sdim  DebugInfoFinder() : TypeMapInitialized(false) {}
774263509Sdim
775263509Sdim  /// processModule - Process entire module and collect debug info
776263509Sdim  /// anchors.
777263509Sdim  void processModule(const Module &M);
778263509Sdim
779263509Sdim  /// processDeclare - Process DbgDeclareInst.
780263509Sdim  void processDeclare(const Module &M, const DbgDeclareInst *DDI);
781263509Sdim  /// Process DbgValueInst.
782263509Sdim  void processValue(const Module &M, const DbgValueInst *DVI);
783263509Sdim  /// processLocation - Process DILocation.
784263509Sdim  void processLocation(const Module &M, DILocation Loc);
785263509Sdim
786263509Sdim  /// Clear all lists.
787263509Sdim  void reset();
788263509Sdim
789263509Sdimprivate:
790263509Sdim  /// Initialize TypeIdentifierMap.
791263509Sdim  void InitializeTypeMap(const Module &M);
792263509Sdim
793263509Sdim  /// processType - Process DIType.
794263509Sdim  void processType(DIType DT);
795263509Sdim
796263509Sdim  /// processLexicalBlock - Process DILexicalBlock.
797263509Sdim  void processLexicalBlock(DILexicalBlock LB);
798263509Sdim
799263509Sdim  /// processSubprogram - Process DISubprogram.
800263509Sdim  void processSubprogram(DISubprogram SP);
801263509Sdim
802263509Sdim  void processScope(DIScope Scope);
803263509Sdim
804263509Sdim  /// addCompileUnit - Add compile unit into CUs.
805263509Sdim  bool addCompileUnit(DICompileUnit CU);
806263509Sdim
807263509Sdim  /// addGlobalVariable - Add global variable into GVs.
808263509Sdim  bool addGlobalVariable(DIGlobalVariable DIG);
809263509Sdim
810263509Sdim  // addSubprogram - Add subprogram into SPs.
811263509Sdim  bool addSubprogram(DISubprogram SP);
812263509Sdim
813263509Sdim  /// addType - Add type into Tys.
814263509Sdim  bool addType(DIType DT);
815263509Sdim
816263509Sdim  bool addScope(DIScope Scope);
817263509Sdim
818263509Sdimpublic:
819263509Sdim  typedef SmallVectorImpl<MDNode *>::const_iterator iterator;
820263509Sdim  iterator compile_unit_begin() const { return CUs.begin(); }
821263509Sdim  iterator compile_unit_end() const { return CUs.end(); }
822263509Sdim  iterator subprogram_begin() const { return SPs.begin(); }
823263509Sdim  iterator subprogram_end() const { return SPs.end(); }
824263509Sdim  iterator global_variable_begin() const { return GVs.begin(); }
825263509Sdim  iterator global_variable_end() const { return GVs.end(); }
826263509Sdim  iterator type_begin() const { return TYs.begin(); }
827263509Sdim  iterator type_end() const { return TYs.end(); }
828263509Sdim  iterator scope_begin() const { return Scopes.begin(); }
829263509Sdim  iterator scope_end() const { return Scopes.end(); }
830263509Sdim
831263509Sdim  unsigned compile_unit_count() const { return CUs.size(); }
832263509Sdim  unsigned global_variable_count() const { return GVs.size(); }
833263509Sdim  unsigned subprogram_count() const { return SPs.size(); }
834263509Sdim  unsigned type_count() const { return TYs.size(); }
835263509Sdim  unsigned scope_count() const { return Scopes.size(); }
836263509Sdim
837263509Sdimprivate:
838263509Sdim  SmallVector<MDNode *, 8> CUs;    // Compile Units
839263509Sdim  SmallVector<MDNode *, 8> SPs;    // Subprograms
840263509Sdim  SmallVector<MDNode *, 8> GVs;    // Global Variables;
841263509Sdim  SmallVector<MDNode *, 8> TYs;    // Types
842263509Sdim  SmallVector<MDNode *, 8> Scopes; // Scopes
843263509Sdim  SmallPtrSet<MDNode *, 64> NodesSeen;
844263509Sdim  DITypeIdentifierMap TypeIdentifierMap;
845263509Sdim  /// Specify if TypeIdentifierMap is initialized.
846263509Sdim  bool TypeMapInitialized;
847263509Sdim};
848239310Sdim} // end namespace llvm
849239310Sdim
850239310Sdim#endif
851