Changeset a32b204 for translator/GenPoly


Ignore:
Timestamp:
May 17, 2015, 1:19:35 PM (9 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, ctor, deferred_resn, demangler, enum, forall-pointer-decay, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, string, with_gc
Children:
0dd3a2f
Parents:
b87a5ed
Message:

licencing: second groups of files

Location:
translator/GenPoly
Files:
8 edited

Legend:

Unmodified
Added
Removed
  • translator/GenPoly/Box.cc

    rb87a5ed ra32b204  
    110110    void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {
    111111        for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
    112             if ( !LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
     112            if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
    113113                (*i)->print( os );
    114114                os << std::endl;
     
    135135        bool isPolyRet( FunctionType *function, std::string &name, const TyVarMap &otherTyVars ) {
    136136            bool doTransform = false;
    137             if ( !function->get_returnVals().empty() ) {
     137            if ( ! function->get_returnVals().empty() ) {
    138138                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType *>( function->get_returnVals().front()->get_type() ) ) {
    139139   
     
    146146                        } // if
    147147                    } // for
    148                     if ( !doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
     148                    if ( ! doTransform && otherTyVars.find( typeInst->get_name() ) != otherTyVars.end() ) {
    149149                        doTransform = true;
    150150                    } // if
     
    304304                ObjectDecl *newObj = makeTemporary( retType->clone() );
    305305                Expression *paramExpr = new VariableExpr( newObj );
    306                 if ( !isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
     306                if ( ! isPolyType( newObj->get_type(), env, scopeTyVars ) ) {
    307307                    paramExpr = new AddressExpr( paramExpr );
    308308                } // if
     
    330330        Expression *Pass1::applyAdapter( ApplicationExpr *appExpr, FunctionType *function, std::list< Expression *>::iterator &arg, const TyVarMap &tyVars ) {
    331331            Expression *ret = appExpr;
    332             if ( !function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
     332            if ( ! function->get_returnVals().empty() && isPolyVal( function->get_returnVals().front()->get_type(), tyVars ) ) {
    333333                ret = addRetParam( appExpr, function, function->get_returnVals().front()->get_type(), arg );
    334334            } // if
     
    343343
    344344        void Pass1::boxParam( Type *param, Expression *&arg, const TyVarMap &exprTyVars ) {
    345             assert( !arg->get_results().empty() );
    346 ///   if ( !dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
     345            assert( ! arg->get_results().empty() );
     346///   if ( ! dynamic_cast< PointerType *>( arg->get_results().front() ) ) {
    347347            TypeInstType *typeInst = dynamic_cast< TypeInstType *>( param );
    348348            if ( typeInst && exprTyVars.find( typeInst->get_name() ) != exprTyVars.end() ) {
     
    373373            // any function mentioning a polymorphic type
    374374            findAndReplaceFunction( newType, functions, tyVars, needsAdapter );
    375             if ( !functions.empty() ) {
     375            if ( ! functions.empty() ) {
    376376                actual = new CastExpr( actual, newType );
    377377            } else {
     
    422422            // actually make the adapter type
    423423            FunctionType *adapter = adaptee->clone();
    424             if ( !adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
     424            if ( ! adapter->get_returnVals().empty() && isPolyVal( adapter->get_returnVals().front()->get_type(), tyVars ) ) {
    425425                makeRetParm( adapter );
    426426            } // if
     
    611611                if ( varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic ) {
    612612                    if ( varExpr->get_var()->get_name() == "?[?]" ) {
    613                         assert( !appExpr->get_results().empty() );
     613                        assert( ! appExpr->get_results().empty() );
    614614                        assert( appExpr->get_args().size() == 2 );
    615615                        TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
    616616                        TypeInstType *typeInst2 = isPolyPtr( appExpr->get_args().back()->get_results().front(), env, scopeTyVars );
    617                         assert( !typeInst1 || !typeInst2 );
     617                        assert( ! typeInst1 || ! typeInst2 );
    618618                        UntypedExpr *ret = 0;
    619619                        if ( typeInst1 || typeInst2 ) {
     
    644644                        } // if
    645645                    } else if ( varExpr->get_var()->get_name() == "*?" ) {
    646                         assert( !appExpr->get_results().empty() );
    647                         assert( !appExpr->get_args().empty() );
     646                        assert( ! appExpr->get_results().empty() );
     647                        assert( ! appExpr->get_args().empty() );
    648648                        if ( isPolyType( appExpr->get_results().front(), env, scopeTyVars ) ) {
    649649                            Expression *ret = appExpr->get_args().front();
     
    659659                        } // if
    660660                    } else if ( varExpr->get_var()->get_name() == "?++" || varExpr->get_var()->get_name() == "?--" ) {
    661                         assert( !appExpr->get_results().empty() );
     661                        assert( ! appExpr->get_results().empty() );
    662662                        assert( appExpr->get_args().size() == 1 );
    663663                        if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
     
    679679                        } // if
    680680                    } else if ( varExpr->get_var()->get_name() == "++?" || varExpr->get_var()->get_name() == "--?" ) {
    681                         assert( !appExpr->get_results().empty() );
     681                        assert( ! appExpr->get_results().empty() );
    682682                        assert( appExpr->get_args().size() == 1 );
    683683                        if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
     
    685685                        } // if
    686686                    } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
    687                         assert( !appExpr->get_results().empty() );
     687                        assert( ! appExpr->get_results().empty() );
    688688                        assert( appExpr->get_args().size() == 2 );
    689689                        TypeInstType *typeInst1 = isPolyPtr( appExpr->get_args().front()->get_results().front(), env, scopeTyVars );
     
    711711                        } // if
    712712                    } else if ( varExpr->get_var()->get_name() == "?+=?" || varExpr->get_var()->get_name() == "?-=?" ) {
    713                         assert( !appExpr->get_results().empty() );
     713                        assert( ! appExpr->get_results().empty() );
    714714                        assert( appExpr->get_args().size() == 2 );
    715715                        TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars );
     
    739739            useRetval = oldUseRetval;
    740740 
    741             assert( !appExpr->get_function()->get_results().empty() );
     741            assert( ! appExpr->get_function()->get_results().empty() );
    742742            PointerType *pointer = dynamic_cast< PointerType *>( appExpr->get_function()->get_results().front() );
    743743            assert( pointer );
     
    784784
    785785        Expression *Pass1::mutate( UntypedExpr *expr ) {
    786             if ( !expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
     786            if ( ! expr->get_results().empty() && isPolyType( expr->get_results().front(), env, scopeTyVars ) ) {
    787787                if ( NameExpr *name = dynamic_cast< NameExpr *>( expr->get_function() ) ) {
    788788                    if ( name->get_name() == "*?" ) {
     
    798798
    799799        Expression *Pass1::mutate( AddressExpr *addrExpr ) {
    800             assert( !addrExpr->get_arg()->get_results().empty() );
     800            assert( ! addrExpr->get_arg()->get_results().empty() );
    801801            addrExpr->set_arg( mutateExpression( addrExpr->get_arg() ) );
    802802            if ( isPolyType( addrExpr->get_arg()->get_results().front(), env, scopeTyVars ) ) {
     
    823823            }
    824824            if ( retval && retStmt->get_expr() ) {
    825                 assert( !retStmt->get_expr()->get_results().empty() );
     825                assert( ! retStmt->get_expr()->get_results().empty() );
    826826                if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    827827///       retStmt->set_expr( mutateExpression( retStmt->get_expr() ) );
  • translator/GenPoly/CopyParams.cc

    rb87a5ed ra32b204  
    4646                    } // if
    4747                } // for
    48                 for( std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin(); param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
     48                for ( std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin(); param != funcDecl->get_functionType()->get_parameters().end(); ++param ) {
    4949                    std::set< UniqueId >::const_iterator var = modVars.find( (*param)->get_uniqueId() );
    5050                    if ( var != modVars.end() ) {
  • translator/GenPoly/FindFunction.cc

    rb87a5ed ra32b204  
    5252FindFunction::handleForall( const std::list< TypeDecl* > &forall )
    5353{
    54   for( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
     54  for ( std::list< TypeDecl* >::const_iterator i = forall.begin(); i != forall.end(); ++i ) {
    5555    TyVarMap::iterator var = tyVars.find( (*i)->get_name() );
    56     if( var != tyVars.end() ) {
     56    if ( var != tyVars.end() ) {
    5757      tyVars.erase( var );
    5858    }
     
    6767  mutateAll( functionType->get_returnVals(), *this );
    6868  Type *ret = functionType;
    69   if( predicate( functionType, tyVars ) ) {
     69  if ( predicate( functionType, tyVars ) ) {
    7070    functions.push_back( functionType );
    71     if( replaceMode ) {
     71    if ( replaceMode ) {
    7272      ret = new FunctionType( Type::Qualifiers(), true );
    7373    }
  • translator/GenPoly/GenPoly.cc

    rb87a5ed ra32b204  
    2626isPolyVal( Type *type, const TyVarMap &tyVars, bool considerAllTyVars )
    2727{
    28   if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
    29     if( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
     28  if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( type ) ) {
     29    if ( tyVars.find( typeInst->get_name() ) != tyVars.end() ) {
    3030      return true;
    3131    }
     
    4141{
    4242  bool needsAdapter = false;
    43   if( !adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars, considerAllTyVars ) ) {
     43  if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars, considerAllTyVars ) ) {
    4444    needsAdapter = true;
    4545  }
    46   for( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); !needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) {
    47     if( isPolyVal( (*innerArg)->get_type(), tyVars, considerAllTyVars ) ) {
     46  for ( std::list< DeclarationWithType* >::const_iterator innerArg = adaptee->get_parameters().begin(); ! needsAdapter && innerArg != adaptee->get_parameters().end(); ++innerArg ) {
     47    if ( isPolyVal( (*innerArg)->get_type(), tyVars, considerAllTyVars ) ) {
    4848      needsAdapter = true;
    4949    }
     
    5656printTyVarMap( std::ostream &os, const TyVarMap &tyVarMap )
    5757{
    58   for( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
     58  for ( TyVarMap::const_iterator i = tyVarMap.begin(); i != tyVarMap.end(); ++i ) {
    5959    os << i->first << " (" << i->second << ") ";
    6060  }
  • translator/GenPoly/Lvalue.cc

    rb87a5ed ra32b204  
    6767isLvalueRet( FunctionType *function )
    6868{
    69   if( !function->get_returnVals().empty() ) {
     69  if ( ! function->get_returnVals().empty() ) {
    7070    return function->get_returnVals().front()->get_type()->get_isLvalue();
    7171  } else {
     
    7777isIntrinsicApp( ApplicationExpr *appExpr )
    7878{
    79   if( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) {
     79  if ( VariableExpr *varExpr = dynamic_cast< VariableExpr* >( appExpr->get_function() ) ) {
    8080    return varExpr->get_var()->get_linkage() == LinkageSpec::Intrinsic;
    8181  } else {
     
    9191Pass1::mutate( FunctionDecl *funcDecl )
    9292{
    93   if( funcDecl->get_statements() ) {
     93  if ( funcDecl->get_statements() ) {
    9494    DeclarationWithType* oldRetval = retval;
    9595    retval = 0;
    96     if( !LinkageSpec::isBuiltin( funcDecl->get_linkage() ) && isLvalueRet( funcDecl->get_functionType() ) ) {
     96    if ( ! LinkageSpec::isBuiltin( funcDecl->get_linkage() ) && isLvalueRet( funcDecl->get_functionType() ) ) {
    9797      retval = funcDecl->get_functionType()->get_returnVals().front();
    9898    }
     
    110110  mutateAll( appExpr->get_args(), *this );
    111111 
    112   assert( !appExpr->get_function()->get_results().empty() );
     112  assert( ! appExpr->get_function()->get_results().empty() );
    113113
    114114  PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
     
    118118
    119119  std::string typeName;
    120   if( isLvalueRet( function ) && !isIntrinsicApp( appExpr ) ) {
     120  if ( isLvalueRet( function ) && ! isIntrinsicApp( appExpr ) ) {
    121121    UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) );
    122122    deref->get_results().push_back( appExpr->get_results().front() );
     
    132132Pass1::mutate(ReturnStmt *retStmt)
    133133{
    134   if( retval && retStmt->get_expr() ) {
    135     assert( !retStmt->get_expr()->get_results().empty() );
    136     while( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
     134  if ( retval && retStmt->get_expr() ) {
     135    assert( ! retStmt->get_expr()->get_results().empty() );
     136    while ( CastExpr *castExpr = dynamic_cast< CastExpr* >( retStmt->get_expr() ) ) {
    137137      retStmt->set_expr( castExpr->get_arg() );
    138138      retStmt->get_expr()->set_env( castExpr->get_env() );
     
    141141      delete castExpr;
    142142    }
    143     if( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
     143    if ( retStmt->get_expr()->get_results().front()->get_isLvalue() ) {
    144144      retStmt->set_expr( new AddressExpr( retStmt->get_expr()->acceptMutator( *this ) ) );
    145145    } else {
     
    154154{
    155155  std::string typeName;
    156   if( isLvalueRet( funType ) ) {
     156  if ( isLvalueRet( funType ) ) {
    157157    DeclarationWithType *retParm = funType->get_returnVals().front();
    158158   
  • translator/GenPoly/PolyMutator.cc

    rb87a5ed ra32b204  
    2828PolyMutator::mutateStatementList( std::list< Statement* > &statements )
    2929{
    30   for( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
    31     if( !stmtsToAddAfter.empty() ) {
     30  for ( std::list< Statement* >::iterator i = statements.begin(); i != statements.end(); ++i ) {
     31    if ( ! stmtsToAddAfter.empty() ) {
    3232      statements.splice( i, stmtsToAddAfter );
    3333    }
    3434    *i = (*i)->acceptMutator( *this );
    35     if( !stmtsToAdd.empty() ) {
     35    if ( ! stmtsToAdd.empty() ) {
    3636      statements.splice( i, stmtsToAdd );
    3737    }
    3838  }
    39   if( !stmtsToAddAfter.empty() ) {
     39  if ( ! stmtsToAddAfter.empty() ) {
    4040    statements.splice( statements.end(), stmtsToAddAfter );
    4141  }
     
    4646{
    4747  Statement *newStmt = maybeMutate( stmt, *this );
    48   if( !stmtsToAdd.empty() || !stmtsToAddAfter.empty() ) {
     48  if ( ! stmtsToAdd.empty() || ! stmtsToAddAfter.empty() ) {
    4949    CompoundStmt *compound = new CompoundStmt( noLabels );
    5050    compound->get_kids().splice( compound->get_kids().end(), stmtsToAdd );
     
    6161PolyMutator::mutateExpression( Expression *expr )
    6262{
    63   if( expr ) {
    64     if( expr->get_env() ) {
     63  if ( expr ) {
     64    if ( expr->get_env() ) {
    6565      env = expr->get_env();
    6666    }
     
    167167PolyMutator::mutate(UntypedExpr *untypedExpr)
    168168{
    169   for( std::list< Expression* >::iterator i = untypedExpr->get_args().begin(); i != untypedExpr->get_args().end(); ++i ) {
     169  for ( std::list< Expression* >::iterator i = untypedExpr->get_args().begin(); i != untypedExpr->get_args().end(); ++i ) {
    170170    *i = mutateExpression( *i );
    171171  }
     
    177177PolyMutator::makeTyVarMap( Type *type, TyVarMap &tyVarMap )
    178178{
    179   for( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
     179  for ( std::list< TypeDecl* >::const_iterator tyVar = type->get_forall().begin(); tyVar != type->get_forall().end(); ++tyVar ) {
    180180    assert( *tyVar );
    181181    tyVarMap[ (*tyVar)->get_name() ] = (*tyVar)->get_kind();
    182182  }
    183   if( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
     183  if ( PointerType *pointer = dynamic_cast< PointerType* >( type ) ) {
    184184    makeTyVarMap( pointer->get_base(), tyVarMap );
    185185  }
  • translator/GenPoly/ScrubTyVars.cc

    rb87a5ed ra32b204  
    1111        TyVarMap::const_iterator tyVar = tyVars.find( typeInst->get_name() );
    1212        if ( doAll || tyVar != tyVars.end() ) {
    13             switch( tyVar->second ) {
     13            switch ( tyVar->second ) {
    1414              case TypeDecl::Any:
    1515              case TypeDecl::Dtype:
  • translator/GenPoly/Specialize.cc

    rb87a5ed ra32b204  
    6161needsSpecialization( Type *formalType, Type *actualType, TypeSubstitution *env )
    6262{
    63   if( env ) {
     63  if ( env ) {
    6464    using namespace ResolvExpr;
    6565    OpenVarSet openVars, closedVars;
     
    6767    findOpenVars( formalType, openVars, closedVars, need, have, false );
    6868    findOpenVars( actualType, openVars, closedVars, need, have, true );
    69     for( OpenVarSet::const_iterator openVar = openVars.begin(); openVar != openVars.end(); ++openVar ) {
     69    for ( OpenVarSet::const_iterator openVar = openVars.begin(); openVar != openVars.end(); ++openVar ) {
    7070      Type *boundType = env->lookup( openVar->first );
    71       if( !boundType ) continue;
    72       if( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) {
    73         if( closedVars.find( typeInst->get_name() ) == closedVars.end() ) {
     71      if ( ! boundType ) continue;
     72      if ( TypeInstType *typeInst = dynamic_cast< TypeInstType* >( boundType ) ) {
     73        if ( closedVars.find( typeInst->get_name() ) == closedVars.end() ) {
    7474          return true;
    7575        }
     
    8787Specialize::doSpecialization( Type *formalType, Expression *actual, InferredParams *inferParams )
    8888{
    89   if( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
     89  if ( needsSpecialization( formalType, actual->get_results().front(), env ) ) {
    9090    PointerType *ptrType;
    9191    FunctionType *funType;
    92     if( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) {
     92    if ( ( ptrType = dynamic_cast< PointerType* >( formalType ) ) && ( funType = dynamic_cast< FunctionType* >( ptrType->get_base() ) ) ) {
    9393      FunctionType *newType = funType->clone();
    94       if( env ) {
     94      if ( env ) {
    9595        TypeSubstitution newEnv( *env );
    9696        // it is important to replace only occurrences of type variables that occur free in the
     
    103103      UniqueName paramNamer( paramPrefix );
    104104      ApplicationExpr *appExpr = new ApplicationExpr( actual );
    105       for( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {
     105      for ( std::list< DeclarationWithType* >::iterator param = thunkFunc->get_functionType()->get_parameters().begin(); param != thunkFunc->get_functionType()->get_parameters().end(); ++param ) {
    106106        (*param)->set_name( paramNamer.newName() );
    107107        appExpr->get_args().push_back( new VariableExpr( *param ) );
    108108      }
    109109      appExpr->set_env( maybeClone( env ) );
    110       if( inferParams ) {
     110      if ( inferParams ) {
    111111        appExpr->get_inferParams() = *inferParams;
    112112      }
     
    123123     
    124124      Statement *appStmt;
    125       if( funType->get_returnVals().empty() ) {
     125      if ( funType->get_returnVals().empty() ) {
    126126        appStmt = new ExprStmt( noLabels, appExpr );
    127127      } else {
     
    143143{
    144144  // create thunks for the explicit parameters
    145   assert( !appExpr->get_function()->get_results().empty() );
     145  assert( ! appExpr->get_function()->get_results().empty() );
    146146  PointerType *pointer = dynamic_cast< PointerType* >( appExpr->get_function()->get_results().front() );
    147147  assert( pointer );
     
    149149  std::list< DeclarationWithType* >::iterator formal;
    150150  std::list< Expression* >::iterator actual;
    151   for( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
     151  for ( formal = function->get_parameters().begin(), actual = appExpr->get_args().begin(); formal != function->get_parameters().end() && actual != appExpr->get_args().end(); ++formal, ++actual ) {
    152152    *actual = doSpecialization( (*formal)->get_type(), *actual, &appExpr->get_inferParams() );
    153153  }
     
    161161 
    162162  // create thunks for the inferred parameters
    163   for( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
     163  for ( InferredParams::iterator inferParam = appExpr->get_inferParams().begin(); inferParam != appExpr->get_inferParams().end(); ++inferParam ) {
    164164    inferParam->second.expr = doSpecialization( inferParam->second.formalType, inferParam->second.expr, &appExpr->get_inferParams() );
    165165  }
Note: See TracChangeset for help on using the changeset viewer.