-template <typename T>
-T DIRef<T>::resolve(const DITypeIdentifierMap &Map) const {
- if (!Val)
- return T();
-
- if (const MDNode *MD = dyn_cast<MDNode>(Val))
- return T(MD);
-
- 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(DIDescriptor(Iter->second).isType() &&
- "MDNode in DITypeIdentifierMap should be a DIType.");
- return T(Iter->second);
-}
-
-template <typename T> StringRef DIRef<T>::getName() const {
- if (!Val)
- return StringRef();
-
- if (const MDNode *MD = dyn_cast<MDNode>(Val))
- return T(MD).getName();
-
- const MDString *MS = cast<MDString>(Val);
- return MS->getString();
-}
-
-/// \brief Handle fields that are references to DIScopes.
-template <> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DIScopeRef.
-template <> DIRef<DIScope>::DIRef(const Metadata *V);
-
-/// \brief Handle fields that are references to DITypes.
-template <> DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;
-/// \brief Specialize DIRef constructor for DITypeRef.
-template <> DIRef<DIType>::DIRef(const Metadata *V);
-
-/// \brief This is a wrapper for a type.
-///
-/// FIXME: Types should be factored much better so that CV qualifiers and
-/// others do not require a huge and empty descriptor full of zeros.
-class DIType : public DIScope {
-protected:
- friend class DIDescriptor;
- void printInternal(raw_ostream &OS) const;
-
-public:
- explicit DIType(const MDNode *N = nullptr) : DIScope(N) {}
- operator DITypeRef() const {
- assert(isType() &&
- "constructing DITypeRef from an MDNode that is not a type");
- return DITypeRef(&*getRef());
- }
-
- bool Verify() const;
-
- DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }
- StringRef getName() const { return getHeaderField(1); }
- unsigned getLineNumber() const { return getHeaderFieldAs<unsigned>(2); }
- uint64_t getSizeInBits() const { return getHeaderFieldAs<unsigned>(3); }
- uint64_t getAlignInBits() const { return getHeaderFieldAs<unsigned>(4); }
- // FIXME: Offset is only used for DW_TAG_member nodes. Making every type
- // carry this is just plain insane.
- uint64_t getOffsetInBits() const { return getHeaderFieldAs<unsigned>(5); }
- unsigned getFlags() const { return getHeaderFieldAs<unsigned>(6); }
- bool isPrivate() const {
- return (getFlags() & FlagAccessibility) == FlagPrivate;
- }
- bool isProtected() const {
- return (getFlags() & FlagAccessibility) == FlagProtected;
- }
- bool isPublic() const {
- return (getFlags() & FlagAccessibility) == FlagPublic;
- }
- bool isForwardDecl() const { return (getFlags() & FlagFwdDecl) != 0; }
- bool isAppleBlockExtension() const {
- return (getFlags() & FlagAppleBlock) != 0;
- }
- bool isBlockByrefStruct() const {
- return (getFlags() & FlagBlockByrefStruct) != 0;
- }
- bool isVirtual() const { return (getFlags() & FlagVirtual) != 0; }
- bool isArtificial() const { return (getFlags() & FlagArtificial) != 0; }
- bool isObjectPointer() const { return (getFlags() & FlagObjectPointer) != 0; }
- bool isObjcClassComplete() const {
- return (getFlags() & FlagObjcClassComplete) != 0;
- }
- bool isVector() const { return (getFlags() & FlagVector) != 0; }
- bool isStaticMember() const { return (getFlags() & FlagStaticMember) != 0; }
- bool isLValueReference() const {
- return (getFlags() & FlagLValueReference) != 0;
- }
- bool isRValueReference() const {
- return (getFlags() & FlagRValueReference) != 0;
- }
- bool isValid() const { return DbgNode && isType(); }
-};