Changeset 4789f44


Ignore:
Timestamp:
Feb 5, 2016, 12:28:21 PM (7 years ago)
Author:
Rob Schluntz <rschlunt@…>
Branches:
aaron-thesis, arm-eh, 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:
408d460, bd85400
Parents:
b4cd03b7 (diff), 2a4b088 (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:

Merge branch 'master' into fix-argument-passing-type-warnings

Location:
src
Files:
18 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rb4cd03b7 r4789f44  
    453453        }
    454454
     455        void CodeGenerator::visit( UntypedOffsetofExpr *offsetofExpr ) {
     456                assert( false );
     457        }
     458
    455459        void CodeGenerator::visit( OffsetofExpr *offsetofExpr ) {
    456460                // use GCC builtin
  • src/CodeGen/CodeGenerator.h

    rb4cd03b7 r4789f44  
    6161                virtual void visit( SizeofExpr *sizeofExpr );
    6262                virtual void visit( AlignofExpr *alignofExpr );
     63                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6364                virtual void visit( OffsetofExpr *offsetofExpr );
    6465                virtual void visit( LogicalExpr *logicalExpr );
  • src/GenPoly/Box.cc

    rb4cd03b7 r4789f44  
    123123                };
    124124
    125                 /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference
     125                /// Replaces member expressions for polymorphic types with calculated add-field-offset-and-dereference;
     126                /// also fixes offsetof expressions.
    126127                class MemberExprFixer : public PolyMutator {
    127128                  public:
     
    136137                        virtual Type *mutate( FunctionType *funcType );
    137138                        virtual Expression *mutate( MemberExpr *memberExpr );
     139                        virtual Expression *mutate( OffsetofExpr *offsetofExpr );
    138140                };
    139141
     
    12831285                }
    12841286
     1287                /// Finds the member in the base list that matches the given declaration; returns its index, or -1 if not present
     1288                long findMember( DeclarationWithType *memberDecl, std::list< Declaration* > &baseDecls ) {
     1289                        long i = 0;
     1290                        for(std::list< Declaration* >::const_iterator decl = baseDecls.begin(); decl != baseDecls.end(); ++decl, ++i ) {
     1291                                if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
     1292
     1293                                if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
     1294                                        if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) return i;
     1295                                        else continue;
     1296                                } else return i;
     1297                        }
     1298                        return -1;
     1299                }
     1300
     1301                /// Returns an index expression into the offset array for a type
     1302                Expression *makeOffsetIndex( Type *objectType, long i ) {
     1303                        std::stringstream offset_namer;
     1304                        offset_namer << i;
     1305                        ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
     1306                        UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
     1307                        fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
     1308                        fieldOffset->get_args().push_back( fieldIndex );
     1309                        return fieldOffset;
     1310                }
     1311
     1312                /// Returns an expression dereferenced n times
     1313                Expression *makeDerefdVar( Expression *derefdVar, long n ) {
     1314                        for ( int i = 1; i < n; ++i ) {
     1315                                UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
     1316                                derefExpr->get_args().push_back( derefdVar );
     1317                                derefdVar = derefExpr;
     1318                        }
     1319                        return derefdVar;
     1320                }
     1321               
    12851322                Expression *MemberExprFixer::mutate( MemberExpr *memberExpr ) {
    12861323                        // mutate, exiting early if no longer MemberExpr
     
    13011338                        if ( ! objectType ) return memberExpr;
    13021339
    1303                         // get base aggregate for type so members can be looked up
    1304                         AggregateDecl *memberBase = 0;
    13051340                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( objectType ) ) {
    1306                                 memberBase = structType->get_baseStruct();
     1341                                // look up offset index
     1342                                long i = findMember( memberExpr->get_member(), structType->get_baseStruct()->get_members() );
     1343                                if ( i == -1 ) return memberExpr;
     1344
     1345                                // replace member expression with pointer to base plus offset
     1346                                UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
     1347                                fieldLoc->get_args().push_back( makeDerefdVar( varExpr->clone(), varDepth ) );
     1348                                fieldLoc->get_args().push_back( makeOffsetIndex( objectType, i ) );
     1349
     1350                                delete memberExpr;
     1351                                return fieldLoc;
    13071352                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType ) ) {
    1308                                 memberBase = unionType->get_baseUnion();
     1353                                // union members are all at offset zero, so build appropriately-dereferenced variable
     1354                                Expression *derefdVar = makeDerefdVar( varExpr->clone(), varDepth );
     1355                                delete memberExpr;
     1356                                return derefdVar;
    13091357                        } else return memberExpr;
    1310 
    1311                         // look up numeric index of member in base aggregate
    1312                         DeclarationWithType *memberDecl = memberExpr->get_member();
    1313                         std::list< Declaration* > &baseDecls = memberBase->get_members();
    1314                         std::list< Declaration* >::const_iterator decl = baseDecls.begin();
    1315                         unsigned long i = 0;
    1316                         for( ; decl != baseDecls.end(); ++decl, ++i ) {
    1317                                 if ( memberDecl->get_name() != (*decl)->get_name() ) continue;
    1318 
    1319                                 if ( DeclarationWithType *declWithType = dynamic_cast< DeclarationWithType* >( *decl ) ) {
    1320                                         if ( memberDecl->get_mangleName() == declWithType->get_mangleName() ) break;
    1321                                         else continue;
    1322                                 } else break;
    1323                         }
    1324                         if ( decl == baseDecls.end() ) return memberExpr;
    1325 
    1326                         // replace member expression with pointer to base plus offset
    1327                         // get offset for field
    1328                         std::stringstream offset_namer;
    1329                         offset_namer << i;
    1330                         ConstantExpr *fieldIndex = new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), offset_namer.str() ) );
    1331                         UntypedExpr *fieldOffset = new UntypedExpr( new NameExpr( "?[?]" ) );
    1332                         fieldOffset->get_args().push_back( new NameExpr( offsetofName( objectType ) ) );
    1333                         fieldOffset->get_args().push_back( fieldIndex );
    1334                         // build appropriately-dereferenced variable
    1335                         Expression *derefdVar = varExpr->clone();
    1336                         for ( int i = 1; i < varDepth; ++i ) {
    1337                                 UntypedExpr *derefExpr = new UntypedExpr( new NameExpr( "*?" ) );
    1338                                 derefExpr->get_args().push_back( derefdVar );
    1339                                 derefdVar = derefExpr;
    1340                         }
    1341                         // add offset to deref'd variable
    1342                         UntypedExpr *fieldLoc = new UntypedExpr( new NameExpr( "?+?" ) );
    1343                         fieldLoc->get_args().push_back( derefdVar );
    1344                         fieldLoc->get_args().push_back( fieldOffset );
    1345 
    1346                         delete memberExpr;
    1347                         return fieldLoc;
     1358                }
     1359
     1360                Expression *MemberExprFixer::mutate( OffsetofExpr *offsetofExpr ) {
     1361                        // mutate, exiting early if no longer OffsetofExpr
     1362                        Expression *expr = Mutator::mutate( offsetofExpr );
     1363                        offsetofExpr = dynamic_cast< OffsetofExpr* >( expr );
     1364                        if ( ! offsetofExpr ) return expr;
     1365
     1366                        // only mutate expressions for polymorphic structs/unions
     1367                        Type *ty = isPolyType( offsetofExpr->get_type(), scopeTyVars );
     1368                        if ( ! ty ) return offsetofExpr;
     1369
     1370                        if ( StructInstType *structType = dynamic_cast< StructInstType* >( ty ) ) {
     1371                                // replace offsetof expression by index into offset array
     1372                                long i = findMember( offsetofExpr->get_member(), structType->get_baseStruct()->get_members() );
     1373                                if ( i == -1 ) return offsetofExpr;
     1374
     1375                                Expression *offsetInd = makeOffsetIndex( ty, i );
     1376                                delete offsetofExpr;
     1377                                return offsetInd;
     1378                        } else if ( UnionInstType *unionType = dynamic_cast< UnionInstType* >( ty ) ) {
     1379                                // all union members are at offset zero
     1380                                delete offsetofExpr;
     1381                                return new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::string("0") ) );
     1382                        } else return offsetofExpr;
    13481383                }
    13491384
  • src/InitTweak/InitModel.h

    rb4cd03b7 r4789f44  
    7373                        void visit( SizeofExpr * ) { throw 0; }
    7474                        void visit( AlignofExpr * ) { throw 0; }
     75                        void visit( UntypedOffsetofExpr * ) { throw 0; }
    7576                        void visit( OffsetofExpr * ) { throw 0; }
    7677                        void visit( AttrExpr * ) { throw 0; }
  • src/Parser/ExpressionNode.cc

    rb4cd03b7 r4789f44  
    606606          case OperatorNode::OffsetOf:
    607607                {
    608                         assert( false );
     608                        assert( args.size() == 2 );
     609                       
     610                        if ( TypeValueNode * arg = dynamic_cast<TypeValueNode *>( get_args() ) ) {
     611                                NameExpr *member = dynamic_cast<NameExpr *>( args.back() );
     612                                assert( member != 0 );
     613
     614                                return new UntypedOffsetofExpr( arg->get_decl()->buildType(), member->get_name() );
     615                        } else assert( false );
    609616                }
    610617          case OperatorNode::Attr:
  • src/ResolvExpr/AlternativeFinder.cc

    rb4cd03b7 r4789f44  
    811811        }
    812812
     813        template< typename StructOrUnionType >
     814        void AlternativeFinder::addOffsetof( StructOrUnionType *aggInst, const std::string &name ) {
     815                std::list< Declaration* > members;
     816                aggInst->lookup( name, members );
     817                for ( std::list< Declaration* >::const_iterator i = members.begin(); i != members.end(); ++i ) {
     818                        if ( DeclarationWithType *dwt = dynamic_cast< DeclarationWithType* >( *i ) ) {
     819                                alternatives.push_back( Alternative( new OffsetofExpr( aggInst->clone(), dwt->clone() ), env, Cost::zero ) );
     820                                renameTypes( alternatives.back().expr );
     821                        } else {
     822                                assert( false );
     823                        }
     824                }
     825        }
     826       
     827        void AlternativeFinder::visit( UntypedOffsetofExpr *offsetofExpr ) {
     828                AlternativeFinder funcFinder( indexer, env );
     829                if ( StructInstType *structInst = dynamic_cast< StructInstType* >( offsetofExpr->get_type() ) ) {
     830                        addOffsetof( structInst, offsetofExpr->get_member() );
     831                } else if ( UnionInstType *unionInst = dynamic_cast< UnionInstType* >( offsetofExpr->get_type() ) ) {
     832                        addOffsetof( unionInst, offsetofExpr->get_member() );
     833                }
     834        }
     835       
    813836        void AlternativeFinder::visit( OffsetofExpr *offsetofExpr ) {
    814837                alternatives.push_back( Alternative( offsetofExpr->clone(), env, Cost::zero ) );
  • src/ResolvExpr/AlternativeFinder.h

    rb4cd03b7 r4789f44  
    5757                virtual void visit( SizeofExpr *sizeofExpr );
    5858                virtual void visit( AlignofExpr *alignofExpr );
     59                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    5960                virtual void visit( OffsetofExpr *offsetofExpr );
    6061                virtual void visit( AttrExpr *attrExpr );
     
    6869
    6970          private:
     71                /// Adds alternatives for member expressions, given the aggregate, conversion cost for that aggregate, and name of the member
    7072                template< typename StructOrUnionType > void addAggMembers( StructOrUnionType *aggInst, Expression *expr, const Cost &newCost, const std::string &name );
     73                /// Adds alternatives for offsetof expressions, given the base type and name of the member
     74                template< typename StructOrUnionType > void addOffsetof( StructOrUnionType *aggInst, const std::string &name );
    7175                bool instantiateFunction( std::list< DeclarationWithType* >& formals, /*const*/ AltList &actuals, bool isVarArgs, OpenVarSet& openVars, TypeEnvironment &resultEnv, AssertionSet &resultNeed, AssertionSet &resultHave );
    7276                template< typename OutputIterator >
  • src/SymTab/Indexer.cc

    rb4cd03b7 r4789f44  
    225225                        maybeAccept( alignofExpr->get_expr(), *this );
    226226                }
     227        }
     228
     229        void Indexer::visit( UntypedOffsetofExpr *offsetofExpr ) {
     230                acceptAllNewScope( offsetofExpr->get_results(), *this );
     231                maybeAccept( offsetofExpr->get_type(), *this );
    227232        }
    228233
  • src/SymTab/Indexer.h

    rb4cd03b7 r4789f44  
    5555                virtual void visit( SizeofExpr *sizeofExpr );
    5656                virtual void visit( AlignofExpr *alignofExpr );
     57                virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    5758                virtual void visit( OffsetofExpr *offsetofExpr );
    5859                virtual void visit( AttrExpr *attrExpr );
  • src/SynTree/Expression.cc

    rb4cd03b7 r4789f44  
    163163}
    164164
     165UntypedOffsetofExpr::UntypedOffsetofExpr( Type *type_, const std::string &member_, Expression *_aname ) :
     166                Expression( _aname ), type(type_), member(member_) {
     167        add_result( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ) );
     168}
     169
     170UntypedOffsetofExpr::UntypedOffsetofExpr( const UntypedOffsetofExpr &other ) :
     171        Expression( other ), type( maybeClone( other.type ) ), member( other.member ) {}
     172
     173UntypedOffsetofExpr::~UntypedOffsetofExpr() {
     174        delete type;
     175}
     176
     177void UntypedOffsetofExpr::print( std::ostream &os, int indent) const {
     178        os << std::string( indent, ' ' ) << "Untyped Offsetof Expression on member " << member << " of ";
     179
     180        if ( type ) {
     181                type->print(os, indent + 2);
     182        } else {
     183                os << "<NULL>";
     184        }
     185
     186        os << std::endl;
     187        Expression::print( os, indent );
     188}
     189
    165190OffsetofExpr::OffsetofExpr( Type *type_, DeclarationWithType *member_, Expression *_aname ) :
    166191                Expression( _aname ), type(type_), member(member_) {
  • src/SynTree/Expression.h

    rb4cd03b7 r4789f44  
    319319};
    320320
     321/// UntypedOffsetofExpr represents an offsetof expression before resolution
     322class UntypedOffsetofExpr : public Expression {
     323  public:
     324        UntypedOffsetofExpr( Type *type, const std::string &member, Expression *_aname = 0 );
     325        UntypedOffsetofExpr( const UntypedOffsetofExpr &other );
     326        virtual ~UntypedOffsetofExpr();
     327
     328        std::string get_member() const { return member; }
     329        void set_member( const std::string &newValue ) { member = newValue; }
     330        Type *get_type() const { return type; }
     331        void set_type( Type *newValue ) { type = newValue; }
     332
     333        virtual UntypedOffsetofExpr *clone() const { return new UntypedOffsetofExpr( *this ); }
     334        virtual void accept( Visitor &v ) { v.visit( this ); }
     335        virtual Expression *acceptMutator( Mutator &m ) { return m.mutate( this ); }
     336        virtual void print( std::ostream &os, int indent = 0 ) const;
     337  private:
     338        Type *type;
     339        std::string member;
     340};
     341
    321342/// OffsetofExpr represents an offsetof expression
    322343class OffsetofExpr : public Expression {
  • src/SynTree/Mutator.cc

    rb4cd03b7 r4789f44  
    261261}
    262262
     263Expression *Mutator::mutate( UntypedOffsetofExpr *offsetofExpr ) {
     264        mutateAll( offsetofExpr->get_results(), *this );
     265        offsetofExpr->set_type( maybeMutate( offsetofExpr->get_type(), *this ) );
     266        return offsetofExpr;
     267}
     268
    263269Expression *Mutator::mutate( OffsetofExpr *offsetofExpr ) {
    264270        mutateAll( offsetofExpr->get_results(), *this );
  • src/SynTree/Mutator.h

    rb4cd03b7 r4789f44  
    6565        virtual Expression* mutate( SizeofExpr *sizeofExpr );
    6666        virtual Expression* mutate( AlignofExpr *alignofExpr );
     67        virtual Expression* mutate( UntypedOffsetofExpr *offsetofExpr );
    6768        virtual Expression* mutate( OffsetofExpr *offsetofExpr );
    6869        virtual Expression* mutate( AttrExpr *attrExpr );
  • src/SynTree/SynTree.h

    rb4cd03b7 r4789f44  
    7070class SizeofExpr;
    7171class AlignofExpr;
     72class UntypedOffsetofExpr;
    7273class OffsetofExpr;
    7374class AttrExpr;
  • src/SynTree/Visitor.cc

    rb4cd03b7 r4789f44  
    219219}
    220220
     221void Visitor::visit( UntypedOffsetofExpr *offsetofExpr ) {
     222        acceptAll( offsetofExpr->get_results(), *this );
     223        maybeAccept( offsetofExpr->get_type(), *this );
     224}
     225
    221226void Visitor::visit( OffsetofExpr *offsetofExpr ) {
    222227        acceptAll( offsetofExpr->get_results(), *this );
  • src/SynTree/Visitor.h

    rb4cd03b7 r4789f44  
    6565        virtual void visit( SizeofExpr *sizeofExpr );
    6666        virtual void visit( AlignofExpr *alignofExpr );
     67        virtual void visit( UntypedOffsetofExpr *offsetofExpr );
    6768        virtual void visit( OffsetofExpr *offsetofExpr );
    6869        virtual void visit( AttrExpr *attrExpr );
  • src/Tuples/FlattenTuple.cc

    rb4cd03b7 r4789f44  
    3737        }
    3838
    39         void FlattenTuple::CollectArgs::visit( UntypedExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    40         void FlattenTuple::CollectArgs::visit( NameExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    41         void FlattenTuple::CollectArgs::visit( CastExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    42         void FlattenTuple::CollectArgs::visit( AddressExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    43         void FlattenTuple::CollectArgs::visit( UntypedMemberExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    44         void FlattenTuple::CollectArgs::visit( MemberExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    45         void FlattenTuple::CollectArgs::visit( VariableExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    46         void FlattenTuple::CollectArgs::visit( ConstantExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    47         void FlattenTuple::CollectArgs::visit( SizeofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    48         void FlattenTuple::CollectArgs::visit( AlignofExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    49         void FlattenTuple::CollectArgs::visit( OffsetofExpr      *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    50         void FlattenTuple::CollectArgs::visit( AttrExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    51         void FlattenTuple::CollectArgs::visit( LogicalExpr       *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    52         void FlattenTuple::CollectArgs::visit( ConditionalExpr   *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    53         void FlattenTuple::CollectArgs::visit( CommaExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    54         void FlattenTuple::CollectArgs::visit( TypeExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    55         void FlattenTuple::CollectArgs::visit( UntypedValofExpr  *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     39        void FlattenTuple::CollectArgs::visit( UntypedExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     40        void FlattenTuple::CollectArgs::visit( NameExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     41        void FlattenTuple::CollectArgs::visit( CastExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     42        void FlattenTuple::CollectArgs::visit( AddressExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     43        void FlattenTuple::CollectArgs::visit( UntypedMemberExpr   *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     44        void FlattenTuple::CollectArgs::visit( MemberExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     45        void FlattenTuple::CollectArgs::visit( VariableExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     46        void FlattenTuple::CollectArgs::visit( ConstantExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     47        void FlattenTuple::CollectArgs::visit( SizeofExpr          *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     48        void FlattenTuple::CollectArgs::visit( AlignofExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     49        void FlattenTuple::CollectArgs::visit( UntypedOffsetofExpr *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     50        void FlattenTuple::CollectArgs::visit( OffsetofExpr        *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     51        void FlattenTuple::CollectArgs::visit( AttrExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     52        void FlattenTuple::CollectArgs::visit( LogicalExpr         *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     53        void FlattenTuple::CollectArgs::visit( ConditionalExpr     *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     54        void FlattenTuple::CollectArgs::visit( CommaExpr           *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     55        void FlattenTuple::CollectArgs::visit( TypeExpr            *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
     56        void FlattenTuple::CollectArgs::visit( UntypedValofExpr    *expr )  {  currentArgs.insert( currentArgs.end(), expr );  }
    5657
    5758        void FlattenTuple::CollectArgs::visit( TupleExpr *tupleExpr) {
  • src/Tuples/FlattenTuple.h

    rb4cd03b7 r4789f44  
    4343                        virtual void visit( SizeofExpr * );
    4444                        virtual void visit( AlignofExpr * );
     45                        virtual void visit( UntypedOffsetofExpr * );
    4546                        virtual void visit( OffsetofExpr * );
    4647                        virtual void visit( AttrExpr * );
Note: See TracChangeset for help on using the changeset viewer.