class DILexicalBlockFile;
class DIVariable;
class DIType;
- class DITypeRef;
+ class DIScopeRef;
class DIObjCProperty;
/// Maps from type identifier to the actual MDNode.
/// This should not be stored in a container, because the underlying MDNode
/// may change in certain situations.
class DIDescriptor {
- // Befriends DITypeRef so DITypeRef can befriend the protected member
- // function: getFieldAs<DITypeRef>.
- friend class DITypeRef;
+ // Befriends DIScopeRef so DIScopeRef can befriend the protected member
+ // function: getFieldAs<DIScopeRef>.
+ friend class DIScopeRef;
public:
enum {
FlagPrivate = 1 << 0,
void dump() const;
};
- /// Specialize getFieldAs to handle fields that are references to DITypes.
+ /// npecialize getFieldAs to handle fields that are references to DIScopes.
template <>
- DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
+ DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
/// DISubrange - This is used to represent ranges, for array bounds.
class DISubrange : public DIDescriptor {
DIScope getContext() const;
StringRef getFilename() const;
StringRef getDirectory() const;
+
+ /// Generate a reference to this DIScope. Uses the type identifier instead
+ /// of the actual MDNode if possible, to help type uniquing.
+ Value *generateRef();
+ };
+
+ /// Represents reference to a DIScope, abstracts over direct and
+ /// identifier-based metadata scope references.
+ class DIScopeRef {
+ template <typename DescTy>
+ friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
+
+ /// Val can be either a MDNode or a MDString, in the latter,
+ /// MDString specifies the type identifier.
+ const Value *Val;
+ explicit DIScopeRef(const Value *V);
+ public:
+ DIScope resolve(const DITypeIdentifierMap &Map) const;
+ operator Value *() const { return const_cast<Value*>(Val); }
};
/// DIType - This is a wrapper for a type.
/// isUnsignedDIType - Return true if type encoding is unsigned.
bool isUnsignedDIType();
- /// Generate a reference to this DIType. Uses the type identifier instead
- /// of the actual MDNode if possible, to help type uniquing.
- DITypeRef generateRef();
-
/// replaceAllUsesWith - Replace all uses of debug info referenced by
/// this descriptor.
void replaceAllUsesWith(DIDescriptor &D);
void replaceAllUsesWith(MDNode *D);
};
- /// Represents reference to a DIType, abstracts over direct and
- /// identifier-based metadata type references.
- class DITypeRef {
- template <typename DescTy>
- friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;
- friend DITypeRef DIType::generateRef();
-
- /// TypeVal can be either a MDNode or a MDString, in the latter,
- /// MDString specifies the type identifier.
- const Value *TypeVal;
- explicit DITypeRef(const Value *V);
- public:
- DIType resolve(const DITypeIdentifierMap &Map) const;
- operator Value *() const { return const_cast<Value*>(TypeVal); }
- };
-
/// DIBasicType - A basic type, like 'int' or 'float'.
class DIBasicType : public DIType {
public:
/// associated with one.
MDNode *getObjCProperty() const;
- DITypeRef getClassType() const {
+ DIScopeRef getClassType() const {
assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);
- return getFieldAs<DITypeRef>(10);
+ return getFieldAs<DIScopeRef>(10);
}
Constant *getConstant() const {
void setTypeArray(DIArray Elements, DIArray TParams = DIArray());
void addMember(DIDescriptor D);
unsigned getRunTimeLang() const { return getUnsignedField(11); }
- DITypeRef getContainingType() const {
- return getFieldAs<DITypeRef>(12);
+ DIScopeRef getContainingType() const {
+ return getFieldAs<DIScopeRef>(12);
}
void setContainingType(DICompositeType ContainingType);
DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }
unsigned getVirtuality() const { return getUnsignedField(10); }
unsigned getVirtualIndex() const { return getUnsignedField(11); }
- DITypeRef getContainingType() const {
- return getFieldAs<DITypeRef>(12);
+ DIScopeRef getContainingType() const {
+ return getFieldAs<DIScopeRef>(12);
}
unsigned getFlags() const {
return !Fld || isa<MDString>(Fld);
}
-/// Check if a value can be a TypeRef.
+/// Check if a value can be a reference to a type.
static bool isTypeRef(const Value *Val) {
- return !Val || isa<MDString>(Val) || isa<MDNode>(Val);
+ return !Val ||
+ (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
+ (isa<MDNode>(Val) && DIType(cast<MDNode>(Val)).isType());
}
-/// Check if a field at position Elt of a MDNode can be a TypeRef.
+/// Check if a field at position Elt of a MDNode can be a reference to a type.
static bool fieldIsTypeRef(const MDNode *DbgNode, unsigned Elt) {
Value *Fld = getField(DbgNode, Elt);
return isTypeRef(Fld);
}
+/// Check if a value can be a ScopeRef.
+static bool isScopeRef(const Value *Val) {
+ return !Val ||
+ (isa<MDString>(Val) && !cast<MDString>(Val)->getString().empty()) ||
+ (isa<MDNode>(Val) && DIScope(cast<MDNode>(Val)).isScope());
+}
+
/// Verify - Verify that a type descriptor is well formed.
bool DIType::Verify() const {
if (!isType())
/// Generate a reference to this DIType. Uses the type identifier instead
/// of the actual MDNode if possible, to help type uniquing.
-DITypeRef DIType::generateRef() {
+Value *DIScope::generateRef() {
if (!isCompositeType())
- return DITypeRef(*this);
+ return *this;
DICompositeType DTy(DbgNode);
if (!DTy.getIdentifier())
- return DITypeRef(*this);
- return DITypeRef(DTy.getIdentifier());
+ return *this;
+ return DTy.getIdentifier();
}
/// \brief Set the containing type.
}
}
-DITypeRef::DITypeRef(const Value *V) : TypeVal(V) {
- assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode");
+DIScopeRef::DIScopeRef(const Value *V) : Val(V) {
+ assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode");
}
/// Given a DITypeIdentifierMap, tries to find the corresponding
-/// DIType for a DITypeRef.
-DIType DITypeRef::resolve(const DITypeIdentifierMap &Map) const {
- if (!TypeVal)
- return NULL;
-
- if (const MDNode *MD = dyn_cast<MDNode>(TypeVal)) {
- assert(DIType(MD).isType() &&
- "MDNode in DITypeRef should be a DIType.");
- return MD;
- }
+/// DIScope for a DIScopeRef.
+DIScope DIScopeRef::resolve(const DITypeIdentifierMap &Map) const {
+ if (!Val)
+ return DIScope();
+
+ if (const MDNode *MD = dyn_cast<MDNode>(Val))
+ return DIScope(MD);
- const MDString *MS = cast<MDString>(TypeVal);
+ const MDString *MS = cast<MDString>(Val);
// Find the corresponding MDNode.
DITypeIdentifierMap::const_iterator Iter = Map.find(MS);
assert(Iter != Map.end() && "Identifier not in the type map?");
assert(DIType(Iter->second).isType() &&
"MDNode in DITypeIdentifierMap should be a DIType.");
- return Iter->second;
+ return DIScope(Iter->second);
}
-/// Specialize getFieldAs to handle fields that are references to DITypes.
+/// Specialize getFieldAs to handle fields that are references to DIScopes.
template <>
-DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const {
- return DITypeRef(getField(DbgNode, Elt));
+DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const {
+ return DIScopeRef(getField(DbgNode, Elt));
}