mirror of https://git.wuffs.org/MWCC
252 lines
8.7 KiB
C
252 lines
8.7 KiB
C
#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 "compiler/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++)
|
|
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(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, target_name, 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();
|
|
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, "");
|
|
}
|