Changeset 2a301ff for src/Validate
- Timestamp:
- Aug 31, 2023, 11:31:15 PM (2 years ago)
- Branches:
- master
- Children:
- 950c58e
- Parents:
- 92355883 (diff), 686912c (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. - Location:
- src/Validate
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/Validate/Autogen.cpp
r92355883 r2a301ff 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
r92355883 r2a301ff 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
r92355883 r2a301ff 23 23 #include "Common/CodeLocation.h" 24 24 #include "Common/ToString.hpp" 25 #include "Common/utility.h" 25 26 #include "SymTab/FixFunction.h" 26 27 #include "AST/Print.hpp"28 27 29 28 namespace Validate { … … 51 50 } 52 51 53 template<typename T> 54 void append( std::vector<T> & dst, std::vector<T> & src ) { 55 dst.reserve( dst.size() + src.size() ); 56 for ( auto el : src ) { 57 dst.emplace_back( std::move( el ) ); 58 } 59 src.clear(); 52 ast::FunctionDecl * updateAssertions( ast::FunctionDecl * decl ) { 53 auto type = ast::mutate( decl->type.get() ); 54 type->assertions.clear(); 55 type->assertions.reserve( decl->assertions.size() ); 56 for ( auto & assertion : decl->assertions ) { 57 type->assertions.emplace_back( 58 new ast::VariableExpr( decl->location, assertion ) ); 59 } 60 decl->type = type; 61 return decl; 60 62 } 61 63 … … 96 98 decl->get_type() ) ) { 97 99 auto moreAsserts = expandTrait( traitInst ); 98 append( assertions, moreAsserts );100 splice( assertions, moreAsserts ); 99 101 } else { 100 102 assertions.push_back( decl ); … … 108 110 static TypeDeclVec expandTypeDecls( const TypeDeclVec & old ) { 109 111 TypeDeclVec typeDecls; 112 typeDecls.reserve( old.size() ); 110 113 for ( const ast::TypeDecl * typeDecl : old ) { 111 114 typeDecls.push_back( ast::mutate_field( typeDecl, … … 123 126 mut->assertions = expandAssertions( decl->assertions ); 124 127 // Update the assertion list on the type as well. 125 auto mutType = ast::mutate( mut->type.get() ); 126 mutType->assertions.clear(); 127 for ( auto & assertion : mut->assertions ) { 128 mutType->assertions.emplace_back( 129 new ast::VariableExpr( mut->location, assertion ) ); 130 } 131 mut->type = mutType; 132 return mut; 128 return updateAssertions( mut ); 133 129 } 134 130 … … 154 150 const std::vector<ast::ptr<ast::DeclWithType>> & assertions ) { 155 151 std::vector<ast::ptr<ast::DeclWithType>> ret; 152 ret.reserve( assertions.size() ); 156 153 for ( const auto & assn : assertions ) { 157 154 bool isVoid = false; … … 187 184 } 188 185 186 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * decl ) { 187 if ( decl->assertions.empty() ) { 188 return decl; 189 } 190 return updateAssertions( mutate( decl ) ); 191 } 192 189 193 const ast::StructDecl * previsit( const ast::StructDecl * decl ) { 190 194 if ( decl->params.empty() ) { … … 204 208 }; 205 209 206 struct O beratorChecker final {210 struct OperatorChecker final { 207 211 void previsit( const ast::ObjectDecl * obj ) { 208 if ( CodeGen::isOperator( obj->name ) ) { 209 auto type = obj->type->stripDeclarator(); 210 if ( ! dynamic_cast< const ast::FunctionType * >( type ) ) { 211 SemanticError( obj->location, 212 toCString( "operator ", obj->name.c_str(), " is not " 213 "a function or function pointer." ) ); 214 } 215 } 212 if ( !CodeGen::isOperator( obj->name ) ) return; 213 auto type = obj->type->stripDeclarator(); 214 if ( dynamic_cast< const ast::FunctionType * >( type ) ) return; 215 SemanticError( obj->location, 216 toCString( "operator ", obj->name.c_str(), 217 " is not a function or function pointer." ) ); 216 218 } 217 219 }; … … 234 236 ast::Pass<TraitExpander>::run( transUnit ); 235 237 ast::Pass<AssertionFunctionFixer>::run( transUnit ); 236 ast::Pass<OberatorChecker>::run( transUnit ); 238 ast::Pass<OperatorChecker>::run( transUnit ); 239 } 240 241 void fixUniqueIds( ast::TranslationUnit & transUnit ) { 237 242 ast::Pass<UniqueFixCore>::run( transUnit ); 238 243 } -
src/Validate/ForallPointerDecay.hpp
r92355883 r2a301ff 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/Validate/GenericParameter.cpp
r92355883 r2a301ff 16 16 #include "GenericParameter.hpp" 17 17 18 #include "AST/Copy.hpp"19 18 #include "AST/Decl.hpp" 20 19 #include "AST/Expr.hpp" … … 165 164 166 165 struct TranslateDimensionCore : 167 public WithNoIdSymbolTable, public ast::WithGuards { 166 public WithNoIdSymbolTable, public ast::WithGuards, 167 public ast::WithVisitorRef<TranslateDimensionCore> { 168 168 169 169 // SUIT: Struct- or Union- InstType … … 190 190 191 191 const ast::TypeDecl * postvisit( const ast::TypeDecl * decl ); 192 const ast::Type * postvisit( const ast::FunctionType * type ); 193 const ast::Type * postvisit( const ast::TypeInstType * type ); 194 192 195 const ast::Expr * postvisit( const ast::DimensionExpr * expr ); 193 196 const ast::Expr * postvisit( const ast::Expr * expr ); … … 195 198 }; 196 199 200 // Declaration of type variable: forall( [N] ) -> forall( N & | sized( N ) ) 197 201 const ast::TypeDecl * TranslateDimensionCore::postvisit( 198 202 const ast::TypeDecl * decl ) { … … 206 210 } 207 211 return decl; 212 } 213 214 // Makes postvisit( TypeInstType ) get called on the entries of the function declaration's type's forall list. 215 // Pass.impl.hpp's visit( FunctionType ) does not consider the forall entries to be child nodes. 216 // Workaround is: during the current TranslateDimension pass, manually visit down there. 217 const ast::Type * TranslateDimensionCore::postvisit( 218 const ast::FunctionType * type ) { 219 visitor->maybe_accept( type, &ast::FunctionType::forall ); 220 return type; 221 } 222 223 // Use of type variable, assuming `forall( [N] )` in scope: void (*)( foo( /*dimension*/ N ) & ) -> void (*)( foo( /*dtype*/ N ) & ) 224 const ast::Type * TranslateDimensionCore::postvisit( 225 const ast::TypeInstType * type ) { 226 if ( type->kind == ast::TypeDecl::Dimension ) { 227 auto mutType = ast::mutate( type ); 228 mutType->kind = ast::TypeDecl::Dtype; 229 return mutType; 230 } 231 return type; 208 232 } 209 233 -
src/Validate/LinkReferenceToTypes.cpp
r92355883 r2a301ff 10 10 // Created On : Thr Apr 21 11:41:00 2022 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Tue Sep 20 16:17:00 202213 // Update Count : 212 // Last Modified On : Fri Jul 14 9:19:00 2023 13 // Update Count : 3 14 14 // 15 15 … … 27 27 struct LinkTypesCore : public WithNoIdSymbolTable, 28 28 public ast::WithCodeLocation, 29 public ast::WithDeclsToAdd<>, 29 30 public ast::WithGuards, 30 31 public ast::WithShortCircuiting, … … 63 64 template<typename AggrDecl> 64 65 AggrDecl const * renameGenericParams( AggrDecl const * decl ); 66 67 // This cluster is used to add declarations (before) but outside of 68 // any "namespaces" which would qualify the names. 69 bool inNamespace = false; 70 std::list<ast::ptr<ast::Decl>> declsToAddOutside; 71 /// The "leaveNamespace" is handled by guard. 72 void enterNamespace(); 73 /// Puts the decl on the back of declsToAddAfter once traversal is 74 /// outside of any namespaces. 75 void addDeclAfterOutside( ast::Decl const * ); 65 76 }; 77 78 void LinkTypesCore::enterNamespace() { 79 if ( inNamespace ) return; 80 inNamespace = true; 81 GuardAction( [this](){ 82 inNamespace = false; 83 declsToAddAfter.splice( declsToAddAfter.begin(), declsToAddOutside ); 84 } ); 85 } 86 87 void LinkTypesCore::addDeclAfterOutside( ast::Decl const * decl ) { 88 if ( inNamespace ) { 89 declsToAddOutside.emplace_back( decl ); 90 } else { 91 declsToAddAfter.emplace_back( decl ); 92 } 93 } 66 94 67 95 ast::TypeInstType const * LinkTypesCore::postvisit( ast::TypeInstType const * type ) { … … 81 109 ast::EnumDecl const * decl = symtab.lookupEnum( type->name ); 82 110 // It's not a semantic error if the enum is not found, just an implicit forward declaration. 83 if ( decl ) { 84 // Just linking in the node. 85 auto mut = ast::mutate( type ); 86 mut->base = decl; 87 type = mut; 88 } 89 if ( !decl || !decl->body ) { 90 auto mut = ast::mutate( type ); 111 // The unset code location is used to detect imaginary declarations. 112 // (They may never be used for enumerations.) 113 if ( !decl || decl->location.isUnset() ) { 114 assert( location ); 115 ast::EnumDecl * mut = new ast::EnumDecl( *location, type->name ); 116 mut->linkage = ast::Linkage::Compiler; 117 decl = mut; 118 symtab.addEnum( decl ); 119 addDeclAfterOutside( decl ); 120 } 121 122 ast::EnumInstType * mut = ast::mutate( type ); 123 124 // Just linking in the node. 125 mut->base = decl; 126 127 if ( !decl->body ) { 91 128 forwardEnums[ mut->name ].push_back( mut ); 92 type = mut; 93 } 94 return type; 129 } 130 return mut; 95 131 } 96 132 … … 98 134 ast::StructDecl const * decl = symtab.lookupStruct( type->name ); 99 135 // It's not a semantic error if the struct is not found, just an implicit forward declaration. 100 if ( decl ) { 101 // Just linking in the node. 102 auto mut = ast::mutate( type ); 103 mut->base = decl; 104 type = mut; 105 } 106 if ( !decl || !decl->body ) { 107 auto mut = ast::mutate( type ); 136 // The unset code location is used to detect imaginary declarations. 137 if ( !decl || decl->location.isUnset() ) { 138 assert( location ); 139 ast::StructDecl * mut = new ast::StructDecl( *location, type->name ); 140 mut->linkage = ast::Linkage::Compiler; 141 decl = mut; 142 symtab.addStruct( decl ); 143 addDeclAfterOutside( decl ); 144 } 145 146 ast::StructInstType * mut = ast::mutate( type ); 147 148 // Just linking in the node. 149 mut->base = decl; 150 151 if ( !decl->body ) { 108 152 forwardStructs[ mut->name ].push_back( mut ); 109 type = mut; 110 } 111 return type; 153 } 154 return mut; 112 155 } 113 156 … … 115 158 ast::UnionDecl const * decl = symtab.lookupUnion( type->name ); 116 159 // It's not a semantic error if the union is not found, just an implicit forward declaration. 117 if ( decl ) { 118 // Just linking in the node. 119 auto mut = ast::mutate( type ); 120 mut->base = decl; 121 type = mut; 122 } 123 if ( !decl || !decl->body ) { 124 auto mut = ast::mutate( type ); 160 // The unset code location is used to detect imaginary declarations. 161 if ( !decl || decl->location.isUnset() ) { 162 assert( location ); 163 ast::UnionDecl * mut = new ast::UnionDecl( *location, type->name ); 164 mut->linkage = ast::Linkage::Compiler; 165 decl = mut; 166 symtab.addUnion( decl ); 167 addDeclAfterOutside( decl ); 168 } 169 170 ast::UnionInstType * mut = ast::mutate( type ); 171 172 // Just linking in the node. 173 mut->base = decl; 174 175 if ( !decl->body ) { 125 176 forwardUnions[ mut->name ].push_back( mut ); 126 type = mut; 127 } 128 return type; 177 } 178 return mut; 129 179 } 130 180 … … 228 278 229 279 ast::StructDecl const * LinkTypesCore::previsit( ast::StructDecl const * decl ) { 280 enterNamespace(); 230 281 return renameGenericParams( decl ); 231 282 } … … 246 297 247 298 ast::UnionDecl const * LinkTypesCore::previsit( ast::UnionDecl const * decl ) { 299 enterNamespace(); 248 300 return renameGenericParams( decl ); 249 301 } … … 264 316 265 317 ast::TraitDecl const * LinkTypesCore::postvisit( ast::TraitDecl const * decl ) { 266 auto mut = ast::mutate( decl );267 if ( mut->name == "sized" ) {268 // "sized" is a special trait - flick the sized status on for the type variable.269 assertf( mut->params.size() == 1, "Built-in trait 'sized' has incorrect number of parameters: %zd", decl->params.size() );270 ast::TypeDecl * td = mut->params.front().get_and_mutate();271 td->sized = true;272 }273 274 318 // There is some overlap with code from decayForallPointers, 275 319 // perhaps reorganization or shared helper functions are called for. 276 320 // Move assertions from type parameters into the body of the trait. 321 auto mut = ast::mutate( decl ); 277 322 for ( ast::ptr<ast::TypeDecl> const & td : decl->params ) { 278 323 auto expanded = expandAssertions( td->assertions ); -
src/Validate/NoIdSymbolTable.hpp
r92355883 r2a301ff 46 46 FORWARD_1( addUnion , const ast::UnionDecl * ) 47 47 FORWARD_1( addTrait , const ast::TraitDecl * ) 48 FORWARD_1( addStruct, const std::string & )49 FORWARD_1( addUnion , const std::string & )50 48 FORWARD_2( addWith , const std::vector< ast::ptr<ast::Expr> > &, const ast::Decl * ) 49 FORWARD_1( addStructId, const std::string & ) 50 FORWARD_1( addUnionId , const std::string & ) 51 51 52 52 FORWARD_1( globalLookupType, const std::string & ) -
src/Validate/ReplaceTypedef.cpp
r92355883 r2a301ff 20 20 #include "Common/ScopedMap.h" 21 21 #include "Common/UniqueName.h" 22 #include "Common/utility.h"23 22 #include "ResolvExpr/Unify.h" 24 23 … … 294 293 aggrDecl->name, ast::Storage::Classes(), type, aggrDecl->linkage ); 295 294 // Add the implicit typedef to the AST. 296 declsToAdd Before.push_back( ast::deepCopy( typeDecl.get() ) );295 declsToAddAfter.push_back( ast::deepCopy( typeDecl.get() ) ); 297 296 // Shore the name in the map of names. 298 297 typedefNames[ aggrDecl->name ] = … … 316 315 auto mut = ast::mutate( decl ); 317 316 318 std:: vector<ast::ptr<ast::Decl>> members;317 std::list<ast::ptr<ast::Decl>> members; 319 318 // Unroll accept_all for decl->members so that implicit typedefs for 320 319 // nested types are added to the aggregate body. 321 320 for ( ast::ptr<ast::Decl> const & member : mut->members ) { 321 assert( declsToAddBefore.empty() ); 322 322 assert( declsToAddAfter.empty() ); 323 323 ast::Decl const * newMember = nullptr; … … 328 328 } 329 329 if ( !declsToAddBefore.empty() ) { 330 for ( auto declToAdd : declsToAddBefore ) { 331 members.push_back( declToAdd ); 332 } 333 declsToAddBefore.clear(); 330 members.splice( members.end(), declsToAddBefore ); 334 331 } 335 332 members.push_back( newMember ); 336 } 333 if ( !declsToAddAfter.empty() ) { 334 members.splice( members.end(), declsToAddAfter ); 335 } 336 } 337 assert( declsToAddBefore.empty() ); 337 338 assert( declsToAddAfter.empty() ); 338 339 if ( !errors.isEmpty() ) { throw errors; }
Note:
See TracChangeset
for help on using the changeset viewer.