Ignore:
Timestamp:
Jul 26, 2017, 4:26:08 PM (6 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
Children:
2afec66
Parents:
d335627
Message:

Fix various reference features.

  • Eliminate multiple address-ofs resulting from &(T&) [address-of reference-cast].
  • Keep rvalue cast if reference base type is incompatible with rvalue type.
  • Keep pointer qualifiers when eliminating reference types.
  • Add VariableExpr::functionPointer helper function to create variable expressions with function pointer type.
  • Change ConstructorExpr? translation so that it temporarily generates a 'fake' assignment operator rather than use UntypedExpr?, so that the correct transformations occur in the Lvalue pass. This is a hack that can be fixed once PassVisitor? properly supports Indexer.
File:
1 edited

Legend:

Unmodified
Added
Removed
  • src/InitTweak/FixInit.cc

    rd335627 r8a6cf7e  
    11821182                        ctorExpr->set_callExpr( nullptr );
    11831183                        ctorExpr->set_env( nullptr );
     1184                        delete ctorExpr;
    11841185
    11851186                        Expression *& firstArg = callExpr->get_args().front();
    1186                         UntypedExpr * assign = new UntypedExpr( new NameExpr( "?=?" ) );
    1187                         assign->get_args().push_back( new VariableExpr( tmp ) );
    1188                         assign->get_args().push_back( firstArg );
    1189                         assign->set_result( ctorExpr->get_result()->clone() );
    1190                         firstArg = assign;
    1191 
    1192                         CommaExpr * commaExpr = new CommaExpr( callExpr, new VariableExpr( tmp ) );
     1187
     1188                        // xxx - hack in 'fake' assignment operator until resolver can easily be called in this pass. Once the resolver can be used in PassVisitor, this hack goes away.
     1189
     1190                        // generate the type of assignment operator using the type of tmp minus any reference types
     1191                        Type * type = tmp->get_type()->stripReferences();
     1192                        FunctionType * ftype = SymTab::genAssignType( type );
     1193
     1194                        // generate fake assignment decl and call it using &tmp and &firstArg
     1195                        // since tmp is guaranteed to be a reference and we want to assign pointers
     1196                        FunctionDecl * assignDecl = new FunctionDecl( "?=?", Type::StorageClasses(), LinkageSpec::Intrinsic, ftype, nullptr );
     1197                        ApplicationExpr * assign = new ApplicationExpr( VariableExpr::functionPointer( assignDecl ) );
     1198                        assign->get_args().push_back( new AddressExpr( new VariableExpr( tmp ) ) );
     1199                        Expression * addrArg = new AddressExpr( firstArg );
     1200                        // if firstArg has type T&&, then &firstArg has type T*&.
     1201                        // Cast away the reference to a value type so that the argument
     1202                        // matches the assignment's parameter types
     1203                        if ( dynamic_cast<ReferenceType *>( addrArg->get_result() ) ) {
     1204                                addrArg = new CastExpr( addrArg, addrArg->get_result()->stripReferences()->clone() );
     1205                        }
     1206                        assign->get_args().push_back( addrArg );
     1207                        firstArg = new VariableExpr( tmp );
     1208
     1209                        // for constructor expr:
     1210                        //   T x;
     1211                        //   x{};
     1212                        // results in:
     1213                        //   T x;
     1214                        //   T & tmp;
     1215                        //   &tmp = &x, ?{}(tmp), tmp
     1216                        CommaExpr * commaExpr = new CommaExpr( assign, new CommaExpr( callExpr, new VariableExpr( tmp ) ) );
    11931217                        commaExpr->set_env( env );
    1194                         delete ctorExpr;
    11951218                        return commaExpr;
    11961219                }
Note: See TracChangeset for help on using the changeset viewer.