- File:
-
- 1 edited
-
src/Validate/ReplacePseudoFunc.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/ReplacePseudoFunc.cpp
rc75b30a r544deb9 17 17 std::set<std::string> queryValues; 18 18 19 struct WrapEnumValueExpr final : public ast::WithShortCircuiting,20 public ast::WithSymbolTable,21 public ast::WithConstTranslationUnit {22 void previsit(const ast::DeclStmt* expr);23 void previsit(const ast::ApplicationExpr* expr);24 void previsit(const ast::CastExpr* expr);25 26 ast::Expr const* postvisit(const ast::VariableExpr* expr);27 };28 29 19 struct FindGenEnumArray final : public ast::WithShortCircuiting { 30 20 void previsit(const ast::ApplicationExpr* enumDecl); 31 21 }; 32 33 struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,34 public ast::WithSymbolTable,35 public ast::WithShortCircuiting {36 void previsit(const ast::EnumDecl* enumDecl);37 };38 39 struct ReplacePseudoFuncCore : public ast::WithShortCircuiting,40 public ast::WithSymbolTable,41 public ast::WithConstTranslationUnit {42 ast::Expr const* postvisit(ast::ApplicationExpr const* decl);43 };44 45 void WrapEnumValueExpr::previsit(const ast::ApplicationExpr* expr) {46 47 auto varExpr = expr->func.as<ast::VariableExpr>();48 auto fname = ast::getFunctionName(expr);49 if ( !varExpr || varExpr->var->linkage == ast::Linkage::Intrinsic ) {50 if ( fname == "?{}" || fname == "?=?" )51 visit_children = false;52 }53 54 if (fname == "labelE" || fname == "valueE" || fname == "posE")55 visit_children = false;56 }57 58 void WrapEnumValueExpr::previsit(const ast::DeclStmt*) {59 visit_children = false;60 }61 62 void WrapEnumValueExpr::previsit(const ast::CastExpr* expr) {63 if (expr->result && expr->result.as<ast::ReferenceType>()) {64 visit_children = false;65 }66 }67 68 ast::Expr const* WrapEnumValueExpr::postvisit(const ast::VariableExpr* expr) {69 visit_children = false;70 if (!expr->result) {71 return expr;72 }73 if (auto enumInst = expr->result.as<ast::EnumInstType>()) {74 if (enumInst->base && enumInst->base->base) {75 auto untyped = new ast::UntypedExpr(76 expr->location, new ast::NameExpr(expr->location, "valueE"),77 {new ast::VariableExpr(*expr)});78 ResolvExpr::ResolveContext context{symtab, transUnit().global};79 auto result = ResolvExpr::findVoidExpression(untyped, context);80 if (result.get()) {81 ast::ptr<ast::ApplicationExpr> ret =82 result.strict_as<ast::ApplicationExpr>();83 return new ast::ApplicationExpr(*ret);84 }85 }86 }87 return expr;88 }89 22 90 23 void FindGenEnumArray::previsit(const ast::ApplicationExpr* expr) { … … 115 48 } 116 49 50 struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>, 51 public ast::WithSymbolTable, 52 public ast::WithShortCircuiting { 53 void previsit(const ast::EnumDecl* enumDecl); 54 }; 55 117 56 void PseudoFuncGenerateRoutine::previsit(const ast::EnumDecl* enumDecl) { 118 57 visit_children = false; … … 128 67 location, ast::ConstantExpr::from_string(location, mem->name))); 129 68 } 130 // Values only131 69 if (queryValues.count(enumDecl->name)) { 132 70 auto init = new ast::ListInit(location, std::move(inits)); 133 const ast::ArrayType* arrT = new ast::ArrayType(134 enumDecl->base,135 ast::ConstantExpr::from_int(location, enumDecl->members.size()),136 ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim);137 ast::ObjectDecl* values = new ast::ObjectDecl(138 location, "values_" + enumDecl->name, arrT, init,139 ast::Storage::Static, ast::Linkage::AutoGen);71 auto values = new ast::ObjectDecl( 72 location, "values_" + enumDecl->name, 73 new ast::ArrayType( 74 enumDecl->base, 75 ast::ConstantExpr::from_int(location, enumDecl->members.size()), 76 ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim), 77 init, ast::Storage::Static, ast::Linkage::AutoGen); 140 78 symtab.addId(values); 141 79 values->mangleName = Mangle::mangle(values); … … 144 82 if (queryLabels.count(enumDecl->name)) { 145 83 auto label_strings = new ast::ListInit(location, std::move(labels)); 146 auto label s= new ast::ObjectDecl(84 auto label_arr = new ast::ObjectDecl( 147 85 location, "labels_" + enumDecl->name, 148 86 new ast::ArrayType( … … 151 89 ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim), 152 90 label_strings, ast::Storage::Static, ast::Linkage::AutoGen); 153 symtab.addId(label s);154 label s->mangleName = Mangle::mangle(labels);155 declsToAddAfter.push_back(label s);91 symtab.addId(label_arr); 92 label_arr->mangleName = Mangle::mangle(label_arr); 93 declsToAddAfter.push_back(label_arr); 156 94 } 157 95 } 158 96 159 ast::ApplicationExpr const* getPseudoFuncApplication( 160 const CodeLocation location, ResolvExpr::ResolveContext context, 161 const ast::VariableExpr* arg, const ast::EnumDecl* base, const std::string & name) { 162 ast::Expr* toResolve = new ast::NameExpr(location, name + base->name); 163 auto result = ResolvExpr::findVoidExpression(toResolve, context); 164 assert(result.get()); 165 auto arrAsVar = result.strict_as<ast::VariableExpr>(); 166 auto untyped = new ast::UntypedExpr( 167 location, new ast::NameExpr(location, "?[?]"), 168 {new ast::VariableExpr(*arrAsVar), new ast::VariableExpr(*arg)}); 169 auto typedResult = ResolvExpr::findVoidExpression(untyped, context); 170 171 ast::ptr<ast::ApplicationExpr> ret = 172 typedResult.strict_as<ast::ApplicationExpr>(); 173 return ast::deepCopy(ret); 174 } 97 struct ReplacePseudoFuncCore : public ast::WithShortCircuiting, 98 public ast::WithSymbolTable, 99 public ast::WithConstTranslationUnit { 100 ast::Expr const* postvisit(ast::ApplicationExpr const* decl); 101 }; 175 102 176 103 ast::Expr const* ReplacePseudoFuncCore::postvisit( … … 198 125 } 199 126 const ast::EnumDecl* base = argType->base; 200 ResolvExpr::ResolveContext context{symtab, transUnit().global};201 // If resolvable as constant202 127 for (size_t i = 0; i < base->members.size(); i++) { 203 128 if (base->members[i]->name == referredName) { … … 208 133 referredName); 209 134 else 210 return getPseudoFuncApplication(location, context, arg.get(), 211 base, "values_"); 135 return new ast::TypeExpr(expr->location, argType); 212 136 } 213 137 } 214 138 139 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 140 215 141 if (fname == "labelE") { 216 if (auto labelExpr = 217 getPseudoFuncApplication(location, context, arg.get(), base, "labels_")) { 218 return labelExpr; 142 ast::Expr* toResolve = 143 new ast::NameExpr(expr->location, "labels_" + base->name); 144 auto result = ResolvExpr::findVoidExpression(toResolve, context); 145 if (result.get()) { 146 auto arrAsVar = result.strict_as<ast::VariableExpr>(); 147 auto untyped = new ast::UntypedExpr( 148 location, new ast::NameExpr(location, "?[?]"), 149 {new ast::VariableExpr(*arrAsVar), 150 ast::ConstantExpr::from_int( 151 location, 152 0)}); /// TODO: dummy value. 153 /// To make it works need to change the unifier 154 155 auto typedResult = 156 ResolvExpr::findVoidExpression(untyped, context); 157 if (result.get()) { 158 ast::ptr<ast::ApplicationExpr> ret = 159 typedResult.strict_as<ast::ApplicationExpr>(); 160 return new ast::ApplicationExpr(*ret); 161 } 219 162 } 220 } else if (fname == "valueE") { 221 if (auto valueExpr = 222 getPseudoFuncApplication(location, context, arg.get(), base, "values_")) { 223 return valueExpr; 163 } 164 165 if (fname == "valueE") { 166 ast::Expr* toResolve = 167 new ast::NameExpr(expr->location, "values_" + base->name); 168 auto result = ResolvExpr::findVoidExpression(toResolve, context); 169 if (result.get()) { 170 auto arrAsVar = result.strict_as<ast::VariableExpr>(); 171 auto untyped = new ast::UntypedExpr( 172 location, new ast::NameExpr(location, "?[?]"), 173 {new ast::VariableExpr(*arrAsVar), 174 ast::ConstantExpr::from_int( 175 location, 176 0)}); /// TODO: dummy value. 177 /// To make it works need to change the unifier 178 179 auto typedResult = 180 ResolvExpr::findVoidExpression(untyped, context); 181 if (result.get()) { 182 ast::ptr<ast::ApplicationExpr> ret = 183 typedResult.strict_as<ast::ApplicationExpr>(); 184 return new ast::ApplicationExpr(*ret); 185 } 224 186 } 225 } else { // it is position; replace itself226 return std::move( arg.get() );227 187 } 228 188 } … … 233 193 234 194 void replacePseudoFunc(ast::TranslationUnit& translationUnit) { 235 ast::Pass<WrapEnumValueExpr>::run(translationUnit);236 195 ast::Pass<FindGenEnumArray>::run(translationUnit); 237 196 ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
Note:
See TracChangeset
for help on using the changeset viewer.