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
17249423Sdim#ifndef LLVM_DEBUGINFO_H
18249423Sdim#define LLVM_DEBUGINFO_H
19239310Sdim
20263508Sdim#include "llvm/Support/Casting.h"
21263508Sdim#include "llvm/ADT/DenseMap.h"
22249423Sdim#include "llvm/ADT/SmallPtrSet.h"
23239310Sdim#include "llvm/ADT/SmallVector.h"
24239310Sdim#include "llvm/ADT/StringRef.h"
25263508Sdim#include "llvm/IR/Metadata.h"
26239310Sdim#include "llvm/Support/Dwarf.h"
27239310Sdim
28239310Sdimnamespace llvm {
29263508Sdimclass BasicBlock;
30263508Sdimclass Constant;
31263508Sdimclass Function;
32263508Sdimclass GlobalVariable;
33263508Sdimclass Module;
34263508Sdimclass Type;
35263508Sdimclass Value;
36263508Sdimclass DbgDeclareInst;
37263508Sdimclass DbgValueInst;
38263508Sdimclass Instruction;
39263508Sdimclass MDNode;
40263508Sdimclass MDString;
41263508Sdimclass NamedMDNode;
42263508Sdimclass LLVMContext;
43263508Sdimclass raw_ostream;
44239310Sdim
45263508Sdimclass DIFile;
46263508Sdimclass DISubprogram;
47263508Sdimclass DILexicalBlock;
48263508Sdimclass DILexicalBlockFile;
49263508Sdimclass DIVariable;
50263508Sdimclass DIType;
51263508Sdimclass DIScope;
52263508Sdimclass DIObjCProperty;
53239310Sdim
54263508Sdim/// Maps from type identifier to the actual MDNode.
55263508Sdimtypedef DenseMap<const MDString *, MDNode *> DITypeIdentifierMap;
56239310Sdim
57263508Sdim/// DIDescriptor - A thin wraper around MDNode to access encoded debug info.
58263508Sdim/// This should not be stored in a container, because the underlying MDNode
59263508Sdim/// may change in certain situations.
60263508Sdimclass DIDescriptor {
61263508Sdim  // Befriends DIRef so DIRef can befriend the protected member
62263508Sdim  // function: getFieldAs<DIRef>.
63263508Sdim  template <typename T> friend class DIRef;
64239310Sdim
65263508Sdimpublic:
66263508Sdim  enum {
67263508Sdim    FlagPrivate = 1 << 0,
68263508Sdim    FlagProtected = 1 << 1,
69263508Sdim    FlagFwdDecl = 1 << 2,
70263508Sdim    FlagAppleBlock = 1 << 3,
71263508Sdim    FlagBlockByrefStruct = 1 << 4,
72263508Sdim    FlagVirtual = 1 << 5,
73263508Sdim    FlagArtificial = 1 << 6,
74263508Sdim    FlagExplicit = 1 << 7,
75263508Sdim    FlagPrototyped = 1 << 8,
76263508Sdim    FlagObjcClassComplete = 1 << 9,
77263508Sdim    FlagObjectPointer = 1 << 10,
78263508Sdim    FlagVector = 1 << 11,
79263508Sdim    FlagStaticMember = 1 << 12,
80263508Sdim    FlagIndirectVariable = 1 << 13
81263508Sdim  };
82239310Sdim
83263508Sdimprotected:
84263508Sdim  const MDNode *DbgNode;
85239310Sdim
86263508Sdim  StringRef getStringField(unsigned Elt) const;
87263508Sdim  unsigned getUnsignedField(unsigned Elt) const {
88263508Sdim    return (unsigned)getUInt64Field(Elt);
89263508Sdim  }
90263508Sdim  uint64_t getUInt64Field(unsigned Elt) const;
91263508Sdim  int64_t getInt64Field(unsigned Elt) const;
92263508Sdim  DIDescriptor getDescriptorField(unsigned Elt) const;
93239310Sdim
94263508Sdim  template <typename DescTy> DescTy getFieldAs(unsigned Elt) const {
95263508Sdim    return DescTy(getDescriptorField(Elt));
96263508Sdim  }
97239310Sdim
98263508Sdim  GlobalVariable *getGlobalVariableField(unsigned Elt) const;
99263508Sdim  Constant *getConstantField(unsigned Elt) const;
100263508Sdim  Function *getFunctionField(unsigned Elt) const;
101263508Sdim  void replaceFunctionField(unsigned Elt, Function *F);
102239310Sdim
103263508Sdimpublic:
104263508Sdim  explicit DIDescriptor(const MDNode *N = 0) : DbgNode(N) {}
105239310Sdim
106263508Sdim  bool Verify() const;
107239310Sdim
108263508Sdim  operator MDNode *() const { return const_cast<MDNode *>(DbgNode); }
109263508Sdim  MDNode *operator->() const { return const_cast<MDNode *>(DbgNode); }
110239310Sdim
111263508Sdim  // An explicit operator bool so that we can do testing of DI values
112263508Sdim  // easily.
113263508Sdim  // FIXME: This operator bool isn't actually protecting anything at the
114263508Sdim  // moment due to the conversion operator above making DIDescriptor nodes
115263508Sdim  // implicitly convertable to bool.
116263508Sdim  LLVM_EXPLICIT operator bool() const { return DbgNode != 0; }
117239310Sdim
118263508Sdim  bool operator==(DIDescriptor Other) const { return DbgNode == Other.DbgNode; }
119263508Sdim  bool operator!=(DIDescriptor Other) const { return !operator==(Other); }
120239310Sdim
121263508Sdim  uint16_t getTag() const {
122263508Sdim    return getUnsignedField(0) & ~LLVMDebugVersionMask;
123263508Sdim  }
124239310Sdim
125263508Sdim  bool isDerivedType() const;
126263508Sdim  bool isCompositeType() const;
127263508Sdim  bool isBasicType() const;
128263508Sdim  bool isVariable() const;
129263508Sdim  bool isSubprogram() const;
130263508Sdim  bool isGlobalVariable() const;
131263508Sdim  bool isScope() const;
132263508Sdim  bool isFile() const;
133263508Sdim  bool isCompileUnit() const;
134263508Sdim  bool isNameSpace() const;
135263508Sdim  bool isLexicalBlockFile() const;
136263508Sdim  bool isLexicalBlock() const;
137263508Sdim  bool isSubrange() const;
138263508Sdim  bool isEnumerator() const;
139263508Sdim  bool isType() const;
140263508Sdim  bool isUnspecifiedParameter() const;
141263508Sdim  bool isTemplateTypeParameter() const;
142263508Sdim  bool isTemplateValueParameter() const;
143263508Sdim  bool isObjCProperty() const;
144263508Sdim  bool isImportedEntity() const;
145239310Sdim
146263508Sdim  /// print - print descriptor.
147263508Sdim  void print(raw_ostream &OS) const;
148239310Sdim
149263508Sdim  /// dump - print descriptor to dbgs() with a newline.
150263508Sdim  void dump() const;
151263508Sdim};
152239310Sdim
153263508Sdim/// DISubrange - This is used to represent ranges, for array bounds.
154263508Sdimclass DISubrange : public DIDescriptor {
155263508Sdim  friend class DIDescriptor;
156263508Sdim  void printInternal(raw_ostream &OS) const;
157239310Sdim
158263508Sdimpublic:
159263508Sdim  explicit DISubrange(const MDNode *N = 0) : DIDescriptor(N) {}
160249423Sdim
161263508Sdim  int64_t getLo() const { return getInt64Field(1); }
162263508Sdim  int64_t getCount() const { return getInt64Field(2); }
163263508Sdim  bool Verify() const;
164263508Sdim};
165239310Sdim
166263508Sdim/// DIArray - This descriptor holds an array of descriptors.
167263508Sdimclass DIArray : public DIDescriptor {
168263508Sdimpublic:
169263508Sdim  explicit DIArray(const MDNode *N = 0) : DIDescriptor(N) {}
170239310Sdim
171263508Sdim  unsigned getNumElements() const;
172263508Sdim  DIDescriptor getElement(unsigned Idx) const {
173263508Sdim    return getDescriptorField(Idx);
174263508Sdim  }
175263508Sdim};
176239310Sdim
177263508Sdim/// DIEnumerator - A wrapper for an enumerator (e.g. X and Y in 'enum {X,Y}').
178263508Sdim/// FIXME: it seems strange that this doesn't have either a reference to the
179263508Sdim/// type/precision or a file/line pair for location info.
180263508Sdimclass DIEnumerator : public DIDescriptor {
181263508Sdim  friend class DIDescriptor;
182263508Sdim  void printInternal(raw_ostream &OS) const;
183239310Sdim
184263508Sdimpublic:
185263508Sdim  explicit DIEnumerator(const MDNode *N = 0) : DIDescriptor(N) {}
186249423Sdim
187263508Sdim  StringRef getName() const { return getStringField(1); }
188263508Sdim  int64_t getEnumValue() const { return getInt64Field(2); }
189263508Sdim  bool Verify() const;
190263508Sdim};
191239310Sdim
192263508Sdimtemplate <typename T> class DIRef;
193263508Sdimtypedef DIRef<DIScope> DIScopeRef;
194263508Sdimtypedef DIRef<DIType> DITypeRef;
195239310Sdim
196263508Sdim/// DIScope - A base class for various scopes.
197263508Sdimclass DIScope : public DIDescriptor {
198263508Sdimprotected:
199263508Sdim  friend class DIDescriptor;
200263508Sdim  void printInternal(raw_ostream &OS) const;
201239310Sdim
202263508Sdimpublic:
203263508Sdim  explicit DIScope(const MDNode *N = 0) : DIDescriptor(N) {}
204239310Sdim
205263508Sdim  /// Gets the parent scope for this scope node or returns a
206263508Sdim  /// default constructed scope.
207263508Sdim  DIScopeRef getContext() const;
208263508Sdim  /// If the scope node has a name, return that, else return an empty string.
209263508Sdim  StringRef getName() const;
210263508Sdim  StringRef getFilename() const;
211263508Sdim  StringRef getDirectory() const;
212239310Sdim
213263508Sdim  /// Generate a reference to this DIScope. Uses the type identifier instead
214263508Sdim  /// of the actual MDNode if possible, to help type uniquing.
215263508Sdim  DIScopeRef getRef() const;
216263508Sdim};
217239310Sdim
218263508Sdim/// Represents reference to a DIDescriptor, abstracts over direct and
219263508Sdim/// identifier-based metadata references.
220263508Sdimtemplate <typename T> class DIRef {
221263508Sdim  template <typename DescTy>
222263508Sdim  friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
223263508Sdim  friend DIScopeRef DIScope::getContext() const;
224263508Sdim  friend DIScopeRef DIScope::getRef() const;
225239310Sdim
226263508Sdim  /// Val can be either a MDNode or a MDString, in the latter,
227263508Sdim  /// MDString specifies the type identifier.
228263508Sdim  const Value *Val;
229263508Sdim  explicit DIRef(const Value *V);
230239310Sdim
231263508Sdimpublic:
232263508Sdim  T resolve(const DITypeIdentifierMap &Map) const;
233263508Sdim  StringRef getName() const;
234263508Sdim  operator Value *() const { return const_cast<Value *>(Val); }
235263508Sdim};
236239310Sdim
237263508Sdimtemplate <typename T>
238263508SdimT DIRef<T>::resolve(const DITypeIdentifierMap &Map) const {
239263508Sdim  if (!Val)
240263508Sdim    return T();
241239310Sdim
242263508Sdim  if (const MDNode *MD = dyn_cast<MDNode>(Val))
243263508Sdim    return T(MD);
244239310Sdim
245263508Sdim  const MDString *MS = cast<MDString>(Val);
246263508Sdim  // Find the corresponding MDNode.
247263508Sdim  DITypeIdentifierMap::const_iterator Iter = Map.find(MS);
248263508Sdim  assert(Iter != Map.end() && "Identifier not in the type map?");
249263508Sdim  assert(DIDescriptor(Iter->second).isType() &&
250263508Sdim         "MDNode in DITypeIdentifierMap should be a DIType.");
251263508Sdim  return T(Iter->second);
252263508Sdim}
253239310Sdim
254263508Sdimtemplate <typename T> StringRef DIRef<T>::getName() const {
255263508Sdim  if (!Val)
256263508Sdim    return StringRef();
257239310Sdim
258263508Sdim  if (const MDNode *MD = dyn_cast<MDNode>(Val))
259263508Sdim    return T(MD).getName();
260239310Sdim
261263508Sdim  const MDString *MS = cast<MDString>(Val);
262263508Sdim  return MS->getString();
263263508Sdim}
264249423Sdim
265263508Sdim/// Specialize getFieldAs to handle fields that are references to DIScopes.
266263508Sdimtemplate <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
267263508Sdim/// Specialize DIRef constructor for DIScopeRef.
268263508Sdimtemplate <> DIRef<DIScope>::DIRef(const Value *V);
269239310Sdim
270263508Sdim/// Specialize getFieldAs to handle fields that are references to DITypes.
271263508Sdimtemplate <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
272263508Sdim/// Specialize DIRef constructor for DITypeRef.
273263508Sdimtemplate <> DIRef<DIType>::DIRef(const Value *V);
274239310Sdim
275263508Sdim/// DIType - This is a wrapper for a type.
276263508Sdim/// FIXME: Types should be factored much better so that CV qualifiers and
277263508Sdim/// others do not require a huge and empty descriptor full of zeros.
278263508Sdimclass DIType : public DIScope {
279263508Sdimprotected:
280263508Sdim  friend class DIDescriptor;
281263508Sdim  void printInternal(raw_ostream &OS) const;
282239310Sdim
283263508Sdimpublic:
284263508Sdim  explicit DIType(const MDNode *N = 0) : DIScope(N) {}
285239310Sdim
286263508Sdim  /// Verify - Verify that a type descriptor is well formed.
287263508Sdim  bool Verify() const;
288239310Sdim
289263508Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
290263508Sdim  StringRef getName() const { return getStringField(3); }
291263508Sdim  unsigned getLineNumber() const { return getUnsignedField(4); }
292263508Sdim  uint64_t getSizeInBits() const { return getUInt64Field(5); }
293263508Sdim  uint64_t getAlignInBits() const { return getUInt64Field(6); }
294263508Sdim  // FIXME: Offset is only used for DW_TAG_member nodes.  Making every type
295263508Sdim  // carry this is just plain insane.
296263508Sdim  uint64_t getOffsetInBits() const { return getUInt64Field(7); }
297263508Sdim  unsigned getFlags() const { return getUnsignedField(8); }
298263508Sdim  bool isPrivate() const { return (getFlags() & FlagPrivate) != 0; }
299263508Sdim  bool isProtected() const { return (getFlags() & FlagProtected) != 0; }
300263508Sdim  bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; }
301263508Sdim  // isAppleBlock - Return true if this is the Apple Blocks extension.
302263508Sdim  bool isAppleBlockExtension() const {
303263508Sdim    return (getFlags() & FlagAppleBlock) != 0;
304263508Sdim  }
305263508Sdim  bool isBlockByrefStruct() const {
306263508Sdim    return (getFlags() & FlagBlockByrefStruct) != 0;
307263508Sdim  }
308263508Sdim  bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; }
309263508Sdim  bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
310263508Sdim  bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; }
311263508Sdim  bool isObjcClassComplete() const {
312263508Sdim    return (getFlags() & FlagObjcClassComplete) != 0;
313263508Sdim  }
314263508Sdim  bool isVector() const { return (getFlags() & FlagVector) != 0; }
315263508Sdim  bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
316263508Sdim  bool isValid() const { return DbgNode && isType(); }
317239310Sdim
318263508Sdim  /// replaceAllUsesWith - Replace all uses of debug info referenced by
319263508Sdim  /// this descriptor.
320263508Sdim  void replaceAllUsesWith(DIDescriptor &D);
321263508Sdim  void replaceAllUsesWith(MDNode *D);
322263508Sdim};
323239310Sdim
324263508Sdim/// DIBasicType - A basic type, like 'int' or 'float'.
325263508Sdimclass DIBasicType : public DIType {
326263508Sdimpublic:
327263508Sdim  explicit DIBasicType(const MDNode *N = 0) : DIType(N) {}
328239310Sdim
329263508Sdim  unsigned getEncoding() const { return getUnsignedField(9); }
330239310Sdim
331263508Sdim  /// Verify - Verify that a basic type descriptor is well formed.
332263508Sdim  bool Verify() const;
333263508Sdim};
334239310Sdim
335263508Sdim/// DIDerivedType - A simple derived type, like a const qualified type,
336263508Sdim/// a typedef, a pointer or reference, et cetera.  Or, a data member of
337263508Sdim/// a class/struct/union.
338263508Sdimclass DIDerivedType : public DIType {
339263508Sdim  friend class DIDescriptor;
340263508Sdim  void printInternal(raw_ostream &OS) const;
341239310Sdim
342263508Sdimpublic:
343263508Sdim  explicit DIDerivedType(const MDNode *N = 0) : DIType(N) {}
344239310Sdim
345263508Sdim  DITypeRef getTypeDerivedFrom() const { return getFieldAs<DITypeRef>(9); }
346239310Sdim
347263508Sdim  /// getObjCProperty - Return property node, if this ivar is
348263508Sdim  /// associated with one.
349263508Sdim  MDNode *getObjCProperty() const;
350239310Sdim
351263508Sdim  DITypeRef getClassType() const {
352263508Sdim    assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
353263508Sdim    return getFieldAs<DITypeRef>(10);
354263508Sdim  }
355239310Sdim
356263508Sdim  Constant *getConstant() const {
357263508Sdim    assert((getTag() == dwarf::DW_TAG_member) && isStaticMember());
358263508Sdim    return getConstantField(10);
359263508Sdim  }
360249423Sdim
361263508Sdim  /// Verify - Verify that a derived type descriptor is well formed.
362263508Sdim  bool Verify() const;
363263508Sdim};
364239310Sdim
365263508Sdim/// DICompositeType - This descriptor holds a type that can refer to multiple
366263508Sdim/// other types, like a function or struct.
367263508Sdim/// DICompositeType is derived from DIDerivedType because some
368263508Sdim/// composite types (such as enums) can be derived from basic types
369263508Sdim// FIXME: Make this derive from DIType directly & just store the
370263508Sdim// base type in a single DIType field.
371263508Sdimclass DICompositeType : public DIDerivedType {
372263508Sdim  friend class DIDescriptor;
373263508Sdim  void printInternal(raw_ostream &OS) const;
374239310Sdim
375263508Sdimpublic:
376263508Sdim  explicit DICompositeType(const MDNode *N = 0) : DIDerivedType(N) {}
377239310Sdim
378263508Sdim  DIArray getTypeArray() const { return getFieldAs<DIArray>(10); }
379263508Sdim  void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
380263508Sdim  void addMember(DIDescriptor D);
381263508Sdim  unsigned getRunTimeLang() const { return getUnsignedField(11); }
382263508Sdim  DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
383263508Sdim  void setContainingType(DICompositeType ContainingType);
384263508Sdim  DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
385263508Sdim  MDString *getIdentifier() const;
386239310Sdim
387263508Sdim  /// Verify - Verify that a composite type descriptor is well formed.
388263508Sdim  bool Verify() const;
389263508Sdim};
390239310Sdim
391263508Sdim/// DIFile - This is a wrapper for a file.
392263508Sdimclass DIFile : public DIScope {
393263508Sdim  friend class DIDescriptor;
394239310Sdim
395263508Sdimpublic:
396263508Sdim  explicit DIFile(const MDNode *N = 0) : DIScope(N) {}
397263508Sdim  MDNode *getFileNode() const;
398263508Sdim  bool Verify() const;
399263508Sdim};
400239310Sdim
401263508Sdim/// DICompileUnit - A wrapper for a compile unit.
402263508Sdimclass DICompileUnit : public DIScope {
403263508Sdim  friend class DIDescriptor;
404263508Sdim  void printInternal(raw_ostream &OS) const;
405239310Sdim
406263508Sdimpublic:
407263508Sdim  explicit DICompileUnit(const MDNode *N = 0) : DIScope(N) {}
408239310Sdim
409263508Sdim  unsigned getLanguage() const { return getUnsignedField(2); }
410263508Sdim  StringRef getProducer() const { return getStringField(3); }
411239310Sdim
412263508Sdim  bool isOptimized() const { return getUnsignedField(4) != 0; }
413263508Sdim  StringRef getFlags() const { return getStringField(5); }
414263508Sdim  unsigned getRunTimeVersion() const { return getUnsignedField(6); }
415239310Sdim
416263508Sdim  DIArray getEnumTypes() const;
417263508Sdim  DIArray getRetainedTypes() const;
418263508Sdim  DIArray getSubprograms() const;
419263508Sdim  DIArray getGlobalVariables() const;
420263508Sdim  DIArray getImportedEntities() const;
421239310Sdim
422263508Sdim  StringRef getSplitDebugFilename() const { return getStringField(12); }
423239310Sdim
424263508Sdim  /// Verify - Verify that a compile unit is well formed.
425263508Sdim  bool Verify() const;
426263508Sdim};
427249423Sdim
428263508Sdim/// DISubprogram - This is a wrapper for a subprogram (e.g. a function).
429263508Sdimclass DISubprogram : public DIScope {
430263508Sdim  friend class DIDescriptor;
431263508Sdim  void printInternal(raw_ostream &OS) const;
432239310Sdim
433263508Sdimpublic:
434263508Sdim  explicit DISubprogram(const MDNode *N = 0) : DIScope(N) {}
435243830Sdim
436263508Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
437263508Sdim  StringRef getName() const { return getStringField(3); }
438263508Sdim  StringRef getDisplayName() const { return getStringField(4); }
439263508Sdim  StringRef getLinkageName() const { return getStringField(5); }
440263508Sdim  unsigned getLineNumber() const { return getUnsignedField(6); }
441263508Sdim  DICompositeType getType() const { return getFieldAs<DICompositeType>(7); }
442239310Sdim
443263508Sdim  /// isLocalToUnit - Return true if this subprogram is local to the current
444263508Sdim  /// compile unit, like 'static' in C.
445263508Sdim  unsigned isLocalToUnit() const { return getUnsignedField(8); }
446263508Sdim  unsigned isDefinition() const { return getUnsignedField(9); }
447239310Sdim
448263508Sdim  unsigned getVirtuality() const { return getUnsignedField(10); }
449263508Sdim  unsigned getVirtualIndex() const { return getUnsignedField(11); }
450239310Sdim
451263508Sdim  DITypeRef getContainingType() const { return getFieldAs<DITypeRef>(12); }
452249423Sdim
453263508Sdim  unsigned getFlags() const { return getUnsignedField(13); }
454239310Sdim
455263508Sdim  unsigned isArtificial() const {
456263508Sdim    return (getUnsignedField(13) & FlagArtificial) != 0;
457263508Sdim  }
458263508Sdim  /// isPrivate - Return true if this subprogram has "private"
459263508Sdim  /// access specifier.
460263508Sdim  bool isPrivate() const { return (getUnsignedField(13) & FlagPrivate) != 0; }
461263508Sdim  /// isProtected - Return true if this subprogram has "protected"
462263508Sdim  /// access specifier.
463263508Sdim  bool isProtected() const {
464263508Sdim    return (getUnsignedField(13) & FlagProtected) != 0;
465263508Sdim  }
466263508Sdim  /// isExplicit - Return true if this subprogram is marked as explicit.
467263508Sdim  bool isExplicit() const { return (getUnsignedField(13) & FlagExplicit) != 0; }
468263508Sdim  /// isPrototyped - Return true if this subprogram is prototyped.
469263508Sdim  bool isPrototyped() const {
470263508Sdim    return (getUnsignedField(13) & FlagPrototyped) != 0;
471263508Sdim  }
472239310Sdim
473263508Sdim  unsigned isOptimized() const;
474239310Sdim
475263508Sdim  /// Verify - Verify that a subprogram descriptor is well formed.
476263508Sdim  bool Verify() const;
477239310Sdim
478263508Sdim  /// describes - Return true if this subprogram provides debugging
479263508Sdim  /// information for the function F.
480263508Sdim  bool describes(const Function *F);
481239310Sdim
482263508Sdim  Function *getFunction() const { return getFunctionField(15); }
483263508Sdim  void replaceFunction(Function *F) { replaceFunctionField(15, F); }
484263508Sdim  DIArray getTemplateParams() const { return getFieldAs<DIArray>(16); }
485263508Sdim  DISubprogram getFunctionDeclaration() const {
486263508Sdim    return getFieldAs<DISubprogram>(17);
487263508Sdim  }
488263508Sdim  MDNode *getVariablesNodes() const;
489263508Sdim  DIArray getVariables() const;
490239310Sdim
491263508Sdim  /// getScopeLineNumber - Get the beginning of the scope of the
492263508Sdim  /// function, not necessarily where the name of the program
493263508Sdim  /// starts.
494263508Sdim  unsigned getScopeLineNumber() const { return getUnsignedField(19); }
495263508Sdim};
496239310Sdim
497263508Sdim/// DILexicalBlock - This is a wrapper for a lexical block.
498263508Sdimclass DILexicalBlock : public DIScope {
499263508Sdimpublic:
500263508Sdim  explicit DILexicalBlock(const MDNode *N = 0) : DIScope(N) {}
501263508Sdim  DIScope getContext() const { return getFieldAs<DIScope>(2); }
502263508Sdim  unsigned getLineNumber() const { return getUnsignedField(3); }
503263508Sdim  unsigned getColumnNumber() const { return getUnsignedField(4); }
504263508Sdim  bool Verify() const;
505263508Sdim};
506239310Sdim
507263508Sdim/// DILexicalBlockFile - This is a wrapper for a lexical block with
508263508Sdim/// a filename change.
509263508Sdimclass DILexicalBlockFile : public DIScope {
510263508Sdimpublic:
511263508Sdim  explicit DILexicalBlockFile(const MDNode *N = 0) : DIScope(N) {}
512263508Sdim  DIScope getContext() const {
513263508Sdim    if (getScope().isSubprogram())
514263508Sdim      return getScope();
515263508Sdim    return getScope().getContext();
516263508Sdim  }
517263508Sdim  unsigned getLineNumber() const { return getScope().getLineNumber(); }
518263508Sdim  unsigned getColumnNumber() const { return getScope().getColumnNumber(); }
519263508Sdim  DILexicalBlock getScope() const { return getFieldAs<DILexicalBlock>(2); }
520263508Sdim  bool Verify() const;
521263508Sdim};
522239310Sdim
523263508Sdim/// DINameSpace - A wrapper for a C++ style name space.
524263508Sdimclass DINameSpace : public DIScope {
525263508Sdim  friend class DIDescriptor;
526263508Sdim  void printInternal(raw_ostream &OS) const;
527239310Sdim
528263508Sdimpublic:
529263508Sdim  explicit DINameSpace(const MDNode *N = 0) : DIScope(N) {}
530263508Sdim  DIScope getContext() const { return getFieldAs<DIScope>(2); }
531263508Sdim  StringRef getName() const { return getStringField(3); }
532263508Sdim  unsigned getLineNumber() const { return getUnsignedField(4); }
533263508Sdim  bool Verify() const;
534263508Sdim};
535239310Sdim
536263508Sdim/// DITemplateTypeParameter - This is a wrapper for template type parameter.
537263508Sdimclass DITemplateTypeParameter : public DIDescriptor {
538263508Sdimpublic:
539263508Sdim  explicit DITemplateTypeParameter(const MDNode *N = 0) : DIDescriptor(N) {}
540239310Sdim
541263508Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
542263508Sdim  StringRef getName() const { return getStringField(2); }
543263508Sdim  DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
544263508Sdim  StringRef getFilename() const { return getFieldAs<DIFile>(4).getFilename(); }
545263508Sdim  StringRef getDirectory() const {
546263508Sdim    return getFieldAs<DIFile>(4).getDirectory();
547263508Sdim  }
548263508Sdim  unsigned getLineNumber() const { return getUnsignedField(5); }
549263508Sdim  unsigned getColumnNumber() const { return getUnsignedField(6); }
550263508Sdim  bool Verify() const;
551263508Sdim};
552239310Sdim
553263508Sdim/// DITemplateValueParameter - This is a wrapper for template value parameter.
554263508Sdimclass DITemplateValueParameter : public DIDescriptor {
555263508Sdimpublic:
556263508Sdim  explicit DITemplateValueParameter(const MDNode *N = 0) : DIDescriptor(N) {}
557239310Sdim
558263508Sdim  DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(1); }
559263508Sdim  StringRef getName() const { return getStringField(2); }
560263508Sdim  DITypeRef getType() const { return getFieldAs<DITypeRef>(3); }
561263508Sdim  Value *getValue() const;
562263508Sdim  StringRef getFilename() const { return getFieldAs<DIFile>(5).getFilename(); }
563263508Sdim  StringRef getDirectory() const {
564263508Sdim    return getFieldAs<DIFile>(5).getDirectory();
565263508Sdim  }
566263508Sdim  unsigned getLineNumber() const { return getUnsignedField(6); }
567263508Sdim  unsigned getColumnNumber() const { return getUnsignedField(7); }
568263508Sdim  bool Verify() const;
569263508Sdim};
570251662Sdim
571263508Sdim/// DIGlobalVariable - This is a wrapper for a global variable.
572263508Sdimclass DIGlobalVariable : public DIDescriptor {
573263508Sdim  friend class DIDescriptor;
574263508Sdim  void printInternal(raw_ostream &OS) const;
575239310Sdim
576263508Sdimpublic:
577263508Sdim  explicit DIGlobalVariable(const MDNode *N = 0) : DIDescriptor(N) {}
578239310Sdim
579263508Sdim  DIScope getContext() const { return getFieldAs<DIScope>(2); }
580263508Sdim  StringRef getName() const { return getStringField(3); }
581263508Sdim  StringRef getDisplayName() const { return getStringField(4); }
582263508Sdim  StringRef getLinkageName() const { return getStringField(5); }
583263508Sdim  StringRef getFilename() const { return getFieldAs<DIFile>(6).getFilename(); }
584263508Sdim  StringRef getDirectory() const {
585263508Sdim    return getFieldAs<DIFile>(6).getDirectory();
586263508Sdim  }
587239310Sdim
588263508Sdim  unsigned getLineNumber() const { return getUnsignedField(7); }
589263508Sdim  DIType getType() const { return getFieldAs<DIType>(8); }
590263508Sdim  unsigned isLocalToUnit() const { return getUnsignedField(9); }
591263508Sdim  unsigned isDefinition() const { return getUnsignedField(10); }
592239310Sdim
593263508Sdim  GlobalVariable *getGlobal() const { return getGlobalVariableField(11); }
594263508Sdim  Constant *getConstant() const { return getConstantField(11); }
595263508Sdim  DIDerivedType getStaticDataMemberDeclaration() const {
596263508Sdim    return getFieldAs<DIDerivedType>(12);
597263508Sdim  }
598239310Sdim
599263508Sdim  /// Verify - Verify that a global variable descriptor is well formed.
600263508Sdim  bool Verify() const;
601263508Sdim};
602239310Sdim
603263508Sdim/// DIVariable - This is a wrapper for a variable (e.g. parameter, local,
604263508Sdim/// global etc).
605263508Sdimclass DIVariable : public DIDescriptor {
606263508Sdim  friend class DIDescriptor;
607263508Sdim  void printInternal(raw_ostream &OS) const;
608239310Sdim
609263508Sdimpublic:
610263508Sdim  explicit DIVariable(const MDNode *N = 0) : DIDescriptor(N) {}
611239310Sdim
612263508Sdim  DIScope getContext() const { return getFieldAs<DIScope>(1); }
613263508Sdim  StringRef getName() const { return getStringField(2); }
614263508Sdim  DIFile getFile() const { return getFieldAs<DIFile>(3); }
615263508Sdim  unsigned getLineNumber() const { return (getUnsignedField(4) << 8) >> 8; }
616263508Sdim  unsigned getArgNumber() const {
617263508Sdim    unsigned L = getUnsignedField(4);
618263508Sdim    return L >> 24;
619263508Sdim  }
620263508Sdim  DIType getType() const { return getFieldAs<DIType>(5); }
621239310Sdim
622263508Sdim  /// isArtificial - Return true if this variable is marked as "artificial".
623263508Sdim  bool isArtificial() const {
624263508Sdim    return (getUnsignedField(6) & FlagArtificial) != 0;
625263508Sdim  }
626239310Sdim
627263508Sdim  bool isObjectPointer() const {
628263508Sdim    return (getUnsignedField(6) & FlagObjectPointer) != 0;
629263508Sdim  }
630239310Sdim
631263508Sdim  /// \brief Return true if this variable is represented as a pointer.
632263508Sdim  bool isIndirect() const {
633263508Sdim    return (getUnsignedField(6) & FlagIndirectVariable) != 0;
634263508Sdim  }
635239310Sdim
636263508Sdim  /// getInlinedAt - If this variable is inlined then return inline location.
637263508Sdim  MDNode *getInlinedAt() const;
638239310Sdim
639263508Sdim  /// Verify - Verify that a variable descriptor is well formed.
640263508Sdim  bool Verify() const;
641239310Sdim
642263508Sdim  /// HasComplexAddr - Return true if the variable has a complex address.
643263508Sdim  bool hasComplexAddress() const { return getNumAddrElements() > 0; }
644239310Sdim
645263508Sdim  unsigned getNumAddrElements() const;
646239310Sdim
647263508Sdim  uint64_t getAddrElement(unsigned Idx) const {
648263508Sdim    return getUInt64Field(Idx + 8);
649263508Sdim  }
650239310Sdim
651263508Sdim  /// isBlockByrefVariable - Return true if the variable was declared as
652263508Sdim  /// a "__block" variable (Apple Blocks).
653263508Sdim  bool isBlockByrefVariable() const { return getType().isBlockByrefStruct(); }
654239310Sdim
655263508Sdim  /// isInlinedFnArgument - Return true if this variable provides debugging
656263508Sdim  /// information for an inlined function arguments.
657263508Sdim  bool isInlinedFnArgument(const Function *CurFn);
658239310Sdim
659263508Sdim  void printExtendedName(raw_ostream &OS) const;
660263508Sdim};
661263508Sdim
662263508Sdim/// DILocation - This object holds location information. This object
663263508Sdim/// is not associated with any DWARF tag.
664263508Sdimclass DILocation : public DIDescriptor {
665263508Sdimpublic:
666263508Sdim  explicit DILocation(const MDNode *N) : DIDescriptor(N) {}
667263508Sdim
668263508Sdim  unsigned getLineNumber() const { return getUnsignedField(0); }
669263508Sdim  unsigned getColumnNumber() const { return getUnsignedField(1); }
670263508Sdim  DIScope getScope() const { return getFieldAs<DIScope>(2); }
671263508Sdim  DILocation getOrigLocation() const { return getFieldAs<DILocation>(3); }
672263508Sdim  StringRef getFilename() const { return getScope().getFilename(); }
673263508Sdim  StringRef getDirectory() const { return getScope().getDirectory(); }
674263508Sdim  bool Verify() const;
675263508Sdim};
676263508Sdim
677263508Sdimclass DIObjCProperty : public DIDescriptor {
678263508Sdim  friend class DIDescriptor;
679263508Sdim  void printInternal(raw_ostream &OS) const;
680263508Sdim
681263508Sdimpublic:
682263508Sdim  explicit DIObjCProperty(const MDNode *N) : DIDescriptor(N) {}
683263508Sdim
684263508Sdim  StringRef getObjCPropertyName() const { return getStringField(1); }
685263508Sdim  DIFile getFile() const { return getFieldAs<DIFile>(2); }
686263508Sdim  unsigned getLineNumber() const { return getUnsignedField(3); }
687263508Sdim
688263508Sdim  StringRef getObjCPropertyGetterName() const { return getStringField(4); }
689263508Sdim  StringRef getObjCPropertySetterName() const { return getStringField(5); }
690263508Sdim  bool isReadOnlyObjCProperty() const {
691263508Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readonly) != 0;
692263508Sdim  }
693263508Sdim  bool isReadWriteObjCProperty() const {
694263508Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_readwrite) != 0;
695263508Sdim  }
696263508Sdim  bool isAssignObjCProperty() const {
697263508Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_assign) != 0;
698263508Sdim  }
699263508Sdim  bool isRetainObjCProperty() const {
700263508Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_retain) != 0;
701263508Sdim  }
702263508Sdim  bool isCopyObjCProperty() const {
703263508Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_copy) != 0;
704263508Sdim  }
705263508Sdim  bool isNonAtomicObjCProperty() const {
706263508Sdim    return (getUnsignedField(6) & dwarf::DW_APPLE_PROPERTY_nonatomic) != 0;
707263508Sdim  }
708263508Sdim
709263508Sdim  DIType getType() const { return getFieldAs<DIType>(7); }
710263508Sdim
711263508Sdim  /// Verify - Verify that a derived type descriptor is well formed.
712263508Sdim  bool Verify() const;
713263508Sdim};
714263508Sdim
715263508Sdim/// \brief An imported module (C++ using directive or similar).
716263508Sdimclass DIImportedEntity : public DIDescriptor {
717263508Sdim  friend class DIDescriptor;
718263508Sdim  void printInternal(raw_ostream &OS) const;
719263508Sdim
720263508Sdimpublic:
721263508Sdim  explicit DIImportedEntity(const MDNode *N) : DIDescriptor(N) {}
722263508Sdim  DIScope getContext() const { return getFieldAs<DIScope>(1); }
723263508Sdim  DIDescriptor getEntity() const { return getFieldAs<DIDescriptor>(2); }
724263508Sdim  unsigned getLineNumber() const { return getUnsignedField(3); }
725263508Sdim  StringRef getName() const { return getStringField(4); }
726263508Sdim  bool Verify() const;
727263508Sdim};
728263508Sdim
729263508Sdim/// getDISubprogram - Find subprogram that is enclosing this scope.
730263508SdimDISubprogram getDISubprogram(const MDNode *Scope);
731263508Sdim
732263508Sdim/// getDICompositeType - Find underlying composite type.
733263508SdimDICompositeType getDICompositeType(DIType T);
734263508Sdim
735263508Sdim/// getOrInsertFnSpecificMDNode - Return a NameMDNode that is suitable
736263508Sdim/// to hold function specific information.
737263508SdimNamedMDNode *getOrInsertFnSpecificMDNode(Module &M, DISubprogram SP);
738263508Sdim
739263508Sdim/// getFnSpecificMDNode - Return a NameMDNode, if available, that is
740263508Sdim/// suitable to hold function specific information.
741263508SdimNamedMDNode *getFnSpecificMDNode(const Module &M, DISubprogram SP);
742263508Sdim
743263508Sdim/// createInlinedVariable - Create a new inlined variable based on current
744263508Sdim/// variable.
745263508Sdim/// @param DV            Current Variable.
746263508Sdim/// @param InlinedScope  Location at current variable is inlined.
747263508SdimDIVariable createInlinedVariable(MDNode *DV, MDNode *InlinedScope,
748263508Sdim                                 LLVMContext &VMContext);
749263508Sdim
750263508Sdim/// cleanseInlinedVariable - Remove inlined scope from the variable.
751263508SdimDIVariable cleanseInlinedVariable(MDNode *DV, LLVMContext &VMContext);
752263508Sdim
753263508Sdim/// Construct DITypeIdentifierMap by going through retained types of each CU.
754263508SdimDITypeIdentifierMap generateDITypeIdentifierMap(const NamedMDNode *CU_Nodes);
755263508Sdim
756263508Sdim/// Strip debug info in the module if it exists.
757263508Sdim/// To do this, we remove all calls to the debugger intrinsics and any named
758263508Sdim/// metadata for debugging. We also remove debug locations for instructions.
759263508Sdim/// Return true if module is modified.
760263508Sdimbool StripDebugInfo(Module &M);
761263508Sdim
762263508Sdim/// Return Debug Info Metadata Version by checking module flags.
763263508Sdimunsigned getDebugMetadataVersionFromModule(const Module &M);
764263508Sdim
765263508Sdim/// DebugInfoFinder tries to list all debug info MDNodes used in a module. To
766263508Sdim/// list debug info MDNodes used by an instruction, DebugInfoFinder uses
767263508Sdim/// processDeclare, processValue and processLocation to handle DbgDeclareInst,
768263508Sdim/// DbgValueInst and DbgLoc attached to instructions. processModule will go
769263508Sdim/// through all DICompileUnits in llvm.dbg.cu and list debug info MDNodes
770263508Sdim/// used by the CUs.
771263508Sdimclass DebugInfoFinder {
772263508Sdimpublic:
773263508Sdim  DebugInfoFinder() : TypeMapInitialized(false) {}
774263508Sdim
775263508Sdim  /// processModule - Process entire module and collect debug info
776263508Sdim  /// anchors.
777263508Sdim  void processModule(const Module &M);
778263508Sdim
779263508Sdim  /// processDeclare - Process DbgDeclareInst.
780263508Sdim  void processDeclare(const Module &M, const DbgDeclareInst *DDI);
781263508Sdim  /// Process DbgValueInst.
782263508Sdim  void processValue(const Module &M, const DbgValueInst *DVI);
783263508Sdim  /// processLocation - Process DILocation.
784263508Sdim  void processLocation(const Module &M, DILocation Loc);
785263508Sdim
786263508Sdim  /// Clear all lists.
787263508Sdim  void reset();
788263508Sdim
789263508Sdimprivate:
790263508Sdim  /// Initialize TypeIdentifierMap.
791263508Sdim  void InitializeTypeMap(const Module &M);
792263508Sdim
793263508Sdim  /// processType - Process DIType.
794263508Sdim  void processType(DIType DT);
795263508Sdim
796263508Sdim  /// processLexicalBlock - Process DILexicalBlock.
797263508Sdim  void processLexicalBlock(DILexicalBlock LB);
798263508Sdim
799263508Sdim  /// processSubprogram - Process DISubprogram.
800263508Sdim  void processSubprogram(DISubprogram SP);
801263508Sdim
802263508Sdim  void processScope(DIScope Scope);
803263508Sdim
804263508Sdim  /// addCompileUnit - Add compile unit into CUs.
805263508Sdim  bool addCompileUnit(DICompileUnit CU);
806263508Sdim
807263508Sdim  /// addGlobalVariable - Add global variable into GVs.
808263508Sdim  bool addGlobalVariable(DIGlobalVariable DIG);
809263508Sdim
810263508Sdim  // addSubprogram - Add subprogram into SPs.
811263508Sdim  bool addSubprogram(DISubprogram SP);
812263508Sdim
813263508Sdim  /// addType - Add type into Tys.
814263508Sdim  bool addType(DIType DT);
815263508Sdim
816263508Sdim  bool addScope(DIScope Scope);
817263508Sdim
818263508Sdimpublic:
819263508Sdim  typedef SmallVectorImpl<MDNode *>::const_iterator iterator;
820263508Sdim  iterator compile_unit_begin() const { return CUs.begin(); }
821263508Sdim  iterator compile_unit_end() const { return CUs.end(); }
822263508Sdim  iterator subprogram_begin() const { return SPs.begin(); }
823263508Sdim  iterator subprogram_end() const { return SPs.end(); }
824263508Sdim  iterator global_variable_begin() const { return GVs.begin(); }
825263508Sdim  iterator global_variable_end() const { return GVs.end(); }
826263508Sdim  iterator type_begin() const { return TYs.begin(); }
827263508Sdim  iterator type_end() const { return TYs.end(); }
828263508Sdim  iterator scope_begin() const { return Scopes.begin(); }
829263508Sdim  iterator scope_end() const { return Scopes.end(); }
830263508Sdim
831263508Sdim  unsigned compile_unit_count() const { return CUs.size(); }
832263508Sdim  unsigned global_variable_count() const { return GVs.size(); }
833263508Sdim  unsigned subprogram_count() const { return SPs.size(); }
834263508Sdim  unsigned type_count() const { return TYs.size(); }
835263508Sdim  unsigned scope_count() const { return Scopes.size(); }
836263508Sdim
837263508Sdimprivate:
838263508Sdim  SmallVector<MDNode *, 8> CUs;    // Compile Units
839263508Sdim  SmallVector<MDNode *, 8> SPs;    // Subprograms
840263508Sdim  SmallVector<MDNode *, 8> GVs;    // Global Variables;
841263508Sdim  SmallVector<MDNode *, 8> TYs;    // Types
842263508Sdim  SmallVector<MDNode *, 8> Scopes; // Scopes
843263508Sdim  SmallPtrSet<MDNode *, 64> NodesSeen;
844263508Sdim  DITypeIdentifierMap TypeIdentifierMap;
845263508Sdim  /// Specify if TypeIdentifierMap is initialized.
846263508Sdim  bool TypeMapInitialized;
847263508Sdim};
848239310Sdim} // end namespace llvm
849239310Sdim
850239310Sdim#endif
851