spyffe updated this revision to Diff 63894. spyffe added a comment. Applied Manman's changes:
- `const auto*` instead of `const RecordType*` - kept the if's separate because I... - ...moved the `Index++` and `continue` in so that we only increment the counter when we're really dealing with something untagged - changed the function name to `findUntaggedStructOrUnionIndex` Repository: rL LLVM http://reviews.llvm.org/D22270 Files: lib/AST/ASTImporter.cpp test/ASTMerge/Inputs/anonymous-fields1.cpp test/ASTMerge/Inputs/anonymous-fields2.cpp test/ASTMerge/anonymous-fields.cpp
Index: test/ASTMerge/anonymous-fields.cpp =================================================================== --- /dev/null +++ test/ASTMerge/anonymous-fields.cpp @@ -0,0 +1,4 @@ +// RUN: %clang_cc1 -emit-pch -o %t.1.ast %S/Inputs/anonymous-fields1.cpp +// RUN: %clang_cc1 -emit-pch -o %t.2.ast %S/Inputs/anonymous-fields2.cpp +// RUN: %clang_cc1 -emit-obj -o /dev/null -ast-merge %t.1.ast -ast-merge %t.2.ast %s +// expected-no-diagnostics Index: test/ASTMerge/Inputs/anonymous-fields2.cpp =================================================================== --- /dev/null +++ test/ASTMerge/Inputs/anonymous-fields2.cpp @@ -0,0 +1,9 @@ +class A { +public: + struct { int foo; } f; + struct { int foo; } g; +}; + +inline int useA(A &a) { + return (a.f.foo + a.g.foo); +} Index: test/ASTMerge/Inputs/anonymous-fields1.cpp =================================================================== --- /dev/null +++ test/ASTMerge/Inputs/anonymous-fields1.cpp @@ -0,0 +1,5 @@ +class A { +public: + struct { int foo; } f; + struct { int foo; } g; +}; Index: lib/AST/ASTImporter.cpp =================================================================== --- lib/AST/ASTImporter.cpp +++ lib/AST/ASTImporter.cpp @@ -1029,7 +1029,7 @@ /// including the next assigned index (if none of them match). Returns an /// empty option if the context is not a record, i.e.. if the anonymous /// struct/union is at namespace or block scope. -static Optional<unsigned> findAnonymousStructOrUnionIndex(RecordDecl *Anon) { +static Optional<unsigned> findUntaggedStructOrUnionIndex(RecordDecl *Anon) { ASTContext &Context = Anon->getASTContext(); QualType AnonTy = Context.getRecordType(Anon); @@ -1040,13 +1040,29 @@ unsigned Index = 0; for (const auto *D : Owner->noload_decls()) { const auto *F = dyn_cast<FieldDecl>(D); - if (!F || !F->isAnonymousStructOrUnion()) + if (!F) continue; - if (Context.hasSameType(F->getType(), AnonTy)) - break; + if (F->isAnonymousStructOrUnion()) { + if (Context.hasSameType(F->getType(), AnonTy)) + break; + ++Index; + continue; + } - ++Index; + // If the field looks like this: + // struct { ... } A; + QualType FieldType = F->getType(); + if (const auto *RecType = dyn_cast<RecordType>(FieldType)) { + const RecordDecl *RecDecl = RecType->getDecl(); + if (RecDecl->getDeclContext() == Owner && + !RecDecl->getIdentifier()) { + if (Context.hasSameType(FieldType, AnonTy)) + break; + ++Index; + continue; + } + } } return Index; @@ -1068,8 +1084,8 @@ if (D1->isAnonymousStructOrUnion() && D2->isAnonymousStructOrUnion()) { // If both anonymous structs/unions are in a record context, make sure // they occur in the same location in the context records. - if (Optional<unsigned> Index1 = findAnonymousStructOrUnionIndex(D1)) { - if (Optional<unsigned> Index2 = findAnonymousStructOrUnionIndex(D2)) { + if (Optional<unsigned> Index1 = findUntaggedStructOrUnionIndex(D1)) { + if (Optional<unsigned> Index2 = findUntaggedStructOrUnionIndex(D2)) { if (*Index1 != *Index2) return false; } @@ -2749,9 +2765,9 @@ // If both anonymous structs/unions are in a record context, make sure // they occur in the same location in the context records. if (Optional<unsigned> Index1 - = findAnonymousStructOrUnionIndex(D)) { + = findUntaggedStructOrUnionIndex(D)) { if (Optional<unsigned> Index2 = - findAnonymousStructOrUnionIndex(FoundRecord)) { + findUntaggedStructOrUnionIndex(FoundRecord)) { if (*Index1 != *Index2) continue; }
_______________________________________________ cfe-commits mailing list cfe-commits@lists.llvm.org http://lists.llvm.org/cgi-bin/mailman/listinfo/cfe-commits