Changeset b82d140
- Timestamp:
- Nov 10, 2020, 12:44:44 PM (4 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, master, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- 080b0a1, 883c4d9, f33eab7
- Parents:
- 82a2fed (diff), cdacb73 (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:
-
- 24 edited
Legend:
- Unmodified
- Added
- Removed
-
benchmark/rmit.py
r82a2fed rb82d140 173 173 # ================================================================================ 174 174 # Prepare to run 175 print(actions)176 175 177 176 # find expected time … … 226 225 d = [r[0], r[1]] 227 226 for k in headers[2:]: 228 d.append(r[2][k]) 227 try: 228 d.append(r[2][k]) 229 except: 230 d.append(0.0) 229 231 230 232 data.append(d) -
libcfa/src/stdlib.hfa
r82a2fed rb82d140 101 101 return (T *)pvalloc( sizeof(T) ); // C pvalloc 102 102 } // pvalloc 103 104 void free( T * addr ) { 105 free( (void *) addr ); // C free 106 } // free 107 } // distribution 108 109 static inline forall( ttype TT | { void free( TT ); } ) { 110 // T* does not take void* and vice-versa 111 112 void free( void * addr, TT rest ) { 113 free( addr ); 114 free( rest ); 115 } // free 116 117 forall( dtype T | sized(T) ) 118 void free( T * addr, TT rest ) { 119 free( addr ); 120 free( rest ); 121 } // free 103 122 } // distribution 104 123 -
src/AST/Convert.cpp
r82a2fed rb82d140 2764 2764 old->location, 2765 2765 GET_ACCEPT_1(value, Expr), 2766 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast:: DoConstruct2766 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct 2767 2767 ); 2768 2768 } … … 2773 2773 GET_ACCEPT_V(initializers, Init), 2774 2774 GET_ACCEPT_V(designations, Designation), 2775 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast:: DoConstruct2775 (old->get_maybeConstructed()) ? ast::MaybeConstruct : ast::NoConstruct 2776 2776 ); 2777 2777 } -
src/AST/Decl.hpp
r82a2fed rb82d140 79 79 ptr<Expr> asmName; 80 80 bool isDeleted = false; 81 bool isTypeFixed = false; 81 82 82 83 DeclWithType( const CodeLocation& loc, const std::string& name, Storage::Classes storage, -
src/AST/Init.hpp
r82a2fed rb82d140 50 50 51 51 /// Flag for whether to construct from initialzier 52 enum ConstructFlag { DoConstruct, MaybeConstruct };52 enum ConstructFlag { NoConstruct, MaybeConstruct }; 53 53 54 54 /// Object initializer base class … … 71 71 ptr<Expr> value; 72 72 73 SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = DoConstruct )73 SingleInit( const CodeLocation & loc, const Expr * val, ConstructFlag mc = NoConstruct ) 74 74 : Init( loc, mc ), value( val ) {} 75 75 … … 90 90 91 91 ListInit( const CodeLocation & loc, std::vector<ptr<Init>> && is, 92 std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = DoConstruct );92 std::vector<ptr<Designation>> && ds = {}, ConstructFlag mc = NoConstruct ); 93 93 94 94 using iterator = std::vector<ptr<Init>>::iterator; … … 118 118 ConstructorInit( 119 119 const CodeLocation & loc, const Stmt * ctor, const Stmt * dtor, const Init * init ) 120 : Init( loc, DoConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {}120 : Init( loc, MaybeConstruct ), ctor( ctor ), dtor( dtor ), init( init ) {} 121 121 122 122 const Init * accept( Visitor & v ) const override { return v.visit( this ); } -
src/AST/Pass.impl.hpp
r82a2fed rb82d140 423 423 } 424 424 catch( SemanticErrorException &e ) { 425 errors.append( e ); 425 if (__pass::onError (visitor.core, *i, 0)) 426 errors.append( e ); 426 427 } 427 428 … … 683 684 // Do not enter (or leave) a new scope if atFunctionTop. Remember to save the result. 684 685 auto guard1 = makeFuncGuard( [this, enterScope = !this->atFunctionTop]() { 685 if ( enterScope ) __pass::symtab::enter(core, 0); 686 if ( enterScope ) { 687 __pass::symtab::enter(core, 0); 688 __pass::scope::enter(core, 0); 689 } 686 690 }, [this, leaveScope = !this->atFunctionTop]() { 687 if ( leaveScope ) __pass::symtab::leave(core, 0); 691 if ( leaveScope ) { 692 __pass::symtab::leave(core, 0); 693 __pass::scope::leave(core, 0); 694 } 688 695 }); 689 696 ValueGuard< bool > guard2( atFunctionTop ); -
src/AST/Pass.proto.hpp
r82a2fed rb82d140 266 266 static void endTrace(core_t &, long) {} 267 267 268 // Allows visitor to handle an error on top-level declarations, and possibly suppress the error. 269 // If onError() returns false, the error will be ignored. By default, it returns true. 270 271 template< typename core_t > 272 static bool onError (core_t &, ptr<Decl> &, long) { return true; } 273 274 template< typename core_t > 275 static auto onError (core_t & core, ptr<Decl> & decl, int) -> decltype(core.onError(decl)) { 276 return core.onError(decl); 277 } 278 268 279 // Another feature of the templated visitor is that it calls beginScope()/endScope() for compound statement. 269 280 // All passes which have such functions are assumed desire this behaviour -
src/AST/Type.cpp
r82a2fed rb82d140 211 211 for ( const Type * ty : types ) { 212 212 members.emplace_back( new ObjectDecl{ 213 CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, MaybeConstruct ),213 CodeLocation{}, "", ty, new ListInit( CodeLocation{}, {}, {}, NoConstruct ), 214 214 Storage::Classes{}, Linkage::Cforall } ); 215 215 } -
src/CodeGen/CodeGenerator.cc
r82a2fed rb82d140 120 120 // GCC builtins should always be printed unmangled 121 121 if ( options.pretty || decl->linkage.is_gcc_builtin ) return decl->name; 122 if ( decl->mangleName != "" ) {122 if ( LinkageSpec::isMangled(decl->linkage) && decl->mangleName != "" ) { 123 123 // need to incorporate scope level in order to differentiate names for destructors 124 124 return decl->get_scopedMangleName(); -
src/CodeGen/FixMain.cc
r82a2fed rb82d140 26 26 #include "SynTree/Declaration.h" // for FunctionDecl, operator<< 27 27 #include "SynTree/Type.h" // for FunctionType 28 #include "SymTab/Mangler.h" 28 29 29 30 namespace CodeGen { … … 47 48 if( main_signature ) { 48 49 os << "static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return "; 50 main_signature->mangleName = SymTab::Mangler::mangle(main_signature.get()); 49 51 50 52 os << main_signature->get_scopedMangleName() << "("; -
src/CodeGen/FixNames.cc
r82a2fed rb82d140 31 31 #include "SynTree/Type.h" // for Type, BasicType, Type::Qualifiers 32 32 #include "SynTree/Visitor.h" // for Visitor, acceptAll 33 #include "CompilationState.h" 33 34 34 35 namespace CodeGen { … … 102 103 if ( dwt->get_name() != "" ) { 103 104 if ( LinkageSpec::isMangled( dwt->get_linkage() ) ) { 104 dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) ); 105 if (!useNewAST) { 106 dwt->set_mangleName( SymTab::Mangler::mangle( dwt ) ); 107 } 105 108 dwt->set_scopeLevel( scopeLevel ); 106 109 } // if -
src/InitTweak/GenInit.cc
r82a2fed rb82d140 26 26 #include "AST/Node.hpp" 27 27 #include "AST/Stmt.hpp" 28 #include "CompilationState.h" 28 29 #include "CodeGen/OperatorTable.h" 29 30 #include "Common/PassVisitor.h" // for PassVisitor, WithGuards, WithShort... … … 122 123 123 124 void genInit( std::list< Declaration * > & translationUnit ) { 125 HoistArrayDimension::hoistArrayDimension( translationUnit ); 124 126 fixReturnStatements( translationUnit ); 125 HoistArrayDimension::hoistArrayDimension( translationUnit ); 126 CtorDtor::generateCtorDtor( translationUnit ); 127 128 if (!useNewAST) { 129 CtorDtor::generateCtorDtor( translationUnit ); 130 } 127 131 } 128 132 … … 192 196 193 197 // need to resolve array dimensions in order to accurately determine if constexpr 194 ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer ); 195 // array is variable-length when the dimension is not constexpr 196 arrayType->isVarLen = ! isConstExpr( arrayType->dimension ); 198 if (!useNewAST) { 199 ResolvExpr::findSingleExpression( arrayType->dimension, Validate::SizeType->clone(), indexer ); 200 // array is variable-length when the dimension is not constexpr 201 arrayType->isVarLen = ! isConstExpr( arrayType->dimension ); 202 } 197 203 // don't need to hoist dimension if it's definitely pure - only need to if there's potential for side effects. 198 if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return; 204 // xxx - hoisting has no side effects anyways, so don't skip since we delay resolve 205 // only skip in the most trivial case, which does not require resolve 206 if (dynamic_cast<ConstantExpr *>(arrayType->dimension)) return; 207 // if ( ! Tuples::maybeImpure( arrayType->dimension ) ) return; 199 208 200 209 ObjectDecl * arrayDimension = new ObjectDecl( dimensionName.newName(), storageClasses, LinkageSpec::C, 0, Validate::SizeType->clone(), new SingleInit( arrayType->get_dimension() ) ); … … 245 254 } 246 255 256 // why is this not just on FunctionDecl? 247 257 void ManagedTypes::handleDWT( DeclarationWithType * dwt ) { 248 258 // if this function is a user-defined constructor or destructor, mark down the type as "managed" … … 274 284 void ManagedTypes::beginScope() { managedTypes.beginScope(); } 275 285 void ManagedTypes::endScope() { managedTypes.endScope(); } 286 287 bool ManagedTypes_new::isManaged( const ast::Type * type ) const { 288 // references are never constructed 289 if ( dynamic_cast< const ast::ReferenceType * >( type ) ) return false; 290 if ( auto tupleType = dynamic_cast< const ast::TupleType * > ( type ) ) { 291 // tuple is also managed if any of its components are managed 292 for (auto & component : tupleType->types) { 293 if (isManaged(component)) return true; 294 } 295 } 296 // need to clear and reset qualifiers when determining if a type is managed 297 // ValueGuard< Type::Qualifiers > qualifiers( type->get_qualifiers() ); 298 auto tmp = shallowCopy(type); 299 tmp->qualifiers = {}; 300 // delete tmp at return 301 ast::ptr<ast::Type> guard = tmp; 302 // a type is managed if it appears in the map of known managed types, or if it contains any polymorphism (is a type variable or generic type containing a type variable) 303 return managedTypes.find( Mangle::mangle( tmp, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) ) != managedTypes.end() || GenPoly::isPolyType( tmp ); 304 } 305 306 bool ManagedTypes_new::isManaged( const ast::ObjectDecl * objDecl ) const { 307 const ast::Type * type = objDecl->type; 308 while ( auto at = dynamic_cast< const ast::ArrayType * >( type ) ) { 309 // must always construct VLAs with an initializer, since this is an error in C 310 if ( at->isVarLen && objDecl->init ) return true; 311 type = at->base; 312 } 313 return isManaged( type ); 314 } 315 316 void ManagedTypes_new::handleDWT( const ast::DeclWithType * dwt ) { 317 // if this function is a user-defined constructor or destructor, mark down the type as "managed" 318 if ( ! dwt->linkage.is_overrideable && CodeGen::isCtorDtor( dwt->name ) ) { 319 auto & params = GenPoly::getFunctionType( dwt->get_type())->params; 320 assert( ! params.empty() ); 321 // Type * type = InitTweak::getPointerBase( params.front() ); 322 // assert( type ); 323 managedTypes.insert( Mangle::mangle( params.front(), {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) ); 324 } 325 } 326 327 void ManagedTypes_new::handleStruct( const ast::StructDecl * aggregateDecl ) { 328 // don't construct members, but need to take note if there is a managed member, 329 // because that means that this type is also managed 330 for ( auto & member : aggregateDecl->members ) { 331 if ( auto field = member.as<ast::ObjectDecl>() ) { 332 if ( isManaged( field ) ) { 333 // generic parameters should not play a role in determining whether a generic type is constructed - construct all generic types, so that 334 // polymorphic constructors make generic types managed types 335 ast::StructInstType inst( aggregateDecl ); 336 managedTypes.insert( Mangle::mangle( &inst, {Mangle::NoOverrideable | Mangle::NoGenericParams | Mangle::Type} ) ); 337 break; 338 } 339 } 340 } 341 } 342 343 void ManagedTypes_new::beginScope() { managedTypes.beginScope(); } 344 void ManagedTypes_new::endScope() { managedTypes.endScope(); } 276 345 277 346 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg ) { … … 370 439 // constructable object 371 440 InitExpander_new srcParam{ objDecl->init }, nullParam{ (const ast::Init *)nullptr }; 441 ast::ptr< ast::Expr > dstParam = new ast::VariableExpr(loc, objDecl); 372 442 373 443 ast::ptr< ast::Stmt > ctor = SymTab::genImplicitCall( 374 srcParam, new ast::VariableExpr{ loc, objDecl }, loc, "?{}", objDecl );444 srcParam, dstParam, loc, "?{}", objDecl ); 375 445 ast::ptr< ast::Stmt > dtor = SymTab::genImplicitCall( 376 nullParam, new ast::VariableExpr{ loc, objDecl }, loc, "^?{}", objDecl,446 nullParam, dstParam, loc, "^?{}", objDecl, 377 447 SymTab::LoopBackward ); 378 448 -
src/InitTweak/GenInit.h
r82a2fed rb82d140 52 52 GenPoly::ScopedSet< std::string > managedTypes; 53 53 }; 54 55 class ManagedTypes_new { 56 public: 57 bool isManaged( const ast::ObjectDecl * objDecl ) const ; // determine if object is managed 58 bool isManaged( const ast::Type * type ) const; // determine if type is managed 59 60 void handleDWT( const ast::DeclWithType * dwt ); // add type to managed if ctor/dtor 61 void handleStruct( const ast::StructDecl * aggregateDecl ); // add type to managed if child is managed 62 63 void beginScope(); 64 void endScope(); 65 private: 66 GenPoly::ScopedSet< std::string > managedTypes; 67 }; 54 68 } // namespace 55 69 -
src/InitTweak/InitTweak.cc
r82a2fed rb82d140 87 87 }; 88 88 89 struct HasDesignations_new : public ast::WithShortCircuiting { 90 bool result = false; 91 92 void previsit( const ast::Node * ) { 93 // short circuit if we already know there are designations 94 if ( result ) visit_children = false; 95 } 96 97 void previsit( const ast::Designation * des ) { 98 // short circuit if we already know there are designations 99 if ( result ) visit_children = false; 100 else if ( ! des->designators.empty() ) { 101 result = true; 102 visit_children = false; 103 } 104 } 105 }; 106 107 struct InitDepthChecker_new : public ast::WithGuards { 108 bool result = true; 109 const ast::Type * type; 110 int curDepth = 0, maxDepth = 0; 111 InitDepthChecker_new( const ast::Type * type ) : type( type ) { 112 const ast::Type * t = type; 113 while ( auto at = dynamic_cast< const ast::ArrayType * >( t ) ) { 114 maxDepth++; 115 t = at->base; 116 } 117 maxDepth++; 118 } 119 void previsit( ListInit * ) { 120 curDepth++; 121 GuardAction( [this]() { curDepth--; } ); 122 if ( curDepth > maxDepth ) result = false; 123 } 124 }; 125 89 126 struct InitFlattener_old : public WithShortCircuiting { 90 127 void previsit( SingleInit * singleInit ) { … … 122 159 maybeAccept( objDecl->init, checker ); 123 160 return checker.pass.depthOkay; 161 } 162 163 bool isDesignated( const ast::Init * init ) { 164 ast::Pass<HasDesignations_new> finder; 165 maybe_accept( init, finder ); 166 return finder.core.result; 167 } 168 169 bool checkInitDepth( const ast::ObjectDecl * objDecl ) { 170 ast::Pass<InitDepthChecker_new> checker( objDecl->type ); 171 maybe_accept( objDecl->init.get(), checker ); 172 return checker.core.result; 124 173 } 125 174 … … 358 407 if ( auto listInit = dynamic_cast< const ast::ListInit * >( init ) ) { 359 408 for ( const ast::Init * init : *listInit ) { 360 buildCallExpr( callExpr, index, dimension, init, out );409 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out ); 361 410 } 362 411 } else { 363 buildCallExpr( callExpr, index, dimension, init, out );412 buildCallExpr( shallowCopy(callExpr), index, dimension, init, out ); 364 413 } 365 414 } else { … … 1027 1076 }; 1028 1077 1078 struct ConstExprChecker_new : public ast::WithShortCircuiting { 1079 // most expressions are not const expr 1080 void previsit( const ast::Expr * ) { result = false; visit_children = false; } 1081 1082 void previsit( const ast::AddressExpr *addressExpr ) { 1083 visit_children = false; 1084 const ast::Expr * arg = addressExpr->arg; 1085 1086 // address of a variable or member expression is constexpr 1087 if ( ! dynamic_cast< const ast::NameExpr * >( arg ) 1088 && ! dynamic_cast< const ast::VariableExpr * >( arg ) 1089 && ! dynamic_cast< const ast::MemberExpr * >( arg ) 1090 && ! dynamic_cast< const ast::UntypedMemberExpr * >( arg ) ) result = false; 1091 } 1092 1093 // these expressions may be const expr, depending on their children 1094 void previsit( const ast::SizeofExpr * ) {} 1095 void previsit( const ast::AlignofExpr * ) {} 1096 void previsit( const ast::UntypedOffsetofExpr * ) {} 1097 void previsit( const ast::OffsetofExpr * ) {} 1098 void previsit( const ast::OffsetPackExpr * ) {} 1099 void previsit( const ast::CommaExpr * ) {} 1100 void previsit( const ast::LogicalExpr * ) {} 1101 void previsit( const ast::ConditionalExpr * ) {} 1102 void previsit( const ast::CastExpr * ) {} 1103 void previsit( const ast::ConstantExpr * ) {} 1104 1105 void previsit( const ast::VariableExpr * varExpr ) { 1106 visit_children = false; 1107 1108 if ( auto inst = varExpr->result.as<ast::EnumInstType>() ) { 1109 long long int value; 1110 if ( inst->base->valueOf( varExpr->var, value ) ) { 1111 // enumerators are const expr 1112 return; 1113 } 1114 } 1115 result = false; 1116 } 1117 1118 bool result = true; 1119 }; 1120 1029 1121 bool isConstExpr( Expression * expr ) { 1030 1122 if ( expr ) { … … 1046 1138 } 1047 1139 1140 bool isConstExpr( const ast::Expr * expr ) { 1141 if ( expr ) { 1142 ast::Pass<ConstExprChecker_new> checker; 1143 expr->accept( checker ); 1144 return checker.core.result; 1145 } 1146 return true; 1147 } 1148 1149 bool isConstExpr( const ast::Init * init ) { 1150 if ( init ) { 1151 ast::Pass<ConstExprChecker_new> checker; 1152 init->accept( checker ); 1153 return checker.core.result; 1154 } // if 1155 // for all intents and purposes, no initializer means const expr 1156 return true; 1157 } 1158 1048 1159 bool isConstructor( const std::string & str ) { return str == "?{}"; } 1049 1160 bool isDestructor( const std::string & str ) { return str == "^?{}"; } -
src/InitTweak/InitTweak.h
r82a2fed rb82d140 59 59 /// True if the Initializer contains designations 60 60 bool isDesignated( Initializer * init ); 61 bool isDesignated( const ast::Init * init ); 61 62 62 63 /// True if the ObjectDecl's Initializer nesting level is not deeper than the depth of its 63 64 /// type, where the depth of its type is the number of nested ArrayTypes + 1 64 65 bool checkInitDepth( ObjectDecl * objDecl ); 66 bool checkInitDepth( const ast::ObjectDecl * objDecl ); 65 67 66 68 /// returns the declaration of the function called by the expr (must be ApplicationExpr or UntypedExpr) … … 107 109 bool isConstExpr( Expression * expr ); 108 110 bool isConstExpr( Initializer * init ); 111 112 bool isConstExpr( const ast::Expr * expr ); 113 bool isConstExpr( const ast::Init * init ); 109 114 110 115 /// Modifies objDecl to have: -
src/ResolvExpr/ResolveTypeof.cc
r82a2fed rb82d140 29 29 #include "SynTree/Mutator.h" // for Mutator 30 30 #include "SynTree/Type.h" // for TypeofType, Type 31 #include "SymTab/Mangler.h" 32 #include "InitTweak/InitTweak.h" // for isConstExpr 31 33 32 34 namespace SymTab { … … 163 165 } 164 166 167 struct FixArrayDimension { 168 // should not require a mutable symbol table - prevent pass template instantiation 169 const ast::SymbolTable & _symtab; 170 FixArrayDimension(const ast::SymbolTable & symtab): _symtab(symtab) {} 171 172 const ast::ArrayType * previsit (const ast::ArrayType * arrayType) { 173 if (!arrayType->dimension) return arrayType; 174 auto mutType = mutate(arrayType); 175 ast::ptr<ast::Type> sizetype = ast::sizeType ? ast::sizeType : new ast::BasicType(ast::BasicType::LongUnsignedInt); 176 mutType->dimension = findSingleExpression(arrayType->dimension, sizetype, _symtab); 177 178 if (InitTweak::isConstExpr(mutType->dimension)) { 179 mutType->isVarLen = ast::LengthFlag::FixedLen; 180 } 181 else { 182 mutType->isVarLen = ast::LengthFlag::VariableLen; 183 } 184 return mutType; 185 } 186 }; 187 188 const ast::Type * fixArrayType( const ast::Type * type, const ast::SymbolTable & symtab) { 189 ast::Pass<FixArrayDimension> visitor {symtab}; 190 return type->accept(visitor); 191 } 192 193 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ) { 194 if (!decl->isTypeFixed) { 195 auto mutDecl = mutate(decl); 196 auto resolvedType = resolveTypeof(decl->type, symtab); 197 resolvedType = fixArrayType(resolvedType, symtab); 198 mutDecl->type = resolvedType; 199 200 // check variable length if object is an array. 201 // xxx - should this be part of fixObjectType? 202 203 /* 204 if (auto arrayType = dynamic_cast<const ast::ArrayType *>(resolvedType)) { 205 auto dimExpr = findSingleExpression(arrayType->dimension, ast::sizeType, symtab); 206 if (auto varexpr = arrayType->dimension.as<ast::VariableExpr>()) {// hoisted previously 207 if (InitTweak::isConstExpr(varexpr->var.strict_as<ast::ObjectDecl>()->init)) { 208 auto mutType = mutate(arrayType); 209 mutType->isVarLen = ast::LengthFlag::VariableLen; 210 mutDecl->type = mutType; 211 } 212 } 213 } 214 */ 215 216 217 if (!mutDecl->name.empty()) 218 mutDecl->mangleName = Mangle::mangle(mutDecl); // do not mangle unnamed variables 219 220 mutDecl->isTypeFixed = true; 221 return mutDecl; 222 } 223 return decl; 224 } 225 165 226 } // namespace ResolvExpr 166 227 -
src/ResolvExpr/ResolveTypeof.h
r82a2fed rb82d140 23 23 class Type; 24 24 class SymbolTable; 25 class ObjectDecl; 25 26 } 26 27 … … 28 29 Type *resolveTypeof( Type*, const SymTab::Indexer &indexer ); 29 30 const ast::Type * resolveTypeof( const ast::Type *, const ast::SymbolTable & ); 31 const ast::ObjectDecl * fixObjectType( const ast::ObjectDecl * decl , const ast::SymbolTable & symtab ); 30 32 } // namespace ResolvExpr 31 33 -
src/ResolvExpr/Resolver.cc
r82a2fed rb82d140 26 26 #include "RenameVars.h" // for RenameVars, global_renamer 27 27 #include "Resolver.h" 28 #include "ResolveTypeof.h" 28 29 #include "ResolvMode.h" // for ResolvMode 29 30 #include "typeops.h" // for extractResultType 30 31 #include "Unify.h" // for unify 32 #include "CompilationState.h" 31 33 #include "AST/Chain.hpp" 32 34 #include "AST/Decl.hpp" … … 45 47 #include "SymTab/Autogen.h" // for SizeType 46 48 #include "SymTab/Indexer.h" // for Indexer 49 #include "SymTab/Mangler.h" // for Mangler 47 50 #include "SynTree/Declaration.h" // for ObjectDecl, TypeDecl, Declar... 48 51 #include "SynTree/Expression.h" // for Expression, CastExpr, InitExpr … … 1179 1182 } // anonymous namespace 1180 1183 1181 1182 1183 1184 1185 1186 1187 1188 1189 1184 ast::ptr< ast::Expr > findSingleExpression( 1185 const ast::Expr * untyped, const ast::Type * type, const ast::SymbolTable & symtab 1186 ) { 1187 assert( untyped && type ); 1188 ast::ptr< ast::Expr > castExpr = new ast::CastExpr{ untyped, type }; 1189 ast::ptr< ast::Expr > newExpr = findSingleExpression( castExpr, symtab ); 1190 removeExtraneousCast( newExpr, symtab ); 1191 return newExpr; 1192 } 1190 1193 1191 1194 namespace { 1195 bool structOrUnion( const Candidate & i ) { 1196 const ast::Type * t = i.expr->result->stripReferences(); 1197 return dynamic_cast< const ast::StructInstType * >( t ) || dynamic_cast< const ast::UnionInstType * >( t ); 1198 } 1192 1199 /// Predicate for "Candidate has integral type" 1193 1200 bool hasIntegralType( const Candidate & i ) { … … 1237 1244 ast::ptr< ast::Type > functionReturn = nullptr; 1238 1245 ast::CurrentObject currentObject; 1246 // for work previously in GenInit 1247 static InitTweak::ManagedTypes_new managedTypes; 1248 1239 1249 bool inEnumDecl = false; 1240 1250 … … 1244 1254 Resolver_new( const ast::SymbolTable & syms ) { symtab = syms; } 1245 1255 1246 voidprevisit( const ast::FunctionDecl * );1256 const ast::FunctionDecl * previsit( const ast::FunctionDecl * ); 1247 1257 const ast::FunctionDecl * postvisit( const ast::FunctionDecl * ); 1248 void previsit( const ast::ObjectDecl * ); 1258 const ast::ObjectDecl * previsit( const ast::ObjectDecl * ); 1259 void previsit( const ast::AggregateDecl * ); 1260 void previsit( const ast::StructDecl * ); 1249 1261 void previsit( const ast::EnumDecl * ); 1250 1262 const ast::StaticAssertDecl * previsit( const ast::StaticAssertDecl * ); … … 1267 1279 const ast::CatchStmt * postvisit( const ast::CatchStmt * ); 1268 1280 const ast::WaitForStmt * previsit( const ast::WaitForStmt * ); 1281 const ast::WithStmt * previsit( const ast::WithStmt * ); 1269 1282 1270 1283 const ast::SingleInit * previsit( const ast::SingleInit * ); 1271 1284 const ast::ListInit * previsit( const ast::ListInit * ); 1272 1285 const ast::ConstructorInit * previsit( const ast::ConstructorInit * ); 1286 1287 void resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd); 1288 1289 void beginScope() { managedTypes.beginScope(); } 1290 void endScope() { managedTypes.endScope(); } 1291 bool onError(ast::ptr<ast::Decl> & decl); 1273 1292 }; 1274 1293 // size_t Resolver_new::traceId = Stats::Heap::new_stacktrace_id("Resolver"); 1294 1295 InitTweak::ManagedTypes_new Resolver_new::managedTypes; 1275 1296 1276 1297 void resolve( ast::TranslationUnit& translationUnit ) { … … 1297 1318 } 1298 1319 1299 void Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 1320 namespace { 1321 const ast::Attribute * handleAttribute(const CodeLocation & loc, const ast::Attribute * attr, const ast::SymbolTable & symtab) { 1322 std::string name = attr->normalizedName(); 1323 if (name == "constructor" || name == "destructor") { 1324 if (attr->params.size() == 1) { 1325 auto arg = attr->params.front(); 1326 auto resolved = ResolvExpr::findSingleExpression( arg, new ast::BasicType( ast::BasicType::LongLongSignedInt ), symtab ); 1327 auto result = eval(arg); 1328 1329 auto mutAttr = mutate(attr); 1330 mutAttr->params.front() = resolved; 1331 if (! result.second) { 1332 SemanticWarning(loc, Warning::GccAttributes, 1333 toCString( name, " priorities must be integers from 0 to 65535 inclusive: ", arg ) ); 1334 } 1335 else { 1336 auto priority = result.first; 1337 if (priority < 101) { 1338 SemanticWarning(loc, Warning::GccAttributes, 1339 toCString( name, " priorities from 0 to 100 are reserved for the implementation" ) ); 1340 } else if (priority < 201 && ! buildingLibrary()) { 1341 SemanticWarning(loc, Warning::GccAttributes, 1342 toCString( name, " priorities from 101 to 200 are reserved for the implementation" ) ); 1343 } 1344 } 1345 return mutAttr; 1346 } else if (attr->params.size() > 1) { 1347 SemanticWarning(loc, Warning::GccAttributes, toCString( "too many arguments to ", name, " attribute" ) ); 1348 } else { 1349 SemanticWarning(loc, Warning::GccAttributes, toCString( "too few arguments to ", name, " attribute" ) ); 1350 } 1351 } 1352 return attr; 1353 } 1354 } 1355 1356 const ast::FunctionDecl * Resolver_new::previsit( const ast::FunctionDecl * functionDecl ) { 1300 1357 GuardValue( functionReturn ); 1358 1359 assert (functionDecl->unique()); 1360 if (!functionDecl->has_body() && !functionDecl->withExprs.empty()) { 1361 SemanticError(functionDecl->location, functionDecl, "Function without body has with declarations"); 1362 } 1363 1364 if (!functionDecl->isTypeFixed) { 1365 auto mutDecl = mutate(functionDecl); 1366 auto mutType = mutDecl->type.get_and_mutate(); 1367 1368 for (auto & attr: mutDecl->attributes) { 1369 attr = handleAttribute(mutDecl->location, attr, symtab); 1370 } 1371 1372 // handle assertions. (seems deep) 1373 1374 symtab.enterScope(); 1375 for (auto & typeParam : mutType->forall) { 1376 auto mutParam = typeParam.get_and_mutate(); 1377 symtab.addType(mutParam); 1378 for (auto & asst : mutParam->assertions) { 1379 asst = fixObjectType(asst.strict_as<ast::ObjectDecl>(), symtab); 1380 symtab.addId(asst); 1381 } 1382 typeParam = mutParam; 1383 } 1384 1385 // temporarily adds params to symbol table. 1386 // actual scoping rules for params and withexprs differ - see Pass::visit(FunctionDecl) 1387 1388 std::vector<ast::ptr<ast::Type>> paramTypes; 1389 std::vector<ast::ptr<ast::Type>> returnTypes; 1390 1391 for (auto & param : mutDecl->params) { 1392 param = fixObjectType(param.strict_as<ast::ObjectDecl>(), symtab); 1393 symtab.addId(param); 1394 paramTypes.emplace_back(param->get_type()); 1395 } 1396 for (auto & ret : mutDecl->returns) { 1397 ret = fixObjectType(ret.strict_as<ast::ObjectDecl>(), symtab); 1398 returnTypes.emplace_back(ret->get_type()); 1399 } 1400 // since function type in decl is just a view of param types, need to update that as well 1401 mutType->params = std::move(paramTypes); 1402 mutType->returns = std::move(returnTypes); 1403 1404 std::list<ast::ptr<ast::Stmt>> newStmts; 1405 resolveWithExprs (mutDecl->withExprs, newStmts); 1406 1407 if (mutDecl->stmts) { 1408 auto mutStmt = mutDecl->stmts.get_and_mutate(); 1409 mutStmt->kids.splice(mutStmt->kids.begin(), std::move(newStmts)); 1410 mutDecl->stmts = mutStmt; 1411 } 1412 1413 symtab.leaveScope(); 1414 1415 mutDecl->mangleName = Mangle::mangle(mutDecl); 1416 mutDecl->isTypeFixed = true; 1417 functionDecl = mutDecl; 1418 } 1419 managedTypes.handleDWT(functionDecl); 1420 1301 1421 functionReturn = extractResultType( functionDecl->type ); 1422 return functionDecl; 1302 1423 } 1303 1424 … … 1330 1451 } 1331 1452 1332 voidResolver_new::previsit( const ast::ObjectDecl * objectDecl ) {1453 const ast::ObjectDecl * Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1333 1454 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1334 1455 // class-variable `initContext` is changed multiple times because the LHS is analyzed … … 1338 1459 // selecting the RHS. 1339 1460 GuardValue( currentObject ); 1340 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1461 1341 1462 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1342 1463 // enumerator initializers should not use the enum type to initialize, since the 1343 1464 // enum type is still incomplete at this point. Use `int` instead. 1465 objectDecl = fixObjectType(objectDecl, symtab); 1344 1466 currentObject = ast::CurrentObject{ 1345 1467 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1346 1468 } 1469 else { 1470 if (!objectDecl->isTypeFixed) { 1471 auto newDecl = fixObjectType(objectDecl, symtab); 1472 auto mutDecl = mutate(newDecl); 1473 1474 // generate CtorInit wrapper when necessary. 1475 // in certain cases, fixObjectType is called before reaching 1476 // this object in visitor pass, thus disabling CtorInit codegen. 1477 // this happens on aggregate members and function parameters. 1478 if ( InitTweak::tryConstruct( mutDecl ) && ( managedTypes.isManaged( mutDecl ) || ((! isInFunction() || mutDecl->storage.is_static ) && ! InitTweak::isConstExpr( mutDecl->init ) ) ) ) { 1479 // constructed objects cannot be designated 1480 if ( InitTweak::isDesignated( mutDecl->init ) ) SemanticError( mutDecl, "Cannot include designations in the initializer for a managed Object. If this is really what you want, then initialize with @=.\n" ); 1481 // constructed objects should not have initializers nested too deeply 1482 if ( ! InitTweak::checkInitDepth( mutDecl ) ) SemanticError( mutDecl, "Managed object's initializer is too deep " ); 1483 1484 mutDecl->init = InitTweak::genCtorInit( mutDecl->location, mutDecl ); 1485 } 1486 1487 objectDecl = mutDecl; 1488 } 1489 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1490 } 1491 1492 return objectDecl; 1493 } 1494 1495 void Resolver_new::previsit( const ast::AggregateDecl * _aggDecl ) { 1496 auto aggDecl = mutate(_aggDecl); 1497 assertf(aggDecl == _aggDecl, "type declarations must be unique"); 1498 1499 for (auto & member: aggDecl->members) { 1500 // nested type decls are hoisted already. no need to do anything 1501 if (auto obj = member.as<ast::ObjectDecl>()) { 1502 member = fixObjectType(obj, symtab); 1503 } 1504 } 1505 } 1506 1507 void Resolver_new::previsit( const ast::StructDecl * structDecl ) { 1508 previsit(static_cast<const ast::AggregateDecl *>(structDecl)); 1509 managedTypes.handleStruct(structDecl); 1347 1510 } 1348 1511 … … 1351 1514 GuardValue( inEnumDecl ); 1352 1515 inEnumDecl = true; 1353 } 1516 // don't need to fix types for enum fields 1517 } 1518 1354 1519 1355 1520 const ast::StaticAssertDecl * Resolver_new::previsit( … … 1780 1945 } 1781 1946 1947 const ast::WithStmt * Resolver_new::previsit( const ast::WithStmt * withStmt ) { 1948 auto mutStmt = mutate(withStmt); 1949 resolveWithExprs(mutStmt->exprs, stmtsToAddBefore); 1950 return mutStmt; 1951 } 1952 1953 void Resolver_new::resolveWithExprs(std::vector<ast::ptr<ast::Expr>> & exprs, std::list<ast::ptr<ast::Stmt>> & stmtsToAdd) { 1954 for (auto & expr : exprs) { 1955 // only struct- and union-typed expressions are viable candidates 1956 expr = findKindExpression( expr, symtab, structOrUnion, "with expression" ); 1957 1958 // if with expression might be impure, create a temporary so that it is evaluated once 1959 if ( Tuples::maybeImpure( expr ) ) { 1960 static UniqueName tmpNamer( "_with_tmp_" ); 1961 const CodeLocation loc = expr->location; 1962 auto tmp = new ast::ObjectDecl(loc, tmpNamer.newName(), expr->result, new ast::SingleInit(loc, expr ) ); 1963 expr = new ast::VariableExpr( loc, tmp ); 1964 stmtsToAdd.push_back( new ast::DeclStmt(loc, tmp ) ); 1965 if ( InitTweak::isConstructable( tmp->type ) ) { 1966 // generate ctor/dtor and resolve them 1967 tmp->init = InitTweak::genCtorInit( loc, tmp ); 1968 } 1969 // since tmp is freshly created, this should modify tmp in-place 1970 tmp->accept( *visitor ); 1971 } 1972 } 1973 } 1782 1974 1783 1975 … … 1875 2067 } 1876 2068 2069 // suppress error on autogen functions and mark invalid autogen as deleted. 2070 bool Resolver_new::onError(ast::ptr<ast::Decl> & decl) { 2071 if (auto functionDecl = decl.as<ast::FunctionDecl>()) { 2072 // xxx - can intrinsic gen ever fail? 2073 if (functionDecl->linkage == ast::Linkage::AutoGen) { 2074 auto mutDecl = mutate(functionDecl); 2075 mutDecl->isDeleted = true; 2076 mutDecl->stmts = nullptr; 2077 decl = mutDecl; 2078 return false; 2079 } 2080 } 2081 return true; 2082 } 2083 1877 2084 } // namespace ResolvExpr 1878 2085 -
src/ResolvExpr/SatisfyAssertions.cpp
r82a2fed rb82d140 247 247 auto it = inferred.find( slot ); 248 248 if ( it == inferred.end() ) { 249 std::cerr << "missing assertion " << slot << std::endl;249 // std::cerr << "missing assertion " << slot << std::endl; 250 250 missingSlots.push_back(slot); 251 251 continue; -
src/SymTab/Autogen.cc
r82a2fed rb82d140 38 38 #include "SynTree/Type.h" // for FunctionType, Type, TypeInstType 39 39 #include "SynTree/Visitor.h" // for maybeAccept, Visitor, acceptAll 40 #include "CompilationState.h" 40 41 41 42 class Attribute; … … 346 347 void FuncGenerator::resolve( FunctionDecl * dcl ) { 347 348 try { 348 ResolvExpr::resolveDecl( dcl, indexer ); 349 if (!useNewAST) // attempt to delay resolver call 350 ResolvExpr::resolveDecl( dcl, indexer ); 349 351 if ( functionNesting == 0 ) { 350 352 // forward declare if top-level struct, so that -
src/SymTab/Autogen.h
r82a2fed rb82d140 167 167 fExpr->args.emplace_back( dstParam ); 168 168 169 const ast::Stmt *listInit = srcParam.buildListInit( fExpr );169 ast::ptr<ast::Stmt> listInit = srcParam.buildListInit( fExpr ); 170 170 171 171 // fetch next set of arguments -
src/SymTab/Validate.cc
r82a2fed rb82d140 64 64 #include "Common/UniqueName.h" // for UniqueName 65 65 #include "Common/utility.h" // for operator+, cloneAll, deleteAll 66 #include "CompilationState.h" // skip some passes in new-ast build 66 67 #include "Concurrency/Keywords.h" // for applyKeywords 67 68 #include "FixFunction.h" // for FixFunction … … 368 369 mutateAll( translationUnit, compoundliteral ); 369 370 }); 370 Stats::Time::TimeBlock("Resolve With Expressions", [&]() { 371 ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables 372 }); 371 if (!useNewAST) { 372 Stats::Time::TimeBlock("Resolve With Expressions", [&]() { 373 ResolvExpr::resolveWithExprs( translationUnit ); // must happen before FixObjectType because user-code is resolved and may contain with variables 374 }); 375 } 373 376 } 374 377 { 375 378 Stats::Heap::newPass("validate-F"); 376 379 Stats::Time::BlockGuard guard("validate-F"); 377 Stats::Time::TimeCall("Fix Object Type", 378 FixObjectType::fix, translationUnit); 380 if (!useNewAST) { 381 Stats::Time::TimeCall("Fix Object Type", 382 FixObjectType::fix, translationUnit); 383 } 379 384 Stats::Time::TimeCall("Array Length", 380 385 ArrayLength::computeLength, translationUnit); … … 383 388 Stats::Time::TimeCall("Fix Label Address", 384 389 mutateAll<LabelAddressFixer>, translationUnit, labelAddrFixer); 385 Stats::Time::TimeCall("Handle Attributes", 386 Validate::handleAttributes, translationUnit); 390 if (!useNewAST) { 391 Stats::Time::TimeCall("Handle Attributes", 392 Validate::handleAttributes, translationUnit); 393 } 387 394 } 388 395 } … … 1340 1347 1341 1348 void ArrayLength::previsit( ArrayType * type ) { 1342 if ( type->dimension ) { 1343 // need to resolve array dimensions early so that constructor code can correctly determine 1344 // if a type is a VLA (and hence whether its elements need to be constructed) 1345 ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer ); 1346 1347 // must re-evaluate whether a type is a VLA, now that more information is available 1348 // (e.g. the dimension may have been an enumerator, which was unknown prior to this step) 1349 type->isVarLen = ! InitTweak::isConstExpr( type->dimension ); 1349 if (!useNewAST) { 1350 if ( type->dimension ) { 1351 // need to resolve array dimensions early so that constructor code can correctly determine 1352 // if a type is a VLA (and hence whether its elements need to be constructed) 1353 ResolvExpr::findSingleExpression( type->dimension, Validate::SizeType->clone(), indexer ); 1354 1355 // must re-evaluate whether a type is a VLA, now that more information is available 1356 // (e.g. the dimension may have been an enumerator, which was unknown prior to this step) 1357 type->isVarLen = ! InitTweak::isConstExpr( type->dimension ); 1358 } 1350 1359 } 1351 1360 } -
tests/alloc.cfa
r82a2fed rb82d140 208 208 209 209 210 int const_count, dest_count; 210 211 struct Struct { int x; double y; }; 212 void ?{}( Struct & a ) { // construct 213 a.[ x, y ] = [ -1, -1.0 ]; 214 } 215 void ?{}( Struct & a, int x, double y ) { // initialize 216 a.[ x, y ] = [ x, y ]; 217 const_count++; 218 } 219 void ^?{}( Struct & a ) { dest_count++; } // destruct 211 220 Struct st, st1, sta[dim], sta1[dim], * stp, * stp1; 212 221 … … 329 338 printf( "\n" ); 330 339 340 const_count = dest_count = 0; 331 341 stp = new( 42, 42.5 ); 342 assert( const_count == 1 && dest_count == 0 ); // assertion for testing 332 343 stp1 = new( 42, 42.5 ); 344 assert( const_count == 2 && dest_count == 0 ); // assertion for testing 345 333 346 printf( "CFA new initialize\n%d %g %d %g\n", stp->x, stp->y, stp1->x, stp1->y ); 334 347 delete( stp, stp1 ); 348 assert( const_count == 2 && dest_count == 2 ); // assertion for testing 335 349 336 350 // new, array types 337 351 stp = anew( dim, 42, 42.5 ); 352 assert( const_count == 2 + dim && dest_count == 2 ); // assertion for testing 338 353 printf( "CFA array new initialize\n" ); 339 354 for ( i; dim ) { printf( "%d %g, ", stp[i].x, stp[i].y ); } 340 355 printf( "\n" ); 356 341 357 stp1 = anew( dim, 42, 42.5 ); 358 assert( const_count == 2 + 2 * dim && dest_count == 2 ); // assertion for testing 342 359 for ( i; dim ) { printf( "%d %g, ", stp1[i].x, stp1[i].y ); } 343 360 printf( "\n" ); 344 361 adelete( stp, stp1 ); 362 assert( const_count == 2 + 2 * dim && dest_count == 2 + 2 * dim); // assertion for testing 345 363 346 364 // extras … … 354 372 *ip = 0xdeadbeef; 355 373 printf( "CFA deep malloc %#x\n", *ip ); 356 free( ip ); 374 375 dp = alloc(5.0`fill); // just for testing multiple free 376 assert(*dp == 5.0); 377 free( ip, dp ); 357 378 358 379 #ifdef ERR1 -
tests/malloc.cfa
r82a2fed rb82d140 319 319 free(ip); 320 320 321 free( 0p ); // sanity check321 free( (void*) 0p ); // sanity check 322 322 free( NULL ); // sanity check 323 323
Note: See TracChangeset
for help on using the changeset viewer.