<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>