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

Aleksei Sidorin via Phabricator via cfe-commits cfe-commits at lists.llvm.org
Mon Mar 5 10:07:29 PST 2018


a.sidorin created this revision.
a.sidorin added reviewers: xazax.hun, szepet, jingham.
Herald added subscribers: martong, rnkovacs.

- There are multiple reasons why field structures can be imported in wrong way. The simplest is the ability of field initializers and method bodies to refer fields not in order they are listed in. Unfortunately, there is no clean solution for that currently so I'm leaving a FIXME.


Repository:
  rC Clang

https://reviews.llvm.org/D44100

Files:
  lib/AST/ASTImporter.cpp
  unittests/AST/ASTImporterTest.cpp


Index: unittests/AST/ASTImporterTest.cpp
===================================================================
--- unittests/AST/ASTImporterTest.cpp
+++ unittests/AST/ASTImporterTest.cpp
@@ -1019,5 +1019,28 @@
       "main.c", enumDecl(), VerificationMatcher);
 }
 
+AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
+  size_t Index = 0;
+  for (FieldDecl *Field : Node.fields()) {
+    if (Index == Order.size())
+      return false;
+    if (Field->getName() != Order[Index])
+      return false;
+    ++Index;
+  }
+  return Index == Order.size();
+}
+
+TEST(ImportDecl, ImportFieldOrder) {
+  MatchVerifier<Decl> Verifier;
+  testImport("struct declToImport {"
+             "  int b = a + 2;"
+             "  int a = 5;"
+             "};",
+             Lang_CXX11, "", Lang_CXX11, Verifier,
+             recordDecl(hasFieldOrder({"b", "a"})));
+}
+
+
 } // end namespace ast_matchers
 } // end namespace clang
Index: lib/AST/ASTImporter.cpp
===================================================================
--- lib/AST/ASTImporter.cpp
+++ lib/AST/ASTImporter.cpp
@@ -1015,6 +1015,34 @@
   
   for (auto *From : FromDC->decls())
     Importer.Import(From);
+
+  // Reorder declarations in RecordDecls because they may have another
+  // order. Keeping field order is vitable because it determines structure
+  // layout.
+  // FIXME: This is an ugly fix. Unfortunately, I cannot come with better
+  // solution for this issue. We cannot defer expression import here because
+  // type import can depend on them.
+  const RecordDecl *FromRD = dyn_cast<RecordDecl>(FromDC);
+  if (!FromRD)
+    return;
+
+  RecordDecl *ToRD = cast<RecordDecl>(Importer.Import(cast<Decl>(FromDC)));
+
+  for (auto *FromField : FromRD->fields()) {
+    Decl *ToField = Importer.GetAlreadyImportedOrNull(FromField);
+    assert(ToRD == ToField->getDeclContext() && ToRD->containsDecl(ToField));
+    ToRD->removeDecl(ToField);
+  }
+
+  assert(ToRD->field_empty());
+
+  for (auto *FromField : FromRD->fields()) {
+    Decl *ToField = Importer.GetAlreadyImportedOrNull(FromField);
+    assert(ToRD == ToField->getDeclContext());
+    assert(ToRD == ToField->getLexicalDeclContext());
+    assert(!ToRD->containsDecl(ToField));
+    ToRD->addDeclInternal(ToField);
+  }
 }
 
 bool ASTNodeImporter::ImportDefinition(RecordDecl *From, RecordDecl *To, 


-------------- next part --------------
A non-text attachment was scrubbed...
Name: D44100.137034.patch
Type: text/x-patch
Size: 2360 bytes
Desc: not available
URL: <http://lists.llvm.org/pipermail/cfe-commits/attachments/20180305/ac03665b/attachment.bin>


More information about the cfe-commits mailing list