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