summaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-09-10 22:04:22 +0000
committerArgyrios Kyrtzidis <akyrtzi@gmail.com>2012-09-10 22:04:22 +0000
commitf89a92702fb8adc121d1020b87a1bba8ef9ab939 (patch)
tree873f4590728d6f6d0f2511018dba712443bf8dda
parentc6fcbf06a69d9443252bae665f79debf8c0b2116 (diff)
downloadbcm5719-llvm-f89a92702fb8adc121d1020b87a1bba8ef9ab939.tar.gz
bcm5719-llvm-f89a92702fb8adc121d1020b87a1bba8ef9ab939.zip
[PCH] When loading fields from external storage make sure to also
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 llvm-svn: 163552
-rw-r--r--clang/lib/AST/Decl.cpp9
-rw-r--r--clang/test/PCH/field-designator.c35
2 files changed, 42 insertions, 2 deletions
diff --git a/clang/lib/AST/Decl.cpp b/clang/lib/AST/Decl.cpp
index bfc6f61c8fb..13f931ae0b1 100644
--- a/clang/lib/AST/Decl.cpp
+++ b/clang/lib/AST/Decl.cpp
@@ -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/clang/test/PCH/field-designator.c b/clang/test/PCH/field-designator.c
new file mode 100644
index 00000000000..763cfdab28d
--- /dev/null
+++ b/clang/test/PCH/field-designator.c
@@ -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
OpenPOWER on IntegriCloud