Changes in / [596bc0a:f265042]
- Location:
- src
- Files:
-
- 17 edited
-
CodeGen/CodeGenerator.cc (modified) (8 diffs)
-
InitTweak/FixInit.cc (modified) (5 diffs)
-
InitTweak/GenInit.cc (modified) (15 diffs)
-
InitTweak/GenInit.h (modified) (1 diff)
-
InitTweak/InitTweak.cc (modified) (9 diffs)
-
InitTweak/InitTweak.h (modified) (1 diff)
-
ResolvExpr/Resolver.cc (modified) (1 diff)
-
ResolvExpr/Resolver.h (modified) (1 diff)
-
ResolvExpr/TypeEnvironment.cc (modified) (1 diff)
-
SymTab/Autogen.cc (modified) (15 diffs)
-
SymTab/FixFunction.cc (modified) (1 diff)
-
SymTab/Indexer.cc (modified) (2 diffs)
-
SymTab/Indexer.h (modified) (3 diffs)
-
SymTab/Mangler.cc (modified) (15 diffs)
-
SymTab/Validate.cc (modified) (6 diffs)
-
SynTree/Visitor.h (modified) (1 diff)
-
main.cc (modified) (1 diff)
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r596bc0a rf265042 443 443 void CodeGenerator::postvisit( UntypedExpr * untypedExpr ) { 444 444 extension( untypedExpr ); 445 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr-> get_function()) ) {445 if ( NameExpr * nameExpr = dynamic_cast< NameExpr* >( untypedExpr->function ) ) { 446 446 OperatorInfo opInfo; 447 if ( operatorLookup( nameExpr-> get_name(), opInfo ) ) {448 std::list< Expression* >::iterator arg = untypedExpr-> get_args().begin();447 if ( operatorLookup( nameExpr->name, opInfo ) ) { 448 std::list< Expression* >::iterator arg = untypedExpr->args.begin(); 449 449 switch ( opInfo.type ) { 450 450 case OT_INDEX: 451 assert( untypedExpr-> get_args().size() == 2 );451 assert( untypedExpr->args.size() == 2 ); 452 452 (*arg++)->accept( *visitor ); 453 453 output << "["; … … 461 461 case OT_CTOR: 462 462 case OT_DTOR: 463 if ( untypedExpr-> get_args().size() == 1 ) {463 if ( untypedExpr->args.size() == 1 ) { 464 464 // the expression fed into a single parameter constructor or destructor may contain side 465 465 // effects, so must still output this expression … … 480 480 (*arg++)->accept( *visitor ); 481 481 output << opInfo.symbol << "{ "; 482 genCommaList( arg, untypedExpr-> get_args().end() );482 genCommaList( arg, untypedExpr->args.end() ); 483 483 output << "}) /* " << opInfo.inputName << " */"; 484 484 } // if … … 488 488 case OT_PREFIXASSIGN: 489 489 case OT_LABELADDRESS: 490 assert( untypedExpr-> get_args().size() == 1 );490 assert( untypedExpr->args.size() == 1 ); 491 491 output << "("; 492 492 output << opInfo.symbol; … … 497 497 case OT_POSTFIX: 498 498 case OT_POSTFIXASSIGN: 499 assert( untypedExpr-> get_args().size() == 1 );499 assert( untypedExpr->args.size() == 1 ); 500 500 (*arg)->accept( *visitor ); 501 501 output << opInfo.symbol; … … 504 504 case OT_INFIX: 505 505 case OT_INFIXASSIGN: 506 assert( untypedExpr-> get_args().size() == 2 );506 assert( untypedExpr->args.size() == 2 ); 507 507 output << "("; 508 508 (*arg++)->accept( *visitor ); … … 517 517 } // switch 518 518 } else { 519 if ( nameExpr->get_name() == "..." ) { // case V1 ... V2 or case V1~V2 520 assert( untypedExpr->get_args().size() == 2 ); 521 (*untypedExpr->get_args().begin())->accept( *visitor ); 522 output << " ... "; 523 (*--untypedExpr->get_args().end())->accept( *visitor ); 524 } else { // builtin routines 525 nameExpr->accept( *visitor ); 526 output << "("; 527 genCommaList( untypedExpr->get_args().begin(), untypedExpr->get_args().end() ); 528 output << ")"; 529 } // if 519 // builtin routines 520 nameExpr->accept( *visitor ); 521 output << "("; 522 genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() ); 523 output << ")"; 530 524 } // if 531 525 } else { 532 untypedExpr-> get_function()->accept( *visitor );526 untypedExpr->function->accept( *visitor ); 533 527 output << "("; 534 genCommaList( untypedExpr-> get_args().begin(), untypedExpr->get_args().end() );528 genCommaList( untypedExpr->args.begin(), untypedExpr->args.end() ); 535 529 output << ")"; 536 530 } // if … … 538 532 539 533 void CodeGenerator::postvisit( RangeExpr * rangeExpr ) { 540 rangeExpr-> get_low()->accept( *visitor );534 rangeExpr->low->accept( *visitor ); 541 535 output << " ... "; 542 rangeExpr-> get_high()->accept( *visitor );536 rangeExpr->high->accept( *visitor ); 543 537 } 544 538 -
src/InitTweak/FixInit.cc
r596bc0a rf265042 58 58 #include "SynTree/TypeSubstitution.h" // for TypeSubstitution, operator<< 59 59 #include "SynTree/Visitor.h" // for acceptAll, maybeAccept 60 #include "Tuples/Tuples.h" // for isTtype61 60 62 61 bool ctordtorp = false; // print all debug … … 339 338 } else if ( DeclarationWithType * funcDecl = dynamic_cast< DeclarationWithType * > ( function->get_var() ) ) { 340 339 FunctionType * ftype = dynamic_cast< FunctionType * >( GenPoly::getFunctionType( funcDecl->get_type() ) ); 341 assert ( ftype);340 assertf( ftype, "Function call without function type: %s", toString( funcDecl ).c_str() ); 342 341 if ( CodeGen::isConstructor( funcDecl->get_name() ) && ftype->get_parameters().size() == 2 ) { 343 342 Type * t1 = getPointerBase( ftype->get_parameters().front()->get_type() ); … … 368 367 } 369 368 370 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { 371 return dynamic_cast< VarArgsType * >( type ) || dynamic_cast< ReferenceType * >( type ) || GenPoly::getFunctionType( type ) || Tuples::isTtype( type ); 372 } 369 bool ResolveCopyCtors::skipCopyConstruct( Type * type ) { return ! isConstructable( type ); } 373 370 374 371 Expression * ResolveCopyCtors::makeCtorDtor( const std::string & fname, ObjectDecl * var, Expression * cpArg ) { … … 819 816 assert( ! ctorInit->get_ctor() || ! ctorInit->get_init() ); 820 817 Statement * dtor = ctorInit->get_dtor(); 818 // don't need to call intrinsic dtor, because it does nothing, but 819 // non-intrinsic dtors must be called 821 820 if ( dtor && ! isIntrinsicSingleArgCallStmt( dtor ) ) { 822 // don't need to call intrinsic dtor, because it does nothing, but823 // non-intrinsic dtors must be called821 // set dtor location to the object's location for error messages 822 ctorInit->dtor->location = objDecl->location; 824 823 reverseDeclOrder.front().push_front( objDecl ); 825 824 } // if … … 1012 1011 // skip non-DWT members 1013 1012 if ( ! field ) continue; 1013 // skip non-constructable members 1014 if ( ! tryConstruct( field ) ) continue; 1014 1015 // skip handled members 1015 1016 if ( ! unhandled.count( field ) ) continue; -
src/InitTweak/GenInit.cc
r596bc0a rf265042 62 62 }; 63 63 64 struct CtorDtor : public WithGuards, public WithShortCircuiting {64 struct CtorDtor : public WithGuards, public WithShortCircuiting, public WithVisitorRef<CtorDtor> { 65 65 /// create constructor and destructor statements for object declarations. 66 66 /// the actual call statements will be added in after the resolver has run … … 75 75 // that need to be constructed or destructed 76 76 void previsit( StructDecl *aggregateDecl ); 77 void previsit( __attribute__((unused)) UnionDecl * aggregateDecl ) { visit_children = false; } 78 void previsit( __attribute__((unused)) EnumDecl * aggregateDecl ) { visit_children = false; } 79 void previsit( __attribute__((unused)) TraitDecl * aggregateDecl ) { visit_children = false; } 80 void previsit( __attribute__((unused)) TypeDecl * typeDecl ) { visit_children = false; } 81 void previsit( __attribute__((unused)) TypedefDecl * typeDecl ) { visit_children = false; } 82 void previsit( __attribute__((unused)) FunctionType * funcType ) { visit_children = false; } 77 void previsit( AggregateDecl * ) { visit_children = false; } 78 void previsit( NamedTypeDecl * ) { visit_children = false; } 79 void previsit( FunctionType * ) { visit_children = false; } 83 80 84 81 void previsit( CompoundStmt * compoundStmt ); … … 96 93 }; 97 94 98 class HoistArrayDimension final : public GenPoly::DeclMutator { 99 public: 100 typedef GenPoly::DeclMutator Parent; 101 95 struct HoistArrayDimension final : public WithDeclsToAdd, public WithShortCircuiting, public WithGuards { 102 96 /// hoist dimension from array types in object declaration so that it uses a single 103 97 /// const variable of type size_t, so that side effecting array dimensions are only … … 105 99 static void hoistArrayDimension( std::list< Declaration * > & translationUnit ); 106 100 107 private: 108 using Parent::mutate; 109 110 virtual DeclarationWithType * mutate( ObjectDecl * objectDecl ) override; 111 virtual DeclarationWithType * mutate( FunctionDecl *functionDecl ) override; 101 void premutate( ObjectDecl * objectDecl ); 102 DeclarationWithType * postmutate( ObjectDecl * objectDecl ); 103 void premutate( FunctionDecl *functionDecl ); 112 104 // should not traverse into any of these declarations to find objects 113 105 // that need to be constructed or destructed 114 virtual Declaration* mutate( StructDecl *aggregateDecl ) override { return aggregateDecl; } 115 virtual Declaration* mutate( UnionDecl *aggregateDecl ) override { return aggregateDecl; } 116 virtual Declaration* mutate( EnumDecl *aggregateDecl ) override { return aggregateDecl; } 117 virtual Declaration* mutate( TraitDecl *aggregateDecl ) override { return aggregateDecl; } 118 virtual TypeDecl* mutate( TypeDecl *typeDecl ) override { return typeDecl; } 119 virtual Declaration* mutate( TypedefDecl *typeDecl ) override { return typeDecl; } 120 121 virtual Type* mutate( FunctionType *funcType ) override { return funcType; } 106 void premutate( AggregateDecl * ) { visit_children = false; } 107 void premutate( NamedTypeDecl * ) { visit_children = false; } 108 void premutate( FunctionType * ) { visit_children = false; } 122 109 123 110 void hoist( Type * type ); … … 128 115 129 116 void genInit( std::list< Declaration * > & translationUnit ) { 130 ReturnFixer::makeReturnTemp( translationUnit );117 fixReturnStatements( translationUnit ); 131 118 HoistArrayDimension::hoistArrayDimension( translationUnit ); 132 119 CtorDtor::generateCtorDtor( translationUnit ); 133 120 } 134 121 135 void ReturnFixer::makeReturnTemp( std::list< Declaration * > & translationUnit ) {122 void fixReturnStatements( std::list< Declaration * > & translationUnit ) { 136 123 PassVisitor<ReturnFixer> fixer; 137 124 mutateAll( translationUnit, fixer ); … … 143 130 // hands off if the function returns a reference - we don't want to allocate a temporary if a variable's address 144 131 // is being returned 145 if ( returnStmt->get_expr() && returnVals.size() == 1 && ! dynamic_cast< ReferenceType * >( returnVals.front()->get_type() ) ) {132 if ( returnStmt->get_expr() && returnVals.size() == 1 && isConstructable( returnVals.front()->get_type() ) ) { 146 133 // explicitly construct the return value using the return expression and the retVal object 147 134 assertf( returnVals.front()->get_name() != "", "Function %s has unnamed return value\n", funcName.c_str() ); … … 158 145 GuardValue( funcName ); 159 146 160 ftype = functionDecl-> get_functionType();161 funcName = functionDecl-> get_name();147 ftype = functionDecl->type; 148 funcName = functionDecl->name; 162 149 } 163 150 … … 165 152 // which would be incorrect if it is a side-effecting computation. 166 153 void HoistArrayDimension::hoistArrayDimension( std::list< Declaration * > & translationUnit ) { 167 HoistArrayDimension hoister; 168 hoister.mutateDeclarationList( translationUnit ); 169 } 170 171 DeclarationWithType * HoistArrayDimension::mutate( ObjectDecl * objectDecl ) { 154 PassVisitor<HoistArrayDimension> hoister; 155 mutateAll( translationUnit, hoister ); 156 } 157 158 void HoistArrayDimension::premutate( ObjectDecl * objectDecl ) { 159 GuardValue( storageClasses ); 172 160 storageClasses = objectDecl->get_storageClasses(); 173 DeclarationWithType * temp = Parent::mutate( objectDecl ); 161 } 162 163 DeclarationWithType * HoistArrayDimension::postmutate( ObjectDecl * objectDecl ) { 174 164 hoist( objectDecl->get_type() ); 175 return temp;165 return objectDecl; 176 166 } 177 167 … … 194 184 195 185 arrayType->set_dimension( new VariableExpr( arrayDimension ) ); 196 addDeclaration( arrayDimension );186 declsToAddBefore.push_back( arrayDimension ); 197 187 198 188 hoist( arrayType->get_base() ); … … 201 191 } 202 192 203 DeclarationWithType * HoistArrayDimension::mutate( FunctionDecl *functionDecl ) { 204 ValueGuard< bool > oldInFunc( inFunction ); 205 inFunction = true; 206 DeclarationWithType * decl = Parent::mutate( functionDecl ); 207 return decl; 193 void HoistArrayDimension::premutate( FunctionDecl * ) { 194 GuardValue( inFunction ); 208 195 } 209 196 … … 214 201 215 202 bool CtorDtor::isManaged( Type * type ) const { 216 // at least for now,references are never constructed203 // references are never constructed 217 204 if ( dynamic_cast< ReferenceType * >( type ) ) return false; 218 205 // need to clear and reset qualifiers when determining if a type is managed … … 221 208 if ( TupleType * tupleType = dynamic_cast< TupleType * > ( type ) ) { 222 209 // tuple is also managed if any of its components are managed 223 if ( std::any_of( tupleType-> get_types().begin(), tupleType->get_types().end(), [&](Type * type) { return isManaged( type ); }) ) {210 if ( std::any_of( tupleType->types.begin(), tupleType->types.end(), [&](Type * type) { return isManaged( type ); }) ) { 224 211 return true; 225 212 } … … 305 292 306 293 void CtorDtor::previsit( FunctionDecl *functionDecl ) { 294 visit_children = false; // do not try and construct parameters or forall parameters 307 295 GuardValue( inFunction ); 308 296 inFunction = true; … … 318 306 } 319 307 320 PassVisitor<CtorDtor> newCtorDtor; 321 newCtorDtor.pass = *this; 322 maybeAccept( functionDecl->get_statements(), newCtorDtor ); 323 visit_children = false; // do not try and construct parameters or forall parameters - must happen after maybeAccept 308 maybeAccept( functionDecl->get_statements(), *visitor ); 324 309 } 325 310 … … 340 325 } 341 326 342 void CtorDtor::previsit( __attribute__((unused)) CompoundStmt * compoundStmt) {327 void CtorDtor::previsit( CompoundStmt * ) { 343 328 GuardScope( managedTypes ); 344 329 } -
src/InitTweak/GenInit.h
r596bc0a rf265042 25 25 void genInit( std::list< Declaration * > & translationUnit ); 26 26 27 /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument 28 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr ); 27 /// Converts return statements into copy constructor calls on the hidden return variable 28 void fixReturnStatements( std::list< Declaration * > & translationUnit ); 29 30 /// generates a single ctor/dtor statement using objDecl as the 'this' parameter and arg as the optional argument 31 ImplicitCtorDtorStmt * genCtorDtor( const std::string & fname, ObjectDecl * objDecl, Expression * arg = nullptr ); 29 32 30 33 /// creates an appropriate ConstructorInit node which contains a constructor, destructor, and C-initializer -
src/InitTweak/InitTweak.cc
r596bc0a rf265042 1 #include <stddef.h> // for NULL2 1 #include <algorithm> // for find, all_of 3 2 #include <cassert> // for assertf, assert, strict_dynamic_cast … … 23 22 #include "SynTree/Type.h" // for FunctionType, ArrayType, PointerType 24 23 #include "SynTree/Visitor.h" // for Visitor, maybeAccept 24 #include "Tuples/Tuples.h" // for Tuples::isTtype 25 25 26 26 class UntypedValofExpr; … … 184 184 callExpr->get_args().splice( callExpr->get_args().end(), args ); 185 185 186 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), NULL);186 *out++ = new IfStmt( noLabels, cond, new ExprStmt( noLabels, callExpr ), nullptr ); 187 187 188 188 UntypedExpr * increment = new UntypedExpr( new NameExpr( "++?" ) ); … … 250 250 // To accomplish this, generate switch statement, consuming all of expander's elements 251 251 Statement * InitImpl::buildListInit( UntypedExpr * dst, std::list< Expression * > & indices ) { 252 if ( ! init ) return NULL;252 if ( ! init ) return nullptr; 253 253 CompoundStmt * block = new CompoundStmt( noLabels ); 254 254 build( dst, indices.begin(), indices.end(), init, back_inserter( block->get_kids() ) ); 255 255 if ( block->get_kids().empty() ) { 256 256 delete block; 257 return NULL;257 return nullptr; 258 258 } else { 259 init = NULL; // init was consumed in creating the list init259 init = nullptr; // init was consumed in creating the list init 260 260 return block; 261 261 } 262 262 } 263 263 264 Statement * ExprImpl::buildListInit( __attribute((unused)) UntypedExpr * dst, __attribute((unused)) std::list< Expression * > & indices) {265 return NULL;264 Statement * ExprImpl::buildListInit( UntypedExpr *, std::list< Expression * > & ) { 265 return nullptr; 266 266 } 267 267 … … 270 270 } 271 271 272 bool tryConstruct( ObjectDecl * objDecl ) { 272 bool tryConstruct( DeclarationWithType * dwt ) { 273 ObjectDecl * objDecl = dynamic_cast< ObjectDecl * >( dwt ); 274 if ( ! objDecl ) return false; 273 275 return ! LinkageSpec::isBuiltin( objDecl->get_linkage() ) && 274 (objDecl->get_init() == NULL || 275 ( objDecl->get_init() != NULL && objDecl->get_init()->get_maybeConstructed() )) 276 && ! objDecl->get_storageClasses().is_extern; 276 (objDecl->get_init() == nullptr || 277 ( objDecl->get_init() != nullptr && objDecl->get_init()->get_maybeConstructed() )) 278 && ! objDecl->get_storageClasses().is_extern 279 && isConstructable( objDecl->type ); 280 } 281 282 bool isConstructable( Type * type ) { 283 return ! dynamic_cast< VarArgsType * >( type ) && ! dynamic_cast< ReferenceType * >( type ) && ! dynamic_cast< FunctionType * >( type ) && ! Tuples::isTtype( type ); 277 284 } 278 285 … … 314 321 collectCtorDtorCalls( stmt, matches ); 315 322 assert( matches.size() <= 1 ); 316 return matches.size() == 1 ? matches.front() : NULL;323 return matches.size() == 1 ? matches.front() : nullptr; 317 324 } 318 325 … … 359 366 ApplicationExpr * isIntrinsicCallExpr( Expression * expr ) { 360 367 ApplicationExpr * appExpr = dynamic_cast< ApplicationExpr * >( expr ); 361 if ( ! appExpr ) return NULL;368 if ( ! appExpr ) return nullptr; 362 369 DeclarationWithType * function = getCalledFunction( appExpr->get_function() ); 363 370 assertf( function, "getCalledFunction returned nullptr: %s", toString( appExpr->get_function() ).c_str() ); 364 371 // check for Intrinsic only - don't want to remove all overridable ctor/dtors because autogenerated ctor/dtor 365 372 // will call all member dtors, and some members may have a user defined dtor. 366 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : NULL;373 return function->get_linkage() == LinkageSpec::Intrinsic ? appExpr : nullptr; 367 374 } 368 375 … … 482 489 return refType->get_base(); 483 490 } else { 484 return NULL;491 return nullptr; 485 492 } 486 493 } … … 488 495 Type * isPointerType( Type * type ) { 489 496 if ( getPointerBase( type ) ) return type; 490 else return NULL;497 else return nullptr; 491 498 } 492 499 -
src/InitTweak/InitTweak.h
r596bc0a rf265042 33 33 std::list< Expression * > makeInitList( Initializer * init ); 34 34 35 /// True if the resolver should try to construct objDecl 36 bool tryConstruct( ObjectDecl * objDecl ); 35 /// True if the resolver should try to construct dwt 36 bool tryConstruct( DeclarationWithType * dwt ); 37 38 /// True if the type can have a user-defined constructor 39 bool isConstructable( Type * t ); 37 40 38 41 /// True if the Initializer contains designations -
src/ResolvExpr/Resolver.cc
r596bc0a rf265042 95 95 PassVisitor<Resolver> resolver; 96 96 acceptAll( translationUnit, resolver ); 97 } 98 99 void resolveDecl( Declaration * decl, const SymTab::Indexer &indexer ) { 100 PassVisitor<Resolver> resolver( indexer ); 101 maybeAccept( decl, resolver ); 97 102 } 98 103 -
src/ResolvExpr/Resolver.h
r596bc0a rf265042 29 29 /// Checks types and binds syntactic constructs to typed representations 30 30 void resolve( std::list< Declaration * > translationUnit ); 31 Expression * resolveInVoidContext( Expression *expr , const SymTab::Indexer &indexer ); 32 Expression * findVoidExpression ( Expression *untyped, const SymTab::Indexer &indexer ); 31 void resolveDecl( Declaration *, const SymTab::Indexer &indexer ); 32 Expression *resolveInVoidContext( Expression *expr, const SymTab::Indexer &indexer ); 33 Expression *findVoidExpression( Expression *untyped, const SymTab::Indexer &indexer ); 33 34 Expression * findSingleExpression( Expression *untyped, const SymTab::Indexer &indexer ); 34 35 void resolveCtorInit( ConstructorInit * ctorInit, const SymTab::Indexer & indexer ); -
src/ResolvExpr/TypeEnvironment.cc
r596bc0a rf265042 123 123 for ( std::list< EqvClass >::const_iterator theClass = env.begin(); theClass != env.end(); ++theClass ) { 124 124 for ( std::set< std::string >::const_iterator theVar = theClass->vars.begin(); theVar != theClass->vars.end(); ++theVar ) { 125 /// std::c out<< "adding " << *theVar;125 /// std::cerr << "adding " << *theVar; 126 126 if ( theClass->type ) { 127 /// std::c out<< " bound to ";128 /// theClass->type->print( std::c out);129 /// std::c out<< std::endl;127 /// std::cerr << " bound to "; 128 /// theClass->type->print( std::cerr ); 129 /// std::cerr << std::endl; 130 130 sub.add( *theVar, theClass->type ); 131 131 } else if ( theVar != theClass->vars.begin() ) { 132 132 TypeInstType *newTypeInst = new TypeInstType( Type::Qualifiers(), *theClass->vars.begin(), theClass->data.kind == TypeDecl::Ftype ); 133 /// std::c out<< " bound to variable " << *theClass->vars.begin() << std::endl;133 /// std::cerr << " bound to variable " << *theClass->vars.begin() << std::endl; 134 134 sub.add( *theVar, newTypeInst ); 135 135 delete newTypeInst; -
src/SymTab/Autogen.cc
r596bc0a rf265042 16 16 #include "Autogen.h" 17 17 18 #include <cstddef> // for NULL19 18 #include <algorithm> // for count_if 20 19 #include <cassert> // for strict_dynamic_cast, assert, assertf … … 27 26 #include "AddVisit.h" // for addVisit 28 27 #include "CodeGen/OperatorTable.h" // for isCtorDtor, isCtorDtorAssign 28 #include "Common/PassVisitor.h" // for PassVisitor 29 29 #include "Common/ScopedMap.h" // for ScopedMap<>::const_iterator, Scope... 30 30 #include "Common/utility.h" // for cloneAll, operator+ 31 31 #include "GenPoly/DeclMutator.h" // for DeclMutator 32 32 #include "GenPoly/ScopedSet.h" // for ScopedSet, ScopedSet<>::iterator 33 #include "InitTweak/GenInit.h" // for fixReturnStatements 34 #include "ResolvExpr/Resolver.h" // for resolveDecl 33 35 #include "SymTab/Mangler.h" // for Mangler 34 36 #include "SynTree/Attribute.h" // For Attribute … … 53 55 }; 54 56 55 class AutogenerateRoutines final : public Visitor { 56 template< typename Visitor > 57 friend void acceptAndAdd( std::list< Declaration * > &translationUnit, Visitor &visitor ); 58 template< typename Visitor > 59 friend void addVisitStatementList( std::list< Statement* > &stmts, Visitor &visitor ); 60 public: 61 std::list< Declaration * > &get_declsToAdd() { return declsToAdd; } 62 63 typedef Visitor Parent; 64 using Parent::visit; 65 57 struct AutogenerateRoutines final : public WithDeclsToAdd, public WithVisitorRef<AutogenerateRoutines>, public WithGuards, public WithShortCircuiting { 66 58 AutogenerateRoutines(); 67 59 68 virtual void visit( EnumDecl *enumDecl ); 69 virtual void visit( StructDecl *structDecl ); 70 virtual void visit( UnionDecl *structDecl ); 71 virtual void visit( TypeDecl *typeDecl ); 72 virtual void visit( TraitDecl *ctxDecl ); 73 virtual void visit( FunctionDecl *functionDecl ); 74 75 virtual void visit( FunctionType *ftype ); 76 virtual void visit( PointerType *ftype ); 77 78 virtual void visit( CompoundStmt *compoundStmt ); 79 virtual void visit( SwitchStmt *switchStmt ); 60 void previsit( EnumDecl * enumDecl ); 61 void previsit( StructDecl * structDecl ); 62 void previsit( UnionDecl * structDecl ); 63 void previsit( TypeDecl * typeDecl ); 64 void previsit( TraitDecl * traitDecl ); 65 void previsit( FunctionDecl * functionDecl ); 66 67 void previsit( FunctionType * ftype ); 68 void previsit( PointerType * ptype ); 69 70 void previsit( CompoundStmt * compoundStmt ); 80 71 81 72 private: 82 template< typename StmtClass > void visitStatement( StmtClass *stmt ); 83 84 std::list< Declaration * > declsToAdd, declsToAddAfter; 85 std::set< std::string > structsDone; 73 GenPoly::ScopedSet< std::string > structsDone; 86 74 unsigned int functionNesting = 0; // current level of nested functions 87 75 /// Note: the following maps could be ScopedSets, but it should be easier to work … … 112 100 113 101 void autogenerateRoutines( std::list< Declaration * > &translationUnit ) { 114 AutogenerateRoutinesgenerator;115 acceptA ndAdd( translationUnit, generator );102 PassVisitor<AutogenerateRoutines> generator; 103 acceptAll( translationUnit, generator ); 116 104 117 105 // needs to be done separately because AutogenerateRoutines skips types that appear as function arguments, etc. … … 121 109 122 110 bool isUnnamedBitfield( ObjectDecl * obj ) { 123 return obj != NULL && obj->get_name() == "" && obj->get_bitfieldWidth() != NULL;111 return obj != nullptr && obj->get_name() == "" && obj->get_bitfieldWidth() != nullptr; 124 112 } 125 113 … … 128 116 FunctionDecl * decl = functionDecl->clone(); 129 117 delete decl->get_statements(); 130 decl->set_statements( NULL);118 decl->set_statements( nullptr ); 131 119 declsToAdd.push_back( decl ); 132 120 decl->fixUniqueId(); … … 339 327 assert( ! func->get_functionType()->get_parameters().empty() ); 340 328 ObjectDecl * dstParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().front() ); 341 ObjectDecl * srcParam = NULL;329 ObjectDecl * srcParam = nullptr; 342 330 if ( func->get_functionType()->get_parameters().size() == 2 ) { 343 331 srcParam = dynamic_cast<ObjectDecl*>( func->get_functionType()->get_parameters().back() ); … … 346 334 assert( dstParam ); 347 335 348 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : NULL;336 Expression *srcselect = srcParam ? new MemberExpr( field, new VariableExpr( srcParam ) ) : nullptr; 349 337 makeStructMemberOp( dstParam, srcselect, field, func, forward ); 350 338 } // if … … 385 373 } else { 386 374 // no matching parameter, initialize field with default ctor 387 makeStructMemberOp( dstParam, NULL, field, func );375 makeStructMemberOp( dstParam, nullptr, field, func ); 388 376 } 389 377 } … … 401 389 void makeStructFunctions( StructDecl *aggregateDecl, StructInstType *refType, unsigned int functionNesting, std::list< Declaration * > & declsToAdd, const std::vector< FuncData > & data ) { 402 390 // Builtins do not use autogeneration. 403 if ( aggregateDecl->get_linkage() == LinkageSpec::BuiltinCFA || 404 aggregateDecl->get_linkage() == LinkageSpec::BuiltinC ) { 391 if ( LinkageSpec::isBuiltin( aggregateDecl->get_linkage() ) ) { 405 392 return; 406 393 } 407 394 408 395 // Make function polymorphic in same parameters as generic struct, if applicable 409 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions396 const std::list< TypeDecl * > & typeParams = aggregateDecl->get_parameters(); // List of type variables to be placed on the generated functions 410 397 411 398 // generate each of the functions based on the supplied FuncData objects … … 572 559 // the order here determines the order that these functions are generated. 573 560 // assignment should come last since it uses copy constructor in return. 574 data.push_back( FuncData( "?{}", genDefaultType, constructable ) ); 575 data.push_back( FuncData( "?{}", genCopyType, copyable ) ); 576 data.push_back( FuncData( "^?{}", genDefaultType, destructable ) ); 577 data.push_back( FuncData( "?=?", genAssignType, assignable ) ); 578 } 579 580 void AutogenerateRoutines::visit( EnumDecl *enumDecl ) { 561 data.emplace_back( "?{}", genDefaultType, constructable ); 562 data.emplace_back( "?{}", genCopyType, copyable ); 563 data.emplace_back( "^?{}", genDefaultType, destructable ); 564 data.emplace_back( "?=?", genAssignType, assignable ); 565 } 566 567 void AutogenerateRoutines::previsit( EnumDecl * enumDecl ) { 568 visit_children = false; 581 569 if ( ! enumDecl->get_members().empty() ) { 582 570 EnumInstType *enumInst = new EnumInstType( Type::Qualifiers(), enumDecl->get_name() ); … … 586 574 } 587 575 588 void AutogenerateRoutines::visit( StructDecl *structDecl ) { 589 if ( structDecl->has_body() && structsDone.find( structDecl->get_name() ) == structsDone.end() ) { 590 StructInstType structInst( Type::Qualifiers(), structDecl->get_name() ); 591 for ( TypeDecl * typeDecl : structDecl->get_parameters() ) { 576 void AutogenerateRoutines::previsit( StructDecl * structDecl ) { 577 visit_children = false; 578 if ( structDecl->has_body() && structsDone.find( structDecl->name ) == structsDone.end() ) { 579 StructInstType structInst( Type::Qualifiers(), structDecl->name ); 580 for ( TypeDecl * typeDecl : structDecl->parameters ) { 592 581 // need to visit assertions so that they are added to the appropriate maps 593 acceptAll( typeDecl-> get_assertions(), *this);594 structInst. get_parameters().push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->get_name(), typeDecl ) ) );582 acceptAll( typeDecl->assertions, *visitor ); 583 structInst.parameters.push_back( new TypeExpr( new TypeInstType( Type::Qualifiers(), typeDecl->name, typeDecl ) ) ); 595 584 } 596 585 structInst.set_baseStruct( structDecl ); 597 586 makeStructFunctions( structDecl, &structInst, functionNesting, declsToAddAfter, data ); 598 structsDone.insert( structDecl-> get_name());587 structsDone.insert( structDecl->name ); 599 588 } // if 600 589 } 601 590 602 void AutogenerateRoutines::visit( UnionDecl *unionDecl ) { 591 void AutogenerateRoutines::previsit( UnionDecl * unionDecl ) { 592 visit_children = false; 603 593 if ( ! unionDecl->get_members().empty() ) { 604 594 UnionInstType unionInst( Type::Qualifiers(), unionDecl->get_name() ); … … 619 609 620 610 // generate ctor/dtors/assign for typedecls, e.g., otype T = int *; 621 void AutogenerateRoutines::visit( TypeDecl *typeDecl ) { 611 void AutogenerateRoutines::previsit( TypeDecl * typeDecl ) { 612 visit_children = false; 622 613 if ( ! typeDecl->base ) return; 623 614 … … 664 655 } 665 656 666 void addDecls( std::list< Declaration * > &declsToAdd, std::list< Statement * > &statements, std::list< Statement * >::iterator i ) { 667 for ( std::list< Declaration * >::iterator decl = declsToAdd.begin(); decl != declsToAdd.end(); ++decl ) { 668 statements.insert( i, new DeclStmt( noLabels, *decl ) ); 669 } // for 670 declsToAdd.clear(); 671 } 672 673 void AutogenerateRoutines::visit( FunctionType *) { 657 void AutogenerateRoutines::previsit( FunctionType *) { 674 658 // ensure that we don't add assignment ops for types defined as part of the function 675 } 676 677 void AutogenerateRoutines::visit( PointerType *) { 659 visit_children = false; 660 } 661 662 void AutogenerateRoutines::previsit( PointerType *) { 678 663 // ensure that we don't add assignment ops for types defined as part of the pointer 679 } 680 681 void AutogenerateRoutines::visit( TraitDecl *) { 664 visit_children = false; 665 } 666 667 void AutogenerateRoutines::previsit( TraitDecl * ) { 682 668 // ensure that we don't add assignment ops for types defined as part of the trait 683 } 684 685 template< typename StmtClass > 686 inline void AutogenerateRoutines::visitStatement( StmtClass *stmt ) { 687 std::set< std::string > oldStructs = structsDone; 688 addVisit( stmt, *this ); 689 structsDone = oldStructs; 690 } 691 692 void AutogenerateRoutines::visit( FunctionDecl *functionDecl ) { 669 visit_children = false; 670 } 671 672 void AutogenerateRoutines::previsit( FunctionDecl * functionDecl ) { 673 visit_children = false; 693 674 // record the existence of this function as appropriate 694 675 insert( functionDecl, constructable, InitTweak::isDefaultConstructor ); … … 697 678 insert( functionDecl, destructable, InitTweak::isDestructor ); 698 679 699 maybeAccept( functionDecl-> get_functionType(), *this);680 maybeAccept( functionDecl->type, *visitor ); 700 681 functionNesting += 1; 701 maybeAccept( functionDecl-> get_statements(), *this);682 maybeAccept( functionDecl->statements, *visitor ); 702 683 functionNesting -= 1; 703 684 } 704 685 705 void AutogenerateRoutines::visit( CompoundStmt *compoundStmt ) { 706 constructable.beginScope(); 707 assignable.beginScope(); 708 copyable.beginScope(); 709 destructable.beginScope(); 710 visitStatement( compoundStmt ); 711 constructable.endScope(); 712 assignable.endScope(); 713 copyable.endScope(); 714 destructable.endScope(); 715 } 716 717 void AutogenerateRoutines::visit( SwitchStmt *switchStmt ) { 718 visitStatement( switchStmt ); 686 void AutogenerateRoutines::previsit( CompoundStmt * ) { 687 GuardScope( constructable ); 688 GuardScope( assignable ); 689 GuardScope( copyable ); 690 GuardScope( destructable ); 691 GuardScope( structsDone ); 719 692 } 720 693 -
src/SymTab/FixFunction.cc
r596bc0a rf265042 27 27 28 28 DeclarationWithType * FixFunction::mutate(FunctionDecl *functionDecl) { 29 // can't delete function type because it may contain assertions, so transfer ownership to new object 29 30 ObjectDecl *pointer = new ObjectDecl( functionDecl->get_name(), functionDecl->get_storageClasses(), functionDecl->get_linkage(), 0, new PointerType( Type::Qualifiers(), functionDecl->get_type() ), 0, functionDecl->get_attributes() ); 30 31 functionDecl->get_attributes().clear(); 31 // can't delete function type because it may contain assertions, but can't transfer ownership without a clone since set_type checks for nullptr 32 functionDecl->set_type( functionDecl->get_type()->clone() ); 32 functionDecl->type = nullptr; 33 33 delete functionDecl; 34 34 return pointer; -
src/SymTab/Indexer.cc
r596bc0a rf265042 40 40 41 41 namespace SymTab { 42 struct NewScope {43 NewScope( SymTab::Indexer & indexer ) : indexer( indexer ) { indexer.enterScope(); }44 ~NewScope() { indexer.leaveScope(); }45 SymTab::Indexer & indexer;46 };47 48 template< typename TreeType, typename VisitorType >49 inline void acceptNewScope( TreeType *tree, VisitorType &visitor ) {50 visitor.enterScope();51 maybeAccept( tree, visitor );52 visitor.leaveScope();53 }54 55 42 typedef std::unordered_map< std::string, DeclarationWithType* > MangleTable; 56 43 typedef std::unordered_map< std::string, MangleTable > IdTable; … … 198 185 } 199 186 200 Indexer::Indexer( bool _doDebug ) : tables( 0 ), scope( 0 ), doDebug( _doDebug) {}201 202 Indexer::Indexer( const Indexer &that ) : tables( newRef( that.tables ) ), scope( that.scope ), doDebug( that.doDebug) {}203 204 Indexer::Indexer( Indexer &&that ) : tables( that.tables ), scope( that.scope ), doDebug( that.doDebug) {187 Indexer::Indexer() : tables( 0 ), scope( 0 ) {} 188 189 Indexer::Indexer( const Indexer &that ) : doDebug( that.doDebug ), tables( newRef( that.tables ) ), scope( that.scope ) {} 190 191 Indexer::Indexer( Indexer &&that ) : doDebug( that.doDebug ), tables( that.tables ), scope( that.scope ) { 205 192 that.tables = 0; 206 193 } -
src/SymTab/Indexer.h
r596bc0a rf265042 26 26 class Indexer { 27 27 public: 28 explicit Indexer( bool useDebug = false);28 explicit Indexer(); 29 29 30 30 Indexer( const Indexer &that ); … … 76 76 void addTrait( TraitDecl *decl ); 77 77 78 bool doDebug = false; ///< Display debugging trace? 78 79 private: 79 80 struct Impl; … … 81 82 Impl *tables; ///< Copy-on-write instance of table data structure 82 83 unsigned long scope; ///< Scope index of this pointer 83 bool doDebug; ///< Display debugging trace?84 84 85 85 /// Takes a new ref to a table (returns null if null) -
src/SymTab/Mangler.cc
r596bc0a rf265042 31 31 32 32 namespace SymTab { 33 std::string Mangler::mangleType( Type * ty ) {33 std::string Mangler::mangleType( Type * ty ) { 34 34 Mangler mangler( false, true ); 35 35 maybeAccept( ty, mangler ); … … 48 48 } 49 49 50 void Mangler::mangleDecl( DeclarationWithType * declaration ) {50 void Mangler::mangleDecl( DeclarationWithType * declaration ) { 51 51 bool wasTopLevel = isTopLevel; 52 52 if ( isTopLevel ) { … … 79 79 } 80 80 81 void Mangler::visit( ObjectDecl * declaration ) {81 void Mangler::visit( ObjectDecl * declaration ) { 82 82 mangleDecl( declaration ); 83 83 } 84 84 85 void Mangler::visit( FunctionDecl * declaration ) {85 void Mangler::visit( FunctionDecl * declaration ) { 86 86 mangleDecl( declaration ); 87 87 } 88 88 89 void Mangler::visit( VoidType * voidType ) {89 void Mangler::visit( VoidType * voidType ) { 90 90 printQualifiers( voidType ); 91 91 mangleName << "v"; 92 92 } 93 93 94 void Mangler::visit( BasicType * basicType ) {94 void Mangler::visit( BasicType * basicType ) { 95 95 static const char *btLetter[] = { 96 96 "b", // Bool … … 121 121 } 122 122 123 void Mangler::visit( PointerType * pointerType ) {123 void Mangler::visit( PointerType * pointerType ) { 124 124 printQualifiers( pointerType ); 125 125 mangleName << "P"; … … 127 127 } 128 128 129 void Mangler::visit( ArrayType * arrayType ) {129 void Mangler::visit( ArrayType * arrayType ) { 130 130 // TODO: encode dimension 131 131 printQualifiers( arrayType ); … … 134 134 } 135 135 136 void Mangler::visit( ReferenceType * refType ) {136 void Mangler::visit( ReferenceType * refType ) { 137 137 printQualifiers( refType ); 138 138 mangleName << "R"; … … 149 149 } 150 150 151 void Mangler::visit( FunctionType * functionType ) {151 void Mangler::visit( FunctionType * functionType ) { 152 152 printQualifiers( functionType ); 153 153 mangleName << "F"; … … 160 160 } 161 161 162 void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) {162 void Mangler::mangleRef( ReferenceToType * refType, std::string prefix ) { 163 163 printQualifiers( refType ); 164 164 … … 166 166 } 167 167 168 void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) {168 void Mangler::mangleGenericRef( ReferenceToType * refType, std::string prefix ) { 169 169 printQualifiers( refType ); 170 170 … … 189 189 } 190 190 191 void Mangler::visit( StructInstType * aggregateUseType ) {191 void Mangler::visit( StructInstType * aggregateUseType ) { 192 192 if ( typeMode ) mangleGenericRef( aggregateUseType, "s" ); 193 193 else mangleRef( aggregateUseType, "s" ); 194 194 } 195 195 196 void Mangler::visit( UnionInstType * aggregateUseType ) {196 void Mangler::visit( UnionInstType * aggregateUseType ) { 197 197 if ( typeMode ) mangleGenericRef( aggregateUseType, "u" ); 198 198 else mangleRef( aggregateUseType, "u" ); 199 199 } 200 200 201 void Mangler::visit( EnumInstType * aggregateUseType ) {201 void Mangler::visit( EnumInstType * aggregateUseType ) { 202 202 mangleRef( aggregateUseType, "e" ); 203 203 } 204 204 205 void Mangler::visit( TypeInstType * typeInst ) {205 void Mangler::visit( TypeInstType * typeInst ) { 206 206 VarMapType::iterator varNum = varNums.find( typeInst->get_name() ); 207 207 if ( varNum == varNums.end() ) { … … 231 231 } 232 232 233 void Mangler::visit( TupleType * tupleType ) {233 void Mangler::visit( TupleType * tupleType ) { 234 234 printQualifiers( tupleType ); 235 235 mangleName << "T"; 236 acceptAll( tupleType-> get_types(), *this );236 acceptAll( tupleType->types, *this ); 237 237 mangleName << "_"; 238 238 } 239 239 240 void Mangler::visit( VarArgsType * varArgsType ) {240 void Mangler::visit( VarArgsType * varArgsType ) { 241 241 printQualifiers( varArgsType ); 242 242 mangleName << "VARGS"; 243 243 } 244 244 245 void Mangler::visit( __attribute__((unused)) ZeroType *zeroType) {245 void Mangler::visit( ZeroType * ) { 246 246 mangleName << "Z"; 247 247 } 248 248 249 void Mangler::visit( __attribute__((unused)) OneType *oneType) {249 void Mangler::visit( OneType * ) { 250 250 mangleName << "O"; 251 251 } 252 252 253 void Mangler::visit( TypeDecl * decl ) {253 void Mangler::visit( TypeDecl * decl ) { 254 254 static const char *typePrefix[] = { "BT", "BD", "BF" }; 255 mangleName << typePrefix[ decl->get_kind() ] << ( decl-> get_name().length() + 1 ) << decl->get_name();255 mangleName << typePrefix[ decl->get_kind() ] << ( decl->name.length() + 1 ) << decl->name; 256 256 } 257 257 … … 262 262 } 263 263 264 void Mangler::printQualifiers( Type * type ) {264 void Mangler::printQualifiers( Type * type ) { 265 265 // skip if not including qualifiers 266 266 if ( typeMode ) return; … … 270 270 int tcount = 0, dcount = 0, fcount = 0, vcount = 0; 271 271 mangleName << "A"; 272 for ( Type::ForallList::iterator i = type-> get_forall().begin(); i != type->get_forall().end(); ++i ) {272 for ( Type::ForallList::iterator i = type->forall.begin(); i != type->forall.end(); ++i ) { 273 273 switch ( (*i)->get_kind() ) { 274 274 case TypeDecl::Any: … … 287 287 assert( false ); 288 288 } // switch 289 varNums[ (*i )->get_name() ] = std::pair< int, int >( nextVarNum++, (int )(*i)->get_kind() );290 for ( std::list< DeclarationWithType* >::iterator assert = (*i )->get_assertions().begin(); assert != (*i )->get_assertions().end(); ++assert ) {289 varNums[ (*i)->name ] = std::pair< int, int >( nextVarNum++, (int)(*i)->get_kind() ); 290 for ( std::list< DeclarationWithType* >::iterator assert = (*i)->assertions.begin(); assert != (*i)->assertions.end(); ++assert ) { 291 291 Mangler sub_mangler( mangleOverridable, typeMode ); 292 292 sub_mangler.nextVarNum = nextVarNum; … … 315 315 // } // if 316 316 if ( type->get_lvalue() ) { 317 // mangle based on whether the type is lvalue, so that the resolver can differentiate lvalues and rvalues 317 318 mangleName << "L"; 318 } // if319 } 319 320 if ( type->get_atomic() ) { 320 321 mangleName << "A"; -
src/SymTab/Validate.cc
r596bc0a rf265042 56 56 #include "FixFunction.h" // for FixFunction 57 57 #include "Indexer.h" // for Indexer 58 #include "InitTweak/GenInit.h" // for fixReturnStatements 58 59 #include "InitTweak/InitTweak.h" // for isCtorDtorAssign 59 60 #include "Parser/LinkageSpec.h" // for C … … 150 151 /// Replaces array and function types in forall lists by appropriate pointer type and assigns each Object and Function declaration a unique ID. 151 152 struct ForallPointerDecay final { 152 void previsit( ObjectDecl * object );153 void previsit( FunctionDecl * func );153 void previsit( ObjectDecl * object ); 154 void previsit( FunctionDecl * func ); 154 155 }; 155 156 … … 579 580 580 581 /// Fix up assertions - flattens assertion lists, removing all trait instances 581 void forallFixer( Type * func) {582 for ( TypeDecl * type : f unc->get_forall()) {582 void forallFixer( std::list< TypeDecl * > & forall, BaseSyntaxNode * node ) { 583 for ( TypeDecl * type : forall ) { 583 584 std::list< DeclarationWithType * > asserts; 584 585 asserts.splice( asserts.end(), type->assertions ); … … 599 600 assertion = assertion->acceptMutator( fixer ); 600 601 if ( fixer.get_isVoid() ) { 601 throw SemanticError( "invalid type void in assertion of function ", func);602 throw SemanticError( "invalid type void in assertion of function ", node ); 602 603 } // if 603 604 } // for … … 607 608 608 609 void ForallPointerDecay::previsit( ObjectDecl *object ) { 609 forallFixer( object-> get_type());610 if ( PointerType *pointer = dynamic_cast< PointerType * >( object-> get_type()) ) {611 forallFixer( pointer-> get_base());610 forallFixer( object->type->forall, object ); 611 if ( PointerType *pointer = dynamic_cast< PointerType * >( object->type ) ) { 612 forallFixer( pointer->base->forall, object ); 612 613 } // if 613 614 object->fixUniqueId(); … … 615 616 616 617 void ForallPointerDecay::previsit( FunctionDecl *func ) { 617 forallFixer( func-> get_type());618 forallFixer( func->type->forall, func ); 618 619 func->fixUniqueId(); 619 620 } -
src/SynTree/Visitor.h
r596bc0a rf265042 25 25 public: 26 26 // visit: Default implementation of all functions visits the children 27 // of the given syntax node, but performs no other action.27 // of the given syntax node, but performs no other action. 28 28 29 29 virtual void visit( ObjectDecl *objectDecl ); -
src/main.cc
r596bc0a rf265042 239 239 } // if 240 240 241 // OPTPRINT( "Concurrency" )242 // Concurrency::applyKeywords( translationUnit );243 244 241 // add the assignment statement after the initialization of a type parameter 245 242 OPTPRINT( "validate" )
Note:
See TracChangeset
for help on using the changeset viewer.