Changes in / [424931d:ea23d10]
- Location:
- src
- Files:
-
- 15 edited
Legend:
- Unmodified
- Added
- Removed
-
src/CodeGen/CodeGenerator.cc
r424931d rea23d10 89 89 } 90 90 91 CodeGenerator::CodeGenerator( std::ostream & os, bool mangle ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), mangle( mangle) {}91 CodeGenerator::CodeGenerator( std::ostream & os, bool pretty ) : indent( *this), cur_indent( 0 ), insideFunction( false ), output( os ), printLabels( *this ), pretty( pretty ) {} 92 92 93 93 CodeGenerator::CodeGenerator( std::ostream & os, std::string init, int indentation, bool infunp ) … … 102 102 103 103 string CodeGenerator::mangleName( DeclarationWithType * decl ) { 104 if ( ! mangle) return decl->get_name();104 if ( pretty ) return decl->get_name(); 105 105 if ( decl->get_mangleName() != "" ) { 106 106 // need to incorporate scope level in order to differentiate names for destructors … … 140 140 output << "_Noreturn "; 141 141 } // if 142 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ) );142 output << genType( functionDecl->get_functionType(), mangleName( functionDecl ), pretty ); 143 143 144 144 // how to get this to the Functype? … … 161 161 162 162 handleStorageClass( objectDecl ); 163 output << genType( objectDecl->get_type(), mangleName( objectDecl ) );163 output << genType( objectDecl->get_type(), mangleName( objectDecl ), pretty ); 164 164 165 165 asmName( objectDecl ); … … 178 178 void CodeGenerator::handleAggregate( AggregateDecl * aggDecl ) { 179 179 genAttributes( aggDecl->get_attributes() ); 180 180 181 181 if ( aggDecl->get_name() != "" ) 182 182 output << aggDecl->get_name(); … … 249 249 assert( false && "Typedefs are removed and substituted in earlier passes." ); 250 250 //output << "typedef "; 251 //output << genType( typeDecl->get_base(), typeDecl->get_name() );251 //output << genType( typeDecl->get_base(), typeDecl->get_name(), pretty ); 252 252 } 253 253 … … 258 258 output << "extern unsigned long " << typeDecl->get_name(); 259 259 if ( typeDecl->get_base() ) { 260 output << " = sizeof( " << genType( typeDecl->get_base(), "" ) << " )";260 output << " = sizeof( " << genType( typeDecl->get_base(), "", pretty ) << " )"; 261 261 } // if 262 262 } … … 552 552 // at least one result type of cast, but not an lvalue 553 553 output << "("; 554 output << genType( castExpr->get_result(), "" );554 output << genType( castExpr->get_result(), "", pretty ); 555 555 output << ")"; 556 556 } else { … … 592 592 output << "sizeof("; 593 593 if ( sizeofExpr->get_isType() ) { 594 output << genType( sizeofExpr->get_type(), "" );594 output << genType( sizeofExpr->get_type(), "", pretty ); 595 595 } else { 596 596 sizeofExpr->get_expr()->accept( *this ); … … 604 604 output << "__alignof__("; 605 605 if ( alignofExpr->get_isType() ) { 606 output << genType( alignofExpr->get_type(), "" );606 output << genType( alignofExpr->get_type(), "", pretty ); 607 607 } else { 608 608 alignofExpr->get_expr()->accept( *this ); … … 618 618 // use GCC builtin 619 619 output << "__builtin_offsetof("; 620 output << genType( offsetofExpr->get_type(), "" );620 output << genType( offsetofExpr->get_type(), "", pretty ); 621 621 output << ", " << mangleName( offsetofExpr->get_member() ); 622 622 output << ")"; … … 680 680 void CodeGenerator::visit( CompoundLiteralExpr *compLitExpr ) { 681 681 assert( compLitExpr->get_type() && dynamic_cast< ListInit * > ( compLitExpr->get_initializer() ) ); 682 output << "(" << genType( compLitExpr->get_type(), "" ) << ")";682 output << "(" << genType( compLitExpr->get_type(), "", pretty ) << ")"; 683 683 compLitExpr->get_initializer()->accept( *this ); 684 684 } -
src/CodeGen/CodeGenerator.h
r424931d rea23d10 30 30 static int tabsize; 31 31 32 CodeGenerator( std::ostream &os, bool mangle = true );32 CodeGenerator( std::ostream &os, bool pretty = false ); 33 33 CodeGenerator( std::ostream &os, std::string, int indent = 0, bool infun = false ); 34 34 CodeGenerator( std::ostream &os, char *, int indent = 0, bool infun = false ); … … 119 119 std::ostream &output; 120 120 LabelPrinter printLabels; 121 bool mangle = true;121 bool pretty = false; // pretty print 122 122 123 123 void printDesignators( std::list< Expression * > & ); -
src/CodeGen/GenType.cc
r424931d rea23d10 28 28 class GenType : public Visitor { 29 29 public: 30 GenType( const std::string &typeString, bool mangle = true );30 GenType( const std::string &typeString, bool pretty = false ); 31 31 std::string get_typeString() const { return typeString; } 32 32 void set_typeString( const std::string &newValue ) { typeString = newValue; } … … 51 51 52 52 std::string typeString; 53 bool mangle = true;53 bool pretty = false; // pretty print 54 54 }; 55 55 56 std::string genType( Type *type, const std::string &baseString, bool mangle) {57 GenType gt( baseString, mangle);58 std::ostringstream os; 59 56 std::string genType( Type *type, const std::string &baseString, bool pretty ) { 57 GenType gt( baseString, pretty ); 58 std::ostringstream os; 59 60 60 if ( ! type->get_attributes().empty() ) { 61 CodeGenerator cg( os, mangle);61 CodeGenerator cg( os, pretty ); 62 62 cg.genAttributes( type->get_attributes() ); 63 63 } // if … … 67 67 } 68 68 69 GenType::GenType( const std::string &typeString, bool mangle ) : typeString( typeString ), mangle( mangle ) {} 69 std::string genPrettyType( Type * type, const std::string & baseString ) { 70 return genType( type, baseString, true ); 71 } 72 73 GenType::GenType( const std::string &typeString, bool pretty ) : typeString( typeString ), pretty( pretty ) {} 70 74 71 75 void GenType::visit( VoidType *voidType ) { … … 108 112 } // if 109 113 if ( dimension != 0 ) { 110 CodeGenerator cg( os, mangle);114 CodeGenerator cg( os, pretty ); 111 115 dimension->accept( cg ); 112 116 } else if ( isVarLen ) { … … 162 166 } // if 163 167 } else { 164 CodeGenerator cg( os, mangle);168 CodeGenerator cg( os, pretty ); 165 169 os << "(" ; 166 170 … … 203 207 204 208 void GenType::visit( TupleType * tupleType ) { 205 assertf( ! mangle, "Tuple types should not make it to Code Gen." );209 assertf( pretty, "Tuple types should not make it to Code Gen." ); 206 210 Visitor::visit( tupleType ); 211 unsigned int i = 0; 212 std::ostringstream os; 213 os << "["; 214 for ( Type * t : *tupleType ) { 215 i++; 216 os << genType( t, "", pretty ) << (i == tupleType->size() ? "" : ", "); 217 } 218 os << "]"; 219 typeString = os.str() + typeString; 207 220 } 208 221 … … 214 227 void GenType::visit( ZeroType *zeroType ) { 215 228 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 216 typeString = "long int "+ typeString;229 typeString = (pretty ? "zero_t " : "long int ") + typeString; 217 230 handleQualifiers( zeroType ); 218 231 } … … 220 233 void GenType::visit( OneType *oneType ) { 221 234 // ideally these wouldn't hit codegen at all, but should be safe to make them ints 222 typeString = "long int "+ typeString;235 typeString = (pretty ? "one_t " : "long int ") + typeString; 223 236 handleQualifiers( oneType ); 224 237 } -
src/CodeGen/GenType.h
r424931d rea23d10 21 21 22 22 namespace CodeGen { 23 std::string genType( Type *type, const std::string &baseString, bool mangle = true ); 23 std::string genType( Type *type, const std::string &baseString, bool pretty = false ); 24 std::string genPrettyType( Type * type, const std::string & baseString ); 24 25 } // namespace CodeGen 25 26 -
src/CodeGen/Generate.cc
r424931d rea23d10 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Generate.cc -- 7 // Generate.cc -- 8 8 // 9 9 // Author : Richard C. Bilson … … 26 26 27 27 namespace CodeGen { 28 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics ) {29 CodeGen::CodeGenerator cgv( os );28 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty ) { 29 CodeGen::CodeGenerator cgv( os, pretty ); 30 30 31 31 for ( std::list<Declaration *>::iterator i = translationUnit.begin(); i != translationUnit.end(); i++ ) { -
src/CodeGen/Generate.h
r424931d rea23d10 5 5 // file "LICENCE" distributed with Cforall. 6 6 // 7 // Generate.h -- 7 // Generate.h -- 8 8 // 9 9 // Author : Richard C. Bilson … … 24 24 namespace CodeGen { 25 25 /// Generates code 26 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics );26 void generate( std::list< Declaration* > translationUnit, std::ostream &os, bool doIntrinsics, bool pretty ); 27 27 } // namespace CodeGen 28 28 -
src/GenPoly/Box.cc
r424931d rea23d10 1307 1307 } 1308 1308 } 1309 // errors should have been caught by this point, remove initializers from parameters to allow correct codegen of default arguments 1310 for ( Declaration * param : functionDecl->get_functionType()->get_parameters() ) { 1311 if ( ObjectDecl * obj = dynamic_cast< ObjectDecl * >( param ) ) { 1312 delete obj->get_init(); 1313 obj->set_init( nullptr ); 1314 } 1315 } 1309 1316 return functionDecl; 1310 1317 } -
src/InitTweak/FixInit.cc
r424931d rea23d10 104 104 virtual void visit( CompoundStmt *compoundStmt ) override; 105 105 virtual void visit( DeclStmt *stmt ) override; 106 107 // don't go into other functions 108 virtual void visit( FunctionDecl *decl ) override {} 109 106 110 protected: 107 111 ObjectSet curVars; … … 166 170 typedef std::list< OrderedDecls > OrderedDeclsStack; 167 171 168 InsertDtors( LabelFinder & finder ) : labelVars( finder.vars ) {}172 InsertDtors( LabelFinder & finder ) : finder( finder ), labelVars( finder.vars ) {} 169 173 170 174 using Parent::visit; 171 175 172 176 virtual void visit( ObjectDecl * objDecl ) override; 177 virtual void visit( FunctionDecl * funcDecl ) override; 173 178 174 179 virtual void visit( CompoundStmt * compoundStmt ) override; … … 178 183 void handleGoto( BranchStmt * stmt ); 179 184 185 LabelFinder & finder; 180 186 LabelFinder::LabelMap & labelVars; 181 187 OrderedDeclsStack reverseDeclOrder; … … 318 324 LabelFinder finder; 319 325 InsertDtors inserter( finder ); 320 acceptAll( translationUnit, finder );321 326 acceptAll( translationUnit, inserter ); 322 327 } … … 778 783 } 779 784 780 void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) {785 void ObjDeclCollector::visit( CompoundStmt * compoundStmt ) { 781 786 std::set< ObjectDecl * > prevVars = curVars; 782 787 Parent::visit( compoundStmt ); … … 784 789 } 785 790 786 void ObjDeclCollector::visit( DeclStmt * stmt ) {791 void ObjDeclCollector::visit( DeclStmt * stmt ) { 787 792 // keep track of all variables currently in scope 788 793 if ( ObjectDecl * objDecl = dynamic_cast< ObjectDecl * > ( stmt->get_decl() ) ) { … … 828 833 } // if 829 834 Parent::visit( objDecl ); 835 } 836 837 template< typename Visitor > 838 void handleFuncDecl( FunctionDecl * funcDecl, Visitor & visitor ) { 839 maybeAccept( funcDecl->get_functionType(), visitor ); 840 acceptAll( funcDecl->get_oldDecls(), visitor ); 841 maybeAccept( funcDecl->get_statements(), visitor ); 842 } 843 844 void InsertDtors::visit( FunctionDecl * funcDecl ) { 845 // each function needs to have its own set of labels 846 ValueGuard< LabelFinder::LabelMap > oldLabels( labelVars ); 847 labelVars.clear(); 848 handleFuncDecl( funcDecl, finder ); 849 850 // all labels for this function have been collected, insert destructors as appropriate. 851 // can't be Parent::mutate, because ObjDeclCollector bottoms out on FunctionDecl 852 handleFuncDecl( funcDecl, *this ); 830 853 } 831 854 … … 952 975 std::set_difference( usedUninit.begin(), usedUninit.end(), unhandled.begin(), unhandled.end(), std::inserter( diff, diff.begin() ) ); 953 976 for ( DeclarationWithType * member : diff ) { 954 emit( "in ", CodeGen::gen Type( function->get_functionType(), function->get_name(), false), ", field ", member->get_name(), " used before being constructed" );977 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", member->get_name(), " used before being constructed" ); 955 978 } 956 979 … … 997 1020 } 998 1021 } catch ( SemanticError & error ) { 999 emit( "in ", CodeGen::gen Type( function->get_functionType(), function->get_name(), false), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" );1022 emit( "in ", CodeGen::genPrettyType( function->get_functionType(), function->get_name() ), ", field ", field->get_name(), " not explicitly ", isCtor ? "constructed" : "destructed", " and no ", isCtor ? "default constructor" : "destructor", " found" ); 1000 1023 } 1001 1024 } -
src/ResolvExpr/AlternativeFinder.cc
r424931d rea23d10 403 403 // End of actuals - Handle default values 404 404 if ( SingleInit *si = dynamic_cast<SingleInit *>( defaultValue )) { 405 // so far, only constant expressions are accepted as default values 406 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( si->get_value()) ) { 407 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) { 408 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 409 // xxx - Don't know if this is right 410 *out++ = cnstexpr->clone(); 411 return true; 405 if ( CastExpr * castExpr = dynamic_cast< CastExpr * >( si->get_value() ) ) { 406 // so far, only constant expressions are accepted as default values 407 if ( ConstantExpr *cnstexpr = dynamic_cast<ConstantExpr *>( castExpr->get_arg() ) ) { 408 if ( Constant *cnst = dynamic_cast<Constant *>( cnstexpr->get_constant() ) ) { 409 if ( unify( formalType, cnst->get_type(), resultEnv, resultNeed, resultHave, openVars, indexer ) ) { 410 *out++ = cnstexpr->clone(); 411 return true; 412 } // if 412 413 } // if 413 414 } // if 414 } // if415 } 415 416 } // if 416 417 return false; -
src/SymTab/Mangler.cc
r424931d rea23d10 172 172 for ( std::list< Expression* >::const_iterator param = params.begin(); param != params.end(); ++param ) { 173 173 TypeExpr *paramType = dynamic_cast< TypeExpr* >( *param ); 174 assert (paramType && "Aggregate parameters should be type expressions");174 assertf(paramType, "Aggregate parameters should be type expressions: %s", toString(*param).c_str()); 175 175 maybeAccept( paramType->get_type(), *this ); 176 176 } -
src/SymTab/Validate.cc
r424931d rea23d10 696 696 FunctionDecl * newDecl = new FunctionDecl( ret->get_name(), ret->get_storageClass(), ret->get_linkage(), funtype, 0, ret->get_isInline(), ret->get_isNoreturn(), objDecl->get_attributes() ); 697 697 objDecl->get_attributes().clear(); 698 objDecl->set_type( nullptr ); 698 699 delete objDecl; 699 700 return newDecl; -
src/main.cc
r424931d rea23d10 76 76 validp = false, 77 77 errorp = false, 78 codegenp = false; 78 codegenp = false, 79 prettycodegenp = false; 79 80 80 81 static void parse_cmdline( int argc, char *argv[], const char *& filename ); … … 309 310 } // if 310 311 311 CodeGen::generate( translationUnit, *output, ! noprotop );312 CodeGen::generate( translationUnit, *output, ! noprotop, prettycodegenp ); 312 313 313 314 CodeGen::FixMain::fix( *output, treep ? "../prelude/bootloader.c" : CFA_LIBDIR "/bootloader.c" ); … … 374 375 375 376 int c; 376 while ( (c = getopt_long( argc, argv, "abBcdefglmnpqrstTvyz D:F:", long_opts, &long_index )) != -1 ) {377 while ( (c = getopt_long( argc, argv, "abBcdefglmnpqrstTvyzZD:F:", long_opts, &long_index )) != -1 ) { 377 378 switch ( c ) { 378 379 case Ast: … … 450 451 case 'z': 451 452 codegenp = true; 453 case 'Z': 454 prettycodegenp = true; 452 455 break; 453 456 case 'D': // ignore -Dxxx -
src/tests/.expect/32/declarationSpecifier.txt
r424931d rea23d10 1 __attribute__ ((__ malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size); 2 2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr); 3 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void abort(void);4 __attribute__ ((__no nnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));5 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void exit(int __status);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void); 4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit(void (*__func)(void)); 5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status); 6 6 extern int printf(const char *__restrict __format, ...); 7 7 volatile const short __x1__CVs_1; … … 629 629 } 630 630 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 631 __attribute__ ((__ malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);631 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size); 632 632 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr); 633 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void abort(void);634 __attribute__ ((__no nnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));635 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void exit(int __status);633 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void); 634 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit(void (*__func)(void)); 635 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status); 636 636 extern int printf(const char *__restrict __format, ...); 637 637 static inline int invoke_main(int argc, char **argv, char **envp); -
src/tests/.expect/32/extension.txt
r424931d rea23d10 1 __attribute__ ((__ malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size); 2 2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr); 3 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void abort(void);4 __attribute__ ((__no nnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));5 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void exit(int __status);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void); 4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit(void (*__func)(void)); 5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status); 6 6 extern int printf(const char *__restrict __format, ...); 7 7 __extension__ int __a__i_1; … … 77 77 __B__C2eE_1, 78 78 }; 79 __extension__ int __f__Fi___1(); 80 __extension__ int i; 81 __extension__ int j; 79 82 __extension__ int __fred__Fi_i__1(int __p__i_1){ 80 83 int ___retval_fred__i_1; … … 83 86 __extension__ int __b__i_2; 84 87 __extension__ int __c__i_2; 88 __extension__ int *__x__Pi_2; 89 __extension__ int *__y__Pi_2; 90 __extension__ int *__z__Pi_2; 85 91 }; 86 92 int __i__i_2 = ((int )(__extension__ __a__i_1+__extension__ 3)); … … 94 100 ((void)((_tmp_cp_ret0=__extension__ __fred__Fi_i__1(3)) , _tmp_cp_ret0)); 95 101 ((void)((*((int *)(&_tmp_cp_ret0)))) /* ^?{} */); 102 __extension__ int __mary__Fi_i__2(int __p__i_2){ 103 int ___retval_mary__i_2; 104 } 96 105 ((void)__extension__ sizeof(3)); 97 106 ((void)__extension__ (((int )(3!=((int )0))) || ((int )(4!=((int )0))))); -
src/tests/.expect/32/gccExtensions.txt
r424931d rea23d10 1 __attribute__ ((__ malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);1 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size); 2 2 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr); 3 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void abort(void);4 __attribute__ ((__no nnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));5 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void exit(int __status);3 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void); 4 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit(void (*__func)(void)); 5 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status); 6 6 extern int printf(const char *__restrict __format, ...); 7 7 extern int __x__i_1 asm ( "xx" ); … … 166 166 } 167 167 static inline int invoke_main(int argc, char* argv[], char* envp[]) { (void)argc; (void)argv; (void)envp; return __main__Fi_iPPCc__1(argc, argv); } 168 __attribute__ ((__ malloc__,__nothrow__,__leaf__)) extern void *malloc(unsigned int __size);168 __attribute__ ((__nothrow__,__leaf__,__malloc__)) extern void *malloc(unsigned int __size); 169 169 __attribute__ ((__nothrow__,__leaf__)) extern void free(void *__ptr); 170 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void abort(void);171 __attribute__ ((__no nnull__(1),__nothrow__,__leaf__)) extern int atexit(void (*__func)(void));172 __attribute__ ((__no return__,__nothrow__,__leaf__)) extern void exit(int __status);170 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void abort(void); 171 __attribute__ ((__nothrow__,__leaf__,__nonnull__(1))) extern int atexit(void (*__func)(void)); 172 __attribute__ ((__nothrow__,__leaf__,__noreturn__)) extern void exit(int __status); 173 173 extern int printf(const char *__restrict __format, ...); 174 174 static inline int invoke_main(int argc, char **argv, char **envp);
Note: See TracChangeset
for help on using the changeset viewer.