Changes in / [ae357ec:b63e376]


Ignore:
Location:
src
Files:
8 added
13 edited

Legend:

Unmodified
Added
Removed
  • src/CodeGen/CodeGenerator.cc

    rae357ec rb63e376  
    2121#include "Parser/ParseNode.h"
    2222
    23 #include "SynTree/Declaration.h"
     23#include "SynTree/Type.h"
    2424#include "SynTree/Expression.h"
    2525#include "SynTree/Initializer.h"
    2626#include "SynTree/Statement.h"
    27 #include "SynTree/Type.h"
    2827
    2928#include "Common/utility.h"
  • src/CodeGen/CodeGenerator.h

    rae357ec rb63e376  
    1919#include <list>
    2020
    21 #include "SynTree/Declaration.h"
    2221#include "SynTree/SynTree.h"
    2322#include "SynTree/Visitor.h"
    24 
    2523#include "SymTab/Indexer.h"
    2624
  • src/CodeGen/GenType.cc

    rae357ec rb63e376  
    1919#include "GenType.h"
    2020#include "CodeGenerator.h"
    21 
    22 #include "SynTree/Declaration.h"
     21#include "SynTree/Visitor.h"
     22#include "SynTree/Type.h"
    2323#include "SynTree/Expression.h"
    24 #include "SynTree/Type.h"
    25 #include "SynTree/Visitor.h"
    2624
    2725namespace CodeGen {
  • src/GenPoly/Box.cc

    rae357ec rb63e376  
    1414//
    1515
    16 #include <algorithm>
    17 #include <iterator>
    18 #include <list>
    19 #include <map>
    2016#include <set>
    2117#include <stack>
    2218#include <string>
    23 #include <utility>
    24 #include <vector>
     19#include <iterator>
     20#include <algorithm>
    2521#include <cassert>
    2622
    2723#include "Box.h"
    28 #include "DeclMutator.h"
     24#include "InstantiateGeneric.h"
    2925#include "PolyMutator.h"
    3026#include "FindFunction.h"
    31 #include "ScopedMap.h"
    3227#include "ScrubTyVars.h"
    3328
     
    3530
    3631#include "SynTree/Constant.h"
    37 #include "SynTree/Declaration.h"
     32#include "SynTree/Type.h"
    3833#include "SynTree/Expression.h"
    3934#include "SynTree/Initializer.h"
     35#include "SynTree/Statement.h"
    4036#include "SynTree/Mutator.h"
    41 #include "SynTree/Statement.h"
    42 #include "SynTree/Type.h"
    43 #include "SynTree/TypeSubstitution.h"
    4437
    4538#include "ResolvExpr/TypeEnvironment.h"
     
    4740#include "ResolvExpr/typeops.h"
    4841
    49 #include "SymTab/Indexer.h"
    5042#include "SymTab/Mangler.h"
    5143
     
    6254                FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars );
    6355
    64                 /// Key for a unique concrete type; generic base type paired with type parameter list
    65                 struct ConcreteType {
    66                         ConcreteType() : base(NULL), params() {}
    67 
    68                         ConcreteType(AggregateDecl *_base, const std::list< Type* >& _params) : base(_base), params() { cloneAll(_params, params); }
    69 
    70                         ConcreteType(const ConcreteType& that) : base(that.base), params() { cloneAll(that.params, params); }
    71 
    72                         /// Extracts types from a list of TypeExpr*
    73                         ConcreteType(AggregateDecl *_base, const std::list< TypeExpr* >& _params) : base(_base), params() {
    74                                 for ( std::list< TypeExpr* >::const_iterator param = _params.begin(); param != _params.end(); ++param ) {
    75                                         params.push_back( (*param)->get_type()->clone() );
    76                                 }
    77                         }
    78 
    79                         ConcreteType& operator= (const ConcreteType& that) {
    80                                 deleteAll( params );
    81                                 params.clear();
    82 
    83                                 base = that.base;
    84                                 cloneAll( that.params, params );
    85 
    86                                 return *this;
    87                         }
    88 
    89                         ~ConcreteType() { deleteAll( params ); }
    90 
    91                         bool operator== (const ConcreteType& that) const {
    92                                 if ( base != that.base ) return false;
    93 
    94                                 SymTab::Indexer dummy;
    95                                 if ( params.size() != that.params.size() ) return false;
    96                                 for ( std::list< Type* >::const_iterator it = params.begin(), jt = that.params.begin(); it != params.end(); ++it, ++jt ) {
    97                                         if ( ! ResolvExpr::typesCompatible( *it, *jt, dummy ) ) return false;
    98                                 }
    99                                 return true;
    100                         }
    101 
    102                         AggregateDecl *base;        ///< Base generic type
    103                         std::list< Type* > params;  ///< Instantiation parameters
    104                 };
    105 
    106                 /// Maps a concrete type to the some value, accounting for scope
    107                 template< typename Value >
    108                 class InstantiationMap {
    109                         /// Information about a specific instantiation of a generic type
    110                         struct Instantiation {
    111                                 ConcreteType key;  ///< Instantiation parameters for this type
    112                                 Value *value;      ///< Value for this instantiation
    113 
    114                                 Instantiation() : key(), value(0) {}
    115                                 Instantiation(const ConcreteType &_key, Value *_value) : key(_key), value(_value) {}
    116                         };
    117                         /// Map of generic types to instantiations of them
    118                         typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;
    119 
    120                         std::vector< Scope > scopes;  ///< list of scopes, from outermost to innermost
    121 
    122                 public:
    123                         /// Starts a new scope
    124                         void beginScope() {
    125                                 Scope scope;
    126                                 scopes.push_back(scope);
    127                         }
    128 
    129                         /// Ends a scope
    130                         void endScope() {
    131                                 scopes.pop_back();
    132                         }
    133 
    134                         /// Default constructor initializes with one scope
    135                         InstantiationMap() { beginScope(); }
    136 
    137 //              private:
    138                         /// Gets the value for the concrete instantiation of this type, assuming it has already been instantiated in the current scope.
    139                         /// Returns NULL on none such.
    140                         Value *lookup( AggregateDecl *generic, const std::list< TypeExpr* >& params ) {
    141                                 ConcreteType key(generic, params);
    142                                 // scan scopes from innermost out
    143                                 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {
    144                                         // skip scope if no instantiations of this generic type
    145                                         typename Scope::const_iterator insts = scope->find( generic );
    146                                         if ( insts == scope->end() ) continue;
    147                                         // look through instantiations for matches to concrete type
    148                                         for ( typename std::vector< Instantiation >::const_iterator inst = insts->second.begin(); inst != insts->second.end(); ++inst ) {
    149                                                 if ( inst->key == key ) return inst->value;
    150                                         }
    151                                 }
    152                                 // no matching instantiation found
    153                                 return 0;
    154                         }
    155                 public:
    156 //                      StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)lookup( inst->get_baseStruct(), typeSubs ); }
    157 //                      UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)lookup( inst->get_baseUnion(), typeSubs ); }
    158 
    159 //              private:
    160                         /// Adds a value for a concrete type to the current scope
    161                         void insert( AggregateDecl *generic, const std::list< TypeExpr* > &params, Value *value ) {
    162                                 ConcreteType key(generic, params);
    163                                 scopes.back()[generic].push_back( Instantiation( key, value ) );
    164                         }
    165 //              public:
    166 //                      void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { insert( inst->get_baseStruct(), typeSubs, decl ); }
    167 //                      void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { insert( inst->get_baseUnion(), typeSubs, decl ); }
    168                 };
    169 
    170                 /// Adds layout-generation functions to polymorphic types
    171                 class LayoutFunctionBuilder : public DeclMutator {
    172                         unsigned int functionNesting;  // current level of nested functions
    173                 public:
    174                         LayoutFunctionBuilder() : functionNesting( 0 ) {}
    175 
    176                         virtual DeclarationWithType *mutate( FunctionDecl *functionDecl );
    177                         virtual Declaration *mutate( StructDecl *structDecl );
    178                         virtual Declaration *mutate( UnionDecl *unionDecl );
    179                 };
    180                
    18156                /// 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
    18257                class Pass1 : public PolyMutator {
     
    225100                        ObjectDecl *makeTemporary( Type *type );
    226101
     102                        typedef std::map< std::string, DeclarationWithType *> AdapterMap;
    227103                        std::map< std::string, DeclarationWithType *> assignOps;
    228104                        ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps;
    229                         ScopedMap< std::string, DeclarationWithType* > adapters;
     105                        std::stack< AdapterMap > adapters;
    230106                        DeclarationWithType *retval;
    231107                        bool useRetval;
     
    248124
    249125                        std::map< UniqueId, std::string > adapterName;
    250                 };
    251 
    252                 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately
    253                 class GenericInstantiator : public DeclMutator {
    254                         /// Map of (generic type, parameter list) pairs to concrete type instantiations
    255                         InstantiationMap< AggregateDecl > instantiations;
    256                         /// Namer for concrete types
    257                         UniqueName typeNamer;
    258 
    259                 public:
    260                         GenericInstantiator() : DeclMutator(), instantiations(), typeNamer("_conc_") {}
    261 
    262                         virtual Type* mutate( StructInstType *inst );
    263                         virtual Type* mutate( UnionInstType *inst );
    264 
    265         //              virtual Expression* mutate( MemberExpr *memberExpr );
    266 
    267                         virtual void doBeginScope();
    268                         virtual void doEndScope();
    269                 private:
    270                         /// Wrap instantiation lookup for structs
    271                         StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }
    272                         /// Wrap instantiation lookup for unions
    273                         UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }
    274                         /// Wrap instantiation insertion for structs
    275                         void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }
    276                         /// Wrap instantiation insertion for unions
    277                         void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }
    278126                };
    279127
     
    311159        } // anonymous namespace
    312160
     161        void printAllNotBuiltin( const std::list< Declaration *>& translationUnit, std::ostream &os ) {
     162                for ( std::list< Declaration *>::const_iterator i = translationUnit.begin(); i != translationUnit.end(); ++i ) {
     163                        if ( ! LinkageSpec::isBuiltin( (*i)->get_linkage() ) ) {
     164                                (*i)->print( os );
     165                                os << std::endl;
     166                        } // if
     167                } // for
     168        }
     169
    313170        /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging
    314171        template< typename MutatorType >
     
    338195
    339196        void box( std::list< Declaration *>& translationUnit ) {
    340                 LayoutFunctionBuilder layoutBuilder;
    341197                Pass1 pass1;
    342198                Pass2 pass2;
    343                 GenericInstantiator instantiator;
    344199                MemberExprFixer memberFixer;
    345200                Pass3 pass3;
    346                
    347                 layoutBuilder.mutateDeclarationList( translationUnit );
    348201                mutateTranslationUnit/*All*/( translationUnit, pass1 );
    349202                mutateTranslationUnit/*All*/( translationUnit, pass2 );
    350 //              instantiateGeneric( translationUnit );
    351                 instantiator.mutateDeclarationList( translationUnit );
     203                instantiateGeneric( translationUnit );
    352204                mutateTranslationUnit/*All*/( translationUnit, memberFixer );
    353205                mutateTranslationUnit/*All*/( translationUnit, pass3 );
    354206        }
    355207
    356         ////////////////////////////////// LayoutFunctionBuilder ////////////////////////////////////////////
    357 
    358         DeclarationWithType *LayoutFunctionBuilder::mutate( FunctionDecl *functionDecl ) {
    359                 functionDecl->set_functionType( maybeMutate( functionDecl->get_functionType(), *this ) );
    360                 mutateAll( functionDecl->get_oldDecls(), *this );
    361                 ++functionNesting;
    362                 functionDecl->set_statements( maybeMutate( functionDecl->get_statements(), *this ) );
    363                 --functionNesting;
    364                 return functionDecl;
    365         }
    366        
    367         /// Get a list of type declarations that will affect a layout function
    368         std::list< TypeDecl* > takeOtypeOnly( std::list< TypeDecl* > &decls ) {
    369                 std::list< TypeDecl * > otypeDecls;
    370 
    371                 for ( std::list< TypeDecl* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    372                         if ( (*decl)->get_kind() == TypeDecl::Any ) {
    373                                 otypeDecls.push_back( *decl );
    374                         }
    375                 }
    376                
    377                 return otypeDecls;
    378         }
    379 
    380         /// Adds parameters for otype layout to a function type
    381         void addOtypeParams( FunctionType *layoutFnType, std::list< TypeDecl* > &otypeParams ) {
    382                 BasicType sizeAlignType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    383                
    384                 for ( std::list< TypeDecl* >::const_iterator param = otypeParams.begin(); param != otypeParams.end(); ++param ) {
    385                         TypeInstType paramType( Type::Qualifiers(), (*param)->get_name(), *param );
    386                         layoutFnType->get_parameters().push_back( new ObjectDecl( sizeofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    387                         layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( &paramType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );
    388                 }
    389         }
    390 
    391         /// Builds a layout function declaration
    392         FunctionDecl *buildLayoutFunctionDecl( const std::string &typeName, unsigned int functionNesting, FunctionType *layoutFnType ) {
    393                 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units
    394                 // because each unit generates copies of the default routines for each aggregate.
    395                 FunctionDecl *layoutDecl = new FunctionDecl(
    396                         "__layoutof_" + typeName, functionNesting > 0 ? DeclarationNode::NoStorageClass : DeclarationNode::Static, LinkageSpec::AutoGen, layoutFnType, new CompoundStmt( noLabels ), true, false );
    397                 layoutDecl->fixUniqueId();
    398                 return layoutDecl;
    399         }
    400 
    401         /// Makes a unary operation
    402         Expression *makeOp( const std::string &name, Expression *arg ) {
    403                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    404                 expr->get_args().push_back( arg );
    405                 return expr;
    406         }
    407 
    408         /// Makes a binary operation
    409         Expression *makeOp( const std::string &name, Expression *lhs, Expression *rhs ) {
    410                 UntypedExpr *expr = new UntypedExpr( new NameExpr( name ) );
    411                 expr->get_args().push_back( lhs );
    412                 expr->get_args().push_back( rhs );
    413                 return expr;
    414         }
    415 
    416         /// Returns the dereference of a local pointer variable
    417         Expression *derefVar( ObjectDecl *var ) {
    418                 return makeOp( "*?", new VariableExpr( var ) );
    419         }
    420 
    421         /// makes an if-statement with a single-expression if-block and no then block
    422         Statement *makeCond( Expression *cond, Expression *ifPart ) {
    423                 return new IfStmt( noLabels, cond, new ExprStmt( noLabels, ifPart ), 0 );
    424         }
    425 
    426         /// makes a statement that assigns rhs to lhs if lhs < rhs
    427         Statement *makeAssignMax( Expression *lhs, Expression *rhs ) {
    428                 return makeCond( makeOp( "?<?", lhs, rhs ), makeOp( "?=?", lhs->clone(), rhs->clone() ) );
    429         }
    430 
    431         /// makes a statement that aligns lhs to rhs (rhs should be an integer power of two)
    432         Statement *makeAlignTo( Expression *lhs, Expression *rhs ) {
    433                 // check that the lhs is zeroed out to the level of rhs
    434                 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );
    435                 // if not aligned, increment to alignment
    436                 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );
    437                 return makeCond( ifCond, ifExpr );
    438         }
    439        
    440         /// adds an expression to a compound statement
    441         void addExpr( CompoundStmt *stmts, Expression *expr ) {
    442                 stmts->get_kids().push_back( new ExprStmt( noLabels, expr ) );
    443         }
    444 
    445         /// adds a statement to a compound statement
    446         void addStmt( CompoundStmt *stmts, Statement *stmt ) {
    447                 stmts->get_kids().push_back( stmt );
    448         }
    449        
    450         Declaration *LayoutFunctionBuilder::mutate( StructDecl *structDecl ) {
    451                 // do not generate layout function for "empty" tag structs
    452                 if ( structDecl->get_members().empty() ) return structDecl;
    453 
    454                 // get parameters that can change layout, exiting early if none
    455                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );
    456                 if ( otypeParams.empty() ) return structDecl;
    457 
    458                 // build layout function signature
    459                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    460                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    461                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    462                
    463                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    464                 layoutFnType->get_parameters().push_back( sizeParam );
    465                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    466                 layoutFnType->get_parameters().push_back( alignParam );
    467                 ObjectDecl *offsetParam = new ObjectDecl( "__offsetof_" + structDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    468                 layoutFnType->get_parameters().push_back( offsetParam );
    469                 addOtypeParams( layoutFnType, otypeParams );
    470 
    471                 // build function decl
    472                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );
    473 
    474                 // calculate struct layout in function body
    475 
    476                 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size
    477                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "0" ) ) ) );
    478                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    479                 unsigned long n_members = 0;
    480                 bool firstMember = true;
    481                 for ( std::list< Declaration* >::const_iterator member = structDecl->get_members().begin(); member != structDecl->get_members().end(); ++member ) {
    482                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    483                         assert( dwt );
    484                         Type *memberType = dwt->get_type();
    485 
    486                         if ( firstMember ) {
    487                                 firstMember = false;
    488                         } else {
    489                                 // make sure all members after the first (automatically aligned at 0) are properly padded for alignment
    490                                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );
    491                         }
    492                        
    493                         // place current size in the current offset index
    494                         addExpr( layoutDecl->get_statements(), makeOp( "?=?", makeOp( "?[?]", new VariableExpr( offsetParam ), new ConstantExpr( Constant::from( n_members ) ) ),
    495                                                                               derefVar( sizeParam ) ) );
    496                         ++n_members;
    497 
    498                         // add member size to current size
    499                         addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    500                        
    501                         // take max of member alignment and global alignment
    502                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
    503                 }
    504                 // make sure the type is end-padded to a multiple of its alignment
    505                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    506 
    507                 addDeclarationAfter( layoutDecl );
    508                 return structDecl;
    509         }
    510        
    511         Declaration *LayoutFunctionBuilder::mutate( UnionDecl *unionDecl ) {
    512                 // do not generate layout function for "empty" tag unions
    513                 if ( unionDecl->get_members().empty() ) return unionDecl;
    514                
    515                 // get parameters that can change layout, exiting early if none
    516                 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );
    517                 if ( otypeParams.empty() ) return unionDecl;
    518 
    519                 // build layout function signature
    520                 FunctionType *layoutFnType = new FunctionType( Type::Qualifiers(), false );
    521                 BasicType *sizeAlignType = new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt );
    522                 PointerType *sizeAlignOutType = new PointerType( Type::Qualifiers(), sizeAlignType );
    523                
    524                 ObjectDecl *sizeParam = new ObjectDecl( "__sizeof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType, 0 );
    525                 layoutFnType->get_parameters().push_back( sizeParam );
    526                 ObjectDecl *alignParam = new ObjectDecl( "__alignof_" + unionDecl->get_name(), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignOutType->clone(), 0 );
    527                 layoutFnType->get_parameters().push_back( alignParam );
    528                 addOtypeParams( layoutFnType, otypeParams );
    529 
    530                 // build function decl
    531                 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );
    532 
    533                 // calculate union layout in function body
    534                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( sizeParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    535                 addExpr( layoutDecl->get_statements(), makeOp( "?=?", derefVar( alignParam ), new ConstantExpr( Constant( sizeAlignType->clone(), "1" ) ) ) );
    536                 for ( std::list< Declaration* >::const_iterator member = unionDecl->get_members().begin(); member != unionDecl->get_members().end(); ++member ) {
    537                         DeclarationWithType *dwt = dynamic_cast< DeclarationWithType * >( *member );
    538                         assert( dwt );
    539                         Type *memberType = dwt->get_type();
    540                        
    541                         // take max member size and global size
    542                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );
    543                        
    544                         // take max of member alignment and global alignment
    545                         addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( alignParam ), new AlignofExpr( memberType->clone() ) ) );
    546                 }
    547                 // make sure the type is end-padded to a multiple of its alignment
    548                 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );
    549 
    550                 addDeclarationAfter( layoutDecl );
    551                 return unionDecl;
    552         }
    553        
    554208        ////////////////////////////////////////// Pass1 ////////////////////////////////////////////////////
    555209
     
    591245                }
    592246
    593                 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {}
     247                Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {
     248                        adapters.push(AdapterMap());
     249                }
    594250
    595251                /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise
     
    694350                                } // for
    695351
     352                                AdapterMap & adapters = Pass1::adapters.top();
    696353                                for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) {
    697354                                        std::string mangleName = mangleAdapterName( *funType, scopeTyVars );
     
    1115772                                        mangleName += makePolyMonoSuffix( originalFunction, exprTyVars );
    1116773
    1117                                         typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;
    1118                                         AdapterIter adapter = adapters.find( mangleName );
     774                                        AdapterMap & adapters = Pass1::adapters.top();
     775                                        AdapterMap::iterator adapter = adapters.find( mangleName );
    1119776                                        if ( adapter == adapters.end() ) {
    1120777                                                // adapter has not been created yet in the current scope, so define it
    1121778                                                FunctionDecl *newAdapter = makeAdapter( *funType, realFunction, mangleName, exprTyVars );
    1122                                                 std::pair< AdapterIter, bool > answer = adapters.insert( std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    1123                                                 adapter = answer.first;
     779                                                adapter = adapters.insert( adapters.begin(), std::pair< std::string, DeclarationWithType *>( mangleName, newAdapter ) );
    1124780                                                stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) );
    1125781                                        } // if
     
    15001156
    15011157                void Pass1::doBeginScope() {
    1502                         adapters.beginScope();
     1158                        // push a copy of the current map
     1159                        adapters.push(adapters.top());
    15031160                        scopedAssignOps.beginScope();
    15041161                }
    15051162
    15061163                void Pass1::doEndScope() {
    1507                         adapters.endScope();
     1164                        adapters.pop();
    15081165                        scopedAssignOps.endScope();
    15091166                }
     
    16521309                }
    16531310
    1654 //////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////
    1655 
    1656                 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type
    1657                 bool makeSubstitutions( const std::list< TypeDecl* >& baseParams, const std::list< Expression* >& params, std::list< TypeExpr* >& out ) {
    1658                         bool allConcrete = true;  // will finish the substitution list even if they're not all concrete
    1659 
    1660                         // substitute concrete types for given parameters, and incomplete types for placeholders
    1661                         std::list< TypeDecl* >::const_iterator baseParam = baseParams.begin();
    1662                         std::list< Expression* >::const_iterator param = params.begin();
    1663                         for ( ; baseParam != baseParams.end() && param != params.end(); ++baseParam, ++param ) {
    1664         //                      switch ( (*baseParam)->get_kind() ) {
    1665         //                      case TypeDecl::Any: {   // any type is a valid substitution here; complete types can be used to instantiate generics
    1666                                         TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param );
    1667                                         assert(paramType && "Aggregate parameters should be type expressions");
    1668                                         out.push_back( paramType->clone() );
    1669                                         // check that the substituted type isn't a type variable itself
    1670                                         if ( dynamic_cast< TypeInstType* >( paramType->get_type() ) ) {
    1671                                                 allConcrete = false;
    1672                                         }
    1673         //                              break;
    1674         //                      }
    1675         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1676         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1677         //                              break;
    1678         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1679         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1680         //                              break;
    1681         //                      }
    1682                         }
    1683 
    1684                         // if any parameters left over, not done
    1685                         if ( baseParam != baseParams.end() ) return false;
    1686         //              // if not enough parameters given, substitute remaining incomplete types for placeholders
    1687         //              for ( ; baseParam != baseParams.end(); ++baseParam ) {
    1688         //                      switch ( (*baseParam)->get_kind() ) {
    1689         //                      case TypeDecl::Any:    // no more substitutions here, fail early
    1690         //                              return false;
    1691         //                      case TypeDecl::Dtype:  // dtype can be consistently replaced with void [only pointers, which become void*]
    1692         //                              out.push_back( new TypeExpr( new VoidType( Type::Qualifiers() ) ) );
    1693         //                              break;
    1694         //                      case TypeDecl::Ftype:  // pointer-to-ftype can be consistently replaced with void (*)(void) [similar to dtype]
    1695         //                              out.push_back( new TypeExpr( new FunctionType( Type::Qualifiers(), false ) ) );
    1696         //                              break;
    1697         //                      }
    1698         //              }
    1699 
    1700                         return allConcrete;
    1701                 }
    1702 
    1703                 /// Substitutes types of members of in according to baseParams => typeSubs, appending the result to out
    1704                 void substituteMembers( const std::list< Declaration* >& in, const std::list< TypeDecl* >& baseParams, const std::list< TypeExpr* >& typeSubs,
    1705                                                                 std::list< Declaration* >& out ) {
    1706                         // substitute types into new members
    1707                         TypeSubstitution subs( baseParams.begin(), baseParams.end(), typeSubs.begin() );
    1708                         for ( std::list< Declaration* >::const_iterator member = in.begin(); member != in.end(); ++member ) {
    1709                                 Declaration *newMember = (*member)->clone();
    1710                                 subs.apply(newMember);
    1711                                 out.push_back( newMember );
    1712                         }
    1713                 }
    1714 
    1715                 Type* GenericInstantiator::mutate( StructInstType *inst ) {
    1716                         // mutate subtypes
    1717                         Type *mutated = Mutator::mutate( inst );
    1718                         inst = dynamic_cast< StructInstType* >( mutated );
    1719                         if ( ! inst ) return mutated;
    1720 
    1721                         // exit early if no need for further mutation
    1722                         if ( inst->get_parameters().empty() ) return inst;
    1723                         assert( inst->get_baseParameters() && "Base struct has parameters" );
    1724 
    1725                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1726                         std::list< TypeExpr* > typeSubs;
    1727                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1728                                 deleteAll( typeSubs );
    1729                                 return inst;
    1730                         }
    1731 
    1732                         // make concrete instantiation of generic type
    1733                         StructDecl *concDecl = lookup( inst, typeSubs );
    1734                         if ( ! concDecl ) {
    1735                                 // set concDecl to new type, insert type declaration into statements to add
    1736                                 concDecl = new StructDecl( typeNamer.newName( inst->get_name() ) );
    1737                                 substituteMembers( inst->get_baseStruct()->get_members(), *inst->get_baseParameters(), typeSubs,        concDecl->get_members() );
    1738                                 DeclMutator::addDeclaration( concDecl );
    1739                                 insert( inst, typeSubs, concDecl );
    1740                         }
    1741                         StructInstType *newInst = new StructInstType( inst->get_qualifiers(), concDecl->get_name() );
    1742                         newInst->set_baseStruct( concDecl );
    1743 
    1744                         deleteAll( typeSubs );
    1745                         delete inst;
    1746                         return newInst;
    1747                 }
    1748 
    1749                 Type* GenericInstantiator::mutate( UnionInstType *inst ) {
    1750                         // mutate subtypes
    1751                         Type *mutated = Mutator::mutate( inst );
    1752                         inst = dynamic_cast< UnionInstType* >( mutated );
    1753                         if ( ! inst ) return mutated;
    1754 
    1755                         // exit early if no need for further mutation
    1756                         if ( inst->get_parameters().empty() ) return inst;
    1757                         assert( inst->get_baseParameters() && "Base union has parameters" );
    1758 
    1759                         // check if type can be concretely instantiated; put substitutions into typeSubs
    1760                         std::list< TypeExpr* > typeSubs;
    1761                         if ( ! makeSubstitutions( *inst->get_baseParameters(), inst->get_parameters(), typeSubs ) ) {
    1762                                 deleteAll( typeSubs );
    1763                                 return inst;
    1764                         }
    1765 
    1766                         // make concrete instantiation of generic type
    1767                         UnionDecl *concDecl = lookup( inst, typeSubs );
    1768                         if ( ! concDecl ) {
    1769                                 // set concDecl to new type, insert type declaration into statements to add
    1770                                 concDecl = new UnionDecl( typeNamer.newName( inst->get_name() ) );
    1771                                 substituteMembers( inst->get_baseUnion()->get_members(), *inst->get_baseParameters(), typeSubs, concDecl->get_members() );
    1772                                 DeclMutator::addDeclaration( concDecl );
    1773                                 insert( inst, typeSubs, concDecl );
    1774                         }
    1775                         UnionInstType *newInst = new UnionInstType( inst->get_qualifiers(), concDecl->get_name() );
    1776                         newInst->set_baseUnion( concDecl );
    1777 
    1778                         deleteAll( typeSubs );
    1779                         delete inst;
    1780                         return newInst;
    1781                 }
    1782 
    1783         //      /// Gets the base struct or union declaration for a member expression; NULL if not applicable
    1784         //      AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {
    1785         //              // get variable for member aggregate
    1786         //              VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );
    1787         //              if ( ! varExpr ) return NULL;
    1788         //
    1789         //              // get object for variable
    1790         //              ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );
    1791         //              if ( ! objectDecl ) return NULL;
    1792         //
    1793         //              // get base declaration from object type
    1794         //              Type *objectType = objectDecl->get_type();
    1795         //              StructInstType *structType = dynamic_cast< StructInstType* >( objectType );
    1796         //              if ( structType ) return structType->get_baseStruct();
    1797         //              UnionInstType *unionType = dynamic_cast< UnionInstType* >( objectType );
    1798         //              if ( unionType ) return unionType->get_baseUnion();
    1799         //
    1800         //              return NULL;
    1801         //      }
    1802         //
    1803         //      /// Finds the declaration with the given name, returning decls.end() if none such
    1804         //      std::list< Declaration* >::const_iterator findDeclNamed( const std::list< Declaration* > &decls, const std::string &name ) {
    1805         //              for( std::list< Declaration* >::const_iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    1806         //                      if ( (*decl)->get_name() == name ) return decl;
    1807         //              }
    1808         //              return decls.end();
    1809         //      }
    1810         //
    1811         //      Expression* Instantiate::mutate( MemberExpr *memberExpr ) {
    1812         //              // mutate, exiting early if no longer MemberExpr
    1813         //              Expression *expr = Mutator::mutate( memberExpr );
    1814         //              memberExpr = dynamic_cast< MemberExpr* >( expr );
    1815         //              if ( ! memberExpr ) return expr;
    1816         //
    1817         //              // get declaration of member and base declaration of member, exiting early if not found
    1818         //              AggregateDecl *memberBase = getMemberBaseDecl( memberExpr );
    1819         //              if ( ! memberBase ) return memberExpr;
    1820         //              DeclarationWithType *memberDecl = memberExpr->get_member();
    1821         //              std::list< Declaration* >::const_iterator baseIt = findDeclNamed( memberBase->get_members(), memberDecl->get_name() );
    1822         //              if ( baseIt == memberBase->get_members().end() ) return memberExpr;
    1823         //              DeclarationWithType *baseDecl = dynamic_cast< DeclarationWithType* >( *baseIt );
    1824         //              if ( ! baseDecl ) return memberExpr;
    1825         //
    1826         //              // check if stated type of the member is not the type of the member's declaration; if so, need a cast
    1827         //              // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker
    1828         //              SymTab::Indexer dummy;
    1829         //              if ( ResolvExpr::typesCompatible( memberDecl->get_type(), baseDecl->get_type(), dummy ) ) return memberExpr;
    1830         //              else return new CastExpr( memberExpr, memberDecl->get_type() );
    1831         //      }
    1832 
    1833                 void GenericInstantiator::doBeginScope() {
    1834                         DeclMutator::doBeginScope();
    1835                         instantiations.beginScope();
    1836                 }
    1837 
    1838                 void GenericInstantiator::doEndScope() {
    1839                         DeclMutator::doEndScope();
    1840                         instantiations.endScope();
    1841                 }
    1842 
    18431311////////////////////////////////////////// MemberExprFixer ////////////////////////////////////////////////////
    18441312
  • src/GenPoly/DeclMutator.cc

    rae357ec rb63e376  
    2424        }
    2525
    26         DeclMutator::DeclMutator() : Mutator(), declsToAdd(1), declsToAddAfter(1) {}
     26        DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) {}
    2727
    2828        DeclMutator::~DeclMutator() {}
    2929       
    3030        void DeclMutator::mutateDeclarationList( std::list< Declaration* > &decls ) {
    31                 for ( std::list< Declaration* >::iterator decl = decls.begin(); ; ++decl ) {
    32                         // splice in new declarations after previous decl
    33                         decls.splice( decl, declsToAddAfter.back() );
    34 
    35                         if ( decl == decls.end() ) break;
    36                        
     31                for ( std::list< Declaration* >::iterator decl = decls.begin(); decl != decls.end(); ++decl ) {
    3732                        // run mutator on declaration
    3833                        *decl = maybeMutate( *decl, *this );
     
    4439
    4540        void DeclMutator::doBeginScope() {
    46                 // add new decl lists for inside of scope
     41                // add new decl list for inside of scope
    4742                declsToAdd.resize( declsToAdd.size()+1 );
    48                 declsToAddAfter.resize( declsToAddAfter.size()+1 );
    4943        }
    5044
     
    5549                newBack->splice( newBack->end(), *back );
    5650                declsToAdd.pop_back();
    57                
    58                 back = declsToAddAfter.rbegin();
    59                 newBack = back + 1;
    60                 newBack->splice( newBack->end(), *back );
    61                 declsToAddAfter.pop_back();
    6251        }
    6352
     
    7261                stmt = maybeMutate( stmt, *this );
    7362                // return if no declarations to add
    74                 if ( declsToAdd.back().empty() && declsToAddAfter.back().empty() ) {
    75                         doEndScope();
    76                         return stmt;
    77                 }
     63                if ( declsToAdd.back().empty() ) return stmt;
    7864
    7965                // otherwise add declarations to new compound statement
     
    8571                declsToAdd.back().clear();
    8672
    87                 // add mutated statement
     73                doEndScope();
     74
     75                // add mutated statement and return
    8876                compound->get_kids().push_back( stmt );
    89 
    90                 // add declarations after to new compound statement
    91                 for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) {
    92                         DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
    93                         compound->get_kids().push_back( declStmt );
    94                 }
    95                 declsToAddAfter.back().clear();
    96 
    97                 doEndScope();
    9877                return compound;
    9978        }
     
    10180        void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) {
    10281                doBeginScope();
    103 
    10482               
    105                 for ( std::list< Statement* >::iterator stmt = stmts.begin(); ; ++stmt ) {
    106                         // add any new declarations after the previous statement
    107                         for ( std::list< Declaration* >::iterator decl = declsToAddAfter.back().begin(); decl != declsToAddAfter.back().end(); ++decl ) {
    108                                 DeclStmt *declStmt = new DeclStmt( noLabels, *decl );
    109                                 stmts.insert( stmt, declStmt );
    110                         }
    111                         declsToAddAfter.back().clear();
    112 
    113                         if ( stmt == stmts.end() ) break;
    114                        
     83                for ( std::list< Statement* >::iterator stmt = stmts.begin(); stmt != stmts.end(); ++stmt ) {
    11584                        // run mutator on statement
    11685                        *stmt = maybeMutate( *stmt, *this );
     
    12392                        declsToAdd.back().clear();
    12493                }
    125                
     94
    12695                doEndScope();
    12796        }
     
    12998        void DeclMutator::addDeclaration( Declaration *decl ) {
    13099                declsToAdd.back().push_back( decl );
    131         }
    132 
    133         void DeclMutator::addDeclarationAfter( Declaration *decl ) {
    134                 declsToAddAfter.back().push_back( decl );
    135100        }
    136101
  • src/GenPoly/DeclMutator.h

    rae357ec rb63e376  
    5555                /// Add a declaration to the list to be added before the current position
    5656                void addDeclaration( Declaration* decl );
    57                 /// Add a declaration to the list to be added after the current position
    58                 void addDeclarationAfter( Declaration* decl );
    5957        private:
    6058                /// A stack of declarations to add before the current declaration or statement
    6159                std::vector< std::list< Declaration* > > declsToAdd;
    62                 /// A stack of declarations to add after the current declaration or statement
    63                 std::vector< std::list< Declaration* > > declsToAddAfter;
    6460        };
    6561} // namespace
  • src/GenPoly/module.mk

    rae357ec rb63e376  
    2323       GenPoly/CopyParams.cc \
    2424       GenPoly/FindFunction.cc \
     25       GenPoly/InstantiateGeneric.cc \
    2526       GenPoly/DeclMutator.cc
  • src/Makefile.in

    rae357ec rb63e376  
    122122        GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \
    123123        GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \
     124        GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \
    124125        GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \
    125126        InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \
     
    153154        ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \
    154155        ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \
     156        SymTab/driver_cfa_cpp-IdTable.$(OBJEXT) \
    155157        SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \
    156158        SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \
     
    345347        GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \
    346348        GenPoly/CopyParams.cc GenPoly/FindFunction.cc \
    347         GenPoly/DeclMutator.cc InitTweak/RemoveInit.cc \
    348         Parser/parser.yy Parser/lex.ll Parser/TypedefTable.cc \
    349         Parser/ParseNode.cc Parser/DeclarationNode.cc \
    350         Parser/ExpressionNode.cc Parser/StatementNode.cc \
    351         Parser/InitializerNode.cc Parser/TypeData.cc \
    352         Parser/LinkageSpec.cc Parser/parseutility.cc Parser/Parser.cc \
     349        GenPoly/InstantiateGeneric.cc GenPoly/DeclMutator.cc \
     350        InitTweak/RemoveInit.cc Parser/parser.yy Parser/lex.ll \
     351        Parser/TypedefTable.cc Parser/ParseNode.cc \
     352        Parser/DeclarationNode.cc Parser/ExpressionNode.cc \
     353        Parser/StatementNode.cc Parser/InitializerNode.cc \
     354        Parser/TypeData.cc Parser/LinkageSpec.cc \
     355        Parser/parseutility.cc Parser/Parser.cc \
    353356        ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \
    354357        ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \
     
    359362        ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \
    360363        ResolvExpr/PolyCost.cc ResolvExpr/Occurs.cc \
    361         ResolvExpr/TypeEnvironment.cc SymTab/Indexer.cc \
    362         SymTab/Mangler.cc SymTab/Validate.cc SymTab/FixFunction.cc \
    363         SymTab/ImplementationType.cc SymTab/TypeEquality.cc \
    364         SynTree/Type.cc SynTree/VoidType.cc SynTree/BasicType.cc \
    365         SynTree/PointerType.cc SynTree/ArrayType.cc \
    366         SynTree/FunctionType.cc SynTree/ReferenceToType.cc \
    367         SynTree/TupleType.cc SynTree/TypeofType.cc SynTree/AttrType.cc \
     364        ResolvExpr/TypeEnvironment.cc SymTab/IdTable.cc \
     365        SymTab/Indexer.cc SymTab/Mangler.cc SymTab/Validate.cc \
     366        SymTab/FixFunction.cc SymTab/ImplementationType.cc \
     367        SymTab/TypeEquality.cc SynTree/Type.cc SynTree/VoidType.cc \
     368        SynTree/BasicType.cc SynTree/PointerType.cc \
     369        SynTree/ArrayType.cc SynTree/FunctionType.cc \
     370        SynTree/ReferenceToType.cc SynTree/TupleType.cc \
     371        SynTree/TypeofType.cc SynTree/AttrType.cc \
    368372        SynTree/VarArgsType.cc SynTree/Constant.cc \
    369373        SynTree/Expression.cc SynTree/TupleExpr.cc \
     
    552556        GenPoly/$(DEPDIR)/$(am__dirstamp)
    553557GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT):  \
     558        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
     559GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT):  \
    554560        GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp)
    555561GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \
     
    658664        @$(MKDIR_P) SymTab/$(DEPDIR)
    659665        @: > SymTab/$(DEPDIR)/$(am__dirstamp)
     666SymTab/driver_cfa_cpp-IdTable.$(OBJEXT): SymTab/$(am__dirstamp) \
     667        SymTab/$(DEPDIR)/$(am__dirstamp)
    660668SymTab/driver_cfa_cpp-Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \
    661669        SymTab/$(DEPDIR)/$(am__dirstamp)
     
    788796        -rm -f GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT)
    789797        -rm -f GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT)
     798        -rm -f GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT)
    790799        -rm -f GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT)
    791800        -rm -f GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT)
     
    823832        -rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT)
    824833        -rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT)
     834        -rm -f SymTab/driver_cfa_cpp-IdTable.$(OBJEXT)
    825835        -rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT)
    826836        -rm -f SymTab/driver_cfa_cpp-Indexer.$(OBJEXT)
     
    893903@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@
    894904@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-GenPoly.Po@am__quote@
     905@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po@am__quote@
    895906@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@
    896907@AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po@am__quote@
     
    928939@AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@
    929940@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-FixFunction.Po@am__quote@
     941@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po@am__quote@
    930942@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@
    931943@AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@
     
    13521364@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-FindFunction.obj `if test -f 'GenPoly/FindFunction.cc'; then $(CYGPATH_W) 'GenPoly/FindFunction.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/FindFunction.cc'; fi`
    13531365
     1366GenPoly/driver_cfa_cpp-InstantiateGeneric.o: GenPoly/InstantiateGeneric.cc
     1367@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
     1368@am__fastdepCXX_TRUE@   $(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po
     1369@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.o' libtool=no @AMDEPBACKSLASH@
     1370@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1371@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.o `test -f 'GenPoly/InstantiateGeneric.cc' || echo '$(srcdir)/'`GenPoly/InstantiateGeneric.cc
     1372
     1373GenPoly/driver_cfa_cpp-InstantiateGeneric.obj: GenPoly/InstantiateGeneric.cc
     1374@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-InstantiateGeneric.obj -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`
     1375@am__fastdepCXX_TRUE@   $(am__mv) GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Tpo GenPoly/$(DEPDIR)/driver_cfa_cpp-InstantiateGeneric.Po
     1376@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='GenPoly/InstantiateGeneric.cc' object='GenPoly/driver_cfa_cpp-InstantiateGeneric.obj' libtool=no @AMDEPBACKSLASH@
     1377@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1378@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o GenPoly/driver_cfa_cpp-InstantiateGeneric.obj `if test -f 'GenPoly/InstantiateGeneric.cc'; then $(CYGPATH_W) 'GenPoly/InstantiateGeneric.cc'; else $(CYGPATH_W) '$(srcdir)/GenPoly/InstantiateGeneric.cc'; fi`
     1379
    13541380GenPoly/driver_cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc
    13551381@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT GenPoly/driver_cfa_cpp-DeclMutator.o -MD -MP -MF GenPoly/$(DEPDIR)/driver_cfa_cpp-DeclMutator.Tpo -c -o GenPoly/driver_cfa_cpp-DeclMutator.o `test -f 'GenPoly/DeclMutator.cc' || echo '$(srcdir)/'`GenPoly/DeclMutator.cc
     
    17851811@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
    17861812@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o ResolvExpr/driver_cfa_cpp-TypeEnvironment.obj `if test -f 'ResolvExpr/TypeEnvironment.cc'; then $(CYGPATH_W) 'ResolvExpr/TypeEnvironment.cc'; else $(CYGPATH_W) '$(srcdir)/ResolvExpr/TypeEnvironment.cc'; fi`
     1813
     1814SymTab/driver_cfa_cpp-IdTable.o: SymTab/IdTable.cc
     1815@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-IdTable.o -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo -c -o SymTab/driver_cfa_cpp-IdTable.o `test -f 'SymTab/IdTable.cc' || echo '$(srcdir)/'`SymTab/IdTable.cc
     1816@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po
     1817@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/IdTable.cc' object='SymTab/driver_cfa_cpp-IdTable.o' libtool=no @AMDEPBACKSLASH@
     1818@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1819@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-IdTable.o `test -f 'SymTab/IdTable.cc' || echo '$(srcdir)/'`SymTab/IdTable.cc
     1820
     1821SymTab/driver_cfa_cpp-IdTable.obj: SymTab/IdTable.cc
     1822@am__fastdepCXX_TRUE@   $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -MT SymTab/driver_cfa_cpp-IdTable.obj -MD -MP -MF SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo -c -o SymTab/driver_cfa_cpp-IdTable.obj `if test -f 'SymTab/IdTable.cc'; then $(CYGPATH_W) 'SymTab/IdTable.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/IdTable.cc'; fi`
     1823@am__fastdepCXX_TRUE@   $(am__mv) SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Tpo SymTab/$(DEPDIR)/driver_cfa_cpp-IdTable.Po
     1824@AMDEP_TRUE@@am__fastdepCXX_FALSE@      source='SymTab/IdTable.cc' object='SymTab/driver_cfa_cpp-IdTable.obj' libtool=no @AMDEPBACKSLASH@
     1825@AMDEP_TRUE@@am__fastdepCXX_FALSE@      DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@
     1826@am__fastdepCXX_FALSE@  $(CXX) $(DEFS) $(DEFAULT_INCLUDES) $(INCLUDES) $(AM_CPPFLAGS) $(CPPFLAGS) $(driver_cfa_cpp_CXXFLAGS) $(CXXFLAGS) -c -o SymTab/driver_cfa_cpp-IdTable.obj `if test -f 'SymTab/IdTable.cc'; then $(CYGPATH_W) 'SymTab/IdTable.cc'; else $(CYGPATH_W) '$(srcdir)/SymTab/IdTable.cc'; fi`
    17871827
    17881828SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc
  • src/SymTab/Indexer.cc

    rae357ec rb63e376  
    1414//
    1515
    16 #include "Indexer.h"
    17 
    18 #include <string>
    19 #include <typeinfo>
    20 #include <unordered_map>
    21 #include <utility>
    22 
    23 #include "Mangler.h"
    24 
    25 #include "Common/utility.h"
    26 
    27 #include "ResolvExpr/typeops.h"
    28 
    2916#include "SynTree/Declaration.h"
    3017#include "SynTree/Type.h"
     
    3219#include "SynTree/Initializer.h"
    3320#include "SynTree/Statement.h"
     21#include "Indexer.h"
     22#include <typeinfo>
     23#include "Common/utility.h"
    3424
    3525#define debugPrint(x) if ( doDebug ) { std::cout << x; }
     
    4333        }
    4434
    45         typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable;
    46         typedef std::unordered_map< std::string, MangleTable > IdTable;
    47         typedef std::unordered_map< std::string, NamedTypeDecl* > TypeTable;
    48         typedef std::unordered_map< std::string, StructDecl* > StructTable;
    49         typedef std::unordered_map< std::string, EnumDecl* > EnumTable;
    50         typedef std::unordered_map< std::string, UnionDecl* > UnionTable;
    51         typedef std::unordered_map< std::string, TraitDecl* > TraitTable;
    52 
    53         void dump( const IdTable &table, std::ostream &os ) {
    54                 for ( IdTable::const_iterator id = table.begin(); id != table.end(); ++id ) {
    55                         for ( MangleTable::const_iterator mangle = id->second.begin(); mangle != id->second.end(); ++mangle ) {
    56                                 os << mangle->second << std::endl;
    57                         }
    58                 }
    59         }
    60        
    61         template< typename Decl >
    62         void dump( const std::unordered_map< std::string, Decl* > &table, std::ostream &os ) {
    63                 for ( typename std::unordered_map< std::string, Decl* >::const_iterator it = table.begin(); it != table.end(); ++it ) {
    64                         os << it->second << std::endl;
    65                 } // for
    66         }
    67        
    68         struct Indexer::Impl {
    69                 Impl( unsigned long _scope ) : refCount(1), scope( _scope ), size( 0 ), base(),
    70                                 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
    71                 Impl( unsigned long _scope, Indexer &&_base ) : refCount(1), scope( _scope ), size( 0 ), base( _base ),
    72                                 idTable(), typeTable(), structTable(), enumTable(), unionTable(), traitTable() {}
    73                 unsigned long refCount;   ///< Number of references to these tables
    74                 unsigned long scope;      ///< Scope these tables are associated with
    75                 unsigned long size;       ///< Number of elements stored in this table
    76                 const Indexer base;       ///< Base indexer this extends
    77                
    78                 IdTable idTable;          ///< Identifier namespace
    79                 TypeTable typeTable;      ///< Type namespace
    80                 StructTable structTable;  ///< Struct namespace
    81                 EnumTable enumTable;      ///< Enum namespace
    82                 UnionTable unionTable;    ///< Union namespace
    83                 TraitTable traitTable;    ///< Trait namespace
    84         };
    85 
    86         Indexer::Impl *Indexer::newRef( Indexer::Impl *toClone ) {
    87                 if ( ! toClone ) return 0;
    88 
    89                 // shorten the search chain by skipping empty links
    90                 Indexer::Impl *ret = toClone->size == 0 ? toClone->base.tables : toClone;
    91                 if ( ret ) { ++ret->refCount; }
    92 
    93                 return ret;
    94         }
    95 
    96         void Indexer::deleteRef( Indexer::Impl *toFree ) {
    97                 if ( ! toFree ) return;
    98 
    99                 if ( --toFree->refCount == 0 ) delete toFree;
    100         }
    101 
    102         void Indexer::makeWritable() {
    103                 if ( ! tables ) {
    104                         // create indexer if not yet set
    105                         tables = new Indexer::Impl( scope );
    106                 } else if ( tables->refCount > 1 || tables->scope != scope ) {
    107                         // make this indexer the base of a fresh indexer at the current scope
    108                         tables = new Indexer::Impl( scope, std::move( *this ) );
    109                 }
    110         }
    111 
    112         Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug ) {}
    113 
    114         Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug ) {}
    115 
    116         Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug ) {
    117                 that.tables = 0;
    118         }
    119 
    120         Indexer::~Indexer() {
    121                 deleteRef( tables );
    122         }
    123 
    124         Indexer& Indexer::operator= ( const Indexer &that ) {
    125                 deleteRef( tables );
    126 
    127                 tables = newRef( that.tables );
    128                 scope = that.scope;
    129                 doDebug = that.doDebug;
    130 
    131                 return *this;
    132         }
    133 
    134         Indexer& Indexer::operator= ( Indexer &&that ) {
    135                 deleteRef( tables );
    136 
    137                 tables = that.tables;
    138                 scope = that.scope;
    139                 doDebug = that.doDebug;
    140 
    141                 that.tables = 0;
    142 
    143                 return *this;
    144         }
     35        Indexer::Indexer( bool useDebug ) : doDebug( useDebug ) {}
     36
     37        Indexer::~Indexer() {}
    14538
    14639        void Indexer::visit( ObjectDecl *objectDecl ) {
     
    15245                if ( objectDecl->get_name() != "" ) {
    15346                        debugPrint( "Adding object " << objectDecl->get_name() << std::endl );
    154                         addId( objectDecl );
     47                        idTable.addDecl( objectDecl );
    15548                } // if
    15649        }
     
    15952                if ( functionDecl->get_name() == "" ) return;
    16053                debugPrint( "Adding function " << functionDecl->get_name() << std::endl );
    161                 addId( functionDecl );
     54                idTable.addDecl( functionDecl );
    16255                enterScope();
    16356                maybeAccept( functionDecl->get_functionType(), *this );
     
    19790                leaveScope();
    19891                debugPrint( "Adding type " << typeDecl->get_name() << std::endl );
    199                 addType( typeDecl );
     92                typeTable.add( typeDecl );
    20093                acceptAll( typeDecl->get_assertions(), *this );
    20194        }
     
    207100                leaveScope();
    208101                debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl );
    209                 addType( typeDecl );
     102                typeTable.add( typeDecl );
    210103        }
    211104
     
    215108                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    216109                debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl );
    217                 addStruct( &fwdDecl );
     110                structTable.add( &fwdDecl );
    218111 
    219112                enterScope();
     
    224117                debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl );
    225118                // this addition replaces the forward declaration
    226                 addStruct( aggregateDecl );
     119                structTable.add( aggregateDecl );
    227120        }
    228121
     
    232125                cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() );
    233126                debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl );
    234                 addUnion( &fwdDecl );
     127                unionTable.add( &fwdDecl );
    235128 
    236129                enterScope();
     
    240133 
    241134                debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl );
    242                 addUnion( aggregateDecl );
     135                unionTable.add( aggregateDecl );
    243136        }
    244137
    245138        void Indexer::visit( EnumDecl *aggregateDecl ) {
    246139                debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl );
    247                 addEnum( aggregateDecl );
     140                enumTable.add( aggregateDecl );
    248141                // unlike structs, contexts, and unions, enums inject their members into the global scope
    249142                acceptAll( aggregateDecl->get_members(), *this );
     
    257150 
    258151                debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl );
    259                 addTrait( aggregateDecl );
     152                contextTable.add( aggregateDecl );
    260153        }
    261154
     
    406299
    407300        void Indexer::visit( StructInstType *structInst ) {
    408                 if ( ! lookupStruct( structInst->get_name() ) ) {
     301                if ( ! structTable.lookup( structInst->get_name() ) ) {
    409302                        debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl );
    410                         addStruct( structInst->get_name() );
     303                        structTable.add( structInst->get_name() );
    411304                }
    412305                enterScope();
     
    416309
    417310        void Indexer::visit( UnionInstType *unionInst ) {
    418                 if ( ! lookupUnion( unionInst->get_name() ) ) {
     311                if ( ! unionTable.lookup( unionInst->get_name() ) ) {
    419312                        debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl );
    420                         addUnion( unionInst->get_name() );
     313                        unionTable.add( unionInst->get_name() );
    421314                }
    422315                enterScope();
     
    432325        }
    433326
    434        
    435 
    436         void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const {
    437                 if ( ! tables ) return;
    438 
    439                 IdTable::const_iterator decls = tables->idTable.find( id );
    440                 if ( decls != tables->idTable.end() ) {
    441                         const MangleTable &mangleTable = decls->second;
    442                         for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    443                                 out.push_back( decl->second );
    444                         }
    445                 }
    446                
    447                 // get declarations from base indexers
    448                 tables->base.lookupId( id, out );
     327
     328        void Indexer::lookupId( const std::string &id, std::list< DeclarationWithType* > &list ) const {
     329                idTable.lookupId( id, list );
     330        }
     331
     332        DeclarationWithType* Indexer::lookupId( const std::string &id) const {
     333                return idTable.lookupId(id);
    449334        }
    450335
    451336        NamedTypeDecl *Indexer::lookupType( const std::string &id ) const {
    452                 if ( ! tables ) return 0;
    453 
    454                 TypeTable::const_iterator ret = tables->typeTable.find( id );
    455                 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupType( id );
     337                return typeTable.lookup( id );
    456338        }
    457339
    458340        StructDecl *Indexer::lookupStruct( const std::string &id ) const {
    459                 if ( ! tables ) return 0;
    460 
    461                 StructTable::const_iterator ret = tables->structTable.find( id );
    462                 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStruct( id );
     341                return structTable.lookup( id );
    463342        }
    464343
    465344        EnumDecl *Indexer::lookupEnum( const std::string &id ) const {
    466                 if ( ! tables ) return 0;
    467 
    468                 EnumTable::const_iterator ret = tables->enumTable.find( id );
    469                 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnum( id );
     345                return enumTable.lookup( id );
    470346        }
    471347
    472348        UnionDecl *Indexer::lookupUnion( const std::string &id ) const {
    473                 if ( ! tables ) return 0;
    474 
    475                 UnionTable::const_iterator ret = tables->unionTable.find( id );
    476                 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnion( id );
    477         }
    478 
    479         TraitDecl *Indexer::lookupTrait( const std::string &id ) const {
    480                 if ( ! tables ) return 0;
    481 
    482                 TraitTable::const_iterator ret = tables->traitTable.find( id );
    483                 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTrait( id );
    484         }
    485 
    486         DeclarationWithType *Indexer::lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const {
    487                 if ( ! tables ) return 0;
    488                 if ( tables->scope < scope ) return 0;
    489 
    490                 IdTable::const_iterator decls = tables->idTable.find( id );
    491                 if ( decls != tables->idTable.end() ) {
    492                         const MangleTable &mangleTable = decls->second;
    493                         MangleTable::const_iterator decl = mangleTable.find( mangleName );
    494                         if ( decl != mangleTable.end() ) return decl->second;
    495                 }
    496 
    497                 return tables->base.lookupIdAtScope( id, mangleName, scope );
    498         }
    499 
    500         bool Indexer::hasCDeclWithName( const std::string &id ) const {
    501                 if ( ! tables ) return false;
    502 
    503                 IdTable::const_iterator decls = tables->idTable.find( id );
    504                 if ( decls != tables->idTable.end() ) {
    505                         const MangleTable &mangleTable = decls->second;
    506                         for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) {
    507                                 if ( decl->second->get_linkage() == LinkageSpec::C ) return true;
    508                         }
    509                 }
    510 
    511                 return tables->base.hasCDeclWithName( id );
    512         }
    513        
    514         NamedTypeDecl *Indexer::lookupTypeAtScope( const std::string &id, unsigned long scope ) const {
    515                 if ( ! tables ) return 0;
    516                 if ( tables->scope < scope ) return 0;
    517 
    518                 TypeTable::const_iterator ret = tables->typeTable.find( id );
    519                 return ret != tables->typeTable.end() ? ret->second : tables->base.lookupTypeAtScope( id, scope );
    520         }
    521        
    522         StructDecl *Indexer::lookupStructAtScope( const std::string &id, unsigned long scope ) const {
    523                 if ( ! tables ) return 0;
    524                 if ( tables->scope < scope ) return 0;
    525 
    526                 StructTable::const_iterator ret = tables->structTable.find( id );
    527                 return ret != tables->structTable.end() ? ret->second : tables->base.lookupStructAtScope( id, scope );
    528         }
    529        
    530         EnumDecl *Indexer::lookupEnumAtScope( const std::string &id, unsigned long scope ) const {
    531                 if ( ! tables ) return 0;
    532                 if ( tables->scope < scope ) return 0;
    533 
    534                 EnumTable::const_iterator ret = tables->enumTable.find( id );
    535                 return ret != tables->enumTable.end() ? ret->second : tables->base.lookupEnumAtScope( id, scope );
    536         }
    537        
    538         UnionDecl *Indexer::lookupUnionAtScope( const std::string &id, unsigned long scope ) const {
    539                 if ( ! tables ) return 0;
    540                 if ( tables->scope < scope ) return 0;
    541 
    542                 UnionTable::const_iterator ret = tables->unionTable.find( id );
    543                 return ret != tables->unionTable.end() ? ret->second : tables->base.lookupUnionAtScope( id, scope );
    544         }
    545        
    546         TraitDecl *Indexer::lookupTraitAtScope( const std::string &id, unsigned long scope ) const {
    547                 if ( ! tables ) return 0;
    548                 if ( tables->scope < scope ) return 0;
    549 
    550                 TraitTable::const_iterator ret = tables->traitTable.find( id );
    551                 return ret != tables->traitTable.end() ? ret->second : tables->base.lookupTraitAtScope( id, scope );
    552         }
    553 
    554         bool addedIdConflicts( DeclarationWithType *existing, DeclarationWithType *added ) {
    555                 // if we're giving the same name mangling to things of different types then there is something wrong
    556                 assert( (dynamic_cast<ObjectDecl*>( added ) && dynamic_cast<ObjectDecl*>( existing ) )
    557                         || (dynamic_cast<FunctionDecl*>( added ) && dynamic_cast<FunctionDecl*>( existing ) ) );
    558 
    559                 if ( LinkageSpec::isOverridable( existing->get_linkage() ) ) {
    560                         // new definition shadows the autogenerated one, even at the same scope
    561                         return false;
    562                 } else if ( added->get_linkage() != LinkageSpec::C || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {
    563                         // typesCompatible doesn't really do the right thing here. When checking compatibility of function types,
    564                         // we should ignore outermost pointer qualifiers, except _Atomic?
    565                         FunctionDecl *newentry = dynamic_cast< FunctionDecl* >( added );
    566                         FunctionDecl *oldentry = dynamic_cast< FunctionDecl* >( existing );
    567                         if ( newentry && oldentry ) {
    568                                 if ( newentry->get_statements() && oldentry->get_statements() ) {
    569                                         throw SemanticError( "duplicate function definition for ", added );
    570                                 } // if
    571                         } else {
    572                                 // two objects with the same mangled name defined in the same scope.
    573                                 // both objects must be marked extern or both must be intrinsic for this to be okay
    574                                 // xxx - perhaps it's actually if either is intrinsic then this is okay?
    575                                 //       might also need to be same storage class?
    576                                 ObjectDecl *newobj = dynamic_cast< ObjectDecl* >( added );
    577                                 ObjectDecl *oldobj = dynamic_cast< ObjectDecl* >( existing );
    578                                 if ( newobj->get_storageClass() != DeclarationNode::Extern && oldobj->get_storageClass() != DeclarationNode::Extern ) {
    579                                         throw SemanticError( "duplicate object definition for ", added );
    580                                 } // if
    581                         } // if
    582                 } else {
    583                         throw SemanticError( "duplicate definition for ", added );
    584                 } // if
    585 
    586                 return true;
    587         }
    588        
    589         void Indexer::addId( DeclarationWithType *decl ) {
    590                 makeWritable();
    591 
    592                 const std::string &name = decl->get_name();
    593                 std::string mangleName;
    594                 if ( decl->get_linkage() == LinkageSpec::C ) {
    595                         mangleName = name;
    596                 } else if ( LinkageSpec::isOverridable( decl->get_linkage() ) ) {
    597                         // mangle the name without including the appropriate suffix, so overridable routines are placed into the
    598                         // same "bucket" as their user defined versions.
    599                         mangleName = Mangler::mangle( decl, false );
    600                 } else {
    601                         mangleName = Mangler::mangle( decl );
    602                 } // if
    603 
    604                 DeclarationWithType *existing = lookupIdAtScope( name, mangleName, scope );
    605                 if ( ! existing || ! addedIdConflicts( existing, decl ) ) {
    606                         // this ensures that no two declarations with the same unmangled name both have C linkage
    607                         if ( decl->get_linkage() == LinkageSpec::C && hasCDeclWithName( name ) ) {
    608                                 throw SemanticError( "invalid overload of C function ", decl );
    609                         }
    610                        
    611                         tables->idTable[ name ][ mangleName ] = decl;
    612                         ++tables->size;
    613                 }
    614         }
    615 
    616         bool addedTypeConflicts( NamedTypeDecl *existing, NamedTypeDecl *added ) {
    617                 if ( existing->get_base() == 0 ) {
    618                         return false;
    619                 } else if ( added->get_base() == 0 ) {
    620                         return true;
    621                 } else {
    622                         throw SemanticError( "redeclaration of ", added );
    623                 }
    624         }
    625        
    626         void Indexer::addType( NamedTypeDecl *decl ) {
    627                 makeWritable();
    628 
    629                 const std::string &id = decl->get_name();
    630                 TypeTable::iterator existing = tables->typeTable.find( id );
    631                 if ( existing == tables->typeTable.end() ) {
    632                         NamedTypeDecl *parent = tables->base.lookupTypeAtScope( id, scope );
    633                         if ( ! parent || ! addedTypeConflicts( parent, decl ) ) {
    634                                 tables->typeTable.insert( existing, std::make_pair( id, decl ) );
    635                                 ++tables->size;
    636                         }
    637                 } else {
    638                         if ( ! addedTypeConflicts( existing->second, decl ) ) {
    639                                 existing->second = decl;
    640                         }
    641                 }
    642         }
    643 
    644         bool addedDeclConflicts( AggregateDecl *existing, AggregateDecl *added ) {
    645                 if ( existing->get_members().empty() ) {
    646                         return false;
    647                 } else if ( ! added->get_members().empty() ) {
    648                         throw SemanticError( "redeclaration of ", added );
    649                 } // if
    650                 return true;
    651         }
    652 
    653         void Indexer::addStruct( const std::string &id ) {
    654                 addStruct( new StructDecl( id ) );
    655         }
    656        
    657         void Indexer::addStruct( StructDecl *decl ) {
    658                 makeWritable();
    659 
    660                 const std::string &id = decl->get_name();
    661                 StructTable::iterator existing = tables->structTable.find( id );
    662                 if ( existing == tables->structTable.end() ) {
    663                         StructDecl *parent = tables->base.lookupStructAtScope( id, scope );
    664                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    665                                 tables->structTable.insert( existing, std::make_pair( id, decl ) );
    666                                 ++tables->size;
    667                         }
    668                 } else {
    669                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    670                                 existing->second = decl;
    671                         }
    672                 }
    673         }
    674        
    675         void Indexer::addEnum( EnumDecl *decl ) {
    676                 makeWritable();
    677 
    678                 const std::string &id = decl->get_name();
    679                 EnumTable::iterator existing = tables->enumTable.find( id );
    680                 if ( existing == tables->enumTable.end() ) {
    681                         EnumDecl *parent = tables->base.lookupEnumAtScope( id, scope );
    682                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    683                                 tables->enumTable.insert( existing, std::make_pair( id, decl ) );
    684                                 ++tables->size;
    685                         }
    686                 } else {
    687                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    688                                 existing->second = decl;
    689                         }
    690                 }
    691         }
    692 
    693         void Indexer::addUnion( const std::string &id ) {
    694                 addUnion( new UnionDecl( id ) );
    695         }
    696        
    697         void Indexer::addUnion( UnionDecl *decl ) {
    698                 makeWritable();
    699 
    700                 const std::string &id = decl->get_name();
    701                 UnionTable::iterator existing = tables->unionTable.find( id );
    702                 if ( existing == tables->unionTable.end() ) {
    703                         UnionDecl *parent = tables->base.lookupUnionAtScope( id, scope );
    704                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    705                                 tables->unionTable.insert( existing, std::make_pair( id, decl ) );
    706                                 ++tables->size;
    707                         }
    708                 } else {
    709                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    710                                 existing->second = decl;
    711                         }
    712                 }
    713         }
    714        
    715         void Indexer::addTrait( TraitDecl *decl ) {
    716                 makeWritable();
    717 
    718                 const std::string &id = decl->get_name();
    719                 TraitTable::iterator existing = tables->traitTable.find( id );
    720                 if ( existing == tables->traitTable.end() ) {
    721                         TraitDecl *parent = tables->base.lookupTraitAtScope( id, scope );
    722                         if ( ! parent || ! addedDeclConflicts( parent, decl ) ) {
    723                                 tables->traitTable.insert( existing, std::make_pair( id, decl ) );
    724                                 ++tables->size;
    725                         }
    726                 } else {
    727                         if ( ! addedDeclConflicts( existing->second, decl ) ) {
    728                                 existing->second = decl;
    729                         }
    730                 }
     349                return unionTable.lookup( id );
     350        }
     351
     352        TraitDecl  * Indexer::lookupTrait( const std::string &id ) const {
     353                return contextTable.lookup( id );
    731354        }
    732355
    733356        void Indexer::enterScope() {
    734                 ++scope;
    735                
    736357                if ( doDebug ) {
    737                         std::cout << "--- Entering scope " << scope << std::endl;
    738                 }
     358                        std::cout << "--- Entering scope" << std::endl;
     359                }
     360                idTable.enterScope();
     361                typeTable.enterScope();
     362                structTable.enterScope();
     363                enumTable.enterScope();
     364                unionTable.enterScope();
     365                contextTable.enterScope();
    739366        }
    740367
    741368        void Indexer::leaveScope() {
    742369                using std::cout;
    743 
    744                 assert( scope > 0 && "cannot leave initial scope" );
    745                 --scope;
    746 
    747                 while ( tables && tables->scope > scope ) {
    748                         if ( doDebug ) {
    749                                 cout << "--- Leaving scope " << tables->scope << " containing" << std::endl;
    750                                 dump( tables->idTable, cout );
    751                                 dump( tables->typeTable, cout );
    752                                 dump( tables->structTable, cout );
    753                                 dump( tables->enumTable, cout );
    754                                 dump( tables->unionTable, cout );
    755                                 dump( tables->traitTable, cout );
    756                         }
    757 
    758                         // swap tables for base table until we find one at an appropriate scope
    759                         Indexer::Impl *base = newRef( tables->base.tables );
    760                         deleteRef( tables );
    761                         tables = base;
    762                 }
     370                using std::endl;
     371 
     372                if ( doDebug ) {
     373                        cout << "--- Leaving scope containing" << endl;
     374                        idTable.dump( cout );
     375                        typeTable.dump( cout );
     376                        structTable.dump( cout );
     377                        enumTable.dump( cout );
     378                        unionTable.dump( cout );
     379                        contextTable.dump( cout );
     380                }
     381                idTable.leaveScope();
     382                typeTable.leaveScope();
     383                structTable.leaveScope();
     384                enumTable.leaveScope();
     385                unionTable.leaveScope();
     386                contextTable.leaveScope();
    763387        }
    764388
    765389        void Indexer::print( std::ostream &os, int indent ) const {
    766390            using std::cerr;
    767 
    768             cerr << "===idTable===" << std::endl;
    769             if ( tables ) dump( tables->idTable, os );
    770             cerr << "===typeTable===" << std::endl;
    771             if ( tables ) dump( tables->typeTable, os );
    772             cerr << "===structTable===" << std::endl;
    773             if ( tables ) dump( tables->structTable, os );
    774             cerr << "===enumTable===" << std::endl;
    775             if ( tables ) dump( tables->enumTable, os );
    776             cerr << "===unionTable===" << std::endl;
    777             if ( tables ) dump( tables->unionTable, os );
    778             cerr << "===contextTable===" << std::endl;
    779             if ( tables ) dump( tables->traitTable, os );
     391            using std::endl;
     392
     393            cerr << "===idTable===" << endl;
     394            idTable.dump( os );
     395            cerr << "===typeTable===" << endl;
     396            typeTable.dump( os );
     397            cerr << "===structTable===" << endl;
     398            structTable.dump( os );
     399            cerr << "===enumTable===" << endl;
     400            enumTable.dump( os );
     401            cerr << "===unionTable===" << endl;
     402            unionTable.dump( os );
     403            cerr << "===contextTable===" << endl;
     404            contextTable.dump( os );
     405#if 0
     406                idTable.dump( os );
     407                typeTable.dump( os );
     408                structTable.dump( os );
     409                enumTable.dump( os );
     410                unionTable.dump( os );
     411                contextTable.dump( os );
     412#endif
    780413        }
    781414} // namespace SymTab
  • src/SymTab/Indexer.h

    rae357ec rb63e376  
    2121
    2222#include "SynTree/Visitor.h"
     23#include "IdTable.h"
     24#include "AggregateTable.h"
     25#include "TypeTable.h"
    2326
    2427namespace SymTab {
     
    2629          public:
    2730                Indexer( bool useDebug = false );
    28 
    29                 Indexer( const Indexer &that );
    30                 Indexer( Indexer &&that );
    3131                virtual ~Indexer();
    32                 Indexer& operator= ( const Indexer &that );
    33                 Indexer& operator= ( Indexer &&that );
    3432
    3533                //using Visitor::visit;
     
    8078                void leaveScope();
    8179
    82                 /// Gets all declarations with the given ID
    83                 void lookupId( const std::string &id, std::list< DeclarationWithType* > &out ) const;
    84                 /// Gets the top-most type declaration with the given ID
     80                void lookupId( const std::string &id, std::list< DeclarationWithType* >& ) const;
     81                DeclarationWithType* lookupId( const std::string &id) const;
    8582                NamedTypeDecl *lookupType( const std::string &id ) const;
    86                 /// Gets the top-most struct declaration with the given ID
    8783                StructDecl *lookupStruct( const std::string &id ) const;
    88                 /// Gets the top-most enum declaration with the given ID
    8984                EnumDecl *lookupEnum( const std::string &id ) const;
    90                 /// Gets the top-most union declaration with the given ID
    9185                UnionDecl *lookupUnion( const std::string &id ) const;
    92                 /// Gets the top-most trait declaration with the given ID
    9386                TraitDecl *lookupTrait( const std::string &id ) const;
    9487 
    9588                void print( std::ostream &os, int indent = 0 ) const;
    9689          private:
    97                 /// looks up a specific mangled ID at the given scope
    98                 DeclarationWithType *lookupIdAtScope( const std::string &id, const std::string &mangleName, unsigned long scope ) const;
    99                 /// returns true if there exists a declaration with C linkage and the given name
    100                 bool hasCDeclWithName( const std::string &id ) const;
    101                 // equivalents to lookup functions that only look at tables at scope `scope` (which should be >= tables->scope)
    102                 NamedTypeDecl *lookupTypeAtScope( const std::string &id, unsigned long scope ) const;
    103                 StructDecl *lookupStructAtScope( const std::string &id, unsigned long scope ) const;
    104                 EnumDecl *lookupEnumAtScope( const std::string &id, unsigned long scope ) const;
    105                 UnionDecl *lookupUnionAtScope( const std::string &id, unsigned long scope ) const;
    106                 TraitDecl *lookupTraitAtScope( const std::string &id, unsigned long scope ) const;
    107                
    108                 void addId( DeclarationWithType *decl );
    109                 void addType( NamedTypeDecl *decl );
    110                 void addStruct( const std::string &id );
    111                 void addStruct( StructDecl *decl );
    112                 void addEnum( EnumDecl *decl );
    113                 void addUnion( const std::string &id );
    114                 void addUnion( UnionDecl *decl );
    115                 void addTrait( TraitDecl *decl );
    116                
    117                 struct Impl;
    118                 Impl *tables;         ///< Copy-on-write instance of table data structure
    119                 unsigned long scope;  ///< Scope index of this pointer
    120                 bool doDebug;         ///< Display debugging trace?
    121 
    122                 /// Takes a new ref to a table (returns null if null)
    123                 static Impl *newRef( Impl *toClone );
    124                 /// Clears a ref to a table (does nothing if null)
    125                 static void deleteRef( Impl *toFree );
    126 
    127                 /// Ensures that tables variable is writable (i.e. allocated, uniquely owned by this Indexer, and at the current scope)
    128                 void makeWritable();
     90                IdTable idTable;
     91                TypeTable typeTable;
     92                StructTable structTable;
     93                EnumTable enumTable;
     94                UnionTable unionTable;
     95                TraitTable contextTable;
     96 
     97                bool doDebug;                                   // display debugging trace
    12998        };
    13099} // namespace SymTab
  • src/SymTab/module.mk

    rae357ec rb63e376  
    1515###############################################################################
    1616
    17 SRC += SymTab/Indexer.cc \
     17SRC += SymTab/IdTable.cc \
     18       SymTab/Indexer.cc \
    1819       SymTab/Mangler.cc \
    1920       SymTab/Validate.cc \
  • src/SynTree/Constant.cc

    rae357ec rb63e376  
    1616#include <iostream>
    1717#include <list>
    18 #include <string>
    1918
    2019#include "Constant.h"
     
    2928
    3029Constant::~Constant() { delete type; }
    31 
    32 Constant Constant::from( int i ) {
    33         return Constant( new BasicType( Type::Qualifiers(), BasicType::SignedInt ), std::to_string( i ) );
    34 }
    35 
    36 Constant Constant::from( unsigned long i ) {
    37         return Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), std::to_string( i ) );
    38 }
    39 
    40 Constant Constant::from( double d ) {
    41         return Constant( new BasicType( Type::Qualifiers(), BasicType::Double ), std::to_string( d ) );
    42 }
    4330
    4431Constant *Constant::clone() const { assert( false ); return 0; }
  • src/SynTree/Constant.h

    rae357ec rb63e376  
    3232        void set_value( std::string newValue ) { value = newValue; }
    3333
    34         /// generates an integer constant of the given int
    35         static Constant from( int i );
    36         /// generates an integer constant of the given unsigned long int
    37         static Constant from( unsigned long i );
    38         /// generates a floating point constant of the given double
    39         static Constant from( double d );
    40 
    4134        virtual Constant *clone() const;
    4235        virtual void accept( Visitor &v ) { v.visit( this ); }
Note: See TracChangeset for help on using the changeset viewer.