- Timestamp:
- Jan 15, 2019, 4:16:15 PM (7 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, no_list, persistent-indexer, pthread-emulation, qualifiedEnum
- Children:
- c802eb88
- Parents:
- 5e49e47 (diff), c9aba81 (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:
-
- 5 added
- 31 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeTools/ResolvProtoDump.cc
r5e49e47 rd0c91a6 51 51 52 52 /// Child constructor 53 ProtoDump(const ProtoDump* p, Type* r) 53 ProtoDump(const ProtoDump* p, Type* r) 54 54 : decls(), exprs(), subs(), closed(p->closed), parent(p), rtnType(r) {} 55 55 56 56 // Fix copy issues 57 ProtoDump(const ProtoDump& o) 58 : decls(o.decls), exprs(o.exprs), subs(o.subs), closed(o.closed), parent(o.parent), 57 ProtoDump(const ProtoDump& o) 58 : decls(o.decls), exprs(o.exprs), subs(o.subs), closed(o.closed), parent(o.parent), 59 59 rtnType(maybeClone(o.rtnType.get())) {} 60 60 ProtoDump( ProtoDump&& ) = default; … … 69 69 parent = o.parent; 70 70 rtnType.reset( maybeClone(o.rtnType.get()) ); 71 71 72 72 return *this; 73 73 } 74 ProtoDump& operator= (ProtoDump&&) = de fault;74 ProtoDump& operator= (ProtoDump&&) = delete; 75 75 76 76 private: … … 96 96 subs.emplace_back( std::move(sub.pass) ); 97 97 } 98 98 99 99 /// Whether lists should be separated, terminated, or preceded by their separator 100 100 enum septype { separated, terminated, preceded }; … … 102 102 /// builds space-separated list of types 103 103 template<typename V> 104 static void build( V& visitor, const std::list< Type* >& tys, std::stringstream& ss, 104 static void build( V& visitor, const std::list< Type* >& tys, std::stringstream& ss, 105 105 septype mode = separated ) { 106 106 if ( tys.empty() ) return; … … 121 121 /// builds list of types wrapped as tuple type 122 122 template<typename V> 123 static void buildAsTuple( V& visitor, const std::list< Type* >& tys, 123 static void buildAsTuple( V& visitor, const std::list< Type* >& tys, 124 124 std::stringstream& ss ) { 125 125 switch ( tys.size() ) { … … 162 162 if ( name.compare( 0, 10, "_operator_" ) == 0 ) { 163 163 ss << name.substr(10); 164 } else if ( name.compare( "_constructor" ) == 0 164 } else if ( name.compare( "_constructor" ) == 0 165 165 || name.compare( "_destructor" ) == 0 ) { 166 166 ss << name.substr(1); … … 173 173 174 174 /// replaces operators with resolv-proto names 175 static void rp_name( const std::string& name, std::stringstream& ss, 175 static void rp_name( const std::string& name, std::stringstream& ss, 176 176 std::string&& pre = "" ) { 177 177 // safety check for anonymous names … … 187 187 op_name( info.outputName, ss ); 188 188 return; 189 } 190 189 } 190 191 191 // replace retval names 192 192 if ( name.compare( 0, 8, "_retval_" ) == 0 ) { … … 195 195 return; 196 196 } 197 197 198 198 // default to just name, with first character in lowercase 199 ss << pre 199 ss << pre 200 200 << (char)std::tolower( static_cast<unsigned char>(name[0]) ) 201 201 << (name.c_str() + 1); … … 221 221 // strip trailing "_generic_" from autogen names (avoids some user-generation issues) 222 222 char generic[] = "_generic_"; size_t n_generic = sizeof(generic) - 1; 223 if ( stripped.size() >= n_generic 223 if ( stripped.size() >= n_generic 224 224 && stripped.substr( stripped.size() - n_generic ) == generic ) { 225 225 stripped.resize( stripped.size() - n_generic ); … … 237 237 unsigned depth; ///< Depth of nesting from root type 238 238 239 TypePrinter( const std::unordered_set<std::string>& closed, std::stringstream& ss ) 239 TypePrinter( const std::unordered_set<std::string>& closed, std::stringstream& ss ) 240 240 : ss(ss), closed(closed), depth(0) {} 241 241 … … 337 337 } 338 338 }; 339 339 340 340 /// builds description of function 341 341 void build( const std::string& name, FunctionType* fnTy, std::stringstream& ss ) { … … 350 350 for ( TypeDecl* tyvar : fnTy->forall ) { 351 351 for ( DeclarationWithType* assn : tyvar->assertions ) { 352 ss << " | "; 352 ss << " | "; 353 353 build( assn->name, assn->get_type(), ss ); 354 354 } … … 360 360 // ignore top-level references 361 361 Type *norefs = ty->stripReferences(); 362 362 363 363 // fall back to function declaration if function type 364 364 if ( PointerType* pTy = dynamic_cast< PointerType* >(norefs) ) { … … 409 409 std::stringstream& ss; ///< Output to print to 410 410 411 ExprPrinter( const std::unordered_set<std::string>& closed, std::stringstream& ss ) 411 ExprPrinter( const std::unordered_set<std::string>& closed, std::stringstream& ss ) 412 412 : closed(closed), ss(ss) {} 413 413 … … 476 476 visit_children = false; 477 477 } 478 478 479 479 /// Member access handled as function from aggregate to member 480 480 void previsit( UntypedMemberExpr* expr ) { … … 662 662 } 663 663 } 664 664 665 665 // add named parameters and returns to local scope 666 666 body.pass.addAll( decl->type->returnVals ); … … 679 679 void previsit( StructDecl* sd ) { addAggregateFields(sd); } 680 680 void previsit( UnionDecl* ud ) { addAggregateFields(ud); } 681 681 682 682 void previsit( EnumDecl* ed ) { 683 std::unique_ptr<Type> eType = 683 std::unique_ptr<Type> eType = 684 684 std::make_unique<BasicType>( Type::Qualifiers{}, BasicType::SignedInt ); 685 685 686 686 // add field names directly to enclosing scope 687 687 for ( Declaration* member : ed->members ) { -
src/Common/utility.h
r5e49e47 rd0c91a6 26 26 #include <string> 27 27 #include <type_traits> 28 #include <utility> 28 29 29 30 #include <cassert> … … 462 463 std::pair<long long int, bool> eval(Expression * expr); 463 464 465 // ----------------------------------------------------------------------------- 466 /// Reorders the input range in-place so that the minimal-value elements according to the 467 /// comparator are in front; 468 /// returns the iterator after the last minimal-value element. 469 template<typename Iter, typename Compare> 470 Iter sort_mins( Iter begin, Iter end, Compare& lt ) { 471 if ( begin == end ) return end; 472 473 Iter min_pos = begin; 474 for ( Iter i = begin + 1; i != end; ++i ) { 475 if ( lt( *i, *min_pos ) ) { 476 // new minimum cost; swap into first position 477 min_pos = begin; 478 std::iter_swap( min_pos, i ); 479 } else if ( ! lt( *min_pos, *i ) ) { 480 // duplicate minimum cost; swap into next minimum position 481 ++min_pos; 482 std::iter_swap( min_pos, i ); 483 } 484 } 485 return ++min_pos; 486 } 487 488 template<typename Iter, typename Compare> 489 inline Iter sort_mins( Iter begin, Iter end, Compare&& lt ) { 490 return sort_mins( begin, end, lt ); 491 } 492 493 /// sort_mins defaulted to use std::less 494 template<typename Iter> 495 inline Iter sort_mins( Iter begin, Iter end ) { 496 return sort_mins( begin, end, std::less<typename std::iterator_traits<Iter>::value_type>{} ); 497 } 498 464 499 // Local Variables: // 465 500 // tab-width: 4 // -
src/GenPoly/Box.cc
r5e49e47 rd0c91a6 798 798 for ( Type::ForallList::iterator tyVar = functionType->get_forall().begin(); tyVar != functionType->get_forall().end(); ++tyVar ) { 799 799 for ( std::list< DeclarationWithType *>::iterator assert = (*tyVar)->assertions.begin(); assert != (*tyVar)->assertions.end(); ++assert ) { 800 InferredParams::const_iterator inferParam = appExpr-> get_inferParams().find( (*assert)->get_uniqueId() );801 assertf( inferParam != appExpr-> get_inferParams().end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() );800 InferredParams::const_iterator inferParam = appExpr->inferParams.find( (*assert)->get_uniqueId() ); 801 assertf( inferParam != appExpr->inferParams.end(), "addInferredParams missing inferred parameter: %s in: %s", toString( *assert ).c_str(), toString( appExpr ).c_str() ); 802 802 Expression *newExpr = inferParam->second.expr->clone(); 803 803 addCast( newExpr, (*assert)->get_type(), tyVars ); -
src/GenPoly/Specialize.cc
r5e49e47 rd0c91a6 245 245 appExpr->env = TypeSubstitution::newFromExpr( appExpr, env ); 246 246 if ( inferParams ) { 247 appExpr-> get_inferParams()= *inferParams;247 appExpr->inferParams = *inferParams; 248 248 } // if 249 249 … … 284 284 std::list< Expression* >::iterator actual; 285 285 for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) { 286 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr-> get_inferParams());286 *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->inferParams ); 287 287 } 288 288 } … … 295 295 // alternatively, if order starts to matter then copy appExpr's inferParams and pass them to handleExplicitParams. 296 296 handleExplicitParams( appExpr ); 297 for ( InferredParams::iterator inferParam = appExpr-> get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {298 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, inferParam->second.inferParams.get());297 for ( InferredParams::iterator inferParam = appExpr->inferParams.begin(); inferParam != appExpr->inferParams.end(); ++inferParam ) { 298 inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &inferParam->second.expr->inferParams ); 299 299 } 300 300 } -
src/Makefile.am
r5e49e47 rd0c91a6 17 17 # create object files in directory with source files 18 18 AUTOMAKE_OPTIONS = foreign subdir-objects 19 ACLOCAL_AMFLAGS = -I automake 19 20 20 21 SRC = main.cc \ … … 126 127 ResolvExpr/PtrsCastable.cc \ 127 128 ResolvExpr/RenameVars.cc \ 129 ResolvExpr/ResolveAssertions.cc \ 128 130 ResolvExpr/Resolver.cc \ 129 131 ResolvExpr/ResolveTypeof.cc \ 132 ResolvExpr/SpecCost.cc \ 130 133 ResolvExpr/TypeEnvironment.cc \ 131 134 ResolvExpr/Unify.cc \ -
src/Makefile.in
r5e49e47 rd0c91a6 141 141 subdir = src 142 142 ACLOCAL_M4 = $(top_srcdir)/aclocal.m4 143 am__aclocal_m4_deps = $(top_srcdir)/automake/cfa.m4 \ 144 $(top_srcdir)/configure.ac 143 am__aclocal_m4_deps = $(top_srcdir)/automake/libtool.m4 \ 144 $(top_srcdir)/automake/ltoptions.m4 \ 145 $(top_srcdir)/automake/ltsugar.m4 \ 146 $(top_srcdir)/automake/ltversion.m4 \ 147 $(top_srcdir)/automake/lt~obsolete.m4 \ 148 $(top_srcdir)/automake/cfa.m4 $(top_srcdir)/configure.ac 145 149 am__configure_deps = $(am__aclocal_m4_deps) $(CONFIGURE_DEPENDENCIES) \ 146 150 $(ACLOCAL_M4) … … 151 155 CONFIG_CLEAN_VPATH_FILES = 152 156 LIBRARIES = $(noinst_LIBRARIES) 153 AR = ar154 157 AM_V_AR = $(am__v_AR_@AM_V@) 155 158 am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) … … 203 206 ResolvExpr/PtrsAssignable.$(OBJEXT) \ 204 207 ResolvExpr/PtrsCastable.$(OBJEXT) \ 205 ResolvExpr/RenameVars.$(OBJEXT) ResolvExpr/Resolver.$(OBJEXT) \ 208 ResolvExpr/RenameVars.$(OBJEXT) \ 209 ResolvExpr/ResolveAssertions.$(OBJEXT) \ 210 ResolvExpr/Resolver.$(OBJEXT) \ 206 211 ResolvExpr/ResolveTypeof.$(OBJEXT) \ 212 ResolvExpr/SpecCost.$(OBJEXT) \ 207 213 ResolvExpr/TypeEnvironment.$(OBJEXT) \ 208 214 ResolvExpr/Unify.$(OBJEXT) SymTab/Autogen.$(OBJEXT) \ … … 259 265 ResolvExpr/TypeEnvironment.$(OBJEXT) \ 260 266 ResolvExpr/CurrentObject.$(OBJEXT) \ 261 ResolvExpr/ExplodedActual.$(OBJEXT) SymTab/Indexer.$(OBJEXT) \ 262 SymTab/Mangler.$(OBJEXT) SymTab/ManglerCommon.$(OBJEXT) \ 263 SymTab/Validate.$(OBJEXT) SymTab/FixFunction.$(OBJEXT) \ 264 SymTab/Autogen.$(OBJEXT) SynTree/Type.$(OBJEXT) \ 265 SynTree/VoidType.$(OBJEXT) SynTree/BasicType.$(OBJEXT) \ 266 SynTree/PointerType.$(OBJEXT) SynTree/ArrayType.$(OBJEXT) \ 267 SynTree/ReferenceType.$(OBJEXT) SynTree/FunctionType.$(OBJEXT) \ 267 ResolvExpr/ExplodedActual.$(OBJEXT) \ 268 ResolvExpr/SpecCost.$(OBJEXT) \ 269 ResolvExpr/ResolveAssertions.$(OBJEXT) \ 270 SymTab/Indexer.$(OBJEXT) SymTab/Mangler.$(OBJEXT) \ 271 SymTab/ManglerCommon.$(OBJEXT) SymTab/Validate.$(OBJEXT) \ 272 SymTab/FixFunction.$(OBJEXT) SymTab/Autogen.$(OBJEXT) \ 273 SynTree/Type.$(OBJEXT) SynTree/VoidType.$(OBJEXT) \ 274 SynTree/BasicType.$(OBJEXT) SynTree/PointerType.$(OBJEXT) \ 275 SynTree/ArrayType.$(OBJEXT) SynTree/ReferenceType.$(OBJEXT) \ 276 SynTree/FunctionType.$(OBJEXT) \ 268 277 SynTree/ReferenceToType.$(OBJEXT) SynTree/TupleType.$(OBJEXT) \ 269 278 SynTree/TypeofType.$(OBJEXT) SynTree/AttrType.$(OBJEXT) \ … … 289 298 ___driver_cfa_cpp_OBJECTS = $(am____driver_cfa_cpp_OBJECTS) 290 299 ___driver_cfa_cpp_DEPENDENCIES = 300 AM_V_lt = $(am__v_lt_@AM_V@) 301 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 302 am__v_lt_0 = --silent 303 am__v_lt_1 = 291 304 am_demangler_OBJECTS = SymTab/demangler.$(OBJEXT) 292 305 demangler_OBJECTS = $(am_demangler_OBJECTS) … … 310 323 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ 311 324 $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 325 LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 326 $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ 327 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 328 $(AM_CXXFLAGS) $(CXXFLAGS) 312 329 AM_V_CXX = $(am__v_CXX_@AM_V@) 313 330 am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) … … 315 332 am__v_CXX_1 = 316 333 CXXLD = $(CXX) 317 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ 318 -o $@ 334 CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 335 $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ 336 $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 319 337 AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) 320 338 am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) … … 322 340 am__v_CXXLD_1 = 323 341 LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) 342 LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 343 $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) 324 344 AM_V_LEX = $(am__v_LEX_@AM_V@) 325 345 am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) … … 330 350 -e s/c++$$/h++/ -e s/c$$/h/ 331 351 YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) 352 LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 353 $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) 332 354 AM_V_YACC = $(am__v_YACC_@AM_V@) 333 355 am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) … … 336 358 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 337 359 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 360 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 361 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ 362 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 363 $(AM_CFLAGS) $(CFLAGS) 338 364 AM_V_CC = $(am__v_CC_@AM_V@) 339 365 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) … … 341 367 am__v_CC_1 = 342 368 CCLD = $(CC) 343 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 369 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 370 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 371 $(AM_LDFLAGS) $(LDFLAGS) -o $@ 344 372 AM_V_CCLD = $(am__v_CCLD_@AM_V@) 345 373 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) … … 391 419 AMTAR = @AMTAR@ 392 420 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 421 AR = @AR@ 393 422 AUTOCONF = @AUTOCONF@ 394 423 AUTOHEADER = @AUTOHEADER@ 395 424 AUTOMAKE = @AUTOMAKE@ 396 425 AWK = @AWK@ 397 BACKEND_CC = @BACKEND_CC@398 426 BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@ 399 427 CC = @CC@ … … 415 443 CPPFLAGS = @CPPFLAGS@ 416 444 CXX = @CXX@ 445 CXXCPP = @CXXCPP@ 417 446 CXXDEPMODE = @CXXDEPMODE@ 418 447 CXXFLAGS = @CXXFLAGS@ … … 420 449 DEFS = @DEFS@ 421 450 DEPDIR = @DEPDIR@ 451 DLLTOOL = @DLLTOOL@ 422 452 DRIVER_DIR = @DRIVER_DIR@ 453 DSYMUTIL = @DSYMUTIL@ 454 DUMPBIN = @DUMPBIN@ 423 455 ECHO_C = @ECHO_C@ 424 456 ECHO_N = @ECHO_N@ … … 426 458 EGREP = @EGREP@ 427 459 EXEEXT = @EXEEXT@ 460 FGREP = @FGREP@ 428 461 GREP = @GREP@ 429 462 HOST_FLAGS = @HOST_FLAGS@ … … 433 466 INSTALL_SCRIPT = @INSTALL_SCRIPT@ 434 467 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 468 LD = @LD@ 435 469 LDFLAGS = @LDFLAGS@ 436 470 LEX = @LEX@ … … 441 475 LIBOBJS = @LIBOBJS@ 442 476 LIBS = @LIBS@ 477 LIBTOOL = @LIBTOOL@ 478 LIPO = @LIPO@ 479 LN_S = @LN_S@ 443 480 LTLIBOBJS = @LTLIBOBJS@ 481 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ 444 482 MAKEINFO = @MAKEINFO@ 483 MANIFEST_TOOL = @MANIFEST_TOOL@ 445 484 MKDIR_P = @MKDIR_P@ 485 NM = @NM@ 486 NMEDIT = @NMEDIT@ 487 OBJDUMP = @OBJDUMP@ 446 488 OBJEXT = @OBJEXT@ 489 OTOOL = @OTOOL@ 490 OTOOL64 = @OTOOL64@ 447 491 PACKAGE = @PACKAGE@ 448 492 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ … … 454 498 PATH_SEPARATOR = @PATH_SEPARATOR@ 455 499 RANLIB = @RANLIB@ 500 SED = @SED@ 456 501 SET_MAKE = @SET_MAKE@ 457 502 SHELL = @SHELL@ … … 465 510 abs_top_builddir = @abs_top_builddir@ 466 511 abs_top_srcdir = @abs_top_srcdir@ 512 ac_ct_AR = @ac_ct_AR@ 467 513 ac_ct_CC = @ac_ct_CC@ 468 514 ac_ct_CXX = @ac_ct_CXX@ 515 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 469 516 am__include = @am__include@ 470 517 am__leading_dot = @am__leading_dot@ … … 516 563 # create object files in directory with source files 517 564 AUTOMAKE_OPTIONS = foreign subdir-objects 565 ACLOCAL_AMFLAGS = -I automake 518 566 SRC = main.cc MakeLibCfa.cc CompilationState.cc CodeGen/Generate.cc \ 519 567 CodeGen/CodeGenerator.cc CodeGen/GenType.cc \ … … 547 595 ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \ 548 596 ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \ 597 ResolvExpr/SpecCost.cc ResolvExpr/ResolveAssertions.cc \ 549 598 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/ManglerCommon.cc \ 550 599 SymTab/Validate.cc SymTab/FixFunction.cc SymTab/Autogen.cc \ … … 654 703 ResolvExpr/PtrsCastable.cc \ 655 704 ResolvExpr/RenameVars.cc \ 705 ResolvExpr/ResolveAssertions.cc \ 656 706 ResolvExpr/Resolver.cc \ 657 707 ResolvExpr/ResolveTypeof.cc \ 708 ResolvExpr/SpecCost.cc \ 658 709 ResolvExpr/TypeEnvironment.cc \ 659 710 ResolvExpr/Unify.cc \ … … 672 723 673 724 .SUFFIXES: 674 .SUFFIXES: .cc .ll . o .obj .yy725 .SUFFIXES: .cc .ll .lo .o .obj .yy 675 726 $(srcdir)/Makefile.in: $(srcdir)/Makefile.am $(srcdir)/CodeGen/module.mk $(srcdir)/CodeTools/module.mk $(srcdir)/Concurrency/module.mk $(srcdir)/Common/module.mk $(srcdir)/ControlStruct/module.mk $(srcdir)/GenPoly/module.mk $(srcdir)/InitTweak/module.mk $(srcdir)/Parser/module.mk $(srcdir)/ResolvExpr/module.mk $(srcdir)/SymTab/module.mk $(srcdir)/SynTree/module.mk $(srcdir)/Tuples/module.mk $(srcdir)/Validate/module.mk $(srcdir)/Virtual/module.mk $(am__configure_deps) 676 727 @for dep in $?; do \ … … 904 955 ResolvExpr/RenameVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 905 956 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 957 ResolvExpr/ResolveAssertions.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 958 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 906 959 ResolvExpr/Resolver.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 907 960 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 908 961 ResolvExpr/ResolveTypeof.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 962 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 963 ResolvExpr/SpecCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 909 964 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 910 965 ResolvExpr/TypeEnvironment.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ … … 957 1012 sed 's/$(EXEEXT)$$//' | \ 958 1013 while read p p1; do if test -f $$p \ 1014 || test -f $$p1 \ 959 1015 ; then echo "$$p"; echo "$$p"; else :; fi; \ 960 1016 done | \ … … 971 1027 if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ 972 1028 test -z "$$files" || { \ 973 echo " $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \974 $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \1029 echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \ 1030 $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \ 975 1031 } \ 976 1032 ; done … … 988 1044 989 1045 clean-cfa_cpplibPROGRAMS: 990 -test -z "$(cfa_cpplib_PROGRAMS)" || rm -f $(cfa_cpplib_PROGRAMS) 1046 @list='$(cfa_cpplib_PROGRAMS)'; test -n "$$list" || exit 0; \ 1047 echo " rm -f" $$list; \ 1048 rm -f $$list || exit $$?; \ 1049 test -n "$(EXEEXT)" || exit 0; \ 1050 list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ 1051 echo " rm -f" $$list; \ 1052 rm -f $$list 991 1053 CodeGen/Generate.$(OBJEXT): CodeGen/$(am__dirstamp) \ 992 1054 CodeGen/$(DEPDIR)/$(am__dirstamp) … … 1158 1220 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PtrsCastable.Po@am__quote@ 1159 1221 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/RenameVars.Po@am__quote@ 1222 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveAssertions.Po@am__quote@ 1160 1223 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveTypeof.Po@am__quote@ 1161 1224 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Resolver.Po@am__quote@ 1225 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SpecCost.Po@am__quote@ 1162 1226 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/TypeEnvironment.Po@am__quote@ 1163 1227 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Unify.Po@am__quote@ … … 1226 1290 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 1227 1291 1292 .cc.lo: 1293 @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ 1294 @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 1295 @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo 1296 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ 1297 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1298 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< 1299 1228 1300 .ll.cc: 1229 1301 $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) … … 1231 1303 .yy.cc: 1232 1304 $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) 1305 1306 mostlyclean-libtool: 1307 -rm -f *.lo 1308 1309 clean-libtool: 1310 -rm -rf .libs _libs 1311 -rm -rf ../driver/.libs ../driver/_libs 1233 1312 1234 1313 ID: $(am__tagged_files) … … 1390 1469 clean: clean-am 1391 1470 1392 clean-am: clean-cfa_cpplibPROGRAMS clean-generic clean- noinstLIBRARIES\1393 mostlyclean-am1471 clean-am: clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \ 1472 clean-noinstLIBRARIES mostlyclean-am 1394 1473 1395 1474 distclean: distclean-am … … 1446 1525 mostlyclean: mostlyclean-am 1447 1526 1448 mostlyclean-am: mostlyclean-compile mostlyclean-generic 1527 mostlyclean-am: mostlyclean-compile mostlyclean-generic \ 1528 mostlyclean-libtool 1449 1529 1450 1530 pdf: pdf-am … … 1461 1541 1462 1542 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ 1463 clean-cfa_cpplibPROGRAMS clean-generic clean-noinstLIBRARIES \ 1464 cscopelist-am ctags ctags-am distclean distclean-compile \ 1465 distclean-generic distclean-tags distdir dvi dvi-am html \ 1466 html-am info info-am install install-am \ 1467 install-cfa_cpplibPROGRAMS install-data install-data-am \ 1468 install-dvi install-dvi-am install-exec install-exec-am \ 1469 install-html install-html-am install-info install-info-am \ 1470 install-man install-pdf install-pdf-am install-ps \ 1471 install-ps-am install-strip installcheck installcheck-am \ 1472 installdirs maintainer-clean maintainer-clean-generic \ 1473 mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ 1474 ps ps-am tags tags-am uninstall uninstall-am \ 1543 clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \ 1544 clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ 1545 distclean-compile distclean-generic distclean-libtool \ 1546 distclean-tags distdir dvi dvi-am html html-am info info-am \ 1547 install install-am install-cfa_cpplibPROGRAMS install-data \ 1548 install-data-am install-dvi install-dvi-am install-exec \ 1549 install-exec-am install-html install-html-am install-info \ 1550 install-info-am install-man install-pdf install-pdf-am \ 1551 install-ps install-ps-am install-strip installcheck \ 1552 installcheck-am installdirs maintainer-clean \ 1553 maintainer-clean-generic mostlyclean mostlyclean-compile \ 1554 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ 1555 tags tags-am uninstall uninstall-am \ 1475 1556 uninstall-cfa_cpplibPROGRAMS 1476 1557 -
src/Parser/TypeData.cc
r5e49e47 rd0c91a6 322 322 function.params->printList( os, indent + 4 ); 323 323 } else { 324 os << string( indent + 2, ' ' ) << "with no parameters 324 os << string( indent + 2, ' ' ) << "with no parameters" << endl; 325 325 } // if 326 326 if ( function.idList ) { … … 347 347 os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl; 348 348 if ( aggregate.params ) { 349 os << string( indent + 2, ' ' ) << "with type parameters 349 os << string( indent + 2, ' ' ) << "with type parameters" << endl; 350 350 aggregate.params->printList( os, indent + 4 ); 351 351 } // if 352 352 if ( aggregate.actuals ) { 353 os << string( indent + 2, ' ' ) << "instantiated with actual parameters 353 os << string( indent + 2, ' ' ) << "instantiated with actual parameters" << endl; 354 354 aggregate.actuals->printList( os, indent + 4 ); 355 355 } // if 356 356 if ( aggregate.fields ) { 357 os << string( indent + 2, ' ' ) << "with members 357 os << string( indent + 2, ' ' ) << "with members" << endl; 358 358 aggregate.fields->printList( os, indent + 4 ); 359 359 } // if 360 360 if ( aggregate.body ) { 361 os << string( indent + 2, ' ' ) << " with body 361 os << string( indent + 2, ' ' ) << " with body" << endl; 362 362 } // if 363 363 break; … … 370 370 } // if 371 371 if ( aggInst.params ) { 372 os << string( indent + 2, ' ' ) << "with parameters 372 os << string( indent + 2, ' ' ) << "with parameters" << endl; 373 373 aggInst.params->printList( os, indent + 2 ); 374 374 } // if … … 381 381 } // if 382 382 if ( enumeration.body ) { 383 os << string( indent + 2, ' ' ) << " with body 383 os << string( indent + 2, ' ' ) << " with body" << endl; 384 384 } // if 385 385 break; … … 418 418 os << "tuple "; 419 419 if ( tuple ) { 420 os << "with members 420 os << "with members" << endl; 421 421 tuple->printList( os, indent + 2 ); 422 422 } // if … … 942 942 assert( td->typeexpr ); 943 943 // assert( td->typeexpr->expr ); 944 return new TypeofType{ 944 return new TypeofType{ 945 945 buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof }; 946 946 } // buildTypeof -
src/ResolvExpr/Alternative.cc
r5e49e47 rd0c91a6 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:44:23 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat May 16 23:54:23 201513 // Update Count : 211 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Thu Oct 11 10:55:00 2018 13 // Update Count : 3 14 14 // 15 15 … … 20 20 #include <utility> // for move 21 21 22 #include "Common/utility.h" // for maybeClone22 #include "Common/utility.h" // for cloneAll 23 23 #include "ResolvExpr/Cost.h" // for Cost, Cost::zero, operator<< 24 24 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment … … 27 27 28 28 namespace ResolvExpr { 29 Alternative::Alternative() : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ) {} 29 Alternative::Alternative() 30 : cost( Cost::zero ), cvtCost( Cost::zero ), expr( nullptr ), env(), openVars(), need() {} 30 31 31 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost ) 32 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ) {} 32 Alternative::Alternative( Expression *expr, const TypeEnvironment &env ) 33 : cost( Cost::zero ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars(), need() {} 34 35 Alternative::Alternative( const Alternative &o, Expression *expr, const Cost &cost ) 36 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( o.env ), openVars( o.openVars ), 37 need() { cloneAll( o.need, need ); } 33 38 34 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, const Cost& cost, const Cost &cvtCost ) 35 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ) {} 39 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 40 const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost ) 41 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ), 42 need() { cloneAll( oneed, need ); } 36 43 37 Alternative::Alternative( const Alternative &other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ), env( other.env ) { 38 } 44 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 45 const OpenVarSet& openVars, const AssertionList& oneed, const Cost& cost, 46 const Cost &cvtCost ) 47 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ), 48 need() { cloneAll( oneed, need ); } 49 50 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 51 const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost) 52 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( env ), openVars( openVars ), 53 need() { cloneAll( oneed, need ); } 54 55 Alternative::Alternative( Expression *expr, const TypeEnvironment &env, 56 const OpenVarSet &openVars, const AssertionSet &oneed, const Cost &cost, 57 const Cost& cvtCost ) 58 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( env ), openVars( openVars ), 59 need() { cloneAll( oneed, need ); } 60 61 Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 62 AssertionSet &&needSet, const Cost &cost ) 63 : cost( cost ), cvtCost( Cost::zero ), expr( expr ), env( std::move(env) ), 64 openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {} 65 66 Alternative::Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 67 AssertionSet &&needSet, const Cost &cost, const Cost &cvtCost ) 68 : cost( cost ), cvtCost( cvtCost ), expr( expr ), env( std::move(env) ), 69 openVars( std::move(openVars) ), need( needSet.begin(), needSet.end() ) {} 70 71 Alternative::Alternative( const Alternative &other ) 72 : cost( other.cost ), cvtCost( other.cvtCost ), expr( maybeClone( other.expr ) ), 73 env( other.env ), openVars( other.openVars ), need() { cloneAll( other.need, need ); } 39 74 40 75 Alternative &Alternative::operator=( const Alternative &other ) { … … 45 80 expr = maybeClone( other.expr ); 46 81 env = other.env; 82 openVars = other.openVars; 83 need.clear(); 84 cloneAll( other.need, need ); 47 85 return *this; 48 86 } 49 87 50 Alternative::Alternative( Alternative && other ) : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), env( std::move( other.env ) ) { 51 other.expr = nullptr; 52 } 88 Alternative::Alternative( Alternative && other ) 89 : cost( other.cost ), cvtCost( other.cvtCost ), expr( other.expr ), 90 env( std::move( other.env ) ), openVars( std::move( other.openVars ) ), 91 need( std::move( other.need ) ) { other.expr = nullptr; } 53 92 54 93 Alternative & Alternative::operator=( Alternative && other ) { … … 59 98 expr = other.expr; 60 99 env = std::move( other.env ); 100 openVars = std::move( other.openVars ); 101 need = std::move( other.need ); 61 102 other.expr = nullptr; 62 103 return *this; … … 64 105 65 106 Alternative::~Alternative() { 107 for ( AssertionItem& n : need ) { delete n.decl; } 66 108 delete expr; 67 109 } … … 78 120 os << "Null expression!" << std::endl; 79 121 } // if 80 os << indent << "Environment: 122 os << indent << "Environment:"; 81 123 env.print( os, indent+1 ); 82 124 os << std::endl; -
src/ResolvExpr/Alternative.h
r5e49e47 rd0c91a6 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:45:43 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:36:36 201713 // Update Count : 311 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Thu Oct 11 10:55:00 2018 13 // Update Count : 4 14 14 // 15 15 … … 20 20 21 21 #include "Cost.h" // for Cost 22 #include "TypeEnvironment.h" // for TypeEnvironment 22 #include "TypeEnvironment.h" // for TypeEnvironment, AssertionSetValue 23 24 #include "Common/utility.h" // for maybeClone 23 25 24 26 class Expression; 25 27 26 28 namespace ResolvExpr { 29 /// One assertion to resolve 30 struct AssertionItem { 31 DeclarationWithType* decl; 32 AssertionSetValue info; 33 34 AssertionItem() = default; 35 AssertionItem( DeclarationWithType* decl, const AssertionSetValue& info ) 36 : decl(decl), info(info) {} 37 AssertionItem( const AssertionSet::value_type& e ) : decl(e.first), info(e.second) {} 38 operator AssertionSet::value_type () const { return { decl, info }; } 39 40 // to support cloneAll 41 AssertionItem clone() const { return { maybeClone(decl), info }; } 42 }; 43 /// A list of unresolved assertions 44 using AssertionList = std::vector<AssertionItem>; 45 46 /// Clones an assertion list into an assertion set 47 static inline void cloneAll( const AssertionList& src, AssertionSet& dst ) { 48 for ( const AssertionItem& item : src ) { 49 dst.emplace( maybeClone(item.decl), item.info ); 50 } 51 } 52 53 /// Clones an assertion set into an assertion list 54 static inline void cloneAll( const AssertionSet& src, AssertionList& dst ) { 55 dst.reserve( dst.size() + src.size() ); 56 for ( const auto& entry : src ) { 57 dst.emplace_back( maybeClone(entry.first), entry.second ); 58 } 59 } 60 61 /// Clones an assertion list into an assertion list 62 static inline void cloneAll( const AssertionList& src, AssertionList& dst ) { 63 dst.reserve( dst.size() + src.size() ); 64 for ( const AssertionItem& item : src ) { 65 dst.emplace_back( maybeClone(item.decl), item.info ); 66 } 67 } 68 69 /// One option for resolution of an expression 27 70 struct Alternative { 28 71 Alternative(); 29 Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost ); 30 Alternative( Expression *expr, const TypeEnvironment &env, const Cost &cost, const Cost &cvtCost ); 72 Alternative( Expression *expr, const TypeEnvironment &env ); 73 Alternative( const Alternative &o, Expression *expr, const Cost &cost ); 74 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet& openVars, 75 const AssertionList& need, const Cost &cost ); 76 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet& openVars, 77 const AssertionList& need, const Cost &cost, const Cost &cvtCost ); 78 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars, 79 const AssertionSet &need, const Cost &cost); 80 Alternative( Expression *expr, const TypeEnvironment &env, const OpenVarSet &openVars, 81 const AssertionSet &need, const Cost &cost, const Cost& cvtCost ); 82 Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 83 AssertionSet &&need, const Cost &cost ); 84 Alternative( Expression *expr, TypeEnvironment &&env, OpenVarSet &&openVars, 85 AssertionSet &&need, const Cost &cost, const Cost &cvtCost ); 31 86 Alternative( const Alternative &other ); 32 87 Alternative &operator=( const Alternative &other ); … … 44 99 } 45 100 46 Cost cost; 47 Cost cvtCost; 48 Expression *expr; 49 TypeEnvironment env; 101 /// Sorts by cost 102 bool operator< ( const Alternative& o ) const { return cost < o.cost; } 103 104 Cost cost; ///< Cost of the whole expression 105 Cost cvtCost; ///< Cost of conversions to the satisfying expression 106 Expression *expr; ///< Satisfying expression 107 TypeEnvironment env; ///< Containing type environment 108 OpenVarSet openVars; ///< Open variables for environment 109 AssertionList need; ///< Assertions which need to be resolved 50 110 }; 51 111 -
src/ResolvExpr/AlternativeFinder.cc
r5e49e47 rd0c91a6 11 11 // Last Modified By : Peter A. Buhr 12 12 // Last Modified On : Thu Nov 1 21:00:56 2018 13 // Update Count : 3 413 // Update Count : 35 14 14 // 15 15 … … 34 34 #include "InitTweak/InitTweak.h" // for getFunctionName 35 35 #include "RenameVars.h" // for RenameVars, global_renamer 36 #include "ResolveAssertions.h" // for resolveAssertions 36 37 #include "ResolveTypeof.h" // for resolveTypeof 37 38 #include "Resolver.h" // for resolveStmtExpr … … 102 103 void addAnonConversions( const Alternative & alt ); 103 104 /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member 104 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name );105 template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative &alt, const Cost &newCost, const std::string & name ); 105 106 /// Adds alternatives for member expressions where the left side has tuple type 106 void addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression *member );107 void addTupleMembers( TupleType *tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member ); 107 108 /// Adds alternatives for offsetof expressions, given the base type and name of the member 108 109 template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name ); … … 113 114 template<typename OutputIterator> 114 115 void makeFunctionAlternatives( const Alternative &func, FunctionType *funcType, const ExplodedArgs& args, OutputIterator out ); 115 /// Checks if assertion parameters match for a newalternative116 /// Sets up parameter inference for an output alternative 116 117 template< typename OutputIterator > 117 void inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out );118 void inferParameters( Alternative &newAlt, OutputIterator out ); 118 119 private: 119 120 AlternativeFinder & altFinder; … … 244 245 } 245 246 246 void AlternativeFinder::find( Expression *expr, bool adjust, bool prune, bool failFast) {247 void AlternativeFinder::find( Expression *expr, ResolvMode mode ) { 247 248 PassVisitor<Finder> finder( *this ); 248 249 expr->accept( finder ); 249 if ( failFast && alternatives.empty() ) {250 if ( mode.failFast && alternatives.empty() ) { 250 251 PRINT( 251 252 std::cerr << "No reasonable alternatives for expression " << expr << std::endl; … … 253 254 SemanticError( expr, "No reasonable alternatives for expression " ); 254 255 } 255 if ( prune ) { 256 if ( mode.resolveAssns || mode.prune ) { 257 // trim candidates just to those where the assertions resolve 258 // - necessary pre-requisite to pruning 259 AltList candidates; 260 for ( unsigned i = 0; i < alternatives.size(); ++i ) { 261 resolveAssertions( alternatives[i], indexer, candidates ); 262 } 263 // fail early if none such 264 if ( mode.failFast && candidates.empty() ) { 265 std::ostringstream stream; 266 stream << "No resolvable alternatives for expression " << expr << "\n" 267 << "Alternatives with failing assertions are:\n"; 268 printAlts( alternatives, stream, 1 ); 269 SemanticError( expr->location, stream.str() ); 270 } 271 // reset alternatives 272 alternatives = std::move( candidates ); 273 } 274 if ( mode.prune ) { 256 275 auto oldsize = alternatives.size(); 257 276 PRINT( … … 261 280 AltList pruned; 262 281 pruneAlternatives( alternatives.begin(), alternatives.end(), back_inserter( pruned ) ); 263 if ( failFast && pruned.empty() ) {282 if ( mode.failFast && pruned.empty() ) { 264 283 std::ostringstream stream; 265 284 AltList winners; … … 280 299 } 281 300 // adjust types after pruning so that types substituted by pruneAlternatives are correctly adjusted 282 for ( AltList::iterator i = alternatives.begin(); i != alternatives.end(); ++i) {283 if ( adjust) {284 adjustExprType( i ->expr->get_result(), i->env, indexer );301 if ( mode.adjust ) { 302 for ( Alternative& i : alternatives ) { 303 adjustExprType( i.expr->get_result(), i.env, indexer ); 285 304 } 286 305 } … … 294 313 295 314 void AlternativeFinder::findWithAdjustment( Expression *expr ) { 296 find( expr, true);315 find( expr, ResolvMode::withAdjustment() ); 297 316 } 298 317 299 318 void AlternativeFinder::findWithoutPrune( Expression * expr ) { 300 find( expr, true, false);319 find( expr, ResolvMode::withoutPrune() ); 301 320 } 302 321 303 322 void AlternativeFinder::maybeFind( Expression * expr ) { 304 find( expr, true, true, false);323 find( expr, ResolvMode::withoutFailFast() ); 305 324 } 306 325 … … 317 336 318 337 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->result ) ) { 319 addAggMembers( structInst, aggrExpr.get(), alt .cost+Cost::safe, alt.env, "" );338 addAggMembers( structInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 320 339 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->result ) ) { 321 addAggMembers( unionInst, aggrExpr.get(), alt .cost+Cost::safe, alt.env, "" );340 addAggMembers( unionInst, aggrExpr.get(), alt, alt.cost+Cost::safe, "" ); 322 341 } // if 323 342 } 324 343 325 344 template< typename StructOrUnionType > 326 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const TypeEnvironment & env, const std::string & name ) {345 void AlternativeFinder::Finder::addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Alternative& alt, const Cost &newCost, const std::string & name ) { 327 346 std::list< Declaration* > members; 328 347 aggInst->lookup( name, members ); … … 332 351 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 333 352 // can't construct in place and use vector::back 334 Alternative newAlt ( new MemberExpr( dwt, expr->clone() ), env, newCost );353 Alternative newAlt{ alt, new MemberExpr{ dwt, expr->clone() }, newCost }; 335 354 renameTypes( newAlt.expr ); 336 355 addAnonConversions( newAlt ); // add anonymous member interpretations whenever an aggregate value type is seen as a member expression. … … 342 361 } 343 362 344 void AlternativeFinder::Finder::addTupleMembers( TupleType * tupleType, Expression *expr, const Cost &newCost, const TypeEnvironment & env, Expression *member ) {363 void AlternativeFinder::Finder::addTupleMembers( TupleType *tupleType, Expression *expr, const Alternative &alt, const Cost &newCost, Expression *member ) { 345 364 if ( ConstantExpr * constantExpr = dynamic_cast< ConstantExpr * >( member ) ) { 346 365 // get the value of the constant expression as an int, must be between 0 and the length of the tuple type to have meaning … … 348 367 std::string tmp; 349 368 if ( val >= 0 && (unsigned long long)val < tupleType->size() ) { 350 alternatives.push_back( Alternative( new TupleIndexExpr( expr->clone(), val ), env, newCost ) ); 369 alternatives.push_back( Alternative{ 370 alt, new TupleIndexExpr( expr->clone(), val ), newCost } ); 351 371 } // if 352 372 } // if … … 354 374 355 375 void AlternativeFinder::Finder::postvisit( ApplicationExpr *applicationExpr ) { 356 alternatives.push_back( Alternative ( applicationExpr->clone(), env, Cost::zero ));376 alternatives.push_back( Alternative{ applicationExpr->clone(), env } ); 357 377 } 358 378 … … 410 430 Cost computeApplicationConversionCost( Alternative &alt, const SymTab::Indexer &indexer ) { 411 431 ApplicationExpr *appExpr = strict_dynamic_cast< ApplicationExpr* >( alt.expr ); 412 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr-> get_function()->get_result());413 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer-> get_base());432 PointerType *pointer = strict_dynamic_cast< PointerType* >( appExpr->function->result ); 433 FunctionType *function = strict_dynamic_cast< FunctionType* >( pointer->base ); 414 434 415 435 Cost convCost = Cost::zero; 416 std::list< DeclarationWithType* >& formals = function-> get_parameters();436 std::list< DeclarationWithType* >& formals = function->parameters; 417 437 std::list< DeclarationWithType* >::iterator formal = formals.begin(); 418 std::list< Expression* >& actuals = appExpr-> get_args();419 420 for ( std::list< Expression* >::iterator actualExpr = actuals.begin(); actualExpr != actuals.end(); ++actualExpr) {421 Type * actualType = (*actualExpr)->get_result();438 std::list< Expression* >& actuals = appExpr->args; 439 440 for ( Expression*& actualExpr : actuals ) { 441 Type * actualType = actualExpr->result; 422 442 PRINT( 423 443 std::cerr << "actual expression:" << std::endl; 424 (*actualExpr)->print( std::cerr, 8 );444 actualExpr->print( std::cerr, 8 ); 425 445 std::cerr << "--- results are" << std::endl; 426 446 actualType->print( std::cerr, 8 ); 427 447 ) 428 448 if ( formal == formals.end() ) { 429 if ( function-> get_isVarArgs()) {449 if ( function->isVarArgs ) { 430 450 convCost.incUnsafe(); 431 451 PRINT( std::cerr << "end of formals with varargs function: inc unsafe: " << convCost << std::endl; ; ) 432 452 // convert reference-typed expressions to value-typed expressions 433 referenceToRvalueConversion( *actualExpr, convCost );453 referenceToRvalueConversion( actualExpr, convCost ); 434 454 continue; 435 455 } else { … … 437 457 } 438 458 } 439 if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( *actualExpr ) ) {459 if ( DefaultArgExpr * def = dynamic_cast< DefaultArgExpr * >( actualExpr ) ) { 440 460 // default arguments should be free - don't include conversion cost. 441 461 // Unwrap them here because they are not relevant to the rest of the system. 442 *actualExpr = def->expr;462 actualExpr = def->expr; 443 463 ++formal; 444 464 continue; 445 465 } 466 // mark conversion cost to formal and also specialization cost of formal type 446 467 Type * formalType = (*formal)->get_type(); 447 convCost += computeExpressionConversionCost( *actualExpr, formalType, indexer, alt.env ); 468 convCost += computeExpressionConversionCost( actualExpr, formalType, indexer, alt.env ); 469 convCost.decSpec( specCost( formalType ) ); 448 470 ++formal; // can't be in for-loop update because of the continue 449 471 } … … 452 474 } 453 475 454 for ( InferredParams::const_iterator assert = appExpr->get_inferParams().begin(); assert != appExpr->get_inferParams().end(); ++assert ) { 476 // mark specialization cost of return types 477 for ( DeclarationWithType* returnVal : function->returnVals ) { 478 convCost.decSpec( specCost( returnVal->get_type() ) ); 479 } 480 481 // mark type variable and specialization cost of forall clause 482 convCost.incVar( function->forall.size() ); 483 for ( TypeDecl* td : function->forall ) { 484 convCost.decSpec( td->assertions.size() ); 485 } 486 487 // xxx -- replace with new costs in resolver 488 for ( InferredParams::const_iterator assert = appExpr->inferParams.begin(); assert != appExpr->inferParams.end(); ++assert ) { 455 489 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 456 490 } … … 466 500 needAssertions[ *assert ].isUsed = true; 467 501 } 468 /// needAssertions.insert( needAssertions.end(), (*tyvar)->get_assertions().begin(), (*tyvar)->get_assertions().end() ); 469 } 470 } 471 472 static const int recursionLimit = /*10*/ 4; ///< Limit to depth of recursion satisfaction 473 474 void addToIndexer( AssertionSet &assertSet, SymTab::Indexer &indexer ) { 475 for ( AssertionSet::iterator i = assertSet.begin(); i != assertSet.end(); ++i ) { 476 if ( i->second.isUsed ) { 477 indexer.addId( i->first ); 478 } 479 } 480 } 481 482 template< typename ForwardIterator, typename OutputIterator > 483 void inferRecursive( ForwardIterator begin, ForwardIterator end, const Alternative &newAlt, OpenVarSet &openVars, const SymTab::Indexer &decls, const AssertionSet &newNeed, int level, const SymTab::Indexer &indexer, OutputIterator out ) { 484 if ( newAlt.cost == Cost::infinity ) return; // don't proceed down this dead end 485 if ( begin == end ) { 486 if ( newNeed.empty() ) { 487 PRINT( 488 std::cerr << "all assertions satisfied, output alternative: "; 489 newAlt.print( std::cerr ); 490 std::cerr << std::endl; 491 ); 492 *out++ = newAlt; 493 return; 494 } else if ( level >= recursionLimit ) { 495 SemanticError( newAlt.expr->location, "Too many recursive assertions" ); 496 } else { 497 AssertionSet newerNeed; 498 PRINT( 499 std::cerr << "recursing with new set:" << std::endl; 500 printAssertionSet( newNeed, std::cerr, 8 ); 501 ) 502 inferRecursive( newNeed.begin(), newNeed.end(), newAlt, openVars, decls, newerNeed, level+1, indexer, out ); 503 return; 504 } 505 } 506 507 ForwardIterator cur = begin++; 508 if ( ! cur->second.isUsed ) { 509 inferRecursive( begin, end, newAlt, openVars, decls, newNeed, level, indexer, out ); 510 return; // xxx - should this continue? previously this wasn't here, and it looks like it should be 511 } 512 DeclarationWithType *curDecl = cur->first; 513 514 PRINT( 515 std::cerr << "inferRecursive: assertion is "; 516 curDecl->print( std::cerr ); 517 std::cerr << std::endl; 518 ) 519 std::list< SymTab::Indexer::IdData > candidates; 520 decls.lookupId( curDecl->get_name(), candidates ); 521 /// if ( candidates.empty() ) { std::cerr << "no candidates!" << std::endl; } 522 for ( const auto & data : candidates ) { 523 DeclarationWithType * candidate = data.id; 524 PRINT( 525 std::cerr << "inferRecursive: candidate is "; 526 candidate->print( std::cerr ); 527 std::cerr << std::endl; 528 ) 529 530 AssertionSet newHave, newerNeed( newNeed ); 531 TypeEnvironment newEnv( newAlt.env ); 532 OpenVarSet newOpenVars( openVars ); 533 Type *adjType = candidate->get_type()->clone(); 534 adjustExprType( adjType, newEnv, indexer ); 535 renameTyVars( adjType ); 536 PRINT( 537 std::cerr << "unifying "; 538 curDecl->get_type()->print( std::cerr ); 539 std::cerr << " with "; 540 adjType->print( std::cerr ); 541 std::cerr << std::endl; 542 ) 543 if ( unify( curDecl->get_type(), adjType, newEnv, newerNeed, newHave, newOpenVars, indexer ) ) { 544 PRINT( 545 std::cerr << "success!" << std::endl; 546 ) 547 SymTab::Indexer newDecls( decls ); 548 addToIndexer( newHave, newDecls ); 549 Alternative newerAlt( newAlt ); 550 newerAlt.env = newEnv; 551 assertf( candidate->get_uniqueId(), "Assertion candidate does not have a unique ID: %s", toString( candidate ).c_str() ); 552 553 // everything with an empty idChain was pulled in by the current assertion. 554 // add current assertion's idChain + current assertion's ID so that the correct inferParameters can be found. 555 for ( auto & a : newerNeed ) { 556 if ( a.second.idChain.empty() ) { 557 a.second.idChain = cur->second.idChain; 558 a.second.idChain.push_back( curDecl->get_uniqueId() ); 559 } 560 } 561 562 Expression *varExpr = data.combine( newerAlt.cvtCost ); 563 delete varExpr->get_result(); 564 varExpr->set_result( adjType->clone() ); 565 PRINT( 566 std::cerr << "satisfying assertion " << curDecl->get_uniqueId() << " "; 567 curDecl->print( std::cerr ); 568 std::cerr << " with declaration " << candidate->get_uniqueId() << " "; 569 candidate->print( std::cerr ); 570 std::cerr << std::endl; 571 ) 572 // follow the current assertion's ID chain to find the correct set of inferred parameters to add the candidate to (i.e. the set of inferred parameters belonging to the entity which requested the assertion parameter). 573 InferredParams * inferParameters = &newerAlt.expr->get_inferParams(); 574 for ( UniqueId id : cur->second.idChain ) { 575 inferParameters = (*inferParameters)[ id ].inferParams.get(); 576 } 577 // XXX: this is a memory leak, but adjType can't be deleted because it might contain assertions 578 (*inferParameters)[ curDecl->get_uniqueId() ] = ParamEntry( candidate->get_uniqueId(), adjType->clone(), curDecl->get_type()->clone(), varExpr ); 579 inferRecursive( begin, end, newerAlt, newOpenVars, newDecls, newerNeed, level, indexer, out ); 580 } else { 581 delete adjType; 582 } 583 } 584 } 502 } 503 } 504 505 /// Unique identifier for matching expression resolutions to their requesting expression 506 UniqueId globalResnSlot = 0; 585 507 586 508 template< typename OutputIterator > 587 void AlternativeFinder::Finder::inferParameters( const AssertionSet &need, AssertionSet &have, const Alternative &newAlt, OpenVarSet &openVars, OutputIterator out ) { 588 // PRINT( 589 // std::cerr << "inferParameters: assertions needed are" << std::endl; 590 // printAll( need, std::cerr, 8 ); 591 // ) 592 SymTab::Indexer decls( indexer ); 593 // PRINT( 594 // std::cerr << "============= original indexer" << std::endl; 595 // indexer.print( std::cerr ); 596 // std::cerr << "============= new indexer" << std::endl; 597 // decls.print( std::cerr ); 598 // ) 599 addToIndexer( have, decls ); 600 AssertionSet newNeed; 601 PRINT( 602 std::cerr << "env is: " << std::endl; 603 newAlt.env.print( std::cerr, 0 ); 604 std::cerr << std::endl; 605 ) 606 607 inferRecursive( need.begin(), need.end(), newAlt, openVars, decls, newNeed, 0, indexer, out ); 608 // PRINT( 609 // std::cerr << "declaration 14 is "; 610 // Declaration::declFromId 611 // *out++ = newAlt; 612 // ) 509 void AlternativeFinder::Finder::inferParameters( Alternative &newAlt, OutputIterator out ) { 510 // Set need bindings for any unbound assertions 511 UniqueId crntResnSlot = 0; // matching ID for this expression's assertions 512 for ( auto& assn : newAlt.need ) { 513 // skip already-matched assertions 514 if ( assn.info.resnSlot != 0 ) continue; 515 // assign slot for expression if needed 516 if ( crntResnSlot == 0 ) { crntResnSlot = ++globalResnSlot; } 517 // fix slot to assertion 518 assn.info.resnSlot = crntResnSlot; 519 } 520 // pair slot to expression 521 if ( crntResnSlot != 0 ) { newAlt.expr->resnSlots.push_back( crntResnSlot ); } 522 523 // add to output list, assertion resolution is deferred 524 *out++ = newAlt; 613 525 } 614 526 … … 951 863 } 952 864 // build and validate new alternative 953 Alternative newAlt ( appExpr, result.env, cost );865 Alternative newAlt{ appExpr, result.env, result.openVars, result.need, cost }; 954 866 PRINT( 955 867 std::cerr << "instantiate function success: " << appExpr << std::endl; … … 957 869 printAssertionSet( result.need, std::cerr, 8 ); 958 870 ) 959 inferParameters( result.need, result.have, newAlt, result.openVars, out );871 inferParameters( newAlt, out ); 960 872 } 961 873 … … 1202 1114 1203 1115 // function may return struct or union value, in which case we need to add alternatives 1204 // for implicit conversions to each of the anonymous members, must happen after findMinCost1116 // for implicit conversions to each of the anonymous members, must happen after findMinCost 1205 1117 // since anon conversions are never the cheapest expression 1206 1118 for ( const Alternative & alt : winners ) { … … 1234 1146 if ( isLvalue( alt.expr ) ) { 1235 1147 alternatives.push_back( 1236 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );1148 Alternative{ alt, new AddressExpr( alt.expr->clone() ), alt.cost } ); 1237 1149 } // if 1238 1150 } // for … … 1240 1152 1241 1153 void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) { 1242 alternatives.push_back( Alternative{ expr->clone(), env , Cost::zero} );1154 alternatives.push_back( Alternative{ expr->clone(), env } ); 1243 1155 } 1244 1156 … … 1285 1197 AltList candidates; 1286 1198 for ( Alternative & alt : finder.alternatives ) { 1287 AssertionSet needAssertions, haveAssertions; 1288 OpenVarSet openVars; 1199 AssertionSet needAssertions( alt.need.begin(), alt.need.end() ); 1200 AssertionSet haveAssertions; 1201 OpenVarSet openVars{ alt.openVars }; 1289 1202 1290 1203 alt.env.extractOpenVars( openVars ); … … 1314 1227 // count one safe conversion for each value that is thrown away 1315 1228 thisCost.incSafe( discardedValues ); 1316 Alternative newAlt ( restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), alt.env,1317 alt.cost, thisCost );1318 inferParameters( needAssertions, haveAssertions, newAlt, openVars,1319 1229 Alternative newAlt{ 1230 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1231 alt.env, openVars, needAssertions, alt.cost + thisCost, thisCost }; 1232 inferParameters( newAlt, back_inserter( candidates ) ); 1320 1233 } // if 1321 1234 } // for … … 1330 1243 1331 1244 void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) { 1332 assertf( castExpr->get_result(), "Implic atevirtual cast targets not yet supported." );1245 assertf( castExpr->get_result(), "Implicit virtual cast targets not yet supported." ); 1333 1246 AlternativeFinder finder( indexer, env ); 1334 1247 // don't prune here, since it's guaranteed all alternatives will have the same type 1335 1248 finder.findWithoutPrune( castExpr->get_arg() ); 1336 1249 for ( Alternative & alt : finder.alternatives ) { 1337 alternatives.push_back( Alternative (1338 new VirtualCastExpr( alt.expr->clone(), castExpr->get_result()->clone() ),1339 alt. env, alt.cost ));1250 alternatives.push_back( Alternative{ 1251 alt, new VirtualCastExpr{ alt.expr->clone(), castExpr->get_result()->clone() }, 1252 alt.cost } ); 1340 1253 } 1341 1254 } … … 1365 1278 // find member of the given type 1366 1279 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 1367 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1280 addAggMembers( structInst, aggrExpr, *agg, cost, get_member_name(memberExpr) ); 1368 1281 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 1369 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1282 addAggMembers( unionInst, aggrExpr, *agg, cost, get_member_name(memberExpr) ); 1370 1283 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) { 1371 addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );1284 addTupleMembers( tupleType, aggrExpr, *agg, cost, memberExpr->get_member() ); 1372 1285 } // if 1373 1286 } // for … … 1375 1288 1376 1289 void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) { 1377 alternatives.push_back( Alternative ( memberExpr->clone(), env, Cost::zero ));1290 alternatives.push_back( Alternative{ memberExpr->clone(), env } ); 1378 1291 } 1379 1292 … … 1388 1301 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 1389 1302 // can't construct in place and use vector::back 1390 Alternative newAlt ( newExpr, env, Cost::zero, cost );1303 Alternative newAlt{ newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost }; 1391 1304 PRINT( 1392 1305 std::cerr << "decl is "; … … 1406 1319 // not sufficient to clone here, because variable's type may have changed 1407 1320 // since the VariableExpr was originally created. 1408 alternatives.push_back( Alternative ( new VariableExpr( variableExpr->var ), env, Cost::zero ));1321 alternatives.push_back( Alternative{ new VariableExpr{ variableExpr->var }, env } ); 1409 1322 } 1410 1323 1411 1324 void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) { 1412 alternatives.push_back( Alternative ( constantExpr->clone(), env, Cost::zero ));1325 alternatives.push_back( Alternative{ constantExpr->clone(), env } ); 1413 1326 } 1414 1327 … … 1416 1329 if ( sizeofExpr->get_isType() ) { 1417 1330 Type * newType = sizeofExpr->get_type()->clone(); 1418 alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) ); 1331 alternatives.push_back( Alternative{ 1332 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1419 1333 } else { 1420 1334 // find all alternatives for the argument to sizeof … … 1430 1344 Alternative &choice = winners.front(); 1431 1345 referenceToRvalueConversion( choice.expr, choice.cost ); 1432 alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1346 alternatives.push_back( Alternative{ 1347 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1433 1348 } // if 1434 1349 } … … 1437 1352 if ( alignofExpr->get_isType() ) { 1438 1353 Type * newType = alignofExpr->get_type()->clone(); 1439 alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) ); 1354 alternatives.push_back( Alternative{ 1355 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1440 1356 } else { 1441 1357 // find all alternatives for the argument to sizeof … … 1451 1367 Alternative &choice = winners.front(); 1452 1368 referenceToRvalueConversion( choice.expr, choice.cost ); 1453 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1369 alternatives.push_back( Alternative{ 1370 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1454 1371 } // if 1455 1372 } … … 1461 1378 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1462 1379 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1463 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) ); 1380 alternatives.push_back( Alternative{ 1381 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1464 1382 renameTypes( alternatives.back().expr ); 1465 1383 } else { … … 1480 1398 1481 1399 void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) { 1482 alternatives.push_back( Alternative ( offsetofExpr->clone(), env, Cost::zero ));1400 alternatives.push_back( Alternative{ offsetofExpr->clone(), env } ); 1483 1401 } 1484 1402 1485 1403 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1486 alternatives.push_back( Alternative ( offsetPackExpr->clone(), env, Cost::zero ));1404 alternatives.push_back( Alternative{ offsetPackExpr->clone(), env } ); 1487 1405 } 1488 1406 … … 1504 1422 Cost cost = Cost::zero; 1505 1423 Expression * newExpr = data.combine( cost ); 1506 alternatives.push_back( Alternative( new AttrExpr( newExpr, argType->clone() ), env, Cost::zero, cost ) ); 1424 alternatives.push_back( Alternative{ 1425 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1426 AssertionList{}, Cost::zero, cost } ); 1507 1427 for ( DeclarationWithType * retVal : function->returnVals ) { 1508 1428 alternatives.back().expr->result = retVal->get_type()->clone(); … … 1543 1463 Cost cost = Cost::zero; 1544 1464 Expression * newExpr = data.combine( cost ); 1545 alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) ); 1465 alternatives.push_back( Alternative{ 1466 newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } ); 1546 1467 renameTypes( alternatives.back().expr ); 1547 1468 } // for … … 1558 1479 for ( const Alternative & first : firstFinder.alternatives ) { 1559 1480 for ( const Alternative & second : secondFinder.alternatives ) { 1560 TypeEnvironment compositeEnv; 1561 compositeEnv.simpleCombine( first.env ); 1481 TypeEnvironment compositeEnv{ first.env }; 1562 1482 compositeEnv.simpleCombine( second.env ); 1563 1564 LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() ); 1565 alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) ); 1483 OpenVarSet openVars{ first.openVars }; 1484 mergeOpenVars( openVars, second.openVars ); 1485 AssertionSet need; 1486 cloneAll( first.need, need ); 1487 cloneAll( second.need, need ); 1488 1489 LogicalExpr *newExpr = new LogicalExpr{ 1490 first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() }; 1491 alternatives.push_back( Alternative{ 1492 newExpr, std::move(compositeEnv), std::move(openVars), 1493 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1566 1494 } 1567 1495 } … … 1584 1512 for ( const Alternative & second : secondFinder.alternatives ) { 1585 1513 for ( const Alternative & third : thirdFinder.alternatives ) { 1586 TypeEnvironment compositeEnv; 1587 compositeEnv.simpleCombine( first.env ); 1514 TypeEnvironment compositeEnv{ first.env }; 1588 1515 compositeEnv.simpleCombine( second.env ); 1589 1516 compositeEnv.simpleCombine( third.env ); 1590 1517 OpenVarSet openVars{ first.openVars }; 1518 mergeOpenVars( openVars, second.openVars ); 1519 mergeOpenVars( openVars, third.openVars ); 1520 AssertionSet need; 1521 cloneAll( first.need, need ); 1522 cloneAll( second.need, need ); 1523 cloneAll( third.need, need ); 1524 AssertionSet have; 1525 1591 1526 // unify true and false types, then infer parameters to produce new alternatives 1592 OpenVarSet openVars;1593 AssertionSet needAssertions, haveAssertions;1594 Alternative newAlt( 0, compositeEnv, first.cost + second.cost + third.cost );1595 1527 Type* commonType = nullptr; 1596 if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1597 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() ); 1528 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1529 need, have, openVars, indexer, commonType ) ) { 1530 ConditionalExpr *newExpr = new ConditionalExpr{ 1531 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1598 1532 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1599 1533 // convert both options to the conditional result type 1600 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env ); 1601 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env ); 1602 newAlt.expr = newExpr; 1603 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); 1534 Cost cost = first.cost + second.cost + third.cost; 1535 cost += computeExpressionConversionCost( 1536 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1537 cost += computeExpressionConversionCost( 1538 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1539 // output alternative 1540 Alternative newAlt{ 1541 newExpr, std::move(compositeEnv), std::move(openVars), 1542 AssertionList( need.begin(), need.end() ), cost }; 1543 inferParameters( newAlt, back_inserter( alternatives ) ); 1604 1544 } // if 1605 1545 } // for … … 1614 1554 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1615 1555 for ( const Alternative & alt : secondFinder.alternatives ) { 1616 alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) ); 1556 alternatives.push_back( Alternative{ 1557 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1617 1558 } // for 1618 1559 delete newFirstArg; … … 1629 1570 for ( const Alternative & first : firstFinder.alternatives ) { 1630 1571 for ( const Alternative & second : secondFinder.alternatives ) { 1631 TypeEnvironment compositeEnv; 1632 compositeEnv.simpleCombine( first.env ); 1572 TypeEnvironment compositeEnv{ first.env }; 1633 1573 compositeEnv.simpleCombine( second.env ); 1634 OpenVarSet openVars; 1635 AssertionSet needAssertions, haveAssertions; 1636 Alternative newAlt( 0, compositeEnv, first.cost + second.cost ); 1574 OpenVarSet openVars{ first.openVars }; 1575 mergeOpenVars( openVars, second.openVars ); 1576 AssertionSet need; 1577 cloneAll( first.need, need ); 1578 cloneAll( second.need, need ); 1579 AssertionSet have; 1580 1637 1581 Type* commonType = nullptr; 1638 if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1639 RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() ); 1582 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1583 openVars, indexer, commonType ) ) { 1584 RangeExpr * newExpr = 1585 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1640 1586 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1641 newAlt.expr = newExpr; 1642 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); 1587 Alternative newAlt{ 1588 newExpr, std::move(compositeEnv), std::move(openVars), 1589 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1590 inferParameters( newAlt, back_inserter( alternatives ) ); 1643 1591 } // if 1644 1592 } // for … … 1658 1606 1659 1607 TypeEnvironment compositeEnv; 1660 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 1661 alternatives.push_back( 1662 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } ); 1608 OpenVarSet openVars; 1609 AssertionSet need; 1610 for ( const Alternative& alt : alts ) { 1611 compositeEnv.simpleCombine( alt.env ); 1612 mergeOpenVars( openVars, alt.openVars ); 1613 cloneAll( alt.need, need ); 1614 } 1615 1616 alternatives.push_back( Alternative{ 1617 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1618 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1663 1619 } // for 1664 1620 } 1665 1621 1666 1622 void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) { 1667 alternatives.push_back( Alternative ( tupleExpr->clone(), env, Cost::zero ));1623 alternatives.push_back( Alternative{ tupleExpr->clone(), env } ); 1668 1624 } 1669 1625 1670 1626 void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1671 alternatives.push_back( Alternative ( impCpCtorExpr->clone(), env, Cost::zero ));1627 alternatives.push_back( Alternative{ impCpCtorExpr->clone(), env } ); 1672 1628 } 1673 1629 … … 1678 1634 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1679 1635 for ( Alternative & alt : finder.alternatives ) { 1680 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) ); 1636 alternatives.push_back( Alternative{ 1637 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1681 1638 } 1682 1639 } 1683 1640 1684 1641 void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) { 1685 alternatives.push_back( Alternative ( tupleExpr->clone(), env, Cost::zero ));1642 alternatives.push_back( Alternative{ tupleExpr->clone(), env } ); 1686 1643 } 1687 1644 1688 1645 void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) { 1689 alternatives.push_back( Alternative ( tupleAssignExpr->clone(), env, Cost::zero ));1646 alternatives.push_back( Alternative{ tupleAssignExpr->clone(), env } ); 1690 1647 } 1691 1648 … … 1696 1653 // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked" 1697 1654 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() ); 1698 alternatives.push_back( Alternative ( newUnqExpr, alt.env, alt.cost ));1655 alternatives.push_back( Alternative{ alt, newUnqExpr, alt.cost } ); 1699 1656 } 1700 1657 } … … 1704 1661 ResolvExpr::resolveStmtExpr( newStmtExpr, indexer ); 1705 1662 // xxx - this env is almost certainly wrong, and needs to somehow contain the combined environments from all of the statements in the stmtExpr... 1706 alternatives.push_back( Alternative ( newStmtExpr, env, Cost::zero ));1663 alternatives.push_back( Alternative{ newStmtExpr, env } ); 1707 1664 } 1708 1665 … … 1726 1683 for ( Alternative & alt : finder.get_alternatives() ) { 1727 1684 TypeEnvironment newEnv( alt.env ); 1728 AssertionSet needAssertions, haveAssertions; 1729 OpenVarSet openVars; // find things in env that don't have a "representative type" and claim those are open vars? 1685 AssertionSet need; 1686 cloneAll( alt.need, need ); 1687 AssertionSet have; 1688 OpenVarSet openVars( alt.openVars ); 1689 // xxx - find things in env that don't have a "representative type" and claim 1690 // those are open vars? 1730 1691 PRINT( 1731 1692 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1732 1693 ) 1733 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1734 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1735 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1736 // to. 1694 // It's possible that a cast can throw away some values in a multiply-valued 1695 // expression. (An example is a cast-to-void, which casts from one value to 1696 // zero.) Figure out the prefix of the subexpression results that are cast 1697 // directly. The candidate is invalid if it has fewer results than there are 1698 // types to cast to. 1737 1699 int discardedValues = alt.expr->result->size() - toType->size(); 1738 1700 if ( discardedValues < 0 ) continue; 1739 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1740 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1701 // xxx - may need to go into tuple types and extract relevant types and use 1702 // unifyList. Note that currently, this does not allow casting a tuple to an 1703 // atomic type (e.g. (int)([1, 2, 3])) 1704 1741 1705 // unification run for side-effects 1742 unify( toType, alt.expr->result, newEnv, needAssertions, haveAssertions, openVars, indexer ); // xxx - do some inspecting on this line... why isn't result bound to initAlt.type?? 1706 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); 1707 // xxx - do some inspecting on this line... why isn't result bound to initAlt.type? 1743 1708 1744 1709 Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv ); … … 1746 1711 // count one safe conversion for each value that is thrown away 1747 1712 thisCost.incSafe( discardedValues ); 1748 Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ); 1749 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 1713 Alternative newAlt{ 1714 new InitExpr{ 1715 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1716 std::move(newEnv), std::move(openVars), 1717 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1718 inferParameters( newAlt, back_inserter( candidates ) ); 1750 1719 } 1751 1720 } -
src/ResolvExpr/AlternativeFinder.h
r5e49e47 rd0c91a6 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sat May 16 23:56:12 2015 11 // Last Modified By : A ndrew Beach12 // Last Modified On : Wed Jul 26 11:24:00 201713 // Update Count : 411 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Oct -5 10:01:00 2018 13 // Update Count : 5 14 14 // 15 15 … … 24 24 #include "ResolvExpr/Cost.h" // for Cost, Cost::infinity 25 25 #include "ResolvExpr/TypeEnvironment.h" // for AssertionSet, OpenVarSet 26 #include "ResolvMode.h" // for ResolvMode 26 27 #include "SynTree/Visitor.h" // for Visitor 27 28 #include "SynTree/SynTree.h" // for Visitor Nodes … … 68 69 } 69 70 70 void find( Expression *expr, bool adjust = false, bool prune = true, bool failFast = true);71 void find( Expression *expr, ResolvMode mode = ResolvMode{} ); 71 72 /// Calls find with the adjust flag set; adjustment turns array and function types into equivalent pointer types 72 73 void findWithAdjustment( Expression *expr ); -
src/ResolvExpr/ConversionCost.cc
r5e49e47 rd0c91a6 28 28 29 29 namespace ResolvExpr { 30 const Cost Cost::zero = Cost( 0, 0, 0, 0 ); 31 const Cost Cost::infinity = Cost( -1, -1, -1, -1 ); 32 const Cost Cost::unsafe = Cost( 1, 0, 0, 0 ); 33 const Cost Cost::poly = Cost( 0, 1, 0, 0 ); 34 const Cost Cost::safe = Cost( 0, 0, 1, 0 ); 35 const Cost Cost::reference = Cost( 0, 0, 0, 1 ); 30 const Cost Cost::zero = Cost{ 0, 0, 0, 0, 0, 0 }; 31 const Cost Cost::infinity = Cost{ -1, -1, -1, -1, 1, -1 }; 32 const Cost Cost::unsafe = Cost{ 1, 0, 0, 0, 0, 0 }; 33 const Cost Cost::poly = Cost{ 0, 1, 0, 0, 0, 0 }; 34 const Cost Cost::safe = Cost{ 0, 0, 1, 0, 0, 0 }; 35 const Cost Cost::var = Cost{ 0, 0, 0, 1, 0, 0 }; 36 const Cost Cost::spec = Cost{ 0, 0, 0, 0, -1, 0 }; 37 const Cost Cost::reference = Cost{ 0, 0, 0, 0, 0, 1 }; 36 38 37 39 #if 0 -
src/ResolvExpr/Cost.h
r5e49e47 rd0c91a6 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 09:39:50 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:35:55 201713 // Update Count : 511 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Oct 05 14:32:00 2018 13 // Update Count : 7 14 14 // 15 15 … … 21 21 class Cost { 22 22 private: 23 Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ); 23 Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost, 24 int referenceCost ); 24 25 25 26 public: … … 27 28 Cost & incPoly( int inc = 1 ); 28 29 Cost & incSafe( int inc = 1 ); 30 Cost & incVar( int inc = 1 ); 31 Cost & decSpec( int inc = 1 ); 29 32 Cost & incReference( int inc = 1 ); 30 33 … … 32 35 int get_polyCost() const { return polyCost; } 33 36 int get_safeCost() const { return safeCost; } 37 int get_varCost() const { return varCost; } 38 int get_specCost() const { return specCost; } 34 39 int get_referenceCost() const { return referenceCost; } 35 40 … … 41 46 bool operator!=( const Cost &other ) const; 42 47 friend std::ostream &operator<<( std::ostream &os, const Cost &cost ); 48 // returns negative for *this < other, 0 for *this == other, positive for *this > other 49 int compare( const Cost &other ) const; 43 50 44 51 static const Cost zero; … … 48 55 static const Cost poly; 49 56 static const Cost safe; 57 static const Cost var; 58 static const Cost spec; 50 59 static const Cost reference; 60 51 61 private: 52 int compare( const Cost &other ) const;53 54 int unsafeCost;55 int polyCost;56 int s afeCost;57 int referenceCost; 62 int unsafeCost; ///< Unsafe (narrowing) conversions 63 int polyCost; ///< Count of parameters and return values bound to some poly type 64 int safeCost; ///< Safe (widening) conversions 65 int varCost; ///< Count of polymorphic type variables 66 int specCost; ///< Polymorphic type specializations (type assertions), negative cost 67 int referenceCost; ///< reference conversions 58 68 }; 59 69 60 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int referenceCost ) : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), referenceCost( referenceCost ) {} 70 inline Cost::Cost( int unsafeCost, int polyCost, int safeCost, int varCost, int specCost, 71 int referenceCost ) 72 : unsafeCost( unsafeCost ), polyCost( polyCost ), safeCost( safeCost ), varCost( varCost ), 73 specCost( specCost ), referenceCost( referenceCost ) {} 61 74 62 75 inline Cost & Cost::incUnsafe( int inc ) { … … 75 88 if ( *this == infinity ) return *this; 76 89 safeCost += inc; 90 return *this; 91 } 92 93 inline Cost & Cost::incVar( int inc ) { 94 if ( *this == infinity ) return *this; 95 varCost += inc; 96 return *this; 97 } 98 99 inline Cost& Cost::decSpec( int dec ) { 100 if ( *this == infinity ) return *this; 101 specCost -= dec; 77 102 return *this; 78 103 } … … 86 111 inline Cost Cost::operator+( const Cost &other ) const { 87 112 if ( *this == infinity || other == infinity ) return infinity; 88 return Cost( unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, referenceCost + other.referenceCost ); 113 return Cost{ 114 unsafeCost + other.unsafeCost, polyCost + other.polyCost, safeCost + other.safeCost, 115 varCost + other.varCost, specCost + other.specCost, 116 referenceCost + other.referenceCost }; 89 117 } 90 118 91 119 inline Cost Cost::operator-( const Cost &other ) const { 92 120 if ( *this == infinity || other == infinity ) return infinity; 93 return Cost( unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost, referenceCost - other.referenceCost ); 121 return Cost{ 122 unsafeCost - other.unsafeCost, polyCost - other.polyCost, safeCost - other.safeCost, 123 varCost - other.varCost, specCost - other.specCost, 124 referenceCost - other.referenceCost }; 94 125 } 95 126 … … 103 134 polyCost += other.polyCost; 104 135 safeCost += other.safeCost; 136 varCost += other.varCost; 137 specCost += other.specCost; 105 138 referenceCost += other.referenceCost; 106 139 return *this; … … 123 156 } else if ( safeCost < other.safeCost ) { 124 157 return true; 158 } else if ( varCost > other.varCost ) { 159 return false; 160 } else if ( varCost < other.varCost ) { 161 return true; 162 } else if ( specCost > other.specCost ) { 163 return false; 164 } else if ( specCost > other.specCost ) { 165 return true; 125 166 } else if ( referenceCost > other.referenceCost ) { 126 167 return false; … … 130 171 return false; 131 172 } // if 173 } 174 175 inline int Cost::compare( const Cost &other ) const { 176 if ( *this == infinity ) return +1; 177 if ( other == infinity ) return -1; 178 179 int c = unsafeCost - other.unsafeCost; if ( c ) return c; 180 c = polyCost - other.polyCost; if ( c ) return c; 181 c = safeCost - other.safeCost; if ( c ) return c; 182 c = varCost - other.varCost; if ( c ) return c; 183 c = specCost - other.specCost; if ( c ) return c; 184 return referenceCost - other.referenceCost; 132 185 } 133 186 … … 136 189 && polyCost == other.polyCost 137 190 && safeCost == other.safeCost 191 && varCost == other.varCost 192 && specCost == other.specCost 138 193 && referenceCost == other.referenceCost; 139 194 } … … 144 199 145 200 inline std::ostream &operator<<( std::ostream &os, const Cost &cost ) { 146 os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " << cost.safeCost << ", " << cost.referenceCost << " )"; 147 return os; 201 return os << "( " << cost.unsafeCost << ", " << cost.polyCost << ", " 202 << cost.safeCost << ", " << cost.varCost << ", " << cost.specCost << ", " 203 << cost.referenceCost << " )"; 148 204 } 149 205 } // namespace ResolvExpr -
src/ResolvExpr/Resolver.cc
r5e49e47 rd0c91a6 9 9 // Author : Richard C. Bilson 10 10 // Created On : Sun May 17 12:17:01 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Feb 17 11:19:40 201813 // Update Count : 21 311 // Last Modified By : Aaron B. Moss 12 // Last Modified On : Fri Oct 05 09:43:00 2018 13 // Update Count : 214 14 14 // 15 15 16 #include <stddef.h> // for NULL17 16 #include <cassert> // for strict_dynamic_cast, assert 18 17 #include <memory> // for allocator, allocator_traits<... 19 18 #include <tuple> // for get 20 #include <vector> 19 #include <vector> // for vector 21 20 22 21 #include "Alternative.h" // for Alternative, AltList … … 31 30 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 32 31 #include "Resolver.h" 32 #include "ResolvMode.h" // for ResolvMode 33 33 #include "SymTab/Autogen.h" // for SizeType 34 34 #include "SymTab/Indexer.h" // for Indexer … … 168 168 169 169 namespace { 170 void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, bool adjust = false, bool prune = true, bool failFast = true) {170 void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{} ) { 171 171 assertf( untyped, "expected a non-null expression." ); 172 173 // xxx - this isn't thread-safe, but should work until we parallelize the resolver 174 static unsigned recursion_level = 0; 175 176 ++recursion_level; 172 177 TypeEnvironment env; 173 178 AlternativeFinder finder( indexer, env ); 174 finder.find( untyped, adjust, prune, failFast ); 179 finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode ); 180 --recursion_level; 175 181 176 182 #if 0 … … 185 191 #endif 186 192 193 // produce filtered list of alternatives 187 194 AltList candidates; 188 195 for ( Alternative & alt : finder.get_alternatives() ) { … … 192 199 } 193 200 194 // xxx - if > 1 alternative with same cost, ignore deleted and pick from remaining 195 // choose the lowest cost expression among the candidates 201 // produce invalid error if no candidates 202 if ( candidates.empty() ) { 203 SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") ); 204 } 205 206 // search for cheapest candidate 196 207 AltList winners; 197 findMinCost( candidates.begin(), candidates.end(), back_inserter( winners ) ); 198 if ( winners.size() == 0 ) { 199 SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") ); 200 } else if ( winners.size() != 1 ) { 208 bool seen_undeleted = false; 209 for ( unsigned i = 0; i < candidates.size(); ++i ) { 210 int c = winners.empty() ? -1 : candidates[i].cost.compare( winners.front().cost ); 211 212 if ( c > 0 ) continue; // skip more expensive than winner 213 214 if ( c < 0 ) { 215 // reset on new cheapest 216 seen_undeleted = ! findDeletedExpr( candidates[i].expr ); 217 winners.clear(); 218 } else /* if ( c == 0 ) */ { 219 if ( findDeletedExpr( candidates[i].expr ) ) { 220 // skip deleted expression if already seen one equivalent-cost not 221 if ( seen_undeleted ) continue; 222 } else if ( ! seen_undeleted ) { 223 // replace list of equivalent-cost deleted expressions with one non-deleted 224 winners.clear(); 225 seen_undeleted = true; 226 } 227 } 228 229 winners.emplace_back( std::move( candidates[i] ) ); 230 } 231 232 // promote alternative.cvtCost to .cost 233 // xxx - I don't know why this is done, but I'm keeping the behaviour from findMinCost 234 for ( Alternative& winner : winners ) { 235 winner.cost = winner.cvtCost; 236 } 237 238 // produce ambiguous errors, if applicable 239 if ( winners.size() != 1 ) { 201 240 std::ostringstream stream; 202 241 stream << "Cannot choose between " << winners.size() << " alternatives for " << kindStr << (kindStr != "" ? " " : "") << "expression\n"; … … 207 246 } 208 247 209 // there is one unambiguous interpretation - move the expression into the with statement 210 Alternative & choice = winners.front(); 211 if ( findDeletedExpr( choice.expr ) ) { 248 // single selected choice 249 Alternative& choice = winners.front(); 250 251 // fail on only expression deleted 252 if ( ! seen_undeleted ) { 212 253 SemanticError( untyped->location, choice.expr, "Unique best alternative includes deleted identifier in " ); 213 254 } 255 256 // xxx - check for ambiguous expressions 257 258 // output selected choice 214 259 alt = std::move( choice ); 215 260 } 216 261 217 262 /// resolve `untyped` to the expression whose alternative satisfies `pred` with the lowest cost; kindStr is used for providing better error messages 218 void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, bool adjust = false, bool prune = true, bool failFast = true) {263 void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{}) { 219 264 if ( ! untyped ) return; 220 265 Alternative choice; 221 findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, adjust, prune, failFast);266 findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, mode ); 222 267 finishExpr( choice.expr, choice.env, untyped->env ); 223 268 delete untyped; … … 250 295 untyped.arg = expr; 251 296 Alternative choice; 252 findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, true);297 findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, ResolvMode::withAdjustment() ); 253 298 CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( choice.expr ); 254 299 env = std::move( choice.env ); … … 357 402 358 403 void Resolver::previsit( ObjectDecl *objectDecl ) { 359 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that class-variable360 // initContext is changed multiple time because the LHS is analysed twice. The second analysis changes361 // initContext because of a function type can contain object declarations in the return and parameter types. So362 // each value of initContext is retained, so the type on the first analysis is preserved and used for selecting363 // the RHS.404 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 405 // class-variable initContext is changed multiple time because the LHS is analysed twice. 406 // The second analysis changes initContext because of a function type can contain object 407 // declarations in the return and parameter types. So each value of initContext is 408 // retained, so the type on the first analysis is preserved and used for selecting the RHS. 364 409 GuardValue( currentObject ); 365 410 currentObject = CurrentObject( objectDecl->get_type() ); … … 397 442 398 443 void Resolver::postvisit( FunctionDecl *functionDecl ) { 399 // default value expressions have an environment which shouldn't be there and trips up later passes. 400 // xxx - it might be necessary to somehow keep the information from this environment, but I can't currently 401 // see how it's useful. 444 // default value expressions have an environment which shouldn't be there and trips up 445 // later passes. 446 // xxx - it might be necessary to somehow keep the information from this environment, but I 447 // can't currently see how it's useful. 402 448 for ( Declaration * d : functionDecl->type->parameters ) { 403 449 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( d ) ) { … … 749 795 initExpr->expr = nullptr; 750 796 std::swap( initExpr->env, newExpr->env ); 751 // InitExpr may have inferParams in the case where the expression specializes a function pointer, 752 // and newExpr may already have inferParams of its own, so a simple swap is not sufficient. 797 // InitExpr may have inferParams in the case where the expression specializes a function 798 // pointer, and newExpr may already have inferParams of its own, so a simple swap is not 799 // sufficient. 753 800 newExpr->spliceInferParams( initExpr ); 754 801 delete initExpr; 755 802 756 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 803 // get the actual object's type (may not exactly match what comes back from the resolver 804 // due to conversions) 757 805 Type * initContext = currentObject.getCurrentType(); 758 806 … … 766 814 if ( isCharType( pt->get_base() ) ) { 767 815 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) { 768 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 816 // strip cast if we're initializing a char[] with a char *, 817 // e.g. char x[] = "hello"; 769 818 newExpr = ce->get_arg(); 770 819 ce->set_arg( nullptr ); … … 788 837 // move cursor into brace-enclosed initializer-list 789 838 currentObject.enterListInit(); 790 // xxx - fix this so that the list isn't copied, iterator should be used to change current element 839 // xxx - fix this so that the list isn't copied, iterator should be used to change current 840 // element 791 841 std::list<Designation *> newDesignations; 792 842 for ( auto p : group_iterate(listInit->get_designations(), listInit->get_initializers()) ) { 793 // iterate designations and initializers in pairs, moving the cursor to the current designated object and resolving794 // the initializer against that object.843 // iterate designations and initializers in pairs, moving the cursor to the current 844 // designated object and resolving the initializer against that object. 795 845 Designation * des = std::get<0>(p); 796 846 Initializer * init = std::get<1>(p); … … 822 872 // fall back on C-style initializer 823 873 delete ctorInit->get_ctor(); 824 ctorInit->set_ctor( NULL);874 ctorInit->set_ctor( nullptr ); 825 875 delete ctorInit->get_dtor(); 826 ctorInit->set_dtor( NULL);876 ctorInit->set_dtor( nullptr ); 827 877 maybeAccept( ctorInit->get_init(), *visitor ); 828 878 } … … 867 917 868 918 // xxx - todo -- what about arrays? 869 // if ( dtor == NULL&& InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {919 // if ( dtor == nullptr && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) { 870 920 // // can reduce the constructor down to a SingleInit using the 871 921 // // second argument from the ctor call, since 872 922 // delete ctorInit->get_ctor(); 873 // ctorInit->set_ctor( NULL);923 // ctorInit->set_ctor( nullptr ); 874 924 875 925 // Expression * arg = -
src/ResolvExpr/TypeEnvironment.cc
r5e49e47 rd0c91a6 120 120 121 121 const EqvClass* TypeEnvironment::lookup( const std::string &var ) const { 122 for ( std::list< EqvClass >::const_iterator i = env.begin(); i != env.end(); ++i ) {122 for ( ClassList::const_iterator i = env.begin(); i != env.end(); ++i ) { 123 123 if ( i->vars.find( var ) != i->vars.end() ) return &*i; 124 124 } // for … … 168 168 169 169 void TypeEnvironment::makeSubstitution( TypeSubstitution &sub ) const { 170 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) {170 for ( ClassList::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) { 171 171 for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) { 172 172 if ( theClass->type ) { … … 188 188 } 189 189 190 std::list< EqvClass >::iterator TypeEnvironment::internal_lookup( const std::string &var ) {191 for ( std::list< EqvClass >::iterator i = env.begin(); i != env.end(); ++i ) {190 TypeEnvironment::ClassList::iterator TypeEnvironment::internal_lookup( const std::string &var ) { 191 for ( ClassList::iterator i = env.begin(); i != env.end(); ++i ) { 192 192 if ( i->vars.count( var ) ) return i; 193 193 } // for … … 199 199 } 200 200 201 // xxx -- this should maybe be worrying about iterator invalidation (see resolv-proto) 202 bool TypeEnvironment::mergeBound( EqvClass& to, const EqvClass& from, OpenVarSet& openVars, const SymTab::Indexer& indexer ) { 203 if ( from.type ) { 204 if ( to.type ) { 205 // attempt to unify bound types 206 std::unique_ptr<Type> toType{ to.type->clone() }, fromType{ from.type->clone() }; 207 WidenMode widenMode{ to.allowWidening, from.allowWidening }; 208 Type* common = nullptr; 209 AssertionSet need, have; 210 if ( unifyInexact( toType.get(), fromType.get(), *this, need, have, openVars, widenMode, indexer, common ) ) { 211 // unifies, set common type if necessary 212 if ( common ) { 213 common->get_qualifiers() = Type::Qualifiers{}; 214 to.set_type( common ); 215 } 216 } else return false; // cannot unify 217 } else { 218 to.type = from.type->clone(); 219 } 220 } 221 222 // unify widening if matches 223 to.allowWidening &= from.allowWidening; 224 return true; 225 } 226 227 // xxx -- this should maybe be worrying about iterator invalidation (see resolv-proto) 228 bool TypeEnvironment::mergeClasses( TypeEnvironment::ClassList::iterator to, TypeEnvironment::ClassList::iterator from, OpenVarSet& openVars, const SymTab::Indexer& indexer ) { 229 EqvClass& r = *to; 230 EqvClass& s = *from; 231 232 // ensure bounds match 233 if ( ! mergeBound( r, s, openVars, indexer ) ) return false; 234 235 // check safely bindable 236 if ( r.type && occursIn( r.type, s.vars.begin(), s.vars.end(), *this ) ) return false; 237 238 // merge classes in 239 r.vars.insert( s.vars.begin(), s.vars.end() ); 240 r.allowWidening &= s.allowWidening; 241 env.erase( from ); 242 243 return true; 244 } 245 246 bool TypeEnvironment::combine( const TypeEnvironment& o, OpenVarSet& openVars, const SymTab::Indexer& indexer ) { 247 // short-circuit easy cases 248 if ( o.isEmpty() ) return true; 249 if ( isEmpty() ) { 250 simpleCombine( o ); 251 return true; 252 } 253 254 // merge classes 255 for ( auto ct = o.env.begin(); ct != o.env.end(); ++ct ) { 256 const EqvClass& c = *ct; 257 258 // typeclass in local environment bound to c 259 auto rt = env.end(); 260 261 // look for first existing bound variable 262 auto vt = c.vars.begin(); 263 for ( ; vt != c.vars.end(); ++vt ) { 264 rt = internal_lookup( *vt ); 265 if ( rt != env.end() ) break; 266 } 267 268 if ( rt != env.end() ) { // c needs to be merged into *rt 269 EqvClass& r = *rt; 270 // merge bindings 271 if ( ! mergeBound( r, c, openVars, indexer ) ) return false; 272 // merge previous unbound variables into this class, checking occurs if needed 273 if ( r.type ) for ( auto ut = c.vars.begin(); ut != vt; ++ut ) { 274 if ( occurs( r.type, *ut, *this ) ) return false; 275 r.vars.insert( *ut ); 276 } else { r.vars.insert( c.vars.begin(), vt ); } 277 // merge subsequent variables into this class (skipping *vt, already there) 278 while ( ++vt != c.vars.end() ) { 279 auto st = internal_lookup( *vt ); 280 if ( st == env.end() ) { 281 // unbound, safe to add if passes occurs 282 if ( r.type && occurs( r.type, *vt, *this ) ) return false; 283 r.vars.insert( *vt ); 284 } else if ( st != rt ) { 285 // bound, but not to the same class 286 if ( ! mergeClasses( rt, st, openVars, indexer ) ) return false; 287 } // ignore bound into the same class 288 } 289 } else { // no variables in c bound; just copy up 290 env.push_back( c ); 291 } 292 } 293 294 // merged all classes 295 return true; 296 } 297 201 298 void TypeEnvironment::extractOpenVars( OpenVarSet &openVars ) const { 202 for ( std::list< EqvClass >::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) {299 for ( ClassList::const_iterator eqvClass = env.begin(); eqvClass != env.end(); ++eqvClass ) { 203 300 for ( std::set< std::string >::const_iterator var = eqvClass->vars.begin(); var != eqvClass->vars.end(); ++var ) { 204 301 openVars[ *var ] = eqvClass->data; -
src/ResolvExpr/TypeEnvironment.h
r5e49e47 rd0c91a6 39 39 // declarations. 40 40 // 41 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this comparator. 41 // I've seen a TU go from 54 minutes to 1 minute 34 seconds with the addition of this 42 // comparator. 42 43 // 43 44 // Note: since this compares pointers for position, minor changes in the source file that affect 44 45 // memory layout can alter compilation time in unpredictable ways. For example, the placement 45 46 // of a line directive can reorder type pointers with respect to each other so that assertions 46 // are seen in different orders, causing a potentially different number of unification calls when 47 // resolving assertions. I've seen a TU go from 36 seconds to 27 seconds by reordering line directives 48 // alone, so it would be nice to fix this comparison so that assertions compare more consistently. 49 // I've tried to modify this to compare on mangle name instead of type as the second comparator, but 50 // this causes some assertions to never be recorded. More investigation is needed. 47 // are seen in different orders, causing a potentially different number of unification calls 48 // when resolving assertions. I've seen a TU go from 36 seconds to 27 seconds by reordering 49 // line directives alone, so it would be nice to fix this comparison so that assertions compare 50 // more consistently. I've tried to modify this to compare on mangle name instead of type as 51 // the second comparator, but this causes some assertions to never be recorded. More 52 // investigation is needed. 51 53 struct AssertCompare { 52 54 bool operator()( DeclarationWithType * d1, DeclarationWithType * d2 ) const { … … 57 59 }; 58 60 struct AssertionSetValue { 59 bool isUsed; 60 // chain of Unique IDs of the assertion declarations. The first ID in the chain is the ID of an assertion on the current type, 61 // with each successive ID being the ID of an assertion pulled in by the previous ID. The last ID in the chain is 62 // the ID of the assertion that pulled in the current assertion. 63 std::list< UniqueId > idChain; 61 bool isUsed; ///< True if assertion needs to be resolved 62 UniqueId resnSlot; ///< ID of slot assertion belongs to 63 64 AssertionSetValue() : isUsed(false), resnSlot(0) {} 64 65 }; 65 66 typedef std::map< DeclarationWithType*, AssertionSetValue, AssertCompare > AssertionSet; 66 67 typedef std::map< std::string, TypeDecl::Data > OpenVarSet; 68 69 /// merges one set of open vars into another 70 static inline void mergeOpenVars( OpenVarSet& dst, const OpenVarSet& src ) { 71 for ( const auto& entry : src ) { dst[ entry.first ] = entry.second; } 72 } 67 73 68 74 void printAssertionSet( const AssertionSet &, std::ostream &, int indent = 0 ); … … 91 97 92 98 class TypeEnvironment { 99 using ClassList = std::list< EqvClass >; 93 100 public: 94 101 const EqvClass* lookup( const std::string &var ) const; … … 103 110 bool isEmpty() const { return env.empty(); } 104 111 void print( std::ostream &os, Indenter indent = {} ) const; 105 // void combine( const TypeEnvironment &second, Type *(*combineFunc)( Type*, Type* ) ); 112 113 /// Simply concatenate the second environment onto this one; no safety checks performed 106 114 void simpleCombine( const TypeEnvironment &second ); 115 116 private: 117 /// Unifies the type bound of to with the type bound of from, returning false if fails 118 bool mergeBound( EqvClass& to, const EqvClass& from, OpenVarSet& openVars, const SymTab::Indexer& indexer ); 119 120 /// Merges two type classes from local environment, returning false if fails 121 bool mergeClasses( ClassList::iterator to, ClassList::iterator from, OpenVarSet& openVars, const SymTab::Indexer& indexer ); 122 123 public: 124 /// Merges the second environment with this one, checking compatibility. 125 /// Returns false if fails, but does NOT roll back partial changes. 126 bool combine( const TypeEnvironment& second, OpenVarSet& openVars, const SymTab::Indexer& indexer ); 127 107 128 void extractOpenVars( OpenVarSet &openVars ) const; 108 129 TypeEnvironment *clone() const { return new TypeEnvironment( *this ); } … … 123 144 void forbidWidening(); 124 145 125 using iterator = std::list< EqvClass >::const_iterator;146 using iterator = ClassList::const_iterator; 126 147 iterator begin() const { return env.begin(); } 127 148 iterator end() const { return env.end(); } 128 149 129 150 private: 130 std::list< EqvClass >env;151 ClassList env; 131 152 132 std::list< EqvClass >::iterator internal_lookup( const std::string &var );153 ClassList::iterator internal_lookup( const std::string &var ); 133 154 }; 134 155 -
src/ResolvExpr/module.mk
r5e49e47 rd0c91a6 33 33 ResolvExpr/TypeEnvironment.cc \ 34 34 ResolvExpr/CurrentObject.cc \ 35 ResolvExpr/ExplodedActual.cc 35 ResolvExpr/ExplodedActual.cc \ 36 ResolvExpr/SpecCost.cc \ 37 ResolvExpr/ResolveAssertions.cc -
src/ResolvExpr/typeops.h
r5e49e47 rd0c91a6 72 72 Cost conversionCost( Type *src, Type *dest, const SymTab::Indexer &indexer, const TypeEnvironment &env ); 73 73 74 // in AlternativeFinder.cc 75 Cost computeConversionCost( Type *actualType, Type *formalType, 76 const SymTab::Indexer &indexer, const TypeEnvironment &env ); 77 74 78 // in PtrsAssignable.cc 75 79 int ptrsAssignable( Type *src, Type *dest, const TypeEnvironment &env ); … … 102 106 int polyCost( Type *type, const TypeEnvironment &env, const SymTab::Indexer &indexer ); 103 107 108 // in SpecCost.cc 109 int specCost( Type *type ); 110 104 111 // in Occurs.cc 105 112 bool occurs( Type *type, std::string varName, const TypeEnvironment &env ); 113 114 template<typename Iter> 115 bool occursIn( Type* ty, Iter begin, Iter end, const TypeEnvironment &env ) { 116 while ( begin != end ) { 117 if ( occurs( ty, *begin, env ) ) return true; 118 ++begin; 119 } 120 return false; 121 } 106 122 107 123 // in AlternativeFinder.cc -
src/SynTree/ApplicationExpr.cc
r5e49e47 rd0c91a6 29 29 30 30 ParamEntry::ParamEntry( const ParamEntry &other ) : 31 decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) ) , inferParams( new InferredParams( *other.inferParams ) ){31 decl( other.decl ), actualType( maybeClone( other.actualType ) ), formalType( maybeClone( other.formalType ) ), expr( maybeClone( other.expr ) )/*, inferParams( new InferredParams( *other.inferParams ) )*/ { 32 32 } 33 33 … … 39 39 formalType = maybeClone( other.formalType ); 40 40 expr = maybeClone( other.expr ); 41 *inferParams = *other.inferParams;41 // *inferParams = *other.inferParams; 42 42 return *this; 43 43 } … … 50 50 51 51 ParamEntry::ParamEntry( ParamEntry && other ) : 52 decl( other.decl ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr ) , inferParams( std::move( other.inferParams ) ){52 decl( other.decl ), actualType( other.actualType ), formalType( other.formalType ), expr( other.expr )/*, inferParams( std::move( other.inferParams ) )*/ { 53 53 other.actualType = nullptr; 54 54 other.formalType = nullptr; … … 68 68 other.formalType = nullptr; 69 69 other.expr = nullptr; 70 inferParams = std::move( other.inferParams );70 // inferParams = std::move( other.inferParams ); 71 71 return *this; 72 72 } -
src/SynTree/Expression.cc
r5e49e47 rd0c91a6 40 40 Declaration::declFromId( i->second.decl )->printShort( os, indent+1 ); 41 41 os << std::endl; 42 printInferParams( *i->second.inferParams, os, indent+1, level+1 );42 printInferParams( i->second.expr->inferParams, os, indent+1, level+1 ); 43 43 } // for 44 44 } // if … … 47 47 Expression::Expression() : result( 0 ), env( 0 ) {} 48 48 49 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ) { 50 } 49 Expression::Expression( const Expression &other ) : BaseSyntaxNode( other ), result( maybeClone( other.result ) ), env( maybeClone( other.env ) ), extension( other.extension ), inferParams( other.inferParams ), resnSlots( other.resnSlots ) {} 51 50 52 51 void Expression::spliceInferParams( Expression * other ) { … … 55 54 inferParams[p.first] = std::move( p.second ); 56 55 } 56 resnSlots.insert( resnSlots.end(), other->resnSlots.begin(), other->resnSlots.end() ); 57 57 } 58 58 … … 376 376 os << "Untyped Member Expression, with field: " << std::endl << indent+1; 377 377 member->print(os, indent+1 ); 378 os << indent << "... from aggregate: 378 os << indent << "... from aggregate:" << std::endl << indent+1; 379 379 aggregate->print(os, indent+1); 380 380 Expression::print( os, indent ); … … 405 405 406 406 void MemberExpr::print( std::ostream &os, Indenter indent ) const { 407 os << "Member Expression, with field: 407 os << "Member Expression, with field:" << std::endl; 408 408 os << indent+1; 409 409 member->print( os, indent+1 ); 410 os << std::endl << indent << "... from aggregate: 410 os << std::endl << indent << "... from aggregate:" << std::endl << indent+1; 411 411 aggregate->print(os, indent + 1); 412 412 Expression::print( os, indent ); … … 456 456 457 457 void UntypedExpr::print( std::ostream &os, Indenter indent ) const { 458 os << "Applying untyped: 458 os << "Applying untyped:" << std::endl; 459 459 os << indent+1; 460 460 function->print(os, indent+1); 461 os << std::endl << indent << "...to: 461 os << std::endl << indent << "...to:" << std::endl; 462 462 printAll(args, os, indent+1); 463 463 Expression::print( os, indent ); -
src/SynTree/Expression.h
r5e49e47 rd0c91a6 21 21 #include <memory> // for allocator, unique_ptr 22 22 #include <string> // for string 23 #include <vector> // for vector 23 24 24 25 #include "BaseSyntaxNode.h" // for BaseSyntaxNode … … 38 39 /// but subject to decay-to-pointer and type parameter renaming 39 40 struct ParamEntry { 40 ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) , inferParams( new InferredParams ){}41 ParamEntry( UniqueId decl, Type * actualType, Type * formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr ) , inferParams( new InferredParams ){}41 ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 )/*, inferParams( new InferredParams )*/ {} 42 ParamEntry( UniqueId decl, Type * actualType, Type * formalType, Expression* expr ): decl( decl ), actualType( actualType ), formalType( formalType ), expr( expr )/*, inferParams( new InferredParams )*/ {} 42 43 ParamEntry( const ParamEntry & other ); 43 44 ParamEntry( ParamEntry && other ); … … 50 51 Type * formalType; 51 52 Expression * expr; 52 std::unique_ptr< InferredParams > inferParams;53 // std::unique_ptr< InferredParams > inferParams; 53 54 }; 54 55 … … 59 60 TypeSubstitution * env; 60 61 bool extension = false; 61 InferredParams inferParams; 62 InferredParams inferParams; ///< Post-resolution inferred parameter slots 63 std::vector<UniqueId> resnSlots; ///< Pre-resolution inferred parameter slots 64 65 // xxx - should turn inferParams+resnSlots into a union to save some memory 62 66 63 67 Expression(); … … 73 77 bool get_extension() const { return extension; } 74 78 Expression * set_extension( bool exten ) { extension = exten; return this; } 75 76 InferredParams & get_inferParams() { return inferParams; }77 79 78 80 // move other's inferParams to this -
src/SynTree/FunctionDecl.cc
r5e49e47 rd0c91a6 87 87 88 88 if ( statements ) { 89 os << indent << "... with body 89 os << indent << "... with body" << endl << indent+1; 90 90 statements->print( os, indent+1 ); 91 91 } // if -
src/SynTree/FunctionType.cc
r5e49e47 rd0c91a6 66 66 os << indent+1 << "accepting unspecified arguments" << endl; 67 67 } // if 68 os << indent << "... returning 68 os << indent << "... returning"; 69 69 if ( returnVals.empty() ) { 70 os << " nothing" << endl;70 os << " nothing" << endl; 71 71 } else { 72 72 os << endl; -
src/SynTree/ObjectDecl.cc
r5e49e47 rd0c91a6 66 66 67 67 if ( ! attributes.empty() ) { 68 os << std::endl << indent << "... with attributes: 68 os << std::endl << indent << "... with attributes:" << std::endl; 69 69 printAll( attributes, os, indent+1 ); 70 70 } -
src/SynTree/ReferenceToType.cc
r5e49e47 rd0c91a6 93 93 else { 94 94 Type::print( os, indent ); 95 os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body() << " ";95 os << "instance of " << typeString() << " " << name << " with body " << baseStruct->has_body(); 96 96 if ( ! parameters.empty() ) { 97 97 os << endl << indent << "... with parameters" << endl; … … 136 136 else { 137 137 Type::print( os, indent ); 138 os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body() << " ";138 os << "instance of " << typeString() << " " << name << " with body " << baseUnion->has_body(); 139 139 if ( ! parameters.empty() ) { 140 140 os << endl << indent << "... with parameters" << endl; … … 160 160 else { 161 161 Type::print( os, indent ); 162 os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body() << " ";162 os << "instance of " << typeString() << " " << name << " with body " << baseEnum->has_body(); 163 163 } // if 164 164 } … … 205 205 206 206 Type::print( os, indent ); 207 os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type) 207 os << "instance of " << typeString() << " " << get_name() << " (" << ( isFtype ? "" : "not" ) << " function type)"; 208 208 if ( ! parameters.empty() ) { 209 209 os << endl << indent << "... with parameters" << endl; -
src/SynTree/Type.cc
r5e49e47 rd0c91a6 118 118 119 119 void QualifiedType::print( std::ostream & os, Indenter indent ) const { 120 os << "Qualified Type: 120 os << "Qualified Type:" << endl; 121 121 os << indent+1; 122 122 parent->print( os, indent+1 ); -
src/Tuples/Explode.h
r5e49e47 rd0c91a6 44 44 template<typename OutputIterator> 45 45 void append( OutputIterator out, Expression* expr, const ResolvExpr::TypeEnvironment& env, 46 const ResolvExpr::OpenVarSet& openVars, const ResolvExpr::AssertionList& need, 46 47 const ResolvExpr::Cost& cost, const ResolvExpr::Cost& cvtCost ) { 47 *out++ = ResolvExpr::Alternative{ expr, env, cost, cvtCost };48 *out++ = ResolvExpr::Alternative{ expr, env, openVars, need, cost, cvtCost }; 48 49 } 49 50 50 51 /// Append alternative to an ExplodedActual 51 52 static inline void append( ResolvExpr::ExplodedActual& ea, Expression* expr, 52 const ResolvExpr::TypeEnvironment&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 53 const ResolvExpr::TypeEnvironment&, const ResolvExpr::OpenVarSet&, 54 const ResolvExpr::AssertionList&, const ResolvExpr::Cost&, const ResolvExpr::Cost& ) { 53 55 ea.exprs.emplace_back( expr ); 54 /// xxx -- merge environment, cost?56 /// xxx -- merge environment, openVars, need, cost? 55 57 } 56 58 … … 68 70 // distribute reference cast over all components 69 71 append( std::forward<Output>(out), distributeReference( alt.release_expr() ), 70 alt.env, alt. cost, alt.cvtCost );72 alt.env, alt.openVars, alt.need, alt.cost, alt.cvtCost ); 71 73 } 72 74 // in tuple assignment, still need to handle the other cases, but only if not already handled here (don't want to output too many alternatives) … … 102 104 } else { 103 105 // atomic (non-tuple) type - output a clone of the expression in a new alternative 104 append( std::forward<Output>(out), expr->clone(), alt.env, alt.cost, alt.cvtCost ); 106 append( std::forward<Output>(out), expr->clone(), alt.env, alt.openVars, alt.need, 107 alt.cost, alt.cvtCost ); 105 108 } 106 109 } -
src/Tuples/TupleAssignment.cc
r5e49e47 rd0c91a6 62 62 struct Matcher { 63 63 public: 64 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, const65 ResolvExpr::AltList& rhs );64 Matcher( TupleAssignSpotter &spotter, const ResolvExpr::AltList& lhs, 65 const ResolvExpr::AltList& rhs ); 66 66 virtual ~Matcher() {} 67 67 68 virtual void match( std::list< Expression * > &out ) = 0; 68 69 ObjectDecl * newObject( UniqueName & namer, Expression * expr ); 70 71 void combineState( const ResolvExpr::Alternative& alt ) { 72 compositeEnv.simpleCombine( alt.env ); 73 ResolvExpr::mergeOpenVars( openVars, alt.openVars ); 74 cloneAll( alt.need, need ); 75 } 76 77 void combineState( const ResolvExpr::AltList& alts ) { 78 for ( const ResolvExpr::Alternative& alt : alts ) { combineState( alt ); } 79 } 80 69 81 ResolvExpr::AltList lhs, rhs; 70 82 TupleAssignSpotter &spotter; … … 72 84 std::list< ObjectDecl * > tmpDecls; 73 85 ResolvExpr::TypeEnvironment compositeEnv; 86 ResolvExpr::OpenVarSet openVars; 87 ResolvExpr::AssertionSet need; 74 88 }; 75 89 … … 245 259 } 246 260 247 // extract expressions from the assignment alternatives to produce a list of assignments that248 // t ogether form a single alternative261 // extract expressions from the assignment alternatives to produce a list of assignments 262 // that together form a single alternative 249 263 std::list< Expression *> solved_assigns; 250 264 for ( ResolvExpr::Alternative & alt : current ) { 251 265 solved_assigns.push_back( alt.expr->clone() ); 252 }253 // combine assignment environments into combined expression environment254 simpleCombineEnvironments( current.begin(), current.end(), matcher->compositeEnv );266 matcher->combineState( alt ); 267 } 268 255 269 // xxx -- was push_front 256 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative( 257 new TupleAssignExpr(solved_assigns, matcher->tmpDecls), matcher->compositeEnv, 258 ResolvExpr::sumCost( current ) + matcher->baseCost ) ); 270 currentFinder.get_alternatives().push_back( ResolvExpr::Alternative{ 271 new TupleAssignExpr{ solved_assigns, matcher->tmpDecls }, matcher->compositeEnv, 272 matcher->openVars, 273 ResolvExpr::AssertionList( matcher->need.begin(), matcher->need.end() ), 274 ResolvExpr::sumCost( current ) + matcher->baseCost } ); 259 275 } 260 276 … … 263 279 : lhs(lhs), rhs(rhs), spotter(spotter), 264 280 baseCost( ResolvExpr::sumCost( lhs ) + ResolvExpr::sumCost( rhs ) ) { 265 simpleCombineEnvironments( lhs.begin(), lhs.end(), compositeEnv );266 simpleCombineEnvironments( rhs.begin(), rhs.end(), compositeEnv);281 combineState( lhs ); 282 combineState( rhs ); 267 283 } 268 284 -
src/cfa.make
r5e49e47 rd0c91a6 21 21 $(LTCFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 22 22 $(am__mv) $$depbase.Tpo $$depbase.Plo 23 24 AM_V_JAVAC = $(am__v_JAVAC_@AM_V@) 25 am__v_JAVAC_ = $(am__v_JAVAC_@AM_DEFAULT_V@) 26 am__v_JAVAC_0 = @echo " JAVAC " $@; 27 am__v_JAVAC_1 = 28 29 AM_V_GOC = $(am__v_GOC_@AM_V@) 30 am__v_GOC_ = $(am__v_GOC_@AM_DEFAULT_V@) 31 am__v_GOC_0 = @echo " GOC " $@; 32 am__v_GOC_1 = 33 34 UPPCC = u++ 35 UPPCOMPILE = $(UPPCC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_UPPFLAGS) $(UPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_CFLAGS) $(CFLAGS) 36 37 AM_V_UPP = $(am__v_UPP_@AM_V@) 38 am__v_UPP_ = $(am__v_UPP_@AM_DEFAULT_V@) 39 am__v_UPP_0 = @echo " UPP " $@; 40 am__v_UPP_1 = -
src/config.h.in
r5e49e47 rd0c91a6 7 7 #undef CFA_64_CPU 8 8 9 /* Location of include files. */9 /* Backend compiler to use. */ 10 10 #undef CFA_BACKEND_CC 11 11 … … 67 67 #undef HAVE_ALLOCA_H 68 68 69 /* Define to 1 if you have the <dlfcn.h> header file. */ 70 #undef HAVE_DLFCN_H 71 69 72 /* Define to 1 if you have the <fenv.h> header file. */ 70 73 #undef HAVE_FENV_H … … 129 132 /* Define to 1 if the system has the type `_Bool'. */ 130 133 #undef HAVE__BOOL 134 135 /* Define to the sub-directory where libtool stores uninstalled libraries. */ 136 #undef LT_OBJDIR 131 137 132 138 /* Name of package */ -
src/main.cc
r5e49e47 rd0c91a6 487 487 resolvep = true; 488 488 break; 489 489 case 'R': // dump resolv-proto instance 490 490 resolvprotop = true; 491 491 break;
Note:
See TracChangeset
for help on using the changeset viewer.