mirror of https://git.wuffs.org/MWCC
250 lines
8.7 KiB
C
250 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/types.h"
|
|
#include "pref_structs.h"
|
|
|
|
Boolean systemHandles;
|
|
|
|
static Boolean using_license_manager;
|
|
Boolean crippled;
|
|
SInt32 license_cookie;
|
|
CParams 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(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, "");
|
|
}
|