]> git.draconx.ca Git - cdecl99.git/blob - src/parse-decl.c
Add support for pointer declarators.
[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_declspecs(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         for (struct cdecl_declspec *c = s; c; c = c->next) {
19                 switch (cdecl_spec_kind(c)) {
20                 case CDECL_SPEC_TYPE:
21                         continue;
22                 case CDECL_SPEC_STOR:
23                         if (++num_storage > 1) {
24                                 fprintf(stderr, "too many storage-class specifiers\n");
25                                 return -1;
26                         }
27                         break;
28                 case CDECL_SPEC_QUAL:
29                         /*
30                          * Restrict qualifiers are only valid in the
31                          * pointer qualifier list, which isn't checked here.
32                          */
33                         if (c->type == CDECL_QUAL_RESTRICT) {
34                                 fprintf(stderr, "only pointer types can be restrict-qualified.\n");
35                                 return -1;
36                         }
37                         break;
38                 case CDECL_SPEC_FUNC:
39                         /*
40                          * We don't support functions yet.
41                          */
42                         fprintf(stderr, "only function declarations may have function specifiers.\n");
43                         return -1;
44                 default:
45                         abort();
46                 }
47         }
48
49         return 0;
50 }
51
52 static int verify_decl(struct cdecl *decl)
53 {
54         return verify_declspecs(decl->specifiers);
55 }
56
57 struct cdecl *cdecl_parse_decl(const char *declstr)
58 {
59         YY_BUFFER_STATE state;
60         struct cdecl *decl;
61         int rc;
62
63         state = yy_scan_string(declstr);
64         rc = yyparse(&decl);
65         yy_delete_buffer(state);
66
67         if (rc != 0)
68                 return NULL;
69
70         rc = verify_decl(decl);
71         if (rc != 0) {
72                 cdecl_free(decl);
73                 return NULL;
74         }
75
76         return decl;
77 }