abingham / emacs-ycmd

Emacs client for ycmd, the code completion system.
MIT License
384 stars 46 forks source link

Maximum number of diagnostics exceeded. #472

Closed jvillasante closed 6 years ago

jvillasante commented 6 years ago

I keep getting this warning on a compilation unit that otherwise compiles without warnings. Don't know if this is the right place to ask but is there something that I don't know about this warning?

I'm using defaults with .ycm_extra_conf.py from ycmd.

Here's my debug info:

Ycmd debug information for buffer main.cpp in c++-mode:

((python
  (executable . "/usr/local/opt/python@2/bin/python2.7")
  (version . "2.7.15"))
 (completer
  (items
   ((value . "None")
    (key . "compilation database path"))
   ((value . "[u'-std=c++17', u'-x', u'c++', u'-stdlib=libc++', u'-Wall', u'-Wextra', u'-pedantic', u'-DDEBUG', u'-Wno-gnu-case-range', u'-isystem', u'/usr/local/opt/llvm/include', u'-isystem', u'/usr/local/opt/llvm/include/c++/v1', u'-I', u'/Users/jvillasante/Downloads/test_cpp', u'-resource-dir=/Users/jvillasante/Hacking/software/ycmd/ycmd/../clang_includes', u'-isystem', u'/Library/Developer/CommandLineTools/usr/include/c++/v1', u'-isystem', u'/usr/local/include', u'-isystem', u'/Library/Developer/CommandLineTools/usr/include', u'-isystem', u'/usr/include', u'-isystem', u'/System/Library/Frameworks', u'-isystem', u'/Library/Frameworks', u'-isystem', u'/Library/Developer/CommandLineTools/usr/lib/clang/9.1.0/include', u'-isystem', u'/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include', u'-fspell-checking']")
    (key . "flags"))
   ((value . "/Users/jvillasante/Downloads/test_cpp/src/main.cpp")
    (key . "translation unit")))
  (name . "C-family")
  (servers))
 (extra_conf
  (path . "/Users/jvillasante/Downloads/test_cpp/.ycm_extra_conf.py")
  (is_loaded . t))
 (clang
  (has_support . t)
  (version . "clang version 6.0.0 (tags/RELEASE_600/final)")))

Server is running at: 127.0.0.1:49558

Ycmd Mode is enabled

--------------------

Ycmd version:   1.3snapshot (package: 20180520.353)
Emacs version:  26.1
System:         x86_64-apple-darwin17.6.0
Window system:  mac

Also, there are some flags that I'm not setting myself, does ycmd does this by itself? All of this flags are not added by me:

u'-resource-dir=/Users/jvillasante/Hacking/software/ycmd/ycmd/../clang_includes', u'-isystem', u'/Library/Developer/CommandLineTools/usr/include/c++/v1', u'-isystem', u'/usr/local/include', u'-isystem', u'/Library/Developer/CommandLineTools/usr/include', u'-isystem', u'/usr/include', u'-isystem', u'/System/Library/Frameworks', u'-isystem', u'/Library/Frameworks', u'-isystem', u'/Library/Developer/CommandLineTools/usr/lib/clang/9.1.0/include', u'-isystem', u'/Applications/Xcode.app/Contents/Developer/Platforms/MacOSX.platform/Developer/SDKs/MacOSX.sdk/usr/include', u'-fspell-checking'

For completion, here's my .ycm_extra_conf.py

import os
import ycm_core

# These are the compilation flags that will be used in case there's no
# compilation database set (by default, one is not set).
# CHANGE THIS LIST OF FLAGS. YES, THIS IS THE DROID YOU HAVE BEEN LOOKING FOR.
flags = [
  '-std=c++17',
  '-x', 'c++',
  '-stdlib=libc++',
  '-Wall',
  '-Wextra',
  '-pedantic',
  '-DDEBUG',
  '-Wno-gnu-case-range',
  '-isystem', '/usr/local/opt/llvm/include',
  '-isystem', '/usr/local/opt/llvm/include/c++/v1',
  '-I', '.',
]

# Set this to the absolute path to the folder (NOT the file!) containing the
# compile_commands.json file to use that instead of 'flags'. See here for
# more details: http://clang.llvm.org/docs/JSONCompilationDatabase.html
#
# You can get CMake to generate this file for you by adding:
#   set( CMAKE_EXPORT_COMPILE_COMMANDS 1 )
# to your CMakeLists.txt file.
#
# Most projects will NOT need to set this to anything; you can just change the
# 'flags' list of compilation flags. Notice that YCM itself uses that approach.
compilation_database_folder = ''

if os.path.exists( compilation_database_folder ):
  database = ycm_core.CompilationDatabase( compilation_database_folder )
else:
  database = None

SOURCE_EXTENSIONS = [ '.cpp', '.cxx', '.cc', '.c', '.m', '.mm' ]

def DirectoryOfThisScript():
  return os.path.dirname( os.path.abspath( __file__ ) )

def IsHeaderFile( filename ):
  extension = os.path.splitext( filename )[ 1 ]
  return extension in [ '.h', '.hxx', '.hpp', '.hh' ]

def GetCompilationInfoForFile( filename ):
  # The compilation_commands.json file generated by CMake does not have entries
  # for header files. So we do our best by asking the db for flags for a
  # corresponding source file, if any. If one exists, the flags for that file
  # should be good enough.
  if IsHeaderFile( filename ):
    basename = os.path.splitext( filename )[ 0 ]
    for extension in SOURCE_EXTENSIONS:
      replacement_file = basename + extension
      if os.path.exists( replacement_file ):
        compilation_info = database.GetCompilationInfoForFile(
          replacement_file )
        if compilation_info.compiler_flags_:
          return compilation_info
    return None
  return database.GetCompilationInfoForFile( filename )

def FlagsForFile( filename, **kwargs ):
  if not database:
    return {
      'flags': flags,
      'include_paths_relative_to_dir': DirectoryOfThisScript()
    }

  compilation_info = GetCompilationInfoForFile( filename )
  if not compilation_info:
    return None

  # Bear in mind that compilation_info.compiler_flags_ does NOT return a
  # python list, but a "list-like" StringVec object.
  final_flags = list( compilation_info.compiler_flags_ )

  return {
    'flags': final_flags,
    'include_paths_relative_to_dir': compilation_info.compiler_working_dir_
  }

Thanks in advance!

micbou commented 6 years ago

This means that ycmd found more than 30 diagnostics when parsing the translation unit. This limit is configurable through the max_diagnostics_to_display option (a value of 0 means no limit). However, emacs-ycmd doesn't seem to provide a way to configure this option.

jvillasante commented 6 years ago

But why or how does ycmd gets to that number of diagnostincs. The file compiles with all -Wall -Werror et. al. without any warnings.

Here's the code that compiles just fine without any warnings:

#include <iostream>
#include <string>
#include <algorithm>
#include <iterator>
#include <list>

template <typename InIt, typename OutIt, typename T, typename F>
InIt split(InIt it, InIt end_it, OutIt out_it, const T& split_val,
           F&& bin_func) {
  while (it != end_it) {
    auto slice_end{std::find(it, end_it, split_val)};
    *out_it++ = bin_func(it, slice_end);

    if (slice_end == end_it) {
      return end_it;
    }

    it = std::next(slice_end);
  }

  return it;
}

int main() {
  const std::string s{"a-b-c-d-e-f-g"};
  auto binfunc{[](auto it_a, auto it_b) { return std::string{it_a, it_b}; }};
  std::list<std::string> l;

  split(std::begin(s), std::end(s), std::back_inserter(l), '-', binfunc);
  std::copy(std::begin(l), std::end(l),
            std::ostream_iterator<std::string>{std::cout, "\n"});

  return 0;
}
jvillasante commented 6 years ago

It seems that ycmd is trying to parse system files as can be seen in this extract of the ycmd logs

(((kind . "ERROR")
  (text . "use of undeclared identifier 'wcschr'")
  (ranges)
  (location
   (filepath . "/usr/local/opt/llvm/include/c++/v1/wchar.h")
   (column_num . 77)
   (line_num . 137))
  (location_extent
   (start
    (filepath . "/usr/local/opt/llvm/include/c++/v1/wchar.h")
    (column_num . 77)
    (line_num . 137))
   (end
    (filepath . "/usr/local/opt/llvm/include/c++/v1/wchar.h")
    (column_num . 83)
    (line_num . 137)))
  (fixit_available . :json-false))

Is there a way to overcome this?

jvillasante commented 6 years ago

Changing .ycm_extra_config.py to this .ycm_extra_config file solves the issue. This one can be closed.

abingham commented 6 years ago

Thanks!

ChoppinBlockParty commented 5 years ago

I have the same problems and this ycmd extra config does not solve it. I am wondering why ycmd diagnostics does not show first max_diagnostics_to_display entries, rather showing one message that the limit is exceeded. What could be helpful if I could see first errors and may be figure out what am I missing, what is wrong with the code.

ChoppinBlockParty commented 5 years ago

I have just cloned the repo and loaded from source. where I changed max_diagnostics_to_display to 0. After that I was able to see some helpful information, it was a single warning. Weird...