#include "compiler/CCompiler.h" #include "compiler/CParser.h" #include "compiler/CPrep.h" #include "compiler/CompilerTools.h" #include "compiler/CodeGen.h" #include "compiler/CodeGenOptPPC.h" #include "../FrontEnd/Optimizer/IrOptimizer.h" #include "compiler/types.h" #include "pref_structs.h" Boolean systemHandles; static Boolean using_license_manager; Boolean crippled; SInt32 license_cookie; CompilerLinkerParamBlk cparams; static void get_extension(ConstStringPtr src, char *dst) { int ep; dst[0] = 0; for (ep = src[0]; src[ep] != '.'; ep--) {} if (ep >= 2) { int x; for (x = 0; (x + ep) <= src[0]; x++) { #ifdef CW_CLT dst[x] = src[x + ep]; #else dst[x] = tolower(src[x + ep]); #endif } dst[x] = 0; } } static int setup_param_block(CWPluginContext context) { static char target_name[128]; CWTargetInfo tinfo; memset(&cparams, 0, sizeof(CompilerLinkerParamBlk)); cparams.context = context; if (CWGetPluginRequest(context, &cparams.request) != cwNoErr) return 0; if (CWGetAPIVersion(context, &cparams.version) != cwNoErr) return 0; if (CWGetProjectFile(context, &cparams.targetfile) != cwNoErr) return 0; if (CWGetProjectFileCount(context, &cparams.numfiles) != cwNoErr) return 0; if (CWGetMainFileNumber(context, &cparams.whichfile) != cwNoErr) return 0; if (CWGetMainFileSpec(context, &cparams.sourcefile) != cwNoErr) return 0; if (CWGetMainFileText(context, &cparams.sourcetext, &cparams.sourcetextsize) != cwNoErr) return 0; if (CWIsPrecompiling(context, &cparams.precompile) != cwNoErr) return 0; if (CWIsAutoPrecompiling(context, &cparams.autoprecompile) != cwNoErr) return 0; if (CWIsPreprocessing(context, &cparams.preprocess) != cwNoErr) return 0; if (CWIsGeneratingDebugInfo(context, &cparams.SYMinfo) != cwNoErr) return 0; if (CWIsCachingPrecompiledHeaders(context, &cparams.caching_includes) != cwNoErr) return 0; if (CWGetBrowseOptions(context, &cparams.browseoptions) != cwNoErr) return 0; cparams.recordbrowseinfo = cparams.preprocess == 0; if (CWGetMainFileID(context, &cparams.browserfileID) != cwNoErr) return 0; if (CWGetTargetInfo(context, &tinfo) != cwNoErr) return 0; cparams.targetOS = tinfo.targetOS; cparams.targetCPU = tinfo.targetCPU; cparams.idetargetname = target_name; return CWGetTargetName(context, cparams.idetargetname, sizeof(target_name)) == cwNoErr; } static short store_compile_results(void) { CWResult result; if (cparams.objectdata) CWSecretAttachHandle(cparams.context, cparams.objectdata, &cparams.object.objectdata); if (cparams.browsedata) CWSecretAttachHandle(cparams.context, cparams.browsedata, &cparams.object.browsedata); if (cparams.preprocess) { if (cparams.object.objectdata) { CWNewTextDocumentInfo docinfo; memset(&docinfo, 0, sizeof(CWNewTextDocumentInfo)); docinfo.text = cparams.object.objectdata; cparams.object.objectdata = NULL; result = CWCreateNewTextDocument(cparams.context, &docinfo); } } else { result = CWStoreObjectData(cparams.context, cparams.whichfile, &cparams.object); } return result; } static void initialize_compiler_options(CompilerLinkerParamBlk *params) { static PFrontEndC pFrontEnd; PWarningC pWarningC; PGlobalOptimizer pGlobalOptimizer; Handle prefsdata; char extension[256]; memclrw(&copts, sizeof(CompilerLinkerOptions)); CWSecretGetNamedPreferences(cparams.context, "C/C++ Compiler", &prefsdata); pFrontEnd = *((PFrontEndC *) *prefsdata); copts.littleendian = 0; copts.cplusplus = 1; copts.objective_c = pFrontEnd.objective_c; get_extension(params->sourcefile.name, extension); if (!strcmp(extension, ".c") || !strcmp(extension, ".h") || !strcmp(extension, ".pch")) { copts.cplusplus = pFrontEnd.cplusplus; } else if (!strcmp(extension, ".m")) { copts.cplusplus = pFrontEnd.cplusplus; copts.objective_c = 1; } else if (!strcmp(extension, ".mm") || !strcmp(extension, ".M")) { copts.cplusplus = 1; copts.objective_c = 1; } copts.checkprotos = pFrontEnd.checkprotos; copts.ARMconform = pFrontEnd.arm; copts.ARMscoping = pFrontEnd.arm; copts.trigraphs = pFrontEnd.trigraphs; copts.onlystdkeywords = pFrontEnd.onlystdkeywords; copts.enumsalwaysint = pFrontEnd.enumsalwaysint; copts.mpwc_relax = pFrontEnd.mpwpointerstyle; copts.ANSIstrict = pFrontEnd.ansistrict; copts.mpwc_newline = pFrontEnd.mpwcnewline; copts.exceptions = pFrontEnd.enableexceptions; copts.dont_reuse_strings = pFrontEnd.dontreusestrings; copts.poolstrings = pFrontEnd.poolstrings; copts.dontinline = pFrontEnd.dontinline; copts.RTTI = pFrontEnd.useRTTI; copts.oldprefixname = pFrontEnd.oldprefixname; copts.multibyteaware = pFrontEnd.multibyteaware; copts.unsigned_char = pFrontEnd.unsignedchars; copts.auto_inline = pFrontEnd.autoinline; copts.direct_to_som = pFrontEnd.direct_to_som; copts.som_env_check = pFrontEnd.som_env_check; copts.booltruefalse = pFrontEnd.booltruefalse; copts.alwaysinline = pFrontEnd.alwaysinline; copts.inlinelevel = pFrontEnd.inlinelevel; copts.wchar_type = pFrontEnd.wchar_type; copts.ecplusplus = pFrontEnd.ecplusplus; copts.defer_codegen = pFrontEnd.defer_codegen; copts.inlinemaxsize = 512; copts.inlinemaxtotalsize = 100000; CWSecretGetNamedPreferences(cparams.context, "C/C++ Warnings", &prefsdata); pWarningC = *((PWarningC *) *prefsdata); copts.warn_illpragma = pWarningC.warn_illpragma; copts.warn_emptydecl = pWarningC.warn_emptydecl; copts.warn_possunwant = pWarningC.warn_possunwant; copts.warn_unusedvar = pWarningC.warn_unusedvar; copts.warn_unusedarg = pWarningC.warn_unusedarg; copts.warn_extracomma = pWarningC.warn_extracomma; copts.pedantic = pWarningC.pedantic; copts.warningerrors = pWarningC.warningerrors; copts.warn_hidevirtual = pWarningC.warn_hidevirtual; copts.warn_implicitconv = pWarningC.warn_implicitconv; copts.warn_notinlined = pWarningC.warn_notinlined; copts.warn_structclass = pWarningC.warn_structclass; CWSecretGetNamedPreferences(cparams.context, "PPC Global Optimizer", &prefsdata); pGlobalOptimizer = *((PGlobalOptimizer *) *prefsdata); copts.optimizationlevel = pGlobalOptimizer.optimizationlevel; copts.optimizesize = (Boolean) (pGlobalOptimizer.optfor == 1); copts.crippled = crippled; copts.unrollfactor = 8; copts.unrollinstrfactor = 100; copts.filesyminfo = params->SYMinfo; copts.appltype = CWFOURCHAR('C', 'W', 'I', 'E'); copts.headtype = CWFOURCHAR('M', 'M', 'C', 'H'); copts.texttype = CWFOURCHAR('T','E','X','T'); } static void GetLicense(void) { if (!license_cookie) { crippled = 1; CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Unlimited", "7", 2, NULL, &license_cookie); if (license_cookie) { CWCheckinLicense(cparams.context, license_cookie); crippled = 0; } CWCheckoutLicense(cparams.context, "MacOS_Plugins_MacOS_Limited", "7", 0, NULL, &license_cookie); using_license_manager = 1; } } static void ReleaseLicense(void) { if (license_cookie && using_license_manager) CWCheckinLicense(cparams.context, license_cookie); using_license_manager = 0; license_cookie = 0; } CWPLUGIN_ENTRY(MWC_main)(CWPluginContext context) { CWResult result; SInt32 request; result = cwNoErr; CWGetPluginRequest(context, &request); switch (request) { case reqInitialize: cparams.context = context; license_cookie = 0; CodeGen_InitCompiler(); break; case reqTerminate: cparams.context = context; CodeGen_TermCompiler(); ReleaseLicense(); break; case reqCompile: setup_param_block(context); GetLicense(); if (license_cookie) { initialize_compiler_options(&cparams); CodeGen_UpdateOptimizerOptions(); CodeGen_InitBackEndOptions(); CodeGen_UpdateOptimizerOptions(); CodeGen_UpdateBackEndOptions(); result = C_Compiler(&cparams); if (result != noErr) result = store_compile_results(); else result = cwErrRequestFailed; } else { result = cwErrSilent; } break; } return CWDonePluginRequest(context, result); } void PrintProgressFunction(const char *str) { char buf[96]; sprintf(buf, "Compiling function:\t%.64s", str); CWShowStatus(cparams.context, buf, ""); }