[cfe-commits] [PATCH][Review request] - IndirectField + designated initializers.
Douglas Gregor
dgregor at apple.com
Mon Dec 20 22:55:05 PST 2010
On Dec 12, 2010, at 7:23 PM, Francois Pichet wrote:
> More IndirectFieldDecl refactoring.
>
> This patch deals with a dark corner of clang: anonymous field
> initialized with designated-initializers (C99 feature)
> This is C++ mixing with C99.. not sure why clang supports that but it does.
Anonymous structs and anonymous unions are GNU extensions in C (and the former is an extension in C++, too) that GCC implements, so Clang also implements it.
> Example:
>
> struct Test {
> union {
> int a;
> char b;
> };
> };
>
> struct Test var = { .a = 4 };
>
> Some explaining: currently designated anonymous fields are found via
> name look. Normal fields are found by iterating all the fields. This
> patch uses the fact that IndirectFieldDecl declarations will follow an
> anonymous implicit field to remove the special case of name lookup for
> anonymous field. With this patch there is no need to calculate the
> anonymous field position afterward. Clear enough?
This is causing Clang to crash on the test
test/CodeGen/designated-initializers.c
This is a bit suspicious:
@@ -1386,7 +1356,15 @@
for (; Field != FieldEnd; ++Field) {
if (Field->isUnnamedBitfield())
continue;
-
+
+ // If we find a field representing an anonymous field, look in the
+ // IndirectFieldDecl that follow for the designated initializer.
+ if (!KnownField && Field->isAnonymousStructOrUnion()) {
+ if (IndirectFieldDecl *IF = FindIndirectFieldDesignator(*Field, FieldName))
+ ExpandAnonymousFieldDesignator(SemaRef, DIE, DesigIdx, IF);
+ D = DIE->getDesignator(DesigIdx);
+ break;
+ }
since there's no { } around the body of the inner if.
+/// \brief Given an implicit anonymous field, search the IndirectField that
+/// corresponds to FieldName.
+static IndirectFieldDecl *FindIndirectFieldDesignator(FieldDecl *AnonField,
+ IdentifierInfo *FieldName) {
+ assert(AnonField->isAnonymousStructOrUnion());
+ Decl *NextDecl = AnonField->getNextDeclInContext();
+ while (IndirectFieldDecl *IF = dyn_cast<IndirectFieldDecl>(NextDecl)) {
+ if (FieldName && FieldName == IF->getAnonField()->getIdentifier())
+ return IF;
+ NextDecl = NextDecl->getNextDeclInContext();
}
-
- assert(false && "Unable to find anonymous struct/union field");
}
There's no "return 0;" at the end here (?)
With those changes, the patch seems fine to me.
- Doug
More information about the cfe-commits
mailing list