/* * This file is part of the Cforall project * * $Id: MakeLibCfa.cc,v 1.6 2005/08/29 20:14:14 rcbilson Exp $ * */ #include "MakeLibCfa.h" #include "SynTree/Declaration.h" #include "SynTree/Type.h" #include "SynTree/Expression.h" #include "SynTree/Statement.h" #include "SynTree/Initializer.h" #include "SynTree/Visitor.h" #include "CodeGen/OperatorTable.h" #include "UniqueName.h" namespace LibCfa { class MakeLibCfa : public Visitor { public: void visit( FunctionDecl* funcDecl ); void visit( ObjectDecl* objDecl ); std::list< Declaration* > &get_newDecls() { return newDecls; } private: std::list< Declaration* > newDecls; }; void makeLibCfa( std::list< Declaration* > &prelude ) { MakeLibCfa maker; acceptAll( prelude, maker ); prelude.splice( prelude.end(), maker.get_newDecls() ); } void MakeLibCfa::visit( FunctionDecl* origFuncDecl ) { if( origFuncDecl->get_linkage() != LinkageSpec::Intrinsic ) return; FunctionDecl *funcDecl = origFuncDecl->clone(); CodeGen::OperatorInfo opInfo; bool lookResult = CodeGen::operatorLookup( funcDecl->get_name(), opInfo ); assert( lookResult ); assert( !funcDecl->get_statements() ); UntypedExpr *newExpr = new UntypedExpr( new NameExpr( funcDecl->get_name() ) ); UniqueName paramNamer( "_p" ); std::list< DeclarationWithType* >::iterator param = funcDecl->get_functionType()->get_parameters().begin(); assert( param != funcDecl->get_functionType()->get_parameters().end() ); if( (*param)->get_name() == "" ) { (*param)->set_name( paramNamer.newName() ); (*param)->set_linkage( LinkageSpec::C ); } switch( opInfo.type ) { case CodeGen::OT_INDEX: case CodeGen::OT_CALL: case CodeGen::OT_PREFIX: case CodeGen::OT_POSTFIX: case CodeGen::OT_INFIX: newExpr->get_args().push_back( new VariableExpr( *param ) ); break; case CodeGen::OT_PREFIXASSIGN: case CodeGen::OT_POSTFIXASSIGN: case CodeGen::OT_INFIXASSIGN: { newExpr->get_args().push_back( new VariableExpr( *param ) ); /// UntypedExpr *deref = new UntypedExpr( new NameExpr( "*?" ) ); /// deref->get_args().push_back( new VariableExpr( *param ) ); /// newExpr->get_args().push_back( deref ); break; } case CodeGen::OT_CONSTANT: assert( false ); } for( param++; param != funcDecl->get_functionType()->get_parameters().end(); ++param ) { if( (*param)->get_name() == "" ) { (*param)->set_name( paramNamer.newName() ); (*param)->set_linkage( LinkageSpec::C ); } newExpr->get_args().push_back( new VariableExpr( *param ) ); } funcDecl->set_statements( new CompoundStmt( std::list< Label >() ) ); funcDecl->get_statements()->get_kids().push_back( new ReturnStmt( std::list< Label >(), newExpr ) ); newDecls.push_back( funcDecl ); } void MakeLibCfa::visit( ObjectDecl* origObjDecl ) { if( origObjDecl->get_linkage() != LinkageSpec::Intrinsic ) return; ObjectDecl *objDecl = origObjDecl->clone(); assert( !objDecl->get_init() ); std::list< Expression* > noDesignators; objDecl->set_init( new SingleInit( new NameExpr( objDecl->get_name() ), noDesignators ) ); newDecls.push_back( objDecl ); } } // namespace LibCfa