diff --git a/uppsrc/ide/Assist.cpp b/uppsrc/ide/Assist.cpp index 5d5e4fe66..708da0805 100644 --- a/uppsrc/ide/Assist.cpp +++ b/uppsrc/ide/Assist.cpp @@ -327,7 +327,7 @@ Vector AssistEditor::ReadBack(int q, const Index& locals) void AssistEditor::SyncAssist() { LTIMING("SyncAssist"); - bool destructor; + bool destructor; // TODO: remove String name = ReadIdBack(GetCursor32(), include_assist, &destructor); String uname = ToUpper(name); assist_item_ndx.Clear(); @@ -447,15 +447,8 @@ CurrentFileContext AssistEditor::CurrentContext(int& line_delta) { CurrentFileContext cfx; cfx.filename = cfx.real_filename = NormalizePath(theide->editfile); - -// TODO: Fix this properly -#ifdef PLATFORM_WIN32 - cfx.includes = theide->GetIncludePath(); -#else - VectorMap bm = GetMethodVars(theide->method); - cfx.includes = Join(GetUppDirs(), ";") + ';' + bm.Get("INCLUDE", ""); -#endif - + cfx.includes = theide->GetCurrentIncludePath(); + cfx.defines = theide->GetCurrentDefines(); line_delta = 0; if(!IsView() && GetLength() < 200000) { cfx.content = Get(); @@ -761,8 +754,6 @@ void AssistEditor::AssistInsert() } else { String txt = f.name; - int l = txt.GetCount(); - int pl = txt.GetCount(); int param_count; ParseSignature(f.name, f.signature, ¶m_count); if(param_count >= 0) @@ -782,14 +773,6 @@ void AssistEditor::AssistInsert() SetCursor(GetCursor32() - 1); StartParamInfo(f, cl); } - else - if(!inbody) - SetCursor(cl + n); - else - if(pl > l) - SetSelection(cl + l, cl + pl); - else - SetCursor(cl + l); } } CloseAssist(); diff --git a/uppsrc/ide/Core/Host.cpp b/uppsrc/ide/Core/Host.cpp index 3f3c1000c..d199ec6a8 100644 --- a/uppsrc/ide/Core/Host.cpp +++ b/uppsrc/ide/Core/Host.cpp @@ -307,11 +307,8 @@ void Host::Launch(const char *_cmdline, bool console) #endif } -void Host::AddFlags(Index& cfg) +void AddHostFlags(Index& cfg) { - if(HasPlatformFlag(cfg)) - return; - #if defined(PLATFORM_WIN32) cfg.Add("WIN32"); #endif @@ -361,6 +358,13 @@ void Host::AddFlags(Index& cfg) #endif } +void Host::AddFlags(Index& cfg) +{ + if(HasPlatformFlag(cfg)) + return; + AddHostFlags(cfg); +} + const Vector& Host::GetExecutablesDirs() const { return exedirs; diff --git a/uppsrc/ide/Core/Host.h b/uppsrc/ide/Core/Host.h index e7ed783ed..3c6a692c2 100644 --- a/uppsrc/ide/Core/Host.h +++ b/uppsrc/ide/Core/Host.h @@ -2,6 +2,8 @@ enum { REMOTE_TIMEOUT = 2000 }; extern String HostConsole; +void AddHostFlags(Index& cfg); + struct Host { struct FileInfo : Time, Moveable { int length; diff --git a/uppsrc/ide/Methods.cpp b/uppsrc/ide/Methods.cpp index c9c80aff3..511baa1af 100644 --- a/uppsrc/ide/Methods.cpp +++ b/uppsrc/ide/Methods.cpp @@ -796,7 +796,7 @@ void ExtractIncludes(Index& r, String h) } String Ide::GetIncludePath() -{ +{ // TODO: remove if(include_path.GetCount()) return include_path; SetupDefaultMethod(); @@ -853,6 +853,7 @@ String Ide::GetIncludePath() } } +// TODO: replicate with clang const Workspace& wspc = GetIdeWorkspace(); Host dummy_host; One b = CreateBuilder(&dummy_host); @@ -875,6 +876,50 @@ String Ide::GetIncludePath() return include_path; } +String Ide::GetCurrentIncludePath() +{ + String include_path; + VectorMap bm = GetMethodVars(method); + include_path = Join(GetUppDirs(), ";") + ';' + bm.Get("INCLUDE", ""); + + const Workspace& wspc = GetIdeWorkspace(); + Host dummy_host; + One b = CreateBuilder(&dummy_host); + Index pkg_config; + for(int i = 0; i < wspc.GetCount(); i++) { + const Package& pkg = wspc.GetPackage(i); + for(int j = 0; j < pkg.include.GetCount(); j++) + MergeWith(include_path, ";", SourcePath(wspc[i], pkg.include[j].text)); + for(String h : Split(Gather(pkg.pkg_config, b->config.GetKeys()), ' ')) + pkg_config.FindAdd(h); + } + + static VectorMap cflags; + for(String s : pkg_config) { + int q = cflags.Find(s); + if(q < 0) { + q = cflags.GetCount(); + cflags.Add(s, Sys("pkg-config --cflags " + s)); + } + for(String p : Split(cflags[q], ' ')) + if(p.TrimStart("-I")) + MergeWith(include_path, ";", p); + } + + return include_path; +} + +String Ide::GetCurrentDefines() +{ + Index flags; + flags = SplitFlags(mainconfigparam, false); // TODO: MAIN + AddHostFlags(flags); + String r; + for(String s : flags) + MergeWith(r, ";", "flag" + s); + return r; +} + String Ide::IdeGetIncludePath() { return GetIncludePath(); diff --git a/uppsrc/ide/clang/AutoComplete.cpp b/uppsrc/ide/clang/AutoComplete.cpp index ef2c6e3e0..a039d0295 100644 --- a/uppsrc/ide/clang/AutoComplete.cpp +++ b/uppsrc/ide/clang/AutoComplete.cpp @@ -57,17 +57,17 @@ void AutocompleteThread() String fn = f.filename; if(!IsSourceFile(fn)) fn.Cat(".cpp"); - if(f.filename != parsed_file.filename || f.includes != parsed_file.includes || - f.real_filename != parsed_file.real_filename || !clang.tu) { + if(f.filename != parsed_file.filename || f.real_filename != parsed_file.real_filename || + f.includes != parsed_file.includes || f.defines != parsed_file.defines || + !clang.tu) { parsed_file = f; clang.Dispose(); TIMESTOP("Autocomplete parse"); - clang.Parse(fn, f.content, f.includes, String(), + clang.Parse(fn, f.content, f.includes, f.defines, CXTranslationUnit_DetailedPreprocessingRecord| CXTranslationUnit_PrecompiledPreamble| CXTranslationUnit_CreatePreambleOnFirstParse| - CXTranslationUnit_KeepGoing| - CXTranslationUnit_RetainExcludedConditionalBlocks); + CXTranslationUnit_KeepGoing); } if(Thread::IsShutdownThreads()) break; diff --git a/uppsrc/ide/clang/CurrentFile.cpp b/uppsrc/ide/clang/CurrentFile.cpp index 7b4edc068..95c33eaa8 100644 --- a/uppsrc/ide/clang/CurrentFile.cpp +++ b/uppsrc/ide/clang/CurrentFile.cpp @@ -35,6 +35,7 @@ void CurrentFileThread() if(!clang.tu || !annotations_done) return; CurrentFileVisitor v; v.Do(clang.tu); + // DumpDiagnostics(clang.tu); Ctrl::Call([&] { if(parsed_file.filename == current_file.filename && parsed_file.real_filename == current_file.real_filename && @@ -58,21 +59,20 @@ void CurrentFileThread() String fn = f.filename; if(!IsSourceFile(fn)) fn.Cat(".cpp"); - if(f.filename != parsed_file.filename || f.includes != parsed_file.includes || - f.real_filename != parsed_file.real_filename || !clang.tu) { + if(f.filename != parsed_file.filename || f.real_filename != parsed_file.real_filename || + f.includes != parsed_file.includes || f.defines != parsed_file.defines || + !clang.tu) { // TODO: same is in autocomplete parsed_file = f; clang.Dispose(); { TIMESTOP("CurrentFile parse"); - clang.Parse(fn, f.content, f.includes, String(), + clang.Parse(fn, f.content, f.includes, f.defines, CXTranslationUnit_DetailedPreprocessingRecord| CXTranslationUnit_PrecompiledPreamble| CXTranslationUnit_CreatePreambleOnFirstParse| - CXTranslationUnit_KeepGoing| - CXTranslationUnit_RetainExcludedConditionalBlocks); + CXTranslationUnit_KeepGoing); } DoAnnotations(); - // DumpDiagnostics(tu); } if(Thread::IsShutdownThreads()) break; if(clang.tu && serial != done_serial) { diff --git a/uppsrc/ide/clang/clang.cpp b/uppsrc/ide/clang/clang.cpp index 1e8d55417..b9b14d545 100644 --- a/uppsrc/ide/clang/clang.cpp +++ b/uppsrc/ide/clang/clang.cpp @@ -29,6 +29,27 @@ String SourceLocation::ToString() const return String() << filename << " (" << line << ":" << column << ")"; } +#ifdef PLATFORM_WIN32 +String GetClangInternalIncludes() +{ + static String includes; + ONCELOCK { + String dummy = ConfigFile("dummy.cpp"); + Upp::SaveFile(dummy, String()); + String h = Sys(GetExeDirFile("bin/clang/bin/c++") + " -v -x c++ -E " + dummy); + DeleteFile(dummy); + h.Replace("\r", ""); + Vector ln = Split(h, '\n'); + for(int i = 0; i < ln.GetCount(); i++) { + String dir = TrimBoth(ln[i]); + if(DirectoryExists(dir)) + MergeWith(includes, ";", NormalizePath(dir)); + } + } + return includes; +} +#endif + SourceLocation::SourceLocation(CXSourceLocation location) { CXFile file; @@ -48,7 +69,7 @@ void Clang::Dispose() tu = nullptr; } -bool Clang::Parse(const String& filename, const String& content, const String& includes, const String& defines, dword options) +bool Clang::Parse(const String& filename, const String& content, const String& includes_, const String& defines, dword options) { if(!index) return false; @@ -57,11 +78,16 @@ bool Clang::Parse(const String& filename, const String& content, const String& i cmdline << filename << " -DflagDEBUG -DflagDEBUG_FULL -DflagBLITZ -DflagWIN32 -DflagMAIN -DflagGUI -xc++ -std=c++17 "; cmdline << RedefineMacros(); + String includes = includes_; +#ifdef PLATFORM_WIN32 + MergeWith(includes, ";", GetClangInternalIncludes()); +#endif + Vector args; for(const String& s : Split(includes, ';')) args.Add("-I" + s); - for(const String& s : Split(defines, ';')) + for(const String& s : Split(defines + ";CLANG", ';')) args.Add("-D" + s); args.Append(Split(cmdline, ' ')); diff --git a/uppsrc/ide/clang/clang.h b/uppsrc/ide/clang/clang.h index 23b958b7f..f3f55585a 100644 --- a/uppsrc/ide/clang/clang.h +++ b/uppsrc/ide/clang/clang.h @@ -87,6 +87,7 @@ struct CurrentFileContext { String filename; String real_filename; String includes; + String defines; String content; }; diff --git a/uppsrc/ide/clang/macros.cpp b/uppsrc/ide/clang/macros.cpp index a008b7a27..c304ba1dc 100644 --- a/uppsrc/ide/clang/macros.cpp +++ b/uppsrc/ide/clang/macros.cpp @@ -1,5 +1,8 @@ #include "clang.h" +// we are (for now?) using libclang.dll for MSVC and therefore need to redefine standard macros +// to mingw clang + const char umacros[] = R"(#define CHECK_GRID(g) #define CHECK_MATRIX(g) diff --git a/uppsrc/ide/ide.h b/uppsrc/ide/ide.h index 35ae3a25a..cc2c99552 100644 --- a/uppsrc/ide/ide.h +++ b/uppsrc/ide/ide.h @@ -1162,6 +1162,8 @@ public: void ShowTopicsWin(); String GetIncludePath(); + String GetCurrentIncludePath(); + String GetCurrentDefines(); void TopicBack(); diff --git a/uppsrc/ide/main.cpp b/uppsrc/ide/main.cpp index 825d24fba..04af09f42 100644 --- a/uppsrc/ide/main.cpp +++ b/uppsrc/ide/main.cpp @@ -116,6 +116,8 @@ void StartEditorMode(const Vector& args, Ide& ide, bool& clset) return Upp::GetExitCode(); \ } +String GetClangInternalIncludes(); + #ifdef flagMAIN GUI_APP_MAIN #else