Closed ddovod closed 6 years ago
Today I have tried to parse this file with simple python script
import clang.cindex
idx = clang.cindex.Index.create()
tu = idx.parse('main.cpp', args=['-std=c++11', '-stdlib=libc++'])
for el in tu.diagnostics:
print(el.spelling)
In both cases, with and without -stdlib=libc++
, there're no errors (clear output), so maybe you can look in irony code, or maybe you have some idea about such behavior?
Btw, it can be helpful
ddovod@/cpp_test: ~/.emacs.d/irony/bin/irony-server --version
irony-server version 1.1.0
clang version 5.0.0-svn312333-1~exp1 (branches/release_50)
Thank you
And also it could be helpful, interactive irony-server session
ddovod@/cpp_test: ~/.emacs.d/irony/bin/irony-server -i
parse main.cpp -- -std=c++11 -stdlib=libc++
execute: Command{action=Command::Parse, file='main.cpp', unsavedFile='', dir='', line=0, column=0, prefix='', caseStyle='exact', flags=['-std=c++11', '-stdlib=libc++'], opt=off}
(success . t)
;;EOT
diagnostics
execute: Command{action=Command::Diagnostics, file='', unsavedFile='', dir='', line=0, column=0, prefix='', caseStyle='exact', flags=[], opt=off}
(
("/usr/include/c++/v1/cstddef" 44 15 810 fatal "'stddef.h' file not found")
("/usr/include/c++/v1/cstddef" 49 9 880 error "no member named 'ptrdiff_t' in the global namespace")
("/usr/include/c++/v1/cstddef" 50 9 899 error "no member named 'size_t' in the global namespace")
("/usr/include/c++/v1/type_traits" 539 44 24935 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 542 32 24994 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 559 42 25492 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 562 32 25550 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 578 30 25980 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 591 29 26387 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 610 79 26958 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 611 79 27051 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 620 85 27329 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 621 85 27428 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 654 61 28597 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 655 61 28672 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 667 64 29053 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 668 69 29136 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 685 79 29721 error "base specifier must name a class")
("/usr/include/c++/v1/type_traits" 686 79 29814 error "base specifier must name a class")
("/home/ddovod/_private/trash/cpp_test/main.cpp" 6 30 66 error "implicit instantiation of undefined template 'std::__1::function<void (int)>'")
)
;;EOT
But
ddovod@/cpp_test: ls -l /usr/include/c++/v1/ | grep stddef
-rw-r--r-- 1 root root 2409 сен 17 18:11 cstddef
-rw-r--r-- 1 root root 1297 сен 17 18:11 stddef.h
Okay, it seems I finally managed to make it work. After commenting lines 100-101 in TUManager.cpp
argv.push_back("-isystem");
argv.push_back(CLANG_BUILTIN_HEADERS_DIR);
it works as expected with -stdlib=libc++, also with same interactive session there're no errors about missing stddef.h. It's ugly hack, so I hope you have better solution for this
Oh interesting, I'm not sure how to handle this situation. A few questions:
-isystem CLANG_BUILTIN_HEADERS_DIR
code, do you find stddef.h?cmake -L |& grep CHECK_LIBCLANG_BUILTIN_HEADERS
ddovod@/build: ls -l /usr/include/c++/v1/ | grep stddef
-rw-r--r-- 1 root root 2409 сен 17 18:11 cstddef
-rw-r--r-- 1 root root 1297 сен 17 18:11 stddef.h
Another stddef.h is in the clang includes
ddovod@/cpp_test: ls -l /usr/lib/llvm-5.0/lib/clang/5.0.0/include | grep stddef
-rw-r--r-- 1 root root 4498 сен 1 20:30 stddef.h
-rw-r--r-- 1 root root 1770 сен 1 20:30 __stddef_max_align_t.h
ddovod@/build: cmake -L .. | grep CHECK_LIBCLANG_BUILTIN_HEADERS
CHECK_LIBCLANG_BUILTIN_HEADERS_STDDEF_DIR:PATH=/usr/lib/llvm-5.0/lib/clang/5.0.0/include
Also these 2 stddef.hs are totally different, I think they do about one work, but their content is absolutely different
And do you know where is your GCC/libstdc++ stddef.h?
For gcc it is in /usr/lib/gcc/x86_64-linux-gnu/6/include/stddef.h
For libstdc++ - I don't know actually, find
onlu found this, libc++ and linux stddefs.
But the content of cstddef in libstdc++ is
#ifndef _GLIBCXX_CSTDDEF
#define _GLIBCXX_CSTDDEF 1
#pragma GCC system_header
#undef __need_wchar_t
#undef __need_ptrdiff_t
#undef __need_size_t
#undef __need_NULL
#undef __need_wint_t
#include <bits/c++config.h>
#include <stddef.h>
#if __cplusplus >= 201103L
namespace std
{
// We handle size_t, ptrdiff_t, and nullptr_t in c++config.h.
using ::max_align_t;
}
#endif
#endif // _GLIBCXX_CSTDDEF
and in libc++
#ifndef _LIBCPP_CSTDDEF
#define _LIBCPP_CSTDDEF
/*
cstddef synopsis
Macros:
offsetof(type,member-designator)
NULL
namespace std
{
Types:
ptrdiff_t
size_t
max_align_t
nullptr_t
byte // C++17
} // std
*/
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
// Don't include our own <stddef.h>; we don't want to declare ::nullptr_t.
#include_next <stddef.h>
#include <__nullptr>
_LIBCPP_BEGIN_NAMESPACE_STD
using ::ptrdiff_t;
using ::size_t;
#if defined(__CLANG_MAX_ALIGN_T_DEFINED) || defined(_GCC_MAX_ALIGN_T) || \
defined(__DEFINED_max_align_t)
// Re-use the compiler's <stddef.h> max_align_t where possible.
using ::max_align_t;
#else
typedef long double max_align_t;
#endif
_LIBCPP_END_NAMESPACE_STD
#if _LIBCPP_STD_VER > 14
namespace std // purposefully not versioned
{
enum class byte : unsigned char {};
constexpr byte& operator|=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) | static_cast<unsigned char>(__rhs)); }
constexpr byte operator| (byte __lhs, byte __rhs) noexcept
{ return byte(static_cast<unsigned char>(__lhs) | static_cast<unsigned char>(__rhs)); }
constexpr byte& operator&=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) & static_cast<unsigned char>(__rhs)); }
constexpr byte operator& (byte __lhs, byte __rhs) noexcept
{ return byte(static_cast<unsigned char>(__lhs) & static_cast<unsigned char>(__rhs)); }
constexpr byte& operator^=(byte& __lhs, byte __rhs) noexcept
{ return __lhs = byte(static_cast<unsigned char>(__lhs) ^ static_cast<unsigned char>(__rhs)); }
constexpr byte operator^ (byte __lhs, byte __rhs) noexcept
{ return byte(static_cast<unsigned char>(__lhs) ^ static_cast<unsigned char>(__rhs)); }
constexpr byte operator~ (byte __b) noexcept
{ return byte(~static_cast<unsigned char>(__b)); }
}
#include <type_traits> // rest of byte
#endif
#endif // _LIBCPP_CSTDDEF
Maybe it can help somehow
I'm actually more curious about stddef.h: What is the content of these two?
1.
// -*- C++ -*-
//===--------------------------- stddef.h ---------------------------------===//
//
// The LLVM Compiler Infrastructure
//
// This file is dual licensed under the MIT and the University of Illinois Open
// Source Licenses. See LICENSE.TXT for details.
//
//===----------------------------------------------------------------------===//
#if defined(__need_ptrdiff_t) || defined(__need_size_t) || \
defined(__need_wchar_t) || defined(__need_NULL) || defined(__need_wint_t)
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#include_next <stddef.h>
#elif !defined(_LIBCPP_STDDEF_H)
#define _LIBCPP_STDDEF_H
/*
stddef.h synopsis
Macros:
offsetof(type,member-designator)
NULL
Types:
ptrdiff_t
size_t
max_align_t
nullptr_t
*/
#include <__config>
#if !defined(_LIBCPP_HAS_NO_PRAGMA_SYSTEM_HEADER)
#pragma GCC system_header
#endif
#include_next <stddef.h>
#ifdef __cplusplus
extern "C++" {
#include <__nullptr>
using std::nullptr_t;
}
// Re-use the compiler's <stddef.h> max_align_t where possible.
#if !defined(__CLANG_MAX_ALIGN_T_DEFINED) && !defined(_GCC_MAX_ALIGN_T) && \
!defined(__DEFINED_max_align_t)
typedef long double max_align_t;
#endif
#endif
#endif // _LIBCPP_STDDEF_H
2.
/*===---- stddef.h - Basic type definitions --------------------------------===
*
* Copyright (c) 2008 Eli Friedman
*
* Permission is hereby granted, free of charge, to any person obtaining a copy
* of this software and associated documentation files (the "Software"), to deal
* in the Software without restriction, including without limitation the rights
* to use, copy, modify, merge, publish, distribute, sublicense, and/or sell
* copies of the Software, and to permit persons to whom the Software is
* furnished to do so, subject to the following conditions:
*
* The above copyright notice and this permission notice shall be included in
* all copies or substantial portions of the Software.
*
* THE SOFTWARE IS PROVIDED "AS IS", WITHOUT WARRANTY OF ANY KIND, EXPRESS OR
* IMPLIED, INCLUDING BUT NOT LIMITED TO THE WARRANTIES OF MERCHANTABILITY,
* FITNESS FOR A PARTICULAR PURPOSE AND NONINFRINGEMENT. IN NO EVENT SHALL THE
* AUTHORS OR COPYRIGHT HOLDERS BE LIABLE FOR ANY CLAIM, DAMAGES OR OTHER
* LIABILITY, WHETHER IN AN ACTION OF CONTRACT, TORT OR OTHERWISE, ARISING FROM,
* OUT OF OR IN CONNECTION WITH THE SOFTWARE OR THE USE OR OTHER DEALINGS IN
* THE SOFTWARE.
*
*===-----------------------------------------------------------------------===
*/
#if !defined(__STDDEF_H) || defined(__need_ptrdiff_t) || \
defined(__need_size_t) || defined(__need_wchar_t) || \
defined(__need_NULL) || defined(__need_wint_t)
#if !defined(__need_ptrdiff_t) && !defined(__need_size_t) && \
!defined(__need_wchar_t) && !defined(__need_NULL) && \
!defined(__need_wint_t)
/* Always define miscellaneous pieces when modules are available. */
#if !__has_feature(modules)
#define __STDDEF_H
#endif
#define __need_ptrdiff_t
#define __need_size_t
#define __need_wchar_t
#define __need_NULL
#define __need_STDDEF_H_misc
/* __need_wint_t is intentionally not defined here. */
#endif
#if defined(__need_ptrdiff_t)
#if !defined(_PTRDIFF_T) || __has_feature(modules)
/* Always define ptrdiff_t when modules are available. */
#if !__has_feature(modules)
#define _PTRDIFF_T
#endif
typedef __PTRDIFF_TYPE__ ptrdiff_t;
#endif
#undef __need_ptrdiff_t
#endif /* defined(__need_ptrdiff_t) */
#if defined(__need_size_t)
#if !defined(_SIZE_T) || __has_feature(modules)
/* Always define size_t when modules are available. */
#if !__has_feature(modules)
#define _SIZE_T
#endif
typedef __SIZE_TYPE__ size_t;
#endif
#undef __need_size_t
#endif /*defined(__need_size_t) */
#if defined(__need_STDDEF_H_misc)
/* ISO9899:2011 7.20 (C11 Annex K): Define rsize_t if __STDC_WANT_LIB_EXT1__ is
* enabled. */
#if (defined(__STDC_WANT_LIB_EXT1__) && __STDC_WANT_LIB_EXT1__ >= 1 && \
!defined(_RSIZE_T)) || __has_feature(modules)
/* Always define rsize_t when modules are available. */
#if !__has_feature(modules)
#define _RSIZE_T
#endif
typedef __SIZE_TYPE__ rsize_t;
#endif
#endif /* defined(__need_STDDEF_H_misc) */
#if defined(__need_wchar_t)
#ifndef __cplusplus
/* Always define wchar_t when modules are available. */
#if !defined(_WCHAR_T) || __has_feature(modules)
#if !__has_feature(modules)
#define _WCHAR_T
#if defined(_MSC_EXTENSIONS)
#define _WCHAR_T_DEFINED
#endif
#endif
typedef __WCHAR_TYPE__ wchar_t;
#endif
#endif
#undef __need_wchar_t
#endif /* defined(__need_wchar_t) */
#if defined(__need_NULL)
#undef NULL
#ifdef __cplusplus
# if !defined(__MINGW32__) && !defined(_MSC_VER)
# define NULL __null
# else
# define NULL 0
# endif
#else
# define NULL ((void*)0)
#endif
#ifdef __cplusplus
#if defined(_MSC_EXTENSIONS) && defined(_NATIVE_NULLPTR_SUPPORTED)
namespace std { typedef decltype(nullptr) nullptr_t; }
using ::std::nullptr_t;
#endif
#endif
#undef __need_NULL
#endif /* defined(__need_NULL) */
#if defined(__need_STDDEF_H_misc)
#if __STDC_VERSION__ >= 201112L || __cplusplus >= 201103L
#include "__stddef_max_align_t.h"
#endif
#define offsetof(t, d) __builtin_offsetof(t, d)
#undef __need_STDDEF_H_misc
#endif /* defined(__need_STDDEF_H_misc) */
/* Some C libraries expect to see a wint_t here. Others (notably MinGW) will use
__WINT_TYPE__ directly; accommodate both by requiring __need_wint_t */
#if defined(__need_wint_t)
/* Always define wint_t when modules are available. */
#if !defined(_WINT_T) || __has_feature(modules)
#if !__has_feature(modules)
#define _WINT_T
#endif
typedef __WINT_TYPE__ wint_t;
#endif
#undef __need_wint_t
#endif /* __need_wint_t */
#endif
@Sarcasm I was just about to open an issue about -isystem, but I'll just comment it here. Instead of using -isystem /path/to/clang/include
, you should use -resource-dir /path/to/clang
in irony. Using -isystem
fucks up the include order, so the #include_next
in libc++ won't find the correct stddef.h
(as you can see in ("/usr/include/c++/v1/cstddef" 44 15 810 fatal "'stddef.h' file not found")
).
See what happens if I manually specify -isystem
on a standalone clang:
$ touch x.cpp
$ clang -v -stdlib=libc++ -E x.cpp -o /dev/null
[...snip...]
#include <...> search starts here:
/usr/include/c++/v1
/usr/local/include
/usr/lib64/llvm/5/bin/../../../../lib/clang/5.0.0/include
/usr/include
End of search list.
$ clang -v -stdlib=libc++ -E x.cpp -o /dev/null -isystem /usr/lib64/clang/5.0.0/include/
[...]
#include <...> search starts here:
/usr/lib64/clang/5.0.0/include
/usr/include/c++/v1
/usr/local/include
/usr/include
End of search list.
Instead of using -isystem /path/to/clang/include, you should use -resource-dir /path/to/clang in irony
Wow! I thought I did, but you are right it is -isystem
, and I cannot find a reason why.
Thank you for finding this, it's not necessarily obvious... :+1:
Changed to -resource-dir
, this change is slightly risky, we will see how it goes, it worked for me but I'm not sure that will be the case for all distributions. Let me know if it works for you guys.
Committed as 6c8b567abad2da4ce975e19f393d0cad05da2d99.
@DirtYiCE Good catch! Just checked on my setup and it works fine without any manual patching. @Sarcasm I think we can close this issue now
Hello. First, thank you a lot for such useful plugin!
I have some issue with projects which use libc++. My setup: Xubuntu 17.04 Emacs 25.3.2 clang 5.0 (from llvm ppa) libc++ and libc++abi 5.0 (built from source due to lack of prebuilt packages, install prefix = /usr, so the headers are located in /usr/include/c++/v1) latest flyckeck, irony-mode, company-irony, flycheck-irony packages with "default" configurations. Actually I also use cpputils-cmake, but I think it doesn't matter in this case.
Test project is very straightforward: main.cpp
CMakeLists.txt
This setup produces compile_commands.json
By default libstdc++ is used, and in this case all works fine, I can get working code completion and flycheck. But if I add -stdlib=libc++ inside target_compile_options, completion and syntax check of std stuff becomes broken![screenshot_2017-09-18_00-42-03](https://user-images.githubusercontent.com/9406025/30525243-a34d7b4e-9c0b-11e7-8df6-9a780de560d0.png)
BTW in both cases program compiles successful. So I'm suspecting some internal logic of irony or maybe libclang. Could you help me please with it? I can provide any additional info if you need one. Thank you again!