]> git.sur5r.net Git - cc65/blob - src/cc65/declattr.c
Fixed the existing but unused attribute parsing code. Added
[cc65] / src / cc65 / declattr.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                declattr.c                                 */
4 /*                                                                           */
5 /*                          Declaration attributes                           */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 1998-2009, Ullrich von Bassewitz                                      */
10 /*                Roemerstrasse 52                                           */
11 /*                D-70794 Filderstadt                                        */
12 /* EMail:         uz@cc65.org                                                */
13 /*                                                                           */
14 /*                                                                           */
15 /* This software is provided 'as-is', without any expressed or implied       */
16 /* warranty.  In no event will the authors be held liable for any damages    */
17 /* arising from the use of this software.                                    */
18 /*                                                                           */
19 /* Permission is granted to anyone to use this software for any purpose,     */
20 /* including commercial applications, and to alter it and redistribute it    */
21 /* freely, subject to the following restrictions:                            */
22 /*                                                                           */
23 /* 1. The origin of this software must not be misrepresented; you must not   */
24 /*    claim that you wrote the original software. If you use this software   */
25 /*    in a product, an acknowledgment in the product documentation would be  */
26 /*    appreciated but is not required.                                       */
27 /* 2. Altered source versions must be plainly marked as such, and must not   */
28 /*    be misrepresented as being the original software.                      */
29 /* 3. This notice may not be removed or altered from any source              */
30 /*    distribution.                                                          */
31 /*                                                                           */
32 /*****************************************************************************/
33
34
35
36 #include <string.h>
37
38 /* common */
39 #include "xmalloc.h"
40
41 /* cc65 */
42 #include "declare.h"
43 #include "declattr.h"
44 #include "error.h"
45 #include "scanner.h"
46 #include "symtab.h"
47 #include "typecmp.h"
48
49
50
51 /*****************************************************************************/
52 /*                                   Data                                    */
53 /*****************************************************************************/
54
55
56
57 /* Forwards for attribute handlers */
58 static void NoReturnAttr (Declaration* D);
59
60
61
62 /* Attribute table */
63 typedef struct AttrDesc AttrDesc;
64 struct AttrDesc {
65     const char  Name[15];
66     void        (*Handler) (Declaration*);
67 };
68 static const AttrDesc AttrTable [] = {
69     { "__noreturn__",   NoReturnAttr    },
70     { "noreturn",       NoReturnAttr    },
71 };
72
73
74
75 /*****************************************************************************/
76 /*                              Struct DeclAttr                              */
77 /*****************************************************************************/
78
79
80
81 static DeclAttr* NewDeclAttr (DeclAttrType AttrType)
82 /* Create a new DeclAttr struct and return it */
83 {
84     /* Allocate memory */
85     DeclAttr* A = xmalloc (sizeof (DeclAttr));
86
87     /* Initialize the fields */
88     A->AttrType = AttrType;
89
90     /* Return the new struct */
91     return A;
92 }
93
94
95
96 /*****************************************************************************/
97 /*                             Helper functions                              */
98 /*****************************************************************************/
99
100
101
102 static const AttrDesc* FindAttribute (const char* Attr)
103 /* Search the attribute and return the corresponding attribute descriptor.
104  * Return NULL if the attribute name is not known.
105  */
106 {
107     unsigned A;
108
109     /* For now do a linear search */
110     for (A = 0; A < sizeof (AttrTable) / sizeof (AttrTable[0]); ++A) {
111         if (strcmp (Attr, AttrTable[A].Name) == 0) {
112             /* Found */
113             return AttrTable + A;
114         }
115     }
116
117     /* Not found */
118     return 0;
119 }
120
121
122
123 static void ErrorSkip (void)
124 {
125     /* List of tokens to skip */
126     static const token_t SkipList[] = { TOK_RPAREN, TOK_SEMI };
127
128     /* Skip until closing brace or semicolon */
129     SkipTokens (SkipList, sizeof (SkipList) / sizeof (SkipList[0]));
130
131     /* If we have a closing brace, read it, otherwise bail out */
132     if (CurTok.Tok == TOK_RPAREN) {
133         /* Read the two closing braces */
134         ConsumeRParen ();
135         ConsumeRParen ();
136     }
137 }
138
139
140
141 static void AddAttr (Declaration* D, DeclAttr* A)
142 /* Add an attribute to a declaration */
143 {
144     /* Allocate the list if necessary, the add the attribute */
145     if (D->Attributes == 0) {
146         D->Attributes = NewCollection ();
147     }
148     CollAppend (D->Attributes, A);
149 }
150
151
152
153 /*****************************************************************************/
154 /*                          Attribute handling code                          */
155 /*****************************************************************************/
156
157
158
159 void NoReturnAttr (Declaration* D)
160 /* Parse the "noreturn" attribute */
161 {
162     /* Add the noreturn attribute */
163     AddAttr (D, NewDeclAttr (atNoReturn));
164 }
165
166
167
168 void ParseAttribute (Declaration* D)
169 /* Parse an additional __attribute__ modifier */
170 {
171     /* Do we have an attribute? */
172     if (CurTok.Tok != TOK_ATTRIBUTE) {
173         /* No attribute, bail out */
174         return;
175     }
176
177     /* Skip the attribute token */
178     NextToken ();
179
180     /* Expect two(!) open braces */
181     ConsumeLParen ();
182     ConsumeLParen ();
183
184     /* Read a list of attributes */
185     while (1) {
186
187         ident           AttrName;
188         const AttrDesc* Attr = 0;
189
190         /* Identifier follows */
191         if (CurTok.Tok != TOK_IDENT) {
192
193             /* No attribute name */
194             Error ("Attribute name expected");
195
196             /* Skip until end of attribute */
197             ErrorSkip ();
198
199             /* Bail out */
200             return;
201         }
202
203         /* Map the attribute name to its id, then skip the identifier */
204         strcpy (AttrName, CurTok.Ident);
205         Attr = FindAttribute (AttrName);
206         NextToken ();
207
208         /* Did we find a valid attribute? */
209         if (Attr) {
210
211             /* Call the handler */
212             Attr->Handler (D);
213
214         } else {
215             /* Attribute not known, maybe typo */
216             Error ("Illegal attribute: `%s'", AttrName);
217
218             /* Skip until end of attribute */
219             ErrorSkip ();
220
221             /* Bail out */
222             return;
223         }
224
225         /* If a comma follows, there's a next attribute. Otherwise this is the
226          * end of the attribute list.
227          */
228         if (CurTok.Tok != TOK_COMMA) {
229             break;
230         }
231         NextToken ();
232     }
233
234     /* The declaration is terminated with two closing braces */
235     ConsumeRParen ();
236     ConsumeRParen ();
237 }
238
239
240