#include #include "AST.h" #include "CodeContext.h" #include "CfHeader.h" #include "CfSource.h" #include "aux-code.h" #include "decls.h" #include "interface.h" #include "lgMacro.h" #include "lower.h" #include "code.h" extern void resetPerFileTempCounters(); void InterfaceDeclNode::codeGen() { resetPerFileTempCounters(); // reset temp counters when starting each source file to // prevent spurious recompilation of unchanged source files ClassDecl &declaration = *decl(); const CtType &descriptorType = declaration.cDescriptorType(); const string descriptorName = declaration.cDescriptorName(); const CtType &className = decl()->cType(); const string classStaticFieldsStructName = declaration.cStaticFieldsStructName(); // Declarations { CfHeader os( declaration.cType() ); os << "\n/* ***** " << decl()->fullName() << " generated header file ***** */\n\n"; declaration.includeSupers( os ); declaration.cType().define( os ); os << "extern " << descriptorType << ' ' << descriptorName << ";\n" << "\nextern void " << MANGLE_CLASS_INIT(<<, className) << "();\n"; foriter (member, members()->allChildren(), ChildIter) if ((*member)->decl()->category() == Decl::Method) { const MethodDecl &decl = static_cast(*(*member)->decl()); os << "#define IFACE_DISPATCH_" << decl.cMethodNameStatic() << "(ci) ((" << cMethodTypeString( decl ) << ") " << lgMacro( "IFACE_DISPATCH", decl.modifiers() & Local ) << "(ci, " << FindIntfMethodId( decl ) << "))\n"; } os << "struct " << descriptorName << "_static_fields_struct {\n"; emitStaticFields(declaration, staticFieldDecl, os); // some linkers choke if we try to declare struct variables with zero size, // so make sure we have at least one byte in here: os << "char _pad; /* padding to prevent zero-size structs */\n"; os << "};\n"; os << "extern struct " << descriptorName << "_static_fields_struct " << "STATIC_DEF(" << classStaticFieldsStructName << ");\n"; } // Definitions { CfSource os( declaration.cType() ); os << "\n/* ***** " << decl()->fullName() << " generated source file ***** */\n\n"; declaration.includeSelf( os ); declaration.includeRequirements( os ); const char *listName = declaration.emitInterfaceList( os ); os << descriptorType << ' ' << descriptorName << " = {\n" << " { &" << JavaLangClassDecl->cDescriptorName() << " },\n" << " NULL,\n" << " Interface, " << listName << "\n};\n\n"; os << "struct " << descriptorName << "_static_fields_struct " << "STATIC_DEF(" << classStaticFieldsStructName << ");\n"; os << "\nvoid " << MANGLE_CLASS_INIT(<<, className) << "()\n"; { CodeContext subcontext( os ); vector< TreeNode * > inits; foriter (member, members()->allChildren(), ChildIter) if ((*member)->decl()->modifiers() & Static) inits.push_back( *member ); subcontext << "#ifdef HAVE_MONITORS\n" << "monitor_init( &" << decl()->cDescriptorName() << ".class_object.monitor);\n" << "#endif /*HAVE_MONITORS*/\n"; subcontext << decl()->cDescriptorName() << ".class_name = java_string_build_8(\"" << decl()->fullName() << "\");\n"; EncapsulateInits(inits)->emitStatement(subcontext); } } }