extend pragma incomplete to accept struct/union tags directly, not just typedefs Reference: /n/sources/patch/applied/cc-incomplete Date: Tue Apr 3 23:45:45 CES 2007 Signed-off-by: forsyth@terzarima.net --- /sys/man/1/2c Tue Apr 3 23:42:38 2007 +++ /sys/man/1/2c Tue Apr 3 23:42:33 2007 @@ -340,14 +340,23 @@ \- A .B #pragma -of the form +with any of the following forms: .EX #pragma incomplete \fItype\fP + #pragma incomplete struct \fItag\fP + #pragma incomplete union \fItag\fP .EE -tells the compiler that +where .I type +is a +.BR typedef 'd +name for a structure or union type, and +.I tag +is a structure or union tag, +tells the compiler that +the corresponding type should have its signature calculated as an incomplete type -even when it is fully defined. +even if it is subsequently fully defined. This allows the type signature mechanism to work in the presence of opaque types declared in header files, with their full definitions visible only to the code which manipulates them. --- /sys/src/cmd/cc/dpchk.c Tue Apr 3 23:42:56 2007 +++ /sys/src/cmd/cc/dpchk.c Tue Apr 3 23:42:52 2007 @@ -445,18 +445,48 @@ pragincomplete(void) { Sym *s; + Type *t; + int istag, w, et; + istag = 0; s = getsym(); - if(s){ - if(strcmp(s->name, "_off_") == 0) - debug['T'] = 0; - else if(strcmp(s->name, "_on_") == 0) - debug['T'] = 1; - else if(s->type == T) - diag(Z, "unknown type %s in pragma incomplete", s->name); - else - s->type->garb |= GINCOMPLETE; + if(s == nil) + goto out; + et = 0; + w = s->lexical; + if(w == LSTRUCT) + et = TSTRUCT; + else if(w == LUNION) + et = TUNION; + if(et != 0){ + s = getsym(); + if(s == nil){ + yyerror("missing struct/union tag in pragma incomplete"); + goto out; + } + if(s->lexical != LNAME && s->lexical != LTYPE){ + yyerror("invalid struct/union tag: %s", s->name); + goto out; + } + dotag(s, et, 0); + istag = 1; + }else if(strcmp(s->name, "_off_") == 0){ + debug['T'] = 0; + goto out; + }else if(strcmp(s->name, "_on_") == 0){ + debug['T'] = 1; + goto out; } + t = s->type; + if(istag) + t = s->suetag; + if(t == T) + yyerror("unknown type %s in pragma incomplete", s->name); + else if(!typesu[t->etype]) + yyerror("not struct/union type in pragma incomplete: %s", s->name); + else + t->garb |= GINCOMPLETE; +out: while(getnsc() != '\n') ; if(debug['f'])