- Timestamp:
- Jul 31, 2023, 11:25:51 AM (2 years ago)
- Branches:
- master
- Children:
- f496046
- Parents:
- e0332dd3
- Location:
- src
- Files:
-
- 9 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Create.cpp
re0332dd3 r14c0f7b 42 42 return nullptr; 43 43 } 44 return new ast::FunctionDecl( decl->location, 45 decl->name, 46 vectorCopy( decl->type_params ), 47 vectorCopy( decl->assertions ), 48 vectorCopy( decl->params ), 49 vectorCopy( decl->returns ), 50 nullptr, 51 decl->storage, 52 decl->linkage, 53 vectorCopy( decl->attributes ), 54 decl->funcSpec, 55 decl->type->isVarArgs 56 ); 44 // The cast and changing the original should be safe as long as the 45 // change is reverted before anything else sees it. It's also faster. 46 FunctionDecl * mutDecl = const_cast<FunctionDecl *>( decl ); 47 CompoundStmt const * stmts = mutDecl->stmts.release(); 48 FunctionDecl * copy = deepCopy( mutDecl ); 49 mutDecl->stmts = stmts; 50 return copy; 57 51 } 58 52 -
src/AST/Util.cpp
re0332dd3 r14c0f7b 20 20 #include "Pass.hpp" 21 21 #include "TranslationUnit.hpp" 22 #include "Common/utility.h" 23 #include "GenPoly/ScopedSet.h" 22 24 23 25 #include <vector> 26 27 using GenPoly::ScopedSet; 24 28 25 29 namespace ast { … … 173 177 }; 174 178 179 /// Checks that referred to nodes are in scope. 180 /// This checks many readonly pointers to see if the declaration they are 181 /// referring to is in scope by the structural rules of code. 182 // Any escapes marked with a bug should be removed once the bug is fixed. 183 struct InScopeCore : public ast::WithShortCircuiting { 184 ScopedSet<DeclWithType const *> typedDecls; 185 ScopedSet<TypeDecl const *> typeDecls; 186 // These 3 are really hard to check, because uses that originally ref. at 187 // a forward declaration can be rewired to point a later full definition. 188 ScopedSet<StructDecl const *> structDecls; 189 ScopedSet<UnionDecl const *> unionDecls; 190 ScopedSet<EnumDecl const *> enumDecls; 191 ScopedSet<TraitDecl const *> traitDecls; 192 193 bool isInGlobal = false; 194 195 void beginScope() { 196 typedDecls.beginScope(); 197 typeDecls.beginScope(); 198 structDecls.beginScope(); 199 unionDecls.beginScope(); 200 enumDecls.beginScope(); 201 traitDecls.beginScope(); 202 } 203 204 void endScope() { 205 typedDecls.endScope(); 206 typeDecls.endScope(); 207 structDecls.endScope(); 208 unionDecls.endScope(); 209 enumDecls.endScope(); 210 traitDecls.endScope(); 211 } 212 213 void previsit( ApplicationExpr const * expr ) { 214 // All isInGlobal manipulation is just to isolate this check. 215 // The invalid compound literals lead to bad ctor/dtors. [#280] 216 VariableExpr const * func = nullptr; 217 CastExpr const * cast = nullptr; 218 VariableExpr const * arg = nullptr; 219 if ( isInGlobal 220 && 1 == expr->args.size() 221 && ( func = expr->func.as<VariableExpr>() ) 222 && ( "?{}" == func->var->name || "^?{}" == func->var->name ) 223 && ( cast = expr->args[0].as<CastExpr>() ) 224 && ( arg = cast->arg.as<VariableExpr>() ) 225 && isPrefix( arg->var->name, "_compLit" ) ) { 226 visit_children = false; 227 } 228 } 229 230 void previsit( VariableExpr const * expr ) { 231 if ( !expr->var ) return; 232 // bitwise assignment escape [#281] 233 if ( expr->var->location.isUnset() ) return; 234 assert( typedDecls.contains( expr->var ) ); 235 } 236 237 void previsit( FunctionType const * type ) { 238 // This is to avoid checking the assertions, which can point at the 239 // function's declaration and not the enclosing function. 240 for ( auto type_param : type->forall ) { 241 if ( type_param->formal_usage ) { 242 visit_children = false; 243 // We could check non-assertion fields here. 244 } 245 } 246 } 247 248 void previsit( TypeInstType const * type ) { 249 if ( !type->base ) return; 250 assertf( type->base->isManaged(), "Floating Node" ); 251 252 // bitwise assignment escape [#281] 253 if ( type->base->location.isUnset() ) return; 254 // Formal types can actually look at out of scope variables. 255 if ( type->formal_usage ) return; 256 assert( typeDecls.contains( type->base ) ); 257 } 258 259 void previsit( TraitInstType const * type ) { 260 if ( !type->base ) return; 261 assert( traitDecls.contains( type->base ) ); 262 } 263 264 void previsit( ObjectDecl const * decl ) { 265 typedDecls.insert( decl ); 266 // There are some ill-formed compound literals. [#280] 267 // The only known problem cases are at the top level. 268 if ( isPrefix( decl->name, "_compLit" ) ) { 269 visit_children = false; 270 } 271 } 272 273 void previsit( FunctionDecl const * decl ) { 274 typedDecls.insert( decl ); 275 beginScope(); 276 for ( auto & type_param : decl->type_params ) { 277 typeDecls.insert( type_param ); 278 } 279 for ( auto & assertion : decl->assertions ) { 280 typedDecls.insert( assertion ); 281 } 282 for ( auto & param : decl->params ) { 283 typedDecls.insert( param ); 284 } 285 for ( auto & ret : decl->returns ) { 286 typedDecls.insert( ret ); 287 } 288 // No special handling of withExprs. 289 290 // Part of the compound literal escape. [#280] 291 if ( "__global_init__" == decl->name 292 || "__global_destroy__" == decl->name ) { 293 assert( !isInGlobal ); 294 isInGlobal = true; 295 } 296 } 297 298 void postvisit( FunctionDecl const * decl ) { 299 endScope(); 300 // Part of the compound literal escape. [#280] 301 if ( isInGlobal && ( "__global_init__" == decl->name 302 || "__global_destroy__" == decl->name ) ) { 303 isInGlobal = false; 304 } 305 } 306 307 void previsit( StructDecl const * decl ) { 308 structDecls.insert( decl ); 309 beginScope(); 310 for ( auto & type_param : decl->params ) { 311 typeDecls.insert( type_param ); 312 } 313 } 314 315 void postvisit( StructDecl const * ) { 316 endScope(); 317 } 318 319 void previsit( UnionDecl const * decl ) { 320 unionDecls.insert( decl ); 321 beginScope(); 322 for ( auto & type_param : decl->params ) { 323 typeDecls.insert( type_param ); 324 } 325 } 326 327 void postvisit( UnionDecl const * ) { 328 endScope(); 329 } 330 331 void previsit( EnumDecl const * decl ) { 332 enumDecls.insert( decl ); 333 if ( ast::EnumDecl::EnumHiding::Visible == decl->hide ) { 334 for ( auto & member : decl->members ) { 335 typedDecls.insert( member.strict_as<ast::DeclWithType>() ); 336 } 337 } 338 beginScope(); 339 for ( auto & type_param : decl->params ) { 340 typeDecls.insert( type_param ); 341 } 342 } 343 344 void postvisit( EnumDecl const * ) { 345 endScope(); 346 } 347 348 void previsit( TraitDecl const * decl ) { 349 traitDecls.insert( decl ); 350 beginScope(); 351 for ( auto & type_param : decl->params ) { 352 typeDecls.insert( type_param ); 353 } 354 } 355 356 void postvisit( TraitDecl const * ) { 357 endScope(); 358 } 359 360 void previsit( Designation const * ) { 361 visit_children = false; 362 } 363 }; 364 175 365 } // namespace 176 366 177 367 void checkInvariants( TranslationUnit & transUnit ) { 178 ast::Pass<InvariantCore>::run( transUnit ); 368 Pass<InvariantCore>::run( transUnit ); 369 Pass<InScopeCore>::run( transUnit ); 179 370 } 180 371 -
src/InitTweak/InitTweak.cc
re0332dd3 r14c0f7b 891 891 dst = new ast::AddressExpr(dst); 892 892 } 893 } 894 else { 893 } else { 895 894 dst = new ast::CastExpr(dst, new ast::ReferenceType(dst->result, {})); 896 895 } … … 900 899 } 901 900 } 902 return new ast::ApplicationExpr(dst->location, ast::VariableExpr::functionPointer(dst->location, assign), {dst, src}); 901 auto var = ast::VariableExpr::functionPointer(dst->location, assign); 902 auto app = new ast::ApplicationExpr(dst->location, var, {dst, src}); 903 // Skip the resolver, just set the result to the correct type. 904 app->result = ast::deepCopy( src->result ); 905 return app; 903 906 } 904 907 -
src/SymTab/GenImplicitCall.cpp
re0332dd3 r14c0f7b 16 16 #include "GenImplicitCall.hpp" 17 17 18 #include "AST/Copy.hpp" // for deepCopy 18 19 #include "AST/Decl.hpp" // for ObjectDecl 19 20 #include "AST/Expr.hpp" // for ConstantExpr, UntypedExpr,... … … 115 116 std::string cmp, update; 116 117 118 const ast::Expr * dimension = deepCopy( array->dimension ); 117 119 if ( forward ) { 118 120 // generate: for ( int i = 0; i < N; ++i ) 119 121 begin = ast::ConstantExpr::from_int( loc, 0 ); 120 end = array->dimension;122 end = dimension; 121 123 cmp = "?<?"; 122 124 update = "++?"; … … 124 126 // generate: for ( int i = N-1; i >= 0; --i ) 125 127 begin = ast::UntypedExpr::createCall( loc, "?-?", 126 { array->dimension, ast::ConstantExpr::from_int( loc, 1 ) } );128 { dimension, ast::ConstantExpr::from_int( loc, 1 ) } ); 127 129 end = ast::ConstantExpr::from_int( loc, 0 ); 128 130 cmp = "?>=?"; -
src/Validate/Autogen.cpp
re0332dd3 r14c0f7b 532 532 ) 533 533 ); 534 returngenImplicitCall(534 auto stmt = genImplicitCall( 535 535 srcParam, dstSelect, location, func->name, 536 536 field, direction 537 537 ); 538 // This could return the above directly, except the generated code is 539 // built using the structure's members and that means all the scoped 540 // names (the forall parameters) are incorrect. This corrects them. 541 if ( stmt && !decl->params.empty() ) { 542 ast::DeclReplacer::TypeMap oldToNew; 543 for ( auto pair : group_iterate( decl->params, func->type_params ) ) { 544 oldToNew.emplace( std::get<0>(pair), std::get<1>(pair) ); 545 } 546 auto node = ast::DeclReplacer::replace( stmt, oldToNew ); 547 stmt = strict_dynamic_cast<const ast::Stmt *>( node ); 548 } 549 return stmt; 538 550 } 539 551 -
src/Validate/FixQualifiedTypes.cpp
re0332dd3 r14c0f7b 89 89 } 90 90 91 ast::Expr const * postvisit( ast::QualifiedNameExpr const * t ) {91 ast::Expr const * postvisit( ast::QualifiedNameExpr const * t ) { 92 92 assert( location ); 93 if ( t->type_decl ) { 94 auto enumName = t->type_decl->name; 95 const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName ); 96 for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) { 97 if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) { 98 if ( memberAsObj->name == t->name ) { 99 return new ast::VariableExpr( t->location, memberAsObj ); 100 } 101 } else { 102 assertf( false, "unhandled qualified child type"); 93 if ( !t->type_decl ) return t; 94 95 auto enumName = t->type_decl->name; 96 const ast::EnumDecl * enumDecl = symtab.lookupEnum( enumName ); 97 for ( ast::ptr<ast::Decl> const & member : enumDecl->members ) { 98 if ( auto memberAsObj = member.as<ast::ObjectDecl>() ) { 99 if ( memberAsObj->name == t->name ) { 100 return new ast::VariableExpr( t->location, memberAsObj ); 103 101 } 102 } else { 103 assertf( false, "unhandled qualified child type" ); 104 104 } 105 } 105 106 106 auto var = new ast::ObjectDecl( t->location, t->name, 107 new ast::EnumInstType(enumDecl, ast::CV::Const), nullptr, {}, ast::Linkage::Cforall ); 108 var->mangleName = Mangle::mangle( var ); 109 return new ast::VariableExpr( t->location, var ); 110 } 111 112 return t; 107 auto var = new ast::ObjectDecl( t->location, t->name, 108 new ast::EnumInstType( enumDecl, ast::CV::Const ), 109 nullptr, {}, ast::Linkage::Cforall ); 110 var->mangleName = Mangle::mangle( var ); 111 return new ast::VariableExpr( t->location, var ); 113 112 } 114 113 -
src/Validate/ForallPointerDecay.cpp
re0332dd3 r14c0f7b 214 214 if ( dynamic_cast< const ast::FunctionType * >( type ) ) return; 215 215 SemanticError( obj->location, 216 toCString( "operator ", obj->name.c_str(), " is not "217 " a function or function pointer." ) );216 toCString( "operator ", obj->name.c_str(), 217 " is not a function or function pointer." ) ); 218 218 } 219 219 }; … … 237 237 ast::Pass<AssertionFunctionFixer>::run( transUnit ); 238 238 ast::Pass<OperatorChecker>::run( transUnit ); 239 } 240 241 void fixUniqueIds( ast::TranslationUnit & transUnit ) { 239 242 ast::Pass<UniqueFixCore>::run( transUnit ); 240 243 } -
src/Validate/ForallPointerDecay.hpp
re0332dd3 r14c0f7b 27 27 28 28 /// Cleans up assertion lists and expands traits. 29 /// Also checks that operator names are used properly on functions and 30 /// assigns unique IDs. This is a "legacy" pass. 29 /// Also checks that operator names are used properly on functions. 30 /// This is a "legacy" pass. 31 /// Must happen before auto-gen routines are added. 32 void decayForallPointers( ast::TranslationUnit & transUnit ); 33 34 /// Sets uniqueIds on any declarations that do not have one set. 31 35 /// Must be after implement concurrent keywords; because uniqueIds must be 32 36 /// set on declaration before resolution. 33 /// Must happen before auto-gen routines are added. 34 void decayForallPointers( ast::TranslationUnit & transUnit ); 37 void fixUniqueIds( ast::TranslationUnit & transUnit ); 35 38 36 39 /// Expand all traits in an assertion list. -
src/main.cc
re0332dd3 r14c0f7b 334 334 PASS( "Link Reference To Types", Validate::linkReferenceToTypes, transUnit ); 335 335 336 PASS( "Forall Pointer Decay", Validate::decayForallPointers, transUnit ); 336 337 PASS( "Fix Qualified Types", Validate::fixQualifiedTypes, transUnit ); 337 338 PASS( "Eliminate Typedef", Validate::eliminateTypedef, transUnit ); … … 342 343 PASS( "Fix Return Statements", InitTweak::fixReturnStatements, transUnit ); 343 344 PASS( "Implement Concurrent Keywords", Concurrency::implementKeywords, transUnit ); 344 PASS( "F orall Pointer Decay", Validate::decayForallPointers, transUnit );345 PASS( "Fix Unique Ids", Validate::fixUniqueIds, transUnit ); 345 346 PASS( "Hoist Control Declarations", ControlStruct::hoistControlDecls, transUnit ); 346 347 … … 369 370 PASS( "Translate Throws", ControlStruct::translateThrows, transUnit ); 370 371 PASS( "Fix Labels", ControlStruct::fixLabels, transUnit ); 371 372 PASS( "Implement Waituntil", Concurrency::generateWaitUntil, transUnit ); 372 373 PASS( "Fix Names", CodeGen::fixNames, transUnit ); 373 374 PASS( "Gen Init", InitTweak::genInit, transUnit );
Note:
See TracChangeset
for help on using the changeset viewer.