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);
63 typedef struct AttrDesc AttrDesc;
66 void (*Handler) (Declaration*);
68 static const AttrDesc AttrTable [] = {
69 { "__noreturn__", NoReturnAttr },
70 { "noreturn", NoReturnAttr },
75 /*****************************************************************************/
77 /*****************************************************************************/
81 static DeclAttr* NewDeclAttr (DeclAttrType AttrType)
82 /* Create a new DeclAttr struct and return it */
85 DeclAttr* A = xmalloc (sizeof (DeclAttr));
87 /* Initialize the fields */
88 A->AttrType = AttrType;
90 /* Return the new struct */
96 /*****************************************************************************/
97 /* Helper functions */
98 /*****************************************************************************/
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.
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) {
113 return AttrTable + A;
123 static void ErrorSkip (void)
125 /* List of tokens to skip */
126 static const token_t SkipList[] = { TOK_RPAREN, TOK_SEMI };
128 /* Skip until closing brace or semicolon */
129 SkipTokens (SkipList, sizeof (SkipList) / sizeof (SkipList[0]));
131 /* If we have a closing brace, read it, otherwise bail out */
132 if (CurTok.Tok == TOK_RPAREN) {
133 /* Read the two closing braces */
141 static void AddAttr (Declaration* D, DeclAttr* A)
142 /* Add an attribute to a declaration */
144 /* Allocate the list if necessary, the add the attribute */
145 if (D->Attributes == 0) {
146 D->Attributes = NewCollection ();
148 CollAppend (D->Attributes, A);
153 /*****************************************************************************/
154 /* Attribute handling code */
155 /*****************************************************************************/
159 void NoReturnAttr (Declaration* D)
160 /* Parse the "noreturn" attribute */
162 /* Add the noreturn attribute */
163 AddAttr (D, NewDeclAttr (atNoReturn));
168 void ParseAttribute (Declaration* D)
169 /* Parse an additional __attribute__ modifier */
171 /* Do we have an attribute? */
172 if (CurTok.Tok != TOK_ATTRIBUTE) {
173 /* No attribute, bail out */
177 /* Skip the attribute token */
180 /* Expect two(!) open braces */
184 /* Read a list of attributes */
188 const AttrDesc* Attr = 0;
190 /* Identifier follows */
191 if (CurTok.Tok != TOK_IDENT) {
193 /* No attribute name */
194 Error ("Attribute name expected");
196 /* Skip until end of attribute */
203 /* Map the attribute name to its id, then skip the identifier */
204 strcpy (AttrName, CurTok.Ident);
205 Attr = FindAttribute (AttrName);
208 /* Did we find a valid attribute? */
211 /* Call the handler */
215 /* Attribute not known, maybe typo */
216 Error ("Illegal attribute: `%s'", AttrName);
218 /* Skip until end of attribute */
225 /* If a comma follows, there's a next attribute. Otherwise this is the
226 * end of the attribute list.
228 if (CurTok.Tok != TOK_COMMA) {
234 /* The declaration is terminated with two closing braces */