<html>
    <head>
      <base href="https://llvm.org/bugs/" />
    </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 --- - RecordDecl::LoadFieldsFromExternalStorage() expels existing decls from the DeclContext linked list"
   href="https://llvm.org/bugs/show_bug.cgi?id=24420">24420</a>
          </td>
        </tr>

        <tr>
          <th>Summary</th>
          <td>RecordDecl::LoadFieldsFromExternalStorage() expels existing decls from the DeclContext linked list
          </td>
        </tr>

        <tr>
          <th>Product</th>
          <td>clang
          </td>
        </tr>

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

        <tr>
          <th>Hardware</th>
          <td>All
          </td>
        </tr>

        <tr>
          <th>OS</th>
          <td>All
          </td>
        </tr>

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

        <tr>
          <th>Severity</th>
          <td>normal
          </td>
        </tr>

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

        <tr>
          <th>Component</th>
          <td>-New Bugs
          </td>
        </tr>

        <tr>
          <th>Assignee</th>
          <td>unassignedclangbugs@nondot.org
          </td>
        </tr>

        <tr>
          <th>Reporter</th>
          <td>syniurge@gmail.com
          </td>
        </tr>

        <tr>
          <th>CC</th>
          <td>llvm-bugs@lists.llvm.org
          </td>
        </tr>

        <tr>
          <th>Classification</th>
          <td>Unclassified
          </td>
        </tr></table>
      <p>
        <div>
        <pre>Unlike DeclContext::LoadLexicalDeclsFromExternalStorage() which preserve
existing decls with:

  // Splice the newly-read declarations into the beginning of the list
  // of declarations.
  Decl *ExternalFirst, *ExternalLast;
  std::tie(ExternalFirst, ExternalLast) =
      BuildDeclChain(Decls, FieldsAlreadyLoaded);
  ExternalLast->NextInContextAndBits.setPointer(FirstDecl);
  FirstDecl = ExternalFirst;
  if (!LastDecl)
    LastDecl = ExternalLast;

RecordDecl::LoadFieldsFromExternalStorage() resets the linked list:

  std::tie(FirstDecl, LastDecl) = BuildDeclChain(Decls,
/*FieldsAlreadyLoaded=*/false);

Assuming it to be empty may be correct most of the time but in my particular
usage of Clang this becomes a serious hassle because implicit
constructors/operators/etc. may be declared before
RecordDecl::LoadFieldsFromExternalStorage() gets called, there's no way to
control this and the only workaround I've found is to traverse the entire PCH's
AST before doing anything to ensure the fields get deserialized before implicit
methods get declared by Sema, which defeats the benefits of lazy
deserialization.

(The implicit methods are still returned by Sema::LookupXXXX after being
expelled, and they still believe their lexical decl context to be the record,
despite missing from a dump())</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>