diff options
| author | Gabor Horvath <xazax.hun@gmail.com> | 2017-04-03 11:57:11 +0000 | 
|---|---|---|
| committer | Gabor Horvath <xazax.hun@gmail.com> | 2017-04-03 11:57:11 +0000 | 
| commit | 3d2c10d941844e5abec6e5058de90ed132d4f145 (patch) | |
| tree | 5a32277d30932d4ee5f07de17a27fc19daedcdbb | |
| parent | 5558ba2d82d7e6c0d30a3a3c1a3de790ca6abac3 (diff) | |
| download | bcm5719-llvm-3d2c10d941844e5abec6e5058de90ed132d4f145.tar.gz bcm5719-llvm-3d2c10d941844e5abec6e5058de90ed132d4f145.zip | |
[ASTImporter] Fix for importing unnamed structs
Patch by Peter Szecsi!
Differential Revision: https://reviews.llvm.org/D30876
llvm-svn: 299355
| -rw-r--r-- | clang/lib/AST/ASTImporter.cpp | 9 | ||||
| -rw-r--r-- | clang/test/ASTMerge/struct/Inputs/struct1.c | 62 | ||||
| -rw-r--r-- | clang/test/ASTMerge/struct/Inputs/struct2.c | 62 | ||||
| -rw-r--r-- | clang/test/ASTMerge/struct/test.c | 10 | 
4 files changed, 139 insertions, 4 deletions
| diff --git a/clang/lib/AST/ASTImporter.cpp b/clang/lib/AST/ASTImporter.cpp index 95492825eb9..74449a965f9 100644 --- a/clang/lib/AST/ASTImporter.cpp +++ b/clang/lib/AST/ASTImporter.cpp @@ -1221,6 +1221,10 @@ static Optional<unsigned> findUntaggedStructOrUnionIndex(RecordDecl *Anon) {      // If the field looks like this:      // struct { ... } A;      QualType FieldType = F->getType(); +    // In case of nested structs. +    while (const auto *ElabType = dyn_cast<ElaboratedType>(FieldType)) { +      FieldType = ElabType->getNamedType(); +    }      if (const auto *RecType = dyn_cast<RecordType>(FieldType)) {        const RecordDecl *RecDecl = RecType->getDecl();        if (RecDecl->getDeclContext() == Owner && @@ -3020,9 +3024,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {        }        if (RecordDecl *FoundRecord = dyn_cast<RecordDecl>(Found)) { -        if (D->isAnonymousStructOrUnion() &&  -            FoundRecord->isAnonymousStructOrUnion()) { -          // If both anonymous structs/unions are in a record context, make sure +        if (!SearchName) { +          // If both unnamed structs/unions are in a record context, make sure            // they occur in the same location in the context records.            if (Optional<unsigned> Index1                = findUntaggedStructOrUnionIndex(D)) { diff --git a/clang/test/ASTMerge/struct/Inputs/struct1.c b/clang/test/ASTMerge/struct/Inputs/struct1.c index 0f3e8b9bc3e..a85aec70a84 100644 --- a/clang/test/ASTMerge/struct/Inputs/struct1.c +++ b/clang/test/ASTMerge/struct/Inputs/struct1.c @@ -77,3 +77,65 @@ typedef struct {  } S13;  S13 x13; + +// Matches +struct Unnamed { +  union { +    struct { +      int i; +    } S; +    struct { +      float i; +    } R; +  } U; +} x14; + +// Matches +struct DeepUnnamed { +  union { +    union { +      struct { +        long i; +      } S; +      struct { +        int i; +      } R; +    } U1; +    union { +      struct { +        long i; +      } S; +      struct { +        float i; +      } T; +    } U2; +  } U; +  struct { +    long i; +  } V; +} x15; + +// Mismatch due to unnamed struct used internally +struct DeepUnnamedError { +  union { +    union { +      struct { +        long i; +      } S; +      struct { +        int i; +      } R; +    } U1; +    union { +      struct { +        long i; // Mismatch here. +      } S; +      struct { +        float i; +      } T; +    } U2; +  } U; +  struct { +    long i; +  } V; +} x16; diff --git a/clang/test/ASTMerge/struct/Inputs/struct2.c b/clang/test/ASTMerge/struct/Inputs/struct2.c index 7fe17a576b2..49fe36d823d 100644 --- a/clang/test/ASTMerge/struct/Inputs/struct2.c +++ b/clang/test/ASTMerge/struct/Inputs/struct2.c @@ -74,3 +74,65 @@ typedef struct {  } S13;  S13 x13; + +// Matches +struct Unnamed { +  union { +    struct { +      int i; +    } S; +    struct { +      float i; +    } R; +  } U; +} x14; + +// Matches +struct DeepUnnamed { +  union { +    union { +      struct { +        long i; +      } S; +      struct { +        int i; +      } R; +    } U1; +    union { +      struct { +        long i; +      } S; +      struct { +        float i; +      } T; +    } U2; +  } U; +  struct { +    long i; +  } V; +} x15; + +// Mismatch due to unnamed struct used internally +struct DeepUnnamedError { +  union { +    union { +      struct { +        long i; +      } S; +      struct { +        int i; +      } R; +    } U1; +    union { +      struct { +        float i; // Mismatch here. +      } S; +      struct { +        float i; +      } T; +    } U2; +  } U; +  struct { +    long i; +  } V; +} x16; diff --git a/clang/test/ASTMerge/struct/test.c b/clang/test/ASTMerge/struct/test.c index ed7750f6bec..b7e24416d25 100644 --- a/clang/test/ASTMerge/struct/test.c +++ b/clang/test/ASTMerge/struct/test.c @@ -44,4 +44,12 @@  // CHECK: struct2.c:72:7: note: field 'i' has type 'int' here  // CHECK: struct2.c:76:5: error: external variable 'x13' declared with incompatible types in different translation units ('S13' vs. 'S13')  // CHECK: struct1.c:79:5: note: declared here with type 'S13' -// CHECK: 9 warnings and 8 errors generated +// CHECK: struct1.c:130:7: warning: type 'struct DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS:.+]]/struct1.c:130:7)' has incompatible definitions in different translation units +// CHECK: struct1.c:131:14: note: field 'i' has type 'long' here +// CHECK: struct2.c:128:15: note: field 'i' has type 'float' here +// CHECK: struct1.c:129:5: warning: type 'union DeepUnnamedError::(anonymous at [[PATH_TO_INPUTS]]/struct1.c:129:5)' has incompatible definitions in different translation units +// CHECK: struct1.c:132:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]/struct1.c:130:7)' here +// CHECK: struct2.c:129:9: note: field 'S' has type 'struct (anonymous struct at [[PATH_TO_INPUTS]]/struct2.c:127:7)' here +// CHECK: struct2.c:138:3: error: external variable 'x16' declared with incompatible types in different translation units ('struct DeepUnnamedError' vs. 'struct DeepUnnamedError') +// CHECK: struct1.c:141:3: note: declared here with type 'struct DeepUnnamedError' +// CHECK: 11 warnings and 9 errors generated | 

