Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20120422210740

Diff

Diff from 1.3 to:

Annotations

Annotate by Age | Author | Mixed | None
/fisheye/browse/pcc/pcc/cc/cxxcom/gcc_compat.c

Annotated File View

plunky
1.3
1 /*      $Id: gcc_compat.c,v 1.3 2012/04/22 21:07:41 plunky Exp $     */
ragge
1.1
2 /*
3  * Copyright (c) 2004 Anders Magnusson (ragge@ludd.luth.se).
4  * All rights reserved.
5  *
6  * Redistribution and use in source and binary forms, with or without
7  * modification, are permitted provided that the following conditions
8  * are met:
9  * 1. Redistributions of source code must retain the above copyright
10  *    notice, this list of conditions and the following disclaimer.
11  * 2. Redistributions in binary form must reproduce the above copyright
12  *    notice, this list of conditions and the following disclaimer in the
13  *    documentation and/or other materials provided with the distribution.
14  * 3. The name of the author may not be used to endorse or promote products
15  *    derived from this software without specific prior written permission
16  *
17  * THIS SOFTWARE IS PROVIDED BY THE AUTHOR ``AS IS'' AND ANY EXPRESS OR
18  * IMPLIED WARRANTIES, INCLUDING, BUT NOT LIMITED TO, THE IMPLIED WARRANTIES
19  * OF MERCHANTABILITY AND FITNESS FOR A PARTICULAR PURPOSE ARE DISCLAIMED.
20  * IN NO EVENT SHALL THE AUTHOR BE LIABLE FOR ANY DIRECT, INDIRECT,
21  * INCIDENTAL, SPECIAL, EXEMPLARY, OR CONSEQUENTIAL DAMAGES (INCLUDING, BUT
22  * NOT LIMITED TO, PROCUREMENT OF SUBSTITUTE GOODS OR SERVICES; LOSS OF USE,
23  * DATA, OR PROFITS; OR BUSINESS INTERRUPTION) HOWEVER CAUSED AND ON ANY
24  * THEORY OF LIABILITY, WHETHER IN CONTRACT, STRICT LIABILITY, OR TORT
25  * (INCLUDING NEGLIGENCE OR OTHERWISE) ARISING IN ANY WAY OUT OF THE USE OF
26  * THIS SOFTWARE, EVEN IF ADVISED OF THE POSSIBILITY OF SUCH DAMAGE.
27  */
28
29 /*
30  * Routines to support some of the gcc extensions to C.
31  */
32 #ifdef GCC_COMPAT
33
34 #include "pass1.h"
35 #include "cgram.h"
36
37 #include <string.h>
38
39 static struct kw {
40         char *name, *ptr;
41         int rv;
42 kw[] = {
43 /*
44  * Do NOT change the order of these entries unless you know 
45  * what you're doing!
46  */
47 /* 0 */ { "__asm"NULLC_ASM },
48 /* 1 */ { "__signed"NULL0 },
49 /* 2 */ { "__inline"NULLC_FUNSPEC },
50 /* 3 */ { "__const"NULL0 },
51 /* 4 */ { "__asm__"NULLC_ASM },
52 /* 5 */ { "__inline__"NULLC_FUNSPEC },
53 /* 6 */ { "__thread"NULL0 },
54 /* 7 */ { "__FUNCTION__"NULL0 },
55 /* 8 */ { "__volatile"NULL0 },
56 /* 9 */ { "__volatile__"NULL0 },
57 /* 10 */"__restrict"NULL, -1 },
58 /* 11 */"__typeof__"NULLC_TYPEOF },
59 /* 12 */"typeof"NULLC_TYPEOF },
60 /* 13 */"__extension__"NULL, -1 },
61 /* 14 */"__signed__"NULL0 },
62 /* 15 */"__attribute__"NULL0 },
63 /* 16 */"__attribute"NULL0 },
64 /* 17 */"__real__"NULL0 },
65 /* 18 */"__imag__"NULL0 },
66 /* 19 */"__builtin_offsetof"NULLPCC_OFFSETOF },
67 /* 20 */"__PRETTY_FUNCTION__"NULL0 },
68 /* 21 */"__alignof__"NULLC_ALIGNOF },
69 /* 22 */"__typeof"NULLC_TYPEOF },
70 /* 23 */"__alignof"NULLC_ALIGNOF },
71 /* 24 */"__restrict__"NULL, -1 },
72         { NULLNULL0 },
73 };
74
75 /* g77 stuff */
76 #if SZFLOAT == SZLONG
77 #define G77_INTEGER LONG
78 #define G77_UINTEGER ULONG
79 #elif SZFLOAT == SZINT
80 #define G77_INTEGER INT
81 #define G77_UINTEGER UNSIGNED
82 #else
83 #error fix g77 stuff
84 #endif
85 #if SZFLOAT*2 == SZLONG
86 #define G77_LONGINT LONG
87 #define G77_ULONGINT ULONG
88 #elif SZFLOAT*2 == SZLONGLONG
89 #define G77_LONGINT LONGLONG
90 #define G77_ULONGINT ULONGLONG
91 #else
92 #error fix g77 long stuff
93 #endif
94
95 static TWORD g77t[] = { G77_INTEGERG77_UINTEGERG77_LONGINTG77_ULONGINT };
96 static char *g77n[] = { "__g77_integer""__g77_uinteger",
97         "__g77_longint""__g77_ulongint" };
98
99 void
plunky
1.3
100 gcc_init(void)
ragge
1.1
101 {
102         struct kw *kwp;
103         NODE *p;
104         TWORD t;
105         int i;
106
107         for (kwp = kwkwp->namekwp++)
108                 kwp->ptr = addname(kwp->name);
109
110         for (i = 0i < 4i++) {
111                 struct symtab *sp;
112                 t = ctype(g77t[i]);
113                 p = block(NAMENILNILtNULL0);
114                 sp = lookup(addname(g77n[i]), 0);
115                 p->n_sp = sp;
116                 defid(pTYPEDEF);
117                 nfree(p);
118         }
119 }
120
121 #define TS      "\n#pragma tls\n# %d\n"
122 #define TLLEN   sizeof(TS)+10
123 /*
124  * See if a string matches a gcc keyword.
125  */
126 int
127 gcc_keyword(char *strNODE **n)
128 {
129         extern int inattrparlvlparbal;
130         YYSTYPE *yyl = (YYSTYPE *)n/* XXX should pass yylval */
131         char tlbuf[TLLEN], *tw;
132         struct kw *kwp;
133         int i;
134
135         /* XXX hack, should pass everything in expressions */
136         if (str == kw[21].ptr)
137                 return kw[21].rv;
138
139         if (inattr)
140                 return 0;
141
142         for (i = 0kwp = kwkwp->namekwp++, i++)
143                 if (str == kwp->ptr)
144                         break;
145         if (kwp->name == NULL)
146                 return 0;
147         if (kwp->rv)
148                 return kwp->rv;
149         switch (i) {
150         case 1:  /* __signed */
151         case 14/* __signed__ */
152                 *n = mkty((TWORD)SIGNED00);
153                 return C_TYPE;
154         case 3/* __const */
155                 *n = block(QUALIFIERNILNILCON00);
156                 (*n)->n_qual = CON;
157                 return C_QUALIFIER;
158         case 6/* __thread */
159                 snprintf(tlbufTLLENTSlineno);
160                 tw = &tlbuf[strlen(tlbuf)];
161                 while (tw > tlbuf)
162                         cunput(*--tw);
163                 return -1;
164         case 7/* __FUNCTION__ */
165         case 20/* __PRETTY_FUNCTION__ */
166                 if (cftnsp == NULL) {
167                         uerror("%s outside function"kwp->name);
168                         yylval.strp = "";
169                 } else
170                         yylval.strp = cftnsp->sname/* XXX - not C99 */
171                 return C_STRING;
172         case 8/* __volatile */
173         case 9/* __volatile__ */
174                 *n = block(QUALIFIERNILNILVOL00);
175                 (*n)->n_qual = VOL;
176                 return C_QUALIFIER;
177         case 15/* __attribute__ */
178         case 16/* __attribute */
179                 inattr = 1;
180                 parlvl = parbal;
181                 return C_ATTRIBUTE;
182         case 17/* __real__ */
183                 yyl->intval = XREAL;
184                 return C_UNOP;
185         case 18/* __imag__ */
186                 yyl->intval = XIMAG;
187                 return C_UNOP;
188         }
189         cerror("gcc_keyword");
190         return 0;
191 }
192
193 #ifndef TARGET_ATTR
194 #define TARGET_ATTR(p, sue)             0
195 #endif
196 #ifndef ALMAX
197 #define ALMAX (ALLDOUBLE > ALLONGLONG ? ALLDOUBLE : ALLONGLONG)
198 #endif
199
200 /* allowed number of args */
201 #define A_0ARG  0x01
202 #define A_1ARG  0x02
203 #define A_2ARG  0x04
204 #define A_3ARG  0x08
205 /* arg # is a name */
206 #define A1_NAME 0x10
207 #define A2_NAME 0x20
208 #define A3_NAME 0x40
209 #define A_MANY  0x80
210 /* arg # is "string" */
211 #define A1_STR  0x100
212 #define A2_STR  0x200
213 #define A3_STR  0x400
214
215 #ifdef __MSC__
216 #define CS(x)
217 #else
218 #define CS(x) [x] =
219 #endif
220
221 struct atax {
222         int typ;
223         char *name;
224 atax[GCC_ATYP_MAX] = {
225         CS(ATTR_NONE)           { 0NULL },
226         CS(ATTR_COMPLEX)        { 0NULL },
227         CS(xxxATTR_BASETYP)     { 0NULL },
228         CS(ATTR_QUALTYP)        { 0NULL },
229         CS(ATTR_STRUCT)         { 0NULL },
230         CS(GCC_ATYP_ALIGNED)    { A_0ARG|A_1ARG"aligned" },
231         CS(GCC_ATYP_PACKED)     { A_0ARG|A_1ARG"packed" },
232         CS(GCC_ATYP_SECTION)    { A_1ARG|A1_STR"section" },
233         CS(GCC_ATYP_TRANSP_UNION) { A_0ARG"transparent_union" },
234         CS(GCC_ATYP_UNUSED)     { A_0ARG"unused" },
235         CS(GCC_ATYP_DEPRECATED) { A_0ARG"deprecated" },
236         CS(GCC_ATYP_MAYALIAS)   { A_0ARG"may_alias" },
237         CS(GCC_ATYP_MODE)       { A_1ARG|A1_NAME"mode" },
238         CS(GCC_ATYP_NORETURN)   { A_0ARG"noreturn" },
239         CS(GCC_ATYP_FORMAT)     { A_3ARG|A1_NAME"format" },
240         CS(GCC_ATYP_NONNULL)    { A_MANY"nonnull" },
241         CS(GCC_ATYP_SENTINEL)   { A_0ARG|A_1ARG"sentinel" },
242         CS(GCC_ATYP_WEAK)       { A_0ARG"weak" },
243         CS(GCC_ATYP_FORMATARG)  { A_1ARG"format_arg" },
244         CS(GCC_ATYP_GNU_INLINE) { A_0ARG"gnu_inline" },
245         CS(GCC_ATYP_MALLOC)     { A_0ARG"malloc" },
246         CS(GCC_ATYP_NOTHROW)    { A_0ARG"nothrow" },
247         CS(GCC_ATYP_CONST)      { A_0ARG"const" },
248         CS(GCC_ATYP_PURE)       { A_0ARG"pure" },
249         CS(GCC_ATYP_CONSTRUCTOR) { A_0ARG"constructor" },
250         CS(GCC_ATYP_DESTRUCTOR) { A_0ARG"destructor" },
251         CS(GCC_ATYP_VISIBILITY) { A_1ARG|A1_STR"visibility" },
252         CS(GCC_ATYP_STDCALL)    { A_0ARG"stdcall" },
253         CS(GCC_ATYP_CDECL)      { A_0ARG"cdecl" },
254         CS(GCC_ATYP_WARN_UNUSED_RESULT) { A_0ARG"warn_unused_result" },
255         CS(GCC_ATYP_USED)       { A_0ARG"used" },
256         CS(GCC_ATYP_NO_INSTR_FUN) { A_0ARG"no_instrument_function" },
257         CS(GCC_ATYP_NOINLINE)   { A_0ARG"noinline" },
258         CS(GCC_ATYP_ALIAS)      { A_1ARG|A1_STR"alias" },
259         CS(GCC_ATYP_WEAKREF)    { A_0ARG|A_1ARG|A1_STR"weakref" },
260         CS(GCC_ATYP_ALLOCSZ)    { A_1ARG|A_2ARG"alloc_size" },
261         CS(GCC_ATYP_ALW_INL)    { A_0ARG"always_inline" },
262         CS(GCC_ATYP_TLSMODEL)   { A_1ARG|A1_STR"tls_model" },
263         CS(GCC_ATYP_ALIASWEAK)  { A_1ARG|A1_STR"aliasweak" },
264
265         CS(GCC_ATYP_BOUNDED)    { A_3ARG|A_MANY|A1_NAME"bounded" },
266 };
267
268 #if SZPOINT(CHAR) == SZLONGLONG
269 #define GPT     LONGLONG
270 #else
271 #define GPT     INT
272 #endif
273
274 struct atax mods[] = {
275         { 0NULL },
276         { INT"SI" },
277         { INT"word" },
278         { GPT"pointer" },
279         { CHAR"byte" },
280         { CHAR"QI" },
281         { SHORT"HI" },
282         { LONGLONG"DI" },
283         { FLOAT"SF" },
284         { DOUBLE"DF" },
285         { LDOUBLE"XF" },
286         { FCOMPLEX"SC" },
287         { COMPLEX"DC" },
288         { LCOMPLEX"XC" },
289 #ifdef TARGET_MODS
290         TARGET_MODS
291 #endif
292 };
293 #define ATSZ    (sizeof(mods)/sizeof(mods[0]))
294
295 static int
296 amatch(char *sstruct atax *atint mx)
297 {
298         int ilen;
299
300         if (s[0] == '_' && s[1] == '_')
301                 s += 2;
302         len = strlen(s);
303         if (len > 2 && s[len-1] == '_' && s[len-2] == '_')
304                 len -= 2;
305         for (i = 0i < mxi++) {
306                 char *t = at[i].name;
307                 if (t != NULL && strncmp(stlen) == 0 && t[len] == 0)
308                         return i;
309         }
310         return 0;
311 }
312
313 static void
314 setaarg(int strunion aarg *aaNODE *p)
315 {
316         if (str) {
317                 if (((str & (A1_STR|A2_STR|A3_STR)) && p->n_op != STRING) ||
318                     ((str & (A1_NAME|A2_NAME|A3_NAME)) && p->n_op != NAME))
319                         uerror("bad arg to attribute");
320                 if (p->n_op == STRING) {
321                         aa->sarg = newstring(p->n_namestrlen(p->n_name)+1);
322                 } else
323                         aa->sarg = (char *)p->n_sp;
324                 nfree(p);
325         } else
326                 aa->iarg = (int)icons(eve(p));
327 }
328
329 /*
330  * Parse attributes from an argument list.
331  */
332 static struct attr *
333 gcc_attribs(NODE *p)
334 {
335         NODE *q, *r;
336         struct attr *ap;
337         char *name = NULL, *c;
338         int cwattrnargi;
339
340         if (p->n_op == NAME) {
341                 name = (char *)p->n_sp;
342         } else if (p->n_op == CALL || p->n_op == UCALL) {
343                 name = (char *)p->n_left->n_sp;
344         } else if (p->n_op == ICON && p->n_type == STRTY) {
345                 return NULL;
346         } else
347                 cerror("bad variable attribute");
348
349         if ((attr = amatch(nameataxGCC_ATYP_MAX)) == 0) {
350                 werror("unsupported attribute '%s'"name);
351                 ap = NULL;
352                 goto out;
353         }
354         narg = 0;
355         if (p->n_op == CALL)
356                 for (narg = 1q = p->n_rightq->n_op == CMq = q->n_left)
357                         narg++;
358
359         cw = atax[attr].typ;
360         if (!(cw & A_MANY) && ((narg > 3) || ((cw & (1 << narg)) == 0))) {
361                 uerror("wrong attribute arg count");
362                 return NULL;
363         }
364         ap = attr_new(attr3); /* XXX should be narg */
365         q = p->n_right;
366
367         switch (narg) {
368         default:
369                 /* XXX */
370                 while (narg-- > 3) {
371                         r = q;
372                         q = q->n_left;
373                         tfree(r->n_right);
374                         nfree(r);
375                 }
376                 /* FALLTHROUGH */
377         case 3:
378                 setaarg(cw & (A3_NAME|A3_STR), &ap->aa[2], q->n_right);
379                 r = q;
380                 q = q->n_left;
381                 nfree(r);
382                 /* FALLTHROUGH */
383         case 2:
384                 setaarg(cw & (A2_NAME|A2_STR), &ap->aa[1], q->n_right);
385                 r = q;
386                 q = q->n_left;
387                 nfree(r);
388                 /* FALLTHROUGH */
389         case 1:
390                 setaarg(cw & (A1_NAME|A1_STR), &ap->aa[0], q);
391                 p->n_op = UCALL;
392                 /* FALLTHROUGH */
393         case 0:
394                 break;
395         }
396
397         /* some attributes must be massaged special */
398         switch (attr) {
399         case GCC_ATYP_ALIGNED:
400                 if (narg == 0)
401                         ap->aa[0].iarg = ALMAX;
402                 else
403                         ap->aa[0].iarg *= SZCHAR;
404                 break;
405         case GCC_ATYP_PACKED:
406                 if (narg == 0)
407                         ap->aa[0].iarg = 1/* bitwise align */
408                 else
409                         ap->aa[0].iarg *= SZCHAR;
410                 break;
411
412         case GCC_ATYP_MODE:
413                 if ((i = amatch(ap->aa[0].sargmodsATSZ)) == 0)
414                         werror("unknown mode arg %s"ap->aa[0].sarg);
415                 ap->aa[0].iarg = ctype(mods[i].typ);
416                 break;
417
418         case GCC_ATYP_VISIBILITY:
419                 c = ap->aa[0].sarg;
420                 if (strcmp(c"default") && strcmp(c"hidden") &&
421                     strcmp(c"internal") && strcmp(c"protected"))
422                         werror("unknown visibility %s"c);
423                 break;
424
425         case GCC_ATYP_TLSMODEL:
426                 c = ap->aa[0].sarg;
427                 if (strcmp(c"global-dynamic") && strcmp(c"local-dynamic") &&
428                     strcmp(c"initial-exec") && strcmp(c"local-exec"))
429                         werror("unknown tls model %s"c);
430                 break;
431
432         default:
433                 break;
434         }
435 out:
436         return ap;
437 }
438
439 /*
440  * Extract attributes from a node tree and return attribute entries 
441  * based on its contents.
442  */
443 struct attr *
444 gcc_attr_parse(NODE *p)
445 {
446         struct attr *b, *c;
447
448         if (p == NIL)
449                 return NULL;
450
451         if (p->n_op != CM) {
452                 b = gcc_attribs(p);
453                 tfree(p);
454         } else {
455                 b = gcc_attr_parse(p->n_left);
456                 c = gcc_attr_parse(p->n_right);
457                 nfree(p);
458                 b = b ? attr_add(bc) : c;
459         }
460         return b;
461 }
462
463 /*
464  * Fixup struct/unions depending on attributes.
465  */
466 void
467 gcc_tcattrfix(NODE *p)
468 {
469         struct symtab *sp;
470         struct attr *ap;
471         int szcoffcszaloalmxal;
472
473         if ((ap = attr_find(p->n_apGCC_ATYP_PACKED)) == NULL)
474                 return/* nothing to fix */
475
476         al = ap->iarg(0);
477         mxal = 0;
478
479         /* Must repack struct */
480         coff = csz = 0;
481         for (sp = strmemb(ap); spsp = sp->snext) {
482                 oal = talign(sp->stypesp->sap);
483                 if (oal > al)
484                         oal = al;
485                 if (mxal < oal)
486                         mxal = oal;
487                 if (sp->sclass & FIELD)
488                         sz = sp->sclass&FLDSIZ;
489                 else
490                         sz = (int)tsize(sp->stypesp->sdfsp->sap);
491                 sp->soffset = upoff(szoal, &coff);
492                 if (coff > csz)
493                         csz = coff;
494                 if (p->n_type == UNIONTY)
495                         coff = 0;
496         }
497         if (mxal < ALCHAR)
498                 mxal = ALCHAR/* for bitfields */
499         SETOFF(cszmxal); /* Roundup to whatever */
500
501         ap = attr_find(p->n_apATTR_STRUCT);
502         ap->amsize = csz;
503         ap = attr_find(p->n_apGCC_ATYP_ALIGNED);
504         ap->iarg(0) = mxal;
505
506 }
507
508 /*
509  * gcc-specific pragmas.
510  */
511 int
512 pragmas_gcc(char *t)
513 {
plunky
1.2
514         char u;
515         int ignwarnerri;
ragge
1.1
516         extern bittype warnary[], werrary[];
517         extern char *flagstr[], *pragstore;
518
519         if (strcmp((t = pragtok(NULL)), "diagnostic") == 0) {
520                 ign = warn = err = 0;
521                 if (strcmp((t = pragtok(NULL)), "ignored") == 0)
522                         ign = 1;
523                 else if (strcmp(t"warning") == 0)
524                         warn = 1;
525                 else if (strcmp(t"error") == 0)
526                         err = 1;
527                 else
528                         return 1;
529                 if (eat('\"') || eat('-'))
530                         return 1;
531                 for (t = pragstore; *t && *t != '\"'t++)
532                         ;
533                 u = *t;
534                 *t = 0;
535                 for (i = 0i < NUMWi++) {
536                         if (strcmp(flagstr[i], pragstore+1) != 0)
537                                 continue;
538                         if (err) {
539                                 BITSET(warnaryi);
540                                 BITSET(werraryi);
541                         } else if (warn) {
542                                 BITSET(warnaryi);
543                                 BITCLEAR(werraryi);
544                         } else {
545                                 BITCLEAR(warnaryi);
546                                 BITCLEAR(werraryi);
547                         }
548                         return 0;
549                 }
550                 *t = u;
551         } else if (strcmp(t"poison") == 0) {
552                 /* currently ignore */;
553         } else if (strcmp(t"visibility") == 0) {
554                 /* currently ignore */;
555         } else if (strcmp(t"system_header") == 0) {
556                 /* currently ignore */;
557         } else
558                 werror("gcc pragma unsupported");
559         return 0;
560 }
561
562 #ifdef PCC_DEBUG
563 void
564 dump_attr(struct attr *ap)
565 {
566         printf("attributes; ");
567         for (; apap = ap->next) {
568                 if (ap->atype >= GCC_ATYP_MAX) {
569                         printf("bad type %d, "ap->atype);
570                 } else if (atax[ap->atype].name == 0) {
571                         char *c = ap->atype == ATTR_COMPLEX ? "complex" :
572                             ap->atype == ATTR_STRUCT ? "struct" : "badtype";
573                         printf("%s, "c);
574                 } else {
575                         printf("%s: "atax[ap->atype].name);
576                         printf("%d %d %d, "ap->iarg(0),
577                             ap->iarg(1), ap->iarg(2));
578                 }
579         }
580         printf("\n");
581 }
582 #endif
583 #endif
FishEye: Open Source License registered to PCC.
Your maintenance has expired. You can renew your license at http://www.atlassian.com/fisheye/renew
Atlassian FishEye, CVS analysis. (Version:1.6.3 Build:build-336 2008-11-04) - Administration - Page generated 2014-08-29 16:02 +0200