<div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">On Tue, Sep 10, 2013 at 5:38 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div class="h5">On Tue, Sep 10, 2013 at 5:24 PM, Manman Ren <span dir="ltr"><<a href="mailto:manman.ren@gmail.com" target="_blank">manman.ren@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote"><div><div>On Tue, Sep 10, 2013 at 4:28 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">
<div>On Tue, Sep 10, 2013 at 3:31 PM, Manman Ren <span dir="ltr"><<a href="mailto:manman.ren@gmail.com" target="_blank">manman.ren@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><br><div class="gmail_extra"><br><br><div class="gmail_quote">
<div>On Tue, Sep 10, 2013 at 12:54 PM, David Blaikie <span dir="ltr"><<a href="mailto:dblaikie@gmail.com" target="_blank">dblaikie@gmail.com</a>></span> wrote:<br>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><p dir="ltr">I assume the specializations I've asked about are there because you didn't have a good way to generalize over scopes and types. What sort of solutions did you consider to avoid this duplication?</p>
</blockquote></div><div>By duplication, do you mean the template? </div></div></div></div></blockquote><div><br></div></div><div>The explicit specializations of the </div><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><div><br>
On Sep 10, 2013 11:35 AM, "Manman Ren" <<a href="mailto:manman.ren@gmail.com" target="_blank">manman.ren@gmail.com</a>> wrote:<br>
><br>
> Author: mren<br>
> Date: Tue Sep 10 13:30:07 2013<br>
> New Revision: 190418<br>
><br>
> URL: <a href="http://llvm.org/viewvc/llvm-project?rev=190418&view=rev" target="_blank">http://llvm.org/viewvc/llvm-project?rev=190418&view=rev</a><br>
> Log:<br>
> Debug Info: define a DIRef template.<br>
><br>
> Specialize the constructors for DIRef<DIScope> and DIRef<DIType> to make sure<br>
> the Value is indeed a scope ref and a type ref.<br>
><br>
> Use DIScopeRef for DIScope::getContext and DIType::getContext and use DITypeRef<br>
> for getContainingType and getClassType.<br>
><br>
> DIScope::generateRef now returns a DIScopeRef instead of a "Value *" for<br>
> readability and type safety.<br>
><br>
> Modified:<br>
> llvm/trunk/include/llvm/DebugInfo.h<br>
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
> llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
> llvm/trunk/lib/IR/DebugInfo.cpp<br>
><br>
> Modified: llvm/trunk/include/llvm/DebugInfo.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo.h?rev=190418&r1=190417&r2=190418&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/include/llvm/DebugInfo.h?rev=190418&r1=190417&r2=190418&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/include/llvm/DebugInfo.h (original)<br>
> +++ llvm/trunk/include/llvm/DebugInfo.h Tue Sep 10 13:30:07 2013<br>
> @@ -17,6 +17,7 @@<br>
> #ifndef LLVM_DEBUGINFO_H<br>
> #define LLVM_DEBUGINFO_H<br>
><br>
> +#include "llvm/Support/Casting.h"<br>
> #include "llvm/ADT/DenseMap.h"<br>
> #include "llvm/ADT/SmallPtrSet.h"<br>
> #include "llvm/ADT/SmallVector.h"<br>
> @@ -46,7 +47,7 @@ namespace llvm {<br>
> class DILexicalBlockFile;<br>
> class DIVariable;<br>
> class DIType;<br>
> - class DIScopeRef;<br>
> + class DIScope;<br>
> class DIObjCProperty;<br>
><br>
> /// Maps from type identifier to the actual MDNode.<br>
> @@ -56,9 +57,10 @@ namespace llvm {<br>
> /// This should not be stored in a container, because the underlying MDNode<br>
> /// may change in certain situations.<br>
> class DIDescriptor {<br>
> - // Befriends DIScopeRef so DIScopeRef can befriend the protected member<br>
> - // function: getFieldAs<DIScopeRef>.<br>
> - friend class DIScopeRef;<br>
> + // Befriends DIRef so DIRef can befriend the protected member<br>
> + // function: getFieldAs<DIRef>.<br>
> + template <typename T><br>
> + friend class DIRef;<br>
> public:<br>
> enum {<br>
> FlagPrivate = 1 << 0,<br>
> @@ -151,10 +153,6 @@ namespace llvm {<br>
> void dump() const;<br>
> };<br>
><br>
> - /// npecialize getFieldAs to handle fields that are references to DIScopes.<br>
> - template <><br>
> - DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;<br>
> -<br>
> /// DISubrange - This is used to represent ranges, for array bounds.<br>
> class DISubrange : public DIDescriptor {<br>
> friend class DIDescriptor;<br>
> @@ -192,6 +190,10 @@ namespace llvm {<br>
> bool Verify() const;<br>
> };<br>
><br>
> + template <typename T><br>
> + class DIRef;<br>
> + typedef DIRef<DIScope> DIScopeRef;</div></div><p></p>
<p dir="ltr">Where's the corresponding dityperef? Could we just declare it here for consistency?</p></blockquote></div></div><div>Sure, I can move it here. Right now, DITypeRef is after def of DIType. </div></div></div>
</div></blockquote><div><br></div></div></div><div>Given we already have a forward declaration of DIType up the top, we could move the typedef up here I think.</div><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><div>
<p dir="ltr">> +<br>
> /// DIScope - A base class for various scopes.<br>
> class DIScope : public DIDescriptor {<br>
> protected:<br>
> @@ -208,23 +210,7 @@ namespace llvm {<br>
><br>
> /// Generate a reference to this DIScope. Uses the type identifier instead<br>
> /// of the actual MDNode if possible, to help type uniquing.<br>
> - Value *generateRef();<br>
> - };<br>
> -<br>
> - /// Represents reference to a DIScope, abstracts over direct and<br>
> - /// identifier-based metadata scope references.<br>
> - class DIScopeRef {<br>
> - template <typename DescTy><br>
> - friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;<br>
> - friend DIScopeRef DIScope::getContext() const;<br>
> -<br>
> - /// Val can be either a MDNode or a MDString, in the latter,<br>
> - /// MDString specifies the type identifier.<br>
> - const Value *Val;<br>
> - explicit DIScopeRef(const Value *V);<br>
> - public:<br>
> - DIScope resolve(const DITypeIdentifierMap &Map) const;<br>
> - operator Value *() const { return const_cast<Value*>(Val); }<br>
> + DIScopeRef generateRef();<br>
> };<br>
><br>
> /// DIType - This is a wrapper for a type.<br>
> @@ -241,7 +227,7 @@ namespace llvm {<br>
> /// Verify - Verify that a type descriptor is well formed.<br>
> bool Verify() const;<br>
><br>
> - DIScopeRef getContext() const { return getFieldAs<DIScopeRef>(2); }<br>
> + DIScopeRef getContext() const;</p>
</div></div><p dir="ltr">Why did this become our of line?</p></blockquote></div></div><div>Because of dependency issues, </div></div></div></div></blockquote><div><br></div></div></div><div>What's the dependency cycle?</div>
<div><div>
</div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div>we can't construct a DIScopeRef here without a full definition.</div>
<div>And the full def of DIRef needs to be after the full def of DIType since we now have the def of DIRef::resolve in the header file.</div></div></div></div></blockquote><div><br></div></div><div>This seems a bit strange, since DIRef shouldn't be specific to type or scope, ideally.<br>
</div></div></div></div></blockquote><div><br></div></div></div><div>It was the assertion in resolve:</div><div><div><br></div><div><span style="color:rgb(80,0,80)">assert(DIType(Iter->second).</span><span style="color:rgb(80,0,80)">isType() &&</span><br style="color:rgb(80,0,80)">
<span style="color:rgb(80,0,80)">> + "MDNode in DITypeIdentifierMap should be a DIType.");</span></div><div><br></div></div><div>which requires the full def of DIType to compile. </div><div>But we should be able to change from DIType().isType() to DIDescriptor().isType().</div>
</div></div></div></blockquote><div><br></div></div></div><div>Right</div><div class="im"><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra">
<div class="gmail_quote">
<div>Then the def of DIRef will only need to be after DIScope because of</div><div><div><span style="color:rgb(80,0,80)">> + friend DIScopeRef DIScope::getContext() const;</span><br style="color:rgb(80,0,80)">
<span style="color:rgb(80,0,80)">> + friend DIScopeRef DIScope::generateRef();</span></div></div></div></div></div></blockquote><div><br></div></div><div>Why would it need to be after those? It'll be calling them on a dependent expression of type T, rather than type DIScope, right? So the template can appear before the definition of DIScope.<br>
</div></div></div></div></blockquote><div><br></div><div>Changing from DIScope::generateRef to T::generateRef means we need an implementation of DIType::generateRef.</div><div>For every T, we require an implementation of T::generateRef and T::getContext.</div>
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>
<br>Also - I'm still a bit dubious of "generateRef" - it should at least be const & I still think "getRef" might make more sense. </div></div></div></div></blockquote><div><br></div><div>Yes, we can constify generateRef. I am okay with changing it to getRef, but the other get functions usually mean accessing a field.</div>
<div><br></div><div>Manman</div><div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div>Or we could make a public (explicit) ctor for DIRef<T> from const T&? But I suppose that'd be different between a DIScope and a DIType, etc... so that's not great.</div>
<div><div class="h5">
<div> </div><blockquote class="gmail_quote" style="margin:0 0 0 .8ex;border-left:1px #ccc solid;padding-left:1ex"><div dir="ltr"><div class="gmail_extra"><div class="gmail_quote"><div><div><br>
</div><div><br></div></div><span><font color="#888888"><div>Manman</div></font></span><div><div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr">
<div class="gmail_extra"><div class="gmail_quote"><div>
<br>So I assume the reason that DIRef is specific to type is for use of DIDescriptor::isType rather than isScope. Is there some way we could generalize over these based on the template parameter to DIRef?<br><br>Eric - this is a question for you too. If the "isFoo" functions were instead members of the relevant DI* functions ("isValid" or is that too subtly different to "Verify"?) then we could use "bool T::is()" (bikeshed as appropriate) in this template.<br>
<br>Of course that would mean rewriting existing calls to x.isFoo() functions into <a href="http://x.is" target="_blank">x.is</a>() or Foo(x).is(), or keeping the duplicates (which would seem a bit unfortunate).</div><div>
<div><div> </div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra"><div class="gmail_quote">
<div>Moving resolve to the header file is to avoid a link error. </div></div></div></div></blockquote><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div dir="ltr"><div class="gmail_extra">
<div class="gmail_quote"><div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div><div>
<p dir="ltr">> StringRef getName() const { return getStringField(3); }<br>
> unsigned getLineNumber() const { return getUnsignedField(4); }<br>
> uint64_t getSizeInBits() const { return getUInt64Field(5); }<br>
> @@ -297,6 +283,53 @@ namespace llvm {<br>
> void replaceAllUsesWith(MDNode *D);<br>
> };<br>
><br>
> + /// Represents reference to a DIDescriptor, abstracts over direct and<br>
> + /// identifier-based metadata references.<br>
> + template <typename T><br>
> + class DIRef {<br>
> + template <typename DescTy><br>
> + friend DescTy DIDescriptor::getFieldAs(unsigned Elt) const;<br>
> + friend DIScopeRef DIScope::getContext() const;<br>
> + friend DIScopeRef DIScope::generateRef();<br>
> +<br>
> + /// Val can be either a MDNode or a MDString, in the latter,<br>
> + /// MDString specifies the type identifier.<br>
> + const Value *Val;<br>
> + explicit DIRef(const Value *V);<br>
> + public:<br>
> + T resolve(const DITypeIdentifierMap &Map) const {<br>
> + if (!Val)<br>
> + return T();<br>
> +<br>
> + if (const MDNode *MD = dyn_cast<MDNode>(Val))<br>
> + return T(MD);<br>
> +<br>
> + const MDString *MS = cast<MDString>(Val);<br>
> + // Find the corresponding MDNode.<br>
> + DITypeIdentifierMap::const_iterator Iter = Map.find(MS);<br>
> + assert(Iter != Map.end() && "Identifier not in the type map?");<br>
> + assert(DIType(Iter->second).isType() &&<br>
> + "MDNode in DITypeIdentifierMap should be a DIType.");</p>
</div></div><p dir="ltr">Could we write this generically somehow? This looks like a type-secific (doesn't work for scopes) implementation.</p></blockquote></div></div><div>The MDNode found in the TypeIdentifierMap should be a DIType, right? </div>
<div>
<blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex"><div>
<p dir="ltr">> + return T(Iter->second);<br>
> + }<br>
> + operator Value *() const { return const_cast<Value*>(Val); }<br>
> + };<br>
> +<br>
> + /// Specialize getFieldAs to handle fields that are references to DIScopes.<br>
> + template <><br>
> + DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const;<br>
> + /// Specialize DIRef constructor for DIScopeRef.</p>
</div><p dir="ltr">Why?</p></blockquote></div><div>Just to have more specific checking of the passed-in Value: use isScopeRef in the constructor. </div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div>
<p dir="ltr">> + template <><br>
> + DIRef<DIScope>::DIRef(const Value *V);<br>
> +<br>
> + typedef DIRef<DIType> DITypeRef;<br>
> + /// Specialize getFieldAs to handle fields that are references to DITypes.<br>
> + template <><br>
> + DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const;<br>
> + /// Specialize DIRef constructor for DITypeRef.<br>
> + template <><br>
> + DIRef<DIType>::DIRef(const Value *V);</p>
</div><p dir="ltr">And this ?</p></blockquote></div><div>To have more specific checking of the passed-in Value: use isTypeRef in the constructor.</div><span><font color="#888888"><div><br></div><div>Manman </div>
</font></span><div><div><blockquote class="gmail_quote" style="margin:0px 0px 0px 0.8ex;border-left-width:1px;border-left-color:rgb(204,204,204);border-left-style:solid;padding-left:1ex">
<div><div>
<p dir="ltr">> +<br>
> /// DIBasicType - A basic type, like 'int' or 'float'.<br>
> class DIBasicType : public DIType {<br>
> public:<br>
> @@ -328,9 +361,9 @@ namespace llvm {<br>
> /// associated with one.<br>
> MDNode *getObjCProperty() const;<br>
><br>
> - DIScopeRef getClassType() const {<br>
> + DITypeRef getClassType() const {<br>
> assert(getTag() == dwarf::DW_TAG_ptr_to_member_type);<br>
> - return getFieldAs<DIScopeRef>(10);<br>
> + return getFieldAs<DITypeRef>(10);<br>
> }<br>
><br>
> Constant *getConstant() const {<br>
> @@ -358,8 +391,8 @@ namespace llvm {<br>
> void setTypeArray(DIArray Elements, DIArray TParams = DIArray());<br>
> void addMember(DIDescriptor D);<br>
> unsigned getRunTimeLang() const { return getUnsignedField(11); }<br>
> - DIScopeRef getContainingType() const {<br>
> - return getFieldAs<DIScopeRef>(12);<br>
> + DITypeRef getContainingType() const {<br>
> + return getFieldAs<DITypeRef>(12);<br>
> }<br>
> void setContainingType(DICompositeType ContainingType);<br>
> DIArray getTemplateParams() const { return getFieldAs<DIArray>(13); }<br>
> @@ -426,8 +459,8 @@ namespace llvm {<br>
> unsigned getVirtuality() const { return getUnsignedField(10); }<br>
> unsigned getVirtualIndex() const { return getUnsignedField(11); }<br>
><br>
> - DIScopeRef getContainingType() const {<br>
> - return getFieldAs<DIScopeRef>(12);<br>
> + DITypeRef getContainingType() const {<br>
> + return getFieldAs<DITypeRef>(12);<br>
> }<br>
><br>
> unsigned getFlags() const {<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=190418&r1=190417&r2=190418&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp?rev=190418&r1=190417&r2=190418&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp (original)<br>
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.cpp Tue Sep 10 13:30:07 2013<br>
> @@ -2644,8 +2644,3 @@ void DwarfDebug::emitDebugStrDWO() {<br>
> InfoHolder.emitStrings(Asm->getObjFileLowering().getDwarfStrDWOSection(),<br>
> OffSec, StrSym);<br>
> }<br>
> -<br>
> -/// Find the MDNode for the given scope reference.<br>
> -DIScope DwarfDebug::resolve(DIScopeRef SRef) const {<br>
> - return SRef.resolve(TypeIdentifierMap);<br>
> -}<br>
><br>
> Modified: llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=190418&r1=190417&r2=190418&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h?rev=190418&r1=190417&r2=190418&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h (original)<br>
> +++ llvm/trunk/lib/CodeGen/AsmPrinter/DwarfDebug.h Tue Sep 10 13:30:07 2013<br>
> @@ -684,7 +684,10 @@ public:<br>
> unsigned getDwarfVersion() const { return DwarfVersion; }<br>
><br>
> /// Find the MDNode for the given scope reference.<br>
> - DIScope resolve(DIScopeRef SRef) const;<br>
> + template <typename T><br>
> + T resolve(DIRef<T> Ref) const {<br>
> + return Ref.resolve(TypeIdentifierMap);<br>
> + }<br>
><br>
> /// isSubprogramContext - Return true if Context is either a subprogram<br>
> /// or another context nested inside a subprogram.<br>
><br>
> Modified: llvm/trunk/lib/IR/DebugInfo.cpp<br>
> URL: <a href="http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfo.cpp?rev=190418&r1=190417&r2=190418&view=diff" target="_blank">http://llvm.org/viewvc/llvm-project/llvm/trunk/lib/IR/DebugInfo.cpp?rev=190418&r1=190417&r2=190418&view=diff</a><br>
> ==============================================================================<br>
> --- llvm/trunk/lib/IR/DebugInfo.cpp (original)<br>
> +++ llvm/trunk/lib/IR/DebugInfo.cpp Tue Sep 10 13:30:07 2013<br>
> @@ -725,13 +725,13 @@ void DICompositeType::addMember(DIDescri<br>
><br>
> /// Generate a reference to this DIType. Uses the type identifier instead<br>
> /// of the actual MDNode if possible, to help type uniquing.<br>
> -Value *DIScope::generateRef() {<br>
> +DIScopeRef DIScope::generateRef() {<br>
> if (!isCompositeType())<br>
> - return *this;<br>
> + return DIScopeRef(*this);<br>
> DICompositeType DTy(DbgNode);<br>
> if (!DTy.getIdentifier())<br>
> - return *this;<br>
> - return DTy.getIdentifier();<br>
> + return DIScopeRef(*this);<br>
> + return DIScopeRef(DTy.getIdentifier());<br>
> }<br>
><br>
> /// \brief Set the containing type.<br>
> @@ -1432,26 +1432,14 @@ void DIVariable::printExtendedName(raw_o<br>
> }<br>
> }<br>
><br>
> -DIScopeRef::DIScopeRef(const Value *V) : Val(V) {<br>
> +/// Specialize constructor to make sure it has the correct type.<br>
> +template <><br>
> +DIRef<DIScope>::DIRef(const Value *V) : Val(V) {<br>
> assert(isScopeRef(V) && "DIScopeRef should be a MDString or MDNode");<br>
> }<br>
> -<br>
> -/// Given a DITypeIdentifierMap, tries to find the corresponding<br>
> -/// DIScope for a DIScopeRef.<br>
> -DIScope DIScopeRef::resolve(const DITypeIdentifierMap &Map) const {<br>
> - if (!Val)<br>
> - return DIScope();<br>
> -<br>
> - if (const MDNode *MD = dyn_cast<MDNode>(Val))<br>
> - return DIScope(MD);<br>
> -<br>
> - const MDString *MS = cast<MDString>(Val);<br>
> - // Find the corresponding MDNode.<br>
> - DITypeIdentifierMap::const_iterator Iter = Map.find(MS);<br>
> - assert(Iter != Map.end() && "Identifier not in the type map?");<br>
> - assert(DIType(Iter->second).isType() &&<br>
> - "MDNode in DITypeIdentifierMap should be a DIType.");<br>
> - return DIScope(Iter->second);<br>
> +template <><br>
> +DIRef<DIType>::DIRef(const Value *V) : Val(V) {<br>
> + assert(isTypeRef(V) && "DITypeRef should be a MDString or MDNode");<br>
> }<br>
><br>
> /// Specialize getFieldAs to handle fields that are references to DIScopes.<br>
> @@ -1459,3 +1447,12 @@ template <><br>
> DIScopeRef DIDescriptor::getFieldAs<DIScopeRef>(unsigned Elt) const {<br>
> return DIScopeRef(getField(DbgNode, Elt));<br>
> }<br>
> +/// Specialize getFieldAs to handle fields that are references to DITypes.<br>
> +template <><br>
> +DITypeRef DIDescriptor::getFieldAs<DITypeRef>(unsigned Elt) const {<br>
> + return DITypeRef(getField(DbgNode, Elt));<br>
> +}<br>
> +<br>
> +DIScopeRef DIType::getContext() const {<br>
> + return getFieldAs<DIScopeRef>(2);<br>
> +}<br>
><br>
><br>
> _______________________________________________<br>
> llvm-commits mailing list<br>
> <a href="mailto:llvm-commits@cs.uiuc.edu" target="_blank">llvm-commits@cs.uiuc.edu</a><br>
> <a href="http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits" target="_blank">http://lists.cs.uiuc.edu/mailman/listinfo/llvm-commits</a><br>
</p>
</div></div></blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div></div></div><br></div></div>
</blockquote></div><br></div></div>