-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathdeclarator.hpp
127 lines (104 loc) · 3.78 KB
/
declarator.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
#ifndef DECLARATOR_HPP
#define DECLARATOR_HPP
#include <llvm/IR/Function.h>
#include <llvm/IR/Type.h>
#include <string>
#include <vector>
#include "ast.hpp"
#include "decl_common.hpp"
class function_declarator; // forward declaration
class direct_decl : public ast_node {
public:
virtual void dump_tree();
virtual std::string get_identifier() = 0;
// TODO: Make this pure virtual
// Generate code for the declarator given type specifiers
virtual value codegen(type_i type) {
raise_error("codegen not defined for this direct declarator");
};
// Helper method to get a function declarator anywhere inside the declarator
// hierarchy, would return nullptr if not found
virtual function_declarator *get_func_decl() = 0;
};
class declarator_node : public direct_decl {
pointer_node *p; // optional
direct_decl *decl;
public:
declarator_node(direct_decl *decl, pointer_node *p = nullptr);
void dump_tree() override;
std::string get_identifier() override;
virtual function_declarator *get_func_decl() override {
return decl->get_func_decl();
}
type_i get_type(type_i type);
value codegen(type_i type) override;
};
class identifier_declarator : public direct_decl {
std::string identifier;
public:
identifier_declarator(std::string &&identifier);
void dump_tree() override;
std::string get_identifier() override;
function_declarator *get_func_decl() override { return nullptr; }
// This basically generates an alloca for a variable with given type
// specifiers. So this shouldn't be called when the declarator is part of a
// function
value codegen(type_i type) override;
};
////////////////// ARRAY DECLARATOR ///////////////////////
class array_declarator : public direct_decl {
direct_decl *decl;
public:
array_declarator(direct_decl *decl);
void dump_tree() override;
function_declarator *get_func_decl() override { return nullptr; }
value codegen(type_i type) override;
};
//////////////// FUNCTION DECLARATOR ///////////////////////
class param_declaration : public ast_node {
declaration_specs *decl_spec;
declarator_node *decl; // Optional
// TODO: Add option for abstract_declarator. Might be worth it to be break the
// class into 2 classes and make this virtual
public:
param_declaration(declaration_specs *decl_spec,
declarator_node *decl = nullptr);
void dump_tree() override;
type_i get_type();
// returns true if a name was set, false otherwise
bool set_arg_name(llvm::Argument *arg);
// Add mapping of identifier (if present) to given value in symbol table
void add_arg_table(value val);
};
class param_list : public ast_node {
std::vector<param_declaration *> param_decls;
bool varargs = false;
public:
param_list *add(param_declaration *decl);
param_list *make_vararg();
void dump_tree() override;
std::vector<type_i> get_types();
bool is_vararg();
// Set names of arguments if present
void set_arg_names(llvm::iterator_range<llvm::Argument *> args);
// Add args mapping to top scope of symbol table
void add_args_table(std::vector<value> values);
};
class function_declarator : public direct_decl {
direct_decl *decl;
param_list *params; // Optional
llvm::Function *codegen_common(type_i ret_type);
public:
function_declarator(direct_decl *decl, param_list *params = nullptr);
static void old_style_error();
void dump_tree() override;
std::string get_identifier() override;
virtual function_declarator *get_func_decl() override { return this; }
// Generates the code for function definition. This would generate a function
// and the corresponding arguments, and push them onto the symbol table in a
// function scope
llvm::Function *codegen_def(type_i ret_type);
// For function declaration
value codegen(type_i ret_type) override;
};
#endif /* DECLARATOR_HPP */