<html>
    <head>
      <base href="https://bugs.llvm.org/">
    </head>
    <body><table border="1" cellspacing="0" cellpadding="8">
        <tr>
          <th>Bug ID</th>
          <td><a class="bz_bug_link 
          bz_status_NEW "
   title="NEW - clang-cl doesn't emit LF_NESTTYPE records for nested template instantiations"
   href="https://bugs.llvm.org/show_bug.cgi?id=39607">39607</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>clang-cl doesn't emit LF_NESTTYPE records for nested template instantiations
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>libraries
          </td>
        </tr>

        <tr>
          <th>Version</th>
          <td>trunk
          </td>
        </tr>

        <tr>
          <th>Hardware</th>
          <td>PC
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>Windows NT
          </td>
        </tr>

        <tr>
          <th>Status</th>
          <td>NEW
          </td>
        </tr>

        <tr>
          <th>Severity</th>
          <td>enhancement
          </td>
        </tr>

        <tr>
          <th>Priority</th>
          <td>P
          </td>
        </tr>

        <tr>
          <th>Component</th>
          <td>DebugInfo
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>rnk@google.com
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>zturner@google.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>aleksandr.urakov@jetbrains.com, jdevlieghere@apple.com, llvm-bugs@lists.llvm.org, mosescu@google.com
          </td>
        </tr></table>
      <p>
        <div>
        <pre>struct U {
  template<typename Param>
  struct V { };
};

template<typename T>
void foo() {
  T t;
}

int main(int argc, char **argv) {
  foo<U>();
  foo<U::V<int>>();
  return 0;
}

MSVC will output this in the field list for U.


  0x1004 | LF_STRUCTURE [size = 48] `U::V<int>`
           unique name: `.?AU?$V@H@U@@`
           vtable: <no type>, base list: <no type>, field list: <no type>
           options: forward ref (-> 0x1008) | has unique name | is nested,
sizeof 0
  0x1005 | LF_FIELDLIST [size = 20]
           - LF_NESTTYPE [name = `?$V@H`, parent = 0x1004]
  0x1006 | LF_STRUCTURE [size = 32] `U`
           unique name: `.?AUU@@`
           vtable: <no type>, base list: <no type>, field list: 0x1005
           options: contains nested class | has unique name, sizeof 1

We do not output this LF_NESTTYPE at all.  This is useful when parsing debug
info in order to be able to reconstruct the DeclContext hierarchy to build an
AST from the debug info.  Without this, we won't be able to figure out what
DeclContext to put these nested template instantiations into.

With it, the algorithm is:

1) We found an LF_STRUCTURE with the contains nested class flag set.
2) We walk it's field list, find the LF_NESTTYPE.
3) It points to 0x1004, so we load the unique name for record 0x1004, call this
`actual`
4) Make a copy of the unique name from record 0x1006, insert the nested type at
offset 4, set offset 3 to actual[3], and compare the strings.
5) If they're the same, We create a definition of U::V<int> inside of U,
otherwise it's an alias (e.g. template<typename T> using V<T> = {0x1004});</pre>
        </div>
      </p>


      <hr>
      <span>You are receiving this mail because:</span>

      <ul>
          <li>You are on the CC list for the bug.</li>
      </ul>
    </body>
</html>