- Timestamp:
- Jul 12, 2019, 1:35:58 PM (5 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- fce4e31
- Parents:
- 7870799
- Location:
- src
- Files:
-
- 8 edited
Legend:
- Unmodified
- Added
- Removed
-
src/ResolvExpr/AdjustExprType.cc
r7870799 ref5b828 47 47 void premutate( OneType * ) { visit_children = false; } 48 48 49 Type * postmutate( ArrayType * arrayType );50 Type * postmutate( FunctionType * functionType );51 Type * postmutate( TypeInstType * aggregateUseType );49 Type * postmutate( ArrayType * arrayType ); 50 Type * postmutate( FunctionType * functionType ); 51 Type * postmutate( TypeInstType * aggregateUseType ); 52 52 53 53 private: … … 61 61 62 62 Type * AdjustExprType_old::postmutate( ArrayType * arrayType ) { 63 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base };63 PointerType * pointerType = new PointerType{ arrayType->get_qualifiers(), arrayType->base }; 64 64 arrayType->base = nullptr; 65 65 delete arrayType; … … 72 72 73 73 Type * AdjustExprType_old::postmutate( TypeInstType * typeInst ) { 74 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) {74 if ( const EqvClass * eqvClass = env.lookup( typeInst->get_name() ) ) { 75 75 if ( eqvClass->data.kind == TypeDecl::Ftype ) { 76 76 return new PointerType{ Type::Qualifiers(), typeInst }; 77 77 } 78 } else if ( NamedTypeDecl *ntDecl = indexer.lookupType( typeInst->get_name() ) ) {79 if ( TypeDecl *tyDecl = dynamic_cast< TypeDecl* >( ntDecl ) ) {78 } else if ( const NamedTypeDecl * ntDecl = indexer.lookupType( typeInst->get_name() ) ) { 79 if ( const TypeDecl * tyDecl = dynamic_cast< const TypeDecl * >( ntDecl ) ) { 80 80 if ( tyDecl->get_kind() == TypeDecl::Ftype ) { 81 81 return new PointerType{ Type::Qualifiers(), typeInst }; … … 89 89 void adjustExprType( Type *&type, const TypeEnvironment &env, const SymTab::Indexer &indexer ) { 90 90 PassVisitor<AdjustExprType_old> adjuster( env, indexer ); 91 Type * newType = type->acceptMutator( adjuster );91 Type * newType = type->acceptMutator( adjuster ); 92 92 type = newType; 93 93 } … … 148 148 } // anonymous namespace 149 149 150 const ast::Type * adjustExprType( 151 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 150 const ast::Type * adjustExprType( 151 const ast::Type * type, const ast::TypeEnvironment & env, const ast::SymbolTable & symtab 152 152 ) { 153 153 ast::Pass<AdjustExprType_new> adjuster{ env, symtab }; -
src/ResolvExpr/CastCost.cc
r7870799 ref5b828 37 37 struct CastCost_old : public ConversionCost { 38 38 public: 39 CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc );39 CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ); 40 40 41 41 using ConversionCost::previsit; … … 45 45 }; 46 46 47 Cost castCost( const Type * src, const Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) {48 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType* >( dest ) ) {49 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {47 Cost castCost( const Type * src, const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ) { 48 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 49 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 50 50 if ( eqvClass->type ) { 51 51 return castCost( src, eqvClass->type, indexer, env ); … … 53 53 return Cost::infinity; 54 54 } 55 } else if ( NamedTypeDecl *namedType = indexer.lookupType( destAsTypeInst->name ) ) {55 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 56 56 // all typedefs should be gone by this point 57 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType );57 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( namedType ); 58 58 if ( type->base ) { 59 59 return castCost( src, type->base, indexer, env ) + Cost::safe; … … 74 74 PRINT( std::cerr << "compatible!" << std::endl; ) 75 75 return Cost::zero; 76 } else if ( dynamic_cast< const VoidType * >( dest ) ) {76 } else if ( dynamic_cast< const VoidType * >( dest ) ) { 77 77 return Cost::safe; 78 78 } else if ( const ReferenceType * refType = dynamic_cast< const ReferenceType * > ( dest ) ) { … … 96 96 } 97 97 98 CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )98 CastCost_old::CastCost_old( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 99 99 : ConversionCost( dest, indexer, env, costFunc ) { 100 100 } 101 101 102 void CastCost_old::postvisit( const BasicType * basicType ) {103 const PointerType * destAsPointer = dynamic_cast< const PointerType* >( dest );102 void CastCost_old::postvisit( const BasicType * basicType ) { 103 const PointerType * destAsPointer = dynamic_cast< const PointerType * >( dest ); 104 104 if ( destAsPointer && basicType->isInteger() ) { 105 // necessary for, e.g. unsigned long => void *105 // necessary for, e.g. unsigned long => void * 106 106 cost = Cost::unsafe; 107 107 } else { … … 110 110 } 111 111 112 void CastCost_old::postvisit( const PointerType * pointerType ) {113 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType* >( dest ) ) {112 void CastCost_old::postvisit( const PointerType * pointerType ) { 113 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 114 114 if ( pointerType->tq <= destAsPtr->tq && typesCompatibleIgnoreQualifiers( pointerType->base, destAsPtr->base, indexer, env ) ) { 115 115 cost = Cost::safe; … … 127 127 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 128 128 if ( destAsBasic->isInteger() ) { 129 // necessary for, e.g. void * => unsigned long129 // necessary for, e.g. void * => unsigned long 130 130 cost = Cost::unsafe; 131 131 } // if -
src/ResolvExpr/CommonType.cc
r7870799 ref5b828 38 38 namespace ResolvExpr { 39 39 struct CommonType_old : public WithShortCircuiting { 40 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars );41 Type * get_result() const { return result; }40 CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 41 Type * get_result() const { return result; } 42 42 43 43 void previsit( BaseSyntaxNode * ) { visit_children = false; } … … 60 60 61 61 private: 62 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer* otherPointer );63 template< typename RefType > void handleRefType( RefType * inst, Type *other );64 65 Type * result;66 Type * type2; // inherited62 template< typename Pointer > void getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ); 63 template< typename RefType > void handleRefType( RefType * inst, Type * other ); 64 65 Type * result; 66 Type * type2; // inherited 67 67 bool widenFirst, widenSecond; 68 68 const SymTab::Indexer &indexer; … … 80 80 std::cerr << "unify success: " << widenFirst << " " << widenSecond << std::endl; 81 81 ) 82 if ( (widenFirst || t2-> get_qualifiers() <= t1->get_qualifiers()) && (widenSecond || t1->get_qualifiers() <= t2->get_qualifiers()) ) {82 if ( (widenFirst || t2->tq <= t1->tq) && (widenSecond || t1->tq <= t2->tq) ) { 83 83 PRINT( 84 84 std::cerr << "widen okay" << std::endl; 85 85 ) 86 common-> get_qualifiers() |= t1->get_qualifiers();87 common-> get_qualifiers() |= t2->get_qualifiers();86 common->tq |= t1->tq; 87 common->tq |= t2->tq; 88 88 return common; 89 89 } … … 95 95 } 96 96 97 Type * commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) {97 Type * commonType( Type * type1, Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 98 98 PassVisitor<CommonType_old> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 99 99 … … 127 127 std::cerr << "formal is reference; result should be reference" << std::endl; 128 128 ) 129 result = new ReferenceType( ref1-> get_qualifiers(), result );129 result = new ReferenceType( ref1->tq, result ); 130 130 } 131 131 PRINT( … … 138 138 139 139 type1->accept( visitor ); 140 Type * result = visitor.pass.get_result();140 Type * result = visitor.pass.get_result(); 141 141 if ( ! result ) { 142 142 // this appears to be handling for opaque type declarations 143 143 if ( widenSecond ) { 144 if ( TypeInstType *inst = dynamic_cast< TypeInstType* >( type2 ) ) {145 if ( NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ) ) {146 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );144 if ( const TypeInstType * inst = dynamic_cast< const TypeInstType * >( type2 ) ) { 145 if ( const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ) ) { 146 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 147 147 if ( type->get_base() ) { 148 Type::Qualifiers tq1 = type1-> get_qualifiers(), tq2 = type2->get_qualifiers();148 Type::Qualifiers tq1 = type1->tq, tq2 = type2->tq; 149 149 AssertionSet have, need; 150 150 OpenVarSet newOpen( openVars ); 151 type1-> get_qualifiers()= Type::Qualifiers();152 type->get_base()-> get_qualifiers()= tq1;151 type1->tq = Type::Qualifiers(); 152 type->get_base()->tq = tq1; 153 153 if ( unifyExact( type1, type->get_base(), env, have, need, newOpen, indexer ) ) { 154 154 result = type1->clone(); 155 result-> get_qualifiers()= tq1 | tq2;155 result->tq = tq1 | tq2; 156 156 } // if 157 type1-> get_qualifiers()= tq1;158 type->get_base()-> get_qualifiers()= Type::Qualifiers();157 type1->tq = tq1; 158 type->get_base()->tq = Type::Qualifiers(); 159 159 } // if 160 160 } // if … … 190 190 */ 191 191 { 192 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,192 /* B */ BT Bool, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 193 193 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 194 194 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 198 198 }, 199 199 { 200 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,200 /* C */ BT Char, BT Char, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 201 201 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 202 202 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 206 206 }, 207 207 { 208 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,208 /* SC */ BT SignedChar, BT SignedChar, BT SignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 209 209 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 210 210 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 214 214 }, 215 215 { 216 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt,216 /* UC */ BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT UnsignedChar, BT ShortSignedInt, BT ShortUnsignedInt, 217 217 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 218 218 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 222 222 }, 223 223 { 224 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt,224 /* SI */ BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortSignedInt, BT ShortUnsignedInt, 225 225 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 226 226 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 230 230 }, 231 231 { 232 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt,232 /* SUI */ BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, BT ShortUnsignedInt, 233 233 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 234 234 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 238 238 }, 239 239 { 240 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt,240 /* I */ BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, BT SignedInt, 241 241 BT SignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 242 242 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 246 246 }, 247 247 { 248 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt,248 /* UI */ BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, BT UnsignedInt, 249 249 BT UnsignedInt, BT UnsignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 250 250 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 254 254 }, 255 255 { 256 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt,256 /* LI */ BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, 257 257 BT LongSignedInt, BT LongSignedInt, BT LongSignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 258 258 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 262 262 }, 263 263 { 264 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt,264 /* LUI */ BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, 265 265 BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongUnsignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 266 266 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 270 270 }, 271 271 { 272 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt,272 /* LLI */ BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, 273 273 BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongSignedInt, BT LongLongUnsignedInt, 274 274 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 278 278 }, 279 279 { 280 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt,280 /* LLUI */ BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 281 281 BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, BT LongLongUnsignedInt, 282 282 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 286 286 }, 287 287 { 288 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128,288 /* IB */ BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 289 289 BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, BT SignedInt128, 290 290 BT SignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 294 294 }, 295 295 { 296 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128,296 /* UIB */ BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 297 297 BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, BT UnsignedInt128, 298 298 BT UnsignedInt128, BT UnsignedInt128, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 302 302 }, 303 303 { 304 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16,304 /* _FH */ BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 305 305 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16, 306 306 BT uFloat16, BT uFloat16, BT uFloat16, BT uFloat16Complex, BT uFloat32, BT uFloat32Complex, … … 310 310 }, 311 311 { 312 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex,312 /* _FH */ BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 313 313 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, 314 314 BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat16Complex, BT uFloat32Complex, BT uFloat32Complex, … … 318 318 }, 319 319 { 320 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32,320 /* _F */ BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 321 321 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32, 322 322 BT uFloat32, BT uFloat32, BT uFloat32, BT uFloat32Complex, BT uFloat32, BT uFloat32Complex, … … 326 326 }, 327 327 { 328 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex,328 /* _FC */ BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 329 329 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, 330 330 BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, BT uFloat32Complex, … … 334 334 }, 335 335 { 336 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float,336 /* F */ BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 337 337 BT Float, BT Float, BT Float, BT Float, BT Float, BT Float, 338 338 BT Float, BT Float, BT Float, BT FloatComplex, BT Float, BT FloatComplex, … … 342 342 }, 343 343 { 344 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex,344 /* FC */ BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 345 345 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, 346 346 BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, BT FloatComplex, … … 350 350 }, 351 351 { 352 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x,352 /* _FX */ BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 353 353 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32x, 354 354 BT uFloat32x, BT uFloat32x, BT uFloat32x, BT uFloat32xComplex, BT uFloat32x, BT uFloat32xComplex, … … 358 358 }, 359 359 { 360 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex,360 /* _FXC */ BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 361 361 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, 362 362 BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, BT uFloat32xComplex, … … 366 366 }, 367 367 { 368 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64,368 /* FD */ BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 369 369 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64, 370 370 BT uFloat64, BT uFloat64, BT uFloat64, BT uFloat64Complex, BT uFloat64, BT uFloat64Complex, … … 374 374 }, 375 375 { 376 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex,376 /* _FDC */ BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 377 377 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, 378 378 BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, BT uFloat64Complex, … … 382 382 }, 383 383 { 384 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double,384 /* D */ BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 385 385 BT Double, BT Double, BT Double, BT Double, BT Double, BT Double, 386 386 BT Double, BT Double, BT Double, BT DoubleComplex, BT Double, BT DoubleComplex, … … 390 390 }, 391 391 { 392 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex,392 /* DC */ BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 393 393 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, 394 394 BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, BT DoubleComplex, … … 398 398 }, 399 399 { 400 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x,400 /* F80X */ BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 401 401 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64x, 402 402 BT uFloat64x, BT uFloat64x, BT uFloat64x, BT uFloat64xComplex, BT uFloat64x, BT uFloat64xComplex, … … 406 406 }, 407 407 { 408 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex,408 /* _FDXC */ BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 409 409 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, 410 410 BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, BT uFloat64xComplex, … … 422 422 }, 423 423 { 424 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128,424 /* _FB */ BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 425 425 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128, 426 426 BT uFloat128, BT uFloat128, BT uFloat128, BT uFloat128Complex, BT uFloat128, BT uFloat128Complex, … … 430 430 }, 431 431 { 432 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex,432 /* _FLDC */ BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 433 433 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, 434 434 BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, BT uFloat128Complex, … … 438 438 }, 439 439 { 440 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128,440 /* FB */ BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 441 441 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uuFloat128, 442 442 BT uuFloat128, BT uuFloat128, BT uuFloat128, BT uFloat128Complex, BT uuFloat128, BT uFloat128Complex, … … 446 446 }, 447 447 { 448 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble,448 /* LD */ BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 449 449 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, BT LongDouble, 450 450 BT LongDouble, BT LongDouble, BT LongDouble, BT LongDoubleComplex, BT LongDouble, BT LongDoubleComplex, … … 454 454 }, 455 455 { 456 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex,456 /* LDC */ BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 457 457 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, 458 458 BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, BT LongDoubleComplex, … … 462 462 }, 463 463 { 464 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x,464 /* _FBX */ BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 465 465 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128x, 466 466 BT uFloat128x, BT uFloat128x, BT uFloat128x, BT uFloat128xComplex, BT uFloat128x, BT uFloat128xComplex, … … 470 470 }, 471 471 { 472 /* _FLDXC*/ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex,472 /* _FLDXC */ BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 473 473 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, 474 474 BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, BT uFloat128xComplex, … … 481 481 // GENERATED END 482 482 static_assert( 483 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,483 sizeof(commonTypes)/sizeof(commonTypes[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 484 484 "Each basic type kind should have a corresponding row in the combined type matrix" 485 485 ); 486 486 487 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars )487 CommonType_old::CommonType_old( Type * type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) 488 488 : result( 0 ), type2( type2 ), widenFirst( widenFirst ), widenSecond( widenSecond ), indexer( indexer ), env( env ), openVars( openVars ) { 489 489 } … … 491 491 void CommonType_old::postvisit( VoidType * ) {} 492 492 493 void CommonType_old::postvisit( BasicType * basicType ) {494 if ( BasicType * otherBasic = dynamic_cast< BasicType* >( type2 ) ) {493 void CommonType_old::postvisit( BasicType * basicType ) { 494 if ( BasicType * otherBasic = dynamic_cast< BasicType * >( type2 ) ) { 495 495 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ otherBasic->get_kind() ]; 496 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= otherBasic->get_qualifiers() ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->get_qualifiers() <= otherBasic->get_qualifiers()) || widenSecond ) ) {497 result = new BasicType( basicType-> get_qualifiers() | otherBasic->get_qualifiers(), newType );496 if ( ( ( newType == basicType->get_kind() && basicType->tq >= otherBasic->tq ) || widenFirst ) && ( ( newType == otherBasic->get_kind() && basicType->tq <= otherBasic->tq ) || widenSecond ) ) { 497 result = new BasicType( basicType->tq | otherBasic->tq, newType ); 498 498 } // if 499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {499 } else if ( dynamic_cast< EnumInstType * > ( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 500 500 // use signed int in lieu of the enum/zero/one type 501 501 BasicType::Kind newType = commonTypes[ basicType->get_kind() ][ BasicType::SignedInt ]; 502 if ( ( ( newType == basicType->get_kind() && basicType-> get_qualifiers() >= type2->get_qualifiers() ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->get_qualifiers() <= type2->get_qualifiers()) || widenSecond ) ) {503 result = new BasicType( basicType-> get_qualifiers() | type2->get_qualifiers(), newType );502 if ( ( ( newType == basicType->get_kind() && basicType->tq >= type2->tq ) || widenFirst ) && ( ( newType != basicType->get_kind() && basicType->tq <= type2->tq ) || widenSecond ) ) { 503 result = new BasicType( basicType->tq | type2->tq, newType ); 504 504 } // if 505 505 } // if … … 507 507 508 508 template< typename Pointer > 509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer* otherPointer ) {510 if ( TypeInstType * var = dynamic_cast< TypeInstType* >( otherPointer->get_base() ) ) {509 void CommonType_old::getCommonWithVoidPointer( Pointer * voidPointer, Pointer * otherPointer ) { 510 if ( TypeInstType * var = dynamic_cast< TypeInstType * >( otherPointer->get_base() ) ) { 511 511 OpenVarSet::const_iterator entry = openVars.find( var->get_name() ); 512 512 if ( entry != openVars.end() ) { … … 517 517 } 518 518 result = voidPointer->clone(); 519 result-> get_qualifiers() |= otherPointer->get_qualifiers();520 } 521 522 void CommonType_old::postvisit( PointerType * pointerType ) {523 if ( PointerType * otherPointer = dynamic_cast< PointerType* >( type2 ) ) {519 result->tq |= otherPointer->tq; 520 } 521 522 void CommonType_old::postvisit( PointerType * pointerType ) { 523 if ( PointerType * otherPointer = dynamic_cast< PointerType * >( type2 ) ) { 524 524 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl; 525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) {525 if ( widenFirst && dynamic_cast< VoidType * >( otherPointer->get_base() ) && ! isFtype(pointerType->get_base()) ) { 526 526 getCommonWithVoidPointer( otherPointer, pointerType ); 527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) {527 } else if ( widenSecond && dynamic_cast< VoidType * >( pointerType->get_base() ) && ! isFtype(otherPointer->get_base()) ) { 528 528 getCommonWithVoidPointer( pointerType, otherPointer ); 529 } else if ( ( pointerType->get_base()-> get_qualifiers() >= otherPointer->get_base()->get_qualifiers()|| widenFirst )530 && ( pointerType->get_base()-> get_qualifiers() <= otherPointer->get_base()->get_qualifiers()|| widenSecond ) ) {529 } else if ( ( pointerType->get_base()->tq >= otherPointer->get_base()->tq || widenFirst ) 530 && ( pointerType->get_base()->tq <= otherPointer->get_base()->tq || widenSecond ) ) { 531 531 // std::cerr << "middle case" << std::endl; 532 Type::Qualifiers tq1 = pointerType->get_base()-> get_qualifiers(), tq2 = otherPointer->get_base()->get_qualifiers();533 pointerType->get_base()-> get_qualifiers()= Type::Qualifiers();534 otherPointer->get_base()-> get_qualifiers()= Type::Qualifiers();532 Type::Qualifiers tq1 = pointerType->get_base()->tq, tq2 = otherPointer->get_base()->tq; 533 pointerType->get_base()->tq = Type::Qualifiers(); 534 otherPointer->get_base()->tq = Type::Qualifiers(); 535 535 AssertionSet have, need; 536 536 OpenVarSet newOpen( openVars ); … … 542 542 result = otherPointer->clone(); 543 543 } // if 544 strict_dynamic_cast<PointerType *>(result)->base->get_qualifiers()= tq1 | tq2;544 strict_dynamic_cast<PointerType *>(result)->base->tq = tq1 | tq2; 545 545 } else { 546 546 /// std::cerr << "place for ptr-to-type" << std::endl; 547 547 } // if 548 pointerType->get_base()-> get_qualifiers()= tq1;549 otherPointer->get_base()-> get_qualifiers()= tq2;548 pointerType->get_base()->tq = tq1; 549 otherPointer->get_base()->tq = tq2; 550 550 } // if 551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {551 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 552 552 result = pointerType->clone(); 553 result-> get_qualifiers() |= type2->get_qualifiers();553 result->tq |= type2->tq; 554 554 } // if 555 555 } … … 557 557 void CommonType_old::postvisit( ArrayType * ) {} 558 558 559 void CommonType_old::postvisit( ReferenceType * refType ) {560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType* >( type2 ) ) {559 void CommonType_old::postvisit( ReferenceType * refType ) { 560 if ( ReferenceType * otherRef = dynamic_cast< ReferenceType * >( type2 ) ) { 561 561 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl; 562 // std::cerr << ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers() || widenFirst ) << (refType->get_base()->get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond) << std::endl;563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) {562 // std::cerr << ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) << (refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond) << std::endl; 563 if ( widenFirst && dynamic_cast< VoidType * >( otherRef->get_base() ) && ! isFtype(refType->get_base()) ) { 564 564 getCommonWithVoidPointer( otherRef, refType ); 565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) {565 } else if ( widenSecond && dynamic_cast< VoidType * >( refType->get_base() ) && ! isFtype(otherRef->get_base()) ) { 566 566 getCommonWithVoidPointer( refType, otherRef ); 567 } else if ( ( refType->get_base()-> get_qualifiers() >= otherRef->get_base()->get_qualifiers()|| widenFirst )568 && ( refType->get_base()-> get_qualifiers() <= otherRef->get_base()->get_qualifiers()|| widenSecond ) ) {567 } else if ( ( refType->get_base()->tq >= otherRef->get_base()->tq || widenFirst ) 568 && ( refType->get_base()->tq <= otherRef->get_base()->tq || widenSecond ) ) { 569 569 // std::cerr << "middle case" << std::endl; 570 Type::Qualifiers tq1 = refType->get_base()-> get_qualifiers(), tq2 = otherRef->get_base()->get_qualifiers();571 refType->get_base()-> get_qualifiers()= Type::Qualifiers();572 otherRef->get_base()-> get_qualifiers()= Type::Qualifiers();570 Type::Qualifiers tq1 = refType->get_base()->tq, tq2 = otherRef->get_base()->tq; 571 refType->get_base()->tq = Type::Qualifiers(); 572 otherRef->get_base()->tq = Type::Qualifiers(); 573 573 AssertionSet have, need; 574 574 OpenVarSet newOpen( openVars ); … … 579 579 result = otherRef->clone(); 580 580 } // if 581 strict_dynamic_cast<ReferenceType *>(result)->base->get_qualifiers()= tq1 | tq2;581 strict_dynamic_cast<ReferenceType *>(result)->base->tq = tq1 | tq2; 582 582 } else { 583 583 /// std::cerr << "place for ptr-to-type" << std::endl; 584 584 } // if 585 refType->get_base()-> get_qualifiers()= tq1;586 otherRef->get_base()-> get_qualifiers()= tq2;585 refType->get_base()->tq = tq1; 586 otherRef->get_base()->tq = tq2; 587 587 } // if 588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {588 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 589 589 result = refType->clone(); 590 result-> get_qualifiers() |= type2->get_qualifiers();590 result->tq |= type2->tq; 591 591 } // if 592 592 } … … 596 596 void CommonType_old::postvisit( UnionInstType * ) {} 597 597 598 void CommonType_old::postvisit( EnumInstType * enumInstType ) {599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType* >( type2 ) ) {598 void CommonType_old::postvisit( EnumInstType * enumInstType ) { 599 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType * >( type2 ) || dynamic_cast< OneType * >( type2 ) ) { 600 600 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 601 601 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); … … 606 606 } 607 607 608 void CommonType_old::postvisit( TypeInstType * inst ) {608 void CommonType_old::postvisit( TypeInstType * inst ) { 609 609 if ( widenFirst ) { 610 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() );610 const NamedTypeDecl * nt = indexer.lookupType( inst->get_name() ); 611 611 if ( nt ) { 612 TypeDecl *type = strict_dynamic_cast< TypeDecl* >( nt );612 const TypeDecl * type = strict_dynamic_cast< const TypeDecl * >( nt ); 613 613 if ( type->get_base() ) { 614 Type::Qualifiers tq1 = inst-> get_qualifiers(), tq2 = type2->get_qualifiers();614 Type::Qualifiers tq1 = inst->tq, tq2 = type2->tq; 615 615 AssertionSet have, need; 616 616 OpenVarSet newOpen( openVars ); 617 type2-> get_qualifiers()= Type::Qualifiers();618 type->get_base()-> get_qualifiers()= tq1;617 type2->tq = Type::Qualifiers(); 618 type->get_base()->tq = tq1; 619 619 if ( unifyExact( type->get_base(), type2, env, have, need, newOpen, indexer ) ) { 620 620 result = type2->clone(); 621 result-> get_qualifiers()= tq1 | tq2;621 result->tq = tq1 | tq2; 622 622 } // if 623 type2-> get_qualifiers()= tq2;624 type->get_base()-> get_qualifiers()= Type::Qualifiers();623 type2->tq = tq2; 624 type->get_base()->tq = Type::Qualifiers(); 625 625 } // if 626 626 } // if … … 631 631 void CommonType_old::postvisit( VarArgsType * ) {} 632 632 633 void CommonType_old::postvisit( ZeroType * zeroType ) {633 void CommonType_old::postvisit( ZeroType * zeroType ) { 634 634 if ( widenFirst ) { 635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {636 if ( widenSecond || zeroType-> get_qualifiers() <= type2->get_qualifiers()) {635 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< PointerType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 636 if ( widenSecond || zeroType->tq <= type2->tq ) { 637 637 result = type2->clone(); 638 result-> get_qualifiers() |= zeroType->get_qualifiers();639 } 640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) {641 result = new BasicType( zeroType-> get_qualifiers(), BasicType::SignedInt );642 result-> get_qualifiers() |= type2->get_qualifiers();643 } 644 } 645 } 646 647 void CommonType_old::postvisit( OneType * oneType ) {638 result->tq |= zeroType->tq; 639 } 640 } else if ( widenSecond && dynamic_cast< OneType * >( type2 ) ) { 641 result = new BasicType( zeroType->tq, BasicType::SignedInt ); 642 result->tq |= type2->tq; 643 } 644 } 645 } 646 647 void CommonType_old::postvisit( OneType * oneType ) { 648 648 if ( widenFirst ) { 649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) {650 if ( widenSecond || oneType-> get_qualifiers() <= type2->get_qualifiers()) {649 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< EnumInstType * >( type2 ) ) { 650 if ( widenSecond || oneType->tq <= type2->tq ) { 651 651 result = type2->clone(); 652 result-> get_qualifiers() |= oneType->get_qualifiers();653 } 654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) {655 result = new BasicType( oneType-> get_qualifiers(), BasicType::SignedInt );656 result-> get_qualifiers() |= type2->get_qualifiers();652 result->tq |= oneType->tq; 653 } 654 } else if ( widenSecond && dynamic_cast< ZeroType * >( type2 ) ) { 655 result = new BasicType( oneType->tq, BasicType::SignedInt ); 656 result->tq |= type2->tq; 657 657 } 658 658 } … … 668 668 ast::ptr< ast::Type > result; 669 669 670 CommonType_new( 671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 670 CommonType_new( 671 const ast::Type * t2, WidenMode w, const ast::SymbolTable & st, 672 672 ast::TypeEnvironment & env, const ast::OpenVarSet & o ) 673 673 : type2( t2 ), widen( w ), symtab( st ), tenv( env ), open( o ), result() {} … … 681 681 #warning remove casts when `commonTypes` moved to new AST 682 682 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)basic2->kind ]; 683 if ( 684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 685 || widen.first ) 686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 687 || widen.second ) 683 if ( 684 ( ( kind == basic->kind && basic->qualifiers >= basic2->qualifiers ) 685 || widen.first ) 686 && ( ( kind == basic2->kind && basic->qualifiers <= basic2->qualifiers ) 687 || widen.second ) 688 688 ) { 689 689 result = new ast::BasicType{ kind, basic->qualifiers | basic2->qualifiers }; 690 690 } 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 691 } else if ( 692 dynamic_cast< const ast::EnumInstType * >( type2 ) 693 693 || dynamic_cast< const ast::ZeroType * >( type2 ) 694 694 || dynamic_cast< const ast::OneType * >( type2 ) … … 696 696 #warning remove casts when `commonTypes` moved to new AST 697 697 ast::BasicType::Kind kind = (ast::BasicType::Kind)(int)commonTypes[ (BasicType::Kind)(int)basic->kind ][ (BasicType::Kind)(int)ast::BasicType::SignedInt ]; 698 if ( 699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 700 || widen.first ) 701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 702 || widen.second ) 698 if ( 699 ( ( kind == basic->kind && basic->qualifiers >= type2->qualifiers ) 700 || widen.first ) 701 && ( ( kind != basic->kind && basic->qualifiers <= type2->qualifiers ) 702 || widen.second ) 703 703 ) { 704 704 result = new ast::BasicType{ kind, basic->qualifiers | type2->qualifiers }; … … 715 715 if ( entry != open.end() ) { 716 716 ast::AssertionSet need, have; 717 if ( ! tenv.bindVar( 718 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 717 if ( ! tenv.bindVar( 718 var, voidPtr->base, entry->second, need, have, open, widen, symtab ) 719 719 ) return; 720 720 } … … 727 727 void postvisit( const ast::PointerType * pointer ) { 728 728 if ( auto pointer2 = dynamic_cast< const ast::PointerType * >( type2 ) ) { 729 if ( 730 widen.first 731 && pointer2->base.as< ast::VoidType >() 732 && ! ast::isFtype( pointer->base ) 729 if ( 730 widen.first 731 && pointer2->base.as< ast::VoidType >() 732 && ! ast::isFtype( pointer->base ) 733 733 ) { 734 734 getCommonWithVoidPointer( pointer2, pointer ); 735 } else if ( 736 widen.second 737 && pointer->base.as< ast::VoidType >() 738 && ! ast::isFtype( pointer2->base ) 735 } else if ( 736 widen.second 737 && pointer->base.as< ast::VoidType >() 738 && ! ast::isFtype( pointer2->base ) 739 739 ) { 740 740 getCommonWithVoidPointer( pointer, pointer2 ); … … 746 746 ast::CV::Qualifiers q2 = pointer2->base->qualifiers; 747 747 748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 748 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 749 749 // pointer{,2}->base are unchanged 750 750 ast::ptr< ast::Type > t1{ pointer->base }, t2{ pointer2->base }; 751 751 reset_qualifiers( t1 ); 752 752 reset_qualifiers( t2 ); 753 753 754 754 ast::AssertionSet have, need; 755 755 ast::OpenVarSet newOpen{ open }; … … 758 758 if ( q1.val != q2.val ) { 759 759 // reset result->base->qualifiers to be union of two base qualifiers 760 strict_dynamic_cast< ast::PointerType * >( 761 result.get_and_mutate() 760 strict_dynamic_cast< ast::PointerType * >( 761 result.get_and_mutate() 762 762 )->base.get_and_mutate()->qualifiers = q1 | q2; 763 763 } … … 775 775 if ( auto ref2 = dynamic_cast< const ast::ReferenceType * >( type2 ) ) { 776 776 if ( 777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 777 widen.first && ref2->base.as< ast::VoidType >() && ! ast::isFtype( ref->base ) 778 778 ) { 779 779 getCommonWithVoidPointer( ref2, ref ); 780 } else if ( 781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 780 } else if ( 781 widen.second && ref->base.as< ast::VoidType>() && ! ast::isFtype( ref2->base ) 782 782 ) { 783 783 getCommonWithVoidPointer( ref, ref2 ); … … 788 788 ast::CV::Qualifiers q1 = ref->base->qualifiers, q2 = ref2->base->qualifiers; 789 789 790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 790 // force t{1,2} to be cloned if their qualifiers must be stripped, so that 791 791 // ref{,2}->base are unchanged 792 792 ast::ptr< ast::Type > t1{ ref->base }, t2{ ref2->base }; … … 800 800 if ( q1.val != q2.val ) { 801 801 // reset result->base->qualifiers to be union of two base qualifiers 802 strict_dynamic_cast< ast::ReferenceType * >( 803 result.get_and_mutate() 802 strict_dynamic_cast< ast::ReferenceType * >( 803 result.get_and_mutate() 804 804 )->base.get_and_mutate()->qualifiers = q1 | q2; 805 805 } … … 819 819 820 820 void postvisit( const ast::EnumInstType * enumInst ) { 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 821 if ( 822 dynamic_cast< const ast::BasicType * >( type2 ) 823 823 || dynamic_cast< const ast::ZeroType * >( type2 ) 824 824 || dynamic_cast< const ast::OneType * >( type2 ) … … 834 834 if ( ! widen.first ) return; 835 835 if ( const ast::NamedTypeDecl * nt = symtab.lookupType( inst->name ) ) { 836 if ( const ast::Type * base = 837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 836 if ( const ast::Type * base = 837 strict_dynamic_cast< const ast::TypeDecl * >( nt )->base 838 838 ) { 839 839 ast::CV::Qualifiers q1 = inst->qualifiers, q2 = type2->qualifiers; … … 860 860 void postvisit( const ast::ZeroType * zero ) { 861 861 if ( ! widen.first ) return; 862 if ( 862 if ( 863 863 dynamic_cast< const ast::BasicType * >( type2 ) 864 864 || dynamic_cast< const ast::PointerType * >( type2 ) … … 870 870 } 871 871 } else if ( widen.second && dynamic_cast< const ast::OneType * >( type2 ) ) { 872 result = new ast::BasicType{ 872 result = new ast::BasicType{ 873 873 ast::BasicType::SignedInt, zero->qualifiers | type2->qualifiers }; 874 874 } … … 877 877 void postvisit( const ast::OneType * one ) { 878 878 if ( ! widen.first ) return; 879 if ( 879 if ( 880 880 dynamic_cast< const ast::BasicType * >( type2 ) 881 881 || dynamic_cast< const ast::EnumInstType * >( type2 ) … … 886 886 } 887 887 } else if ( widen.second && dynamic_cast< const ast::ZeroType * >( type2 ) ) { 888 result = new ast::BasicType{ 888 result = new ast::BasicType{ 889 889 ast::BasicType::SignedInt, one->qualifiers | type2->qualifiers }; 890 890 } … … 894 894 895 895 namespace { 896 ast::ptr< ast::Type > handleReference( 897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 899 const ast::OpenVarSet & open 896 ast::ptr< ast::Type > handleReference( 897 const ast::ptr< ast::Type > & t1, const ast::ptr< ast::Type > & t2, WidenMode widen, 898 const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 899 const ast::OpenVarSet & open 900 900 ) { 901 901 ast::ptr<ast::Type> common; … … 926 926 927 927 ast::ptr< ast::Type > commonType( 928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 930 const ast::OpenVarSet & open 928 const ast::ptr< ast::Type > & type1, const ast::ptr< ast::Type > & type2, 929 WidenMode widen, const ast::SymbolTable & symtab, ast::TypeEnvironment & env, 930 const ast::OpenVarSet & open 931 931 ) { 932 932 unsigned depth1 = type1->referenceDepth(); … … 940 940 const ast::ReferenceType * ref1 = type1.as< ast::ReferenceType >(); 941 941 const ast::ReferenceType * ref2 = type1.as< ast::ReferenceType >(); 942 942 943 943 if ( depth1 > depth2 ) { 944 944 assert( ref1 ); … … 978 978 ast::OpenVarSet newOpen{ open }; 979 979 980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 981 // type1 and type->base are left unchanged; calling convention forces 980 // force t{1,2} to be cloned if its qualifiers must be stripped, so that 981 // type1 and type->base are left unchanged; calling convention forces 982 982 // {type1,type->base}->strong_ref >= 1 983 983 ast::ptr<ast::Type> t1{ type1 }, t2{ type->base }; 984 984 reset_qualifiers( t1 ); 985 985 reset_qualifiers( t2, q1 ); 986 986 987 987 if ( unifyExact( t1, t2, env, have, need, newOpen, noWiden(), symtab ) ) { 988 988 result = t1; -
src/ResolvExpr/ConversionCost.cc
r7870799 ref5b828 49 49 if ( const TypeInstType * destAsTypeInst = dynamic_cast< const TypeInstType * >( dest ) ) { 50 50 PRINT( std::cerr << "type inst " << destAsTypeInst->name; ) 51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) {51 if ( const EqvClass * eqvClass = env.lookup( destAsTypeInst->name ) ) { 52 52 if ( eqvClass->type ) { 53 53 return conversionCost( src, eqvClass->type, indexer, env ); … … 57 57 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( destAsTypeInst->name ) ) { 58 58 PRINT( std::cerr << " found" << std::endl; ) 59 const TypeDecl * type = dynamic_cast< const TypeDecl* >( namedType );59 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 60 60 // all typedefs should be gone by this point 61 61 assert( type ); … … 87 87 PassVisitor<ConversionCost> converter( 88 88 dest, indexer, env, 89 (Cost (*)(const Type *, const Type*, const SymTab::Indexer&, const TypeEnvironment&))89 (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&)) 90 90 conversionCost ); 91 91 src->accept( converter ); … … 139 139 PassVisitor<ConversionCost> converter( 140 140 dest, indexer, env, 141 (Cost (*)(const Type *, const Type*, const SymTab::Indexer&, const TypeEnvironment&))141 (Cost (*)(const Type *, const Type *, const SymTab::Indexer&, const TypeEnvironment&)) 142 142 conversionCost ); 143 143 src->accept( converter ); … … 185 185 } 186 186 187 ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc )187 ConversionCost::ConversionCost( const Type * dest, const SymTab::Indexer &indexer, const TypeEnvironment &env, CostFunction costFunc ) 188 188 : dest( dest ), indexer( indexer ), cost( Cost::infinity ), env( env ), costFunc( costFunc ) { 189 189 } … … 218 218 static const int costMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // path length from root to node 219 219 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 220 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, },221 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },222 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },223 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, },224 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, },225 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, },226 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, },227 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, },228 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, },229 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, },230 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, },231 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, },232 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, },233 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, },234 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, },235 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, },236 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, },237 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, },238 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, },239 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, },240 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, },241 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, },242 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, },243 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, },244 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, },245 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, },246 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 3, 5, 4, },247 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, 3, },220 /* B */ { 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 15, 16, 17, 16, 18, 17, }, 221 /* C */ { -1, 0, 1, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 222 /* SC */ { -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 223 /* UC */ { -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 14, 15, 16, 15, 17, 16, }, 224 /* SI */ { -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 225 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 13, 14, 15, 14, 16, 15, }, 226 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 227 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 12, 13, 14, 13, 15, 14, }, 228 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 229 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 11, 12, 13, 12, 14, 13, }, 230 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 231 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 10, 11, 12, 11, 13, 12, }, 232 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 233 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 9, 10, 11, 10, 12, 11, }, 234 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 8, 9, 10, 9, 11, 10, }, 235 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, 6, -1, -1, 7, -1, -1, 8, -1, 9, }, 236 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 7, 8, 9, 8, 10, 9, }, 237 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, 5, -1, -1, 6, -1, -1, 7, -1, 8, }, 238 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 6, 7, 8, 7, 9, 8, }, 239 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, 4, -1, -1, 5, -1, -1, 6, -1, 7, }, 240 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 5, 6, 7, 6, 8, 7, }, 241 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, 3, -1, -1, 4, -1, -1, 5, -1, 6, }, 242 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 4, 5, 6, 5, 7, 6, }, 243 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, 2, -1, -1, 3, -1, -1, 4, -1, 5, }, 244 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, 4, 5, 4, 6, 5, }, 245 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, -1, -1, 2, -1, -1, 3, -1, 4, }, 246 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 4, 3, 5, 4, }, 247 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, -1, 2, -1, 3, }, 248 248 /* F80*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, 3, 4, 4, }, 249 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, },250 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, },251 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, },252 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, },253 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, },254 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, },255 /* _FLDXC*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, },249 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, 2, 3, 3, }, 250 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 1, -1, 2, }, 251 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 1, 0, 1, 2, 2, 3, }, 252 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 1, 2, }, 253 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 1, }, 254 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, }, 255 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 256 256 }; // costMatrix 257 257 static const int maxIntCost = 15; 258 258 // GENERATED END 259 259 static_assert( 260 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,260 sizeof(costMatrix)/sizeof(costMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 261 261 "Missing row in the cost matrix" 262 262 ); … … 266 266 static const int signMatrix[BasicType::NUMBER_OF_BASIC_TYPES][BasicType::NUMBER_OF_BASIC_TYPES] = { // number of sign changes in safe conversion 267 267 /* B C SC UC SI SUI I UI LI LUI LLI LLUI IB UIB _FH _FH _F _FC F FC _FX _FXC FD _FDC D DC F80X_FDXC F80 _FB_FLDC FB LD LDC _FBX_FLDXC */ 268 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },269 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },270 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },271 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },272 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },273 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },274 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },275 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },276 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },277 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },278 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },279 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },280 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },281 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },282 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },283 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },284 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },285 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },286 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },287 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },288 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },289 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },290 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },291 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },292 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },293 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },294 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, },295 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, },268 /* B */ { 0, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 269 /* C */ { -1, 0, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 270 /* SC */ { -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 271 /* UC */ { -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 272 /* SI */ { -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 273 /* SUI */ { -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 274 /* I */ { -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 275 /* UI */ { -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 276 /* LI */ { -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 277 /* LUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 278 /* LLI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 279 /* LLUI */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 280 /* IB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 281 /* UIB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 282 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 283 /* _FH */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 284 /* _F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 285 /* _FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 286 /* F */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 287 /* FC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 288 /* _FX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 289 /* _FXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 290 /* FD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 291 /* _FDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 292 /* D */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 293 /* DC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 294 /* F80X */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 295 /* _FDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, -1, 0, -1, 0, }, 296 296 /* F80*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, 0, 0, }, 297 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, },298 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, },299 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, },300 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, },301 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, },302 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, },303 /* _FLDXC*/ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, },297 /* _FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, 0, }, 298 /* _FLDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, -1, 0, -1, 0, }, 299 /* FB */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, 0, 0, }, 300 /* LD */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, 0, 0, }, 301 /* LDC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, -1, 0, }, 302 /* _FBX */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, 0, }, 303 /* _FLDXC */ { -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, -1, 0, }, 304 304 }; // signMatrix 305 305 // GENERATED END 306 306 static_assert( 307 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES *BasicType::NUMBER_OF_BASIC_TYPES,307 sizeof(signMatrix)/sizeof(signMatrix[0][0]) == BasicType::NUMBER_OF_BASIC_TYPES * BasicType::NUMBER_OF_BASIC_TYPES, 308 308 "Missing row in the sign matrix" 309 309 ); … … 313 313 } 314 314 315 void ConversionCost::postvisit(const BasicType * basicType) {316 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) {315 void ConversionCost::postvisit(const BasicType * basicType) { 316 if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 317 317 int tableResult = costMatrix[ basicType->kind ][ destAsBasic->kind ]; 318 318 if ( tableResult == -1 ) { … … 331 331 332 332 void ConversionCost::postvisit( const PointerType * pointerType ) { 333 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) {333 if ( const PointerType * destAsPtr = dynamic_cast< const PointerType * >( dest ) ) { 334 334 PRINT( std::cerr << pointerType << " ===> " << destAsPtr << std::endl; ) 335 335 Type::Qualifiers tq1 = pointerType->base->tq; … … 385 385 386 386 void ConversionCost::postvisit( const StructInstType * inst ) { 387 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) {387 if ( const StructInstType * destAsInst = dynamic_cast< const StructInstType * >( dest ) ) { 388 388 if ( inst->name == destAsInst->name ) { 389 389 cost = Cost::zero; … … 393 393 394 394 void ConversionCost::postvisit( const UnionInstType * inst ) { 395 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) {395 if ( const UnionInstType * destAsInst = dynamic_cast< const UnionInstType * >( dest ) ) { 396 396 if ( inst->name == destAsInst->name ) { 397 397 cost = Cost::zero; … … 411 411 void ConversionCost::postvisit( const TraitInstType * ) {} 412 412 413 void ConversionCost::postvisit( const TypeInstType * inst ) {414 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) {413 void ConversionCost::postvisit( const TypeInstType * inst ) { 414 if ( const EqvClass * eqvClass = env.lookup( inst->name ) ) { 415 415 cost = costFunc( eqvClass->type, dest, indexer, env ); 416 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType* >( dest ) ) {416 } else if ( const TypeInstType * destAsInst = dynamic_cast< const TypeInstType * >( dest ) ) { 417 417 if ( inst->name == destAsInst->name ) { 418 418 cost = Cost::zero; 419 419 } 420 } else if ( NamedTypeDecl *namedType = indexer.lookupType( inst->name ) ) {421 const TypeDecl * type = dynamic_cast< const TypeDecl* >( namedType );420 } else if ( const NamedTypeDecl * namedType = indexer.lookupType( inst->name ) ) { 421 const TypeDecl * type = dynamic_cast< const TypeDecl * >( namedType ); 422 422 // all typedefs should be gone by this point 423 423 assert( type ); … … 434 434 std::list< Type * >::const_iterator destIt = destAsTuple->types.begin(); 435 435 while ( srcIt != tupleType->types.end() && destIt != destAsTuple->types.end() ) { 436 Cost newCost = costFunc( * srcIt++, *destIt++, indexer, env );436 Cost newCost = costFunc( * srcIt++, * destIt++, indexer, env ); 437 437 if ( newCost == Cost::infinity ) { 438 438 return; … … 449 449 450 450 void ConversionCost::postvisit( const VarArgsType * ) { 451 if ( dynamic_cast< const VarArgsType * >( dest ) ) {451 if ( dynamic_cast< const VarArgsType * >( dest ) ) { 452 452 cost = Cost::zero; 453 453 } … … 457 457 if ( dynamic_cast< const ZeroType * >( dest ) ) { 458 458 cost = Cost::zero; 459 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType* >( dest ) ) {460 // copied from visit(BasicType *) for signed int, but +1 for safe conversions459 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 460 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 461 461 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 462 462 if ( tableResult == -1 ) { … … 467 467 cost.incSign( signMatrix[ BasicType::SignedInt ][ destAsBasic->kind ] ); 468 468 } // if 469 } else if ( dynamic_cast< const PointerType * >( dest ) ) {469 } else if ( dynamic_cast< const PointerType * >( dest ) ) { 470 470 cost = Cost::zero; 471 471 cost.incSafe( maxIntCost + 2 ); // +1 for zero_t -> int, +1 for disambiguation … … 477 477 cost = Cost::zero; 478 478 } else if ( const BasicType * destAsBasic = dynamic_cast< const BasicType * >( dest ) ) { 479 // copied from visit(BasicType *) for signed int, but +1 for safe conversions479 // copied from visit(BasicType *) for signed int, but +1 for safe conversions 480 480 int tableResult = costMatrix[ BasicType::SignedInt ][ destAsBasic->kind ]; 481 481 if ( tableResult == -1 ) { … … 729 729 auto dstEnd = dstAsTuple->types.end(); 730 730 while ( srcIt != srcEnd && dstIt != dstEnd ) { 731 Cost newCost = costCalc( * srcIt++, *dstIt++, symtab, env );731 Cost newCost = costCalc( * srcIt++, * dstIt++, symtab, env ); 732 732 if ( newCost == Cost::infinity ) { 733 733 return; -
src/ResolvExpr/Resolver.cc
r7870799 ref5b828 562 562 // TODO: Replace *exception type with &exception type. 563 563 if ( throwStmt->get_expr() ) { 564 StructDecl * exception_decl = 565 indexer.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 564 StructDecl * exception_decl = indexer.lookupMutableStruct( "__cfaabi_ehm__base_exception_t" ); 566 565 assert( exception_decl ); 567 566 Type * exceptType = new PointerType( noQualifiers, new StructInstType( noQualifiers, exception_decl ) ); … … 972 971 /// Calls the CandidateFinder and finds the single best candidate 973 972 CandidateRef findUnfinishedKindExpression( 974 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 973 const ast::Expr * untyped, const ast::SymbolTable & symtab, const std::string & kind, 975 974 std::function<bool(const Candidate &)> pred = anyCandidate, ResolvMode mode = {} 976 975 ) { … … 994 993 // produce invalid error if no candidates 995 994 if ( candidates.empty() ) { 996 SemanticError( untyped, 997 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 995 SemanticError( untyped, 996 toString( "No reasonable alternatives for ", kind, (kind != "" ? " " : ""), 998 997 "expression: ") ); 999 998 } … … 1031 1030 if ( winners.size() != 1 ) { 1032 1031 std::ostringstream stream; 1033 stream << "Cannot choose between " << winners.size() << " alternatives for " 1032 stream << "Cannot choose between " << winners.size() << " alternatives for " 1034 1033 << kind << (kind != "" ? " " : "") << "expression\n"; 1035 1034 ast::print( stream, untyped ); … … 1054 1053 struct StripCasts_new final { 1055 1054 const ast::Expr * postmutate( const ast::CastExpr * castExpr ) { 1056 if ( 1057 castExpr->isGenerated 1058 && typesCompatible( castExpr->arg->result, castExpr->result ) 1055 if ( 1056 castExpr->isGenerated 1057 && typesCompatible( castExpr->arg->result, castExpr->result ) 1059 1058 ) { 1060 1059 // generated cast is the same type as its argument, remove it after keeping env 1061 return ast::mutate_field( 1060 return ast::mutate_field( 1062 1061 castExpr->arg.get(), &ast::Expr::env, castExpr->env ); 1063 1062 } … … 1088 1087 1089 1088 /// Establish post-resolver invariants for expressions 1090 void finishExpr( 1091 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1089 void finishExpr( 1090 ast::ptr< ast::Expr > & expr, const ast::TypeEnvironment & env, 1092 1091 const ast::TypeSubstitution * oldenv = nullptr 1093 1092 ) { 1094 1093 // set up new type substitution for expression 1095 ast::ptr< ast::TypeSubstitution > newenv = 1094 ast::ptr< ast::TypeSubstitution > newenv = 1096 1095 oldenv ? oldenv : new ast::TypeSubstitution{}; 1097 1096 env.writeToSubstitution( *newenv.get_and_mutate() ); … … 1102 1101 } // anonymous namespace 1103 1102 1104 1103 1105 1104 ast::ptr< ast::Expr > resolveInVoidContext( 1106 1105 const ast::Expr * expr, const ast::SymbolTable & symtab, ast::TypeEnvironment & env 1107 1106 ) { 1108 1107 assertf( expr, "expected a non-null expression" ); 1109 1108 1110 1109 // set up and resolve expression cast to void 1111 1110 ast::CastExpr * untyped = new ast::CastExpr{ expr }; 1112 CandidateRef choice = findUnfinishedKindExpression( 1111 CandidateRef choice = findUnfinishedKindExpression( 1113 1112 untyped, symtab, "", anyCandidate, ResolvMode::withAdjustment() ); 1114 1113 1115 1114 // a cast expression has either 0 or 1 interpretations (by language rules); 1116 1115 // if 0, an exception has already been thrown, and this code will not run … … 1122 1121 1123 1122 namespace { 1124 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1123 /// Resolve `untyped` to the expression whose candidate is the best match for a `void` 1125 1124 /// context. 1126 ast::ptr< ast::Expr > findVoidExpression( 1125 ast::ptr< ast::Expr > findVoidExpression( 1127 1126 const ast::Expr * untyped, const ast::SymbolTable & symtab 1128 1127 ) { … … 1134 1133 } 1135 1134 1136 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1135 /// resolve `untyped` to the expression whose candidate satisfies `pred` with the 1137 1136 /// lowest cost, returning the resolved version 1138 1137 ast::ptr< ast::Expr > findKindExpression( 1139 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1140 std::function<bool(const Candidate &)> pred = anyCandidate, 1138 const ast::Expr * untyped, const ast::SymbolTable & symtab, 1139 std::function<bool(const Candidate &)> pred = anyCandidate, 1141 1140 const std::string & kind = "", ResolvMode mode = {} 1142 1141 ) { 1143 1142 if ( ! untyped ) return {}; 1144 CandidateRef choice = 1143 CandidateRef choice = 1145 1144 findUnfinishedKindExpression( untyped, symtab, kind, pred, mode ); 1146 1145 finishExpr( choice->expr, choice->env, untyped->env ); … … 1149 1148 1150 1149 /// Resolve `untyped` to the single expression whose candidate is the best match 1151 ast::ptr< ast::Expr > findSingleExpression( 1152 const ast::Expr * untyped, const ast::SymbolTable & symtab 1150 ast::ptr< ast::Expr > findSingleExpression( 1151 const ast::Expr * untyped, const ast::SymbolTable & symtab 1153 1152 ) { 1154 1153 return findKindExpression( untyped, symtab ); … … 1170 1169 bool hasIntegralType( const Candidate & i ) { 1171 1170 const ast::Type * type = i.expr->result; 1172 1171 1173 1172 if ( auto bt = dynamic_cast< const ast::BasicType * >( type ) ) { 1174 1173 return bt->isInteger(); 1175 } else if ( 1176 dynamic_cast< const ast::EnumInstType * >( type ) 1174 } else if ( 1175 dynamic_cast< const ast::EnumInstType * >( type ) 1177 1176 || dynamic_cast< const ast::ZeroType * >( type ) 1178 1177 || dynamic_cast< const ast::OneType * >( type ) … … 1183 1182 1184 1183 /// Resolve `untyped` as an integral expression, returning the resolved version 1185 ast::ptr< ast::Expr > findIntegralExpression( 1186 const ast::Expr * untyped, const ast::SymbolTable & symtab 1184 ast::ptr< ast::Expr > findIntegralExpression( 1185 const ast::Expr * untyped, const ast::SymbolTable & symtab 1187 1186 ) { 1188 1187 return findKindExpression( untyped, symtab, hasIntegralType, "condition" ); … … 1192 1191 bool isCharType( const ast::Type * t ) { 1193 1192 if ( auto bt = dynamic_cast< const ast::BasicType * >( t ) ) { 1194 return bt->kind == ast::BasicType::Char 1195 || bt->kind == ast::BasicType::SignedChar 1193 return bt->kind == ast::BasicType::Char 1194 || bt->kind == ast::BasicType::SignedChar 1196 1195 || bt->kind == ast::BasicType::UnsignedChar; 1197 1196 } … … 1253 1252 } 1254 1253 1255 ast::ptr< ast::Init > resolveCtorInit( 1256 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1254 ast::ptr< ast::Init > resolveCtorInit( 1255 const ast::ConstructorInit * ctorInit, const ast::SymbolTable & symtab 1257 1256 ) { 1258 1257 assert( ctorInit ); … … 1261 1260 } 1262 1261 1263 ast::ptr< ast::Expr > resolveStmtExpr( 1264 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1262 ast::ptr< ast::Expr > resolveStmtExpr( 1263 const ast::StmtExpr * stmtExpr, const ast::SymbolTable & symtab 1265 1264 ) { 1266 1265 assert( stmtExpr ); … … 1303 1302 1304 1303 void Resolver_new::previsit( const ast::ObjectDecl * objectDecl ) { 1305 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1306 // class-variable `initContext` is changed multiple times because the LHS is analyzed 1307 // twice. The second analysis changes `initContext` because a function type can contain 1308 // object declarations in the return and parameter types. Therefore each value of 1309 // `initContext` is retained so the type on the first analysis is preserved and used for 1304 // To handle initialization of routine pointers [e.g. int (*fp)(int) = foo()], 1305 // class-variable `initContext` is changed multiple times because the LHS is analyzed 1306 // twice. The second analysis changes `initContext` because a function type can contain 1307 // object declarations in the return and parameter types. Therefore each value of 1308 // `initContext` is retained so the type on the first analysis is preserved and used for 1310 1309 // selecting the RHS. 1311 1310 GuardValue( currentObject ); 1312 1311 currentObject = ast::CurrentObject{ objectDecl->location, objectDecl->get_type() }; 1313 1312 if ( inEnumDecl && dynamic_cast< const ast::EnumInstType * >( objectDecl->get_type() ) ) { 1314 // enumerator initializers should not use the enum type to initialize, since the 1313 // enumerator initializers should not use the enum type to initialize, since the 1315 1314 // enum type is still incomplete at this point. Use `int` instead. 1316 currentObject = ast::CurrentObject{ 1315 currentObject = ast::CurrentObject{ 1317 1316 objectDecl->location, new ast::BasicType{ ast::BasicType::SignedInt } }; 1318 1317 } … … 1325 1324 } 1326 1325 1327 const ast::StaticAssertDecl * Resolver_new::previsit( 1328 const ast::StaticAssertDecl * assertDecl 1326 const ast::StaticAssertDecl * Resolver_new::previsit( 1327 const ast::StaticAssertDecl * assertDecl 1329 1328 ) { 1330 return ast::mutate_field( 1331 assertDecl, &ast::StaticAssertDecl::cond, 1329 return ast::mutate_field( 1330 assertDecl, &ast::StaticAssertDecl::cond, 1332 1331 findIntegralExpression( assertDecl->cond, symtab ) ); 1333 1332 } … … 1338 1337 #warning should use new equivalent to Validate::SizeType rather than sizeType here 1339 1338 ast::ptr< ast::Type > sizeType = new ast::BasicType{ ast::BasicType::LongUnsignedInt }; 1340 ast::mutate_field( 1341 type, &PtrType::dimension, 1339 ast::mutate_field( 1340 type, &PtrType::dimension, 1342 1341 findSingleExpression( type->dimension, sizeType, symtab ) ); 1343 1342 } … … 1356 1355 visit_children = false; 1357 1356 assertf( exprStmt->expr, "ExprStmt has null expression in resolver" ); 1358 1359 return ast::mutate_field( 1357 1358 return ast::mutate_field( 1360 1359 exprStmt, &ast::ExprStmt::expr, findVoidExpression( exprStmt->expr, symtab ) ); 1361 1360 } … … 1364 1363 visit_children = false; 1365 1364 1366 asmExpr = ast::mutate_field( 1365 asmExpr = ast::mutate_field( 1367 1366 asmExpr, &ast::AsmExpr::operand, findVoidExpression( asmExpr->operand, symtab ) ); 1368 1367 1369 1368 if ( asmExpr->inout ) { 1370 1369 asmExpr = ast::mutate_field( 1371 1370 asmExpr, &ast::AsmExpr::inout, findVoidExpression( asmExpr->inout, symtab ) ); 1372 1371 } 1373 1372 1374 1373 return asmExpr; 1375 1374 } … … 1388 1387 1389 1388 const ast::WhileStmt * Resolver_new::previsit( const ast::WhileStmt * whileStmt ) { 1390 return ast::mutate_field( 1389 return ast::mutate_field( 1391 1390 whileStmt, &ast::WhileStmt::cond, findIntegralExpression( whileStmt->cond, symtab ) ); 1392 1391 } … … 1409 1408 GuardValue( currentObject ); 1410 1409 switchStmt = ast::mutate_field( 1411 switchStmt, &ast::SwitchStmt::cond, 1410 switchStmt, &ast::SwitchStmt::cond, 1412 1411 findIntegralExpression( switchStmt->cond, symtab ) ); 1413 1412 currentObject = ast::CurrentObject{ switchStmt->location, switchStmt->cond->result }; … … 1420 1419 assertf( initAlts.size() == 1, "SwitchStmt did not correctly resolve an integral " 1421 1420 "expression." ); 1422 1423 ast::ptr< ast::Expr > untyped = 1421 1422 ast::ptr< ast::Expr > untyped = 1424 1423 new ast::CastExpr{ caseStmt->location, caseStmt->cond, initAlts.front().type }; 1425 1424 ast::ptr< ast::Expr > newExpr = findSingleExpression( untyped, symtab ); 1426 1427 // case condition cannot have a cast in C, so it must be removed here, regardless of 1425 1426 // case condition cannot have a cast in C, so it must be removed here, regardless of 1428 1427 // whether it would perform a conversion. 1429 1428 if ( const ast::CastExpr * castExpr = newExpr.as< ast::CastExpr >() ) { 1430 1429 swap_and_save_env( newExpr, castExpr->arg ); 1431 1430 } 1432 1431 1433 1432 caseStmt = ast::mutate_field( caseStmt, &ast::CaseStmt::cond, newExpr ); 1434 1433 } … … 1443 1442 ast::ptr< ast::Type > target = new ast::PointerType{ new ast::VoidType{} }; 1444 1443 branchStmt = ast::mutate_field( 1445 branchStmt, &ast::BranchStmt::computedTarget, 1444 branchStmt, &ast::BranchStmt::computedTarget, 1446 1445 findSingleExpression( branchStmt->computedTarget, target, symtab ) ); 1447 1446 } … … 1453 1452 if ( returnStmt->expr ) { 1454 1453 returnStmt = ast::mutate_field( 1455 returnStmt, &ast::ReturnStmt::expr, 1454 returnStmt, &ast::ReturnStmt::expr, 1456 1455 findSingleExpression( returnStmt->expr, functionReturn, symtab ) ); 1457 1456 } … … 1462 1461 visit_children = false; 1463 1462 if ( throwStmt->expr ) { 1464 const ast::StructDecl * exceptionDecl = 1463 const ast::StructDecl * exceptionDecl = 1465 1464 symtab.lookupStruct( "__cfaabi_ehm__base_exception_t" ); 1466 1465 assert( exceptionDecl ); 1467 ast::ptr< ast::Type > exceptType = 1466 ast::ptr< ast::Type > exceptType = 1468 1467 new ast::PointerType{ new ast::StructInstType{ exceptionDecl } }; 1469 1468 throwStmt = ast::mutate_field( 1470 throwStmt, &ast::ThrowStmt::expr, 1469 throwStmt, &ast::ThrowStmt::expr, 1471 1470 findSingleExpression( throwStmt->expr, exceptType, symtab ) ); 1472 1471 } … … 1477 1476 if ( catchStmt->cond ) { 1478 1477 ast::ptr< ast::Type > boolType = new ast::BasicType{ ast::BasicType::Bool }; 1479 catchStmt = ast::mutate_field( 1480 catchStmt, &ast::CatchStmt::cond, 1478 catchStmt = ast::mutate_field( 1479 catchStmt, &ast::CatchStmt::cond, 1481 1480 findSingleExpression( catchStmt->cond, boolType, symtab ) ); 1482 1481 } … … 1506 1505 1507 1506 if ( clause.target.args.empty() ) { 1508 SemanticError( stmt->location, 1507 SemanticError( stmt->location, 1509 1508 "Waitfor clause must have at least one mutex parameter"); 1510 1509 } 1511 1510 1512 1511 // Find all alternatives for all arguments in canonical form 1513 std::vector< CandidateFinder > argFinders = 1512 std::vector< CandidateFinder > argFinders = 1514 1513 funcFinder.findSubExprs( clause.target.args ); 1515 1514 1516 1515 // List all combinations of arguments 1517 1516 std::vector< CandidateList > possibilities; … … 1519 1518 1520 1519 // For every possible function: 1521 // * try matching the arguments to the parameters, not the other way around because 1520 // * try matching the arguments to the parameters, not the other way around because 1522 1521 // more arguments than parameters 1523 1522 CandidateList funcCandidates; … … 1526 1525 for ( CandidateRef & func : funcFinder.candidates ) { 1527 1526 try { 1528 auto pointerType = dynamic_cast< const ast::PointerType * >( 1527 auto pointerType = dynamic_cast< const ast::PointerType * >( 1529 1528 func->expr->result->stripReferences() ); 1530 1529 if ( ! pointerType ) { 1531 SemanticError( stmt->location, func->expr->result.get(), 1530 SemanticError( stmt->location, func->expr->result.get(), 1532 1531 "candidate not viable: not a pointer type\n" ); 1533 1532 } … … 1535 1534 auto funcType = pointerType->base.as< ast::FunctionType >(); 1536 1535 if ( ! funcType ) { 1537 SemanticError( stmt->location, func->expr->result.get(), 1536 SemanticError( stmt->location, func->expr->result.get(), 1538 1537 "candidate not viable: not a function type\n" ); 1539 1538 } … … 1544 1543 1545 1544 if( ! nextMutex( param, paramEnd ) ) { 1546 SemanticError( stmt->location, funcType, 1545 SemanticError( stmt->location, funcType, 1547 1546 "candidate function not viable: no mutex parameters\n"); 1548 1547 } … … 1560 1559 ast::AssertionSet need, have; 1561 1560 ast::TypeEnvironment resultEnv{ func->env }; 1562 // Add all type variables as open so that those not used in the 1561 // Add all type variables as open so that those not used in the 1563 1562 // parameter list are still considered open 1564 1563 resultEnv.add( funcType->forall ); … … 1580 1579 unsigned n_mutex_param = 0; 1581 1580 1582 // For every argument of its set, check if it matches one of the 1581 // For every argument of its set, check if it matches one of the 1583 1582 // parameters. The order is important 1584 1583 for ( auto & arg : argsList ) { … … 1587 1586 // We ran out of parameters but still have arguments. 1588 1587 // This function doesn't match 1589 SemanticError( stmt->location, funcType, 1588 SemanticError( stmt->location, funcType, 1590 1589 toString("candidate function not viable: too many mutex " 1591 1590 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1594 1593 ++n_mutex_param; 1595 1594 1596 // Check if the argument matches the parameter type in the current 1595 // Check if the argument matches the parameter type in the current 1597 1596 // scope 1598 1597 ast::ptr< ast::Type > paramType = (*param)->get_type(); 1599 if ( 1600 ! unify( 1601 arg->expr->result, paramType, resultEnv, need, have, open, 1602 symtab ) 1598 if ( 1599 ! unify( 1600 arg->expr->result, paramType, resultEnv, need, have, open, 1601 symtab ) 1603 1602 ) { 1604 1603 // Type doesn't match … … 1627 1626 } while ( nextMutex( param, paramEnd ) ); 1628 1627 1629 // We ran out of arguments but still have parameters left; this 1628 // We ran out of arguments but still have parameters left; this 1630 1629 // function doesn't match 1631 SemanticError( stmt->location, funcType, 1630 SemanticError( stmt->location, funcType, 1632 1631 toString( "candidate function not viable: too few mutex " 1633 1632 "arguments, expected ", n_mutex_param, "\n" ) ); … … 1657 1656 // Make sure correct number of arguments 1658 1657 if( funcCandidates.empty() ) { 1659 SemanticErrorException top( stmt->location, 1658 SemanticErrorException top( stmt->location, 1660 1659 "No alternatives for function in call to waitfor" ); 1661 1660 top.append( errors ); … … 1664 1663 1665 1664 if( argsCandidates.empty() ) { 1666 SemanticErrorException top( stmt->location, 1667 "No alternatives for arguments in call to waitfor" ); 1665 SemanticErrorException top( stmt->location, 1666 "No alternatives for arguments in call to waitfor" ); 1668 1667 top.append( errors ); 1669 1668 throw top; … … 1671 1670 1672 1671 if( funcCandidates.size() > 1 ) { 1673 SemanticErrorException top( stmt->location, 1672 SemanticErrorException top( stmt->location, 1674 1673 "Ambiguous function in call to waitfor" ); 1675 1674 top.append( errors ); … … 1686 1685 // build new clause 1687 1686 ast::WaitForStmt::Clause clause2; 1688 1687 1689 1688 clause2.target.func = funcCandidates.front()->expr; 1690 1689 1691 1690 clause2.target.args.reserve( clause.target.args.size() ); 1692 1691 for ( auto arg : argsCandidates.front() ) { … … 1708 1707 ast::WaitForStmt::Timeout timeout2; 1709 1708 1710 ast::ptr< ast::Type > target = 1709 ast::ptr< ast::Type > target = 1711 1710 new ast::BasicType{ ast::BasicType::LongLongUnsignedInt }; 1712 1711 timeout2.time = findSingleExpression( stmt->timeout.time, target, symtab ); … … 1740 1739 const ast::SingleInit * Resolver_new::previsit( const ast::SingleInit * singleInit ) { 1741 1740 visit_children = false; 1742 // resolve initialization using the possibilities as determined by the `currentObject` 1741 // resolve initialization using the possibilities as determined by the `currentObject` 1743 1742 // cursor. 1744 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1743 ast::ptr< ast::Expr > untyped = new ast::UntypedInitExpr{ 1745 1744 singleInit->location, singleInit->value, currentObject.getOptions() }; 1746 1745 ast::ptr<ast::Expr> newExpr = findSingleExpression( untyped, symtab ); … … 1751 1750 1752 1751 // discard InitExpr wrapper and retain relevant pieces. 1753 // `initExpr` may have inferred params in the case where the expression specialized a 1754 // function pointer, and newExpr may already have inferParams of its own, so a simple 1752 // `initExpr` may have inferred params in the case where the expression specialized a 1753 // function pointer, and newExpr may already have inferParams of its own, so a simple 1755 1754 // swap is not sufficient 1756 1755 ast::Expr::InferUnion inferred = initExpr->inferred; … … 1758 1757 newExpr.get_and_mutate()->inferred.splice( std::move(inferred) ); 1759 1758 1760 // get the actual object's type (may not exactly match what comes back from the resolver 1759 // get the actual object's type (may not exactly match what comes back from the resolver 1761 1760 // due to conversions) 1762 1761 const ast::Type * initContext = currentObject.getCurrentType(); … … 1770 1769 if ( auto pt = newExpr->result.as< ast::PointerType >() ) { 1771 1770 if ( isCharType( pt->base ) ) { 1772 // strip cast if we're initializing a char[] with a char* 1771 // strip cast if we're initializing a char[] with a char* 1773 1772 // e.g. char x[] = "hello" 1774 1773 if ( auto ce = newExpr.as< ast::CastExpr >() ) { … … 1793 1792 assert( listInit->designations.size() == listInit->initializers.size() ); 1794 1793 for ( unsigned i = 0; i < listInit->designations.size(); ++i ) { 1795 // iterate designations and initializers in pairs, moving the cursor to the current 1794 // iterate designations and initializers in pairs, moving the cursor to the current 1796 1795 // designated object and resolving the initializer against that object 1797 1796 listInit = ast::mutate_field_index( 1798 listInit, &ast::ListInit::designations, i, 1797 listInit, &ast::ListInit::designations, i, 1799 1798 currentObject.findNext( listInit->designations[i] ) ); 1800 1799 listInit = ast::mutate_field_index( … … 1818 1817 ctorInit = ast::mutate_field( ctorInit, &ast::ConstructorInit::init, nullptr ); 1819 1818 1820 // intrinsic single-parameter constructors and destructors do nothing. Since this was 1821 // implicitly generated, there's no way for it to have side effects, so get rid of it to 1819 // intrinsic single-parameter constructors and destructors do nothing. Since this was 1820 // implicitly generated, there's no way for it to have side effects, so get rid of it to 1822 1821 // clean up generated code 1823 1822 if ( InitTweak::isIntrinsicSingleArgCallStmt( ctorInit->ctor ) ) { -
src/SymTab/Indexer.cc
r7870799 ref5b828 74 74 } 75 75 76 Indexer::Indexer() 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; }76 Indexer::Indexer() 77 : idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable(), 78 prevScope(), scope( 0 ), repScope( 0 ) { ++* stats().count; } 79 79 80 80 Indexer::~Indexer() { … … 84 84 void Indexer::lazyInitScope() { 85 85 if ( repScope < scope ) { 86 ++* stats().lazy_scopes;86 ++* stats().lazy_scopes; 87 87 // create rollback 88 prevScope = std::make_shared<Indexer>( * this );88 prevScope = std::make_shared<Indexer>( * this ); 89 89 // update repScope 90 90 repScope = scope; … … 95 95 ++scope; 96 96 97 ++* stats().new_scopes;97 ++* stats().new_scopes; 98 98 stats().avg_scope_depth->push( scope ); 99 99 stats().max_scope_depth->push( scope ); … … 103 103 if ( repScope == scope ) { 104 104 Ptr prev = prevScope; // make sure prevScope stays live 105 * this = std::move(*prevScope); // replace with previous scope105 * this = std::move(* prevScope); // replace with previous scope 106 106 } 107 107 … … 109 109 } 110 110 111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const {112 ++* stats().lookup_calls;111 void Indexer::lookupId( const std::string & id, std::list< IdData > &out ) const { 112 ++* stats().lookup_calls; 113 113 if ( ! idTable ) return; 114 114 115 ++* stats().map_lookups;115 ++* stats().map_lookups; 116 116 auto decls = idTable->find( id ); 117 117 if ( decls == idTable->end() ) return; … … 122 122 } 123 123 124 NamedTypeDecl *Indexer::lookupType( const std::string &id ) const { 125 ++*stats().lookup_calls; 124 const NamedTypeDecl * Indexer::lookupType( const std::string & id ) const { return lookupMutableType(id); } 125 NamedTypeDecl * Indexer::lookupMutableType( const std::string & id ) const { 126 ++* stats().lookup_calls; 126 127 if ( ! typeTable ) return nullptr; 127 ++* stats().map_lookups;128 ++* stats().map_lookups; 128 129 auto it = typeTable->find( id ); 129 130 return it == typeTable->end() ? nullptr : it->second.decl; 130 131 } 131 132 132 StructDecl *Indexer::lookupStruct( const std::string &id ) const { 133 ++*stats().lookup_calls; 133 const StructDecl * Indexer::lookupStruct( const std::string & id ) const { return lookupMutableStruct(id); } 134 StructDecl * Indexer::lookupMutableStruct( const std::string & id ) const { 135 ++* stats().lookup_calls; 134 136 if ( ! structTable ) return nullptr; 135 ++* stats().map_lookups;137 ++* stats().map_lookups; 136 138 auto it = structTable->find( id ); 137 139 return it == structTable->end() ? nullptr : it->second.decl; 138 140 } 139 141 140 EnumDecl *Indexer::lookupEnum( const std::string &id ) const { 141 ++*stats().lookup_calls; 142 const EnumDecl * Indexer::lookupEnum( const std::string & id ) const { return lookupMutableEnum(id); } 143 EnumDecl * Indexer::lookupMutableEnum( const std::string & id ) const { 144 ++* stats().lookup_calls; 142 145 if ( ! enumTable ) return nullptr; 143 ++* stats().map_lookups;146 ++* stats().map_lookups; 144 147 auto it = enumTable->find( id ); 145 148 return it == enumTable->end() ? nullptr : it->second.decl; 146 149 } 147 150 148 UnionDecl *Indexer::lookupUnion( const std::string &id ) const { 149 ++*stats().lookup_calls; 151 const UnionDecl * Indexer::lookupUnion( const std::string & id ) const { return lookupMutableUnion(id); } 152 UnionDecl * Indexer::lookupMutableUnion( const std::string & id ) const { 153 ++* stats().lookup_calls; 150 154 if ( ! unionTable ) return nullptr; 151 ++* stats().map_lookups;155 ++* stats().map_lookups; 152 156 auto it = unionTable->find( id ); 153 157 return it == unionTable->end() ? nullptr : it->second.decl; 154 158 } 155 159 156 TraitDecl *Indexer::lookupTrait( const std::string &id ) const { 157 ++*stats().lookup_calls; 160 const TraitDecl * Indexer::lookupTrait( const std::string & id ) const { return lookupMutableTrait(id); } 161 TraitDecl * Indexer::lookupMutableTrait( const std::string & id ) const { 162 ++* stats().lookup_calls; 158 163 if ( ! traitTable ) return nullptr; 159 ++* stats().map_lookups;164 ++* stats().map_lookups; 160 165 auto it = traitTable->find( id ); 161 166 return it == traitTable->end() ? nullptr : it->second.decl; 162 167 } 163 168 164 const Indexer * Indexer::atScope( unsigned long target ) const {169 const Indexer * Indexer::atScope( unsigned long target ) const { 165 170 // by lazy construction, final indexer in list has repScope 0, cannot be > target 166 171 // otherwise, will find first scope representing the target 167 const Indexer * indexer = this;172 const Indexer * indexer = this; 168 173 while ( indexer->repScope > target ) { 169 174 indexer = indexer->prevScope.get(); … … 172 177 } 173 178 174 NamedTypeDecl *Indexer::globalLookupType( const std::string &id ) const {179 const NamedTypeDecl * Indexer::globalLookupType( const std::string & id ) const { 175 180 return atScope( 0 )->lookupType( id ); 176 181 } 177 182 178 StructDecl *Indexer::globalLookupStruct( const std::string &id ) const {183 const StructDecl * Indexer::globalLookupStruct( const std::string & id ) const { 179 184 return atScope( 0 )->lookupStruct( id ); 180 185 } 181 186 182 UnionDecl *Indexer::globalLookupUnion( const std::string &id ) const {187 const UnionDecl * Indexer::globalLookupUnion( const std::string & id ) const { 183 188 return atScope( 0 )->lookupUnion( id ); 184 189 } 185 190 186 EnumDecl *Indexer::globalLookupEnum( const std::string &id ) const {191 const EnumDecl * Indexer::globalLookupEnum( const std::string & id ) const { 187 192 return atScope( 0 )->lookupEnum( id ); 188 193 } … … 207 212 } 208 213 209 210 bool Indexer::addedIdConflicts( 211 const Indexer::IdData & existing, DeclarationWithType * added,214 215 bool Indexer::addedIdConflicts( 216 const Indexer::IdData & existing, DeclarationWithType * added, 212 217 Indexer::OnConflict handleConflicts, BaseSyntaxNode * deleteStmt ) { 213 // if we're giving the same name mangling to things of different types then there is 218 // if we're giving the same name mangling to things of different types then there is 214 219 // something wrong 215 220 assert( (isObject( added ) && isObject( existing.id ) ) … … 219 224 // new definition shadows the autogenerated one, even at the same scope 220 225 return false; 221 } else if ( LinkageSpec::isMangled( added->linkage ) 222 || ResolvExpr::typesCompatible( 226 } else if ( LinkageSpec::isMangled( added->linkage ) 227 || ResolvExpr::typesCompatible( 223 228 added->get_type(), existing.id->get_type(), Indexer() ) ) { 224 229 … … 238 243 if ( isDefinition( added ) && isDefinition( existing.id ) ) { 239 244 if ( handleConflicts.mode == OnConflict::Error ) { 240 SemanticError( added, 241 isFunction( added ) ? 242 "duplicate function definition for " : 245 SemanticError( added, 246 isFunction( added ) ? 247 "duplicate function definition for " : 243 248 "duplicate object definition for " ); 244 249 } … … 255 260 } 256 261 257 bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const {262 bool Indexer::hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const { 258 263 if ( ! idTable ) return false; 259 264 260 ++* stats().map_lookups;265 ++* stats().map_lookups; 261 266 auto decls = idTable->find( id ); 262 267 if ( decls == idTable->end() ) return false; … … 270 275 } 271 276 } 272 277 273 278 return false; 274 279 } 275 280 276 bool Indexer::hasIncompatibleCDecl( 277 const std::string & id, const std::string &mangleName ) const {281 bool Indexer::hasIncompatibleCDecl( 282 const std::string & id, const std::string &mangleName ) const { 278 283 if ( ! idTable ) return false; 279 284 280 ++* stats().map_lookups;285 ++* stats().map_lookups; 281 286 auto decls = idTable->find( id ); 282 287 if ( decls == idTable->end() ) return false; … … 295 300 296 301 /// gets the base type of the first parameter; decl must be a ctor/dtor/assignment function 297 std::string getOtypeKey( FunctionDecl * function ) {302 std::string getOtypeKey( FunctionDecl * function ) { 298 303 auto& params = function->type->parameters; 299 304 assert( ! params.empty() ); 300 305 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 301 Type * base = InitTweak::getPointerBase( params.front()->get_type() );306 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 302 307 assert( base ); 303 308 return Mangler::mangle( base ); 304 309 } 305 310 306 /// gets the declaration for the function acting on a type specified by otype key, 311 /// gets the declaration for the function acting on a type specified by otype key, 307 312 /// nullptr if none such 308 313 FunctionDecl * getFunctionForOtype( DeclarationWithType * decl, const std::string& otypeKey ) { … … 312 317 } 313 318 314 bool Indexer::removeSpecialOverrides( 319 bool Indexer::removeSpecialOverrides( 315 320 Indexer::IdData& data, Indexer::MangleTable::Ptr& mangleTable ) { 316 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 317 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 318 // if the user defines a default ctor, then the generated default ctor is unavailable, 319 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 320 // field ctors are available. If the user defines any ctor then the generated default ctor 321 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 322 // anything that looks like a copy constructor, then the generated copy constructor is 321 // if a type contains user defined ctor/dtor/assign, then special rules trigger, which 322 // determinethe set of ctor/dtor/assign that can be used by the requester. In particular, 323 // if the user defines a default ctor, then the generated default ctor is unavailable, 324 // likewise for copy ctor and dtor. If the user defines any ctor/dtor, then no generated 325 // field ctors are available. If the user defines any ctor then the generated default ctor 326 // is unavailable (intrinsic default ctor must be overridden exactly). If the user defines 327 // anything that looks like a copy constructor, then the generated copy constructor is 323 328 // unavailable, and likewise for the assignment operator. 324 329 … … 340 345 std::vector< MangleTable::value_type > deleted; 341 346 bool alreadyUserDefinedFunc = false; 342 343 for ( const auto& entry : * mangleTable ) {347 348 for ( const auto& entry : * mangleTable ) { 344 349 // skip decls that aren't functions or are for the wrong type 345 350 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); … … 368 373 // perform removals from mangle table, and deletions if necessary 369 374 for ( const auto& key : removed ) { 370 ++* stats().map_mutations;375 ++* stats().map_mutations; 371 376 mangleTable = mangleTable->erase( key ); 372 377 } 373 378 if ( ! alreadyUserDefinedFunc ) for ( const auto& entry : deleted ) { 374 ++* stats().map_mutations;379 ++* stats().map_mutations; 375 380 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 376 381 } … … 379 384 // if this is the first user-defined function, delete non-user-defined overloads 380 385 std::vector< MangleTable::value_type > deleted; 381 382 for ( const auto& entry : * mangleTable ) {386 387 for ( const auto& entry : * mangleTable ) { 383 388 // skip decls that aren't functions or are for the wrong type 384 389 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); … … 402 407 // this needs to be a separate loop because of iterator invalidation 403 408 for ( const auto& entry : deleted ) { 404 ++* stats().map_mutations;409 ++* stats().map_mutations; 405 410 mangleTable = mangleTable->set( entry.first, IdData{ entry.second, function } ); 406 411 } … … 408 413 // this is an overridable generated function 409 414 // if there already exists a matching user-defined function, delete this appropriately 410 for ( const auto& entry : * mangleTable ) {415 for ( const auto& entry : * mangleTable ) { 411 416 // skip decls that aren't functions or are for the wrong type 412 417 FunctionDecl * decl = getFunctionForOtype( entry.second.id, dataOtypeKey ); … … 418 423 if ( dataIsCopyFunc ) { 419 424 // remove current function if exists a user-defined copy function 420 // since the signatures for copy functions don't need to match exactly, using 425 // since the signatures for copy functions don't need to match exactly, using 421 426 // a delete statement is the wrong approach 422 427 if ( InitTweak::isCopyFunction( decl, decl->name ) ) return false; … … 428 433 } 429 434 } 430 435 431 436 // nothing (more) to fix, return true 432 437 return true; 433 438 } 434 439 435 void Indexer::addId( 436 DeclarationWithType * decl, OnConflict handleConflicts, Expression * baseExpr,440 void Indexer::addId( 441 DeclarationWithType * decl, OnConflict handleConflicts, Expression * baseExpr, 437 442 BaseSyntaxNode * deleteStmt ) { 438 ++* stats().add_calls;443 ++* stats().add_calls; 439 444 const std::string &name = decl->name; 440 445 if ( name == "" ) return; 441 446 442 447 std::string mangleName; 443 448 if ( LinkageSpec::isOverridable( decl->linkage ) ) { 444 // mangle the name without including the appropriate suffix, so overridable routines 449 // mangle the name without including the appropriate suffix, so overridable routines 445 450 // are placed into the same "bucket" as their user defined versions. 446 451 mangleName = Mangler::mangle( decl, false ); … … 449 454 } // if 450 455 451 // this ensures that no two declarations with the same unmangled name at the same scope 456 // this ensures that no two declarations with the same unmangled name at the same scope 452 457 // both have C linkage 453 458 if ( LinkageSpec::isMangled( decl->linkage ) ) { … … 457 462 } 458 463 } else { 459 // NOTE: only correct if name mangling is completely isomorphic to C 464 // NOTE: only correct if name mangling is completely isomorphic to C 460 465 // type-compatibility, which it may not be. 461 466 if ( hasIncompatibleCDecl( name, mangleName ) ) { … … 470 475 mangleTable = MangleTable::new_ptr(); 471 476 } else { 472 ++* stats().map_lookups;477 ++* stats().map_lookups; 473 478 auto decls = idTable->find( name ); 474 479 if ( decls == idTable->end() ) { … … 477 482 mangleTable = decls->second; 478 483 // skip in-scope repeat declarations of same identifier 479 ++* stats().map_lookups;484 ++* stats().map_lookups; 480 485 auto existing = mangleTable->find( mangleName ); 481 486 if ( existing != mangleTable->end() … … 486 491 // set delete expression for conflicting identifier 487 492 lazyInitScope(); 488 * stats().map_mutations += 2;493 * stats().map_mutations += 2; 489 494 idTable = idTable->set( 490 495 name, 491 mangleTable->set( 492 mangleName, 496 mangleTable->set( 497 mangleName, 493 498 IdData{ existing->second, handleConflicts.deleteStmt } ) ); 494 499 } … … 504 509 // Ensure that auto-generated ctor/dtor/assignment are deleted if necessary 505 510 if ( ! removeSpecialOverrides( data, mangleTable ) ) return; 506 * stats().map_mutations += 2;511 * stats().map_mutations += 2; 507 512 idTable = idTable->set( name, mangleTable->set( mangleName, std::move(data) ) ); 508 513 } … … 518 523 } 519 524 520 bool addedTypeConflicts( NamedTypeDecl * existing, NamedTypeDecl *added ) {525 bool addedTypeConflicts( NamedTypeDecl * existing, NamedTypeDecl * added ) { 521 526 if ( existing->base == nullptr ) { 522 527 return false; … … 530 535 } 531 536 } 532 // does not need to be added to the table if both existing and added have a base that are 537 // does not need to be added to the table if both existing and added have a base that are 533 538 // the same 534 539 return true; 535 540 } 536 541 537 void Indexer::addType( NamedTypeDecl * decl ) {538 ++* stats().add_calls;539 const std::string & id = decl->name;540 541 if ( ! typeTable ) { 542 void Indexer::addType( NamedTypeDecl * decl ) { 543 ++* stats().add_calls; 544 const std::string & id = decl->name; 545 546 if ( ! typeTable ) { 542 547 typeTable = TypeTable::new_ptr(); 543 548 } else { 544 ++* stats().map_lookups;549 ++* stats().map_lookups; 545 550 auto existing = typeTable->find( id ); 546 if ( existing != typeTable->end() 547 && existing->second.scope == scope 551 if ( existing != typeTable->end() 552 && existing->second.scope == scope 548 553 && addedTypeConflicts( existing->second.decl, decl ) ) return; 549 554 } 550 555 551 556 lazyInitScope(); 552 ++* stats().map_mutations;557 ++* stats().map_mutations; 553 558 typeTable = typeTable->set( id, Scoped<NamedTypeDecl>{ decl, scope } ); 554 559 } 555 560 556 bool addedDeclConflicts( AggregateDecl * existing, AggregateDecl *added ) {561 bool addedDeclConflicts( AggregateDecl * existing, AggregateDecl * added ) { 557 562 if ( ! existing->body ) { 558 563 return false; … … 563 568 } 564 569 565 void Indexer::addStruct( const std::string & id ) {570 void Indexer::addStruct( const std::string & id ) { 566 571 addStruct( new StructDecl( id ) ); 567 572 } 568 573 569 void Indexer::addStruct( StructDecl * decl ) {570 ++* stats().add_calls;571 const std::string & id = decl->name;574 void Indexer::addStruct( StructDecl * decl ) { 575 ++* stats().add_calls; 576 const std::string & id = decl->name; 572 577 573 578 if ( ! structTable ) { 574 579 structTable = StructTable::new_ptr(); 575 580 } else { 576 ++* stats().map_lookups;581 ++* stats().map_lookups; 577 582 auto existing = structTable->find( id ); 578 if ( existing != structTable->end() 579 && existing->second.scope == scope 583 if ( existing != structTable->end() 584 && existing->second.scope == scope 580 585 && addedDeclConflicts( existing->second.decl, decl ) ) return; 581 586 } 582 587 583 588 lazyInitScope(); 584 ++* stats().map_mutations;589 ++* stats().map_mutations; 585 590 structTable = structTable->set( id, Scoped<StructDecl>{ decl, scope } ); 586 591 } 587 592 588 void Indexer::addEnum( EnumDecl * decl ) {589 ++* stats().add_calls;590 const std::string & id = decl->name;593 void Indexer::addEnum( EnumDecl * decl ) { 594 ++* stats().add_calls; 595 const std::string & id = decl->name; 591 596 592 597 if ( ! enumTable ) { 593 598 enumTable = EnumTable::new_ptr(); 594 599 } else { 595 ++* stats().map_lookups;600 ++* stats().map_lookups; 596 601 auto existing = enumTable->find( id ); 597 if ( existing != enumTable->end() 598 && existing->second.scope == scope 602 if ( existing != enumTable->end() 603 && existing->second.scope == scope 599 604 && addedDeclConflicts( existing->second.decl, decl ) ) return; 600 605 } 601 606 602 607 lazyInitScope(); 603 ++* stats().map_mutations;608 ++* stats().map_mutations; 604 609 enumTable = enumTable->set( id, Scoped<EnumDecl>{ decl, scope } ); 605 610 } 606 611 607 void Indexer::addUnion( const std::string & id ) {612 void Indexer::addUnion( const std::string & id ) { 608 613 addUnion( new UnionDecl( id ) ); 609 614 } 610 615 611 void Indexer::addUnion( UnionDecl * decl ) {612 ++* stats().add_calls;613 const std::string & id = decl->name;616 void Indexer::addUnion( UnionDecl * decl ) { 617 ++* stats().add_calls; 618 const std::string & id = decl->name; 614 619 615 620 if ( ! unionTable ) { 616 621 unionTable = UnionTable::new_ptr(); 617 622 } else { 618 ++* stats().map_lookups;623 ++* stats().map_lookups; 619 624 auto existing = unionTable->find( id ); 620 if ( existing != unionTable->end() 621 && existing->second.scope == scope 625 if ( existing != unionTable->end() 626 && existing->second.scope == scope 622 627 && addedDeclConflicts( existing->second.decl, decl ) ) return; 623 628 } 624 629 625 630 lazyInitScope(); 626 ++* stats().map_mutations;631 ++* stats().map_mutations; 627 632 unionTable = unionTable->set( id, Scoped<UnionDecl>{ decl, scope } ); 628 633 } 629 634 630 void Indexer::addTrait( TraitDecl * decl ) {631 ++* stats().add_calls;632 const std::string & id = decl->name;635 void Indexer::addTrait( TraitDecl * decl ) { 636 ++* stats().add_calls; 637 const std::string & id = decl->name; 633 638 634 639 if ( ! traitTable ) { 635 640 traitTable = TraitTable::new_ptr(); 636 641 } else { 637 ++* stats().map_lookups;642 ++* stats().map_lookups; 638 643 auto existing = traitTable->find( id ); 639 if ( existing != traitTable->end() 640 && existing->second.scope == scope 644 if ( existing != traitTable->end() 645 && existing->second.scope == scope 641 646 && addedDeclConflicts( existing->second.decl, decl ) ) return; 642 647 } 643 648 644 649 lazyInitScope(); 645 ++* stats().map_mutations;650 ++* stats().map_mutations; 646 651 traitTable = traitTable->set( id, Scoped<TraitDecl>{ decl, scope } ); 647 652 } 648 653 649 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 654 void Indexer::addMembers( AggregateDecl * aggr, Expression * expr, 650 655 OnConflict handleConflicts ) { 651 656 for ( Declaration * decl : aggr->members ) { … … 654 659 if ( dwt->name == "" ) { 655 660 Type * t = dwt->get_type()->stripReferences(); 656 if ( dynamic_cast<StructInstType *>( t ) || dynamic_cast<UnionInstType*>( t ) ) {661 if ( dynamic_cast<StructInstType *>( t ) || dynamic_cast<UnionInstType *>( t ) ) { 657 662 Expression * base = expr->clone(); 658 663 ResolvExpr::Cost cost = ResolvExpr::Cost::zero; // xxx - carry this cost into the indexer as a base cost? -
src/SymTab/Indexer.h
r7870799 ref5b828 34 34 virtual ~Indexer(); 35 35 36 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 36 // when using an indexer manually (e.g., within a mutator traversal), it is necessary to 37 37 // tell the indexer explicitly when scopes begin and end 38 38 void enterScope(); … … 50 50 // NOTE: shouldn't need either of these constructors, but gcc-4 does not properly support initializer lists with default members. 51 51 IdData() = default; 52 IdData( 52 IdData( 53 53 DeclarationWithType * id, Expression * baseExpr, BaseSyntaxNode * deleteStmt, 54 unsigned long scope ) 54 unsigned long scope ) 55 55 : id( id ), baseExpr( baseExpr ), deleteStmt( deleteStmt ), scope( scope ) {} 56 56 IdData( const IdData& o, BaseSyntaxNode * deleteStmt ) … … 61 61 62 62 /// Gets all declarations with the given ID 63 void lookupId( const std::string & id, std::list< IdData > &out ) const;63 void lookupId( const std::string & id, std::list< IdData > &out ) const; 64 64 /// Gets the top-most type declaration with the given ID 65 NamedTypeDecl *lookupType( const std::string &id ) const; 65 const NamedTypeDecl * lookupType( const std::string & id ) const; 66 NamedTypeDecl * lookupMutableType( const std::string & id ) const; 66 67 /// Gets the top-most struct declaration with the given ID 67 StructDecl *lookupStruct( const std::string &id ) const; 68 const StructDecl * lookupStruct( const std::string & id ) const; 69 StructDecl * lookupMutableStruct( const std::string & id ) const; 68 70 /// Gets the top-most enum declaration with the given ID 69 EnumDecl *lookupEnum( const std::string &id ) const; 71 const EnumDecl * lookupEnum( const std::string & id ) const; 72 EnumDecl * lookupMutableEnum( const std::string & id ) const; 70 73 /// Gets the top-most union declaration with the given ID 71 UnionDecl *lookupUnion( const std::string &id ) const; 74 const UnionDecl * lookupUnion( const std::string & id ) const; 75 UnionDecl * lookupMutableUnion( const std::string & id ) const; 72 76 /// Gets the top-most trait declaration with the given ID 73 TraitDecl *lookupTrait( const std::string &id ) const; 77 const TraitDecl * lookupTrait( const std::string & id ) const; 78 TraitDecl * lookupMutableTrait( const std::string & id ) const; 74 79 75 80 /// Gets the type declaration with the given ID at global scope 76 NamedTypeDecl *globalLookupType( const std::string &id ) const;81 const NamedTypeDecl * globalLookupType( const std::string & id ) const; 77 82 /// Gets the struct declaration with the given ID at global scope 78 StructDecl *globalLookupStruct( const std::string &id ) const;83 const StructDecl * globalLookupStruct( const std::string & id ) const; 79 84 /// Gets the union declaration with the given ID at global scope 80 UnionDecl *globalLookupUnion( const std::string &id ) const;85 const UnionDecl * globalLookupUnion( const std::string & id ) const; 81 86 /// Gets the enum declaration with the given ID at global scope 82 EnumDecl *globalLookupEnum( const std::string &id ) const;87 const EnumDecl * globalLookupEnum( const std::string & id ) const; 83 88 84 89 void addId( DeclarationWithType * decl, Expression * baseExpr = nullptr ); 85 90 void addDeletedId( DeclarationWithType * decl, BaseSyntaxNode * deleteStmt ); 86 91 87 void addType( NamedTypeDecl * decl );88 void addStruct( const std::string & id );89 void addStruct( StructDecl * decl );90 void addEnum( EnumDecl * decl );91 void addUnion( const std::string & id );92 void addUnion( UnionDecl * decl );93 void addTrait( TraitDecl * decl );92 void addType( NamedTypeDecl * decl ); 93 void addStruct( const std::string & id ); 94 void addStruct( StructDecl * decl ); 95 void addEnum( EnumDecl * decl ); 96 void addUnion( const std::string & id ); 97 void addUnion( UnionDecl * decl ); 98 void addTrait( TraitDecl * decl ); 94 99 95 100 /// adds all of the IDs from WithStmt exprs … … 106 111 107 112 private: 108 /// Wraps a Decl * with a scope113 /// Wraps a Decl * with a scope 109 114 template<typename Decl> 110 115 struct Scoped { 111 Decl * decl; ///< declaration116 Decl * decl; ///< declaration 112 117 unsigned long scope; ///< scope of this declaration 113 118 114 Scoped(Decl * d, unsigned long s) : decl(d), scope(s) {}119 Scoped(Decl * d, unsigned long s) : decl(d), scope(s) {} 115 120 }; 116 121 … … 140 145 141 146 /// Gets the indexer at the given scope 142 const Indexer * atScope( unsigned long scope ) const;147 const Indexer * atScope( unsigned long scope ) const; 143 148 144 /// Removes matching autogenerated constructors and destructors so that they will not be 149 /// Removes matching autogenerated constructors and destructors so that they will not be 145 150 /// selected. If returns false, passed decl should not be added. 146 151 bool removeSpecialOverrides( IdData& decl, MangleTable::Ptr& mangleTable ); … … 166 171 /// true if the existing identifier conflicts with the added identifier 167 172 bool addedIdConflicts( 168 const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts, 173 const IdData& existing, DeclarationWithType * added, OnConflict handleConflicts, 169 174 BaseSyntaxNode * deleteStmt ); 170 175 171 176 /// common code for addId, addDeletedId, etc. 172 void addId( 173 DeclarationWithType * decl, OnConflict handleConflicts, 177 void addId( 178 DeclarationWithType * decl, OnConflict handleConflicts, 174 179 Expression * baseExpr = nullptr, BaseSyntaxNode * deleteStmt = nullptr ); 175 180 … … 178 183 179 184 /// returns true if there exists a declaration with C linkage and the given name with the same mangled name 180 bool hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const;185 bool hasCompatibleCDecl( const std::string & id, const std::string &mangleName ) const; 181 186 /// returns true if there exists a declaration with C linkage and the given name with a different mangled name 182 bool hasIncompatibleCDecl( const std::string & id, const std::string &mangleName ) const;187 bool hasIncompatibleCDecl( const std::string & id, const std::string &mangleName ) const; 183 188 }; 184 189 } // namespace SymTab -
src/SymTab/Validate.cc
r7870799 ref5b828 119 119 120 120 private: 121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl );121 template< typename AggDecl > void handleAggregate( AggDecl * aggregateDecl ); 122 122 123 123 AggregateDecl * parentAggr = nullptr; … … 134 134 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 135 135 struct EnumAndPointerDecay_old { 136 void previsit( EnumDecl * aggregateDecl );137 void previsit( FunctionType * func );136 void previsit( EnumDecl * aggregateDecl ); 137 void previsit( FunctionType * func ); 138 138 }; 139 139 140 140 /// Associates forward declarations of aggregates with their definitions 141 141 struct LinkReferenceToTypes_old final : public WithIndexer, public WithGuards, public WithVisitorRef<LinkReferenceToTypes_old>, public WithShortCircuiting { 142 LinkReferenceToTypes_old( const Indexer * indexer );143 void postvisit( TypeInstType * typeInst );144 145 void postvisit( EnumInstType * enumInst );146 void postvisit( StructInstType * structInst );147 void postvisit( UnionInstType * unionInst );148 void postvisit( TraitInstType * traitInst );142 LinkReferenceToTypes_old( const Indexer * indexer ); 143 void postvisit( TypeInstType * typeInst ); 144 145 void postvisit( EnumInstType * enumInst ); 146 void postvisit( StructInstType * structInst ); 147 void postvisit( UnionInstType * unionInst ); 148 void postvisit( TraitInstType * traitInst ); 149 149 void previsit( QualifiedType * qualType ); 150 150 void postvisit( QualifiedType * qualType ); 151 151 152 void postvisit( EnumDecl * enumDecl );153 void postvisit( StructDecl * structDecl );154 void postvisit( UnionDecl * unionDecl );152 void postvisit( EnumDecl * enumDecl ); 153 void postvisit( StructDecl * structDecl ); 154 void postvisit( UnionDecl * unionDecl ); 155 155 void postvisit( TraitDecl * traitDecl ); 156 156 157 void previsit( StructDecl * structDecl );158 void previsit( UnionDecl * unionDecl );157 void previsit( StructDecl * structDecl ); 158 void previsit( UnionDecl * unionDecl ); 159 159 160 160 void renameGenericParams( std::list< TypeDecl * > & params ); 161 161 162 162 private: 163 const Indexer * local_indexer;163 const Indexer * local_indexer; 164 164 165 165 typedef std::map< std::string, std::list< EnumInstType * > > ForwardEnumsType; … … 239 239 240 240 template<typename AggDecl> 241 void handleAggregate( AggDecl * aggregateDecl );241 void handleAggregate( AggDecl * aggregateDecl ); 242 242 243 243 void previsit( StructDecl * aggregateDecl ); … … 252 252 static void verify( std::list< Declaration * > &translationUnit ); 253 253 254 void previsit( FunctionDecl * funcDecl );254 void previsit( FunctionDecl * funcDecl ); 255 255 }; 256 256 … … 287 287 Type::StorageClasses storageClasses; 288 288 289 void premutate( ObjectDecl * objectDecl );290 Expression * postmutate( CompoundLiteralExpr * compLitExpr );289 void premutate( ObjectDecl * objectDecl ); 290 Expression * postmutate( CompoundLiteralExpr * compLitExpr ); 291 291 }; 292 292 … … 393 393 } 394 394 395 void validateType( Type * type, const Indexer *indexer ) {395 void validateType( Type * type, const Indexer * indexer ) { 396 396 PassVisitor<EnumAndPointerDecay_old> epc; 397 397 PassVisitor<LinkReferenceToTypes_old> lrt( indexer ); … … 496 496 } 497 497 498 bool shouldHoist( Declaration * decl ) {498 bool shouldHoist( Declaration * decl ) { 499 499 return dynamic_cast< StructDecl * >( decl ) || dynamic_cast< UnionDecl * >( decl ) || dynamic_cast< StaticAssertDecl * >( decl ); 500 500 } … … 515 515 516 516 template< typename AggDecl > 517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) {517 void HoistStruct::handleAggregate( AggDecl * aggregateDecl ) { 518 518 if ( parentAggr ) { 519 519 aggregateDecl->parent = parentAggr; … … 560 560 561 561 562 bool isTypedef( Declaration * decl ) {562 bool isTypedef( Declaration * decl ) { 563 563 return dynamic_cast< TypedefDecl * >( decl ); 564 564 } … … 571 571 572 572 template< typename AggDecl > 573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) {573 void EliminateTypedef::handleAggregate( AggDecl * aggregateDecl ) { 574 574 filter( aggregateDecl->members, isTypedef, true ); 575 575 } … … 586 586 // remove and delete decl stmts 587 587 filter( compoundStmt->kids, [](Statement * stmt) { 588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) {588 if ( DeclStmt * declStmt = dynamic_cast< DeclStmt * >( stmt ) ) { 589 589 if ( dynamic_cast< TypedefDecl * >( declStmt->decl ) ) { 590 590 return true; … … 595 595 } 596 596 597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) {597 void EnumAndPointerDecay_old::previsit( EnumDecl * enumDecl ) { 598 598 // Set the type of each member of the enumeration to be EnumConstant 599 599 for ( std::list< Declaration * >::iterator i = enumDecl->members.begin(); i != enumDecl->members.end(); ++i ) { 600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i );600 ObjectDecl * obj = dynamic_cast< ObjectDecl * >( * i ); 601 601 assert( obj ); 602 602 obj->set_type( new EnumInstType( Type::Qualifiers( Type::Const ), enumDecl->name ) ); … … 627 627 } 628 628 629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) {629 void EnumAndPointerDecay_old::previsit( FunctionType * func ) { 630 630 // Fix up parameters and return types 631 631 fixFunctionList( func->parameters, func->isVarArgs, func ); … … 633 633 } 634 634 635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) {635 LinkReferenceToTypes_old::LinkReferenceToTypes_old( const Indexer * other_indexer ) { 636 636 if ( other_indexer ) { 637 637 local_indexer = other_indexer; … … 641 641 } 642 642 643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) {644 EnumDecl * st = local_indexer->lookupEnum( enumInst->name );643 void LinkReferenceToTypes_old::postvisit( EnumInstType * enumInst ) { 644 EnumDecl * st = local_indexer->lookupMutableEnum( enumInst->name ); 645 645 // it's not a semantic error if the enum is not found, just an implicit forward declaration 646 646 if ( st ) { … … 661 661 } 662 662 663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) {664 StructDecl * st = local_indexer->lookupStruct( structInst->name );663 void LinkReferenceToTypes_old::postvisit( StructInstType * structInst ) { 664 StructDecl * st = local_indexer->lookupMutableStruct( structInst->name ); 665 665 // it's not a semantic error if the struct is not found, just an implicit forward declaration 666 666 if ( st ) { … … 674 674 } 675 675 676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) {677 UnionDecl * un = local_indexer->lookupUnion( unionInst->name );676 void LinkReferenceToTypes_old::postvisit( UnionInstType * unionInst ) { 677 UnionDecl * un = local_indexer->lookupMutableUnion( unionInst->name ); 678 678 // it's not a semantic error if the union is not found, just an implicit forward declaration 679 679 if ( un ) { … … 693 693 void LinkReferenceToTypes_old::postvisit( QualifiedType * qualType ) { 694 694 // linking only makes sense for the 'oldest ancestor' of the qualified type 695 qualType->parent->accept( * visitor );695 qualType->parent->accept( * visitor ); 696 696 } 697 697 … … 762 762 void LinkReferenceToTypes_old::postvisit( TraitInstType * traitInst ) { 763 763 // handle other traits 764 TraitDecl * traitDecl = local_indexer->lookupTrait( traitInst->name );764 TraitDecl * traitDecl = local_indexer->lookupMutableTrait( traitInst->name ); 765 765 if ( ! traitDecl ) { 766 766 SemanticError( traitInst->location, "use of undeclared trait " + traitInst->name ); … … 786 786 } 787 787 788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) {788 void LinkReferenceToTypes_old::postvisit( EnumDecl * enumDecl ) { 789 789 // visit enum members first so that the types of self-referencing members are updated properly 790 790 if ( enumDecl->body ) { … … 792 792 if ( fwds != forwardEnums.end() ) { 793 793 for ( std::list< EnumInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 794 (* inst)->baseEnum = enumDecl;794 (* inst)->baseEnum = enumDecl; 795 795 } // for 796 796 forwardEnums.erase( fwds ); … … 834 834 } 835 835 836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) {836 void LinkReferenceToTypes_old::postvisit( StructDecl * structDecl ) { 837 837 // visit struct members first so that the types of self-referencing members are updated properly 838 838 // xxx - need to ensure that type parameters match up between forward declarations and definition (most importantly, number of type parameters and their defaults) … … 841 841 if ( fwds != forwardStructs.end() ) { 842 842 for ( std::list< StructInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 843 (* inst)->baseStruct = structDecl;843 (* inst)->baseStruct = structDecl; 844 844 } // for 845 845 forwardStructs.erase( fwds ); … … 848 848 } 849 849 850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) {850 void LinkReferenceToTypes_old::postvisit( UnionDecl * unionDecl ) { 851 851 if ( unionDecl->body ) { 852 852 ForwardUnionsType::iterator fwds = forwardUnions.find( unionDecl->name ); 853 853 if ( fwds != forwardUnions.end() ) { 854 854 for ( std::list< UnionInstType * >::iterator inst = fwds->second.begin(); inst != fwds->second.end(); ++inst ) { 855 (* inst)->baseUnion = unionDecl;855 (* inst)->baseUnion = unionDecl; 856 856 } // for 857 857 forwardUnions.erase( fwds ); … … 860 860 } 861 861 862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) {862 void LinkReferenceToTypes_old::postvisit( TypeInstType * typeInst ) { 863 863 // ensure generic parameter instances are renamed like the base type 864 864 if ( inGeneric && typeInst->baseType ) typeInst->name = typeInst->baseType->name; 865 if ( NamedTypeDecl *namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) {866 if ( TypeDecl *typeDecl = dynamic_cast<TypeDecl * >( namedTypeDecl ) ) {867 typeInst->set_isFtype( typeDecl-> get_kind()== TypeDecl::Ftype );865 if ( const NamedTypeDecl * namedTypeDecl = local_indexer->lookupType( typeInst->name ) ) { 866 if ( const TypeDecl * typeDecl = dynamic_cast< const TypeDecl * >( namedTypeDecl ) ) { 867 typeInst->set_isFtype( typeDecl->kind == TypeDecl::Ftype ); 868 868 } // if 869 869 } // if … … 877 877 // expand trait instances into their members 878 878 for ( DeclarationWithType * assertion : asserts ) { 879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) {879 if ( TraitInstType * traitInst = dynamic_cast< TraitInstType * >( assertion->get_type() ) ) { 880 880 // expand trait instance into all of its members 881 881 expandAssertions( traitInst, back_inserter( type->assertions ) ); … … 897 897 } 898 898 899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) {899 void ForallPointerDecay_old::previsit( ObjectDecl * object ) { 900 900 // ensure that operator names only apply to functions or function pointers 901 901 if ( CodeGen::isOperator( object->name ) && ! dynamic_cast< FunctionType * >( object->type->stripDeclarator() ) ) { … … 905 905 } 906 906 907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) {907 void ForallPointerDecay_old::previsit( FunctionDecl * func ) { 908 908 func->fixUniqueId(); 909 909 } … … 961 961 Type * ReplaceTypedef::postmutate( QualifiedType * qualType ) { 962 962 // replacing typedefs only makes sense for the 'oldest ancestor' of the qualified type 963 qualType->parent = qualType->parent->acceptMutator( * visitor );963 qualType->parent = qualType->parent->acceptMutator( * visitor ); 964 964 return qualType; 965 965 } … … 970 970 TypedefMap::const_iterator def = typedefNames.find( typeInst->name ); 971 971 if ( def != typedefNames.end() ) { 972 Type * ret = def->second.first->base->clone();972 Type * ret = def->second.first->base->clone(); 973 973 ret->location = typeInst->location; 974 974 ret->get_qualifiers() |= typeInst->get_qualifiers(); … … 982 982 // place instance parameters on the typedef'd type 983 983 if ( ! typeInst->parameters.empty() ) { 984 ReferenceToType * rtt = dynamic_cast<ReferenceToType*>(ret);984 ReferenceToType * rtt = dynamic_cast<ReferenceToType *>(ret); 985 985 if ( ! rtt ) { 986 986 SemanticError( typeInst->location, "Cannot apply type parameters to base type of " + typeInst->name ); … … 988 988 rtt->parameters.clear(); 989 989 cloneAll( typeInst->parameters, rtt->parameters ); 990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters990 mutateAll( rtt->parameters, * visitor ); // recursively fix typedefs on parameters 991 991 } // if 992 992 delete typeInst; … … 1043 1043 // struct screen; 1044 1044 // because the expansion of the typedef is: 1045 // void rtn( SCREEN * p ) => void rtn( struct screen *p )1045 // void rtn( SCREEN * p ) => void rtn( struct screen * p ) 1046 1046 // hence the type-name "screen" must be defined. 1047 1047 // Note, qualifiers on the typedef are superfluous for the forward declaration. 1048 1048 1049 Type * designatorType = tyDecl->base->stripDeclarator();1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) {1049 Type * designatorType = tyDecl->base->stripDeclarator(); 1050 if ( StructInstType * aggDecl = dynamic_cast< StructInstType * >( designatorType ) ) { 1051 1051 declsToAddBefore.push_back( new StructDecl( aggDecl->name, DeclarationNode::Struct, noAttributes, tyDecl->linkage ) ); 1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) {1052 } else if ( UnionInstType * aggDecl = dynamic_cast< UnionInstType * >( designatorType ) ) { 1053 1053 declsToAddBefore.push_back( new UnionDecl( aggDecl->name, noAttributes, tyDecl->linkage ) ); 1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) {1054 } else if ( EnumInstType * enumDecl = dynamic_cast< EnumInstType * >( designatorType ) ) { 1055 1055 declsToAddBefore.push_back( new EnumDecl( enumDecl->name, noAttributes, tyDecl->linkage ) ); 1056 1056 } // if … … 1078 1078 1079 1079 DeclarationWithType * ReplaceTypedef::postmutate( ObjectDecl * objDecl ) { 1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type?1080 if ( FunctionType * funtype = dynamic_cast<FunctionType *>( objDecl->type ) ) { // function type? 1081 1081 // replace the current object declaration with a function declaration 1082 1082 FunctionDecl * newDecl = new FunctionDecl( objDecl->name, objDecl->get_storageClasses(), objDecl->linkage, funtype, 0, objDecl->attributes, objDecl->get_funcSpec() ); … … 1104 1104 void ReplaceTypedef::addImplicitTypedef( AggDecl * aggDecl ) { 1105 1105 if ( typedefNames.count( aggDecl->get_name() ) == 0 ) { 1106 Type * type = nullptr;1106 Type * type = nullptr; 1107 1107 if ( StructDecl * newDeclStructDecl = dynamic_cast< StructDecl * >( aggDecl ) ) { 1108 1108 type = new StructInstType( Type::Qualifiers(), newDeclStructDecl->get_name() ); … … 1130 1130 GuardScope( typedefNames ); 1131 1131 GuardScope( typedeclNames ); 1132 mutateAll( aggr->parameters, * visitor );1132 mutateAll( aggr->parameters, * visitor ); 1133 1133 1134 1134 // unroll mutateAll for aggr->members so that implicit typedefs for nested types are added to the aggregate body. … … 1137 1137 1138 1138 try { 1139 * i = maybeMutate( *i, *visitor );1139 * i = maybeMutate( * i, * visitor ); 1140 1140 } catch ( SemanticErrorException &e ) { 1141 1141 errors.append( e ); … … 1217 1217 for ( size_t i = 0; paramIter != params->end(); ++paramIter, ++i ) { 1218 1218 if ( i < args.size() ) { 1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) );1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() );1219 TypeExpr * expr = strict_dynamic_cast< TypeExpr * >( * std::next( args.begin(), i ) ); 1220 sub.add( (* paramIter)->get_name(), expr->get_type()->clone() ); 1221 1221 } else if ( i == args.size() ) { 1222 Type * defaultType = (* paramIter)->get_init();1222 Type * defaultType = (* paramIter)->get_init(); 1223 1223 if ( defaultType ) { 1224 1224 args.push_back( new TypeExpr( defaultType->clone() ) ); 1225 sub.add( (* paramIter)->get_name(), defaultType->clone() );1225 sub.add( (* paramIter)->get_name(), defaultType->clone() ); 1226 1226 } 1227 1227 } … … 1242 1242 } 1243 1243 1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) {1244 void CompoundLiteral::premutate( ObjectDecl * objectDecl ) { 1245 1245 storageClasses = objectDecl->get_storageClasses(); 1246 1246 } 1247 1247 1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) {1248 Expression * CompoundLiteral::postmutate( CompoundLiteralExpr * compLitExpr ) { 1249 1249 // transform [storage_class] ... (struct S){ 3, ... }; 1250 1250 // into [storage_class] struct S temp = { 3, ... }; 1251 1251 static UniqueName indexName( "_compLit" ); 1252 1252 1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() );1253 ObjectDecl * tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() ); 1254 1254 compLitExpr->set_result( nullptr ); 1255 1255 compLitExpr->set_initializer( nullptr ); … … 1289 1289 TupleType * tupleType = strict_dynamic_cast< TupleType * >( ResolvExpr::extractResultType( ftype ) ); 1290 1290 // ensure return value is not destructed by explicitly creating an empty ListInit node wherein maybeConstruct is false. 1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) );1291 ObjectDecl * newRet = new ObjectDecl( "", Type::StorageClasses(), LinkageSpec::Cforall, 0, tupleType, new ListInit( std::list<Initializer *>(), noDesignators, false ) ); 1292 1292 deleteAll( retVals ); 1293 1293 retVals.clear(); … … 1302 1302 1303 1303 void FixObjectType::previsit( ObjectDecl * objDecl ) { 1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer );1304 Type * new_type = ResolvExpr::resolveTypeof( objDecl->get_type(), indexer ); 1305 1305 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1306 1306 objDecl->set_type( new_type ); … … 1308 1308 1309 1309 void FixObjectType::previsit( FunctionDecl * funcDecl ) { 1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer );1310 Type * new_type = ResolvExpr::resolveTypeof( funcDecl->type, indexer ); 1311 1311 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1312 1312 funcDecl->set_type( new_type ); 1313 1313 } 1314 1314 1315 void FixObjectType::previsit( TypeDecl * typeDecl ) {1315 void FixObjectType::previsit( TypeDecl * typeDecl ) { 1316 1316 if ( typeDecl->get_base() ) { 1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer );1317 Type * new_type = ResolvExpr::resolveTypeof( typeDecl->get_base(), indexer ); 1318 1318 new_type->get_qualifiers() -= Type::Lvalue; // even if typeof is lvalue, variable can never have lvalue-qualified type 1319 1319 typeDecl->set_base( new_type ); … … 1378 1378 1379 1379 namespace { 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1380 /// Replaces enum types by int, and function/array types in function parameter and return 1381 1381 /// lists by appropriate pointers 1382 1382 struct EnumAndPointerDecay_new { … … 1385 1385 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1386 1386 // build new version of object with EnumConstant 1387 ast::ptr< ast::ObjectDecl > obj = 1387 ast::ptr< ast::ObjectDecl > obj = 1388 1388 enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1389 obj.get_and_mutate()->type = 1389 obj.get_and_mutate()->type = 1390 1390 new ast::EnumInstType{ enumDecl->name, ast::CV::Const }; 1391 1391 1392 1392 // set into decl 1393 1393 ast::EnumDecl * mut = mutate( enumDecl ); … … 1399 1399 1400 1400 static const ast::FunctionType * fixFunctionList( 1401 const ast::FunctionType * func, 1401 const ast::FunctionType * func, 1402 1402 std::vector< ast::ptr< ast::DeclWithType > > ast::FunctionType::* field, 1403 1403 ast::ArgumentFlag isVarArgs = ast::FixedArgs 1404 1404 ) { 1405 const auto & dwts = func->* field;1405 const auto & dwts = func->* field; 1406 1406 unsigned nvals = dwts.size(); 1407 1407 bool hasVoid = false; … … 1409 1409 func = ast::mutate_field_index( func, field, i, fixFunction( dwts[i], hasVoid ) ); 1410 1410 } 1411 1411 1412 1412 // the only case in which "void" is valid is where it is the only one in the list 1413 1413 if ( hasVoid && ( nvals > 1 || isVarArgs ) ) { 1414 SemanticError( 1414 SemanticError( 1415 1415 dwts.front()->location, func, "invalid type void in function type" ); 1416 1416 } … … 1418 1418 // one void is the only thing in the list, remove it 1419 1419 if ( hasVoid ) { 1420 func = ast::mutate_field( 1420 func = ast::mutate_field( 1421 1421 func, field, std::vector< ast::ptr< ast::DeclWithType > >{} ); 1422 1422 } … … 1432 1432 1433 1433 /// expand assertions from a trait instance, performing appropriate type variable substitutions 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1434 void expandAssertions( 1435 const ast::TraitInstType * inst, std::vector< ast::ptr< ast::DeclWithType > > & out 1436 1436 ) { 1437 1437 assertf( inst->base, "Trait instance not linked to base trait: %s", toCString( inst ) ); 1438 1438 1439 1439 // build list of trait members, substituting trait decl parameters for instance parameters 1440 ast::TypeSubstitution sub{ 1440 ast::TypeSubstitution sub{ 1441 1441 inst->base->params.begin(), inst->base->params.end(), inst->params.begin() }; 1442 1442 // deliberately take ast::ptr by-value to ensure this does not mutate inst->base … … 1449 1449 1450 1450 /// Associates forward declarations of aggregates with their definitions 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1451 class LinkReferenceToTypes_new final 1452 : public ast::WithSymbolTable, public ast::WithGuards, public 1453 1453 ast::WithVisitorRef<LinkReferenceToTypes_new>, public ast::WithShortCircuiting { 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in * after* they have been traversed. To enable this in the1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1454 1455 // these maps of uses of forward declarations of types need to have the actual type 1456 // declaration switched in * after * they have been traversed. To enable this in the 1457 // ast::Pass framework, any node that needs to be so mutated has mutate() called on it 1458 // before it is placed in the map, properly updating its parents in the usual traversal, 1459 1459 // then can have the actual mutation applied later 1460 1460 using ForwardEnumsType = std::unordered_multimap< std::string, ast::EnumInstType * >; 1461 1461 using ForwardStructsType = std::unordered_multimap< std::string, ast::StructInstType * >; 1462 1462 using ForwardUnionsType = std::unordered_multimap< std::string, ast::UnionInstType * >; 1463 1463 1464 1464 const CodeLocation & location; 1465 1465 const ast::SymbolTable * localSymtab; 1466 1466 1467 1467 ForwardEnumsType forwardEnums; 1468 1468 ForwardStructsType forwardStructs; 1469 1469 ForwardUnionsType forwardUnions; 1470 1470 1471 /// true if currently in a generic type body, so that type parameter instances can be 1471 /// true if currently in a generic type body, so that type parameter instances can be 1472 1472 /// renamed appropriately 1473 1473 bool inGeneric = false; … … 1475 1475 public: 1476 1476 /// contstruct using running symbol table 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1477 LinkReferenceToTypes_new( const CodeLocation & loc ) 1478 1478 : location( loc ), localSymtab( &symtab ) {} 1479 1479 1480 1480 /// construct using provided symbol table 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1481 LinkReferenceToTypes_new( const CodeLocation & loc, const ast::SymbolTable & syms ) 1482 1482 : location( loc ), localSymtab( &syms ) {} 1483 1483 … … 1485 1485 // ensure generic parameter instances are renamed like the base type 1486 1486 if ( inGeneric && typeInst->base ) { 1487 typeInst = ast::mutate_field( 1487 typeInst = ast::mutate_field( 1488 1488 typeInst, &ast::TypeInstType::name, typeInst->base->name ); 1489 1489 } 1490 1490 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1491 if ( 1492 auto typeDecl = dynamic_cast< const ast::TypeDecl * >( 1493 localSymtab->lookupType( typeInst->name ) ) 1494 1494 ) { 1495 1495 typeInst = ast::mutate_field( typeInst, &ast::TypeInstType::kind, typeDecl->kind ); … … 1517 1517 for ( const ast::Expr * param : inst->params ) { 1518 1518 if ( ! dynamic_cast< const ast::TypeExpr * >( param ) ) { 1519 SemanticError( 1519 SemanticError( 1520 1520 location, inst, "Expression parameters for generic types are currently " 1521 1521 "unsupported: " ); … … 1571 1571 auto expr = traitInst->params[i].as< ast::TypeExpr >(); 1572 1572 if ( ! expr ) { 1573 SemanticError( 1573 SemanticError( 1574 1574 traitInst->params[i].get(), "Expression parameters for trait instances " 1575 1575 "are currently unsupported: " ); … … 1593 1593 return traitInst; 1594 1594 } 1595 1595 1596 1596 void previsit( const ast::QualifiedType * ) { visit_children = false; } 1597 1597 1598 1598 const ast::Type * postvisit( const ast::QualifiedType * qualType ) { 1599 1599 // linking only makes sense for the "oldest ancestor" of the qualified type 1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) );1600 return ast::mutate_field( 1601 qualType, &ast::QualifiedType::parent, qualType->parent->accept( * visitor ) ); 1602 1602 } 1603 1603 1604 1604 const ast::Decl * postvisit( const ast::EnumDecl * enumDecl ) { 1605 // visit enum members first so that the types of self-referencing members are updated 1605 // visit enum members first so that the types of self-referencing members are updated 1606 1606 // properly 1607 1607 if ( ! enumDecl->body ) return enumDecl; … … 1612 1612 auto inst = fwds.first; 1613 1613 do { 1614 // forward decl is stored * mutably* in map, can thus be updated1614 // forward decl is stored * mutably * in map, can thus be updated 1615 1615 inst->second->base = enumDecl; 1616 1616 } while ( ++inst != fwds.second ); 1617 1617 forwardEnums.erase( fwds.first, fwds.second ); 1618 1618 } 1619 1619 1620 1620 // ensure that enumerator initializers are properly set 1621 1621 for ( unsigned i = 0; i < enumDecl->members.size(); ++i ) { 1622 1622 auto field = enumDecl->members[i].strict_as< ast::ObjectDecl >(); 1623 1623 if ( field->init ) { 1624 // need to resolve enumerator initializers early so that other passes that 1624 // need to resolve enumerator initializers early so that other passes that 1625 1625 // determine if an expression is constexpr have appropriate information 1626 1626 auto init = field->init.strict_as< ast::SingleInit >(); 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1627 1628 enumDecl = ast::mutate_field_index( 1629 enumDecl, &ast::EnumDecl::members, i, 1630 ast::mutate_field( field, &ast::ObjectDecl::init, 1631 1631 ast::mutate_field( init, &ast::SingleInit::value, 1632 ResolvExpr::findSingleExpression( 1632 ResolvExpr::findSingleExpression( 1633 1633 init->value, new ast::BasicType{ ast::BasicType::SignedInt }, 1634 1634 symtab ) ) ) ); … … 1639 1639 } 1640 1640 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1641 /// rename generic type parameters uniquely so that they do not conflict with user defined 1642 1642 /// function forall parameters, e.g. the T in Box and the T in f, below 1643 1643 /// forall(otype T) … … 1657 1657 const ast::TypeDecl * td = aggr->params[i]; 1658 1658 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1659 aggr = ast::mutate_field_index( 1660 aggr, &AggrDecl::params, i, 1661 1661 ast::mutate_field( td, &ast::TypeDecl::name, "__" + td->name + "_generic_" ) ); 1662 1662 } … … 1669 1669 1670 1670 void postvisit( const ast::StructDecl * structDecl ) { 1671 // visit struct members first so that the types of self-referencing members are 1671 // visit struct members first so that the types of self-referencing members are 1672 1672 // updated properly 1673 1673 if ( ! structDecl->body ) return; … … 1678 1678 auto inst = fwds.first; 1679 1679 do { 1680 // forward decl is stored * mutably* in map, can thus be updated1680 // forward decl is stored * mutably * in map, can thus be updated 1681 1681 inst->second->base = structDecl; 1682 1682 } while ( ++inst != fwds.second ); … … 1690 1690 1691 1691 void postvisit( const ast::UnionDecl * unionDecl ) { 1692 // visit union members first so that the types of self-referencing members are updated 1692 // visit union members first so that the types of self-referencing members are updated 1693 1693 // properly 1694 1694 if ( ! unionDecl->body ) return; … … 1699 1699 auto inst = fwds.first; 1700 1700 do { 1701 // forward decl is stored * mutably* in map, can thus be updated1701 // forward decl is stored * mutably * in map, can thus be updated 1702 1702 inst->second->base = unionDecl; 1703 1703 } while ( ++inst != fwds.second ); … … 1712 1712 "number of parameters: %zd", traitDecl->params.size() ); 1713 1713 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1714 traitDecl = ast::mutate_field_index( 1715 traitDecl, &ast::TraitDecl::params, 0, 1716 ast::mutate_field( 1717 1717 traitDecl->params.front().get(), &ast::TypeDecl::sized, true ) ); 1718 1718 } … … 1737 1737 traitDecl = mut; 1738 1738 } 1739 1739 1740 1740 return traitDecl; 1741 1741 } 1742 1742 }; 1743 1743 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1744 /// Replaces array and function types in forall lists by appropriate pointer type and assigns 1745 1745 /// each object and function declaration a unique ID 1746 1746 class ForallPointerDecay_new { … … 1751 1751 const ast::ObjectDecl * previsit( const ast::ObjectDecl * obj ) { 1752 1752 // ensure that operator names only apply to functions or function pointers 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1753 if ( 1754 CodeGen::isOperator( obj->name ) 1755 1755 && ! dynamic_cast< const ast::FunctionType * >( obj->type->stripDeclarator() ) 1756 1756 ) { … … 1776 1776 /// Fix up assertions -- flattens assertion lists, removing all trait instances 1777 1777 template< typename node_t, typename parent_t > 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1778 static const node_t * forallFixer( 1779 const CodeLocation & loc, const node_t * node, 1780 1780 ast::ParameterizedType::ForallList parent_t::* forallField 1781 1781 ) { 1782 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) {1783 const ast::TypeDecl * type = (node->* forallField)[i];1782 for ( unsigned i = 0; i < (node->* forallField).size(); ++i ) { 1783 const ast::TypeDecl * type = (node->* forallField)[i]; 1784 1784 if ( type->assertions.empty() ) continue; 1785 1785 … … 1789 1789 // expand trait instances into their members 1790 1790 for ( const ast::DeclWithType * assn : type->assertions ) { 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1791 auto traitInst = 1792 dynamic_cast< const ast::TraitInstType * >( assn->get_type() ); 1793 1793 if ( traitInst ) { 1794 1794 // expand trait instance to all its members … … 1831 1831 } // anonymous namespace 1832 1832 1833 const ast::Type * validateType( 1833 const ast::Type * validateType( 1834 1834 const CodeLocation & loc, const ast::Type * type, const ast::SymbolTable & symtab ) { 1835 1835 ast::Pass< EnumAndPointerDecay_new > epc;
Note: See TracChangeset
for help on using the changeset viewer.