]> git.sur5r.net Git - cc65/blob - src/cc65/declattr.c
Fixed handling of function definitions with an empty parameter list. According
[cc65] / src / cc65 / declattr.c
1 /*****************************************************************************/
2 /*                                                                           */
3 /*                                declattr.c                                 */
4 /*                                                                           */
5 /*                          Declaration attributes                           */
6 /*                                                                           */
7 /*                                                                           */
8 /*                                                                           */
9 /* (C) 2000-2002 Ullrich von Bassewitz                                       */
10 /*               Wacholderweg 14                                             */
11 /*               D-70597 Stuttgart                                           */
12 /* EMail:        uz@musoftware.de                                            */
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 /* cc65 */
39 #include "error.h"
40 #include "scanner.h"
41 #include "symtab.h"
42 #include "typecmp.h"
43 #include "declattr.h"
44
45
46
47 /*****************************************************************************/
48 /*                                   Data                                    */
49 /*****************************************************************************/
50
51
52
53 /* Forwards for attribute handlers */
54 static void AliasAttr (const Declaration* D, DeclAttr* A);
55 static void UnusedAttr (const Declaration* D, DeclAttr* A);
56 static void ZeroPageAttr (const Declaration* D, DeclAttr* A);
57
58
59
60 /* Attribute table */
61 typedef struct AttrDesc AttrDesc;
62 struct AttrDesc {
63     const char  Name[12];
64     void        (*Handler) (const Declaration*, DeclAttr*);
65 };
66 static const AttrDesc AttrTable [atCount] = {
67     { "alias",          AliasAttr       },
68     { "unused",         UnusedAttr      },
69     { "zeropage",       ZeroPageAttr    },
70 };
71
72
73
74 /*****************************************************************************/
75 /*                                   Code                                    */
76 /*****************************************************************************/
77
78
79
80 static const AttrDesc* FindAttribute (const char* Attr)
81 /* Search the attribute and return the corresponding attribute descriptor.
82  * Return NULL if the attribute name is not known.
83  */
84 {
85     unsigned A;
86
87     /* For now do a linear search */
88     for (A = 0; A < atCount; ++A) {
89         if (strcmp (Attr, AttrTable[A].Name) == 0) {
90             /* Found */
91             return AttrTable + A;
92         }
93     }
94
95     /* Not found */
96     return 0;
97 }
98
99
100
101 static void AliasAttr (const Declaration* D, DeclAttr* A)
102 /* Handle the "alias" attribute */
103 {
104     SymEntry* Sym;
105
106     /* Comma expected */
107     ConsumeComma ();
108
109     /* The next identifier is the name of the alias symbol */
110     if (CurTok.Tok != TOK_IDENT) {
111         Error ("Identifier expected");
112         return;
113     }
114
115     /* Lookup the symbol for this name, it must exist */
116     Sym = FindSym (CurTok.Ident);
117     if (Sym == 0) {
118         Error ("Unknown identifier: `%s'", CurTok.Ident);
119         NextToken ();
120         return;
121     }
122
123     /* Since we have the symbol entry now, skip the name */
124     NextToken ();
125
126     /* Check if the types of the symbols are identical */
127     if (TypeCmp (D->Type, Sym->Type) < TC_EQUAL) {
128         /* Types are not identical */
129         Error ("Incompatible types");
130         return;
131     }
132
133     /* Attribute is verified, set the stuff in the attribute description */
134     A->AttrType = atAlias;
135     A->V.Sym    = Sym;
136 }
137
138
139
140 static void UnusedAttr (const Declaration* D attribute ((unused)), DeclAttr* A)
141 /* Handle the "unused" attribute */
142 {
143     /* No parameters */
144     A->AttrType = atUnused;
145 }
146
147
148
149 static void ZeroPageAttr (const Declaration* D attribute ((unused)), DeclAttr* A)
150 /* Handle the "zeropage" attribute */
151 {
152     /* No parameters */
153     A->AttrType = atZeroPage;
154 }
155
156
157
158 void ParseAttribute (const Declaration* D, DeclAttr* A)
159 /* Parse an additional __attribute__ modifier */
160 {
161     ident           AttrName;
162     const AttrDesc* Attr;
163
164     /* Initialize the attribute description with "no attribute" */
165     A->AttrType = atNone;
166
167     /* Do we have an attribute? */
168     if (CurTok.Tok != TOK_ATTRIBUTE) {
169         /* No attribute, bail out */
170         return;
171     }
172
173     /* Skip the attribute token */
174     NextToken ();
175
176     /* Expect two(!) open braces */
177     ConsumeLParen ();
178     ConsumeLParen ();
179
180     /* Identifier follows */
181     if (CurTok.Tok != TOK_IDENT) {
182         Error ("Identifier expected");
183         /* We should *really* try to recover here, but for now: */
184         return;
185     }
186
187     /* Map the attribute name to its id, then skip the identifier */
188     strcpy (AttrName, CurTok.Ident);
189     Attr = FindAttribute (AttrName);
190     NextToken ();
191
192     /* Did we find a valid attribute? */
193     if (Attr) {
194
195         /* Call the handler */
196         Attr->Handler (D, A);
197
198         /* Read the two closing braces */
199         ConsumeRParen ();
200         ConsumeRParen ();
201
202     } else {
203         /* List of tokens to skip */
204         static const token_t SkipList[] = { TOK_LPAREN, TOK_SEMI };
205
206         /* Attribute not known, maybe typo */
207         Error ("Illegal attribute: `%s'", AttrName);
208
209         /* Skip until closing brace or semicolon */
210         SkipTokens (SkipList, sizeof (SkipList) / sizeof (SkipList[0]));
211
212         /* If we have a closing brace, read it, otherwise bail out */
213         if (CurTok.Tok == TOK_LPAREN) {
214             /* Read the two closing braces */
215             ConsumeRParen ();
216             ConsumeRParen ();
217         }
218     }
219 }
220
221
222