Quick Search:

View

Revision:
Expand:  
Changeset: MAIN:plunky:20140606131903

Diff

Diff from 1.8 to:

Annotations

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

Annotated File View

plunky
1.8
1 /*      $Id: gcc_compat.c,v 1.8 2014/06/06 13:19:03 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 },
ragge
1.7
230         CS(ATTR_ALIGNED)        { A_0ARG|A_1ARG"aligned" },
ragge
1.1
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" },
plunky
1.6
264         CS(GCC_ATYP_REGPARM)    { A_1ARG"regparm" },
ragge
1.1
265
266         CS(GCC_ATYP_BOUNDED)    { A_3ARG|A_MANY|A1_NAME"bounded" },
267 };
268
269 #if SZPOINT(CHAR) == SZLONGLONG
270 #define GPT     LONGLONG
271 #else
272 #define GPT     INT
273 #endif
274
275 struct atax mods[] = {
276         { 0NULL },
277         { INT"SI" },
278         { INT"word" },
279         { GPT"pointer" },
280         { CHAR"byte" },
281         { CHAR"QI" },
282         { SHORT"HI" },
283         { LONGLONG"DI" },
284         { FLOAT"SF" },
285         { DOUBLE"DF" },
286         { LDOUBLE"XF" },
287         { FCOMPLEX"SC" },
288         { COMPLEX"DC" },
289         { LCOMPLEX"XC" },
290 #ifdef TARGET_MODS
291         TARGET_MODS
292 #endif
293 };
294 #define ATSZ    (sizeof(mods)/sizeof(mods[0]))
295
296 static int
297 amatch(char *sstruct atax *atint mx)
298 {
299         int ilen;
300
301         if (s[0] == '_' && s[1] == '_')
302                 s += 2;
303         len = strlen(s);
304         if (len > 2 && s[len-1] == '_' && s[len-2] == '_')
305                 len -= 2;
306         for (i = 0i < mxi++) {
307                 char *t = at[i].name;
308                 if (t != NULL && strncmp(stlen) == 0 && t[len] == 0)
309                         return i;
310         }
311         return 0;
312 }
313
314 static void
315 setaarg(int strunion aarg *aaNODE *p)
316 {
317         if (str) {
318                 if (((str & (A1_STR|A2_STR|A3_STR)) && p->n_op != STRING) ||
319                     ((str & (A1_NAME|A2_NAME|A3_NAME)) && p->n_op != NAME))
320                         uerror("bad arg to attribute");
321                 if (p->n_op == STRING) {
plunky
1.4
322                         aa->sarg = newstring(p->n_namestrlen(p->n_name));
ragge
1.1
323                 } else
324                         aa->sarg = (char *)p->n_sp;
325                 nfree(p);
326         } else
327                 aa->iarg = (int)icons(eve(p));
328 }
329
330 /*
331  * Parse attributes from an argument list.
332  */
333 static struct attr *
334 gcc_attribs(NODE *p)
335 {
336         NODE *q, *r;
337         struct attr *ap;
338         char *name = NULL, *c;
339         int cwattrnargi;
340
341         if (p->n_op == NAME) {
342                 name = (char *)p->n_sp;
343         } else if (p->n_op == CALL || p->n_op == UCALL) {
344                 name = (char *)p->n_left->n_sp;
345         } else if (p->n_op == ICON && p->n_type == STRTY) {
346                 return NULL;
347         } else
348                 cerror("bad variable attribute");
349
350         if ((attr = amatch(nameataxGCC_ATYP_MAX)) == 0) {
351                 werror("unsupported attribute '%s'"name);
352                 ap = NULL;
353                 goto out;
354         }
355         narg = 0;
356         if (p->n_op == CALL)
357                 for (narg = 1q = p->n_rightq->n_op == CMq = q->n_left)
358                         narg++;
359
360         cw = atax[attr].typ;
361         if (!(cw & A_MANY) && ((narg > 3) || ((cw & (1 << narg)) == 0))) {
362                 uerror("wrong attribute arg count");
363                 return NULL;
364         }
365         ap = attr_new(attr3); /* XXX should be narg */
366         q = p->n_right;
367
368         switch (narg) {
369         default:
370                 /* XXX */
371                 while (narg-- > 3) {
372                         r = q;
373                         q = q->n_left;
374                         tfree(r->n_right);
375                         nfree(r);
376                 }
377                 /* FALLTHROUGH */
378         case 3:
379                 setaarg(cw & (A3_NAME|A3_STR), &ap->aa[2], q->n_right);
380                 r = q;
381                 q = q->n_left;
382                 nfree(r);
383                 /* FALLTHROUGH */
384         case 2:
385                 setaarg(cw & (A2_NAME|A2_STR), &ap->aa[1], q->n_right);
386                 r = q;
387                 q = q->n_left;
388                 nfree(r);
389                 /* FALLTHROUGH */
390         case 1:
391                 setaarg(cw & (A1_NAME|A1_STR), &ap->aa[0], q);
392                 p->n_op = UCALL;
393                 /* FALLTHROUGH */
394         case 0:
395                 break;
396         }
397
398         /* some attributes must be massaged special */
399         switch (attr) {
ragge
1.7
400         case ATTR_ALIGNED:
ragge
1.1
401                 if (narg == 0)
402                         ap->aa[0].iarg = ALMAX;
403                 else
404                         ap->aa[0].iarg *= SZCHAR;
405                 break;
406         case GCC_ATYP_PACKED:
407                 if (narg == 0)
408                         ap->aa[0].iarg = 1/* bitwise align */
409                 else
410                         ap->aa[0].iarg *= SZCHAR;
411                 break;
412
413         case GCC_ATYP_MODE:
414                 if ((i = amatch(ap->aa[0].sargmodsATSZ)) == 0)
415                         werror("unknown mode arg %s"ap->aa[0].sarg);
416                 ap->aa[0].iarg = ctype(mods[i].typ);
417                 break;
418
419         case GCC_ATYP_VISIBILITY:
420                 c = ap->aa[0].sarg;
421                 if (strcmp(c"default") && strcmp(c"hidden") &&
422                     strcmp(c"internal") && strcmp(c"protected"))
423                         werror("unknown visibility %s"c);
424                 break;
425
426         case GCC_ATYP_TLSMODEL:
427                 c = ap->aa[0].sarg;
428                 if (strcmp(c"global-dynamic") && strcmp(c"local-dynamic") &&
429                     strcmp(c"initial-exec") && strcmp(c"local-exec"))
430                         werror("unknown tls model %s"c);
431                 break;
432
433         default:
434                 break;
435         }
436 out:
437         return ap;
438 }
439
440 /*
441  * Extract attributes from a node tree and return attribute entries 
442  * based on its contents.
443  */
444 struct attr *
445 gcc_attr_parse(NODE *p)
446 {
447         struct attr *b, *c;
448
449         if (p == NIL)
450                 return NULL;
451
452         if (p->n_op != CM) {
453                 b = gcc_attribs(p);
454                 tfree(p);
455         } else {
456                 b = gcc_attr_parse(p->n_left);
457                 c = gcc_attr_parse(p->n_right);
458                 nfree(p);
459                 b = b ? attr_add(bc) : c;
460         }
461         return b;
462 }
463
464 /*
465  * Fixup struct/unions depending on attributes.
466  */
467 void
468 gcc_tcattrfix(NODE *p)
469 {
470         struct symtab *sp;
471         struct attr *ap;
472         int szcoffcszaloalmxal;
473
474         if ((ap = attr_find(p->n_apGCC_ATYP_PACKED)) == NULL)
475                 return/* nothing to fix */
476
477         al = ap->iarg(0);
478         mxal = 0;
479
480         /* Must repack struct */
481         coff = csz = 0;
482         for (sp = strmemb(ap); spsp = sp->snext) {
483                 oal = talign(sp->stypesp->sap);
484                 if (oal > al)
485                         oal = al;
486                 if (mxal < oal)
487                         mxal = oal;
488                 if (sp->sclass & FIELD)
489                         sz = sp->sclass&FLDSIZ;
490                 else
491                         sz = (int)tsize(sp->stypesp->sdfsp->sap);
492                 sp->soffset = upoff(szoal, &coff);
493                 if (coff > csz)
494                         csz = coff;
495                 if (p->n_type == UNIONTY)
496                         coff = 0;
497         }
498         if (mxal < ALCHAR)
499                 mxal = ALCHAR/* for bitfields */
500         SETOFF(cszmxal); /* Roundup to whatever */
501
502         ap = attr_find(p->n_apATTR_STRUCT);
503         ap->amsize = csz;
ragge
1.7
504         ap = attr_find(p->n_apATTR_ALIGNED);
ragge
1.1
505         ap->iarg(0) = mxal;
506
507 }
508
509 /*
510  * gcc-specific pragmas.
511  */
512 int
513 pragmas_gcc(char *t)
514 {
plunky
1.2
515         char u;
plunky
1.8
516         extern char *pragstore;
ragge
1.1
517
518         if (strcmp((t = pragtok(NULL)), "diagnostic") == 0) {
plunky
1.8
519                 int warnerr;
520
ragge
1.1
521                 if (strcmp((t = pragtok(NULL)), "ignored") == 0)
plunky
1.8
522                         warn = 0err = 0;
ragge
1.1
523                 else if (strcmp(t"warning") == 0)
plunky
1.8
524                         warn = 1err = 0;
ragge
1.1
525                 else if (strcmp(t"error") == 0)
plunky
1.8
526                         warn = 1err = 1;
ragge
1.1
527                 else
528                         return 1;
plunky
1.8
529
ragge
1.1
530                 if (eat('\"') || eat('-'))
531                         return 1;
plunky
1.8
532
ragge
1.1
533                 for (t = pragstore; *t && *t != '\"'t++)
534                         ;
plunky
1.8
535
ragge
1.1
536                 u = *t;
537                 *t = 0;
plunky
1.8
538                 Wset(pragstore + 1warnerr);
ragge
1.1
539                 *t = u;
540         } else if (strcmp(t"poison") == 0) {
541                 /* currently ignore */;
542         } else if (strcmp(t"visibility") == 0) {
543                 /* currently ignore */;
544         } else if (strcmp(t"system_header") == 0) {
545                 /* currently ignore */;
546         } else
547                 werror("gcc pragma unsupported");
548         return 0;
549 }
550
551 #ifdef PCC_DEBUG
552 void
553 dump_attr(struct attr *ap)
554 {
555         printf("attributes; ");
556         for (; apap = ap->next) {
557                 if (ap->atype >= GCC_ATYP_MAX) {
558                         printf("bad type %d, "ap->atype);
559                 } else if (atax[ap->atype].name == 0) {
560                         char *c = ap->atype == ATTR_COMPLEX ? "complex" :
561                             ap->atype == ATTR_STRUCT ? "struct" : "badtype";
562                         printf("%s, "c);
563                 } else {
564                         printf("%s: "atax[ap->atype].name);
565                         printf("%d %d %d, "ap->iarg(0),
566                             ap->iarg(1), ap->iarg(2));
567                 }
568         }
569         printf("\n");
570 }
571 #endif
572 #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-11-01 11:34 +0100