]> granicus.if.org Git - clang/commitdiff
[PCH] When loading fields from external storage make sure to also
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 10 Sep 2012 22:04:22 +0000 (22:04 +0000)
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>
Mon, 10 Sep 2012 22:04:22 +0000 (22:04 +0000)
load in the IndirectField declarations as well.

Field designators in initializer lists depend on traversing the fields
decl chain to find the indirect fields.

Fixes rdar://12239321

git-svn-id: https://llvm.org/svn/llvm-project/cfe/trunk@163552 91177308-0d34-0410-b5e6-96231b3b80d8

lib/AST/Decl.cpp
test/PCH/field-designator.c [new file with mode: 0644]

index bfc6f61c8fb60715bb03daf82304dec28fa5287c..13f931ae0b180bc7b7c67a01823b6d3eb4f100ef 100644 (file)
@@ -2762,6 +2762,10 @@ void RecordDecl::completeDefinition() {
   TagDecl::completeDefinition();
 }
 
+static bool isFieldOrIndirectField(Decl::Kind K) {
+  return FieldDecl::classofKind(K) || IndirectFieldDecl::classofKind(K);
+}
+
 void RecordDecl::LoadFieldsFromExternalStorage() const {
   ExternalASTSource *Source = getASTContext().getExternalSource();
   assert(hasExternalLexicalStorage() && Source && "No external storage?");
@@ -2771,7 +2775,8 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
 
   SmallVector<Decl*, 64> Decls;
   LoadedFieldsFromExternalStorage = true;  
-  switch (Source->FindExternalLexicalDeclsBy<FieldDecl>(this, Decls)) {
+  switch (Source->FindExternalLexicalDecls(this, isFieldOrIndirectField,
+                                           Decls)) {
   case ELR_Success:
     break;
     
@@ -2783,7 +2788,7 @@ void RecordDecl::LoadFieldsFromExternalStorage() const {
 #ifndef NDEBUG
   // Check that all decls we got were FieldDecls.
   for (unsigned i=0, e=Decls.size(); i != e; ++i)
-    assert(isa<FieldDecl>(Decls[i]));
+    assert(isa<FieldDecl>(Decls[i]) || isa<IndirectFieldDecl>(Decls[i]));
 #endif
 
   if (Decls.empty())
diff --git a/test/PCH/field-designator.c b/test/PCH/field-designator.c
new file mode 100644 (file)
index 0000000..763cfda
--- /dev/null
@@ -0,0 +1,35 @@
+// RUN: %clang_cc1 -cc1 %s -include %s
+// RUN: %clang_cc1 -cc1 %s -emit-pch -o %t.pch
+// RUN: %clang_cc1 -cc1 %s -include-pch %t.pch
+
+// rdar://12239321 Make sure we don't emit a bogus
+//     error: field designator 'e' does not refer to a non-static data member
+
+#ifndef HEADER
+#define HEADER
+//===----------------------------------------------------------------------===//
+
+struct U {
+  union {
+    struct {
+      int e;
+      int f;
+    };
+
+    int a;
+  };
+};
+
+//===----------------------------------------------------------------------===//
+#else
+#if !defined(HEADER)
+# error Header inclusion order messed up
+#endif
+//===----------------------------------------------------------------------===//
+
+void bar() {
+  static const struct U plan = { .e = 1 };
+}
+
+//===----------------------------------------------------------------------===//
+#endif