Changes in / [ae357ec:b63e376]
- Location:
- src
- Files:
-
- 8 added
- 13 edited
-
CodeGen/CodeGenerator.cc (modified) (1 diff)
-
CodeGen/CodeGenerator.h (modified) (1 diff)
-
CodeGen/GenType.cc (modified) (1 diff)
-
GenPoly/Box.cc (modified) (13 diffs)
-
GenPoly/DeclMutator.cc (modified) (8 diffs)
-
GenPoly/DeclMutator.h (modified) (1 diff)
-
GenPoly/InstantiateGeneric.cc (added)
-
GenPoly/InstantiateGeneric.h (added)
-
GenPoly/module.mk (modified) (1 diff)
-
Makefile.in (modified) (12 diffs)
-
SymTab/AggregateTable.h (added)
-
SymTab/IdTable.cc (added)
-
SymTab/IdTable.h (added)
-
SymTab/Indexer.cc (modified) (15 diffs)
-
SymTab/Indexer.h (modified) (3 diffs)
-
SymTab/StackTable.cc (added)
-
SymTab/StackTable.h (added)
-
SymTab/TypeTable.h (added)
-
SymTab/module.mk (modified) (1 diff)
-
SynTree/Constant.cc (modified) (2 diffs)
-
SynTree/Constant.h (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
rae357ec rb63e376 21 21 #include "Parser/ParseNode.h" 22 22 23 #include "SynTree/ Declaration.h"23 #include "SynTree/Type.h" 24 24 #include "SynTree/Expression.h" 25 25 #include "SynTree/Initializer.h" 26 26 #include "SynTree/Statement.h" 27 #include "SynTree/Type.h"28 27 29 28 #include "Common/utility.h" -
src/CodeGen/CodeGenerator.h
rae357ec rb63e376 19 19 #include <list> 20 20 21 #include "SynTree/Declaration.h"22 21 #include "SynTree/SynTree.h" 23 22 #include "SynTree/Visitor.h" 24 25 23 #include "SymTab/Indexer.h" 26 24 -
src/CodeGen/GenType.cc
rae357ec rb63e376 19 19 #include "GenType.h" 20 20 #include "CodeGenerator.h" 21 22 #include "SynTree/ Declaration.h"21 #include "SynTree/Visitor.h" 22 #include "SynTree/Type.h" 23 23 #include "SynTree/Expression.h" 24 #include "SynTree/Type.h"25 #include "SynTree/Visitor.h"26 24 27 25 namespace CodeGen { -
src/GenPoly/Box.cc
rae357ec rb63e376 14 14 // 15 15 16 #include <algorithm>17 #include <iterator>18 #include <list>19 #include <map>20 16 #include <set> 21 17 #include <stack> 22 18 #include <string> 23 #include < utility>24 #include < vector>19 #include <iterator> 20 #include <algorithm> 25 21 #include <cassert> 26 22 27 23 #include "Box.h" 28 #include " DeclMutator.h"24 #include "InstantiateGeneric.h" 29 25 #include "PolyMutator.h" 30 26 #include "FindFunction.h" 31 #include "ScopedMap.h"32 27 #include "ScrubTyVars.h" 33 28 … … 35 30 36 31 #include "SynTree/Constant.h" 37 #include "SynTree/ Declaration.h"32 #include "SynTree/Type.h" 38 33 #include "SynTree/Expression.h" 39 34 #include "SynTree/Initializer.h" 35 #include "SynTree/Statement.h" 40 36 #include "SynTree/Mutator.h" 41 #include "SynTree/Statement.h"42 #include "SynTree/Type.h"43 #include "SynTree/TypeSubstitution.h"44 37 45 38 #include "ResolvExpr/TypeEnvironment.h" … … 47 40 #include "ResolvExpr/typeops.h" 48 41 49 #include "SymTab/Indexer.h"50 42 #include "SymTab/Mangler.h" 51 43 … … 62 54 FunctionType *makeAdapterType( FunctionType *adaptee, const TyVarMap &tyVars ); 63 55 64 /// Key for a unique concrete type; generic base type paired with type parameter list65 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 type103 std::list< Type* > params; ///< Instantiation parameters104 };105 106 /// Maps a concrete type to the some value, accounting for scope107 template< typename Value >108 class InstantiationMap {109 /// Information about a specific instantiation of a generic type110 struct Instantiation {111 ConcreteType key; ///< Instantiation parameters for this type112 Value *value; ///< Value for this instantiation113 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 them118 typedef std::map< AggregateDecl*, std::vector< Instantiation > > Scope;119 120 std::vector< Scope > scopes; ///< list of scopes, from outermost to innermost121 122 public:123 /// Starts a new scope124 void beginScope() {125 Scope scope;126 scopes.push_back(scope);127 }128 129 /// Ends a scope130 void endScope() {131 scopes.pop_back();132 }133 134 /// Default constructor initializes with one scope135 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 out143 for ( typename std::vector< Scope >::const_reverse_iterator scope = scopes.rbegin(); scope != scopes.rend(); ++scope ) {144 // skip scope if no instantiations of this generic type145 typename Scope::const_iterator insts = scope->find( generic );146 if ( insts == scope->end() ) continue;147 // look through instantiations for matches to concrete type148 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 found153 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 scope161 void insert( AggregateDecl *generic, const std::list< TypeExpr* > ¶ms, 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 types171 class LayoutFunctionBuilder : public DeclMutator {172 unsigned int functionNesting; // current level of nested functions173 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 181 56 /// 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 182 57 class Pass1 : public PolyMutator { … … 225 100 ObjectDecl *makeTemporary( Type *type ); 226 101 102 typedef std::map< std::string, DeclarationWithType *> AdapterMap; 227 103 std::map< std::string, DeclarationWithType *> assignOps; 228 104 ResolvExpr::TypeMap< DeclarationWithType > scopedAssignOps; 229 ScopedMap< std::string, DeclarationWithType*> adapters;105 std::stack< AdapterMap > adapters; 230 106 DeclarationWithType *retval; 231 107 bool useRetval; … … 248 124 249 125 std::map< UniqueId, std::string > adapterName; 250 };251 252 /// Mutator pass that replaces concrete instantiations of generic types with actual struct declarations, scoped appropriately253 class GenericInstantiator : public DeclMutator {254 /// Map of (generic type, parameter list) pairs to concrete type instantiations255 InstantiationMap< AggregateDecl > instantiations;256 /// Namer for concrete types257 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 structs271 StructDecl* lookup( StructInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (StructDecl*)instantiations.lookup( inst->get_baseStruct(), typeSubs ); }272 /// Wrap instantiation lookup for unions273 UnionDecl* lookup( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs ) { return (UnionDecl*)instantiations.lookup( inst->get_baseUnion(), typeSubs ); }274 /// Wrap instantiation insertion for structs275 void insert( StructInstType *inst, const std::list< TypeExpr* > &typeSubs, StructDecl *decl ) { instantiations.insert( inst->get_baseStruct(), typeSubs, decl ); }276 /// Wrap instantiation insertion for unions277 void insert( UnionInstType *inst, const std::list< TypeExpr* > &typeSubs, UnionDecl *decl ) { instantiations.insert( inst->get_baseUnion(), typeSubs, decl ); }278 126 }; 279 127 … … 311 159 } // anonymous namespace 312 160 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 313 170 /// version of mutateAll with special handling for translation unit so you can check the end of the prelude when debugging 314 171 template< typename MutatorType > … … 338 195 339 196 void box( std::list< Declaration *>& translationUnit ) { 340 LayoutFunctionBuilder layoutBuilder;341 197 Pass1 pass1; 342 198 Pass2 pass2; 343 GenericInstantiator instantiator;344 199 MemberExprFixer memberFixer; 345 200 Pass3 pass3; 346 347 layoutBuilder.mutateDeclarationList( translationUnit );348 201 mutateTranslationUnit/*All*/( translationUnit, pass1 ); 349 202 mutateTranslationUnit/*All*/( translationUnit, pass2 ); 350 // instantiateGeneric( translationUnit ); 351 instantiator.mutateDeclarationList( translationUnit ); 203 instantiateGeneric( translationUnit ); 352 204 mutateTranslationUnit/*All*/( translationUnit, memberFixer ); 353 205 mutateTranslationUnit/*All*/( translationUnit, pass3 ); 354 206 } 355 207 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 function368 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 type381 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( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );387 layoutFnType->get_parameters().push_back( new ObjectDecl( alignofName( ¶mType ), DeclarationNode::NoStorageClass, LinkageSpec::Cforall, 0, sizeAlignType.clone(), 0 ) );388 }389 }390 391 /// Builds a layout function declaration392 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 units394 // 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 operation402 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 operation409 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 variable417 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 block422 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 < rhs427 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 rhs434 Expression *ifCond = makeOp( "?&?", lhs, makeOp( "?-?", rhs, new ConstantExpr( Constant( new BasicType( Type::Qualifiers(), BasicType::LongUnsignedInt ), "1" ) ) ) );435 // if not aligned, increment to alignment436 Expression *ifExpr = makeOp( "?+=?", lhs->clone(), makeOp( "?-?", rhs->clone(), ifCond->clone() ) );437 return makeCond( ifCond, ifExpr );438 }439 440 /// adds an expression to a compound statement441 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 statement446 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 structs452 if ( structDecl->get_members().empty() ) return structDecl;453 454 // get parameters that can change layout, exiting early if none455 std::list< TypeDecl* > otypeParams = takeOtypeOnly( structDecl->get_parameters() );456 if ( otypeParams.empty() ) return structDecl;457 458 // build layout function signature459 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 decl472 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( structDecl->get_name(), functionNesting, layoutFnType );473 474 // calculate struct layout in function body475 476 // initialize size and alignment to 0 and 1 (will have at least one member to re-edit size477 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 alignment490 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), new AlignofExpr( memberType->clone() ) ) );491 }492 493 // place current size in the current offset index494 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 size499 addExpr( layoutDecl->get_statements(), makeOp( "?+=?", derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );500 501 // take max of member alignment and global alignment502 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 alignment505 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 unions513 if ( unionDecl->get_members().empty() ) return unionDecl;514 515 // get parameters that can change layout, exiting early if none516 std::list< TypeDecl* > otypeParams = takeOtypeOnly( unionDecl->get_parameters() );517 if ( otypeParams.empty() ) return unionDecl;518 519 // build layout function signature520 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 decl531 FunctionDecl *layoutDecl = buildLayoutFunctionDecl( unionDecl->get_name(), functionNesting, layoutFnType );532 533 // calculate union layout in function body534 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 size542 addStmt( layoutDecl->get_statements(), makeAssignMax( derefVar( sizeParam ), new SizeofExpr( memberType->clone() ) ) );543 544 // take max of member alignment and global alignment545 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 alignment548 addStmt( layoutDecl->get_statements(), makeAlignTo( derefVar( sizeParam ), derefVar( alignParam ) ) );549 550 addDeclarationAfter( layoutDecl );551 return unionDecl;552 }553 554 208 ////////////////////////////////////////// Pass1 //////////////////////////////////////////////////// 555 209 … … 591 245 } 592 246 593 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) {} 247 Pass1::Pass1() : useRetval( false ), tempNamer( "_temp" ) { 248 adapters.push(AdapterMap()); 249 } 594 250 595 251 /// Returns T if the given declaration is (*?=?)(T *, T) for some TypeInstType T (return not checked, but maybe should be), NULL otherwise … … 694 350 } // for 695 351 352 AdapterMap & adapters = Pass1::adapters.top(); 696 353 for ( std::list< FunctionType *>::iterator funType = functions.begin(); funType != functions.end(); ++funType ) { 697 354 std::string mangleName = mangleAdapterName( *funType, scopeTyVars ); … … 1115 772 mangleName += makePolyMonoSuffix( originalFunction, exprTyVars ); 1116 773 1117 typedef ScopedMap< std::string, DeclarationWithType* >::iterator AdapterIter;1118 Adapter Iter adapter = adapters.find( mangleName );774 AdapterMap & adapters = Pass1::adapters.top(); 775 AdapterMap::iterator adapter = adapters.find( mangleName ); 1119 776 if ( adapter == adapters.end() ) { 1120 777 // adapter has not been created yet in the current scope, so define it 1121 778 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 ) ); 1124 780 stmtsToAdd.push_back( new DeclStmt( noLabels, newAdapter ) ); 1125 781 } // if … … 1500 1156 1501 1157 void Pass1::doBeginScope() { 1502 adapters.beginScope(); 1158 // push a copy of the current map 1159 adapters.push(adapters.top()); 1503 1160 scopedAssignOps.beginScope(); 1504 1161 } 1505 1162 1506 1163 void Pass1::doEndScope() { 1507 adapters. endScope();1164 adapters.pop(); 1508 1165 scopedAssignOps.endScope(); 1509 1166 } … … 1652 1309 } 1653 1310 1654 //////////////////////////////////////// GenericInstantiator //////////////////////////////////////////////////1655 1656 /// Makes substitutions of params into baseParams; returns true if all parameters substituted for a concrete type1657 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 concrete1659 1660 // substitute concrete types for given parameters, and incomplete types for placeholders1661 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 generics1666 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 itself1670 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 done1685 if ( baseParam != baseParams.end() ) return false;1686 // // if not enough parameters given, substitute remaining incomplete types for placeholders1687 // for ( ; baseParam != baseParams.end(); ++baseParam ) {1688 // switch ( (*baseParam)->get_kind() ) {1689 // case TypeDecl::Any: // no more substitutions here, fail early1690 // 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 out1704 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 members1707 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 subtypes1717 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 mutation1722 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 typeSubs1726 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 type1733 StructDecl *concDecl = lookup( inst, typeSubs );1734 if ( ! concDecl ) {1735 // set concDecl to new type, insert type declaration into statements to add1736 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 subtypes1751 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 mutation1756 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 typeSubs1760 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 type1767 UnionDecl *concDecl = lookup( inst, typeSubs );1768 if ( ! concDecl ) {1769 // set concDecl to new type, insert type declaration into statements to add1770 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 applicable1784 // AggregateDecl* getMemberBaseDecl( MemberExpr *memberExpr ) {1785 // // get variable for member aggregate1786 // VariableExpr *varExpr = dynamic_cast< VariableExpr* >( memberExpr->get_aggregate() );1787 // if ( ! varExpr ) return NULL;1788 //1789 // // get object for variable1790 // ObjectDecl *objectDecl = dynamic_cast< ObjectDecl* >( varExpr->get_var() );1791 // if ( ! objectDecl ) return NULL;1792 //1793 // // get base declaration from object type1794 // 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 such1804 // 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 MemberExpr1813 // 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 found1818 // 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 cast1827 // // this *SHOULD* be safe, I don't think anything but the void-replacements I put in for dtypes would make it past the typechecker1828 // 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 1843 1311 ////////////////////////////////////////// MemberExprFixer //////////////////////////////////////////////////// 1844 1312 -
src/GenPoly/DeclMutator.cc
rae357ec rb63e376 24 24 } 25 25 26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) , declsToAddAfter(1){}26 DeclMutator::DeclMutator() : Mutator(), declsToAdd(1) {} 27 27 28 28 DeclMutator::~DeclMutator() {} 29 29 30 30 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 ) { 37 32 // run mutator on declaration 38 33 *decl = maybeMutate( *decl, *this ); … … 44 39 45 40 void DeclMutator::doBeginScope() { 46 // add new decl list sfor inside of scope41 // add new decl list for inside of scope 47 42 declsToAdd.resize( declsToAdd.size()+1 ); 48 declsToAddAfter.resize( declsToAddAfter.size()+1 );49 43 } 50 44 … … 55 49 newBack->splice( newBack->end(), *back ); 56 50 declsToAdd.pop_back(); 57 58 back = declsToAddAfter.rbegin();59 newBack = back + 1;60 newBack->splice( newBack->end(), *back );61 declsToAddAfter.pop_back();62 51 } 63 52 … … 72 61 stmt = maybeMutate( stmt, *this ); 73 62 // 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; 78 64 79 65 // otherwise add declarations to new compound statement … … 85 71 declsToAdd.back().clear(); 86 72 87 // add mutated statement 73 doEndScope(); 74 75 // add mutated statement and return 88 76 compound->get_kids().push_back( stmt ); 89 90 // add declarations after to new compound statement91 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();98 77 return compound; 99 78 } … … 101 80 void DeclMutator::mutateStatementList( std::list< Statement* > &stmts ) { 102 81 doBeginScope(); 103 104 82 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 ) { 115 84 // run mutator on statement 116 85 *stmt = maybeMutate( *stmt, *this ); … … 123 92 declsToAdd.back().clear(); 124 93 } 125 94 126 95 doEndScope(); 127 96 } … … 129 98 void DeclMutator::addDeclaration( Declaration *decl ) { 130 99 declsToAdd.back().push_back( decl ); 131 }132 133 void DeclMutator::addDeclarationAfter( Declaration *decl ) {134 declsToAddAfter.back().push_back( decl );135 100 } 136 101 -
src/GenPoly/DeclMutator.h
rae357ec rb63e376 55 55 /// Add a declaration to the list to be added before the current position 56 56 void addDeclaration( Declaration* decl ); 57 /// Add a declaration to the list to be added after the current position58 void addDeclarationAfter( Declaration* decl );59 57 private: 60 58 /// A stack of declarations to add before the current declaration or statement 61 59 std::vector< std::list< Declaration* > > declsToAdd; 62 /// A stack of declarations to add after the current declaration or statement63 std::vector< std::list< Declaration* > > declsToAddAfter;64 60 }; 65 61 } // namespace -
src/GenPoly/module.mk
rae357ec rb63e376 23 23 GenPoly/CopyParams.cc \ 24 24 GenPoly/FindFunction.cc \ 25 GenPoly/InstantiateGeneric.cc \ 25 26 GenPoly/DeclMutator.cc -
src/Makefile.in
rae357ec rb63e376 122 122 GenPoly/driver_cfa_cpp-CopyParams.$(OBJEXT) \ 123 123 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) \ 124 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) \ 124 125 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT) \ 125 126 InitTweak/driver_cfa_cpp-RemoveInit.$(OBJEXT) \ … … 153 154 ResolvExpr/driver_cfa_cpp-Occurs.$(OBJEXT) \ 154 155 ResolvExpr/driver_cfa_cpp-TypeEnvironment.$(OBJEXT) \ 156 SymTab/driver_cfa_cpp-IdTable.$(OBJEXT) \ 155 157 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) \ 156 158 SymTab/driver_cfa_cpp-Mangler.$(OBJEXT) \ … … 345 347 GenPoly/ScrubTyVars.cc GenPoly/Lvalue.cc GenPoly/Specialize.cc \ 346 348 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 \ 353 356 ResolvExpr/AlternativeFinder.cc ResolvExpr/Alternative.cc \ 354 357 ResolvExpr/Unify.cc ResolvExpr/PtrsAssignable.cc \ … … 359 362 ResolvExpr/RenameVars.cc ResolvExpr/FindOpenVars.cc \ 360 363 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 \ 368 372 SynTree/VarArgsType.cc SynTree/Constant.cc \ 369 373 SynTree/Expression.cc SynTree/TupleExpr.cc \ … … 552 556 GenPoly/$(DEPDIR)/$(am__dirstamp) 553 557 GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT): \ 558 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp) 559 GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT): \ 554 560 GenPoly/$(am__dirstamp) GenPoly/$(DEPDIR)/$(am__dirstamp) 555 561 GenPoly/driver_cfa_cpp-DeclMutator.$(OBJEXT): GenPoly/$(am__dirstamp) \ … … 658 664 @$(MKDIR_P) SymTab/$(DEPDIR) 659 665 @: > SymTab/$(DEPDIR)/$(am__dirstamp) 666 SymTab/driver_cfa_cpp-IdTable.$(OBJEXT): SymTab/$(am__dirstamp) \ 667 SymTab/$(DEPDIR)/$(am__dirstamp) 660 668 SymTab/driver_cfa_cpp-Indexer.$(OBJEXT): SymTab/$(am__dirstamp) \ 661 669 SymTab/$(DEPDIR)/$(am__dirstamp) … … 788 796 -rm -f GenPoly/driver_cfa_cpp-FindFunction.$(OBJEXT) 789 797 -rm -f GenPoly/driver_cfa_cpp-GenPoly.$(OBJEXT) 798 -rm -f GenPoly/driver_cfa_cpp-InstantiateGeneric.$(OBJEXT) 790 799 -rm -f GenPoly/driver_cfa_cpp-Lvalue.$(OBJEXT) 791 800 -rm -f GenPoly/driver_cfa_cpp-PolyMutator.$(OBJEXT) … … 823 832 -rm -f ResolvExpr/driver_cfa_cpp-Unify.$(OBJEXT) 824 833 -rm -f SymTab/driver_cfa_cpp-FixFunction.$(OBJEXT) 834 -rm -f SymTab/driver_cfa_cpp-IdTable.$(OBJEXT) 825 835 -rm -f SymTab/driver_cfa_cpp-ImplementationType.$(OBJEXT) 826 836 -rm -f SymTab/driver_cfa_cpp-Indexer.$(OBJEXT) … … 893 903 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-FindFunction.Po@am__quote@ 894 904 @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@ 895 906 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-Lvalue.Po@am__quote@ 896 907 @AMDEP_TRUE@@am__include@ @am__quote@GenPoly/$(DEPDIR)/driver_cfa_cpp-PolyMutator.Po@am__quote@ … … 928 939 @AMDEP_TRUE@@am__include@ @am__quote@ResolvExpr/$(DEPDIR)/driver_cfa_cpp-Unify.Po@am__quote@ 929 940 @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@ 930 942 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-ImplementationType.Po@am__quote@ 931 943 @AMDEP_TRUE@@am__include@ @am__quote@SymTab/$(DEPDIR)/driver_cfa_cpp-Indexer.Po@am__quote@ … … 1352 1364 @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` 1353 1365 1366 GenPoly/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 1373 GenPoly/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 1354 1380 GenPoly/driver_cfa_cpp-DeclMutator.o: GenPoly/DeclMutator.cc 1355 1381 @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 … … 1785 1811 @AMDEP_TRUE@@am__fastdepCXX_FALSE@ DEPDIR=$(DEPDIR) $(CXXDEPMODE) $(depcomp) @AMDEPBACKSLASH@ 1786 1812 @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 1814 SymTab/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 1821 SymTab/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` 1787 1827 1788 1828 SymTab/driver_cfa_cpp-Indexer.o: SymTab/Indexer.cc -
src/SymTab/Indexer.cc
rae357ec rb63e376 14 14 // 15 15 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 29 16 #include "SynTree/Declaration.h" 30 17 #include "SynTree/Type.h" … … 32 19 #include "SynTree/Initializer.h" 33 20 #include "SynTree/Statement.h" 21 #include "Indexer.h" 22 #include <typeinfo> 23 #include "Common/utility.h" 34 24 35 25 #define debugPrint(x) if ( doDebug ) { std::cout << x; } … … 43 33 } 44 34 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() {} 145 38 146 39 void Indexer::visit( ObjectDecl *objectDecl ) { … … 152 45 if ( objectDecl->get_name() != "" ) { 153 46 debugPrint( "Adding object " << objectDecl->get_name() << std::endl ); 154 addId( objectDecl );47 idTable.addDecl( objectDecl ); 155 48 } // if 156 49 } … … 159 52 if ( functionDecl->get_name() == "" ) return; 160 53 debugPrint( "Adding function " << functionDecl->get_name() << std::endl ); 161 addId( functionDecl );54 idTable.addDecl( functionDecl ); 162 55 enterScope(); 163 56 maybeAccept( functionDecl->get_functionType(), *this ); … … 197 90 leaveScope(); 198 91 debugPrint( "Adding type " << typeDecl->get_name() << std::endl ); 199 addType( typeDecl );92 typeTable.add( typeDecl ); 200 93 acceptAll( typeDecl->get_assertions(), *this ); 201 94 } … … 207 100 leaveScope(); 208 101 debugPrint( "Adding typedef " << typeDecl->get_name() << std::endl ); 209 addType( typeDecl );102 typeTable.add( typeDecl ); 210 103 } 211 104 … … 215 108 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 216 109 debugPrint( "Adding fwd decl for struct " << fwdDecl.get_name() << std::endl ); 217 addStruct( &fwdDecl );110 structTable.add( &fwdDecl ); 218 111 219 112 enterScope(); … … 224 117 debugPrint( "Adding struct " << aggregateDecl->get_name() << std::endl ); 225 118 // this addition replaces the forward declaration 226 addStruct( aggregateDecl );119 structTable.add( aggregateDecl ); 227 120 } 228 121 … … 232 125 cloneAll( aggregateDecl->get_parameters(), fwdDecl.get_parameters() ); 233 126 debugPrint( "Adding fwd decl for union " << fwdDecl.get_name() << std::endl ); 234 addUnion( &fwdDecl );127 unionTable.add( &fwdDecl ); 235 128 236 129 enterScope(); … … 240 133 241 134 debugPrint( "Adding union " << aggregateDecl->get_name() << std::endl ); 242 addUnion( aggregateDecl );135 unionTable.add( aggregateDecl ); 243 136 } 244 137 245 138 void Indexer::visit( EnumDecl *aggregateDecl ) { 246 139 debugPrint( "Adding enum " << aggregateDecl->get_name() << std::endl ); 247 addEnum( aggregateDecl );140 enumTable.add( aggregateDecl ); 248 141 // unlike structs, contexts, and unions, enums inject their members into the global scope 249 142 acceptAll( aggregateDecl->get_members(), *this ); … … 257 150 258 151 debugPrint( "Adding context " << aggregateDecl->get_name() << std::endl ); 259 addTrait( aggregateDecl );152 contextTable.add( aggregateDecl ); 260 153 } 261 154 … … 406 299 407 300 void Indexer::visit( StructInstType *structInst ) { 408 if ( ! lookupStruct( structInst->get_name() ) ) {301 if ( ! structTable.lookup( structInst->get_name() ) ) { 409 302 debugPrint( "Adding struct " << structInst->get_name() << " from implicit forward declaration" << std::endl ); 410 addStruct( structInst->get_name() );303 structTable.add( structInst->get_name() ); 411 304 } 412 305 enterScope(); … … 416 309 417 310 void Indexer::visit( UnionInstType *unionInst ) { 418 if ( ! lookupUnion( unionInst->get_name() ) ) {311 if ( ! unionTable.lookup( unionInst->get_name() ) ) { 419 312 debugPrint( "Adding union " << unionInst->get_name() << " from implicit forward declaration" << std::endl ); 420 addUnion( unionInst->get_name() );313 unionTable.add( unionInst->get_name() ); 421 314 } 422 315 enterScope(); … … 432 325 } 433 326 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); 449 334 } 450 335 451 336 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 ); 456 338 } 457 339 458 340 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 ); 463 342 } 464 343 465 344 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 ); 470 346 } 471 347 472 348 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 ); 731 354 } 732 355 733 356 void Indexer::enterScope() { 734 ++scope;735 736 357 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(); 739 366 } 740 367 741 368 void Indexer::leaveScope() { 742 369 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(); 763 387 } 764 388 765 389 void Indexer::print( std::ostream &os, int indent ) const { 766 390 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 780 413 } 781 414 } // namespace SymTab -
src/SymTab/Indexer.h
rae357ec rb63e376 21 21 22 22 #include "SynTree/Visitor.h" 23 #include "IdTable.h" 24 #include "AggregateTable.h" 25 #include "TypeTable.h" 23 26 24 27 namespace SymTab { … … 26 29 public: 27 30 Indexer( bool useDebug = false ); 28 29 Indexer( const Indexer &that );30 Indexer( Indexer &&that );31 31 virtual ~Indexer(); 32 Indexer& operator= ( const Indexer &that );33 Indexer& operator= ( Indexer &&that );34 32 35 33 //using Visitor::visit; … … 80 78 void leaveScope(); 81 79 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; 85 82 NamedTypeDecl *lookupType( const std::string &id ) const; 86 /// Gets the top-most struct declaration with the given ID87 83 StructDecl *lookupStruct( const std::string &id ) const; 88 /// Gets the top-most enum declaration with the given ID89 84 EnumDecl *lookupEnum( const std::string &id ) const; 90 /// Gets the top-most union declaration with the given ID91 85 UnionDecl *lookupUnion( const std::string &id ) const; 92 /// Gets the top-most trait declaration with the given ID93 86 TraitDecl *lookupTrait( const std::string &id ) const; 94 87 95 88 void print( std::ostream &os, int indent = 0 ) const; 96 89 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 129 98 }; 130 99 } // namespace SymTab -
src/SymTab/module.mk
rae357ec rb63e376 15 15 ############################################################################### 16 16 17 SRC += SymTab/Indexer.cc \ 17 SRC += SymTab/IdTable.cc \ 18 SymTab/Indexer.cc \ 18 19 SymTab/Mangler.cc \ 19 20 SymTab/Validate.cc \ -
src/SynTree/Constant.cc
rae357ec rb63e376 16 16 #include <iostream> 17 17 #include <list> 18 #include <string>19 18 20 19 #include "Constant.h" … … 29 28 30 29 Constant::~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 }43 30 44 31 Constant *Constant::clone() const { assert( false ); return 0; } -
src/SynTree/Constant.h
rae357ec rb63e376 32 32 void set_value( std::string newValue ) { value = newValue; } 33 33 34 /// generates an integer constant of the given int35 static Constant from( int i );36 /// generates an integer constant of the given unsigned long int37 static Constant from( unsigned long i );38 /// generates a floating point constant of the given double39 static Constant from( double d );40 41 34 virtual Constant *clone() const; 42 35 virtual void accept( Visitor &v ) { v.visit( this ); }
Note:
See TracChangeset
for help on using the changeset viewer.