[PATCH] D44100: [ASTImporter] Reorder fields after structure import is finished

Gabor Marton via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Thu Dec 6 09:53:32 PST 2018


martong added a comment.

Hey Alexey,

Here is what I found so far:
The new assertion is this:

  Assertion failed: (ToRD == ToD->getDeclContext() && ToRD->containsDecl(ToD)), function ImportDeclContext

ToRD looks like this in code:

  typedef struct __sFILE {
     // several fields here ...
  } FILE;

And the AST:

  CXXRecordDecl 0x7f87ce97d488 </Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX10.14.sdk/usr/include/_stdio.h:126:9, col:16> col:16 struct __sFILE definition
  |-DefinitionData pass_in_registers aggregate standard_layout trivially_copyable pod trivial literal
  | |-DefaultConstructor exists trivial needs_implicit
  | |-CopyConstructor simple trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveConstructor exists simple trivial needs_implicit
  | |-CopyAssignment trivial has_const_param needs_implicit implicit_has_const_param
  | |-MoveAssignment exists simple trivial needs_implicit
  | `-Destructor simple irrelevant trivial needs_implicit
  |-CXXRecordDecl 0x7f87d1886000 <col:9, col:16> col:16 implicit struct __sFILE
  | `-<undeserialized declarations>
  `-<undeserialized declarations>

I dug deeper and this is because `ToRD` is not equal with `ToD->getDeclContext()`.
However, if I load the fields of `ToRD` and then dump it seems to be structurally equivalent with `ToD->getDeclContext()`.
Both `ToRD` and `ToD->getDeclContext()` are part of a Decl chain with one element, this is true for `FromRD` and `D->getDeclContext()`. So I suspect some sort of lookup problem here: first we import the declContext during the import of a field, then when we do `auto ImportedDC = import(cast<Decl>(FromDC));` where we fail to find the first imported DeclContext. I suspect that this is because typedef hides the real struct, I mean `__sFILE` seems to be not find-able by normal C lookup (ie. it is hidden).

Here is one workaround (I did not try it yet):
We could lazy initialize `ToRD` inside the for loop to be equal to the first 'ToD`'s decl context.

  RecordDecl *ToRD = nullptr;
  for (auto *D : FromRD->decls()) {
    if (isa<FieldDecl>(D) || isa<FriendDecl>(D)) {
      Decl *ToD = Importer.GetAlreadyImportedOrNull(D);
      if (!ToRD)
          ToRD = ToD->getDeclContext();
      ToRD->removeDecl(ToD);
    }
  }

I am afraid I can continue with the debug only next week.


Repository:
  rC Clang

CHANGES SINCE LAST ACTION
  https://reviews.llvm.org/D44100/new/

https://reviews.llvm.org/D44100





More information about the cfe-commits mailing list