danix800 updated this revision to Diff 543535.
danix800 retitled this revision from "[ASTImporter] Add extra sorting round for 
keeping lexical order of all imported decls within record" to "[ASTImporter] 
Re-odering by lexical order for all imported decls within record".
danix800 edited the summary of this revision.
danix800 added a reviewer: balazske.

Repository:
  rG LLVM Github Monorepo

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

https://reviews.llvm.org/D156093

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

Index: clang/unittests/AST/ASTImporterTest.cpp
===================================================================
--- clang/unittests/AST/ASTImporterTest.cpp
+++ clang/unittests/AST/ASTImporterTest.cpp
@@ -1462,11 +1462,18 @@
       MatchVerifier<Decl>{}.match(To->getTranslationUnitDecl(), Pattern));
 }
 
-AST_MATCHER_P(RecordDecl, hasFieldOrder, std::vector<StringRef>, Order) {
+AST_MATCHER_P(RecordDecl, hasLexicalOrder, std::vector<StringRef>, Order) {
   size_t Index = 0;
   for (Decl *D : Node.decls()) {
-    if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D)) {
-      auto *ND = cast<NamedDecl>(D);
+    if (isa<FieldDecl>(D) || isa<IndirectFieldDecl>(D) || !D->isImplicit()) {
+      NamedDecl *ND = nullptr;
+      if (isa<NamedDecl>(D))
+        ND = cast<NamedDecl>(D);
+      else if (auto *Friend = dyn_cast<FriendDecl>(D);
+               Friend && !(ND = Friend->getFriendDecl()))
+        ND = Friend->getFriendType()->getType()->getAsRecordDecl();
+      if (!ND)
+        return false;
       if (Index == Order.size())
         return false;
       if (ND->getName() != Order[Index])
@@ -1513,8 +1520,8 @@
                       Lang_CXX11, "", Lang_CXX11);
 
   MatchVerifier<Decl> Verifier;
-  ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
-  EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b"}))));
+  ASSERT_TRUE(Verifier.match(From, cxxRecordDecl(hasLexicalOrder({"a", "b"}))));
+  EXPECT_TRUE(Verifier.match(To, cxxRecordDecl(hasLexicalOrder({"a", "b"}))));
 }
 
 TEST_P(ASTImporterOptionSpecificTestBase,
@@ -1532,19 +1539,46 @@
       )s",
       Lang_CXX11, "", Lang_CXX11);
 
+  auto Pattern = cxxRecordDecl(hasLexicalOrder({"a", "b", "c"}));
   MatchVerifier<Decl> Verifier;
-  ASSERT_TRUE(
-      Verifier.match(From, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
-  EXPECT_TRUE(
-      Verifier.match(To, cxxRecordDecl(hasFieldOrder({"a", "b", "c"}))));
+  ASSERT_TRUE(Verifier.match(From, Pattern));
+  EXPECT_TRUE(Verifier.match(To, Pattern));
+}
+
+TEST_P(ASTImporterOptionSpecificTestBase, CXXRecordDeclCorrectLexicalOrder) {
+  Decl *From, *To;
+  std::tie(From, To) = getImportedDecl(
+      R"s(
+      struct declToImport {
+        int a = c;
+        void b() { d(); }
+        int c = 1;
+        void d();
+        friend class e;
+        int f = 2;
+        enum {
+          g, h
+        };
+        class I {};
+        enum J {
+          k, l
+        };
+        template<class T> class M;
+      };
+      )s",
+      Lang_CXX11, "", Lang_CXX11);
+
+  auto Pattern = cxxRecordDecl(
+      hasLexicalOrder({"a", "b", "c", "d", "e", "f", "", "I", "J", "M"}));
+  MatchVerifier<Decl> Verifier;
+  ASSERT_TRUE(Verifier.match(From, Pattern));
+  EXPECT_TRUE(Verifier.match(To, Pattern));
 }
 
 TEST_P(ASTImporterOptionSpecificTestBase,
        CXXRecordDeclFieldAndIndirectFieldOrder) {
   Decl *From, *To;
   std::tie(From, To) = getImportedDecl(
-      // First field is "a", then the field for unnamed union, then "b" and "c"
-      // from it (indirect fields), then "d".
       R"s(
       struct declToImport {
         int a = d;
@@ -1557,11 +1591,14 @@
       )s",
       Lang_CXX11, "", Lang_CXX11);
 
+  auto Pattern = cxxRecordDecl(hasLexicalOrder({"a", "", /* anonymous union */
+                                                "",      /* implicit field */
+                                                "b",     /* indirect field */
+                                                "c",     /* indirect field */
+                                                "d"}));
   MatchVerifier<Decl> Verifier;
-  ASSERT_TRUE(Verifier.match(
-      From, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
-  EXPECT_TRUE(Verifier.match(
-      To, cxxRecordDecl(hasFieldOrder({"a", "", "b", "c", "d"}))));
+  ASSERT_TRUE(Verifier.match(From, Pattern));
+  EXPECT_TRUE(Verifier.match(To, Pattern));
 }
 
 TEST_P(ASTImporterOptionSpecificTestBase, ShouldImportImplicitCXXRecordDecl) {
@@ -3007,7 +3044,7 @@
              "  int a = 5;"
              "};",
              Lang_CXX11, "", Lang_CXX11, Verifier,
-             recordDecl(hasFieldOrder({"b", "a"})));
+             recordDecl(hasLexicalOrder({"b", "a"})));
 }
 
 const internal::VariadicDynCastAllOfMatcher<Expr, DependentScopeDeclRefExpr>
Index: clang/lib/AST/ASTImporter.cpp
===================================================================
--- clang/lib/AST/ASTImporter.cpp
+++ clang/lib/AST/ASTImporter.cpp
@@ -1942,6 +1942,17 @@
                                                 ImportedOrErr.takeError());
   }
 
+  // Finally re-order everything by lexical order.
+  for (auto *D : FromDC->decls()) {
+    assert(D && "DC contains a null decl");
+    if (Decl *ToD = Importer.GetAlreadyImportedOrNull(D);
+        ToD && ToDC == ToD->getLexicalDeclContext() &&
+        ToDC->containsDecl(ToD)) {
+      ToDC->removeDecl(ToD);
+      ToDC->addDeclInternal(ToD);
+    }
+  }
+
   return ChildErrors;
 }
 
_______________________________________________
cfe-commits mailing list
cfe-commits@lists.llvm.org
https://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits

Reply via email to