- Timestamp:
- Jan 23, 2019, 4:52:16 PM (7 years ago)
- Branches:
- ADT, arm-eh, ast-experimental, cleanup-dtors, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, pthread-emulation, qualifiedEnum
- Children:
- a200795
- Parents:
- 9b086ca (diff), 1d832f4 (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:
-
- 7 added
- 51 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeTools/module.mk
r9b086ca rcde3891 16 16 17 17 SRC += CodeTools/DeclStats.cc \ 18 CodeTools/ResolvProtoDump.cc \ 18 19 CodeTools/TrackLoc.cc -
src/Common/utility.h
r9b086ca rcde3891 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/CompilationState.cc
r9b086ca rcde3891 30 30 parsep = false, 31 31 resolvep = false, 32 resolvprotop = false, 32 33 symtabp = false, 33 34 treep = false, -
src/CompilationState.h
r9b086ca rcde3891 31 31 parsep, 32 32 resolvep, 33 resolvprotop, 33 34 symtabp, 34 35 treep, -
src/Concurrency/Keywords.cc
r9b086ca rcde3891 575 575 576 576 //in reverse order : 577 // monitor_ guard_t __guard = { __monitors, #, func };577 // monitor_dtor_guard_t __guard = { __monitors, func }; 578 578 body->push_front( 579 579 new DeclStmt( new ObjectDecl( … … 634 634 assert(generic_func); 635 635 636 // in reverse order :636 // in reverse order : 637 637 // monitor_guard_t __guard = { __monitors, #, func }; 638 638 body->push_front( -
src/Concurrency/Waitfor.cc
r9b086ca rcde3891 66 66 void foo() { 67 67 while( true ) { 68 69 acceptable_t acceptables[3]; 70 if( a < 1 ) { 71 acceptables[0].func = f; 72 acceptables[0].mon = a; 73 } 74 acceptables[1].func = g; 75 acceptables[1].mon = a; 76 77 acceptables[2].func = f; 78 acceptables[2].mon = a; 79 acceptables[2].is_dtor = true; 80 81 int ret = waitfor_internal( acceptables, swagl() ); 82 83 switch( ret ) { 84 case 0: 85 { 86 bar(); 68 { 69 acceptable_t acceptables[3]; 70 if( a < 1 ) { 71 acceptables[0].func = f; 72 acceptables[0].mon = a; 87 73 } 88 case 1: 89 { 90 baz(); 74 acceptables[1].func = g; 75 acceptables[1].mon = a; 76 77 acceptables[2].func = f; 78 acceptables[2].mon = a; 79 acceptables[2].is_dtor = true; 80 81 int ret = waitfor_internal( acceptables, swagl() ); 82 83 switch( ret ) { 84 case 0: 85 { 86 bar(); 87 } 88 case 1: 89 { 90 baz(); 91 } 92 case 2: 93 signal(a); 94 { 95 break; 96 } 91 97 } 92 case 2:93 signal(a);94 {95 break;96 }97 98 } 98 99 } … … 555 556 new ConstantExpr( Constant::from_ulong( i++ ) ), 556 557 { 557 clause.statement, 558 new BranchStmt( 559 "", 560 BranchStmt::Break 561 ) 558 new CompoundStmt({ 559 clause.statement, 560 new BranchStmt( 561 "", 562 BranchStmt::Break 563 ) 564 }) 562 565 } 563 566 ) … … 570 573 new ConstantExpr( Constant::from_int( -2 ) ), 571 574 { 572 waitfor->timeout.statement, 573 new BranchStmt( 574 "", 575 BranchStmt::Break 576 ) 575 new CompoundStmt({ 576 waitfor->timeout.statement, 577 new BranchStmt( 578 "", 579 BranchStmt::Break 580 ) 581 }) 577 582 } 578 583 ) … … 585 590 new ConstantExpr( Constant::from_int( -1 ) ), 586 591 { 587 waitfor->orelse.statement, 588 new BranchStmt( 589 "", 590 BranchStmt::Break 591 ) 592 new CompoundStmt({ 593 waitfor->orelse.statement, 594 new BranchStmt( 595 "", 596 BranchStmt::Break 597 ) 598 }) 592 599 } 593 600 ) -
src/GenPoly/Box.cc
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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 \ … … 50 51 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O2 -g -std=c++14 51 52 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 53 ARFLAGS = cr 52 54 53 55 demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete … … 126 128 ResolvExpr/PtrsCastable.cc \ 127 129 ResolvExpr/RenameVars.cc \ 130 ResolvExpr/ResolveAssertions.cc \ 128 131 ResolvExpr/Resolver.cc \ 129 132 ResolvExpr/ResolveTypeof.cc \ 133 ResolvExpr/SpecCost.cc \ 130 134 ResolvExpr/TypeEnvironment.cc \ 131 135 ResolvExpr/Unify.cc \ -
src/Makefile.in
r9b086ca rcde3891 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 ARFLAGS = cru155 157 AM_V_AR = $(am__v_AR_@AM_V@) 156 158 am__v_AR_ = $(am__v_AR_@AM_DEFAULT_V@) … … 204 206 ResolvExpr/PtrsAssignable.$(OBJEXT) \ 205 207 ResolvExpr/PtrsCastable.$(OBJEXT) \ 206 ResolvExpr/RenameVars.$(OBJEXT) ResolvExpr/Resolver.$(OBJEXT) \ 208 ResolvExpr/RenameVars.$(OBJEXT) \ 209 ResolvExpr/ResolveAssertions.$(OBJEXT) \ 210 ResolvExpr/Resolver.$(OBJEXT) \ 207 211 ResolvExpr/ResolveTypeof.$(OBJEXT) \ 212 ResolvExpr/SpecCost.$(OBJEXT) \ 208 213 ResolvExpr/TypeEnvironment.$(OBJEXT) \ 209 214 ResolvExpr/Unify.$(OBJEXT) SymTab/Autogen.$(OBJEXT) \ … … 222 227 CodeGen/FixNames.$(OBJEXT) CodeGen/FixMain.$(OBJEXT) \ 223 228 CodeGen/OperatorTable.$(OBJEXT) CodeTools/DeclStats.$(OBJEXT) \ 229 CodeTools/ResolvProtoDump.$(OBJEXT) \ 224 230 CodeTools/TrackLoc.$(OBJEXT) Concurrency/Keywords.$(OBJEXT) \ 225 231 Concurrency/Waitfor.$(OBJEXT) Common/SemanticError.$(OBJEXT) \ … … 260 266 ResolvExpr/TypeEnvironment.$(OBJEXT) \ 261 267 ResolvExpr/CurrentObject.$(OBJEXT) \ 262 ResolvExpr/ExplodedActual.$(OBJEXT) SymTab/Indexer.$(OBJEXT) \ 263 SymTab/Mangler.$(OBJEXT) SymTab/ManglerCommon.$(OBJEXT) \ 264 SymTab/Validate.$(OBJEXT) SymTab/FixFunction.$(OBJEXT) \ 265 SymTab/Autogen.$(OBJEXT) SynTree/Type.$(OBJEXT) \ 266 SynTree/VoidType.$(OBJEXT) SynTree/BasicType.$(OBJEXT) \ 267 SynTree/PointerType.$(OBJEXT) SynTree/ArrayType.$(OBJEXT) \ 268 SynTree/ReferenceType.$(OBJEXT) SynTree/FunctionType.$(OBJEXT) \ 268 ResolvExpr/ExplodedActual.$(OBJEXT) \ 269 ResolvExpr/SpecCost.$(OBJEXT) \ 270 ResolvExpr/ResolveAssertions.$(OBJEXT) \ 271 SymTab/Indexer.$(OBJEXT) SymTab/Mangler.$(OBJEXT) \ 272 SymTab/ManglerCommon.$(OBJEXT) SymTab/Validate.$(OBJEXT) \ 273 SymTab/FixFunction.$(OBJEXT) SymTab/Autogen.$(OBJEXT) \ 274 SynTree/Type.$(OBJEXT) SynTree/VoidType.$(OBJEXT) \ 275 SynTree/BasicType.$(OBJEXT) SynTree/PointerType.$(OBJEXT) \ 276 SynTree/ArrayType.$(OBJEXT) SynTree/ReferenceType.$(OBJEXT) \ 277 SynTree/FunctionType.$(OBJEXT) \ 269 278 SynTree/ReferenceToType.$(OBJEXT) SynTree/TupleType.$(OBJEXT) \ 270 279 SynTree/TypeofType.$(OBJEXT) SynTree/AttrType.$(OBJEXT) \ … … 291 300 ___driver_cfa_cpp_OBJECTS = $(am____driver_cfa_cpp_OBJECTS) 292 301 ___driver_cfa_cpp_DEPENDENCIES = 302 AM_V_lt = $(am__v_lt_@AM_V@) 303 am__v_lt_ = $(am__v_lt_@AM_DEFAULT_V@) 304 am__v_lt_0 = --silent 305 am__v_lt_1 = 293 306 am_demangler_OBJECTS = SymTab/demangler.$(OBJEXT) 294 307 demangler_OBJECTS = $(am_demangler_OBJECTS) … … 312 325 CXXCOMPILE = $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) \ 313 326 $(AM_CPPFLAGS) $(CPPFLAGS) $(AM_CXXFLAGS) $(CXXFLAGS) 327 LTCXXCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 328 $(LIBTOOLFLAGS) --mode=compile $(CXX) $(DEFS) \ 329 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 330 $(AM_CXXFLAGS) $(CXXFLAGS) 314 331 AM_V_CXX = $(am__v_CXX_@AM_V@) 315 332 am__v_CXX_ = $(am__v_CXX_@AM_DEFAULT_V@) … … 317 334 am__v_CXX_1 = 318 335 CXXLD = $(CXX) 319 CXXLINK = $(CXXLD) $(AM_CXXFLAGS) $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) \ 320 -o $@ 336 CXXLINK = $(LIBTOOL) $(AM_V_lt) --tag=CXX $(AM_LIBTOOLFLAGS) \ 337 $(LIBTOOLFLAGS) --mode=link $(CXXLD) $(AM_CXXFLAGS) \ 338 $(CXXFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 321 339 AM_V_CXXLD = $(am__v_CXXLD_@AM_V@) 322 340 am__v_CXXLD_ = $(am__v_CXXLD_@AM_DEFAULT_V@) … … 324 342 am__v_CXXLD_1 = 325 343 LEXCOMPILE = $(LEX) $(AM_LFLAGS) $(LFLAGS) 344 LTLEXCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 345 $(LIBTOOLFLAGS) --mode=compile $(LEX) $(AM_LFLAGS) $(LFLAGS) 326 346 AM_V_LEX = $(am__v_LEX_@AM_V@) 327 347 am__v_LEX_ = $(am__v_LEX_@AM_DEFAULT_V@) … … 332 352 -e s/c++$$/h++/ -e s/c$$/h/ 333 353 YACCCOMPILE = $(YACC) $(AM_YFLAGS) $(YFLAGS) 354 LTYACCCOMPILE = $(LIBTOOL) $(AM_V_lt) $(AM_LIBTOOLFLAGS) \ 355 $(LIBTOOLFLAGS) --mode=compile $(YACC) $(AM_YFLAGS) $(YFLAGS) 334 356 AM_V_YACC = $(am__v_YACC_@AM_V@) 335 357 am__v_YACC_ = $(am__v_YACC_@AM_DEFAULT_V@) … … 338 360 COMPILE = $(CC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) \ 339 361 $(CPPFLAGS) $(AM_CFLAGS) $(CFLAGS) 362 LTCOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 363 $(LIBTOOLFLAGS) --mode=compile $(CC) $(DEFS) \ 364 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) \ 365 $(AM_CFLAGS) $(CFLAGS) 340 366 AM_V_CC = $(am__v_CC_@AM_V@) 341 367 am__v_CC_ = $(am__v_CC_@AM_DEFAULT_V@) … … 343 369 am__v_CC_1 = 344 370 CCLD = $(CC) 345 LINK = $(CCLD) $(AM_CFLAGS) $(CFLAGS) $(AM_LDFLAGS) $(LDFLAGS) -o $@ 371 LINK = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 372 $(LIBTOOLFLAGS) --mode=link $(CCLD) $(AM_CFLAGS) $(CFLAGS) \ 373 $(AM_LDFLAGS) $(LDFLAGS) -o $@ 346 374 AM_V_CCLD = $(am__v_CCLD_@AM_V@) 347 375 am__v_CCLD_ = $(am__v_CCLD_@AM_DEFAULT_V@) … … 393 421 AMTAR = @AMTAR@ 394 422 AM_DEFAULT_VERBOSITY = @AM_DEFAULT_VERBOSITY@ 423 AR = @AR@ 395 424 AUTOCONF = @AUTOCONF@ 396 425 AUTOHEADER = @AUTOHEADER@ 397 426 AUTOMAKE = @AUTOMAKE@ 398 427 AWK = @AWK@ 399 BACKEND_CC = @BACKEND_CC@400 428 BUILD_IN_TREE_FLAGS = @BUILD_IN_TREE_FLAGS@ 401 429 CC = @CC@ … … 417 445 CPPFLAGS = @CPPFLAGS@ 418 446 CXX = @CXX@ 447 CXXCPP = @CXXCPP@ 419 448 CXXDEPMODE = @CXXDEPMODE@ 420 449 CXXFLAGS = @CXXFLAGS@ … … 422 451 DEFS = @DEFS@ 423 452 DEPDIR = @DEPDIR@ 453 DLLTOOL = @DLLTOOL@ 424 454 DRIVER_DIR = @DRIVER_DIR@ 455 DSYMUTIL = @DSYMUTIL@ 456 DUMPBIN = @DUMPBIN@ 425 457 ECHO_C = @ECHO_C@ 426 458 ECHO_N = @ECHO_N@ … … 428 460 EGREP = @EGREP@ 429 461 EXEEXT = @EXEEXT@ 462 FGREP = @FGREP@ 430 463 GREP = @GREP@ 431 464 HOST_FLAGS = @HOST_FLAGS@ … … 435 468 INSTALL_SCRIPT = @INSTALL_SCRIPT@ 436 469 INSTALL_STRIP_PROGRAM = @INSTALL_STRIP_PROGRAM@ 470 LD = @LD@ 437 471 LDFLAGS = @LDFLAGS@ 438 472 LEX = @LEX@ … … 443 477 LIBOBJS = @LIBOBJS@ 444 478 LIBS = @LIBS@ 479 LIBTOOL = @LIBTOOL@ 480 LIPO = @LIPO@ 481 LN_S = @LN_S@ 445 482 LTLIBOBJS = @LTLIBOBJS@ 483 LT_SYS_LIBRARY_PATH = @LT_SYS_LIBRARY_PATH@ 446 484 MAKEINFO = @MAKEINFO@ 485 MANIFEST_TOOL = @MANIFEST_TOOL@ 447 486 MKDIR_P = @MKDIR_P@ 487 NM = @NM@ 488 NMEDIT = @NMEDIT@ 489 OBJDUMP = @OBJDUMP@ 448 490 OBJEXT = @OBJEXT@ 491 OTOOL = @OTOOL@ 492 OTOOL64 = @OTOOL64@ 449 493 PACKAGE = @PACKAGE@ 450 494 PACKAGE_BUGREPORT = @PACKAGE_BUGREPORT@ … … 456 500 PATH_SEPARATOR = @PATH_SEPARATOR@ 457 501 RANLIB = @RANLIB@ 502 SED = @SED@ 458 503 SET_MAKE = @SET_MAKE@ 459 504 SHELL = @SHELL@ … … 467 512 abs_top_builddir = @abs_top_builddir@ 468 513 abs_top_srcdir = @abs_top_srcdir@ 514 ac_ct_AR = @ac_ct_AR@ 469 515 ac_ct_CC = @ac_ct_CC@ 470 516 ac_ct_CXX = @ac_ct_CXX@ 517 ac_ct_DUMPBIN = @ac_ct_DUMPBIN@ 471 518 am__include = @am__include@ 472 519 am__leading_dot = @am__leading_dot@ … … 518 565 # create object files in directory with source files 519 566 AUTOMAKE_OPTIONS = foreign subdir-objects 567 ACLOCAL_AMFLAGS = -I automake 520 568 SRC = main.cc MakeLibCfa.cc CompilationState.cc CodeGen/Generate.cc \ 521 569 CodeGen/CodeGenerator.cc CodeGen/GenType.cc \ 522 570 CodeGen/FixNames.cc CodeGen/FixMain.cc \ 523 571 CodeGen/OperatorTable.cc CodeTools/DeclStats.cc \ 524 CodeTools/TrackLoc.cc Concurrency/Keywords.cc \ 525 Concurrency/Waitfor.cc Common/SemanticError.cc \ 526 Common/UniqueName.cc Common/DebugMalloc.cc Common/Assert.cc \ 527 Common/Heap.cc Common/Eval.cc ControlStruct/LabelGenerator.cc \ 572 CodeTools/ResolvProtoDump.cc CodeTools/TrackLoc.cc \ 573 Concurrency/Keywords.cc Concurrency/Waitfor.cc \ 574 Common/SemanticError.cc Common/UniqueName.cc \ 575 Common/DebugMalloc.cc Common/Assert.cc Common/Heap.cc \ 576 Common/Eval.cc ControlStruct/LabelGenerator.cc \ 528 577 ControlStruct/LabelFixer.cc ControlStruct/MLEMutator.cc \ 529 578 ControlStruct/Mutate.cc ControlStruct/ForExprMutator.cc \ … … 548 597 ResolvExpr/Occurs.cc ResolvExpr/TypeEnvironment.cc \ 549 598 ResolvExpr/CurrentObject.cc ResolvExpr/ExplodedActual.cc \ 599 ResolvExpr/SpecCost.cc ResolvExpr/ResolveAssertions.cc \ 550 600 SymTab/Indexer.cc SymTab/Mangler.cc SymTab/ManglerCommon.cc \ 551 601 SymTab/Validate.cc SymTab/FixFunction.cc SymTab/Autogen.cc \ … … 582 632 AM_CXXFLAGS = @HOST_FLAGS@ -Wno-deprecated -Wall -Wextra -DDEBUG_ALL -I./Parser -I$(srcdir)/Parser -I$(srcdir)/include -DYY_NO_INPUT -O2 -g -std=c++14 583 633 AM_LDFLAGS = @HOST_FLAGS@ -Xlinker -export-dynamic 634 ARFLAGS = cr 584 635 demangler_SOURCES = SymTab/demangler.cc # test driver for the demangler, also useful as a sanity check that libdemangle.a is complete 585 636 demangler_LDADD = libdemangle.a # yywrap … … 655 706 ResolvExpr/PtrsCastable.cc \ 656 707 ResolvExpr/RenameVars.cc \ 708 ResolvExpr/ResolveAssertions.cc \ 657 709 ResolvExpr/Resolver.cc \ 658 710 ResolvExpr/ResolveTypeof.cc \ 711 ResolvExpr/SpecCost.cc \ 659 712 ResolvExpr/TypeEnvironment.cc \ 660 713 ResolvExpr/Unify.cc \ … … 674 727 675 728 .SUFFIXES: 676 .SUFFIXES: .cc .ll . o .obj .yy729 .SUFFIXES: .cc .ll .lo .o .obj .yy 677 730 $(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) 678 731 @for dep in $?; do \ … … 908 961 ResolvExpr/RenameVars.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 909 962 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 963 ResolvExpr/ResolveAssertions.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 964 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 910 965 ResolvExpr/Resolver.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 911 966 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 912 967 ResolvExpr/ResolveTypeof.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 968 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 969 ResolvExpr/SpecCost.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ 913 970 ResolvExpr/$(DEPDIR)/$(am__dirstamp) 914 971 ResolvExpr/TypeEnvironment.$(OBJEXT): ResolvExpr/$(am__dirstamp) \ … … 963 1020 sed 's/$(EXEEXT)$$//' | \ 964 1021 while read p p1; do if test -f $$p \ 1022 || test -f $$p1 \ 965 1023 ; then echo "$$p"; echo "$$p"; else :; fi; \ 966 1024 done | \ … … 977 1035 if test "$$dir" = .; then dir=; else dir=/$$dir; fi; \ 978 1036 test -z "$$files" || { \ 979 echo " $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \980 $(INSTALL_PROGRAM_ENV)$(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \1037 echo " $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files '$(DESTDIR)$(cfa_cpplibdir)$$dir'"; \ 1038 $(INSTALL_PROGRAM_ENV) $(LIBTOOL) $(AM_LIBTOOLFLAGS) $(LIBTOOLFLAGS) --mode=install $(INSTALL_PROGRAM) $$files "$(DESTDIR)$(cfa_cpplibdir)$$dir" || exit $$?; \ 981 1039 } \ 982 1040 ; done … … 994 1052 995 1053 clean-cfa_cpplibPROGRAMS: 996 -test -z "$(cfa_cpplib_PROGRAMS)" || rm -f $(cfa_cpplib_PROGRAMS) 1054 @list='$(cfa_cpplib_PROGRAMS)'; test -n "$$list" || exit 0; \ 1055 echo " rm -f" $$list; \ 1056 rm -f $$list || exit $$?; \ 1057 test -n "$(EXEEXT)" || exit 0; \ 1058 list=`for p in $$list; do echo "$$p"; done | sed 's/$(EXEEXT)$$//'`; \ 1059 echo " rm -f" $$list; \ 1060 rm -f $$list 997 1061 CodeGen/FixNames.$(OBJEXT): CodeGen/$(am__dirstamp) \ 998 1062 CodeGen/$(DEPDIR)/$(am__dirstamp) … … 1004 1068 @: > CodeTools/$(DEPDIR)/$(am__dirstamp) 1005 1069 CodeTools/DeclStats.$(OBJEXT): CodeTools/$(am__dirstamp) \ 1070 CodeTools/$(DEPDIR)/$(am__dirstamp) 1071 CodeTools/ResolvProtoDump.$(OBJEXT): CodeTools/$(am__dirstamp) \ 1006 1072 CodeTools/$(DEPDIR)/$(am__dirstamp) 1007 1073 CodeTools/TrackLoc.$(OBJEXT): CodeTools/$(am__dirstamp) \ … … 1107 1173 @AMDEP_TRUE@@am__include@ @am__quote@CodeGen/$(DEPDIR)/OperatorTable.Po@am__quote@ 1108 1174 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/DeclStats.Po@am__quote@ 1175 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/ResolvProtoDump.Po@am__quote@ 1109 1176 @AMDEP_TRUE@@am__include@ @am__quote@CodeTools/$(DEPDIR)/TrackLoc.Po@am__quote@ 1110 1177 @AMDEP_TRUE@@am__include@ @am__quote@Common/$(DEPDIR)/Assert.Po@am__quote@ … … 1159 1226 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/PtrsCastable.Po@am__quote@ 1160 1227 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/RenameVars.Po@am__quote@ 1228 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveAssertions.Po@am__quote@ 1161 1229 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/ResolveTypeof.Po@am__quote@ 1162 1230 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Resolver.Po@am__quote@ 1231 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/SpecCost.Po@am__quote@ 1163 1232 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/TypeEnvironment.Po@am__quote@ 1164 1233 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/Unify.Po@am__quote@ … … 1228 1297 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(CXXCOMPILE) -c -o $@ `$(CYGPATH_W) '$<'` 1229 1298 1299 .cc.lo: 1300 @am__fastdepCXX_TRUE@ $(AM_V_CXX)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ 1301 @am__fastdepCXX_TRUE@ $(LTCXXCOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 1302 @am__fastdepCXX_TRUE@ $(am__mv) $$depbase.Tpo $$depbase.Plo 1303 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ $(AM_V_CXX)source='$<' object='$@' libtool=yes @AMDEPBACKSLASH@ 1304 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1305 @am__fastdepCXX_FALSE@ $(AM_V_CXX@am__nodep@)$(LTCXXCOMPILE) -c -o $@ $< 1306 1230 1307 .ll.cc: 1231 1308 $(AM_V_LEX)$(am__skiplex) $(SHELL) $(YLWRAP) $< $(LEX_OUTPUT_ROOT).c $@ -- $(LEXCOMPILE) … … 1233 1310 .yy.cc: 1234 1311 $(AM_V_YACC)$(am__skipyacc) $(SHELL) $(YLWRAP) $< y.tab.c $@ y.tab.h `echo $@ | $(am__yacc_c2h)` y.output $*.output -- $(YACCCOMPILE) 1312 1313 mostlyclean-libtool: 1314 -rm -f *.lo 1315 1316 clean-libtool: 1317 -rm -rf .libs _libs 1318 -rm -rf ../driver/.libs ../driver/_libs 1235 1319 1236 1320 ID: $(am__tagged_files) … … 1392 1476 clean: clean-am 1393 1477 1394 clean-am: clean-cfa_cpplibPROGRAMS clean-generic clean- noinstLIBRARIES\1395 mostlyclean-am1478 clean-am: clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \ 1479 clean-noinstLIBRARIES mostlyclean-am 1396 1480 1397 1481 distclean: distclean-am … … 1448 1532 mostlyclean: mostlyclean-am 1449 1533 1450 mostlyclean-am: mostlyclean-compile mostlyclean-generic 1534 mostlyclean-am: mostlyclean-compile mostlyclean-generic \ 1535 mostlyclean-libtool 1451 1536 1452 1537 pdf: pdf-am … … 1463 1548 1464 1549 .PHONY: CTAGS GTAGS TAGS all all-am check check-am clean \ 1465 clean-cfa_cpplibPROGRAMS clean-generic clean-noinstLIBRARIES \ 1466 cscopelist-am ctags ctags-am distclean distclean-compile \ 1467 distclean-generic distclean-tags distdir dvi dvi-am html \ 1468 html-am info info-am install install-am \ 1469 install-cfa_cpplibPROGRAMS install-data install-data-am \ 1470 install-dvi install-dvi-am install-exec install-exec-am \ 1471 install-html install-html-am install-info install-info-am \ 1472 install-man install-pdf install-pdf-am install-ps \ 1473 install-ps-am install-strip installcheck installcheck-am \ 1474 installdirs maintainer-clean maintainer-clean-generic \ 1475 mostlyclean mostlyclean-compile mostlyclean-generic pdf pdf-am \ 1476 ps ps-am tags tags-am uninstall uninstall-am \ 1550 clean-cfa_cpplibPROGRAMS clean-generic clean-libtool \ 1551 clean-noinstLIBRARIES cscopelist-am ctags ctags-am distclean \ 1552 distclean-compile distclean-generic distclean-libtool \ 1553 distclean-tags distdir dvi dvi-am html html-am info info-am \ 1554 install install-am install-cfa_cpplibPROGRAMS install-data \ 1555 install-data-am install-dvi install-dvi-am install-exec \ 1556 install-exec-am install-html install-html-am install-info \ 1557 install-info-am install-man install-pdf install-pdf-am \ 1558 install-ps install-ps-am install-strip installcheck \ 1559 installcheck-am installdirs maintainer-clean \ 1560 maintainer-clean-generic mostlyclean mostlyclean-compile \ 1561 mostlyclean-generic mostlyclean-libtool pdf pdf-am ps ps-am \ 1562 tags tags-am uninstall uninstall-am \ 1477 1563 uninstall-cfa_cpplibPROGRAMS 1478 1564 -
src/Parser/DeclarationNode.cc
r9b086ca rcde3891 10 10 // Created On : Sat May 16 12:34:05 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 20 14:56:54201813 // Update Count : 110 712 // Last Modified On : Thu Nov 1 20:54:26 2018 13 // Update Count : 1108 14 14 // 15 15 … … 402 402 } 403 403 404 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr ) {405 DeclarationNode * newnode = new DeclarationNode; 406 newnode->type = new TypeData( TypeData::Typeof );404 DeclarationNode * DeclarationNode::newTypeof( ExpressionNode * expr, bool basetypeof ) { 405 DeclarationNode * newnode = new DeclarationNode; 406 newnode->type = new TypeData( basetypeof ? TypeData::Basetypeof : TypeData::Typeof ); 407 407 newnode->type->typeexpr = expr; 408 408 return newnode; -
src/Parser/LinkageSpec.cc
r9b086ca rcde3891 10 10 // Created On : Sat May 16 13:22:09 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 7 11:11:00 201713 // Update Count : 2 512 // Last Modified On : Thr Spt 12 15:59:00 2018 13 // Update Count : 26 14 14 // 15 15 … … 23 23 24 24 namespace LinkageSpec { 25 26 Spec linkageCheck( CodeLocation location, const string * spec ) {27 assert( spec );28 unique_ptr<const string> guard( spec ); // allocated by lexer29 if ( *spec == "\"Cforall\"" ) {30 return Cforall;31 } else if ( *spec == "\"C\"" ) {32 return C;33 } else if ( *spec == "\"BuiltinC\"" ) {34 return BuiltinC;35 } else {36 SemanticError( location, "Invalid linkage specifier " + *spec );37 } // if38 }39 25 40 26 Spec linkageUpdate( CodeLocation location, Spec old_spec, const string * cmd ) { -
src/Parser/LinkageSpec.h
r9b086ca rcde3891 9 9 // Author : Rodolfo G. Esteves 10 10 // Created On : Sat May 16 13:24:28 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Mon Jul 2 07:46:49201813 // Update Count : 1 611 // Last Modified By : Andrew Beach 12 // Last Modified On : Thr Spt 13 15:59:00 2018 13 // Update Count : 17 14 14 // 15 15 … … 41 41 42 42 43 Spec linkageCheck( CodeLocation location, const std::string * );44 // Returns the Spec with the given name (limited to C, Cforall & BuiltinC)45 43 Spec linkageUpdate( CodeLocation location, Spec old_spec, const std::string * cmd ); 46 44 /* If cmd = "C" returns a Spec that is old_spec with is_mangled = false -
src/Parser/ParseNode.h
r9b086ca rcde3891 10 10 // Created On : Sat May 16 13:28:16 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Aug 4 09:39:40201813 // Update Count : 85 312 // Last Modified On : Thu Nov 1 20:54:53 2018 13 // Update Count : 854 14 14 // 15 15 … … 249 249 static DeclarationNode * newBitfield( ExpressionNode * size ); 250 250 static DeclarationNode * newTuple( DeclarationNode * members ); 251 static DeclarationNode * newTypeof( ExpressionNode * expr );251 static DeclarationNode * newTypeof( ExpressionNode * expr, bool basetypeof = false ); 252 252 static DeclarationNode * newAttr( const std::string *, ExpressionNode * expr ); // @ attributes 253 253 static DeclarationNode * newAttr( const std::string *, DeclarationNode * type ); // @ attributes -
src/Parser/TypeData.cc
r9b086ca rcde3891 10 10 // Created On : Sat May 16 15:12:51 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 20 14:39:31201813 // Update Count : 62 212 // Last Modified On : Fri Nov 2 07:54:26 2018 13 // Update Count : 624 14 14 // 15 15 … … 96 96 break; 97 97 case Typeof: 98 case Basetypeof: 98 99 // typeexpr = new Typeof_t; 99 100 typeexpr = nullptr; … … 166 167 break; 167 168 case Typeof: 169 case Basetypeof: 168 170 // delete typeexpr->expr; 169 171 delete typeexpr; … … 245 247 break; 246 248 case Typeof: 249 case Basetypeof: 247 250 newtype->typeexpr = maybeClone( typeexpr ); 248 251 break; … … 319 322 function.params->printList( os, indent + 4 ); 320 323 } else { 321 os << string( indent + 2, ' ' ) << "with no parameters 324 os << string( indent + 2, ' ' ) << "with no parameters" << endl; 322 325 } // if 323 326 if ( function.idList ) { … … 344 347 os << DeclarationNode::aggregateNames[ aggregate.kind ] << ' ' << *aggregate.name << endl; 345 348 if ( aggregate.params ) { 346 os << string( indent + 2, ' ' ) << "with type parameters 349 os << string( indent + 2, ' ' ) << "with type parameters" << endl; 347 350 aggregate.params->printList( os, indent + 4 ); 348 351 } // if 349 352 if ( aggregate.actuals ) { 350 os << string( indent + 2, ' ' ) << "instantiated with actual parameters 353 os << string( indent + 2, ' ' ) << "instantiated with actual parameters" << endl; 351 354 aggregate.actuals->printList( os, indent + 4 ); 352 355 } // if 353 356 if ( aggregate.fields ) { 354 os << string( indent + 2, ' ' ) << "with members 357 os << string( indent + 2, ' ' ) << "with members" << endl; 355 358 aggregate.fields->printList( os, indent + 4 ); 356 359 } // if 357 360 if ( aggregate.body ) { 358 os << string( indent + 2, ' ' ) << " with body 361 os << string( indent + 2, ' ' ) << " with body" << endl; 359 362 } // if 360 363 break; … … 367 370 } // if 368 371 if ( aggInst.params ) { 369 os << string( indent + 2, ' ' ) << "with parameters 372 os << string( indent + 2, ' ' ) << "with parameters" << endl; 370 373 aggInst.params->printList( os, indent + 2 ); 371 374 } // if … … 378 381 } // if 379 382 if ( enumeration.body ) { 380 os << string( indent + 2, ' ' ) << " with body 383 os << string( indent + 2, ' ' ) << " with body" << endl; 381 384 } // if 382 385 break; … … 415 418 os << "tuple "; 416 419 if ( tuple ) { 417 os << "with members 420 os << "with members" << endl; 418 421 tuple->printList( os, indent + 2 ); 419 422 } // if 420 423 break; 424 case Basetypeof: 425 os << "base-"; 426 #if defined(__GNUC__) && __GNUC__ >= 7 427 __attribute__((fallthrough)); 428 #endif 421 429 case Typeof: 422 430 os << "type-of expression "; … … 457 465 case Tuple: 458 466 case Typeof: 467 case Basetypeof: 459 468 case Builtin: 460 469 assertf(false, "Tried to get leaf name from kind without a name: %d", kind); … … 513 522 switch ( td->kind ) { 514 523 case TypeData::Unknown: 515 // fill in implicit int516 return new BasicType( buildQualifiers( td ), BasicType::SignedInt );524 // fill in implicit int 525 return new BasicType( buildQualifiers( td ), BasicType::SignedInt ); 517 526 case TypeData::Basic: 518 return buildBasicType( td );527 return buildBasicType( td ); 519 528 case TypeData::Pointer: 520 return buildPointer( td );529 return buildPointer( td ); 521 530 case TypeData::Array: 522 return buildArray( td );531 return buildArray( td ); 523 532 case TypeData::Reference: 524 return buildReference( td );533 return buildReference( td ); 525 534 case TypeData::Function: 526 return buildFunction( td );535 return buildFunction( td ); 527 536 case TypeData::AggregateInst: 528 return buildAggInst( td );537 return buildAggInst( td ); 529 538 case TypeData::EnumConstant: 530 // the name gets filled in later -- by SymTab::Validate531 return new EnumInstType( buildQualifiers( td ), "" );539 // the name gets filled in later -- by SymTab::Validate 540 return new EnumInstType( buildQualifiers( td ), "" ); 532 541 case TypeData::SymbolicInst: 533 return buildSymbolicInst( td );542 return buildSymbolicInst( td ); 534 543 case TypeData::Tuple: 535 return buildTuple( td );544 return buildTuple( td ); 536 545 case TypeData::Typeof: 537 return buildTypeof( td ); 546 case TypeData::Basetypeof: 547 return buildTypeof( td ); 538 548 case TypeData::Builtin: 539 if(td->builtintype == DeclarationNode::Zero) {540 return new ZeroType( noQualifiers );541 }542 else if(td->builtintype == DeclarationNode::One) {543 return new OneType( noQualifiers );544 }545 else {546 return new VarArgsType( buildQualifiers( td ) );547 }549 if (td->builtintype == DeclarationNode::Zero) { 550 return new ZeroType( noQualifiers ); 551 } 552 else if (td->builtintype == DeclarationNode::One) { 553 return new OneType( noQualifiers ); 554 } 555 else { 556 return new VarArgsType( buildQualifiers( td ) ); 557 } 548 558 case TypeData::GlobalScope: 549 return new GlobalScopeType();559 return new GlobalScopeType(); 550 560 case TypeData::Qualified: 551 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) );561 return new QualifiedType( buildQualifiers( td ), typebuild( td->qualified.parent ), typebuild( td->qualified.child ) ); 552 562 case TypeData::Symbolic: 553 563 case TypeData::Enum: 554 564 case TypeData::Aggregate: 555 assert( false );565 assert( false ); 556 566 } // switch 557 567 … … 929 939 930 940 TypeofType * buildTypeof( const TypeData * td ) { 931 assert( td->kind == TypeData::Typeof );941 assert( td->kind == TypeData::Typeof || td->kind == TypeData::Basetypeof ); 932 942 assert( td->typeexpr ); 933 943 // assert( td->typeexpr->expr ); 934 return new TypeofType( buildQualifiers( td ), td->typeexpr->build() ); 944 return new TypeofType{ 945 buildQualifiers( td ), td->typeexpr->build(), td->kind == TypeData::Basetypeof }; 935 946 } // buildTypeof 936 947 -
src/Parser/TypeData.h
r9b086ca rcde3891 10 10 // Created On : Sat May 16 15:18:36 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Fri Jul 20 13:56:40201813 // Update Count : 19 512 // Last Modified On : Thu Nov 1 20:56:46 2018 13 // Update Count : 196 14 14 // 15 15 … … 27 27 struct TypeData { 28 28 enum Kind { Basic, Pointer, Reference, Array, Function, Aggregate, AggregateInst, Enum, EnumConstant, Symbolic, 29 SymbolicInst, Tuple, Typeof, B uiltin, GlobalScope, Qualified, Unknown };29 SymbolicInst, Tuple, Typeof, Basetypeof, Builtin, GlobalScope, Qualified, Unknown }; 30 30 31 31 struct Aggregate_t { -
src/Parser/lex.ll
r9b086ca rcde3891 10 10 * Created On : Sat Sep 22 08:58:10 2001 11 11 * Last Modified By : Peter A. Buhr 12 * Last Modified On : Wed Aug 8 17:23:17201813 * Update Count : 68 512 * Last Modified On : Thu Nov 1 20:57:35 2018 13 * Update Count : 687 14 14 */ 15 15 … … 209 209 __attribute__ { KEYWORD_RETURN(ATTRIBUTE); } // GCC 210 210 auto { KEYWORD_RETURN(AUTO); } 211 basetypeof { KEYWORD_RETURN(BASETYPEOF); } // CFA 211 212 _Bool { KEYWORD_RETURN(BOOL); } // C99 212 213 break { KEYWORD_RETURN(BREAK); } … … 410 411 ">>=" { NAMEDOP_RETURN(RSassign); } 411 412 412 "~=" { NAMEDOP_RETURN(Erange); } // CFA413 413 "@=" { NAMEDOP_RETURN(ATassign); } // CFA 414 "~=" { NAMEDOP_RETURN(ErangeUpEq); } // CFA 415 "-~" { NAMEDOP_RETURN(ErangeDown); } // CFA 416 "-~=" { NAMEDOP_RETURN(ErangeDownEq); } // CFA 414 417 415 418 /* CFA, operator identifier */ -
src/Parser/parser.yy
r9b086ca rcde3891 10 10 // Created On : Sat Sep 1 20:22:55 2001 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Aug 8 17:50:07201813 // Update Count : 399812 // Last Modified On : Thu Nov 8 18:08:23 2018 13 // Update Count : 4052 14 14 // 15 15 … … 187 187 188 188 ForCtrl * forCtrl( ExpressionNode * type, string * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 189 ConstantExpr * constant = dynamic_cast<ConstantExpr *>(type->get_expr()); 190 if ( constant && (constant->get_constant()->get_value() == "0" || constant->get_constant()->get_value() == "1") ) { 191 type = new ExpressionNode( new CastExpr( maybeMoveBuild< Expression >(type), new BasicType( Type::Qualifiers(), BasicType::SignedInt ) ) ); 192 } // if 189 193 return new ForCtrl( 190 distAttr( DeclarationNode::newTypeof( type ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ),194 distAttr( DeclarationNode::newTypeof( type, true ), DeclarationNode::newName( index )->addInitializer( new InitializerNode( start ) ) ), 191 195 new ExpressionNode( build_binary_val( compop, new ExpressionNode( build_varref( new string( *index ) ) ), comp ) ), 192 new ExpressionNode( build_binary_val( OperKinds::PlusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) ); 196 new ExpressionNode( build_binary_val( compop == OperKinds::LThan || compop == OperKinds::LEThan ? // choose += or -= for upto/downto 197 OperKinds::PlusAssn : OperKinds::MinusAssn, new ExpressionNode( build_varref( new string( *index ) ) ), inc ) ) ); 198 } // forCtrl 199 200 ForCtrl * forCtrl( ExpressionNode * type, ExpressionNode * index, ExpressionNode * start, enum OperKinds compop, ExpressionNode * comp, ExpressionNode * inc ) { 201 if ( NameExpr * identifier = dynamic_cast<NameExpr *>(index->get_expr()) ) { 202 return forCtrl( type, new string( identifier->name ), start, compop, comp, inc ); 203 } else { 204 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); return nullptr; 205 } // if 193 206 } // forCtrl 194 207 … … 214 227 215 228 // Types declaration for productions 216 %union 217 { 229 %union { 218 230 Token tok; 219 231 ParseNode * pn; … … 254 266 %token ZERO_T ONE_T // CFA 255 267 %token VALIST // GCC 256 %token TYPEOF LABEL// GCC268 %token TYPEOF BASETYPEOF LABEL // GCC 257 269 %token ENUM STRUCT UNION 258 270 %token EXCEPTION // CFA … … 290 302 %token ANDassign ERassign ORassign // &= ^= |= 291 303 292 %token Erange //~=304 %token ErangeUpEq ErangeDown ErangeDownEq // ~= -~ -~= 293 305 %token ATassign // @= 294 306 … … 629 641 { $$ = new ExpressionNode( build_fieldSel( $1, build_tuple( $4 ) ) ); } 630 642 | postfix_expression ARROW no_attr_identifier 631 { 632 $$ = new ExpressionNode( build_pfieldSel( $1, *$3 == "0" || *$3 == "1" ? build_constantInteger( *$3 ) : build_varref( $3 ) ) ); 633 } 643 { $$ = new ExpressionNode( build_pfieldSel( $1, build_varref( $3 ) ) ); } 634 644 | postfix_expression ARROW INTEGERconstant // CFA, tuple index 635 645 { $$ = new ExpressionNode( build_pfieldSel( $1, build_constantInteger( *$3 ) ) ); } … … 1130 1140 | FOR '(' push for_control_expression ')' statement pop 1131 1141 { $$ = new StatementNode( build_for( $4, $6 ) ); } 1142 | FOR '(' ')' statement // CFA => for ( ;; ) 1143 { $$ = new StatementNode( build_for( new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ), $4 ) ); } 1132 1144 ; 1133 1145 1134 1146 for_control_expression: 1135 comma_expression_opt // CFA 1136 { 1137 if ( ! $1 ) { // => for ( ;; ) 1138 $$ = new ForCtrl( (ExpressionNode * )nullptr, (ExpressionNode * )nullptr, (ExpressionNode * )nullptr ); 1139 } else { 1140 $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), OperKinds::LThan, $1->clone(), 1141 new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); 1142 } // if 1143 } 1147 comma_expression // CFA 1148 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1149 OperKinds::LThan, $1->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1144 1150 | constant_expression inclexcl constant_expression // CFA 1145 1151 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1146 1152 | constant_expression inclexcl constant_expression '~' constant_expression // CFA 1147 1153 { $$ = forCtrl( $1, new string( DeclarationNode::anonymous.newName() ), $1->clone(), $2, $3, $5 ); } 1148 | comma_expression_opt ';' comma_expression // CFA 1149 { 1150 if ( ! $1 ) { 1151 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr; 1152 } else if ( ! $3 ) { 1153 SemanticError( yylloc, "Missing loop range." ); $$ = nullptr; 1154 } else { 1155 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) { 1156 $$ = forCtrl( $3, new string( identifier->name ), new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), OperKinds::LThan, $3->clone(), 1157 new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); 1158 } else { 1159 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr; 1160 } // if 1161 } // if 1162 } 1163 | comma_expression_opt ';' constant_expression inclexcl constant_expression // CFA 1164 { 1165 if ( ! $1 ) { 1166 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr; 1167 } else { 1168 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) { 1169 $$ = forCtrl( $3, new string( identifier->name ), $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); 1170 } else { 1171 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr; 1172 } // if 1173 } // if 1174 } 1175 | comma_expression_opt ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA 1176 { 1177 if ( ! $1 ) { 1178 SemanticError( yylloc, "Missing loop index." ); $$ = nullptr; 1179 } else { 1180 if ( NameExpr *identifier = dynamic_cast<NameExpr *>($1->get_expr()) ) { 1181 $$ = forCtrl( $3, new string( identifier->name ), $3->clone(), $4, $5, $7 ); 1182 } else { 1183 SemanticError( yylloc, "Expression disallowed. Only loop-index name allowed" ); $$ = nullptr; 1184 } // if 1185 } // if 1186 } 1187 | comma_expression_opt ';' comma_expression_opt ';' comma_expression_opt 1154 | comma_expression ';' comma_expression // CFA 1155 { $$ = forCtrl( $3, $1, new ExpressionNode( build_constantInteger( *new string( "0" ) ) ), 1156 OperKinds::LThan, $3->clone(), new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1157 | comma_expression ';' constant_expression inclexcl constant_expression // CFA 1158 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, new ExpressionNode( build_constantInteger( *new string( "1" ) ) ) ); } 1159 | comma_expression ';' constant_expression inclexcl constant_expression '~' constant_expression // CFA 1160 { $$ = forCtrl( $3, $1, $3->clone(), $4, $5, $7 ); } 1161 | comma_expression ';' comma_expression_opt ';' comma_expression_opt 1188 1162 { $$ = new ForCtrl( $1, $3, $5 ); } 1163 | ';' comma_expression_opt ';' comma_expression_opt 1164 { $$ = new ForCtrl( (ExpressionNode * )nullptr, $2, $4 ); } 1189 1165 | declaration comma_expression_opt ';' comma_expression_opt // C99, declaration has ';' 1190 1166 { $$ = new ForCtrl( $1, $2, $4 ); } … … 1194 1170 '~' 1195 1171 { $$ = OperKinds::LThan; } 1196 | Erange 1172 | ErangeUpEq 1197 1173 { $$ = OperKinds::LEThan; } 1174 | ErangeDown 1175 { $$ = OperKinds::GThan; } 1176 | ErangeDownEq 1177 { $$ = OperKinds::GEThan; } 1198 1178 ; 1199 1179 … … 1844 1824 1845 1825 indirect_type: 1846 TYPEOF '(' type ')' // GCC: typeof( x) y;1826 TYPEOF '(' type ')' // GCC: typeof( x ) y; 1847 1827 { $$ = $3; } 1848 | TYPEOF '(' comma_expression ')' // GCC: typeof( a+b) y;1828 | TYPEOF '(' comma_expression ')' // GCC: typeof( a+b ) y; 1849 1829 { $$ = DeclarationNode::newTypeof( $3 ); } 1850 | ATTR_TYPEGENname '(' type ')' // CFA: e.g., @type(x) y; 1830 | BASETYPEOF '(' type ')' // CFA: basetypeof( x ) y; 1831 { $$ = DeclarationNode::newTypeof( new ExpressionNode( new TypeExpr( maybeMoveBuildType( $3 ) ) ), true ); } 1832 | BASETYPEOF '(' comma_expression ')' // CFA: basetypeof( a+b ) y; 1833 { $$ = DeclarationNode::newTypeof( $3, true ); } 1834 | ATTR_TYPEGENname '(' type ')' // CFA: e.g., @type( x ) y; 1851 1835 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1852 | ATTR_TYPEGENname '(' comma_expression ')' // CFA: e.g., @type( a+b) y;1836 | ATTR_TYPEGENname '(' comma_expression ')' // CFA: e.g., @type( a+b ) y; 1853 1837 { $$ = DeclarationNode::newAttr( $1, $3 ); } 1854 1838 | ZERO_T // CFA -
src/ResolvExpr/Alternative.cc
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 10 10 // Created On : Sat May 16 23:52:08 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Sat Feb 17 11:19:39201813 // Update Count : 3 312 // Last Modified On : Thu Nov 1 21:00:56 2018 13 // 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 ) { 455 convCost += computeConversionCost( assert->second.actualType, assert->second.formalType, indexer, alt.env ); 476 // specialization cost of return types can't be accounted for directly, it disables 477 // otherwise-identical calls, like this example based on auto-newline in the I/O lib: 478 // 479 // forall(otype OS) { 480 // void ?|?(OS&, int); // with newline 481 // OS& ?|?(OS&, int); // no newline, always chosen due to more specialization 482 // } 483 484 // mark type variable and specialization cost of forall clause 485 convCost.incVar( function->forall.size() ); 486 for ( TypeDecl* td : function->forall ) { 487 convCost.decSpec( td->assertions.size() ); 456 488 } 457 489 … … 466 498 needAssertions[ *assert ].isUsed = true; 467 499 } 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 } 500 } 501 } 502 503 /// Unique identifier for matching expression resolutions to their requesting expression 504 UniqueId globalResnSlot = 0; 585 505 586 506 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 // ) 507 void AlternativeFinder::Finder::inferParameters( Alternative &newAlt, OutputIterator out ) { 508 // Set need bindings for any unbound assertions 509 UniqueId crntResnSlot = 0; // matching ID for this expression's assertions 510 for ( auto& assn : newAlt.need ) { 511 // skip already-matched assertions 512 if ( assn.info.resnSlot != 0 ) continue; 513 // assign slot for expression if needed 514 if ( crntResnSlot == 0 ) { crntResnSlot = ++globalResnSlot; } 515 // fix slot to assertion 516 assn.info.resnSlot = crntResnSlot; 517 } 518 // pair slot to expression 519 if ( crntResnSlot != 0 ) { newAlt.expr->resnSlots.push_back( crntResnSlot ); } 520 521 // add to output list, assertion resolution is deferred 522 *out++ = newAlt; 613 523 } 614 524 … … 951 861 } 952 862 // build and validate new alternative 953 Alternative newAlt ( appExpr, result.env, cost );863 Alternative newAlt{ appExpr, result.env, result.openVars, result.need, cost }; 954 864 PRINT( 955 865 std::cerr << "instantiate function success: " << appExpr << std::endl; … … 957 867 printAssertionSet( result.need, std::cerr, 8 ); 958 868 ) 959 inferParameters( result.need, result.have, newAlt, result.openVars, out );869 inferParameters( newAlt, out ); 960 870 } 961 871 … … 1202 1112 1203 1113 // 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 findMinCost1114 // for implicit conversions to each of the anonymous members, must happen after findMinCost 1205 1115 // since anon conversions are never the cheapest expression 1206 1116 for ( const Alternative & alt : winners ) { … … 1234 1144 if ( isLvalue( alt.expr ) ) { 1235 1145 alternatives.push_back( 1236 Alternative{ new AddressExpr( alt.expr->clone() ), alt.env, alt.cost } );1146 Alternative{ alt, new AddressExpr( alt.expr->clone() ), alt.cost } ); 1237 1147 } // if 1238 1148 } // for … … 1240 1150 1241 1151 void AlternativeFinder::Finder::postvisit( LabelAddressExpr * expr ) { 1242 alternatives.push_back( Alternative{ expr->clone(), env , Cost::zero} );1152 alternatives.push_back( Alternative{ expr->clone(), env } ); 1243 1153 } 1244 1154 … … 1285 1195 AltList candidates; 1286 1196 for ( Alternative & alt : finder.alternatives ) { 1287 AssertionSet needAssertions, haveAssertions; 1288 OpenVarSet openVars; 1197 AssertionSet needAssertions( alt.need.begin(), alt.need.end() ); 1198 AssertionSet haveAssertions; 1199 OpenVarSet openVars{ alt.openVars }; 1289 1200 1290 1201 alt.env.extractOpenVars( openVars ); … … 1314 1225 // count one safe conversion for each value that is thrown away 1315 1226 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 1227 Alternative newAlt{ 1228 restructureCast( alt.expr->clone(), toType, castExpr->isGenerated ), 1229 alt.env, openVars, needAssertions, alt.cost, alt.cost + thisCost }; 1230 inferParameters( newAlt, back_inserter( candidates ) ); 1320 1231 } // if 1321 1232 } // for … … 1330 1241 1331 1242 void AlternativeFinder::Finder::postvisit( VirtualCastExpr * castExpr ) { 1332 assertf( castExpr->get_result(), "Implic atevirtual cast targets not yet supported." );1243 assertf( castExpr->get_result(), "Implicit virtual cast targets not yet supported." ); 1333 1244 AlternativeFinder finder( indexer, env ); 1334 1245 // don't prune here, since it's guaranteed all alternatives will have the same type 1335 1246 finder.findWithoutPrune( castExpr->get_arg() ); 1336 1247 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 ));1248 alternatives.push_back( Alternative{ 1249 alt, new VirtualCastExpr{ alt.expr->clone(), castExpr->get_result()->clone() }, 1250 alt.cost } ); 1340 1251 } 1341 1252 } … … 1344 1255 /// Gets name from untyped member expression (member must be NameExpr) 1345 1256 const std::string& get_member_name( UntypedMemberExpr *memberExpr ) { 1257 if ( dynamic_cast< ConstantExpr * >( memberExpr->get_member() ) ) { 1258 SemanticError( memberExpr, "Indexed access to struct fields unsupported: " ); 1259 } // if 1346 1260 NameExpr * nameExpr = dynamic_cast< NameExpr * >( memberExpr->get_member() ); 1347 1261 assert( nameExpr ); … … 1362 1276 // find member of the given type 1363 1277 if ( StructInstType *structInst = dynamic_cast< StructInstType* >( aggrExpr->get_result() ) ) { 1364 addAggMembers( structInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1278 addAggMembers( structInst, aggrExpr, *agg, cost, get_member_name(memberExpr) ); 1365 1279 } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( aggrExpr->get_result() ) ) { 1366 addAggMembers( unionInst, aggrExpr, cost, agg->env, get_member_name(memberExpr) );1280 addAggMembers( unionInst, aggrExpr, *agg, cost, get_member_name(memberExpr) ); 1367 1281 } else if ( TupleType * tupleType = dynamic_cast< TupleType * >( aggrExpr->get_result() ) ) { 1368 addTupleMembers( tupleType, aggrExpr, cost, agg->env, memberExpr->get_member() );1282 addTupleMembers( tupleType, aggrExpr, *agg, cost, memberExpr->get_member() ); 1369 1283 } // if 1370 1284 } // for … … 1372 1286 1373 1287 void AlternativeFinder::Finder::postvisit( MemberExpr *memberExpr ) { 1374 alternatives.push_back( Alternative ( memberExpr->clone(), env, Cost::zero ));1288 alternatives.push_back( Alternative{ memberExpr->clone(), env } ); 1375 1289 } 1376 1290 … … 1385 1299 // addAnonAlternatives uses vector::push_back, which invalidates references to existing elements, so 1386 1300 // can't construct in place and use vector::back 1387 Alternative newAlt ( newExpr, env, Cost::zero, cost );1301 Alternative newAlt{ newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost }; 1388 1302 PRINT( 1389 1303 std::cerr << "decl is "; … … 1403 1317 // not sufficient to clone here, because variable's type may have changed 1404 1318 // since the VariableExpr was originally created. 1405 alternatives.push_back( Alternative ( new VariableExpr( variableExpr->var ), env, Cost::zero ));1319 alternatives.push_back( Alternative{ new VariableExpr{ variableExpr->var }, env } ); 1406 1320 } 1407 1321 1408 1322 void AlternativeFinder::Finder::postvisit( ConstantExpr *constantExpr ) { 1409 alternatives.push_back( Alternative ( constantExpr->clone(), env, Cost::zero ));1323 alternatives.push_back( Alternative{ constantExpr->clone(), env } ); 1410 1324 } 1411 1325 … … 1413 1327 if ( sizeofExpr->get_isType() ) { 1414 1328 Type * newType = sizeofExpr->get_type()->clone(); 1415 alternatives.push_back( Alternative( new SizeofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) ); 1329 alternatives.push_back( Alternative{ 1330 new SizeofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1416 1331 } else { 1417 1332 // find all alternatives for the argument to sizeof … … 1427 1342 Alternative &choice = winners.front(); 1428 1343 referenceToRvalueConversion( choice.expr, choice.cost ); 1429 alternatives.push_back( Alternative( new SizeofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1344 alternatives.push_back( Alternative{ 1345 choice, new SizeofExpr( choice.expr->clone() ), Cost::zero } ); 1430 1346 } // if 1431 1347 } … … 1434 1350 if ( alignofExpr->get_isType() ) { 1435 1351 Type * newType = alignofExpr->get_type()->clone(); 1436 alternatives.push_back( Alternative( new AlignofExpr( resolveTypeof( newType, indexer ) ), env, Cost::zero ) ); 1352 alternatives.push_back( Alternative{ 1353 new AlignofExpr{ resolveTypeof( newType, indexer ) }, env } ); 1437 1354 } else { 1438 1355 // find all alternatives for the argument to sizeof … … 1448 1365 Alternative &choice = winners.front(); 1449 1366 referenceToRvalueConversion( choice.expr, choice.cost ); 1450 alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) ); 1367 alternatives.push_back( Alternative{ 1368 choice, new AlignofExpr{ choice.expr->clone() }, Cost::zero } ); 1451 1369 } // if 1452 1370 } … … 1458 1376 for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) { 1459 1377 if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) { 1460 alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt ), env, Cost::zero ) ); 1378 alternatives.push_back( Alternative{ 1379 new OffsetofExpr{ aggInst->clone(), dwt }, env } ); 1461 1380 renameTypes( alternatives.back().expr ); 1462 1381 } else { … … 1477 1396 1478 1397 void AlternativeFinder::Finder::postvisit( OffsetofExpr *offsetofExpr ) { 1479 alternatives.push_back( Alternative ( offsetofExpr->clone(), env, Cost::zero ));1398 alternatives.push_back( Alternative{ offsetofExpr->clone(), env } ); 1480 1399 } 1481 1400 1482 1401 void AlternativeFinder::Finder::postvisit( OffsetPackExpr *offsetPackExpr ) { 1483 alternatives.push_back( Alternative ( offsetPackExpr->clone(), env, Cost::zero ));1402 alternatives.push_back( Alternative{ offsetPackExpr->clone(), env } ); 1484 1403 } 1485 1404 … … 1501 1420 Cost cost = Cost::zero; 1502 1421 Expression * newExpr = data.combine( cost ); 1503 alternatives.push_back( Alternative( new AttrExpr( newExpr, argType->clone() ), env, Cost::zero, cost ) ); 1422 alternatives.push_back( Alternative{ 1423 new AttrExpr{ newExpr, argType->clone() }, env, OpenVarSet{}, 1424 AssertionList{}, Cost::zero, cost } ); 1504 1425 for ( DeclarationWithType * retVal : function->returnVals ) { 1505 1426 alternatives.back().expr->result = retVal->get_type()->clone(); … … 1540 1461 Cost cost = Cost::zero; 1541 1462 Expression * newExpr = data.combine( cost ); 1542 alternatives.push_back( Alternative( newExpr, env, Cost::zero, cost ) ); 1463 alternatives.push_back( Alternative{ 1464 newExpr, env, OpenVarSet{}, AssertionList{}, Cost::zero, cost } ); 1543 1465 renameTypes( alternatives.back().expr ); 1544 1466 } // for … … 1555 1477 for ( const Alternative & first : firstFinder.alternatives ) { 1556 1478 for ( const Alternative & second : secondFinder.alternatives ) { 1557 TypeEnvironment compositeEnv; 1558 compositeEnv.simpleCombine( first.env ); 1479 TypeEnvironment compositeEnv{ first.env }; 1559 1480 compositeEnv.simpleCombine( second.env ); 1560 1561 LogicalExpr *newExpr = new LogicalExpr( first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() ); 1562 alternatives.push_back( Alternative( newExpr, compositeEnv, first.cost + second.cost ) ); 1481 OpenVarSet openVars{ first.openVars }; 1482 mergeOpenVars( openVars, second.openVars ); 1483 AssertionSet need; 1484 cloneAll( first.need, need ); 1485 cloneAll( second.need, need ); 1486 1487 LogicalExpr *newExpr = new LogicalExpr{ 1488 first.expr->clone(), second.expr->clone(), logicalExpr->get_isAnd() }; 1489 alternatives.push_back( Alternative{ 1490 newExpr, std::move(compositeEnv), std::move(openVars), 1491 AssertionList( need.begin(), need.end() ), first.cost + second.cost } ); 1563 1492 } 1564 1493 } … … 1581 1510 for ( const Alternative & second : secondFinder.alternatives ) { 1582 1511 for ( const Alternative & third : thirdFinder.alternatives ) { 1583 TypeEnvironment compositeEnv; 1584 compositeEnv.simpleCombine( first.env ); 1512 TypeEnvironment compositeEnv{ first.env }; 1585 1513 compositeEnv.simpleCombine( second.env ); 1586 1514 compositeEnv.simpleCombine( third.env ); 1587 1515 OpenVarSet openVars{ first.openVars }; 1516 mergeOpenVars( openVars, second.openVars ); 1517 mergeOpenVars( openVars, third.openVars ); 1518 AssertionSet need; 1519 cloneAll( first.need, need ); 1520 cloneAll( second.need, need ); 1521 cloneAll( third.need, need ); 1522 AssertionSet have; 1523 1588 1524 // unify true and false types, then infer parameters to produce new alternatives 1589 OpenVarSet openVars;1590 AssertionSet needAssertions, haveAssertions;1591 Alternative newAlt( 0, compositeEnv, first.cost + second.cost + third.cost );1592 1525 Type* commonType = nullptr; 1593 if ( unify( second.expr->result, third.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1594 ConditionalExpr *newExpr = new ConditionalExpr( first.expr->clone(), second.expr->clone(), third.expr->clone() ); 1526 if ( unify( second.expr->result, third.expr->result, compositeEnv, 1527 need, have, openVars, indexer, commonType ) ) { 1528 ConditionalExpr *newExpr = new ConditionalExpr{ 1529 first.expr->clone(), second.expr->clone(), third.expr->clone() }; 1595 1530 newExpr->result = commonType ? commonType : second.expr->result->clone(); 1596 1531 // convert both options to the conditional result type 1597 newAlt.cost += computeExpressionConversionCost( newExpr->arg2, newExpr->result, indexer, newAlt.env ); 1598 newAlt.cost += computeExpressionConversionCost( newExpr->arg3, newExpr->result, indexer, newAlt.env ); 1599 newAlt.expr = newExpr; 1600 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); 1532 Cost cost = first.cost + second.cost + third.cost; 1533 cost += computeExpressionConversionCost( 1534 newExpr->arg2, newExpr->result, indexer, compositeEnv ); 1535 cost += computeExpressionConversionCost( 1536 newExpr->arg3, newExpr->result, indexer, compositeEnv ); 1537 // output alternative 1538 Alternative newAlt{ 1539 newExpr, std::move(compositeEnv), std::move(openVars), 1540 AssertionList( need.begin(), need.end() ), cost }; 1541 inferParameters( newAlt, back_inserter( alternatives ) ); 1601 1542 } // if 1602 1543 } // for … … 1611 1552 secondFinder.findWithAdjustment( commaExpr->get_arg2() ); 1612 1553 for ( const Alternative & alt : secondFinder.alternatives ) { 1613 alternatives.push_back( Alternative( new CommaExpr( newFirstArg->clone(), alt.expr->clone() ), alt.env, alt.cost ) ); 1554 alternatives.push_back( Alternative{ 1555 alt, new CommaExpr{ newFirstArg->clone(), alt.expr->clone() }, alt.cost } ); 1614 1556 } // for 1615 1557 delete newFirstArg; … … 1626 1568 for ( const Alternative & first : firstFinder.alternatives ) { 1627 1569 for ( const Alternative & second : secondFinder.alternatives ) { 1628 TypeEnvironment compositeEnv; 1629 compositeEnv.simpleCombine( first.env ); 1570 TypeEnvironment compositeEnv{ first.env }; 1630 1571 compositeEnv.simpleCombine( second.env ); 1631 OpenVarSet openVars; 1632 AssertionSet needAssertions, haveAssertions; 1633 Alternative newAlt( 0, compositeEnv, first.cost + second.cost ); 1572 OpenVarSet openVars{ first.openVars }; 1573 mergeOpenVars( openVars, second.openVars ); 1574 AssertionSet need; 1575 cloneAll( first.need, need ); 1576 cloneAll( second.need, need ); 1577 AssertionSet have; 1578 1634 1579 Type* commonType = nullptr; 1635 if ( unify( first.expr->result, second.expr->result, newAlt.env, needAssertions, haveAssertions, openVars, indexer, commonType ) ) { 1636 RangeExpr * newExpr = new RangeExpr( first.expr->clone(), second.expr->clone() ); 1580 if ( unify( first.expr->result, second.expr->result, compositeEnv, need, have, 1581 openVars, indexer, commonType ) ) { 1582 RangeExpr * newExpr = 1583 new RangeExpr{ first.expr->clone(), second.expr->clone() }; 1637 1584 newExpr->result = commonType ? commonType : first.expr->result->clone(); 1638 newAlt.expr = newExpr; 1639 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( alternatives ) ); 1585 Alternative newAlt{ 1586 newExpr, std::move(compositeEnv), std::move(openVars), 1587 AssertionList( need.begin(), need.end() ), first.cost + second.cost }; 1588 inferParameters( newAlt, back_inserter( alternatives ) ); 1640 1589 } // if 1641 1590 } // for … … 1655 1604 1656 1605 TypeEnvironment compositeEnv; 1657 simpleCombineEnvironments( alts.begin(), alts.end(), compositeEnv ); 1658 alternatives.push_back( 1659 Alternative{ new TupleExpr( exprs ), compositeEnv, sumCost( alts ) } ); 1606 OpenVarSet openVars; 1607 AssertionSet need; 1608 for ( const Alternative& alt : alts ) { 1609 compositeEnv.simpleCombine( alt.env ); 1610 mergeOpenVars( openVars, alt.openVars ); 1611 cloneAll( alt.need, need ); 1612 } 1613 1614 alternatives.push_back( Alternative{ 1615 new TupleExpr{ exprs }, std::move(compositeEnv), std::move(openVars), 1616 AssertionList( need.begin(), need.end() ), sumCost( alts ) } ); 1660 1617 } // for 1661 1618 } 1662 1619 1663 1620 void AlternativeFinder::Finder::postvisit( TupleExpr *tupleExpr ) { 1664 alternatives.push_back( Alternative ( tupleExpr->clone(), env, Cost::zero ));1621 alternatives.push_back( Alternative{ tupleExpr->clone(), env } ); 1665 1622 } 1666 1623 1667 1624 void AlternativeFinder::Finder::postvisit( ImplicitCopyCtorExpr * impCpCtorExpr ) { 1668 alternatives.push_back( Alternative ( impCpCtorExpr->clone(), env, Cost::zero ));1625 alternatives.push_back( Alternative{ impCpCtorExpr->clone(), env } ); 1669 1626 } 1670 1627 … … 1675 1632 finder.findWithoutPrune( ctorExpr->get_callExpr() ); 1676 1633 for ( Alternative & alt : finder.alternatives ) { 1677 alternatives.push_back( Alternative( new ConstructorExpr( alt.expr->clone() ), alt.env, alt.cost ) ); 1634 alternatives.push_back( Alternative{ 1635 alt, new ConstructorExpr( alt.expr->clone() ), alt.cost } ); 1678 1636 } 1679 1637 } 1680 1638 1681 1639 void AlternativeFinder::Finder::postvisit( TupleIndexExpr *tupleExpr ) { 1682 alternatives.push_back( Alternative ( tupleExpr->clone(), env, Cost::zero ));1640 alternatives.push_back( Alternative{ tupleExpr->clone(), env } ); 1683 1641 } 1684 1642 1685 1643 void AlternativeFinder::Finder::postvisit( TupleAssignExpr *tupleAssignExpr ) { 1686 alternatives.push_back( Alternative ( tupleAssignExpr->clone(), env, Cost::zero ));1644 alternatives.push_back( Alternative{ tupleAssignExpr->clone(), env } ); 1687 1645 } 1688 1646 … … 1693 1651 // ensure that the id is passed on to the UniqueExpr alternative so that the expressions are "linked" 1694 1652 UniqueExpr * newUnqExpr = new UniqueExpr( alt.expr->clone(), unqExpr->get_id() ); 1695 alternatives.push_back( Alternative ( newUnqExpr, alt.env, alt.cost ));1653 alternatives.push_back( Alternative{ alt, newUnqExpr, alt.cost } ); 1696 1654 } 1697 1655 } … … 1701 1659 ResolvExpr::resolveStmtExpr( newStmtExpr, indexer ); 1702 1660 // xxx - this env is almost certainly wrong, and needs to somehow contain the combined environments from all of the statements in the stmtExpr... 1703 alternatives.push_back( Alternative ( newStmtExpr, env, Cost::zero ));1661 alternatives.push_back( Alternative{ newStmtExpr, env } ); 1704 1662 } 1705 1663 … … 1723 1681 for ( Alternative & alt : finder.get_alternatives() ) { 1724 1682 TypeEnvironment newEnv( alt.env ); 1725 AssertionSet needAssertions, haveAssertions; 1726 OpenVarSet openVars; // find things in env that don't have a "representative type" and claim those are open vars? 1683 AssertionSet need; 1684 cloneAll( alt.need, need ); 1685 AssertionSet have; 1686 OpenVarSet openVars( alt.openVars ); 1687 // xxx - find things in env that don't have a "representative type" and claim 1688 // those are open vars? 1727 1689 PRINT( 1728 1690 std::cerr << " @ " << toType << " " << initAlt.designation << std::endl; 1729 1691 ) 1730 // It's possible that a cast can throw away some values in a multiply-valued expression. (An example is a 1731 // cast-to-void, which casts from one value to zero.) Figure out the prefix of the subexpression results 1732 // that are cast directly. The candidate is invalid if it has fewer results than there are types to cast 1733 // to. 1692 // It's possible that a cast can throw away some values in a multiply-valued 1693 // expression. (An example is a cast-to-void, which casts from one value to 1694 // zero.) Figure out the prefix of the subexpression results that are cast 1695 // directly. The candidate is invalid if it has fewer results than there are 1696 // types to cast to. 1734 1697 int discardedValues = alt.expr->result->size() - toType->size(); 1735 1698 if ( discardedValues < 0 ) continue; 1736 // xxx - may need to go into tuple types and extract relevant types and use unifyList. Note that currently, this does not 1737 // allow casting a tuple to an atomic type (e.g. (int)([1, 2, 3])) 1699 // xxx - may need to go into tuple types and extract relevant types and use 1700 // unifyList. Note that currently, this does not allow casting a tuple to an 1701 // atomic type (e.g. (int)([1, 2, 3])) 1702 1738 1703 // unification run for side-effects 1739 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?? 1704 unify( toType, alt.expr->result, newEnv, need, have, openVars, indexer ); 1705 // xxx - do some inspecting on this line... why isn't result bound to initAlt.type? 1740 1706 1741 1707 Cost thisCost = castCost( alt.expr->result, toType, indexer, newEnv ); … … 1743 1709 // count one safe conversion for each value that is thrown away 1744 1710 thisCost.incSafe( discardedValues ); 1745 Alternative newAlt( new InitExpr( restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() ), newEnv, alt.cost, thisCost ); 1746 inferParameters( needAssertions, haveAssertions, newAlt, openVars, back_inserter( candidates ) ); 1711 Alternative newAlt{ 1712 new InitExpr{ 1713 restructureCast( alt.expr->clone(), toType, true ), initAlt.designation->clone() }, 1714 std::move(newEnv), std::move(openVars), 1715 AssertionList( need.begin(), need.end() ), alt.cost, thisCost }; 1716 inferParameters( newAlt, back_inserter( candidates ) ); 1747 1717 } 1748 1718 } -
src/ResolvExpr/AlternativeFinder.h
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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/ResolveTypeof.cc
r9b086ca rcde3891 67 67 std::cerr << std::endl; 68 68 #endif 69 if ( typeofType->expr ) { 69 // pass on null expression 70 if ( ! typeofType->expr ) return typeofType; 71 72 bool isBasetypeof = typeofType->is_basetypeof; 73 auto oldQuals = typeofType->get_qualifiers().val; 74 75 Type* newType; 76 if ( TypeExpr* tyExpr = dynamic_cast<TypeExpr*>(typeofType->expr) ) { 77 // typeof wrapping type 78 newType = tyExpr->type; 79 tyExpr->type = nullptr; 80 delete tyExpr; 81 } else { 82 // typeof wrapping expression 70 83 Expression * newExpr = resolveInVoidContext( typeofType->expr, indexer ); 71 84 assert( newExpr->result && ! newExpr->result->isVoid() ); 72 Type *newType = newExpr->result;85 newType = newExpr->result; 73 86 newExpr->result = nullptr; 74 87 delete typeofType; 75 88 delete newExpr; 76 return newType; 77 } // if 78 return typeofType; 89 } 90 91 // clear qualifiers for base, combine with typeoftype quals in any case 92 if ( isBasetypeof ) { 93 // replace basetypeof(<enum>) by int 94 if ( dynamic_cast<EnumInstType*>(newType) ) { 95 Type* newerType = 96 new BasicType{ newType->get_qualifiers(), BasicType::SignedInt, 97 newType->attributes }; 98 delete newType; 99 newType = newerType; 100 } 101 newType->get_qualifiers().val 102 = ( newType->get_qualifiers().val & ~Type::Qualifiers::Mask ) | oldQuals; 103 } else { 104 newType->get_qualifiers().val |= oldQuals; 105 } 106 107 return newType; 79 108 } 80 109 } // namespace ResolvExpr -
src/ResolvExpr/Resolver.cc
r9b086ca rcde3891 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 #include "SymTab/Autogen.h" // for SizeType 33 34 #include "SymTab/Indexer.h" // for Indexer 34 35 #include "SynTree/Declaration.h" // for ObjectDecl, TypeDecl, Declar... … … 168 169 169 170 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) {171 void findUnfinishedKindExpression(Expression * untyped, Alternative & alt, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{} ) { 171 172 assertf( untyped, "expected a non-null expression." ); 173 174 // xxx - this isn't thread-safe, but should work until we parallelize the resolver 175 static unsigned recursion_level = 0; 176 177 ++recursion_level; 172 178 TypeEnvironment env; 173 179 AlternativeFinder finder( indexer, env ); 174 finder.find( untyped, adjust, prune, failFast ); 180 finder.find( untyped, recursion_level == 1 ? mode.atTopLevel() : mode ); 181 --recursion_level; 175 182 176 183 #if 0 … … 185 192 #endif 186 193 194 // produce filtered list of alternatives 187 195 AltList candidates; 188 196 for ( Alternative & alt : finder.get_alternatives() ) { … … 192 200 } 193 201 194 // xxx - if > 1 alternative with same cost, ignore deleted and pick from remaining 195 // choose the lowest cost expression among the candidates 202 // produce invalid error if no candidates 203 if ( candidates.empty() ) { 204 SemanticError( untyped, toString( "No reasonable alternatives for ", kindStr, (kindStr != "" ? " " : ""), "expression: ") ); 205 } 206 207 // search for cheapest candidate 196 208 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 ) { 209 bool seen_undeleted = false; 210 for ( unsigned i = 0; i < candidates.size(); ++i ) { 211 int c = winners.empty() ? -1 : candidates[i].cost.compare( winners.front().cost ); 212 213 if ( c > 0 ) continue; // skip more expensive than winner 214 215 if ( c < 0 ) { 216 // reset on new cheapest 217 seen_undeleted = ! findDeletedExpr( candidates[i].expr ); 218 winners.clear(); 219 } else /* if ( c == 0 ) */ { 220 if ( findDeletedExpr( candidates[i].expr ) ) { 221 // skip deleted expression if already seen one equivalent-cost not 222 if ( seen_undeleted ) continue; 223 } else if ( ! seen_undeleted ) { 224 // replace list of equivalent-cost deleted expressions with one non-deleted 225 winners.clear(); 226 seen_undeleted = true; 227 } 228 } 229 230 winners.emplace_back( std::move( candidates[i] ) ); 231 } 232 233 // promote alternative.cvtCost to .cost 234 // xxx - I don't know why this is done, but I'm keeping the behaviour from findMinCost 235 for ( Alternative& winner : winners ) { 236 winner.cost = winner.cvtCost; 237 } 238 239 // produce ambiguous errors, if applicable 240 if ( winners.size() != 1 ) { 201 241 std::ostringstream stream; 202 242 stream << "Cannot choose between " << winners.size() << " alternatives for " << kindStr << (kindStr != "" ? " " : "") << "expression\n"; … … 207 247 } 208 248 209 // there is one unambiguous interpretation - move the expression into the with statement 210 Alternative & choice = winners.front(); 211 if ( findDeletedExpr( choice.expr ) ) { 249 // single selected choice 250 Alternative& choice = winners.front(); 251 252 // fail on only expression deleted 253 if ( ! seen_undeleted ) { 212 254 SemanticError( untyped->location, choice.expr, "Unique best alternative includes deleted identifier in " ); 213 255 } 256 257 // xxx - check for ambiguous expressions 258 259 // output selected choice 214 260 alt = std::move( choice ); 215 261 } 216 262 217 263 /// 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) {264 void findKindExpression(Expression *& untyped, const SymTab::Indexer & indexer, const std::string & kindStr, std::function<bool(const Alternative &)> pred, ResolvMode mode = ResolvMode{}) { 219 265 if ( ! untyped ) return; 220 266 Alternative choice; 221 findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, adjust, prune, failFast);267 findUnfinishedKindExpression( untyped, choice, indexer, kindStr, pred, mode ); 222 268 finishExpr( choice.expr, choice.env, untyped->env ); 223 269 delete untyped; … … 250 296 untyped.arg = expr; 251 297 Alternative choice; 252 findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, true);298 findUnfinishedKindExpression( &untyped, choice, indexer, "", standardAlternativeFilter, ResolvMode::withAdjustment() ); 253 299 CastExpr * castExpr = strict_dynamic_cast< CastExpr * >( choice.expr ); 254 300 env = std::move( choice.env ); … … 357 403 358 404 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.405 // To handle initialization of routine pointers, e.g., int (*fp)(int) = foo(), means that 406 // class-variable initContext is changed multiple time because the LHS is analysed twice. 407 // The second analysis changes initContext because of a function type can contain object 408 // declarations in the return and parameter types. So each value of initContext is 409 // retained, so the type on the first analysis is preserved and used for selecting the RHS. 364 410 GuardValue( currentObject ); 365 411 currentObject = CurrentObject( objectDecl->get_type() ); … … 397 443 398 444 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. 445 // default value expressions have an environment which shouldn't be there and trips up 446 // later passes. 447 // xxx - it might be necessary to somehow keep the information from this environment, but I 448 // can't currently see how it's useful. 402 449 for ( Declaration * d : functionDecl->type->parameters ) { 403 450 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( d ) ) { … … 749 796 initExpr->expr = nullptr; 750 797 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. 798 // InitExpr may have inferParams in the case where the expression specializes a function 799 // pointer, and newExpr may already have inferParams of its own, so a simple swap is not 800 // sufficient. 753 801 newExpr->spliceInferParams( initExpr ); 754 802 delete initExpr; 755 803 756 // get the actual object's type (may not exactly match what comes back from the resolver due to conversions) 804 // get the actual object's type (may not exactly match what comes back from the resolver 805 // due to conversions) 757 806 Type * initContext = currentObject.getCurrentType(); 758 807 … … 766 815 if ( isCharType( pt->get_base() ) ) { 767 816 if ( CastExpr *ce = dynamic_cast< CastExpr * >( newExpr ) ) { 768 // strip cast if we're initializing a char[] with a char *, e.g. char x[] = "hello"; 817 // strip cast if we're initializing a char[] with a char *, 818 // e.g. char x[] = "hello"; 769 819 newExpr = ce->get_arg(); 770 820 ce->set_arg( nullptr ); … … 788 838 // move cursor into brace-enclosed initializer-list 789 839 currentObject.enterListInit(); 790 // xxx - fix this so that the list isn't copied, iterator should be used to change current element 840 // xxx - fix this so that the list isn't copied, iterator should be used to change current 841 // element 791 842 std::list<Designation *> newDesignations; 792 843 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.844 // iterate designations and initializers in pairs, moving the cursor to the current 845 // designated object and resolving the initializer against that object. 795 846 Designation * des = std::get<0>(p); 796 847 Initializer * init = std::get<1>(p); … … 822 873 // fall back on C-style initializer 823 874 delete ctorInit->get_ctor(); 824 ctorInit->set_ctor( NULL);875 ctorInit->set_ctor( nullptr ); 825 876 delete ctorInit->get_dtor(); 826 ctorInit->set_dtor( NULL);877 ctorInit->set_dtor( nullptr ); 827 878 maybeAccept( ctorInit->get_init(), *visitor ); 828 879 } … … 867 918 868 919 // xxx - todo -- what about arrays? 869 // if ( dtor == NULL&& InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) {920 // if ( dtor == nullptr && InitTweak::isIntrinsicCallStmt( ctorInit->get_ctor() ) ) { 870 921 // // can reduce the constructor down to a SingleInit using the 871 922 // // second argument from the ctor call, since 872 923 // delete ctorInit->get_ctor(); 873 // ctorInit->set_ctor( NULL);924 // ctorInit->set_ctor( nullptr ); 874 925 875 926 // Expression * arg = -
src/ResolvExpr/TypeEnvironment.cc
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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/SymTab/Demangle.cc
r9b086ca rcde3891 392 392 parsers.emplace_back(Encoding::enum_t, [this](Type::Qualifiers tq) { return parseEnum(tq); }); 393 393 parsers.emplace_back(Encoding::type, [this](Type::Qualifiers tq) { return parseType(tq); }); 394 parsers.emplace_back(Encoding::zero, [ this](Type::Qualifiers tq) { return new ZeroType(tq); });395 parsers.emplace_back(Encoding::one, [ this](Type::Qualifiers tq) { return new OneType(tq); });394 parsers.emplace_back(Encoding::zero, [](Type::Qualifiers tq) { return new ZeroType(tq); }); 395 parsers.emplace_back(Encoding::one, [](Type::Qualifiers tq) { return new OneType(tq); }); 396 396 } 397 397 -
src/SymTab/Mangler.cc
r9b086ca rcde3891 15 15 #include "Mangler.h" 16 16 17 #include <algorithm> // for copy, transform18 #include <cassert> // for assert, assertf19 #include <functional> // for const_mem_fun_t, mem_fun20 #include <iterator> // for ostream_iterator, back_insert_ite...21 #include <list> // for _List_iterator, list, _List_const...22 #include <string> // for string, char_traits, operator<<23 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup17 #include <algorithm> // for copy, transform 18 #include <cassert> // for assert, assertf 19 #include <functional> // for const_mem_fun_t, mem_fun 20 #include <iterator> // for ostream_iterator, back_insert_ite... 21 #include <list> // for _List_iterator, list, _List_const... 22 #include <string> // for string, char_traits, operator<< 23 24 #include "CodeGen/OperatorTable.h" // for OperatorInfo, operatorLookup 25 25 #include "Common/PassVisitor.h" 26 #include "Common/SemanticError.h" // for SemanticError 27 #include "Common/utility.h" // for toString 28 #include "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... 29 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType 30 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<< 31 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora... 26 #include "Common/SemanticError.h" // for SemanticError 27 #include "Common/utility.h" // for toString 28 #include "Parser/LinkageSpec.h" // for Spec, isOverridable, AutoGen, Int... 29 #include "ResolvExpr/TypeEnvironment.h" // for TypeEnvironment 30 #include "SynTree/Declaration.h" // for TypeDecl, DeclarationWithType 31 #include "SynTree/Expression.h" // for TypeExpr, Expression, operator<< 32 #include "SynTree/Type.h" // for Type, ReferenceToType, Type::Fora... 32 33 33 34 namespace SymTab { … … 37 38 struct Mangler : public WithShortCircuiting, public WithVisitorRef<Mangler>, public WithGuards { 38 39 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ); 40 Mangler( const ResolvExpr::TypeEnvironment& env ); 39 41 Mangler( const Mangler & ) = delete; 40 42 … … 65 67 private: 66 68 std::ostringstream mangleName; ///< Mangled name being constructed 67 typedef std::map< std::string, std::pair< int, int > > VarMapType;69 typedef std::map< std::string, std::pair< std::string, int > > VarMapType; 68 70 VarMapType varNums; ///< Map of type variables to indices 69 71 int nextVarNum; ///< Next type variable index 72 const ResolvExpr::TypeEnvironment* env; ///< optional environment for substitutions 70 73 bool isTopLevel; ///< Is the Mangler at the top level 71 74 bool mangleOverridable; ///< Specially mangle overridable built-in methods … … 75 78 bool inQualifiedType = false; ///< Add start/end delimiters around qualified type 76 79 80 public: 81 Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 82 int nextVarNum, const ResolvExpr::TypeEnvironment* env, 83 const VarMapType& varNums ); 84 85 private: 77 86 void mangleDecl( DeclarationWithType *declaration ); 78 87 void mangleRef( ReferenceToType *refType, std::string prefix ); … … 100 109 } 101 110 111 std::string mangleAssnKey( DeclarationWithType* decl, 112 const ResolvExpr::TypeEnvironment& env ) { 113 PassVisitor<Mangler> mangler( env ); 114 maybeAccept( decl, mangler ); 115 return mangler.pass.get_mangleName(); 116 } 117 102 118 namespace { 103 119 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams ) 104 : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), typeMode( typeMode ), mangleGenericParams( mangleGenericParams ) {} 120 : nextVarNum( 0 ), env(nullptr), isTopLevel( true ), 121 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 122 mangleGenericParams( mangleGenericParams ) {} 123 124 Mangler::Mangler( const ResolvExpr::TypeEnvironment& env ) 125 : nextVarNum( 0 ), env( &env ), isTopLevel( true ), mangleOverridable( false ), 126 typeMode( false ), mangleGenericParams( true ) {} 127 128 Mangler::Mangler( bool mangleOverridable, bool typeMode, bool mangleGenericParams, 129 int nextVarNum, const ResolvExpr::TypeEnvironment* env, 130 const VarMapType& varNums ) 131 : varNums( varNums ), nextVarNum( nextVarNum ), env( env ), isTopLevel( false ), 132 mangleOverridable( mangleOverridable ), typeMode( typeMode ), 133 mangleGenericParams( mangleGenericParams ) {} 105 134 106 135 void Mangler::mangleDecl( DeclarationWithType * declaration ) { … … 329 358 assert( false ); 330 359 } // switch 331 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); 360 std::string varName; 361 // replace type with substitution name if environment is available and bound 362 if ( env ) { 363 const ResolvExpr::EqvClass* varClass = env->lookup( (*i)->name ); 364 if ( varClass && varClass->type ) { 365 PassVisitor<Mangler> sub_mangler( 366 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, 367 env, varNums ); 368 varClass->type->accept( sub_mangler ); 369 varName = std::string{"%"} + sub_mangler.pass.get_mangleName(); 370 } 371 } 372 // otherwise just give type numeric name 373 if ( varName.empty() ) { 374 varName = std::to_string( nextVarNum++ ); 375 } 376 varNums[ (*i)->name ] = std::make_pair( varName, (int)(*i)->get_kind() ); 332 377 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { 333 PassVisitor<Mangler> sub_mangler( mangleOverridable, typeMode, mangleGenericParams ); 334 sub_mangler.pass.nextVarNum = nextVarNum; 335 sub_mangler.pass.isTopLevel = false; 336 sub_mangler.pass.varNums = varNums; 378 PassVisitor<Mangler> sub_mangler( 379 mangleOverridable, typeMode, mangleGenericParams, nextVarNum, env, 380 varNums ); 337 381 (*assert)->accept( sub_mangler ); 338 assertionNames.push_back( sub_mangler.pass. mangleName.str() );382 assertionNames.push_back( sub_mangler.pass.get_mangleName() ); 339 383 acount++; 340 384 } // for -
src/SymTab/Mangler.h
r9b086ca rcde3891 31 31 // * Currently name compression is not implemented. 32 32 33 namespace ResolvExpr { 34 class TypeEnvironment; 35 } 36 33 37 namespace SymTab { 34 38 namespace Mangler { … … 40 44 /// Mangle ignoring generic type parameters 41 45 std::string mangleConcrete( Type* ty ); 46 /// Mangle for assertion key 47 std::string mangleAssnKey( DeclarationWithType* decl, 48 const ResolvExpr::TypeEnvironment& env ); 42 49 43 50 namespace Encoding { -
src/SymTab/Validate.cc
r9b086ca rcde3891 398 398 assert( aggr ); // TODO: need to handle forward declarations 399 399 for ( Declaration * member : aggr->members ) { 400 if ( StructInstType * inst = dynamic_cast< StructInstType * >( child ) ) { 401 if ( StructDecl * aggr = dynamic_cast< StructDecl * >( member ) ) { 402 if ( aggr->name == inst->name ) { 403 // TODO: is this case, and other non-TypeInstType cases, necessary? 404 return new StructInstType( qualType->get_qualifiers(), aggr ); 405 } 406 } 407 } else if ( UnionInstType * inst = dynamic_cast< UnionInstType * >( child ) ) { 408 if ( UnionDecl * aggr = dynamic_cast< UnionDecl * > ( member ) ) { 409 if ( aggr->name == inst->name ) { 410 return new UnionInstType( qualType->get_qualifiers(), aggr ); 411 } 412 } 413 } else if ( EnumInstType * inst = dynamic_cast< EnumInstType * >( child ) ) { 414 if ( EnumDecl * aggr = dynamic_cast< EnumDecl * > ( member ) ) { 415 if ( aggr->name == inst->name ) { 416 return new EnumInstType( qualType->get_qualifiers(), aggr ); 417 } 418 } 419 } else if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) { 400 if ( TypeInstType * inst = dynamic_cast< TypeInstType * >( child ) ) { 420 401 // name on the right is a typedef 421 402 if ( NamedTypeDecl * aggr = dynamic_cast< NamedTypeDecl * > ( member ) ) { … … 424 405 Type * ret = aggr->base->clone(); 425 406 ret->get_qualifiers() = qualType->get_qualifiers(); 407 TypeSubstitution sub = parent->genericSubstitution(); 408 sub.apply(ret); 426 409 return ret; 427 410 } -
src/SynTree/ApplicationExpr.cc
r9b086ca rcde3891 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/Constant.cc
r9b086ca rcde3891 10 10 // Created On : Mon May 18 07:44:20 2015 11 11 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Jul 14 14:50:00 201713 // Update Count : 2912 // Last Modified On : Fri Spt 28 14:49:00 2018 13 // Update Count : 30 14 14 // 15 15 … … 19 19 20 20 #include "Constant.h" 21 #include "Expression.h" // for ConstantExpr 21 22 #include "Type.h" // for BasicType, Type, Type::Qualifiers, PointerType 22 23 … … 48 49 Constant Constant::from_double( double d ) { 49 50 return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ), d ); 51 } 52 53 Constant Constant::from_string( std::string const & str ) { 54 return Constant( 55 new ArrayType( 56 noQualifiers, 57 new BasicType( Type::Qualifiers( Type::Const ), BasicType::Char ), 58 new ConstantExpr( Constant::from_int( str.size() + 1 /* \0 */ )), 59 false, false ), 60 std::string("\"") + str + "\"", (unsigned long long int)0 ); 50 61 } 51 62 -
src/SynTree/Constant.h
r9b086ca rcde3891 9 9 // Author : Richard C. Bilson 10 10 // Created On : Mon May 18 07:44:20 2015 11 // Last Modified By : Peter A. Buhr12 // Last Modified On : Sat Jul 22 09:54:46 201713 // Update Count : 1 711 // Last Modified By : Andrew Beach 12 // Last Modified On : Fri Spt 28 14:48:00 2018 13 // Update Count : 18 14 14 // 15 15 … … 51 51 /// generates a floating point constant of the given double 52 52 static Constant from_double( double d ); 53 /// generates an array of chars constant of the given string 54 static Constant from_string( std::string const & s ); 53 55 54 56 /// generates a null pointer value for the given type. void * if omitted. -
src/SynTree/Expression.cc
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 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/SynTree/Type.h
r9b086ca rcde3891 598 598 class TypeofType : public Type { 599 599 public: 600 Expression *expr; 601 602 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 600 Expression *expr; ///< expression to take the type of 601 bool is_basetypeof; ///< true iff is basetypeof type 602 603 TypeofType( const Type::Qualifiers & tq, Expression *expr, const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 604 TypeofType( const Type::Qualifiers & tq, Expression *expr, bool is_basetypeof, 605 const std::list< Attribute * > & attributes = std::list< Attribute * >() ); 603 606 TypeofType( const TypeofType& ); 604 607 virtual ~TypeofType(); -
src/SynTree/TypeofType.cc
r9b086ca rcde3891 23 23 class Attribute; 24 24 25 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, const std::list< Attribute * > & attributes ) : Type( tq, attributes ), expr( expr ) { 26 } 25 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, 26 const std::list< Attribute * > & attributes ) 27 : Type( tq, attributes ), expr( expr ), is_basetypeof(false) {} 27 28 28 TypeofType::TypeofType( const TypeofType &other ) : Type( other ), expr( maybeClone( other.expr ) ) { 29 } 29 TypeofType::TypeofType( const Type::Qualifiers &tq, Expression *expr, bool is_basetypeof, 30 const std::list< Attribute * > & attributes ) 31 : Type( tq, attributes ), expr( expr ), is_basetypeof( is_basetypeof ) {} 32 33 TypeofType::TypeofType( const TypeofType &other ) 34 : Type( other ), expr( maybeClone( other.expr ) ), is_basetypeof( other.is_basetypeof ) {} 30 35 31 36 TypeofType::~TypeofType() { … … 35 40 void TypeofType::print( std::ostream &os, Indenter indent ) const { 36 41 Type::print( os, indent ); 42 if ( is_basetypeof ) { os << "base-"; } 37 43 os << "type-of expression "; 38 44 if ( expr ) { -
src/Tuples/Explode.h
r9b086ca rcde3891 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
r9b086ca rcde3891 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
r9b086ca rcde3891 1 2 1 3 CFACOMPILE = $(CFACC) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) $(AM_CFLAGS) $(CFLAGS) 4 LTCFACOMPILE = $(LIBTOOL) $(AM_V_lt) --tag=CC $(AM_LIBTOOLFLAGS) \ 5 $(LIBTOOLFLAGS) --mode=compile $(CFACC) $(DEFS) \ 6 $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CFAFLAGS) $(CFAFLAGS) \ 7 $(AM_CFLAGS) $(CFLAGS) 2 8 3 9 AM_V_CFA = $(am__v_CFA_@AM_V@) … … 6 12 am__v_CFA_1 = 7 13 8 .cfa.o: $(CFACC) $(CFACPP)14 .cfa.o: 9 15 $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.o$$||'`;\ 10 16 $(CFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 11 17 $(am__mv) $$depbase.Tpo $$depbase.Po 18 19 .cfa.lo: 20 $(AM_V_CFA)depbase=`echo $@ | sed 's|[^/]*$$|$(DEPDIR)/&|;s|\.lo$$||'`;\ 21 $(LTCFACOMPILE) -MT $@ -MD -MP -MF $$depbase.Tpo -c -o $@ $< &&\ 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
r9b086ca rcde3891 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
r9b086ca rcde3891 10 10 // Created On : Fri May 15 23:12:02 2015 11 11 // Last Modified By : Peter A. Buhr 12 // Last Modified On : Wed Jun 6 15:51:47201813 // Update Count : 49 812 // Last Modified On : Wed Dec 26 08:11:19 2018 13 // Update Count : 499 14 14 // 15 15 … … 34 34 #include "CodeGen/Generate.h" // for generate 35 35 #include "CodeTools/DeclStats.h" // for printDeclStats 36 #include "CodeTools/ResolvProtoDump.h" // for dumpAsResolvProto 36 37 #include "CodeTools/TrackLoc.h" // for fillLocations 37 38 #include "Common/CompilerError.h" // for CompilerError … … 171 172 if ( filename == nullptr ) filename = argv[ optind ]; 172 173 // prelude filename comes in differently 173 if ( libcfap ) filename = "prelude.cf ";174 if ( libcfap ) filename = "prelude.cfa"; 174 175 optind += 1; 175 176 } else { // no input file name … … 198 199 if ( ! libcfap ) { 199 200 // read the prelude in, if not generating the cfa library 200 FILE * prelude = fopen( (PreludeDirector + "/prelude.cf ").c_str(), "r" );201 assertf( prelude, "cannot open prelude.cf \n" );201 FILE * prelude = fopen( (PreludeDirector + "/prelude.cfa").c_str(), "r" ); 202 assertf( prelude, "cannot open prelude.cfa\n" ); 202 203 parse( prelude, LinkageSpec::Intrinsic ); 203 204 … … 270 271 271 272 CodeTools::fillLocations( translationUnit ); 273 274 if ( resolvprotop ) { 275 CodeTools::dumpAsResolvProto( translationUnit ); 276 return 0; 277 } 272 278 273 279 PASS( "resolve", ResolvExpr::resolve( translationUnit ) ); … … 365 371 } 366 372 } catch(const std::exception& e) { 367 std::cerr << "Un aught Exception \"" << e.what() << "\"\n";373 std::cerr << "Uncaught Exception \"" << e.what() << "\"\n"; 368 374 } 369 375 return 1; … … 376 382 377 383 void parse_cmdline( int argc, char * argv[], const char *& filename ) { 378 enum { Ast, Bbox, Bresolver, CtorInitFix, DeclStats, Expr, ExprAlt, Grammar, LibCFA, Linemarks, Nolinemarks, Nopreamble, Parse, PreludeDir, Prototypes, Resolver, Symbol, Tree, TupleExpansion, Validate, };384 enum { Ast, Bbox, Bresolver, CtorInitFix, DeclStats, Expr, ExprAlt, Grammar, LibCFA, Linemarks, Nolinemarks, Nopreamble, Parse, PreludeDir, Prototypes, Resolver, ResolvProto, Symbol, Tree, TupleExpansion, Validate, }; 379 385 380 386 static struct option long_opts[] = { … … 395 401 { "no-prototypes", no_argument, 0, Prototypes }, 396 402 { "resolver", no_argument, 0, Resolver }, 403 { "resolv-proto", no_argument, 0, ResolvProto }, 397 404 { "symbol", no_argument, 0, Symbol }, 398 405 { "tree", no_argument, 0, Tree }, … … 407 414 bool Wsuppress = false, Werror = false; 408 415 int c; 409 while ( (c = getopt_long( argc, argv, "abBcCdefgGlLmnNpqr stTvwW:yzZD:F:", long_opts, &long_index )) != -1 ) {416 while ( (c = getopt_long( argc, argv, "abBcCdefgGlLmnNpqrRstTvwW:yzZD:F:", long_opts, &long_index )) != -1 ) { 410 417 switch ( c ) { 411 418 case Ast: … … 479 486 case 'r': // print resolver steps 480 487 resolvep = true; 488 break; 489 case 'R': // dump resolv-proto instance 490 resolvprotop = true; 481 491 break; 482 492 case Symbol:
Note:
See TracChangeset
for help on using the changeset viewer.