diff options
author | Mike Emmel <mike.emmel@gmail.com> | 2006-01-18 00:53:12 +0000 |
---|---|---|
committer | Tom Tromey <tromey@redhat.com> | 2006-01-18 00:53:12 +0000 |
commit | 856ef236f62a9157d67c0cf9840ab6faa3bce397 (patch) | |
tree | 446a8262eede92b5e2e0e240e911e036e7413baf | |
parent | a3c1367a84fa9096cb7772f3407619e2219215ff (diff) |
2006-01-17 Mike Emmel <mike.emmel@gmail.com>
* llvm/llvmgen.hh, llvm/llvmfunction.cc, llvm/llvmclass.cc,
llvm/llvmgen.cc, llvm/llvmclass.hh, llvm/llvmfunction.hh: New
files.
git-svn-id: https://gcc.gnu.org/svn/gcc/branches/gcjx-branch@109859 138bc75d-0d04-0410-961f-82ee72b054a4
-rw-r--r-- | gcjx/ChangeLog | 6 | ||||
-rw-r--r-- | gcjx/llvm/llvmclass.cc | 79 | ||||
-rw-r--r-- | gcjx/llvm/llvmclass.hh | 45 | ||||
-rw-r--r-- | gcjx/llvm/llvmfunction.cc | 233 | ||||
-rw-r--r-- | gcjx/llvm/llvmfunction.hh | 84 | ||||
-rw-r--r-- | gcjx/llvm/llvmgen.cc | 1018 | ||||
-rw-r--r-- | gcjx/llvm/llvmgen.hh | 786 |
7 files changed, 2251 insertions, 0 deletions
diff --git a/gcjx/ChangeLog b/gcjx/ChangeLog index 6a397bd34ab..416ad62bd08 100644 --- a/gcjx/ChangeLog +++ b/gcjx/ChangeLog @@ -1,3 +1,9 @@ +2006-01-17 Mike Emmel <mike.emmel@gmail.com> + + * llvm/llvmgen.hh, llvm/llvmfunction.cc, llvm/llvmclass.cc, + llvm/llvmgen.cc, llvm/llvmclass.hh, llvm/llvmfunction.hh: New + files. + 2006-01-16 Mike Emmel <mike.emmel@gmail.com> * Makefile.in: Rebuilt. diff --git a/gcjx/llvm/llvmclass.cc b/gcjx/llvm/llvmclass.cc new file mode 100644 index 00000000000..b2a257d3afa --- /dev/null +++ b/gcjx/llvm/llvmclass.cc @@ -0,0 +1,79 @@ +// Code generator for llvm. + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// gcjx is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// gcjx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with gcjx; see the file COPYING.LIB. If +// not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "llvmclass.hh" + +#include "llvm/SymbolTable.h" +#include "llvm/Module.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/Bytecode/Writer.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/DepthFirstIterator.h" + +/** Generate C code**/ +#include "llvm/Bytecode/Reader.h" +#include "llvm/Target/SubtargetFeature.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetMachineRegistry.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PluginLoader.h" +#include "llvm/Support/PassNameParser.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/System/Signals.h" +#include "llvm/Config/config.h" +/** End gnerate c code **/ + + + +#include <list> +#include <utility> +#include <algorithm> +#include <fstream> +#include <iostream> +#include <memory> + + +using namespace std; +using namespace llvm; + + +llvm_class::llvm_class( Module *owner){ + this->owner = owner; +} + +void +llvm_class::addField(const Type *type,string name ) +{ + fields.push_back(type); +} + +void +llvm_class::emitStruct() +{ + classStruct = StructType::get(fields); +} diff --git a/gcjx/llvm/llvmclass.hh b/gcjx/llvm/llvmclass.hh new file mode 100644 index 00000000000..c61e523758e --- /dev/null +++ b/gcjx/llvm/llvmclass.hh @@ -0,0 +1,45 @@ +// Code generator for bytecode. + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// gcjx is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// gcjx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with gcjx; see the file COPYING.LIB. If +// not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef GCJX_LLVM_CLASS_HH +#define GCJX_LLVM_CLASS_HH + +#include "llvm/Module.h" +#include "llvm/Instructions.h" +#include "llvm/DerivedTypes.h" +#include <stack> +#include <iostream> + +using namespace llvm; +using namespace std; + +class llvm_class +{ +public: + Module *owner; + StructType *classStruct; + vector<const Type*> fields; + llvm_class( Module *owner); + void addField(const Type *type,string name ); + void emitStruct(); +}; + +#endif // GCJX_LLVM_CLASS_HH diff --git a/gcjx/llvm/llvmfunction.cc b/gcjx/llvm/llvmfunction.cc new file mode 100644 index 00000000000..ea45c44c633 --- /dev/null +++ b/gcjx/llvm/llvmfunction.cc @@ -0,0 +1,233 @@ +// Code generator for llvm. + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// gcjx is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// gcjx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with gcjx; see the file COPYING.LIB. If +// not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "llvmfunction.hh" + +#include "llvm/SymbolTable.h" +#include "llvm/Module.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/Bytecode/Writer.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/DepthFirstIterator.h" + +/** Generate C code**/ +#include "llvm/Bytecode/Reader.h" +#include "llvm/Target/SubtargetFeature.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetMachineRegistry.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PluginLoader.h" +#include "llvm/Support/PassNameParser.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/System/Signals.h" +#include "llvm/Config/config.h" +/** End gnerate c code **/ + + + +#include <list> +#include <utility> +#include <algorithm> +#include <fstream> +#include <iostream> +#include <memory> + + +using namespace std; +using namespace llvm; + + + +/// CastToType - Cast the specified value to the specified type if it is +/// not already that type. +Value *llvm_function::castToType(Value *V, const Type *Ty) { + if (V->getType() == Ty) return V; + if (Constant *C = dyn_cast<Constant>(V)) + return ConstantExpr::getCast(C, Ty); + + // Handle cast (cast bool X to T2) to bool as X, because this occurs all over + // the place. + if (CastInst *CI = dyn_cast<CastInst>(V)) + if (Ty == Type::BoolTy && CI->getOperand(0)->getType() == Type::BoolTy) + return CI->getOperand(0); + return new CastInst(V, Ty, V->getName(), currentBlock); +} + + +/// emitBlock - Add the specified basic block to the end of the function. If +/// the previous block falls through into it, add an explicit branch. Also, +/// manage fixups for EH info. +void llvm_function::emitBlock(BasicBlock *BB) { + // If the previous block falls through to BB, add an explicit branch. + if ( currentBlock->getTerminator() == 0) { + // If the previous block has no label and is empty, remove it: it is a + // post-terminator block. + if (currentBlock->getName().empty() && currentBlock->begin() == currentBlock->end()) + currentBlock->eraseFromParent(); + else { + // Otherwise, fall through to this block. + new BranchInst(BB, currentBlock); + } + } + + // Add this block. + function->getBasicBlockList().push_back(BB); + currentBlock = BB; // It is now the current block. +} + +/// CreateTemporary - Create a new alloca instruction of the specified type, +/// inserting it into the entry block and returning it. The resulting +/// instruction's type is a pointer to the specified type. +AllocaInst *llvm_function::createTemporary(const Type *type) { + if (allocaInsertionPoint == 0) { + // Create a dummy instruction in the entry block as a marker to insert new + // alloc instructions before. It doesn't matter what this instruction is, + // it is dead. This allows us to insert allocas in order without having to + // scan for an insertion point. + allocaInsertionPoint = new CastInst(Constant::getNullValue(Type::IntTy), + Type::IntTy, "alloca point"); + // Insert it as the first instruction in the entry block. + function->begin()->getInstList().insert(function->begin()->begin(), + allocaInsertionPoint); + } + return new AllocaInst(type, 0, "memtmp", allocaInsertionPoint); +} + + + + +llvm_function::llvm_function ( Module *owner) +:isVarArg(0), + module(owner), + function(0), + name(""), + parameters(0), + varStack(), + returnType(0), + currentBlock(0), + returnBlock(0) +{ +} + +void llvm_function::emitDeclaration() { + FunctionType *ftype = FunctionType::get(returnType, + parameters,isVarArg); + function = new Function(ftype,Function::ExternalLinkage, + name,module); + + currentBlock = NULL; + //create the return block but add it later + //we will branch ahead to here on returns + returnBlock = new BasicBlock("return"); +} + +void llvm_function::emitFunction() { + emitBlock(returnBlock); + //If the function returns a value, get it into a register and return it now. + if (returnType != Type::VoidTy) { + //Value *returnValue = new LoadInst(DECL_LLVM(DECL_RESULT(FnDecl)), "retval", currentBlock); + //returnValue = castToType(RV, function->getReturnType()); + //new ReturnInst(RV, currentBlock); + new ReturnInst( castToType(pop(),function->getReturnType()),currentBlock); + } else { + // Otherwise, just return. + new ReturnInst(currentBlock); + } +} + +void llvm_function::emitReturnValue(){ + new BranchInst(returnBlock,currentBlock); +} + +void llvm_function::emitCall(llvm_function * callee){ + vector<Value*> args; + args.reserve(callee->parameters.size()); + for( unsigned int i = 0,e = callee->parameters.size(); i < e ; i++ ) + { + args.push_back(pop()); + } + CallInst *call=new CallInst(callee->function,args,callee->name,currentBlock); + if (callee->returnType != Type::VoidTy) { + push(call); + } +} + +void llvm_function::setIsVarArg(bool b) +{ + isVarArg = b; +} + +void llvm_function::setReturnType (const Type *type ) +{ + returnType = type; +} + +void llvm_function::setName (string inName ) +{ + name = inName; +} + +void llvm_function::initParameters (int size ) +{ + parameters.reserve(size); +} + +void llvm_function::addParameter (const Type * type,const string name) +{ + parameters.push_back(type); +} + + +Value * llvm_function::addLocalVariable (const Type * type,Value *size, + const string &name ) +{ + if (allocaInsertionPoint == 0) { + // Create a dummy instruction in the entry block as a marker to insert new + // alloc instructions before. It doesn't matter what this instruction is, + // it is dead. This allows us to insert allocas in order without having to + // scan for an insertion point. + allocaInsertionPoint = new CastInst(Constant::getNullValue(Type::IntTy), + Type::IntTy, "alloca point"); + // Insert it as the first instruction in the entry block. + function->begin()->getInstList().insert(function->begin()->begin(), + allocaInsertionPoint); + } + + lvalue=new AllocaInst(type,size,name,allocaInsertionPoint); + return lvalue; +} + +void llvm_function::startBlock() +{ + if( currentBlock == NULL ) { + currentBlock = new BasicBlock("EntryBlock",function); + }else { + emitBlock(new BasicBlock("")); + } +} + diff --git a/gcjx/llvm/llvmfunction.hh b/gcjx/llvm/llvmfunction.hh new file mode 100644 index 00000000000..93507c296f0 --- /dev/null +++ b/gcjx/llvm/llvmfunction.hh @@ -0,0 +1,84 @@ +// Code generator for bytecode. + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// gcjx is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// gcjx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with gcjx; see the file COPYING.LIB. If +// not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef GCJX_LLVM_FUNCTION_HH +#define GCJX_LLVM_FUNCTION_HH + +#include "llvm/Module.h" +#include "llvm/Instructions.h" +#include <stack> +#include <iostream> + +using namespace llvm; +using namespace std; + +class llvm_function +{ +public: + bool isVarArg; + Module* module; + Function *function; + string name; + vector<const Type*> parameters; + stack<Value*> varStack; + const Type *returnType; + BasicBlock *currentBlock; + BasicBlock *returnBlock; + //allocaInsertionPoint - Place to insert alloca instructions. + //Lazily created and managed by CreateTemporary. + Instruction *allocaInsertionPoint; + Value *lvalue; + Value *rvalue; + + llvm_function(Module *owner); + + Value * castToType(Value *V, const Type *type); + void emitBlock(BasicBlock *BB); + AllocaInst * createTemporary(const Type *type); + void initParameters( int size ); + void addParameter(const Type *type,string name ); + void setName(string name); + void setIsVarArg(bool b); + void setReturnType(const Type* type); + void startBlock(); + Value *addLocalVariable (const Type * type,Value *size, const string &name ); + void push(Value *var){ + std::cout << "push\n"; + varStack.push(var); + } + Value *pop(){ + std::cout << "pop\n"; + Value *var = varStack.top(); + varStack.pop(); + return var; + } + + bool empty() { + return varStack.empty(); + } + void emitDeclaration(); + void emitFunction(); + void emitReturnValue(); + void llvm_function::emitCall(llvm_function * function); + +}; + +#endif // GCJX_LLVM_GEN_HH diff --git a/gcjx/llvm/llvmgen.cc b/gcjx/llvm/llvmgen.cc new file mode 100644 index 00000000000..5450cfc57dc --- /dev/null +++ b/gcjx/llvm/llvmgen.cc @@ -0,0 +1,1018 @@ +// Code generator for llvm. + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// gcjx is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// gcjx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with gcjx; see the file COPYING.LIB. If +// not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#include "typedefs.hh" +#include "llvmgen.hh" +#include "dump.hh" + + +#include "llvm/SymbolTable.h" +#include "llvm/Module.h" +#include "llvm/DerivedTypes.h" +#include "llvm/Instructions.h" +#include "llvm/Constants.h" +#include "llvm/Instructions.h" +#include "llvm/Bytecode/Writer.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/DepthFirstIterator.h" + +/** Generate C code**/ +#include "llvm/Bytecode/Reader.h" +#include "llvm/Target/SubtargetFeature.h" +#include "llvm/Target/TargetMachine.h" +#include "llvm/Target/TargetMachineRegistry.h" +#include "llvm/Transforms/Scalar.h" +#include "llvm/Module.h" +#include "llvm/PassManager.h" +#include "llvm/Pass.h" +#include "llvm/Support/CommandLine.h" +#include "llvm/Support/PluginLoader.h" +#include "llvm/Support/PassNameParser.h" +#include "llvm/Analysis/Verifier.h" +#include "llvm/System/Signals.h" +//#include "llvm/Config/config.h" +/** End gnerate c code **/ + + + +#include <list> +#include <utility> +#include <algorithm> +#include <fstream> +#include <iostream> +#include <memory> + + +using namespace std; +using namespace llvm; + +// GetFileNameRoot - Helper function to get the basename of a filename. +static inline string +GetFileNameRoot(const string &InputFilename) { + string IFN = InputFilename; + string outputFilename; + int Len = IFN.length(); + if ((Len > 2) && + IFN[Len-3] == '.' && IFN[Len-2] == 'b' && IFN[Len-1] == 'c') { + outputFilename = string(IFN.begin(), IFN.end()-3); // s/.bc/.s/ + } else { + outputFilename = IFN; + } + return outputFilename; +} + +const Type * llvm_code_generator::convertType( model_type *type ) +{ + if (typemap.find (type) == typemap.end ()) + { + const Type *Ty; + assert (type->reference_p ()); + model_class *klass = assert_cast<model_class *> (type); + Ty = OpaqueType::get(); + module->addTypeName(klass->get_fully_qualified_name (),Ty); + //typemap[klass] = TypeDB.setType(type,PointerType::get(Ty)); + typemap[klass] = PointerType::get(Ty); + return typemap[klass]; + } + return typemap[type]; +} + +/// CastToType - Cast the specified value to the specified type if it is +/// not already that type. +Value *llvm_code_generator::castToType(Value *V, const Type *Ty) { +#if 0 + if (V->getType() == Ty) return V; + if (Constant *C = dyn_cast<Constant>(V)) + return ConstantExpr::getCast(C, Ty); + + // Handle cast (cast bool X to T2) to bool as X, because this occurs all over + // the place. + if (CastInst *CI = dyn_cast<CastInst>(V)) + if (Ty == Type::BoolTy && CI->getOperand(0)->getType() == Type::BoolTy) + return CI->getOperand(0); + return new CastInst(V, Ty, V->getName(), currentBlock); +#endif + return NULL; +} + + +llvm_code_generator::llvm_code_generator (compiler *comp, + directory_cache &dirs) +: code_generator (dirs) +{ + // Set up all primitive types. + typemap[primitive_byte_type] = Type::SByteTy; + typemap[primitive_short_type] = Type::ShortTy; + typemap[primitive_int_type] = Type::IntTy; + typemap[primitive_long_type] = Type::LongTy; + typemap[primitive_float_type] = Type::FloatTy; + typemap[primitive_double_type] = Type::DoubleTy; + typemap[primitive_boolean_type] = Type::BoolTy; + typemap[primitive_char_type] = Type::UShortTy; + typemap[primitive_void_type] = Type::VoidTy; + typemap[null_type] = PointerType::get(OpaqueType::get()); + +} + + void +llvm_code_generator::generate (model_class *klass) +{ + cout << "Class " << klass->get_name() << "\n"; + string FeaturesStr; + string OutputFilename; + ostream *Out = 0; + const TargetMachineRegistry::Entry * target = TargetMachineRegistry::getList(); + + module = new Module(klass->get_name()); + OutputFilename=GetFileNameRoot(klass->get_name())+".cgen"; + //while( target != NULL ) { + cout << "Target=" << target->Name << "\n"; + //target = target->getNext(); + //} + auto_ptr<TargetMachine> targetArch(target->CtorFn(*module, 0, FeaturesStr)); + assert(targetArch.get() && "Could not allocate target machine!"); + TargetMachine &Target = *targetArch.get(); + const TargetData &TD = Target.getTargetData(); + // Build up all of the passes that we want to do to the module... + PassManager Passes; + Passes.add(new TargetData(TD)); + Out = new ofstream(OutputFilename.c_str()); + if (!Out->good()) { + cerr << ": error opening " << OutputFilename << "!\n"; + delete Out; + return ; + } + sys::RemoveFileOnSignal(sys::Path(OutputFilename)); + Target.addPassesToEmitFile(Passes,*Out,TargetMachine::AssemblyFile, true); + + + //visit the class + klass->visit(this); + + + // Output the bytecode file to stdout + //WriteBytecodeToFile(module, cout); + Passes.run(*module); + // Delete the ostream if it's not a stdout stream + if (Out != &cout) delete Out; + delete module; + //dump_tree(klass); +} + +llvm_code_generator::~llvm_code_generator () +{ + //XXX dunno about this is it enough ? + delete currentMethod; + delete this; +} + + void +llvm_code_generator::generate( model_method *m) +{ + m->visit (this); +} + +llvm_function * +llvm_code_generator::get_method (model_method * method ) +{ + + llvm_function * function; + if (methodMap.find (method) == methodMap.end ()) { + function = new llvm_function(module); + const list<ref_variable_decl> & params = method->get_parameters (); +cout << "Method " << method->get_name() << " " << method->get_pretty_name() << "\n"; + function->setName(method->get_name()); + function->initParameters(params.size()); + for (list<ref_variable_decl>::const_iterator i = params.begin (); + i != params.end (); ++i) + { + model_type *type = (*i)->type (); + const Type *Ty =convertType(type); + function->addParameter(Ty,(*i)->get_name()); + } + function->setReturnType(convertType(method->get_return_type())); + //finished with the declaration + function->emitDeclaration(); + methodMap[method]=function; + return function; + } + function = methodMap[method]; + assert(function != 0 ); + return function; +} + +void +llvm_code_generator::visit_class (model_class *klass, const std::string &descr, + const std::string &name) +{ +cout << " visit_class callled --------- " << descr << "++" << name << "\n"; + currentClass = new llvm_class(module); + list<ref_field> fields = klass->get_fields (); + for (list<ref_field>::const_iterator i = fields.begin (); + i != fields.end (); ++i) + { + (*i).get ()->visit(this); + } + currentClass->emitStruct(); + + + // First we generate code for the methods. Then we write the bytes + // for the fields and the methods in a separate step. We do this + // because code generation might require adding a new field. + list<ref_method> methods = klass->get_methods (); + for (list<ref_method>::const_iterator i = methods.begin (); + i != methods.end (); ++i) + { + generate ((*i).get ()); + } + + +} + +void +llvm_code_generator::visit_field (model_field *field) +{ +cout << " VISIT visit_field " << field->get_name() << "\n"; + model_type *type = field->type (); + const Type *llvmType =convertType(type); + currentClass->addField(llvmType,field->get_name()); +#if 0 + Value *size = 0; +cout << "----> ADDING LOCAL VARIABLE " << name << "\n"; + Value *location =currentMethod->addLocalVariable(Ty,size,name); + localmap[decl] = location; + if (init){ + init->visit (this); + new StoreInst(currentMethod->pop(),location,currentMethod->currentBlock); + } +#endif +} + +void +llvm_code_generator::visit_method (model_method * method, + const list<ref_variable_decl> & params, + const ref_block &block) +{ + currentMethod = get_method(method); + list<ref_variable_decl>::const_iterator i = params.begin (); + for (Function::arg_iterator arg = currentMethod->function->arg_begin (); + arg != currentMethod->function->arg_end(); arg++,i++) + { + model_variable_decl *decl = (*i).get(); + localmap[decl]=arg; + } + //start walking + if( block) + block->visit(this); + //finish the function + currentMethod->emitFunction(); +} + + void +llvm_code_generator::visit_assert (model_assert *stmt, + const ref_expression &first, + const ref_expression &second) +{ +cout << "VISIT model_assert \n"; + if(first) + first->visit(this); + if(second) + second->visit(this); +} + + void +llvm_code_generator::visit_block (model_block *block, + const list<ref_stmt> &statements) +{ + currentMethod->startBlock(); + ::visit(this,statements); +} + + void +llvm_code_generator::visit_bytecode_block (model_bytecode_block *block, + int, int, int, const uint8 *) +{ +} + + void +llvm_code_generator::visit_break (model_break *brk, const ref_stmt &target) +{ +cout << "VISIT break \n"; +} + + void +llvm_code_generator::visit_catch (model_catch *stmt, + const ref_variable_decl &var, + const ref_block &body) +{ +cout << "VISIT catch \n"; +} + +void llvm_code_generator::visit_continue (model_continue *stmt, + const ref_stmt &target) +{ +cout << "VISIT continue \n"; +} + + void +llvm_code_generator::visit_class_decl_stmt (model_class_decl_stmt *stmt, + const ref_class &klass) +{ +cout << "VISIT ---- class decl_stmt \n"; +} + +void llvm_code_generator::visit_do (model_do *stmt, const ref_expression &cond, + const ref_stmt &body) +{ + if(cond) + cond->visit(this); +cout << "VISIT do \n"; +} + +void llvm_code_generator::visit_empty (model_empty *) +{ +cout << "VISIT empty \n"; +} + +void llvm_code_generator::visit_expression_stmt (model_expression_stmt *, + const ref_expression &expr) +{ + if( expr) + expr->visit(this); +cout << " visit_expression_stmt \n"; +} + +void llvm_code_generator::visit_for_enhanced (model_for_enhanced *, + const ref_stmt &, const ref_expression & expr, + const ref_variable_decl &) +{ +cout << "VISIT visit_for_enhanced \n"; + if( expr) + expr->visit(this); +} + +void llvm_code_generator::visit_for (model_for *, const ref_stmt &, + const ref_expression &expr, const ref_stmt &, + const ref_stmt &) +{ + if( expr) + expr->visit(this); +cout << "VISIT visit_for\n"; +} + +void llvm_code_generator::visit_if (model_if *, const ref_expression &cond, + const ref_stmt &true_branch, const ref_stmt &false_branch) +{ + if( cond) + cond->visit(this); +cout << "VISIT visit_if\n"; +} + +void llvm_code_generator::visit_label (model_label *, const ref_stmt &) +{ +cout << "VISIT visit_label\n"; +} + +void llvm_code_generator::visit_return (model_return *, const ref_expression &expr) +{ + if(expr) + expr->visit(this); +cout << "VISIT visit_return\n"; + currentMethod->emitReturnValue(); +} + +void llvm_code_generator::visit_switch (model_switch *, + const ref_expression & expr, + const list<ref_switch_block> &) +{ + if(expr) + expr->visit(this); +cout << "VISIT visit_switch\n"; +} + +void llvm_code_generator::visit_switch_block (model_switch_block *, + const list<ref_stmt> &) +{ +cout << "VISIT visit_switch_block\n"; +} + +void llvm_code_generator::visit_synchronized (model_synchronized *, + const ref_expression & expr, + const ref_stmt &) +{ + if(expr) + expr->visit(this); +cout << "VISIT visit_synchronized\n"; +} + +void llvm_code_generator::visit_throw (model_throw *, const ref_expression & expr) +{ + if(expr) + expr->visit(this); +cout << "VISIT visit_throw\n"; +} + +void llvm_code_generator::visit_try (model_try *, const ref_block &, + const list<ref_catch> &, const ref_block &) +{ +cout << "VISIT visit_try\n"; +} + +void llvm_code_generator::visit_variable_stmt (model_variable_stmt *, + const list<ref_variable_decl> & decls) +{ + for (list<ref_variable_decl>::const_iterator i = decls.begin (); + i != decls.end (); ++i) + { + (*i)->visit(this); + } +} +void llvm_code_generator::visit_variable_decl (model_variable_decl *decl, + const std::string &name, + const ref_forwarding_type &fortype, + const ref_expression &init, + bool isfinal, + bool isused) +{ + Value *size = 0; + model_type *type = decl->type (); + const Type *Ty =convertType(type); +cout << "----> ADDING LOCAL VARIABLE " << name << "\n"; + Value *location =currentMethod->addLocalVariable(Ty,size,name); + localmap[decl] = location; + if (init){ + init->visit (this); + new StoreInst(currentMethod->pop(),location,currentMethod->currentBlock); + } +} + +void llvm_code_generator::visit_while (model_while *, const ref_expression &cond, + const ref_stmt &body) +{ + if(cond) + cond->visit(this); + body->visit(this); + +cout << "VISIT visit_while\n"; +} + +void llvm_code_generator::visit_array_initializer (model_array_initializer *, + const ref_forwarding_type &, + const list<ref_expression> &) +{ +cout << "VISIT visit_array_initializer \n"; +} + +void llvm_code_generator::visit_array_ref (model_array_ref *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT visit_array_ref \n"; +} + +void llvm_code_generator::visit_assignment (model_assignment *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT VARIALBEL ASSIGNMENT visit_assignment \n"; +} + +void llvm_code_generator::visit_op_assignment (model_minus_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT OP model_minus_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_mult_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT OP model_mult_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_div_equal *, + const ref_expression &, + const ref_expression &) +{ +} + +void llvm_code_generator::visit_op_assignment (model_and_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_and_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_or_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_or_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_plus_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_plus_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_xor_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_xor_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_mod_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT OP model_mod_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_ls_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT OP visit_op_assignment \n"; +} + +void llvm_code_generator::visit_op_assignment (model_rs_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT OP model_rs_equal \n"; +} + +void llvm_code_generator::visit_op_assignment (model_urs_equal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT OP model_urs_equal \n"; +} + +void llvm_code_generator::visit_arith_binary (model_minus *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_minus \n"; +} + +void llvm_code_generator::visit_arith_binary (model_mult *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_mult \n"; +} + +void llvm_code_generator::visit_arith_binary (model_div *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_div \n"; +} + +void llvm_code_generator::visit_arith_binary (model_mod *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_mod \n"; +} + +void llvm_code_generator::visit_arith_binary (model_and *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_and \n"; +} + +void llvm_code_generator::visit_arith_binary (model_or *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_or \n"; +} + +void llvm_code_generator::visit_arith_binary (model_xor *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_xor \n"; +} + + void +llvm_code_generator::visit_arith_binary (model_plus *, + const ref_expression &lhs, + const ref_expression &rhs) +{ + lhs->visit(this); + rhs->visit(this); + // Create the add instruction... does not insert... + Instruction *add =BinaryOperator::create(Instruction::Add, + currentMethod->pop(),currentMethod->pop(),"addresult", + currentMethod->currentBlock); + currentMethod->push(add); +cout << "VISIT OP visit_arith_binary model_plus \n"; +} + + void +llvm_code_generator::visit_arith_shift (model_left_shift *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_left_shift \n"; +} + + void +llvm_code_generator::visit_arith_shift (model_right_shift *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_right_shift \n"; + +} + + void +llvm_code_generator::visit_arith_shift (model_unsigned_right_shift *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_unsigned_right_shift \n"; + +} + + void +llvm_code_generator::visit_cast (model_cast *, const ref_forwarding_type &, + const ref_expression &) +{ +cout << "VISIT visit_cast \n"; +} + + void +llvm_code_generator::visit_class_ref (model_class_ref *, + const ref_forwarding_type &) +{ +cout << "VISIT visit_class_ref \n"; +} + + void +llvm_code_generator::visit_comparison (model_equal *, + const ref_expression &, + const ref_expression &) +{ + +cout << "VISIT visit_comparison model_equal \n"; +} + + void +llvm_code_generator::visit_comparison (model_notequal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_notequal \n"; +} + + void +llvm_code_generator::visit_comparison (model_lessthan *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_lessthan \n"; + +} + + void +llvm_code_generator::visit_comparison (model_greaterthan *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_greaterthan \n"; + +} + + void +llvm_code_generator::visit_comparison (model_lessthanequal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_lessthanequal \n"; + +} + + void +llvm_code_generator::visit_comparison (model_greaterthanequal *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_greaterthanequal \n"; + +} + + void +llvm_code_generator::visit_conditional (model_conditional *, + const ref_expression &, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_conditional \n"; + +} + + void +llvm_code_generator::visit_field_ref (model_field_ref *, + const ref_expression &, + model_field *) +{ +cout << "VISIT visit_field_ref \n"; + +} + + void +llvm_code_generator::visit_field_initializer (model_field_initializer *, + model_field *) +{ +cout << "VISIT FIELD INITIALIZER \n"; + +} + + void +llvm_code_generator::visit_instanceof (model_instanceof *, + const ref_expression &, + const ref_forwarding_type &) +{ +cout << "VISIT model_instanceof \n"; + +} + + void +llvm_code_generator::visit_logical_binary (model_lor *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_lor \n"; + +} + + void +llvm_code_generator::visit_logical_binary (model_land *, + const ref_expression &, + const ref_expression &) +{ +cout << "VISIT model_land \n"; + +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jboolean &val) +{ +cout << "VISIT visit_simple_literal jboolean \n"; + currentMethod->rvalue = ConstantBool::get(Type::BoolTy,val); + +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jbyte &val) +{ +cout << "VISIT visit_simple_literal jbyte \n"; + currentMethod->rvalue = ConstantSInt::get(Type::SByteTy,val); +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jchar &val) +{ +cout << "VISIT visit_simple_literal jchar \n"; + currentMethod->rvalue = ConstantSInt::get(Type::ShortTy,val); + +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jshort &val) +{ +cout << "VISIT visit_simple_literal jshort \n"; + currentMethod->rvalue = ConstantSInt::get(Type::ShortTy,val); + +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jint &val) +{ +cout << "VISIT visit_simple_literal jint " << val << "\n"; + currentMethod->push( ConstantSInt::get(Type::IntTy,val)); +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jlong &val) +{ +cout << "VISIT visit_simple_literal jlong \n"; + currentMethod->rvalue = ConstantSInt::get(Type::LongTy,val); +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jfloat &val) +{ +cout << "VISIT visit_simple_literal jfloat \n"; + currentMethod->rvalue = ConstantFP::get(Type::FloatTy,val); + +} + + void +llvm_code_generator::visit_simple_literal (model_literal_base *, + const jdouble &val) +{ +cout << "VISIT visit_simple_literal jdouble \n"; + currentMethod->rvalue = ConstantFP::get(Type::DoubleTy,val); +} + + void +llvm_code_generator::visit_string_literal (model_string_literal *, + const string &val) +{ +cout << "VISIT visit_string_literal \n"; +} + + void +llvm_code_generator::visit_method_invocation (model_method_invocation *, + model_method * method, + const ref_expression &this_expr, + const list<ref_expression> &args) +{ + if( this_expr ) + this_expr->visit(this); + if (method->static_p ()) { + //push this ? + }else { + //push class ? + + } + + for (std::list<ref_expression>::const_iterator i = args.begin (); + i != args.end (); ++i) + { + (*i)->visit (this); + } + llvm_function *function = get_method(method); + currentMethod->emitCall(function); +} + + void +llvm_code_generator::visit_type_qualified_invocation (model_type_qualified_invocation *, + const model_method *, + const list<ref_expression> &, + bool) +{ + +cout << "VISIT visit_type_qualified_invocation \n"; +} + + void +llvm_code_generator::visit_super_invocation (model_super_invocation *, + const model_method *, + const list<ref_expression> &args, + const ref_expression &finit) +{ + for (list<ref_expression>::const_iterator i = args.begin (); + i != args.end (); ++i) + { + (*i)->visit (this); + } +#if 0 + /* field initializer */ + if( finit ) + finit->visit(this); +#endif +cout << "VISIT visit_super_invocation \n"; +} + + void +llvm_code_generator::visit_this_invocation (model_this_invocation *, + const model_method *, + const list<ref_expression> &) +{ +cout << "VISIT visit_this_invocation \n"; + +} + + void +llvm_code_generator::visit_new (model_new *, const model_method *, + const ref_forwarding_type &, + const list<ref_expression> &) +{ + +} + + void +llvm_code_generator::visit_new_array (model_new_array *, + const ref_forwarding_type &, + const list<ref_expression> &, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_null_literal (model_null_literal *) +{ + +cout << "VISIT visit_null_literal \n"; +} + + void +llvm_code_generator::visit_prefix_simple (model_prefix_plus *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_prefix_simple (model_prefix_minus *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_prefix_simple (model_bitwise_not *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_prefix_simple (model_logical_not *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_prefix_side_effect (model_prefix_plusplus *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_prefix_side_effect (model_prefix_minusminus *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_postfix_side_effect (model_postfix_plusplus *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_postfix_side_effect (model_postfix_minusminus *, + const ref_expression &) +{ + +} + + void +llvm_code_generator::visit_this (model_this *) +{ + +cout << "VISIT visit_this \n"; +} + + void +llvm_code_generator::visit_simple_variable_ref (model_simple_variable_ref *, + const model_variable_decl *decl) +{ + currentMethod->push(localmap[decl]); +cout << "VISIT visit_simple_variable_ref \n"; + +} + + diff --git a/gcjx/llvm/llvmgen.hh b/gcjx/llvm/llvmgen.hh new file mode 100644 index 00000000000..5c07d592a4e --- /dev/null +++ b/gcjx/llvm/llvmgen.hh @@ -0,0 +1,786 @@ +// Code generator for bytecode. + +// Copyright (C) 2004 Free Software Foundation, Inc. +// +// This file is part of GCC. +// +// gcjx is free software; you can redistribute it and/or +// modify it under the terms of the GNU Library General Public +// License as published by the Free Software Foundation; either +// version 2 of the License, or (at your option) any later version. +// +// gcjx is distributed in the hope that it will be useful, +// but WITHOUT ANY WARRANTY; without even the implied warranty of +// MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the GNU +// Library General Public License for more details. +// +// You should have received a copy of the GNU Library General Public +// License along with gcjx; see the file COPYING.LIB. If +// not, write to the Free Software Foundation, Inc., +// 59 Temple Place - Suite 330, Boston, MA 02111-1307, USA. + +#ifndef GCJX_LLVM_GEN_HH +#define GCJX_LLVM_GEN_HH + +#include "codegen.hh" +#include "llvm/Module.h" +#include "llvm/llvmclass.hh" +#include "llvm/llvmfunction.hh" + +using namespace llvm; + +/// This is the primary interface to bytecode generation. +class llvm_code_generator : public visitor, public code_generator +{ +public: + + /// Construct a new bytecode code generator. Argument is the + /// compiler being used to generate code. + llvm_code_generator (compiler *, directory_cache &); + virtual ~llvm_code_generator(); + + /// This is called to generate code for a class and write it. + void generate (model_class *); + void generate (model_method *); + + void visit_method (model_method *, + const std::list<ref_variable_decl> &, + const ref_block &); + + void visit_assert (model_assert *, const ref_expression &, + const ref_expression &); + + void visit_block (model_block *, + const std::list<ref_stmt> &); + + void visit_bytecode_block (model_bytecode_block *, int, int, int, + const uint8 *); + + void visit_break (model_break *, const ref_stmt &); + + void visit_catch (model_catch *, const ref_variable_decl &, + const ref_block &); + + void visit_continue (model_continue *, const ref_stmt &); + + void visit_class_decl_stmt (model_class_decl_stmt *, + const ref_class &); + + void visit_do (model_do *, const ref_expression &, + const ref_stmt &); + + void visit_empty (model_empty *); + + void visit_expression_stmt (model_expression_stmt *, + const ref_expression &); + + void visit_for_enhanced (model_for_enhanced *, + const ref_stmt &, const ref_expression &, + const ref_variable_decl &); + + void visit_for (model_for *, const ref_stmt &, + const ref_expression &, const ref_stmt &, + const ref_stmt &); + + void visit_if (model_if *, const ref_expression &, + const ref_stmt &, const ref_stmt &); + + void visit_label (model_label *, const ref_stmt &); + + void visit_return (model_return *, const ref_expression &); + + void visit_switch (model_switch *, + const ref_expression &, + const std::list<ref_switch_block> &); + + void visit_switch_block (model_switch_block *, + const std::list<ref_stmt> &); + + void visit_synchronized (model_synchronized *, + const ref_expression &, + const ref_stmt &); + + void visit_throw (model_throw *, const ref_expression &); + + void visit_try (model_try *, const ref_block &, + const std::list<ref_catch> &, const ref_block &); + + void visit_variable_stmt (model_variable_stmt *, + const std::list<ref_variable_decl> &); + + void visit_while (model_while *, const ref_expression &, + const ref_stmt &); + + + void visit_array_initializer (model_array_initializer *, + const ref_forwarding_type &, + const std::list<ref_expression> &); + + void visit_array_ref (model_array_ref *, + const ref_expression &, + const ref_expression &); + + void visit_assignment (model_assignment *, + const ref_expression &, + const ref_expression &); + + void visit_method_invocation (model_method_invocation *, + model_method *, + const ref_expression &, + const std::list<ref_expression> &); + + void visit_type_qualified_invocation (model_type_qualified_invocation *, + const model_method *, + const std::list<ref_expression> &, + bool); + + void visit_super_invocation (model_super_invocation *, + const model_method *, + const std::list<ref_expression> &, + const ref_expression &); + + void visit_this_invocation (model_this_invocation *, + const model_method *, + const std::list<ref_expression> &); + + void visit_op_assignment (model_minus_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_mult_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_div_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_and_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_or_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_xor_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_mod_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_ls_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_rs_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_urs_equal *, + const ref_expression &, + const ref_expression &); + + void visit_op_assignment (model_plus_equal *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_minus *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_mult *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_div *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_mod *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_and *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_or *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_xor *, + const ref_expression &, + const ref_expression &); + + void visit_arith_binary (model_plus *, + const ref_expression &, + const ref_expression &); + + void visit_arith_shift (model_left_shift *, + const ref_expression &, + const ref_expression &); + + void visit_arith_shift (model_right_shift *, + const ref_expression &, + const ref_expression &); + + void visit_arith_shift (model_unsigned_right_shift *, + const ref_expression &, + const ref_expression &); + + void visit_cast (model_cast *, const ref_forwarding_type &, + const ref_expression &); + + void visit_class_ref (model_class_ref *, + const ref_forwarding_type &); + + void visit_comparison (model_equal *, + const ref_expression &, + const ref_expression &); + + void visit_comparison (model_notequal *, + const ref_expression &, + const ref_expression &); + + void visit_comparison (model_lessthan *, + const ref_expression &, + const ref_expression &); + + void visit_comparison (model_greaterthan *, + const ref_expression &, + const ref_expression &); + + void visit_comparison (model_lessthanequal *, + const ref_expression &, + const ref_expression &); + + void visit_comparison (model_greaterthanequal *, + const ref_expression &, + const ref_expression &); + + void visit_conditional (model_conditional *, + const ref_expression &, + const ref_expression &, + const ref_expression &); + + void visit_field_ref (model_field_ref *, + const ref_expression &, + model_field *); + + void visit_field_initializer (model_field_initializer *, + model_field *); + + void visit_field (model_field *); + + void visit_instanceof (model_instanceof *, + const ref_expression &, + const ref_forwarding_type &); + + void visit_logical_binary (model_lor *, + const ref_expression &, + const ref_expression &); + + void visit_logical_binary (model_land *, + const ref_expression &, + const ref_expression &); + + void visit_simple_literal (model_literal_base *, + const jboolean &val); + + void visit_simple_literal (model_literal_base *, + const jbyte &val); + + void visit_simple_literal (model_literal_base *, + const jchar &val); + + void visit_simple_literal (model_literal_base *, + const jshort &val); + + void visit_simple_literal (model_literal_base *, + const jint &val); + + void visit_simple_literal (model_literal_base *, + const jlong &val); + + void visit_simple_literal (model_literal_base *, + const jfloat &val); + + void visit_simple_literal (model_literal_base *, + const jdouble &val); + + void visit_string_literal (model_string_literal *, + const std::string &val); + + void visit_new (model_new *, const model_method *, + const ref_forwarding_type &, + const std::list<ref_expression> &); + + void visit_new_array (model_new_array *, + const ref_forwarding_type &, + const std::list<ref_expression> &, + const ref_expression &); + + void visit_null_literal (model_null_literal *); + + void visit_prefix_simple (model_prefix_plus *, + const ref_expression &); + + void visit_prefix_simple (model_prefix_minus *, + const ref_expression &); + + void visit_prefix_simple (model_bitwise_not *, + const ref_expression &); + + void visit_prefix_simple (model_logical_not *, + const ref_expression &); + + void visit_prefix_side_effect (model_prefix_plusplus *, + const ref_expression &); + + void visit_prefix_side_effect (model_prefix_minusminus *, + const ref_expression &); + + void visit_postfix_side_effect (model_postfix_plusplus *, + const ref_expression &); + + void visit_postfix_side_effect (model_postfix_minusminus *, + const ref_expression &); + + void visit_this (model_this *); + + void visit_simple_variable_ref (model_simple_variable_ref *, + const model_variable_decl *); + + void visit_forwarding_type (model_forwarding_type *, + model_type *) + { + // Nothing. + } + + void visit_forwarding_resolved (model_forwarding_resolved *, + model_type *) + { + // Nothing. + } + + void visit_forwarding_owned (model_forwarding_owned *, + const ref_type &) + { + // Nothing. + } + + void visit_forwarding_simple (model_forwarding_simple *, + const std::list<std::string> &) + { + // Nothing. + } + + void + visit_forwarding_array (model_forwarding_array *, + const owner<model_forwarding_type> &) + { + // Nothing. + } + + void + visit_forwarding_element (model_forwarding_element *, + const owner<model_forwarding_type> &) + { + // Nothing. + } + + void visit_forwarding_full (model_forwarding_full *, + const std::string &) + { + // Nothing. + } + + void + visit_forwarding_inner (model_forwarding_inner *, + const std::list<std::string> &, + const owner<model_forwarding_type> &) + { + // Nothing. + } + + void + visit_forwarding_parameterized (model_forwarding_parameterized *, + const owner<model_forwarding_type> &, + const std::list< owner<model_forwarding_type> > &) + { + // Nothing. + } + void visit_variable_decl (model_variable_decl *, + const std::string &, + const ref_forwarding_type &, + const ref_expression &, + bool, + bool); + + + void visit_parameter_decl (model_variable_decl *, + const std::string &, + const ref_forwarding_type &, + const ref_expression &, + bool, + bool) + { + // Nothing. + } + + void visit_catch_decl (model_variable_decl *, + const std::string &, + const ref_forwarding_type &, + const ref_expression &, + bool, + bool) + { + // Nothing. + } + + void visit_package (model_package *, const std::list<std::string> &) + { + // Nothing. + } + + void visit_type (model_type *, const std::string &) + { + // Nothing. + } + + void visit_identifier (model_identifier *, const std::string &) + { + // Nothing. + } + + void visit_annotation_member (model_annotation_member *, + const ref_forwarding_type &) + { + // Nothing. + } + + void visit_annotation_value (model_annotation_value *, + const std::string &, const ref_expression &) + { + // Nothing. + } + + void visit_import_single (model_import_single *, + const std::list<std::string> &, model_class *) + { + // Nothing. + } + + void visit_import_on_demand (model_import_on_demand *, + const std::list<std::string> &, Iname *, bool) + { + // Nothing. + } + + void visit_static_import_single (model_static_import_single *, + const std::list<std::string> &, + model_class *, const std::string &) + { + // Nothing. + } + + void visit_static_import_on_demand (model_static_import_on_demand *, + const std::list<std::string> &, + model_class *) + { + // Nothing. + } + + void visit_unit_source (model_unit_source *, model_package *, + const std::list<ref_class> &, + const std::string &, + bool, const std::list<ref_import> &) + { + // Nothing. + } + + void visit_unit_class (model_unit_class *, model_package *, + const std::list<ref_class> &, + const std::string &, bool) + { + // Nothing. + } + + void visit_unit_fake (model_unit_fake *, model_package *, + const std::list<ref_class> &, + const std::string &, bool) + { + // Nothing. + } + + void visit_abstract_method (model_abstract_method *am, + const std::list<ref_variable_decl> ¶ms, + const ref_block &body, model_method *) + { + visit_method (am, params, body); + } + + void visit_annotation_type (model_annotation_type *at, + const std::string &descr, + const std::string &name) + { + visit_class (at, descr, name); + } + + void visit_array_type (model_array_type *at, const std::string &descr, + const std::string &name, model_type *) + { + visit_class (at, descr, name); + } + + + void visit_class_instance (model_class_instance *ci, + const std::string &descr, + const std::string &name, model_class *) + { + visit_class (ci, descr, name); + } + + void visit_constructor (model_constructor *c, + const std::list<ref_variable_decl> ¶ms, + const ref_block &body) + { + visit_method (c, params, body); + } + + void visit_enum (model_enum *e, const std::string &descr, + const std::string &name, + const std::list<ref_enum_constant> &) + { + visit_class (e, descr, name); + } + +void visit_class (model_class *c, const std::string &descr, + const std::string &name); + + void visit_enum_constant (model_enum_constant *ec, + const std::string &descr, + const std::string &name, + const std::list<ref_expression> &) + { + visit_class (ec, descr, name); + } + + void visit_fp_primitive (model_primitive_base *, char, jfloat) + { + // Nothing. + } + + void visit_fp_primitive (model_primitive_base *, char, jdouble) + { + // Nothing. + } + + void visit_int_primitive (model_primitive_base *, char, + long long, long long, jbyte) + { + // Nothing. + } + + void visit_int_primitive (model_primitive_base *, char, + long long, long long, jchar) + { + // Nothing. + } + + void visit_int_primitive (model_primitive_base *, char, + long long, long long, jshort) + { + // Nothing. + } + + void visit_int_primitive (model_primitive_base *, char, + long long, long long, jint) + { + // Nothing. + } + + void visit_int_primitive (model_primitive_base *, char, + long long, long long, jlong) + { + // Nothing. + } + + void visit_primitive_boolean (model_primitive_boolean *) + { + // Nothing. + } + + void visit_initializer_block (model_initializer_block *ib, + const std::list<ref_stmt> &stmts, bool) + { + visit_block (ib, stmts); + } + + void visit_new_primary (model_new_primary *np, const model_method *meth, + const ref_forwarding_type &klass, + const std::list<ref_expression> &args, + const std::string &, + const std::list<ref_forwarding_type> &) + { + visit_new (np, meth, klass, args); + } + + void visit_null_type (model_null_type *nt, const std::string &descr) + { + visit_type (nt, descr); + } + + void visit_phony_block (model_phony_block *pb, + const std::list<ref_stmt> &stmts) + { + visit_block (pb, stmts); + } + + void visit_primordial_package (model_primordial_package *pp, + const std::list<std::string> &name) + { + visit_package (pp, name); + } + + void visit_unnamed_package (model_unnamed_package *up, + const std::list<std::string> &name) + { + visit_package (up, name); + } + + void visit_synthetic_this (model_synthetic_this *st) + { + visit_this (st); + } + + void visit_this_outer (model_this_outer *to) + { + visit_this (to); + } + + void + visit_type_variable (model_type_variable *tv, + const std::string &descr, const std::string &name, + const std::list<ref_forwarding_type> &) + { + visit_class (tv, descr, name); + } + + void visit_void_type (model_void_type *vt, const std::string &descr) + { + visit_type (vt, descr); + } + + void visit_wildcard (model_wildcard *w, const std::string &descr, + const std::string &name, bool, + const ref_forwarding_type &) + { + visit_class (w, descr, name); + } + + void visit_javadoc (model_javadoc *, bool) + { + // Nothing. + } + + void + visit_generic_invocation (model_method_invocation *mi, + model_method *meth, + const ref_expression &qual, + const std::list<ref_expression> &args, + const std::list<ref_forwarding_type> &) + { + visit_method_invocation (mi, meth, qual, args); + } + + void + visit_generic_invocation (model_type_qualified_invocation *tqi, + const model_method *meth, + const std::list<ref_expression> &args, + bool is_super, + const std::list<ref_forwarding_type> &) + { + visit_type_qualified_invocation (tqi, meth, args, is_super); + } + + void + visit_generic_invocation (model_super_invocation *si, + const model_method *meth, + const std::list<ref_expression> &args, + const ref_expression &finit, + const std::list<ref_forwarding_type> &) + { + visit_super_invocation (si, meth, args, finit); + } + + void + visit_generic_invocation (model_this_invocation *ti, + const model_method *meth, + const std::list<ref_expression> &args, + const std::list<ref_forwarding_type> &) + { + visit_this_invocation (ti, meth, args); + } + + void + visit_generic_invocation (model_new *n, const model_method *meth, + const ref_forwarding_type &klass, + const std::list<ref_expression> &args, + const std::list<ref_forwarding_type> &) + { + visit_new (n, meth, klass, args); + } + + void + visit_generic_invocation (model_new_primary *np, const model_method *meth, + const ref_forwarding_type &klass, + const std::list<ref_expression> &args, + const std::string &simple_name, + const std::list<ref_forwarding_type> &type_params, + const std::list<ref_forwarding_type> &) + { + visit_new_primary (np, meth, klass, args, simple_name, type_params); + } + + void + visit_annotation (model_annotation *, const ref_forwarding_type &, + const std::list<ref_annotation_value> &) + { + abort (); + } + + void + visit_annotation_initializer (model_annotation_initializer *, + const ref_forwarding_type &, + const std::list<ref_expression> &) + { + abort (); + } + + void visit_memberref_enum (model_memberref_enum *, + const ref_forwarding_type &, + const std::string &) + { + abort (); + } + +private: + // This maps our types to llvm types. + std::map<model_type *,Type *> typemap; + std::map<const model_variable_decl *,Value *> localmap; + std::map<const model_field *,Value *> fieldMap; + std::map<const model_method *,llvm_function *> methodMap; + Module* module; + llvm_function *currentMethod; + llvm_class *currentClass; + const Type * convertType( model_type *type ); + Value * castToType(Value *V, const Type *Ty); + llvm_function * get_method (model_method * method ); + +}; + +#endif // GCJX_LLVM_GEN_HH |