Changeset 6b224a52 for src/SymTab
- Timestamp:
- Aug 25, 2017, 12:11:53 PM (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:
- bf7b9da7
- Parents:
- 135b431 (diff), f676b84 (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:
-
- 6 edited
Legend:
- Unmodified
- Added
- Removed
-
src/SymTab/Autogen.cc
r135b431 r6b224a52 13 13 // Update Count : 62 14 14 // 15 15 16 #include "Autogen.h" 16 17 … … 24 25 #include <vector> // for vector 25 26 26 #include "AddVisit.h" // for addVisit 27 #include "Common/ScopedMap.h" // for ScopedMap 28 #include "GenPoly/DeclMutator.h" // for DeclMutator 29 #include "GenPoly/ScopedSet.h" // for ScopedSet 30 #include "Parser/LinkageSpec.h" // for AutoGen, Intrinsic, Spec 31 #include "SymTab/Mangler.h" // for mangleType 32 #include "SynTree/Statement.h" // for SwitchStmt (ptr only), CompoundStmt 33 #include "SynTree/Type.h" // for Type, ArrayType, Type::StorageClasses 34 #include "SynTree/Visitor.h" // for Visitor 27 #include "AddVisit.h" // for addVisit 28 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 29 #include "Common/ScopedMap.h" // for ScopedMap<>::const_iterator, Scope... 30 #include "Common/utility.h" // for cloneAll, operator+ 31 #include "GenPoly/DeclMutator.h" // for DeclMutator 32 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 33 #include "SymTab/Mangler.h" // for Mangler 34 #include "SynTree/Attribute.h" // For Attribute 35 #include "SynTree/Mutator.h" // for maybeMutate 36 #include "SynTree/Statement.h" // for CompoundStmt, ReturnStmt, ExprStmt 37 #include "SynTree/Type.h" // for FunctionType, Type, TypeInstType 38 #include "SynTree/Visitor.h" // for maybeAccept, Visitor, acceptAll 39 40 class Attribute; 35 41 36 42 namespace SymTab { … … 130 136 FunctionType * genDefaultType( Type * paramType ) { 131 137 FunctionType *ftype = new FunctionType( Type::Qualifiers(), false ); 132 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new PointerType( Type::Qualifiers(), paramType->clone() ), nullptr );138 ObjectDecl *dstParam = new ObjectDecl( "_dst", Type::StorageClasses(), LinkageSpec::Cforall, nullptr, new ReferenceType( Type::Qualifiers(), paramType->clone() ), nullptr ); 133 139 ftype->get_parameters().push_back( dstParam ); 134 140 … … 150 156 ftype->get_returnVals().push_back( returnVal ); 151 157 return ftype; 152 }153 154 /// true if the aggregate's layout is dynamic155 template< typename AggrDecl >156 bool hasDynamicLayout( AggrDecl * aggregateDecl ) {157 for ( TypeDecl * param : aggregateDecl->get_parameters() ) {158 if ( param->isComplete() ) return true;159 }160 return false;161 158 } 162 159 … … 181 178 FunctionType * ftype = funcDecl->get_functionType(); 182 179 assert( ! ftype->get_parameters().empty() ); 183 Type * t = safe_dynamic_cast< PointerType * >( ftype->get_parameters().front()->get_type() )->get_base(); 180 Type * t = InitTweak::getPointerBase( ftype->get_parameters().front()->get_type() ); 181 assert( t ); 184 182 map.insert( Mangler::mangleType( t ), true ); 185 183 } … … 227 225 FunctionType * ftype = data.genType( refType ); 228 226 229 if(concurrent_type && InitTweak::isDestructor( data.fname )) {227 if(concurrent_type && CodeGen::isDestructor( data.fname )) { 230 228 ftype->get_parameters().front()->get_type()->set_mutex( true ); 231 229 } … … 279 277 FunctionType *copyCtorType = genCopyType( refType->clone() ); 280 278 279 // add unused attribute to parameters of default constructor and destructor 280 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 281 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 282 281 283 // xxx - should we also generate void ?{}(E *, int) and E ?{}(E *, E)? 282 284 // right now these cases work, but that might change. … … 301 303 302 304 /// generates a single struct member operation (constructor call, destructor call, assignment call) 303 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool isDynamicLayout, bool forward = true ) { 304 ObjectDecl * returnVal = NULL; 305 if ( ! func->get_functionType()->get_returnVals().empty() ) { 306 returnVal = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_returnVals().front() ); 307 } 308 305 void makeStructMemberOp( ObjectDecl * dstParam, Expression * src, DeclarationWithType * field, FunctionDecl * func, bool forward = true ) { 309 306 InitTweak::InitExpander srcParam( src ); 310 307 311 // assign to destination (and return value if generic) 312 UntypedExpr *derefExpr = UntypedExpr::createDeref( new VariableExpr( dstParam ) ); 313 Expression *dstselect = new MemberExpr( field, derefExpr ); 308 // assign to destination 309 Expression *dstselect = new MemberExpr( field, new CastExpr( new VariableExpr( dstParam ), safe_dynamic_cast< ReferenceType* >( dstParam->get_type() )->get_base()->clone() ) ); 314 310 genImplicitCall( srcParam, dstselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward ); 315 316 if ( isDynamicLayout && returnVal ) {317 // xxx - there used to be a dereference on returnVal, but this seems to have been wrong?318 Expression *retselect = new MemberExpr( field, new VariableExpr( returnVal ) );319 genImplicitCall( srcParam, retselect, func->get_name(), back_inserter( func->get_statements()->get_kids() ), field, forward );320 } // if321 311 } 322 312 323 313 /// generates the body of a struct function by iterating the struct members (via parameters) - generates default ctor, copy ctor, assignment, and dtor bodies, but NOT field ctor bodies 324 314 template<typename Iterator> 325 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool isDynamicLayout, boolforward = true ) {315 void makeStructFunctionBody( Iterator member, Iterator end, FunctionDecl * func, bool forward = true ) { 326 316 for ( ; member != end; ++member ) { 327 317 if ( DeclarationWithType *field = dynamic_cast< DeclarationWithType * >( *member ) ) { // otherwise some form of type declaration, e.g. Aggregate … … 359 349 360 350 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL; 361 makeStructMemberOp( dstParam, srcselect, field, func, isDynamicLayout,forward );351 makeStructMemberOp( dstParam, srcselect, field, func, forward ); 362 352 } // if 363 353 } // for … … 367 357 /// void ?{}(A *, int) and void?{}(A *, int, int) for a struct A which has two int fields. 368 358 template<typename Iterator> 369 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func , bool isDynamicLayout) {359 void makeStructFieldCtorBody( Iterator member, Iterator end, FunctionDecl * func ) { 370 360 FunctionType * ftype = func->get_functionType(); 371 361 std::list<DeclarationWithType*> & params = ftype->get_parameters(); … … 393 383 // matching parameter, initialize field with copy ctor 394 384 Expression *srcselect = new VariableExpr(*parameter); 395 makeStructMemberOp( dstParam, srcselect, field, func , isDynamicLayout);385 makeStructMemberOp( dstParam, srcselect, field, func ); 396 386 ++parameter; 397 387 } else { 398 388 // no matching parameter, initialize field with default ctor 399 makeStructMemberOp( dstParam, NULL, field, func , isDynamicLayout);389 makeStructMemberOp( dstParam, NULL, field, func ); 400 390 } 401 391 } … … 413 403 // Make function polymorphic in same parameters as generic struct, if applicable 414 404 const std::list< TypeDecl* > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 415 bool isDynamicLayout = hasDynamicLayout( aggregateDecl ); // NOTE this flag is an incredibly ugly kludge; we should fix the assignment signature instead (ditto for union)416 405 417 406 // generate each of the functions based on the supplied FuncData objects … … 423 412 424 413 // field ctors are only generated if default constructor and copy constructor are both generated 425 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return InitTweak::isConstructor( dcl->get_name() ); } );414 unsigned numCtors = std::count_if( newFuncs.begin(), newFuncs.end(), [](FunctionDecl * dcl) { return CodeGen::isConstructor( dcl->get_name() ); } ); 426 415 427 416 if ( functionNesting == 0 ) { … … 438 427 // generate appropriate calls to member ctor, assignment 439 428 // destructor needs to do everything in reverse, so pass "forward" based on whether the function is a destructor 440 if ( ! InitTweak::isDestructor( dcl->get_name() ) ) {441 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl , isDynamicLayout);429 if ( ! CodeGen::isDestructor( dcl->get_name() ) ) { 430 makeStructFunctionBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), dcl ); 442 431 } else { 443 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, isDynamicLayout,false );444 } 445 if ( InitTweak::isAssignment( dcl->get_name() ) ) {432 makeStructFunctionBody( aggregateDecl->get_members().rbegin(), aggregateDecl->get_members().rend(), dcl, false ); 433 } 434 if ( CodeGen::isAssignment( dcl->get_name() ) ) { 446 435 // assignment needs to return a value 447 436 FunctionType * assignType = dcl->get_functionType(); … … 472 461 // our inheritance model. I think the correct way to handle this is to 473 462 // cast the structure to the type of the member and let the resolver 474 // figure out whether it's valid and have a pass afterwards that fixes 475 // the assignment to use pointer arithmetic with the offset of the 476 // member, much like how generic type members are handled. 463 // figure out whether it's valid/choose the correct unnamed member 477 464 continue; 478 465 } 479 466 memCtorType->get_parameters().push_back( new ObjectDecl( member->get_name(), Type::StorageClasses(), LinkageSpec::Cforall, 0, member->get_type()->clone(), 0 ) ); 480 467 FunctionDecl * ctor = genFunc( "?{}", memCtorType->clone(), functionNesting ); 481 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor , isDynamicLayout);468 makeStructFieldCtorBody( aggregateDecl->get_members().begin(), aggregateDecl->get_members().end(), ctor ); 482 469 declsToAdd.push_back( ctor ); 483 470 } … … 490 477 void makeUnionFieldsAssignment( ObjectDecl * srcParam, ObjectDecl * dstParam, OutputIterator out ) { 491 478 UntypedExpr *copy = new UntypedExpr( new NameExpr( "__builtin_memcpy" ) ); 492 copy->get_args().push_back( new VariableExpr( dstParam) );479 copy->get_args().push_back( new AddressExpr( new VariableExpr( dstParam ) ) ); 493 480 copy->get_args().push_back( new AddressExpr( new VariableExpr( srcParam ) ) ); 494 481 copy->get_args().push_back( new SizeofExpr( srcParam->get_type()->clone() ) ); … … 502 489 ObjectDecl * dstParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().front() ); 503 490 ObjectDecl * srcParam = safe_dynamic_cast< ObjectDecl * >( ftype->get_parameters().back() ); 504 ObjectDecl * returnVal = nullptr;505 if ( ! ftype->get_returnVals().empty() ) {506 returnVal = safe_dynamic_cast< ObjectDecl * >( ftype->get_returnVals().front() );507 }508 491 509 492 makeUnionFieldsAssignment( srcParam, dstParam, back_inserter( funcDecl->get_statements()->get_kids() ) ); 510 if ( returnVal ) { 493 if ( CodeGen::isAssignment( funcDecl->get_name() ) ) { 494 // also generate return statement in assignment 511 495 funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( noLabels, new VariableExpr( srcParam ) ) ); 512 496 } … … 535 519 cloneAll( typeParams, copyCtorType->get_forall() ); 536 520 cloneAll( typeParams, assignType->get_forall() ); 521 522 // add unused attribute to parameters of default constructor and destructor 523 ctorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 524 dtorType->get_parameters().front()->get_attributes().push_back( new Attribute( "unused" ) ); 537 525 538 526 // Routines at global scope marked "static" to prevent multiple definitions is separate translation units -
src/SymTab/Autogen.h
r135b431 r6b224a52 40 40 extern Type * SizeType; 41 41 42 /// intrinsic dereference operator for unqualified types - set when *? function is seen in FindSpecialDeclarations. 43 /// Useful for creating dereference ApplicationExprs without a full resolver pass. 44 extern FunctionDecl * dereferenceOperator; 45 46 // temporary 47 FunctionType * genAssignType( Type * paramType ); 48 42 49 /// inserts into out a generated call expression to function fname with arguments dstParam and srcParam. Intended to be used with generated ?=?, ?{}, and ^?{} calls. 43 50 template< typename OutputIterator > … … 48 55 template< typename OutputIterator > 49 56 Statement * genScalarCall( InitTweak::InitExpander & srcParam, Expression *dstParam, const std::string & fname, OutputIterator out, Type * type, bool addCast = false ) { 50 // want to be able to generate assignment, ctor, and dtor generically,51 // so fname is either ?=?, ?{}, or ^?{}52 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) );57 // want to be able to generate assignment, ctor, and dtor generically, 58 // so fname is either ?=?, ?{}, or ^?{} 59 UntypedExpr *fExpr = new UntypedExpr( new NameExpr( fname ) ); 53 60 54 // do something special for unnamed members 55 dstParam = new AddressExpr( dstParam ); 56 if ( addCast ) { 57 // cast to T* with qualifiers removed, so that qualified objects can be constructed 58 // and destructed with the same functions as non-qualified objects. 59 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 60 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 61 // remove lvalue as a qualifier, this can change to 62 // type->get_qualifiers() = Type::Qualifiers(); 63 assert( type ); 64 Type * castType = type->clone(); 65 castType->get_qualifiers() -= Type::Qualifiers( Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 66 castType->set_lvalue( true ); // xxx - might not need this 67 dstParam = new CastExpr( dstParam, new PointerType( Type::Qualifiers(), castType ) ); 68 } 69 fExpr->get_args().push_back( dstParam ); 61 if ( addCast ) { 62 // cast to T& with qualifiers removed, so that qualified objects can be constructed 63 // and destructed with the same functions as non-qualified objects. 64 // unfortunately, lvalue is considered a qualifier. For AddressExpr to resolve, its argument 65 // must have an lvalue qualified type, so remove all qualifiers except lvalue. If we ever 66 // remove lvalue as a qualifier, this can change to 67 // type->get_qualifiers() = Type::Qualifiers(); 68 assert( type ); 69 Type * castType = type->clone(); 70 castType->get_qualifiers() -= Type::Qualifiers( Type::Lvalue | Type::Const | Type::Volatile | Type::Restrict | Type::Atomic ); 71 // castType->set_lvalue( true ); // xxx - might not need this 72 dstParam = new CastExpr( dstParam, new ReferenceType( Type::Qualifiers(), castType ) ); 73 } 74 fExpr->get_args().push_back( dstParam ); 70 75 71 Statement * listInit = srcParam.buildListInit( fExpr );76 Statement * listInit = srcParam.buildListInit( fExpr ); 72 77 73 std::list< Expression * > args = *++srcParam;74 fExpr->get_args().splice( fExpr->get_args().end(), args );78 std::list< Expression * > args = *++srcParam; 79 fExpr->get_args().splice( fExpr->get_args().end(), args ); 75 80 76 *out++ = new ExprStmt( noLabels, fExpr );81 *out++ = new ExprStmt( noLabels, fExpr ); 77 82 78 srcParam.clearArrayIndices();83 srcParam.clearArrayIndices(); 79 84 80 return listInit;85 return listInit; 81 86 } 82 87 … … 114 119 115 120 UntypedExpr *inc = new UntypedExpr( update ); 116 inc->get_args().push_back( new AddressExpr( new VariableExpr( index )) );121 inc->get_args().push_back( new VariableExpr( index ) ); 117 122 118 123 UntypedExpr *dstIndex = new UntypedExpr( new NameExpr( "?[?]" ) ); -
src/SymTab/Indexer.cc
r135b431 r6b224a52 23 23 #include <utility> // for pair, make_pair, move 24 24 25 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 25 26 #include "Common/SemanticError.h" // for SemanticError 26 27 #include "Common/utility.h" // for cloneAll … … 111 112 void Indexer::removeSpecialOverrides( const std::string &id, std::list< DeclarationWithType * > & out ) const { 112 113 // only need to perform this step for constructors, destructors, and assignment functions 113 if ( ! InitTweak::isCtorDtorAssign( id ) ) return;114 if ( ! CodeGen::isCtorDtorAssign( id ) ) return; 114 115 115 116 // helpful data structure … … 139 140 decls.push_back( DeclBall{ function, isUserDefinedFunc, isDefaultCtor, isDtor, isCopyFunc } ); 140 141 existsUserDefinedFunc = existsUserDefinedFunc || isUserDefinedFunc; 141 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && InitTweak::isConstructor( function->get_name() ) );142 existsUserDefinedCtor = existsUserDefinedCtor || (isUserDefinedFunc && CodeGen::isConstructor( function->get_name() ) ); 142 143 existsUserDefinedDtor = existsUserDefinedDtor || (isUserDefinedFunc && isDtor); 143 144 existsUserDefinedCopyFunc = existsUserDefinedCopyFunc || (isUserDefinedFunc && isCopyFunc); … … 157 158 assert( ! params.empty() ); 158 159 // use base type of pointer, so that qualifiers on the pointer type aren't considered. 159 Type * base = safe_dynamic_cast< PointerType * >( params.front()->get_type() )->get_base(); 160 Type * base = InitTweak::getPointerBase( params.front()->get_type() ); 161 assert( base ); 160 162 funcMap[ Mangler::mangle( base ) ] += function; 161 163 } else { -
src/SymTab/Mangler.cc
r135b431 r6b224a52 132 132 mangleName << "A0"; 133 133 maybeAccept( arrayType->get_base(), *this ); 134 } 135 136 void Mangler::visit( ReferenceType *refType ) { 137 printQualifiers( refType ); 138 mangleName << "R"; 139 maybeAccept( refType->get_base(), *this ); 134 140 } 135 141 … … 303 309 // Removed due to restrict not affecting function compatibility in GCC 304 310 // if ( type->get_isRestrict() ) { 305 // mangleName << " R";311 // mangleName << "E"; 306 312 // } // if 307 313 if ( type->get_lvalue() ) { -
src/SymTab/Mangler.h
r135b431 r6b224a52 42 42 virtual void visit( PointerType *pointerType ); 43 43 virtual void visit( ArrayType *arrayType ); 44 virtual void visit( ReferenceType *refType ); 44 45 virtual void visit( FunctionType *functionType ); 45 46 virtual void visit( StructInstType *aggregateUseType ); -
src/SymTab/Validate.cc
r135b431 r6b224a52 47 47 48 48 #include "CodeGen/CodeGenerator.h" // for genName 49 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 49 50 #include "Common/PassVisitor.h" // for PassVisitor, WithDeclsToAdd 50 51 #include "Common/ScopedMap.h" // for ScopedMap … … 239 240 }; 240 241 242 243 FunctionDecl * dereferenceOperator = nullptr; 244 struct FindSpecialDeclarations final { 245 void previsit( FunctionDecl * funcDecl ); 246 }; 247 241 248 void validate( std::list< Declaration * > &translationUnit, bool doDebug ) { 242 249 PassVisitor<EnumAndPointerDecay> epc; … … 245 252 PassVisitor<CompoundLiteral> compoundliteral; 246 253 PassVisitor<ValidateGenericParameters> genericParams; 254 PassVisitor<FindSpecialDeclarations> finder; 247 255 248 256 EliminateTypedef::eliminateTypedef( translationUnit ); … … 261 269 acceptAll( translationUnit, fpd ); 262 270 ArrayLength::computeLength( translationUnit ); 271 acceptAll( translationUnit, finder ); 263 272 } 264 273 … … 821 830 std::list< DeclarationWithType * > ¶ms = funcType->get_parameters(); 822 831 823 if ( InitTweak::isCtorDtorAssign( funcDecl->get_name() ) ) {832 if ( CodeGen::isCtorDtorAssign( funcDecl->get_name() ) ) { // TODO: also check /=, etc. 824 833 if ( params.size() == 0 ) { 825 834 throw SemanticError( "Constructors, destructors, and assignment functions require at least one parameter ", funcDecl ); 826 835 } 827 PointerType * ptrType = dynamic_cast< PointerType * >( params.front()->get_type() );828 if ( ! ptrType || ptrType->is_array()) {829 throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a pointer", funcDecl );836 ReferenceType * refType = dynamic_cast< ReferenceType * >( params.front()->get_type() ); 837 if ( ! refType ) { 838 throw SemanticError( "First parameter of a constructor, destructor, or assignment function must be a reference ", funcDecl ); 830 839 } 831 if ( InitTweak::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) {840 if ( CodeGen::isCtorDtor( funcDecl->get_name() ) && returnVals.size() != 0 ) { 832 841 throw SemanticError( "Constructors and destructors cannot have explicit return values ", funcDecl ); 833 842 } … … 945 954 } 946 955 } 956 957 void FindSpecialDeclarations::previsit( FunctionDecl * funcDecl ) { 958 if ( ! dereferenceOperator ) { 959 if ( funcDecl->get_name() == "*?" && funcDecl->get_linkage() == LinkageSpec::Intrinsic ) { 960 FunctionType * ftype = funcDecl->get_functionType(); 961 if ( ftype->get_parameters().size() == 1 && ftype->get_parameters().front()->get_type()->get_qualifiers() == Type::Qualifiers() ) { 962 dereferenceOperator = funcDecl; 963 } 964 } 965 } 966 } 947 967 } // namespace SymTab 948 968
Note:
See TracChangeset
for help on using the changeset viewer.