-
Notifications
You must be signed in to change notification settings - Fork 0
/
decl_common.hpp
138 lines (120 loc) · 3.25 KB
/
decl_common.hpp
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
#ifndef DECL_COMMON_HPP
#define DECL_COMMON_HPP
#include <llvm/IR/Type.h>
#include <set>
#include "ast.hpp"
/*
* (Section 6.7.1)
* Represents zero or more storage specifiers in the declaration specifiers
*
* Implementation restrictions:
* Since there is no plan to support threads, THREAD_LOCAL won't be supported.
* So removing THREAD_LOCAL implies there can be at most one storage specifier
* the declaration specifiers, so only one variable has been used
*/
class storage_specifiers : public ast_node {
public:
enum storage {
UNSET, // To indicate no storage specifier has been given
TYPEDEF,
EXTERN,
STATIC,
THREAD_LOCAL,
AUTO,
REGISTER
};
private:
storage spec;
public:
storage_specifiers(storage spec = UNSET);
storage_specifiers* add_spec(storage spec);
void dump_tree() override;
std::string to_string();
};
/*
* (Section 6.7.2)
* Represents one or more type specifiers in the declaration specifiers
*
* Implementation restrictions:
* - COMPLEX is not mandated and so not supported by this implementation
* - Does not contain atomic, struct, union, enum types. Implemented as derived
* classes
* - While there is always atleast one type specifier in the declaration
* specifiers, the UNSET enum is given so a type specifier can be added later
*/
class type_specifiers : public ast_node {
public:
enum type {
UNSET,
VOID,
CHAR,
SCHAR,
UCHAR,
SHORT,
USHORT,
INT,
UINT,
LONG,
ULONG,
LONG_LONG,
ULONG_LONG,
FLOAT,
DOUBLE,
LONG_DOUBLE,
SIGNED,
UNSIGNED,
BOOL,
/* Doesn't include complex (non mandated) */
// TODO: Implement atomic, struct, union, enum as derived classes
};
private:
std::set<type> types_seen;
type specs;
type_specifiers* raise_incompat_error(type spec);
type_specifiers* change_type(type specs);
llvm::Type* get_llvm_type();
public:
type_specifiers(type spec = UNSET);
type_specifiers* add_spec(type spec);
type get_specs();
void dump_tree() override;
std::string to_string();
bool is_signed();
type_i get_type();
};
/*
* (Section 6.7.3)
* Represents one or more type qualifiers in the declaration specifiers
*/
class type_qualifiers : public ast_node {
public:
enum qualifier { CONST, RESTRICT, VOLATILE, ATOMIC };
private:
std::set<qualifier> qualifiers;
public:
type_qualifiers* add_qual(qualifier qual);
void dump_tree() override;
static std::string to_string(qualifier qual);
};
// TODO: Add function_specifier and alignment_specifier here
class pointer_node : public ast_node {
std::vector<type_qualifiers*> quals;
public:
pointer_node* add(type_qualifiers* quals);
void dump_tree() override;
// For a pointer is_signed is related to signedness of the pointed-to type
type_i get_type(type_i type);
};
class declaration_specs : public ast_node {
storage_specifiers storage_spec;
type_specifiers type_spec;
type_qualifiers type_qual;
// TODO: Add function_specifier and alignment specifier
public:
declaration_specs* add(storage_specifiers::storage storage_spec);
declaration_specs* add(type_specifiers::type type_spec);
declaration_specs* add(type_qualifiers::qualifier type_qual);
void dump_tree() override;
type_i get_type();
};
#endif /* DECL_COMMON_HPP */