- Timestamp:
- Jul 14, 2023, 9:32:31 AM (14 months ago)
- Branches:
- master
- Children:
- 402a1e7
- Parents:
- 4acf56d
- Location:
- src
- Files:
-
- 5 edited
Legend:
- Unmodified
- Added
- Removed
-
src/AST/Util.cpp
r4acf56d rb7c53a9d 102 102 } 103 103 104 /// Check for Floating Nodes: 105 /// Every node should be reachable from a root (the TranslationUnit) via a 106 /// chain of structural references (tracked with ptr). This cannot check all 107 /// of that, it just checks if a given node's field has a strong reference. 108 template<typename node_t, typename field_t> 109 void noFloatingNode( const node_t * node, field_t node_t::*field_ptr ) { 110 const field_t & field = node->*field_ptr; 111 if ( nullptr == field ) return; 112 assertf( field->isManaged(), "Floating node found." ); 113 } 114 104 115 struct InvariantCore { 105 116 // To save on the number of visits: this is a kind of composed core. … … 127 138 } 128 139 140 void previsit( const VariableExpr * node ) { 141 previsit( (const ParseNode *)node ); 142 noFloatingNode( node, &VariableExpr::var ); 143 } 144 129 145 void previsit( const MemberExpr * node ) { 130 146 previsit( (const ParseNode *)node ); 131 147 memberMatchesAggregate( node ); 148 } 149 150 void previsit( const StructInstType * node ) { 151 previsit( (const Node *)node ); 152 noFloatingNode( node, &StructInstType::base ); 153 } 154 155 void previsit( const UnionInstType * node ) { 156 previsit( (const Node *)node ); 157 noFloatingNode( node, &UnionInstType::base ); 158 } 159 160 void previsit( const EnumInstType * node ) { 161 previsit( (const Node *)node ); 162 noFloatingNode( node, &EnumInstType::base ); 163 } 164 165 void previsit( const TypeInstType * node ) { 166 previsit( (const Node *)node ); 167 noFloatingNode( node, &TypeInstType::base ); 132 168 } 133 169 -
src/InitTweak/InitTweak.cc
r4acf56d rb7c53a9d 882 882 if (!assign) { 883 883 auto td = new ast::TypeDecl(CodeLocation(), "T", {}, nullptr, ast::TypeDecl::Dtype, true); 884 assign = new ast::FunctionDecl(CodeLocation(), "?=?", { },884 assign = new ast::FunctionDecl(CodeLocation(), "?=?", {td}, 885 885 { new ast::ObjectDecl(CodeLocation(), "_dst", new ast::ReferenceType(new ast::TypeInstType("T", td))), 886 886 new ast::ObjectDecl(CodeLocation(), "_src", new ast::TypeInstType("T", td))}, -
src/Validate/ForallPointerDecay.cpp
r4acf56d rb7c53a9d 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(), " is not " 217 "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<O beratorChecker>::run( transUnit );238 ast::Pass<OperatorChecker>::run( transUnit ); 237 239 ast::Pass<UniqueFixCore>::run( transUnit ); 238 240 } -
src/Validate/LinkReferenceToTypes.cpp
r4acf56d rb7c53a9d 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 declsToAddBefore once traversal is 74 /// outside of any namespaces. 75 void addDeclBeforeOutside( ast::Decl const * ); 65 76 }; 77 78 void LinkTypesCore::enterNamespace() { 79 if ( inNamespace ) return; 80 inNamespace = true; 81 GuardAction( [this](){ 82 inNamespace = false; 83 declsToAddBefore.splice( declsToAddBefore.begin(), declsToAddOutside ); 84 } ); 85 } 86 87 void LinkTypesCore::addDeclBeforeOutside( ast::Decl const * decl ) { 88 if ( inNamespace ) { 89 declsToAddOutside.emplace_back( decl ); 90 } else { 91 declsToAddBefore.emplace_back( decl ); 92 } 93 } 66 94 67 95 ast::TypeInstType const * LinkTypesCore::postvisit( ast::TypeInstType const * type ) { … … 80 108 ast::EnumInstType const * LinkTypesCore::postvisit( ast::EnumInstType const * type ) { 81 109 ast::EnumDecl const * decl = symtab.lookupEnum( type->name ); 110 // It's not a semantic error if the enum is not found, just an implicit forward declaration. 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 decl = new ast::EnumDecl( *location, type->name ); 116 symtab.addEnum( decl ); 117 addDeclBeforeOutside( decl ); 118 } 119 82 120 ast::EnumInstType * mut = ast::mutate( type ); 83 // It's not a semantic error if the enum is not found, just an implicit forward declaration. 84 if ( decl ) { 85 // Just linking in the node. 86 mut->base = decl; 87 } 88 if ( !decl || !decl->body ) { 121 122 // Just linking in the node. 123 mut->base = decl; 124 125 if ( !decl->body ) { 89 126 forwardEnums[ mut->name ].push_back( mut ); 90 127 } … … 94 131 ast::StructInstType const * LinkTypesCore::postvisit( ast::StructInstType const * type ) { 95 132 ast::StructDecl const * decl = symtab.lookupStruct( type->name ); 133 // It's not a semantic error if the struct is not found, just an implicit forward declaration. 134 // The unset code location is used to detect imaginary declarations. 135 if ( !decl || decl->location.isUnset() ) { 136 assert( location ); 137 decl = new ast::StructDecl( *location, type->name ); 138 symtab.addStruct( decl ); 139 addDeclBeforeOutside( decl ); 140 } 141 96 142 ast::StructInstType * mut = ast::mutate( type ); 97 // It's not a semantic error if the struct is not found, just an implicit forward declaration. 98 if ( decl ) { 99 // Just linking in the node. 100 mut->base = decl; 101 } 102 if ( !decl || !decl->body ) { 143 144 // Just linking in the node. 145 mut->base = decl; 146 147 if ( !decl->body ) { 103 148 forwardStructs[ mut->name ].push_back( mut ); 104 149 } … … 108 153 ast::UnionInstType const * LinkTypesCore::postvisit( ast::UnionInstType const * type ) { 109 154 ast::UnionDecl const * decl = symtab.lookupUnion( type->name ); 155 // It's not a semantic error if the union is not found, just an implicit forward declaration. 156 // The unset code location is used to detect imaginary declarations. 157 if ( !decl || decl->location.isUnset() ) { 158 assert( location ); 159 decl = new ast::UnionDecl( *location, type->name ); 160 symtab.addUnion( decl ); 161 addDeclBeforeOutside( decl ); 162 } 163 110 164 ast::UnionInstType * mut = ast::mutate( type ); 111 // It's not a semantic error if the union is not found, just an implicit forward declaration. 112 if ( decl ) { 113 // Just linking in the node. 114 mut->base = decl; 115 } 116 if ( !decl || !decl->body ) { 165 166 // Just linking in the node. 167 mut->base = decl; 168 169 if ( !decl->body ) { 117 170 forwardUnions[ mut->name ].push_back( mut ); 118 171 } … … 219 272 220 273 ast::StructDecl const * LinkTypesCore::previsit( ast::StructDecl const * decl ) { 274 enterNamespace(); 221 275 return renameGenericParams( decl ); 222 276 } … … 237 291 238 292 ast::UnionDecl const * LinkTypesCore::previsit( ast::UnionDecl const * decl ) { 293 enterNamespace(); 239 294 return renameGenericParams( decl ); 240 295 } -
src/Validate/ReplaceTypedef.cpp
r4acf56d rb7c53a9d 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.