]> git.draconx.ca Git - cdecl99.git/blob - src/parse-decl.c
Add missing copyright headers.
[cdecl99.git] / src / parse-decl.c
1 /*
2  *  Parse and validate C declarations.
3  *  Copyright © 2011 Nick Bowler
4  *
5  *  This program is free software: you can redistribute it and/or modify
6  *  it under the terms of the GNU General Public License as published by
7  *  the Free Software Foundation, either version 3 of the License, or
8  *  (at your option) any later version.
9  *
10  *  This program is distributed in the hope that it will be useful,
11  *  but WITHOUT ANY WARRANTY; without even the implied warranty of
12  *  MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
13  *  GNU General Public License for more details.
14  *
15  *  You should have received a copy of the GNU General Public License
16  *  along with this program.  If not, see <http://www.gnu.org/licenses/>.
17  */
18 #include <stdio.h>
19 #include <assert.h>
20
21 #include "cdecl.h"
22 #include "typemap.h"
23 #include "parse.h"
24 #include "scan.h"
25
26 static int verify_declspecs(struct cdecl_declspec *s)
27 {
28         unsigned num_storage = 0;
29         unsigned long typemap;
30
31         typemap = cdecl__build_typemap(s);
32         if (typemap == -1)
33                 return -1;
34
35         for (struct cdecl_declspec *c = s; c; c = c->next) {
36                 switch (cdecl_spec_kind(c)) {
37                 case CDECL_SPEC_TYPE:
38                         continue;
39                 case CDECL_SPEC_STOR:
40                         if (++num_storage > 1) {
41                                 fprintf(stderr, "too many storage-class specifiers\n");
42                                 return -1;
43                         }
44                         break;
45                 case CDECL_SPEC_QUAL:
46                         /*
47                          * Restrict qualifiers are only valid in the
48                          * pointer qualifier list, which isn't checked here.
49                          */
50                         if (c->type == CDECL_QUAL_RESTRICT) {
51                                 fprintf(stderr, "only pointer types can be restrict-qualified.\n");
52                                 return -1;
53                         }
54                         break;
55                 case CDECL_SPEC_FUNC:
56                         /*
57                          * We don't support functions yet.
58                          */
59                         fprintf(stderr, "only function declarations may have function specifiers.\n");
60                         return -1;
61                 default:
62                         assert(0);
63                 }
64         }
65
66         return 0;
67 }
68
69 static int verify_decl(struct cdecl *decl)
70 {
71         return verify_declspecs(decl->specifiers);
72 }
73
74 struct cdecl *cdecl_parse_decl(const char *declstr)
75 {
76         YY_BUFFER_STATE state;
77         struct cdecl *decl;
78         int rc;
79
80         state = yy_scan_string(declstr);
81         rc = yyparse(&decl);
82         yy_delete_buffer(state);
83
84         if (rc != 0)
85                 return NULL;
86
87         rc = verify_decl(decl);
88         if (rc != 0) {
89                 cdecl_free(decl);
90                 return NULL;
91         }
92
93         return decl;
94 }