diff options
2297 files changed, 104294 insertions, 33806 deletions
diff --git a/.clang-tidy b/.clang-tidy new file mode 100644 index 000000000000..3186da43d43d --- /dev/null +++ b/.clang-tidy @@ -0,0 +1 @@ +Checks: '-*,clang-diagnostic-*,llvm-*,misc-*' diff --git a/CMakeLists.txt b/CMakeLists.txt index 02374e20f439..75b80757038d 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -83,7 +83,13 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) # They are used as destination of target generators. set(LLVM_RUNTIME_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/bin) - set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib) + set(LLVM_LIBRARY_OUTPUT_INTDIR ${CMAKE_BINARY_DIR}/${CMAKE_CFG_INTDIR}/lib${LLVM_LIBDIR_SUFFIX}) + if(WIN32 OR CYGWIN) + # DLL platform -- put DLLs into bin. + set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_RUNTIME_OUTPUT_INTDIR}) + else() + set(LLVM_SHLIB_OUTPUT_INTDIR ${LLVM_LIBRARY_OUTPUT_INTDIR}) + endif() option(LLVM_INSTALL_TOOLCHAIN_ONLY "Only include toolchain files in the 'install' target." OFF) @@ -105,8 +111,8 @@ if( CMAKE_SOURCE_DIR STREQUAL CMAKE_CURRENT_SOURCE_DIR ) link_directories("${LLVM_LIBRARY_DIR}") set( CMAKE_RUNTIME_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/bin ) - set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) - set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib ) + set( CMAKE_LIBRARY_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX} ) + set( CMAKE_ARCHIVE_OUTPUT_DIRECTORY ${CMAKE_BINARY_DIR}/lib${LLVM_LIBDIR_SUFFIX} ) if(LLVM_INCLUDE_TESTS) # Check prebuilt llvm/utils. @@ -193,6 +199,9 @@ endif() set(CLANG_VENDOR_UTI "org.llvm.clang" CACHE STRING "Vendor-specific uti.") +# The libdir suffix must exactly match whatever LLVM's configuration used. +set(CLANG_LIBDIR_SUFFIX "${LLVM_LIBDIR_SUFFIX}") + set(CLANG_SOURCE_DIR ${CMAKE_CURRENT_SOURCE_DIR}) set(CLANG_BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}) @@ -240,7 +249,7 @@ configure_file( # Add appropriate flags for GCC if (LLVM_COMPILER_IS_GCC_COMPATIBLE) - set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -Wcast-qual -fno-strict-aliasing") + set(CMAKE_CXX_FLAGS "${CMAKE_CXX_FLAGS} -fno-common -Woverloaded-virtual -fno-strict-aliasing") # Enable -pedantic for Clang even if it's not enabled for LLVM. if (NOT LLVM_ENABLE_PEDANTIC) @@ -253,6 +262,26 @@ if (LLVM_COMPILER_IS_GCC_COMPATIBLE) endif() endif () +# Determine HOST_LINK_VERSION on Darwin. +set(HOST_LINK_VERSION) +if (APPLE) + set(LD_V_OUTPUT) + execute_process( + COMMAND sh -c "${CMAKE_LINKER} -v 2>&1 | head -1" + RESULT_VARIABLE HAD_ERROR + OUTPUT_VARIABLE LD_V_OUTPUT + ) + if (NOT HAD_ERROR) + if ("${LD_V_OUTPUT}" MATCHES ".*ld64-([0-9.]+).*") + string(REGEX REPLACE ".*ld64-([0-9.]+).*" "\\1" HOST_LINK_VERSION ${LD_V_OUTPUT}) + elseif ("${LD_V_OUTPUT}" MATCHES "[^0-9]*([0-9.]+).*") + string(REGEX REPLACE "[^0-9]*([0-9.]+).*" "\\1" HOST_LINK_VERSION ${LD_V_OUTPUT}) + endif() + else() + message(FATAL_ERROR "${CMAKE_LINKER} failed with status ${HAD_ERROR}") + endif() +endif() + configure_file( ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake ${CLANG_BINARY_DIR}/include/clang/Config/config.h) @@ -337,6 +366,7 @@ macro(add_clang_library name) ARCHIVE DESTINATION lib${LLVM_LIBDIR_SUFFIX} RUNTIME DESTINATION bin) endif() + set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) else() # Add empty "phony" target add_custom_target(${name}) @@ -478,3 +508,27 @@ endif() set(CLANG_ORDER_FILE "" CACHE FILEPATH "Order file to use when compiling clang in order to improve startup time.") + +if (CLANG_BUILT_STANDALONE) + # Generate a list of CMake library targets so that other CMake projects can + # link against them. LLVM calls its version of this file LLVMExports.cmake, but + # the usual CMake convention seems to be ${Project}Targets.cmake. + set(CLANG_INSTALL_PACKAGE_DIR share/clang/cmake) + set(clang_cmake_builddir "${CMAKE_BINARY_DIR}/${CLANG_INSTALL_PACKAGE_DIR}") + get_property(CLANG_EXPORTS GLOBAL PROPERTY CLANG_EXPORTS) + export(TARGETS ${CLANG_EXPORTS} FILE ${clang_cmake_builddir}/ClangTargets.cmake) + + # Install a <prefix>/share/clang/cmake/ClangConfig.cmake file so that + # find_package(Clang) works. Install the target list with it. + install(FILES + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake + ${CLANG_BINARY_DIR}/share/clang/cmake/ClangTargets.cmake + DESTINATION share/clang/cmake) + + # Also copy ClangConfig.cmake to the build directory so that dependent projects + # can build against a build directory of Clang more easily. + configure_file( + ${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules/ClangConfig.cmake + ${CLANG_BINARY_DIR}/share/clang/cmake/ClangConfig.cmake + COPYONLY) +endif () diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index bbd3142bc87c..b58014fee1aa 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -22,6 +22,7 @@ E: echristo@gmail.com D: Debug Information, autotools/configure/make build, inline assembly N: Doug Gregor +E: dgregor@apple.com D: All parts of Clang not covered by someone else N: Anton Korobeynikov @@ -29,6 +30,7 @@ E: anton@korobeynikov.info D: Exception handling, Windows codegen, ARM EABI N: Ted Kremenek +E: kremenek@apple.com D: Clang Static Analyzer N: John McCall @@ -37,7 +39,7 @@ D: Clang LLVM IR generation N: Chad Rosier E: mcrosier@codeaurora.org -D: MS-inline asm, and the compiler driver +D: Compiler driver N: Richard Smith E: richard@metafoo.co.uk diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index 517b3c1bac6e..5792effea59b 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -496,24 +496,28 @@ class TokenKind(object): setattr(TokenKind, name, kind) ### Cursor Kinds ### - -class CursorKind(object): - """ - A CursorKind describes the kind of entity that a cursor points to. +class BaseEnumeration(object): """ + Common base class for named enumerations held in sync with Index.h values. - # The unique kind objects, indexed by id. + Subclasses must define their own _kinds and _name_map members, as: _kinds = [] _name_map = None + These values hold the per-subclass instances and value-to-name mappings, + respectively. + + """ def __init__(self, value): - if value >= len(CursorKind._kinds): - CursorKind._kinds += [None] * (value - len(CursorKind._kinds) + 1) - if CursorKind._kinds[value] is not None: - raise ValueError,'CursorKind already loaded' + if value >= len(self.__class__._kinds): + self.__class__._kinds += [None] * (value - len(self.__class__._kinds) + 1) + if self.__class__._kinds[value] is not None: + raise ValueError,'{0} value {1} already loaded'.format( + str(self.__class__), value) self.value = value - CursorKind._kinds[value] = self - CursorKind._name_map = None + self.__class__._kinds[value] = self + self.__class__._name_map = None + def from_param(self): return self.value @@ -523,16 +527,29 @@ class CursorKind(object): """Get the enumeration name of this cursor kind.""" if self._name_map is None: self._name_map = {} - for key,value in CursorKind.__dict__.items(): - if isinstance(value,CursorKind): + for key, value in self.__class__.__dict__.items(): + if isinstance(value, self.__class__): self._name_map[value] = key return self._name_map[self] - @staticmethod - def from_id(id): - if id >= len(CursorKind._kinds) or CursorKind._kinds[id] is None: - raise ValueError,'Unknown cursor kind %d' % id - return CursorKind._kinds[id] + @classmethod + def from_id(cls, id): + if id >= len(cls._kinds) or cls._kinds[id] is None: + raise ValueError,'Unknown template argument kind %d' % id + return cls._kinds[id] + + def __repr__(self): + return '%s.%s' % (self.__class__, self.name,) + + +class CursorKind(BaseEnumeration): + """ + A CursorKind describes the kind of entity that a cursor points to. + """ + + # The required BaseEnumeration declarations. + _kinds = [] + _name_map = None @staticmethod def get_all_kinds(): @@ -578,11 +595,6 @@ class CursorKind(object): def __repr__(self): return 'CursorKind.%s' % (self.name,) -# FIXME: Is there a nicer way to expose this enumeration? We could potentially -# represent the nested structure, or even build a class hierarchy. The main -# things we want for sure are (a) simple external access to kinds, (b) a place -# to hang a description and name, (c) easy to keep in sync with Index.h. - ### # Declaration Kinds @@ -1086,6 +1098,7 @@ CursorKind.CUDACONSTANT_ATTR = CursorKind(412) CursorKind.CUDADEVICE_ATTR = CursorKind(413) CursorKind.CUDAGLOBAL_ATTR = CursorKind(414) CursorKind.CUDAHOST_ATTR = CursorKind(415) +CursorKind.CUDASHARED_ATTR = CursorKind(416) ### # Preprocessing @@ -1100,6 +1113,24 @@ CursorKind.INCLUSION_DIRECTIVE = CursorKind(503) # A module import declaration. CursorKind.MODULE_IMPORT_DECL = CursorKind(600) + +### Template Argument Kinds ### +class TemplateArgumentKind(BaseEnumeration): + """ + A TemplateArgumentKind describes the kind of entity that a template argument + represents. + """ + + # The required BaseEnumeration declarations. + _kinds = [] + _name_map = None + +TemplateArgumentKind.NULL = TemplateArgumentKind(0) +TemplateArgumentKind.TYPE = TemplateArgumentKind(1) +TemplateArgumentKind.DECLARATION = TemplateArgumentKind(2) +TemplateArgumentKind.NULLPTR = TemplateArgumentKind(3) +TemplateArgumentKind.INTEGRAL = TemplateArgumentKind(4) + ### Cursors ### class Cursor(Structure): @@ -1176,9 +1207,9 @@ class Cursor(Structure): """ Return the display name for the entity referenced by this cursor. - The display name contains extra information that helps identify the cursor, - such as the parameters of a function or template or the arguments of a - class template specialization. + The display name contains extra information that helps identify the + cursor, such as the parameters of a function or template or the + arguments of a class template specialization. """ if not hasattr(self, '_displayname'): self._displayname = conf.lib.clang_getCursorDisplayName(self) @@ -1186,6 +1217,14 @@ class Cursor(Structure): return self._displayname @property + def mangled_name(self): + """Return the mangled name for the entity referenced by this cursor.""" + if not hasattr(self, '_mangled_name'): + self._mangled_name = conf.lib.clang_Cursor_getMangling(self) + + return self._mangled_name + + @property def location(self): """ Return the source location (the starting character) of the entity @@ -1208,6 +1247,17 @@ class Cursor(Structure): return self._extent @property + def storage_class(self): + """ + Retrieves the storage class (if any) of the entity pointed at by the + cursor. + """ + if not hasattr(self, '_storage_class'): + self._storage_class = conf.lib.clang_Cursor_getStorageClass(self) + + return StorageClass.from_id(self._storage_class) + + @property def access_specifier(self): """ Retrieves the access specifier (if any) of the entity pointed at by the @@ -1369,6 +1419,27 @@ class Cursor(Structure): for i in range(0, num_args): yield conf.lib.clang_Cursor_getArgument(self, i) + def get_num_template_arguments(self): + """Returns the number of template args associated with this cursor.""" + return conf.lib.clang_Cursor_getNumTemplateArguments(self) + + def get_template_argument_kind(self, num): + """Returns the TemplateArgumentKind for the indicated template + argument.""" + return conf.lib.clang_Cursor_getTemplateArgumentKind(self, num) + + def get_template_argument_type(self, num): + """Returns the CXType for the indicated template argument.""" + return conf.lib.clang_Cursor_getTemplateArgumentType(self, num) + + def get_template_argument_value(self, num): + """Returns the value of the indicated arg as a signed 64b integer.""" + return conf.lib.clang_Cursor_getTemplateArgumentValue(self, num) + + def get_template_argument_unsigned_value(self, num): + """Returns the value of the indicated arg as an unsigned 64b integer.""" + return conf.lib.clang_Cursor_getTemplateArgumentUnsignedValue(self, num) + def get_children(self): """Return an iterator for accessing the children of this cursor.""" @@ -1450,11 +1521,9 @@ class Cursor(Structure): res._tu = args[0]._tu return res -### C++ access specifiers ### - -class AccessSpecifier(object): +class StorageClass(object): """ - Describes the access of a C++ class member + Describes the storage class of a declaration """ # The unique kind objects, index by id. @@ -1462,32 +1531,59 @@ class AccessSpecifier(object): _name_map = None def __init__(self, value): - if value >= len(AccessSpecifier._kinds): - AccessSpecifier._kinds += [None] * (value - len(AccessSpecifier._kinds) + 1) - if AccessSpecifier._kinds[value] is not None: - raise ValueError,'AccessSpecifier already loaded' + if value >= len(StorageClass._kinds): + StorageClass._kinds += [None] * (value - len(StorageClass._kinds) + 1) + if StorageClass._kinds[value] is not None: + raise ValueError,'StorageClass already loaded' self.value = value - AccessSpecifier._kinds[value] = self - AccessSpecifier._name_map = None + StorageClass._kinds[value] = self + StorageClass._name_map = None def from_param(self): return self.value @property def name(self): - """Get the enumeration name of this access specifier.""" + """Get the enumeration name of this storage class.""" if self._name_map is None: self._name_map = {} - for key,value in AccessSpecifier.__dict__.items(): - if isinstance(value,AccessSpecifier): + for key,value in StorageClass.__dict__.items(): + if isinstance(value,StorageClass): self._name_map[value] = key return self._name_map[self] @staticmethod def from_id(id): - if id >= len(AccessSpecifier._kinds) or not AccessSpecifier._kinds[id]: - raise ValueError,'Unknown access specifier %d' % id - return AccessSpecifier._kinds[id] + if id >= len(StorageClass._kinds) or not StorageClass._kinds[id]: + raise ValueError,'Unknown storage class %d' % id + return StorageClass._kinds[id] + + def __repr__(self): + return 'StorageClass.%s' % (self.name,) + +StorageClass.INVALID = StorageClass(0) +StorageClass.NONE = StorageClass(1) +StorageClass.EXTERN = StorageClass(2) +StorageClass.STATIC = StorageClass(3) +StorageClass.PRIVATEEXTERN = StorageClass(4) +StorageClass.OPENCLWORKGROUPLOCAL = StorageClass(5) +StorageClass.AUTO = StorageClass(6) +StorageClass.REGISTER = StorageClass(7) + + +### C++ access specifiers ### + +class AccessSpecifier(BaseEnumeration): + """ + Describes the access of a C++ class member + """ + + # The unique kind objects, index by id. + _kinds = [] + _name_map = None + + def from_param(self): + return self.value def __repr__(self): return 'AccessSpecifier.%s' % (self.name,) @@ -1500,7 +1596,7 @@ AccessSpecifier.NONE = AccessSpecifier(4) ### Type Kinds ### -class TypeKind(object): +class TypeKind(BaseEnumeration): """ Describes the kind of type. """ @@ -1509,39 +1605,11 @@ class TypeKind(object): _kinds = [] _name_map = None - def __init__(self, value): - if value >= len(TypeKind._kinds): - TypeKind._kinds += [None] * (value - len(TypeKind._kinds) + 1) - if TypeKind._kinds[value] is not None: - raise ValueError,'TypeKind already loaded' - self.value = value - TypeKind._kinds[value] = self - TypeKind._name_map = None - - def from_param(self): - return self.value - - @property - def name(self): - """Get the enumeration name of this cursor kind.""" - if self._name_map is None: - self._name_map = {} - for key,value in TypeKind.__dict__.items(): - if isinstance(value,TypeKind): - self._name_map[value] = key - return self._name_map[self] - @property def spelling(self): """Retrieve the spelling of this TypeKind.""" return conf.lib.clang_getTypeKindSpelling(self.value) - @staticmethod - def from_id(id): - if id >= len(TypeKind._kinds) or TypeKind._kinds[id] is None: - raise ValueError,'Unknown type kind %d' % id - return TypeKind._kinds[id] - def __repr__(self): return 'TypeKind.%s' % (self.name,) @@ -1594,43 +1662,16 @@ TypeKind.VARIABLEARRAY = TypeKind(115) TypeKind.DEPENDENTSIZEDARRAY = TypeKind(116) TypeKind.MEMBERPOINTER = TypeKind(117) -class RefQualifierKind(object): +class RefQualifierKind(BaseEnumeration): """Describes a specific ref-qualifier of a type.""" # The unique kind objects, indexed by id. _kinds = [] _name_map = None - def __init__(self, value): - if value >= len(RefQualifierKind._kinds): - num_kinds = value - len(RefQualifierKind._kinds) + 1 - RefQualifierKind._kinds += [None] * num_kinds - if RefQualifierKind._kinds[value] is not None: - raise ValueError, 'RefQualifierKind already loaded' - self.value = value - RefQualifierKind._kinds[value] = self - RefQualifierKind._name_map = None - def from_param(self): return self.value - @property - def name(self): - """Get the enumeration name of this kind.""" - if self._name_map is None: - self._name_map = {} - for key, value in RefQualifierKind.__dict__.items(): - if isinstance(value, RefQualifierKind): - self._name_map[value] = key - return self._name_map[self] - - @staticmethod - def from_id(id): - if (id >= len(RefQualifierKind._kinds) or - RefQualifierKind._kinds[id] is None): - raise ValueError, 'Unknown type kind %d' % id - return RefQualifierKind._kinds[id] - def __repr__(self): return 'RefQualifierKind.%s' % (self.name,) @@ -2973,6 +3014,11 @@ functionList = [ _CXString, _CXString.from_result), + ("clang_Cursor_getMangling", + [Cursor], + _CXString, + _CXString.from_result), + # ("clang_getCXTUResourceUsage", # [TranslationUnit], # CXTUResourceUsage), @@ -3300,6 +3346,27 @@ functionList = [ Cursor, Cursor.from_result), + ("clang_Cursor_getNumTemplateArguments", + [Cursor], + c_int), + + ("clang_Cursor_getTemplateArgumentKind", + [Cursor, c_uint], + TemplateArgumentKind.from_id), + + ("clang_Cursor_getTemplateArgumentType", + [Cursor, c_uint], + Type, + Type.from_result), + + ("clang_Cursor_getTemplateArgumentValue", + [Cursor, c_uint], + c_longlong), + + ("clang_Cursor_getTemplateArgumentUnsignedValue", + [Cursor, c_uint], + c_ulonglong), + ("clang_Cursor_isBitField", [Cursor], bool), diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index 431504502245..a5224aafabc1 100644 --- a/bindings/python/tests/cindex/test_cursor.py +++ b/bindings/python/tests/cindex/test_cursor.py @@ -1,6 +1,8 @@ +import ctypes import gc from clang.cindex import CursorKind +from clang.cindex import TemplateArgumentKind from clang.cindex import TranslationUnit from clang.cindex import TypeKind from .util import get_cursor @@ -244,6 +246,48 @@ def test_get_arguments(): assert arguments[0].spelling == "i" assert arguments[1].spelling == "j" +kTemplateArgTest = """\ + template <int kInt, typename T, bool kBool> + void foo(); + + template<> + void foo<-7, float, true>(); + """ + +def test_get_num_template_arguments(): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + assert foos[1].get_num_template_arguments() == 3 + +def test_get_template_argument_kind(): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + assert foos[1].get_template_argument_kind(0) == TemplateArgumentKind.INTEGRAL + assert foos[1].get_template_argument_kind(1) == TemplateArgumentKind.TYPE + assert foos[1].get_template_argument_kind(2) == TemplateArgumentKind.INTEGRAL + +def test_get_template_argument_type(): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + assert foos[1].get_template_argument_type(1).kind == TypeKind.FLOAT + +def test_get_template_argument_value(): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + assert foos[1].get_template_argument_value(0) == -7 + assert foos[1].get_template_argument_value(2) == True + +def test_get_template_argument_unsigned_value(): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + assert foos[1].get_template_argument_unsigned_value(0) == 2 ** 32 - 7 + assert foos[1].get_template_argument_unsigned_value(2) == True + def test_referenced(): tu = get_tu('void foo(); void bar() { foo(); }') foo = get_cursor(tu, 'foo') @@ -252,3 +296,17 @@ def test_referenced(): if c.kind == CursorKind.CALL_EXPR: assert c.referenced.spelling == foo.spelling break + +def test_mangled_name(): + kInputForMangling = """\ + int foo(int, int); + """ + tu = get_tu(kInputForMangling, lang='cpp') + foo = get_cursor(tu, 'foo') + + # Since libclang does not link in targets, we cannot pass a triple to it + # and force the target. To enable this test to pass on all platforms, accept + # all valid manglings. + # [c-index-test handles this by running the source through clang, emitting + # an AST file and running libclang on that AST file] + assert foo.mangled_name in ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH') diff --git a/cmake/modules/ClangConfig.cmake b/cmake/modules/ClangConfig.cmake new file mode 100644 index 000000000000..f052bb9e8c8e --- /dev/null +++ b/cmake/modules/ClangConfig.cmake @@ -0,0 +1,8 @@ +# This file allows users to call find_package(Clang) and pick up our targets. + +# Clang doesn't have any CMake configuration settings yet because it mostly +# uses LLVM's. When it does, we should move this file to ClangConfig.cmake.in +# and call configure_file() on it. + +# Provide all our library targets to users. +include("${CMAKE_CURRENT_LIST_DIR}/ClangTargets.cmake") diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst index 93a6a0ebaa50..cbdd7c65e847 100644 --- a/docs/AddressSanitizer.rst +++ b/docs/AddressSanitizer.rst @@ -165,9 +165,9 @@ problems happening in certain source files or with certain global variables. # Disable out-of-bound checks for global: global:bad_array # Disable out-of-bound checks for global instances of a given class ... - type:class.Namespace::BadClassName + type:Namespace::BadClassName # ... or a given struct. Use wildcard to deal with anonymous namespace. - type:struct.Namespace2::*::BadStructName + type:Namespace2::*::BadStructName # Disable initialization-order checks for globals: global:bad_init_global=init type:*BadInitClassSubstring*=init @@ -187,6 +187,7 @@ AddressSanitizer is supported on * Linux i386/x86\_64 (tested on Ubuntu 12.04); * MacOS 10.6 - 10.9 (i386/x86\_64). * Android ARM +* FreeBSD i386/x86\_64 (tested on FreeBSD 11-current) Ports to various other platforms are in progress. diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst index 86c5ec5e5873..45ea32717995 100644 --- a/docs/ClangFormat.rst +++ b/docs/ClangFormat.rst @@ -96,8 +96,8 @@ This can be integrated by adding the following to your `.vimrc`: .. code-block:: vim - map <C-K> :pyf <path-to-this-file>/clang-format.py<CR> - imap <C-K> <ESC>:pyf <path-to-this-file>/clang-format.py<CR>i + map <C-K> :pyf <path-to-this-file>/clang-format.py<cr> + imap <C-K> <c-o>:pyf <path-to-this-file>/clang-format.py<cr> The first line enables :program:`clang-format` for NORMAL and VISUAL mode, the second line adds support for INSERT mode. Change "C-K" to another binding if diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 07febaf3898b..ce6fae19c09b 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -33,6 +33,43 @@ The ``.clang-format`` file uses YAML format: # A comment. ... +The configuration file can consist of several sections each having different +``Language:`` parameter denoting the programming language this section of the +configuration is targeted at. See the description of the **Language** option +below for the list of supported languages. The first section may have no +language set, it will set the default style options for all lanugages. +Configuration sections for specific language will override options set in the +default section. + +When :program:`clang-format` formats a file, it auto-detects the language using +the file name. When formatting standard input or a file that doesn't have the +extension corresponding to its language, ``-assume-filename=`` option can be +used to override the file name :program:`clang-format` uses to detect the +language. + +An example of a configuration file for multiple languages: + +.. code-block:: yaml + + --- + # We'll use defaults from the LLVM style, but with 4 columns indentation. + BasedOnStyle: LLVM + IndentWidth: 4 + --- + Language: Cpp + # Force pointers to the type for C++. + DerivePointerAlignment: false + PointerAlignment: Left + --- + Language: JavaScript + # Use 100 columns for JS. + ColumnLimit: 100 + --- + Language: Proto + # Don't format .proto files. + DisableFormat: true + ... + An easy way to get a valid ``.clang-format`` file containing all configuration options of a certain predefined style is: @@ -48,6 +85,24 @@ is applied for all input files. The format of the configuration is: -style='{key1: value1, key2: value2, ...}' +Disabling Formatting on a Piece of Code +======================================= + +Clang-format understands also special comments that switch formatting in a +delimited range. The code between a comment ``// clang-format off`` or +``/* clang-format off */`` up to a comment ``// clang-format on`` or +``/* clang-format on */`` will not be formatted. The comments themselves +will be formatted (aligned) normally. + +.. code-block:: c++ + + int formatted_code; + // clang-format off + void unformatted_code ; + // clang-format on + void formatted_code_again; + + Configuring Style in Code ========================= @@ -95,10 +150,24 @@ the configuration (without a prefix: ``Auto``). **AccessModifierOffset** (``int``) The extra indent or outdent of access modifiers, e.g. ``public:``. +**AlignAfterOpenBracke |