+ int FieldWidth; /* Width in bits, -1 if not a bit-field */
+ SymTable* FieldTab;
+ SymEntry* Entry;
+
+
+ if (CurTok.Tok != TOK_LCURLY) {
+ /* Just a forward declaration. */
+ return StructOrUnionForwardDecl (Name);
+ }
+
+ /* Add a forward declaration for the struct in the current lexical level */
+ Entry = AddStructSym (Name, 0, 0);
+
+ /* Skip the curly brace */
+ NextToken ();
+
+ /* Enter a new lexical level for the struct */
+ EnterStructLevel ();
+
+ /* Parse union fields */
+ UnionSize = 0;
+ while (CurTok.Tok != TOK_RCURLY) {
+
+ /* Get the type of the entry */
+ DeclSpec Spec;
+ InitDeclSpec (&Spec);
+ ParseTypeSpec (&Spec, -1, T_QUAL_NONE);
+
+ /* Read fields with this type */
+ while (1) {
+
+ Declaration Decl;
+
+ /* Get type and name of the struct field */
+ ParseDecl (&Spec, &Decl, DM_ACCEPT_IDENT);
+
+ /* Check for a bit-field declaration */
+ FieldWidth = ParseFieldWidth (&Decl);
+
+ /* Ignore zero sized bit fields in a union */
+ if (FieldWidth == 0) {
+ goto NextMember;
+ }
+
+ /* Check for fields without a name */
+ if (Decl.Ident[0] == '\0') {
+ /* Any field without a name is legal but useless in a union */
+ Warning ("Declaration does not declare anything");
+ goto NextMember;
+ }
+
+ /* Handle sizes */
+ FieldSize = CheckedSizeOf (Decl.Type);
+ if (FieldSize > UnionSize) {
+ UnionSize = FieldSize;
+ }
+
+ /* Add a field entry to the table. */
+ if (FieldWidth > 0) {
+ AddBitField (Decl.Ident, 0, 0, FieldWidth);
+ } else {
+ AddLocalSym (Decl.Ident, Decl.Type, SC_STRUCTFIELD, 0);
+ }
+
+NextMember: if (CurTok.Tok != TOK_COMMA) {
+ break;
+ }
+ NextToken ();
+ }
+ ConsumeSemi ();
+ }
+
+ /* Skip the closing brace */
+ NextToken ();
+
+ /* Remember the symbol table and leave the struct level */
+ FieldTab = GetSymTab ();
+ LeaveStructLevel ();
+
+ /* Make a real entry from the forward decl and return it */
+ return AddStructSym (Name, UnionSize, FieldTab);
+}
+
+
+
+static SymEntry* ParseStructDecl (const char* Name)
+/* Parse a struct declaration. */
+{
+
+ unsigned StructSize;