Changes in / [32490deb:e71b09a]
- Location:
- src
- Files:
-
- 9 edited
-
AST/Print.cpp (modified) (1 diff)
-
CodeGen/CodeGenerator.cpp (modified) (3 diffs)
-
CodeGen/GenType.cc (modified) (1 diff)
-
GenPoly/Lvalue.cpp (modified) (2 diffs)
-
ResolvExpr/CandidateFinder.cpp (modified) (3 diffs)
-
ResolvExpr/ConversionCost.cc (modified) (2 diffs)
-
ResolvExpr/Unify.cc (modified) (1 diff)
-
Validate/Autogen.cpp (modified) (4 diffs)
-
Validate/ReplacePseudoFunc.cpp (modified) (8 diffs)
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Print.cpp
r32490deb re71b09a 175 175 } 176 176 177 os << " " << (node->body ? "with" : "without") << " body"; 178 179 if ( ! node->params.empty() ) { 180 os << endl << indent << "... with parameters" << endl; 181 ++indent; 182 printAll( node->params ); 183 --indent; 184 } 185 186 if ( ! short_mode && ! node->members.empty() ) { 187 os << endl << indent << "... with members" << endl; 188 ++indent; 189 printAll( node->members ); 190 --indent; 191 } 192 193 if ( ! short_mode && ! node->attributes.empty() ) { 194 os << endl << indent << "... with attributes" << endl; 195 ++indent; 196 printAll( node->attributes ); 197 --indent; 198 } 199 177 200 auto ptrToEnum = dynamic_cast<const ast::EnumDecl *>(node); 178 201 if ( ! short_mode && ptrToEnum && ptrToEnum->base ) { 179 os << endl << indent << "... with base type" << endl; 180 ++indent; 181 os << indent; 202 os << endl << indent << ".. with (enum) base" << endl; 203 ++indent; 182 204 ptrToEnum->base->accept( *this ); 183 205 --indent; 184 206 } 185 186 os << " " << (node->body ? "with" : "without") << " body";187 188 if ( ! node->params.empty() ) {189 os << endl << indent << "... with parameters" << endl;190 ++indent;191 printAll( node->params );192 --indent;193 }194 195 if ( ! short_mode && ! node->members.empty() ) {196 os << endl << indent << "... with members" << endl;197 ++indent;198 printAll( node->members );199 --indent;200 }201 202 if ( ! short_mode && ! node->attributes.empty() ) {203 os << endl << indent << "... with attributes" << endl;204 ++indent;205 printAll( node->attributes );206 --indent;207 }208 209 210 207 211 208 os << endl; -
src/CodeGen/CodeGenerator.cpp
r32490deb re71b09a 331 331 extension( decl ); 332 332 auto members = decl->members; 333 //if ( decl->base && !members.empty() ) {334 //long long curVal = 0;335 //for ( auto member : members ) {336 //auto obj = member.strict_as<ast::ObjectDecl>();337 //output << "static ";338 //output << genType( decl->base, mangleName( obj ), options );339 //genEnumInitializer( visitor, decl->base, output, obj->init, &curVal, options );340 //output << ";" << endl;341 //}342 //} else {333 if ( decl->base && !members.empty() ) { 334 long long curVal = 0; 335 for ( auto member : members ) { 336 auto obj = member.strict_as<ast::ObjectDecl>(); 337 output << "static "; 338 output << genType( decl->base, mangleName( obj ), options ); 339 genEnumInitializer( visitor, decl->base, output, obj->init, &curVal, options ); 340 output << ";" << endl; 341 } 342 } else { 343 343 output << "enum "; 344 344 genAttributes( decl->attributes ); … … 353 353 auto obj = member.strict_as<ast::ObjectDecl>(); 354 354 output << indent << mangleName( obj ); 355 if ( !decl->base &&obj->init ) {355 if ( obj->init ) { 356 356 output << " = "; 357 357 obj->init->accept( *visitor ); … … 363 363 output << indent << "}"; 364 364 } 365 //}365 } 366 366 } 367 367 -
src/CodeGen/GenType.cc
r32490deb re71b09a 228 228 229 229 void GenType::postvisit( ast::EnumInstType const * type ) { 230 //if ( type->base && type->base->base ) {231 //result = genType( type->base->base, result, options );232 //} else {230 if ( type->base && type->base->base ) { 231 result = genType( type->base->base, result, options ); 232 } else { 233 233 result = type->name + " " + result; 234 234 if ( options.genC ) { 235 235 result = "enum " + result; 236 236 } 237 //}237 } 238 238 handleQualifiers( type ); 239 239 } -
src/GenPoly/Lvalue.cpp
r32490deb re71b09a 133 133 return func->linkage == ast::Linkage::Intrinsic 134 134 && lvalueFunctions.count( func->name ); 135 }136 }137 return false;138 }139 140 bool isGeneratedInstrinct( ast::Expr const * expr ) {141 if ( auto app = dynamic_cast<ast::ApplicationExpr const *>( expr ) ) {142 if ( app->args.size() == 2 && ast::getFunction( app )->name == "?[?]" ) {143 auto param_1 = dynamic_cast<ast::VariableExpr const *>(app->args.front().get());144 if ( param_1 ) {145 auto param_1_as_obj = param_1->var.as<ast::ObjectDecl>();146 return ( param_1_as_obj->name.find( "values_") != std::string::npos147 || param_1_as_obj->name.find( "labels_" ) != std::string::npos );148 }149 135 } 150 136 } … … 175 161 ast::Expr const * FixIntrinsicResults::postvisit( 176 162 ast::ApplicationExpr const * expr ) { 177 178 if ( skip == SkipInProgress || !isIntrinsicReference( expr ) || isGeneratedInstrinct( expr ) ) { 163 if ( skip == SkipInProgress || !isIntrinsicReference( expr ) ) { 179 164 return expr; 180 165 } -
src/ResolvExpr/CandidateFinder.cpp
r32490deb re71b09a 891 891 } else if ( auto unionInst = aggrExpr->result.as< ast::UnionInstType >() ) { 892 892 addAggMembers( unionInst, aggrExpr, *cand, Cost::unsafe, "" ); 893 } else if ( auto enumInst = aggrExpr->result.as< ast::EnumInstType >() ) {894 // The Attribute Arrays are not yet generated, need to proxy them895 // as attribute function call896 const CodeLocation & location = cand->expr->location;897 if ( enumInst->base && enumInst->base->base ) {898 auto valueName = new ast::NameExpr(location, "valueE");899 auto untypedValueCall = new ast::UntypedExpr(900 location, valueName, { aggrExpr } );901 auto result = ResolvExpr::findVoidExpression( untypedValueCall, context );902 assert( result.get() );903 CandidateRef newCand = std::make_shared<Candidate>(904 *cand, result, Cost::safe );905 candidates.emplace_back( std::move( newCand ) );906 }907 893 } 908 894 } … … 975 961 976 962 if (argType.as<ast::PointerType>()) funcFinder.otypeKeys.insert(Mangle::Encoding::pointer); 963 // else if (const ast::EnumInstType * enumInst = argType.as<ast::EnumInstType>()) { 964 // const ast::EnumDecl * enumDecl = enumInst->base; // Here 965 // if ( const ast::Type* enumType = enumDecl->base ) { 966 // // instance of enum (T) is a instance of type (T) 967 // funcFinder.otypeKeys.insert(Mangle::mangle(enumType, Mangle::NoGenericParams | Mangle::Type)); 968 // } else { 969 // // instance of an untyped enum is techically int 970 // funcFinder.otypeKeys.insert(Mangle::mangle(enumDecl, Mangle::NoGenericParams | Mangle::Type)); 971 // } 972 // } 977 973 else funcFinder.otypeKeys.insert(Mangle::mangle(argType, Mangle::NoGenericParams | Mangle::Type)); 978 974 } … … 1403 1399 // not sufficient to just pass `variableExpr` here, type might have changed since 1404 1400 // creation 1405 if ( auto obj = dynamic_cast<const ast::ObjectDecl *>( variableExpr->var.get() )) { 1406 if ( auto enumInstType = dynamic_cast<const ast::EnumInstType *>( obj->type.get() ) ) { 1407 if ( enumInstType->base && enumInstType->base->base ) { 1408 const CodeLocation & location = variableExpr->location; 1409 auto ids = symtab.lookupId( "valueE" ); 1410 for ( ast::SymbolTable::IdData & id : ids ) { 1411 if ( auto func = id.id.as<ast::FunctionDecl>() ) { 1412 if ( func->params.size() == 1 ) { 1413 ast::ptr<ast::DeclWithType> valueEParam = func->params.front(); 1414 auto valueEParamType = valueEParam->get_type(); 1415 ast::OpenVarSet funcOpen; 1416 ast::AssertionSet funcNeed, funcHave; 1417 ast::TypeEnvironment funcEnv{ tenv }; 1418 ast::ptr<ast::Type> common; 1419 if ( unifyInexact( valueEParamType, enumInstType, funcEnv, funcNeed, funcHave, funcOpen, WidenMode{ true, true }, common ) ) { 1420 auto appl = new ast::ApplicationExpr( location, 1421 ast::VariableExpr::functionPointer( location, func), { variableExpr } ); 1422 // addCandidate( appl, copy( tenv ), ); 1423 Candidate cand {appl, copy( tenv )}; 1424 addCandidate( cand, appl, Cost::safe ); 1425 } 1426 } 1427 } 1428 } 1429 } 1430 1431 } 1432 } 1433 addCandidate( variableExpr, tenv ); 1434 1401 addCandidate( 1402 new ast::VariableExpr{ variableExpr->location, variableExpr->var }, tenv ); 1435 1403 } 1436 1404 -
src/ResolvExpr/ConversionCost.cc
r32490deb re71b09a 279 279 conversionCostFromBasicToBasic( basicType, dstAsBasic ); 280 280 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 281 auto enumDecl = enumInst->base; 282 if ( auto baseType = enumDecl->base.get() ) { 283 cost = costCalc( basicType, baseType, srcIsLvalue, symtab, env ); 284 cost.incUnsafe(); 281 const ast::EnumDecl * enumDecl = enumInst->base.get(); 282 if ( enumDecl->isTyped && !enumDecl->base.get() ) { 283 cost = Cost::infinity; 284 } else if ( const ast::Type * enumType = enumDecl->base.get() ) { 285 if ( const ast::BasicType * enumTypeAsBasic = dynamic_cast<const ast::BasicType *>(enumType) ) { 286 conversionCostFromBasicToBasic( basicType, enumTypeAsBasic ); 287 } else { 288 cost = Cost::infinity; 289 } 285 290 } else { 286 291 cost = Cost::unsafe; … … 362 367 363 368 void ConversionCost::postvisit( const ast::EnumInstType * enumInstType ) { 364 //const ast::EnumDecl * baseEnum = enumInstType->base;365 //if ( const ast::Type * baseType = baseEnum->base ) {366 //costCalc( baseType, dst, srcIsLvalue, symtab, env );367 //} else {368 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) };369 cost = costCalc( integer, dst, srcIsLvalue, symtab, env );370 //}369 const ast::EnumDecl * baseEnum = enumInstType->base; 370 if ( const ast::Type * baseType = baseEnum->base ) { 371 costCalc( baseType, dst, srcIsLvalue, symtab, env ); 372 } else { 373 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicType::SignedInt ) }; 374 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 375 } 371 376 if ( cost < Cost::unsafe ) { 372 377 cost.incSafe(); -
src/ResolvExpr/Unify.cc
r32490deb re71b09a 73 73 ast::Type * newFirst = shallowCopy( first ); 74 74 ast::Type * newSecond = shallowCopy( second ); 75 if ( auto temp = dynamic_cast<const ast::EnumInstType *>(first) ) { 76 if ( !dynamic_cast< const ast::EnumInstType * >( second ) ) { 77 const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get()); 78 if ( auto t = baseEnum->base.get() ) { 79 newFirst = ast::shallowCopy( t ); 80 } 81 } 82 } else if ( auto temp = dynamic_cast<const ast::EnumInstType *>(second) ) { 83 const ast::EnumDecl * baseEnum = dynamic_cast<const ast::EnumDecl *>(temp->base.get()); 84 if ( auto t = baseEnum->base.get() ) { 85 newSecond = ast::shallowCopy( t ); 86 } 87 } 75 88 76 89 newFirst ->qualifiers = {}; -
src/Validate/Autogen.cpp
r32490deb re71b09a 197 197 198 198 bool shouldAutogen() const final { return true; } 199 void genAttrFuncForward();200 void __attribute__ ((unused)) genDualFuncs();201 199 private: 202 200 void genFuncBody( ast::FunctionDecl * decl ) final; 203 201 void genFieldCtors() final; 204 202 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 );216 203 }; 217 204 … … 251 238 // -------------------------------------------------------------------------- 252 239 void AutogenerateRoutines::previsit( const ast::EnumDecl * enumDecl ) { 240 // Must visit children (enum constants) to add them to the symbol table. 253 241 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 // } 254 249 255 250 ast::EnumInstType enumInst( enumDecl->name ); 256 251 enumInst.base = enumDecl; 257 252 EnumFuncGenerator gen( enumDecl, &enumInst, functionNesting ); 258 if ( enumDecl->base ) {259 gen.genAttrFuncForward();260 // gen.genDualFuncs();261 }262 253 gen.generateAndAppendFunctions( declsToAddAfter ); 263 254 } … … 751 742 * returns to zero. 752 743 */ 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 766 744 auto callExpr = new ast::ApplicationExpr( location, 767 745 ast::VariableExpr::functionPointer( location, functionDecl ), 768 746 { 769 dstExpr,770 srcExpr,747 new ast::VariableExpr( location, dstParam ), 748 new ast::VariableExpr( location, srcParam ), 771 749 } 772 750 ); 773 751 // auto fname = ast::getFunctionName( callExpr ); 752 // if (fname == "posE" ) { 753 // std::cerr << "Found posE autogen" << std::endl; 754 // } 774 755 functionDecl->stmts = new ast::CompoundStmt( location, 775 756 { new ast::ExprStmt( location, callExpr ) } … … 787 768 forwards.back().get_and_mutate() ); 788 769 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 );880 770 } 881 771 } -
src/Validate/ReplacePseudoFunc.cpp
r32490deb re71b09a 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.