]> git.draconx.ca Git - cdecl99.git/blob - src/parse-decl.c
Move typemap stuff into a separate file.
[cdecl99.git] / src / parse-decl.c
1 #include <stdio.h>
2 #include <assert.h>
3
4 #include "cdecl.h"
5 #include "typemap.h"
6 #include "parse.h"
7 #include "scan.h"
8
9 static int verify_specs(struct cdecl_declspec *s)
10 {
11         unsigned num_storage = 0;
12         unsigned long typemap;
13
14         typemap = cdecl__build_typemap(s);
15         if (typemap == -1)
16                 return -1;
17
18         if (!cdecl__typemap_is_valid(typemap)) {
19                 fprintf(stderr, "conflicting type specifiers\n");
20                 return -1;
21         }
22
23         for (struct cdecl_declspec *c = s; c; c = c->next) {
24                 switch (cdecl_spec_kind(c)) {
25                 case CDECL_SPEC_TYPE:
26                         continue;
27                 case CDECL_SPEC_STOR:
28                         if (++num_storage > 1) {
29                                 fprintf(stderr, "too many storage-class specifiers\n");
30                                 return -1;
31                         }
32                         break;
33                 case CDECL_SPEC_QUAL:
34                         /*
35                          * Since we don't support pointer types yet, all
36                          * restrict qualifiers are invalid.  Other qualifiers
37                          * are always valid.
38                          */
39                         if (c->type == CDECL_QUAL_RESTRICT) {
40                                 fprintf(stderr, "only pointer types can be restrict-qualified.\n");
41                                 return -1;
42                         }
43                         break;
44                 case CDECL_SPEC_FUNC:
45                         /*
46                          * Likewise for function specifiers.
47                          */
48                         fprintf(stderr, "only function declarations may have function specifiers.\n");
49                         return -1;
50                 default:
51                         abort();
52                 }
53         }
54
55         return 0;
56 }
57
58 static int verify_decl(struct cdecl *decl)
59 {
60         return verify_specs(decl->specifiers);
61 }
62
63 struct cdecl *cdecl_parse_decl(const char *declstr)
64 {
65         YY_BUFFER_STATE state;
66         struct cdecl *decl;
67         int rc;
68
69         state = yy_scan_string(declstr);
70         rc = yyparse(&decl);
71         yy_delete_buffer(state);
72
73         if (rc != 0)
74                 return NULL;
75
76         rc = verify_decl(decl);
77         if (rc != 0) {
78                 cdecl_free(decl);
79                 return NULL;
80         }
81
82         return decl;
83 }