Get Apple clang version and corresponding upstream LLVM version

C++11ClangC++14Llvm ClangC++17

C++11 Problem Overview


I want to understand which version of clang Apple installed in my macbook, to see with c++11 and/or c++14 features are available. I typed this command:

clang --version

//----response
Apple LLVM version 7.0.0 (clang-700.1.76)     
Target: x86_64-apple-darwin15.0.0    
Thread model: posix

But I am not able to understand what (clang-700.1.76) mean. How can I convert this code to a clang version?

This is the site where you could check c++ features available in clang version http://clang.llvm.org/cxx_status.html

C++11 Solutions


Solution 1 - C++11

Wikipedia's Xcode page has a map of Apple to LLVM versions. The LLVM column has the open-source LLVM/Clang version. From this you can look up a language feature in cppreference's chart of compiler support for language features.

Solution 2 - C++11

Here is the best listing I've found that correlates Apple's clang versions with the LLVM versions:

https://trac.macports.org/wiki/XcodeVersionInfo

Previous versions used to say what LLVM version they corresponded to, but starting with 7.0, Apple decided to no longer do that. They even define the __clang_version__ and related preprocessor macros to indicate the Apple version number, not the LLVM version. So they're useless for this as well.

Unfortunately, it looks like the only way to see if you have a feature is to try it and check if it works. e.g. 7.0.2 still doesn't have OpenMP enabled by default (although it's enable-able), so I guess it's still 3.6, not 3.7 yet.

Solution 3 - C++11

As hinted by pkolbus, you can look at the /src/CMakeLists.txt to guess the corresponding Clang version. For example, Apple Clang 800.0.38 and 800.0.42.1 both seem to based on Clang 3.9.0 according to

if(NOT DEFINED LLVM_VERSION_MAJOR)
  set(LLVM_VERSION_MAJOR 3)
endif()
if(NOT DEFINED LLVM_VERSION_MINOR)
  set(LLVM_VERSION_MINOR 9)
endif()
if(NOT DEFINED LLVM_VERSION_PATCH)
  set(LLVM_VERSION_PATCH 0)
endif()
if(NOT DEFINED LLVM_VERSION_SUFFIX)
  set(LLVM_VERSION_SUFFIX svn)
endif()

Solution 4 - C++11

Take a look at https://en.wikipedia.org/wiki/Xcode#Toolchain_versions

------------------------------------------------------------------------------------ Xcode cctools[93] ld64[94] LLVM[85] Clang version string[95] 8.3.3 898 278.4 3.9.0svn[85] 8.1.0 (clang-802.0.42)[80] 9.0 900 302.3 4.0.0?[86] 9.0.0 (clang-900.0.37)[80] 9.1 900 302.3.1 4.0.0?[87] 9.0.0 (clang-900.0.38)[80] 9.2 900 305 4.0.0?[88] 9.0.0 (clang-900.0.39.2)[80] 9.3 906 351.8 5.0.2?[89] 9.1.0 (clang-902.0.39.1)[80] 9.3.1 906 351.8 5.0.2?[89] 9.1.0 (clang-902.0.39.1)[80] 9.4 906 351.8 5.0.2?[90] 9.1.0 (clang-902.0.39.2)[80] 9.4.1 906 351.8 5.0.2?[90] 9.1.0 (clang-902.0.39.2)[80] 10.0 921.0.1 409.12 6.0.1?[91] 10.0.0 (clang-1000.11.45.2)[80] 10.1 921.0.1 409.12 6.0.1?[92] 10.0.0 (clang-1000.11.45.5)[80]

For example, Apple CLang 10.x is LLVM 6.0.1 based.

Solution 5 - C++11

First, I want to say that Daniel Frey's answer is absolutely correct; you really should be using __has_feature, __has_extension, etc. when possible. The Clang Language Extensions page documents the different things you can check for, and that should be your go-to solution.

That said, sometimes you really do need to check the version. For example, sometimes it is necessary to work around compiler bugs which have been fixed in newer versions, or which only appear in newer versions. Sometimes new functionality is added; for example, prior to clang 9 __builtin_constant_p didn't work correctly with the diagnose_if attribute. Sometimes a feature is added but there is no corresponding check.

I really wish clang would just expose the upstream version numbers as preprocessor macros so we could reliably handle cases like that, but they don't. You could manually create a map of Apple version numbers to upstream, which is what several other answers have proposed, but that has some pretty obvious drawbacks. For me, the fatal flaw is that it doesn't really work for compilers other than Apple clang; there are a lot of compilers based on clang these days (IBM XL C/C++, some newer PGI/NVIDIA compilers, next-gen Intel C/C++, etc.).

My work-around is to use feature detection macros to estimate a version number. For example, -Wimplicit-const-int-float-conversion was added in clang 11, so if __has_warning("-Wimplicit-const-int-float-conversion") is true we can assume the upstream clang version is >= 11. Similarly, clang 10 added -Wmisleading-indentation, clang 9 started definining the __FILE_NAME__ preprocessor macro, etc.

I've created a small header which contains the necessary logic. It's public domain (CC0), and even though it is part of one of my projects (SIMDe) it doesn't depend on anything else from any other files, so you're free to steal it for your own projects without copying all of SIMDe.

Obviously the file needs a new test for each version of clang, so it does require occasional updates if you need to be able to check for newer compilers, so I'd suggest grabbing the latest version from the SIMDe git repository (I'm not likely to keep this answer up to date), but here is what the checks look like right now:

#if defined(__clang__) && !defined(SIMDE_DETECT_CLANG_VERSION)
#  if __has_warning("-Wformat-insufficient-args")
#    define SIMDE_DETECT_CLANG_VERSION 120000
#  elif __has_warning("-Wimplicit-const-int-float-conversion")
#    define SIMDE_DETECT_CLANG_VERSION 110000
#  elif __has_warning("-Wmisleading-indentation")
#    define SIMDE_DETECT_CLANG_VERSION 100000
#  elif defined(__FILE_NAME__)
#    define SIMDE_DETECT_CLANG_VERSION 90000
#  elif __has_warning("-Wextra-semi-stmt") || __has_builtin(__builtin_rotateleft32)
#    define SIMDE_DETECT_CLANG_VERSION 80000
#  elif __has_warning("-Wc++98-compat-extra-semi")
#    define SIMDE_DETECT_CLANG_VERSION 70000
#  elif __has_warning("-Wpragma-pack")
#    define SIMDE_DETECT_CLANG_VERSION 60000
#  elif __has_warning("-Wbitfield-enum-conversion")
#    define SIMDE_DETECT_CLANG_VERSION 50000
#  elif __has_attribute(diagnose_if)
#    define SIMDE_DETECT_CLANG_VERSION 40000
#  elif __has_warning("-Wcomma")
#    define SIMDE_DETECT_CLANG_VERSION 39000
#  elif __has_warning("-Wdouble-promotion")
#    define SIMDE_DETECT_CLANG_VERSION 38000
#  elif __has_warning("-Wshift-negative-value")
#    define SIMDE_DETECT_CLANG_VERSION 37000
#  elif __has_warning("-Wambiguous-ellipsis")
#    define SIMDE_DETECT_CLANG_VERSION 36000
#  else
#    define SIMDE_DETECT_CLANG_VERSION 1
#  endif
#endif /* defined(__clang__) && !defined(SIMDE_DETECT_CLANG_VERSION) */

I think the biggest problem with this method is actually shared with all other attempts to detect the upstream clang version that I'm aware of: there isn't necessarily a clang release that corresponds to the code in question. As far as I can tell, most compilers based on clang aren't actually based on releases, but rather some random commit (probably whatever is the latest commit for the branch they want to base their work on). That means that, for example, if an issue is was fixed late in the clang $N development cycle, Apple's fork may generally be the same as clang $N but not contain the bug fix. Conversely, maybe Apple will back-port a fix from clang $N+1 and a bug present in clang $N will be fixed in Apple's version.

Solution 6 - C++11

One can try to compile some file with --verbose option.

For example: c++ --verbose -c test1.cpp

Apple LLVM version 7.0.2 (clang-700.1.81)
Target: x86_64-apple-darwin14.5.0
Thread model: posix
 "/Library/Developer/CommandLineTools/usr/bin/clang" -cc1 -triple x86_64-apple-macosx10.10.0 -Wdeprecated-objc-isa-usage -Werror=deprecated-objc-isa-usage -emit-obj -mrelax-all -disable-free -disable-llvm-verifier -main-file-name test1.cpp -mrelocation-model pic -pic-level 2 -mthread-model posix -mdisable-fp-elim -masm-verbose -munwind-tables -target-cpu core2 -target-linker-version 253.9 -v -dwarf-column-info -coverage-file /Users/az/ctest/test1.cpp -resource-dir /Library/Developer/CommandLineTools/usr/bin/../lib/clang/7.0.2 -stdlib=libc++ -fdeprecated-macro -fdebug-compilation-dir /Users/az/ctest -ferror-limit 19 -fmessage-length 130 -stack-protector 1 -mstackrealign -fblocks -fobjc-runtime=macosx-10.10.0 -fencode-extended-block-signature -fcxx-exceptions -fexceptions -fmax-type-align=16 -fdiagnostics-show-option -fcolor-diagnostics -o test1.o -x c++ test1.cpp
clang -cc1 version 7.0.2 based upon LLVM 3.7.0svn default target x86_64-apple-darwin14.5.0

It does print LLVM svn version (3.7.0 in our example)

Solution 7 - C++11

If you use the strings command on the compiler you might get the LLVM version.

For example if you have the clang version that identifies itself as Apple LLVM version 7.0.2 (clang-700.1.81), the output of strings will have this value:

LLVM 3.7.0svn

This doesn't appear to work with version Apple LLVM version 7.3.0 (clang-703.0.29)

Solution 8 - C++11

The (Apple) version number of the compiler is mostly useless, since you also need to consider whether your code is compiled with libstdc++ or with libc++ (or any other standard library) - and which version of those.

If you want to test for language or library features, it is better to check other defined values, e.g., __cplusplus, __cpp_constexpr, __cpp_variadic_templates, etc. It is not perfect, but it seems to work better (if you want portability) in my experience and the support from all major compiler is improving.

Each C++ standard version defines a value for __cplusplus, some compilers use intermediate values to say "we already started on C++14, but we are not there yet". Use >= to test when needed.

The other feature test macros are similar, you can find the current version at N4440. Not all compilers implement N4440, though.

Solution 9 - C++11

If you installed clion, in it's preference-toolchains, you might see 'debugger' as bundled LLDB 7.0.1.

I believe this is the current Apple clang version. (eg.Apple LLVM version 10.0.1)

Solution 10 - C++11

As your Terminal output

clang --version
//----response
Apple LLVM version 7.0.0 (clang-700.1.76)     
Target: x86_64-apple-darwin15.0.0    
Thread model: posix

The first line "Apple LLVM version 7.0.0 (clang-700.1.76)" means: Your Xcode7.1 with embedded Clang7.0.0(The Clang7.0.0 Identifier:clang-700.1.76).

From this website, i know your Clang version is 7.0.0. If Clang version is >= Clang5.0, that Clang support C++11 or C++14.

Attributions

All content for this solution is sourced from the original question on Stackoverflow.

The content on this page is licensed under the Attribution-ShareAlike 4.0 International (CC BY-SA 4.0) license.

Content TypeOriginal AuthorOriginal Content on Stackoverflow
Questionuser72708View Question on Stackoverflow
Solution 1 - C++11John McFarlaneView Answer on Stackoverflow
Solution 2 - C++11Mike JarvisView Answer on Stackoverflow
Solution 3 - C++11Franklin YuView Answer on Stackoverflow
Solution 4 - C++11Virgilio FornazinView Answer on Stackoverflow
Solution 5 - C++11nemequView Answer on Stackoverflow
Solution 6 - C++11user8308676View Answer on Stackoverflow
Solution 7 - C++11user2956983View Answer on Stackoverflow
Solution 8 - C++11Daniel FreyView Answer on Stackoverflow
Solution 9 - C++11user11275640View Answer on Stackoverflow
Solution 10 - C++11Vittore MarcasView Answer on Stackoverflow