void AdvancedCompilerOptionsDlg::OnRegexTest(wxCommandEvent& WXUNUSED(event)) { if (m_SelectedRegex == -1) return; wxString text = XRCCTRL(*this, "txtRegexTest", wxTextCtrl)->GetValue(); if (text.IsEmpty()) { cbMessageBox(_("Please enter a compiler line in the \"Compiler output\" text box..."), _("Error"), wxICON_ERROR, this); return; } Compiler* compiler = CompilerFactory::GetCompiler(m_CompilerId); if (!compiler) return; // backup regexes RegExArray regex_copy = m_Regexes; SaveRegexDetails(m_SelectedRegex); // test-run compiler->SetRegExArray(m_Regexes); CompilerLineType clt = compiler->CheckForWarningsAndErrors(text); // restore regexes compiler->SetRegExArray(regex_copy); m_Regexes = regex_copy; wxString msg; msg.Printf(_("Regular expression analyzed as follows:\n\n" "Type: %s message\n" "Filename: %s\n" "Line number: %s\n" "Message: %s"), clt == cltNormal ? _("Normal") : (clt == cltInfo ? _("Info") : (clt == cltError ? _("Error") : _("Warning") ) ), compiler->GetLastErrorFilename().wx_str(), compiler->GetLastErrorLine().wx_str(), compiler->GetLastError().wx_str() ); cbMessageBox(msg, _("Test results"), wxICON_INFORMATION, this); }
Compiler::value NumberSTD::pow_mpz_mpz(Compiler& c, std::vector<Compiler::value> args) { auto r = [&]() { if (args[0].t.temporary) return args[0]; if (args[1].t.temporary) return args[1]; return c.new_mpz(); }(); auto r_addr = c.insn_address_of(r); auto a = c.insn_address_of(args[0]); auto b = c.insn_address_of(args[1]); auto p = c.insn_call(Type::LONG, {b}, &mpz_get_ui); c.insn_call(Type::VOID, {r_addr, a, p}, &mpz_pow_ui); if (args[1].t.temporary && args[1] != r) { c.insn_delete_mpz(args[1]); } return r; }
Compiler::value NumberSTD::sub_mpz_int(Compiler& c, std::vector<Compiler::value> args) { auto a = c.insn_address_of(args[0]); auto b = args[1]; auto r = c.new_mpz(); auto r_addr = c.insn_address_of(r); jit_label_t label_end = jit_label_undefined; jit_label_t label_else = jit_label_undefined; auto cond = c.insn_lt(b, c.new_integer(0)); jit_insn_branch_if_not(c.F, cond.v, &label_else); Compiler::value neg_b = {jit_insn_neg(c.F, b.v), Type::INTEGER}; c.insn_call(Type::VOID, {r_addr, a, neg_b}, &mpz_add_ui); jit_insn_branch(c.F, &label_end); jit_insn_label(c.F, &label_else); c.insn_call(Type::VOID, {r_addr, a, b}, &mpz_sub_ui); jit_insn_label(c.F, &label_end); if (args[0].t.temporary) { c.insn_delete_mpz(args[0]); } return r; }
void PrintReturnStack() { *rstack_top++ = (Value)pc; Value *rstack_cur = rstack_top; while (rstack_bottom < rstack_cur) { Value *v = (Value *)*--rstack_cur; if (v == 0) { std::cout << " <repl>"; } else { std::string name = compiler.name_for_value((Value *)*v); if (!name.empty()) { if ((*v & 3) == 3) { std::cout << " <prim:" << name << ">"; } else { std::cout << " " << name; } } else { std::cout << " <clause:" << v << ">"; } } std::cout << " (" << v << ")" << std::endl; } rstack_top--; }
void Project :: compile(ident_t filePath, Compiler& compiler, Parser& parser, ModuleInfo& moduleInfo, Unresolveds& unresolved) { try { // based on the target type generate the syntax tree for the file Path fullPath(StrSetting(_ELENA_::opProjectPath)); fullPath.combine(filePath); // parse TextFileReader sourceFile(fullPath.c_str(), getDefaultEncoding(), true); if (!sourceFile.isOpened()) raiseError(errInvalidFile, filePath); SyntaxTree tree; DerivationWriter writer(tree); parser.parse(&sourceFile, writer, getTabSize()); // compile the syntax tree compiler.compileModule(*this, filePath, tree.readRoot(), moduleInfo, unresolved); } catch (LineTooLong& e) { raiseError(errLineTooLong, filePath, e.row, 1); } catch (InvalidChar& e) { size_t destLength = 6; _ELENA_::String<char, 6> symbol; _ELENA_::Convertor::copy(symbol, (_ELENA_::unic_c*)&e.ch, 1, destLength); raiseError(errInvalidChar, filePath, e.row, e.column, (const char*)symbol); } catch (SyntaxError& e) { raiseError(e.error, filePath, e.row, e.column, e.token); } }
void Project :: compile(ident_t filePath, Compiler& compiler, ScriptParser parser, ModuleInfo& moduleInfo, Unresolveds& unresolved) { try { // based on the target type generate the syntax tree for the file Path fullPath(StrSetting(_ELENA_::opProjectPath)); fullPath.combine(filePath); // parse SyntaxTree tree; parser.parse(fullPath.c_str(), tree/*, getTabSize()*/); // compile the syntax tree compiler.compileModule(*this, filePath, tree.readRoot(), moduleInfo, unresolved); } catch (LineTooLong& e) { raiseError(errLineTooLong, filePath, e.row, 1); } catch (InvalidChar& e) { size_t destLength = 6; _ELENA_::String<char, 6> symbol; _ELENA_::Convertor::copy(symbol, (_ELENA_::unic_c*)&e.ch, 1, destLength); raiseError(errInvalidChar, filePath, e.row, e.column, (const char*)symbol); } catch (SyntaxError& e) { raiseError(e.error, filePath, e.row, e.column, e.token); } catch (ScriptError& e) { raiseError(e.error, filePath); } }
AutoDetectResult CompilerICC::AutoDetectInstallationDir() { wxString sep = wxFileName::GetPathSeparator(); wxString extraDir = _T(""); if (platform::windows) { if (wxDirExists(_T("C:\\Program Files\\Intel\\Compiler"))) { wxDir icc_dir(_T("C:\\Program Files\\Intel\\Compiler\\C++")); if (icc_dir.IsOpened()) { wxArrayString dirs; wxIccDirTraverser IccDirTraverser(dirs); icc_dir.Traverse(IccDirTraverser); if (!dirs.IsEmpty()) { // Now sort the array in reverse order to get the latest version's path dirs.Sort(true); m_MasterPath = dirs[0]; m_MasterPath.Append(_T("\\IA32")); // Now check for the installation of MSVC const wxString msvcIds[4] = { _T("msvc6"), _T("msvctk"), _T("msvc8"), _T("msvc10") }; bool msvcFound = false; for (unsigned int which_msvc = 0; which_msvc < array_size(msvcIds); ++which_msvc) { Compiler* vcComp = CompilerFactory::GetCompiler(msvcIds[which_msvc]); if (vcComp) { if (vcComp->AutoDetectInstallationDir() == adrDetected) { const wxString& vcMasterPath = vcComp->GetMasterPath(); if (m_ExtraPaths.Index(vcMasterPath) == wxNOT_FOUND && wxDirExists(vcMasterPath)) { m_ExtraPaths.Add(vcMasterPath); } AddIncludeDir(vcMasterPath + _T("\\Include")); AddLibDir(vcMasterPath + _T("\\Lib")); AddResourceIncludeDir(vcMasterPath + _T("\\Include")); const wxArrayString& vcExtraPaths = vcComp->GetExtraPaths(); for (size_t i = 0; i < vcExtraPaths.GetCount(); ++i) { if (m_ExtraPaths.Index(vcExtraPaths[i]) == wxNOT_FOUND && wxDirExists(vcExtraPaths[i])) { m_ExtraPaths.Add(vcExtraPaths[i]); } } const wxArrayString& vcIncludeDirs = vcComp->GetIncludeDirs(); for (size_t i = 0; i < vcIncludeDirs.GetCount(); ++i) { if (wxDirExists(vcIncludeDirs[i])) { if (m_IncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND) { AddIncludeDir(vcIncludeDirs[i]); } if (m_ResIncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND) { AddResourceIncludeDir(vcIncludeDirs[i]); } } } const wxArrayString& vcLibDirs = vcComp->GetLibDirs(); for (size_t i = 0; i < vcLibDirs.GetCount(); ++i) { if (m_LibDirs.Index(vcLibDirs[i]) == wxNOT_FOUND && wxDirExists(vcLibDirs[i])) { AddLibDir(vcLibDirs[i]); } } msvcFound = true; break; } } } if (!msvcFound) { cbMessageBox(_T("It seems your computer doesn't have a working MSVC compiler.\n\n" "This compiler requires MS compiler for proper functioning and\n" "it may not work without it."), _T("Error"), wxOK | wxICON_ERROR); } } } } // Read the ICPP_COMPILER90 environment variable wxGetEnv(_T("ICPP_COMPILER90"), &m_MasterPath); extraDir = sep + _T("IA32");// Intel also provides compiler for Itanium processors if (m_MasterPath.IsEmpty()) { // just a guess the default installation dir wxString Programs = _T("C:\\Program Files"); // what's the "Program Files" location // TO DO : support 64 bit -> 32 bit apps are in "ProgramFiles(x86)" // 64 bit apps are in "ProgramFiles" wxGetEnv(_T("ProgramFiles"), &Programs); m_MasterPath = Programs + _T("\\Intel\\Compiler\\C++\\9.0"); } } else { m_MasterPath = _T("/opt/intel/cc/9.0"); if (wxDirExists(_T("/opt/intel"))) { wxDir icc_dir(_T("/opt/intel/cc")); if (icc_dir.IsOpened()) { wxArrayString dirs; wxIccDirTraverser IccDirTraverser(dirs); icc_dir.Traverse(IccDirTraverser); if (!dirs.IsEmpty()) { // Now sort the array in reverse order to get the latest version's path dirs.Sort(true); m_MasterPath = dirs[0]; } } } } AutoDetectResult ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C) ? adrDetected : adrGuessed; if (ret == adrDetected) { m_IncludeDirs.Insert(m_MasterPath + sep + _T("Include"), 0); m_LibDirs.Insert(m_MasterPath + sep + _T("Lib"), 0); m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("Include"), 0); } // Try to detect the debugger. If not detected successfully the debugger plugin will // complain, so only the autodetection of compiler is considered in return value wxString path; wxString dbg; if (platform::windows) { dbg = _T("idb.exe"); wxGetEnv(_T("IDB_PATH"), &path); path += _T("IDB\\9.0\\IA32"); } else { dbg = _T("idb"); path= _T("/opt/intel/idb/9.0"); if (wxDirExists(_T("/opt/intel"))) { wxDir icc_debug_dir(_T("/opt/intel/idb")); if (icc_debug_dir.IsOpened()) { wxArrayString debug_dirs; wxIccDirTraverser IccDebugDirTraverser(debug_dirs); icc_debug_dir.Traverse(IccDebugDirTraverser); if (!debug_dirs.IsEmpty()) { // Now sort the array in reverse order to get the latest version's path debug_dirs.Sort(true); path = debug_dirs[0]; } } } } if (wxFileExists(path + sep + _T("bin") + sep + dbg)) m_ExtraPaths.Add(path); return ret; }
Compiler::value If::compile(Compiler& c) const { auto label_then = c.insn_init_label("then"); auto label_else = c.insn_init_label("else"); auto label_end = c.insn_init_label("end"); Compiler::value then_v; Compiler::value else_v; auto cond = condition->compile(c); condition->compile_end(c); auto cond_boolean = c.insn_to_bool(cond); c.insn_delete_temporary(cond); c.insn_if_new(cond_boolean, &label_then, &label_else); c.insn_label(&label_then); then_v = c.insn_convert(then->compile(c), type.fold()); if (!then_v.v) then_v = c.insn_convert(c.new_null(), type.fold()); then->compile_end(c); c.insn_branch(&label_end); label_then.block = Compiler::builder.GetInsertBlock(); c.insn_label(&label_else); if (elze != nullptr) { else_v = c.insn_convert(elze->compile(c), type.fold()); elze->compile_end(c); } else { else_v = c.insn_convert(c.new_null(), type.fold()); } c.insn_branch(&label_end); label_else.block = Compiler::builder.GetInsertBlock(); c.insn_label(&label_end); if (type.is_void()) { return {}; } else { return c.insn_phi(type, then_v, label_then, else_v, label_else); } }
/* ipfc 1.0 flags are: /INF -- generate an *.inf file /S ---- suppress search table generation /X ---- generate cross-reference list /Wn --- warning level n /COUNTRY=nnn /CODEPAGE=nnn /LANGUAGE=XYZse ipfc 2.0 flags are: -i ------- generate an *.inf file -s ------- suppress search table generation -x ------- generate cross-reference list -Wn ------ set warning level -d:nnn --- set 3 digit country code -c:nnnn -- set 4 digit code page -l:xyz -- set 3 letter language identifier -X:? ----- help on option '?' We support the version 2 flags */ static void processCommandLine(int argc, char **argv, Compiler& c) { if (argc < 2) usage(); int inIndex( 0 ); int outIndex( 0 ); bool info( false ); for( int count = 1; count < argc; ++count ) { #ifdef __UNIX__ if( argv[count][0] == '-' ) { #else if( argv[count][0] == '-' || argv[count][0] == '/' ) { #endif switch( argv[count][1] ) { case 'C': case 'c': case 'd': std::cout << "Country code and code page selection are not supported." << std::endl; std::cout << "Use the 'l' option to select a localization file instead." << std::endl; if (argv[count][2] == '?') info = true; break; case 'I': case 'i': c.setOutputType( Compiler::INF ); break; case 'L': case 'l': if (argv[count][2] == '?') { std::cout << "xx_YY is the root name of a localization file" << std::endl; std::cout << "with the full name xx_YY.nls\nSee en_US.nls for an example." << std::endl; info = true; } else c.setLocalization( argv[++count] ); break; case 'O': case 'o': outIndex = ++count; break; case 'Q': case 'q': c.noBanner(); break; case 'S': case 's': c.noSearch(); break; case 'w': case 'W': if (argv[count][2] == '?') { std::cout << "-wN where N is one of 1, 2, or 3" << std::endl; info = true; } else c.setWarningLevel( std::atoi( argv[count] + 2 )); break; case 'X': case 'x': c.setXRef( true ); break; default: usage(); break; } } else if( !inIndex ) inIndex = count; else std::cout << "Warning: extra filename '" << argv[count] << "' will be ignored" << std::endl; } if( inIndex ) { std::string fullpath( canonicalPath( argv[ inIndex ] ) ); c.setInputFile( fullpath ); if( !outIndex ) { std::string outFile( fullpath ); outFile.erase( outFile.rfind( '.' ) ); if( c.outputType() == Compiler::INF ) outFile += ".inf"; else outFile += ".hlp"; c.setOutputFile( outFile ); } } else { std::cout << "Fatal Error: You must specify an input file" << std::endl; std::exit( EXIT_FAILURE ); } if( outIndex ) { std::string fullpath( canonicalPath( argv[ outIndex ] ) ); c.setOutputFile( fullpath ); } if( info ) std::exit( EXIT_SUCCESS ); } /*****************************************************************************/ static void usage() { printBanner(); std::cout << "Usage:" << std::endl; std::cout << "wipfc [-switches] [-options] infile [outfile]" << std::endl; std::cout << std::endl; std::cout << "Switches" << std::endl; std::cout << "-i generate outfile.inf instead of outfile.hlp" << std::endl; std::cout << "-s do not generate full text search tables" << std::endl; std::cout << "-x generate and display cross-reference list" << std::endl; std::cout << std::endl; std::cout << "Options\n" << std::endl; std::cout << "-l xx_YY localization code (default: en_US)" << std::endl; std::cout << "-o name set the output file path, name and extension" << std::endl; std::cout << "-q operate quietly" << std::endl; std::cout << "-wn 1 digit warning level (default: 3)" << std::endl; std::cout << "-X? display help on option X" << std::endl; std::exit( EXIT_FAILURE ); }
AutoDetectResult CompilerICC::AutoDetectInstallationDir() { wxString sep = wxFileName::GetPathSeparator(); if (platform::windows) { if ( wxDirExists(_T("C:\\Program Files\\Intel\\Compiler")) ) { wxDir icc_dir(_T("C:\\Program Files\\Intel\\Compiler\\C++")); if (icc_dir.IsOpened()) { wxArrayString dirs; wxIccDirTraverser IccDirTraverser(dirs); icc_dir.Traverse(IccDirTraverser); if (!dirs.IsEmpty()) { // Now sort the array in reverse order to get the latest version's path dirs.Sort(true); m_MasterPath = dirs[0]; m_MasterPath.Append(_T("\\IA32")); } } } int version = 0; while ( m_MasterPath.IsEmpty() || !wxDirExists(m_MasterPath) ) { wxString iccEnvVar; if (version==0) { // Try default w/o version number iccEnvVar = _T("ICPP_COMPILER"); version = 8; } else if (version>15) break; // exit while-loop else { // Try ICPP_COMPILER80 ... ICPP_COMPILER12 iccEnvVar.Printf(wxT("ICPP_COMPILER%d0"), version); version++; } // Read the ICPP_COMPILER[XX] environment variable if ( !wxGetEnv(iccEnvVar, &m_MasterPath) ) m_MasterPath.Clear(); } // Now check for the installation of MSVC const wxString msvcIds[4] = { _T("msvc6"), _T("msvctk"), _T("msvc8"), _T("msvc10") }; bool msvcFound = false; for (unsigned int which_msvc = 0; which_msvc < array_size(msvcIds); ++which_msvc) { Compiler* vcComp = CompilerFactory::GetCompiler(msvcIds[which_msvc]); if (!vcComp) continue; // compiler not registered? try next one wxString vcMasterNoMacros = vcComp->GetMasterPath(); Manager::Get()->GetMacrosManager()->ReplaceMacros(vcMasterNoMacros); if ( !wxFileExists(vcMasterNoMacros + sep + wxT("bin") + sep + vcComp->GetPrograms().C) && !wxFileExists(vcMasterNoMacros + sep + vcComp->GetPrograms().C) ) continue; // this MSVC is not installed; try next one const wxString& vcMasterPath = vcComp->GetMasterPath(); if (m_ExtraPaths.Index(vcMasterPath) == wxNOT_FOUND) m_ExtraPaths.Add(vcMasterPath); if ( !vcMasterPath.EndsWith(wxT("bin")) && m_ExtraPaths.Index(vcMasterPath + sep + wxT("bin")) == wxNOT_FOUND ) { m_ExtraPaths.Add(vcMasterPath + sep + wxT("bin")); } AddIncludeDir(vcMasterPath + _T("\\Include")); AddLibDir(vcMasterPath + _T("\\Lib")); AddResourceIncludeDir(vcMasterPath + _T("\\Include")); const wxArrayString& vcExtraPaths = vcComp->GetExtraPaths(); for (size_t i = 0; i < vcExtraPaths.GetCount(); ++i) { if ( m_ExtraPaths.Index(vcExtraPaths[i]) == wxNOT_FOUND && wxDirExists(vcExtraPaths[i]) ) { m_ExtraPaths.Add(vcExtraPaths[i]); } } const wxArrayString& vcIncludeDirs = vcComp->GetIncludeDirs(); for (size_t i = 0; i < vcIncludeDirs.GetCount(); ++i) { if (wxDirExists(vcIncludeDirs[i])) { if (m_IncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND) AddIncludeDir(vcIncludeDirs[i]); if (m_ResIncludeDirs.Index(vcIncludeDirs[i]) == wxNOT_FOUND) AddResourceIncludeDir(vcIncludeDirs[i]); } } const wxArrayString& vcLibDirs = vcComp->GetLibDirs(); for (size_t i = 0; i < vcLibDirs.GetCount(); ++i) { if ( m_LibDirs.Index(vcLibDirs[i]) == wxNOT_FOUND && wxDirExists(vcLibDirs[i]) ) { AddLibDir(vcLibDirs[i]); } } msvcFound = true; break; } if ( m_MasterPath.IsEmpty() || !wxDirExists(m_MasterPath) ) { // Just a final guess for the default installation dir wxString Programs = _T("C:\\Program Files"); // what's the "Program Files" location // TO DO : support 64 bit -> 32 bit apps are in "ProgramFiles(x86)" // 64 bit apps are in "ProgramFiles" wxGetEnv(_T("ProgramFiles"), &Programs); m_MasterPath = Programs + _T("\\Intel\\Compiler\\C++\\9.0"); } else if (!msvcFound) { cbMessageBox(_T("It seems your computer doesn't have a MSVC compiler installed.\n\n" "The ICC compiler requires MSVC for proper functioning and\n" "it may not work without it."), _T("Error"), wxOK | wxICON_ERROR); } } else { m_MasterPath = _T("/opt/intel/cc/9.0"); if (wxDirExists(_T("/opt/intel"))) { wxDir icc_dir(_T("/opt/intel/cc")); if (icc_dir.IsOpened()) { wxArrayString dirs; wxIccDirTraverser IccDirTraverser(dirs); icc_dir.Traverse(IccDirTraverser); if (!dirs.IsEmpty()) { // Now sort the array in reverse order to get the latest version's path dirs.Sort(true); m_MasterPath = dirs[0]; } } } } AutoDetectResult ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + m_Programs.C) ? adrDetected : adrGuessed; if (ret == adrGuessed) ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("ia32") + sep + m_Programs.C) ? adrDetected : adrGuessed; if (ret == adrGuessed) ret = wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("intel64") + sep + m_Programs.C) ? adrDetected : adrGuessed; if (ret == adrDetected) { if ( wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("ia32") + sep + m_Programs.C) ) m_ExtraPaths.Add(m_MasterPath + sep + _T("bin") + sep + _T("ia32")); if ( wxFileExists(m_MasterPath + sep + _T("bin") + sep + _T("intel64") + sep + m_Programs.C) ) m_ExtraPaths.Add(m_MasterPath + sep + _T("bin") + sep + _T("intel64")); if ( wxDirExists(m_MasterPath + sep + _T("include")) ) { m_IncludeDirs.Insert(m_MasterPath + sep + _T("include"), 0); m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("include"), 0); } if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("include")) ) { m_IncludeDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("include"), 0); m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("include"), 0); } if ( wxDirExists(m_MasterPath + sep + _T("lib")) ) { m_IncludeDirs.Insert(m_MasterPath + sep + _T("lib"), 0); m_ResIncludeDirs.Insert(m_MasterPath + sep + _T("lib"), 0); } if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("lib")) ) m_LibDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("lib"), 0); if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("ia32")) ) m_LibDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("ia32"), 0); if ( wxDirExists(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("intel64")) ) m_LibDirs.Insert(m_MasterPath + sep + _T("compiler") + sep + _T("lib") + sep + _T("intel64"), 0); } // Try to detect the debugger. If not detected successfully the debugger plugin will // complain, so only the autodetection of compiler is considered in return value wxString path; wxString dbg; if (platform::windows) { dbg = _T("idb.exe"); wxGetEnv(_T("IDB_PATH"), &path); if ( !path.IsEmpty() && wxDirExists(path) ) { int version = 9; while ( true ) { wxString idbPath = path + sep + _T("IDB") + sep + wxString::Format(_T("%d.0"), version) + sep + _T("IA32"); if ( wxDirExists(idbPath) ) { path = idbPath; // found break; // exit while-loop } else if (version>15) break; // exit while-loop else version++; } } } else { dbg = _T("idb"); path = _T("/opt/intel/idb/9.0"); if ( wxDirExists(_T("/opt/intel")) ) { wxDir icc_debug_dir(_T("/opt/intel/idb")); if (icc_debug_dir.IsOpened()) { wxArrayString debug_dirs; wxIccDirTraverser IccDebugDirTraverser(debug_dirs); icc_debug_dir.Traverse(IccDebugDirTraverser); if (!debug_dirs.IsEmpty()) { // Now sort the array in reverse order to get the latest version's path debug_dirs.Sort(true); path = debug_dirs[0]; } } } } if ( wxFileExists(path + sep + _T("bin") + sep + dbg) ) m_ExtraPaths.Add(path); return ret; }
llvm_value CompileExpression::DoRewrite(RewriteCandidate &cand) // ---------------------------------------------------------------------------- // Generate code for a particular rewwrite candidate // ---------------------------------------------------------------------------- { Infix *rw = cand.rewrite; llvm_value result = NULL; IFTRACE(calltypes) std::cerr << "Rewrite: " << rw << "\n"; // Evaluate parameters llvm_values args; RewriteBindings &bnds = cand.bindings; RewriteBindings::iterator b; for (b = bnds.begin(); b != bnds.end(); b++) { Tree *tree = (*b).value; IFTRACE(calltypes) std::cerr << " Arg: " << tree << ": "; if (llvm_value closure = (*b).Closure(unit)) { args.push_back(closure); IFTRACE(calltypes) llvm::errs() << " closure " << *closure << "\n"; } else if (llvm_value value = Value(tree)) { args.push_back(value); llvm_type mtype = value->getType(); if (unit->compiler->IsClosureType(mtype)) (*b).closure = value; IFTRACE(calltypes) llvm::errs() << " value " << *value << " mtype " << *mtype << "\n"; } } // Check if this is an LLVM builtin Tree *builtin = NULL; if (Tree *value = rw->right) if (Prefix *prefix = value->AsPrefix()) if (Name *name = prefix->left->AsName()) if (name->value == "opcode") builtin = prefix->right; if (builtin) { llvm_builder bld = unit->code; if (Prefix *prefix = builtin->AsPrefix()) { if (Name *name = prefix->left->AsName()) { if (name->value == "data") { bld = unit->data; builtin = prefix->right; } } } Name *name = builtin->AsName(); if (!name) { Ooops("Malformed primitive $1", builtin); result = unit->CallFormError(builtin); } else { Compiler *compiler = unit->compiler; text op = name->value; uint sz = args.size(); llvm_value *a = &args[0]; result = compiler->Primitive(*unit, bld, op, sz, a); if (!result) Ooops("Invalid primitive $1", builtin); IFTRACE(calltypes) llvm::errs() << " = Primitive: " << *result << "\n"; } } else { llvm_value function = unit->Compile(cand, args); IFTRACE(calltypes) llvm::errs() << " < Function: " << *function << "\n"; if (function) result = unit->code->CreateCall(function, LLVMS_ARGS(args)); IFTRACE(calltypes) llvm::errs() << " =Call: " << *result << "\n"; } return result; }
int main() { using namespace moon; Compiler compiler; // Script parsing and bytecode output. VM vm; // Executes bytecode produced by a Compiler. try { compiler.parseScript(&vm, "tests/script/globals.ml"); compiler.compile(&vm); // Init the globals: logStream() << "C++: First run...\n"; vm.execute(); // Print the current values: logStream() << "C++: Calling print_globals()...\n"; vm.call("print_globals"); // Change them: logStream() << "C++: Editing globals vars...\n"; { Variant var; var.type = Variant::Type::Integer; var.value.asInteger = 1337; MOON_ASSERT(vm.globals.setGlobal("an_integer", var) == true); var.type = Variant::Type::Float; var.value.asFloat = 3.141592; MOON_ASSERT(vm.globals.setGlobal("a_float", var) == true); var.type = Variant::Type::Range; var.value.asRange.begin = -5; var.value.asRange.end = +5; MOON_ASSERT(vm.globals.setGlobal("a_range", var) == true); var.type = Variant::Type::Str; const char * s = "hello from C++"; var.value.asString = Str::newFromString(vm, s, std::strlen(s), true); MOON_ASSERT(vm.globals.setGlobal("a_string", var) == true); } // Print the new values: logStream() << "C++: Calling print_globals() again...\n"; vm.call("print_globals"); } catch (...) { #if MOON_SAVE_SCRIPT_CALLSTACK if (!vm.callstack.isEmpty()) { vm.printStackTrace(logStream()); } #endif // MOON_SAVE_SCRIPT_CALLSTACK logStream() << color::red() << "terminating with error(s)...\n" << color::restore(); return EXIT_FAILURE; } }
static bool slang_reflect(const Compiler &vertex_compiler, const Compiler &fragment_compiler, const ShaderResources &vertex, const ShaderResources &fragment, slang_reflection *reflection) { // Validate use of unexpected types. if ( !vertex.sampled_images.empty() || !vertex.storage_buffers.empty() || !vertex.subpass_inputs.empty() || !vertex.storage_images.empty() || !vertex.atomic_counters.empty() || !fragment.storage_buffers.empty() || !fragment.subpass_inputs.empty() || !fragment.storage_images.empty() || !fragment.atomic_counters.empty()) { RARCH_ERR("[slang]: Invalid resource type detected.\n"); return false; } // Validate vertex input. if (vertex.stage_inputs.size() != 2) { RARCH_ERR("[slang]: Vertex must have two attributes.\n"); return false; } if (fragment.stage_outputs.size() != 1) { RARCH_ERR("[slang]: Multiple render targets not supported.\n"); return false; } if (fragment_compiler.get_decoration(fragment.stage_outputs[0].id, spv::DecorationLocation) != 0) { RARCH_ERR("[slang]: Render target must use location = 0.\n"); return false; } uint32_t location_mask = 0; for (auto &input : vertex.stage_inputs) location_mask |= 1 << vertex_compiler.get_decoration(input.id, spv::DecorationLocation); if (location_mask != 0x3) { RARCH_ERR("[slang]: The two vertex attributes do not use location = 0 and location = 1.\n"); return false; } // Validate the single uniform buffer. if (vertex.uniform_buffers.size() > 1) { RARCH_ERR("[slang]: Vertex must use zero or one uniform buffer.\n"); return false; } if (fragment.uniform_buffers.size() > 1) { RARCH_ERR("[slang]: Fragment must use zero or one uniform buffer.\n"); return false; } // Validate the single push constant buffer. if (vertex.push_constant_buffers.size() > 1) { RARCH_ERR("[slang]: Vertex must use zero or one push constant buffers.\n"); return false; } if (fragment.push_constant_buffers.size() > 1) { RARCH_ERR("[slang]: Fragment must use zero or one push cosntant buffer.\n"); return false; } uint32_t vertex_ubo = vertex.uniform_buffers.empty() ? 0 : vertex.uniform_buffers[0].id; uint32_t fragment_ubo = fragment.uniform_buffers.empty() ? 0 : fragment.uniform_buffers[0].id; uint32_t vertex_push = vertex.push_constant_buffers.empty() ? 0 : vertex.push_constant_buffers[0].id; uint32_t fragment_push = fragment.push_constant_buffers.empty() ? 0 : fragment.push_constant_buffers[0].id; if (vertex_ubo && vertex_compiler.get_decoration(vertex_ubo, spv::DecorationDescriptorSet) != 0) { RARCH_ERR("[slang]: Resources must use descriptor set #0.\n"); return false; } if (fragment_ubo && fragment_compiler.get_decoration(fragment_ubo, spv::DecorationDescriptorSet) != 0) { RARCH_ERR("[slang]: Resources must use descriptor set #0.\n"); return false; } unsigned vertex_ubo_binding = vertex_ubo ? vertex_compiler.get_decoration(vertex_ubo, spv::DecorationBinding) : -1u; unsigned fragment_ubo_binding = fragment_ubo ? fragment_compiler.get_decoration(fragment_ubo, spv::DecorationBinding) : -1u; bool has_ubo = vertex_ubo || fragment_ubo; if (vertex_ubo_binding != -1u && fragment_ubo_binding != -1u && vertex_ubo_binding != fragment_ubo_binding) { RARCH_ERR("[slang]: Vertex and fragment uniform buffer must have same binding.\n"); return false; } unsigned ubo_binding = vertex_ubo_binding != -1u ? vertex_ubo_binding : fragment_ubo_binding; if (has_ubo && ubo_binding >= SLANG_NUM_BINDINGS) { RARCH_ERR("[slang]: Binding %u is out of range.\n", ubo_binding); return false; } reflection->ubo_binding = has_ubo ? ubo_binding : 0; reflection->ubo_stage_mask = 0; reflection->ubo_size = 0; reflection->push_constant_size = 0; reflection->push_constant_stage_mask = 0; if (vertex_ubo) { reflection->ubo_stage_mask |= SLANG_STAGE_VERTEX_MASK; reflection->ubo_size = max(reflection->ubo_size, vertex_compiler.get_declared_struct_size(vertex_compiler.get_type(vertex.uniform_buffers[0].base_type_id))); } if (fragment_ubo) { reflection->ubo_stage_mask |= SLANG_STAGE_FRAGMENT_MASK; reflection->ubo_size = max(reflection->ubo_size, fragment_compiler.get_declared_struct_size(fragment_compiler.get_type(fragment.uniform_buffers[0].base_type_id))); } if (vertex_push) { reflection->push_constant_stage_mask |= SLANG_STAGE_VERTEX_MASK; reflection->push_constant_size = max(reflection->push_constant_size, vertex_compiler.get_declared_struct_size(vertex_compiler.get_type(vertex.push_constant_buffers[0].base_type_id))); } if (fragment_push) { reflection->push_constant_stage_mask |= SLANG_STAGE_FRAGMENT_MASK; reflection->push_constant_size = max(reflection->push_constant_size, fragment_compiler.get_declared_struct_size(fragment_compiler.get_type(fragment.push_constant_buffers[0].base_type_id))); } // Validate push constant size against Vulkan's minimum spec to avoid cross-vendor issues. if (reflection->push_constant_size > 128) { RARCH_ERR("[slang]: Exceeded maximum size of 128 bytes for push constant buffer.\n"); return false; } // Find all relevant uniforms and push constants. if (vertex_ubo && !add_active_buffer_ranges(vertex_compiler, vertex.uniform_buffers[0], reflection, false)) return false; if (fragment_ubo && !add_active_buffer_ranges(fragment_compiler, fragment.uniform_buffers[0], reflection, false)) return false; if (vertex_push && !add_active_buffer_ranges(vertex_compiler, vertex.push_constant_buffers[0], reflection, true)) return false; if (fragment_push && !add_active_buffer_ranges(fragment_compiler, fragment.push_constant_buffers[0], reflection, true)) return false; uint32_t binding_mask = has_ubo ? (1 << ubo_binding) : 0; // On to textures. for (auto &texture : fragment.sampled_images) { unsigned set = fragment_compiler.get_decoration(texture.id, spv::DecorationDescriptorSet); unsigned binding = fragment_compiler.get_decoration(texture.id, spv::DecorationBinding); if (set != 0) { RARCH_ERR("[slang]: Resources must use descriptor set #0.\n"); return false; } if (binding >= SLANG_NUM_BINDINGS) { RARCH_ERR("[slang]: Binding %u is out of range.\n", ubo_binding); return false; } if (binding_mask & (1 << binding)) { RARCH_ERR("[slang]: Binding %u is already in use.\n", binding); return false; } binding_mask |= 1 << binding; unsigned array_index = 0; slang_texture_semantic index = slang_name_to_texture_semantic(*reflection->texture_semantic_map, texture.name, &array_index); if (index == SLANG_INVALID_TEXTURE_SEMANTIC) { RARCH_ERR("[slang]: Non-semantic textures not supported yet.\n"); return false; } resize_minimum(reflection->semantic_textures[index], array_index + 1); auto &semantic = reflection->semantic_textures[index][array_index]; semantic.binding = binding; semantic.stage_mask = SLANG_STAGE_FRAGMENT_MASK; semantic.texture = true; } RARCH_LOG("[slang]: Reflection\n"); RARCH_LOG("[slang]: Textures:\n"); for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++) { unsigned index = 0; for (auto &sem : reflection->semantic_textures[i]) { if (sem.texture) RARCH_LOG("[slang]: %s (#%u)\n", texture_semantic_names[i], index); index++; } } RARCH_LOG("[slang]:\n"); RARCH_LOG("[slang]: Uniforms (Vertex: %s, Fragment: %s):\n", reflection->ubo_stage_mask & SLANG_STAGE_VERTEX_MASK ? "yes": "no", reflection->ubo_stage_mask & SLANG_STAGE_FRAGMENT_MASK ? "yes": "no"); RARCH_LOG("[slang]: Push Constants (Vertex: %s, Fragment: %s):\n", reflection->push_constant_stage_mask & SLANG_STAGE_VERTEX_MASK ? "yes": "no", reflection->push_constant_stage_mask & SLANG_STAGE_FRAGMENT_MASK ? "yes": "no"); for (unsigned i = 0; i < SLANG_NUM_SEMANTICS; i++) { if (reflection->semantics[i].uniform) { RARCH_LOG("[slang]: %s (Offset: %u)\n", semantic_uniform_names[i], unsigned(reflection->semantics[i].ubo_offset)); } if (reflection->semantics[i].push_constant) { RARCH_LOG("[slang]: %s (PushOffset: %u)\n", semantic_uniform_names[i], unsigned(reflection->semantics[i].push_constant_offset)); } } for (unsigned i = 0; i < SLANG_NUM_TEXTURE_SEMANTICS; i++) { unsigned index = 0; for (auto &sem : reflection->semantic_textures[i]) { if (sem.uniform) { RARCH_LOG("[slang]: %s (#%u) (Offset: %u)\n", texture_semantic_uniform_names[i], index, unsigned(sem.ubo_offset)); } if (sem.push_constant) { RARCH_LOG("[slang]: %s (#%u) (PushOffset: %u)\n", texture_semantic_uniform_names[i], index, unsigned(sem.push_constant_offset)); } index++; } } RARCH_LOG("[slang]:\n"); RARCH_LOG("[slang]: Parameters:\n"); unsigned i = 0; for (auto ¶m : reflection->semantic_float_parameters) { if (param.uniform) RARCH_LOG("[slang]: #%u (Offset: %u)\n", i, param.ubo_offset); if (param.push_constant) RARCH_LOG("[slang]: #%u (PushOffset: %u)\n", i, param.push_constant_offset); i++; } return true; }
static bool add_active_buffer_ranges(const Compiler &compiler, const Resource &resource, slang_reflection *reflection, bool push_constant) { // Get which uniforms are actually in use by this shader. auto ranges = compiler.get_active_buffer_ranges(resource.id); for (auto &range : ranges) { auto &name = compiler.get_member_name(resource.base_type_id, range.index); auto &type = compiler.get_type(compiler.get_type(resource.base_type_id).member_types[range.index]); unsigned sem_index = 0; unsigned tex_sem_index = 0; auto sem = slang_uniform_name_to_semantic(*reflection->semantic_map, name, &sem_index); auto tex_sem = slang_uniform_name_to_texture_semantic(*reflection->texture_semantic_uniform_map, name, &tex_sem_index); if (tex_sem == SLANG_TEXTURE_SEMANTIC_PASS_OUTPUT && tex_sem_index >= reflection->pass_number) { RARCH_ERR("[slang]: Non causal filter chain detected. Shader is trying to use output from pass #%u, but this shader is pass #%u.\n", tex_sem_index, reflection->pass_number); return false; } if (sem != SLANG_INVALID_SEMANTIC) { if (!validate_type_for_semantic(type, sem)) { RARCH_ERR("[slang]: Underlying type of semantic is invalid.\n"); return false; } switch (sem) { case SLANG_SEMANTIC_FLOAT_PARAMETER: if (!set_ubo_float_parameter_offset(reflection, sem_index, range.offset, type.vecsize, push_constant)) return false; break; default: if (!set_ubo_offset(reflection, sem, range.offset, type.vecsize, push_constant)) return false; break; } } else if (tex_sem != SLANG_INVALID_TEXTURE_SEMANTIC) { if (!validate_type_for_texture_semantic(type)) { RARCH_ERR("[slang]: Underlying type of texture semantic is invalid.\n"); return false; } if (!set_ubo_texture_offset(reflection, tex_sem, tex_sem_index, range.offset, push_constant)) return false; } else { RARCH_ERR("[slang]: Unknown semantic found.\n"); return false; } } return true; }
Compiler * CompilerGNUPOWERPC::CreateCopy() { Compiler* c = new CompilerGNUPOWERPC(*this); c->SetExtraPaths(m_ExtraPaths); // wxArrayString doesn't seem to be copied with the default copy ctor... return c; }
bool AstIdentifier::emit_lvalue(Compiler &c) const { c.push_inst(Instruction::make_get(name.c_str(), Instruction::GET_NAME_REF)); return false; }
void NodePrintLine::accept(Compiler& c) { c.nodePrintLine(*this); }
//------------------------------------------------------------------------ // TreeNodeInfoInitCall: Set the NodeInfo for a call. // // Arguments: // call - The call node of interest // // Return Value: // None. // void Lowering::TreeNodeInfoInitCall(GenTreeCall* call) { TreeNodeInfo* info = &(call->gtLsraInfo); LinearScan* l = m_lsra; Compiler* compiler = comp; bool hasMultiRegRetVal = false; ReturnTypeDesc* retTypeDesc = nullptr; info->srcCount = 0; if (call->TypeGet() != TYP_VOID) { hasMultiRegRetVal = call->HasMultiRegRetVal(); if (hasMultiRegRetVal) { // dst count = number of registers in which the value is returned by call retTypeDesc = call->GetReturnTypeDesc(); info->dstCount = retTypeDesc->GetReturnRegCount(); } else { info->dstCount = 1; } } else { info->dstCount = 0; } GenTree* ctrlExpr = call->gtControlExpr; if (call->gtCallType == CT_INDIRECT) { // either gtControlExpr != null or gtCallAddr != null. // Both cannot be non-null at the same time. assert(ctrlExpr == nullptr); assert(call->gtCallAddr != nullptr); ctrlExpr = call->gtCallAddr; } // set reg requirements on call target represented as control sequence. if (ctrlExpr != nullptr) { // we should never see a gtControlExpr whose type is void. assert(ctrlExpr->TypeGet() != TYP_VOID); info->srcCount++; // In case of fast tail implemented as jmp, make sure that gtControlExpr is // computed into a register. if (call->IsFastTailCall()) { NYI_ARM("tail call"); #ifdef _TARGET_ARM64_ // Fast tail call - make sure that call target is always computed in IP0 // so that epilog sequence can generate "br xip0" to achieve fast tail call. ctrlExpr->gtLsraInfo.setSrcCandidates(l, genRegMask(REG_IP0)); #endif // _TARGET_ARM64_ } } #ifdef _TARGET_ARM_ else { info->internalIntCount = 1; } #endif // _TARGET_ARM_ RegisterType registerType = call->TypeGet(); // Set destination candidates for return value of the call. #ifdef _TARGET_ARM_ if (call->IsHelperCall(compiler, CORINFO_HELP_INIT_PINVOKE_FRAME)) { // The ARM CORINFO_HELP_INIT_PINVOKE_FRAME helper uses a custom calling convention that returns with // TCB in REG_PINVOKE_TCB. fgMorphCall() sets the correct argument registers. info->setDstCandidates(l, RBM_PINVOKE_TCB); } else #endif // _TARGET_ARM_ if (hasMultiRegRetVal) { assert(retTypeDesc != nullptr); info->setDstCandidates(l, retTypeDesc->GetABIReturnRegs()); } else if (varTypeIsFloating(registerType)) { info->setDstCandidates(l, RBM_FLOATRET); } else if (registerType == TYP_LONG) { info->setDstCandidates(l, RBM_LNGRET); } else { info->setDstCandidates(l, RBM_INTRET); } // If there is an explicit this pointer, we don't want that node to produce anything // as it is redundant if (call->gtCallObjp != nullptr) { GenTreePtr thisPtrNode = call->gtCallObjp; if (thisPtrNode->gtOper == GT_PUTARG_REG) { l->clearOperandCounts(thisPtrNode); thisPtrNode->SetContained(); l->clearDstCount(thisPtrNode->gtOp.gtOp1); } else { l->clearDstCount(thisPtrNode); } } // First, count reg args bool callHasFloatRegArgs = false; for (GenTreePtr list = call->gtCallLateArgs; list; list = list->MoveNext()) { assert(list->OperIsList()); GenTreePtr argNode = list->Current(); fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode); assert(curArgTabEntry); if (curArgTabEntry->regNum == REG_STK) { // late arg that is not passed in a register assert(argNode->gtOper == GT_PUTARG_STK); TreeNodeInfoInitPutArgStk(argNode->AsPutArgStk(), curArgTabEntry); continue; } // A GT_FIELD_LIST has a TYP_VOID, but is used to represent a multireg struct if (argNode->OperGet() == GT_FIELD_LIST) { argNode->SetContained(); // There could be up to 2-4 PUTARG_REGs in the list (3 or 4 can only occur for HFAs) regNumber argReg = curArgTabEntry->regNum; for (GenTreeFieldList* entry = argNode->AsFieldList(); entry != nullptr; entry = entry->Rest()) { TreeNodeInfoInitPutArgReg(entry->Current()->AsUnOp(), argReg, *info, false, &callHasFloatRegArgs); // Update argReg for the next putarg_reg (if any) argReg = genRegArgNext(argReg); #if defined(_TARGET_ARM_) // A double register is modelled as an even-numbered single one if (entry->Current()->TypeGet() == TYP_DOUBLE) { argReg = genRegArgNext(argReg); } #endif // _TARGET_ARM_ } } #ifdef _TARGET_ARM_ else if (argNode->OperGet() == GT_PUTARG_SPLIT) { fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, argNode); TreeNodeInfoInitPutArgSplit(argNode->AsPutArgSplit(), *info, curArgTabEntry); } #endif else { TreeNodeInfoInitPutArgReg(argNode->AsUnOp(), curArgTabEntry->regNum, *info, false, &callHasFloatRegArgs); } } // Now, count stack args // Note that these need to be computed into a register, but then // they're just stored to the stack - so the reg doesn't // need to remain live until the call. In fact, it must not // because the code generator doesn't actually consider it live, // so it can't be spilled. GenTreePtr args = call->gtCallArgs; while (args) { GenTreePtr arg = args->gtOp.gtOp1; // Skip arguments that have been moved to the Late Arg list if (!(args->gtFlags & GTF_LATE_ARG)) { if (arg->gtOper == GT_PUTARG_STK) { fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg); assert(curArgTabEntry); assert(curArgTabEntry->regNum == REG_STK); TreeNodeInfoInitPutArgStk(arg->AsPutArgStk(), curArgTabEntry); } #ifdef _TARGET_ARM_ else if (arg->OperGet() == GT_PUTARG_SPLIT) { fgArgTabEntryPtr curArgTabEntry = compiler->gtArgEntryByNode(call, arg); TreeNodeInfoInitPutArgSplit(arg->AsPutArgSplit(), *info, curArgTabEntry); } #endif else { TreeNodeInfo* argInfo = &(arg->gtLsraInfo); if (argInfo->dstCount != 0) { argInfo->isLocalDefUse = true; } argInfo->dstCount = 0; } } args = args->gtOp.gtOp2; } // If it is a fast tail call, it is already preferenced to use IP0. // Therefore, no need set src candidates on call tgt again. if (call->IsVarargs() && callHasFloatRegArgs && !call->IsFastTailCall() && (ctrlExpr != nullptr)) { NYI_ARM("float reg varargs"); // Don't assign the call target to any of the argument registers because // we will use them to also pass floating point arguments as required // by Arm64 ABI. ctrlExpr->gtLsraInfo.setSrcCandidates(l, l->allRegs(TYP_INT) & ~(RBM_ARG_REGS)); } #ifdef _TARGET_ARM_ if (call->NeedsNullCheck()) { info->internalIntCount++; } #endif // _TARGET_ARM_ }
// Don't call this function from within the scope of: // ClangPlugin::OnEditorHook // ClangPlugin::OnTimer int ClangPlugin::UpdateCompileCommand(cbEditor* ed) { wxString compileCommand; ProjectFile* pf = ed->GetProjectFile(); m_UpdateCompileCommand++; if ( m_UpdateCompileCommand > 1 ) { // Re-entry is not allowed m_UpdateCompileCommand--; return 0; } ProjectBuildTarget* target = nullptr; Compiler* comp = nullptr; if (pf && pf->GetParentProject() && !pf->GetBuildTargets().IsEmpty()) { target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]); comp = CompilerFactory::GetCompiler(target->GetCompilerID()); } cbProject* proj = (pf ? pf->GetParentProject() : nullptr); if ( (!comp) && proj) comp = CompilerFactory::GetCompiler(proj->GetCompilerID()); if (!comp) { cbProject* tmpPrj = Manager::Get()->GetProjectManager()->GetActiveProject(); if (tmpPrj) comp = CompilerFactory::GetCompiler(tmpPrj->GetCompilerID()); } if (!comp) comp = CompilerFactory::GetDefaultCompiler(); if (pf && (!pf->GetBuildTargets().IsEmpty()) ) { target = pf->GetParentProject()->GetBuildTarget(pf->GetBuildTargets()[0]); if (pf->GetUseCustomBuildCommand(target->GetCompilerID() )) compileCommand = pf->GetCustomBuildCommand(target->GetCompilerID()).AfterFirst(wxT(' ')); } if (compileCommand.IsEmpty()) compileCommand = wxT("$options $includes"); CompilerCommandGenerator* gen = comp->GetCommandGenerator(proj); if (gen) gen->GenerateCommandLine(compileCommand, target, pf, ed->GetFilename(), g_InvalidStr, g_InvalidStr, g_InvalidStr ); delete gen; wxStringTokenizer tokenizer(compileCommand); compileCommand.Empty(); wxString pathStr; while (tokenizer.HasMoreTokens()) { wxString flag = tokenizer.GetNextToken(); // make all include paths absolute, so clang does not choke if Code::Blocks switches directories if (flag.StartsWith(wxT("-I"), &pathStr)) { wxFileName path(pathStr); if (path.Normalize(wxPATH_NORM_ALL & ~wxPATH_NORM_CASE)) flag = wxT("-I") + path.GetFullPath(); } compileCommand += flag + wxT(" "); } compileCommand += GetCompilerInclDirs(comp->GetID()); m_UpdateCompileCommand--; if (compileCommand != m_CompileCommand) { m_CompileCommand = compileCommand; return 1; } return 0; }
void ProjectFile::SetObjName(const wxString& name) { bool extendedObjectNames = project->GetExtendedObjectNamesGeneration(); wxFileName fname(name); m_ObjName = name; FileType ft = FileTypeOf(name); if (ft == ftResource || ft == ftResourceBin) { if (extendedObjectNames) m_ObjName += FileFilters::RESOURCEBIN_DOT_EXT; else { fname.SetExt(FileFilters::RESOURCEBIN_EXT); m_ObjName = fname.GetFullPath(); } } else if (ft == ftHeader) // support precompiled headers? { Compiler* compiler = CompilerFactory::GetCompiler(project->GetCompilerID()); if (compiler && compiler->GetSwitches().supportsPCH) { // PCHs are always using the extended name mode (at least for GCC) // the extension is set to "h.gch" if (project->GetModeForPCH() == pchSourceFile) fname.Assign(relativeFilename); fname.SetExt(compiler->GetSwitches().PCHExtension); m_ObjName = fname.GetFullPath(); } } else { if (project) { Compiler* compiler = CompilerFactory::GetCompiler(project->GetCompilerID()); if (compiler) { if (extendedObjectNames) m_ObjName += _T('.') + compiler->GetSwitches().objectExtension; else { fname.SetExt(compiler->GetSwitches().objectExtension); m_ObjName = fname.GetFullPath(); } } } else { if (extendedObjectNames) m_ObjName += _T(".o"); // fallback? else { fname.SetExt(_T(".o")); m_ObjName = fname.GetFullPath(); } } } //#ifdef __WXMSW__ // // special case for windows and files on a different drive // if (name.Length() > 1 && name.GetChar(1) == _T(':')) // { // m_ObjName.Remove(1, 1); // NOTE (mandrav): why remove the colon??? // } //#endif }
void NodeTernary::accept(Compiler& c) { c.nodeTernary(*this); }
void pfDetails::Update(ProjectBuildTarget* target, ProjectFile* pf) { wxString sep = wxFILE_SEP_PATH; wxFileName tmp; wxFileName prjbase(target->GetParentProject()->GetBasePath()); wxString objOut = target ? target->GetObjectOutput() : _T("."); wxString depsOut = target ? target->GetDepsOutput() : _T("."); // we must replace any macros here early because if the macros expand // to absolute paths (like global vars usually do), we 're gonna create // invalid filenames below Manager::Get()->GetMacrosManager()->ReplaceMacros(objOut, target); Manager::Get()->GetMacrosManager()->ReplaceMacros(depsOut, target); source_file_native = pf->relativeFilename; source_file_absolute_native = pf->file.GetFullPath(); tmp = pf->GetObjName(); FileType ft = FileTypeOf(pf->relativeFilename); Compiler* compiler = target ? CompilerFactory::GetCompiler(target->GetCompilerID()) : CompilerFactory::GetDefaultCompiler(); // support for precompiled headers if (target && ft == ftHeader && compiler && compiler->GetSwitches().supportsPCH) { switch (target->GetParentProject()->GetModeForPCH()) { case pchSourceDir: { // if PCH is for a file called all.h, we create // all.h.gch/<target>_all.h.gch // (that's right: a directory) wxString new_gch = target->GetTitle() + _T('_') + pf->GetObjName(); // make sure we 're not generating subdirs size_t len = new_gch.Length(); for (size_t i = 0; i < len; ++i) { wxChar c = new_gch[i]; if (c == _T('/') || c == _T('\\') || c == _T('.')) new_gch[i] = _T('_'); } wxFileName fn(source_file_native); object_file_native = fn.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR) + fn.GetName() + _T('.') + compiler->GetSwitches().PCHExtension + wxFILE_SEP_PATH + new_gch; object_file_flat_native = object_file_native; break; } case pchObjectDir: { object_file_native = objOut + sep + tmp.GetFullPath(); object_file_flat_native = objOut + sep + tmp.GetFullName(); break; } case pchSourceFile: { object_file_native = pf->GetObjName(); object_file_flat_native = object_file_native; break; } } } else { if (pf->GetParentProject()) { wxFileName fname(pf->relativeToCommonTopLevelPath); if (pf->generatedFiles.size()) { // for files generating other files, // use the first generated file's "object name" fname.Assign(pf->generatedFiles[0]->relativeToCommonTopLevelPath); } /* NOTE: In case the source file resides in a different volume * than the volume where project file is, * then the object file will be created as follows. * * Project object output dir: C:\Foo\obj\Debug * Source: D:\Source\foo.cpp * Obj file: C:\Foo\obj\Debug\D\Source\foo.o */ wxString fileVol = fname.GetVolume(); wxString obj_file_full_path = fname.GetFullPath(); bool diffVolume = false; if (platform::windows && (!fileVol.IsEmpty() && !fileVol.IsSameAs(prjbase.GetVolume()))) { objOut += fileVol; obj_file_full_path = obj_file_full_path.AfterFirst(_T('\\')); diffVolume = true; } if (ft == ftResource || ft == ftResourceBin) { if (pf->GetParentProject()->GetExtendedObjectNamesGeneration()) { object_file_native = objOut + sep + obj_file_full_path; object_file_flat_native = objOut + sep + fname.GetFullName(); object_file_native += FileFilters::RESOURCEBIN_DOT_EXT; object_file_flat_native += FileFilters::RESOURCEBIN_DOT_EXT; } else { fname.SetExt(FileFilters::RESOURCEBIN_EXT); wxString obj_file_path = fname.GetFullPath(); if (diffVolume) obj_file_path = obj_file_path.AfterFirst(_T('\\')); object_file_native = objOut + sep + obj_file_path; object_file_flat_native = objOut + sep + fname.GetFullName(); } } else { if (pf->GetParentProject()->GetExtendedObjectNamesGeneration()) { object_file_native = objOut + sep + obj_file_full_path; object_file_flat_native = objOut + sep + fname.GetFullName(); if (compiler) { object_file_native += _T('.') + compiler->GetSwitches().objectExtension; object_file_flat_native += _T('.') + compiler->GetSwitches().objectExtension; } } else { if (compiler) fname.SetExt(compiler->GetSwitches().objectExtension); wxString obj_file_path = fname.GetFullPath(); if (diffVolume) obj_file_path = obj_file_path.AfterFirst(_T('\\')); object_file_native = objOut + sep + obj_file_path; object_file_flat_native = objOut + sep + fname.GetFullName(); } } } } wxFileName o_file(object_file_native); wxFileName o_file_flat(object_file_flat_native); o_file.MakeAbsolute(prjbase.GetFullPath()); o_file_flat.MakeAbsolute(prjbase.GetFullPath()); object_dir_native = o_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); object_dir_flat_native = o_file_flat.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); object_file_absolute_native = o_file.GetFullPath(); object_file_flat_absolute_native = o_file_flat.GetFullPath(); tmp.SetExt(_T("depend")); dep_file_native = depsOut + sep + tmp.GetFullPath(); wxFileName d_file(dep_file_native); d_file.MakeAbsolute(prjbase.GetFullPath()); dep_dir_native = d_file.GetPath(wxPATH_GET_VOLUME | wxPATH_GET_SEPARATOR); dep_file_absolute_native = o_file.GetFullPath(); source_file = UnixFilename(source_file_native); QuoteStringIfNeeded(source_file); object_file = UnixFilename(object_file_native); QuoteStringIfNeeded(object_file); object_file_flat = UnixFilename(object_file_flat_native); QuoteStringIfNeeded(object_file_flat); dep_file = UnixFilename(dep_file_native); QuoteStringIfNeeded(dep_file); object_dir = UnixFilename(object_dir_native); QuoteStringIfNeeded(object_dir); object_dir_flat = UnixFilename(object_dir_flat_native); QuoteStringIfNeeded(object_dir_flat); dep_dir = UnixFilename(dep_dir_native); QuoteStringIfNeeded(dep_dir); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_absolute_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat_absolute_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file_absolute_native); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_dir); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_dir_flat); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(dep_file); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(object_file_flat); Manager::Get()->GetMacrosManager()->ReplaceEnvVars(source_file); }
/***************************************************************************** * gsMarkPtrsAndAssignGroups * Walk a tree looking for assignment groups, variables whose value is used * in a *p store or use, and variable passed to calls. This info is then used * to determine parameters which are vulnerable. * This function carries a state to know if it is under an assign node, call node * or indirection node. It starts a new tree walk for it's subtrees when the state * changes. */ Compiler::fgWalkResult Compiler::gsMarkPtrsAndAssignGroups(GenTreePtr *pTree, fgWalkData *data) { struct MarkPtrsInfo *pState= (MarkPtrsInfo *)data->pCallbackData; struct MarkPtrsInfo newState = *pState; Compiler *comp = data->compiler; GenTreePtr tree = *pTree; ShadowParamVarInfo *shadowVarInfo = pState->comp->gsShadowVarInfo; assert(shadowVarInfo); bool fIsBlk = false; unsigned lclNum; assert(!pState->isAssignSrc || pState->lvAssignDef != (unsigned)-1); if (pState->skipNextNode) { pState->skipNextNode = false; return WALK_CONTINUE; } switch (tree->OperGet()) { // Indirections - look for *p uses and defs case GT_INITBLK: case GT_COPYOBJ: case GT_COPYBLK: fIsBlk = true; // fallthrough case GT_IND: case GT_LDOBJ: case GT_ARR_ELEM: case GT_ARR_INDEX: case GT_ARR_OFFSET: case GT_FIELD: newState.isUnderIndir = true; { if (fIsBlk) { // Blk nodes have implicit indirections. comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void *)&newState); if (tree->OperGet() == GT_INITBLK) { newState.isUnderIndir = false; } comp->fgWalkTreePre(&tree->gtOp.gtOp2, comp->gsMarkPtrsAndAssignGroups, (void *)&newState); } else { newState.skipNextNode = true; // Don't have to worry about which kind of node we're dealing with comp->fgWalkTreePre(&tree, comp->gsMarkPtrsAndAssignGroups, (void *)&newState); } } return WALK_SKIP_SUBTREES; // local vars and param uses case GT_LCL_VAR: case GT_LCL_FLD: lclNum = tree->gtLclVarCommon.gtLclNum; if (pState->isUnderIndir) { // The variable is being dereferenced for a read or a write. comp->lvaTable[lclNum].lvIsPtr = 1; } if (pState->isAssignSrc) { // // Add lvAssignDef and lclNum to a common assign group if (shadowVarInfo[pState->lvAssignDef].assignGroup) { if (shadowVarInfo[lclNum].assignGroup) { // OR both bit vector shadowVarInfo[pState->lvAssignDef].assignGroup->bitVectOr(shadowVarInfo[lclNum].assignGroup); } else { shadowVarInfo[pState->lvAssignDef].assignGroup->bitVectSet(lclNum); } // Point both to the same bit vector shadowVarInfo[lclNum].assignGroup = shadowVarInfo[pState->lvAssignDef].assignGroup; } else if (shadowVarInfo[lclNum].assignGroup) { shadowVarInfo[lclNum].assignGroup->bitVectSet(pState->lvAssignDef); // Point both to the same bit vector shadowVarInfo[pState->lvAssignDef].assignGroup = shadowVarInfo[lclNum].assignGroup; } else { FixedBitVect *bv = FixedBitVect::bitVectInit(pState->comp->lvaCount, pState->comp); // (shadowVarInfo[pState->lvAssignDef] == NULL && shadowVarInfo[lclNew] == NULL); // Neither of them has an assign group yet. Make a new one. shadowVarInfo[pState->lvAssignDef].assignGroup = bv; shadowVarInfo[lclNum].assignGroup = bv; bv->bitVectSet(pState->lvAssignDef); bv->bitVectSet(lclNum); } } return WALK_CONTINUE; // Calls - Mark arg variables case GT_CALL: newState.isUnderIndir = false; newState.isAssignSrc = false; { if (tree->gtCall.gtCallObjp) { newState.isUnderIndir = true; comp->fgWalkTreePre(&tree->gtCall.gtCallObjp, gsMarkPtrsAndAssignGroups, (void *)&newState); } for (GenTreeArgList* args = tree->gtCall.gtCallArgs; args; args = args->Rest()) { comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void *)&newState); } for (GenTreeArgList* args = tree->gtCall.gtCallLateArgs; args; args = args->Rest()) { comp->fgWalkTreePre(&args->Current(), gsMarkPtrsAndAssignGroups, (void *)&newState); } if (tree->gtCall.gtCallType == CT_INDIRECT) { newState.isUnderIndir = true; // A function pointer is treated like a write-through pointer since // it controls what code gets executed, and so indirectly can cause // a write to memory. comp->fgWalkTreePre(&tree->gtCall.gtCallAddr, gsMarkPtrsAndAssignGroups, (void *)&newState); } } return WALK_SKIP_SUBTREES; case GT_ADDR: newState.isUnderIndir = false; // We'll assume p in "**p = " can be vulnerable because by changing 'p', someone // could control where **p stores to. { comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void *)&newState); } return WALK_SKIP_SUBTREES; default: // Assignments - track assign groups and *p defs. if (tree->OperIsAssignment()) { bool isLocVar; bool isLocFld; // Walk dst side comp->fgWalkTreePre(&tree->gtOp.gtOp1, comp->gsMarkPtrsAndAssignGroups, (void *)&newState); // Now handle src side isLocVar = tree->gtOp.gtOp1->OperGet() == GT_LCL_VAR; isLocFld = tree->gtOp.gtOp1->OperGet() == GT_LCL_FLD; if ((isLocVar || isLocFld) && tree->gtOp.gtOp2) { lclNum = tree->gtOp.gtOp1->gtLclVarCommon.gtLclNum; newState.lvAssignDef = lclNum; newState.isAssignSrc = true; } comp->fgWalkTreePre(&tree->gtOp.gtOp2, comp->gsMarkPtrsAndAssignGroups, (void *)&newState); return WALK_SKIP_SUBTREES; } } return WALK_CONTINUE; }
std::shared_ptr<Operand> PredicateParser::createPrimitive(const std::string& fullExpression, size_t from, size_t to) { from = skipSpace(fullExpression, from, to); while(to > from && std::isspace(fullExpression.at(to - 1))) { --to; } if(from >= to) { return nullptr; } char c = fullExpression.at(from); switch(c) { case '"': { auto last = skipString(fullExpression, from + 1, to); auto str = fullExpression.substr(from + 1, last - from - 1); if(last == to) { throw std::logic_error(str + " not a string"); } return std::make_shared<StringOperand>(str); } case '^': case '.': { Compiler subCompiler; auto subExpression = subCompiler.compile(fullExpression, from, to); return std::make_shared<LocationOperand>(subExpression); } case '{': case '[': { std::stack<char> unmatched; unmatched.push(c); auto last = skip2MatchParenthesis(unmatched, fullExpression, from + 1, to); auto str = fullExpression.substr(from, last - from + 1); if(last == to) { throw std::logic_error(str + " not a json"); } json value = json::parse(str); return std::make_shared<JsonOperand>(value); } case '/': { auto toPos = skip2(fullExpression, from + 1, '/', to); auto regex = fullExpression.substr(from + 1, toPos - from - 1); return std::make_shared<RegexOperand>(regex); } case '$': { auto variableName = fullExpression.substr(from + 1, to - from - 1); return std::make_shared<VariableOperand>(variableName); } default: if(isBool(fullExpression, from, to) && '0' != fullExpression.at(from) && '1' != fullExpression.at(from)) { bool v = convert2Bool(fullExpression, from, to); return std::make_shared<BoolOperand>(v); } else if(isInt(fullExpression, from, to)) { int v = convert2Int(fullExpression, from, to); return std::make_shared<IntOperand>(v); } else if(isReal(fullExpression, from, to)) { double v = convert2Real(fullExpression, from, to); return std::make_shared<RealOperand>(v); } else { throw std::logic_error(fullExpression.substr(from, to - from) + " can't be interpreted as an operand"); } } }
void NodeBody::accept(Compiler& c) { c.nodeBody(*this); }
void AsebaNetworkInterface::LoadScripts(const QString& fileName, const QDBusMessage &message) { QFile file(fileName); if (!file.open(QFile::ReadOnly)) { DBusConnectionBus().send(message.createErrorReply(QDBusError::InvalidArgs, QString("file %0 does not exists").arg(fileName))); return; } QDomDocument document("aesl-source"); QString errorMsg; int errorLine; int errorColumn; if (!document.setContent(&file, false, &errorMsg, &errorLine, &errorColumn)) { DBusConnectionBus().send(message.createErrorReply(QDBusError::Other, QString("Error in XML source file: %0 at line %1, column %2").arg(errorMsg).arg(errorLine).arg(errorColumn))); return; } commonDefinitions.events.clear(); commonDefinitions.constants.clear(); userDefinedVariablesMap.clear(); int noNodeCount = 0; QDomNode domNode = document.documentElement().firstChild(); // FIXME: this code depends on event and contants being before any code bool wasError = false; while (!domNode.isNull()) { if (domNode.isElement()) { QDomElement element = domNode.toElement(); if (element.tagName() == "node") { bool ok; const unsigned nodeId(getNodeId(element.attribute("name").toStdWString(), element.attribute("nodeId", 0).toUInt(), &ok)); if (ok) { std::wistringstream is(element.firstChild().toText().data().toStdWString()); Error error; BytecodeVector bytecode; unsigned allocatedVariablesCount; Compiler compiler; compiler.setTargetDescription(getDescription(nodeId)); compiler.setCommonDefinitions(&commonDefinitions); bool result = compiler.compile(is, bytecode, allocatedVariablesCount, error); if (result) { typedef std::vector<Message*> MessageVector; MessageVector messages; sendBytecode(messages, nodeId, std::vector<uint16>(bytecode.begin(), bytecode.end())); for (MessageVector::const_iterator it = messages.begin(); it != messages.end(); ++it) { hub->sendMessage(*it); delete *it; } Run msg(nodeId); hub->sendMessage(msg); } else { DBusConnectionBus().send(message.createErrorReply(QDBusError::Failed, QString::fromStdWString(error.toWString()))); wasError = true; break; } // retrieve user-defined variables for use in get/set userDefinedVariablesMap[element.attribute("name")] = *compiler.getVariablesMap(); } else noNodeCount++; } else if (element.tagName() == "event") { const QString eventName(element.attribute("name")); const unsigned eventSize(element.attribute("size").toUInt()); if (eventSize > ASEBA_MAX_EVENT_ARG_SIZE) { DBusConnectionBus().send(message.createErrorReply(QDBusError::Failed, QString("Event %1 has a length %2 larger than maximum %3").arg(eventName).arg(eventSize).arg(ASEBA_MAX_EVENT_ARG_SIZE))); wasError = true; break; } else { commonDefinitions.events.push_back(NamedValue(eventName.toStdWString(), eventSize)); } } else if (element.tagName() == "constant") { commonDefinitions.constants.push_back(NamedValue(element.attribute("name").toStdWString(), element.attribute("value").toInt())); } } domNode = domNode.nextSibling(); } // check if there was an error if (wasError) { std::wcerr << QString("There was an error while loading script %1").arg(fileName).toStdWString() << std::endl; commonDefinitions.events.clear(); commonDefinitions.constants.clear(); userDefinedVariablesMap.clear(); } // check if there was some matching problem if (noNodeCount) { std::wcerr << QString("%0 scripts have no corresponding nodes in the current network and have not been loaded.").arg(noNodeCount).toStdWString() << std::endl; } }
jit_value_t Break::compile_jit(Compiler& c, jit_function_t& F, Type) const { jit_insn_branch(F, c.get_current_loop_end_label()); return JIT_CREATE_CONST_POINTER(F, LSNull::null_var); }
bool AstMember::emit_lvalue(Compiler& c) const { if (node->emit(c)) return true; c.push_inst(Instruction::make_get(name.c_str(), Instruction::GET_MEMBER_REF)); return false; }
int main(int, char**) { Compiler c; FileLogger logger(stderr); c.setLogger(&logger); c.newFunction(CALL_CONV_DEFAULT, FunctionBuilder0<Void>()); Label L_A = c.newLabel(); Label L_B = c.newLabel(); Label L_C = c.newLabel(); c.jmp(L_B); c.bind(L_A); c.jmp(L_C); c.bind(L_B); c.jmp(L_A); c.bind(L_C); c.ret(); c.endFunction(); VoidFn fn = function_cast<VoidFn>(c.make()); // Ensure that everything is ok. if (!fn) { printf("Error making jit function (%u).\n", c.getError()); return 1; } // Free the JIT function if it's not needed anymore. MemoryManager::getGlobal()->free((void*)fn); return 0; }
bool AstAssign::emit(Compiler& c) const { if (src->emit(c)) return true; if (dst->emit_lvalue(c)) return true; c.push_inst(Instruction::make_set()); return false; }