Changeset 81e1f32
- Timestamp:
- Jan 23, 2018, 10:49:53 AM (5 years ago)
- Branches:
- aaron-thesis, arm-eh, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 15d248e, f7d6bb0
- Parents:
- d2d50d7 (diff), fc67d6f (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src
- Files:
-
- 1 added
- 2 deleted
- 25 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/GenType.cc
rd2d50d7 r81e1f32 26 26 27 27 namespace CodeGen { 28 class GenType : public Visitor { 29 public: 28 struct GenType : public WithVisitorRef<GenType>, public WithShortCircuiting { 30 29 GenType( const std::string &typeString, bool pretty = false, bool genC = false, bool lineMarks = false ); 31 30 std::string get_typeString() const { return typeString; } 32 31 void set_typeString( const std::string &newValue ) { typeString = newValue; } 33 32 34 virtual void visit( FunctionType *funcType ); 35 virtual void visit( VoidType *voidType ); 36 virtual void visit( BasicType *basicType ); 37 virtual void visit( PointerType *pointerType ); 38 virtual void visit( ArrayType *arrayType ); 39 virtual void visit( ReferenceType *refType ); 40 virtual void visit( StructInstType *structInst ); 41 virtual void visit( UnionInstType *unionInst ); 42 virtual void visit( EnumInstType *enumInst ); 43 virtual void visit( TypeInstType *typeInst ); 44 virtual void visit( TupleType * tupleType ); 45 virtual void visit( VarArgsType *varArgsType ); 46 virtual void visit( ZeroType *zeroType ); 47 virtual void visit( OneType *oneType ); 33 void previsit( BaseSyntaxNode * ); 34 void postvisit( BaseSyntaxNode * ); 35 36 void postvisit( FunctionType * funcType ); 37 void postvisit( VoidType * voidType ); 38 void postvisit( BasicType * basicType ); 39 void postvisit( PointerType * pointerType ); 40 void postvisit( ArrayType * arrayType ); 41 void postvisit( ReferenceType * refType ); 42 void postvisit( StructInstType * structInst ); 43 void postvisit( UnionInstType * unionInst ); 44 void postvisit( EnumInstType * enumInst ); 45 void postvisit( TypeInstType * typeInst ); 46 void postvisit( TupleType * tupleType ); 47 void postvisit( VarArgsType * varArgsType ); 48 void postvisit( ZeroType * zeroType ); 49 void postvisit( OneType * oneType ); 48 50 49 51 private: … … 59 61 60 62 std::string genType( Type *type, const std::string &baseString, bool pretty, bool genC , bool lineMarks ) { 61 GenTypegt( baseString, pretty, genC, lineMarks );63 PassVisitor<GenType> gt( baseString, pretty, genC, lineMarks ); 62 64 std::ostringstream os; 63 65 … … 68 70 69 71 type->accept( gt ); 70 return os.str() + gt. get_typeString();72 return os.str() + gt.pass.get_typeString(); 71 73 } 72 74 … … 77 79 GenType::GenType( const std::string &typeString, bool pretty, bool genC, bool lineMarks ) : typeString( typeString ), pretty( pretty ), genC( genC ), lineMarks( lineMarks ) {} 78 80 79 void GenType::visit( VoidType *voidType ) { 81 // *** BaseSyntaxNode 82 void GenType::previsit( BaseSyntaxNode * ) { 83 // turn off automatic recursion for all nodes, to allow each visitor to 84 // precisely control the order in which its children are visited. 85 visit_children = false; 86 } 87 88 void GenType::postvisit( BaseSyntaxNode * node ) { 89 std::stringstream ss; 90 node->print( ss ); 91 assertf( false, "Unhandled node reached in GenType: %s", ss.str().c_str() ); 92 } 93 94 void GenType::postvisit( VoidType * voidType ) { 80 95 typeString = "void " + typeString; 81 96 handleQualifiers( voidType ); 82 97 } 83 98 84 void GenType:: visit( BasicType *basicType ) {85 BasicType::Kind kind = basicType-> get_kind();99 void GenType::postvisit( BasicType * basicType ) { 100 BasicType::Kind kind = basicType->kind; 86 101 assert( 0 <= kind && kind < BasicType::NUMBER_OF_BASIC_TYPES ); 87 102 typeString = std::string( BasicType::typeNames[kind] ) + " " + typeString; … … 89 104 } 90 105 91 void GenType::genArray( const Type::Qualifiers & qualifiers, Type *base, Expression *dimension, bool isVarLen, bool isStatic ) {106 void GenType::genArray( const Type::Qualifiers & qualifiers, Type * base, Expression *dimension, bool isVarLen, bool isStatic ) { 92 107 std::ostringstream os; 93 108 if ( typeString != "" ) { … … 126 141 typeString = os.str(); 127 142 128 base->accept( * this);129 } 130 131 void GenType:: visit( PointerType *pointerType ) {132 assert( pointerType-> get_base()!= 0);133 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType-> get_dimension()) {134 genArray( pointerType->get_qualifiers(), pointerType-> get_base(), pointerType->get_dimension(), pointerType->get_isVarLen(), pointerType->get_isStatic() );143 base->accept( *visitor ); 144 } 145 146 void GenType::postvisit( PointerType * pointerType ) { 147 assert( pointerType->base != 0); 148 if ( pointerType->get_isStatic() || pointerType->get_isVarLen() || pointerType->dimension ) { 149 genArray( pointerType->get_qualifiers(), pointerType->base, pointerType->dimension, pointerType->get_isVarLen(), pointerType->get_isStatic() ); 135 150 } else { 136 151 handleQualifiers( pointerType ); … … 140 155 typeString = "*" + typeString; 141 156 } // if 142 pointerType-> get_base()->accept( *this);143 } // if 144 } 145 146 void GenType:: visit( ArrayType *arrayType ) {147 genArray( arrayType->get_qualifiers(), arrayType-> get_base(), arrayType->get_dimension(), arrayType->get_isVarLen(), arrayType->get_isStatic() );148 } 149 150 void GenType:: visit( ReferenceType *refType ) {151 assert( refType-> get_base()!= 0);157 pointerType->base->accept( *visitor ); 158 } // if 159 } 160 161 void GenType::postvisit( ArrayType * arrayType ) { 162 genArray( arrayType->get_qualifiers(), arrayType->base, arrayType->dimension, arrayType->get_isVarLen(), arrayType->get_isStatic() ); 163 } 164 165 void GenType::postvisit( ReferenceType * refType ) { 166 assert( refType->base != 0); 152 167 assertf( ! genC, "Reference types should not reach code generation." ); 153 168 handleQualifiers( refType ); 154 169 typeString = "&" + typeString; 155 refType-> get_base()->accept( *this);156 } 157 158 void GenType:: visit( FunctionType *funcType ) {170 refType->base->accept( *visitor ); 171 } 172 173 void GenType::postvisit( FunctionType * funcType ) { 159 174 std::ostringstream os; 160 175 … … 169 184 /************* parameters ***************/ 170 185 171 const std::list<DeclarationWithType *> &pars = funcType-> get_parameters();186 const std::list<DeclarationWithType *> &pars = funcType->parameters; 172 187 173 188 if ( pars.empty() ) { … … 191 206 typeString = os.str(); 192 207 193 if ( funcType-> get_returnVals().size() == 0 ) {208 if ( funcType->returnVals.size() == 0 ) { 194 209 typeString = "void " + typeString; 195 210 } else { 196 funcType-> get_returnVals().front()->get_type()->accept( *this);211 funcType->returnVals.front()->get_type()->accept( *visitor ); 197 212 } // if 198 213 199 214 // add forall 200 if( ! funcType-> get_forall().empty() && ! genC ) {215 if( ! funcType->forall.empty() && ! genC ) { 201 216 // assertf( ! genC, "Aggregate type parameters should not reach code generation." ); 202 217 std::ostringstream os; 203 218 PassVisitor<CodeGenerator> cg( os, pretty, genC, lineMarks ); 204 219 os << "forall("; 205 cg.pass.genCommaList( funcType-> get_forall().begin(), funcType->get_forall().end() );220 cg.pass.genCommaList( funcType->forall.begin(), funcType->forall.end() ); 206 221 os << ")" << std::endl; 207 222 typeString = os.str() + typeString; … … 221 236 } 222 237 223 void GenType:: visit( StructInstType *structInst ) {224 typeString = structInst-> get_name()+ handleGeneric( structInst ) + " " + typeString;238 void GenType::postvisit( StructInstType * structInst ) { 239 typeString = structInst->name + handleGeneric( structInst ) + " " + typeString; 225 240 if ( genC ) typeString = "struct " + typeString; 226 241 handleQualifiers( structInst ); 227 242 } 228 243 229 void GenType:: visit( UnionInstType *unionInst ) {230 typeString = unionInst-> get_name()+ handleGeneric( unionInst ) + " " + typeString;244 void GenType::postvisit( UnionInstType * unionInst ) { 245 typeString = unionInst->name + handleGeneric( unionInst ) + " " + typeString; 231 246 if ( genC ) typeString = "union " + typeString; 232 247 handleQualifiers( unionInst ); 233 248 } 234 249 235 void GenType:: visit( EnumInstType *enumInst ) {236 typeString = enumInst-> get_name()+ " " + typeString;250 void GenType::postvisit( EnumInstType * enumInst ) { 251 typeString = enumInst->name + " " + typeString; 237 252 if ( genC ) typeString = "enum " + typeString; 238 253 handleQualifiers( enumInst ); 239 254 } 240 255 241 void GenType:: visit( TypeInstType *typeInst ) {242 typeString = typeInst-> get_name()+ " " + typeString;256 void GenType::postvisit( TypeInstType * typeInst ) { 257 typeString = typeInst->name + " " + typeString; 243 258 handleQualifiers( typeInst ); 244 259 } 245 260 246 void GenType:: visit( TupleType * tupleType ) {261 void GenType::postvisit( TupleType * tupleType ) { 247 262 assertf( ! genC, "Tuple types should not reach code generation." ); 248 263 unsigned int i = 0; … … 257 272 } 258 273 259 void GenType:: visit( VarArgsType *varArgsType ) {274 void GenType::postvisit( VarArgsType * varArgsType ) { 260 275 typeString = "__builtin_va_list " + typeString; 261 276 handleQualifiers( varArgsType ); 262 277 } 263 278 264 void GenType:: visit( ZeroType *zeroType ) {279 void GenType::postvisit( ZeroType * zeroType ) { 265 280 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 266 281 typeString = (pretty ? "zero_t " : "long int ") + typeString; … … 268 283 } 269 284 270 void GenType:: visit( OneType *oneType ) {285 void GenType::postvisit( OneType * oneType ) { 271 286 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 272 287 typeString = (pretty ? "one_t " : "long int ") + typeString; … … 274 289 } 275 290 276 void GenType::handleQualifiers( Type * type ) {291 void GenType::handleQualifiers( Type * type ) { 277 292 if ( type->get_const() ) { 278 293 typeString = "const " + typeString; -
src/CodeTools/DeclStats.cc
rd2d50d7 r81e1f32 23 23 #include <utility> // for pair, make_pair 24 24 25 #include "Common/PassVisitor.h" 25 26 #include "Common/SemanticError.h" // for SemanticError 26 27 #include "Common/VectorMap.h" // for VectorMap … … 35 36 namespace CodeTools { 36 37 37 class DeclStats : public Visitor{38 struct DeclStats : public WithShortCircuiting { 38 39 template<typename T> 39 40 static void sum(T& a, const T& b) { a += b; } … … 61 62 62 63 struct ArgPackStats { 63 VectorMap<unsigned> n; ///< Count of decls with each number of elements 64 VectorMap<unsigned> n_basic; ///< Count of decls with each number of basic type elements 65 VectorMap<unsigned> n_poly; ///< Count of decls with each number of polymorphic elements 66 std::map<unsigned, unsigned> p_basic; ///< Count of decls with each percentage of basic type elements 67 std::map<unsigned, unsigned> p_poly; ///< Count of decls with each percentage of polymorphic elements 68 VectorMap<unsigned> n_types; ///< Count of decls with each number of distinct types in the pack 64 VectorMap<unsigned> n; ///< Count of decls with each number of elements 65 VectorMap<unsigned> n_basic; ///< Count of decls with each number of basic type elements 66 VectorMap<unsigned> n_generic; ///< Count of decls with each number of generic type elements 67 VectorMap<unsigned> n_poly; ///< Count of decls with each number of polymorphic elements 68 VectorMap<unsigned> n_compound; ///< Count of decls with each number of non-generic compound types 69 std::map<unsigned, unsigned> p_basic; ///< Count of decls with each percentage of basic type elements 70 std::map<unsigned, unsigned> p_generic; ///< Count of decls with each percentage of generic type elements 71 std::map<unsigned, unsigned> p_poly; ///< Count of decls with each percentage of polymorphic elements 72 std::map<unsigned, unsigned> p_compound; ///< Count of decls with each percentage of non-generic compound type elements 73 VectorMap<unsigned> n_types; ///< Count of decls with each number of distinct types in the pack 69 74 /// Count of decls with each percentage of new types in lists. 70 75 /// Types used in the parameter list that recur in the return list are not considered to be new. … … 74 79 sum(n, o.n); 75 80 sum(n_basic, o.n_basic); 81 sum(n_generic, o.n_generic); 76 82 sum(n_poly, o.n_poly); 83 sum(n_compound, o.n_compound); 77 84 sum(p_basic, o.p_basic); 85 sum(p_generic, o.p_generic); 78 86 sum(p_poly, o.p_poly); 87 sum(p_compound, o.p_compound); 79 88 sum(n_types, o.n_types); 80 89 sum(p_new, o.p_new); … … 88 97 /// Count of declarations with each number of assertion parameters 89 98 VectorMap<unsigned> n_type_params; 99 /// Count of generic types with each number of type parameters 100 VectorMap<unsigned> n_generic_params; 101 /// Count of maximum nesting depth of types 102 VectorMap<unsigned> n_generic_nesting; 90 103 /// Count of declarations with each name 91 104 std::unordered_map<std::string, unsigned> by_name; 92 105 /// Count of uses of each basic type 93 106 std::unordered_map<std::string, unsigned> basic_type_names; 94 /// Count of uses of each non-basic type 107 /// Count of uses of each generic type name (includes "*", "[]", "(*)", "[,]") 108 std::unordered_map<std::string, unsigned> generic_type_names; 109 /// Count of uses of each non-generic aggregate type 95 110 std::unordered_map<std::string, unsigned> compound_type_names; 96 111 /// Count of decls using each basic type 97 112 std::unordered_map<std::string, unsigned> basic_type_decls; 113 /// Count of decls using each generic type (includes "*", "[]", "(*)", "[,]") 114 std::unordered_map<std::string, unsigned> generic_type_decls; 98 115 /// Count of decls using each compound type 99 116 std::unordered_map<std::string, unsigned> compound_type_decls; … … 110 127 ArgPackStats assn_returns; 111 128 112 Stats() : n_decls(0), n_type_params(), by_name(), basic_type_names(), compound_type_names(), basic_type_decls(), compound_type_decls(), params(), returns(), n_assns(), assn_params(), assn_returns() {} 129 Stats() : n_decls(0), n_type_params(), n_generic_params(), n_generic_nesting(), 130 by_name(), basic_type_names(), generic_type_names(), compound_type_names(), 131 basic_type_decls(), generic_type_decls(), compound_type_decls(), params(), 132 returns(), n_assns(), assn_params(), assn_returns() {} 113 133 114 134 public: … … 116 136 sum( n_decls, o.n_decls ); 117 137 sum( n_type_params, o.n_type_params ); 138 sum( n_generic_params, o.n_generic_params ); 139 sum( n_generic_nesting, o.n_generic_nesting ); 118 140 sum( by_name, o.by_name ); 119 141 sum( basic_type_names, o.basic_type_names ); 142 sum( generic_type_names, o.generic_type_names ); 120 143 sum( compound_type_names, o.compound_type_names ); 121 144 sum( basic_type_decls, o.basic_type_decls ); 145 sum( generic_type_decls, o.generic_type_decls ); 122 146 sum( compound_type_decls, o.compound_type_decls ); 123 147 sum( params, o.params ); … … 131 155 }; 132 156 133 Stats for_linkage[LinkageSpec::NoOfSpecs]; ///< Stores separate stats per linkage 157 /// number of counting bins for linkages 158 static const unsigned n_named_specs = 8; 159 /// map from total number of specs to bins 160 static const unsigned ind_for_linkage[16]; 161 162 Stats for_linkage[n_named_specs]; ///< Stores separate stats per linkage 134 163 std::unordered_set<std::string> seen_names; ///< Stores manglenames already seen to avoid double-counting 135 164 Stats total; … … 137 166 std::map<std::pair<unsigned, unsigned>, unsigned> exprs_by_fanout_at_depth; 138 167 168 void countType( const std::string& name, unsigned& n, std::unordered_map<std::string, 169 unsigned>& names, std::unordered_map<std::string, unsigned>& decls, 170 std::unordered_set<std::string>& elSeen ) { 171 ++n; 172 ++names[ name ]; 173 if ( elSeen.insert( name ).second ) { ++decls[ name ]; } 174 } 175 176 void update_max( unsigned& max, unsigned crnt ) { 177 if ( crnt > max ) max = crnt; 178 } 179 180 void analyzeSubtype( Type* ty, Stats& stats, std::unordered_set<std::string>& elSeen, 181 unsigned& n_poly, bool& seen_poly, unsigned& max_depth, unsigned depth ) { 182 unsigned x; 183 analyzeType( ty, stats, elSeen, x, x, n_poly, x, seen_poly, max_depth, depth + 1 ); 184 } 185 186 void analyzeSubtypes( std::list<DeclarationWithType*>& tys, Stats& stats, 187 std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly, 188 unsigned& max_depth, unsigned depth, unsigned& n_subs ) { 189 for ( DeclarationWithType* dwt : tys ) { 190 Type* ty = dwt->get_type(); 191 n_subs += (unsigned)( dynamic_cast<VoidType*>(ty) != nullptr ); 192 analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth ); 193 } 194 } 195 196 void analyzeSubtypes( std::list<Expression*>& tys, Stats& stats, 197 std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly, 198 unsigned& max_depth, unsigned depth ) { 199 for ( Expression* expr : tys ) { 200 TypeExpr* texpr = dynamic_cast<TypeExpr*>(expr); 201 if ( ! texpr ) continue; 202 Type* ty = texpr->get_type(); 203 analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth ); 204 } 205 } 206 207 void analyzeSubtypes( std::list<Type*>& tys, Stats& stats, 208 std::unordered_set<std::string>& elSeen, unsigned& n_poly, bool& seen_poly, 209 unsigned& max_depth, unsigned depth ) { 210 for ( Type* ty : tys ) { 211 analyzeSubtype( ty, stats, elSeen, n_poly, seen_poly, max_depth, depth ); 212 } 213 } 214 215 void analyzeType( Type* ty, Stats& stats, std::unordered_set<std::string>& elSeen, 216 unsigned& n_basic, unsigned& n_generic, unsigned& n_poly, unsigned& n_agg, 217 bool& seen_poly, unsigned& max_depth, unsigned depth = 0 ) { 218 if ( BasicType* bt = dynamic_cast<BasicType*>(ty) ) { 219 std::string name = BasicType::typeNames[ bt->get_kind() ]; 220 countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen ); 221 update_max( max_depth, depth ); 222 } else if ( PointerType* pt = dynamic_cast<PointerType*>(ty) ) { 223 std::string name = "*"; 224 countType( 225 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen); 226 analyzeSubtype( 227 pt->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth ); 228 ++stats.n_generic_params.at( 1 ); 229 } else if ( ArrayType* at = dynamic_cast<ArrayType*>(ty) ) { 230 std::string name = "[]"; 231 countType( 232 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen); 233 analyzeSubtype( 234 at->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth ); 235 ++stats.n_generic_params.at( 1 ); 236 } else if ( ReferenceType* rt = dynamic_cast<ReferenceType*>(ty) ) { 237 std::string name = "&"; 238 countType( 239 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen); 240 analyzeSubtype( 241 rt->get_base(), stats, elSeen, n_poly, seen_poly, max_depth, depth ); 242 ++stats.n_generic_params.at( 1 ); 243 } else if ( FunctionType* ft = dynamic_cast<FunctionType*>(ty) ) { 244 std::string name = "(*)"; 245 countType( 246 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen); 247 unsigned n_subs = 0; 248 analyzeSubtypes( 249 ft->get_returnVals(), stats, elSeen, n_poly, seen_poly, max_depth, depth, 250 n_subs ); 251 analyzeSubtypes( 252 ft->get_parameters(), stats, elSeen, n_poly, seen_poly, max_depth, depth, 253 n_subs ); 254 ++stats.n_generic_params.at( n_subs ); 255 } else if ( TypeInstType* vt = dynamic_cast<TypeInstType*>(ty) ) { 256 if ( ! seen_poly ) { 257 ++n_poly; 258 seen_poly = true; 259 } 260 countType( 261 vt->get_name(), n_agg, stats.compound_type_names, stats.compound_type_decls, 262 elSeen ); 263 update_max( max_depth, depth ); 264 } else if ( ReferenceToType* st = dynamic_cast<ReferenceToType*>(ty) ) { 265 std::list<Expression*>& params = st->get_parameters(); 266 if ( params.empty() ) { 267 countType( 268 st->get_name(), n_agg, stats.compound_type_names, 269 stats.compound_type_decls, elSeen ); 270 update_max( max_depth, depth ); 271 } else { 272 countType( 273 st->get_name(), n_generic, stats.generic_type_names, 274 stats.generic_type_decls, elSeen); 275 analyzeSubtypes( params, stats, elSeen, n_poly, seen_poly, max_depth, depth ); 276 ++stats.n_generic_params.at( params.size() ); 277 } 278 } else if ( TupleType* tt = dynamic_cast<TupleType*>(ty) ) { 279 std::string name = "[,]"; 280 countType( 281 name, n_generic, stats.generic_type_names, stats.generic_type_decls, elSeen); 282 analyzeSubtypes( 283 tt->get_types(), stats, elSeen, n_poly, seen_poly, max_depth, depth ); 284 ++stats.n_generic_params.at( tt->size() ); 285 } else if ( dynamic_cast<VarArgsType*>(ty) ) { 286 std::string name = "..."; 287 countType( 288 name, n_agg, stats.compound_type_names, stats.compound_type_decls, elSeen ); 289 update_max( max_depth, depth ); 290 } else if ( dynamic_cast<ZeroType*>(ty) ) { 291 std::string name = "0"; 292 countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen ); 293 update_max( max_depth, depth ); 294 } else if ( dynamic_cast<OneType*>(ty) ) { 295 std::string name = "1"; 296 countType( name, n_basic, stats.basic_type_names, stats.basic_type_decls, elSeen ); 297 update_max( max_depth, depth ); 298 } 299 } 300 139 301 /// Update arg pack stats based on a declaration list 140 void analyze( Stats& stats, std::unordered_set<std::string>& seen, ArgPackStats& pstats, std::list<DeclarationWithType*>& decls ) { 302 void analyze( Stats& stats, std::unordered_set<std::string>& seen, 303 std::unordered_set<std::string>& elSeen, ArgPackStats& pstats, 304 std::list<DeclarationWithType*>& decls ) { 141 305 std::unordered_set<std::string> types; 142 unsigned n = 0; ///< number of args/returns 143 unsigned n_basic = 0; ///< number of basic types 144 unsigned n_poly = 0; ///< number of polymorphic types 145 unsigned n_new = 0; ///< number of new types 306 unsigned n = 0; ///< number of args/returns 307 unsigned n_basic = 0; ///< number of basic types 308 unsigned n_generic = 0; ///< number of generic types (includes "*", "&", "[]", "(*)", "[,]") 309 unsigned n_poly = 0; ///< number of polymorphic types 310 unsigned n_agg = 0; ///< number of non-generic aggregate types 311 unsigned n_new = 0; ///< number of new types 312 146 313 for ( auto decl : decls ) { 147 314 Type* dt = decl->get_type(); … … 152 319 dt->print( ss ); 153 320 types.insert( ss.str() ); 154 bool this_new = seen.insert( ss.str() ).second; 155 if ( this_new ) { ++n_new; } 156 157 if ( dynamic_cast<BasicType*>( dt ) ) { 158 ++n_basic; 159 ++stats.basic_type_names[ ss.str() ]; 160 if ( this_new ) { 161 ++stats.basic_type_decls[ ss.str() ]; 162 } 163 } else if ( GenPoly::hasPolyBase( dt ) ) { 164 ++n_poly; 165 } else { 166 ++stats.compound_type_names[ ss.str() ]; 167 if ( this_new ) { 168 ++stats.compound_type_decls[ ss.str() ]; 169 } 170 } 171 } 321 if ( seen.insert( ss.str() ).second ) { ++n_new; } 322 323 bool seen_poly = false; 324 unsigned max_depth = 0; 325 analyzeType( 326 dt, stats, elSeen, n_basic, n_generic, n_poly, n_agg, seen_poly, max_depth ); 327 ++stats.n_generic_nesting.at( max_depth ); 328 } 329 172 330 ++pstats.n.at( n ); 173 331 ++pstats.n_basic.at( n_basic ); 332 ++pstats.n_generic.at( n_generic ); 174 333 ++pstats.n_poly.at( n_poly ); 334 ++pstats.n_compound.at( n_agg ); 175 335 if ( n > 0 ) { 176 336 ++pstats.p_basic[ n_basic*100/n ]; 337 ++pstats.p_generic[ n_generic*100/n ]; 177 338 ++pstats.p_poly[ n_poly*100/n ]; 178 ++pstats.p_new[ n_new*100/n ]; 339 ++pstats.p_compound[ n_agg*100/n ]; 340 if ( n > 1 ) ++pstats.p_new[ (n_new-1)*100/(n-1) ]; 179 341 } 180 342 ++pstats.n_types.at( types.size() ); … … 183 345 void analyzeFunc( FunctionType* fnTy, Stats& stats, ArgPackStats& params, ArgPackStats& returns ) { 184 346 std::unordered_set<std::string> seen; 185 analyze( stats, seen, params, fnTy->get_parameters() ); 186 analyze( stats, seen, returns, fnTy->get_returnVals() ); 347 std::unordered_set<std::string> elSeen; 348 analyze( stats, seen, elSeen, params, fnTy->get_parameters() ); 349 analyze( stats, seen, elSeen, returns, fnTy->get_returnVals() ); 187 350 } 188 351 … … 200 363 201 364 public: 202 using Visitor::visit; 203 204 virtual void visit( FunctionDecl *decl ) { 365 void previsit( FunctionDecl *decl ) { 205 366 // skip if already seen declaration for this function 206 const std::string& mangleName = decl->get_mangleName().empty() ? decl->get_name() : decl->get_mangleName(); 207 if ( ! seen_names.insert( mangleName ).second ) { 208 maybeAccept( decl->get_statements(), *this ); 209 return; 210 } 211 212 Stats& stats = for_linkage[ decl->get_linkage() ]; 213 214 ++stats.n_decls; 215 FunctionType* fnTy = decl->get_functionType(); 216 const Type::ForallList& forall = fnTy->get_forall(); 217 ++stats.n_type_params.at( forall.size() ); 218 unsigned n_assns = 0; 219 for ( TypeDecl* fdecl : forall ) { 220 n_assns += fdecl->get_assertions().size(); 221 for ( DeclarationWithType* assn : fdecl->get_assertions() ) { 222 FunctionType *assnTy = 0; 223 if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) { 224 if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) { 225 assnTy = dynamic_cast<FunctionType*>(ptrTy->get_base()); 226 } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type()); 227 } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) { 228 assnTy = assnDecl->get_functionType(); 367 const std::string& mangleName = decl->get_mangleName().empty() ? decl->name : decl->get_mangleName(); 368 if ( seen_names.insert( mangleName ).second ) { 369 Stats& stats = for_linkage[ ind_for_linkage[ decl->linkage ] ]; 370 371 ++stats.n_decls; 372 FunctionType* fnTy = decl->type; 373 const Type::ForallList& forall = fnTy->forall; 374 ++stats.n_type_params.at( forall.size() ); 375 unsigned n_assns = 0; 376 for ( TypeDecl* fdecl : forall ) { 377 n_assns += fdecl->assertions.size(); 378 for ( DeclarationWithType* assn : fdecl->assertions ) { 379 FunctionType *assnTy = nullptr; 380 if ( ObjectDecl *assnObj = dynamic_cast<ObjectDecl*>(assn) ) { 381 if ( PointerType *ptrTy = dynamic_cast<PointerType*>(assnObj->get_type()) ) { 382 assnTy = dynamic_cast<FunctionType*>(ptrTy->base); 383 } else assnTy = dynamic_cast<FunctionType*>(assnObj->get_type()); 384 } else if ( FunctionDecl *assnDecl = dynamic_cast<FunctionDecl*>(assn) ) { 385 assnTy = assnDecl->type; 386 } 387 if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns ); 229 388 } 230 if ( assnTy ) analyzeFunc( assnTy, stats, stats.assn_params, stats.assn_returns ); 231 } 232 } 233 ++stats.n_assns[ n_assns ]; 234 235 ++stats.by_name[ decl->get_name() ]; 236 237 analyzeFunc( fnTy, stats, stats.params, stats.returns ); 238 239 // analyze expressions in decl statements 240 maybeAccept( decl->get_statements(), *this ); 241 } 242 243 virtual void visit( UntypedExpr *expr ) { 389 } 390 ++stats.n_assns[ n_assns ]; 391 ++stats.by_name[ decl->name ]; 392 analyzeFunc( fnTy, stats, stats.params, stats.returns ); 393 } 394 } 395 396 void previsit( UntypedExpr *expr ) { 397 visit_children = false; 244 398 analyzeExpr( expr, 0 ); 245 399 } … … 272 426 template<typename F> 273 427 void printAllHisto( const std::string& name, F extract ) { 274 VectorMap<unsigned> histos[ LinkageSpec::NoOfSpecs];428 VectorMap<unsigned> histos[n_named_specs]; 275 429 VectorMap<unsigned> thisto; 276 430 277 431 for ( const auto& entry : extract(total) ) { ++thisto.at( entry.second ); } 278 432 279 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {433 for ( unsigned i = 0; i < n_named_specs; ++i ) { 280 434 // can't be a higher count in one of the sub-histograms than the total 281 435 histos[i].reserve( thisto.size() ); … … 295 449 template<typename F> 296 450 void printAllSparseHisto( const std::string& name, F extract ) { 297 std::map<unsigned, unsigned> histos[ LinkageSpec::NoOfSpecs];451 std::map<unsigned, unsigned> histos[n_named_specs]; 298 452 std::map<unsigned, unsigned> thisto; 299 453 300 454 for ( const auto& entry : extract(total) ) { ++thisto[ entry.second ]; } 301 455 302 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {456 for ( unsigned i = 0; i < n_named_specs; ++i ) { 303 457 for ( const auto& entry : extract(for_linkage[i]) ) { ++histos[i][entry.second]; } 304 458 } … … 307 461 const auto& key = entry.first; 308 462 std::cout << "\"" << name << "\"," << key; 309 for ( unsigned i = 0; i < LinkageSpec::NoOfSpecs; ++i ) {463 for ( unsigned i = 0; i < n_named_specs; ++i ) { 310 464 auto it = histos[i].find( key ); 311 465 if ( it == histos[i].end() ) std::cout << ",0"; … … 319 473 void printAllPack( const std::string& name, F extract ) { 320 474 printAllMap("n_basic_" + name, [&extract](const Stats& stats) { return extract(stats).n_basic; }); 475 printAllMap("n_generic_" + name, [&extract](const Stats& stats) { return extract(stats).n_generic; }); 321 476 printAllMap("n_poly_" + name, [&extract](const Stats& stats) { return extract(stats).n_poly; }); 477 printAllMap("n_compound_" + name, [&extract](const Stats& stats) { return extract(stats).n_compound; }); 322 478 printAllMap("n_" + name, [&extract](const Stats& stats) { return extract(stats).n; }); 323 479 printAllMap("%_basic_" + name, [&extract](const Stats& stats) { return extract(stats).p_basic; }); 480 printAllMap("%_generic_" + name, [&extract](const Stats& stats) { return extract(stats).p_generic; }); 324 481 printAllMap("%_poly_" + name, [&extract](const Stats& stats) { return extract(stats).p_poly; }); 482 printAllMap("%_compound_" + name, [&extract](const Stats& stats) { return extract(stats).p_compound; }); 325 483 printAllMap("n_distinct_types_" + name, [&extract](const Stats& stats) { return extract(stats).n_types; }); 326 484 printAllMap("%_new_types_in_" + name, [&extract](const Stats& stats) { return extract(stats).p_new; }); … … 342 500 } 343 501 344 std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\" builtin\",\"TOTAL\"" << std::endl;502 std::cout << ",,\"intrinsic\",\"Cforall\",\"C\",\"autogen\",\"compiler\",\"builtinCFA\",\"builtinC\",\"other\",\"TOTAL\"" << std::endl; 345 503 346 504 printAllMap("n_type_params", [](const Stats& stats) { return stats.n_type_params; }); 505 printAllMap("n_generic_params", [](const Stats& stats) { return stats.n_generic_params; }); 506 printAllMap("n_generic_nesting", [](const Stats& stats) { return stats.n_generic_nesting; }); 347 507 printAll("n_decls", [](const Stats& stats) { return stats.n_decls; }); 348 508 printAll("unique_names", [](const Stats& stats) { return stats.by_name.size(); }); … … 351 511 printAllSparseHisto("basic_type_uses", [](const Stats& stats) { return stats.basic_type_names; }); 352 512 printAllSparseHisto("decls_using_basic_type", [](const Stats& stats) { return stats.basic_type_decls; }); 513 printAll("generic_type_names", [](const Stats& stats) { return stats.generic_type_names.size(); }); 514 printAllSparseHisto("generic_type_uses", [](const Stats& stats) { return stats.generic_type_names; }); 515 printAllSparseHisto("decls_using_generic_type", [](const Stats& stats) { return stats.generic_type_decls; }); 353 516 printAll("compound_type_names", [](const Stats& stats) { return stats.compound_type_names.size(); }); 354 517 printAllSparseHisto("compound_type_uses", [](const Stats& stats) { return stats.compound_type_names; }); … … 365 528 }; 366 529 530 const unsigned DeclStats::ind_for_linkage[] 531 = { 7, 7, 2, 1, 7, 7, 7, 3, 4, 7, 6, 5, 7, 7, 7, 0 }; 532 367 533 void printDeclStats( std::list< Declaration * > &translationUnit ) { 368 DeclStatsstats;534 PassVisitor<DeclStats> stats; 369 535 acceptAll( translationUnit, stats ); 370 stats.p rint();536 stats.pass.print(); 371 537 } 372 538 -
src/Common/PassVisitor.h
rd2d50d7 r81e1f32 119 119 virtual void visit( StmtExpr * stmtExpr ) override final; 120 120 virtual void visit( UniqueExpr * uniqueExpr ) override final; 121 virtual void visit( UntypedInitExpr * initExpr ) override final; 122 virtual void visit( InitExpr * initExpr ) override final; 121 123 122 124 virtual void visit( VoidType * basicType ) override final; … … 211 213 virtual Expression * mutate( StmtExpr * stmtExpr ) override final; 212 214 virtual Expression * mutate( UniqueExpr * uniqueExpr ) override final; 215 virtual Expression * mutate( UntypedInitExpr * initExpr ) override final; 216 virtual Expression * mutate( InitExpr * initExpr ) override final; 213 217 214 218 virtual Type * mutate( VoidType * basicType ) override final; -
src/Common/PassVisitor.impl.h
rd2d50d7 r81e1f32 1853 1853 } 1854 1854 1855 //-------------------------------------------------------------------------- 1856 // UntypedInitExpr 1857 template< typename pass_type > 1858 void PassVisitor< pass_type >::visit( UntypedInitExpr * node ) { 1859 VISIT_START( node ); 1860 1861 indexerScopedAccept( node->result, *this ); 1862 maybeAccept_impl ( node->expr , *this ); 1863 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 1864 1865 VISIT_END( node ); 1866 } 1867 1868 template< typename pass_type > 1869 Expression * PassVisitor< pass_type >::mutate( UntypedInitExpr * node ) { 1870 MUTATE_START( node ); 1871 1872 indexerScopedMutate( node->env , *this ); 1873 indexerScopedMutate( node->result, *this ); 1874 maybeMutate_impl ( node->expr , *this ); 1875 // not currently visiting initAlts, but this doesn't matter since this node is only used in the resolver. 1876 1877 MUTATE_END( Expression, node ); 1878 } 1879 1880 //-------------------------------------------------------------------------- 1881 // InitExpr 1882 template< typename pass_type > 1883 void PassVisitor< pass_type >::visit( InitExpr * node ) { 1884 VISIT_START( node ); 1885 1886 indexerScopedAccept( node->result, *this ); 1887 maybeAccept_impl ( node->expr , *this ); 1888 maybeAccept_impl ( node->designation, *this ); 1889 1890 VISIT_END( node ); 1891 } 1892 1893 template< typename pass_type > 1894 Expression * PassVisitor< pass_type >::mutate( InitExpr * node ) { 1895 MUTATE_START( node ); 1896 1897 indexerScopedMutate( node->env , *this ); 1898 indexerScopedMutate( node->result, *this ); 1899 maybeMutate_impl ( node->expr , *this ); 1900 maybeMutate_impl ( node->designation, *this ); 1901 1902 MUTATE_END( Expression, node ); 1903 } 1904 1855 1905 template< typename pass_type > 1856 1906 void PassVisitor< pass_type >::visit( VoidType * node ) { -
src/ControlStruct/ExceptTranslate.cc
rd2d50d7 r81e1f32 316 316 VarExprReplacer::DeclMap mapping; 317 317 mapping[ handler_decl ] = local_except; 318 VarExprReplacer mapper( mapping ); 319 handler->get_body()->accept( mapper ); 318 VarExprReplacer::replace( handler->body, mapping ); 320 319 } 321 320 -
src/ResolvExpr/AlternativeFinder.cc
rd2d50d7 r81e1f32 60 60 61 61 namespace ResolvExpr { 62 struct AlternativeFinder::Finder : public WithShortCircuiting { 63 Finder( AlternativeFinder & altFinder ) : altFinder( altFinder ), indexer( altFinder.indexer ), alternatives( altFinder.alternatives ), env( altFinder.env ), targetType( altFinder.targetType ) {} 64 65 void previsit( BaseSyntaxNode * ) { visit_children = false; } 66 67 void postvisit( ApplicationExpr * applicationExpr ); 68 void postvisit( UntypedExpr * untypedExpr ); 69 void postvisit( AddressExpr * addressExpr ); 70 void postvisit( LabelAddressExpr * labelExpr ); 71 void postvisit( CastExpr * castExpr ); 72 void postvisit( VirtualCastExpr * castExpr ); 73 void postvisit( UntypedMemberExpr * memberExpr ); 74 void postvisit( MemberExpr * memberExpr ); 75 void postvisit( NameExpr * variableExpr ); 76 void postvisit( VariableExpr * variableExpr ); 77 void postvisit( ConstantExpr * constantExpr ); 78 void postvisit( SizeofExpr * sizeofExpr ); 79 void postvisit( AlignofExpr * alignofExpr ); 80 void postvisit( UntypedOffsetofExpr * offsetofExpr ); 81 void postvisit( OffsetofExpr * offsetofExpr ); 82 void postvisit( OffsetPackExpr * offsetPackExpr ); 83 void postvisit( AttrExpr * attrExpr ); 84 void postvisit( LogicalExpr * logicalExpr ); 85 void postvisit( ConditionalExpr * conditionalExpr ); 86 void postvisit( CommaExpr * commaExpr ); 87 void postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ); 88 void postvisit( ConstructorExpr * ctorExpr ); 89 void postvisit( RangeExpr * rangeExpr ); 90 void postvisit( UntypedTupleExpr * tupleExpr ); 91 void postvisit( TupleExpr * tupleExpr ); 92 void postvisit( TupleIndexExpr * tupleExpr ); 93 void postvisit( TupleAssignExpr * tupleExpr ); 94 void postvisit( UniqueExpr * unqExpr ); 95 void postvisit( StmtExpr * stmtExpr ); 96 void postvisit( UntypedInitExpr * initExpr ); 97 98 /// Adds alternatives for anonymous members 99 void addAnonConversions( const Alternative & alt ); 100 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 101 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 102 /// Adds alternatives for member expressions where the left side has tuple type 103 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 104 /// Adds alternatives for offsetof expressions, given the base type and name of the member 105 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 106 /// Takes a final result and checks if its assertions can be satisfied 107 template<typename OutputIterator> 108 void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out ); 109 /// Finds matching alternatives for a function, given a set of arguments 110 template<typename OutputIterator> 111 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 112 /// Checks if assertion parameters match for a new alternative 113 template< typename OutputIterator > 114 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 115 private: 116 AlternativeFinder & altFinder; 117 const SymTab::Indexer &indexer; 118 AltList & alternatives; 119 const TypeEnvironment &env; 120 Type *& targetType; 121 }; 122 62 123 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer, TypeEnvironment &env ) { 63 124 CastExpr *castToVoid = new CastExpr( expr ); … … 152 213 153 214 void renameTypes( Expression *expr ) { 154 expr->get_result()->accept( global_renamer);215 renameTyVars( expr->result ); 155 216 } 156 217 } // namespace … … 185 246 186 247 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast ) { 187 expr->accept( *this ); 248 PassVisitor<Finder> finder( *this ); 249 expr->accept( finder ); 188 250 if ( failFast && alternatives.empty() ) { 189 251 PRINT( … … 244 306 } 245 307 246 void AlternativeFinder:: addAnonConversions( const Alternative & alt ) {308 void AlternativeFinder::Finder::addAnonConversions( const Alternative & alt ) { 247 309 // adds anonymous member interpretations whenever an aggregate value type is seen. 248 310 // it's okay for the aggregate expression to have reference type -- cast it to the base type to treat the aggregate as the referenced value … … 265 327 266 328 template< typename StructOrUnionType > 267 void AlternativeFinder:: addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {329 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 268 330 // by this point, member must be a name expr 269 331 NameExpr * nameExpr = dynamic_cast< NameExpr * >( member ); … … 284 346 } 285 347 286 void AlternativeFinder:: addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) {348 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ) { 287 349 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 288 350 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 308 370 } 309 371 310 void AlternativeFinder:: visit( ApplicationExpr *applicationExpr ) {372 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 311 373 alternatives.push_back( Alternative( applicationExpr->clone(), env, Cost::zero ) ); 312 374 } … … 485 547 Type *adjType = candidate->get_type()->clone(); 486 548 adjustExprType( adjType, newEnv, indexer ); 487 adjType->accept( global_renamer);549 renameTyVars( adjType ); 488 550 PRINT( 489 551 std::cerr << "unifying "; … … 541 603 542 604 template< typename OutputIterator > 543 void AlternativeFinder:: inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) {605 void AlternativeFinder::Finder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) { 544 606 // PRINT( 545 607 // std::cerr << "inferParameters: assertions needed are" << std::endl; … … 595 657 596 658 ArgPack() 597 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 659 : parent(0), expr(), cost(Cost::zero), env(), need(), have(), openVars(), nextArg(0), 598 660 tupleStart(0), nextExpl(0), explAlt(0) {} 599 661 … … 706 768 707 769 if ( nTuples > 0 || ! results[i].expr ) { 708 // first iteration or no expression to clone, 770 // first iteration or no expression to clone, 709 771 // push empty tuple expression 710 772 newResult.parent = i; … … 892 954 893 955 template<typename OutputIterator> 894 void AlternativeFinder:: validateFunctionAlternative( const Alternative &func, ArgPack& result,956 void AlternativeFinder::Finder::validateFunctionAlternative( const Alternative &func, ArgPack& result, 895 957 const std::vector<ArgPack>& results, OutputIterator out ) { 896 958 ApplicationExpr *appExpr = new ApplicationExpr( func.expr->clone() ); … … 915 977 916 978 template<typename OutputIterator> 917 void AlternativeFinder:: makeFunctionAlternatives( const Alternative &func,979 void AlternativeFinder::Finder::makeFunctionAlternatives( const Alternative &func, 918 980 FunctionType *funcType, const ExplodedArgs &args, OutputIterator out ) { 919 981 OpenVarSet funcOpenVars; … … 1022 1084 } 1023 1085 1024 void AlternativeFinder:: visit( UntypedExpr *untypedExpr ) {1086 void AlternativeFinder::Finder::postvisit( UntypedExpr *untypedExpr ) { 1025 1087 AlternativeFinder funcFinder( indexer, env ); 1026 1088 funcFinder.findWithAdjustment( untypedExpr->get_function() ); … … 1029 1091 1030 1092 std::vector< AlternativeFinder > argAlternatives; 1031 findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(),1093 altFinder.findSubExprs( untypedExpr->begin_args(), untypedExpr->end_args(), 1032 1094 back_inserter( argAlternatives ) ); 1033 1095 1034 1096 // take care of possible tuple assignments 1035 1097 // if not tuple assignment, assignment is taken care of as a normal function call 1036 Tuples::handleTupleAssignment( *this, untypedExpr, argAlternatives );1098 Tuples::handleTupleAssignment( altFinder, untypedExpr, argAlternatives ); 1037 1099 1038 1100 // find function operators … … 1172 1234 // fix this issue in a more robust way. 1173 1235 targetType = nullptr; 1174 visit( untypedExpr );1236 postvisit( untypedExpr ); 1175 1237 } 1176 1238 } … … 1181 1243 } 1182 1244 1183 void AlternativeFinder:: visit( AddressExpr *addressExpr ) {1245 void AlternativeFinder::Finder::postvisit( AddressExpr *addressExpr ) { 1184 1246 AlternativeFinder finder( indexer, env ); 1185 1247 finder.find( addressExpr->get_arg() ); … … 1192 1254 } 1193 1255 1194 void AlternativeFinder:: visit( LabelAddressExpr * expr ) {1256 void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) { 1195 1257 alternatives.push_back( Alternative{ expr->clone(), env, Cost::zero } ); 1196 1258 } … … 1223 1285 } 1224 1286 1225 void AlternativeFinder:: visit( CastExpr *castExpr ) {1287 void AlternativeFinder::Finder::postvisit( CastExpr *castExpr ) { 1226 1288 Type *& toType = castExpr->get_result(); 1227 1289 assert( toType ); … … 1278 1340 } 1279 1341 1280 void AlternativeFinder:: visit( VirtualCastExpr * castExpr ) {1342 void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) { 1281 1343 assertf( castExpr->get_result(), "Implicate virtual cast targets not yet supported." ); 1282 1344 AlternativeFinder finder( indexer, env ); … … 1290 1352 } 1291 1353 1292 void AlternativeFinder:: visit( UntypedMemberExpr *memberExpr ) {1354 void AlternativeFinder::Finder::postvisit( UntypedMemberExpr *memberExpr ) { 1293 1355 AlternativeFinder funcFinder( indexer, env ); 1294 1356 funcFinder.findWithAdjustment( memberExpr->get_aggregate() ); … … 1312 1374 } 1313 1375 1314 void AlternativeFinder:: visit( MemberExpr *memberExpr ) {1376 void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) { 1315 1377 alternatives.push_back( Alternative( memberExpr->clone(), env, Cost::zero ) ); 1316 1378 } 1317 1379 1318 void AlternativeFinder:: visit( NameExpr *nameExpr ) {1380 void AlternativeFinder::Finder::postvisit( NameExpr *nameExpr ) { 1319 1381 std::list< SymTab::Indexer::IdData > declList; 1320 1382 indexer.lookupId( nameExpr->get_name(), declList ); … … 1337 1399 } 1338 1400 1339 void AlternativeFinder:: visit( VariableExpr *variableExpr ) {1401 void AlternativeFinder::Finder::postvisit( VariableExpr *variableExpr ) { 1340 1402 // not sufficient to clone here, because variable's type may have changed 1341 1403 // since the VariableExpr was originally created. … … 1343 1405 } 1344 1406 1345 void AlternativeFinder:: visit( ConstantExpr *constantExpr ) {1407 void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) { 1346 1408 alternatives.push_back( Alternative( constantExpr->clone(), env, Cost::zero ) ); 1347 1409 } 1348 1410 1349 void AlternativeFinder:: visit( SizeofExpr *sizeofExpr ) {1411 void AlternativeFinder::Finder::postvisit( SizeofExpr *sizeofExpr ) { 1350 1412 if ( sizeofExpr->get_isType() ) { 1351 1413 Type * newType = sizeofExpr->get_type()->clone(); … … 1368 1430 } 1369 1431 1370 void AlternativeFinder:: visit( AlignofExpr *alignofExpr ) {1432 void AlternativeFinder::Finder::postvisit( AlignofExpr *alignofExpr ) { 1371 1433 if ( alignofExpr->get_isType() ) { 1372 1434 Type * newType = alignofExpr->get_type()->clone(); … … 1390 1452 1391 1453 template< typename StructOrUnionType > 1392 void AlternativeFinder:: addOffsetof( StructOrUnionType *aggInst, const std::string &name ) {1454 void AlternativeFinder::Finder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) { 1393 1455 std::list< Declaration* > members; 1394 1456 aggInst->lookup( name, members ); … … 1403 1465 } 1404 1466 1405 void AlternativeFinder:: visit( UntypedOffsetofExpr *offsetofExpr ) {1467 void AlternativeFinder::Finder::postvisit( UntypedOffsetofExpr *offsetofExpr ) { 1406 1468 AlternativeFinder funcFinder( indexer, env ); 1407 1469 // xxx - resolveTypeof? … … 1413 1475 } 1414 1476 1415 void AlternativeFinder:: visit( OffsetofExpr *offsetofExpr ) {1477 void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) { 1416 1478 alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) ); 1417 1479 } 1418 1480 1419 void AlternativeFinder:: visit( OffsetPackExpr *offsetPackExpr ) {1481 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1420 1482 alternatives.push_back( Alternative( offsetPackExpr->clone(), env, Cost::zero ) ); 1421 1483 } … … 1444 1506 } 1445 1507 1446 void AlternativeFinder:: visit( AttrExpr *attrExpr ) {1508 void AlternativeFinder::Finder::postvisit( AttrExpr *attrExpr ) { 1447 1509 // assume no 'pointer-to-attribute' 1448 1510 NameExpr *nameExpr = dynamic_cast< NameExpr* >( attrExpr->get_attr() ); … … 1458 1520 if ( function->get_parameters().size() == 1 ) { 1459 1521 if ( attrExpr->get_isType() ) { 1460 resolveAttr( data, function, attrExpr->get_type(), env, *this);1522 resolveAttr( data, function, attrExpr->get_type(), env, altFinder); 1461 1523 } else { 1462 1524 AlternativeFinder finder( indexer, env ); … … 1464 1526 for ( AltList::iterator choice = finder.alternatives.begin(); choice != finder.alternatives.end(); ++choice ) { 1465 1527 if ( choice->expr->get_result()->size() == 1 ) { 1466 resolveAttr(data, function, choice->expr->get_result(), choice->env, *this);1528 resolveAttr(data, function, choice->expr->get_result(), choice->env, altFinder ); 1467 1529 } // fi 1468 1530 } // for … … 1479 1541 } 1480 1542 1481 void AlternativeFinder:: visit( LogicalExpr *logicalExpr ) {1543 void AlternativeFinder::Finder::postvisit( LogicalExpr *logicalExpr ) { 1482 1544 AlternativeFinder firstFinder( indexer, env ); 1483 1545 firstFinder.findWithAdjustment( logicalExpr->get_arg1() ); … … 1492 1554 } 1493 1555 1494 void AlternativeFinder:: visit( ConditionalExpr *conditionalExpr ) {1556 void AlternativeFinder::Finder::postvisit( ConditionalExpr *conditionalExpr ) { 1495 1557 // find alternatives for condition 1496 1558 AlternativeFinder firstFinder( indexer, env ); … … 1524 1586 } 1525 1587 1526 void AlternativeFinder:: visit( CommaExpr *commaExpr ) {1588 void AlternativeFinder::Finder::postvisit( CommaExpr *commaExpr ) { 1527 1589 TypeEnvironment newEnv( env ); 1528 1590 Expression *newFirstArg = resolveInVoidContext( commaExpr->get_arg1(), indexer, newEnv ); … … 1535 1597 } 1536 1598 1537 void AlternativeFinder:: visit( RangeExpr * rangeExpr ) {1599 void AlternativeFinder::Finder::postvisit( RangeExpr * rangeExpr ) { 1538 1600 // resolve low and high, accept alternatives whose low and high types unify 1539 1601 AlternativeFinder firstFinder( indexer, env ); … … 1557 1619 } 1558 1620 1559 void AlternativeFinder:: visit( UntypedTupleExpr *tupleExpr ) {1621 void AlternativeFinder::Finder::postvisit( UntypedTupleExpr *tupleExpr ) { 1560 1622 std::vector< AlternativeFinder > subExprAlternatives; 1561 findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(),1623 altFinder.findSubExprs( tupleExpr->get_exprs().begin(), tupleExpr->get_exprs().end(), 1562 1624 back_inserter( subExprAlternatives ) ); 1563 1625 std::vector< AltList > possibilities; … … 1575 1637 } 1576 1638 1577 void AlternativeFinder:: visit( TupleExpr *tupleExpr ) {1639 void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) { 1578 1640 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1579 1641 } 1580 1642 1581 void AlternativeFinder:: visit( ImplicitCopyCtorExpr * impCpCtorExpr ) {1643 void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1582 1644 alternatives.push_back( Alternative( impCpCtorExpr->clone(), env, Cost::zero ) ); 1583 1645 } 1584 1646 1585 void AlternativeFinder:: visit( ConstructorExpr * ctorExpr ) {1647 void AlternativeFinder::Finder::postvisit( ConstructorExpr * ctorExpr ) { 1586 1648 AlternativeFinder finder( indexer, env ); 1587 1649 // don't prune here, since it's guaranteed all alternatives will have the same type … … 1593 1655 } 1594 1656 1595 void AlternativeFinder:: visit( TupleIndexExpr *tupleExpr ) {1657 void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) { 1596 1658 alternatives.push_back( Alternative( tupleExpr->clone(), env, Cost::zero ) ); 1597 1659 } 1598 1660 1599 void AlternativeFinder:: visit( TupleAssignExpr *tupleAssignExpr ) {1661 void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) { 1600 1662 alternatives.push_back( Alternative( tupleAssignExpr->clone(), env, Cost::zero ) ); 1601 1663 } 1602 1664 1603 void AlternativeFinder:: visit( UniqueExpr *unqExpr ) {1665 void AlternativeFinder::Finder::postvisit( UniqueExpr *unqExpr ) { 1604 1666 AlternativeFinder finder( indexer, env ); 1605 1667 finder.findWithAdjustment( unqExpr->get_expr() ); … … 1611 1673 } 1612 1674 1613 void AlternativeFinder:: visit( StmtExpr *stmtExpr ) {1675 void AlternativeFinder::Finder::postvisit( StmtExpr *stmtExpr ) { 1614 1676 StmtExpr * newStmtExpr = stmtExpr->clone(); 1615 1677 ResolvExpr::resolveStmtExpr( newStmtExpr, indexer ); … … 1618 1680 } 1619 1681 1620 void AlternativeFinder:: visit( UntypedInitExpr *initExpr ) {1682 void AlternativeFinder::Finder::postvisit( UntypedInitExpr *initExpr ) { 1621 1683 // handle each option like a cast 1622 1684 AltList candidates; 1623 PRINT( std::cerr << "untyped init expr: " << initExpr << std::endl; ) 1685 PRINT( 1686 std::cerr << "untyped init expr: " << initExpr << std::endl; 1687 ) 1624 1688 // O(N^2) checks of d-types with e-types 1625 1689 for ( InitAlternative & initAlt : initExpr->get_initAlts() ) { … … 1637 1701 AssertionSet needAssertions, haveAssertions; 1638 1702 OpenVarSet openVars; // find things in env that don't have a "representative type" and claim those are open vars? 1639 PRINT( std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; ) 1703 PRINT( 1704 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1705 ) 1640 1706 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1641 1707 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results -
src/ResolvExpr/AlternativeFinder.h
rd2d50d7 r81e1f32 38 38 using ExplodedArgs = std::vector< std::vector< ExplodedActual > >; 39 39 40 class AlternativeFinder : public Visitor{40 class AlternativeFinder { 41 41 public: 42 42 AlternativeFinder( const SymTab::Indexer &indexer, const TypeEnvironment &env ); … … 94 94 void findSubExprs( InputIterator begin, InputIterator end, OutputIterator out ); 95 95 private: 96 virtual void visit( ApplicationExpr *applicationExpr ); 97 virtual void visit( UntypedExpr *untypedExpr ); 98 virtual void visit( AddressExpr *addressExpr ); 99 virtual void visit( LabelAddressExpr *labelExpr ); 100 virtual void visit( CastExpr *castExpr ); 101 virtual void visit( VirtualCastExpr *castExpr ); 102 virtual void visit( UntypedMemberExpr *memberExpr ); 103 virtual void visit( MemberExpr *memberExpr ); 104 virtual void visit( NameExpr *variableExpr ); 105 virtual void visit( VariableExpr *variableExpr ); 106 virtual void visit( ConstantExpr *constantExpr ); 107 virtual void visit( SizeofExpr *sizeofExpr ); 108 virtual void visit( AlignofExpr *alignofExpr ); 109 virtual void visit( UntypedOffsetofExpr *offsetofExpr ); 110 virtual void visit( OffsetofExpr *offsetofExpr ); 111 virtual void visit( OffsetPackExpr *offsetPackExpr ); 112 virtual void visit( AttrExpr *attrExpr ); 113 virtual void visit( LogicalExpr *logicalExpr ); 114 virtual void visit( ConditionalExpr *conditionalExpr ); 115 virtual void visit( CommaExpr *commaExpr ); 116 virtual void visit( ImplicitCopyCtorExpr * impCpCtorExpr ); 117 virtual void visit( ConstructorExpr * ctorExpr ); 118 virtual void visit( RangeExpr * rangeExpr ); 119 virtual void visit( UntypedTupleExpr *tupleExpr ); 120 virtual void visit( TupleExpr *tupleExpr ); 121 virtual void visit( TupleIndexExpr *tupleExpr ); 122 virtual void visit( TupleAssignExpr *tupleExpr ); 123 virtual void visit( UniqueExpr *unqExpr ); 124 virtual void visit( StmtExpr *stmtExpr ); 125 virtual void visit( UntypedInitExpr *initExpr ); 126 127 /// Adds alternatives for anonymous members 128 void addAnonConversions( const Alternative & alt ); 129 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 130 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 131 /// Adds alternatives for member expressions where the left side has tuple type 132 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression * member ); 133 /// Adds alternatives for offsetof expressions, given the base type and name of the member 134 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); 135 /// Takes a final result and checks if its assertions can be satisfied 136 template<typename OutputIterator> 137 void validateFunctionAlternative( const Alternative &func, ArgPack& result, const std::vector<ArgPack>& results, OutputIterator out ); 138 /// Finds matching alternatives for a function, given a set of arguments 139 template<typename OutputIterator> 140 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 141 /// Checks if assertion parameters match for a new alternative 142 template< typename OutputIterator > 143 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ); 144 96 struct Finder; 145 97 const SymTab::Indexer &indexer; 146 98 AltList alternatives; -
src/ResolvExpr/CommonType.cc
rd2d50d7 r81e1f32 18 18 #include <utility> // for pair 19 19 20 #include "Common/PassVisitor.h" 20 21 #include "ResolvExpr/TypeEnvironment.h" // for OpenVarSet, AssertionSet 21 22 #include "SymTab/Indexer.h" // for Indexer … … 29 30 30 31 namespace ResolvExpr { 31 class CommonType : public Visitor { 32 public: 32 struct CommonType : public WithShortCircuiting { 33 33 CommonType( Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ); 34 34 Type *get_result() const { return result; } 35 36 void previsit( BaseSyntaxNode * ) { visit_children = false; } 37 38 void postvisit( VoidType * voidType ); 39 void postvisit( BasicType * basicType ); 40 void postvisit( PointerType * pointerType ); 41 void postvisit( ArrayType * arrayType ); 42 void postvisit( ReferenceType * refType ); 43 void postvisit( FunctionType * functionType ); 44 void postvisit( StructInstType * aggregateUseType ); 45 void postvisit( UnionInstType * aggregateUseType ); 46 void postvisit( EnumInstType * aggregateUseType ); 47 void postvisit( TraitInstType * aggregateUseType ); 48 void postvisit( TypeInstType * aggregateUseType ); 49 void postvisit( TupleType * tupleType ); 50 void postvisit( VarArgsType * varArgsType ); 51 void postvisit( ZeroType * zeroType ); 52 void postvisit( OneType * oneType ); 53 35 54 private: 36 virtual void visit( VoidType *voidType );37 virtual void visit( BasicType *basicType );38 virtual void visit( PointerType *pointerType );39 virtual void visit( ArrayType *arrayType );40 virtual void visit( ReferenceType *refType );41 virtual void visit( FunctionType *functionType );42 virtual void visit( StructInstType *aggregateUseType );43 virtual void visit( UnionInstType *aggregateUseType );44 virtual void visit( EnumInstType *aggregateUseType );45 virtual void visit( TraitInstType *aggregateUseType );46 virtual void visit( TypeInstType *aggregateUseType );47 virtual void visit( TupleType *tupleType );48 virtual void visit( VarArgsType *varArgsType );49 virtual void visit( ZeroType *zeroType );50 virtual void visit( OneType *oneType );51 52 55 template< typename Pointer > void getCommonWithVoidPointer( Pointer* voidPointer, Pointer* otherPointer ); 53 56 template< typename RefType > void handleRefType( RefType *inst, Type *other ); … … 80 83 81 84 Type *commonType( Type *type1, Type *type2, bool widenFirst, bool widenSecond, const SymTab::Indexer &indexer, TypeEnvironment &env, const OpenVarSet &openVars ) { 82 CommonTypevisitor( type2, widenFirst, widenSecond, indexer, env, openVars );85 PassVisitor<CommonType> visitor( type2, widenFirst, widenSecond, indexer, env, openVars ); 83 86 84 87 int depth1 = type1->referenceDepth(); … … 116 119 117 120 type1->accept( visitor ); 118 Type *result = visitor. get_result();121 Type *result = visitor.pass.get_result(); 119 122 if ( ! result ) { 120 123 // this appears to be handling for opaque type declarations … … 188 191 } 189 192 190 void CommonType:: visit( VoidType * ) {}191 192 void CommonType:: visit( BasicType *basicType ) {193 void CommonType::postvisit( VoidType * ) {} 194 195 void CommonType::postvisit( BasicType *basicType ) { 193 196 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) { 194 197 BasicType::Kind newType = combinedType[ basicType->get_kind() ][ otherBasic->get_kind() ]; … … 219 222 } 220 223 221 void CommonType:: visit( PointerType *pointerType ) {224 void CommonType::postvisit( PointerType *pointerType ) { 222 225 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) { 223 226 // std::cerr << "commonType: two pointers: " << pointerType << " / " << otherPointer << std::endl; … … 254 257 } 255 258 256 void CommonType:: visit( ArrayType * ) {}257 258 void CommonType:: visit( ReferenceType *refType ) {259 void CommonType::postvisit( ArrayType * ) {} 260 261 void CommonType::postvisit( ReferenceType *refType ) { 259 262 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) { 260 263 // std::cerr << "commonType: both references: " << refType << " / " << otherRef << std::endl; … … 291 294 } 292 295 293 void CommonType:: visit( FunctionType * ) {}294 void CommonType:: visit( StructInstType * ) {}295 void CommonType:: visit( UnionInstType * ) {}296 297 void CommonType:: visit( EnumInstType *enumInstType ) {296 void CommonType::postvisit( FunctionType * ) {} 297 void CommonType::postvisit( StructInstType * ) {} 298 void CommonType::postvisit( UnionInstType * ) {} 299 300 void CommonType::postvisit( EnumInstType *enumInstType ) { 298 301 if ( dynamic_cast< BasicType * >( type2 ) || dynamic_cast< ZeroType* >( type2 ) || dynamic_cast< OneType* >( type2 ) ) { 299 302 // reuse BasicType, EnumInstType code by swapping type2 with enumInstType 300 ValueGuard< Type * > temp( type2 ); 301 type2 = enumInstType; 302 temp.old->accept( *this ); 303 } // if 304 } 305 306 void CommonType::visit( TraitInstType * ) { 307 } 308 309 void CommonType::visit( TypeInstType *inst ) { 303 result = commonType( type2, enumInstType, widenSecond, widenFirst, indexer, env, openVars ); 304 } // if 305 } 306 307 void CommonType::postvisit( TraitInstType * ) { 308 } 309 310 void CommonType::postvisit( TypeInstType *inst ) { 310 311 if ( widenFirst ) { 311 312 NamedTypeDecl *nt = indexer.lookupType( inst->get_name() ); … … 329 330 } 330 331 331 void CommonType:: visit( TupleType * ) {}332 void CommonType:: visit( VarArgsType * ) {}333 334 void CommonType:: visit( ZeroType *zeroType ) {332 void CommonType::postvisit( TupleType * ) {} 333 void CommonType::postvisit( VarArgsType * ) {} 334 335 void CommonType::postvisit( ZeroType *zeroType ) { 335 336 if ( widenFirst ) { 336 337 if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< PointerType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) { … … 346 347 } 347 348 348 void CommonType:: visit( OneType *oneType ) {349 void CommonType::postvisit( OneType *oneType ) { 349 350 if ( widenFirst ) { 350 351 if ( dynamic_cast< BasicType* >( type2 ) || dynamic_cast< EnumInstType* >( type2 ) ) { -
src/ResolvExpr/CurrentObject.cc
rd2d50d7 r81e1f32 443 443 return new UnionIterator( uit ); 444 444 } else { 445 assertf( dynamic_cast< TypeInstType * >( type ), "some other reftotype");445 assertf( dynamic_cast< EnumInstType * >( type ) || dynamic_cast< TypeInstType * >( type ), "Encountered unhandled ReferenceToType in createMemberIterator: %s", toString( type ).c_str() ); 446 446 return new SimpleIterator( type ); 447 447 } -
src/ResolvExpr/PtrsAssignable.cc
rd2d50d7 r81e1f32 14 14 // 15 15 16 #include "Common/PassVisitor.h" 16 17 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 17 18 #include "SynTree/Type.h" // for TypeInstType, Type, BasicType … … 20 21 21 22 namespace ResolvExpr { 22 class PtrsAssignable : public Visitor { 23 public: 23 struct PtrsAssignable : public WithShortCircuiting { 24 24 PtrsAssignable( Type *dest, const TypeEnvironment &env ); 25 25 26 26 int get_result() const { return result; } 27 27 28 virtual void visit( VoidType *voidType ); 29 virtual void visit( BasicType *basicType ); 30 virtual void visit( PointerType *pointerType ); 31 virtual void visit( ArrayType *arrayType ); 32 virtual void visit( FunctionType *functionType ); 33 virtual void visit( StructInstType *inst ); 34 virtual void visit( UnionInstType *inst ); 35 virtual void visit( EnumInstType *inst ); 36 virtual void visit( TraitInstType *inst ); 37 virtual void visit( TypeInstType *inst ); 38 virtual void visit( TupleType *tupleType ); 39 virtual void visit( VarArgsType *varArgsType ); 40 virtual void visit( ZeroType *zeroType ); 41 virtual void visit( OneType *oneType ); 28 void previsit( Type * ) { visit_children = false; } 29 30 void postvisit( VoidType * voidType ); 31 void postvisit( BasicType * basicType ); 32 void postvisit( PointerType * pointerType ); 33 void postvisit( ArrayType * arrayType ); 34 void postvisit( FunctionType * functionType ); 35 void postvisit( StructInstType * inst ); 36 void postvisit( UnionInstType * inst ); 37 void postvisit( EnumInstType * inst ); 38 void postvisit( TraitInstType * inst ); 39 void postvisit( TypeInstType * inst ); 40 void postvisit( TupleType * tupleType ); 41 void postvisit( VarArgsType * varArgsType ); 42 void postvisit( ZeroType * zeroType ); 43 void postvisit( OneType * oneType ); 42 44 private: 43 45 Type *dest; … … 59 61 return -1; 60 62 } else { 61 P trsAssignableptrs( dest, env );63 PassVisitor<PtrsAssignable> ptrs( dest, env ); 62 64 src->accept( ptrs ); 63 return ptrs. get_result();65 return ptrs.pass.get_result(); 64 66 } // if 65 67 } … … 67 69 PtrsAssignable::PtrsAssignable( Type *dest, const TypeEnvironment &env ) : dest( dest ), result( 0 ), env( env ) {} 68 70 69 void PtrsAssignable:: visit( VoidType * ) {71 void PtrsAssignable::postvisit( VoidType * ) { 70 72 // T * = void * is disallowed - this is a change from C, where any 71 73 // void * can be assigned or passed to a non-void pointer without a cast. 72 74 } 73 75 74 void PtrsAssignable:: visit( __attribute__((unused)) BasicType *basicType ) {}75 void PtrsAssignable:: visit( __attribute__((unused)) PointerType *pointerType ) {}76 void PtrsAssignable:: visit( __attribute__((unused)) ArrayType *arrayType ) {}77 void PtrsAssignable:: visit( __attribute__((unused)) FunctionType *functionType ) {}76 void PtrsAssignable::postvisit( __attribute__((unused)) BasicType *basicType ) {} 77 void PtrsAssignable::postvisit( __attribute__((unused)) PointerType *pointerType ) {} 78 void PtrsAssignable::postvisit( __attribute__((unused)) ArrayType *arrayType ) {} 79 void PtrsAssignable::postvisit( __attribute__((unused)) FunctionType *functionType ) {} 78 80 79 void PtrsAssignable:: visit( __attribute__((unused)) StructInstType *inst ) {}80 void PtrsAssignable:: visit( __attribute__((unused)) UnionInstType *inst ) {}81 void PtrsAssignable::postvisit( __attribute__((unused)) StructInstType *inst ) {} 82 void PtrsAssignable::postvisit( __attribute__((unused)) UnionInstType *inst ) {} 81 83 82 void PtrsAssignable:: visit( EnumInstType * ) {84 void PtrsAssignable::postvisit( EnumInstType * ) { 83 85 if ( dynamic_cast< BasicType* >( dest ) ) { 84 86 // int * = E *, etc. is safe. This isn't technically correct, as each … … 91 93 } 92 94 93 void PtrsAssignable:: visit( __attribute__((unused)) TraitInstType *inst ) {}94 void PtrsAssignable:: visit( TypeInstType *inst ) {95 void PtrsAssignable::postvisit( __attribute__((unused)) TraitInstType *inst ) {} 96 void PtrsAssignable::postvisit( TypeInstType *inst ) { 95 97 EqvClass eqvClass; 96 98 if ( env.lookup( inst->get_name(), eqvClass ) && eqvClass.type ) { … … 100 102 } 101 103 102 void PtrsAssignable:: visit( __attribute__((unused)) TupleType *tupleType ) {}103 void PtrsAssignable:: visit( __attribute__((unused)) VarArgsType *varArgsType ) {}104 void PtrsAssignable:: visit( __attribute__((unused)) ZeroType *zeroType ) {}105 void PtrsAssignable:: visit( __attribute__((unused)) OneType *oneType ) {}104 void PtrsAssignable::postvisit( __attribute__((unused)) TupleType *tupleType ) {} 105 void PtrsAssignable::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) {} 106 void PtrsAssignable::postvisit( __attribute__((unused)) ZeroType *zeroType ) {} 107 void PtrsAssignable::postvisit( __attribute__((unused)) OneType *oneType ) {} 106 108 107 109 } // namespace ResolvExpr -
src/ResolvExpr/PtrsCastable.cc
rd2d50d7 r81e1f32 14 14 // 15 15 16 #include "Common/PassVisitor.h" 16 17 #include "ResolvExpr/TypeEnvironment.h" // for EqvClass, TypeEnvironment 17 18 #include "SymTab/Indexer.h" // for Indexer … … 21 22 #include "typeops.h" // for ptrsAssignable 22 23 23 24 24 namespace ResolvExpr { 25 class PtrsCastable : public Visitor{25 struct PtrsCastable : public WithShortCircuiting { 26 26 public: 27 27 PtrsCastable( Type *dest, const TypeEnvironment &env, const SymTab::Indexer &indexer ); … … 29 29 int get_result() const { return result; } 30 30 31 virtual void visit(VoidType *voidType); 32 virtual void visit(BasicType *basicType); 33 virtual void visit(PointerType *pointerType); 34 virtual void visit(ArrayType *arrayType); 35 virtual void visit(FunctionType *functionType); 36 virtual void visit(StructInstType *inst); 37 virtual void visit(UnionInstType *inst); 38 virtual void visit(EnumInstType *inst); 39 virtual void visit(TraitInstType *inst); 40 virtual void visit(TypeInstType *inst); 41 virtual void visit(TupleType *tupleType); 42 virtual void visit(VarArgsType *varArgsType); 43 virtual void visit(ZeroType *zeroType); 44 virtual void visit(OneType *oneType); 31 void previsit( Type * ) { visit_children = false; } 32 33 void postvisit( VoidType * voidType ); 34 void postvisit( BasicType * basicType ); 35 void postvisit( PointerType * pointerType ); 36 void postvisit( ArrayType * arrayType ); 37 void postvisit( FunctionType * functionType ); 38 void postvisit( StructInstType * inst ); 39 void postvisit( UnionInstType * inst ); 40 void postvisit( EnumInstType * inst ); 41 void postvisit( TraitInstType * inst ); 42 void postvisit( TypeInstType * inst ); 43 void postvisit( TupleType * tupleType ); 44 void postvisit( VarArgsType * varArgsType ); 45 void postvisit( ZeroType * zeroType ); 46 void postvisit( OneType * oneType ); 45 47 private: 46 48 Type *dest; … … 79 81 EqvClass eqvClass; 80 82 if ( env.lookup( destAsTypeInst->get_name(), eqvClass ) ) { 83 // xxx - should this be ptrsCastable? 81 84 return ptrsAssignable( src, eqvClass.type, env ); 82 85 } // if … … 85 88 return objectCast( src, env, indexer ); 86 89 } else { 87 P trsCastableptrs( dest, env, indexer );90 PassVisitor<PtrsCastable> ptrs( dest, env, indexer ); 88 91 src->accept( ptrs ); 89 return ptrs. get_result();92 return ptrs.pass.get_result(); 90 93 } // if 91 94 } … … 95 98 } 96 99 97 void PtrsCastable:: visit( VoidType * ) {100 void PtrsCastable::postvisit( VoidType * ) { 98 101 result = objectCast( dest, env, indexer ); 99 102 } 100 103 101 void PtrsCastable:: visit( BasicType * ) {104 void PtrsCastable::postvisit( BasicType * ) { 102 105 result = objectCast( dest, env, indexer ); 103 106 } 104 107 105 void PtrsCastable:: visit( PointerType * ) {108 void PtrsCastable::postvisit( PointerType * ) { 106 109 result = objectCast( dest, env, indexer ); 107 110 } 108 111 109 void PtrsCastable:: visit( ArrayType * ) {112 void PtrsCastable::postvisit( ArrayType * ) { 110 113 result = objectCast( dest, env, indexer ); 111 114 } 112 115 113 void PtrsCastable:: visit( FunctionType * ) {116 void PtrsCastable::postvisit( FunctionType * ) { 114 117 // result = -1; 115 118 result = functionCast( dest, env, indexer ); 116 119 } 117 120 118 void PtrsCastable:: visit( StructInstType * ) {121 void PtrsCastable::postvisit( StructInstType * ) { 119 122 result = objectCast( dest, env, indexer ); 120 123 } 121 124 122 void PtrsCastable:: visit( UnionInstType * ) {125 void PtrsCastable::postvisit( UnionInstType * ) { 123 126 result = objectCast( dest, env, indexer ); 124 127 } 125 128 126 void PtrsCastable:: visit( EnumInstType * ) {129 void PtrsCastable::postvisit( EnumInstType * ) { 127 130 if ( dynamic_cast< EnumInstType* >( dest ) ) { 128 131 result = 1; … … 138 141 } 139 142 140 void PtrsCastable:: visit( TraitInstType * ) {}143 void PtrsCastable::postvisit( TraitInstType * ) {} 141 144 142 void PtrsCastable:: visit(TypeInstType *inst) {145 void PtrsCastable::postvisit(TypeInstType *inst) { 143 146 //result = objectCast( inst, env, indexer ) > 0 && objectCast( dest, env, indexer ) > 0 ? 1 : -1; 144 147 result = objectCast( inst, env, indexer ) == objectCast( dest, env, indexer ) ? 1 : -1; 145 148 } 146 149 147 void PtrsCastable:: visit( TupleType * ) {150 void PtrsCastable::postvisit( TupleType * ) { 148 151 result = objectCast( dest, env, indexer ); 149 152 } 150 153 151 void PtrsCastable:: visit( VarArgsType * ) {154 void PtrsCastable::postvisit( VarArgsType * ) { 152 155 result = objectCast( dest, env, indexer ); 153 156 } 154 157 155 void PtrsCastable:: visit( ZeroType * ) {158 void PtrsCastable::postvisit( ZeroType * ) { 156 159 result = objectCast( dest, env, indexer ); 157 160 } 158 161 159 void PtrsCastable:: visit( OneType * ) {162 void PtrsCastable::postvisit( OneType * ) { 160 163 result = objectCast( dest, env, indexer ); 161 164 } -
src/ResolvExpr/RenameVars.cc
rd2d50d7 r81e1f32 19 19 #include <utility> // for pair 20 20 21 #include "Common/PassVisitor.h" 21 22 #include "Common/SemanticError.h" // for SemanticError 22 23 #include "RenameVars.h" … … 27 28 28 29 namespace ResolvExpr { 29 RenameVars global_renamer; 30 namespace { 31 struct RenameVars { 32 RenameVars(); 33 void reset(); 30 34 31 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 32 mapStack.push_front( std::map< std::string, std::string >() ); 35 void previsit( TypeInstType * instType ); 36 void previsit( Type * ); 37 void postvisit( Type * ); 38 39 private: 40 int level, resetCount; 41 std::list< std::map< std::string, std::string > > mapStack; 42 }; 43 44 PassVisitor<RenameVars> global_renamer; 45 } // namespace 46 47 void renameTyVars( Type * t ) { 48 t->accept( global_renamer ); 33 49 } 34 50 35 void RenameVars::reset() { 36 level = 0; 37 resetCount++; 51 void resetTyVarRenaming() { 52 global_renamer.pass.reset(); 38 53 } 39 54 40 void RenameVars::visit( VoidType *voidType ){41 typeBefore( voidType );42 typeAfter( voidType);43 }55 namespace { 56 RenameVars::RenameVars() : level( 0 ), resetCount( 0 ) { 57 mapStack.push_front( std::map< std::string, std::string >() ); 58 } 44 59 45 void RenameVars::visit( BasicType *basicType) {46 typeBefore( basicType );47 typeAfter( basicType );48 }60 void RenameVars::reset() { 61 level = 0; 62 resetCount++; 63 } 49 64 50 void RenameVars::visit( PointerType *pointerType ) { 51 typeBefore( pointerType ); 52 maybeAccept( pointerType->get_base(), *this ); 53 typeAfter( pointerType ); 54 } 65 void RenameVars::previsit( TypeInstType * instType ) { 66 previsit( (Type *)instType ); 67 std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->name ); 68 if ( i != mapStack.front().end() ) { 69 instType->name = i->second; 70 } // if 71 } 55 72 56 void RenameVars::visit( ArrayType *arrayType ) { 57 typeBefore( arrayType ); 58 maybeAccept( arrayType->get_dimension(), *this ); 59 maybeAccept( arrayType->get_base(), *this ); 60 typeAfter( arrayType ); 61 } 73 void RenameVars::previsit( Type * type ) { 74 if ( ! type->forall.empty() ) { 75 // copies current name mapping into new mapping 76 mapStack.push_front( mapStack.front() ); 77 // renames all "forall" type names to `_${level}_${name}' 78 for ( auto td : type->forall ) { 79 std::ostringstream output; 80 output << "_" << resetCount << "_" << level << "_" << td->name; 81 std::string newname( output.str() ); 82 mapStack.front()[ td->get_name() ] = newname; 83 td->name = newname; 84 // ditto for assertion names, the next level in 85 level++; 86 // acceptAll( td->assertions, *this ); 87 } // for 88 } // if 89 } 62 90 63 void RenameVars::visit( FunctionType *functionType ) { 64 typeBefore( functionType ); 65 acceptAll( functionType->get_returnVals(), *this ); 66 acceptAll( functionType->get_parameters(), *this ); 67 typeAfter( functionType ); 68 } 69 70 void RenameVars::visit( StructInstType *aggregateUseType ) { 71 typeBefore( aggregateUseType ); 72 acceptAll( aggregateUseType->get_parameters(), *this ); 73 typeAfter( aggregateUseType ); 74 } 75 76 void RenameVars::visit( UnionInstType *aggregateUseType ) { 77 typeBefore( aggregateUseType ); 78 acceptAll( aggregateUseType->get_parameters(), *this ); 79 typeAfter( aggregateUseType ); 80 } 81 82 void RenameVars::visit( EnumInstType *aggregateUseType ) { 83 typeBefore( aggregateUseType ); 84 acceptAll( aggregateUseType->get_parameters(), *this ); 85 typeAfter( aggregateUseType ); 86 } 87 88 void RenameVars::visit( TraitInstType *aggregateUseType ) { 89 typeBefore( aggregateUseType ); 90 acceptAll( aggregateUseType->get_parameters(), *this ); 91 typeAfter( aggregateUseType ); 92 } 93 94 void RenameVars::visit( TypeInstType *instType ) { 95 typeBefore( instType ); 96 std::map< std::string, std::string >::const_iterator i = mapStack.front().find( instType->get_name() ); 97 if ( i != mapStack.front().end() ) { 98 instType->set_name( i->second ); 99 } else { 100 } // if 101 acceptAll( instType->get_parameters(), *this ); 102 typeAfter( instType ); 103 } 104 105 void RenameVars::visit( TupleType *tupleType ) { 106 typeBefore( tupleType ); 107 acceptAll( tupleType->get_types(), *this ); 108 typeAfter( tupleType ); 109 } 110 111 void RenameVars::visit( VarArgsType *varArgsType ) { 112 typeBefore( varArgsType ); 113 typeAfter( varArgsType ); 114 } 115 116 void RenameVars::visit( ZeroType *zeroType ) { 117 typeBefore( zeroType ); 118 typeAfter( zeroType ); 119 } 120 121 void RenameVars::visit( OneType *oneType ) { 122 typeBefore( oneType ); 123 typeAfter( oneType ); 124 } 125 126 void RenameVars::typeBefore( Type *type ) { 127 if ( ! type->get_forall().empty() ) { 128 // copies current name mapping into new mapping 129 mapStack.push_front( mapStack.front() ); 130 // renames all "forall" type names to `_${level}_${name}' 131 for ( Type::ForallList::iterator i = type->get_forall().begin(); i != type->get_forall().end(); ++i ) { 132 std::ostringstream output; 133 output << "_" << resetCount << "_" << level << "_" << (*i)->get_name(); 134 std::string newname( output.str() ); 135 mapStack.front()[ (*i)->get_name() ] = newname; 136 (*i)->set_name( newname ); 137 // ditto for assertion names, the next level in 138 level++; 139 acceptAll( (*i)->get_assertions(), *this ); 140 } // for 141 } // if 142 } 143 144 void RenameVars::typeAfter( Type *type ) { 145 // clears name mapping added by typeBefore() 146 if ( ! type->get_forall().empty() ) { 147 mapStack.pop_front(); 148 } // if 149 } 150 91 void RenameVars::postvisit( Type * type ) { 92 // clears name mapping added by typeBefore() 93 if ( ! type->forall.empty() ) { 94 mapStack.pop_front(); 95 } // if 96 } 97 } // namespace 151 98 } // namespace ResolvExpr 152 99 -
src/ResolvExpr/RenameVars.h
rd2d50d7 r81e1f32 24 24 25 25 namespace ResolvExpr { 26 /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID 27 void renameTyVars( Type * ); 26 28 27 /// Provides a consistent renaming of forall type names in a hierarchy by prefixing them with a unique "level" ID 28 class RenameVars : public Visitor { 29 public: 30 RenameVars(); 31 void reset(); 32 private: 33 virtual void visit( VoidType *basicType ); 34 virtual void visit( BasicType *basicType ); 35 virtual void visit( PointerType *pointerType ); 36 virtual void visit( ArrayType *arrayType ); 37 virtual void visit( FunctionType *functionType ); 38 virtual void visit( StructInstType *aggregateUseType ); 39 virtual void visit( UnionInstType *aggregateUseType ); 40 virtual void visit( EnumInstType *aggregateUseType ); 41 virtual void visit( TraitInstType *aggregateUseType ); 42 virtual void visit( TypeInstType *aggregateUseType ); 43 virtual void visit( TupleType *tupleType ); 44 virtual void visit( VarArgsType *varArgsType ); 45 virtual void visit( ZeroType *zeroType ); 46 virtual void visit( OneType *oneType ); 47 48 void typeBefore( Type *type ); 49 void typeAfter( Type *type ); 50 int level, resetCount; 51 std::list< std::map< std::string, std::string > > mapStack; 52 }; 53 54 extern RenameVars global_renamer; 29 /// resets internal state of renamer to avoid overflow 30 void resetTyVarRenaming(); 55 31 } // namespace ResolvExpr 56 32 -
src/ResolvExpr/Resolver.cc
rd2d50d7 r81e1f32 132 132 133 133 void findVoidExpression( Expression *& untyped, const SymTab::Indexer &indexer ) { 134 global_renamer.reset();134 resetTyVarRenaming(); 135 135 TypeEnvironment env; 136 136 Expression *newExpr = resolveInVoidContext( untyped, indexer, env ); -
src/ResolvExpr/Unify.cc
rd2d50d7 r81e1f32 44 44 namespace ResolvExpr { 45 45 46 class Unify : public Visitor { 47 public: 46 struct Unify : public WithShortCircuiting { 48 47 Unify( Type *type2, TypeEnvironment &env, AssertionSet &needAssertions, AssertionSet &haveAssertions, const OpenVarSet &openVars, WidenMode widenMode, const SymTab::Indexer &indexer ); 49 48 50 49 bool get_result() const { return result; } 50 51 void previsit( BaseSyntaxNode * ) { visit_children = false; } 52 53 void postvisit( VoidType * voidType ); 54 void postvisit( BasicType * basicType ); 55 void postvisit( PointerType * pointerType ); 56 void postvisit( ArrayType * arrayType ); 57 void postvisit( ReferenceType * refType ); 58 void postvisit( FunctionType * functionType ); 59 void postvisit( StructInstType * aggregateUseType ); 60 void postvisit( UnionInstType * aggregateUseType ); 61 void postvisit( EnumInstType * aggregateUseType ); 62 void postvisit( TraitInstType * aggregateUseType ); 63 void postvisit( TypeInstType * aggregateUseType ); 64 void postvisit( TupleType * tupleType ); 65 void postvisit( VarArgsType * varArgsType ); 66 void postvisit( ZeroType * zeroType ); 67 void postvisit( OneType * oneType ); 68 51 69 private: 52 virtual void visit(VoidType *voidType);53 virtual void visit(BasicType *basicType);54 virtual void visit(PointerType *pointerType);55 virtual void visit(ArrayType *arrayType);56 virtual void visit(ReferenceType *refType);57 virtual void visit(FunctionType *functionType);58 virtual void visit(StructInstType *aggregateUseType);59 virtual void visit(UnionInstType *aggregateUseType);60 virtual void visit(EnumInstType *aggregateUseType);61 virtual void visit(TraitInstType *aggregateUseType);62 virtual void visit(TypeInstType *aggregateUseType);63 virtual void visit(TupleType *tupleType);64 virtual void visit(VarArgsType *varArgsType);65 virtual void visit(ZeroType *zeroType);66 virtual void visit(OneType *oneType);67 68 70 template< typename RefType > void handleRefType( RefType *inst, Type *other ); 69 71 template< typename RefType > void handleGenericRefType( RefType *inst, Type *other ); … … 325 327 result = bindVar( var2, type1, entry2->second, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 326 328 } else { 327 Unifycomparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer );329 PassVisitor<Unify> comparator( type2, env, needAssertions, haveAssertions, openVars, widenMode, indexer ); 328 330 type1->accept( comparator ); 329 result = comparator. get_result();331 result = comparator.pass.get_result(); 330 332 } // if 331 333 #ifdef DEBUG … … 404 406 } 405 407 406 void Unify:: visit( __attribute__((unused)) VoidType *voidType) {408 void Unify::postvisit( __attribute__((unused)) VoidType *voidType) { 407 409 result = dynamic_cast< VoidType* >( type2 ); 408 410 } 409 411 410 void Unify:: visit(BasicType *basicType) {412 void Unify::postvisit(BasicType *basicType) { 411 413 if ( BasicType *otherBasic = dynamic_cast< BasicType* >( type2 ) ) { 412 414 result = basicType->get_kind() == otherBasic->get_kind(); … … 436 438 } 437 439 438 void Unify:: visit(PointerType *pointerType) {440 void Unify::postvisit(PointerType *pointerType) { 439 441 if ( PointerType *otherPointer = dynamic_cast< PointerType* >( type2 ) ) { 440 442 result = unifyExact( pointerType->get_base(), otherPointer->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); … … 444 446 } 445 447 446 void Unify:: visit(ReferenceType *refType) {448 void Unify::postvisit(ReferenceType *refType) { 447 449 if ( ReferenceType *otherRef = dynamic_cast< ReferenceType* >( type2 ) ) { 448 450 result = unifyExact( refType->get_base(), otherRef->get_base(), env, needAssertions, haveAssertions, openVars, WidenMode( false, false ), indexer ); … … 452 454 } 453 455 454 void Unify:: visit(ArrayType *arrayType) {456 void Unify::postvisit(ArrayType *arrayType) { 455 457 ArrayType *otherArray = dynamic_cast< ArrayType* >( type2 ); 456 458 // to unify, array types must both be VLA or both not VLA … … 567 569 } 568 570 569 void Unify:: visit(FunctionType *functionType) {571 void Unify::postvisit(FunctionType *functionType) { 570 572 FunctionType *otherFunction = dynamic_cast< FunctionType* >( type2 ); 571 573 if ( otherFunction && functionType->get_isVarArgs() == otherFunction->get_isVarArgs() ) { … … 669 671 } 670 672 671 void Unify:: visit(StructInstType *structInst) {673 void Unify::postvisit(StructInstType *structInst) { 672 674 handleGenericRefType( structInst, type2 ); 673 675 } 674 676 675 void Unify:: visit(UnionInstType *unionInst) {677 void Unify::postvisit(UnionInstType *unionInst) { 676 678 handleGenericRefType( unionInst, type2 ); 677 679 } 678 680 679 void Unify:: visit(EnumInstType *enumInst) {681 void Unify::postvisit(EnumInstType *enumInst) { 680 682 handleRefType( enumInst, type2 ); 681 683 } 682 684 683 void Unify:: visit(TraitInstType *contextInst) {685 void Unify::postvisit(TraitInstType *contextInst) { 684 686 handleRefType( contextInst, type2 ); 685 687 } 686 688 687 void Unify:: visit(TypeInstType *typeInst) {689 void Unify::postvisit(TypeInstType *typeInst) { 688 690 assert( openVars.find( typeInst->get_name() ) == openVars.end() ); 689 691 TypeInstType *otherInst = dynamic_cast< TypeInstType* >( type2 ); … … 740 742 } 741 743 742 void Unify:: visit(TupleType *tupleType) {744 void Unify::postvisit(TupleType *tupleType) { 743 745 if ( TupleType *otherTuple = dynamic_cast< TupleType* >( type2 ) ) { 744 746 std::unique_ptr<TupleType> flat1( tupleType->clone() ); … … 757 759 } 758 760 759 void Unify:: visit( __attribute__((unused)) VarArgsType *varArgsType ) {761 void Unify::postvisit( __attribute__((unused)) VarArgsType *varArgsType ) { 760 762 result = dynamic_cast< VarArgsType* >( type2 ); 761 763 } 762 764 763 void Unify:: visit( __attribute__((unused)) ZeroType *zeroType ) {765 void Unify::postvisit( __attribute__((unused)) ZeroType *zeroType ) { 764 766 result = dynamic_cast< ZeroType* >( type2 ); 765 767 } 766 768 767 void Unify:: visit( __attribute__((unused)) OneType *oneType ) {769 void Unify::postvisit( __attribute__((unused)) OneType *oneType ) { 768 770 result = dynamic_cast< OneType* >( type2 ); 769 771 } -
src/SymTab/Mangler.cc
rd2d50d7 r81e1f32 23 23 24 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 25 #include "Common/PassVisitor.h" 25 26 #include "Common/SemanticError.h" // for SemanticError 26 27 #include "Common/utility.h" // for toString … … 31 32 32 33 namespace SymTab { 33 std::string Mangler::mangleType( Type * ty ){34 Mangler mangler( false, true, true );35 maybeAccept( ty, mangler );36 return mangler.get_mangleName();37 }38 39 std::string Mangler::mangleConcrete( Type* ty ) { 40 Mangler mangler( false, false, false );41 maybeAccept( ty, mangler ); 42 return mangler.get_mangleName();43 }44 45 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 46 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {}47 48 Mangler::Mangler( const Mangler &rhs ) : mangleName() {49 varNums = rhs.varNums;50 nextVarNum = rhs.nextVarNum;51 isTopLevel = rhs.isTopLevel;52 mangleOverridable = rhs.mangleOverridable;53 typeMode = rhs.typeMode;54 }55 56 void Mangler::mangleDecl( DeclarationWithType * declaration ) {57 bool wasTopLevel = isTopLevel;58 if ( isTopLevel ) {59 varNums.clear();60 nextVarNum = 0; 61 isTopLevel = false;62 } // if63 mangleName << "__";64 CodeGen::OperatorInfo opInfo;65 if ( operatorLookup( declaration->get_name(), opInfo ) ) {66 mangleName << opInfo.outputName;67 } else {68 mangleName << declaration->get_name();69 } // if70 mangleName << "__";71 maybeAccept( declaration->get_type(), *this ); 72 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) {73 // want to be able to override autogenerated and intrinsic routines,74 // so they need a different name mangling 75 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) {76 mangleName << "autogen__";77 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) {78 mangleName << "intrinsic__"; 79 } else{80 // if we add another kind of overridable function, this has to change81 assert( false && "unknown overrideable linkage");82 } // if34 namespace Mangler { 35 namespace { 36 /// Mangles names to a unique C identifier 37 struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler> { 38 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 39 Mangler( const Mangler & ); 40 41 void previsit( BaseSyntaxNode * ) { visit_children = false; } 42 43 void postvisit( ObjectDecl * declaration ); 44 void postvisit( FunctionDecl * declaration ); 45 void postvisit( TypeDecl * declaration ); 46 47 void postvisit( VoidType * voidType ); 48 void postvisit( BasicType * basicType ); 49 void postvisit( PointerType * pointerType ); 50 void postvisit( ArrayType * arrayType ); 51 void postvisit( ReferenceType * refType ); 52 void postvisit( FunctionType * functionType ); 53 void postvisit( StructInstType * aggregateUseType ); 54 void postvisit( UnionInstType * aggregateUseType ); 55 void postvisit( EnumInstType * aggregateUseType ); 56 void postvisit( TypeInstType * aggregateUseType ); 57 void postvisit( TupleType * tupleType ); 58 void postvisit( VarArgsType * varArgsType ); 59 void postvisit( ZeroType * zeroType ); 60 void postvisit( OneType * oneType ); 61 62 std::string get_mangleName() { return mangleName.str(); } 63 private: 64 std::ostringstream mangleName; ///< Mangled name being constructed 65 typedef std::map< std::string, std::pair< int, int > > VarMapType; 66 VarMapType varNums; ///< Map of type variables to indices 67 int nextVarNum; ///< Next type variable index 68 bool isTopLevel; ///< Is the Mangler at the top level 69 bool mangleOverridable; ///< Specially mangle overridable built-in methods 70 bool typeMode; ///< Produce a unique mangled name for a type 71 bool mangleGenericParams; ///< Include generic parameters in name mangling if true 72 73 void mangleDecl( DeclarationWithType *declaration ); 74 void mangleRef( ReferenceToType *refType, std::string prefix ); 75 76 void printQualifiers( Type *type ); 77 }; // Mangler 78 } // namespace 79 80 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 81 PassVisitor<Mangler> mangler( mangleOverridable, typeMode, mangleGenericParams ); 82 maybeAccept( decl, mangler ); 83 return mangler.pass.get_mangleName(); 83 84 } 84 isTopLevel = wasTopLevel; 85 } 86 87 void Mangler::visit( ObjectDecl * declaration ) { 88 mangleDecl( declaration ); 89 } 90 91 void Mangler::visit( FunctionDecl * declaration ) { 92 mangleDecl( declaration ); 93 } 94 95 void Mangler::visit( VoidType * voidType ) { 96 printQualifiers( voidType ); 97 mangleName << "v"; 98 } 99 100 void Mangler::visit( BasicType * basicType ) { 101 static const char *btLetter[] = { 102 "b", // Bool 103 "c", // Char 104 "Sc", // SignedChar 105 "Uc", // UnsignedChar 106 "s", // ShortSignedInt 107 "Us", // ShortUnsignedInt 108 "i", // SignedInt 109 "Ui", // UnsignedInt 110 "l", // LongSignedInt 111 "Ul", // LongUnsignedInt 112 "q", // LongLongSignedInt 113 "Uq", // LongLongUnsignedInt 114 "f", // Float 115 "d", // Double 116 "r", // LongDouble 117 "Xf", // FloatComplex 118 "Xd", // DoubleComplex 119 "Xr", // LongDoubleComplex 120 "If", // FloatImaginary 121 "Id", // DoubleImaginary 122 "Ir", // LongDoubleImaginary 123 "w", // SignedInt128 124 "Uw", // UnsignedInt128 125 }; 126 127 printQualifiers( basicType ); 128 mangleName << btLetter[ basicType->get_kind() ]; 129 } 130 131 void Mangler::visit( PointerType * pointerType ) { 132 printQualifiers( pointerType ); 133 mangleName << "P"; 134 maybeAccept( pointerType->get_base(), *this ); 135 } 136 137 void Mangler::visit( ArrayType * arrayType ) { 138 // TODO: encode dimension 139 printQualifiers( arrayType ); 140 mangleName << "A0"; 141 maybeAccept( arrayType->get_base(), *this ); 142 } 143 144 void Mangler::visit( ReferenceType * refType ) { 145 printQualifiers( refType ); 146 mangleName << "R"; 147 maybeAccept( refType->get_base(), *this ); 148 } 149 150 namespace { 151 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) { 152 std::list< Type* > ret; 153 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ), 154 std::mem_fun( &DeclarationWithType::get_type ) ); 155 return ret; 85 86 std::string mangleType( Type * ty ) { 87 PassVisitor<Mangler> mangler( false, true, true ); 88 maybeAccept( ty, mangler ); 89 return mangler.pass.get_mangleName(); 156 90 } 157 } 158 159 void Mangler::visit( FunctionType * functionType ) { 160 printQualifiers( functionType ); 161 mangleName << "F"; 162 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() ); 163 acceptAll( returnTypes, *this ); 164 mangleName << "_"; 165 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() ); 166 acceptAll( paramTypes, *this ); 167 mangleName << "_"; 168 } 169 170 void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) { 171 printQualifiers( refType ); 172 173 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name(); 174 175 if ( mangleGenericParams ) { 176 std::list< Expression* >& params = refType->get_parameters(); 177 if ( ! params.empty() ) { 91 92 std::string mangleConcrete( Type * ty ) { 93 PassVisitor<Mangler> mangler( false, false, false ); 94 maybeAccept( ty, mangler ); 95 return mangler.pass.get_mangleName(); 96 } 97 98 namespace { 99 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 100 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {} 101 102 Mangler::Mangler( const Mangler &rhs ) : mangleName() { 103 varNums = rhs.varNums; 104 nextVarNum = rhs.nextVarNum; 105 isTopLevel = rhs.isTopLevel; 106 mangleOverridable = rhs.mangleOverridable; 107 typeMode = rhs.typeMode; 108 } 109 110 void Mangler::mangleDecl( DeclarationWithType * declaration ) { 111 bool wasTopLevel = isTopLevel; 112 if ( isTopLevel ) { 113 varNums.clear(); 114 nextVarNum = 0; 115 isTopLevel = false; 116 } // if 117 mangleName << "__"; 118 CodeGen::OperatorInfo opInfo; 119 if ( operatorLookup( declaration->get_name(), opInfo ) ) { 120 mangleName << opInfo.outputName; 121 } else { 122 mangleName << declaration->get_name(); 123 } // if 124 mangleName << "__"; 125 maybeAccept( declaration->get_type(), *visitor ); 126 if ( mangleOverridable && LinkageSpec::isOverridable( declaration->get_linkage() ) ) { 127 // want to be able to override autogenerated and intrinsic routines, 128 // so they need a different name mangling 129 if ( declaration->get_linkage() == LinkageSpec::AutoGen ) { 130 mangleName << "autogen__"; 131 } else if ( declaration->get_linkage() == LinkageSpec::Intrinsic ) { 132 mangleName << "intrinsic__"; 133 } else { 134 // if we add another kind of overridable function, this has to change 135 assert( false && "unknown overrideable linkage" ); 136 } // if 137 } 138 isTopLevel = wasTopLevel; 139 } 140 141 void Mangler::postvisit( ObjectDecl * declaration ) { 142 mangleDecl( declaration ); 143 } 144 145 void Mangler::postvisit( FunctionDecl * declaration ) { 146 mangleDecl( declaration ); 147 } 148 149 void Mangler::postvisit( VoidType * voidType ) { 150 printQualifiers( voidType ); 151 mangleName << "v"; 152 } 153 154 void Mangler::postvisit( BasicType * basicType ) { 155 static const char *btLetter[] = { 156 "b", // Bool 157 "c", // Char 158 "Sc", // SignedChar 159 "Uc", // UnsignedChar 160 "s", // ShortSignedInt 161 "Us", // ShortUnsignedInt 162 "i", // SignedInt 163 "Ui", // UnsignedInt 164 "l", // LongSignedInt 165 "Ul", // LongUnsignedInt 166 "q", // LongLongSignedInt 167 "Uq", // LongLongUnsignedInt 168 "f", // Float 169 "d", // Double 170 "r", // LongDouble 171 "Xf", // FloatComplex 172 "Xd", // DoubleComplex 173 "Xr", // LongDoubleComplex 174 "If", // FloatImaginary 175 "Id", // DoubleImaginary 176 "Ir", // LongDoubleImaginary 177 "w", // SignedInt128 178 "Uw", // UnsignedInt128 179 }; 180 181 printQualifiers( basicType ); 182 mangleName << btLetter[ basicType->get_kind() ]; 183 } 184 185 void Mangler::postvisit( PointerType * pointerType ) { 186 printQualifiers( pointerType ); 187 mangleName << "P"; 188 maybeAccept( pointerType->get_base(), *visitor ); 189 } 190 191 void Mangler::postvisit( ArrayType * arrayType ) { 192 // TODO: encode dimension 193 printQualifiers( arrayType ); 194 mangleName << "A0"; 195 maybeAccept( arrayType->get_base(), *visitor ); 196 } 197 198 void Mangler::postvisit( ReferenceType * refType ) { 199 printQualifiers( refType ); 200 mangleName << "R"; 201 maybeAccept( refType->get_base(), *visitor ); 202 } 203 204 namespace { 205 inline std::list< Type* > getTypes( const std::list< DeclarationWithType* > decls ) { 206 std::list< Type* > ret; 207 std::transform( decls.begin(), decls.end(), std::back_inserter( ret ), 208 std::mem_fun( &DeclarationWithType::get_type ) ); 209 return ret; 210 } 211 } 212 213 void Mangler::postvisit( FunctionType * functionType ) { 214 printQualifiers( functionType ); 215 mangleName << "F"; 216 std::list< Type* > returnTypes = getTypes( functionType->get_returnVals() ); 217 acceptAll( returnTypes, *visitor ); 178 218 mangleName << "_"; 179 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) { 180 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 181 assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str()); 182 maybeAccept( paramType->get_type(), *this ); 219 std::list< Type* > paramTypes = getTypes( functionType->get_parameters() ); 220 acceptAll( paramTypes, *visitor ); 221 mangleName << "_"; 222 } 223 224 void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) { 225 printQualifiers( refType ); 226 227 mangleName << ( refType->get_name().length() + prefix.length() ) << prefix << refType->get_name(); 228 229 if ( mangleGenericParams ) { 230 std::list< Expression* >& params = refType->get_parameters(); 231 if ( ! params.empty() ) { 232 mangleName << "_"; 233 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) { 234 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 235 assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str()); 236 maybeAccept( paramType->get_type(), *visitor ); 237 } 238 mangleName << "_"; 239 } 183 240 } 241 } 242 243 void Mangler::postvisit( StructInstType * aggregateUseType ) { 244 mangleRef( aggregateUseType, "s" ); 245 } 246 247 void Mangler::postvisit( UnionInstType * aggregateUseType ) { 248 mangleRef( aggregateUseType, "u" ); 249 } 250 251 void Mangler::postvisit( EnumInstType * aggregateUseType ) { 252 mangleRef( aggregateUseType, "e" ); 253 } 254 255 void Mangler::postvisit( TypeInstType * typeInst ) { 256 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 257 if ( varNum == varNums.end() ) { 258 mangleRef( typeInst, "t" ); 259 } else { 260 printQualifiers( typeInst ); 261 std::ostringstream numStream; 262 numStream << varNum->second.first; 263 switch ( (TypeDecl::Kind )varNum->second.second ) { 264 case TypeDecl::Dtype: 265 mangleName << "d"; 266 break; 267 case TypeDecl::Ftype: 268 mangleName << "f"; 269 break; 270 case TypeDecl::Ttype: 271 mangleName << "tVARGS"; 272 break; 273 default: 274 assert( false ); 275 } // switch 276 mangleName << numStream.str(); 277 } // if 278 } 279 280 void Mangler::postvisit( TupleType * tupleType ) { 281 printQualifiers( tupleType ); 282 mangleName << "T"; 283 acceptAll( tupleType->types, *visitor ); 184 284 mangleName << "_"; 185 285 } 186 } 187 } 188 189 void Mangler::visit( StructInstType * aggregateUseType ) { 190 mangleRef( aggregateUseType, "s" ); 191 } 192 193 void Mangler::visit( UnionInstType * aggregateUseType ) { 194 mangleRef( aggregateUseType, "u" ); 195 } 196 197 void Mangler::visit( EnumInstType * aggregateUseType ) { 198 mangleRef( aggregateUseType, "e" ); 199 } 200 201 void Mangler::visit( TypeInstType * typeInst ) { 202 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 203 if ( varNum == varNums.end() ) { 204 mangleRef( typeInst, "t" ); 205 } else { 206 printQualifiers( typeInst ); 207 std::ostringstream numStream; 208 numStream << varNum->second.first; 209 switch ( (TypeDecl::Kind )varNum->second.second ) { 210 case TypeDecl::Dtype: 211 mangleName << "d"; 212 break; 213 case TypeDecl::Ftype: 214 mangleName << "f"; 215 break; 216 case TypeDecl::Ttype: 217 mangleName << "tVARGS"; 218 break; 219 default: 220 assert( false ); 221 } // switch 222 mangleName << numStream.str(); 223 } // if 224 } 225 226 void Mangler::visit( TupleType * tupleType ) { 227 printQualifiers( tupleType ); 228 mangleName << "T"; 229 acceptAll( tupleType->types, *this ); 230 mangleName << "_"; 231 } 232 233 void Mangler::visit( VarArgsType * varArgsType ) { 234 printQualifiers( varArgsType ); 235 mangleName << "VARGS"; 236 } 237 238 void Mangler::visit( ZeroType * ) { 239 mangleName << "Z"; 240 } 241 242 void Mangler::visit( OneType * ) { 243 mangleName << "O"; 244 } 245 246 void Mangler::visit( TypeDecl * decl ) { 247 static const char *typePrefix[] = { "BT", "BD", "BF" }; 248 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name; 249 } 250 251 void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) { 252 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) { 253 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl; 254 } // for 255 } 256 257 void Mangler::printQualifiers( Type * type ) { 258 // skip if not including qualifiers 259 if ( typeMode ) return; 260 261 if ( ! type->get_forall().empty() ) { 262 std::list< std::string > assertionNames; 263 int tcount = 0, dcount = 0, fcount = 0, vcount = 0; 264 mangleName << "A"; 265 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) { 266 switch ( (*i)->get_kind() ) { 267 case TypeDecl::Dtype: 268 dcount++; 269 break; 270 case TypeDecl::Ftype: 271 fcount++; 272 break; 273 case TypeDecl::Ttype: 274 vcount++; 275 break; 276 default: 277 assert( false ); 278 } // switch 279 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); 280 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { 281 Mangler sub_mangler( mangleOverridable, typeMode, mangleGenericParams ); 282 sub_mangler.nextVarNum = nextVarNum; 283 sub_mangler.isTopLevel = false; 284 sub_mangler.varNums = varNums; 285 (*assert)->accept( sub_mangler ); 286 assertionNames.push_back( sub_mangler.mangleName.str() ); 286 287 void Mangler::postvisit( VarArgsType * varArgsType ) { 288 printQualifiers( varArgsType ); 289 mangleName << "VARGS"; 290 } 291 292 void Mangler::postvisit( ZeroType * ) { 293 mangleName << "Z"; 294 } 295 296 void Mangler::postvisit( OneType * ) { 297 mangleName << "O"; 298 } 299 300 void Mangler::postvisit( TypeDecl * decl ) { 301 static const char *typePrefix[] = { "BT", "BD", "BF" }; 302 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name; 303 } 304 305 __attribute__((unused)) void printVarMap( const std::map< std::string, std::pair< int, int > > &varMap, std::ostream &os ) { 306 for ( std::map< std::string, std::pair< int, int > >::const_iterator i = varMap.begin(); i != varMap.end(); ++i ) { 307 os << i->first << "(" << i->second.first << "/" << i->second.second << ")" << std::endl; 287 308 } // for 288 } // for 289 mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_"; 290 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); 291 mangleName << "_"; 292 } // if 293 if ( type->get_const() ) { 294 mangleName << "C"; 295 } // if 296 if ( type->get_volatile() ) { 297 mangleName << "V"; 298 } // if 299 if ( type->get_mutex() ) { 300 mangleName << "M"; 301 } // if 302 // Removed due to restrict not affecting function compatibility in GCC 303 // if ( type->get_isRestrict() ) { 304 // mangleName << "E"; 305 // } // if 306 if ( type->get_lvalue() ) { 307 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues 308 mangleName << "L"; 309 } 310 if ( type->get_atomic() ) { 311 mangleName << "A"; 312 } // if 313 } 309 } 310 311 void Mangler::printQualifiers( Type * type ) { 312 // skip if not including qualifiers 313 if ( typeMode ) return; 314 315 if ( ! type->get_forall().empty() ) { 316 std::list< std::string > assertionNames; 317 int tcount = 0, dcount = 0, fcount = 0, vcount = 0; 318 mangleName << "A"; 319 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) { 320 switch ( (*i)->get_kind() ) { 321 case TypeDecl::Dtype: 322 dcount++; 323 break; 324 case TypeDecl::Ftype: 325 fcount++; 326 break; 327 case TypeDecl::Ttype: 328 vcount++; 329 break; 330 default: 331 assert( false ); 332 } // switch 333 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); 334 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { 335 PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams ); 336 sub_mangler.pass.nextVarNum = nextVarNum; 337 sub_mangler.pass.isTopLevel = false; 338 sub_mangler.pass.varNums = varNums; 339 (*assert)->accept( sub_mangler ); 340 assertionNames.push_back( sub_mangler.pass.mangleName.str() ); 341 } // for 342 } // for 343 mangleName << tcount << "_" << dcount << "_" << fcount << "_" << vcount << "_"; 344 std::copy( assertionNames.begin(), assertionNames.end(), std::ostream_iterator< std::string >( mangleName, "" ) ); 345 mangleName << "_"; 346 } // if 347 if ( type->get_const() ) { 348 mangleName << "C"; 349 } // if 350 if ( type->get_volatile() ) { 351 mangleName << "V"; 352 } // if 353 if ( type->get_mutex() ) { 354 mangleName << "M"; 355 } // if 356 // Removed due to restrict not affecting function compatibility in GCC 357 // if ( type->get_isRestrict() ) { 358 // mangleName << "E"; 359 // } // if 360 if ( type->get_lvalue() ) { 361 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues 362 mangleName << "L"; 363 } 364 if ( type->get_atomic() ) { 365 mangleName << "A"; 366 } // if 367 } 368 } // namespace 369 } // namespace Mangler 314 370 } // namespace SymTab 315 371 -
src/SymTab/Mangler.h
rd2d50d7 r81e1f32 25 25 26 26 namespace SymTab { 27 /// Mangles names to a unique C identifier 28 class Mangler : public Visitor { 29 public: 27 namespace Mangler { 30 28 /// Mangle syntax tree object; primary interface to clients 31 template< typename SynTreeClass >32 static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true ); 29 std::string mangle( BaseSyntaxNode * decl, bool mangleOverridable = true, bool typeMode = false, bool mangleGenericParams = true ); 30 33 31 /// Mangle a type name; secondary interface 34 st atic std::string mangleType( Type* ty );32 std::string mangleType( Type* ty ); 35 33 /// Mangle ignoring generic type parameters 36 static std::string mangleConcrete( Type* ty ); 37 38 39 virtual void visit( ObjectDecl *declaration ); 40 virtual void visit( FunctionDecl *declaration ); 41 virtual void visit( TypeDecl *declaration ); 42 43 virtual void visit( VoidType *voidType ); 44 virtual void visit( BasicType *basicType ); 45 virtual void visit( PointerType *pointerType ); 46 virtual void visit( ArrayType *arrayType ); 47 virtual void visit( ReferenceType *refType ); 48 virtual void visit( FunctionType *functionType ); 49 virtual void visit( StructInstType *aggregateUseType ); 50 virtual void visit( UnionInstType *aggregateUseType ); 51 virtual void visit( EnumInstType *aggregateUseType ); 52 virtual void visit( TypeInstType *aggregateUseType ); 53 virtual void visit( TupleType *tupleType ); 54 virtual void visit( VarArgsType *varArgsType ); 55 virtual void visit( ZeroType *zeroType ); 56 virtual void visit( OneType *oneType ); 57 58 std::string get_mangleName() { return mangleName.str(); } 59 private: 60 std::ostringstream mangleName; ///< Mangled name being constructed 61 typedef std::map< std::string, std::pair< int, int > > VarMapType; 62 VarMapType varNums; ///< Map of type variables to indices 63 int nextVarNum; ///< Next type variable index 64 bool isTopLevel; ///< Is the Mangler at the top level 65 bool mangleOverridable; ///< Specially mangle overridable built-in methods 66 bool typeMode; ///< Produce a unique mangled name for a type 67 bool mangleGenericParams; ///< Include generic parameters in name mangling if true 68 69 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 70 Mangler( const Mangler & ); 71 72 void mangleDecl( DeclarationWithType *declaration ); 73 void mangleRef( ReferenceToType *refType, std::string prefix ); 74 75 void printQualifiers( Type *type ); 76 }; // Mangler 77 78 template< typename SynTreeClass > 79 std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool typeMode, bool mangleGenericParams ) { 80 Mangler mangler( mangleOverridable, typeMode, mangleGenericParams ); 81 maybeAccept( decl, mangler ); 82 return mangler.get_mangleName(); 83 } 34 std::string mangleConcrete( Type* ty ); 35 } // Mangler 84 36 } // SymTab 85 37 -
src/SynTree/CompoundStmt.cc
rd2d50d7 r81e1f32 64 64 } 65 65 if ( ! declMap.empty() ) { 66 VarExprReplacer replacer( declMap ); 67 accept( replacer ); 66 VarExprReplacer::replace( this, declMap ); 68 67 } 69 68 } -
src/SynTree/FunctionDecl.cc
rd2d50d7 r81e1f32 49 49 } 50 50 if ( ! declMap.empty() ) { 51 VarExprReplacer replacer( declMap ); 52 accept( replacer ); 51 VarExprReplacer::replace( this, declMap ); 53 52 } 54 53 } -
src/SynTree/VarExprReplacer.cc
rd2d50d7 r81e1f32 16 16 #include <iostream> // for operator<<, basic_ostream, ostream, basic_o... 17 17 18 #include "Common/PassVisitor.h" 18 19 #include "Declaration.h" // for operator<<, DeclarationWithType 19 20 #include "Expression.h" // for VariableExpr 20 21 #include "VarExprReplacer.h" 21 22 22 VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {} 23 namespace VarExprReplacer { 24 namespace { 25 /// Visitor that replaces the declarations that VariableExprs refer to, according to the supplied mapping 26 struct VarExprReplacer { 27 private: 28 const DeclMap & declMap; 29 bool debug; 30 public: 31 VarExprReplacer( const DeclMap & declMap, bool debug = false ); 23 32 24 // replace variable with new node from decl map 25 void VarExprReplacer::visit( VariableExpr * varExpr ) { 26 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 27 if ( declMap.count( varExpr->get_var() ) ) { 28 if ( debug ) { 29 std::cerr << "replacing variable reference: " << (void*)varExpr->get_var() << " " << varExpr->get_var() << " with " << (void*)declMap.at( varExpr->get_var() ) << " " << declMap.at( varExpr->get_var() ) << std::endl; 33 // replace variable with new node from decl map 34 void previsit( VariableExpr * varExpr ); 35 }; 36 } 37 38 void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug ) { 39 PassVisitor<VarExprReplacer> replacer( declMap, debug ); 40 maybeAccept( node, replacer ); 41 } 42 43 namespace { 44 VarExprReplacer::VarExprReplacer( const DeclMap & declMap, bool debug ) : declMap( declMap ), debug( debug ) {} 45 46 // replace variable with new node from decl map 47 void VarExprReplacer::previsit( VariableExpr * varExpr ) { 48 // xxx - assertions and parameters aren't accounted for in this... (i.e. they aren't inserted into the map when it's made, only DeclStmts are) 49 if ( declMap.count( varExpr->var ) ) { 50 if ( debug ) { 51 std::cerr << "replacing variable reference: " << (void*)varExpr->var << " " << varExpr->var << " with " << (void*)declMap.at( varExpr->var ) << " " << declMap.at( varExpr->var ) << std::endl; 52 } 53 varExpr->var = declMap.at( varExpr->var ); 54 } 30 55 } 31 varExpr->set_var( declMap.at( varExpr->get_var() ) );32 56 } 33 } 57 } // namespace VarExprReplacer 58 59 60 61 62 63 64 -
src/SynTree/VarExprReplacer.h
rd2d50d7 r81e1f32 23 23 class VariableExpr; 24 24 25 /// Visitor that replaces the declarations that VariableExprs refer to, according to the supplied mapping 26 class VarExprReplacer : public Visitor { 27 public: 25 namespace VarExprReplacer { 28 26 typedef std::map< DeclarationWithType *, DeclarationWithType * > DeclMap; 29 private:30 const DeclMap & declMap;31 bool debug;32 public:33 VarExprReplacer( const DeclMap & declMap, bool debug = false );34 27 35 // replace variable with new node from decl map 36 virtual void visit( VariableExpr * varExpr ); 37 38 static void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false ) { 39 VarExprReplacer replacer( declMap, debug ); 40 maybeAccept( node, replacer ); 41 } 42 }; 28 void replace( BaseSyntaxNode * node, const DeclMap & declMap, bool debug = false ); 29 } 43 30 44 31 // Local Variables: // -
src/tests/.expect/alloc-ERROR.txt
rd2d50d7 r81e1f32 1 1 alloc.c:264:1 error: No reasonable alternatives for expression Applying untyped: 2 Name: ?=? 3 ...to: 4 Name: p 5 Applying untyped: 6 Name: realloc 7 ...to: 8 Name: stp 9 Applying untyped: 10 Name: ?*? 11 ...to: 12 Name: dim 13 Sizeof Expression on: Applying untyped: 14 Name: *? 15 ...to: 16 Name: stp 17 18 19 20 21 alloc.c:265:1 error: No reasonable alternatives for expression Applying untyped: 2 22 Name: ?=? 3 23 ...to: … … 19 39 20 40 21 alloc.c:26 5:1 error: No reasonable alternatives for expression Applying untyped:41 alloc.c:266:1 error: No reasonable alternatives for expression Applying untyped: 22 42 Name: ?=? 23 43 ...to: … … 30 50 31 51 32 alloc.c:26 6:1 error: No reasonable alternatives for expression Applying untyped:52 alloc.c:267:1 error: No reasonable alternatives for expression Applying untyped: 33 53 Name: ?=? 34 54 ...to: -
src/tests/.expect/alloc.txt
rd2d50d7 r81e1f32 60 60 pointer arithmetic 0 61 61 CFA deep malloc 0xdeadbeef 62 63 SHOULD FAIL -
src/tests/alloc.c
rd2d50d7 r81e1f32 10 10 // Created On : Wed Feb 3 07:56:22 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Nov 24 23:06:42 201713 // Update Count : 3 1912 // Last Modified On : Mon Jan 22 21:26:40 2018 13 // Update Count : 326 14 14 // 15 15 … … 32 32 // allocation, non-array types 33 33 34 // int & r = malloc();34 // int & r = malloc(); 35 35 // r = 0xdeadbeef; 36 36 // printf( "C malloc %#x\n", r ); 37 37 // free( &r ); 38 38 39 p = (int *) (void *)malloc( sizeof(*p) );// C malloc, type unsafe39 p = (int *)malloc( sizeof(*p) ); // C malloc, type unsafe 40 40 *p = 0xdeadbeef; 41 41 printf( "C malloc %#x\n", *p ); … … 88 88 printf( "\n" ); 89 89 90 p = (int *) (void *)realloc( p, dim * sizeof(*p) );// C realloc90 p = (int *)realloc( p, dim * sizeof(*p) ); // C realloc 91 91 for ( int i = 0; i < dim; i += 1 ) { p[i] = 0xdeadbeef; } 92 92 printf( "C realloc\n" ); … … 259 259 free( p ); 260 260 261 #ifdef ERR1 261 262 stp = malloc(); 262 263 printf( "\nSHOULD FAIL\n" ); 263 #ifdef ERR1 264 p = alloc( stp, dim * sizeof( *stp) );264 p = realloc( stp, dim * sizeof( *stp ) ); 265 p = alloc( stp, dim * sizeof( *stp ) ); 265 266 p = memset( stp, 10 ); 266 267 p = memcpy( &st1, &st ); -
src/tests/vector.c
rd2d50d7 r81e1f32 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // libcfa_vector.c --7 // vector.c -- 8 8 // 9 9 // Author : Thierry Delisle 10 10 // Created On : Mon Jul 4 23:36:19 2016 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : T ue Jul 5 15:08:05 201613 // Update Count : 2 612 // Last Modified On : Thu Jan 18 17:08:08 2018 13 // Update Count : 27 14 14 // 15 15 … … 63 63 // Local Variables: // 64 64 // tab-width: 4 // 65 // compile-command: "cfa libcfa_vector.c" //65 // compile-command: "cfa vector.c" // 66 66 // End: //
Note: See TracChangeset
for help on using the changeset viewer.