1 /*****************************************************************************/
5 /* Declaration attributes */
9 /* (C) 1998-2009, Ullrich von Bassewitz */
10 /* Roemerstrasse 52 */
11 /* D-70794 Filderstadt */
12 /* EMail: uz@cc65.org */
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. */
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: */
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 */
32 /*****************************************************************************/
51 /*****************************************************************************/
53 /*****************************************************************************/
57 /* Forwards for attribute handlers */
58 static void NoReturnAttr (Declaration* D);
59 static void UnusedAttr (Declaration* D);
64 typedef struct AttrDesc AttrDesc;
67 void (*Handler) (Declaration*);
69 static const AttrDesc AttrTable [] = {
70 { "__noreturn__", NoReturnAttr },
71 { "__unused__", UnusedAttr },
72 { "noreturn", NoReturnAttr },
73 { "unused", UnusedAttr },
78 /*****************************************************************************/
80 /*****************************************************************************/
84 static DeclAttr* NewDeclAttr (DeclAttrType AttrType)
85 /* Create a new DeclAttr struct and return it */
88 DeclAttr* A = xmalloc (sizeof (DeclAttr));
90 /* Initialize the fields */
91 A->AttrType = AttrType;
93 /* Return the new struct */
99 /*****************************************************************************/
100 /* Helper functions */
101 /*****************************************************************************/
105 static const AttrDesc* FindAttribute (const char* Attr)
106 /* Search the attribute and return the corresponding attribute descriptor.
107 * Return NULL if the attribute name is not known.
112 /* For now do a linear search */
113 for (A = 0; A < sizeof (AttrTable) / sizeof (AttrTable[0]); ++A) {
114 if (strcmp (Attr, AttrTable[A].Name) == 0) {
116 return AttrTable + A;
126 static void ErrorSkip (void)
128 /* List of tokens to skip */
129 static const token_t SkipList[] = { TOK_RPAREN, TOK_SEMI };
131 /* Skip until closing brace or semicolon */
132 SkipTokens (SkipList, sizeof (SkipList) / sizeof (SkipList[0]));
134 /* If we have a closing brace, read it, otherwise bail out */
135 if (CurTok.Tok == TOK_RPAREN) {
136 /* Read the two closing braces */
144 static void AddAttr (Declaration* D, DeclAttr* A)
145 /* Add an attribute to a declaration */
147 /* Allocate the list if necessary, the add the attribute */
148 if (D->Attributes == 0) {
149 D->Attributes = NewCollection ();
151 CollAppend (D->Attributes, A);
156 /*****************************************************************************/
157 /* Attribute handling code */
158 /*****************************************************************************/
162 static void NoReturnAttr (Declaration* D)
163 /* Parse the "noreturn" attribute */
165 /* Add the noreturn attribute */
166 AddAttr (D, NewDeclAttr (atNoReturn));
171 static void UnusedAttr (Declaration* D)
172 /* Parse the "unused" attribute */
174 /* Add the noreturn attribute */
175 AddAttr (D, NewDeclAttr (atUnused));
180 void ParseAttribute (Declaration* D)
181 /* Parse an additional __attribute__ modifier */
183 /* Do we have an attribute? */
184 if (CurTok.Tok != TOK_ATTRIBUTE) {
185 /* No attribute, bail out */
189 /* Skip the attribute token */
192 /* Expect two(!) open braces */
196 /* Read a list of attributes */
200 const AttrDesc* Attr = 0;
202 /* Identifier follows */
203 if (CurTok.Tok != TOK_IDENT) {
205 /* No attribute name */
206 Error ("Attribute name expected");
208 /* Skip until end of attribute */
215 /* Map the attribute name to its id, then skip the identifier */
216 strcpy (AttrName, CurTok.Ident);
217 Attr = FindAttribute (AttrName);
220 /* Did we find a valid attribute? */
223 /* Call the handler */
227 /* Attribute not known, maybe typo */
228 Error ("Illegal attribute: `%s'", AttrName);
230 /* Skip until end of attribute */
237 /* If a comma follows, there's a next attribute. Otherwise this is the
238 * end of the attribute list.
240 if (CurTok.Tok != TOK_COMMA) {
246 /* The declaration is terminated with two closing braces */