Changeset 67fa9f9 for src/SymTab
- Timestamp:
- Jul 5, 2017, 10:50:22 AM (8 years ago)
- Branches:
- ADT, aaron-thesis, arm-eh, ast-experimental, cleanup-dtors, deferred_resn, demangler, enum, forall-pointer-decay, jacob/cs343-translation, jenkins-sandbox, master, new-ast, new-ast-unique-expr, new-env, no_list, persistent-indexer, pthread-emulation, qualifiedEnum, resolv-new, with_gc
- Children:
- 0614d14
- Parents:
- 11dbfe1 (diff), 307a732 (diff)
Note: this is a merge changeset, the changes displayed below correspond to the merge itself.
Use the(diff)
links above to see all the changes relative to each parent. - Location:
- src/SymTab
- Files:
-
- 4 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.h
r11dbfe1 r67fa9f9 25 25 26 26 namespace SymTab { 27 28 27 /// Generates assignment operators, constructors, and destructor for aggregate types as required 28 void autogenerateRoutines( std::list< Declaration * > &translationUnit ); 29 29 30 31 30 /// returns true if obj's name is the empty string and it has a bitfield width 31 bool isUnnamedBitfield( ObjectDecl * obj ); 32 32 33 34 35 33 /// size_t type - set when size_t typedef is seen. Useful in a few places, 34 /// such as in determining array dimension type 35 extern Type * SizeType; 36 36 37 38 37 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 38 template< typename OutputIterator > 39 39 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false, bool forward = true ); 40 40 41 42 43 41 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Should only be called with non-array types. 42 /// optionally returns a statement which must be inserted prior to the containing loop, if there is one 43 template< typename OutputIterator > 44 44 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) { 45 45 // want to be able to generate assignment, ctor, and dtor generically, … … 50 50 dstParam = new AddressExpr( dstParam ); 51 51 if ( addCast ) { 52 // cast to T* with qualifiers removed, so that qualified objects can be constructed 53 // and destructed with the same functions as non-qualified objects. 54 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 55 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 56 // remove lvalue as a qualifier, this can change to 57 // type->get_qualifiers() = Type::Qualifiers(); 58 assert( type ); 59 Type * castType = type->clone(); 60 // castType->get_qualifiers() -= Type::Qualifiers(true, true, true, false, true, false); 61 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 62 castType->set_lvalue( true ); // xxx - might not need this 63 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) ); 52 // cast to T* with qualifiers removed, so that qualified objects can be constructed 53 // and destructed with the same functions as non-qualified objects. 54 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 55 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 56 // remove lvalue as a qualifier, this can change to 57 // type->get_qualifiers() = Type::Qualifiers(); 58 assert( type ); 59 Type * castType = type->clone(); 60 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 61 castType->set_lvalue( true ); // xxx - might not need this 62 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) ); 64 63 } 65 64 fExpr->get_args().push_back( dstParam ); … … 75 74 76 75 return listInit; 77 }78 79 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments.80 /// If forward is true, loop goes from 0 to N-1, else N-1 to 081 template< typename OutputIterator >82 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) {83 static UniqueName indexName( "_index" );84 85 // for a flexible array member nothing is done -- user must define own assignment86 if ( ! array->get_dimension() ) return ;87 88 Expression * begin, * end, * update, * cmp;89 if ( forward ) {90 // generate: for ( int i = 0; i < N; ++i )91 begin = new ConstantExpr( Constant::from_int( 0 ) );92 end = array->get_dimension()->clone();93 cmp = new NameExpr( "?<?" );94 update = new NameExpr( "++?" );95 } else {96 // generate: for ( int i = N-1; i >= 0; --i )97 begin = new UntypedExpr( new NameExpr( "?-?" ) );98 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() );99 ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) );100 end = new ConstantExpr( Constant::from_int( 0 ) );101 cmp = new NameExpr( "?>=?" );102 update = new NameExpr( "--?" );103 76 } 104 77 105 ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin, std::list<Expression*>() ) ); 78 /// Store in out a loop which calls fname on each element of the array with srcParam and dstParam as arguments. 79 /// If forward is true, loop goes from 0 to N-1, else N-1 to 0 80 template< typename OutputIterator > 81 void genArrayCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, ArrayType *array, bool addCast = false, bool forward = true ) { 82 static UniqueName indexName( "_index" ); 106 83 107 UntypedExpr *cond = new UntypedExpr( cmp ); 108 cond->get_args().push_back( new VariableExpr( index ) ); 109 cond->get_args().push_back( end ); 84 // for a flexible array member nothing is done -- user must define own assignment 85 if ( ! array->get_dimension() ) return ; 110 86 111 UntypedExpr *inc = new UntypedExpr( update ); 112 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 87 Expression * begin, * end, * update, * cmp; 88 if ( forward ) { 89 // generate: for ( int i = 0; i < N; ++i ) 90 begin = new ConstantExpr( Constant::from_int( 0 ) ); 91 end = array->get_dimension()->clone(); 92 cmp = new NameExpr( "?<?" ); 93 update = new NameExpr( "++?" ); 94 } else { 95 // generate: for ( int i = N-1; i >= 0; --i ) 96 begin = new UntypedExpr( new NameExpr( "?-?" ) ); 97 ((UntypedExpr*)begin)->get_args().push_back( array->get_dimension()->clone() ); 98 ((UntypedExpr*)begin)->get_args().push_back( new ConstantExpr( Constant::from_int( 1 ) ) ); 99 end = new ConstantExpr( Constant::from_int( 0 ) ); 100 cmp = new NameExpr( "?>=?" ); 101 update = new NameExpr( "--?" ); 102 } 113 103 114 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 115 dstIndex->get_args().push_back( dstParam ); 116 dstIndex->get_args().push_back( new VariableExpr( index ) ); 117 dstParam = dstIndex; 104 ObjectDecl *index = new ObjectDecl( indexName.newName(), Type::StorageClasses(), LinkageSpec::C, 0, new BasicType( Type::Qualifiers(), BasicType::SignedInt ), new SingleInit( begin ) ); 118 105 119 // srcParam must keep track of the array indices to build the120 // source parameter and/or array list initializer121 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone());106 UntypedExpr *cond = new UntypedExpr( cmp ); 107 cond->get_args().push_back( new VariableExpr( index ) ); 108 cond->get_args().push_back( end ); 122 109 123 // for stmt's body, eventually containing call 124 CompoundStmt * body = new CompoundStmt( noLabels ); 125 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward ); 110 UntypedExpr *inc = new UntypedExpr( update ); 111 inc->get_args().push_back( new AddressExpr( new VariableExpr( index ) ) ); 126 112 127 // block containing for stmt and index variable 128 std::list<Statement *> initList; 129 CompoundStmt * block = new CompoundStmt( noLabels ); 130 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 131 if ( listInit ) block->get_kids().push_back( listInit ); 132 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 113 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); 114 dstIndex->get_args().push_back( dstParam ); 115 dstIndex->get_args().push_back( new VariableExpr( index ) ); 116 dstParam = dstIndex; 133 117 134 *out++ = block; 135 } 118 // srcParam must keep track of the array indices to build the 119 // source parameter and/or array list initializer 120 srcParam.addArrayIndex( new VariableExpr( index ), array->get_dimension()->clone() ); 136 121 137 template< typename OutputIterator > 122 // for stmt's body, eventually containing call 123 CompoundStmt * body = new CompoundStmt( noLabels ); 124 Statement * listInit = genCall( srcParam, dstParam, fname, back_inserter( body->get_kids() ), array->get_base(), addCast, forward ); 125 126 // block containing for stmt and index variable 127 std::list<Statement *> initList; 128 CompoundStmt * block = new CompoundStmt( noLabels ); 129 block->get_kids().push_back( new DeclStmt( noLabels, index ) ); 130 if ( listInit ) block->get_kids().push_back( listInit ); 131 block->get_kids().push_back( new ForStmt( noLabels, initList, cond, inc, body ) ); 132 133 *out++ = block; 134 } 135 136 template< typename OutputIterator > 138 137 Statement * genCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast, bool forward ) { 139 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 140 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); 141 return 0; 142 } else { 143 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 138 if ( ArrayType * at = dynamic_cast< ArrayType * >( type ) ) { 139 genArrayCall( srcParam, dstParam, fname, out, at, addCast, forward ); 140 return 0; 141 } else { 142 return genScalarCall( srcParam, dstParam, fname, out, type, addCast ); 143 } 144 144 } 145 }146 145 147 148 149 150 151 146 /// inserts into out a generated call expression to function fname with arguments dstParam 147 /// and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. decl is the 148 /// object being constructed. The function wraps constructor and destructor calls in an 149 /// ImplicitCtorDtorStmt node. 150 template< typename OutputIterator > 152 151 void genImplicitCall( InitTweak::InitExpander & srcParam, Expression * dstParam, const std::string & fname, OutputIterator out, DeclarationWithType * decl, bool forward = true ) { 153 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl );154 assert( obj );155 // unnamed bit fields are not copied as they cannot be accessed156 if ( isUnnamedBitfield( obj ) ) return;152 ObjectDecl *obj = dynamic_cast<ObjectDecl *>( decl ); 153 assert( obj ); 154 // unnamed bit fields are not copied as they cannot be accessed 155 if ( isUnnamedBitfield( obj ) ) return; 157 156 158 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) );159 std::list< Statement * > stmts;160 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward );157 bool addCast = (fname == "?{}" || fname == "^?{}") && ( !obj || ( obj && obj->get_bitfieldWidth() == NULL ) ); 158 std::list< Statement * > stmts; 159 genCall( srcParam, dstParam, fname, back_inserter( stmts ), obj->get_type(), addCast, forward ); 161 160 162 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call 163 assert( stmts.size() <= 1 ); 164 if ( stmts.size() == 1 ) { 165 Statement * callStmt = stmts.front(); 166 if ( addCast ) { 167 // implicitly generated ctor/dtor calls should be wrapped 168 // so that later passes are aware they were generated. 169 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 170 // because this causes the address to be taken at codegen, which is illegal in C. 171 callStmt = new ImplicitCtorDtorStmt( callStmt ); 172 } 173 *out++ = callStmt; 161 // currently genCall should produce at most one element, but if that changes then the next line needs to be updated to grab the statement which contains the call 162 assert( stmts.size() <= 1 ); 163 if ( stmts.size() == 1 ) { 164 Statement * callStmt = stmts.front(); 165 if ( addCast ) { 166 // implicitly generated ctor/dtor calls should be wrapped 167 // so that later passes are aware they were generated. 168 // xxx - don't mark as an implicit ctor/dtor if obj is a bitfield, 169 // because this causes the address to be taken at codegen, which is illegal in C. 170 callStmt = new ImplicitCtorDtorStmt( callStmt ); 171 } 172 *out++ = callStmt; 173 } 174 174 } 175 }176 175 } // namespace SymTab 177 176 #endif // AUTOGEN_H -
src/SymTab/ImplementationType.cc
r11dbfe1 r67fa9f9 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // ImplementationType.cc -- 7 // ImplementationType.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 92 92 93 93 void ImplementationType::visit(TupleType *tupleType) { 94 TupleType *newType = new TupleType( Type::Qualifiers() );94 std::list< Type * > types; 95 95 for ( std::list< Type* >::iterator i = tupleType->get_types().begin(); i != tupleType->get_types().end(); ++i ) { 96 96 Type *implType = implementationType( *i, indexer ); 97 97 implType->get_qualifiers() |= tupleType->get_qualifiers(); 98 newType->get_types().push_back( implType );98 types.push_back( implType ); 99 99 } // for 100 result = new Type;100 result = new TupleType( Type::Qualifiers(), types ); 101 101 } 102 102 -
src/SymTab/Indexer.cc
r11dbfe1 r67fa9f9 652 652 for ( MangleTable::const_iterator decl = mangleTable.begin(); decl != mangleTable.end(); ++decl ) { 653 653 // check for C decls with the same name, skipping those with a compatible type (by mangleName) 654 if ( decl->second->get_linkage() == LinkageSpec::C&& decl->first != mangleName ) return true;654 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first != mangleName ) return true; 655 655 } 656 656 } … … 669 669 // check for C decls with the same name, skipping 670 670 // those with an incompatible type (by mangleName) 671 if ( decl->second->get_linkage() == LinkageSpec::C&& decl->first == mangleName ) return true;671 if ( ! LinkageSpec::isMangled( decl->second->get_linkage() ) && decl->first == mangleName ) return true; 672 672 } 673 673 } … … 724 724 // new definition shadows the autogenerated one, even at the same scope 725 725 return false; 726 } else if ( added->get_linkage() != LinkageSpec::C|| ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) {726 } else if ( LinkageSpec::isMangled( added->get_linkage() ) || ResolvExpr::typesCompatible( added->get_type(), existing->get_type(), Indexer() ) ) { 727 727 // typesCompatible doesn't really do the right thing here. When checking compatibility of function types, 728 728 // we should ignore outermost pointer qualifiers, except _Atomic? … … 765 765 766 766 // this ensures that no two declarations with the same unmangled name at the same scope both have C linkage 767 if ( decl->get_linkage() == LinkageSpec::C) {767 if ( ! LinkageSpec::isMangled( decl->get_linkage() ) ) { 768 768 // NOTE this is broken in Richard's original code in such a way that it never triggers (it 769 769 // doesn't check decls that have the same manglename, and all C-linkage decls are defined to -
src/SymTab/Validate.cc
r11dbfe1 r67fa9f9 106 106 107 107 /// Fix return types so that every function returns exactly one value 108 class ReturnTypeFixer { 109 public: 108 struct ReturnTypeFixer { 110 109 static void fix( std::list< Declaration * > &translationUnit ); 111 110 … … 115 114 116 115 /// Replaces enum types by int, and function or array types in function parameter and return lists by appropriate pointers. 117 class EnumAndPointerDecay { 118 public: 116 struct EnumAndPointerDecay { 119 117 void previsit( EnumDecl *aggregateDecl ); 120 118 void previsit( FunctionType *func ); … … 159 157 }; 160 158 161 class ReturnChecker : public WithScopes { 162 public: 159 struct ReturnChecker : public WithGuards { 163 160 /// Checks that return statements return nothing if their return type is void 164 161 /// and return something if the return type is non-void. 165 162 static void checkFunctionReturns( std::list< Declaration * > & translationUnit ); 166 private: 163 167 164 void previsit( FunctionDecl * functionDecl ); 168 165 void previsit( ReturnStmt * returnStmt ); … … 205 202 }; 206 203 207 class VerifyCtorDtorAssign { 208 public: 204 struct VerifyCtorDtorAssign { 209 205 /// ensure that constructors, destructors, and assignment have at least one 210 206 /// parameter, the first of which must be a pointer, and that ctor/dtors have no … … 216 212 217 213 /// ensure that generic types have the correct number of type arguments 218 class ValidateGenericParameters { 219 public: 214 struct ValidateGenericParameters { 220 215 void previsit( StructInstType * inst ); 221 216 void previsit( UnionInstType * inst ); 222 217 }; 223 218 224 class ArrayLength { 225 public: 219 struct ArrayLength { 226 220 /// for array types without an explicit length, compute the length and store it so that it 227 221 /// is known to the rest of the phases. For example, … … 236 230 }; 237 231 238 class CompoundLiteral final : public GenPoly::DeclMutator{232 struct CompoundLiteral final : public WithDeclsToAdd, public WithVisitorRef<CompoundLiteral> { 239 233 Type::StorageClasses storageClasses; 240 234 241 using GenPoly::DeclMutator::mutate; 242 DeclarationWithType * mutate( ObjectDecl *objectDecl ) final; 243 Expression *mutate( CompoundLiteralExpr *compLitExpr ) final; 235 void premutate( ObjectDecl *objectDecl ); 236 Expression * postmutate( CompoundLiteralExpr *compLitExpr ); 244 237 }; 245 238 … … 248 241 LinkReferenceToTypes lrt( doDebug, 0 ); 249 242 ForallPointerDecay fpd( 0 ); 250 CompoundLiteralcompoundliteral;243 PassVisitor<CompoundLiteral> compoundliteral; 251 244 PassVisitor<ValidateGenericParameters> genericParams; 252 245 … … 263 256 Concurrency::implementThreadStarter( translationUnit ); 264 257 ReturnChecker::checkFunctionReturns( translationUnit ); 265 compoundliteral.mutateDeclarationList( translationUnit);258 mutateAll( translationUnit, compoundliteral ); 266 259 acceptAll( translationUnit, fpd ); 267 260 ArrayLength::computeLength( translationUnit ); … … 883 876 } 884 877 885 DeclarationWithType * CompoundLiteral::mutate( ObjectDecl *objectDecl ) {878 void CompoundLiteral::premutate( ObjectDecl *objectDecl ) { 886 879 storageClasses = objectDecl->get_storageClasses(); 887 DeclarationWithType * temp = Mutator::mutate( objectDecl ); 888 return temp; 889 } 890 891 Expression *CompoundLiteral::mutate( CompoundLiteralExpr *compLitExpr ) { 880 } 881 882 Expression *CompoundLiteral::postmutate( CompoundLiteralExpr *compLitExpr ) { 892 883 // transform [storage_class] ... (struct S){ 3, ... }; 893 884 // into [storage_class] struct S temp = { 3, ... }; 894 885 static UniqueName indexName( "_compLit" ); 895 886 896 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, 0, compLitExpr->get_result(), compLitExpr->get_initializer() );897 compLitExpr->set_result( 0);898 compLitExpr->set_initializer( 0);887 ObjectDecl *tempvar = new ObjectDecl( indexName.newName(), storageClasses, LinkageSpec::C, nullptr, compLitExpr->get_result(), compLitExpr->get_initializer() ); 888 compLitExpr->set_result( nullptr ); 889 compLitExpr->set_initializer( nullptr ); 899 890 delete compLitExpr; 900 DeclarationWithType * newtempvar = mutate( tempvar ); 901 addDeclaration( newtempvar ); // add modified temporary to current block 902 return new VariableExpr( newtempvar ); 891 declsToAddBefore.push_back( tempvar ); // add modified temporary to current block 892 return new VariableExpr( tempvar ); 903 893 } 904 894
Note:
See TracChangeset
for help on using the changeset viewer.