[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