r339226 - [ASTImporter] Load external Decls when getting field index.

Balazs Keri via cfe-commits cfe-commits at lists.llvm.org
Wed Aug 8 02:40:57 PDT 2018


Author: balazske
Date: Wed Aug  8 02:40:57 2018
New Revision: 339226

URL: http://llvm.org/viewvc/llvm-project?rev=339226&view=rev
Log:
[ASTImporter] Load external Decls when getting field index.

Summary:
At equality check of fields without name the index of fields is compared.
At determining the index of a field all fields of the parent context
should be loaded from external source to find the field at all.

Reviewers: a.sidorin, a_sidorin, r.stahl

Reviewed By: a.sidorin

Subscribers: martong, cfe-commits

Differential Revision: https://reviews.llvm.org/D49796

Added:
    cfe/trunk/test/ASTMerge/unnamed_fields/
    cfe/trunk/test/ASTMerge/unnamed_fields/Inputs/
    cfe/trunk/test/ASTMerge/unnamed_fields/Inputs/il.cpp
    cfe/trunk/test/ASTMerge/unnamed_fields/test.cpp
Modified:
    cfe/trunk/include/clang/AST/ASTImporter.h
    cfe/trunk/lib/AST/ASTImporter.cpp
    cfe/trunk/unittests/AST/ASTImporterTest.cpp

Modified: cfe/trunk/include/clang/AST/ASTImporter.h
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/AST/ASTImporter.h?rev=339226&r1=339225&r2=339226&view=diff
==============================================================================
--- cfe/trunk/include/clang/AST/ASTImporter.h (original)
+++ cfe/trunk/include/clang/AST/ASTImporter.h Wed Aug  8 02:40:57 2018
@@ -333,6 +333,13 @@ class Attr;
     /// equivalent.
     bool IsStructurallyEquivalent(QualType From, QualType To,
                                   bool Complain = true);
+
+    /// Determine the index of a field in its parent record.
+    /// F should be a field (or indirect field) declaration.
+    /// \returns The index of the field in its parent context, starting from 1.
+    /// 0 is returned on error (parent context is non-record).
+    static unsigned getFieldIndex(Decl *F);
+
   };
 
 } // namespace clang

Modified: cfe/trunk/lib/AST/ASTImporter.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/lib/AST/ASTImporter.cpp?rev=339226&r1=339225&r2=339226&view=diff
==============================================================================
--- cfe/trunk/lib/AST/ASTImporter.cpp (original)
+++ cfe/trunk/lib/AST/ASTImporter.cpp Wed Aug  8 02:40:57 2018
@@ -71,6 +71,28 @@
 
 namespace clang {
 
+  unsigned ASTImporter::getFieldIndex(Decl *F) {
+    assert(F && (isa<FieldDecl>(*F) || isa<IndirectFieldDecl>(*F)) &&
+        "Try to get field index for non-field.");
+
+    auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
+    if (!Owner)
+      return 0;
+
+    unsigned Index = 1;
+    for (const auto *D : Owner->decls()) {
+      if (D == F)
+        return Index;
+
+      if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
+        ++Index;
+    }
+
+    llvm_unreachable("Field was not found in its parent context.");
+
+    return 0;
+  }
+
   template <class T>
   SmallVector<Decl*, 2>
   getCanonicalForwardRedeclChain(Redeclarable<T>* D) {
@@ -2829,23 +2851,6 @@ Decl *ASTNodeImporter::VisitCXXConversio
   return VisitCXXMethodDecl(D);
 }
 
-static unsigned getFieldIndex(Decl *F) {
-  auto *Owner = dyn_cast<RecordDecl>(F->getDeclContext());
-  if (!Owner)
-    return 0;
-
-  unsigned Index = 1;
-  for (const auto *D : Owner->noload_decls()) {
-    if (D == F)
-      return Index;
-
-    if (isa<FieldDecl>(*D) || isa<IndirectFieldDecl>(*D))
-      ++Index;
-  }
-
-  return Index;
-}
-
 Decl *ASTNodeImporter::VisitFieldDecl(FieldDecl *D) {
   // Import the major distinguishing characteristics of a variable.
   DeclContext *DC, *LexicalDC;
@@ -2863,7 +2868,9 @@ Decl *ASTNodeImporter::VisitFieldDecl(Fi
   for (auto *FoundDecl : FoundDecls) {
     if (auto *FoundField = dyn_cast<FieldDecl>(FoundDecl)) {
       // For anonymous fields, match up by index.
-      if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
+      if (!Name &&
+          ASTImporter::getFieldIndex(D) !=
+          ASTImporter::getFieldIndex(FoundField))
         continue;
 
       if (Importer.IsStructurallyEquivalent(D->getType(),
@@ -2928,7 +2935,9 @@ Decl *ASTNodeImporter::VisitIndirectFiel
   for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
     if (auto *FoundField = dyn_cast<IndirectFieldDecl>(FoundDecls[I])) {
       // For anonymous indirect fields, match up by index.
-      if (!Name && getFieldIndex(D) != getFieldIndex(FoundField))
+      if (!Name &&
+          ASTImporter::getFieldIndex(D) !=
+          ASTImporter::getFieldIndex(FoundField))
         continue;
 
       if (Importer.IsStructurallyEquivalent(D->getType(),

Added: cfe/trunk/test/ASTMerge/unnamed_fields/Inputs/il.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/unnamed_fields/Inputs/il.cpp?rev=339226&view=auto
==============================================================================
--- cfe/trunk/test/ASTMerge/unnamed_fields/Inputs/il.cpp (added)
+++ cfe/trunk/test/ASTMerge/unnamed_fields/Inputs/il.cpp Wed Aug  8 02:40:57 2018
@@ -0,0 +1,3 @@
+void f(int X, int Y, bool Z) {
+  auto x = [X, Y, Z] { (void)Z; };
+}

Added: cfe/trunk/test/ASTMerge/unnamed_fields/test.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/test/ASTMerge/unnamed_fields/test.cpp?rev=339226&view=auto
==============================================================================
--- cfe/trunk/test/ASTMerge/unnamed_fields/test.cpp (added)
+++ cfe/trunk/test/ASTMerge/unnamed_fields/test.cpp Wed Aug  8 02:40:57 2018
@@ -0,0 +1,3 @@
+// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/il.cpp
+// RUN: %clang_cc1 -ast-merge %t.1.ast -fsyntax-only %s 2>&1 | FileCheck --allow-empty %s
+// CHECK-NOT: warning: field '' declared with incompatible types in different translation units ('bool' vs. 'int')

Modified: cfe/trunk/unittests/AST/ASTImporterTest.cpp
URL: http://llvm.org/viewvc/llvm-project/cfe/trunk/unittests/AST/ASTImporterTest.cpp?rev=339226&r1=339225&r2=339226&view=diff
==============================================================================
--- cfe/trunk/unittests/AST/ASTImporterTest.cpp (original)
+++ cfe/trunk/unittests/AST/ASTImporterTest.cpp Wed Aug  8 02:40:57 2018
@@ -2641,6 +2641,40 @@ TEST_P(ASTImporterTestBase, ImportUnname
       R1, recordDecl(has(fieldDecl(hasName("next"))))));
 }
 
+TEST_P(ASTImporterTestBase, ImportUnnamedFieldsInCorrectOrder) {
+  Decl *FromTU = getTuDecl(
+      R"(
+      void f(int X, int Y, bool Z) {
+        (void)[X, Y, Z] { (void)Z; };
+      }
+      )",
+      Lang_CXX11, "input0.cc");
+  auto *FromF = FirstDeclMatcher<FunctionDecl>().match(
+      FromTU, functionDecl(hasName("f")));
+  auto *ToF = cast_or_null<FunctionDecl>(Import(FromF, Lang_CXX11));
+  EXPECT_TRUE(ToF);
+
+  CXXRecordDecl *FromLambda =
+      cast<LambdaExpr>(cast<CStyleCastExpr>(cast<CompoundStmt>(
+          FromF->getBody())->body_front())->getSubExpr())->getLambdaClass();
+
+  auto *ToLambda = cast_or_null<CXXRecordDecl>(Import(FromLambda, Lang_CXX11));
+  EXPECT_TRUE(ToLambda);
+
+  // Check if the fields of the lambda class are imported in correct order.
+  unsigned FromIndex = 0u;
+  for (auto *FromField : FromLambda->fields()) {
+    ASSERT_FALSE(FromField->getDeclName());
+    auto *ToField = cast_or_null<FieldDecl>(Import(FromField, Lang_CXX11));
+    EXPECT_TRUE(ToField);
+    unsigned ToIndex = ASTImporter::getFieldIndex(ToField);
+    EXPECT_EQ(ToIndex, FromIndex + 1);
+    ++FromIndex;
+  }
+
+  EXPECT_EQ(FromIndex, 3u);
+}
+
 struct DeclContextTest : ASTImporterTestBase {};
 
 TEST_P(DeclContextTest, removeDeclOfClassTemplateSpecialization) {




More information about the cfe-commits mailing list