Changeset c75b30a for src/Validate
- Timestamp:
- Jan 31, 2024, 6:25:02 PM (20 months ago)
- Branches:
- master
- Children:
- 32490deb
- Parents:
- 16afb2a
- Location:
- src/Validate
- Files:
-
- 2 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/Autogen.cpp
r16afb2a rc75b30a 197 197 198 198 bool shouldAutogen() const final { return true; } 199 void genAttrFuncForward(); 200 void __attribute__ ((unused)) genDualFuncs(); 199 201 private: 200 202 void genFuncBody( ast::FunctionDecl * decl ) final; 201 203 void genFieldCtors() final; 202 204 const ast::Decl * getDecl() const final { return decl; } 205 206 ast::ObjectDecl * dualDstParam() const; 207 208 ast::FunctionDecl * genPosProto() const; 209 ast::FunctionDecl * genLabelProto() const; 210 ast::FunctionDecl * genValueProto() const; 211 212 ast::FunctionDecl * genCopyEnumToDualProto() const; 213 ast::FunctionDecl * genAssignEnumToDualProto() const; 214 215 void genDualBody( ast::FunctionDecl * decl ); 203 216 }; 204 217 … … 238 251 // -------------------------------------------------------------------------- 239 252 void AutogenerateRoutines::previsit( const ast::EnumDecl * enumDecl ) { 240 // Must visit children (enum constants) to add them to the symbol table.241 253 if ( !enumDecl->body ) return; 242 243 // if ( auto enumBaseType = enumDecl->base ) {244 // if ( auto enumBaseTypeAsStructInst = dynamic_cast<const ast::StructInstType *>(enumBaseType.get()) ) {245 // const ast::StructDecl * structDecl = enumBaseTypeAsStructInst->base.get();246 // this->previsit( structDecl );247 // }248 // }249 254 250 255 ast::EnumInstType enumInst( enumDecl->name ); 251 256 enumInst.base = enumDecl; 252 257 EnumFuncGenerator gen( enumDecl, &enumInst, functionNesting ); 258 if ( enumDecl->base ) { 259 gen.genAttrFuncForward(); 260 // gen.genDualFuncs(); 261 } 253 262 gen.generateAndAppendFunctions( declsToAddAfter ); 254 263 } … … 742 751 * returns to zero. 743 752 */ 753 auto dstExpr = new ast::VariableExpr( location, dstParam ); 754 const ast::Expr * srcExpr; 755 if ( decl->base ) { 756 srcExpr = new ast::ApplicationExpr( location, 757 ast::VariableExpr::functionPointer( location, genPosProto() ), 758 { 759 new ast::VariableExpr( location, srcParam ) 760 } 761 ); 762 } else { 763 srcExpr = new ast::VariableExpr( location, srcParam ); 764 } 765 744 766 auto callExpr = new ast::ApplicationExpr( location, 745 767 ast::VariableExpr::functionPointer( location, functionDecl ), 746 768 { 747 new ast::VariableExpr( location, dstParam ),748 new ast::VariableExpr( location, srcParam ),769 dstExpr, 770 srcExpr, 749 771 } 750 772 ); 751 // auto fname = ast::getFunctionName( callExpr ); 752 // if (fname == "posE" ) { 753 // std::cerr << "Found posE autogen" << std::endl; 754 // } 773 755 774 functionDecl->stmts = new ast::CompoundStmt( location, 756 775 { new ast::ExprStmt( location, callExpr ) } … … 768 787 forwards.back().get_and_mutate() ); 769 788 addUnusedAttribute( fwd->params.front() ); 789 } 790 } 791 792 ast::FunctionDecl * EnumFuncGenerator::genPosProto() const { 793 return genProto( "posE", 794 { new ast::ObjectDecl( getLocation(), "_i", 795 new ast::EnumInstType( decl ) )}, 796 { new ast::ObjectDecl( getLocation(), "_ret", 797 new ast::BasicType{ ast::BasicType::UnsignedInt } )} ); 798 } 799 800 ast::FunctionDecl * EnumFuncGenerator::genLabelProto() const { 801 return genProto( "labelE", 802 { new ast::ObjectDecl( getLocation(), "_i", 803 new ast::EnumInstType( decl ) ) }, 804 { new ast::ObjectDecl( getLocation(), "_ret", 805 new ast::PointerType( new ast::BasicType{ ast::BasicType::Char } ) ) } ); 806 } 807 808 ast::FunctionDecl * EnumFuncGenerator::genValueProto() const { 809 return genProto( "valueE", 810 { new ast::ObjectDecl( getLocation(), "_i", new ast::EnumInstType( decl ) )}, 811 { new ast::ObjectDecl( getLocation(), "_ret", ast::deepCopy( decl->base ) ) } ); 812 } 813 814 void EnumFuncGenerator::genAttrFuncForward() { 815 if ( decl->base ) { 816 ast::FunctionDecl *(EnumFuncGenerator::*attrProtos[3])() const = { 817 &EnumFuncGenerator::genPosProto, &EnumFuncGenerator::genLabelProto, 818 &EnumFuncGenerator::genValueProto }; 819 for ( auto & generator : attrProtos ) { 820 produceForwardDecl( (this->*generator)() ); 821 } 822 } 823 } 824 825 ast::ObjectDecl * EnumFuncGenerator::dualDstParam() const { 826 auto base = decl->base; 827 assert( base ); 828 return new ast::ObjectDecl( getLocation(), "_dst", 829 new ast::ReferenceType( ast::deepCopy( base ) ) ); 830 } 831 832 // void ?{}(T & _dst, enum E _src ) 833 ast::FunctionDecl * EnumFuncGenerator::genCopyEnumToDualProto() const { 834 return genProto( "?{}", { dualDstParam(), srcParam() }, {} ); 835 } 836 837 // T ?{}(T & _dst, enum E _src ) 838 ast::FunctionDecl * EnumFuncGenerator::genAssignEnumToDualProto() const { 839 auto retval = dualDstParam(); 840 retval->name = "_ret"; 841 return genProto( "?=?", { dualDstParam(), srcParam() }, { retval }); 842 } 843 844 void EnumFuncGenerator::genDualBody( ast::FunctionDecl * functionDecl ) { 845 assert( decl->base ); 846 const CodeLocation& location = functionDecl->location; 847 auto & params = functionDecl->params; 848 849 assert( 2 == params.size() ); 850 auto dstParam = params.front().strict_as<ast::ObjectDecl>(); 851 auto srcParam = params.back().strict_as<ast::ObjectDecl>(); 852 853 auto dstExpr = new ast::VariableExpr( location, dstParam ); 854 855 auto srcExpr = new ast::ApplicationExpr( location, 856 ast::VariableExpr::functionPointer( location, genValueProto() ), 857 { 858 new ast::VariableExpr( location, srcParam ) 859 }); 860 auto callExpr = new ast::ApplicationExpr( location, 861 ast::VariableExpr::functionPointer( location, functionDecl ), 862 { dstExpr, srcExpr } ); 863 functionDecl->stmts = new ast::CompoundStmt( location, 864 { new ast::ExprStmt( location, callExpr)} ); 865 } 866 867 void EnumFuncGenerator::genDualFuncs() { 868 assert( decl->base ); 869 ast::FunctionDecl *(EnumFuncGenerator::*dualProtos[2])() const = { 870 &EnumFuncGenerator::genCopyEnumToDualProto, 871 &EnumFuncGenerator::genAssignEnumToDualProto }; 872 for ( auto & generator : dualProtos ) { 873 ast::FunctionDecl * decl = (this->*generator)(); 874 produceForwardDecl( decl ); 875 genDualBody( decl ); 876 if ( CodeGen::isAssignment( decl->name ) ) { 877 appendReturnThis( decl ); 878 } 879 produceDecl( decl ); 770 880 } 771 881 } -
src/Validate/ReplacePseudoFunc.cpp
r16afb2a rc75b30a 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 19 29 struct FindGenEnumArray final : public ast::WithShortCircuiting { 20 30 void previsit(const ast::ApplicationExpr* enumDecl); 21 31 }; 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 } 22 89 23 90 void FindGenEnumArray::previsit(const ast::ApplicationExpr* expr) { … … 48 115 } 49 116 50 struct PseudoFuncGenerateRoutine final : public ast::WithDeclsToAdd<>,51 public ast::WithSymbolTable,52 public ast::WithShortCircuiting {53 void previsit(const ast::EnumDecl* enumDecl);54 };55 56 117 void PseudoFuncGenerateRoutine::previsit(const ast::EnumDecl* enumDecl) { 57 118 visit_children = false; … … 67 128 location, ast::ConstantExpr::from_string(location, mem->name))); 68 129 } 130 // Values only 69 131 if (queryValues.count(enumDecl->name)) { 70 132 auto init = new ast::ListInit(location, std::move(inits)); 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);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); 78 140 symtab.addId(values); 79 141 values->mangleName = Mangle::mangle(values); … … 82 144 if (queryLabels.count(enumDecl->name)) { 83 145 auto label_strings = new ast::ListInit(location, std::move(labels)); 84 auto label _arr= new ast::ObjectDecl(146 auto labels = new ast::ObjectDecl( 85 147 location, "labels_" + enumDecl->name, 86 148 new ast::ArrayType( … … 89 151 ast::LengthFlag::FixedLen, ast::DimensionFlag::DynamicDim), 90 152 label_strings, ast::Storage::Static, ast::Linkage::AutoGen); 91 symtab.addId(label_arr); 92 label_arr->mangleName = Mangle::mangle(label_arr); 93 declsToAddAfter.push_back(label_arr); 94 } 95 } 96 97 struct ReplacePseudoFuncCore : public ast::WithShortCircuiting, 98 public ast::WithSymbolTable, 99 public ast::WithConstTranslationUnit { 100 ast::Expr const* postvisit(ast::ApplicationExpr const* decl); 101 }; 153 symtab.addId(labels); 154 labels->mangleName = Mangle::mangle(labels); 155 declsToAddAfter.push_back(labels); 156 } 157 } 158 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 } 102 175 103 176 ast::Expr const* ReplacePseudoFuncCore::postvisit( … … 125 198 } 126 199 const ast::EnumDecl* base = argType->base; 200 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 201 // If resolvable as constant 127 202 for (size_t i = 0; i < base->members.size(); i++) { 128 203 if (base->members[i]->name == referredName) { … … 133 208 referredName); 134 209 else 135 return new ast::TypeExpr(expr->location, argType); 136 } 137 } 138 139 ResolvExpr::ResolveContext context{symtab, transUnit().global}; 210 return getPseudoFuncApplication(location, context, arg.get(), 211 base, "values_"); 212 } 213 } 140 214 141 215 if (fname == "labelE") { 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 } 162 } 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 } 186 } 216 if (auto labelExpr = 217 getPseudoFuncApplication(location, context, arg.get(), base, "labels_")) { 218 return labelExpr; 219 } 220 } else if (fname == "valueE") { 221 if (auto valueExpr = 222 getPseudoFuncApplication(location, context, arg.get(), base, "values_")) { 223 return valueExpr; 224 } 225 } else { // it is position; replace itself 226 return std::move( arg.get() ); 187 227 } 188 228 } … … 193 233 194 234 void replacePseudoFunc(ast::TranslationUnit& translationUnit) { 235 ast::Pass<WrapEnumValueExpr>::run(translationUnit); 195 236 ast::Pass<FindGenEnumArray>::run(translationUnit); 196 237 ast::Pass<PseudoFuncGenerateRoutine>::run(translationUnit);
Note:
See TracChangeset
for help on using the changeset viewer.