VapourSynth-llvmexpr
Loading...
Searching...
No Matches
SemanticAnalyzer.hpp
Go to the documentation of this file.
1
19
20#ifndef LLVMEXPR_FRONTEND_INFIX2POSTFIX_SEMANTICANALYZER_HPP
21#define LLVMEXPR_FRONTEND_INFIX2POSTFIX_SEMANTICANALYZER_HPP
22
23#include "AST.hpp"
24#include "AnalysisEngine.hpp"
25#include "SymbolTable.hpp"
26#include "types.hpp"
27
28#include <map>
29#include <memory>
30#include <set>
31#include <string>
32#include <vector>
33
34namespace infix2postfix {
35
37 public:
38 SemanticAnalyzer(Mode mode, int num_inputs, int num_intermediate_inputs = 0,
39 int library_line_count = 0);
40
41 class ScopeGuard {
42 public:
43 explicit ScopeGuard(SemanticAnalyzer* analyzer) : analyzer(analyzer) {
44 analyzer->enterScope();
45 }
46 ~ScopeGuard() { analyzer->exitScope(); }
47 ScopeGuard(const ScopeGuard&) = delete;
48 ScopeGuard& operator=(const ScopeGuard&) = delete;
51
52 private:
53 SemanticAnalyzer* analyzer;
54 };
55
56 bool analyze(const Program* program);
57
58 [[nodiscard]] const std::vector<Diagnostic>& getDiagnostics() const {
59 return diagnostics;
60 }
61
62 [[nodiscard]] bool hasErrors() const;
63
64 [[nodiscard]] const std::map<std::string, std::vector<FunctionSignature>>&
66 return function_signatures;
67 }
68
69 [[nodiscard]] const std::map<std::string, std::vector<FunctionDef*>>&
71 return function_defs;
72 }
73
74 [[nodiscard]] const std::map<std::string, std::pair<std::string, Range>>&
76 return written_properties;
77 }
78
79 private:
80 Type analyzeExpr(Expr* expr);
82 Type analyze(const NumberExpr& expr);
83 Type analyze(UnaryExpr& expr);
84 Type analyze(BinaryExpr& expr);
86 Type analyze(CallExpr& expr);
87 Type analyze(const PropAccessExpr& expr);
91
92 // Statement analysis
93 void analyzeStmt(Stmt* stmt);
94 void analyze(const ExprStmt& stmt);
95 void analyze(AssignStmt& stmt);
96 void analyze(const BlockStmt& stmt);
97 void analyze(IfStmt& stmt);
98 void analyze(WhileStmt& stmt);
99 void analyze(const ReturnStmt& stmt);
100 void analyze(LabelStmt& stmt);
101 void analyze(GotoStmt& stmt);
102 void analyze(FunctionDef& stmt);
103 void analyze(const GlobalDecl& stmt);
104 void analyze(ArrayAssignStmt& stmt);
105
106 void getAllSymbols(
107 const SymbolTable* scope,
108 std::map<std::string, std::shared_ptr<Symbol>>& symbols) const;
109
110 struct ForwardGotoInfo {
111 GotoStmt* stmt;
112 std::map<std::string, std::shared_ptr<Symbol>> symbols_at_goto;
113 };
114
115 void enterScope();
116 void exitScope();
117 std::shared_ptr<Symbol> defineSymbol(SymbolKind kind,
118 const std::string& name, Type type,
119 const Range& range);
120 std::shared_ptr<Symbol> resolveSymbol(const std::string& name,
121 const Range& range);
122
123 void reportError(const std::string& message, const Range& range);
124 void reportWarning(const std::string& message, const Range& range);
125 bool builtinParamTypeIsEvaluatable(
126 const std::vector<struct BuiltinFunction>& overloads, size_t param_idx);
127
128 const FunctionSignature*
129 resolveOverload(const std::string& name,
130 const std::vector<std::unique_ptr<Expr>>& args,
131 const Range& range, CallExpr* call_expr = nullptr);
132
133 void collectLabels(Stmt* stmt, std::set<std::string>& labels,
134 const std::string& context, const Range& context_range);
135
136 void validateGlobalDependencies(Stmt* stmt);
137 void validateFunctionCall(const CallExpr& expr);
138
139 void collectUsedGlobals(Expr* expr, std::set<std::string>& used_globals);
140 void collectUsedGlobalsInStmt(Stmt* stmt,
141 std::set<std::string>& used_globals);
142
143 bool pathAlwaysReturns(Stmt* stmt);
144
145 void validateClipReference(const std::string& clip_name, const Range& range,
146 bool allow_buffer = true);
147
148 Mode mode;
149 int num_inputs;
150 int num_intermediate_inputs;
151 int library_line_count;
152 bool has_result = false;
153 bool result_defined_in_global_scope = false;
154
155 std::unique_ptr<SymbolTable> global_scope;
156 SymbolTable* current_scope;
157
158 std::vector<std::unique_ptr<SymbolTable>> scope_stack;
159
160 std::set<std::string> defined_global_vars;
161
162 std::map<std::string, std::vector<FunctionSignature>> function_signatures;
163 std::map<std::string, std::vector<FunctionDef*>> function_defs;
164
165 std::set<std::string> global_labels;
166 std::set<std::string> current_function_labels;
167
168 std::vector<Diagnostic> diagnostics;
169
170 std::map<std::string, std::vector<ForwardGotoInfo>> current_pending_gotos;
171 std::set<std::string> current_labels_seen;
172
173 std::map<std::string, std::pair<std::string, Range>> written_properties;
174
175 const FunctionSignature* current_function = nullptr;
176
177 std::vector<std::string> function_call_stack;
178
179 std::map<std::string, std::set<std::string>> function_call_graph;
180
181 bool detectCycleInCallGraph(const std::string& func_name,
182 std::set<std::string>& visiting,
183 std::set<std::string>& visited,
184 std::vector<std::string>& cycle_path);
185};
186
187} // namespace infix2postfix
188
189#endif // LLVMEXPR_FRONTEND_INFIX2POSTFIX_SEMANTICANALYZER_HPP
ScopeGuard & operator=(const ScopeGuard &)=delete
ScopeGuard & operator=(ScopeGuard &&)=delete
ScopeGuard(const ScopeGuard &)=delete
const std::map< std::string, std::pair< std::string, Range > > & getWrittenProperties() const
const std::vector< Diagnostic > & getDiagnostics() const
const std::map< std::string, std::vector< FunctionSignature > > & getFunctionSignatures() const
bool analyze(const Program *program)
const std::map< std::string, std::vector< FunctionDef * > > & getFunctionDefs() const
SemanticAnalyzer(Mode mode, int num_inputs, int num_intermediate_inputs=0, int library_line_count=0)