Changeset 332e93a
- Timestamp:
- Feb 4, 2025, 9:18:54 PM (7 months ago)
- Branches:
- master
- Children:
- 090b076
- Parents:
- 985ff5f (diff), 1ee74df (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Files:
-
- 3 added
- 19 edited
Legend:
- Unmodified
- Added
- Removed
-
libcfa/src/parseargs.cfa
r985ff5f r332e93a 73 73 //----------------------------------------------------------------------------- 74 74 // Parsing args 75 forall([opt_count]) { 76 void parse_args( const array( cfa_option, opt_count ) & options, const char * usage, char ** & left ) { 77 if ( 0p != &cfa_args_argc ) { 78 parse_args( cfa_args_argc, cfa_args_argv, options, usage, left ); 79 } else { 80 char * temp[1] = { 0p }; 81 parse_args(0, temp, options, usage, left ); 82 } 83 } 84 85 void parse_args( 86 int argc, 87 char * argv[], 88 const array( cfa_option, opt_count ) & options, 89 const char * usage, 90 char ** & left 91 ) { 92 check_args( options ); 93 94 int maxv = 'h'; 95 char optstring[(opt_count * 3) + 2] = { '\0' }; 96 { 97 int idx = 0; 98 for ( i; opt_count ) { 99 if ( options[i].short_name ) { 100 maxv = max( options[i].short_name, maxv ); 101 optstring[idx] = options[i].short_name; 102 idx++; 103 if ( (intptr_t)options[i].parse != (intptr_t)parse_settrue 104 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) { 105 optstring[idx] = ':'; 106 idx++; 107 } 108 } 109 } 110 optstring[idx+0] = 'h'; 111 optstring[idx+1] = '\0'; 112 } 113 114 struct option optarr[opt_count + 2]; 115 { 116 int idx = 0; 117 for ( i; opt_count ) { 118 if ( options[i].long_name ) { 119 // we don't have the mutable keyword here, which is really what we would want 120 int & val_ref = (int &)(const int &)options[i].val; 121 val_ref = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv; 122 123 optarr[idx].name = options[i].long_name; 124 optarr[idx].flag = 0p; 125 optarr[idx].val = options[i].val; 126 if ( ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue) 127 || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) { 128 optarr[idx].has_arg = no_argument; 129 } else { 130 optarr[idx].has_arg = required_argument; 131 } 75 forall([opt_count]) 76 void parse_args( const array( cfa_option, opt_count ) & options, const char * usage, char ** & left ) { 77 if ( 0p != &cfa_args_argc ) { 78 parse_args( cfa_args_argc, cfa_args_argv, options, usage, left ); 79 } else { 80 char * temp[1] = { 0p }; 81 parse_args(0, temp, options, usage, left ); 82 } 83 } 84 85 forall([opt_count]) 86 void parse_args( 87 int argc, 88 char * argv[], 89 const array( cfa_option, opt_count ) & options, 90 const char * usage, 91 char ** & left 92 ) { 93 check_args( options ); 94 95 int maxv = 'h'; 96 char optstring[(opt_count * 3) + 2] = { '\0' }; 97 { 98 int idx = 0; 99 for ( i; opt_count ) { 100 if ( options[i].short_name ) { 101 maxv = max( options[i].short_name, maxv ); 102 optstring[idx] = options[i].short_name; 103 idx++; 104 if ( (intptr_t)options[i].parse != (intptr_t)parse_settrue 105 && ((intptr_t)options[i].parse) != ((intptr_t)parse_setfalse) ) { 106 optstring[idx] = ':'; 132 107 idx++; 133 108 } 134 109 } 135 optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h']; 136 optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0]; 137 } 138 139 FILE * out = stderr; 140 NEXT_ARG: 141 for () { 142 int idx = 0; 143 int opt = getopt_long( argc, argv, optstring, optarr, &idx ); 144 switch( opt ) { 145 case -1: 146 if ( &left != 0p ) left = argv + optind; 147 return; 148 case 'h': 149 out = stdout; 150 case '?': 110 } 111 optstring[idx+0] = 'h'; 112 optstring[idx+1] = '\0'; 113 } 114 115 struct option optarr[opt_count + 2]; 116 { 117 int idx = 0; 118 for ( i; opt_count ) { 119 if ( options[i].long_name ) { 120 // we don't have the mutable keyword here, which is really what we would want 121 int & val_ref = (int &)(const int &)options[i].val; 122 val_ref = (options[i].short_name != '\0') ? ((int)options[i].short_name) : ++maxv; 123 124 optarr[idx].name = options[i].long_name; 125 optarr[idx].flag = 0p; 126 optarr[idx].val = options[i].val; 127 if ( ((intptr_t)options[i].parse) == ((intptr_t)parse_settrue) 128 || ((intptr_t)options[i].parse) == ((intptr_t)parse_setfalse) ) { 129 optarr[idx].has_arg = no_argument; 130 } else { 131 optarr[idx].has_arg = required_argument; 132 } 133 idx++; 134 } 135 } 136 optarr[idx+0].[name, has_arg, flag, val] = ["help", no_argument, 0, 'h']; 137 optarr[idx+1].[name, has_arg, flag, val] = [0, no_argument, 0, 0]; 138 } 139 140 FILE * out = stderr; 141 NEXT_ARG: 142 for () { 143 int idx = 0; 144 int opt = getopt_long( argc, argv, optstring, optarr, &idx ); 145 switch( opt ) { 146 case -1: 147 if ( &left != 0p ) left = argv + optind; 148 return; 149 case 'h': 150 out = stdout; 151 case '?': 152 usage( argv[0], options, usage, out ); 153 default: 154 for ( i; opt_count ) { 155 if ( opt == options[i].val ) { 156 const char * arg = optarg ? optarg : ""; 157 if ( arg[0] == '=' ) { arg++; } 158 // work around for some weird bug 159 void * variable = options[i].variable; 160 bool (*parse_func)(const char *, void * ) = options[i].parse; 161 bool success = parse_func( arg, variable ); 162 if ( success ) continue NEXT_ARG; 163 164 fprintf( out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt ); 151 165 usage( argv[0], options, usage, out ); 152 default: 153 for ( i; opt_count ) { 154 if ( opt == options[i].val ) { 155 const char * arg = optarg ? optarg : ""; 156 if ( arg[0] == '=' ) { arg++; } 157 // work around for some weird bug 158 void * variable = options[i].variable; 159 bool (*parse_func)(const char *, void * ) = options[i].parse; 160 bool success = parse_func( arg, variable ); 161 if ( success ) continue NEXT_ARG; 162 163 fprintf( out, "Argument '%s' for option %c could not be parsed\n\n", arg, (char)opt ); 164 usage( argv[0], options, usage, out ); 165 } 166 } 167 abort( "Internal parse arg error\n" ); 166 } 168 167 } 169 168 abort( "Internal parse arg error\n" ); 170 169 } 171 170 } … … 240 239 } 241 240 242 forall( [N] ) {243 244 245 246 247 void print_args_usage( int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error ) { 248 usage( argv[0], options, usage, error ? stderr : stdout ); 249 }241 forall([N]) 242 void print_args_usage( const array(cfa_option, N ) & options, const char * usage, bool error ) { 243 usage( cfa_args_argv[0], options, usage, error ? stderr : stdout ); 244 } 245 246 forall([N]) 247 void print_args_usage( int argc, char * argv[], const array( cfa_option, N ) & options, const char * usage, bool error ) { 248 usage( argv[0], options, usage, error ? stderr : stdout ); 250 249 } 251 250 -
src/AST/Decl.cpp
r985ff5f r332e93a 169 169 } 170 170 171 bool EnumDecl::isTyped() const { return base; }172 173 bool EnumDecl::isOpaque() const { return isCfa && !isTyped(); }174 175 171 } 176 172 -
src/AST/Decl.hpp
r985ff5f r332e93a 306 306 enum class EnumAttribute{ Value, Posn, Label }; 307 307 308 /// enum declaration `enum Foo { ... };` 308 /// enum declaration `enum Foo { ... };` or `enum(...) Foo { ... };` 309 309 class EnumDecl final : public AggregateDecl { 310 310 public: … … 317 317 std::vector< ast::ptr<ast::EnumInstType>> inlinedDecl; // child enums 318 318 319 bool is_c_enum () const { return !isCfa; } 320 bool is_opaque_enum() const { return isCfa && nullptr == base; } 321 bool is_typed_enum () const { return isCfa && nullptr != base; } 322 319 323 EnumDecl( const CodeLocation& loc, const std::string& name, bool isCfa = false, 320 324 std::vector<ptr<Attribute>>&& attrs = {}, Linkage::Spec linkage = Linkage::Cforall, … … 331 335 const char * typeString() const override { return aggrString( Enum ); } 332 336 333 bool isTyped() const;334 bool isOpaque() const;335 337 private: 336 338 EnumDecl * clone() const override { return new EnumDecl{ *this }; } -
src/AST/Util.cpp
r985ff5f r332e93a 85 85 // Check that `type->returns` corresponds with `decl->returns`. 86 86 assert( type->returns.size() == decl->returns.size() ); 87 } 88 89 /// Check that an enumeration has not been made with an inconsistent spec. 90 void isEnumerationConsistent( const EnumDecl * node ) { 91 if ( node->is_c_enum() ) { 92 assert( nullptr == node->base ); 93 } 87 94 } 88 95 … … 135 142 previsit( (const ParseNode *)node ); 136 143 functionDeclMatchesType( node ); 144 } 145 146 void previsit( const EnumDecl * node ) { 147 previsit( (const ParseNode *)node ); 148 isEnumerationConsistent( node ); 137 149 } 138 150 -
src/CodeGen/CodeGenerator.cpp
r985ff5f r332e93a 130 130 // TODO: Which means the ast::Pass is just providing a default no visit? 131 131 visit_children = false; 132 changeState_ArgToIntrinsic(false); 132 133 } 133 134 … … 466 467 if ( var->var->linkage == ast::Linkage::Intrinsic && 467 468 ( opInfo = operatorLookup( var->var->name ) ) ) { 469 changeState_ArgToIntrinsic(true); 468 470 auto arg = expr->args.begin(); 469 471 switch ( opInfo->type ) { … … 558 560 if ( auto name = expr->func.as<ast::NameExpr>() ) { 559 561 if ( const OperatorInfo * opInfo = operatorLookup( name->name ) ) { 562 changeState_ArgToIntrinsic(true); 560 563 auto arg = expr->args.begin(); 561 564 switch ( opInfo->type ) { … … 743 746 extension( expr ); 744 747 const OperatorInfo * opInfo; 745 if ( expr->var->linkage == ast::Linkage::Intrinsic 748 if ( visitingArgToIntrinsic 749 && options.genC 750 && dynamic_cast<ast::ZeroType const *>( expr->var->get_type() ) ) { 751 // int * p; p = 0; ==> ?=?( p, (zero_t){} ); ==> p = 0; 752 // void f( zero_t z ) { g(z); } ==> g(z); ==> g(z); 753 // (we are at the last '==>') 754 output << "0"; 755 } else if ( expr->var->linkage == ast::Linkage::Intrinsic 746 756 && ( opInfo = operatorLookup( expr->var->name ) ) 747 757 && opInfo->type == OT_CONSTANT ) { -
src/CodeGen/CodeGenerator.hpp
r985ff5f r332e93a 181 181 void handleTypedef( ast::NamedTypeDecl const * type ); 182 182 std::string mangleName( ast::DeclWithType const * decl ); 183 184 bool nextVisitedNodeIsArgToIntrinsic = false; 185 bool visitingArgToIntrinsic = false; 186 void changeState_ArgToIntrinsic( bool newValue ) { 187 GuardValue( visitingArgToIntrinsic ) = nextVisitedNodeIsArgToIntrinsic; 188 GuardValue( nextVisitedNodeIsArgToIntrinsic ) = newValue; 189 } 183 190 }; 184 191 -
src/CodeGen/GenType.cpp
r985ff5f r332e93a 268 268 void GenType::postvisit( ast::ZeroType const * type ) { 269 269 // Ideally these wouldn't hit codegen at all, but should be safe to make them ints. 270 result = ( options.pretty ? "zero_t " : "long int ") + result;270 result = ( options.genC ? "long int /*zero_t*/ " : "zero_t " ) + result; 271 271 handleQualifiers( type ); 272 272 } … … 274 274 void GenType::postvisit( ast::OneType const * type ) { 275 275 // Ideally these wouldn't hit codegen at all, but should be safe to make them ints. 276 result = ( options.pretty ? "one_t " : "long int ") + result;276 result = ( options.genC ? "long int /*one_t*/ " : "one_t " ) + result; 277 277 handleQualifiers( type ); 278 278 } -
src/CodeGen/Generate.cpp
r985ff5f r332e93a 46 46 } 47 47 }; 48 49 struct ZeroOneObjectHider final { 50 ast::ObjectDecl const * postvisit( ast::ObjectDecl const * decl ) { 51 if ( decl->type.as<ast::ZeroType>() || decl->type.as<ast::OneType>() ) { 52 ast::ObjectDecl * mutDecl = ast::mutate( decl ); 53 mutDecl->attributes.push_back( new ast::Attribute( "unused" ) ); 54 return mutDecl; 55 } 56 return decl; 57 } 58 }; 48 59 } // namespace 49 60 … … 52 63 erase_if( translationUnit.decls, shouldClean ); 53 64 ast::Pass<TreeCleaner>::run( translationUnit ); 65 ast::Pass<ZeroOneObjectHider>::run( translationUnit ); 54 66 55 67 ast::Pass<CodeGenerator> cgv( os, -
src/Concurrency/Actors.cpp
r985ff5f r332e93a 29 29 struct CollectactorStructDecls : public ast::WithGuards { 30 30 unordered_set<const StructDecl *> & actorStructDecls; 31 unordered_set<const StructDecl *> 32 const StructDecl * *requestDecl;33 const EnumDecl * *allocationDecl;34 const StructDecl * *actorDecl;35 const StructDecl * *msgDecl;31 unordered_set<const StructDecl *> & messageStructDecls; 32 const StructDecl *& requestDecl; 33 const EnumDecl *& allocationDecl; 34 const StructDecl *& actorDecl; 35 const StructDecl *& msgDecl; 36 36 StructDecl * parentDecl; 37 37 bool insideStruct = false; … … 40 40 // finds and sets a ptr to the allocation enum, which is needed in the next pass 41 41 void previsit( const EnumDecl * decl ) { 42 if( decl->name == "allocation" ) *allocationDecl = decl;42 if( decl->name == "allocation" ) allocationDecl = decl; 43 43 } 44 44 … … 48 48 if ( decl->name == "actor" ) { 49 49 actorStructDecls.insert( decl ); // skip inserting fwd decl 50 *actorDecl = decl;50 actorDecl = decl; 51 51 } else if( decl->name == "message" ) { 52 52 messageStructDecls.insert( decl ); // skip inserting fwd decl 53 *msgDecl = decl; 54 } else if( decl->name == "request" ) *requestDecl = decl; 55 else { 53 msgDecl = decl; 54 } else if( decl->name == "request" ) { 55 requestDecl = decl; 56 } else { 56 57 GuardValue(insideStruct); 57 58 insideStruct = true; … … 73 74 // this collects the derived actor and message struct decl ptrs 74 75 void postvisit( const StructInstType * node ) { 75 if ( ! *actorDecl || ! *msgDecl ) return;76 if ( !actorDecl || !msgDecl ) return; 76 77 if ( insideStruct && !namedDecl ) { 77 78 auto actorIter = actorStructDecls.find( node->aggr() ); … … 89 90 public: 90 91 CollectactorStructDecls( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 91 const StructDecl * * requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl **msgDecl )92 const StructDecl *& requestDecl, const EnumDecl *& allocationDecl, const StructDecl *& actorDecl, const StructDecl *& msgDecl ) 92 93 : actorStructDecls( actorStructDecls ), messageStructDecls( messageStructDecls ), requestDecl( requestDecl ), 93 94 allocationDecl( allocationDecl ), actorDecl(actorDecl), msgDecl(msgDecl) {} … … 196 197 struct GenFuncsCreateTables : public ast::WithDeclsToAdd { 197 198 unordered_set<const StructDecl *> & actorStructDecls; 198 unordered_set<const StructDecl *> 199 const StructDecl * *requestDecl;200 const EnumDecl * *allocationDecl;201 const StructDecl * *actorDecl;202 const StructDecl * *msgDecl;199 unordered_set<const StructDecl *> & messageStructDecls; 200 const StructDecl *& requestDecl; 201 const EnumDecl *& allocationDecl; 202 const StructDecl *& actorDecl; 203 const StructDecl *& msgDecl; 203 204 FwdDeclTable & forwardDecls; 204 205 … … 279 280 decl->location, 280 281 "base_actor", 281 new PointerType( new PointerType( new StructInstType( *actorDecl ) ) )282 new PointerType( new PointerType( new StructInstType( actorDecl ) ) ) 282 283 ), 283 284 new ObjectDecl( 284 285 decl->location, 285 286 "base_msg", 286 new PointerType( new PointerType( new StructInstType( *msgDecl ) ) )287 new PointerType( new PointerType( new StructInstType( msgDecl ) ) ) 287 288 ) 288 289 }, // params … … 291 292 decl->location, 292 293 "__CFA_receive_wrap_ret", 293 new EnumInstType( *allocationDecl )294 new EnumInstType( allocationDecl ) 294 295 ) 295 296 }, … … 323 324 decl->location, 324 325 "new_req", 325 new StructInstType( *requestDecl )326 new StructInstType( requestDecl ) 326 327 ) 327 328 )); … … 331 332 derivedReceive->params.push_back( ast::deepCopy( derivedActorRef ) ); 332 333 derivedReceive->params.push_back( ast::deepCopy( derivedMsgRef ) ); 333 derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );334 derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );335 derivedReceive->returns.push_back( new EnumInstType( *allocationDecl ) );334 derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( actorDecl ) ) ) ); 335 derivedReceive->params.push_back( new PointerType( new PointerType( new StructInstType( msgDecl ) ) ) ); 336 derivedReceive->returns.push_back( new EnumInstType( allocationDecl ) ); 336 337 337 338 // Generates: allocation (*my_work_fn)( derived_actor &, derived_msg &, actor **, message ** ) = receive; … … 348 349 // Function type is: allocation (*)( actor &, message & ) 349 350 FunctionType * genericReceive = new FunctionType(); 350 genericReceive->params.push_back( new ReferenceType( new StructInstType( *actorDecl ) ) );351 genericReceive->params.push_back( new ReferenceType( new StructInstType( *msgDecl ) ) );352 genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *actorDecl ) ) ) );353 genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( *msgDecl ) ) ) );354 genericReceive->returns.push_back( new EnumInstType( *allocationDecl ) );351 genericReceive->params.push_back( new ReferenceType( new StructInstType( actorDecl ) ) ); 352 genericReceive->params.push_back( new ReferenceType( new StructInstType( msgDecl ) ) ); 353 genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( actorDecl ) ) ) ); 354 genericReceive->params.push_back( new PointerType( new PointerType( new StructInstType( msgDecl ) ) ) ); 355 genericReceive->returns.push_back( new EnumInstType( allocationDecl ) ); 355 356 356 357 // Generates: allocation (*fn)( actor &, message & ) = (allocation (*)( actor &, message & ))my_work_fn; … … 378 379 { 379 380 new NameExpr( decl->location, "new_req" ), 380 new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "receiver" ) ), new PointerType( new StructInstType( *actorDecl ) ), ExplicitCast ),381 new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "msg" ) ), new PointerType( new StructInstType( *msgDecl ) ), ExplicitCast ),381 new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "receiver" ) ), new PointerType( new StructInstType( actorDecl ) ), ExplicitCast ), 382 new CastExpr( decl->location, new AddressExpr( new NameExpr( decl->location, "msg" ) ), new PointerType( new StructInstType( msgDecl ) ), ExplicitCast ), 382 383 new NameExpr( decl->location, "fn" ) 383 384 } … … 443 444 public: 444 445 GenFuncsCreateTables( unordered_set<const StructDecl *> & actorStructDecls, unordered_set<const StructDecl *> & messageStructDecls, 445 const StructDecl * * requestDecl, const EnumDecl ** allocationDecl, const StructDecl ** actorDecl, const StructDecl **msgDecl,446 const StructDecl *& requestDecl, const EnumDecl *& allocationDecl, const StructDecl *& actorDecl, const StructDecl *& msgDecl, 446 447 FwdDeclTable & forwardDecls ) : actorStructDecls(actorStructDecls), messageStructDecls(messageStructDecls), 447 448 requestDecl(requestDecl), allocationDecl(allocationDecl), actorDecl(actorDecl), msgDecl(msgDecl), forwardDecls(forwardDecls) {} … … 453 454 struct FwdDeclOperator : public ast::WithDeclsToAdd { 454 455 unordered_set<const StructDecl *> & actorStructDecls; 455 unordered_set<const StructDecl *> 456 unordered_set<const StructDecl *> & messageStructDecls; 456 457 FwdDeclTable & forwardDecls; 457 458 … … 495 496 // for storing through the passes 496 497 // these are populated with various important struct decls 497 const StructDecl * requestDeclPtr = nullptr; 498 const EnumDecl * allocationDeclPtr = nullptr; 499 const StructDecl * actorDeclPtr = nullptr; 500 const StructDecl * msgDeclPtr = nullptr; 501 502 // double pointer to modify local ptrs above 503 const StructDecl ** requestDecl = &requestDeclPtr; 504 const EnumDecl ** allocationDecl = &allocationDeclPtr; 505 const StructDecl ** actorDecl = &actorDeclPtr; 506 const StructDecl ** msgDecl = &msgDeclPtr; 498 const StructDecl * requestDecl = nullptr; 499 const EnumDecl * allocationDecl = nullptr; 500 const StructDecl * actorDecl = nullptr; 501 const StructDecl * msgDecl = nullptr; 507 502 508 503 // first pass collects ptrs to allocation enum, request type, and generic receive fn typedef 509 504 // also populates maps of all derived actors and messages 510 Pass<CollectactorStructDecls>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl,511 allocationDecl, actorDecl, msgDecl );505 Pass<CollectactorStructDecls>::run( translationUnit, actorStructDecls, messageStructDecls, 506 requestDecl, allocationDecl, actorDecl, msgDecl ); 512 507 513 508 // check that we have found all the decls we need from <actor.hfa>, if not no need to run the rest of this pass 514 if ( !allocationDecl Ptr || !requestDeclPtr || !actorDeclPtr || !msgDeclPtr)509 if ( !allocationDecl || !requestDecl || !actorDecl || !msgDecl ) 515 510 return; 516 511 517 512 // second pass locates all receive() routines that overload the generic receive fn 518 513 // it then generates the appropriate operator '|' send routines for the receive routines 519 Pass<GenFuncsCreateTables>::run( translationUnit, actorStructDecls, messageStructDecls, requestDecl,520 allocationDecl, actorDecl, msgDecl, forwardDecls );514 Pass<GenFuncsCreateTables>::run( translationUnit, actorStructDecls, messageStructDecls, 515 requestDecl, allocationDecl, actorDecl, msgDecl, forwardDecls ); 521 516 522 517 // The third pass forward declares operator '|' send routines -
src/InitTweak/GenInit.cpp
r985ff5f r332e93a 164 164 ast::ObjectDecl * arrayDimension = nullptr; 165 165 166 const ast::TypeExpr * ty = dynamic_cast< const ast::TypeExpr * >( arrayType->dimension.get() ); 167 if ( ty ) { 166 if ( auto ty = dynamic_cast< const ast::TypeExpr * >( arrayType->dimension.get() ) ) { 168 167 auto inst = ty->type.as<ast::EnumInstType>(); 169 if ( inst ) { 170 if ( inst->base->isCfa ) { 171 arrayDimension = new ast::ObjectDecl( 168 if ( inst && !inst->base->is_c_enum() ) { 169 arrayDimension = new ast::ObjectDecl( 170 arrayType->dimension->location, 171 dimensionName.newName(), 172 new ast::BasicType( ast::BasicKind::UnsignedChar ), 173 new ast::SingleInit( 172 174 arrayType->dimension->location, 173 dimensionName.newName(), 174 new ast::BasicType( ast::BasicKind::UnsignedChar ), 175 new ast::SingleInit( 176 arrayType->dimension->location, 177 ast::ConstantExpr::from_int( arrayType->dimension->location, inst->base->members.size() ) 178 ) 179 ); 180 // return arrayType; 181 } 175 ast::ConstantExpr::from_int( arrayType->dimension->location, inst->base->members.size() ) 176 ) 177 ); 182 178 } 183 179 } -
src/Parser/TypeData.cpp
r985ff5f r332e93a 1482 1482 object->isHidden = ast::EnumDecl::EnumHiding::Hide == ret->hide; 1483 1483 object->isMember = true; 1484 if ( ret->is Opaque() && cur->has_enumeratorValue() ) {1484 if ( ret->is_opaque_enum() && cur->has_enumeratorValue() ) { 1485 1485 SemanticError( td->location, "Opague cannot have an explicit initializer value." ); 1486 1486 } else if ( cur->has_enumeratorValue() ) { 1487 1487 ast::Expr * initValue; 1488 if ( ret->is Cfa && ret->base) {1488 if ( ret->is_typed_enum() ) { 1489 1489 CodeLocation location = cur->enumeratorValue->location; 1490 1490 initValue = new ast::CastExpr( location, maybeMoveBuild( cur->consume_enumeratorValue() ), ret->base ); -
src/ResolvExpr/CastCost.cpp
r985ff5f r332e93a 53 53 void postvisit( const ast::EnumInstType * enumInst ) { 54 54 cost = conversionCost( enumInst, dst, srcIsLvalue, symtab, env ); 55 if ( enumInst->base->is Typed() ) {56 auto baseConversionCost = 55 if ( enumInst->base->is_typed_enum() ) { 56 auto baseConversionCost = 57 57 castCost( enumInst->base->base, dst, srcIsLvalue, symtab, env ); 58 cost = baseConversionCost < cost ? baseConversionCost: cost;58 cost = baseConversionCost < cost ? baseConversionCost : cost; 59 59 } 60 60 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 61 61 Cost intCost = costCalc( integer, dst, srcIsLvalue, symtab, env ); 62 62 intCost.incSafe(); 63 cost = intCost < cost ? intCost: cost;63 cost = intCost < cost ? intCost : cost; 64 64 } 65 65 -
src/ResolvExpr/CommonType.cpp
r985ff5f r332e93a 386 386 } else if ( const ast::EnumInstType * enumInst = dynamic_cast< const ast::EnumInstType * >( type2 ) ) { 387 387 const ast::EnumDecl* enumDecl = enumInst->base; 388 if ( !enumDecl->isCfa) {388 if ( enumDecl->is_c_enum() ) { 389 389 ast::BasicKind kind = commonTypes[ basic->kind ][ ast::BasicKind::SignedInt ]; 390 390 if ( … … 654 654 result = param; 655 655 } 656 } else if ( param->base && !param->base->isCfa) {656 } else if ( param->base && param->base->is_c_enum() ) { 657 657 auto basicType = new ast::BasicType( ast::BasicKind::UnsignedInt ); 658 658 result = commonType( basicType, type2, tenv, need, have, open, widen); -
src/ResolvExpr/ConversionCost.cpp
r985ff5f r332e93a 246 246 } 247 247 if (const ast::EnumInstType * srcAsInst = dynamic_cast< const ast::EnumInstType * >( src )) { 248 if ( srcAsInst->base && !srcAsInst->base->isCfa) {248 if ( srcAsInst->base && srcAsInst->base->is_c_enum() ) { 249 249 static const ast::BasicType* integer = new ast::BasicType( ast::BasicKind::UnsignedInt ); 250 250 return ast::Pass<ConversionCost>::read( integer, dst, srcIsLvalue, symtab, env, conversionCost ); … … 324 324 conversionCostFromBasicToBasic( basicType, dstAsBasic ); 325 325 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 326 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa) {326 if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) { 327 327 cost = Cost::safe; 328 328 } … … 405 405 if ( auto dstInst = dynamic_cast<const ast::EnumInstType *>( dst ) ) { 406 406 cost = enumCastCost(inst, dstInst, symtab, env); 407 } else if ( !inst->base->isCfa) {407 } else if ( inst->base->is_c_enum() ) { 408 408 static ast::ptr<ast::BasicType> integer = { new ast::BasicType( ast::BasicKind::SignedInt ) }; 409 409 cost = costCalc( integer, dst, srcIsLvalue, symtab, env ); … … 455 455 } 456 456 457 void ConversionCost::postvisit( const ast::VarArgsType * varArgsType ) { 458 (void)varArgsType; 457 void ConversionCost::postvisit( const ast::VarArgsType * ) { 459 458 if ( dynamic_cast< const ast::VarArgsType * >( dst ) ) { 460 459 cost = Cost::zero; … … 462 461 } 463 462 464 void ConversionCost::postvisit( const ast::ZeroType * zeroType ) { 465 (void)zeroType; 463 void ConversionCost::postvisit( const ast::ZeroType * ) { 466 464 if ( dynamic_cast< const ast::ZeroType * >( dst ) ) { 467 465 cost = Cost::zero; … … 487 485 // assuming 0p is supposed to be used for pointers? 488 486 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 489 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa) {487 if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) { 490 488 cost = Cost::safe; 491 489 } … … 493 491 } 494 492 495 void ConversionCost::postvisit( const ast::OneType * oneType ) { 496 (void)oneType; 493 void ConversionCost::postvisit( const ast::OneType * ) { 497 494 if ( dynamic_cast< const ast::OneType * >( dst ) ) { 498 495 cost = Cost::zero; … … 508 505 } 509 506 } else if ( auto dstAsEnumInst = dynamic_cast< const ast::EnumInstType * >( dst ) ) { 510 if ( dstAsEnumInst->base && !dstAsEnumInst->base->isCfa) {507 if ( dstAsEnumInst->base && dstAsEnumInst->base->is_c_enum() ) { 511 508 cost = Cost::safe; 512 509 } -
src/ResolvExpr/ResolveTypeof.cpp
r985ff5f r332e93a 62 62 // replace basetypeof(<enum>) by int 63 63 auto enumInst = newType.as< ast::EnumInstType >(); 64 if ( enumInst && (!enumInst->base || !enumInst->base->isCfa) ) {64 if ( enumInst && (!enumInst->base || enumInst->base->is_c_enum() ) ) { 65 65 newType = new ast::BasicType( 66 66 ast::BasicKind::SignedInt, newType->qualifiers, copy(newType->attributes) ); … … 144 144 145 145 auto enumInst = decl->type.as<ast::EnumInstType>(); 146 if ( enumInst && enumInst->base->isCfa) {146 if ( enumInst && !enumInst->base->is_c_enum() ) { 147 147 if ( auto init = decl->init.as<ast::SingleInit>() ) { 148 148 if ( auto initExpr = init->value.as<ast::ConstantExpr>() ) { 149 149 if ( initExpr->result.as<ast::ZeroType>() ) { 150 auto newInit = new ast::SingleInit( init->location, 150 auto newInit = new ast::SingleInit( init->location, 151 151 ast::UntypedExpr::createCall( init->location, "lowerBound", {} ) 152 152 ); -
src/Validate/ImplementEnumFunc.cpp
r985ff5f r332e93a 61 61 ast::FunctionDecl* genLabelProto() const; 62 62 ast::FunctionDecl* genValueProto() const; 63 ast::FunctionDecl* genQuasiValueProto() const;64 63 ast::FunctionDecl* genTypeNameProto() const; 65 64 … … 206 205 207 206 ast::FunctionDecl* EnumAttrFuncGenerator::genValueProto() const { 208 assert (decl->isTyped());207 assert( decl->is_typed_enum() ); 209 208 return genProto( 210 209 "value", … … 414 413 void EnumAttrFuncGenerator::genTypedEnumFunction(const ast::EnumAttribute attr) { 415 414 if (attr == ast::EnumAttribute::Value) { 416 if ( !decl->is Typed() ) return;415 if ( !decl->is_typed_enum() ) return; 417 416 std::vector<ast::ptr<ast::Init>> inits = genValueInit(); 418 417 ast::ObjectDecl* arrayProto = … … 483 482 484 483 void ImplementEnumFunc::previsit(const ast::EnumDecl* enumDecl) { 485 if ( !enumDecl->body || !enumDecl->isCfa) return;484 if ( !enumDecl->body || enumDecl->is_c_enum() ) return; 486 485 ast::EnumInstType enumInst(enumDecl->name); 487 486 enumInst.base = enumDecl; -
tests/.expect/zero_one.txt
r985ff5f r332e93a 3 3 It's a Number! 4 4 2 2 5 0 0 6 42 42 7 0 0 8 1 1 9 42 42 10 1 1 11 zero true 12 zero true 13 one false 14 one false -
tests/Makefile.am
r985ff5f r332e93a 354 354 -cp ${test} ${abspath ${@}} 355 355 356 zero_one-ERR1 : zero_one.cfa ${CFACCBIN} 357 ${CFACOMPILE_SYNTAX} -DERR1 358 -cp ${test} ${abspath ${@}} 359 356 360 ctrl-flow/loop_else : ctrl-flow/loop_else.cfa ${CFACCBIN} 357 361 ${CC} ${AM_CFLAGS} -Wno-superfluous-else $< -o $@ -
tests/zero_one.cfa
r985ff5f r332e93a 39 39 } 40 40 41 void testCompats() { 42 zero_t zero = 0; 43 one_t one = 1; 44 45 int x = 0; 46 int xx = zero; 47 48 sout | x | xx; 49 50 x = xx = 42; 51 sout | x | xx; 52 53 x = 0; 54 xx = zero; 55 sout | x | xx; 56 57 int y = 1; 58 int yy = one; 59 60 sout | y | yy; 61 62 y = yy = 42; 63 sout | y | yy; 64 65 y = 1; 66 yy = one; 67 sout | y | yy; 68 69 void z_helper( int * p, zero_t z ) { 70 p = z; // expect z not reported unused here; expect no missing cast from -Wint-conversion 71 sout | "zero" | (bool) (p == 0); 72 } 73 74 void z_call( int * p, zero_t z ) { 75 z_helper(p, z); 76 } 77 78 void o_helper( int * p, one_t o ) { 79 #ifdef ERR1 80 p = o; 81 #else 82 (void) x; (void) o; 83 #endif 84 sout | "one" | (bool) (p == 0); 85 } 86 87 void o_call( int * p, one_t o ) { 88 o_helper(p, o); 89 } 90 91 z_call( &x, 0 ); 92 z_call( &x, zero ); 93 94 o_call( &x, 1 ); 95 o_call( &x, one ); 96 } 97 41 98 int main() { 42 99 testOverloads(); 43 100 testInitAssignQueryIncrement(); 101 testCompats(); 44 102 return 0; 45 103 }
Note:
See TracChangeset
for help on using the changeset viewer.