void CompilerCommandLineParser::AddIncludesFromFile(const wxFileName& includeFile)
{
    wxFFile fp( includeFile.GetFullPath(), "rb" );
    if ( fp.IsOpened() ) {
        wxString content;
        fp.ReadAll( &content );
        content.Replace("\n", " ");
        CompilerCommandLineParser cclp( content );
        m_includes.insert(m_includes.end(), cclp.GetIncludes().begin(), cclp.GetIncludes().end());
        m_includesWithPrefix.insert(m_includesWithPrefix.end(), cclp.GetIncludesWithPrefix().begin(), cclp.GetIncludesWithPrefix().end());
        fp.Close();
    }
}
bool CodeCompletionManager::GetDefinitionsAndSearchPaths(clEditor* editor, wxArrayString& searchPaths,
                                                         wxArrayString& definitions)
{
    // Sanity
    CHECK_PTR_RET_FALSE(editor);

    if(editor->GetProjectName().IsEmpty()) return false;
    if(!clCxxWorkspaceST::Get()->IsOpen()) return false;

    // Support only C/C++ files
    if(!FileExtManager::IsCxxFile(editor->GetFileName().GetFullName())) return false;

    // Get the file's project and get the build configuration settings
    // for it
    ProjectPtr proj = clCxxWorkspaceST::Get()->GetProject(editor->GetProjectName());
    CHECK_PTR_RET_FALSE(proj);

    BuildConfigPtr buildConf = proj->GetBuildConfiguration();
    CHECK_PTR_RET_FALSE(buildConf);

    CompilerPtr compiler = buildConf->GetCompiler();
    CHECK_PTR_RET_FALSE(compiler);

#if 0
    if(buildConf->IsCustomBuild()) {
        definitions = proj->GetPreProcessors();
        CL_DEBUG("CxxPreProcessor will use the following macros:");
        CL_DEBUG_ARR(definitions);
        // Custom builds are handled differently
        CompilationDatabase compileDb;
        compileDb.Open();
        if(compileDb.IsOpened()) {
            // we have compilation database for this workspace
            wxString compileLine, cwd;
            compileDb.CompilationLine(editor->GetFileName().GetFullPath(), compileLine, cwd);

            CL_DEBUG("Pre Processor dimming: %s\n", compileLine);
            CompilerCommandLineParser cclp(compileLine, cwd);
            searchPaths = cclp.GetIncludes();

            // get the mcros
            definitions << cclp.GetMacros();
        }
    }
#endif
    // get the include paths based on the project settings (this is per build configuration)
    searchPaths = proj->GetIncludePaths();
    CL_DEBUG("CxxPreProcessor will use the following include paths:");
    CL_DEBUG_ARR(searchPaths);

    // get the compiler include paths
    // wxArrayString compileIncludePaths = compiler->GetDefaultIncludePaths();

    // includePaths.insert(includePaths.end(), compileIncludePaths.begin(), compileIncludePaths.end());
    definitions = proj->GetPreProcessors();

    // get macros out of workspace
    wxString strWorkspaceMacros = clCxxWorkspaceST::Get()->GetParserMacros();
    wxArrayString workspaceMacros = wxStringTokenize(strWorkspaceMacros, wxT("\n\r"), wxTOKEN_STRTOK);
    for(size_t i = 0; i < workspaceMacros.GetCount(); i++)
        definitions.Add(workspaceMacros.Item(i).Trim().Trim(false).c_str());

    CL_DEBUG("CxxPreProcessor will use the following macros:");
    CL_DEBUG_ARR(definitions);

    // Append the compiler builtin macros
    wxArrayString builtinMacros = compiler->GetBuiltinMacros();
    definitions.insert(definitions.end(), builtinMacros.begin(), builtinMacros.end());

    return true;
}
bool CodeCompletionManager::GetDefinitionsAndSearchPaths(LEditor* editor,
                                                         wxArrayString& searchPaths,
                                                         wxArrayString& definitions)
{
    // Sanity
    CHECK_PTR_RET_FALSE(editor);

    if(editor->GetProjectName().IsEmpty())
        return false;
    if(!WorkspaceST::Get()->IsOpen())
        return false;

    // Support only C/C++ files
    if(!FileExtManager::IsCxxFile(editor->GetFileName().GetFullName()))
        return false;

    // Get the file's project and get the build configuration settings
    // for it
    ProjectPtr proj = WorkspaceST::Get()->GetProject(editor->GetProjectName());
    CHECK_PTR_RET_FALSE(proj);

    BuildConfigPtr buildConf = proj->GetBuildConfiguration();
    CHECK_PTR_RET_FALSE(buildConf);

    CompilerPtr compiler = buildConf->GetCompiler();
    CHECK_PTR_RET_FALSE(compiler);

    if(buildConf->IsCustomBuild()) {
        // Custom builds are handled differently
        CompilationDatabase compileDb;
        compileDb.Open();
        if(compileDb.IsOpened()) {
            // we have compilation database for this workspace
            wxString compileLine, cwd;
            compileDb.CompilationLine(editor->GetFileName().GetFullPath(), compileLine, cwd);

            CL_DEBUG("Pre Processor dimming: %s\n", compileLine);
            CompilerCommandLineParser cclp(compileLine, cwd);
            searchPaths = cclp.GetIncludes();

            // get the mcros
            definitions = cclp.GetMacros();
        } else {
            // we will probably will fail...
            return false;
        }
    } else {
        // get the include paths based on the project settings (this is per build configuration)
        searchPaths = proj->GetIncludePaths();
        CL_DEBUG("CxxPreProcessor will use the following include paths:");
        CL_DEBUG_ARR(searchPaths);

        // get the compiler include paths
        // wxArrayString compileIncludePaths = compiler->GetDefaultIncludePaths();

        // includePaths.insert(includePaths.end(), compileIncludePaths.begin(), compileIncludePaths.end());
        definitions = proj->GetPreProcessors();
        CL_DEBUG("CxxPreProcessor will use the following macros:");
        CL_DEBUG_ARR(definitions);
    }

    // Append the compiler builtin macros
    wxArrayString builtinMacros = compiler->GetBuiltinMacros();
    definitions.insert(definitions.end(), builtinMacros.begin(), builtinMacros.end());

    return true;
}
Esempio n. 4
0
FileTypeCmpArgs_t ClangDriver::DoPrepareCompilationArgs(const wxString& projectName,
                                                        const wxString& sourceFile,
                                                        wxString& projectPath,
                                                        wxString& pchfile)
{
    FileTypeCmpArgs_t cmpArgs;

    cmpArgs.insert(std::make_pair(FileExtManager::TypeSourceC, wxArrayString()));
    cmpArgs.insert(std::make_pair(FileExtManager::TypeSourceCpp, wxArrayString()));

    wxArrayString args;
    wxString errMsg;

    wxArrayString& cppCompileArgs = cmpArgs[FileExtManager::TypeSourceCpp];
    wxArrayString& cCompileArgs = cmpArgs[FileExtManager::TypeSourceC];

    // Build the TU file name
    wxFileName fnSourceFile(sourceFile);
    pchfile << WorkspaceST::Get()->GetWorkspaceFileName().GetPath() << wxFileName::GetPathSeparator() << wxT(".clang");

    {
        wxLogNull nl;
        wxMkdir(pchfile);
    }

    pchfile << wxFileName::GetPathSeparator() << fnSourceFile.GetFullName() << wxT(".TU");

    CompilationDatabase cdb;
    static bool once = false;
    if(!cdb.IsOk() && !once) {
        once = true;

        wxString msg;
        msg << _("Could not locate compilation database or database version is not up-to-date: ")
            << cdb.GetFileName().GetFullPath() << wxT("\n\n")
            << _("This file should be created automatically for you.\nIf you don't have it, please run a full rebuild "
                 "of your workspace\n\n")
            << _("If this is a custom build project (i.e. project that uses a custom makefile),\nplease set the CXX "
                 "and CC environment variables like this:\n") << _("CXX=codelite-cc g++\n")
            << _("CC=codelite-cc gcc\n\n");

        clMainFrame::Get()->GetMainBook()->ShowMessage(
            msg,
            true,
            PluginManager::Get()->GetStdIcons()->LoadBitmap(wxT("messages/48/tip")),
            ButtonDetails(),
            ButtonDetails(),
            ButtonDetails(),
            CheckboxDetails(wxT("CodeCompletionMissingCompilationDB")));

    } else {
        cdb.Open();
        if(cdb.IsOpened()) {
            CL_DEBUG(wxT("Loading compilation flags for file: %s"), fnSourceFile.GetFullPath().c_str());
            wxString compilationLine, cwd;
            cdb.CompilationLine(fnSourceFile.GetFullPath(), compilationLine, cwd);
            cdb.Close();

            CompilerCommandLineParser cclp(compilationLine, cwd);
            cclp.MakeAbsolute(cwd);

            CL_DEBUG(wxT("Loaded compilation flags: %s"), compilationLine.c_str());
            args.insert(args.end(), cclp.GetIncludesWithPrefix().begin(), cclp.GetIncludesWithPrefix().end());
            args.insert(args.end(), cclp.GetMacrosWithPrefix().begin(), cclp.GetMacrosWithPrefix().end());
            args.Add(cclp.GetStandardWithPrefix());
        }
    }

    const TagsOptionsData& options = TagsManagerST::Get()->GetCtagsOptions();

    ///////////////////////////////////////////////////////////////////////
    // add global clang include paths
    wxString strGlobalIncludes = options.GetClangSearchPaths();

    // expand any macros from the include paths
    strGlobalIncludes = MacroManager::Instance()->Expand(strGlobalIncludes, PluginManager::Get(), projectName);

    wxArrayString globalIncludes = wxStringTokenize(strGlobalIncludes, wxT("\n\r"), wxTOKEN_STRTOK);
    for(size_t i = 0; i < globalIncludes.GetCount(); i++) {
        wxFileName fn(globalIncludes.Item(i).Trim().Trim(false), wxT(""));
        fn.MakeAbsolute(projectPath);

        cppCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str()));
        cCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str()));
    }

    ///////////////////////////////////////////////////////////////////////
    // Workspace setting additional flags
    ///////////////////////////////////////////////////////////////////////

    // Include paths
    wxArrayString workspaceIncls, dummy;
    LocalWorkspaceST::Get()->GetParserPaths(workspaceIncls, dummy);
    for(size_t i = 0; i < workspaceIncls.GetCount(); i++) {
        wxFileName fn(workspaceIncls.Item(i).Trim().Trim(false), wxT(""));
        fn.MakeAbsolute(WorkspaceST::Get()->GetWorkspaceFileName().GetPath());
        cppCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str()));
        cCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str()));
    }

    // Macros
    wxString strWorkspaceMacros;
    LocalWorkspaceST::Get()->GetParserMacros(strWorkspaceMacros);
    wxArrayString workspaceMacros = wxStringTokenize(strWorkspaceMacros, wxT("\n\r"), wxTOKEN_STRTOK);
    for(size_t i = 0; i < workspaceMacros.GetCount(); i++) {
        cppCompileArgs.Add(wxString::Format(wxT("-D%s"), workspaceMacros.Item(i).Trim().Trim(false).c_str()));
        cCompileArgs.Add(wxString::Format(wxT("-D%s"), workspaceMacros.Item(i).Trim().Trim(false).c_str()));
    }

    // C++ 11 / 14
    size_t workspaceFlags = LocalWorkspaceST::Get()->GetParserFlags();
    if(workspaceFlags & LocalWorkspace::EnableCpp11) {
        cppCompileArgs.Add(wxT("-std=c++11"));
        cCompileArgs.Add(wxT("-std=c++11"));
    }
    if(workspaceFlags & LocalWorkspace::EnableCpp14) {
        cppCompileArgs.Add(wxT("-std=c++14"));
        cCompileArgs.Add(wxT("-std=c++14"));
    }

    ///////////////////////////////////////////////////////////////////////
    // Project setting additional flags
    ///////////////////////////////////////////////////////////////////////

    BuildConfigPtr buildConf = ManagerST::Get()->GetCurrentBuildConf();
    if(buildConf) {
        wxString projSearchPaths = buildConf->GetCcSearchPaths();
        wxArrayString projectIncludePaths = wxStringTokenize(projSearchPaths, wxT("\r\n"), wxTOKEN_STRTOK);
        for(size_t i = 0; i < projectIncludePaths.GetCount(); i++) {
            wxFileName fn(MacroManager::Instance()
                              ->Expand(projectIncludePaths.Item(i),
                                       PluginManager::Get(),
                                       ManagerST::Get()->GetActiveProjectName()),
                          wxT(""));
            fn.MakeAbsolute(WorkspaceST::Get()->GetWorkspaceFileName().GetPath());
            cppCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str()));
            cCompileArgs.Add(wxString::Format(wxT("-I%s"), fn.GetPath().c_str()));
        }

        wxString strProjectMacros = buildConf->GetClangPPFlags();
        wxArrayString projectMacros = wxStringTokenize(strProjectMacros, wxT("\n\r"), wxTOKEN_STRTOK);
        for(size_t i = 0; i < projectMacros.GetCount(); i++) {
            cppCompileArgs.Add(wxString::Format(wxT("-D%s"), projectMacros.Item(i).Trim().Trim(false).c_str()));
            cCompileArgs.Add(wxString::Format(wxT("-D%s"), projectMacros.Item(i).Trim().Trim(false).c_str()));
        }

        if(buildConf->IsClangC11()) {
            cppCompileArgs.Add(wxT("-std=c++11"));
            cCompileArgs.Add(wxT("-std=c++11"));
        }
        if(buildConf->IsClangC14()) {
            cppCompileArgs.Add(wxT("-std=c++14"));
            cCompileArgs.Add(wxT("-std=c++14"));
        }
    }

    cppCompileArgs.insert(cppCompileArgs.end(), args.begin(), args.end());
    cCompileArgs.insert(cCompileArgs.end(), args.begin(), args.end());

    // Remove some of the flags which are known to cause problems to clang
    int where = wxNOT_FOUND;

    where = cppCompileArgs.Index(wxT("-fno-strict-aliasing"));
    if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where);

    where = cppCompileArgs.Index(wxT("-mthreads"));
    if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where);

    where = cppCompileArgs.Index(wxT("-pipe"));
    if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where);

    where = cppCompileArgs.Index(wxT("-fmessage-length=0"));
    if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where);

    where = cppCompileArgs.Index(wxT("-fPIC"));
    if(where != wxNOT_FOUND) cppCompileArgs.RemoveAt(where);

    // Now do the same for the "C" arguments
    where = cCompileArgs.Index(wxT("-fno-strict-aliasing"));
    if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where);

    where = cCompileArgs.Index(wxT("-mthreads"));
    if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where);

    where = cCompileArgs.Index(wxT("-pipe"));
    if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where);

    where = cCompileArgs.Index(wxT("-fmessage-length=0"));
    if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where);

    where = cCompileArgs.Index(wxT("-fPIC"));
    if(where != wxNOT_FOUND) cCompileArgs.RemoveAt(where);

    return cmpArgs;
}