#include "compiler/common.h" #include "compiler.h" #include "compiler/types.h" #include "pref_structs.h" #include "compiler/CompilerTools.h" Boolean systemHandles; static Boolean using_license_manager; Boolean crippled; SInt32 license_cookie; CParams cparams; // TODO move me to CParser.c, or maybe CMachine.c? Type sttemplexpr = {TYPETEMPLDEPEXPR, 0}; Type stillegal = {TYPEILLEGAL, 1}; Type stvoid = {TYPEVOID, 0}; TypePointer void_ptr = {TYPEPOINTER, 0, &stvoid, 0}; TypeFunc rt_func = {TYPEFUNC, 0, NULL, NULL, &stvoid, 0, 0}; // TODO move me to CParser.c 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++) dst[x] = src[x + ep]; dst[x] = 0; } } static int setup_param_block(CWPluginContext context) { static char target_name[128]; CWTargetInfo tinfo; memset(&cparams, 0, sizeof(CParams)); cparams.context = context; if (CWGetPluginRequest(context, &cparams.pluginRequest) != cwNoErr) return 0; if (CWGetAPIVersion(context, &cparams.apiVersion) != cwNoErr) return 0; if (CWGetProjectFile(context, &cparams.projectFile) != cwNoErr) return 0; if (CWGetProjectFileCount(context, &cparams.projectFileCount) != cwNoErr) return 0; if (CWGetMainFileNumber(context, &cparams.mainFileNumber) != cwNoErr) return 0; if (CWGetMainFileSpec(context, &cparams.mainFileSpec) != cwNoErr) return 0; if (CWGetMainFileText(context, &cparams.mainFileText, &cparams.mainFileTextLength) != cwNoErr) return 0; if (CWIsPrecompiling(context, &cparams.isPrecompiling) != cwNoErr) return 0; if (CWIsAutoPrecompiling(context, &cparams.isAutoPrecompiling) != cwNoErr) return 0; if (CWIsPreprocessing(context, &cparams.isPreprocessing) != cwNoErr) return 0; if (CWIsGeneratingDebugInfo(context, &cparams.isGeneratingDebugInfo) != cwNoErr) return 0; if (CWIsCachingPrecompiledHeaders(context, &cparams.isCachingPrecompiledHeaders) != cwNoErr) return 0; if (CWGetBrowseOptions(context, &cparams.browseOptions) != cwNoErr) return 0; cparams.field276 = cparams.isPreprocessing == 0; if (CWGetMainFileID(context, &cparams.mainFileID) != cwNoErr) return 0; if (CWGetTargetInfo(context, &tinfo) != cwNoErr) return 0; cparams.targetOS = tinfo.targetOS; cparams.targetCPU = tinfo.targetCPU; cparams.targetName = target_name; return CWGetTargetName(context, target_name, sizeof(target_name)) == cwNoErr; } static short store_compile_results() { CWResult result; if (cparams.objectDataHandle) CWSecretAttachHandle(cparams.context, cparams.objectDataHandle, &cparams.objectdata.objectdata); if (cparams.browseDataHandle) CWSecretAttachHandle(cparams.context, cparams.browseDataHandle, &cparams.objectdata.browsedata); if (cparams.isPreprocessing) { if (cparams.objectdata.objectdata) { CWNewTextDocumentInfo docinfo; memset(&docinfo, 0, sizeof(CWNewTextDocumentInfo)); docinfo.text = cparams.objectdata.objectdata; cparams.objectdata.objectdata = NULL; result = CWCreateNewTextDocument(cparams.context, &docinfo); } } else { result = CWStoreObjectData(cparams.context, cparams.mainFileNumber, &cparams.objectdata); } return result; } static void initialize_compiler_options(CParams *params) { static PFrontEndC pFrontEnd; PWarningC pWarningC; PGlobalOptimizer pGlobalOptimizer; Handle prefsdata; char extension[256]; memclrw(&copts, sizeof(COpts)); CWSecretGetNamedPreferences(cparams.context, "C/C++ Compiler", &prefsdata); pFrontEnd = *((PFrontEndC *) *prefsdata); copts.little_endian = 0; copts.cplusplus = 1; copts.objective_c = pFrontEnd.objective_c; get_extension(params->mainFileSpec.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.require_prototypes = pFrontEnd.checkprotos; copts.ARM_conform = pFrontEnd.arm; copts.ARM_scoping = pFrontEnd.arm; copts.trigraphs = pFrontEnd.trigraphs; copts.only_std_keywords = pFrontEnd.onlystdkeywords; copts.enumsalwaysint = pFrontEnd.enumsalwaysint; copts.mpwc_relax = pFrontEnd.mpwpointerstyle; copts.ANSI_strict = pFrontEnd.ansistrict; copts.mpwc_newline = pFrontEnd.mpwcnewline; copts.exceptions = pFrontEnd.enableexceptions; copts.dont_reuse_strings = pFrontEnd.dontreusestrings; copts.pool_strings = pFrontEnd.poolstrings; copts.dont_inline = pFrontEnd.dontinline; copts.useRTTI = pFrontEnd.useRTTI; copts.oldprefixname = pFrontEnd.oldprefixname; copts.multibyteaware = pFrontEnd.multibyteaware; copts.unsignedchars = pFrontEnd.unsignedchars; copts.autoinline = pFrontEnd.autoinline; copts.direct_to_som = pFrontEnd.direct_to_som; copts.som_env_check = pFrontEnd.som_env_check; copts.booltruefalse = pFrontEnd.booltruefalse; copts.always_inline = pFrontEnd.alwaysinline; copts.inlinelevel = pFrontEnd.inlinelevel; copts.wchar_type = pFrontEnd.wchar_type; copts.ecplusplus = pFrontEnd.ecplusplus; copts.defer_codegen = pFrontEnd.defer_codegen; copts.inline_max_size = 512; copts.inline_max_total_size = 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.optimize_for_size = (Boolean) (pGlobalOptimizer.optfor == 1); copts.crippled = crippled; copts.loop_unroll_count = 8; copts.loop_unroll_size_threshold = 100; copts.isGeneratingDebugInfo = params->isGeneratingDebugInfo; copts.pchCreator = CWFOURCHAR('C','W','I','E'); copts.pchType = CWFOURCHAR('M','M','C','H'); copts.text = CWFOURCHAR('T','E','X','T'); } static void GetLicense() { 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() { 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(); if (C_Compiler(&cparams)) 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, ""); }