Skip to content

Commit

Permalink
DebugInfo: Create MDTypeRef, etc., to replace DITypeRef
Browse files Browse the repository at this point in the history
Create a string-based wrapper in the debug info hierarchy for type
references.

git-svn-id: https://llvm.org/svn/llvm-project/llvm/trunk@234188 91177308-0d34-0410-b5e6-96231b3b80d8
  • Loading branch information
dexonsmith committed Apr 6, 2015
1 parent 3a69ccd commit 05652b6
Show file tree
Hide file tree
Showing 3 changed files with 81 additions and 8 deletions.
6 changes: 6 additions & 0 deletions include/llvm/IR/DebugInfo.h
Original file line number Diff line number Diff line change
Expand Up @@ -290,6 +290,12 @@ template <typename T> class DIRef {
explicit DIRef(const Metadata *V);

public:
template <class U>
DIRef(const TypedDebugNodeRef<U> &Ref,
typename std::enable_if<std::is_convertible<U *, T>::value>::type * =
nullptr)
: Val(Ref) {}

T resolve(const DITypeIdentifierMap &Map) const;
operator Metadata *() const { return const_cast<Metadata *>(Val); }

Expand Down
74 changes: 74 additions & 0 deletions include/llvm/IR/DebugInfoMetadata.h
Original file line number Diff line number Diff line change
Expand Up @@ -41,6 +41,54 @@

namespace llvm {

/// \brief Pointer union between a subclass of DebugNode and MDString.
///
/// \a MDCompositeType can be referenced via an \a MDString unique identifier.
/// This class allows some type safety in the face of that, requiring either a
/// node of a particular type or an \a MDString.
template <class T> class TypedDebugNodeRef {
const Metadata *MD = nullptr;

public:
TypedDebugNodeRef(std::nullptr_t) {}

/// \brief Construct from a raw pointer.
explicit TypedDebugNodeRef(const Metadata *MD) : MD(MD) {
assert((!MD || isa<MDString>(MD) || isa<T>(MD)) && "Expected valid ref");
}

template <class U>
TypedDebugNodeRef(
const TypedDebugNodeRef<U> &X,
typename std::enable_if<std::is_convertible<U *, T *>::value>::type * =
nullptr)
: MD(X) {}

operator Metadata *() const { return const_cast<Metadata *>(MD); }

bool operator==(const TypedDebugNodeRef<T> &X) const { return MD == X.MD; };
bool operator!=(const TypedDebugNodeRef<T> &X) const { return MD != X.MD; };

/// \brief Create a reference.
///
/// Get a reference to \c N, using an \a MDString reference if available.
static TypedDebugNodeRef get(const T *N);

template <class MapTy> T *resolve(const MapTy &Map) const {
if (auto *Typed = dyn_cast<T>(MD))
return const_cast<T *>(Typed);

auto *S = cast<MDString>(MD);
auto I = Map.find(S);
assert(I != Map.end() && "Missing identifier in type map");
return cast<T>(I->second);
}
};

typedef TypedDebugNodeRef<DebugNode> DebugNodeRef;
typedef TypedDebugNodeRef<MDScope> MDScopeRef;
typedef TypedDebugNodeRef<MDType> MDTypeRef;

/// \brief Tagged DWARF-like metadata node.
///
/// A metadata node with a DWARF tag (i.e., a constant named \c DW_TAG_*,
Expand Down Expand Up @@ -88,6 +136,8 @@ class DebugNode : public MDNode {
FlagAccessibility = FlagPrivate | FlagProtected | FlagPublic
};

DebugNodeRef getRef() const { return DebugNodeRef::get(this); }

static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
Expand Down Expand Up @@ -116,6 +166,18 @@ class DebugNode : public MDNode {
}
};

template <class T>
struct simplify_type<const TypedDebugNodeRef<T>> {
typedef Metadata *SimpleType;
static SimpleType getSimplifiedValue(const TypedDebugNodeRef<T> &MD) {
return MD;
}
};

template <class T>
struct simplify_type<TypedDebugNodeRef<T>>
: simplify_type<const TypedDebugNodeRef<T>> {};

/// \brief Generic tagged DWARF-like metadata node.
///
/// An un-specialized DWARF-like metadata node. The first operand is a
Expand Down Expand Up @@ -305,6 +367,8 @@ class MDScope : public DebugNode {
: static_cast<Metadata *>(getOperand(0));
}

MDScopeRef getRef() const { return MDScopeRef::get(this); }

static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
Expand Down Expand Up @@ -414,6 +478,8 @@ class MDType : public MDScope {
Flags = NewFlags;
}

MDTypeRef getRef() const { return MDTypeRef::get(this); }

static bool classof(const Metadata *MD) {
switch (MD->getMetadataID()) {
default:
Expand Down Expand Up @@ -724,6 +790,14 @@ class MDCompositeType : public MDCompositeTypeBase {
}
};

template <class T> TypedDebugNodeRef<T> TypedDebugNodeRef<T>::get(const T *N) {
if (N)
if (auto *Composite = dyn_cast<MDCompositeType>(N))
if (auto *S = Composite->getRawIdentifier())
return TypedDebugNodeRef<T>(S);
return TypedDebugNodeRef<T>(N);
}

/// \brief Type array for a subprogram.
///
/// TODO: Detach from CompositeType, and fold the array of types in directly
Expand Down
9 changes: 1 addition & 8 deletions lib/IR/DebugInfo.cpp
Original file line number Diff line number Diff line change
Expand Up @@ -253,14 +253,7 @@ void DICompositeType::setArraysHelper(MDNode *Elements, MDNode *TParams) {
DbgNode = N;
}

DIScopeRef DIScope::getRef() const {
if (!isCompositeType())
return DIScopeRef(*this);
DICompositeType DTy(DbgNode);
if (!DTy.getIdentifier())
return DIScopeRef(*this);
return DIScopeRef(DTy.getIdentifier());
}
DIScopeRef DIScope::getRef() const { return MDScopeRef::get(get()); }

void DICompositeType::setContainingType(DICompositeType ContainingType) {
TypedTrackingMDRef<MDCompositeTypeBase> N(get());
Expand Down

0 comments on commit 05652b6

Please sign in to comment.