2 #include "ast/AstNode.h"
4 #include "semantic/AstValidator.h"
5 #include "semantic/ConstantTypeResolver.h"
6 #include "semantic/DataflowAnalysis.h"
7 #include "semantic/ExprResolver.h"
8 #include "semantic/ExprStaticChecker.h"
9 #include "semantic/ExprTypeResolver.h"
10 #include "utils/BumpAllocator.h"
11 #include "utils/PassManager.h"
13 using namespace joos1;
14 using namespace semantic;
15 using std::string_view;
17 using utils::PassManager;
23 class ExprResolverPass
final :
public Pass {
32 ExprResolverPass(PassManager& PM)
noexcept :
Pass(PM
) {}
34 string_view
Desc()
const override {
return "Expression Resolution"; }
36 auto LU = GetPass<LinkerPass>().LinkingUnit();
37 auto& NR = GetPass<NameResolverPass>().Resolver();
38 auto& HC = GetPass<HierarchyCheckerPass>().Checker();
39 auto& Sema = GetPass<AstContextPass>().Sema();
40 ExprResolver ER{PM().Diag(), NewHeap()};
41 ExprTypeResolver TR{PM().Diag(), NewHeap(), Sema};
43 BumpAllocator alloc{NewHeap()};
45 ER.Init(&TR, &NR, &Sema, &HC);
51 resolveRecursive(data, LU);
59 void evaluateAsList(Data d, ast::Expr* expr) {
60 if(
PM().Diag().Verbose(2)) {
61 auto dbg =
PM().Diag().ReportDebug(2);
62 dbg <<
"[*] Location: ";
63 expr->location().print(dbg.get()) <<
"\n";
64 dbg <<
"[*] Printing expression before resolution:\n";
65 expr->print(dbg.get(), 1);
67 ast::ExprNodeList list = d.ER.Evaluate(expr);
68 if(
PM().Diag().Verbose(2)) {
69 auto dbg =
PM().Diag().ReportDebug(2);
70 dbg <<
"[*] Printing expression after resolution:\n ";
71 list.print(dbg.get());
75 d.ESC.Evaluate(expr, d.state);
78 void resolveRecursive(Data d, ast::AstNode* node) {
80 if(
auto* cu = dyn_cast<ast::CompilationUnit>(node)) d.ER.BeginCU(cu);
81 if(
auto* ctx = dyn_cast<ast::DeclContext>(node)) d.ER.BeginContext(ctx);
82 if(
auto* classDecl = dyn_cast<ast::ClassDecl>(node))
83 d.state.currentClass = classDecl;
86 d.state.isInstFieldInitializer =
false;
87 d.state.fieldScope =
nullptr;
88 if(
auto* field = dyn_cast<ast::FieldDecl>(node)) {
89 d.state.isStaticContext = field->modifiers().isStatic();
90 if(field->hasInit()) {
91 d.state.isInstFieldInitializer = !field->modifiers().isStatic();
92 d.state.fieldScope = field->init()->scope();
94 }
else if(
auto* method = dyn_cast<ast::MethodDecl>(node)) {
95 d.state.isStaticContext = method->modifiers().isStatic();
99 if(
auto* decl =
dynamic_cast<ast::TypedDecl*>(node)) {
100 if(
auto* init = decl->mut_init()) {
101 if(
PM().Diag().Verbose(2)) {
102 PM().Diag().ReportDebug(2)
103 <<
"[*] Resolving initializer for variable: " << decl->name();
105 evaluateAsList(d, init);
107 }
else if(
auto* stmt =
dynamic_cast<ast::Stmt*>(node)) {
108 for(
auto* expr : stmt->mut_exprs()) {
110 if(PM().Diag().Verbose(2)) {
111 PM().Diag().ReportDebug(2)
112 <<
"[*] Resolving expression in statement:";
114 evaluateAsList(d, expr);
118 if(
dynamic_cast<ast::DeclStmt*>(node))
return;
120 for(
auto* child : node->mut_children()) {
121 if(child) resolveRecursive(d, child);
126 void computeDependencies()
override {
137 class DFAPass
final :
public Pass {
139 DFAPass(PassManager& PM)
noexcept :
Pass(PM
) {}
143 optEnable =
PM().PO().GetExistingOption(
"--enable-dfa-check")->count();
146 if(!optEnable)
return;
147 auto LU = GetPass<LinkerPass>().LinkingUnit();
148 auto& Sema = GetPass<AstContextPass>().Sema();
149 ConstantTypeResolver CTR{NewHeap()};
151 CFGBuilder builder{PM().Diag(), &CTR, NewHeap(), Sema};
162 void computeDependencies()
override {