Changeset 4389966


Ignore:
Timestamp:
Dec 15, 2015, 4:14:01 PM (6 years ago)
Author:
Peter A. Buhr <pabuhr@…>
Branches:
aaron-thesis, arm-eh, cleanup-dtors, ctor, deferred_resn, demangler, gc_noraii, jacob/cs343-translation, jenkins-sandbox, master, memory, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, resolv-new, string, with_gc
Children:
5f6c42c
Parents:
cf16f94 (diff), 78dd0da (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.
Message:

fix comment

Location:
src
Files:
1 deleted
26 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rcf16f94 r4389966  
    442442                output << ")";
    443443        }
     444
     445        void CodeGenerator::visit( AlignofExpr *sizeofExpr ) {
     446                // use GCC extension to avoid bumping std to C11
     447                output << "__alignof__(";
     448                if ( sizeofExpr->get_isType() ) {
     449                        output << genType( sizeofExpr->get_type(), "" );
     450                } else {
     451                        sizeofExpr->get_expr()->accept( *this );
     452                } // if
     453                output << ")";
     454        }
    444455 
    445456        void CodeGenerator::visit( LogicalExpr *logicalExpr ) {
  • src/CodeGen/CodeGenerator.h

    rcf16f94 r4389966  
    6060                virtual void visit( ConstantExpr *constantExpr );
    6161                virtual void visit( SizeofExpr *sizeofExpr );
     62                virtual void visit( AlignofExpr *alignofExpr );
    6263                virtual void visit( LogicalExpr *logicalExpr );
    6364                virtual void visit( ConditionalExpr *conditionalExpr );
  • src/GenPoly/Box.cc

    rcf16f94 r4389966  
    2828#include "Parser/ParseNode.h"
    2929
     30#include "SynTree/Constant.h"
    3031#include "SynTree/Type.h"
    3132#include "SynTree/Expression.h"
     
    5051                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    5152
     53                /// Replaces polymorphic return types with out-parameters, replaces calls to polymorphic functions with adapter calls as needed, and adds appropriate type variables to the function call
    5254                class Pass1 : public PolyMutator {
    5355                  public:
     
    8890                };
    8991
     92                /// Moves polymorphic returns in function types to pointer-type parameters, adds type size and assertion parameters to parameter lists as well
    9093                class Pass2 : public PolyMutator {
    9194                  public:
    92                         Pass2();
    9395                        template< typename DeclClass >
    9496                        DeclClass *handleDecl( DeclClass *decl, Type *type );
     
    105107                };
    106108
     109                /// Replaces initialization of polymorphic values with alloca, declaration of dtype/ftype with appropriate void expression, and sizeof expressions of polymorphic types with the proper variable
    107110                class Pass3 : public PolyMutator {
    108111                  public:
     
    178181                }
    179182
    180                 Pass1::Pass1()
    181                         : useRetval( false ), tempNamer( "_temp" ) {
     183                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
    182184                        adapters.push(AdapterMap());
    183185                }
     
    312314                                        if ( concrete ) {
    313315                                                arg = appExpr->get_args().insert( arg, new SizeofExpr( concrete->clone() ) );
     316                                                arg++;
     317                                                arg = appExpr->get_args().insert( arg, new AlignofExpr( concrete->clone() ) );
    314318                                                arg++;
    315319                                        } else {
     
    647651                }
    648652
    649                 Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, std::string polyName, bool isIncr ) {
     653                Expression *makeIncrDecrExpr( ApplicationExpr *appExpr, Type *polyType, bool isIncr ) {
    650654                        NameExpr *opExpr;
    651655                        if ( isIncr ) {
     
    660664                                addAssign->get_args().push_back( appExpr->get_args().front() );
    661665                        } // if
    662                         addAssign->get_args().push_back( new NameExpr( polyName ) );
     666                        addAssign->get_args().push_back( new NameExpr( sizeofName( polyType ) ) );
    663667                        addAssign->get_results().front() = appExpr->get_results().front()->clone();
    664668                        if ( appExpr->get_env() ) {
     
    687691                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    688692                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    689                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     693                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
    690694                                                        ret->get_args().push_back( appExpr->get_args().front() );
    691695                                                        ret->get_args().push_back( multiply );
     
    693697                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    694698                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    695                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     699                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) );
    696700                                                        ret->get_args().push_back( multiply );
    697701                                                        ret->get_args().push_back( appExpr->get_args().back() );
     
    739743                                                                assignExpr->get_args().push_back( appExpr->get_args().front()->clone() );
    740744                                                        } // if
    741                                                         CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "?++" ) );
     745                                                        CommaExpr *firstComma = new CommaExpr( assignExpr, makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "?++" ) );
    742746                                                        return new CommaExpr( firstComma, tempExpr );
    743747                                                } // if
     
    746750                                                assert( appExpr->get_args().size() == 1 );
    747751                                                if ( TypeInstType *typeInst = isPolyPtr( appExpr->get_results().front(), env, scopeTyVars ) ) {
    748                                                         return makeIncrDecrExpr( appExpr, typeInst->get_name(), varExpr->get_var()->get_name() == "++?" );
     752                                                        return makeIncrDecrExpr( appExpr, typeInst, varExpr->get_var()->get_name() == "++?" );
    749753                                                } // if
    750754                                        } else if ( varExpr->get_var()->get_name() == "?+?" || varExpr->get_var()->get_name() == "?-?" ) {
     
    756760                                                        UntypedExpr *divide = new UntypedExpr( new NameExpr( "?/?" ) );
    757761                                                        divide->get_args().push_back( appExpr );
    758                                                         divide->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     762                                                        divide->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
    759763                                                        divide->get_results().push_front( appExpr->get_results().front()->clone() );
    760764                                                        if ( appExpr->get_env() ) {
     
    766770                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    767771                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    768                                                         multiply->get_args().push_back( new NameExpr( typeInst1->get_name() ) );
     772                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst1 ) ) );
    769773                                                        appExpr->get_args().back() = multiply;
    770774                                                } else if ( typeInst2 ) {
    771775                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    772776                                                        multiply->get_args().push_back( appExpr->get_args().front() );
    773                                                         multiply->get_args().push_back( new NameExpr( typeInst2->get_name() ) );
     777                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst2 ) ) );
    774778                                                        appExpr->get_args().front() = multiply;
    775779                                                } // if
     
    781785                                                        UntypedExpr *multiply = new UntypedExpr( new NameExpr( "?*?" ) );
    782786                                                        multiply->get_args().push_back( appExpr->get_args().back() );
    783                                                         multiply->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     787                                                        multiply->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) );
    784788                                                        appExpr->get_args().back() = multiply;
    785789                                                } // if
     
    963967////////////////////////////////////////// Pass2 ////////////////////////////////////////////////////
    964968
    965                 Pass2::Pass2() {}
    966 
    967969                void Pass2::addAdapters( FunctionType *functionType ) {
    968970                        std::list< DeclarationWithType *> &paramList = functionType->get_parameters();
     
    10371039                        std::list< DeclarationWithType *>::iterator last = funcType->get_parameters().begin();
    10381040                        std::list< DeclarationWithType *> inferredParams;
    1039                         ObjectDecl *newObj = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
    1040 ///   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
     1041                        ObjectDecl newObj( "", DeclarationNode::NoStorageClass, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), 0 );
     1042//   ObjectDecl *newFunPtr = new ObjectDecl( "", DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, new PointerType( Type::Qualifiers(), new FunctionType( Type::Qualifiers(), true ) ), 0 );
    10411043                        for ( std::list< TypeDecl *>::const_iterator tyParm = funcType->get_forall().begin(); tyParm != funcType->get_forall().end(); ++tyParm ) {
    1042                                 ObjectDecl *thisParm;
    1043                                 // add all size parameters to parameter list
     1044                                ObjectDecl *sizeParm, *alignParm;
     1045                                // add all size and alignment parameters to parameter list
    10441046                                if ( (*tyParm)->get_kind() == TypeDecl::Any ) {
    1045                                         thisParm = newObj->clone();
    1046                                         thisParm->set_name( (*tyParm)->get_name() );
    1047                                         last = funcType->get_parameters().insert( last, thisParm );
     1047                                        TypeInstType parmType( Type::Qualifiers(), (*tyParm)->get_name(), *tyParm );
     1048                                       
     1049                                        sizeParm = newObj.clone();
     1050                                        sizeParm->set_name( sizeofName( &parmType ) );
     1051                                        last = funcType->get_parameters().insert( last, sizeParm );
     1052                                        ++last;
     1053
     1054                                        alignParm = newObj.clone();
     1055                                        alignParm->set_name( alignofName( &parmType ) );
     1056                                        last = funcType->get_parameters().insert( last, alignParm );
    10481057                                        ++last;
    10491058                                }
    10501059                                // move all assertions into parameter list
    10511060                                for ( std::list< DeclarationWithType *>::iterator assert = (*tyParm)->get_assertions().begin(); assert != (*tyParm)->get_assertions().end(); ++assert ) {
    1052 ///      *assert = (*assert)->acceptMutator( *this );
     1061//      *assert = (*assert)->acceptMutator( *this );
    10531062                                        inferredParams.push_back( *assert );
    10541063                                }
    10551064                                (*tyParm)->get_assertions().clear();
    10561065                        }
    1057                         delete newObj;
    10581066                        funcType->get_parameters().splice( last, inferredParams );
    10591067                        addAdapters( funcType );
     
    10921100
    10931101                TypeDecl * Pass3::mutate( TypeDecl *typeDecl ) {
    1094 ///   Initializer *init = 0;
    1095 ///   std::list< Expression *> designators;
    1096 ///   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
    1097 ///   if ( typeDecl->get_base() ) {
    1098 ///     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
    1099 ///   }
    1100 ///   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
     1102//   Initializer *init = 0;
     1103//   std::list< Expression *> designators;
     1104//   scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     1105//   if ( typeDecl->get_base() ) {
     1106//     init = new SimpleInit( new SizeofExpr( handleDecl( typeDecl, typeDecl->get_base() ) ), designators );
     1107//   }
     1108//   return new ObjectDecl( typeDecl->get_name(), Declaration::Extern, LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ), init );
    11011109
    11021110                        scopeTyVars[ typeDecl->get_name() ] = typeDecl->get_kind();
     
    11311139                                        assert( typeInst );
    11321140                                        UntypedExpr *alloc = new UntypedExpr( new NameExpr( "__builtin_alloca" ) );
    1133                                         alloc->get_args().push_back( new NameExpr( typeInst->get_name() ) );
     1141                                        alloc->get_args().push_back( new NameExpr( sizeofName( typeInst ) ) );
    11341142
    11351143                                        delete objectDecl->get_init();
  • src/GenPoly/FindFunction.h

    rcf16f94 r4389966  
    2323        typedef bool (*FindFunctionPredicate)( FunctionType*, const TyVarMap& );
    2424
     25        /// recursively walk `type`, placing all functions that match `predicate` under `tyVars` into `functions`
    2526        void findFunction( Type *type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
     27        /// like `findFunction`, but also replaces the function type with void ()(void)
    2628        void findAndReplaceFunction( Type *&type, std::list< FunctionType* > &functions, const TyVarMap &tyVars, FindFunctionPredicate predicate );
    2729} // namespace GenPoly
  • src/GenPoly/GenPoly.cc

    rcf16f94 r4389966  
    1010// Created On       : Mon May 18 07:44:20 2015
    1111// Last Modified By : Peter A. Buhr
    12 // Last Modified On : Tue Dec  1 15:18:54 2015
    13 // Update Count     : 12
     12// Last Modified On : Tue Dec 15 16:11:18 2015
     13// Update Count     : 13
    1414//
    1515
     
    2121
    2222namespace GenPoly {
    23         // A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type
     23        /// A function needs an adapter if it returns a polymorphic value or if any of its parameters have polymorphic type
    2424        bool needsAdapter( FunctionType *adaptee, const TyVarMap &tyVars ) {
    2525                if ( ! adaptee->get_returnVals().empty() && isPolyVal( adaptee->get_returnVals().front()->get_type(), tyVars ) ) {
  • src/GenPoly/InstantiateGeneric.cc

    rcf16f94 r4389966  
    4444                ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    4545
    46                 /// Extracts types from a list of Expression* (which should be TypeExpr*)
    47                 ConcreteType(AggregateDecl *_base, const std::list< Expression* >& _params) : base(_base), params() {
    48                         for ( std::list< Expression* >::const_iterator it = _params.begin(); it != _params.end(); ++it ) {
    49                                 TypeExpr *param = dynamic_cast< TypeExpr* >(*it);
    50                                 assert(param && "Aggregate parameters should be type expressions");
    51                                 params.push_back( param->get_type()->clone() );
     46                /// Extracts types from a list of TypeExpr*
     47                ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
     48                        for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
     49                                params.push_back( (*param)->get_type()->clone() );
    5250                        }
    5351                }
     
    6664
    6765                bool operator== (const ConcreteType& that) const {
     66                        if ( base != that.base ) return false;
     67
    6868                        SymTab::Indexer dummy;
    69 
    70                         if ( base != that.base ) return false;
    7169                        if ( params.size() != that.params.size() ) return false;
    7270                        for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
     
    7977                std::list< Type* > params;  ///< Instantiation parameters
    8078        };
    81 
     79       
    8280        /// Maps a concrete type to the instantiated struct type, accounting for scope
    8381        class InstantiationMap {
    84                 /// Pair of concrete type and declaration that instantiates it
    85                 typedef std::pair< ConcreteType, AggregateDecl* > Instantiation;
     82                /// Instantiation of a generic type, with key information to find it
     83                struct Instantiation {
     84                        ConcreteType key;     ///< Instantiation parameters for this type
     85                        AggregateDecl *decl;  ///< Declaration of the instantiated generic type
     86
     87                        Instantiation() : key(), decl(0) {}
     88                        Instantiation(const ConcreteType &_key, AggregateDecl *_decl) : key(_key), decl(_decl) {}
     89                };
    8690                /// Map of generic types to instantiations of them
    8791                typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
     
    107111                /// Gets the declaration for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
    108112                /// Returns NULL on none such.
    109                 AggregateDecl* lookup( AggregateDecl *generic, std::list< Expression* >& params ) {
     113                AggregateDecl* lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
    110114                        ConcreteType key(generic, params);
    111115                        // scan scopes from innermost out
     
    116120                                // look through instantiations for matches to concrete type
    117121                                for ( std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
    118                                         if ( inst->first == key ) return inst->second;
     122                                        if ( inst->key == key ) return inst->decl;
    119123                                }
    120124                        }
     
    123127                }
    124128        public:
    125                 StructDecl* lookup( StructInstType *inst ) { return (StructDecl*)lookup( inst->get_baseStruct(), inst->get_parameters() ); }
    126                 UnionDecl* lookup( UnionInstType *inst ) { return (UnionDecl*)lookup( inst->get_baseUnion(), inst->get_parameters() ); }
     129                StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
     130                UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
    127131
    128132        private:
    129133                /// Adds a declaration for a concrete type to the current scope
    130                 void insert( AggregateDecl *generic, std::list< Expression* >& params, AggregateDecl *decl ) {
     134                void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, AggregateDecl *decl ) {
    131135                        ConcreteType key(generic, params);
    132                         scopes.back()[generic].push_back( std::make_pair( key, decl ) );
     136                        scopes.back()[generic].push_back( Instantiation( key, decl ) );
    133137                }
    134138        public:
    135                 void insert( StructInstType *inst, StructDecl *decl ) { insert( inst->get_baseStruct(), inst->get_parameters(), decl ); }
    136                 void insert( UnionInstType *inst, UnionDecl *decl ) { insert( inst->get_baseUnion(), inst->get_parameters(), decl ); }
     139                void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
     140                void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
    137141        };
    138142
    139143        /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    140144        class Instantiate : public DeclMutator {
     145                /// Map of (generic type, parameter list) pairs to concrete type instantiations
    141146                InstantiationMap instantiations;
     147                /// Namer for concrete types
    142148                UniqueName typeNamer;
    143149
     
    147153                virtual Type* mutate( StructInstType *inst );
    148154                virtual Type* mutate( UnionInstType *inst );
     155
     156//              virtual Expression* mutate( MemberExpr *memberExpr );
    149157               
    150158                virtual void doBeginScope();
     
    157165        }
    158166
    159         /// Substitutes types of members of in according to baseParams => params, appending the result to out
    160         void substituteMembers( const std::list< Declaration* >& in,
    161                                                         const std::list< TypeDecl * >& baseParams, const std::list< Expression* >& params,
     167        /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
     168        bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
     169                bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
     170
     171                // substitute concrete types for given parameters, and incomplete types for placeholders
     172                std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
     173                std::list< Expression* >::const_iterator param = params.begin();
     174                for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
     175//                      switch ( (*baseParam)->get_kind() ) {
     176//                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
     177                                TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
     178                                assert(paramType && "Aggregate parameters should be type expressions");
     179                                out.push_back( paramType->clone() );
     180                                // check that the substituted type isn't a type variable itself
     181                                if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
     182                                        allConcrete = false;
     183                                }
     184//                              break;
     185//                      }
     186//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     187//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     188//                              break;
     189//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     190//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     191//                              break;
     192//                      }
     193                }
     194
     195                // if any parameters left over, not done
     196                if ( baseParam != baseParams.end() ) return false;
     197//              // if not enough parameters given, substitute remaining incomplete types for placeholders
     198//              for ( ; baseParam != baseParams.end(); ++baseParam ) {
     199//                      switch ( (*baseParam)->get_kind() ) {
     200//                      case TypeDecl::Any:    // no more substitutions here, fail early
     201//                              return false;
     202//                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
     203//                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
     204//                              break;
     205//                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
     206//                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
     207//                              break;
     208//                      }
     209//              }
     210
     211                return allConcrete;
     212        }
     213
     214        /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
     215        void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    162216                                                    std::list< Declaration* >& out ) {
    163217                // substitute types into new members
    164                 TypeSubstitution subs( baseParams.begin(), baseParams.end(), params.begin() );
     218                TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    165219                for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    166220                        Declaration *newMember = (*member)->clone();
     
    178232                // exit early if no need for further mutation
    179233                if ( inst->get_parameters().empty() ) return inst;
     234                assert( inst->get_baseParameters() && "Base struct has parameters" );
     235
     236                // check if type can be concretely instantiated; put substitutions into typeSubs
     237                std::list< TypeExpr* > typeSubs;
     238                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     239                        deleteAll( typeSubs );
     240                        return inst;
     241                }
    180242               
    181243                // make concrete instantiation of generic type
    182                 StructDecl *concDecl = instantiations.lookup( inst );
     244                StructDecl *concDecl = instantiations.lookup( inst, typeSubs );
    183245                if ( ! concDecl ) {
    184                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    185246                        // set concDecl to new type, insert type declaration into statements to add
    186247                        concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    187                         substituteMembers( inst->get_baseStruct()->get_members(),
    188                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    189                                                                 concDecl->get_members() );
     248                        substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
    190249                        DeclMutator::addDeclaration( concDecl );
    191                         instantiations.insert( inst, concDecl );
     250                        instantiations.insert( inst, typeSubs, concDecl );
    192251                }
    193252                StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    194253                newInst->set_baseStruct( concDecl );
     254
     255                deleteAll( typeSubs );
    195256                delete inst;
    196257                return newInst;
     
    205266                // exit early if no need for further mutation
    206267                if ( inst->get_parameters().empty() ) return inst;
    207 
     268                assert( inst->get_baseParameters() && "Base union has parameters" );
     269
     270                // check if type can be concretely instantiated; put substitutions into typeSubs
     271                std::list< TypeExpr* > typeSubs;
     272                if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
     273                        deleteAll( typeSubs );
     274                        return inst;
     275                }
     276               
    208277                // make concrete instantiation of generic type
    209                 UnionDecl *concDecl = instantiations.lookup( inst );
     278                UnionDecl *concDecl = instantiations.lookup( inst, typeSubs );
    210279                if ( ! concDecl ) {
    211280                        // set concDecl to new type, insert type declaration into statements to add
    212                         assert( inst->get_baseParameters() && "Base union has parameters" );
    213281                        concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    214                         substituteMembers( inst->get_baseUnion()->get_members(),
    215                                                                 *inst->get_baseParameters(), inst->get_parameters(),
    216                                                                 concDecl->get_members() );
     282                        substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    217283                        DeclMutator::addDeclaration( concDecl );
    218                         instantiations.insert( inst, concDecl );
     284                        instantiations.insert( inst, typeSubs, concDecl );
    219285                }
    220286                UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    221287                newInst->set_baseUnion( concDecl );
     288
     289                deleteAll( typeSubs );
    222290                delete inst;
    223291                return newInst;
    224292        }
     293
     294//      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
     295//      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
     296//              // get variable for member aggregate
     297//              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
     298//              if ( ! varExpr ) return NULL;
     299//
     300//              // get object for variable
     301//              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
     302//              if ( ! objectDecl ) return NULL;
     303//
     304//              // get base declaration from object type
     305//              Type *objectType = objectDecl->get_type();
     306//              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
     307//              if ( structType ) return structType->get_baseStruct();
     308//              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
     309//              if ( unionType ) return unionType->get_baseUnion();
     310//
     311//              return NULL;
     312//      }
     313//
     314//      /// Finds the declaration with the given name, returning decls.end() if none such
     315//      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
     316//              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
     317//                      if ( (*decl)->get_name() == name ) return decl;
     318//              }
     319//              return decls.end();
     320//      }
     321//     
     322//      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
     323//              // mutate, exiting early if no longer MemberExpr
     324//              Expression *expr = Mutator::mutate( memberExpr );
     325//              memberExpr = dynamic_cast< MemberExpr* >( expr );
     326//              if ( ! memberExpr ) return expr;
     327//
     328//              // get declaration of member and base declaration of member, exiting early if not found
     329//              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
     330//              if ( ! memberBase ) return memberExpr;
     331//              DeclarationWithType *memberDecl = memberExpr->get_member();
     332//              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
     333//              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
     334//              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
     335//              if ( ! baseDecl ) return memberExpr;
     336//
     337//              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
     338//              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
     339//              SymTab::Indexer dummy;
     340//              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
     341//              else return new CastExpr( memberExpr, memberDecl->get_type() );
     342//      }
    225343       
    226344        void Instantiate::doBeginScope() {
    227345                DeclMutator::doBeginScope();
    228                 // push a new concrete type scope
    229346                instantiations.beginScope();
    230347        }
     
    232349        void Instantiate::doEndScope() {
    233350                DeclMutator::doEndScope();
    234                 // pop the last concrete type scope
    235351                instantiations.endScope();
    236352        }
  • src/GenPoly/Lvalue.cc

    rcf16f94 r4389966  
    3535                const std::list<Label> noLabels;
    3636
     37                /// Replace uses of lvalue returns with appropriate pointers
    3738                class Pass1 : public Mutator {
    3839                  public:
     
    4647                };
    4748
     49                /// Replace declarations of lvalue returns with appropriate pointers
    4850                class Pass2 : public Visitor {
    4951                  public:
  • src/GenPoly/ScrubTyVars.cc

    rcf16f94 r4389966  
    1414//
    1515
     16#include <sstream>
     17#include <string>
     18
    1619#include "GenPoly.h"
    1720#include "ScrubTyVars.h"
     21
     22#include "SymTab/Mangler.h"
    1823
    1924#include "SynTree/Mutator.h"
     
    4247
    4348        Expression * ScrubTyVars::mutate( SizeofExpr *szeof ) {
    44                 // sizeof( T ) => T parameter, which is the size of T
     49                // sizeof( T ) => _sizeof_T parameter, which is the size of T
    4550                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( szeof->get_type() ) ) {
    46                         Expression *expr = new NameExpr( typeInst->get_name() );
     51                        Expression *expr = new NameExpr( sizeofName( typeInst ) );
    4752                        return expr;
    4853                } else {
    4954                        return Mutator::mutate( szeof );
     55                } // if
     56        }
     57
     58        Expression * ScrubTyVars::mutate( AlignofExpr *algnof ) {
     59                // alignof( T ) => _alignof_T parameter, which is the alignment of T
     60                if ( TypeInstType *typeInst = dynamic_cast< TypeInstType * >( algnof->get_type() ) ) {
     61                        Expression *expr = new NameExpr( alignofName( typeInst ) );
     62                        return expr;
     63                } else {
     64                        return Mutator::mutate( algnof );
    5065                } // if
    5166        }
     
    6378                return Mutator::mutate( pointer );
    6479        }
     80       
     81        std::string sizeofName( Type *ty ) {
     82                return std::string( "_sizeof_" ) + SymTab::Mangler::mangle( ty, false, false );
     83        }
     84
     85        std::string alignofName( Type *ty ) {
     86                return std::string( "_alignof_" ) + SymTab::Mangler::mangle( ty, false, false );
     87        }
    6588} // namespace GenPoly
    6689
  • src/GenPoly/ScrubTyVars.h

    rcf16f94 r4389966  
    1717#define _SCRUBTYVARS_H
    1818
     19#include <string>
     20
    1921#include "GenPoly.h"
    2022
     
    2628          public:
    2729                ScrubTyVars( bool doAll, const TyVarMap &tyVars ): doAll( doAll ), tyVars( tyVars ) {}
    28  
     30
     31                /// Like scrub( SynTreeClass* ), but only applies to type variables in `tyVars`
    2932                template< typename SynTreeClass >
    3033                static SynTreeClass *scrub( SynTreeClass *target, const TyVarMap &tyVars );
     34                /// Replaces dtypes and ftypes with the appropriate void type, and sizeof expressions of polymorphic types with the proper variable
    3135                template< typename SynTreeClass >
    3236                static SynTreeClass *scrub( SynTreeClass *target );
     
    3438                virtual Type* mutate( TypeInstType *typeInst );
    3539                Expression* mutate( SizeofExpr *szeof );
     40                Expression* mutate( AlignofExpr *algnof );
    3641                virtual Type* mutate( PointerType *pointer );
    3742          private:
     
    5459                return static_cast< SynTreeClass* >( target->acceptMutator( scrubber ) );
    5560        }
     61
     62        /// Gets the name of the sizeof parameter for the type
     63        std::string sizeofName( Type *ty );
     64
     65        /// Gets the name of the alignof parameter for the type
     66        std::string alignofName( Type *ty );
    5667} // namespace GenPoly
    5768
  • src/InitTweak/InitModel.h

    rcf16f94 r4389966  
    7272                        void visit( ConstantExpr * );
    7373                        void visit( SizeofExpr * ) { throw 0; }
     74                        void visit( AlignofExpr * ) { throw 0; }
    7475                        void visit( AttrExpr * ) { throw 0; }
    7576                        void visit( LogicalExpr * ) { throw 0; }
  • src/Parser/ExpressionNode.cc

    rcf16f94 r4389966  
    586586                }
    587587          case OperatorNode::AlignOf:
     588                {
     589                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
     590                                return new AlignofExpr( arg->get_decl()->buildType());
     591                        } else {
     592                                return new AlignofExpr( args.front());
     593                        } // if
     594                }
    588595          case OperatorNode::SizeOf:
    589596                {
    590 ///     bool isSizeOf = ( op->get_type() == OperatorNode::SizeOf );
    591 
    592597                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args()) ) {
    593598                                return new SizeofExpr( arg->get_decl()->buildType());
  • src/ResolvExpr/AlternativeFinder.cc

    rcf16f94 r4389966  
    792792        }
    793793
     794        void AlternativeFinder::visit( AlignofExpr *alignofExpr ) {
     795                if ( alignofExpr->get_isType() ) {
     796                        alternatives.push_back( Alternative( alignofExpr->clone(), env, Cost::zero ) );
     797                } else {
     798                        // find all alternatives for the argument to sizeof
     799                        AlternativeFinder finder( indexer, env );
     800                        finder.find( alignofExpr->get_expr() );
     801                        // find the lowest cost alternative among the alternatives, otherwise ambiguous
     802                        AltList winners;
     803                        findMinCost( finder.alternatives.begin(), finder.alternatives.end(), back_inserter( winners ) );
     804                        if ( winners.size() != 1 ) {
     805                                throw SemanticError( "Ambiguous expression in alignof operand: ", alignofExpr->get_expr() );
     806                        } // if
     807                        // return the lowest cost alternative for the argument
     808                        Alternative &choice = winners.front();
     809                        alternatives.push_back( Alternative( new AlignofExpr( choice.expr->clone() ), choice.env, Cost::zero ) );
     810                } // if
     811        }
     812
    794813        void AlternativeFinder::resolveAttr( DeclarationWithType *funcDecl, FunctionType *function, Type *argType, const TypeEnvironment &env ) {
    795814                // assume no polymorphism
  • src/ResolvExpr/AlternativeFinder.h

    rcf16f94 r4389966  
    5656                virtual void visit( ConstantExpr *constantExpr );
    5757                virtual void visit( SizeofExpr *sizeofExpr );
     58                virtual void visit( AlignofExpr *sizeofExpr );
    5859                virtual void visit( AttrExpr *attrExpr );
    5960                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Indexer.cc

    rcf16f94 r4389966  
    215215                } else {
    216216                        maybeAccept( sizeofExpr->get_expr(), *this );
     217                }
     218        }
     219
     220        void Indexer::visit( AlignofExpr *alignofExpr ) {
     221                acceptAllNewScope( alignofExpr->get_results(), *this );
     222                if ( alignofExpr->get_isType() ) {
     223                        maybeAccept( alignofExpr->get_type(), *this );
     224                } else {
     225                        maybeAccept( alignofExpr->get_expr(), *this );
    217226                }
    218227        }
  • src/SymTab/Indexer.h

    rcf16f94 r4389966  
    5454                virtual void visit( ConstantExpr *constantExpr );
    5555                virtual void visit( SizeofExpr *sizeofExpr );
     56                virtual void visit( AlignofExpr *alignofExpr );
    5657                virtual void visit( AttrExpr *attrExpr );
    5758                virtual void visit( LogicalExpr *logicalExpr );
  • src/SymTab/Mangler.cc

    rcf16f94 r4389966  
    3030
    3131namespace SymTab {
    32         Mangler::Mangler( bool mangleOverridable ) : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ) {
    33         }
    34 
    35 //Mangler::Mangler( const Mangler & )
    36 //  : mangleName(), varNums( varNums ), nextVarNum( nextVarNum ), isTopLevel( isTopLevel )
    37 //{
    38 //}
     32        Mangler::Mangler( bool mangleOverridable, bool includeQualifiers )
     33                : nextVarNum( 0 ), isTopLevel( true ), mangleOverridable( mangleOverridable ), includeQualifiers(includeQualifiers) {}
     34               
    3935        Mangler::Mangler( const Mangler &rhs ) : mangleName() {
    4036                varNums = rhs.varNums;
     
    4238                isTopLevel = rhs.isTopLevel;
    4339                mangleOverridable = rhs.mangleOverridable;
     40                includeQualifiers = rhs.includeQualifiers;
    4441        }
    4542
     
    209206
    210207        void Mangler::printQualifiers( Type *type ) {
     208                // skip if not including qualifiers
     209                if ( ! includeQualifiers ) return;
     210               
    211211                if ( ! type->get_forall().empty() ) {
    212212                        std::list< std::string > assertionNames;
     
    227227                                varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i )->get_kind() );
    228228                                for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {
    229                                         Mangler sub_mangler( mangleOverridable );
     229                                        Mangler sub_mangler( mangleOverridable, includeQualifiers );
    230230                                        sub_mangler.nextVarNum = nextVarNum;
    231231                                        sub_mangler.isTopLevel = false;
  • src/SymTab/Mangler.h

    rcf16f94 r4389966  
    2222
    2323namespace SymTab {
     24        /// Mangles names to a unique C identifier
    2425        class Mangler : public Visitor {
    2526          public:
    2627                template< typename SynTreeClass >
    27             static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true ); // interface to clients
     28            static std::string mangle( SynTreeClass *decl, bool mangleOverridable = true, bool includeQualifiers = true ); // interface to clients
    2829
    29 ///   using Visitor::visit;
    3030                virtual void visit( ObjectDecl *declaration );
    3131                virtual void visit( FunctionDecl *declaration );
     
    4545                std::string get_mangleName() { return mangleName.str(); }
    4646          private:
    47                 std::ostringstream mangleName;
     47                std::ostringstream mangleName;  ///< Mangled name being constructed
    4848                typedef std::map< std::string, std::pair< int, int > > VarMapType;
    49                 VarMapType varNums;
    50                 int nextVarNum;
    51                 bool isTopLevel;
    52                 bool mangleOverridable;
     49                VarMapType varNums;             ///< Map of type variables to indices
     50                int nextVarNum;                 ///< Next type variable index
     51                bool isTopLevel;                ///< Is the Mangler at the top level
     52                bool mangleOverridable;         ///< Specially mangle overridable built-in methods
     53                bool includeQualifiers;         ///< Include type qualifiers in mangled name
    5354 
    54                 Mangler( bool mangleOverridable );
     55                Mangler( bool mangleOverridable, bool includeQualifiers );
    5556                Mangler( const Mangler & );
    5657 
     
    6263
    6364        template< typename SynTreeClass >
    64         std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable ) {
    65                 Mangler mangler( mangleOverridable );
     65        std::string Mangler::mangle( SynTreeClass *decl, bool mangleOverridable, bool includeQualifiers ) {
     66                Mangler mangler( mangleOverridable, includeQualifiers );
    6667                maybeAccept( decl, mangler );
    6768                return mangler.get_mangleName();
  • src/SynTree/Expression.cc

    rcf16f94 r4389966  
    122122void SizeofExpr::print( std::ostream &os, int indent) const {
    123123        os << std::string( indent, ' ' ) << "Sizeof Expression on: ";
     124
     125        if (isType)
     126                type->print(os, indent + 2);
     127        else
     128                expr->print(os, indent + 2);
     129
     130        os << std::endl;
     131        Expression::print( os, indent );
     132}
     133
     134AlignofExpr::AlignofExpr( Expression *expr_, Expression *_aname ) :
     135                Expression( _aname ), expr(expr_), type(0), isType(false) {
     136        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
     137}
     138
     139AlignofExpr::AlignofExpr( Type *type_, Expression *_aname ) :
     140                Expression( _aname ), expr(0), type(type_), isType(true) {
     141        add_result( new BasicType( Type::Qualifiers(), BasicType::UnsignedInt ) );
     142}
     143
     144AlignofExpr::AlignofExpr( const AlignofExpr &other ) :
     145        Expression( other ), expr( maybeClone( other.expr ) ), type( maybeClone( other.type ) ), isType( other.isType ) {
     146}
     147
     148AlignofExpr::~AlignofExpr() {
     149        delete expr;
     150        delete type;
     151}
     152
     153void AlignofExpr::print( std::ostream &os, int indent) const {
     154        os << std::string( indent, ' ' ) << "Alignof Expression on: ";
    124155
    125156        if (isType)
  • src/SynTree/Expression.h

    rcf16f94 r4389966  
    2323#include "Constant.h"
    2424
     25/// Expression is the root type for all expressions
    2526class Expression {
    2627  public:
     
    4748};
    4849
    49 // ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
    50 // but subject to decay-to-pointer and type parameter renaming
    51 
     50/// ParamEntry contains the i.d. of a declaration and a type that is derived from that declaration,
     51/// but subject to decay-to-pointer and type parameter renaming
    5252struct ParamEntry {
    5353        ParamEntry(): decl( 0 ), actualType( 0 ), formalType( 0 ), expr( 0 ) {}
     
    6565typedef std::map< UniqueId, ParamEntry > InferredParams;
    6666
    67 // ApplicationExpr represents the application of a function to a set of parameters.  This is the
    68 // result of running an UntypedExpr through the expression analyzer.
    69 
     67/// ApplicationExpr represents the application of a function to a set of parameters.  This is the
     68/// result of running an UntypedExpr through the expression analyzer.
    7069class ApplicationExpr : public Expression {
    7170  public:
     
    8988};
    9089
    91 // UntypedExpr represents the application of a function to a set of parameters, but where the
    92 // particular overload for the function name has not yet been determined.  Most operators are
    93 // converted into functional form automatically, to permit operator overloading.
    94 
     90/// UntypedExpr represents the application of a function to a set of parameters, but where the
     91/// particular overload for the function name has not yet been determined.  Most operators are
     92/// converted into functional form automatically, to permit operator overloading.
    9593class UntypedExpr : public Expression {
    9694  public:
     
    118116};
    119117
    120 // this class contains a name whose meaning is still not determined
     118/// NameExpr contains a name whose meaning is still not determined
    121119class NameExpr : public Expression {
    122120  public:
     
    139137// function-call format.
    140138
    141 // AddressExpr represents a address-of expression, e.g. &e
     139/// AddressExpr represents a address-of expression, e.g. &e
    142140class AddressExpr : public Expression {
    143141  public:
     
    174172};
    175173
    176 // CastExpr represents a type cast expression, e.g. (int)e
     174/// CastExpr represents a type cast expression, e.g. (int)e
    177175class CastExpr : public Expression {
    178176  public:
     
    193191};
    194192
    195 // UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
     193/// UntypedMemberExpr represents a member selection operation, e.g. q.p before processing by the expression analyzer
    196194class UntypedMemberExpr : public Expression {
    197195  public:
     
    214212};
    215213
    216 // MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
     214/// MemberExpr represents a member selection operation, e.g. q.p after processing by the expression analyzer
    217215class MemberExpr : public Expression {
    218216  public:
     
    235233};
    236234
    237 // VariableExpr represents an expression that simply refers to the value of a named variable
     235/// VariableExpr represents an expression that simply refers to the value of a named variable
    238236class VariableExpr : public Expression {
    239237  public:
     
    253251};
    254252
    255 // ConstantExpr represents an expression that simply refers to the value of a constant
     253/// ConstantExpr represents an expression that simply refers to the value of a constant
    256254class ConstantExpr : public Expression {
    257255  public:
     
    271269};
    272270
    273 // SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
     271/// SizeofExpr represents a sizeof expression (could be sizeof(int) or sizeof 3+4)
    274272class SizeofExpr : public Expression {
    275273  public:
     
    296294};
    297295
    298 // AttrExpr represents an @attribute expression (like sizeof, but user-defined)
     296/// AlignofExpr represents an alignof expression
     297class AlignofExpr : public Expression {
     298  public:
     299        AlignofExpr( Expression *expr, Expression *_aname = 0 );
     300        AlignofExpr( const AlignofExpr &other );
     301        AlignofExpr( Type *type, Expression *_aname = 0 );
     302        virtual ~AlignofExpr();
     303
     304        Expression *get_expr() const { return expr; }
     305        void set_expr( Expression *newValue ) { expr = newValue; }
     306        Type *get_type() const { return type; }
     307        void set_type( Type *newValue ) { type = newValue; }
     308        bool get_isType() const { return isType; }
     309        void set_isType( bool newValue ) { isType = newValue; }
     310
     311        virtual AlignofExpr *clone() const { return new AlignofExpr( *this ); }
     312        virtual void accept( Visitor &v ) { v.visit( this ); }
     313        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     314        virtual void print( std::ostream &os, int indent = 0 ) const;
     315  private:
     316        Expression *expr;
     317        Type *type;
     318        bool isType;
     319};
     320
     321/// AttrExpr represents an @attribute expression (like sizeof, but user-defined)
    299322class AttrExpr : public Expression {
    300323  public:
     
    324347};
    325348
    326 // LogicalExpr represents a short-circuit boolean expression (&& or ||)
     349/// LogicalExpr represents a short-circuit boolean expression (&& or ||)
    327350class LogicalExpr : public Expression {
    328351  public:
     
    347370};
    348371
    349 // ConditionalExpr represents the three-argument conditional ( p ? a : b )
     372/// ConditionalExpr represents the three-argument conditional ( p ? a : b )
    350373class ConditionalExpr : public Expression {
    351374  public:
     
    371394};
    372395
    373 // CommaExpr represents the sequence operator ( a, b )
     396/// CommaExpr represents the sequence operator ( a, b )
    374397class CommaExpr : public Expression {
    375398  public:
     
    392415};
    393416
    394 // TupleExpr represents a tuple expression ( [a, b, c] )
     417/// TupleExpr represents a tuple expression ( [a, b, c] )
    395418class TupleExpr : public Expression {
    396419  public:
     
    410433};
    411434
    412 // SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
     435/// SolvedTupleExpr represents a TupleExpr whose components have been type-resolved. It is effectively a shell for the code generator to work on
    413436class SolvedTupleExpr : public Expression {
    414437  public:
     
    428451};
    429452
    430 // TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
     453/// TypeExpr represents a type used in an expression (e.g. as a type generator parameter)
    431454class TypeExpr : public Expression {
    432455  public:
     
    446469};
    447470
    448 // AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
     471/// AsmExpr represents a GCC 'asm constraint operand' used in an asm statement: [output] "=f" (result)
    449472class AsmExpr : public Expression {
    450473  public:
     
    472495};
    473496
    474 // ValofExpr represents a GCC 'lambda expression'
     497/// ValofExpr represents a GCC 'lambda expression'
    475498class UntypedValofExpr : public Expression {
    476499  public:
  • src/SynTree/Mutator.cc

    rcf16f94 r4389966  
    251251}
    252252
     253Expression *Mutator::mutate( AlignofExpr *alignofExpr ) {
     254        mutateAll( alignofExpr->get_results(), *this );
     255        if ( alignofExpr->get_isType() ) {
     256                alignofExpr->set_type( maybeMutate( alignofExpr->get_type(), *this ) );
     257        } else {
     258                alignofExpr->set_expr( maybeMutate( alignofExpr->get_expr(), *this ) );
     259        }
     260        return alignofExpr;
     261}
     262
    253263Expression *Mutator::mutate( AttrExpr *attrExpr ) {
    254264        mutateAll( attrExpr->get_results(), *this );
  • src/SynTree/Mutator.h

    rcf16f94 r4389966  
    6464        virtual Expression* mutate( ConstantExpr *constantExpr );
    6565        virtual Expression* mutate( SizeofExpr *sizeofExpr );
     66        virtual Expression* mutate( AlignofExpr *alignofExpr );
    6667        virtual Expression* mutate( AttrExpr *attrExpr );
    6768        virtual Expression* mutate( LogicalExpr *logicalExpr );
  • src/SynTree/SynTree.h

    rcf16f94 r4389966  
    6969class ConstantExpr;
    7070class SizeofExpr;
     71class AlignofExpr;
    7172class AttrExpr;
    7273class LogicalExpr;
  • src/SynTree/Visitor.cc

    rcf16f94 r4389966  
    210210}
    211211
     212void Visitor::visit( AlignofExpr *alignofExpr ) {
     213        acceptAll( alignofExpr->get_results(), *this );
     214        if ( alignofExpr->get_isType() ) {
     215                maybeAccept( alignofExpr->get_type(), *this );
     216        } else {
     217                maybeAccept( alignofExpr->get_expr(), *this );
     218        }
     219}
     220
    212221void Visitor::visit( AttrExpr *attrExpr ) {
    213222        acceptAll( attrExpr->get_results(), *this );
  • src/SynTree/Visitor.h

    rcf16f94 r4389966  
    6464        virtual void visit( ConstantExpr *constantExpr );
    6565        virtual void visit( SizeofExpr *sizeofExpr );
     66        virtual void visit( AlignofExpr *alignofExpr );
    6667        virtual void visit( AttrExpr *attrExpr );
    6768        virtual void visit( LogicalExpr *logicalExpr );
  • src/Tuples/FlattenTuple.cc

    rcf16f94 r4389966  
    4646        void FlattenTuple::CollectArgs::visit( ConstantExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    4747        void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     48        void FlattenTuple::CollectArgs::visit( AlignofExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    4849        void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    4950        void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
  • src/Tuples/FlattenTuple.h

    rcf16f94 r4389966  
    4242                        virtual void visit( ConstantExpr * );
    4343                        virtual void visit( SizeofExpr * );
     44                        virtual void visit( AlignofExpr * );
    4445                        virtual void visit( AttrExpr * );
    4546                        virtual void visit( LogicalExpr * );
Note: See TracChangeset for help on using the changeset viewer.