From 461a67fa15370a9ec88f8f8a240bf7c123bb2029 Mon Sep 17 00:00:00 2001 From: Dimitry Andric Date: Dec 18 2017 20:11:37 +0000 Subject: Vendor import of clang trunk r321017: https://llvm.org/svn/llvm-project/cfe/trunk@321017 --- diff --git a/.arcconfig b/.arcconfig index 048706a..b258e7a 100644 --- a/.arcconfig +++ b/.arcconfig @@ -1,4 +1,4 @@ { - "project_id" : "clang", + "repository.callsign" : "C", "conduit_uri" : "https://reviews.llvm.org/" } diff --git a/CMakeLists.txt b/CMakeLists.txt index 2667b1d..2eee8e6 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -132,6 +132,9 @@ Please install Python or specify the PYTHON_EXECUTABLE CMake variable.") if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) # Note: path not really used, except for checking if lit was found set(LLVM_LIT ${LLVM_MAIN_SRC_DIR}/utils/lit/lit.py) + if(EXISTS ${LLVM_MAIN_SRC_DIR}/utils/llvm-lit) + add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/llvm-lit utils/llvm-lit) + endif() if(NOT LLVM_UTILS_PROVIDED) add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/FileCheck utils/FileCheck) add_subdirectory(${LLVM_MAIN_SRC_DIR}/utils/count utils/count) @@ -181,13 +184,16 @@ endif() # we can include cmake files from this directory. list(APPEND CMAKE_MODULE_PATH "${CMAKE_CURRENT_SOURCE_DIR}/cmake/modules") -find_package(LibXml2 2.5.3 QUIET) -if (LIBXML2_FOUND) - set(CLANG_HAVE_LIBXML 1) +# Don't look for libxml if we're using MSan, since uninstrumented third party +# code may call MSan interceptors like strlen, leading to false positives. +if(NOT LLVM_USE_SANITIZER MATCHES "Memory.*") + set (LIBXML2_FOUND 0) + find_package(LibXml2 2.5.3 QUIET) + if (LIBXML2_FOUND) + set(CLANG_HAVE_LIBXML 1) + endif() endif() -find_package(Z3 4.5) - include(CheckIncludeFile) check_include_file(sys/resource.h CLANG_HAVE_RLIMITS) @@ -229,9 +235,24 @@ if (NOT(CLANG_DEFAULT_RTLIB STREQUAL "" OR "Default runtime library to use (\"libgcc\" or \"compiler-rt\", empty for platform default)" FORCE) endif() +set(CLANG_DEFAULT_OBJCOPY "objcopy" CACHE STRING + "Default objcopy executable to use.") + set(CLANG_DEFAULT_OPENMP_RUNTIME "libomp" CACHE STRING "Default OpenMP runtime used by -fopenmp.") +# OpenMP offloading requires at least sm_35 because we use shuffle instructions +# to generate efficient code for reductions and the atomicMax instruction on +# 64-bit integers in the implementation of conditional lastprivate. +set(CLANG_OPENMP_NVPTX_DEFAULT_ARCH "sm_35" CACHE STRING + "Default architecture for OpenMP offloading to Nvidia GPUs.") +string(REGEX MATCH "^sm_([0-9]+)$" MATCHED_ARCH "${CLANG_OPENMP_NVPTX_DEFAULT_ARCH}") +if (NOT DEFINED MATCHED_ARCH OR "${CMAKE_MATCH_1}" LESS 35) + message(WARNING "Resetting default architecture for OpenMP offloading to Nvidia GPUs to sm_35") + set(CLANG_OPENMP_NVPTX_DEFAULT_ARCH "sm_35" CACHE STRING + "Default architecture for OpenMP offloading to Nvidia GPUs." FORCE) +endif() + set(CLANG_VENDOR ${PACKAGE_VENDOR} CACHE STRING "Vendor-specific text for showing with version information.") @@ -376,11 +397,14 @@ option(CLANG_ENABLE_STATIC_ANALYZER "Build static analyzer." ON) option(CLANG_ANALYZER_BUILD_Z3 "Build the static analyzer with the Z3 constraint manager." OFF) +option(CLANG_ENABLE_PROTO_FUZZER "Build Clang protobuf fuzzer." OFF) + if(NOT CLANG_ENABLE_STATIC_ANALYZER AND (CLANG_ENABLE_ARCMT OR CLANG_ANALYZER_BUILD_Z3)) message(FATAL_ERROR "Cannot disable static analyzer while enabling ARCMT or Z3") endif() if(CLANG_ANALYZER_BUILD_Z3) + find_package(Z3 4.5) if(Z3_FOUND) set(CLANG_ANALYZER_WITH_Z3 1) else() @@ -411,7 +435,16 @@ add_subdirectory(include) # All targets below may depend on all tablegen'd files. get_property(CLANG_TABLEGEN_TARGETS GLOBAL PROPERTY CLANG_TABLEGEN_TARGETS) -list(APPEND LLVM_COMMON_DEPENDS ${CLANG_TABLEGEN_TARGETS}) +add_custom_target(clang-tablegen-targets DEPENDS ${CLANG_TABLEGEN_TARGETS}) +set_target_properties(clang-tablegen-targets PROPERTIES FOLDER "Misc") +list(APPEND LLVM_COMMON_DEPENDS clang-tablegen-targets) + +# Force target to be built as soon as possible. Clang modules builds depend +# header-wise on it as they ship all headers from the umbrella folders. Building +# an entire module might include header, which depends on intrinsics_gen. +if(LLVM_ENABLE_MODULES AND NOT CLANG_BUILT_STANDALONE) + list(APPEND LLVM_COMMON_DEPENDS intrinsics_gen) +endif() add_subdirectory(lib) add_subdirectory(tools) @@ -508,8 +541,8 @@ if (CLANG_ENABLE_BOOTSTRAP) set(NEXT_CLANG_STAGE ${NEXT_CLANG_STAGE}-instrumented) endif() message(STATUS "Setting next clang stage to: ${NEXT_CLANG_STAGE}") - - + + set(STAMP_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-stamps/) set(BINARY_DIR ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-bins/) @@ -571,7 +604,9 @@ if (CLANG_ENABLE_BOOTSTRAP) LLVM_BINUTILS_INCDIR CLANG_REPOSITORY_STRING CMAKE_MAKE_PROGRAM - CMAKE_OSX_ARCHITECTURES) + CMAKE_OSX_ARCHITECTURES + LLVM_ENABLE_PROJECTS + LLVM_ENABLE_RUNTIMES) # We don't need to depend on compiler-rt if we're building instrumented # because the next stage will use the same compiler used to build this stage. @@ -621,7 +656,7 @@ if (CLANG_ENABLE_BOOTSTRAP) foreach(variableName ${variableNames}) if(variableName MATCHES "^BOOTSTRAP_") string(SUBSTRING ${variableName} 10 -1 varName) - string(REPLACE ";" "\;" value "${${variableName}}") + string(REPLACE ";" "|" value "${${variableName}}") list(APPEND PASSTHROUGH_VARIABLES -D${varName}=${value}) endif() @@ -637,7 +672,7 @@ if (CLANG_ENABLE_BOOTSTRAP) if("${${variableName}}" STREQUAL "") set(value "") else() - string(REPLACE ";" "\;" value ${${variableName}}) + string(REPLACE ";" "|" value "${${variableName}}") endif() list(APPEND PASSTHROUGH_VARIABLES -D${variableName}=${value}) @@ -665,6 +700,7 @@ if (CLANG_ENABLE_BOOTSTRAP) USES_TERMINAL_CONFIGURE 1 USES_TERMINAL_BUILD 1 USES_TERMINAL_INSTALL 1 + LIST_SEPARATOR | ) # exclude really-install from main target diff --git a/CODE_OWNERS.TXT b/CODE_OWNERS.TXT index 0aa156b..2fa9f21 100644 --- a/CODE_OWNERS.TXT +++ b/CODE_OWNERS.TXT @@ -25,6 +25,10 @@ N: Eric Christopher E: echristo@gmail.com D: Debug Information, inline assembly +N: Devin Coughlin +E: dcoughlin@apple.com +D: Clang Static Analyzer + N: Doug Gregor E: dgregor@apple.com D: Emeritus owner @@ -41,10 +45,6 @@ N: Anton Korobeynikov E: anton@korobeynikov.info D: Exception handling, Windows codegen, ARM EABI -N: Anna Zaks -E: ganna@apple.com -D: Clang Static Analyzer - N: John McCall E: rjmccall@apple.com D: Clang LLVM IR generation diff --git a/README.txt b/README.txt index ada9ebc..b5f33bb 100644 --- a/README.txt +++ b/README.txt @@ -13,10 +13,10 @@ different source-level tools. One example of this is the Clang Static Analyzer. If you're interested in more (including how to build Clang) it is best to read the relevant web sites. Here are some pointers: -Information on Clang: http://clang.llvm.org/ -Building and using Clang: http://clang.llvm.org/get_started.html -Clang Static Analyzer: http://clang-analyzer.llvm.org/ -Information on the LLVM project: http://llvm.org/ +Information on Clang: http://clang.llvm.org/ +Building and using Clang: http://clang.llvm.org/get_started.html +Clang Static Analyzer: http://clang-analyzer.llvm.org/ +Information on the LLVM project: http://llvm.org/ If you have questions or comments about Clang, a great place to discuss them is on the Clang development mailing list: @@ -24,3 +24,4 @@ on the Clang development mailing list: If you find a bug in Clang, please file it in the LLVM bug tracker: http://llvm.org/bugs/ + diff --git a/bindings/python/README.txt b/bindings/python/README.txt index 742cf8f..8a0bf99 100644 --- a/bindings/python/README.txt +++ b/bindings/python/README.txt @@ -5,11 +5,12 @@ This directory implements Python bindings for Clang. You may need to alter LD_LIBRARY_PATH so that the Clang library can be -found. The unit tests are designed to be run with 'nosetests'. For example: +found. The unit tests are designed to be run with any standard test +runner. For example: -- $ env PYTHONPATH=$(echo ~/llvm/tools/clang/bindings/python/) \ LD_LIBRARY_PATH=$(llvm-config --libdir) \ - nosetests -v + python -m unittest discover -v tests.cindex.test_index.test_create ... ok ... diff --git a/bindings/python/clang/cindex.py b/bindings/python/clang/cindex.py index 4069ab8..b53661a 100644 --- a/bindings/python/clang/cindex.py +++ b/bindings/python/clang/cindex.py @@ -94,6 +94,9 @@ if sys.version_info[0] == 3: return cls(param) if isinstance(param, bytes): return cls(param) + if param is None: + # Support passing null to C functions expecting char arrays + return None raise TypeError("Cannot convert '{}' to '{}'".format(type(param).__name__, cls.__name__)) @staticmethod @@ -1476,6 +1479,12 @@ class Cursor(Structure): """ return conf.lib.clang_CXXMethod_isVirtual(self) + def is_abstract_record(self): + """Returns True if the cursor refers to a C++ record declaration + that has pure virtual member functions. + """ + return conf.lib.clang_CXXRecord_isAbstract(self) + def is_scoped_enum(self): """Returns True if the cursor refers to a scoped enum declaration. """ @@ -1549,6 +1558,22 @@ class Cursor(Structure): return self._loc @property + def linkage(self): + """Return the linkage of this cursor.""" + if not hasattr(self, '_linkage'): + self._linkage = conf.lib.clang_getCursorLinkage(self) + + return LinkageKind.from_id(self._linkage) + + @property + def tls_kind(self): + """Return the thread-local storage (TLS) kind of this cursor.""" + if not hasattr(self, '_tls_kind'): + self._tls_kind = conf.lib.clang_getCursorTLSKind(self) + + return TLSKind.from_id(self._tls_kind) + + @property def extent(self): """ Return the source range (the range of text) occupied by the entity @@ -1571,6 +1596,16 @@ class Cursor(Structure): return StorageClass.from_id(self._storage_class) @property + def availability(self): + """ + Retrieves the availability of the entity pointed at by the cursor. + """ + if not hasattr(self, '_availability'): + self._availability = conf.lib.clang_getCursorAvailability(self) + + return AvailabilityKind.from_id(self._availability) + + @property def access_specifier(self): """ Retrieves the access specifier (if any) of the entity pointed at by the @@ -1907,6 +1942,24 @@ StorageClass.OPENCLWORKGROUPLOCAL = StorageClass(5) StorageClass.AUTO = StorageClass(6) StorageClass.REGISTER = StorageClass(7) +### Availability Kinds ### + +class AvailabilityKind(BaseEnumeration): + """ + Describes the availability of an entity. + """ + + # The unique kind objects, indexed by id. + _kinds = [] + _name_map = None + + def __repr__(self): + return 'AvailabilityKind.%s' % (self.name,) + +AvailabilityKind.AVAILABLE = AvailabilityKind(0) +AvailabilityKind.DEPRECATED = AvailabilityKind(1) +AvailabilityKind.NOT_AVAILABLE = AvailabilityKind(2) +AvailabilityKind.NOT_ACCESSIBLE = AvailabilityKind(3) ### C++ access specifiers ### @@ -2061,6 +2114,42 @@ RefQualifierKind.NONE = RefQualifierKind(0) RefQualifierKind.LVALUE = RefQualifierKind(1) RefQualifierKind.RVALUE = RefQualifierKind(2) +class LinkageKind(BaseEnumeration): + """Describes the kind of linkage of a cursor.""" + + # The unique kind objects, indexed by id. + _kinds = [] + _name_map = None + + def from_param(self): + return self.value + + def __repr__(self): + return 'LinkageKind.%s' % (self.name,) + +LinkageKind.INVALID = LinkageKind(0) +LinkageKind.NO_LINKAGE = LinkageKind(1) +LinkageKind.INTERNAL = LinkageKind(2) +LinkageKind.UNIQUE_EXTERNAL = LinkageKind(3) +LinkageKind.EXTERNAL = LinkageKind(4) + +class TLSKind(BaseEnumeration): + """Describes the kind of thread-local storage (TLS) of a cursor.""" + + # The unique kind objects, indexed by id. + _kinds = [] + _name_map = None + + def from_param(self): + return self.value + + def __repr__(self): + return 'TLSKind.%s' % (self.name,) + +TLSKind.NONE = TLSKind(0) +TLSKind.DYNAMIC = TLSKind(1) +TLSKind.STATIC = TLSKind(2) + class Type(Structure): """ The type of an element in the abstract syntax tree. @@ -3191,6 +3280,7 @@ class Token(Structure): def cursor(self): """The Cursor this Token corresponds to.""" cursor = Cursor() + cursor._tu = self._tu conf.lib.clang_annotateTokens(self._tu, byref(self), 1, byref(cursor)) @@ -3317,6 +3407,10 @@ functionList = [ [Cursor], bool), + ("clang_CXXRecord_isAbstract", + [Cursor], + bool), + ("clang_EnumDecl_isScoped", [Cursor], bool), @@ -3438,6 +3532,10 @@ functionList = [ [TranslationUnit, SourceLocation], Cursor), + ("clang_getCursorAvailability", + [Cursor], + c_int), + ("clang_getCursorDefinition", [Cursor], Cursor, @@ -4053,6 +4151,7 @@ conf = Config() register_enumerations() __all__ = [ + 'AvailabilityKind', 'Config', 'CodeCompletionResults', 'CompilationDatabase', @@ -4064,8 +4163,10 @@ __all__ = [ 'File', 'FixIt', 'Index', + 'LinkageKind', 'SourceLocation', 'SourceRange', + 'TLSKind', 'TokenKind', 'Token', 'TranslationUnitLoadError', diff --git a/bindings/python/tests/cindex/test_access_specifiers.py b/bindings/python/tests/cindex/test_access_specifiers.py index cfa04dc..2f6144b 100644 --- a/bindings/python/tests/cindex/test_access_specifiers.py +++ b/bindings/python/tests/cindex/test_access_specifiers.py @@ -6,10 +6,14 @@ from clang.cindex import TranslationUnit from .util import get_cursor from .util import get_tu -def test_access_specifiers(): - """Ensure that C++ access specifiers are available on cursors""" +import unittest - tu = get_tu(""" + +class TestAccessSpecifiers(unittest.TestCase): + def test_access_specifiers(self): + """Ensure that C++ access specifiers are available on cursors""" + + tu = get_tu(""" class test_class { public: void public_member_function(); @@ -20,15 +24,14 @@ private: }; """, lang = 'cpp') - test_class = get_cursor(tu, "test_class") - assert test_class.access_specifier == AccessSpecifier.INVALID; - - public = get_cursor(tu.cursor, "public_member_function") - assert public.access_specifier == AccessSpecifier.PUBLIC + test_class = get_cursor(tu, "test_class") + self.assertEqual(test_class.access_specifier, AccessSpecifier.INVALID) - protected = get_cursor(tu.cursor, "protected_member_function") - assert protected.access_specifier == AccessSpecifier.PROTECTED + public = get_cursor(tu.cursor, "public_member_function") + self.assertEqual(public.access_specifier, AccessSpecifier.PUBLIC) - private = get_cursor(tu.cursor, "private_member_function") - assert private.access_specifier == AccessSpecifier.PRIVATE + protected = get_cursor(tu.cursor, "protected_member_function") + self.assertEqual(protected.access_specifier, AccessSpecifier.PROTECTED) + private = get_cursor(tu.cursor, "private_member_function") + self.assertEqual(private.access_specifier, AccessSpecifier.PRIVATE) diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py index 35fe3e1..bd6e773 100644 --- a/bindings/python/tests/cindex/test_cdb.py +++ b/bindings/python/tests/cindex/test_cdb.py @@ -4,114 +4,116 @@ from clang.cindex import CompileCommands from clang.cindex import CompileCommand import os import gc +import unittest + kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') -def test_create_fail(): - """Check we fail loading a database with an assertion""" - path = os.path.dirname(__file__) - try: - cdb = CompilationDatabase.fromDirectory(path) - except CompilationDatabaseError as e: - assert e.cdb_error == CompilationDatabaseError.ERROR_CANNOTLOADDATABASE - else: - assert False -def test_create(): - """Check we can load a compilation database""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) +class TestCDB(unittest.TestCase): + def test_create_fail(self): + """Check we fail loading a database with an assertion""" + path = os.path.dirname(__file__) + with self.assertRaises(CompilationDatabaseError) as cm: + cdb = CompilationDatabase.fromDirectory(path) + e = cm.exception + self.assertEqual(e.cdb_error, + CompilationDatabaseError.ERROR_CANNOTLOADDATABASE) -def test_lookup_fail(): - """Check file lookup failure""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - assert cdb.getCompileCommands('file_do_not_exist.cpp') == None + def test_create(self): + """Check we can load a compilation database""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) -def test_lookup_succeed(): - """Check we get some results if the file exists in the db""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') - assert len(cmds) != 0 + def test_lookup_fail(self): + """Check file lookup failure""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + self.assertIsNone(cdb.getCompileCommands('file_do_not_exist.cpp')) -def test_all_compilecommand(): - """Check we get all results from the db""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - cmds = cdb.getAllCompileCommands() - assert len(cmds) == 3 - expected = [ - { 'wd': '/home/john.doe/MyProject', - 'file': '/home/john.doe/MyProject/project.cpp', - 'line': ['clang++', '-o', 'project.o', '-c', - '/home/john.doe/MyProject/project.cpp']}, - { 'wd': '/home/john.doe/MyProjectA', - 'file': '/home/john.doe/MyProject/project2.cpp', - 'line': ['clang++', '-o', 'project2.o', '-c', - '/home/john.doe/MyProject/project2.cpp']}, - { 'wd': '/home/john.doe/MyProjectB', - 'file': '/home/john.doe/MyProject/project2.cpp', - 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', - '/home/john.doe/MyProject/project2.cpp']}, + def test_lookup_succeed(self): + """Check we get some results if the file exists in the db""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') + self.assertNotEqual(len(cmds), 0) - ] - for i in range(len(cmds)): - assert cmds[i].directory == expected[i]['wd'] - assert cmds[i].filename == expected[i]['file'] - for arg, exp in zip(cmds[i].arguments, expected[i]['line']): - assert arg == exp + def test_all_compilecommand(self): + """Check we get all results from the db""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + cmds = cdb.getAllCompileCommands() + self.assertEqual(len(cmds), 3) + expected = [ + { 'wd': '/home/john.doe/MyProject', + 'file': '/home/john.doe/MyProject/project.cpp', + 'line': ['clang++', '-o', 'project.o', '-c', + '/home/john.doe/MyProject/project.cpp']}, + { 'wd': '/home/john.doe/MyProjectA', + 'file': '/home/john.doe/MyProject/project2.cpp', + 'line': ['clang++', '-o', 'project2.o', '-c', + '/home/john.doe/MyProject/project2.cpp']}, + { 'wd': '/home/john.doe/MyProjectB', + 'file': '/home/john.doe/MyProject/project2.cpp', + 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', + '/home/john.doe/MyProject/project2.cpp']}, -def test_1_compilecommand(): - """Check file with single compile command""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - file = '/home/john.doe/MyProject/project.cpp' - cmds = cdb.getCompileCommands(file) - assert len(cmds) == 1 - assert cmds[0].directory == os.path.dirname(file) - assert cmds[0].filename == file - expected = [ 'clang++', '-o', 'project.o', '-c', - '/home/john.doe/MyProject/project.cpp'] - for arg, exp in zip(cmds[0].arguments, expected): - assert arg == exp + ] + for i in range(len(cmds)): + self.assertEqual(cmds[i].directory, expected[i]['wd']) + self.assertEqual(cmds[i].filename, expected[i]['file']) + for arg, exp in zip(cmds[i].arguments, expected[i]['line']): + self.assertEqual(arg, exp) -def test_2_compilecommand(): - """Check file with 2 compile commands""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp') - assert len(cmds) == 2 - expected = [ - { 'wd': '/home/john.doe/MyProjectA', - 'line': ['clang++', '-o', 'project2.o', '-c', - '/home/john.doe/MyProject/project2.cpp']}, - { 'wd': '/home/john.doe/MyProjectB', - 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', - '/home/john.doe/MyProject/project2.cpp']} - ] - for i in range(len(cmds)): - assert cmds[i].directory == expected[i]['wd'] - for arg, exp in zip(cmds[i].arguments, expected[i]['line']): - assert arg == exp + def test_1_compilecommand(self): + """Check file with single compile command""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + file = '/home/john.doe/MyProject/project.cpp' + cmds = cdb.getCompileCommands(file) + self.assertEqual(len(cmds), 1) + self.assertEqual(cmds[0].directory, os.path.dirname(file)) + self.assertEqual(cmds[0].filename, file) + expected = [ 'clang++', '-o', 'project.o', '-c', + '/home/john.doe/MyProject/project.cpp'] + for arg, exp in zip(cmds[0].arguments, expected): + self.assertEqual(arg, exp) -def test_compilecommand_iterator_stops(): - """Check that iterator stops after the correct number of elements""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - count = 0 - for cmd in cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp'): - count += 1 - assert count <= 2 + def test_2_compilecommand(self): + """Check file with 2 compile commands""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp') + self.assertEqual(len(cmds), 2) + expected = [ + { 'wd': '/home/john.doe/MyProjectA', + 'line': ['clang++', '-o', 'project2.o', '-c', + '/home/john.doe/MyProject/project2.cpp']}, + { 'wd': '/home/john.doe/MyProjectB', + 'line': ['clang++', '-DFEATURE=1', '-o', 'project2-feature.o', '-c', + '/home/john.doe/MyProject/project2.cpp']} + ] + for i in range(len(cmds)): + self.assertEqual(cmds[i].directory, expected[i]['wd']) + for arg, exp in zip(cmds[i].arguments, expected[i]['line']): + self.assertEqual(arg, exp) -def test_compilationDB_references(): - """Ensure CompilationsCommands are independent of the database""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') - del cdb - gc.collect() - workingdir = cmds[0].directory + def test_compilecommand_iterator_stops(self): + """Check that iterator stops after the correct number of elements""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + count = 0 + for cmd in cdb.getCompileCommands('/home/john.doe/MyProject/project2.cpp'): + count += 1 + self.assertLessEqual(count, 2) -def test_compilationCommands_references(): - """Ensure CompilationsCommand keeps a reference to CompilationCommands""" - cdb = CompilationDatabase.fromDirectory(kInputsDir) - cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') - del cdb - cmd0 = cmds[0] - del cmds - gc.collect() - workingdir = cmd0.directory + def test_compilationDB_references(self): + """Ensure CompilationsCommands are independent of the database""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') + del cdb + gc.collect() + workingdir = cmds[0].directory + def test_compilationCommands_references(self): + """Ensure CompilationsCommand keeps a reference to CompilationCommands""" + cdb = CompilationDatabase.fromDirectory(kInputsDir) + cmds = cdb.getCompileCommands('/home/john.doe/MyProject/project.cpp') + del cdb + cmd0 = cmds[0] + del cmds + gc.collect() + workingdir = cmd0.directory diff --git a/bindings/python/tests/cindex/test_code_completion.py b/bindings/python/tests/cindex/test_code_completion.py index 357d50d..a56bb30 100644 --- a/bindings/python/tests/cindex/test_code_completion.py +++ b/bindings/python/tests/cindex/test_code_completion.py @@ -1,16 +1,20 @@ from clang.cindex import TranslationUnit -def check_completion_results(cr, expected): - assert cr is not None - assert len(cr.diagnostics) == 0 +import unittest - completions = [str(c) for c in cr.results] - for c in expected: - assert c in completions +class TestCodeCompletion(unittest.TestCase): + def check_completion_results(self, cr, expected): + self.assertIsNotNone(cr) + self.assertEqual(len(cr.diagnostics), 0) -def test_code_complete(): - files = [('fake.c', """ + completions = [str(c) for c in cr.results] + + for c in expected: + self.assertIn(c, completions) + + def test_code_complete(self): + files = [('fake.c', """ /// Aaa. int test1; @@ -22,20 +26,20 @@ void f() { } """)] - tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files, - options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION) + tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files, + options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION) - cr = tu.codeComplete('fake.c', 9, 1, unsaved_files=files, include_brief_comments=True) + cr = tu.codeComplete('fake.c', 9, 1, unsaved_files=files, include_brief_comments=True) - expected = [ - "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", - "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", - "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None" - ] - check_completion_results(cr, expected) + expected = [ + "{'int', ResultType} | {'test1', TypedText} || Priority: 50 || Availability: Available || Brief comment: Aaa.", + "{'void', ResultType} | {'test2', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 50 || Availability: Available || Brief comment: Bbb.", + "{'return', TypedText} || Priority: 40 || Availability: Available || Brief comment: None" + ] + self.check_completion_results(cr, expected) -def test_code_complete_availability(): - files = [('fake.cpp', """ + def test_code_complete_availability(self): + files = [('fake.cpp', """ class P { protected: int member; @@ -52,24 +56,24 @@ void f(P x, Q y) { } """)] - tu = TranslationUnit.from_source('fake.cpp', ['-std=c++98'], unsaved_files=files) - - cr = tu.codeComplete('fake.cpp', 12, 5, unsaved_files=files) - - expected = [ - "{'const', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", - "{'volatile', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", - "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", - "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None", - "{'Q', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None" - ] - check_completion_results(cr, expected) - - cr = tu.codeComplete('fake.cpp', 13, 5, unsaved_files=files) - expected = [ - "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None", - "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 34 || Availability: Available || Brief comment: None", - "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: None", - "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 34 || Availability: Available || Brief comment: None" - ] - check_completion_results(cr, expected) + tu = TranslationUnit.from_source('fake.cpp', ['-std=c++98'], unsaved_files=files) + + cr = tu.codeComplete('fake.cpp', 12, 5, unsaved_files=files) + + expected = [ + "{'const', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", + "{'volatile', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", + "{'operator', TypedText} || Priority: 40 || Availability: Available || Brief comment: None", + "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None", + "{'Q', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None" + ] + self.check_completion_results(cr, expected) + + cr = tu.codeComplete('fake.cpp', 13, 5, unsaved_files=files) + expected = [ + "{'P', TypedText} | {'::', Text} || Priority: 75 || Availability: Available || Brief comment: None", + "{'P &', ResultType} | {'operator=', TypedText} | {'(', LeftParen} | {'const P &', Placeholder} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None", + "{'int', ResultType} | {'member', TypedText} || Priority: 35 || Availability: NotAccessible || Brief comment: None", + "{'void', ResultType} | {'~P', TypedText} | {'(', LeftParen} | {')', RightParen} || Priority: 79 || Availability: Available || Brief comment: None" + ] + self.check_completion_results(cr, expected) diff --git a/bindings/python/tests/cindex/test_comment.py b/bindings/python/tests/cindex/test_comment.py index d8f3129..d6c6d8e 100644 --- a/bindings/python/tests/cindex/test_comment.py +++ b/bindings/python/tests/cindex/test_comment.py @@ -1,8 +1,12 @@ from clang.cindex import TranslationUnit from tests.cindex.util import get_cursor -def test_comment(): - files = [('fake.c', """ +import unittest + + +class TestComment(unittest.TestCase): + def test_comment(self): + files = [('fake.c', """ /// Aaa. int test1; @@ -14,27 +18,25 @@ void f() { } """)] - # make a comment-aware TU - tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files, - options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION) - test1 = get_cursor(tu, 'test1') - assert test1 is not None, "Could not find test1." - assert test1.type.is_pod() - raw = test1.raw_comment - brief = test1.brief_comment - assert raw == """/// Aaa.""" - assert brief == """Aaa.""" - - test2 = get_cursor(tu, 'test2') - raw = test2.raw_comment - brief = test2.brief_comment - assert raw == """/// Bbb.\n/// x""" - assert brief == """Bbb. x""" - - f = get_cursor(tu, 'f') - raw = f.raw_comment - brief = f.brief_comment - assert raw is None - assert brief is None + # make a comment-aware TU + tu = TranslationUnit.from_source('fake.c', ['-std=c99'], unsaved_files=files, + options=TranslationUnit.PARSE_INCLUDE_BRIEF_COMMENTS_IN_CODE_COMPLETION) + test1 = get_cursor(tu, 'test1') + self.assertIsNotNone(test1, "Could not find test1.") + self.assertTrue(test1.type.is_pod()) + raw = test1.raw_comment + brief = test1.brief_comment + self.assertEqual(raw, """/// Aaa.""") + self.assertEqual(brief, """Aaa.""") + test2 = get_cursor(tu, 'test2') + raw = test2.raw_comment + brief = test2.brief_comment + self.assertEqual(raw, """/// Bbb.\n/// x""") + self.assertEqual(brief, """Bbb. x""") + f = get_cursor(tu, 'f') + raw = f.raw_comment + brief = f.brief_comment + self.assertIsNone(raw) + self.assertIsNone(brief) diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index 4787ea9..c2a4eb5 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 +import unittest +from clang.cindex import AvailabilityKind from clang.cindex import CursorKind from clang.cindex import TemplateArgumentKind from clang.cindex import TranslationUnit @@ -9,6 +11,7 @@ from .util import get_cursor from .util import get_cursors from .util import get_tu + kInput = """\ struct s0 { int a; @@ -29,257 +32,6 @@ void f0(int a0, int a1) { } """ -def test_get_children(): - tu = get_tu(kInput) - - it = tu.cursor.get_children() - tu_nodes = list(it) - - assert len(tu_nodes) == 3 - for cursor in tu_nodes: - assert cursor.translation_unit is not None - - assert tu_nodes[0] != tu_nodes[1] - assert tu_nodes[0].kind == CursorKind.STRUCT_DECL - assert tu_nodes[0].spelling == 's0' - assert tu_nodes[0].is_definition() == True - assert tu_nodes[0].location.file.name == 't.c' - assert tu_nodes[0].location.line == 1 - assert tu_nodes[0].location.column == 8 - assert tu_nodes[0].hash > 0 - assert tu_nodes[0].translation_unit is not None - - s0_nodes = list(tu_nodes[0].get_children()) - assert len(s0_nodes) == 2 - assert s0_nodes[0].kind == CursorKind.FIELD_DECL - assert s0_nodes[0].spelling == 'a' - assert s0_nodes[0].type.kind == TypeKind.INT - assert s0_nodes[1].kind == CursorKind.FIELD_DECL - assert s0_nodes[1].spelling == 'b' - assert s0_nodes[1].type.kind == TypeKind.INT - - assert tu_nodes[1].kind == CursorKind.STRUCT_DECL - assert tu_nodes[1].spelling == 's1' - assert tu_nodes[1].displayname == 's1' - assert tu_nodes[1].is_definition() == False - - assert tu_nodes[2].kind == CursorKind.FUNCTION_DECL - assert tu_nodes[2].spelling == 'f0' - assert tu_nodes[2].displayname == 'f0(int, int)' - assert tu_nodes[2].is_definition() == True - -def test_references(): - """Ensure that references to TranslationUnit are kept.""" - tu = get_tu('int x;') - cursors = list(tu.cursor.get_children()) - assert len(cursors) > 0 - - cursor = cursors[0] - assert isinstance(cursor.translation_unit, TranslationUnit) - - # Delete reference to TU and perform a full GC. - del tu - gc.collect() - assert isinstance(cursor.translation_unit, TranslationUnit) - - # If the TU was destroyed, this should cause a segfault. - parent = cursor.semantic_parent - -def test_canonical(): - source = 'struct X; struct X; struct X { int member; };' - tu = get_tu(source) - - cursors = [] - for cursor in tu.cursor.get_children(): - if cursor.spelling == 'X': - cursors.append(cursor) - - assert len(cursors) == 3 - assert cursors[1].canonical == cursors[2].canonical - -def test_is_const_method(): - """Ensure Cursor.is_const_method works.""" - source = 'class X { void foo() const; void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_const_method() - assert not bar.is_const_method() - -def test_is_converting_constructor(): - """Ensure Cursor.is_converting_constructor works.""" - source = 'class X { explicit X(int); X(double); X(); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - - assert len(xs) == 4 - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - assert cs[2].kind == CursorKind.CONSTRUCTOR - - assert not cs[0].is_converting_constructor() - assert cs[1].is_converting_constructor() - assert not cs[2].is_converting_constructor() - - -def test_is_copy_constructor(): - """Ensure Cursor.is_copy_constructor works.""" - source = 'class X { X(); X(const X&); X(X&&); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - assert cs[2].kind == CursorKind.CONSTRUCTOR - - assert not cs[0].is_copy_constructor() - assert cs[1].is_copy_constructor() - assert not cs[2].is_copy_constructor() - -def test_is_default_constructor(): - """Ensure Cursor.is_default_constructor works.""" - source = 'class X { X(); X(int); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - - assert cs[0].is_default_constructor() - assert not cs[1].is_default_constructor() - -def test_is_move_constructor(): - """Ensure Cursor.is_move_constructor works.""" - source = 'class X { X(); X(const X&); X(X&&); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - assert xs[0].kind == CursorKind.CLASS_DECL - cs = xs[1:] - assert cs[0].kind == CursorKind.CONSTRUCTOR - assert cs[1].kind == CursorKind.CONSTRUCTOR - assert cs[2].kind == CursorKind.CONSTRUCTOR - - assert not cs[0].is_move_constructor() - assert not cs[1].is_move_constructor() - assert cs[2].is_move_constructor() - -def test_is_default_method(): - """Ensure Cursor.is_default_method works.""" - source = 'class X { X() = default; }; class Y { Y(); };' - tu = get_tu(source, lang='cpp') - - xs = get_cursors(tu, 'X') - ys = get_cursors(tu, 'Y') - - assert len(xs) == 2 - assert len(ys) == 2 - - xc = xs[1] - yc = ys[1] - - assert xc.is_default_method() - assert not yc.is_default_method() - -def test_is_mutable_field(): - """Ensure Cursor.is_mutable_field works.""" - source = 'class X { int x_; mutable int y_; };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - x_ = get_cursor(tu, 'x_') - y_ = get_cursor(tu, 'y_') - assert cls is not None - assert x_ is not None - assert y_ is not None - - assert not x_.is_mutable_field() - assert y_.is_mutable_field() - -def test_is_static_method(): - """Ensure Cursor.is_static_method works.""" - - source = 'class X { static void foo(); void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_static_method() - assert not bar.is_static_method() - -def test_is_pure_virtual_method(): - """Ensure Cursor.is_pure_virtual_method works.""" - source = 'class X { virtual void foo() = 0; virtual void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_pure_virtual_method() - assert not bar.is_pure_virtual_method() - -def test_is_virtual_method(): - """Ensure Cursor.is_virtual_method works.""" - source = 'class X { virtual void foo(); void bar(); };' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - assert cls is not None - assert foo is not None - assert bar is not None - - assert foo.is_virtual_method() - assert not bar.is_virtual_method() - -def test_is_scoped_enum(): - """Ensure Cursor.is_scoped_enum works.""" - source = 'class X {}; enum RegularEnum {}; enum class ScopedEnum {};' - tu = get_tu(source, lang='cpp') - - cls = get_cursor(tu, 'X') - regular_enum = get_cursor(tu, 'RegularEnum') - scoped_enum = get_cursor(tu, 'ScopedEnum') - assert cls is not None - assert regular_enum is not None - assert scoped_enum is not None - - assert not cls.is_scoped_enum() - assert not regular_enum.is_scoped_enum() - assert scoped_enum.is_scoped_enum() - -def test_underlying_type(): - tu = get_tu('typedef int foo;') - typedef = get_cursor(tu, 'foo') - assert typedef is not None - - assert typedef.kind.is_declaration() - underlying = typedef.underlying_typedef_type - assert underlying.kind == TypeKind.INT - kParentTest = """\ class C { void f(); @@ -287,122 +39,6 @@ kParentTest = """\ void C::f() { } """ -def test_semantic_parent(): - tu = get_tu(kParentTest, 'cpp') - curs = get_cursors(tu, 'f') - decl = get_cursor(tu, 'C') - assert(len(curs) == 2) - assert(curs[0].semantic_parent == curs[1].semantic_parent) - assert(curs[0].semantic_parent == decl) - -def test_lexical_parent(): - tu = get_tu(kParentTest, 'cpp') - curs = get_cursors(tu, 'f') - decl = get_cursor(tu, 'C') - assert(len(curs) == 2) - assert(curs[0].lexical_parent != curs[1].lexical_parent) - assert(curs[0].lexical_parent == decl) - assert(curs[1].lexical_parent == tu.cursor) - -def test_enum_type(): - tu = get_tu('enum TEST { FOO=1, BAR=2 };') - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - enum_type = enum.enum_type - assert enum_type.kind == TypeKind.UINT - -def test_enum_type_cpp(): - tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp") - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - assert enum.enum_type.kind == TypeKind.LONGLONG - -def test_objc_type_encoding(): - tu = get_tu('int i;', lang='objc') - i = get_cursor(tu, 'i') - - assert i is not None - assert i.objc_type_encoding == 'i' - -def test_enum_values(): - tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};') - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - - enum_constants = list(enum.get_children()) - assert len(enum_constants) == 3 - - spam, egg, ham = enum_constants - - assert spam.kind == CursorKind.ENUM_CONSTANT_DECL - assert spam.enum_value == 1 - assert egg.kind == CursorKind.ENUM_CONSTANT_DECL - assert egg.enum_value == 2 - assert ham.kind == CursorKind.ENUM_CONSTANT_DECL - assert ham.enum_value == 40 - -def test_enum_values_cpp(): - tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp") - enum = get_cursor(tu, 'TEST') - assert enum is not None - - assert enum.kind == CursorKind.ENUM_DECL - - enum_constants = list(enum.get_children()) - assert len(enum_constants) == 2 - - spam, ham = enum_constants - - assert spam.kind == CursorKind.ENUM_CONSTANT_DECL - assert spam.enum_value == -1 - assert ham.kind == CursorKind.ENUM_CONSTANT_DECL - assert ham.enum_value == 0x10000000000 - -def test_annotation_attribute(): - tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));') - - foo = get_cursor(tu, 'foo') - assert foo is not None - - for c in foo.get_children(): - if c.kind == CursorKind.ANNOTATE_ATTR: - assert c.displayname == "here be annotation attribute" - break - else: - assert False, "Couldn't find annotation" - -def test_result_type(): - tu = get_tu('int foo();') - foo = get_cursor(tu, 'foo') - - assert foo is not None - t = foo.result_type - assert t.kind == TypeKind.INT - -def test_get_tokens(): - """Ensure we can map cursors back to tokens.""" - tu = get_tu('int foo(int i);') - foo = get_cursor(tu, 'foo') - - tokens = list(foo.get_tokens()) - assert len(tokens) == 6 - assert tokens[0].spelling == 'int' - assert tokens[1].spelling == 'foo' - -def test_get_arguments(): - tu = get_tu('void foo(int i, int j);') - foo = get_cursor(tu, 'foo') - arguments = list(foo.get_arguments()) - - assert len(arguments) == 2 - assert arguments[0].spelling == "i" - assert arguments[1].spelling == "j" kTemplateArgTest = """\ template @@ -412,59 +48,505 @@ kTemplateArgTest = """\ 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') - bar = get_cursor(tu, 'bar') - for c in bar.get_children(): - 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') +class TestCursor(unittest.TestCase): + def test_get_children(self): + tu = get_tu(kInput) + + it = tu.cursor.get_children() + tu_nodes = list(it) + + self.assertEqual(len(tu_nodes), 3) + for cursor in tu_nodes: + self.assertIsNotNone(cursor.translation_unit) + + self.assertNotEqual(tu_nodes[0], tu_nodes[1]) + self.assertEqual(tu_nodes[0].kind, CursorKind.STRUCT_DECL) + self.assertEqual(tu_nodes[0].spelling, 's0') + self.assertEqual(tu_nodes[0].is_definition(), True) + self.assertEqual(tu_nodes[0].location.file.name, 't.c') + self.assertEqual(tu_nodes[0].location.line, 1) + self.assertEqual(tu_nodes[0].location.column, 8) + self.assertGreater(tu_nodes[0].hash, 0) + self.assertIsNotNone(tu_nodes[0].translation_unit) + + s0_nodes = list(tu_nodes[0].get_children()) + self.assertEqual(len(s0_nodes), 2) + self.assertEqual(s0_nodes[0].kind, CursorKind.FIELD_DECL) + self.assertEqual(s0_nodes[0].spelling, 'a') + self.assertEqual(s0_nodes[0].type.kind, TypeKind.INT) + self.assertEqual(s0_nodes[1].kind, CursorKind.FIELD_DECL) + self.assertEqual(s0_nodes[1].spelling, 'b') + self.assertEqual(s0_nodes[1].type.kind, TypeKind.INT) + + self.assertEqual(tu_nodes[1].kind, CursorKind.STRUCT_DECL) + self.assertEqual(tu_nodes[1].spelling, 's1') + self.assertEqual(tu_nodes[1].displayname, 's1') + self.assertEqual(tu_nodes[1].is_definition(), False) + + self.assertEqual(tu_nodes[2].kind, CursorKind.FUNCTION_DECL) + self.assertEqual(tu_nodes[2].spelling, 'f0') + self.assertEqual(tu_nodes[2].displayname, 'f0(int, int)') + self.assertEqual(tu_nodes[2].is_definition(), True) + + def test_references(self): + """Ensure that references to TranslationUnit are kept.""" + tu = get_tu('int x;') + cursors = list(tu.cursor.get_children()) + self.assertGreater(len(cursors), 0) + + cursor = cursors[0] + self.assertIsInstance(cursor.translation_unit, TranslationUnit) + + # Delete reference to TU and perform a full GC. + del tu + gc.collect() + self.assertIsInstance(cursor.translation_unit, TranslationUnit) + + # If the TU was destroyed, this should cause a segfault. + parent = cursor.semantic_parent + + def test_canonical(self): + source = 'struct X; struct X; struct X { int member; };' + tu = get_tu(source) + + cursors = [] + for cursor in tu.cursor.get_children(): + if cursor.spelling == 'X': + cursors.append(cursor) + + self.assertEqual(len(cursors), 3) + self.assertEqual(cursors[1].canonical, cursors[2].canonical) + + def test_is_const_method(self): + """Ensure Cursor.is_const_method works.""" + source = 'class X { void foo() const; void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_const_method()) + self.assertFalse(bar.is_const_method()) + + def test_is_converting_constructor(self): + """Ensure Cursor.is_converting_constructor works.""" + source = 'class X { explicit X(int); X(double); X(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + + self.assertEqual(len(xs), 4) + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) + + self.assertFalse(cs[0].is_converting_constructor()) + self.assertTrue(cs[1].is_converting_constructor()) + self.assertFalse(cs[2].is_converting_constructor()) + + + def test_is_copy_constructor(self): + """Ensure Cursor.is_copy_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) + + self.assertFalse(cs[0].is_copy_constructor()) + self.assertTrue(cs[1].is_copy_constructor()) + self.assertFalse(cs[2].is_copy_constructor()) + + def test_is_default_constructor(self): + """Ensure Cursor.is_default_constructor works.""" + source = 'class X { X(); X(int); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + + self.assertTrue(cs[0].is_default_constructor()) + self.assertFalse(cs[1].is_default_constructor()) + + def test_is_move_constructor(self): + """Ensure Cursor.is_move_constructor works.""" + source = 'class X { X(); X(const X&); X(X&&); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + self.assertEqual(xs[0].kind, CursorKind.CLASS_DECL) + cs = xs[1:] + self.assertEqual(cs[0].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[1].kind, CursorKind.CONSTRUCTOR) + self.assertEqual(cs[2].kind, CursorKind.CONSTRUCTOR) + + self.assertFalse(cs[0].is_move_constructor()) + self.assertFalse(cs[1].is_move_constructor()) + self.assertTrue(cs[2].is_move_constructor()) + + def test_is_default_method(self): + """Ensure Cursor.is_default_method works.""" + source = 'class X { X() = default; }; class Y { Y(); };' + tu = get_tu(source, lang='cpp') + + xs = get_cursors(tu, 'X') + ys = get_cursors(tu, 'Y') + + self.assertEqual(len(xs), 2) + self.assertEqual(len(ys), 2) + + xc = xs[1] + yc = ys[1] + + self.assertTrue(xc.is_default_method()) + self.assertFalse(yc.is_default_method()) + + def test_is_mutable_field(self): + """Ensure Cursor.is_mutable_field works.""" + source = 'class X { int x_; mutable int y_; };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + x_ = get_cursor(tu, 'x_') + y_ = get_cursor(tu, 'y_') + self.assertIsNotNone(cls) + self.assertIsNotNone(x_) + self.assertIsNotNone(y_) + + self.assertFalse(x_.is_mutable_field()) + self.assertTrue(y_.is_mutable_field()) + + def test_is_static_method(self): + """Ensure Cursor.is_static_method works.""" + + source = 'class X { static void foo(); void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_static_method()) + self.assertFalse(bar.is_static_method()) + + def test_is_pure_virtual_method(self): + """Ensure Cursor.is_pure_virtual_method works.""" + source = 'class X { virtual void foo() = 0; virtual void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_pure_virtual_method()) + self.assertFalse(bar.is_pure_virtual_method()) + + def test_is_virtual_method(self): + """Ensure Cursor.is_virtual_method works.""" + source = 'class X { virtual void foo(); void bar(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + self.assertIsNotNone(cls) + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertTrue(foo.is_virtual_method()) + self.assertFalse(bar.is_virtual_method()) + + def test_is_abstract_record(self): + """Ensure Cursor.is_abstract_record works.""" + source = 'struct X { virtual void x() = 0; }; struct Y : X { void x(); };' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + self.assertTrue(cls.is_abstract_record()) + + cls = get_cursor(tu, 'Y') + self.assertFalse(cls.is_abstract_record()) + + def test_is_scoped_enum(self): + """Ensure Cursor.is_scoped_enum works.""" + source = 'class X {}; enum RegularEnum {}; enum class ScopedEnum {};' + tu = get_tu(source, lang='cpp') + + cls = get_cursor(tu, 'X') + regular_enum = get_cursor(tu, 'RegularEnum') + scoped_enum = get_cursor(tu, 'ScopedEnum') + self.assertIsNotNone(cls) + self.assertIsNotNone(regular_enum) + self.assertIsNotNone(scoped_enum) + + self.assertFalse(cls.is_scoped_enum()) + self.assertFalse(regular_enum.is_scoped_enum()) + self.assertTrue(scoped_enum.is_scoped_enum()) + + def test_underlying_type(self): + tu = get_tu('typedef int foo;') + typedef = get_cursor(tu, 'foo') + self.assertIsNotNone(typedef) + + self.assertTrue(typedef.kind.is_declaration()) + underlying = typedef.underlying_typedef_type + self.assertEqual(underlying.kind, TypeKind.INT) + + def test_semantic_parent(self): + tu = get_tu(kParentTest, 'cpp') + curs = get_cursors(tu, 'f') + decl = get_cursor(tu, 'C') + self.assertEqual(len(curs), 2) + self.assertEqual(curs[0].semantic_parent, curs[1].semantic_parent) + self.assertEqual(curs[0].semantic_parent, decl) + + def test_lexical_parent(self): + tu = get_tu(kParentTest, 'cpp') + curs = get_cursors(tu, 'f') + decl = get_cursor(tu, 'C') + self.assertEqual(len(curs), 2) + self.assertNotEqual(curs[0].lexical_parent, curs[1].lexical_parent) + self.assertEqual(curs[0].lexical_parent, decl) + self.assertEqual(curs[1].lexical_parent, tu.cursor) + + def test_enum_type(self): + tu = get_tu('enum TEST { FOO=1, BAR=2 };') + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + enum_type = enum.enum_type + self.assertEqual(enum_type.kind, TypeKind.UINT) + + def test_enum_type_cpp(self): + tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp") + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + self.assertEqual(enum.enum_type.kind, TypeKind.LONGLONG) + + def test_objc_type_encoding(self): + tu = get_tu('int i;', lang='objc') + i = get_cursor(tu, 'i') + + self.assertIsNotNone(i) + self.assertEqual(i.objc_type_encoding, 'i') + + def test_enum_values(self): + tu = get_tu('enum TEST { SPAM=1, EGG, HAM = EGG * 20};') + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + + enum_constants = list(enum.get_children()) + self.assertEqual(len(enum_constants), 3) + + spam, egg, ham = enum_constants + + self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(spam.enum_value, 1) + self.assertEqual(egg.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(egg.enum_value, 2) + self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(ham.enum_value, 40) + + def test_enum_values_cpp(self): + tu = get_tu('enum TEST : long long { SPAM = -1, HAM = 0x10000000000};', lang="cpp") + enum = get_cursor(tu, 'TEST') + self.assertIsNotNone(enum) + + self.assertEqual(enum.kind, CursorKind.ENUM_DECL) + + enum_constants = list(enum.get_children()) + self.assertEqual(len(enum_constants), 2) + + spam, ham = enum_constants + + self.assertEqual(spam.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(spam.enum_value, -1) + self.assertEqual(ham.kind, CursorKind.ENUM_CONSTANT_DECL) + self.assertEqual(ham.enum_value, 0x10000000000) + + def test_annotation_attribute(self): + tu = get_tu('int foo (void) __attribute__ ((annotate("here be annotation attribute")));') + + foo = get_cursor(tu, 'foo') + self.assertIsNotNone(foo) + + for c in foo.get_children(): + if c.kind == CursorKind.ANNOTATE_ATTR: + self.assertEqual(c.displayname, "here be annotation attribute") + break + else: + self.fail("Couldn't find annotation") + + def test_annotation_template(self): + annotation = '__attribute__ ((annotate("annotation")))' + for source, kind in [ + ('int foo (T value) %s;', CursorKind.FUNCTION_TEMPLATE), + ('class %s foo {};', CursorKind.CLASS_TEMPLATE), + ]: + source = 'template ' + (source % annotation) + tu = get_tu(source, lang="cpp") + + foo = get_cursor(tu, 'foo') + self.assertIsNotNone(foo) + self.assertEqual(foo.kind, kind) + + for c in foo.get_children(): + if c.kind == CursorKind.ANNOTATE_ATTR: + self.assertEqual(c.displayname, "annotation") + break + else: + self.fail("Couldn't find annotation for {}".format(kind)) + + def test_result_type(self): + tu = get_tu('int foo();') + foo = get_cursor(tu, 'foo') + + self.assertIsNotNone(foo) + t = foo.result_type + self.assertEqual(t.kind, TypeKind.INT) + + def test_availability(self): + tu = get_tu('class A { A(A const&) = delete; };', lang='cpp') + + # AvailabilityKind.AVAILABLE + cursor = get_cursor(tu, 'A') + self.assertEqual(cursor.kind, CursorKind.CLASS_DECL) + self.assertEqual(cursor.availability, AvailabilityKind.AVAILABLE) + + # AvailabilityKind.NOT_AVAILABLE + cursors = get_cursors(tu, 'A') + for c in cursors: + if c.kind == CursorKind.CONSTRUCTOR: + self.assertEqual(c.availability, AvailabilityKind.NOT_AVAILABLE) + break + else: + self.fail("Could not find cursor for deleted constructor") + + # AvailabilityKind.DEPRECATED + tu = get_tu('void test() __attribute__((deprecated));', lang='cpp') + cursor = get_cursor(tu, 'test') + self.assertEqual(cursor.availability, AvailabilityKind.DEPRECATED) + + # AvailabilityKind.NOT_ACCESSIBLE is only used in the code completion results + + def test_get_tokens(self): + """Ensure we can map cursors back to tokens.""" + tu = get_tu('int foo(int i);') + foo = get_cursor(tu, 'foo') + + tokens = list(foo.get_tokens()) + self.assertEqual(len(tokens), 6) + self.assertEqual(tokens[0].spelling, 'int') + self.assertEqual(tokens[1].spelling, 'foo') + + def test_get_token_cursor(self): + """Ensure we can map tokens to cursors.""" + tu = get_tu('class A {}; int foo(A var = A());', lang='cpp') + foo = get_cursor(tu, 'foo') + + for cursor in foo.walk_preorder(): + if cursor.kind.is_expression() and not cursor.kind.is_statement(): + break + else: + self.fail("Could not find default value expression") + + tokens = list(cursor.get_tokens()) + self.assertEqual(len(tokens), 4, [t.spelling for t in tokens]) + self.assertEqual(tokens[0].spelling, '=') + self.assertEqual(tokens[1].spelling, 'A') + self.assertEqual(tokens[2].spelling, '(') + self.assertEqual(tokens[3].spelling, ')') + t_cursor = tokens[1].cursor + self.assertEqual(t_cursor.kind, CursorKind.TYPE_REF) + r_cursor = t_cursor.referenced # should not raise an exception + self.assertEqual(r_cursor.kind, CursorKind.CLASS_DECL) + + def test_get_arguments(self): + tu = get_tu('void foo(int i, int j);') + foo = get_cursor(tu, 'foo') + arguments = list(foo.get_arguments()) + + self.assertEqual(len(arguments), 2) + self.assertEqual(arguments[0].spelling, "i") + self.assertEqual(arguments[1].spelling, "j") + + def test_get_num_template_arguments(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_num_template_arguments(), 3) + + def test_get_template_argument_kind(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_template_argument_kind(0), TemplateArgumentKind.INTEGRAL) + self.assertEqual(foos[1].get_template_argument_kind(1), TemplateArgumentKind.TYPE) + self.assertEqual(foos[1].get_template_argument_kind(2), TemplateArgumentKind.INTEGRAL) + + def test_get_template_argument_type(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_template_argument_type(1).kind, TypeKind.FLOAT) + + def test_get_template_argument_value(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_template_argument_value(0), -7) + self.assertEqual(foos[1].get_template_argument_value(2), True) + + def test_get_template_argument_unsigned_value(self): + tu = get_tu(kTemplateArgTest, lang='cpp') + foos = get_cursors(tu, 'foo') + + self.assertEqual(foos[1].get_template_argument_unsigned_value(0), 2 ** 32 - 7) + self.assertEqual(foos[1].get_template_argument_unsigned_value(2), True) + + def test_referenced(self): + tu = get_tu('void foo(); void bar() { foo(); }') + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + for c in bar.get_children(): + if c.kind == CursorKind.CALL_EXPR: + self.assertEqual(c.referenced.spelling, foo.spelling) + break + + def test_mangled_name(self): + 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] + self.assertIn(foo.mangled_name, ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH')) diff --git a/bindings/python/tests/cindex/test_cursor_kind.py b/bindings/python/tests/cindex/test_cursor_kind.py index 4d8d88b..f1ee753 100644 --- a/bindings/python/tests/cindex/test_cursor_kind.py +++ b/bindings/python/tests/cindex/test_cursor_kind.py @@ -1,49 +1,53 @@ from clang.cindex import CursorKind -def test_name(): - assert CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL' - -def test_get_all_kinds(): - kinds = CursorKind.get_all_kinds() - assert CursorKind.UNEXPOSED_DECL in kinds - assert CursorKind.TRANSLATION_UNIT in kinds - assert CursorKind.VARIABLE_REF in kinds - assert CursorKind.LAMBDA_EXPR in kinds - assert CursorKind.OBJ_BOOL_LITERAL_EXPR in kinds - assert CursorKind.OBJ_SELF_EXPR in kinds - assert CursorKind.MS_ASM_STMT in kinds - assert CursorKind.MODULE_IMPORT_DECL in kinds - assert CursorKind.TYPE_ALIAS_TEMPLATE_DECL in kinds - -def test_kind_groups(): - """Check that every kind classifies to exactly one group.""" - - assert CursorKind.UNEXPOSED_DECL.is_declaration() - assert CursorKind.TYPE_REF.is_reference() - assert CursorKind.DECL_REF_EXPR.is_expression() - assert CursorKind.UNEXPOSED_STMT.is_statement() - assert CursorKind.INVALID_FILE.is_invalid() - - assert CursorKind.TRANSLATION_UNIT.is_translation_unit() - assert not CursorKind.TYPE_REF.is_translation_unit() - - assert CursorKind.PREPROCESSING_DIRECTIVE.is_preprocessing() - assert not CursorKind.TYPE_REF.is_preprocessing() - - assert CursorKind.UNEXPOSED_DECL.is_unexposed() - assert not CursorKind.TYPE_REF.is_unexposed() - - for k in CursorKind.get_all_kinds(): - group = [n for n in ('is_declaration', 'is_reference', 'is_expression', - 'is_statement', 'is_invalid', 'is_attribute') - if getattr(k, n)()] - - if k in ( CursorKind.TRANSLATION_UNIT, - CursorKind.MACRO_DEFINITION, - CursorKind.MACRO_INSTANTIATION, - CursorKind.INCLUSION_DIRECTIVE, - CursorKind.PREPROCESSING_DIRECTIVE, - CursorKind.OVERLOAD_CANDIDATE): - assert len(group) == 0 - else: - assert len(group) == 1 +import unittest + + +class TestCursorKind(unittest.TestCase): + def test_name(self): + self.assertTrue(CursorKind.UNEXPOSED_DECL.name is 'UNEXPOSED_DECL') + + def test_get_all_kinds(self): + kinds = CursorKind.get_all_kinds() + self.assertIn(CursorKind.UNEXPOSED_DECL, kinds) + self.assertIn(CursorKind.TRANSLATION_UNIT, kinds) + self.assertIn(CursorKind.VARIABLE_REF, kinds) + self.assertIn(CursorKind.LAMBDA_EXPR, kinds) + self.assertIn(CursorKind.OBJ_BOOL_LITERAL_EXPR, kinds) + self.assertIn(CursorKind.OBJ_SELF_EXPR, kinds) + self.assertIn(CursorKind.MS_ASM_STMT, kinds) + self.assertIn(CursorKind.MODULE_IMPORT_DECL, kinds) + self.assertIn(CursorKind.TYPE_ALIAS_TEMPLATE_DECL, kinds) + + def test_kind_groups(self): + """Check that every kind classifies to exactly one group.""" + + self.assertTrue(CursorKind.UNEXPOSED_DECL.is_declaration()) + self.assertTrue(CursorKind.TYPE_REF.is_reference()) + self.assertTrue(CursorKind.DECL_REF_EXPR.is_expression()) + self.assertTrue(CursorKind.UNEXPOSED_STMT.is_statement()) + self.assertTrue(CursorKind.INVALID_FILE.is_invalid()) + + self.assertTrue(CursorKind.TRANSLATION_UNIT.is_translation_unit()) + self.assertFalse(CursorKind.TYPE_REF.is_translation_unit()) + + self.assertTrue(CursorKind.PREPROCESSING_DIRECTIVE.is_preprocessing()) + self.assertFalse(CursorKind.TYPE_REF.is_preprocessing()) + + self.assertTrue(CursorKind.UNEXPOSED_DECL.is_unexposed()) + self.assertFalse(CursorKind.TYPE_REF.is_unexposed()) + + for k in CursorKind.get_all_kinds(): + group = [n for n in ('is_declaration', 'is_reference', 'is_expression', + 'is_statement', 'is_invalid', 'is_attribute') + if getattr(k, n)()] + + if k in ( CursorKind.TRANSLATION_UNIT, + CursorKind.MACRO_DEFINITION, + CursorKind.MACRO_INSTANTIATION, + CursorKind.INCLUSION_DIRECTIVE, + CursorKind.PREPROCESSING_DIRECTIVE, + CursorKind.OVERLOAD_CANDIDATE): + self.assertEqual(len(group), 0) + else: + self.assertEqual(len(group), 1) diff --git a/bindings/python/tests/cindex/test_diagnostics.py b/bindings/python/tests/cindex/test_diagnostics.py index 23cbe89..78b327d 100644 --- a/bindings/python/tests/cindex/test_diagnostics.py +++ b/bindings/python/tests/cindex/test_diagnostics.py @@ -1,102 +1,105 @@ from clang.cindex import * from .util import get_tu +import unittest + + # FIXME: We need support for invalid translation units to test better. -def test_diagnostic_warning(): - tu = get_tu('int f0() {}\n') - assert len(tu.diagnostics) == 1 - assert tu.diagnostics[0].severity == Diagnostic.Warning - assert tu.diagnostics[0].location.line == 1 - assert tu.diagnostics[0].location.column == 11 - assert (tu.diagnostics[0].spelling == - 'control reaches end of non-void function') - -def test_diagnostic_note(): - # FIXME: We aren't getting notes here for some reason. - tu = get_tu('#define A x\nvoid *A = 1;\n') - assert len(tu.diagnostics) == 1 - assert tu.diagnostics[0].severity == Diagnostic.Warning - assert tu.diagnostics[0].location.line == 2 - assert tu.diagnostics[0].location.column == 7 - assert 'incompatible' in tu.diagnostics[0].spelling -# assert tu.diagnostics[1].severity == Diagnostic.Note -# assert tu.diagnostics[1].location.line == 1 -# assert tu.diagnostics[1].location.column == 11 -# assert tu.diagnostics[1].spelling == 'instantiated from' - -def test_diagnostic_fixit(): - tu = get_tu('struct { int f0; } x = { f0 : 1 };') - assert len(tu.diagnostics) == 1 - assert tu.diagnostics[0].severity == Diagnostic.Warning - assert tu.diagnostics[0].location.line == 1 - assert tu.diagnostics[0].location.column == 26 - assert tu.diagnostics[0].spelling.startswith('use of GNU old-style') - assert len(tu.diagnostics[0].fixits) == 1 - assert tu.diagnostics[0].fixits[0].range.start.line == 1 - assert tu.diagnostics[0].fixits[0].range.start.column == 26 - assert tu.diagnostics[0].fixits[0].range.end.line == 1 - assert tu.diagnostics[0].fixits[0].range.end.column == 30 - assert tu.diagnostics[0].fixits[0].value == '.f0 = ' - -def test_diagnostic_range(): - tu = get_tu('void f() { int i = "a" + 1; }') - assert len(tu.diagnostics) == 1 - assert tu.diagnostics[0].severity == Diagnostic.Warning - assert tu.diagnostics[0].location.line == 1 - assert tu.diagnostics[0].location.column == 16 - assert tu.diagnostics[0].spelling.startswith('incompatible pointer to') - assert len(tu.diagnostics[0].fixits) == 0 - assert len(tu.diagnostics[0].ranges) == 1 - assert tu.diagnostics[0].ranges[0].start.line == 1 - assert tu.diagnostics[0].ranges[0].start.column == 20 - assert tu.diagnostics[0].ranges[0].end.line == 1 - assert tu.diagnostics[0].ranges[0].end.column == 27 - try: - tu.diagnostics[0].ranges[1].start.line - except IndexError: - assert True - else: - assert False - -def test_diagnostic_category(): - """Ensure that category properties work.""" - tu = get_tu('int f(int i) { return 7; }', all_warnings=True) - assert len(tu.diagnostics) == 1 - d = tu.diagnostics[0] - - assert d.severity == Diagnostic.Warning - assert d.location.line == 1 - assert d.location.column == 11 - - assert d.category_number == 2 - assert d.category_name == 'Semantic Issue' - -def test_diagnostic_option(): - """Ensure that category option properties work.""" - tu = get_tu('int f(int i) { return 7; }', all_warnings=True) - assert len(tu.diagnostics) == 1 - d = tu.diagnostics[0] - - assert d.option == '-Wunused-parameter' - assert d.disable_option == '-Wno-unused-parameter' - -def test_diagnostic_children(): - tu = get_tu('void f(int x) {} void g() { f(); }') - assert len(tu.diagnostics) == 1 - d = tu.diagnostics[0] - - children = d.children - assert len(children) == 1 - assert children[0].severity == Diagnostic.Note - assert children[0].spelling.endswith('declared here') - assert children[0].location.line == 1 - assert children[0].location.column == 1 - -def test_diagnostic_string_repr(): - tu = get_tu('struct MissingSemicolon{}') - assert len(tu.diagnostics) == 1 - d = tu.diagnostics[0] - - assert repr(d) == ', spelling "expected \';\' after struct">' - + +class TestDiagnostics(unittest.TestCase): + def test_diagnostic_warning(self): + tu = get_tu('int f0() {}\n') + self.assertEqual(len(tu.diagnostics), 1) + self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning) + self.assertEqual(tu.diagnostics[0].location.line, 1) + self.assertEqual(tu.diagnostics[0].location.column, 11) + self.assertEqual(tu.diagnostics[0].spelling, + 'control reaches end of non-void function') + + def test_diagnostic_note(self): + # FIXME: We aren't getting notes here for some reason. + tu = get_tu('#define A x\nvoid *A = 1;\n') + self.assertEqual(len(tu.diagnostics), 1) + self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning) + self.assertEqual(tu.diagnostics[0].location.line, 2) + self.assertEqual(tu.diagnostics[0].location.column, 7) + self.assertIn('incompatible', tu.diagnostics[0].spelling) +# self.assertEqual(tu.diagnostics[1].severity, Diagnostic.Note) +# self.assertEqual(tu.diagnostics[1].location.line, 1) +# self.assertEqual(tu.diagnostics[1].location.column, 11) +# self.assertEqual(tu.diagnostics[1].spelling, 'instantiated from') + + def test_diagnostic_fixit(self): + tu = get_tu('struct { int f0; } x = { f0 : 1 };') + self.assertEqual(len(tu.diagnostics), 1) + self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning) + self.assertEqual(tu.diagnostics[0].location.line, 1) + self.assertEqual(tu.diagnostics[0].location.column, 26) + self.assertRegexpMatches(tu.diagnostics[0].spelling, + 'use of GNU old-style.*') + self.assertEqual(len(tu.diagnostics[0].fixits), 1) + self.assertEqual(tu.diagnostics[0].fixits[0].range.start.line, 1) + self.assertEqual(tu.diagnostics[0].fixits[0].range.start.column, 26) + self.assertEqual(tu.diagnostics[0].fixits[0].range.end.line, 1) + self.assertEqual(tu.diagnostics[0].fixits[0].range.end.column, 30) + self.assertEqual(tu.diagnostics[0].fixits[0].value, '.f0 = ') + + def test_diagnostic_range(self): + tu = get_tu('void f() { int i = "a" + 1; }') + self.assertEqual(len(tu.diagnostics), 1) + self.assertEqual(tu.diagnostics[0].severity, Diagnostic.Warning) + self.assertEqual(tu.diagnostics[0].location.line, 1) + self.assertEqual(tu.diagnostics[0].location.column, 16) + self.assertRegexpMatches(tu.diagnostics[0].spelling, + 'incompatible pointer to.*') + self.assertEqual(len(tu.diagnostics[0].fixits), 0) + self.assertEqual(len(tu.diagnostics[0].ranges), 1) + self.assertEqual(tu.diagnostics[0].ranges[0].start.line, 1) + self.assertEqual(tu.diagnostics[0].ranges[0].start.column, 20) + self.assertEqual(tu.diagnostics[0].ranges[0].end.line, 1) + self.assertEqual(tu.diagnostics[0].ranges[0].end.column, 27) + with self.assertRaises(IndexError): + tu.diagnostics[0].ranges[1].start.line + + def test_diagnostic_category(self): + """Ensure that category properties work.""" + tu = get_tu('int f(int i) { return 7; }', all_warnings=True) + self.assertEqual(len(tu.diagnostics), 1) + d = tu.diagnostics[0] + + self.assertEqual(d.severity, Diagnostic.Warning) + self.assertEqual(d.location.line, 1) + self.assertEqual(d.location.column, 11) + + self.assertEqual(d.category_number, 2) + self.assertEqual(d.category_name, 'Semantic Issue') + + def test_diagnostic_option(self): + """Ensure that category option properties work.""" + tu = get_tu('int f(int i) { return 7; }', all_warnings=True) + self.assertEqual(len(tu.diagnostics), 1) + d = tu.diagnostics[0] + + self.assertEqual(d.option, '-Wunused-parameter') + self.assertEqual(d.disable_option, '-Wno-unused-parameter') + + def test_diagnostic_children(self): + tu = get_tu('void f(int x) {} void g() { f(); }') + self.assertEqual(len(tu.diagnostics), 1) + d = tu.diagnostics[0] + + children = d.children + self.assertEqual(len(children), 1) + self.assertEqual(children[0].severity, Diagnostic.Note) + self.assertRegexpMatches(children[0].spelling, + '.*declared here') + self.assertEqual(children[0].location.line, 1) + self.assertEqual(children[0].location.column, 1) + + def test_diagnostic_string_repr(self): + tu = get_tu('struct MissingSemicolon{}') + self.assertEqual(len(tu.diagnostics), 1) + d = tu.diagnostics[0] + + self.assertEqual(repr(d), ', spelling "expected \';\' after struct">') diff --git a/bindings/python/tests/cindex/test_exception_specification_kind.py b/bindings/python/tests/cindex/test_exception_specification_kind.py index 543d47f..80b3639 100644 --- a/bindings/python/tests/cindex/test_exception_specification_kind.py +++ b/bindings/python/tests/cindex/test_exception_specification_kind.py @@ -2,6 +2,8 @@ import clang.cindex from clang.cindex import ExceptionSpecificationKind from .util import get_tu +import unittest + def find_function_declarations(node, declarations=[]): if node.kind == clang.cindex.CursorKind.FUNCTION_DECL: @@ -11,17 +13,18 @@ def find_function_declarations(node, declarations=[]): return declarations -def test_exception_specification_kind(): - source = """int square1(int x); - int square2(int x) noexcept; - int square3(int x) noexcept(noexcept(x * x));""" +class TestExceptionSpecificationKind(unittest.TestCase): + def test_exception_specification_kind(self): + source = """int square1(int x); + int square2(int x) noexcept; + int square3(int x) noexcept(noexcept(x * x));""" - tu = get_tu(source, lang='cpp', flags=['-std=c++14']) + tu = get_tu(source, lang='cpp', flags=['-std=c++14']) - declarations = find_function_declarations(tu.cursor) - expected = [ - ('square1', ExceptionSpecificationKind.NONE), - ('square2', ExceptionSpecificationKind.BASIC_NOEXCEPT), - ('square3', ExceptionSpecificationKind.COMPUTED_NOEXCEPT) - ] - assert declarations == expected + declarations = find_function_declarations(tu.cursor) + expected = [ + ('square1', ExceptionSpecificationKind.NONE), + ('square2', ExceptionSpecificationKind.BASIC_NOEXCEPT), + ('square3', ExceptionSpecificationKind.COMPUTED_NOEXCEPT) + ] + self.assertListEqual(declarations, expected) diff --git a/bindings/python/tests/cindex/test_file.py b/bindings/python/tests/cindex/test_file.py index 146e8c5..98f6575 100644 --- a/bindings/python/tests/cindex/test_file.py +++ b/bindings/python/tests/cindex/test_file.py @@ -1,9 +1,13 @@ from clang.cindex import Index, File -def test_file(): - index = Index.create() - tu = index.parse('t.c', unsaved_files = [('t.c', "")]) - file = File.from_name(tu, "t.c") - assert str(file) == "t.c" - assert file.name == "t.c" - assert repr(file) == "" +import unittest + + +class TestFile(unittest.TestCase): + def test_file(self): + index = Index.create() + tu = index.parse('t.c', unsaved_files = [('t.c', "")]) + file = File.from_name(tu, "t.c") + self.assertEqual(str(file), "t.c") + self.assertEqual(file.name, "t.c") + self.assertEqual(repr(file), "") diff --git a/bindings/python/tests/cindex/test_index.py b/bindings/python/tests/cindex/test_index.py index dc173f0..cfdf98e 100644 --- a/bindings/python/tests/cindex/test_index.py +++ b/bindings/python/tests/cindex/test_index.py @@ -1,15 +1,21 @@ from clang.cindex import * import os +import unittest + kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') -def test_create(): - index = Index.create() -# FIXME: test Index.read +class TestIndex(unittest.TestCase): + def test_create(self): + index = Index.create() + + # FIXME: test Index.read -def test_parse(): - index = Index.create() - assert isinstance(index, Index) - tu = index.parse(os.path.join(kInputsDir, 'hello.cpp')) - assert isinstance(tu, TranslationUnit) + def test_parse(self): + index = Index.create() + self.assertIsInstance(index, Index) + tu = index.parse(os.path.join(kInputsDir, 'hello.cpp')) + self.assertIsInstance(tu, TranslationUnit) + tu = index.parse(None, ['-c', os.path.join(kInputsDir, 'hello.cpp')]) + self.assertIsInstance(tu, TranslationUnit) diff --git a/bindings/python/tests/cindex/test_linkage.py b/bindings/python/tests/cindex/test_linkage.py new file mode 100644 index 0000000..6b482f8 --- /dev/null +++ b/bindings/python/tests/cindex/test_linkage.py @@ -0,0 +1,33 @@ +from clang.cindex import LinkageKind +from clang.cindex import Cursor +from clang.cindex import TranslationUnit + +from .util import get_cursor +from .util import get_tu + +import unittest + + +class TestLinkage(unittest.TestCase): + def test_linkage(self): + """Ensure that linkage specifers are available on cursors""" + + tu = get_tu(""" +void foo() { int no_linkage; } +static int internal; +namespace { struct unique_external_type {} } +unique_external_type unique_external; +extern int external; +""", lang = 'cpp') + + no_linkage = get_cursor(tu.cursor, 'no_linkage') + self.assertEqual(no_linkage.linkage, LinkageKind.NO_LINKAGE) + + internal = get_cursor(tu.cursor, 'internal') + self.assertEqual(internal.linkage, LinkageKind.INTERNAL) + + unique_external = get_cursor(tu.cursor, 'unique_external') + self.assertEqual(unique_external.linkage, LinkageKind.UNIQUE_EXTERNAL) + + external = get_cursor(tu.cursor, 'external') + self.assertEqual(external.linkage, LinkageKind.EXTERNAL) diff --git a/bindings/python/tests/cindex/test_location.py b/bindings/python/tests/cindex/test_location.py index 9e9ef48..cbc32de 100644 --- a/bindings/python/tests/cindex/test_location.py +++ b/bindings/python/tests/cindex/test_location.py @@ -5,91 +5,96 @@ from clang.cindex import SourceRange from .util import get_cursor from .util import get_tu +import unittest + + baseInput="int one;\nint two;\n" -def assert_location(loc, line, column, offset): - assert loc.line == line - assert loc.column == column - assert loc.offset == offset -def test_location(): - tu = get_tu(baseInput) - one = get_cursor(tu, 'one') - two = get_cursor(tu, 'two') +class TestLocation(unittest.TestCase): + def assert_location(self, loc, line, column, offset): + self.assertEqual(loc.line, line) + self.assertEqual(loc.column, column) + self.assertEqual(loc.offset, offset) + + def test_location(self): + tu = get_tu(baseInput) + one = get_cursor(tu, 'one') + two = get_cursor(tu, 'two') - assert one is not None - assert two is not None + self.assertIsNotNone(one) + self.assertIsNotNone(two) - assert_location(one.location,line=1,column=5,offset=4) - assert_location(two.location,line=2,column=5,offset=13) + self.assert_location(one.location,line=1,column=5,offset=4) + self.assert_location(two.location,line=2,column=5,offset=13) - # adding a linebreak at top should keep columns same - tu = get_tu('\n' + baseInput) - one = get_cursor(tu, 'one') - two = get_cursor(tu, 'two') + # adding a linebreak at top should keep columns same + tu = get_tu('\n' + baseInput) + one = get_cursor(tu, 'one') + two = get_cursor(tu, 'two') - assert one is not None - assert two is not None + self.assertIsNotNone(one) + self.assertIsNotNone(two) - assert_location(one.location,line=2,column=5,offset=5) - assert_location(two.location,line=3,column=5,offset=14) + self.assert_location(one.location,line=2,column=5,offset=5) + self.assert_location(two.location,line=3,column=5,offset=14) - # adding a space should affect column on first line only - tu = get_tu(' ' + baseInput) - one = get_cursor(tu, 'one') - two = get_cursor(tu, 'two') + # adding a space should affect column on first line only + tu = get_tu(' ' + baseInput) + one = get_cursor(tu, 'one') + two = get_cursor(tu, 'two') - assert_location(one.location,line=1,column=6,offset=5) - assert_location(two.location,line=2,column=5,offset=14) + self.assert_location(one.location,line=1,column=6,offset=5) + self.assert_location(two.location,line=2,column=5,offset=14) - # define the expected location ourselves and see if it matches - # the returned location - tu = get_tu(baseInput) + # define the expected location ourselves and see if it matches + # the returned location + tu = get_tu(baseInput) - file = File.from_name(tu, 't.c') - location = SourceLocation.from_position(tu, file, 1, 5) - cursor = Cursor.from_location(tu, location) + file = File.from_name(tu, 't.c') + location = SourceLocation.from_position(tu, file, 1, 5) + cursor = Cursor.from_location(tu, location) - one = get_cursor(tu, 'one') - assert one is not None - assert one == cursor + one = get_cursor(tu, 'one') + self.assertIsNotNone(one) + self.assertEqual(one, cursor) - # Ensure locations referring to the same entity are equivalent. - location2 = SourceLocation.from_position(tu, file, 1, 5) - assert location == location2 - location3 = SourceLocation.from_position(tu, file, 1, 4) - assert location2 != location3 + # Ensure locations referring to the same entity are equivalent. + location2 = SourceLocation.from_position(tu, file, 1, 5) + self.assertEqual(location, location2) + location3 = SourceLocation.from_position(tu, file, 1, 4) + self.assertNotEqual(location2, location3) - offset_location = SourceLocation.from_offset(tu, file, 5) - cursor = Cursor.from_location(tu, offset_location) - verified = False - for n in [n for n in tu.cursor.get_children() if n.spelling == 'one']: - assert n == cursor - verified = True + offset_location = SourceLocation.from_offset(tu, file, 5) + cursor = Cursor.from_location(tu, offset_location) + verified = False + for n in [n for n in tu.cursor.get_children() if n.spelling == 'one']: + self.assertEqual(n, cursor) + verified = True - assert verified + self.assertTrue(verified) -def test_extent(): - tu = get_tu(baseInput) - one = get_cursor(tu, 'one') - two = get_cursor(tu, 'two') + def test_extent(self): + tu = get_tu(baseInput) + one = get_cursor(tu, 'one') + two = get_cursor(tu, 'two') - assert_location(one.extent.start,line=1,column=1,offset=0) - assert_location(one.extent.end,line=1,column=8,offset=7) - assert baseInput[one.extent.start.offset:one.extent.end.offset] == "int one" + self.assert_location(one.extent.start,line=1,column=1,offset=0) + self.assert_location(one.extent.end,line=1,column=8,offset=7) + self.assertEqual(baseInput[one.extent.start.offset:one.extent.end.offset], "int one") - assert_location(two.extent.start,line=2,column=1,offset=9) - assert_location(two.extent.end,line=2,column=8,offset=16) - assert baseInput[two.extent.start.offset:two.extent.end.offset] == "int two" + self.assert_location(two.extent.start,line=2,column=1,offset=9) + self.assert_location(two.extent.end,line=2,column=8,offset=16) + self.assertEqual(baseInput[two.extent.start.offset:two.extent.end.offset], "int two") - file = File.from_name(tu, 't.c') - location1 = SourceLocation.from_position(tu, file, 1, 1) - location2 = SourceLocation.from_position(tu, file, 1, 8) + file = File.from_name(tu, 't.c') + location1 = SourceLocation.from_position(tu, file, 1, 1) + location2 = SourceLocation.from_position(tu, file, 1, 8) - range1 = SourceRange.from_locations(location1, location2) - range2 = SourceRange.from_locations(location1, location2) - assert range1 == range2 + range1 = SourceRange.from_locations(location1, location2) + range2 = SourceRange.from_locations(location1, location2) + self.assertEqual(range1, range2) - location3 = SourceLocation.from_position(tu, file, 1, 6) - range3 = SourceRange.from_locations(location1, location3) - assert range1 != range3 + location3 = SourceLocation.from_position(tu, file, 1, 6) + range3 = SourceRange.from_locations(location1, location3) + self.assertNotEqual(range1, range3) diff --git a/bindings/python/tests/cindex/test_tls_kind.py b/bindings/python/tests/cindex/test_tls_kind.py new file mode 100644 index 0000000..fbc3418 --- /dev/null +++ b/bindings/python/tests/cindex/test_tls_kind.py @@ -0,0 +1,49 @@ +from clang.cindex import TLSKind +from clang.cindex import Cursor +from clang.cindex import TranslationUnit + +from .util import get_cursor +from .util import get_tu + +import unittest + + +class TestTLSKind(unittest.TestCase): + def test_tls_kind(self): + """Ensure that thread-local storage kinds are available on cursors.""" + + tu = get_tu(""" +int tls_none; +thread_local int tls_dynamic; +_Thread_local int tls_static; +""", lang = 'cpp') + + tls_none = get_cursor(tu.cursor, 'tls_none') + self.assertEqual(tls_none.tls_kind, TLSKind.NONE) + + tls_dynamic = get_cursor(tu.cursor, 'tls_dynamic') + self.assertEqual(tls_dynamic.tls_kind, TLSKind.DYNAMIC) + + tls_static = get_cursor(tu.cursor, 'tls_static') + self.assertEqual(tls_static.tls_kind, TLSKind.STATIC) + + # The following case tests '__declspec(thread)'. Since it is a Microsoft + # specific extension, specific flags are required for the parser to pick + # these up. + flags = ['-fms-extensions', '-target', 'x86_64-unknown-windows-win32', + '-fms-compatibility-version=18'] + tu = get_tu(""" +__declspec(thread) int tls_declspec_msvc18; +""", lang = 'cpp', flags=flags) + + tls_declspec_msvc18 = get_cursor(tu.cursor, 'tls_declspec_msvc18') + self.assertEqual(tls_declspec_msvc18.tls_kind, TLSKind.STATIC) + + flags = ['-fms-extensions', '-target', 'x86_64-unknown-windows-win32', + '-fms-compatibility-version=19'] + tu = get_tu(""" +__declspec(thread) int tls_declspec_msvc19; +""", lang = 'cpp', flags=flags) + + tls_declspec_msvc19 = get_cursor(tu.cursor, 'tls_declspec_msvc19') + self.assertEqual(tls_declspec_msvc19.tls_kind, TLSKind.DYNAMIC) diff --git a/bindings/python/tests/cindex/test_token_kind.py b/bindings/python/tests/cindex/test_token_kind.py index 62ec63e..700f95a 100644 --- a/bindings/python/tests/cindex/test_token_kind.py +++ b/bindings/python/tests/cindex/test_token_kind.py @@ -1,43 +1,44 @@ from clang.cindex import TokenKind -from nose.tools import eq_ -from nose.tools import ok_ -from nose.tools import raises -def test_constructor(): - """Ensure TokenKind constructor works as expected.""" +import unittest - t = TokenKind(5, 'foo') - eq_(t.value, 5) - eq_(t.name, 'foo') +class TestTokenKind(unittest.TestCase): + def test_constructor(self): + """Ensure TokenKind constructor works as expected.""" -@raises(ValueError) -def test_bad_register(): - """Ensure a duplicate value is rejected for registration.""" + t = TokenKind(5, 'foo') - TokenKind.register(2, 'foo') + self.assertEqual(t.value, 5) + self.assertEqual(t.name, 'foo') -@raises(ValueError) -def test_unknown_value(): - """Ensure trying to fetch an unknown value raises.""" + def test_bad_register(self): + """Ensure a duplicate value is rejected for registration.""" - TokenKind.from_value(-1) + with self.assertRaises(ValueError): + TokenKind.register(2, 'foo') -def test_registration(): - """Ensure that items registered appear as class attributes.""" - ok_(hasattr(TokenKind, 'LITERAL')) - literal = TokenKind.LITERAL + def test_unknown_value(self): + """Ensure trying to fetch an unknown value raises.""" - ok_(isinstance(literal, TokenKind)) + with self.assertRaises(ValueError): + TokenKind.from_value(-1) -def test_from_value(): - """Ensure registered values can be obtained from from_value().""" - t = TokenKind.from_value(3) - ok_(isinstance(t, TokenKind)) - eq_(t, TokenKind.LITERAL) + def test_registration(self): + """Ensure that items registered appear as class attributes.""" + self.assertTrue(hasattr(TokenKind, 'LITERAL')) + literal = TokenKind.LITERAL -def test_repr(): - """Ensure repr() works.""" + self.assertIsInstance(literal, TokenKind) - r = repr(TokenKind.LITERAL) - eq_(r, 'TokenKind.LITERAL') + def test_from_value(self): + """Ensure registered values can be obtained from from_value().""" + t = TokenKind.from_value(3) + self.assertIsInstance(t, TokenKind) + self.assertEqual(t, TokenKind.LITERAL) + + def test_repr(self): + """Ensure repr() works.""" + + r = repr(TokenKind.LITERAL) + self.assertEqual(r, 'TokenKind.LITERAL') diff --git a/bindings/python/tests/cindex/test_tokens.py b/bindings/python/tests/cindex/test_tokens.py index 688b5c1..c93353d 100644 --- a/bindings/python/tests/cindex/test_tokens.py +++ b/bindings/python/tests/cindex/test_tokens.py @@ -3,50 +3,52 @@ from clang.cindex import Index from clang.cindex import SourceLocation from clang.cindex import SourceRange from clang.cindex import TokenKind -from nose.tools import eq_ -from nose.tools import ok_ from .util import get_tu -def test_token_to_cursor(): - """Ensure we can obtain a Cursor from a Token instance.""" - tu = get_tu('int i = 5;') - r = tu.get_extent('t.c', (0, 9)) - tokens = list(tu.get_tokens(extent=r)) +import unittest - assert len(tokens) == 4 - assert tokens[1].spelling == 'i' - assert tokens[1].kind == TokenKind.IDENTIFIER - cursor = tokens[1].cursor - assert cursor.kind == CursorKind.VAR_DECL - assert tokens[1].cursor == tokens[2].cursor +class TestTokens(unittest.TestCase): + def test_token_to_cursor(self): + """Ensure we can obtain a Cursor from a Token instance.""" + tu = get_tu('int i = 5;') + r = tu.get_extent('t.c', (0, 9)) + tokens = list(tu.get_tokens(extent=r)) -def test_token_location(): - """Ensure Token.location works.""" + self.assertEqual(len(tokens), 4) + self.assertEqual(tokens[1].spelling, 'i') + self.assertEqual(tokens[1].kind, TokenKind.IDENTIFIER) - tu = get_tu('int foo = 10;') - r = tu.get_extent('t.c', (0, 11)) + cursor = tokens[1].cursor + self.assertEqual(cursor.kind, CursorKind.VAR_DECL) + self.assertEqual(tokens[1].cursor, tokens[2].cursor) - tokens = list(tu.get_tokens(extent=r)) - eq_(len(tokens), 4) + def test_token_location(self): + """Ensure Token.location works.""" - loc = tokens[1].location - ok_(isinstance(loc, SourceLocation)) - eq_(loc.line, 1) - eq_(loc.column, 5) - eq_(loc.offset, 4) + tu = get_tu('int foo = 10;') + r = tu.get_extent('t.c', (0, 11)) -def test_token_extent(): - """Ensure Token.extent works.""" - tu = get_tu('int foo = 10;') - r = tu.get_extent('t.c', (0, 11)) + tokens = list(tu.get_tokens(extent=r)) + self.assertEqual(len(tokens), 4) - tokens = list(tu.get_tokens(extent=r)) - eq_(len(tokens), 4) + loc = tokens[1].location + self.assertIsInstance(loc, SourceLocation) + self.assertEqual(loc.line, 1) + self.assertEqual(loc.column, 5) + self.assertEqual(loc.offset, 4) - extent = tokens[1].extent - ok_(isinstance(extent, SourceRange)) + def test_token_extent(self): + """Ensure Token.extent works.""" + tu = get_tu('int foo = 10;') + r = tu.get_extent('t.c', (0, 11)) - eq_(extent.start.offset, 4) - eq_(extent.end.offset, 7) + tokens = list(tu.get_tokens(extent=r)) + self.assertEqual(len(tokens), 4) + + extent = tokens[1].extent + self.assertIsInstance(extent, SourceRange) + + self.assertEqual(extent.start.offset, 4) + self.assertEqual(extent.end.offset, 7) diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py index 65d1ee0..1b3973d 100644 --- a/bindings/python/tests/cindex/test_translation_unit.py +++ b/bindings/python/tests/cindex/test_translation_unit.py @@ -1,6 +1,7 @@ import gc import os import tempfile +import unittest from clang.cindex import CursorKind from clang.cindex import Cursor @@ -14,83 +15,9 @@ from clang.cindex import TranslationUnit from .util import get_cursor from .util import get_tu + kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') -def test_spelling(): - path = os.path.join(kInputsDir, 'hello.cpp') - tu = TranslationUnit.from_source(path) - assert tu.spelling == path - -def test_cursor(): - path = os.path.join(kInputsDir, 'hello.cpp') - tu = get_tu(path) - c = tu.cursor - assert isinstance(c, Cursor) - assert c.kind is CursorKind.TRANSLATION_UNIT - -def test_parse_arguments(): - path = os.path.join(kInputsDir, 'parse_arguments.c') - tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi']) - spellings = [c.spelling for c in tu.cursor.get_children()] - assert spellings[-2] == 'hello' - assert spellings[-1] == 'hi' - -def test_reparse_arguments(): - path = os.path.join(kInputsDir, 'parse_arguments.c') - tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi']) - tu.reparse() - spellings = [c.spelling for c in tu.cursor.get_children()] - assert spellings[-2] == 'hello' - assert spellings[-1] == 'hi' - -def test_unsaved_files(): - tu = TranslationUnit.from_source('fake.c', ['-I./'], unsaved_files = [ - ('fake.c', """ -#include "fake.h" -int x; -int SOME_DEFINE; -"""), - ('./fake.h', """ -#define SOME_DEFINE y -""") - ]) - spellings = [c.spelling for c in tu.cursor.get_children()] - assert spellings[-2] == 'x' - assert spellings[-1] == 'y' - -def test_unsaved_files_2(): - try: - from StringIO import StringIO - except: - from io import StringIO - tu = TranslationUnit.from_source('fake.c', unsaved_files = [ - ('fake.c', StringIO('int x;'))]) - spellings = [c.spelling for c in tu.cursor.get_children()] - assert spellings[-1] == 'x' - -def normpaths_equal(path1, path2): - """ Compares two paths for equality after normalizing them with - os.path.normpath - """ - return os.path.normpath(path1) == os.path.normpath(path2) - -def test_includes(): - def eq(expected, actual): - if not actual.is_input_file: - return normpaths_equal(expected[0], actual.source.name) and \ - normpaths_equal(expected[1], actual.include.name) - else: - return normpaths_equal(expected[1], actual.include.name) - - src = os.path.join(kInputsDir, 'include.cpp') - h1 = os.path.join(kInputsDir, "header1.h") - h2 = os.path.join(kInputsDir, "header2.h") - h3 = os.path.join(kInputsDir, "header3.h") - inc = [(src, h1), (h1, h3), (src, h2), (h2, h3)] - - tu = TranslationUnit.from_source(src) - for i in zip(inc, tu.get_includes()): - assert eq(i[0], i[1]) def save_tu(tu): """Convenience API to save a TranslationUnit to a file. @@ -102,153 +29,227 @@ def save_tu(tu): return path -def test_save(): - """Ensure TranslationUnit.save() works.""" - - tu = get_tu('int foo();') - - path = save_tu(tu) - assert os.path.exists(path) - assert os.path.getsize(path) > 0 - os.unlink(path) -def test_save_translation_errors(): - """Ensure that saving to an invalid directory raises.""" - - tu = get_tu('int foo();') - - path = '/does/not/exist/llvm-test.ast' - assert not os.path.exists(os.path.dirname(path)) - - try: - tu.save(path) - assert False - except TranslationUnitSaveError as ex: +class TestTranslationUnit(unittest.TestCase): + def test_spelling(self): + path = os.path.join(kInputsDir, 'hello.cpp') + tu = TranslationUnit.from_source(path) + self.assertEqual(tu.spelling, path) + + def test_cursor(self): + path = os.path.join(kInputsDir, 'hello.cpp') + tu = get_tu(path) + c = tu.cursor + self.assertIsInstance(c, Cursor) + self.assertIs(c.kind, CursorKind.TRANSLATION_UNIT) + + def test_parse_arguments(self): + path = os.path.join(kInputsDir, 'parse_arguments.c') + tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi']) + spellings = [c.spelling for c in tu.cursor.get_children()] + self.assertEqual(spellings[-2], 'hello') + self.assertEqual(spellings[-1], 'hi') + + def test_reparse_arguments(self): + path = os.path.join(kInputsDir, 'parse_arguments.c') + tu = TranslationUnit.from_source(path, ['-DDECL_ONE=hello', '-DDECL_TWO=hi']) + tu.reparse() + spellings = [c.spelling for c in tu.cursor.get_children()] + self.assertEqual(spellings[-2], 'hello') + self.assertEqual(spellings[-1], 'hi') + + def test_unsaved_files(self): + tu = TranslationUnit.from_source('fake.c', ['-I./'], unsaved_files = [ + ('fake.c', """ +#include "fake.h" +int x; +int SOME_DEFINE; +"""), + ('./fake.h', """ +#define SOME_DEFINE y +""") + ]) + spellings = [c.spelling for c in tu.cursor.get_children()] + self.assertEqual(spellings[-2], 'x') + self.assertEqual(spellings[-1], 'y') + + def test_unsaved_files_2(self): + try: + from StringIO import StringIO + except: + from io import StringIO + tu = TranslationUnit.from_source('fake.c', unsaved_files = [ + ('fake.c', StringIO('int x;'))]) + spellings = [c.spelling for c in tu.cursor.get_children()] + self.assertEqual(spellings[-1], 'x') + + def assert_normpaths_equal(self, path1, path2): + """ Compares two paths for equality after normalizing them with + os.path.normpath + """ + self.assertEqual(os.path.normpath(path1), + os.path.normpath(path2)) + + def test_includes(self): + def eq(expected, actual): + if not actual.is_input_file: + self.assert_normpaths_equal(expected[0], actual.source.name) + self.assert_normpaths_equal(expected[1], actual.include.name) + else: + self.assert_normpaths_equal(expected[1], actual.include.name) + + src = os.path.join(kInputsDir, 'include.cpp') + h1 = os.path.join(kInputsDir, "header1.h") + h2 = os.path.join(kInputsDir, "header2.h") + h3 = os.path.join(kInputsDir, "header3.h") + inc = [(src, h1), (h1, h3), (src, h2), (h2, h3)] + + tu = TranslationUnit.from_source(src) + for i in zip(inc, tu.get_includes()): + eq(i[0], i[1]) + + def test_save(self): + """Ensure TranslationUnit.save() works.""" + + tu = get_tu('int foo();') + + path = save_tu(tu) + self.assertTrue(os.path.exists(path)) + self.assertGreater(os.path.getsize(path), 0) + os.unlink(path) + + def test_save_translation_errors(self): + """Ensure that saving to an invalid directory raises.""" + + tu = get_tu('int foo();') + + path = '/does/not/exist/llvm-test.ast' + self.assertFalse(os.path.exists(os.path.dirname(path))) + + with self.assertRaises(TranslationUnitSaveError) as cm: + tu.save(path) + ex = cm.exception expected = TranslationUnitSaveError.ERROR_UNKNOWN - assert ex.save_error == expected + self.assertEqual(ex.save_error, expected) -def test_load(): - """Ensure TranslationUnits can be constructed from saved files.""" + def test_load(self): + """Ensure TranslationUnits can be constructed from saved files.""" - tu = get_tu('int foo();') - assert len(tu.diagnostics) == 0 - path = save_tu(tu) + tu = get_tu('int foo();') + self.assertEqual(len(tu.diagnostics), 0) + path = save_tu(tu) - assert os.path.exists(path) - assert os.path.getsize(path) > 0 + self.assertTrue(os.path.exists(path)) + self.assertGreater(os.path.getsize(path), 0) - tu2 = TranslationUnit.from_ast_file(filename=path) - assert len(tu2.diagnostics) == 0 + tu2 = TranslationUnit.from_ast_file(filename=path) + self.assertEqual(len(tu2.diagnostics), 0) - foo = get_cursor(tu2, 'foo') - assert foo is not None + foo = get_cursor(tu2, 'foo') + self.assertIsNotNone(foo) - # Just in case there is an open file descriptor somewhere. - del tu2 - - os.unlink(path) - -def test_index_parse(): - path = os.path.join(kInputsDir, 'hello.cpp') - index = Index.create() - tu = index.parse(path) - assert isinstance(tu, TranslationUnit) - -def test_get_file(): - """Ensure tu.get_file() works appropriately.""" - - tu = get_tu('int foo();') - - f = tu.get_file('t.c') - assert isinstance(f, File) - assert f.name == 't.c' - - try: - f = tu.get_file('foobar.cpp') - except: - pass - else: - assert False - -def test_get_source_location(): - """Ensure tu.get_source_location() works.""" - - tu = get_tu('int foo();') - - location = tu.get_location('t.c', 2) - assert isinstance(location, SourceLocation) - assert location.offset == 2 - assert location.file.name == 't.c' - - location = tu.get_location('t.c', (1, 3)) - assert isinstance(location, SourceLocation) - assert location.line == 1 - assert location.column == 3 - assert location.file.name == 't.c' - -def test_get_source_range(): - """Ensure tu.get_source_range() works.""" - - tu = get_tu('int foo();') - - r = tu.get_extent('t.c', (1,4)) - assert isinstance(r, SourceRange) - assert r.start.offset == 1 - assert r.end.offset == 4 - assert r.start.file.name == 't.c' - assert r.end.file.name == 't.c' - - r = tu.get_extent('t.c', ((1,2), (1,3))) - assert isinstance(r, SourceRange) - assert r.start.line == 1 - assert r.start.column == 2 - assert r.end.line == 1 - assert r.end.column == 3 - assert r.start.file.name == 't.c' - assert r.end.file.name == 't.c' - - start = tu.get_location('t.c', 0) - end = tu.get_location('t.c', 5) - - r = tu.get_extent('t.c', (start, end)) - assert isinstance(r, SourceRange) - assert r.start.offset == 0 - assert r.end.offset == 5 - assert r.start.file.name == 't.c' - assert r.end.file.name == 't.c' - -def test_get_tokens_gc(): - """Ensures get_tokens() works properly with garbage collection.""" - - tu = get_tu('int foo();') - r = tu.get_extent('t.c', (0, 10)) - tokens = list(tu.get_tokens(extent=r)) - - assert tokens[0].spelling == 'int' - gc.collect() - assert tokens[0].spelling == 'int' - - del tokens[1] - gc.collect() - assert tokens[0].spelling == 'int' - - # May trigger segfault if we don't do our job properly. - del tokens - gc.collect() - gc.collect() # Just in case. - -def test_fail_from_source(): - path = os.path.join(kInputsDir, 'non-existent.cpp') - try: - tu = TranslationUnit.from_source(path) - except TranslationUnitLoadError: - tu = None - assert tu == None - -def test_fail_from_ast_file(): - path = os.path.join(kInputsDir, 'non-existent.ast') - try: - tu = TranslationUnit.from_ast_file(path) - except TranslationUnitLoadError: - tu = None - assert tu == None + # Just in case there is an open file descriptor somewhere. + del tu2 + + os.unlink(path) + + def test_index_parse(self): + path = os.path.join(kInputsDir, 'hello.cpp') + index = Index.create() + tu = index.parse(path) + self.assertIsInstance(tu, TranslationUnit) + + def test_get_file(self): + """Ensure tu.get_file() works appropriately.""" + + tu = get_tu('int foo();') + + f = tu.get_file('t.c') + self.assertIsInstance(f, File) + self.assertEqual(f.name, 't.c') + + with self.assertRaises(Exception): + f = tu.get_file('foobar.cpp') + + def test_get_source_location(self): + """Ensure tu.get_source_location() works.""" + + tu = get_tu('int foo();') + + location = tu.get_location('t.c', 2) + self.assertIsInstance(location, SourceLocation) + self.assertEqual(location.offset, 2) + self.assertEqual(location.file.name, 't.c') + + location = tu.get_location('t.c', (1, 3)) + self.assertIsInstance(location, SourceLocation) + self.assertEqual(location.line, 1) + self.assertEqual(location.column, 3) + self.assertEqual(location.file.name, 't.c') + + def test_get_source_range(self): + """Ensure tu.get_source_range() works.""" + + tu = get_tu('int foo();') + + r = tu.get_extent('t.c', (1,4)) + self.assertIsInstance(r, SourceRange) + self.assertEqual(r.start.offset, 1) + self.assertEqual(r.end.offset, 4) + self.assertEqual(r.start.file.name, 't.c') + self.assertEqual(r.end.file.name, 't.c') + + r = tu.get_extent('t.c', ((1,2), (1,3))) + self.assertIsInstance(r, SourceRange) + self.assertEqual(r.start.line, 1) + self.assertEqual(r.start.column, 2) + self.assertEqual(r.end.line, 1) + self.assertEqual(r.end.column, 3) + self.assertEqual(r.start.file.name, 't.c') + self.assertEqual(r.end.file.name, 't.c') + + start = tu.get_location('t.c', 0) + end = tu.get_location('t.c', 5) + + r = tu.get_extent('t.c', (start, end)) + self.assertIsInstance(r, SourceRange) + self.assertEqual(r.start.offset, 0) + self.assertEqual(r.end.offset, 5) + self.assertEqual(r.start.file.name, 't.c') + self.assertEqual(r.end.file.name, 't.c') + + def test_get_tokens_gc(self): + """Ensures get_tokens() works properly with garbage collection.""" + + tu = get_tu('int foo();') + r = tu.get_extent('t.c', (0, 10)) + tokens = list(tu.get_tokens(extent=r)) + + self.assertEqual(tokens[0].spelling, 'int') + gc.collect() + self.assertEqual(tokens[0].spelling, 'int') + + del tokens[1] + gc.collect() + self.assertEqual(tokens[0].spelling, 'int') + + # May trigger segfault if we don't do our job properly. + del tokens + gc.collect() + gc.collect() # Just in case. + + def test_fail_from_source(self): + path = os.path.join(kInputsDir, 'non-existent.cpp') + try: + tu = TranslationUnit.from_source(path) + except TranslationUnitLoadError: + tu = None + self.assertEqual(tu, None) + + def test_fail_from_ast_file(self): + path = os.path.join(kInputsDir, 'non-existent.ast') + try: + tu = TranslationUnit.from_ast_file(path) + except TranslationUnitLoadError: + tu = None + self.assertEqual(tu, None) diff --git a/bindings/python/tests/cindex/test_type.py b/bindings/python/tests/cindex/test_type.py index 6ee0773..4dec058 100644 --- a/bindings/python/tests/cindex/test_type.py +++ b/bindings/python/tests/cindex/test_type.py @@ -1,12 +1,13 @@ import gc +import unittest from clang.cindex import CursorKind from clang.cindex import TranslationUnit from clang.cindex import TypeKind -from nose.tools import raises from .util import get_cursor from .util import get_tu + kInput = """\ typedef int I; @@ -24,400 +25,414 @@ struct teststruct { """ -def test_a_struct(): - tu = get_tu(kInput) - - teststruct = get_cursor(tu, 'teststruct') - assert teststruct is not None, "Could not find teststruct." - fields = list(teststruct.get_children()) - assert all(x.kind == CursorKind.FIELD_DECL for x in fields) - assert all(x.translation_unit is not None for x in fields) - - assert fields[0].spelling == 'a' - assert not fields[0].type.is_const_qualified() - assert fields[0].type.kind == TypeKind.INT - assert fields[0].type.get_canonical().kind == TypeKind.INT - assert fields[0].type.get_typedef_name() == '' - - assert fields[1].spelling == 'b' - assert not fields[1].type.is_const_qualified() - assert fields[1].type.kind == TypeKind.TYPEDEF - assert fields[1].type.get_canonical().kind == TypeKind.INT - assert fields[1].type.get_declaration().spelling == 'I' - assert fields[1].type.get_typedef_name() == 'I' - - assert fields[2].spelling == 'c' - assert not fields[2].type.is_const_qualified() - assert fields[2].type.kind == TypeKind.LONG - assert fields[2].type.get_canonical().kind == TypeKind.LONG - assert fields[2].type.get_typedef_name() == '' - - assert fields[3].spelling == 'd' - assert not fields[3].type.is_const_qualified() - assert fields[3].type.kind == TypeKind.ULONG - assert fields[3].type.get_canonical().kind == TypeKind.ULONG - assert fields[3].type.get_typedef_name() == '' - - assert fields[4].spelling == 'e' - assert not fields[4].type.is_const_qualified() - assert fields[4].type.kind == TypeKind.LONG - assert fields[4].type.get_canonical().kind == TypeKind.LONG - assert fields[4].type.get_typedef_name() == '' - - assert fields[5].spelling == 'f' - assert fields[5].type.is_const_qualified() - assert fields[5].type.kind == TypeKind.INT - assert fields[5].type.get_canonical().kind == TypeKind.INT - assert fields[5].type.get_typedef_name() == '' - - assert fields[6].spelling == 'g' - assert not fields[6].type.is_const_qualified() - assert fields[6].type.kind == TypeKind.POINTER - assert fields[6].type.get_pointee().kind == TypeKind.INT - assert fields[6].type.get_typedef_name() == '' - - assert fields[7].spelling == 'h' - assert not fields[7].type.is_const_qualified() - assert fields[7].type.kind == TypeKind.POINTER - assert fields[7].type.get_pointee().kind == TypeKind.POINTER - assert fields[7].type.get_pointee().get_pointee().kind == TypeKind.POINTER - assert fields[7].type.get_pointee().get_pointee().get_pointee().kind == TypeKind.INT - assert fields[7].type.get_typedef_name() == '' - -def test_references(): - """Ensure that a Type maintains a reference to a TranslationUnit.""" - - tu = get_tu('int x;') - children = list(tu.cursor.get_children()) - assert len(children) > 0 - - cursor = children[0] - t = cursor.type - - assert isinstance(t.translation_unit, TranslationUnit) - - # Delete main TranslationUnit reference and force a GC. - del tu - gc.collect() - assert isinstance(t.translation_unit, TranslationUnit) - - # If the TU was destroyed, this should cause a segfault. - decl = t.get_declaration() constarrayInput=""" struct teststruct { void *A[2]; }; """ -def testConstantArray(): - tu = get_tu(constarrayInput) - - teststruct = get_cursor(tu, 'teststruct') - assert teststruct is not None, "Didn't find teststruct??" - fields = list(teststruct.get_children()) - assert fields[0].spelling == 'A' - assert fields[0].type.kind == TypeKind.CONSTANTARRAY - assert fields[0].type.get_array_element_type() is not None - assert fields[0].type.get_array_element_type().kind == TypeKind.POINTER - assert fields[0].type.get_array_size() == 2 - -def test_equal(): - """Ensure equivalence operators work on Type.""" - source = 'int a; int b; void *v;' - tu = get_tu(source) - - a = get_cursor(tu, 'a') - b = get_cursor(tu, 'b') - v = get_cursor(tu, 'v') - - assert a is not None - assert b is not None - assert v is not None - - assert a.type == b.type - assert a.type != v.type - - assert a.type != None - assert a.type != 'foo' - -def test_type_spelling(): - """Ensure Type.spelling works.""" - tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];') - c = get_cursor(tu, 'c') - i = get_cursor(tu, 'i') - x = get_cursor(tu, 'x') - v = get_cursor(tu, 'v') - assert c is not None - assert i is not None - assert x is not None - assert v is not None - assert c.type.spelling == "int [5]" - assert i.type.spelling == "int []" - assert x.type.spelling == "int" - assert v.type.spelling == "int [x]" - -def test_typekind_spelling(): - """Ensure TypeKind.spelling works.""" - tu = get_tu('int a;') - a = get_cursor(tu, 'a') - - assert a is not None - assert a.type.kind.spelling == 'Int' - -def test_function_argument_types(): - """Ensure that Type.argument_types() works as expected.""" - tu = get_tu('void f(int, int);') - f = get_cursor(tu, 'f') - assert f is not None - - args = f.type.argument_types() - assert args is not None - assert len(args) == 2 - - t0 = args[0] - assert t0 is not None - assert t0.kind == TypeKind.INT - - t1 = args[1] - assert t1 is not None - assert t1.kind == TypeKind.INT - - args2 = list(args) - assert len(args2) == 2 - assert t0 == args2[0] - assert t1 == args2[1] - -@raises(TypeError) -def test_argument_types_string_key(): - """Ensure that non-int keys raise a TypeError.""" - tu = get_tu('void f(int, int);') - f = get_cursor(tu, 'f') - assert f is not None - - args = f.type.argument_types() - assert len(args) == 2 - - args['foo'] - -@raises(IndexError) -def test_argument_types_negative_index(): - """Ensure that negative indexes on argument_types Raises an IndexError.""" - tu = get_tu('void f(int, int);') - f = get_cursor(tu, 'f') - args = f.type.argument_types() - - args[-1] - -@raises(IndexError) -def test_argument_types_overflow_index(): - """Ensure that indexes beyond the length of Type.argument_types() raise.""" - tu = get_tu('void f(int, int);') - f = get_cursor(tu, 'f') - args = f.type.argument_types() - - args[2] - -@raises(Exception) -def test_argument_types_invalid_type(): - """Ensure that obtaining argument_types on a Type without them raises.""" - tu = get_tu('int i;') - i = get_cursor(tu, 'i') - assert i is not None - - i.type.argument_types() - -def test_is_pod(): - """Ensure Type.is_pod() works.""" - tu = get_tu('int i; void f();') - i = get_cursor(tu, 'i') - f = get_cursor(tu, 'f') - - assert i is not None - assert f is not None - - assert i.type.is_pod() - assert not f.type.is_pod() - -def test_function_variadic(): - """Ensure Type.is_function_variadic works.""" - - source =""" -#include -void foo(int a, ...); -void bar(int a, int b); -""" - tu = get_tu(source) - foo = get_cursor(tu, 'foo') - bar = get_cursor(tu, 'bar') - - assert foo is not None - assert bar is not None - - assert isinstance(foo.type.is_function_variadic(), bool) - assert foo.type.is_function_variadic() - assert not bar.type.is_function_variadic() - -def test_element_type(): - """Ensure Type.element_type works.""" - tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];') - c = get_cursor(tu, 'c') - i = get_cursor(tu, 'i') - v = get_cursor(tu, 'v') - assert c is not None - assert i is not None - assert v is not None - - assert c.type.kind == TypeKind.CONSTANTARRAY - assert c.type.element_type.kind == TypeKind.INT - assert i.type.kind == TypeKind.INCOMPLETEARRAY - assert i.type.element_type.kind == TypeKind.INT - assert v.type.kind == TypeKind.VARIABLEARRAY - assert v.type.element_type.kind == TypeKind.INT - -@raises(Exception) -def test_invalid_element_type(): - """Ensure Type.element_type raises if type doesn't have elements.""" - tu = get_tu('int i;') - i = get_cursor(tu, 'i') - assert i is not None - i.element_type - -def test_element_count(): - """Ensure Type.element_count works.""" - tu = get_tu('int i[5]; int j;') - i = get_cursor(tu, 'i') - j = get_cursor(tu, 'j') - - assert i is not None - assert j is not None - - assert i.type.element_count == 5 - - try: - j.type.element_count - assert False - except: - assert True - -def test_is_volatile_qualified(): - """Ensure Type.is_volatile_qualified works.""" - - tu = get_tu('volatile int i = 4; int j = 2;') - - i = get_cursor(tu, 'i') - j = get_cursor(tu, 'j') - - assert i is not None - assert j is not None - - assert isinstance(i.type.is_volatile_qualified(), bool) - assert i.type.is_volatile_qualified() - assert not j.type.is_volatile_qualified() - -def test_is_restrict_qualified(): - """Ensure Type.is_restrict_qualified works.""" - - tu = get_tu('struct s { void * restrict i; void * j; };') - - i = get_cursor(tu, 'i') - j = get_cursor(tu, 'j') - - assert i is not None - assert j is not None - - assert isinstance(i.type.is_restrict_qualified(), bool) - assert i.type.is_restrict_qualified() - assert not j.type.is_restrict_qualified() - -def test_record_layout(): - """Ensure Cursor.type.get_size, Cursor.type.get_align and - Cursor.type.get_offset works.""" - - source =""" -struct a { - long a1; - long a2:3; - long a3:4; - long long a4; -}; -""" - tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)), - (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)), - (['-target','i386-pc-win32'],(8,16,0,32,35,64)), - (['-target','msp430-none-none'],(2,14,0,32,35,48))] - for flags, values in tries: - align,total,a1,a2,a3,a4 = values - - tu = get_tu(source, flags=flags) - teststruct = get_cursor(tu, 'a') +class TestType(unittest.TestCase): + def test_a_struct(self): + tu = get_tu(kInput) + + teststruct = get_cursor(tu, 'teststruct') + self.assertIsNotNone(teststruct, "Could not find teststruct.") fields = list(teststruct.get_children()) - assert teststruct.type.get_align() == align - assert teststruct.type.get_size() == total - assert teststruct.type.get_offset(fields[0].spelling) == a1 - assert teststruct.type.get_offset(fields[1].spelling) == a2 - assert teststruct.type.get_offset(fields[2].spelling) == a3 - assert teststruct.type.get_offset(fields[3].spelling) == a4 - assert fields[0].is_bitfield() == False - assert fields[1].is_bitfield() == True - assert fields[1].get_bitfield_width() == 3 - assert fields[2].is_bitfield() == True - assert fields[2].get_bitfield_width() == 4 - assert fields[3].is_bitfield() == False - -def test_offset(): - """Ensure Cursor.get_record_field_offset works in anonymous records""" - source=""" -struct Test { - struct {int a;} typeanon; - struct { - int bariton; - union { - int foo; - }; - }; - int bar; -};""" - tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64,96)), - (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64,96)), - (['-target','i386-pc-win32'],(8,16,0,32,64,96)), - (['-target','msp430-none-none'],(2,14,0,32,64,96))] - for flags, values in tries: - align,total,f1,bariton,foo,bar = values + self.assertEqual(fields[0].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[0].translation_unit) + self.assertEqual(fields[0].spelling, 'a') + self.assertFalse(fields[0].type.is_const_qualified()) + self.assertEqual(fields[0].type.kind, TypeKind.INT) + self.assertEqual(fields[0].type.get_canonical().kind, TypeKind.INT) + self.assertEqual(fields[0].type.get_typedef_name(), '') + + self.assertEqual(fields[1].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[1].translation_unit) + self.assertEqual(fields[1].spelling, 'b') + self.assertFalse(fields[1].type.is_const_qualified()) + self.assertEqual(fields[1].type.kind, TypeKind.TYPEDEF) + self.assertEqual(fields[1].type.get_canonical().kind, TypeKind.INT) + self.assertEqual(fields[1].type.get_declaration().spelling, 'I') + self.assertEqual(fields[1].type.get_typedef_name(), 'I') + + self.assertEqual(fields[2].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[2].translation_unit) + self.assertEqual(fields[2].spelling, 'c') + self.assertFalse(fields[2].type.is_const_qualified()) + self.assertEqual(fields[2].type.kind, TypeKind.LONG) + self.assertEqual(fields[2].type.get_canonical().kind, TypeKind.LONG) + self.assertEqual(fields[2].type.get_typedef_name(), '') + + self.assertEqual(fields[3].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[3].translation_unit) + self.assertEqual(fields[3].spelling, 'd') + self.assertFalse(fields[3].type.is_const_qualified()) + self.assertEqual(fields[3].type.kind, TypeKind.ULONG) + self.assertEqual(fields[3].type.get_canonical().kind, TypeKind.ULONG) + self.assertEqual(fields[3].type.get_typedef_name(), '') + + self.assertEqual(fields[4].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[4].translation_unit) + self.assertEqual(fields[4].spelling, 'e') + self.assertFalse(fields[4].type.is_const_qualified()) + self.assertEqual(fields[4].type.kind, TypeKind.LONG) + self.assertEqual(fields[4].type.get_canonical().kind, TypeKind.LONG) + self.assertEqual(fields[4].type.get_typedef_name(), '') + + self.assertEqual(fields[5].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[5].translation_unit) + self.assertEqual(fields[5].spelling, 'f') + self.assertTrue(fields[5].type.is_const_qualified()) + self.assertEqual(fields[5].type.kind, TypeKind.INT) + self.assertEqual(fields[5].type.get_canonical().kind, TypeKind.INT) + self.assertEqual(fields[5].type.get_typedef_name(), '') + + self.assertEqual(fields[6].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[6].translation_unit) + self.assertEqual(fields[6].spelling, 'g') + self.assertFalse(fields[6].type.is_const_qualified()) + self.assertEqual(fields[6].type.kind, TypeKind.POINTER) + self.assertEqual(fields[6].type.get_pointee().kind, TypeKind.INT) + self.assertEqual(fields[6].type.get_typedef_name(), '') + + self.assertEqual(fields[7].kind, CursorKind.FIELD_DECL) + self.assertIsNotNone(fields[7].translation_unit) + self.assertEqual(fields[7].spelling, 'h') + self.assertFalse(fields[7].type.is_const_qualified()) + self.assertEqual(fields[7].type.kind, TypeKind.POINTER) + self.assertEqual(fields[7].type.get_pointee().kind, TypeKind.POINTER) + self.assertEqual(fields[7].type.get_pointee().get_pointee().kind, TypeKind.POINTER) + self.assertEqual(fields[7].type.get_pointee().get_pointee().get_pointee().kind, TypeKind.INT) + self.assertEqual(fields[7].type.get_typedef_name(), '') + + def test_references(self): + """Ensure that a Type maintains a reference to a TranslationUnit.""" + + tu = get_tu('int x;') + children = list(tu.cursor.get_children()) + self.assertGreater(len(children), 0) + + cursor = children[0] + t = cursor.type + + self.assertIsInstance(t.translation_unit, TranslationUnit) + + # Delete main TranslationUnit reference and force a GC. + del tu + gc.collect() + self.assertIsInstance(t.translation_unit, TranslationUnit) + + # If the TU was destroyed, this should cause a segfault. + decl = t.get_declaration() + + def testConstantArray(self): + tu = get_tu(constarrayInput) + + teststruct = get_cursor(tu, 'teststruct') + self.assertIsNotNone(teststruct, "Didn't find teststruct??") + fields = list(teststruct.get_children()) + self.assertEqual(fields[0].spelling, 'A') + self.assertEqual(fields[0].type.kind, TypeKind.CONSTANTARRAY) + self.assertIsNotNone(fields[0].type.get_array_element_type()) + self.assertEqual(fields[0].type.get_array_element_type().kind, TypeKind.POINTER) + self.assertEqual(fields[0].type.get_array_size(), 2) + + def test_equal(self): + """Ensure equivalence operators work on Type.""" + source = 'int a; int b; void *v;' tu = get_tu(source) - teststruct = get_cursor(tu, 'Test') - children = list(teststruct.get_children()) - fields = list(teststruct.type.get_fields()) - assert children[0].kind == CursorKind.STRUCT_DECL - assert children[0].spelling != "typeanon" - assert children[1].spelling == "typeanon" - assert fields[0].kind == CursorKind.FIELD_DECL - assert fields[1].kind == CursorKind.FIELD_DECL - assert fields[1].is_anonymous() - assert teststruct.type.get_offset("typeanon") == f1 - assert teststruct.type.get_offset("bariton") == bariton - assert teststruct.type.get_offset("foo") == foo - assert teststruct.type.get_offset("bar") == bar - - -def test_decay(): - """Ensure decayed types are handled as the original type""" - - tu = get_tu("void foo(int a[]);") - foo = get_cursor(tu, 'foo') - a = foo.type.argument_types()[0] - - assert a.kind == TypeKind.INCOMPLETEARRAY - assert a.element_type.kind == TypeKind.INT - assert a.get_canonical().kind == TypeKind.INCOMPLETEARRAY - -def test_addrspace(): - """Ensure the address space can be queried""" - tu = get_tu('__attribute__((address_space(2))) int testInteger = 3;', 'c') - - testInteger = get_cursor(tu, 'testInteger') - - assert testInteger is not None, "Could not find testInteger." - assert testInteger.type.get_address_space() == 2 + + a = get_cursor(tu, 'a') + b = get_cursor(tu, 'b') + v = get_cursor(tu, 'v') + + self.assertIsNotNone(a) + self.assertIsNotNone(b) + self.assertIsNotNone(v) + + self.assertEqual(a.type, b.type) + self.assertNotEqual(a.type, v.type) + + self.assertNotEqual(a.type, None) + self.assertNotEqual(a.type, 'foo') + + def test_type_spelling(self): + """Ensure Type.spelling works.""" + tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];') + c = get_cursor(tu, 'c') + i = get_cursor(tu, 'i') + x = get_cursor(tu, 'x') + v = get_cursor(tu, 'v') + self.assertIsNotNone(c) + self.assertIsNotNone(i) + self.assertIsNotNone(x) + self.assertIsNotNone(v) + self.assertEqual(c.type.spelling, "int [5]") + self.assertEqual(i.type.spelling, "int []") + self.assertEqual(x.type.spelling, "int") + self.assertEqual(v.type.spelling, "int [x]") + + def test_typekind_spelling(self): + """Ensure TypeKind.spelling works.""" + tu = get_tu('int a;') + a = get_cursor(tu, 'a') + + self.assertIsNotNone(a) + self.assertEqual(a.type.kind.spelling, 'Int') + + def test_function_argument_types(self): + """Ensure that Type.argument_types() works as expected.""" + tu = get_tu('void f(int, int);') + f = get_cursor(tu, 'f') + self.assertIsNotNone(f) + + args = f.type.argument_types() + self.assertIsNotNone(args) + self.assertEqual(len(args), 2) + + t0 = args[0] + self.assertIsNotNone(t0) + self.assertEqual(t0.kind, TypeKind.INT) + + t1 = args[1] + self.assertIsNotNone(t1) + self.assertEqual(t1.kind, TypeKind.INT) + + args2 = list(args) + self.assertEqual(len(args2), 2) + self.assertEqual(t0, args2[0]) + self.assertEqual(t1, args2[1]) + + def test_argument_types_string_key(self): + """Ensure that non-int keys raise a TypeError.""" + tu = get_tu('void f(int, int);') + f = get_cursor(tu, 'f') + self.assertIsNotNone(f) + + args = f.type.argument_types() + self.assertEqual(len(args), 2) + + with self.assertRaises(TypeError): + args['foo'] + + def test_argument_types_negative_index(self): + """Ensure that negative indexes on argument_types Raises an IndexError.""" + tu = get_tu('void f(int, int);') + f = get_cursor(tu, 'f') + args = f.type.argument_types() + + with self.assertRaises(IndexError): + args[-1] + + def test_argument_types_overflow_index(self): + """Ensure that indexes beyond the length of Type.argument_types() raise.""" + tu = get_tu('void f(int, int);') + f = get_cursor(tu, 'f') + args = f.type.argument_types() + + with self.assertRaises(IndexError): + args[2] + + def test_argument_types_invalid_type(self): + """Ensure that obtaining argument_types on a Type without them raises.""" + tu = get_tu('int i;') + i = get_cursor(tu, 'i') + self.assertIsNotNone(i) + + with self.assertRaises(Exception): + i.type.argument_types() + + def test_is_pod(self): + """Ensure Type.is_pod() works.""" + tu = get_tu('int i; void f();') + i = get_cursor(tu, 'i') + f = get_cursor(tu, 'f') + + self.assertIsNotNone(i) + self.assertIsNotNone(f) + + self.assertTrue(i.type.is_pod()) + self.assertFalse(f.type.is_pod()) + + def test_function_variadic(self): + """Ensure Type.is_function_variadic works.""" + + source =""" +#include + + void foo(int a, ...); + void bar(int a, int b); + """ + + tu = get_tu(source) + foo = get_cursor(tu, 'foo') + bar = get_cursor(tu, 'bar') + + self.assertIsNotNone(foo) + self.assertIsNotNone(bar) + + self.assertIsInstance(foo.type.is_function_variadic(), bool) + self.assertTrue(foo.type.is_function_variadic()) + self.assertFalse(bar.type.is_function_variadic()) + + def test_element_type(self): + """Ensure Type.element_type works.""" + tu = get_tu('int c[5]; void f(int i[]); int x; int v[x];') + c = get_cursor(tu, 'c') + i = get_cursor(tu, 'i') + v = get_cursor(tu, 'v') + self.assertIsNotNone(c) + self.assertIsNotNone(i) + self.assertIsNotNone(v) + + self.assertEqual(c.type.kind, TypeKind.CONSTANTARRAY) + self.assertEqual(c.type.element_type.kind, TypeKind.INT) + self.assertEqual(i.type.kind, TypeKind.INCOMPLETEARRAY) + self.assertEqual(i.type.element_type.kind, TypeKind.INT) + self.assertEqual(v.type.kind, TypeKind.VARIABLEARRAY) + self.assertEqual(v.type.element_type.kind, TypeKind.INT) + + def test_invalid_element_type(self): + """Ensure Type.element_type raises if type doesn't have elements.""" + tu = get_tu('int i;') + i = get_cursor(tu, 'i') + self.assertIsNotNone(i) + with self.assertRaises(Exception): + i.element_type + + def test_element_count(self): + """Ensure Type.element_count works.""" + tu = get_tu('int i[5]; int j;') + i = get_cursor(tu, 'i') + j = get_cursor(tu, 'j') + + self.assertIsNotNone(i) + self.assertIsNotNone(j) + + self.assertEqual(i.type.element_count, 5) + + with self.assertRaises(Exception): + j.type.element_count + + def test_is_volatile_qualified(self): + """Ensure Type.is_volatile_qualified works.""" + + tu = get_tu('volatile int i = 4; int j = 2;') + + i = get_cursor(tu, 'i') + j = get_cursor(tu, 'j') + + self.assertIsNotNone(i) + self.assertIsNotNone(j) + + self.assertIsInstance(i.type.is_volatile_qualified(), bool) + self.assertTrue(i.type.is_volatile_qualified()) + self.assertFalse(j.type.is_volatile_qualified()) + + def test_is_restrict_qualified(self): + """Ensure Type.is_restrict_qualified works.""" + + tu = get_tu('struct s { void * restrict i; void * j; };') + + i = get_cursor(tu, 'i') + j = get_cursor(tu, 'j') + + self.assertIsNotNone(i) + self.assertIsNotNone(j) + + self.assertIsInstance(i.type.is_restrict_qualified(), bool) + self.assertTrue(i.type.is_restrict_qualified()) + self.assertFalse(j.type.is_restrict_qualified()) + + def test_record_layout(self): + """Ensure Cursor.type.get_size, Cursor.type.get_align and + Cursor.type.get_offset works.""" + + source =""" + struct a { + long a1; + long a2:3; + long a3:4; + long long a4; + }; + """ + tries=[(['-target','i386-linux-gnu'],(4,16,0,32,35,64)), + (['-target','nvptx64-unknown-unknown'],(8,24,0,64,67,128)), + (['-target','i386-pc-win32'],(8,16,0,32,35,64)), + (['-target','msp430-none-none'],(2,14,0,32,35,48))] + for flags, values in tries: + align,total,a1,a2,a3,a4 = values + + tu = get_tu(source, flags=flags) + teststruct = get_cursor(tu, 'a') + fields = list(teststruct.get_children()) + + self.assertEqual(teststruct.type.get_align(), align) + self.assertEqual(teststruct.type.get_size(), total) + self.assertEqual(teststruct.type.get_offset(fields[0].spelling), a1) + self.assertEqual(teststruct.type.get_offset(fields[1].spelling), a2) + self.assertEqual(teststruct.type.get_offset(fields[2].spelling), a3) + self.assertEqual(teststruct.type.get_offset(fields[3].spelling), a4) + self.assertEqual(fields[0].is_bitfield(), False) + self.assertEqual(fields[1].is_bitfield(), True) + self.assertEqual(fields[1].get_bitfield_width(), 3) + self.assertEqual(fields[2].is_bitfield(), True) + self.assertEqual(fields[2].get_bitfield_width(), 4) + self.assertEqual(fields[3].is_bitfield(), False) + + def test_offset(self): + """Ensure Cursor.get_record_field_offset works in anonymous records""" + source=""" + struct Test { + struct {int a;} typeanon; + struct { + int bariton; + union { + int foo; + }; + }; + int bar; + };""" + tries=[(['-target','i386-linux-gnu'],(4,16,0,32,64,96)), + (['-target','nvptx64-unknown-unknown'],(8,24,0,32,64,96)), + (['-target','i386-pc-win32'],(8,16,0,32,64,96)), + (['-target','msp430-none-none'],(2,14,0,32,64,96))] + for flags, values in tries: + align,total,f1,bariton,foo,bar = values + tu = get_tu(source) + teststruct = get_cursor(tu, 'Test') + children = list(teststruct.get_children()) + fields = list(teststruct.type.get_fields()) + self.assertEqual(children[0].kind, CursorKind.STRUCT_DECL) + self.assertNotEqual(children[0].spelling, "typeanon") + self.assertEqual(children[1].spelling, "typeanon") + self.assertEqual(fields[0].kind, CursorKind.FIELD_DECL) + self.assertEqual(fields[1].kind, CursorKind.FIELD_DECL) + self.assertTrue(fields[1].is_anonymous()) + self.assertEqual(teststruct.type.get_offset("typeanon"), f1) + self.assertEqual(teststruct.type.get_offset("bariton"), bariton) + self.assertEqual(teststruct.type.get_offset("foo"), foo) + self.assertEqual(teststruct.type.get_offset("bar"), bar) + + def test_decay(self): + """Ensure decayed types are handled as the original type""" + + tu = get_tu("void foo(int a[]);") + foo = get_cursor(tu, 'foo') + a = foo.type.argument_types()[0] + + self.assertEqual(a.kind, TypeKind.INCOMPLETEARRAY) + self.assertEqual(a.element_type.kind, TypeKind.INT) + self.assertEqual(a.get_canonical().kind, TypeKind.INCOMPLETEARRAY) + + def test_addrspace(self): + """Ensure the address space can be queried""" + tu = get_tu('__attribute__((address_space(2))) int testInteger = 3;', 'c') + + testInteger = get_cursor(tu, 'testInteger') + + self.assertIsNotNone(testInteger, "Could not find testInteger.") + self.assertEqual(testInteger.type.get_address_space(), 2) diff --git a/cmake/caches/Android-stage2.cmake b/cmake/caches/Android-stage2.cmake new file mode 100644 index 0000000..6720517 --- /dev/null +++ b/cmake/caches/Android-stage2.cmake @@ -0,0 +1,52 @@ +set(LLVM_TARGETS_TO_BUILD X86;ARM;AArch64 CACHE STRING "") + +set(CLANG_VENDOR Android CACHE STRING "") +set(CMAKE_BUILD_TYPE Release CACHE STRING "") +set(LLVM_ENABLE_THREADS OFF CACHE BOOL "") +set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") +set(LLVM_LIBDIR_SUFFIX 64 CACHE STRING "") +set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "") + +set(ANDROID_RUNTIMES_ENABLE_ASSERTIONS ON CACHE BOOL "") +set(ANDROID_RUNTIMES_BUILD_TYPE Release CACHE STRING "") +set(ANDROID_BUILTINS_BUILD_TYPE Release CACHE STRING "") + +set(LLVM_BUILTIN_TARGETS "i686-linux-android;x86_64-linux-android;aarch64-linux-android;armv7-linux-android" CACHE STRING "") +foreach(target i686;x86_64;aarch64;armv7) + set(BUILTINS_${target}-linux-android_ANDROID 1 CACHE STRING "") + set(BUILTINS_${target}-linux-android_CMAKE_BUILD_TYPE ${ANDROID_BUILTINS_BUILD_TYPE} CACHE STRING "") + set(BUILTINS_${target}-linux-android_CMAKE_ASM_FLAGS ${ANDROID_${target}_C_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-linux-android_CMAKE_C_FLAGS ${ANDROID_${target}_C_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-linux-android_CMAKE_SYSROOT ${ANDROID_${target}_SYSROOT} CACHE PATH "") + set(BUILTINS_${target}-linux-android_CMAKE_EXE_LINKER_FLAGS ${ANDROID_${target}_LINKER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-linux-android_CMAKE_SHARED_LINKER_FLAGS ${ANDROID_${target}_LINKER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-linux-android_CMAKE_MOUDLE_LINKER_FLAGS ${ANDROID_${target}_LINKER_FLAGS} CACHE PATH "") +endforeach() + + +set(LLVM_RUNTIME_TARGETS "i686-linux-android;x86_64-linux-android;aarch64-linux-android;armv7-linux-android" CACHE STRING "") +foreach(target i686;x86_64;aarch64;armv7) + set(RUNTIMES_${target}-linux-android_ANDROID 1 CACHE STRING "") + set(RUNTIMES_${target}-linux-android_CMAKE_ASM_FLAGS ${ANDROID_${target}_C_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_CMAKE_BUILD_TYPE ${ANDROID_RUNTIMES_BUILD_TYPE} CACHE STRING "") + set(RUNTIMES_${target}-linux-android_CMAKE_C_FLAGS ${ANDROID_${target}_C_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_CMAKE_CXX_FLAGS ${ANDROID_${target}_CXX_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_CMAKE_SYSROOT ${ANDROID_${target}_SYSROOT} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_CMAKE_EXE_LINKER_FLAGS ${ANDROID_${target}_LINKER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_CMAKE_SHARED_LINKER_FLAGS ${ANDROID_${target}_LINKER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_CMAKE_MODULE_LINKER_FLAGS ${ANDROID_${target}_LINKER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_COMPILER_RT_ENABLE_WERROR ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_COMPILER_RT_TEST_COMPILER_CFLAGS ${ANDROID_${target}_C_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-linux-android_COMPILER_RT_INCLUDE_TESTS OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LLVM_ENABLE_ASSERTIONS ${ANDROID_RUNTIMES_ENABLE_ASSERTIONS} CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LLVM_ENABLE_LIBCXX ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LLVM_ENABLE_THREADS OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LLVM_INCLUDE_TESTS OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LIBUNWIND_HAS_NO_EXCEPTIONS_FLAG ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-android_LIBUNWIND_HAS_FUNWIND_TABLES ON CACHE BOOL "") +endforeach() + +set(RUNTIMES_armv7-linux-android_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") + diff --git a/cmake/caches/Android.cmake b/cmake/caches/Android.cmake new file mode 100644 index 0000000..6fbc4a5 --- /dev/null +++ b/cmake/caches/Android.cmake @@ -0,0 +1,43 @@ +# This file sets up a CMakeCache for an Android toolchain build. + +set(LLVM_TARGETS_TO_BUILD X86 CACHE STRING "") + +set(CLANG_ENABLE_ARCMT OFF CACHE BOOL "") +set(CLANG_ENABLE_STATIC_ANALYZER OFF CACHE BOOL "") +set(CLANG_VENDOR Android CACHE STRING "") + +set(CMAKE_BUILD_TYPE RELEASE CACHE STRING "") + +set(HAVE_LIBCXXABI ON CACHE BOOL "") +set(LLVM_BUILD_TOOLS OFF CACHE BOOL "") +set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") +set(LLVM_ENABLE_THREADS OFF CACHE BOOL "") +set(LLVM_LIBDIR_SUFFIX 64 CACHE STRING "") +set(LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD OFF CACHE BOOL "") +set(LLVM_TOOL_OPENMP_BUILD OFF CACHE BOOL "") +set(LLVM_ENABLE_LIBCXX ON CACHE BOOL "") + +if (LIBCXX_ENABLE_ABI_LINKER_SCRIPT) + list(APPEND EXTRA_ARGS -DLIBCXX_ENABLE_ABI_LINKER_SCRIPT=${LIBCXX_ENABLE_ABI_LINKER_SCRIPT}) +endif() + +if (LIBCXX_ENABLE_STATIC_ABI_LIBRARY) + list(APPEND EXTRA_ARGS -DLIBCXX_ENABLE_STATIC_ABI_LIBRARY=${LIBCXX_ENABLE_STATIC_ABI_LIBRARY}) +endif() + +if (LLVM_BUILD_EXTERNAL_COMPILER_RT) + set(APPEND EXTRA_ARGS -DLLVM_BUILD_EXTERNAL_COMPILER_RT=${LLVM_BUILD_EXTERNAL_COMPILER_RT}) +endif() + +get_cmake_property(variableNames VARIABLES) +foreach(variableName ${variableNames}) + if(variableName MATCHES "^STAGE2_") + string(REPLACE "STAGE2_" "" new_name ${variableName}) + list(APPEND EXTRA_ARGS "-D${new_name}=${${variableName}}") + endif() +endforeach() + +set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "") +set(CLANG_BOOTSTRAP_CMAKE_ARGS + ${EXTRA_ARGS} + -C${CMAKE_CURRENT_LIST_DIR}/Android-stage2.cmake CACHE STRING "") diff --git a/cmake/caches/Apple-stage1.cmake b/cmake/caches/Apple-stage1.cmake index 3215981..5180888 100644 --- a/cmake/caches/Apple-stage1.cmake +++ b/cmake/caches/Apple-stage1.cmake @@ -24,6 +24,12 @@ set(CLANG_BOOTSTRAP_PASSTHROUGH CMAKE_OSX_ARCHITECTURES CACHE STRING "") +# Disabling embedded darwin compiler-rt on stage1 builds is required because we +# don't build stage1 to support arm code generation. +set(COMPILER_RT_ENABLE_IOS OFF CACHE BOOL "") +set(COMPILER_RT_ENABLE_WATCHOS OFF CACHE BOOL "") +set(COMPILER_RT_ENABLE_TVOS OFF CACHE BOOL "") + set(BOOTSTRAP_LLVM_ENABLE_LTO ON CACHE BOOL "") set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") @@ -39,6 +45,8 @@ set(CLANG_BOOTSTRAP_TARGETS clang-test-depends distribution install-distribution + install-xcode-toolchain + install-distribution-toolchain clang CACHE STRING "") #bootstrap diff --git a/cmake/caches/Apple-stage2.cmake b/cmake/caches/Apple-stage2.cmake index f07973d..d58e4b6 100644 --- a/cmake/caches/Apple-stage2.cmake +++ b/cmake/caches/Apple-stage2.cmake @@ -40,6 +40,10 @@ set(LIBCXX_INSTALL_HEADERS ON CACHE BOOL "") set(LIBCXX_INCLUDE_TESTS OFF CACHE BOOL "") set(LLVM_LTO_VERSION_OFFSET 3000 CACHE STRING "") +# Generating Xcode toolchains is useful for developers wanting to build and use +# clang without installing over existing tools. +set(LLVM_CREATE_XCODE_TOOLCHAIN ON CACHE BOOL "") + # setup toolchain set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "") set(LLVM_TOOLCHAIN_TOOLS @@ -57,7 +61,7 @@ set(LLVM_DISTRIBUTION_COMPONENTS LTO clang-format clang-headers - libcxx-headers + cxx-headers ${LLVM_TOOLCHAIN_TOOLS} CACHE STRING "") diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake index 1b7b636..52512e9 100644 --- a/cmake/caches/Fuchsia-stage2.cmake +++ b/cmake/caches/Fuchsia-stage2.cmake @@ -7,8 +7,9 @@ set(PACKAGE_VENDOR Fuchsia CACHE STRING "") set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") -set(LLVM_ENABLE_ZLIB ON CACHE BOOL "") set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") +set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") +set(LLVM_ENABLE_ZLIB ON CACHE BOOL "") set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") @@ -23,19 +24,16 @@ if(APPLE) endif() set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "") -set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "") -set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "") +set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "") +set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRING "") -set(LLVM_BUILTIN_TARGETS "x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "") +set(LLVM_BUILTIN_TARGETS "default;x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "") foreach(target x86_64;aarch64) set(BUILTINS_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") set(BUILTINS_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "") endforeach() -if(NOT APPLE) - list(APPEND LLVM_BUILTIN_TARGETS "default") -endif() -set(LLVM_RUNTIME_TARGETS "default;x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "") +set(LLVM_RUNTIME_TARGETS "default;x86_64-fuchsia;aarch64-fuchsia;x86_64-fuchsia-asan:x86_64-fuchsia;aarch64-fuchsia-asan:aarch64-fuchsia" CACHE STRING "") foreach(target x86_64;aarch64) set(RUNTIMES_${target}-fuchsia_CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "") set(RUNTIMES_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") @@ -43,9 +41,19 @@ foreach(target x86_64;aarch64) set(RUNTIMES_${target}-fuchsia_UNIX 1 CACHE BOOL "") set(RUNTIMES_${target}-fuchsia_LLVM_ENABLE_LIBCXX ON CACHE BOOL "") set(RUNTIMES_${target}-fuchsia_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBUNWIND_ENABLE_STATIC OFF CACHE BOOL "") set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "") set(RUNTIMES_${target}-fuchsia_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBCXX_ABI_VERSION 2 CACHE STRING "") + set(RUNTIMES_${target}-fuchsia_LIBCXX_ENABLE_STATIC OFF CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_SANITIZER_USE_COMPILER_RT ON CACHE BOOL "") + + set(RUNTIMES_${target}-fuchsia-asan_LLVM_USE_SANITIZER Address CACHE STRING "") + set(RUNTIMES_${target}-fuchsia-asan_LLVM_RUNTIMES_PREFIX "${target}-fuchsia/" CACHE STRING "") + set(RUNTIMES_${target}-fuchsia-asan_LLVM_RUNTIMES_LIBDIR_SUFFIX "/asan" CACHE STRING "") + set(RUNTIMES_${target}-fuchsia-asan_LIBCXX_INSTALL_HEADERS OFF CACHE BOOL "") endforeach() # Setup toolchain. @@ -59,6 +67,7 @@ set(LLVM_TOOLCHAIN_TOOLS llvm-dsymutil llvm-lib llvm-nm + llvm-objcopy llvm-objdump llvm-profdata llvm-ranlib @@ -67,6 +76,7 @@ set(LLVM_TOOLCHAIN_TOOLS llvm-size llvm-symbolizer opt + sancov CACHE STRING "") set(LLVM_DISTRIBUTION_COMPONENTS @@ -77,6 +87,7 @@ set(LLVM_DISTRIBUTION_COMPONENTS LTO clang-format clang-headers + clang-refactor clang-tidy clangd builtins diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake index 0932c04..05a28d6 100644 --- a/cmake/caches/Fuchsia.cmake +++ b/cmake/caches/Fuchsia.cmake @@ -8,8 +8,9 @@ set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") set(LLVM_INCLUDE_TESTS OFF CACHE BOOL "") set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "") -set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") +set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") +set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") set(CMAKE_BUILD_TYPE Release CACHE STRING "") diff --git a/cmake/modules/AddClang.cmake b/cmake/modules/AddClang.cmake index e657059..c09a842 100644 --- a/cmake/modules/AddClang.cmake +++ b/cmake/modules/AddClang.cmake @@ -104,11 +104,9 @@ macro(add_clang_library name) RUNTIME DESTINATION bin) if (${ARG_SHARED} AND NOT CMAKE_CONFIGURATION_TYPES) - add_custom_target(install-${name} - DEPENDS ${name} - COMMAND "${CMAKE_COMMAND}" - -DCMAKE_INSTALL_COMPONENT=${name} - -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + add_llvm_install_targets(install-${name} + DEPENDS ${name} + COMPONENT ${name}) endif() endif() set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) @@ -147,11 +145,9 @@ macro(add_clang_tool name) COMPONENT ${name}) if(NOT CMAKE_CONFIGURATION_TYPES) - add_custom_target(install-${name} - DEPENDS ${name} - COMMAND "${CMAKE_COMMAND}" - -DCMAKE_INSTALL_COMPONENT=${name} - -P "${CMAKE_BINARY_DIR}/cmake_install.cmake") + add_llvm_install_targets(install-${name} + DEPENDS ${name} + COMPONENT ${name}) endif() set_property(GLOBAL APPEND PROPERTY CLANG_EXPORTS ${name}) endif() diff --git a/cmake/modules/ClangConfig.cmake.in b/cmake/modules/ClangConfig.cmake.in index 03bca69..a5a7eae 100644 --- a/cmake/modules/ClangConfig.cmake.in +++ b/cmake/modules/ClangConfig.cmake.in @@ -11,3 +11,10 @@ set(CLANG_INCLUDE_DIRS "@CLANG_CONFIG_INCLUDE_DIRS@") # Provide all our library targets to users. include("@CLANG_CONFIG_EXPORTS_FILE@") + +# By creating clang-tablegen-targets here, subprojects that depend on Clang's +# tablegen-generated headers can always depend on this target whether building +# in-tree with Clang or not. +if(NOT TARGET clang-tablegen-targets) + add_custom_target(clang-tablegen-targets) +endif() diff --git a/cmake/modules/ProtobufMutator.cmake b/cmake/modules/ProtobufMutator.cmake new file mode 100644 index 0000000..5f23f33 --- /dev/null +++ b/cmake/modules/ProtobufMutator.cmake @@ -0,0 +1,19 @@ +set(PBM_PREFIX protobuf_mutator) +set(PBM_PATH ${CMAKE_CURRENT_BINARY_DIR}/${PBM_PREFIX}/src/${PBM_PREFIX}) +set(PBM_LIB_PATH ${PBM_PATH}-build/src/libprotobuf-mutator.a) +set(PBM_FUZZ_LIB_PATH ${PBM_PATH}-build/src/libfuzzer/libprotobuf-mutator-libfuzzer.a) + +ExternalProject_Add(${PBM_PREFIX} + PREFIX ${PBM_PREFIX} + GIT_REPOSITORY https://github.com/google/libprotobuf-mutator.git + GIT_TAG master + CMAKE_ARGS -DCMAKE_BUILD_TYPE=${CMAKE_BUILD_TYPE} + CMAKE_CACHE_ARGS -DCMAKE_C_COMPILER:FILEPATH=${CMAKE_C_COMPILER} + -DCMAKE_CXX_COMPILER:FILEPATH=${CMAKE_CXX_COMPILER} + BUILD_BYPRODUCTS ${PBM_LIB_PATH} ${PBM_FUZZ_LIB_PATH} + UPDATE_COMMAND "" + INSTALL_COMMAND "" + ) + +set(ProtobufMutator_INCLUDE_DIRS ${PBM_PATH}) +set(ProtobufMutator_LIBRARIES ${PBM_FUZZ_LIB_PATH} ${PBM_LIB_PATH}) diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst index ed28ad4..f589955 100644 --- a/docs/AddressSanitizer.rst +++ b/docs/AddressSanitizer.rst @@ -140,7 +140,8 @@ Memory leak detection --------------------- For more information on leak detector in AddressSanitizer, see -:doc:`LeakSanitizer`. The leak detection is turned on by default on Linux; +:doc:`LeakSanitizer`. The leak detection is turned on by default on Linux, +and can be enabled using ``ASAN_OPTIONS=detect_leaks=1`` on OS X; however, it is not yet supported on other platforms. Issue Suppression diff --git a/docs/AttributeReference.rst b/docs/AttributeReference.rst index 58004a3..a763dde 100644 --- a/docs/AttributeReference.rst +++ b/docs/AttributeReference.rst @@ -1,3471 +1,13 @@ .. ------------------------------------------------------------------- NOTE: This file is automatically generated by running clang-tblgen - -gen-attr-docs. Do not edit this file by hand!! + -gen-attr-docs. Do not edit this file by hand!! The contents for + this file are automatically generated by a server-side process. + + Please do not commit this file. The file exists for local testing + purposes only. ------------------------------------------------------------------- =================== Attributes in Clang -=================== -.. contents:: - :local: - -Introduction -============ - -This page lists the attributes currently supported by Clang. - -Function Attributes -=================== - - -interrupt ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -Clang supports the GNU style ``__attribute__((interrupt("TYPE")))`` attribute on -ARM targets. This attribute may be attached to a function definition and -instructs the backend to generate appropriate function entry/exit code so that -it can be used directly as an interrupt service routine. - -The parameter passed to the interrupt attribute is optional, but if -provided it must be a string literal with one of the following values: "IRQ", -"FIQ", "SWI", "ABORT", "UNDEF". - -The semantics are as follows: - -- If the function is AAPCS, Clang instructs the backend to realign the stack to - 8 bytes on entry. This is a general requirement of the AAPCS at public - interfaces, but may not hold when an exception is taken. Doing this allows - other AAPCS functions to be called. -- If the CPU is M-class this is all that needs to be done since the architecture - itself is designed in such a way that functions obeying the normal AAPCS ABI - constraints are valid exception handlers. -- If the CPU is not M-class, the prologue and epilogue are modified to save all - non-banked registers that are used, so that upon return the user-mode state - will not be corrupted. Note that to avoid unnecessary overhead, only - general-purpose (integer) registers are saved in this way. If VFP operations - are needed, that state must be saved manually. - - Specifically, interrupt kinds other than "FIQ" will save all core registers - except "lr" and "sp". "FIQ" interrupts will save r0-r7. -- If the CPU is not M-class, the return instruction is changed to one of the - canonical sequences permitted by the architecture for exception return. Where - possible the function itself will make the necessary "lr" adjustments so that - the "preferred return address" is selected. - - Unfortunately the compiler is unable to make this guarantee for an "UNDEF" - handler, where the offset from "lr" to the preferred return address depends on - the execution state of the code which generated the exception. In this case - a sequence equivalent to "movs pc, lr" will be used. - - -interrupt ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Clang supports the GNU style ``__attribute__((interrupt))`` attribute on -AVR targets. This attribute may be attached to a function definition and instructs -the backend to generate appropriate function entry/exit code so that it can be used -directly as an interrupt service routine. - -On the AVR, the hardware globally disables interrupts when an interrupt is executed. -The first instruction of an interrupt handler declared with this attribute is a SEI -instruction to re-enable interrupts. See also the signal attribute that -does not insert a SEI instruction. - - -signal ------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Clang supports the GNU style ``__attribute__((signal))`` attribute on -AVR targets. This attribute may be attached to a function definition and instructs -the backend to generate appropriate function entry/exit code so that it can be used -directly as an interrupt service routine. - -Interrupt handler functions defined with the signal attribute do not re-enable interrupts. - - -abi_tag (gnu::abi_tag) ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``abi_tag`` attribute can be applied to a function, variable, class or -inline namespace declaration to modify the mangled name of the entity. It gives -the ability to distinguish between different versions of the same entity but -with different ABI versions supported. For example, a newer version of a class -could have a different set of data members and thus have a different size. Using -the ``abi_tag`` attribute, it is possible to have different mangled names for -a global variable of the class type. Therefor, the old code could keep using -the old manged name and the new code will use the new mangled name with tags. - - -acquire_capability (acquire_shared_capability, clang::acquire_capability, clang::acquire_shared_capability) ------------------------------------------------------------------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -Marks a function as acquiring a capability. - - -alloc_align (gnu::alloc_align) ------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -Use ``__attribute__((alloc_align())`` on a function -declaration to specify that the return value of the function (which must be a -pointer type) is at least as aligned as the value of the indicated parameter. The -parameter is given by its index in the list of formal parameters; the first -parameter has index 1 unless the function is a C++ non-static member function, -in which case the first parameter has index 2 to account for the implicit ``this`` -parameter. - -.. code-block:: c++ - - // The returned pointer has the alignment specified by the first parameter. - void *a(size_t align) __attribute__((alloc_align(1))); - - // The returned pointer has the alignment specified by the second parameter. - void *b(void *v, size_t align) __attribute__((alloc_align(2))); - - // The returned pointer has the alignment specified by the second visible - // parameter, however it must be adjusted for the implicit 'this' parameter. - void *Foo::b(void *v, size_t align) __attribute__((alloc_align(3))); - -Note that this attribute merely informs the compiler that a function always -returns a sufficiently aligned pointer. It does not cause the compiler to -emit code to enforce that alignment. The behavior is undefined if the returned -poitner is not sufficiently aligned. - - -alloc_size (gnu::alloc_size) ----------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``alloc_size`` attribute can be placed on functions that return pointers in -order to hint to the compiler how many bytes of memory will be available at the -returned poiner. ``alloc_size`` takes one or two arguments. - -- ``alloc_size(N)`` implies that argument number N equals the number of - available bytes at the returned pointer. -- ``alloc_size(N, M)`` implies that the product of argument number N and - argument number M equals the number of available bytes at the returned - pointer. - -Argument numbers are 1-based. - -An example of how to use ``alloc_size`` - -.. code-block:: c - - void *my_malloc(int a) __attribute__((alloc_size(1))); - void *my_calloc(int a, int b) __attribute__((alloc_size(1, 2))); - - int main() { - void *const p = my_malloc(100); - assert(__builtin_object_size(p, 0) == 100); - void *const a = my_calloc(20, 5); - assert(__builtin_object_size(a, 0) == 100); - } - -.. Note:: This attribute works differently in clang than it does in GCC. - Specifically, clang will only trace ``const`` pointers (as above); we give up - on pointers that are not marked as ``const``. In the vast majority of cases, - this is unimportant, because LLVM has support for the ``alloc_size`` - attribute. However, this may cause mildly unintuitive behavior when used with - other attributes, such as ``enable_if``. - - -interrupt ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -Clang supports the GNU style ``__attribute__((interrupt))`` attribute on -x86/x86-64 targets.The compiler generates function entry and exit sequences -suitable for use in an interrupt handler when this attribute is present. -The 'IRET' instruction, instead of the 'RET' instruction, is used to return -from interrupt or exception handlers. All registers, except for the EFLAGS -register which is restored by the 'IRET' instruction, are preserved by the -compiler. - -Any interruptible-without-stack-switch code must be compiled with --mno-red-zone since interrupt handlers can and will, because of the -hardware design, touch the red zone. - -1. interrupt handler must be declared with a mandatory pointer argument: - - .. code-block:: c - - struct interrupt_frame - { - uword_t ip; - uword_t cs; - uword_t flags; - uword_t sp; - uword_t ss; - }; - - __attribute__ ((interrupt)) - void f (struct interrupt_frame *frame) { - ... - } - -2. exception handler: - - The exception handler is very similar to the interrupt handler with - a different mandatory function signature: - - .. code-block:: c - - __attribute__ ((interrupt)) - void f (struct interrupt_frame *frame, uword_t error_code) { - ... - } - - and compiler pops 'ERROR_CODE' off stack before the 'IRET' instruction. - - The exception handler should only be used for exceptions which push an - error code and all other exceptions must use the interrupt handler. - The system will crash if the wrong handler is used. - - -no_caller_saved_registers (gnu::no_caller_saved_registers) ----------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -Use this attribute to indicate that the specified function has no -caller-saved registers. That is, all registers are callee-saved except for -registers used for passing parameters to the function or returning parameters -from the function. -The compiler saves and restores any modified registers that were not used for -passing or returning arguments to the function. - -The user can call functions specified with the 'no_caller_saved_registers' -attribute from an interrupt handler without saving and restoring all -call-clobbered registers. - -Note that 'no_caller_saved_registers' attribute is not a calling convention. -In fact, it only overrides the decision of which registers should be saved by -the caller, but not how the parameters are passed from the caller to the callee. - -For example: - - .. code-block:: c - - __attribute__ ((no_caller_saved_registers, fastcall)) - void f (int arg1, int arg2) { - ... - } - - In this case parameters 'arg1' and 'arg2' will be passed in registers. - In this case, on 32-bit x86 targets, the function 'f' will use ECX and EDX as - register parameters. However, it will not assume any scratch registers and - should save and restore any modified registers except for ECX and EDX. - - -assert_capability (assert_shared_capability, clang::assert_capability, clang::assert_shared_capability) -------------------------------------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -Marks a function that dynamically tests whether a capability is held, and halts -the program if it is not held. - - -assume_aligned (gnu::assume_aligned) ------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -Use ``__attribute__((assume_aligned([,]))`` on a function -declaration to specify that the return value of the function (which must be a -pointer type) has the specified offset, in bytes, from an address with the -specified alignment. The offset is taken to be zero if omitted. - -.. code-block:: c++ - - // The returned pointer value has 32-byte alignment. - void *a() __attribute__((assume_aligned (32))); - - // The returned pointer value is 4 bytes greater than an address having - // 32-byte alignment. - void *b() __attribute__((assume_aligned (32, 4))); - -Note that this attribute provides information to the compiler regarding a -condition that the code already ensures is true. It does not cause the compiler -to enforce the provided alignment assumption. - - -availability ------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -The ``availability`` attribute can be placed on declarations to describe the -lifecycle of that declaration relative to operating system versions. Consider -the function declaration for a hypothetical function ``f``: - -.. code-block:: c++ - - void f(void) __attribute__((availability(macos,introduced=10.4,deprecated=10.6,obsoleted=10.7))); - -The availability attribute states that ``f`` was introduced in macOS 10.4, -deprecated in macOS 10.6, and obsoleted in macOS 10.7. This information -is used by Clang to determine when it is safe to use ``f``: for example, if -Clang is instructed to compile code for macOS 10.5, a call to ``f()`` -succeeds. If Clang is instructed to compile code for macOS 10.6, the call -succeeds but Clang emits a warning specifying that the function is deprecated. -Finally, if Clang is instructed to compile code for macOS 10.7, the call -fails because ``f()`` is no longer available. - -The availability attribute is a comma-separated list starting with the -platform name and then including clauses specifying important milestones in the -declaration's lifetime (in any order) along with additional information. Those -clauses can be: - -introduced=\ *version* - The first version in which this declaration was introduced. - -deprecated=\ *version* - The first version in which this declaration was deprecated, meaning that - users should migrate away from this API. - -obsoleted=\ *version* - The first version in which this declaration was obsoleted, meaning that it - was removed completely and can no longer be used. - -unavailable - This declaration is never available on this platform. - -message=\ *string-literal* - Additional message text that Clang will provide when emitting a warning or - error about use of a deprecated or obsoleted declaration. Useful to direct - users to replacement APIs. - -replacement=\ *string-literal* - Additional message text that Clang will use to provide Fix-It when emitting - a warning about use of a deprecated declaration. The Fix-It will replace - the deprecated declaration with the new declaration specified. - -Multiple availability attributes can be placed on a declaration, which may -correspond to different platforms. Only the availability attribute with the -platform corresponding to the target platform will be used; any others will be -ignored. If no availability attribute specifies availability for the current -target platform, the availability attributes are ignored. Supported platforms -are: - -``ios`` - Apple's iOS operating system. The minimum deployment target is specified by - the ``-mios-version-min=*version*`` or ``-miphoneos-version-min=*version*`` - command-line arguments. - -``macos`` - Apple's macOS operating system. The minimum deployment target is - specified by the ``-mmacosx-version-min=*version*`` command-line argument. - ``macosx`` is supported for backward-compatibility reasons, but it is - deprecated. - -``tvos`` - Apple's tvOS operating system. The minimum deployment target is specified by - the ``-mtvos-version-min=*version*`` command-line argument. - -``watchos`` - Apple's watchOS operating system. The minimum deployment target is specified by - the ``-mwatchos-version-min=*version*`` command-line argument. - -A declaration can typically be used even when deploying back to a platform -version prior to when the declaration was introduced. When this happens, the -declaration is `weakly linked -`_, -as if the ``weak_import`` attribute were added to the declaration. A -weakly-linked declaration may or may not be present a run-time, and a program -can determine whether the declaration is present by checking whether the -address of that declaration is non-NULL. - -The flag ``strict`` disallows using API when deploying back to a -platform version prior to when the declaration was introduced. An -attempt to use such API before its introduction causes a hard error. -Weakly-linking is almost always a better API choice, since it allows -users to query availability at runtime. - -If there are multiple declarations of the same entity, the availability -attributes must either match on a per-platform basis or later -declarations must not have availability attributes for that -platform. For example: - -.. code-block:: c - - void g(void) __attribute__((availability(macos,introduced=10.4))); - void g(void) __attribute__((availability(macos,introduced=10.4))); // okay, matches - void g(void) __attribute__((availability(ios,introduced=4.0))); // okay, adds a new platform - void g(void); // okay, inherits both macos and ios availability from above. - void g(void) __attribute__((availability(macos,introduced=10.5))); // error: mismatch - -When one method overrides another, the overriding method can be more widely available than the overridden method, e.g.,: - -.. code-block:: objc - - @interface A - - (id)method __attribute__((availability(macos,introduced=10.4))); - - (id)method2 __attribute__((availability(macos,introduced=10.4))); - @end - - @interface B : A - - (id)method __attribute__((availability(macos,introduced=10.3))); // okay: method moved into base class later - - (id)method __attribute__((availability(macos,introduced=10.5))); // error: this method was available via the base class in 10.4 - @end - -Starting with the macOS 10.12 SDK, the ``API_AVAILABLE`` macro from -```` can simplify the spelling: - -.. code-block:: objc - - @interface A - - (id)method API_AVAILABLE(macos(10.11))); - - (id)otherMethod API_AVAILABLE(macos(10.11), ios(11.0)); - @end - -Also see the documentation for `@available -`_ - - -_Noreturn ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -A function declared as ``_Noreturn`` shall not return to its caller. The -compiler will generate a diagnostic for a function declared as ``_Noreturn`` -that appears to be capable of returning to its caller. - - -noreturn --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","X","","", "", "X" - -A function declared as ``[[noreturn]]`` shall not return to its caller. The -compiler will generate a diagnostic for a function declared as ``[[noreturn]]`` -that appears to be capable of returning to its caller. - - -carries_dependency ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``carries_dependency`` attribute specifies dependency propagation into and -out of functions. - -When specified on a function or Objective-C method, the ``carries_dependency`` -attribute means that the return value carries a dependency out of the function, -so that the implementation need not constrain ordering upon return from that -function. Implementations of the function and its caller may choose to preserve -dependencies instead of emitting memory ordering instructions such as fences. - -Note, this attribute does not change the meaning of the program, but may result -in generation of more efficient code. - - -convergent (clang::convergent) ------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``convergent`` attribute can be placed on a function declaration. It is -translated into the LLVM ``convergent`` attribute, which indicates that the call -instructions of a function with this attribute cannot be made control-dependent -on any additional values. - -In languages designed for SPMD/SIMT programming model, e.g. OpenCL or CUDA, -the call instructions of a function with this attribute must be executed by -all work items or threads in a work group or sub group. - -This attribute is different from ``noduplicate`` because it allows duplicating -function calls if it can be proved that the duplicated function calls are -not made control-dependent on any additional values, e.g., unrolling a loop -executed by all work items. - -Sample usage: -.. code-block:: c - - void convfunc(void) __attribute__((convergent)); - // Setting it as a C++11 attribute is also valid in a C++ program. - // void convfunc(void) [[clang::convergent]]; - - -deprecated (gnu::deprecated) ----------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","X","", "", "" - -The ``deprecated`` attribute can be applied to a function, a variable, or a -type. This is useful when identifying functions, variables, or types that are -expected to be removed in a future version of a program. - -Consider the function declaration for a hypothetical function ``f``: - -.. code-block:: c++ - - void f(void) __attribute__((deprecated("message", "replacement"))); - -When spelled as `__attribute__((deprecated))`, the deprecated attribute can have -two optional string arguments. The first one is the message to display when -emitting the warning; the second one enables the compiler to provide a Fix-It -to replace the deprecated name with a new name. Otherwise, when spelled as -`[[gnu::deprecated]] or [[deprecated]]`, the attribute can have one optional -string argument which is the message to display when emitting the warning. - - -diagnose_if ------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -The ``diagnose_if`` attribute can be placed on function declarations to emit -warnings or errors at compile-time if calls to the attributed function meet -certain user-defined criteria. For example: - -.. code-block:: c - - void abs(int a) - __attribute__((diagnose_if(a >= 0, "Redundant abs call", "warning"))); - void must_abs(int a) - __attribute__((diagnose_if(a >= 0, "Redundant abs call", "error"))); - - int val = abs(1); // warning: Redundant abs call - int val2 = must_abs(1); // error: Redundant abs call - int val3 = abs(val); - int val4 = must_abs(val); // Because run-time checks are not emitted for - // diagnose_if attributes, this executes without - // issue. - - -``diagnose_if`` is closely related to ``enable_if``, with a few key differences: - -* Overload resolution is not aware of ``diagnose_if`` attributes: they're - considered only after we select the best candidate from a given candidate set. -* Function declarations that differ only in their ``diagnose_if`` attributes are - considered to be redeclarations of the same function (not overloads). -* If the condition provided to ``diagnose_if`` cannot be evaluated, no - diagnostic will be emitted. - -Otherwise, ``diagnose_if`` is essentially the logical negation of ``enable_if``. - -As a result of bullet number two, ``diagnose_if`` attributes will stack on the -same function. For example: - -.. code-block:: c - - int foo() __attribute__((diagnose_if(1, "diag1", "warning"))); - int foo() __attribute__((diagnose_if(1, "diag2", "warning"))); - - int bar = foo(); // warning: diag1 - // warning: diag2 - int (*fooptr)(void) = foo; // warning: diag1 - // warning: diag2 - - constexpr int supportsAPILevel(int N) { return N < 5; } - int baz(int a) - __attribute__((diagnose_if(!supportsAPILevel(10), - "Upgrade to API level 10 to use baz", "error"))); - int baz(int a) - __attribute__((diagnose_if(!a, "0 is not recommended.", "warning"))); - - int (*bazptr)(int) = baz; // error: Upgrade to API level 10 to use baz - int v = baz(0); // error: Upgrade to API level 10 to use baz - -Query for this feature with ``__has_attribute(diagnose_if)``. - - -disable_tail_calls (clang::disable_tail_calls) ----------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``disable_tail_calls`` attribute instructs the backend to not perform tail call optimization inside the marked function. - -For example: - - .. code-block:: c - - int callee(int); - - int foo(int a) __attribute__((disable_tail_calls)) { - return callee(a); // This call is not tail-call optimized. - } - -Marking virtual functions as ``disable_tail_calls`` is legal. - - .. code-block:: c++ - - int callee(int); - - class Base { - public: - [[clang::disable_tail_calls]] virtual int foo1() { - return callee(); // This call is not tail-call optimized. - } - }; - - class Derived1 : public Base { - public: - int foo1() override { - return callee(); // This call is tail-call optimized. - } - }; - - -enable_if ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -.. Note:: Some features of this attribute are experimental. The meaning of - multiple enable_if attributes on a single declaration is subject to change in - a future version of clang. Also, the ABI is not standardized and the name - mangling may change in future versions. To avoid that, use asm labels. - -The ``enable_if`` attribute can be placed on function declarations to control -which overload is selected based on the values of the function's arguments. -When combined with the ``overloadable`` attribute, this feature is also -available in C. - -.. code-block:: c++ - - int isdigit(int c); - int isdigit(int c) __attribute__((enable_if(c <= -1 || c > 255, "chosen when 'c' is out of range"))) __attribute__((unavailable("'c' must have the value of an unsigned char or EOF"))); - - void foo(char c) { - isdigit(c); - isdigit(10); - isdigit(-10); // results in a compile-time error. - } - -The enable_if attribute takes two arguments, the first is an expression written -in terms of the function parameters, the second is a string explaining why this -overload candidate could not be selected to be displayed in diagnostics. The -expression is part of the function signature for the purposes of determining -whether it is a redeclaration (following the rules used when determining -whether a C++ template specialization is ODR-equivalent), but is not part of -the type. - -The enable_if expression is evaluated as if it were the body of a -bool-returning constexpr function declared with the arguments of the function -it is being applied to, then called with the parameters at the call site. If the -result is false or could not be determined through constant expression -evaluation, then this overload will not be chosen and the provided string may -be used in a diagnostic if the compile fails as a result. - -Because the enable_if expression is an unevaluated context, there are no global -state changes, nor the ability to pass information from the enable_if -expression to the function body. For example, suppose we want calls to -strnlen(strbuf, maxlen) to resolve to strnlen_chk(strbuf, maxlen, size of -strbuf) only if the size of strbuf can be determined: - -.. code-block:: c++ - - __attribute__((always_inline)) - static inline size_t strnlen(const char *s, size_t maxlen) - __attribute__((overloadable)) - __attribute__((enable_if(__builtin_object_size(s, 0) != -1))), - "chosen when the buffer size is known but 'maxlen' is not"))) - { - return strnlen_chk(s, maxlen, __builtin_object_size(s, 0)); - } - -Multiple enable_if attributes may be applied to a single declaration. In this -case, the enable_if expressions are evaluated from left to right in the -following manner. First, the candidates whose enable_if expressions evaluate to -false or cannot be evaluated are discarded. If the remaining candidates do not -share ODR-equivalent enable_if expressions, the overload resolution is -ambiguous. Otherwise, enable_if overload resolution continues with the next -enable_if attribute on the candidates that have not been discarded and have -remaining enable_if attributes. In this way, we pick the most specific -overload out of a number of viable overloads using enable_if. - -.. code-block:: c++ - - void f() __attribute__((enable_if(true, ""))); // #1 - void f() __attribute__((enable_if(true, ""))) __attribute__((enable_if(true, ""))); // #2 - - void g(int i, int j) __attribute__((enable_if(i, ""))); // #1 - void g(int i, int j) __attribute__((enable_if(j, ""))) __attribute__((enable_if(true))); // #2 - -In this example, a call to f() is always resolved to #2, as the first enable_if -expression is ODR-equivalent for both declarations, but #1 does not have another -enable_if expression to continue evaluating, so the next round of evaluation has -only a single candidate. In a call to g(1, 1), the call is ambiguous even though -#2 has more enable_if attributes, because the first enable_if expressions are -not ODR-equivalent. - -Query for this feature with ``__has_attribute(enable_if)``. - -Note that functions with one or more ``enable_if`` attributes may not have -their address taken, unless all of the conditions specified by said -``enable_if`` are constants that evaluate to ``true``. For example: - -.. code-block:: c - - const int TrueConstant = 1; - const int FalseConstant = 0; - int f(int a) __attribute__((enable_if(a > 0, ""))); - int g(int a) __attribute__((enable_if(a == 0 || a != 0, ""))); - int h(int a) __attribute__((enable_if(1, ""))); - int i(int a) __attribute__((enable_if(TrueConstant, ""))); - int j(int a) __attribute__((enable_if(FalseConstant, ""))); - - void fn() { - int (*ptr)(int); - ptr = &f; // error: 'a > 0' is not always true - ptr = &g; // error: 'a == 0 || a != 0' is not a truthy constant - ptr = &h; // OK: 1 is a truthy constant - ptr = &i; // OK: 'TrueConstant' is a truthy constant - ptr = &j; // error: 'FalseConstant' is a constant, but not truthy - } - -Because ``enable_if`` evaluation happens during overload resolution, -``enable_if`` may give unintuitive results when used with templates, depending -on when overloads are resolved. In the example below, clang will emit a -diagnostic about no viable overloads for ``foo`` in ``bar``, but not in ``baz``: - -.. code-block:: c++ - - double foo(int i) __attribute__((enable_if(i > 0, ""))); - void *foo(int i) __attribute__((enable_if(i <= 0, ""))); - template - auto bar() { return foo(I); } - - template - auto baz() { return foo(T::number); } - - struct WithNumber { constexpr static int number = 1; }; - void callThem() { - bar(); - baz(); - } - -This is because, in ``bar``, ``foo`` is resolved prior to template -instantiation, so the value for ``I`` isn't known (thus, both ``enable_if`` -conditions for ``foo`` fail). However, in ``baz``, ``foo`` is resolved during -template instantiation, so the value for ``T::number`` is known. - - -external_source_symbol (clang::external_source_symbol) ------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``external_source_symbol`` attribute specifies that a declaration originates -from an external source and describes the nature of that source. - -The fact that Clang is capable of recognizing declarations that were defined -externally can be used to provide better tooling support for mixed-language -projects or projects that rely on auto-generated code. For instance, an IDE that -uses Clang and that supports mixed-language projects can use this attribute to -provide a correct 'jump-to-definition' feature. For a concrete example, -consider a protocol that's defined in a Swift file: - -.. code-block:: swift - - @objc public protocol SwiftProtocol { - func method() - } - -This protocol can be used from Objective-C code by including a header file that -was generated by the Swift compiler. The declarations in that header can use -the ``external_source_symbol`` attribute to make Clang aware of the fact -that ``SwiftProtocol`` actually originates from a Swift module: - -.. code-block:: objc - - __attribute__((external_source_symbol(language="Swift",defined_in="module"))) - @protocol SwiftProtocol - @required - - (void) method; - @end - -Consequently, when 'jump-to-definition' is performed at a location that -references ``SwiftProtocol``, the IDE can jump to the original definition in -the Swift source file rather than jumping to the Objective-C declaration in the -auto-generated header file. - -The ``external_source_symbol`` attribute is a comma-separated list that includes -clauses that describe the origin and the nature of the particular declaration. -Those clauses can be: - -language=\ *string-literal* - The name of the source language in which this declaration was defined. - -defined_in=\ *string-literal* - The name of the source container in which the declaration was defined. The - exact definition of source container is language-specific, e.g. Swift's - source containers are modules, so ``defined_in`` should specify the Swift - module name. - -generated_declaration - This declaration was automatically generated by some tool. - -The clauses can be specified in any order. The clauses that are listed above are -all optional, but the attribute has to have at least one clause. - - -flatten (gnu::flatten) ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``flatten`` attribute causes calls within the attributed function to -be inlined unless it is impossible to do so, for example if the body of the -callee is unavailable or if the callee has the ``noinline`` attribute. - - -format (gnu::format) --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -Clang supports the ``format`` attribute, which indicates that the function -accepts a ``printf`` or ``scanf``-like format string and corresponding -arguments or a ``va_list`` that contains these arguments. - -Please see `GCC documentation about format attribute -`_ to find details -about attribute syntax. - -Clang implements two kinds of checks with this attribute. - -#. Clang checks that the function with the ``format`` attribute is called with - a format string that uses format specifiers that are allowed, and that - arguments match the format string. This is the ``-Wformat`` warning, it is - on by default. - -#. Clang checks that the format string argument is a literal string. This is - the ``-Wformat-nonliteral`` warning, it is off by default. - - Clang implements this mostly the same way as GCC, but there is a difference - for functions that accept a ``va_list`` argument (for example, ``vprintf``). - GCC does not emit ``-Wformat-nonliteral`` warning for calls to such - functions. Clang does not warn if the format string comes from a function - parameter, where the function is annotated with a compatible attribute, - otherwise it warns. For example: - - .. code-block:: c - - __attribute__((__format__ (__scanf__, 1, 3))) - void foo(const char* s, char *buf, ...) { - va_list ap; - va_start(ap, buf); - - vprintf(s, ap); // warning: format string is not a string literal - } - - In this case we warn because ``s`` contains a format string for a - ``scanf``-like function, but it is passed to a ``printf``-like function. - - If the attribute is removed, clang still warns, because the format string is - not a string literal. - - Another example: - - .. code-block:: c - - __attribute__((__format__ (__printf__, 1, 3))) - void foo(const char* s, char *buf, ...) { - va_list ap; - va_start(ap, buf); - - vprintf(s, ap); // warning - } - - In this case Clang does not warn because the format string ``s`` and - the corresponding arguments are annotated. If the arguments are - incorrect, the caller of ``foo`` will receive a warning. - - -ifunc (gnu::ifunc) ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -``__attribute__((ifunc("resolver")))`` is used to mark that the address of a declaration should be resolved at runtime by calling a resolver function. - -The symbol name of the resolver function is given in quotes. A function with this name (after mangling) must be defined in the current translation unit; it may be ``static``. The resolver function should take no arguments and return a pointer. - -The ``ifunc`` attribute may only be used on a function declaration. A function declaration with an ``ifunc`` attribute is considered to be a definition of the declared entity. The entity must not have weak linkage; for example, in C++, it cannot be applied to a declaration if a definition at that location would be considered inline. - -Not all targets support this attribute. ELF targets support this attribute when using binutils v2.20.1 or higher and glibc v2.11.1 or higher. Non-ELF targets currently do not support this attribute. - - -internal_linkage (clang::internal_linkage) ------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``internal_linkage`` attribute changes the linkage type of the declaration to internal. -This is similar to C-style ``static``, but can be used on classes and class methods. When applied to a class definition, -this attribute affects all methods and static data members of that class. -This can be used to contain the ABI of a C++ library by excluding unwanted class methods from the export tables. - - -micromips (gnu::micromips) --------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -Clang supports the GNU style ``__attribute__((micromips))`` and -``__attribute__((nomicromips))`` attributes on MIPS targets. These attributes -may be attached to a function definition and instructs the backend to generate -or not to generate microMIPS code for that function. - -These attributes override the `-mmicromips` and `-mno-micromips` options -on the command line. - - -interrupt ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Clang supports the GNU style ``__attribute__((interrupt("ARGUMENT")))`` attribute on -MIPS targets. This attribute may be attached to a function definition and instructs -the backend to generate appropriate function entry/exit code so that it can be used -directly as an interrupt service routine. - -By default, the compiler will produce a function prologue and epilogue suitable for -an interrupt service routine that handles an External Interrupt Controller (eic) -generated interrupt. This behaviour can be explicitly requested with the "eic" -argument. - -Otherwise, for use with vectored interrupt mode, the argument passed should be -of the form "vector=LEVEL" where LEVEL is one of the following values: -"sw0", "sw1", "hw0", "hw1", "hw2", "hw3", "hw4", "hw5". The compiler will -then set the interrupt mask to the corresponding level which will mask all -interrupts up to and including the argument. - -The semantics are as follows: - -- The prologue is modified so that the Exception Program Counter (EPC) and - Status coprocessor registers are saved to the stack. The interrupt mask is - set so that the function can only be interrupted by a higher priority - interrupt. The epilogue will restore the previous values of EPC and Status. - -- The prologue and epilogue are modified to save and restore all non-kernel - registers as necessary. - -- The FPU is disabled in the prologue, as the floating pointer registers are not - spilled to the stack. - -- The function return sequence is changed to use an exception return instruction. - -- The parameter sets the interrupt mask for the function corresponding to the - interrupt level specified. If no mask is specified the interrupt mask - defaults to "eic". - - -noalias -------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","X","", "", "" - -The ``noalias`` attribute indicates that the only memory accesses inside -function are loads and stores from objects pointed to by its pointer-typed -arguments, with arbitrary offsets. - - -noduplicate (clang::noduplicate) --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``noduplicate`` attribute can be placed on function declarations to control -whether function calls to this function can be duplicated or not as a result of -optimizations. This is required for the implementation of functions with -certain special requirements, like the OpenCL "barrier" function, that might -need to be run concurrently by all the threads that are executing in lockstep -on the hardware. For example this attribute applied on the function -"nodupfunc" in the code below avoids that: - -.. code-block:: c - - void nodupfunc() __attribute__((noduplicate)); - // Setting it as a C++11 attribute is also valid - // void nodupfunc() [[clang::noduplicate]]; - void foo(); - void bar(); - - nodupfunc(); - if (a > n) { - foo(); - } else { - bar(); - } - -gets possibly modified by some optimizations into code similar to this: - -.. code-block:: c - - if (a > n) { - nodupfunc(); - foo(); - } else { - nodupfunc(); - bar(); - } - -where the call to "nodupfunc" is duplicated and sunk into the two branches -of the condition. - - -nomicromips (gnu::nomicromips) ------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -Clang supports the GNU style ``__attribute__((micromips))`` and -``__attribute__((nomicromips))`` attributes on MIPS targets. These attributes -may be attached to a function definition and instructs the backend to generate -or not to generate microMIPS code for that function. - -These attributes override the `-mmicromips` and `-mno-micromips` options -on the command line. - - -no_sanitize (clang::no_sanitize) --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -Use the ``no_sanitize`` attribute on a function declaration to specify -that a particular instrumentation or set of instrumentations should not be -applied to that function. The attribute takes a list of string literals, -which have the same meaning as values accepted by the ``-fno-sanitize=`` -flag. For example, ``__attribute__((no_sanitize("address", "thread")))`` -specifies that AddressSanitizer and ThreadSanitizer should not be applied -to the function. - -See :ref:`Controlling Code Generation ` for a -full list of supported sanitizer flags. - - -no_sanitize_address (no_address_safety_analysis, gnu::no_address_safety_analysis, gnu::no_sanitize_address) ------------------------------------------------------------------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -.. _langext-address_sanitizer: - -Use ``__attribute__((no_sanitize_address))`` on a function declaration to -specify that address safety instrumentation (e.g. AddressSanitizer) should -not be applied to that function. - - -no_sanitize_thread ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -.. _langext-thread_sanitizer: - -Use ``__attribute__((no_sanitize_thread))`` on a function declaration to -specify that checks for data races on plain (non-atomic) memory accesses should -not be inserted by ThreadSanitizer. The function is still instrumented by the -tool to avoid false positives and provide meaningful stack traces. - - -no_sanitize_memory ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -.. _langext-memory_sanitizer: - -Use ``__attribute__((no_sanitize_memory))`` on a function declaration to -specify that checks for uninitialized memory should not be inserted -(e.g. by MemorySanitizer). The function may still be instrumented by the tool -to avoid false positives in other places. - - -no_split_stack (gnu::no_split_stack) ------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``no_split_stack`` attribute disables the emission of the split stack -preamble for a particular function. It has no effect if ``-fsplit-stack`` -is not specified. - - -not_tail_called (clang::not_tail_called) ----------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``not_tail_called`` attribute prevents tail-call optimization on statically bound calls. It has no effect on indirect calls. Virtual functions, objective-c methods, and functions marked as ``always_inline`` cannot be marked as ``not_tail_called``. - -For example, it prevents tail-call optimization in the following case: - - .. code-block:: c - - int __attribute__((not_tail_called)) foo1(int); - - int foo2(int a) { - return foo1(a); // No tail-call optimization on direct calls. - } - -However, it doesn't prevent tail-call optimization in this case: - - .. code-block:: c - - int __attribute__((not_tail_called)) foo1(int); - - int foo2(int a) { - int (*fn)(int) = &foo1; - - // not_tail_called has no effect on an indirect call even if the call can be - // resolved at compile time. - return (*fn)(a); - } - -Marking virtual functions as ``not_tail_called`` is an error: - - .. code-block:: c++ - - class Base { - public: - // not_tail_called on a virtual function is an error. - [[clang::not_tail_called]] virtual int foo1(); - - virtual int foo2(); - - // Non-virtual functions can be marked ``not_tail_called``. - [[clang::not_tail_called]] int foo3(); - }; - - class Derived1 : public Base { - public: - int foo1() override; - - // not_tail_called on a virtual function is an error. - [[clang::not_tail_called]] int foo2() override; - }; - - -#pragma omp declare simd ------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","", "X", "" - -The `declare simd` construct can be applied to a function to enable the creation -of one or more versions that can process multiple arguments using SIMD -instructions from a single invocation in a SIMD loop. The `declare simd` -directive is a declarative directive. There may be multiple `declare simd` -directives for a function. The use of a `declare simd` construct on a function -enables the creation of SIMD versions of the associated function that can be -used to process multiple arguments from a single invocation from a SIMD loop -concurrently. -The syntax of the `declare simd` construct is as follows: - - .. code-block:: c - - #pragma omp declare simd [clause[[,] clause] ...] new-line - [#pragma omp declare simd [clause[[,] clause] ...] new-line] - [...] - function definition or declaration - -where clause is one of the following: - - .. code-block:: c - - simdlen(length) - linear(argument-list[:constant-linear-step]) - aligned(argument-list[:alignment]) - uniform(argument-list) - inbranch - notinbranch - - -#pragma omp declare target --------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","", "X", "" - -The `declare target` directive specifies that variables and functions are mapped -to a device for OpenMP offload mechanism. - -The syntax of the declare target directive is as follows: - - .. code-block:: c - - #pragma omp declare target new-line - declarations-definition-seq - #pragma omp end declare target new-line - - -objc_boxable ------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Structs and unions marked with the ``objc_boxable`` attribute can be used -with the Objective-C boxed expression syntax, ``@(...)``. - -**Usage**: ``__attribute__((objc_boxable))``. This attribute -can only be placed on a declaration of a trivially-copyable struct or union: - -.. code-block:: objc - - struct __attribute__((objc_boxable)) some_struct { - int i; - }; - union __attribute__((objc_boxable)) some_union { - int i; - float f; - }; - typedef struct __attribute__((objc_boxable)) _some_struct some_struct; - - // ... - - some_struct ss; - NSValue *boxed = @(ss); - - -objc_method_family ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Many methods in Objective-C have conventional meanings determined by their -selectors. It is sometimes useful to be able to mark a method as having a -particular conventional meaning despite not having the right selector, or as -not having the conventional meaning that its selector would suggest. For these -use cases, we provide an attribute to specifically describe the "method family" -that a method belongs to. - -**Usage**: ``__attribute__((objc_method_family(X)))``, where ``X`` is one of -``none``, ``alloc``, ``copy``, ``init``, ``mutableCopy``, or ``new``. This -attribute can only be placed at the end of a method declaration: - -.. code-block:: objc - - - (NSString *)initMyStringValue __attribute__((objc_method_family(none))); - -Users who do not wish to change the conventional meaning of a method, and who -merely want to document its non-standard retain and release semantics, should -use the retaining behavior attributes (``ns_returns_retained``, -``ns_returns_not_retained``, etc). - -Query for this feature with ``__has_attribute(objc_method_family)``. - - -objc_requires_super -------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Some Objective-C classes allow a subclass to override a particular method in a -parent class but expect that the overriding method also calls the overridden -method in the parent class. For these cases, we provide an attribute to -designate that a method requires a "call to ``super``" in the overriding -method in the subclass. - -**Usage**: ``__attribute__((objc_requires_super))``. This attribute can only -be placed at the end of a method declaration: - -.. code-block:: objc - - - (void)foo __attribute__((objc_requires_super)); - -This attribute can only be applied the method declarations within a class, and -not a protocol. Currently this attribute does not enforce any placement of -where the call occurs in the overriding method (such as in the case of -``-dealloc`` where the call must appear at the end). It checks only that it -exists. - -Note that on both OS X and iOS that the Foundation framework provides a -convenience macro ``NS_REQUIRES_SUPER`` that provides syntactic sugar for this -attribute: - -.. code-block:: objc - - - (void)foo NS_REQUIRES_SUPER; - -This macro is conditionally defined depending on the compiler's support for -this attribute. If the compiler does not support the attribute the macro -expands to nothing. - -Operationally, when a method has this annotation the compiler will warn if the -implementation of an override in a subclass does not call super. For example: - -.. code-block:: objc - - warning: method possibly missing a [super AnnotMeth] call - - (void) AnnotMeth{}; - ^ - - -objc_runtime_name ------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -By default, the Objective-C interface or protocol identifier is used -in the metadata name for that object. The `objc_runtime_name` -attribute allows annotated interfaces or protocols to use the -specified string argument in the object's metadata name instead of the -default name. - -**Usage**: ``__attribute__((objc_runtime_name("MyLocalName")))``. This attribute -can only be placed before an @protocol or @interface declaration: - -.. code-block:: objc - - __attribute__((objc_runtime_name("MyLocalName"))) - @interface Message - @end - - -objc_runtime_visible --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -This attribute specifies that the Objective-C class to which it applies is visible to the Objective-C runtime but not to the linker. Classes annotated with this attribute cannot be subclassed and cannot have categories defined for them. - - -optnone (clang::optnone) ------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``optnone`` attribute suppresses essentially all optimizations -on a function or method, regardless of the optimization level applied to -the compilation unit as a whole. This is particularly useful when you -need to debug a particular function, but it is infeasible to build the -entire application without optimization. Avoiding optimization on the -specified function can improve the quality of the debugging information -for that function. - -This attribute is incompatible with the ``always_inline`` and ``minsize`` -attributes. - - -overloadable ------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Clang provides support for C++ function overloading in C. Function overloading -in C is introduced using the ``overloadable`` attribute. For example, one -might provide several overloaded versions of a ``tgsin`` function that invokes -the appropriate standard function computing the sine of a value with ``float``, -``double``, or ``long double`` precision: - -.. code-block:: c - - #include - float __attribute__((overloadable)) tgsin(float x) { return sinf(x); } - double __attribute__((overloadable)) tgsin(double x) { return sin(x); } - long double __attribute__((overloadable)) tgsin(long double x) { return sinl(x); } - -Given these declarations, one can call ``tgsin`` with a ``float`` value to -receive a ``float`` result, with a ``double`` to receive a ``double`` result, -etc. Function overloading in C follows the rules of C++ function overloading -to pick the best overload given the call arguments, with a few C-specific -semantics: - -* Conversion from ``float`` or ``double`` to ``long double`` is ranked as a - floating-point promotion (per C99) rather than as a floating-point conversion - (as in C++). - -* A conversion from a pointer of type ``T*`` to a pointer of type ``U*`` is - considered a pointer conversion (with conversion rank) if ``T`` and ``U`` are - compatible types. - -* A conversion from type ``T`` to a value of type ``U`` is permitted if ``T`` - and ``U`` are compatible types. This conversion is given "conversion" rank. - -* If no viable candidates are otherwise available, we allow a conversion from a - pointer of type ``T*`` to a pointer of type ``U*``, where ``T`` and ``U`` are - incompatible. This conversion is ranked below all other types of conversions. - Please note: ``U`` lacking qualifiers that are present on ``T`` is sufficient - for ``T`` and ``U`` to be incompatible. - -The declaration of ``overloadable`` functions is restricted to function -declarations and definitions. If a function is marked with the ``overloadable`` -attribute, then all declarations and definitions of functions with that name, -except for at most one (see the note below about unmarked overloads), must have -the ``overloadable`` attribute. In addition, redeclarations of a function with -the ``overloadable`` attribute must have the ``overloadable`` attribute, and -redeclarations of a function without the ``overloadable`` attribute must *not* -have the ``overloadable`` attribute. e.g., - -.. code-block:: c - - int f(int) __attribute__((overloadable)); - float f(float); // error: declaration of "f" must have the "overloadable" attribute - int f(int); // error: redeclaration of "f" must have the "overloadable" attribute - - int g(int) __attribute__((overloadable)); - int g(int) { } // error: redeclaration of "g" must also have the "overloadable" attribute - - int h(int); - int h(int) __attribute__((overloadable)); // error: declaration of "h" must not - // have the "overloadable" attribute - -Functions marked ``overloadable`` must have prototypes. Therefore, the -following code is ill-formed: - -.. code-block:: c - - int h() __attribute__((overloadable)); // error: h does not have a prototype - -However, ``overloadable`` functions are allowed to use a ellipsis even if there -are no named parameters (as is permitted in C++). This feature is particularly -useful when combined with the ``unavailable`` attribute: - -.. code-block:: c++ - - void honeypot(...) __attribute__((overloadable, unavailable)); // calling me is an error - -Functions declared with the ``overloadable`` attribute have their names mangled -according to the same rules as C++ function names. For example, the three -``tgsin`` functions in our motivating example get the mangled names -``_Z5tgsinf``, ``_Z5tgsind``, and ``_Z5tgsine``, respectively. There are two -caveats to this use of name mangling: - -* Future versions of Clang may change the name mangling of functions overloaded - in C, so you should not depend on an specific mangling. To be completely - safe, we strongly urge the use of ``static inline`` with ``overloadable`` - functions. - -* The ``overloadable`` attribute has almost no meaning when used in C++, - because names will already be mangled and functions are already overloadable. - However, when an ``overloadable`` function occurs within an ``extern "C"`` - linkage specification, it's name *will* be mangled in the same way as it - would in C. - -For the purpose of backwards compatibility, at most one function with the same -name as other ``overloadable`` functions may omit the ``overloadable`` -attribute. In this case, the function without the ``overloadable`` attribute -will not have its name mangled. - -For example: - -.. code-block:: c - - // Notes with mangled names assume Itanium mangling. - int f(int); - int f(double) __attribute__((overloadable)); - void foo() { - f(5); // Emits a call to f (not _Z1fi, as it would with an overload that - // was marked with overloadable). - f(1.0); // Emits a call to _Z1fd. - } - -Support for unmarked overloads is not present in some versions of clang. You may -query for it using ``__has_extension(overloadable_unmarked)``. - -Query for this attribute with ``__has_attribute(overloadable)``. - - -release_capability (release_shared_capability, clang::release_capability, clang::release_shared_capability) ------------------------------------------------------------------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -Marks a function as releasing a capability. - - -kernel ------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -``__attribute__((kernel))`` is used to mark a ``kernel`` function in -RenderScript. - -In RenderScript, ``kernel`` functions are used to express data-parallel -computations. The RenderScript runtime efficiently parallelizes ``kernel`` -functions to run on computational resources such as multi-core CPUs and GPUs. -See the RenderScript_ documentation for more information. - -.. _RenderScript: https://developer.android.com/guide/topics/renderscript/compute.html - - -target (gnu::target) --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -Clang supports the GNU style ``__attribute__((target("OPTIONS")))`` attribute. -This attribute may be attached to a function definition and instructs -the backend to use different code generation options than were passed on the -command line. - -The current set of options correspond to the existing "subtarget features" for -the target with or without a "-mno-" in front corresponding to the absence -of the feature, as well as ``arch="CPU"`` which will change the default "CPU" -for the function. - -Example "subtarget features" from the x86 backend include: "mmx", "sse", "sse4.2", -"avx", "xop" and largely correspond to the machine specific options handled by -the front end. - - -try_acquire_capability (try_acquire_shared_capability, clang::try_acquire_capability, clang::try_acquire_shared_capability) ---------------------------------------------------------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -Marks a function that attempts to acquire a capability. This function may fail to -actually acquire the capability; they accept a Boolean value determining -whether acquiring the capability means success (true), or failing to acquire -the capability means success (false). - - -nodiscard, warn_unused_result, clang::warn_unused_result, gnu::warn_unused_result ---------------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -Clang supports the ability to diagnose when the results of a function call -expression are discarded under suspicious circumstances. A diagnostic is -generated when a function or its return type is marked with ``[[nodiscard]]`` -(or ``__attribute__((warn_unused_result))``) and the function call appears as a -potentially-evaluated discarded-value expression that is not explicitly cast to -`void`. - -.. code-block: c++ - struct [[nodiscard]] error_info { /*...*/ }; - error_info enable_missile_safety_mode(); - - void launch_missiles(); - void test_missiles() { - enable_missile_safety_mode(); // diagnoses - launch_missiles(); - } - error_info &foo(); - void f() { foo(); } // Does not diagnose, error_info is a reference. - - -xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::xray_log_args) --------------------------------------------------------------------------------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching. - -Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points. - -If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise. - -``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function. Currently, only N==1 is supported. - - -xray_always_instrument (clang::xray_always_instrument), xray_never_instrument (clang::xray_never_instrument), xray_log_args (clang::xray_log_args) --------------------------------------------------------------------------------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -``__attribute__((xray_always_instrument))`` or ``[[clang::xray_always_instrument]]`` is used to mark member functions (in C++), methods (in Objective C), and free functions (in C, C++, and Objective C) to be instrumented with XRay. This will cause the function to always have space at the beginning and exit points to allow for runtime patching. - -Conversely, ``__attribute__((xray_never_instrument))`` or ``[[clang::xray_never_instrument]]`` will inhibit the insertion of these instrumentation points. - -If a function has neither of these attributes, they become subject to the XRay heuristics used to determine whether a function should be instrumented or otherwise. - -``__attribute__((xray_log_args(N)))`` or ``[[clang::xray_log_args(N)]]`` is used to preserve N function arguments for the logging function. Currently, only N==1 is supported. - - -Variable Attributes -=================== - - -dllexport (gnu::dllexport) --------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","X","", "", "X" - -The ``__declspec(dllexport)`` attribute declares a variable, function, or -Objective-C interface to be exported from the module. It is available under the -``-fdeclspec`` flag for compatibility with various compilers. The primary use -is for COFF object files which explicitly specify what interfaces are available -for external use. See the dllexport_ documentation on MSDN for more -information. - -.. _dllexport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx - - -dllimport (gnu::dllimport) --------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","X","", "", "X" - -The ``__declspec(dllimport)`` attribute declares a variable, function, or -Objective-C interface to be imported from an external module. It is available -under the ``-fdeclspec`` flag for compatibility with various compilers. The -primary use is for COFF object files which explicitly specify what interfaces -are imported from external modules. See the dllimport_ documentation on MSDN -for more information. - -.. _dllimport: https://msdn.microsoft.com/en-us/library/3y1sfaz2.aspx - - -init_seg --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","", "X", "" - -The attribute applied by ``pragma init_seg()`` controls the section into -which global initialization function pointers are emitted. It is only -available with ``-fms-extensions``. Typically, this function pointer is -emitted into ``.CRT$XCU`` on Windows. The user can change the order of -initialization by using a different section name with the same -``.CRT$XC`` prefix and a suffix that sorts lexicographically before or -after the standard ``.CRT$XCU`` sections. See the init_seg_ -documentation on MSDN for more information. - -.. _init_seg: http://msdn.microsoft.com/en-us/library/7977wcck(v=vs.110).aspx - - -nodebug (gnu::nodebug) ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``nodebug`` attribute allows you to suppress debugging information for a -function or method, or for a variable that is not a parameter or a non-static -data member. - - -nosvm ------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -OpenCL 2.0 supports the optional ``__attribute__((nosvm))`` qualifier for -pointer variable. It informs the compiler that the pointer does not refer -to a shared virtual memory region. See OpenCL v2.0 s6.7.2 for details. - -Since it is not widely used and has been removed from OpenCL 2.1, it is ignored -by Clang. - - -pass_object_size ----------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -.. Note:: The mangling of functions with parameters that are annotated with - ``pass_object_size`` is subject to change. You can get around this by - using ``__asm__("foo")`` to explicitly name your functions, thus preserving - your ABI; also, non-overloadable C functions with ``pass_object_size`` are - not mangled. - -The ``pass_object_size(Type)`` attribute can be placed on function parameters to -instruct clang to call ``__builtin_object_size(param, Type)`` at each callsite -of said function, and implicitly pass the result of this call in as an invisible -argument of type ``size_t`` directly after the parameter annotated with -``pass_object_size``. Clang will also replace any calls to -``__builtin_object_size(param, Type)`` in the function by said implicit -parameter. - -Example usage: - -.. code-block:: c - - int bzero1(char *const p __attribute__((pass_object_size(0)))) - __attribute__((noinline)) { - int i = 0; - for (/**/; i < (int)__builtin_object_size(p, 0); ++i) { - p[i] = 0; - } - return i; - } - - int main() { - char chars[100]; - int n = bzero1(&chars[0]); - assert(n == sizeof(chars)); - return 0; - } - -If successfully evaluating ``__builtin_object_size(param, Type)`` at the -callsite is not possible, then the "failed" value is passed in. So, using the -definition of ``bzero1`` from above, the following code would exit cleanly: - -.. code-block:: c - - int main2(int argc, char *argv[]) { - int n = bzero1(argv); - assert(n == -1); - return 0; - } - -``pass_object_size`` plays a part in overload resolution. If two overload -candidates are otherwise equally good, then the overload with one or more -parameters with ``pass_object_size`` is preferred. This implies that the choice -between two identical overloads both with ``pass_object_size`` on one or more -parameters will always be ambiguous; for this reason, having two such overloads -is illegal. For example: - -.. code-block:: c++ - - #define PS(N) __attribute__((pass_object_size(N))) - // OK - void Foo(char *a, char *b); // Overload A - // OK -- overload A has no parameters with pass_object_size. - void Foo(char *a PS(0), char *b PS(0)); // Overload B - // Error -- Same signature (sans pass_object_size) as overload B, and both - // overloads have one or more parameters with the pass_object_size attribute. - void Foo(void *a PS(0), void *b); - - // OK - void Bar(void *a PS(0)); // Overload C - // OK - void Bar(char *c PS(1)); // Overload D - - void main() { - char known[10], *unknown; - Foo(unknown, unknown); // Calls overload B - Foo(known, unknown); // Calls overload B - Foo(unknown, known); // Calls overload B - Foo(known, known); // Calls overload B - - Bar(known); // Calls overload D - Bar(unknown); // Calls overload D - } - -Currently, ``pass_object_size`` is a bit restricted in terms of its usage: - -* Only one use of ``pass_object_size`` is allowed per parameter. - -* It is an error to take the address of a function with ``pass_object_size`` on - any of its parameters. If you wish to do this, you can create an overload - without ``pass_object_size`` on any parameters. - -* It is an error to apply the ``pass_object_size`` attribute to parameters that - are not pointers. Additionally, any parameter that ``pass_object_size`` is - applied to must be marked ``const`` at its function's definition. - - -require_constant_initialization (clang::require_constant_initialization) ------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -This attribute specifies that the variable to which it is attached is intended -to have a `constant initializer `_ -according to the rules of [basic.start.static]. The variable is required to -have static or thread storage duration. If the initialization of the variable -is not a constant initializer an error will be produced. This attribute may -only be used in C++. - -Note that in C++03 strict constant expression checking is not done. Instead -the attribute reports if Clang can emit the variable as a constant, even if it's -not technically a 'constant initializer'. This behavior is non-portable. - -Static storage duration variables with constant initializers avoid hard-to-find -bugs caused by the indeterminate order of dynamic initialization. They can also -be safely used during dynamic initialization across translation units. - -This attribute acts as a compile time assertion that the requirements -for constant initialization have been met. Since these requirements change -between dialects and have subtle pitfalls it's important to fail fast instead -of silently falling back on dynamic initialization. - -.. code-block:: c++ - - // -std=c++14 - #define SAFE_STATIC [[clang::require_constant_initialization]] - struct T { - constexpr T(int) {} - ~T(); // non-trivial - }; - SAFE_STATIC T x = {42}; // Initialization OK. Doesn't check destructor. - SAFE_STATIC T y = 42; // error: variable does not have a constant initializer - // copy initialization is not a constant expression on a non-literal type. - - -section (gnu::section, __declspec(allocate)) --------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","X","", "", "X" - -The ``section`` attribute allows you to specify a specific section a -global variable or function should be in after translation. - - -swiftcall (gnu::swiftcall) --------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -The ``swiftcall`` attribute indicates that a function should be called -using the Swift calling convention for a function or function pointer. - -The lowering for the Swift calling convention, as described by the Swift -ABI documentation, occurs in multiple phases. The first, "high-level" -phase breaks down the formal parameters and results into innately direct -and indirect components, adds implicit paraameters for the generic -signature, and assigns the context and error ABI treatments to parameters -where applicable. The second phase breaks down the direct parameters -and results from the first phase and assigns them to registers or the -stack. The ``swiftcall`` convention only handles this second phase of -lowering; the C function type must accurately reflect the results -of the first phase, as follows: - -- Results classified as indirect by high-level lowering should be - represented as parameters with the ``swift_indirect_result`` attribute. - -- Results classified as direct by high-level lowering should be represented - as follows: - - - First, remove any empty direct results. - - - If there are no direct results, the C result type should be ``void``. - - - If there is one direct result, the C result type should be a type with - the exact layout of that result type. - - - If there are a multiple direct results, the C result type should be - a struct type with the exact layout of a tuple of those results. - -- Parameters classified as indirect by high-level lowering should be - represented as parameters of pointer type. - -- Parameters classified as direct by high-level lowering should be - omitted if they are empty types; otherwise, they should be represented - as a parameter type with a layout exactly matching the layout of the - Swift parameter type. - -- The context parameter, if present, should be represented as a trailing - parameter with the ``swift_context`` attribute. - -- The error result parameter, if present, should be represented as a - trailing parameter (always following a context parameter) with the - ``swift_error_result`` attribute. - -``swiftcall`` does not support variadic arguments or unprototyped functions. - -The parameter ABI treatment attributes are aspects of the function type. -A function type which which applies an ABI treatment attribute to a -parameter is a different type from an otherwise-identical function type -that does not. A single parameter may not have multiple ABI treatment -attributes. - -Support for this feature is target-dependent, although it should be -supported on every target that Swift supports. Query for this support -with ``__has_attribute(swiftcall)``. This implies support for the -``swift_context``, ``swift_error_result``, and ``swift_indirect_result`` -attributes. - - -swift_context (gnu::swift_context) ----------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``swift_context`` attribute marks a parameter of a ``swiftcall`` -function as having the special context-parameter ABI treatment. - -This treatment generally passes the context value in a special register -which is normally callee-preserved. - -A ``swift_context`` parameter must either be the last parameter or must be -followed by a ``swift_error_result`` parameter (which itself must always be -the last parameter). - -A context parameter must have pointer or reference type. - - -swift_error_result (gnu::swift_error_result) --------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``swift_error_result`` attribute marks a parameter of a ``swiftcall`` -function as having the special error-result ABI treatment. - -This treatment generally passes the underlying error value in and out of -the function through a special register which is normally callee-preserved. -This is modeled in C by pretending that the register is addressable memory: - -- The caller appears to pass the address of a variable of pointer type. - The current value of this variable is copied into the register before - the call; if the call returns normally, the value is copied back into the - variable. - -- The callee appears to receive the address of a variable. This address - is actually a hidden location in its own stack, initialized with the - value of the register upon entry. When the function returns normally, - the value in that hidden location is written back to the register. - -A ``swift_error_result`` parameter must be the last parameter, and it must be -preceded by a ``swift_context`` parameter. - -A ``swift_error_result`` parameter must have type ``T**`` or ``T*&`` for some -type T. Note that no qualifiers are permitted on the intermediate level. - -It is undefined behavior if the caller does not pass a pointer or -reference to a valid object. - -The standard convention is that the error value itself (that is, the -value stored in the apparent argument) will be null upon function entry, -but this is not enforced by the ABI. - - -swift_indirect_result (gnu::swift_indirect_result) --------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``swift_indirect_result`` attribute marks a parameter of a ``swiftcall`` -function as having the special indirect-result ABI treatment. - -This treatment gives the parameter the target's normal indirect-result -ABI treatment, which may involve passing it differently from an ordinary -parameter. However, only the first indirect result will receive this -treatment. Furthermore, low-level lowering may decide that a direct result -must be returned indirectly; if so, this will take priority over the -``swift_indirect_result`` parameters. - -A ``swift_indirect_result`` parameter must either be the first parameter or -follow another ``swift_indirect_result`` parameter. - -A ``swift_indirect_result`` parameter must have type ``T*`` or ``T&`` for -some object type ``T``. If ``T`` is a complete type at the point of -definition of a function, it is undefined behavior if the argument -value does not point to storage of adequate size and alignment for a -value of type ``T``. - -Making indirect results explicit in the signature allows C functions to -directly construct objects into them without relying on language -optimizations like C++'s named return value optimization (NRVO). - - -tls_model (gnu::tls_model) --------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``tls_model`` attribute allows you to specify which thread-local storage -model to use. It accepts the following strings: - -* global-dynamic -* local-dynamic -* initial-exec -* local-exec - -TLS models are mutually exclusive. - - -thread ------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","X","", "", "" - -The ``__declspec(thread)`` attribute declares a variable with thread local -storage. It is available under the ``-fms-extensions`` flag for MSVC -compatibility. See the documentation for `__declspec(thread)`_ on MSDN. - -.. _`__declspec(thread)`: http://msdn.microsoft.com/en-us/library/9w1sdazb.aspx - -In Clang, ``__declspec(thread)`` is generally equivalent in functionality to the -GNU ``__thread`` keyword. The variable must not have a destructor and must have -a constant initializer, if any. The attribute only applies to variables -declared with static storage duration, such as globals, class static data -members, and static locals. - - -maybe_unused, unused, gnu::unused ---------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -When passing the ``-Wunused`` flag to Clang, entities that are unused by the -program may be diagnosed. The ``[[maybe_unused]]`` (or -``__attribute__((unused))``) attribute can be used to silence such diagnostics -when the entity cannot be removed. For instance, a local variable may exist -solely for use in an ``assert()`` statement, which makes the local variable -unused when ``NDEBUG`` is defined. - -The attribute may be applied to the declaration of a class, a typedef, a -variable, a function or method, a function parameter, an enumeration, an -enumerator, a non-static data member, or a label. - -.. code-block: c++ - #include - - [[maybe_unused]] void f([[maybe_unused]] bool thing1, - [[maybe_unused]] bool thing2) { - [[maybe_unused]] bool b = thing1 && thing2; - assert(b); - } - - -Type Attributes -=============== - - -align_value ------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -The align_value attribute can be added to the typedef of a pointer type or the -declaration of a variable of pointer or reference type. It specifies that the -pointer will point to, or the reference will bind to, only objects with at -least the provided alignment. This alignment value must be some positive power -of 2. - - .. code-block:: c - - typedef double * aligned_double_ptr __attribute__((align_value(64))); - void foo(double & x __attribute__((align_value(128)), - aligned_double_ptr y) { ... } - -If the pointer value does not have the specified alignment at runtime, the -behavior of the program is undefined. - - -empty_bases ------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","X","", "", "" - -The empty_bases attribute permits the compiler to utilize the -empty-base-optimization more frequently. -This attribute only applies to struct, class, and union types. -It is only supported when using the Microsoft C++ ABI. - - -enum_extensibility (clang::enum_extensibility) ----------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -Attribute ``enum_extensibility`` is used to distinguish between enum definitions -that are extensible and those that are not. The attribute can take either -``closed`` or ``open`` as an argument. ``closed`` indicates a variable of the -enum type takes a value that corresponds to one of the enumerators listed in the -enum definition or, when the enum is annotated with ``flag_enum``, a value that -can be constructed using values corresponding to the enumerators. ``open`` -indicates a variable of the enum type can take any values allowed by the -standard and instructs clang to be more lenient when issuing warnings. - -.. code-block:: c - - enum __attribute__((enum_extensibility(closed))) ClosedEnum { - A0, A1 - }; - - enum __attribute__((enum_extensibility(open))) OpenEnum { - B0, B1 - }; - - enum __attribute__((enum_extensibility(closed),flag_enum)) ClosedFlagEnum { - C0 = 1 << 0, C1 = 1 << 1 - }; - - enum __attribute__((enum_extensibility(open),flag_enum)) OpenFlagEnum { - D0 = 1 << 0, D1 = 1 << 1 - }; - - void foo1() { - enum ClosedEnum ce; - enum OpenEnum oe; - enum ClosedFlagEnum cfe; - enum OpenFlagEnum ofe; - - ce = A1; // no warnings - ce = 100; // warning issued - oe = B1; // no warnings - oe = 100; // no warnings - cfe = C0 | C1; // no warnings - cfe = C0 | C1 | 4; // warning issued - ofe = D0 | D1; // no warnings - ofe = D0 | D1 | 4; // no warnings - } - - -flag_enum ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -This attribute can be added to an enumerator to signal to the compiler that it -is intended to be used as a flag type. This will cause the compiler to assume -that the range of the type includes all of the values that you can get by -manipulating bits of the enumerator when issuing warnings. - - -lto_visibility_public (clang::lto_visibility_public) ----------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","X","","", "", "X" - -See :doc:`LTOVisibility`. - - -layout_version --------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","X","", "", "" - -The layout_version attribute requests that the compiler utilize the class -layout rules of a particular compiler version. -This attribute only applies to struct, class, and union types. -It is only supported when using the Microsoft C++ ABI. - - -__single_inhertiance, __multiple_inheritance, __virtual_inheritance -------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -This collection of keywords is enabled under ``-fms-extensions`` and controls -the pointer-to-member representation used on ``*-*-win32`` targets. - -The ``*-*-win32`` targets utilize a pointer-to-member representation which -varies in size and alignment depending on the definition of the underlying -class. - -However, this is problematic when a forward declaration is only available and -no definition has been made yet. In such cases, Clang is forced to utilize the -most general representation that is available to it. - -These keywords make it possible to use a pointer-to-member representation other -than the most general one regardless of whether or not the definition will ever -be present in the current translation unit. - -This family of keywords belong between the ``class-key`` and ``class-name``: - -.. code-block:: c++ - - struct __single_inheritance S; - int S::*i; - struct S {}; - -This keyword can be applied to class templates but only has an effect when used -on full specializations: - -.. code-block:: c++ - - template struct __single_inheritance A; // warning: inheritance model ignored on primary template - template struct __multiple_inheritance A; // warning: inheritance model ignored on partial specialization - template <> struct __single_inheritance A; - -Note that choosing an inheritance model less general than strictly necessary is -an error: - -.. code-block:: c++ - - struct __multiple_inheritance S; // error: inheritance model does not match definition - int S::*i; - struct S {}; - - -novtable --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","X","", "", "" - -This attribute can be added to a class declaration or definition to signal to -the compiler that constructors and destructors will not reference the virtual -function table. It is only supported when using the Microsoft C++ ABI. - - -objc_subclassing_restricted ---------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -This attribute can be added to an Objective-C ``@interface`` declaration to -ensure that this class cannot be subclassed. - - -transparent_union (gnu::transparent_union) ------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -This attribute can be applied to a union to change the behaviour of calls to -functions that have an argument with a transparent union type. The compiler -behaviour is changed in the following manner: - -- A value whose type is any member of the transparent union can be passed as an - argument without the need to cast that value. - -- The argument is passed to the function using the calling convention of the - first member of the transparent union. Consequently, all the members of the - transparent union should have the same calling convention as its first member. - -Transparent unions are not supported in C++. - - -Statement Attributes -==================== - - -fallthrough, clang::fallthrough -------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","X","","", "", "" - -The ``fallthrough`` (or ``clang::fallthrough``) attribute is used -to annotate intentional fall-through -between switch labels. It can only be applied to a null statement placed at a -point of execution between any statement and the next switch label. It is -common to mark these places with a specific comment, but this attribute is -meant to replace comments with a more strict annotation, which can be checked -by the compiler. This attribute doesn't change semantics of the code and can -be used wherever an intended fall-through occurs. It is designed to mimic -control-flow statements like ``break;``, so it can be placed in most places -where ``break;`` can, but only if there are no statements on the execution path -between it and the next switch label. - -By default, Clang does not warn on unannotated fallthrough from one ``switch`` -case to another. Diagnostics on fallthrough without a corresponding annotation -can be enabled with the ``-Wimplicit-fallthrough`` argument. - -Here is an example: - -.. code-block:: c++ - - // compile with -Wimplicit-fallthrough - switch (n) { - case 22: - case 33: // no warning: no statements between case labels - f(); - case 44: // warning: unannotated fall-through - g(); - [[clang::fallthrough]]; - case 55: // no warning - if (x) { - h(); - break; - } - else { - i(); - [[clang::fallthrough]]; - } - case 66: // no warning - p(); - [[clang::fallthrough]]; // warning: fallthrough annotation does not - // directly precede case label - q(); - case 77: // warning: unannotated fall-through - r(); - } - - -#pragma clang loop ------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","", "X", "" - -The ``#pragma clang loop`` directive allows loop optimization hints to be -specified for the subsequent loop. The directive allows vectorization, -interleaving, and unrolling to be enabled or disabled. Vector width as well -as interleave and unrolling count can be manually specified. See -`language extensions -`_ -for details. - - -#pragma unroll, #pragma nounroll --------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","", "X", "" - -Loop unrolling optimization hints can be specified with ``#pragma unroll`` and -``#pragma nounroll``. The pragma is placed immediately before a for, while, -do-while, or c++11 range-based for loop. - -Specifying ``#pragma unroll`` without a parameter directs the loop unroller to -attempt to fully unroll the loop if the trip count is known at compile time and -attempt to partially unroll the loop if the trip count is not known at compile -time: - -.. code-block:: c++ - - #pragma unroll - for (...) { - ... - } - -Specifying the optional parameter, ``#pragma unroll _value_``, directs the -unroller to unroll the loop ``_value_`` times. The parameter may optionally be -enclosed in parentheses: - -.. code-block:: c++ - - #pragma unroll 16 - for (...) { - ... - } - - #pragma unroll(16) - for (...) { - ... - } - -Specifying ``#pragma nounroll`` indicates that the loop should not be unrolled: - -.. code-block:: c++ - - #pragma nounroll - for (...) { - ... - } - -``#pragma unroll`` and ``#pragma unroll _value_`` have identical semantics to -``#pragma clang loop unroll(full)`` and -``#pragma clang loop unroll_count(_value_)`` respectively. ``#pragma nounroll`` -is equivalent to ``#pragma clang loop unroll(disable)``. See -`language extensions -`_ -for further details including limitations of the unroll hints. - - -__read_only, __write_only, __read_write (read_only, write_only, read_write) ---------------------------------------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The access qualifiers must be used with image object arguments or pipe arguments -to declare if they are being read or written by a kernel or function. - -The read_only/__read_only, write_only/__write_only and read_write/__read_write -names are reserved for use as access qualifiers and shall not be used otherwise. - -.. code-block:: c - - kernel void - foo (read_only image2d_t imageA, - write_only image2d_t imageB) { - ... - } - -In the above example imageA is a read-only 2D image object, and imageB is a -write-only 2D image object. - -The read_write (or __read_write) qualifier can not be used with pipe. - -More details can be found in the OpenCL C language Spec v2.0, Section 6.6. - - -__attribute__((intel_reqd_sub_group_size)) ------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -The optional attribute intel_reqd_sub_group_size can be used to indicate that -the kernel must be compiled and executed with the specified subgroup size. When -this attribute is present, get_max_sub_group_size() is guaranteed to return the -specified integer value. This is important for the correctness of many subgroup -algorithms, and in some cases may be used by the compiler to generate more optimal -code. See `cl_intel_required_subgroup_size -` -for details. - - -__attribute__((opencl_unroll_hint)) ------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -The opencl_unroll_hint attribute qualifier can be used to specify that a loop -(for, while and do loops) can be unrolled. This attribute qualifier can be -used to specify full unrolling or partial unrolling by a specified amount. -This is a compiler hint and the compiler may ignore this directive. See -`OpenCL v2.0 `_ -s6.11.5 for details. - - -suppress (gsl::suppress) ------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","X","","", "", "" - -The ``[[gsl::suppress]]`` attribute suppresses specific -clang-tidy diagnostics for rules of the `C++ Core Guidelines`_ in a portable -way. The attribute can be attached to declarations, statements, and at -namespace scope. - -.. code-block:: c++ - - [[gsl::suppress("Rh-public")]] - void f_() { - int *p; - [[gsl::suppress("type")]] { - p = reinterpret_cast(7); - } - } - namespace N { - [[clang::suppress("type", "bounds")]]; - ... - } - -.. _`C++ Core Guidelines`: https://github.com/isocpp/CppCoreGuidelines/blob/master/CppCoreGuidelines.md#inforce-enforcement - - -Consumed Annotation Checking -============================ -Clang supports additional attributes for checking basic resource management -properties, specifically for unique objects that have a single owning reference. -The following attributes are currently supported, although **the implementation -for these annotations is currently in development and are subject to change.** - -callable_when -------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Use ``__attribute__((callable_when(...)))`` to indicate what states a method -may be called in. Valid states are unconsumed, consumed, or unknown. Each -argument to this attribute must be a quoted string. E.g.: - -``__attribute__((callable_when("unconsumed", "unknown")))`` - - -consumable ----------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Each ``class`` that uses any of the typestate annotations must first be marked -using the ``consumable`` attribute. Failure to do so will result in a warning. - -This attribute accepts a single parameter that must be one of the following: -``unknown``, ``consumed``, or ``unconsumed``. - - -param_typestate ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -This attribute specifies expectations about function parameters. Calls to an -function with annotated parameters will issue a warning if the corresponding -argument isn't in the expected state. The attribute is also used to set the -initial state of the parameter when analyzing the function's body. - - -return_typestate ----------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -The ``return_typestate`` attribute can be applied to functions or parameters. -When applied to a function the attribute specifies the state of the returned -value. The function's body is checked to ensure that it always returns a value -in the specified state. On the caller side, values returned by the annotated -function are initialized to the given state. - -When applied to a function parameter it modifies the state of an argument after -a call to the function returns. The function's body is checked to ensure that -the parameter is in the expected state before returning. - - -set_typestate -------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Annotate methods that transition an object into a new state with -``__attribute__((set_typestate(new_state)))``. The new state must be -unconsumed, consumed, or unknown. - - -test_typestate --------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Use ``__attribute__((test_typestate(tested_state)))`` to indicate that a method -returns true if the object is in the specified state.. - - -AMD GPU Attributes -================== - - -amdgpu_flat_work_group_size ---------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -The flat work-group size is the number of work-items in the work-group size -specified when the kernel is dispatched. It is the product of the sizes of the -x, y, and z dimension of the work-group. - -Clang supports the -``__attribute__((amdgpu_flat_work_group_size(, )))`` attribute for the -AMDGPU target. This attribute may be attached to a kernel function definition -and is an optimization hint. - -```` parameter specifies the minimum flat work-group size, and ```` -parameter specifies the maximum flat work-group size (must be greater than -````) to which all dispatches of the kernel will conform. Passing ``0, 0`` -as ``, `` implies the default behavior (``128, 256``). - -If specified, the AMDGPU target backend might be able to produce better machine -code for barriers and perform scratch promotion by estimating available group -segment size. - -An error will be given if: - - Specified values violate subtarget specifications; - - Specified values are not compatible with values provided through other - attributes. - - -amdgpu_num_sgpr ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Clang supports the ``__attribute__((amdgpu_num_sgpr()))`` and -``__attribute__((amdgpu_num_vgpr()))`` attributes for the AMDGPU -target. These attributes may be attached to a kernel function definition and are -an optimization hint. - -If these attributes are specified, then the AMDGPU target backend will attempt -to limit the number of SGPRs and/or VGPRs used to the specified value(s). The -number of used SGPRs and/or VGPRs may further be rounded up to satisfy the -allocation requirements or constraints of the subtarget. Passing ``0`` as -``num_sgpr`` and/or ``num_vgpr`` implies the default behavior (no limits). - -These attributes can be used to test the AMDGPU target backend. It is -recommended that the ``amdgpu_waves_per_eu`` attribute be used to control -resources such as SGPRs and VGPRs since it is aware of the limits for different -subtargets. - -An error will be given if: - - Specified values violate subtarget specifications; - - Specified values are not compatible with values provided through other - attributes; - - The AMDGPU target backend is unable to create machine code that can meet the - request. - - -amdgpu_num_vgpr ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -Clang supports the ``__attribute__((amdgpu_num_sgpr()))`` and -``__attribute__((amdgpu_num_vgpr()))`` attributes for the AMDGPU -target. These attributes may be attached to a kernel function definition and are -an optimization hint. - -If these attributes are specified, then the AMDGPU target backend will attempt -to limit the number of SGPRs and/or VGPRs used to the specified value(s). The -number of used SGPRs and/or VGPRs may further be rounded up to satisfy the -allocation requirements or constraints of the subtarget. Passing ``0`` as -``num_sgpr`` and/or ``num_vgpr`` implies the default behavior (no limits). - -These attributes can be used to test the AMDGPU target backend. It is -recommended that the ``amdgpu_waves_per_eu`` attribute be used to control -resources such as SGPRs and VGPRs since it is aware of the limits for different -subtargets. - -An error will be given if: - - Specified values violate subtarget specifications; - - Specified values are not compatible with values provided through other - attributes; - - The AMDGPU target backend is unable to create machine code that can meet the - request. - - -amdgpu_waves_per_eu -------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "X" - -A compute unit (CU) is responsible for executing the wavefronts of a work-group. -It is composed of one or more execution units (EU), which are responsible for -executing the wavefronts. An EU can have enough resources to maintain the state -of more than one executing wavefront. This allows an EU to hide latency by -switching between wavefronts in a similar way to symmetric multithreading on a -CPU. In order to allow the state for multiple wavefronts to fit on an EU, the -resources used by a single wavefront have to be limited. For example, the number -of SGPRs and VGPRs. Limiting such resources can allow greater latency hiding, -but can result in having to spill some register state to memory. - -Clang supports the ``__attribute__((amdgpu_waves_per_eu([, ])))`` -attribute for the AMDGPU target. This attribute may be attached to a kernel -function definition and is an optimization hint. - -```` parameter specifies the requested minimum number of waves per EU, and -*optional* ```` parameter specifies the requested maximum number of waves -per EU (must be greater than ```` if specified). If ```` is omitted, -then there is no restriction on the maximum number of waves per EU other than -the one dictated by the hardware for which the kernel is compiled. Passing -``0, 0`` as ``, `` implies the default behavior (no limits). - -If specified, this attribute allows an advanced developer to tune the number of -wavefronts that are capable of fitting within the resources of an EU. The AMDGPU -target backend can use this information to limit resources, such as number of -SGPRs, number of VGPRs, size of available group and private memory segments, in -such a way that guarantees that at least ```` wavefronts and at most -```` wavefronts are able to fit within the resources of an EU. Requesting -more wavefronts can hide memory latency but limits available registers which -can result in spilling. Requesting fewer wavefronts can help reduce cache -thrashing, but can reduce memory latency hiding. - -This attribute controls the machine code generated by the AMDGPU target backend -to ensure it is capable of meeting the requested values. However, when the -kernel is executed, there may be other reasons that prevent meeting the request, -for example, there may be wavefronts from other kernels executing on the EU. - -An error will be given if: - - Specified values violate subtarget specifications; - - Specified values are not compatible with values provided through other - attributes; - - The AMDGPU target backend is unable to create machine code that can meet the - request. - - -Calling Conventions -=================== -Clang supports several different calling conventions, depending on the target -platform and architecture. The calling convention used for a function determines -how parameters are passed, how results are returned to the caller, and other -low-level details of calling a function. - -fastcall (gnu::fastcall, __fastcall, _fastcall) ------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","X", "", "" - -On 32-bit x86 targets, this attribute changes the calling convention of a -function to use ECX and EDX as register parameters and clear parameters off of -the stack on return. This convention does not support variadic calls or -unprototyped functions in C, and has no effect on x86_64 targets. This calling -convention is supported primarily for compatibility with existing code. Users -seeking register parameters should use the ``regparm`` attribute, which does -not require callee-cleanup. See the documentation for `__fastcall`_ on MSDN. - -.. _`__fastcall`: http://msdn.microsoft.com/en-us/library/6xa169sk.aspx - - -ms_abi (gnu::ms_abi) --------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -On non-Windows x86_64 targets, this attribute changes the calling convention of -a function to match the default convention used on Windows x86_64. This -attribute has no effect on Windows targets or non-x86_64 targets. - - -pcs (gnu::pcs) --------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -On ARM targets, this attribute can be used to select calling conventions -similar to ``stdcall`` on x86. Valid parameter values are "aapcs" and -"aapcs-vfp". - - -preserve_all ------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -On X86-64 and AArch64 targets, this attribute changes the calling convention of -a function. The ``preserve_all`` calling convention attempts to make the code -in the caller even less intrusive than the ``preserve_most`` calling convention. -This calling convention also behaves identical to the ``C`` calling convention -on how arguments and return values are passed, but it uses a different set of -caller/callee-saved registers. This removes the burden of saving and -recovering a large register set before and after the call in the caller. If -the arguments are passed in callee-saved registers, then they will be -preserved by the callee across the call. This doesn't apply for values -returned in callee-saved registers. - -- On X86-64 the callee preserves all general purpose registers, except for - R11. R11 can be used as a scratch register. Furthermore it also preserves - all floating-point registers (XMMs/YMMs). - -The idea behind this convention is to support calls to runtime functions -that don't need to call out to any other functions. - -This calling convention, like the ``preserve_most`` calling convention, will be -used by a future version of the Objective-C runtime and should be considered -experimental at this time. - - -preserve_most -------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -On X86-64 and AArch64 targets, this attribute changes the calling convention of -a function. The ``preserve_most`` calling convention attempts to make the code -in the caller as unintrusive as possible. This convention behaves identically -to the ``C`` calling convention on how arguments and return values are passed, -but it uses a different set of caller/callee-saved registers. This alleviates -the burden of saving and recovering a large register set before and after the -call in the caller. If the arguments are passed in callee-saved registers, -then they will be preserved by the callee across the call. This doesn't -apply for values returned in callee-saved registers. - -- On X86-64 the callee preserves all general purpose registers, except for - R11. R11 can be used as a scratch register. Floating-point registers - (XMMs/YMMs) are not preserved and need to be saved by the caller. - -The idea behind this convention is to support calls to runtime functions -that have a hot path and a cold path. The hot path is usually a small piece -of code that doesn't use many registers. The cold path might need to call out to -another function and therefore only needs to preserve the caller-saved -registers, which haven't already been saved by the caller. The -`preserve_most` calling convention is very similar to the ``cold`` calling -convention in terms of caller/callee-saved registers, but they are used for -different types of function calls. ``coldcc`` is for function calls that are -rarely executed, whereas `preserve_most` function calls are intended to be -on the hot path and definitely executed a lot. Furthermore ``preserve_most`` -doesn't prevent the inliner from inlining the function call. - -This calling convention will be used by a future version of the Objective-C -runtime and should therefore still be considered experimental at this time. -Although this convention was created to optimize certain runtime calls to -the Objective-C runtime, it is not limited to this runtime and might be used -by other runtimes in the future too. The current implementation only -supports X86-64 and AArch64, but the intention is to support more architectures -in the future. - - -regcall (gnu::regcall, __regcall) ---------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","X", "", "" - -On x86 targets, this attribute changes the calling convention to -`__regcall`_ convention. This convention aims to pass as many arguments -as possible in registers. It also tries to utilize registers for the -return value whenever it is possible. - -.. _`__regcall`: https://software.intel.com/en-us/node/693069 - - -regparm (gnu::regparm) ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -On 32-bit x86 targets, the regparm attribute causes the compiler to pass -the first three integer parameters in EAX, EDX, and ECX instead of on the -stack. This attribute has no effect on variadic functions, and all parameters -are passed via the stack as normal. - - -stdcall (gnu::stdcall, __stdcall, _stdcall) -------------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","X", "", "" - -On 32-bit x86 targets, this attribute changes the calling convention of a -function to clear parameters off of the stack on return. This convention does -not support variadic calls or unprototyped functions in C, and has no effect on -x86_64 targets. This calling convention is used widely by the Windows API and -COM applications. See the documentation for `__stdcall`_ on MSDN. - -.. _`__stdcall`: http://msdn.microsoft.com/en-us/library/zxk0tw93.aspx - - -thiscall (gnu::thiscall, __thiscall, _thiscall) ------------------------------------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","X", "", "" - -On 32-bit x86 targets, this attribute changes the calling convention of a -function to use ECX for the first parameter (typically the implicit ``this`` -parameter of C++ methods) and clear parameters off of the stack on return. This -convention does not support variadic calls or unprototyped functions in C, and -has no effect on x86_64 targets. See the documentation for `__thiscall`_ on -MSDN. - -.. _`__thiscall`: http://msdn.microsoft.com/en-us/library/ek8tkfbw.aspx - - -vectorcall (__vectorcall, _vectorcall) --------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","X", "", "" - -On 32-bit x86 *and* x86_64 targets, this attribute changes the calling -convention of a function to pass vector parameters in SSE registers. - -On 32-bit x86 targets, this calling convention is similar to ``__fastcall``. -The first two integer parameters are passed in ECX and EDX. Subsequent integer -parameters are passed in memory, and callee clears the stack. On x86_64 -targets, the callee does *not* clear the stack, and integer parameters are -passed in RCX, RDX, R8, and R9 as is done for the default Windows x64 calling -convention. - -On both 32-bit x86 and x86_64 targets, vector and floating point arguments are -passed in XMM0-XMM5. Homogeneous vector aggregates of up to four elements are -passed in sequential SSE registers if enough are available. If AVX is enabled, -256 bit vectors are passed in YMM0-YMM5. Any vector or aggregate type that -cannot be passed in registers for any reason is passed by reference, which -allows the caller to align the parameter memory. - -See the documentation for `__vectorcall`_ on MSDN for more details. - -.. _`__vectorcall`: http://msdn.microsoft.com/en-us/library/dn375768.aspx - - -Type Safety Checking -==================== -Clang supports additional attributes to enable checking type safety properties -that can't be enforced by the C type system. To see warnings produced by these -checks, ensure that -Wtype-safety is enabled. Use cases include: - -* MPI library implementations, where these attributes enable checking that - the buffer type matches the passed ``MPI_Datatype``; -* for HDF5 library there is a similar use case to MPI; -* checking types of variadic functions' arguments for functions like - ``fcntl()`` and ``ioctl()``. - -You can detect support for these attributes with ``__has_attribute()``. For -example: - -.. code-block:: c++ - - #if defined(__has_attribute) - # if __has_attribute(argument_with_type_tag) && \ - __has_attribute(pointer_with_type_tag) && \ - __has_attribute(type_tag_for_datatype) - # define ATTR_MPI_PWT(buffer_idx, type_idx) __attribute__((pointer_with_type_tag(mpi,buffer_idx,type_idx))) - /* ... other macros ... */ - # endif - #endif - - #if !defined(ATTR_MPI_PWT) - # define ATTR_MPI_PWT(buffer_idx, type_idx) - #endif - - int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) - ATTR_MPI_PWT(1,3); - -argument_with_type_tag ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -Use ``__attribute__((argument_with_type_tag(arg_kind, arg_idx, -type_tag_idx)))`` on a function declaration to specify that the function -accepts a type tag that determines the type of some other argument. - -This attribute is primarily useful for checking arguments of variadic functions -(``pointer_with_type_tag`` can be used in most non-variadic cases). - -In the attribute prototype above: - * ``arg_kind`` is an identifier that should be used when annotating all - applicable type tags. - * ``arg_idx`` provides the position of a function argument. The expected type of - this function argument will be determined by the function argument specified - by ``type_tag_idx``. In the code example below, "3" means that the type of the - function's third argument will be determined by ``type_tag_idx``. - * ``type_tag_idx`` provides the position of a function argument. This function - argument will be a type tag. The type tag will determine the expected type of - the argument specified by ``arg_idx``. In the code example below, "2" means - that the type tag associated with the function's second argument should agree - with the type of the argument specified by ``arg_idx``. - -For example: - -.. code-block:: c++ - - int fcntl(int fd, int cmd, ...) - __attribute__(( argument_with_type_tag(fcntl,3,2) )); - // The function's second argument will be a type tag; this type tag will - // determine the expected type of the function's third argument. - - -pointer_with_type_tag ---------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -Use ``__attribute__((pointer_with_type_tag(ptr_kind, ptr_idx, type_tag_idx)))`` -on a function declaration to specify that the function accepts a type tag that -determines the pointee type of some other pointer argument. - -In the attribute prototype above: - * ``ptr_kind`` is an identifier that should be used when annotating all - applicable type tags. - * ``ptr_idx`` provides the position of a function argument; this function - argument will have a pointer type. The expected pointee type of this pointer - type will be determined by the function argument specified by - ``type_tag_idx``. In the code example below, "1" means that the pointee type - of the function's first argument will be determined by ``type_tag_idx``. - * ``type_tag_idx`` provides the position of a function argument; this function - argument will be a type tag. The type tag will determine the expected pointee - type of the pointer argument specified by ``ptr_idx``. In the code example - below, "3" means that the type tag associated with the function's third - argument should agree with the pointee type of the pointer argument specified - by ``ptr_idx``. - -For example: - -.. code-block:: c++ - - typedef int MPI_Datatype; - int MPI_Send(void *buf, int count, MPI_Datatype datatype /*, other args omitted */) - __attribute__(( pointer_with_type_tag(mpi,1,3) )); - // The function's 3rd argument will be a type tag; this type tag will - // determine the expected pointee type of the function's 1st argument. - - -type_tag_for_datatype ---------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","","","", "", "" - -When declaring a variable, use -``__attribute__((type_tag_for_datatype(kind, type)))`` to create a type tag that -is tied to the ``type`` argument given to the attribute. - -In the attribute prototype above: - * ``kind`` is an identifier that should be used when annotating all applicable - type tags. - * ``type`` indicates the name of the type. - -Clang supports annotating type tags of two forms. - - * **Type tag that is a reference to a declared identifier.** - Use ``__attribute__((type_tag_for_datatype(kind, type)))`` when declaring that - identifier: - - .. code-block:: c++ - - typedef int MPI_Datatype; - extern struct mpi_datatype mpi_datatype_int - __attribute__(( type_tag_for_datatype(mpi,int) )); - #define MPI_INT ((MPI_Datatype) &mpi_datatype_int) - // &mpi_datatype_int is a type tag. It is tied to type "int". - - * **Type tag that is an integral literal.** - Declare a ``static const`` variable with an initializer value and attach - ``__attribute__((type_tag_for_datatype(kind, type)))`` on that declaration: - - .. code-block:: c++ - - typedef int MPI_Datatype; - static const MPI_Datatype mpi_datatype_int - __attribute__(( type_tag_for_datatype(mpi,int) )) = 42; - #define MPI_INT ((MPI_Datatype) 42) - // The number 42 is a type tag. It is tied to type "int". - - -The ``type_tag_for_datatype`` attribute also accepts an optional third argument -that determines how the type of the function argument specified by either -``arg_idx`` or ``ptr_idx`` is compared against the type associated with the type -tag. (Recall that for the ``argument_with_type_tag`` attribute, the type of the -function argument specified by ``arg_idx`` is compared against the type -associated with the type tag. Also recall that for the ``pointer_with_type_tag`` -attribute, the pointee type of the function argument specified by ``ptr_idx`` is -compared against the type associated with the type tag.) There are two supported -values for this optional third argument: - - * ``layout_compatible`` will cause types to be compared according to - layout-compatibility rules (In C++11 [class.mem] p 17, 18, see the - layout-compatibility rules for two standard-layout struct types and for two - standard-layout union types). This is useful when creating a type tag - associated with a struct or union type. For example: - - .. code-block:: c++ - - /* In mpi.h */ - typedef int MPI_Datatype; - struct internal_mpi_double_int { double d; int i; }; - extern struct mpi_datatype mpi_datatype_double_int - __attribute__(( type_tag_for_datatype(mpi, - struct internal_mpi_double_int, layout_compatible) )); - - #define MPI_DOUBLE_INT ((MPI_Datatype) &mpi_datatype_double_int) - - int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...) - __attribute__(( pointer_with_type_tag(mpi,1,3) )); - - /* In user code */ - struct my_pair { double a; int b; }; - struct my_pair *buffer; - MPI_Send(buffer, 1, MPI_DOUBLE_INT /*, ... */); // no warning because the - // layout of my_pair is - // compatible with that of - // internal_mpi_double_int - - struct my_int_pair { int a; int b; } - struct my_int_pair *buffer2; - MPI_Send(buffer2, 1, MPI_DOUBLE_INT /*, ... */); // warning because the - // layout of my_int_pair - // does not match that of - // internal_mpi_double_int - - * ``must_be_null`` specifies that the function argument specified by either - ``arg_idx`` (for the ``argument_with_type_tag`` attribute) or ``ptr_idx`` (for - the ``pointer_with_type_tag`` attribute) should be a null pointer constant. - The second argument to the ``type_tag_for_datatype`` attribute is ignored. For - example: - - .. code-block:: c++ - - /* In mpi.h */ - typedef int MPI_Datatype; - extern struct mpi_datatype mpi_datatype_null - __attribute__(( type_tag_for_datatype(mpi, void, must_be_null) )); - - #define MPI_DATATYPE_NULL ((MPI_Datatype) &mpi_datatype_null) - int MPI_Send(void *buf, int count, MPI_Datatype datatype, ...) - __attribute__(( pointer_with_type_tag(mpi,1,3) )); - - /* In user code */ - struct my_pair { double a; int b; }; - struct my_pair *buffer; - MPI_Send(buffer, 1, MPI_DATATYPE_NULL /*, ... */); // warning: MPI_DATATYPE_NULL - // was specified but buffer - // is not a null pointer - - -OpenCL Address Spaces -===================== -The address space qualifier may be used to specify the region of memory that is -used to allocate the object. OpenCL supports the following address spaces: -__generic(generic), __global(global), __local(local), __private(private), -__constant(constant). - - .. code-block:: c - - __constant int c = ...; - - __generic int* foo(global int* g) { - __local int* l; - private int p; - ... - return l; - } - -More details can be found in the OpenCL C language Spec v2.0, Section 6.5. - -constant (__constant) ---------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The constant address space attribute signals that an object is located in -a constant (non-modifiable) memory region. It is available to all work items. -Any type can be annotated with the constant address space attribute. Objects -with the constant address space qualifier can be declared in any scope and must -have an initializer. - - -generic (__generic) -------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The generic address space attribute is only available with OpenCL v2.0 and later. -It can be used with pointer types. Variables in global and local scope and -function parameters in non-kernel functions can have the generic address space -type attribute. It is intended to be a placeholder for any other address space -except for '__constant' in OpenCL code which can be used with multiple address -spaces. - - -global (__global) ------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The global address space attribute specifies that an object is allocated in -global memory, which is accessible by all work items. The content stored in this -memory area persists between kernel executions. Pointer types to the global -address space are allowed as function parameters or local variables. Starting -with OpenCL v2.0, the global address space can be used with global (program -scope) variables and static local variable as well. - - -local (__local) ---------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The local address space specifies that an object is allocated in the local (work -group) memory area, which is accessible to all work items in the same work -group. The content stored in this memory region is not accessible after -the kernel execution ends. In a kernel function scope, any variable can be in -the local address space. In other scopes, only pointer types to the local address -space are allowed. Local address space variables cannot have an initializer. - - -private (__private) -------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The private address space specifies that an object is allocated in the private -(work item) memory. Other work items cannot access the same memory area and its -content is destroyed after work item execution ends. Local variables can be -declared in the private address space. Function arguments are always in the -private address space. Kernel function arguments of a pointer or an array type -cannot point to the private address space. - - -Nullability Attributes -====================== -Whether a particular pointer may be "null" is an important concern when working with pointers in the C family of languages. The various nullability attributes indicate whether a particular pointer can be null or not, which makes APIs more expressive and can help static analysis tools identify bugs involving null pointers. Clang supports several kinds of nullability attributes: the ``nonnull`` and ``returns_nonnull`` attributes indicate which function or method parameters and result types can never be null, while nullability type qualifiers indicate which pointer types can be null (``_Nullable``) or cannot be null (``_Nonnull``). - -The nullability (type) qualifiers express whether a value of a given pointer type can be null (the ``_Nullable`` qualifier), doesn't have a defined meaning for null (the ``_Nonnull`` qualifier), or for which the purpose of null is unclear (the ``_Null_unspecified`` qualifier). Because nullability qualifiers are expressed within the type system, they are more general than the ``nonnull`` and ``returns_nonnull`` attributes, allowing one to express (for example) a nullable pointer to an array of nonnull pointers. Nullability qualifiers are written to the right of the pointer to which they apply. For example: - - .. code-block:: c - - // No meaningful result when 'ptr' is null (here, it happens to be undefined behavior). - int fetch(int * _Nonnull ptr) { return *ptr; } - - // 'ptr' may be null. - int fetch_or_zero(int * _Nullable ptr) { - return ptr ? *ptr : 0; - } - - // A nullable pointer to non-null pointers to const characters. - const char *join_strings(const char * _Nonnull * _Nullable strings, unsigned n); - -In Objective-C, there is an alternate spelling for the nullability qualifiers that can be used in Objective-C methods and properties using context-sensitive, non-underscored keywords. For example: - - .. code-block:: objective-c - - @interface NSView : NSResponder - - (nullable NSView *)ancestorSharedWithView:(nonnull NSView *)aView; - @property (assign, nullable) NSView *superview; - @property (readonly, nonnull) NSArray *subviews; - @end - -nonnull (gnu::nonnull) ----------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "" - -The ``nonnull`` attribute indicates that some function parameters must not be null, and can be used in several different ways. It's original usage (`from GCC `_) is as a function (or Objective-C method) attribute that specifies which parameters of the function are nonnull in a comma-separated list. For example: - - .. code-block:: c - - extern void * my_memcpy (void *dest, const void *src, size_t len) - __attribute__((nonnull (1, 2))); - -Here, the ``nonnull`` attribute indicates that parameters 1 and 2 -cannot have a null value. Omitting the parenthesized list of parameter indices means that all parameters of pointer type cannot be null: - - .. code-block:: c - - extern void * my_memcpy (void *dest, const void *src, size_t len) - __attribute__((nonnull)); - -Clang also allows the ``nonnull`` attribute to be placed directly on a function (or Objective-C method) parameter, eliminating the need to specify the parameter index ahead of type. For example: - - .. code-block:: c - - extern void * my_memcpy (void *dest __attribute__((nonnull)), - const void *src __attribute__((nonnull)), size_t len); - -Note that the ``nonnull`` attribute indicates that passing null to a non-null parameter is undefined behavior, which the optimizer may take advantage of to, e.g., remove null checks. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable. - - -returns_nonnull (gnu::returns_nonnull) --------------------------------------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "X","X","","", "", "X" - -The ``returns_nonnull`` attribute indicates that a particular function (or Objective-C method) always returns a non-null pointer. For example, a particular system ``malloc`` might be defined to terminate a process when memory is not available rather than returning a null pointer: - - .. code-block:: c - - extern void * malloc (size_t size) __attribute__((returns_nonnull)); - -The ``returns_nonnull`` attribute implies that returning a null pointer is undefined behavior, which the optimizer may take advantage of. The ``_Nonnull`` type qualifier indicates that a pointer cannot be null in a more general manner (because it is part of the type system) and does not imply undefined behavior, making it more widely applicable - - -_Nonnull --------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The ``_Nonnull`` nullability qualifier indicates that null is not a meaningful value for a value of the ``_Nonnull`` pointer type. For example, given a declaration such as: - - .. code-block:: c - - int fetch(int * _Nonnull ptr); - -a caller of ``fetch`` should not provide a null value, and the compiler will produce a warning if it sees a literal null value passed to ``fetch``. Note that, unlike the declaration attribute ``nonnull``, the presence of ``_Nonnull`` does not imply that passing null is undefined behavior: ``fetch`` is free to consider null undefined behavior or (perhaps for backward-compatibility reasons) defensively handle null. - - -_Null_unspecified ------------------ -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The ``_Null_unspecified`` nullability qualifier indicates that neither the ``_Nonnull`` nor ``_Nullable`` qualifiers make sense for a particular pointer type. It is used primarily to indicate that the role of null with specific pointers in a nullability-annotated header is unclear, e.g., due to overly-complex implementations or historical factors with a long-lived API. - - -_Nullable ---------- -.. csv-table:: Supported Syntaxes - :header: "GNU", "C++11", "__declspec", "Keyword", "Pragma", "Pragma clang attribute" - - "","","","X", "", "" - -The ``_Nullable`` nullability qualifier indicates that a value of the ``_Nullable`` pointer type can be null. For example, given: - - .. code-block:: c - - int fetch_or_zero(int * _Nullable ptr); - -a caller of ``fetch_or_zero`` can provide null. - - +=================== \ No newline at end of file diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst index d964e34..4d09588 100644 --- a/docs/ClangCommandLineReference.rst +++ b/docs/ClangCommandLineReference.rst @@ -56,6 +56,16 @@ Pass to fatbinary invocation Pass to the ptxas assembler +.. option:: -Xopenmp-target + +Pass to the target offloading toolchain. + +.. program:: clang1 +.. option:: -Xopenmp-target= +.. program:: clang + +Pass to the specified target offloading toolchain. The triple that identifies the toolchain must be provided after the equals sign. + .. option:: -Z .. option:: -a, --profile-blocks @@ -312,6 +322,10 @@ Disable standard #include directories for the C++ standard library .. option:: -nostdlib, --no-standard-libraries +.. program:: clang1 +.. option:: -nostdlib++ +.. program:: clang + .. option:: -nostdlibinc .. option:: -o, --output , --output= @@ -510,10 +524,10 @@ Serialize compiler diagnostics to a file .. option:: -shared, --shared -.. option:: -shared-libasan - .. option:: -shared-libgcc +.. option:: -shared-libsan, -shared-libasan + .. option:: -single\_module .. option:: -specs=, --specs= @@ -522,6 +536,8 @@ Serialize compiler diagnostics to a file .. option:: -static-libgcc +.. option:: -static-libsan + .. option:: -static-libstdc++ .. option:: -std-default= @@ -574,6 +590,8 @@ Verify the binary representation of debug output .. option:: --version +Print version information + .. option:: -w, --no-warnings Suppress all warnings @@ -688,6 +706,10 @@ Print source range spans in numeric form Enables an experimental new pass manager in LLVM. +.. option:: -ffine-grained-bitfield-accesses, -fno-fine-grained-bitfield-accesses + +Use separate accesses for bitfields with legal widths and alignments. + .. option:: -finline-functions, -fno-inline-functions Inline suitable functions @@ -726,6 +748,10 @@ Path to blacklist file for sanitizers Enable control flow integrity (CFI) checks for cross-DSO calls. +.. option:: -fsanitize-cfi-icall-generalize-pointers + +Generalize pointers in CFI indirect call type signature checks + .. option:: -fsanitize-coverage=,..., -fno-sanitize-coverage=,... Specify the type of coverage instrumentation for Sanitizers @@ -742,10 +768,12 @@ Enable origins tracking in MemorySanitizer Enable origins tracking in MemorySanitizer -.. option:: -fsanitize-memory-use-after-dtor +.. option:: -fsanitize-memory-use-after-dtor, -fno-sanitize-memory-use-after-dtor Enable use-after-destroy detection in MemorySanitizer +.. option:: -fsanitize-minimal-runtime, -fno-sanitize-minimal-runtime + .. option:: -fsanitize-recover, -fno-sanitize-recover .. program:: clang1 @@ -856,6 +884,10 @@ Use the last modification time of as the build session timestamp Time when the current build session started +.. option:: -fmodule-file=\[=\] + +Specify the mapping of module name to precompiled module file, or load a module file if name is omitted. + .. option:: -fmodules-cache-path= Specify the module cache path @@ -1243,8 +1275,16 @@ Print a template comparison tree for differing templates Allow '$' in identifiers +.. option:: -fdouble-square-bracket-attributes, -fno-double-square-bracket-attributes + +Enable '\[\[\]\]' attributes in all C and C++ language modes + .. option:: -fdwarf-directory-asm, -fno-dwarf-directory-asm +.. option:: -fdwarf-exceptions + +Use DWARF style exceptions + .. option:: -felide-constructors, -fno-elide-constructors .. option:: -feliminate-unused-debug-symbols, -fno-eliminate-unused-debug-symbols @@ -1321,10 +1361,18 @@ Implicitly search the file system for module map files. .. option:: -finput-charset= +.. option:: -finstrument-function-entry-bare + +Instrument function entry only, after inlining, without arguments to the instrumentation call + .. option:: -finstrument-functions Generate calls to instrument function entry and exit +.. option:: -finstrument-functions-after-inlining + +Like -finstrument-functions, but insert the calls after inlining + .. option:: -fintegrated-as, -fno-integrated-as, -integrated-as Enable the integrated assembler @@ -1365,10 +1413,6 @@ Specify the maximum alignment to enforce on pointers lacking an explicit alignme .. option:: -fmodule-file-deps, -fno-module-file-deps -.. option:: -fmodule-file= - -Load this precompiled module file - .. option:: -fmodule-map-file= Load this module map file @@ -1451,6 +1495,10 @@ Do not treat C++ operator name keywords as synonyms for operators .. option:: -fno-working-directory +.. option:: -fnoopenmp-relocatable-target + +Do not compile OpenMP target code as relocatable. + .. option:: -fnoopenmp-use-tls .. option:: -fobjc-abi-version= @@ -1493,6 +1541,10 @@ Enable ARC-style weak references in Objective-C .. option:: -fopenmp-dump-offload-linker-script +.. option:: -fopenmp-relocatable-target + +OpenMP target code is compiled as relocatable using the -c flag. For OpenMP targets the code is relocatable by default. + .. option:: -fopenmp-use-tls .. option:: -fopenmp-version= @@ -1533,6 +1585,10 @@ Override the default ABI to return all structs on the stack .. option:: -fpie, -fno-pie +.. option:: -fplt, -fno-plt + +Use the PLT to make function calls + .. option:: -fplugin= Load the named plugin (dynamic shared object) @@ -1571,6 +1627,13 @@ Generate instrumented code to collect execution counts into (overridden b Use instrumentation data for profile-guided optimization +.. option:: -fprofile-sample-accurate, -fauto-profile-accurate, -fno-profile-sample-accurate + +Specifies that the sample profile is accurate. If the sample + profile is accurate, callsites without profile samples are marked + as cold. Otherwise, treat callsites without profile samples as if + we have no profile + .. option:: -fprofile-sample-use, -fauto-profile, -fno-profile-sample-use .. program:: clang1 @@ -1623,6 +1686,10 @@ Turn on loop reroller Generate a YAML optimization record file +.. option:: -fseh-exceptions + +Use SEH style exceptions + .. option:: -fshort-enums, -fno-short-enums Allocate to an enum type only as many bytes as it needs for the declared range of possible values @@ -1807,6 +1874,10 @@ Treat signed integer overflow as two's complement Store string literals as writable data +.. option:: -fxray-always-emit-customevents, -fno-xray-always-emit-customevents + +Determine whether to always emit \_\_xray\_customevent(...) calls even if the function it appears in is not always instrumented. + .. option:: -fxray-always-instrument= Filename defining the whitelist for imbuing the 'always instrument' XRay attribute. @@ -1905,6 +1976,8 @@ Put objects of at most bytes into small data section (MIPS / Hexagon) Enable SVR4-style position-independent code (Mips only) +.. option:: -mabs= + .. option:: -malign-double Align doubles to two words in structs (x86 only) @@ -1943,6 +2016,14 @@ Link stack frames through backchain on System Z Set EABI type, e.g. 4, 5 or gnu (default depends on triple) +.. option:: -membedded-data, -mno-embedded-data + +Place constants in the .rodata section instead of the .sdata section even if they meet the -G threshold (MIPS) + +.. option:: -mextern-sdata, -mno-extern-sdata + +Assume that externally defined data is in the small data if it meets the -G threshold (MIPS) + .. option:: -mfentry Insert calls to fentry at function entry (x86 only) @@ -1965,6 +2046,10 @@ Use 64-bit floating point registers (MIPS only) Enable merging of globals +.. option:: -mgpopt, -mno-gpopt + +Use GP relative accesses for symbols known to be in a small data section (MIPS) + .. option:: -mhard-float .. option:: -mhwdiv=, --mhwdiv , --mhwdiv= @@ -1989,6 +2074,10 @@ Use Intel MCU ABI .. option:: -mldc1-sdc1, -mno-ldc1-sdc1 +.. option:: -mlocal-sdata, -mno-local-sdata + +Extend the -G behaviour to object local data (MIPS) + .. option:: -mlong-calls, -mno-long-calls Generate branches with extended addressability, usually via indirect jumps. @@ -2031,6 +2120,10 @@ Omit frame pointer setup for leaf functions Use copy relocations support for PIE builds +.. option:: -mprefer-vector-width= + +Specifies preferred vector width for auto-vectorization. Defaults to 'none' which allows target specific decisions. + .. option:: -mqdsp6-compat Enable hexagon-qdsp6 backward compatibility @@ -2113,6 +2206,10 @@ Generate code which only uses the general purpose registers (AArch64 only) AMDGPU ------ +.. option:: -mxnack, -mno-xnack + +Enable XNACK (AMDGPU only) + ARM --- .. option:: -ffixed-r9 @@ -2143,12 +2240,20 @@ Disallow use of CRC instructions (ARM only) Disallow generation of deprecated IT blocks for ARMv8. It is on by default for ARMv8 Thumb mode. +.. option:: -mtp= + +Read thread pointer from coprocessor register (ARM only) + .. option:: -munaligned-access, -mno-unaligned-access Allow memory accesses to be unaligned (AArch32/AArch64 only) Hexagon ------- +.. option:: -mieee-rnd-near + +Hexagon +------- .. option:: -mhvx, -mno-hvx Enable Hexagon Vector eXtensions @@ -2157,7 +2262,15 @@ Enable Hexagon Vector eXtensions Enable Hexagon Double Vector eXtensions -.. option:: -mieee-rnd-near +.. option:: -mhvx-length= + +Set Hexagon Vector Length + +.. program:: clang1 +.. option:: -mhvx= +.. program:: clang + +Enable Hexagon Vector eXtensions PowerPC ------- @@ -2197,6 +2310,8 @@ PowerPC WebAssembly ----------- +.. option:: -mnontrapping-fptoint, -mno-nontrapping-fptoint + .. option:: -msimd128, -mno-simd128 X86 @@ -2255,6 +2370,8 @@ X86 .. option:: -mfxsr, -mno-fxsr +.. option:: -mibt, -mno-ibt + .. option:: -mlwp, -mno-lwp .. option:: -mlzcnt, -mno-lzcnt @@ -2287,6 +2404,8 @@ X86 .. option:: -msha, -mno-sha +.. option:: -mshstk, -mno-shstk + .. option:: -msse, -mno-sse .. option:: -msse2, -mno-sse2 diff --git a/docs/ClangFormat.rst b/docs/ClangFormat.rst index 902afcd..f53c02a 100644 --- a/docs/ClangFormat.rst +++ b/docs/ClangFormat.rst @@ -11,7 +11,7 @@ Standalone Tool =============== :program:`clang-format` is located in `clang/tools/clang-format` and can be used -to format C/C++/Obj-C code. +to format C/C++/Java/JavaScript/Objective-C/Protobuf code. .. code-block:: console @@ -71,6 +71,7 @@ to format C/C++/Obj-C code. Use -style="{key: value, ...}" to set specific parameters, e.g.: -style="{BasedOnStyle: llvm, IndentWidth: 8}" + -verbose - If set, shows the list of processed files Generic Options: diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 6133ca9..0426792 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -271,15 +271,22 @@ the configuration (without a prefix: ``Auto``). int b = 2; // comment b int b = 2; // comment about b **AllowAllParametersOfDeclarationOnNextLine** (``bool``) - Allow putting all parameters of a function declaration onto + If the function declaration doesn't fit on a line, + allow putting all parameters of a function declaration onto the next line even if ``BinPackParameters`` is ``false``. .. code-block:: c++ - true: false: - myFunction(foo, vs. myFunction(foo, bar, plop); - bar, - plop); + true: + void myFunction( + int a, int b, int c, int d, int e); + + false: + void myFunction(int a, + int b, + int c, + int d, + int e); **AllowShortBlocksOnASingleLine** (``bool``) Allows contracting simple braced statements to a single line. @@ -533,6 +540,15 @@ the configuration (without a prefix: ``Auto``). If ``BreakBeforeBraces`` is set to ``BS_Custom``, use this to specify how each individual brace case should be handled. Otherwise, this is ignored. + .. code-block:: yaml + + # Example of usage: + BreakBeforeBraces: Custom + BraceWrapping: + AfterEnum: true + AfterStruct: false + SplitEmptyFunction: false + Nested configuration flags: @@ -645,6 +661,21 @@ the configuration (without a prefix: ``Auto``). int x; } + * ``bool AfterExternBlock`` Wrap extern blocks. + + .. code-block:: c++ + + true: + extern "C" + { + int foo(); + } + + false: + extern "C" { + int foo(); + } + * ``bool BeforeCatch`` Wrap before ``catch``. .. code-block:: c++ @@ -679,7 +710,7 @@ the configuration (without a prefix: ``Auto``). * ``bool IndentBraces`` Indent the wrapped braces themselves. - * ``bool SplitEmptyFunctionBody`` If ``false``, empty function body can be put on a single line. + * ``bool SplitEmptyFunction`` If ``false``, empty function body can be put on a single line. This option is used only if the opening brace of the function has already been wrapped, i.e. the `AfterFunction` brace wrapping mode is set, and the function could/should not be put on a single line (as per @@ -691,6 +722,28 @@ the configuration (without a prefix: ``Auto``). {} { } + * ``bool SplitEmptyRecord`` If ``false``, empty record (e.g. class, struct or union) body + can be put on a single line. This option is used only if the opening + brace of the record has already been wrapped, i.e. the `AfterClass` + (for classes) brace wrapping mode is set. + + .. code-block:: c++ + + class Foo vs. class Foo + {} { + } + + * ``bool SplitEmptyNamespace`` If ``false``, empty namespace body can be put on a single line. + This option is used only if the opening brace of the namespace has + already been wrapped, i.e. the `AfterNamespace` brace wrapping mode is + set. + + .. code-block:: c++ + + namespace Foo vs. namespace Foo + {} { + } + **BreakAfterJavaFieldAnnotations** (``bool``) Break after each annotation on a field in Java files. @@ -941,9 +994,9 @@ the configuration (without a prefix: ``Auto``). .. code-block:: c++ - Constructor() - : initializer1(), - initializer2() + Constructor() + : initializer1(), + initializer2() * ``BCIS_BeforeComma`` (in configuration: ``BeforeComma``) Break constructor initializers before the colon and commas, and align @@ -951,18 +1004,18 @@ the configuration (without a prefix: ``Auto``). .. code-block:: c++ - Constructor() - : initializer1() - , initializer2() + Constructor() + : initializer1() + , initializer2() * ``BCIS_AfterColon`` (in configuration: ``AfterColon``) Break constructor initializers after the colon and commas. .. code-block:: c++ - Constructor() : - initializer1(), - initializer2() + Constructor() : + initializer1(), + initializer2() @@ -1120,6 +1173,45 @@ the configuration (without a prefix: ``Auto``). For example: BOOST_FOREACH. +**IncludeBlocks** (``IncludeBlocksStyle``) + Dependent on the value, multiple ``#include`` blocks can be sorted + as one and divided based on category. + + Possible values: + + * ``IBS_Preserve`` (in configuration: ``Preserve``) + Sort each ``#include`` block separately. + + .. code-block:: c++ + + #include "b.h" into #include "b.h" + + #include #include "a.h" + #include "a.h" #include + + * ``IBS_Merge`` (in configuration: ``Merge``) + Merge multiple ``#include`` blocks together and sort as one. + + .. code-block:: c++ + + #include "b.h" into #include "a.h" + #include "b.h" + #include #include + #include "a.h" + + * ``IBS_Regroup`` (in configuration: ``Regroup``) + Merge multiple ``#include`` blocks together and sort as one. + Then split into groups based on category priority. See ``IncludeCategories``. + + .. code-block:: c++ + + #include "b.h" into #include "a.h" + #include "b.h" + #include + #include "a.h" #include + + + **IncludeCategories** (``std::vector``) Regular expressions denoting the different ``#include`` categories used for ordering ``#includes``. @@ -1144,7 +1236,7 @@ the configuration (without a prefix: ``Auto``). IncludeCategories: - Regex: '^"(llvm|llvm-c|clang|clang-c)/' Priority: 2 - - Regex: '^(<|"(gtest|isl|json)/)' + - Regex: '^(<|"(gtest|gmock|isl|json)/)' Priority: 3 - Regex: '.*' Priority: 1 @@ -1179,6 +1271,35 @@ the configuration (without a prefix: ``Auto``). plop(); plop(); } } +**IndentPPDirectives** (``PPDirectiveIndentStyle``) + The preprocessor directive indenting style to use. + + Possible values: + + * ``PPDIS_None`` (in configuration: ``None``) + Does not indent any directives. + + .. code-block:: c++ + + #if FOO + #if BAR + #include + #endif + #endif + + * ``PPDIS_AfterHash`` (in configuration: ``AfterHash``) + Indents directives after the hash. + + .. code-block:: c++ + + #if FOO + # if BAR + # include + # endif + #endif + + + **IndentWidth** (``unsigned``) The number of columns to use for indentation. @@ -1291,6 +1412,10 @@ the configuration (without a prefix: ``Auto``). * ``LK_TableGen`` (in configuration: ``TableGen``) Should be used for TableGen code. + * ``LK_TextProto`` (in configuration: ``TextProto``) + Should be used for Protocol Buffer messages in text format + (https://developers.google.com/protocol-buffers/). + **MacroBlockBegin** (``std::string``) @@ -1451,6 +1576,26 @@ the configuration (without a prefix: ``Auto``). +**RawStringFormats** (``std::vector``) + Raw string delimiters denoting that the raw string contents are + code in a particular language and can be reformatted. + + A raw string with a matching delimiter will be reformatted assuming the + specified language based on a predefined style given by 'BasedOnStyle'. + If 'BasedOnStyle' is not found, the formatting is based on llvm style. + + To configure this in the .clang-format file, use: + + .. code-block:: yaml + + RawStringFormats: + - Delimiter: 'pb' + Language: TextProto + BasedOnStyle: llvm + - Delimiter: 'proto' + Language: TextProto + BasedOnStyle: google + **ReflowComments** (``bool``) If ``true``, clang-format will attempt to re-flow comments. @@ -1478,6 +1623,14 @@ the configuration (without a prefix: ``Auto``). **SortUsingDeclarations** (``bool``) If ``true``, clang-format will sort using declarations. + The order of using declarations is defined as follows: + Split the strings by "::" and discard any initial empty strings. The last + element of each list is a non-namespace name; all others are namespace + names. Sort the lists of names lexicographically, where the sort order of + individual names is that all non-namespace names come before all namespace + names, and within those groups, names are in case-insensitive + lexicographic order. + .. code-block:: c++ false: true: diff --git a/docs/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst index eed5ac5..12b4610 100644 --- a/docs/ControlFlowIntegrity.rst +++ b/docs/ControlFlowIntegrity.rst @@ -215,6 +215,23 @@ shared library boundaries are handled as if the callee was not compiled with This scheme is currently only supported on the x86 and x86_64 architectures. +``-fsanitize-cfi-icall-generalize-pointers`` +-------------------------------------------- + +Mismatched pointer types are a common cause of cfi-icall check failures. +Translation units compiled with the ``-fsanitize-cfi-icall-generalize-pointers`` +flag relax pointer type checking for call sites in that translation unit, +applied across all functions compiled with ``-fsanitize=cfi-icall``. + +Specifically, pointers in return and argument types are treated as equivalent as +long as the qualifiers for the type they point to match. For example, ``char*`` +``char**`, and ``int*`` are considered equivalent types. However, ``char*`` and +``const char*`` are considered separate types. + +``-fsanitize-cfi-icall-generalize-pointers`` is not compatible with +``-fsanitize-cfi-cross-dso``. + + ``-fsanitize=cfi-icall`` and ``-fsanitize=function`` ---------------------------------------------------- @@ -243,17 +260,25 @@ Blacklist A :doc:`SanitizerSpecialCaseList` can be used to relax CFI checks for certain source files, functions and types using the ``src``, ``fun`` and ``type`` -entity types. +entity types. Specific CFI modes can be be specified using ``[section]`` +headers. .. code-block:: bash - # Suppress checking for code in a file. + # Suppress all CFI checking for code in a file. src:bad_file.cpp src:bad_header.h # Ignore all functions with names containing MyFooBar. fun:*MyFooBar* # Ignore all types in the standard library. type:std::* + # Disable only unrelated cast checks for this function + [cfi-unrelated-cast] + fun:*UnrelatedCast* + # Disable CFI call checks for this function without affecting cast checks + [cfi-vcall|cfi-nvcall|cfi-icall] + fun:*BadCall* + .. _cfi-cross-dso: diff --git a/docs/ControlFlowIntegrityDesign.rst b/docs/ControlFlowIntegrityDesign.rst index e4225b3..15e20e1 100644 --- a/docs/ControlFlowIntegrityDesign.rst +++ b/docs/ControlFlowIntegrityDesign.rst @@ -92,7 +92,7 @@ The compiler relies on co-operation from the linker in order to assemble the bit vectors for the whole program. It currently does this using LLVM's `type metadata`_ mechanism together with link-time optimization. -.. _address point: https://mentorembedded.github.io/cxx-abi/abi.html#vtable-general +.. _address point: http://itanium-cxx-abi.github.io/cxx-abi/abi.html#vtable-general .. _type metadata: http://llvm.org/docs/TypeMetadata.html .. _ByteArrayBuilder: http://llvm.org/docs/doxygen/html/structllvm_1_1ByteArrayBuilder.html diff --git a/docs/DiagnosticsReference.rst b/docs/DiagnosticsReference.rst index d8c486f..e2b0bd7 100644 --- a/docs/DiagnosticsReference.rst +++ b/docs/DiagnosticsReference.rst @@ -244,6 +244,21 @@ This diagnostic is an error by default, but the flag ``-Wno-address-of-temporary ------------------ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. +-Waligned-allocation-unavailable +-------------------------------- +This diagnostic is an error by default, but the flag ``-Wno-aligned-allocation-unavailable`` can be used to disable the error. + +**Diagnostic text:** + ++--------------------------------------------------+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:error:`error:` |nbsp| :diagtext:`aligned` |nbsp| |+------------------------+| |nbsp| :diagtext:`function of type '`:placeholder:`B`:diagtext:`' is only available on` |nbsp| :placeholder:`C` |nbsp| :placeholder:`D` |nbsp| :diagtext:`or newer`| +| ||:diagtext:`allocation` || | +| |+------------------------+| | +| ||:diagtext:`deallocation`|| | +| |+------------------------+| | ++--------------------------------------------------+--------------------------+--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wall ----- Some of the diagnostics controlled by this flag are enabled by default. @@ -745,6 +760,11 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wbinary-literal +---------------- +Controls `-Wc++14-binary-literal`_, `-Wc++98-c++11-compat-binary-literal`_, `-Wgnu-binary-literal`_. + + -Wbind-to-temporary-copy ------------------------ Also controls `-Wc++98-compat-bind-to-temporary-copy`_. @@ -972,7 +992,7 @@ Synonym for `-Wc++11-narrowing`_. -------------- Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wc++11-compat-deprecated-writable-strings`_, `-Wc++11-compat-reserved-user-defined-literal`_, `-Wc++11-narrowing`_, `-Wc++98-c++11-c++14-compat`_, `-Wc++98-c++11-compat`_. +Also controls `-Wc++11-compat-deprecated-writable-strings`_, `-Wc++11-compat-reserved-user-defined-literal`_, `-Wc++11-narrowing`_, `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_, `-Wc++98-c++11-compat`_. **Diagnostic text:** @@ -1038,7 +1058,9 @@ This diagnostic is enabled by default. -Wc++11-compat-pedantic ----------------------- -Controls `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_. +Some of the diagnostics controlled by this flag are enabled by default. + +Controls `-Wc++11-compat`_, `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_. -Wc++11-compat-reserved-user-defined-literal @@ -1288,12 +1310,12 @@ Some of the diagnostics controlled by this flag are enabled by default. -Wc++14-compat -------------- -Synonym for `-Wc++98-c++11-c++14-compat`_. +Controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_. -Wc++14-compat-pedantic ----------------------- -Synonym for `-Wc++98-c++11-c++14-compat-pedantic`_. +Controls `-Wc++14-compat`_, `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_. -Wc++14-extensions @@ -1349,16 +1371,16 @@ Also controls `-Wc++14-binary-literal`_. +-------------------------------------------------------------------------------+ --Wc++1y-extensions ------------------- -Synonym for `-Wc++14-extensions`_. +-Wc++17-compat +-------------- +Some of the diagnostics controlled by this flag are enabled by default. +Controls `-Wc++17-compat-mangling`_, `-Wc++98-c++11-c++14-c++17-compat`_, `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_. --Wc++1z-compat --------------- -This diagnostic is enabled by default. -Also controls `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_. +-Wc++17-compat-mangling +----------------------- +This diagnostic is enabled by default. **Diagnostic text:** @@ -1367,42 +1389,49 @@ Also controls `-Wdeprecated-increment-bool`_, `-Wdeprecated-register`_. +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ --Wc++1z-extensions +-Wc++17-compat-pedantic +----------------------- +Some of the diagnostics controlled by this flag are enabled by default. + +Controls `-Wc++17-compat`_, `-Wc++98-c++11-c++14-c++17-compat-pedantic`_. + + +-Wc++17-extensions ------------------ Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** +------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr if is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`constexpr if is a C++17 extension`| +------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'constexpr' on lambda expressions is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`'constexpr' on lambda expressions is a C++17 extension`| +---------------------------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++17 extension`| +---------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`decomposition declarations are a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`decomposition declarations are a C++17 extension`| +---------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack fold expression is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`pack fold expression is a C++17 extension`| +--------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'begin' and 'end' returning different types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`'begin' and 'end' returning different types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is a C++17 extension`| +-------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are a C++1z feature`| +|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are a C++17 feature`| +----------------------------------------------------------------------------------------+ +----------------------------------------+--------------------+-------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'`|+------------------+|:diagtext:`' initialization statements are a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`'`|+------------------+|:diagtext:`' initialization statements are a C++17 extension`| | ||:diagtext:`if` || | | |+------------------+| | | ||:diagtext:`switch`|| | @@ -1410,68 +1439,145 @@ Some of the diagnostics controlled by this flag are enabled by default. +----------------------------------------+--------------------+-------------------------------------------------------------+ +-----------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline variables are a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`inline variables are a C++17 extension`| +-----------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is a C++17 extension`| +---------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nested namespace definition is a C++1z extension; define each namespace separately`| +|:warning:`warning:` |nbsp| :diagtext:`nested namespace definition is a C++17 extension; define each namespace separately`| +-------------------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------+---------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`attributes on` |nbsp| |+-------------------------+| |nbsp| :diagtext:`declaration are a C++17 extension`| +| ||:diagtext:`a namespace` || | +| |+-------------------------+| | +| ||:diagtext:`an enumerator`|| | +| |+-------------------------+| | ++------------------------------------------------------------+---------------------------+-----------------------------------------------------+ + +---------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`capture of '\*this' by copy is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`capture of '\*this' by copy is a C++17 extension`| +---------------------------------------------------------------------------------------+ +------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static\_assert with no message is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`static\_assert with no message is a C++17 extension`| +------------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template template parameter using 'typename' is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`template template parameter using 'typename' is a C++17 extension`| +--------------------------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is a C++17 extension`| +--------------------------------------------------------------------------------------------------+ +-----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack expansion of using declaration is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`pack expansion of using declaration is a C++17 extension`| +-----------------------------------------------------------------------------------------------+ +-Wc++1y-extensions +------------------ +Synonym for `-Wc++14-extensions`_. + + +-Wc++1z-compat +-------------- +Synonym for `-Wc++17-compat`_. + + +-Wc++1z-compat-mangling +----------------------- +Synonym for `-Wc++17-compat-mangling`_. + + +-Wc++1z-extensions +------------------ +Synonym for `-Wc++17-extensions`_. + + +-Wc++2a-compat +-------------- +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`'`:placeholder:`A`:diagtext:`' is a keyword in C++2a`| ++-------------------------------------------------------------------------------------------+ + + +-Wc++2a-compat-pedantic +----------------------- +Synonym for `-Wc++2a-compat`_. + + +-Wc++2a-extensions +------------------ +Some of the diagnostics controlled by this flag are enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`default member initializer for bit-field is a C++2a extension`| ++----------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`explicit capture of 'this' with a capture default of '=' is a C++2a extension`| ++--------------------------------------------------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension`| ++--------------------------------------------------------------------------------------------------------------------------+ + + +-Wc++98-c++11-c++14-c++17-compat +-------------------------------- +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`default member initializer for bit-field is incompatible with C++ standards before C++2a`| ++-------------------------------------------------------------------------------------------------------------------------------+ + ++-----------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`explicit capture of 'this' with a capture default of '=' is incompatible with C++ standards before C++2a`| ++-----------------------------------------------------------------------------------------------------------------------------------------------+ + + +-Wc++98-c++11-c++14-c++17-compat-pedantic +----------------------------------------- +Also controls `-Wc++98-c++11-c++14-c++17-compat`_. + +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`invoking a pointer to a 'const &' member function on an rvalue is incompatible with C++ standards before C++2a`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wc++98-c++11-c++14-compat -------------------------- **Diagnostic text:** -+------------------------------------------------------------+---------------------------+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`attributes on` |nbsp| |+-------------------------+| |nbsp| :diagtext:`declaration are incompatible with C++ standards before C++1z`| -| ||:diagtext:`a namespace` || | -| |+-------------------------+| | -| ||:diagtext:`an enumerator`|| | -| |+-------------------------+| | -+------------------------------------------------------------+---------------------------+--------------------------------------------------------------------------------+ - +---------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr if is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`constexpr if is incompatible with C++ standards before C++17`| +---------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`constexpr on lambda expressions is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`constexpr on lambda expressions is incompatible with C++ standards before C++17`| +----------------------------------------------------------------------------------------------------------------------+ +------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`decomposition declarations are incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`decomposition declarations are incompatible with C++ standards before C++17`| +------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack fold expression is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`pack fold expression is incompatible with C++ standards before C++17`| +-----------------------------------------------------------------------------------------------------------+ +---------------------------+--------------------+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| |+------------------+| |nbsp| :diagtext:`initialization statements are incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| |+------------------+| |nbsp| :diagtext:`initialization statements are incompatible with C++ standards before C++17`| | ||:diagtext:`if` || | | |+------------------+| | | ||:diagtext:`switch`|| | @@ -1479,47 +1585,47 @@ Some of the diagnostics controlled by this flag are enabled by default. +---------------------------+--------------------+----------------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`inline variables are incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`inline variables are incompatible with C++ standards before C++17`| +--------------------------------------------------------------------------------------------------------+ +------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`nested namespace definition is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`nested namespace definition is incompatible with C++ standards before C++17`| +------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`by value capture of '\*this' is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`by value capture of '\*this' is incompatible with C++ standards before C++17`| +-------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`static\_assert with no message is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`static\_assert with no message is incompatible with C++ standards before C++17`| +---------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`non-type template parameters declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`are incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`non-type template parameters declared with` |nbsp| :placeholder:`A` |nbsp| :diagtext:`are incompatible with C++ standards before C++17`| +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`template template parameter using 'typename' is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`template template parameter using 'typename' is incompatible with C++ standards before C++17`| +-----------------------------------------------------------------------------------------------------------------------------------+ +--------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unicode literals are incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`unicode literals are incompatible with C++ standards before C++17`| +--------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`default scope specifier for attributes is incompatible with C++ standards before C++17`| +-----------------------------------------------------------------------------------------------------------------------------+ +------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`use of multiple declarators in a single using declaration is incompatible with C++ standards before C++17`| +------------------------------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`pack expansion using declaration is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`pack expansion using declaration is incompatible with C++ standards before C++17`| +-----------------------------------------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'begin' and 'end' returning different types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`'begin' and 'end' returning different types (`:placeholder:`A` |nbsp| :diagtext:`and` |nbsp| :placeholder:`B`:diagtext:`) is incompatible with C++ standards before C++17`| +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -1529,8 +1635,16 @@ Also controls `-Wc++98-c++11-c++14-compat`_. **Diagnostic text:** ++------------------------------------------------------------+---------------------------+--------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`attributes on` |nbsp| |+-------------------------+| |nbsp| :diagtext:`declaration are incompatible with C++ standards before C++17`| +| ||:diagtext:`a namespace` || | +| |+-------------------------+| | +| ||:diagtext:`an enumerator`|| | +| |+-------------------------+| | ++------------------------------------------------------------+---------------------------+--------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are incompatible with C++ standards before C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are incompatible with C++ standards before C++17`| +---------------------------------------------------------------------------------------------------------------------+ @@ -1587,10 +1701,8 @@ Also controls `-Wc++98-c++11-c++14-compat`_. +----------------------------------------------------------------------------------------------------------+ --Wc++98-c++11-compat-pedantic ------------------------------ -Also controls `-Wc++98-c++11-compat`_. - +-Wc++98-c++11-compat-binary-literal +----------------------------------- **Diagnostic text:** +---------------------------------------------------------------------------------------------------------------+ @@ -1598,9 +1710,14 @@ Also controls `-Wc++98-c++11-compat`_. +---------------------------------------------------------------------------------------------------------------+ +-Wc++98-c++11-compat-pedantic +----------------------------- +Controls `-Wc++98-c++11-compat`_, `-Wc++98-c++11-compat-binary-literal`_. + + -Wc++98-compat -------------- -Also controls `-Wc++98-c++11-c++14-compat`_, `-Wc++98-c++11-compat`_, `-Wc++98-compat-local-type-template-args`_, `-Wc++98-compat-unnamed-type-template-args`_. +Also controls `-Wc++98-c++11-c++14-c++17-compat`_, `-Wc++98-c++11-c++14-compat`_, `-Wc++98-c++11-compat`_, `-Wc++98-compat-local-type-template-args`_, `-Wc++98-compat-unnamed-type-template-args`_. **Diagnostic text:** @@ -1941,7 +2058,7 @@ Also controls `-Wc++98-c++11-c++14-compat`_, `-Wc++98-c++11-compat`_, `-Wc++98-c -Wc++98-compat-pedantic ----------------------- -Also controls `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_, `-Wc++98-compat`_, `-Wc++98-compat-bind-to-temporary-copy`_. +Also controls `-Wc++98-c++11-c++14-c++17-compat-pedantic`_, `-Wc++98-c++11-c++14-compat-pedantic`_, `-Wc++98-c++11-compat-pedantic`_, `-Wc++98-compat`_, `-Wc++98-compat-bind-to-temporary-copy`_. **Diagnostic text:** @@ -2435,6 +2552,11 @@ Synonym for `-Wnull-conversion`_. -Wcoroutine ----------- +Synonym for `-Wcoroutine-missing-unhandled-exception`_. + + +-Wcoroutine-missing-unhandled-exception +--------------------------------------- This diagnostic is enabled by default. **Diagnostic text:** @@ -2453,6 +2575,11 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------+ +-Wcpp +----- +Synonym for `-W#warnings`_. + + -Wcstring-format-directive -------------------------- **Diagnostic text:** @@ -2716,6 +2843,10 @@ This diagnostic is enabled by default. **Diagnostic text:** ++--------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`specifying 'uuid' as an ATL attribute is deprecated; use \_\_declspec instead`| ++--------------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`use of C-style parameters in Objective-C method declarations is deprecated`| +-----------------------------------------------------------------------------------------------------------------+ @@ -2751,7 +2882,7 @@ This diagnostic is enabled by default. **Diagnostic text:** +----------------------------------------------------------------------+----------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Implementing deprecated` |nbsp| |+--------------------+| +|:warning:`warning:` |nbsp| :diagtext:`implementing deprecated` |nbsp| |+--------------------+| | ||:diagtext:`method` || | |+--------------------+| | ||:diagtext:`class` || @@ -2760,6 +2891,10 @@ This diagnostic is enabled by default. | |+--------------------+| +----------------------------------------------------------------------+----------------------+ ++----------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implementing unavailable method`| ++----------------------------------------------------------------------+ + -Wdeprecated-increment-bool --------------------------- @@ -2768,7 +2903,7 @@ This diagnostic is enabled by default. **Diagnostic text:** +---------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`incrementing expression of type bool is deprecated and incompatible with C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`incrementing expression of type bool is deprecated and incompatible with C++17`| +---------------------------------------------------------------------------------------------------------------------+ @@ -2818,7 +2953,7 @@ This diagnostic is enabled by default. **Diagnostic text:** +-------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`'register' storage class specifier is deprecated and incompatible with C++1z`| +|:warning:`warning:` |nbsp| :diagtext:`'register' storage class specifier is deprecated and incompatible with C++17`| +-------------------------------------------------------------------------------------------------------------------+ @@ -3227,7 +3362,7 @@ Also controls `-Wdeprecated-dynamic-exception-spec`_. **Diagnostic text:** +--------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ISO C++1z does not allow dynamic exception specifications`| +|:error:`error:` |nbsp| :diagtext:`ISO C++17 does not allow dynamic exception specifications`| +--------------------------------------------------------------------------------------------+ @@ -3279,7 +3414,7 @@ This diagnostic is enabled by default. **Diagnostic text:** +-------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`ISO C++1z does not allow a decomposition group to be empty`| +|:warning:`warning:` |nbsp| :diagtext:`ISO C++17 does not allow a decomposition group to be empty`| +-------------------------------------------------------------------------------------------------+ @@ -3312,6 +3447,8 @@ Synonym for `-Wextra-tokens`_. -------------- This diagnostic is enabled by default. +Also controls `-Wenum-compare-switch`_. + **Diagnostic text:** +------------------------------------------------------------------------------------------------+ @@ -3319,6 +3456,17 @@ This diagnostic is enabled by default. +------------------------------------------------------------------------------------------------+ +-Wenum-compare-switch +--------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++--------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`comparison of two values with different enumeration types in switch statement`| ++--------------------------------------------------------------------------------------------------------------------+ + + -Wenum-conversion ----------------- This diagnostic is enabled by default. @@ -3363,6 +3511,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`exception of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`will be caught by earlier handler`| +-------------------------------------------------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`has a non-throwing exception specification but can still throw`| ++-----------------------------------------------------------------------------------------------------------------------------+ + -Wexit-time-destructors ----------------------- @@ -3451,7 +3603,7 @@ This diagnostic is enabled by default. ------- Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wignored-qualifiers`_, `-Winitializer-overrides`_, `-Wmissing-field-initializers`_, `-Wmissing-method-return-type`_, `-Wsemicolon-before-method-body`_, `-Wsign-compare`_, `-Wunused-parameter`_. +Also controls `-Wignored-qualifiers`_, `-Winitializer-overrides`_, `-Wmissing-field-initializers`_, `-Wmissing-method-return-type`_, `-Wnull-pointer-arithmetic`_, `-Wsemicolon-before-method-body`_, `-Wsign-compare`_, `-Wunused-parameter`_. **Diagnostic text:** @@ -4317,6 +4469,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute ignored`| +--------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute ignored for field of type` |nbsp| :placeholder:`B`| ++--------------------------------------------------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute ignored on inline function`| +---------------------------------------------------------------------------------------------------+ @@ -4453,6 +4609,8 @@ This diagnostic is enabled by default. | |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`methods and properties` || | |+----------------------------------------------------------------------------------------------------------------+| +| ||:diagtext:`functions, methods, and properties` || +| |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`struct or union` || | |+----------------------------------------------------------------------------------------------------------------+| | ||:diagtext:`struct, union or class` || @@ -4645,9 +4803,13 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`\_\_declspec attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is not supported`| +-------------------------------------------------------------------------------------------------------------------------+ -+-------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`Ignoring unsupported '`:placeholder:`A`:diagtext:`' in the target attribute string`| -+-------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring` |nbsp| |+-----------------------+|+--------------------------------+| |nbsp| :diagtext:`'`:placeholder:`C`:diagtext:`' in the target attribute string`| +| ||:diagtext:`unsupported`||| || | +| |+-----------------------+|+--------------------------------+| | +| ||:diagtext:`duplicate` ||| |nbsp| :diagtext:`architecture`|| | +| |+-----------------------+|+--------------------------------+| | ++-------------------------------------------------------+-------------------------+----------------------------------+---------------------------------------------------------------------------------+ -Wignored-optimization-argument @@ -4970,9 +5132,13 @@ Some of the diagnostics controlled by this flag are enabled by default. **Diagnostic text:** -+------------------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`implicit declaration of function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is invalid in C99`| -+------------------------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------------------------+--------------------+ +|:warning:`warning:` |nbsp| :diagtext:`implicit declaration of function` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is invalid in` |nbsp| |+------------------+| +| ||:diagtext:`C99` || +| |+------------------+| +| ||:diagtext:`OpenCL`|| +| |+------------------+| ++----------------------------------------------------------------------------------------------------------------------------------------+--------------------+ +---------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`implicitly declaring library function '`:placeholder:`A`:diagtext:`' with type` |nbsp| :placeholder:`B`| @@ -5250,6 +5416,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`missing submodule '`:placeholder:`A`:diagtext:`'`| +---------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`umbrella directory '`:placeholder:`A`:diagtext:`' not found`| ++--------------------------------------------------------------------------------------------------+ + +-------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`umbrella header for module '`:placeholder:`A`:diagtext:`' does not include header '`:placeholder:`B`:diagtext:`'`| +-------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -5299,7 +5469,7 @@ Also controls `-Wdeprecated-increment-bool`_. **Diagnostic text:** +------------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ISO C++1z does not allow incrementing expression of type bool`| +|:error:`error:` |nbsp| :diagtext:`ISO C++17 does not allow incrementing expression of type bool`| +------------------------------------------------------------------------------------------------+ @@ -5472,6 +5642,10 @@ Also controls `-Wignored-optimization-argument`_. **Diagnostic text:** ++-----------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the object size sanitizer has no effect at -O0, but is explicitly enabled:` |nbsp| :placeholder:`A`| ++-----------------------------------------------------------------------------------------------------------------------------------------+ + +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`optimization level '`:placeholder:`A`:diagtext:`' is not supported; using '`:placeholder:`B`:placeholder:`C`:diagtext:`' instead`| +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -5522,6 +5696,17 @@ This diagnostic is enabled by default. +--------------------------------------------------------------------------------------------------------------+ +-Winvalid-ios-deployment-target +------------------------------- +This diagnostic is an error by default, but the flag ``-Wno-invalid-ios-deployment-target`` can be used to disable the error. + +**Diagnostic text:** + ++------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:error:`error:` |nbsp| :diagtext:`invalid iOS deployment version '`:placeholder:`A`:diagtext:`', iOS 10 is the maximum deployment target for 32-bit targets`| ++------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Winvalid-noreturn ------------------ This diagnostic is enabled by default. @@ -6013,6 +6198,8 @@ This diagnostic is enabled by default. -Wmicrosoft-enum-forward-reference ---------------------------------- +This diagnostic is enabled by default. + **Diagnostic text:** +---------------------------------------------------------------------------------------------------+ @@ -6022,8 +6209,6 @@ This diagnostic is enabled by default. -Wmicrosoft-enum-value ---------------------- -This diagnostic is enabled by default. - **Diagnostic text:** +---------------------------------------------------------------------------------------------------------------------------+ @@ -6433,6 +6618,17 @@ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. +--------------------------------------------------------------------------------------------+ +-Wmissing-noescape +------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`parameter of overriding method should be annotated with \_\_attribute\_\_((noescape))`| ++----------------------------------------------------------------------------------------------------------------------------+ + + -Wmissing-noreturn ------------------ **Diagnostic text:** @@ -6596,7 +6792,7 @@ This diagnostic is an error by default, but the flag ``-Wno-modules-import-neste ------ Some of the diagnostics controlled by this flag are enabled by default. -Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-non-virtual-dtor`_, `-Wextern-c-compat`_, `-Wfor-loop-analysis`_, `-Wformat`_, `-Wimplicit`_, `-Winfinite-recursion`_, `-Wmismatched-tags`_, `-Wmissing-braces`_, `-Wmove`_, `-Wmultichar`_, `-Wobjc-designated-initializers`_, `-Wobjc-missing-super-calls`_, `-Woverloaded-virtual`_, `-Wprivate-extern`_, `-Wreorder`_, `-Wreturn-type`_, `-Wself-assign`_, `-Wself-move`_, `-Wsizeof-array-argument`_, `-Wsizeof-array-decay`_, `-Wstring-plus-int`_, `-Wtrigraphs`_, `-Wuninitialized`_, `-Wunknown-pragmas`_, `-Wunused`_, `-Wuser-defined-warnings`_, `-Wvolatile-register-var`_. +Controls `-Wcast-of-sel-type`_, `-Wchar-subscripts`_, `-Wcomment`_, `-Wdelete-non-virtual-dtor`_, `-Wextern-c-compat`_, `-Wfor-loop-analysis`_, `-Wformat`_, `-Wimplicit`_, `-Winfinite-recursion`_, `-Wmismatched-tags`_, `-Wmissing-braces`_, `-Wmove`_, `-Wmultichar`_, `-Wobjc-designated-initializers`_, `-Wobjc-flexible-array`_, `-Wobjc-missing-super-calls`_, `-Woverloaded-virtual`_, `-Wprivate-extern`_, `-Wreorder`_, `-Wreturn-type`_, `-Wself-assign`_, `-Wself-move`_, `-Wsizeof-array-argument`_, `-Wsizeof-array-decay`_, `-Wstring-plus-int`_, `-Wtrigraphs`_, `-Wuninitialized`_, `-Wunknown-pragmas`_, `-Wunused`_, `-Wuser-defined-warnings`_, `-Wvolatile-register-var`_. -Wmove @@ -6692,6 +6888,11 @@ This diagnostic is enabled by default. +----------------------------------------------------------------+ +-Wnoexcept-type +--------------- +Synonym for `-Wc++17-compat-mangling`_. + + -Wnon-gcc --------- Some of the diagnostics controlled by this flag are enabled by default. @@ -6832,6 +7033,32 @@ This diagnostic is enabled by default. +---------------------------------------------------------------------------------------------------------------------+ +-Wnsconsumed-mismatch +--------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`overriding method has mismatched ns\_consumed attribute on its parameter`| ++---------------------------------------------------------------------------------------------------------------+ + + +-Wnsreturns-mismatch +-------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------+---------------------------+------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`overriding method has mismatched ns\_returns\_`|+-------------------------+| |nbsp| :diagtext:`attributes`| +| ||:diagtext:`not\_retained`|| | +| |+-------------------------+| | +| ||:diagtext:`retained` || | +| |+-------------------------+| | ++-------------------------------------------------------------------------------------+---------------------------+------------------------------+ + + -Wnull-arithmetic ----------------- This diagnostic is enabled by default. @@ -6904,6 +7131,23 @@ This diagnostic is enabled by default. +---------------------------------------------------------------------------------------------------------+ +-Wnull-pointer-arithmetic +------------------------- +**Diagnostic text:** + ++--------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`arithmetic on a null pointer treated as a cast from integer to pointer is a GNU extension`| ++--------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------+----------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`performing pointer arithmetic on a null pointer has undefined behavior`|+--------------------------------------------+| +| || || +| |+--------------------------------------------+| +| || |nbsp| :diagtext:`if the offset is nonzero`|| +| |+--------------------------------------------+| ++-------------------------------------------------------------------------------------------------------------+----------------------------------------------+ + + -Wnullability ------------- This diagnostic is enabled by default. @@ -7077,6 +7321,21 @@ This diagnostic is enabled by default. +----------------------------------------------------------------------------------------------------------+ +-Wobjc-flexible-array +--------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`can overwrite instance variable` |nbsp| :placeholder:`B` |nbsp| :diagtext:`with variable sized type` |nbsp| :placeholder:`C` |nbsp| :diagtext:`in superclass` |nbsp| :placeholder:`D`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`field` |nbsp| :placeholder:`A` |nbsp| :diagtext:`with variable sized type` |nbsp| :placeholder:`B` |nbsp| :diagtext:`is not visible to subclasses and can conflict with their instance variables`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wobjc-forward-class-redefinition --------------------------------- This diagnostic is enabled by default. @@ -7152,6 +7411,15 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------+ +-Wobjc-messaging-id +------------------- +**Diagnostic text:** + ++---------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`messaging unqualified id`| ++---------------------------------------------------------------+ + + -Wobjc-method-access -------------------- This diagnostic is enabled by default. @@ -7515,10 +7783,26 @@ This diagnostic is enabled by default. **Diagnostic text:** ++------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`option '-ffine-grained-bitfield-accesses' cannot be enabled together with a sanitizer; flag ignored`| ++------------------------------------------------------------------------------------------------------------------------------------------+ + +----------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`option '`:placeholder:`A`:diagtext:`' was ignored by the PS4 toolchain, using '-fPIC'`| +----------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mabicalls' option as it cannot be used with non position-independent code and the N64 ABI`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mlong-calls' option as it is not currently supported with` |nbsp| |+-----------------------------------------+|:diagtext:`-mabicalls`| +| || || | +| |+-----------------------------------------+| | +| ||:diagtext:`the implicit usage of` |nbsp| || | +| |+-----------------------------------------+| | ++-------------------------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ + -Wout-of-line-declaration ------------------------- @@ -7531,6 +7815,21 @@ This diagnostic is an error by default, but the flag ``-Wno-out-of-line-declarat +-------------------------------------------------------------------------------------------+ +-Wout-of-scope-function +----------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`use of out-of-scope declaration of` |nbsp| :placeholder:`A`|+-------------------------------------------------------------------------------------+| +| || || +| |+-------------------------------------------------------------------------------------+| +| || |nbsp| :diagtext:`whose type is not compatible with that of an implicit declaration`|| +| |+-------------------------------------------------------------------------------------+| ++-------------------------------------------------------------------------------------------------+---------------------------------------------------------------------------------------+ + + -Wover-aligned -------------- **Diagnostic text:** @@ -7776,7 +8075,7 @@ This diagnostic is enabled by default. -Wpedantic ---------- -Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-literal`_, `-Wc11-extensions`_, `-Wcomplex-component-init`_, `-Wdeclaration-after-statement`_, `-Wdollar-in-identifier-extension`_, `-Wembedded-directive`_, `-Wempty-translation-unit`_, `-Wextended-offsetof`_, `-Wflexible-array-extensions`_, `-Wformat-pedantic`_, `-Wfour-char-constants`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-union-cast`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wimport-preprocessor-directive-pedantic`_, `-Wkeyword-macro`_, `-Wlanguage-extension-token`_, `-Wlong-long`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-forward-reference`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-redeclare-static`_, `-Wnested-anon-types`_, `-Wnullability-extension`_, `-Woverlength-strings`_, `-Wretained-language-linkage`_, `-Wvariadic-macros`_, `-Wvla-extension`_, `-Wzero-length-array`_. +Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-literal`_, `-Wc11-extensions`_, `-Wcomplex-component-init`_, `-Wdeclaration-after-statement`_, `-Wdollar-in-identifier-extension`_, `-Wembedded-directive`_, `-Wempty-translation-unit`_, `-Wextended-offsetof`_, `-Wflexible-array-extensions`_, `-Wformat-pedantic`_, `-Wfour-char-constants`_, `-Wgnu-anonymous-struct`_, `-Wgnu-auto-type`_, `-Wgnu-binary-literal`_, `-Wgnu-case-range`_, `-Wgnu-complex-integer`_, `-Wgnu-compound-literal-initializer`_, `-Wgnu-conditional-omitted-operand`_, `-Wgnu-empty-initializer`_, `-Wgnu-empty-struct`_, `-Wgnu-flexible-array-initializer`_, `-Wgnu-flexible-array-union-member`_, `-Wgnu-folding-constant`_, `-Wgnu-imaginary-constant`_, `-Wgnu-include-next`_, `-Wgnu-label-as-value`_, `-Wgnu-redeclared-enum`_, `-Wgnu-statement-expression`_, `-Wgnu-union-cast`_, `-Wgnu-zero-line-directive`_, `-Wgnu-zero-variadic-macro-arguments`_, `-Wimport-preprocessor-directive-pedantic`_, `-Wkeyword-macro`_, `-Wlanguage-extension-token`_, `-Wlong-long`_, `-Wmicrosoft-charize`_, `-Wmicrosoft-comment-paste`_, `-Wmicrosoft-cpp-macro`_, `-Wmicrosoft-end-of-file`_, `-Wmicrosoft-enum-value`_, `-Wmicrosoft-fixed-enum`_, `-Wmicrosoft-flexible-array`_, `-Wmicrosoft-redeclare-static`_, `-Wnested-anon-types`_, `-Wnullability-extension`_, `-Woverlength-strings`_, `-Wretained-language-linkage`_, `-Wundefined-internal-type`_, `-Wvla-extension`_, `-Wzero-length-array`_. **Diagnostic text:** @@ -7842,6 +8141,10 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter |:warning:`warning:` |nbsp| :diagtext:`parameter` |nbsp| :placeholder:`A` |nbsp| :diagtext:`was not declared, defaulting to type 'int'`| +--------------------------------------------------------------------------------------------------------------------------------------+ ++--------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`invoking a pointer to a 'const &' member function on an rvalue is a C++2a extension`| ++--------------------------------------------------------------------------------------------------------------------------+ + +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`qualifier in explicit instantiation of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`requires a template-id (a typedef is not permitted)`| +----------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ @@ -7995,7 +8298,7 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter +---------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++1z extension`| +|:warning:`warning:` |nbsp| :diagtext:`use of the` |nbsp| :placeholder:`A` |nbsp| :diagtext:`attribute is a C++17 extension`| +---------------------------------------------------------------------------------------------------------------------------+ +-----------------------------------------------------------------------------+--------------------+---------------------------------------------+ @@ -8080,6 +8383,14 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter |:warning:`warning:` |nbsp| :diagtext:`exception specification of '...' is a Microsoft extension`| +------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------+---------------------------+-----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`attributes on` |nbsp| |+-------------------------+| |nbsp| :diagtext:`declaration are a C++17 extension`| +| ||:diagtext:`a namespace` || | +| |+-------------------------+| | +| ||:diagtext:`an enumerator`|| | +| |+-------------------------+| | ++------------------------------------------------------------+---------------------------+-----------------------------------------------------+ + +-----------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`extern templates are a C++11 extension`| +-----------------------------------------------------------------------------+ @@ -8105,7 +8416,7 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter +---------------------------------------------------------------------------------------+ +----------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are a C++1z feature`| +|:warning:`warning:` |nbsp| :diagtext:`hexadecimal floating literals are a C++17 feature`| +----------------------------------------------------------------------------------------+ +---------------------------------------------------------------------+ @@ -8124,6 +8435,14 @@ Also controls `-Wc++11-extra-semi`_, `-Wc++11-long-long`_, `-Wc++14-binary-liter |:warning:`warning:` |nbsp| :diagtext:`\_\_VA\_ARGS\_\_ can only appear in the expansion of a C99 variadic macro`| +----------------------------------------------------------------------------------------------------------------+ ++------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`variadic macros are a C99 feature`| ++------------------------------------------------------------------------+ + ++--------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`named variadic macros are a GNU extension`| ++--------------------------------------------------------------------------------+ + +------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`empty macro arguments are a C99 feature`| +------------------------------------------------------------------------------+ @@ -8288,6 +8607,17 @@ This diagnostic is enabled by default. +----------------------------------------------------------------------------------------------------------------------------------+ +-Wpragma-clang-attribute +------------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`unused attribute` |nbsp| :placeholder:`A` |nbsp| :diagtext:`in '#pragma clang attribute push' region`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wpragma-once-outside-header ---------------------------- This diagnostic is enabled by default. @@ -8299,6 +8629,32 @@ This diagnostic is enabled by default. +----------------------------------------------------------------+ +-Wpragma-pack +------------- +Some of the diagnostics controlled by this flag are enabled by default. + +Also controls `-Wpragma-pack-suspicious-include`_. + +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the current #pragma pack aligment value is modified in the included file`| ++---------------------------------------------------------------------------------------------------------------+ + ++---------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`unterminated '#pragma pack (push, ...)' at end of file`| ++---------------------------------------------------------------------------------------------+ + + +-Wpragma-pack-suspicious-include +-------------------------------- +**Diagnostic text:** + ++-------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`non-default #pragma pack value changes the alignment of struct or union members in the included file`| ++-------------------------------------------------------------------------------------------------------------------------------------------+ + + -Wpragma-system-header-outside-header ------------------------------------- This diagnostic is enabled by default. @@ -8314,7 +8670,7 @@ This diagnostic is enabled by default. --------- Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wignored-pragmas`_, `-Wunknown-pragmas`_. +Also controls `-Wignored-pragmas`_, `-Wpragma-clang-attribute`_, `-Wpragma-pack`_, `-Wunknown-pragmas`_. **Diagnostic text:** @@ -8370,6 +8726,23 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`top-level module '`:placeholder:`A`:diagtext:`' in private module map, expected a submodule of '`:placeholder:`B`:diagtext:`'`| +--------------------------------------------------------------------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`module '`:placeholder:`A`:diagtext:`' already re-exported as '`:placeholder:`B`:diagtext:`'`| ++----------------------------------------------------------------------------------------------------------------------------------+ + + +-Wprofile-instr-missing +----------------------- +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+---------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`profile data may be incomplete: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+-----------------+| |nbsp| :diagtext:`no data`| +| || || ||:diagtext:`:has` || | +| |+-------------+| |+-----------------+| | +| ||:diagtext:`s`|| ||:diagtext:`:have`|| | +| |+-------------+| |+-----------------+| | ++-----------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+---------------------------+ + -Wprofile-instr-out-of-date --------------------------- @@ -8377,13 +8750,13 @@ This diagnostic is enabled by default. **Diagnostic text:** -+------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+---------------------------------------------------------------+-------------------+--------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`profile data may be out of date: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+-----------------+| |nbsp| :diagtext:`no data and` |nbsp| :placeholder:`C` |nbsp| |+-----------------+| |nbsp| :diagtext:`mismatched data that will be ignored`| -| || || ||:diagtext:`:has` || ||:diagtext:`:has` || | -| |+-------------+| |+-----------------+| |+-----------------+| | -| ||:diagtext:`s`|| ||:diagtext:`:have`|| ||:diagtext:`:have`|| | -| |+-------------+| |+-----------------+| |+-----------------+| | -+------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+---------------------------------------------------------------+-------------------+--------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+--------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`profile data may be out of date: of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`function`|+-------------+|:diagtext:`,` |nbsp| :placeholder:`B` |nbsp| |+-----------------+| |nbsp| :diagtext:`mismatched data that will be ignored`| +| || || ||:diagtext:`:has` || | +| |+-------------+| |+-----------------+| | +| ||:diagtext:`s`|| ||:diagtext:`:have`|| | +| |+-------------+| |+-----------------+| | ++------------------------------------------------------------------------------------------------------------------------------+---------------+---------------------------------------------+-------------------+--------------------------------------------------------+ -Wprofile-instr-unprofiled @@ -8448,9 +8821,29 @@ This diagnostic is enabled by default. **Diagnostic text:** -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`property of type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`was selected for synthesis`| -+-----------------------------------------------------------------------------------------------------------------------------+ ++-------------------------------------------------------+----------------------------------------------------------------+----------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`property` |nbsp| |+--------------------------------------------------------------+| |nbsp| :diagtext:`was selected for synthesis`| +| ||+-------------------------------------------+ || | +| |||:diagtext:`of type` |nbsp| :placeholder:`B`| || | +| ||+-------------------------------------------+ || | +| |+--------------------------------------------------------------+| | +| ||+---------------------------------------------------------+ || | +| |||:diagtext:`with attribute '`:placeholder:`B`:diagtext:`'`| || | +| ||+---------------------------------------------------------+ || | +| |+--------------------------------------------------------------+| | +| ||+------------------------------------------------------------+|| | +| |||:diagtext:`without attribute '`:placeholder:`B`:diagtext:`'`||| | +| ||+------------------------------------------------------------+|| | +| |+--------------------------------------------------------------+| | +| ||+-----------------------------------------------+ || | +| |||:diagtext:`with getter` |nbsp| :placeholder:`B`| || | +| ||+-----------------------------------------------+ || | +| |+--------------------------------------------------------------+| | +| ||+-----------------------------------------------+ || | +| |||:diagtext:`with setter` |nbsp| :placeholder:`B`| || | +| ||+-----------------------------------------------+ || | +| |+--------------------------------------------------------------+| | ++-------------------------------------------------------+----------------------------------------------------------------+----------------------------------------------+ -Wqualified-void-return-type @@ -8542,6 +8935,15 @@ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. +-------------------------------------------------------------------------+ +-Wredundant-parens +------------------ +**Diagnostic text:** + ++-----------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`redundant parentheses surrounding declarator`| ++-----------------------------------------------------------------------------------+ + + -Wregister ---------- This diagnostic is enabled by default. @@ -8551,7 +8953,7 @@ Also controls `-Wdeprecated-register`_. **Diagnostic text:** +----------------------------------------------------------------------------------------------+ -|:error:`error:` |nbsp| :diagtext:`ISO C++1z does not allow 'register' storage class specifier`| +|:error:`error:` |nbsp| :diagtext:`ISO C++17 does not allow 'register' storage class specifier`| +----------------------------------------------------------------------------------------------+ @@ -8695,9 +9097,9 @@ Also controls `-Wreturn-type-c-linkage`_. | |+--------------------+| | +---------------------------------------------------+----------------------+-----------------------------------------------------------------+ -+--------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`control reaches end of non-void coroutine`| -+--------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`control reaches end of coroutine; which is undefined behavior because the promise type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`does not declare 'return\_void()'`| ++----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`control reaches end of non-void function`| @@ -8707,9 +9109,9 @@ Also controls `-Wreturn-type-c-linkage`_. |:warning:`warning:` |nbsp| :diagtext:`control reaches end of non-void lambda`| +-----------------------------------------------------------------------------+ -+----------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`control may reach end of non-void coroutine`| -+----------------------------------------------------------------------------------+ ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`control may reach end of coroutine; which is undefined behavior because the promise type` |nbsp| :placeholder:`A` |nbsp| :diagtext:`does not declare 'return\_void()'`| ++------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +---------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`control may reach end of non-void function`| @@ -8789,6 +9191,10 @@ This diagnostic is enabled by default. **Diagnostic text:** ++--------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`section attribute is specified on redeclared variable`| ++--------------------------------------------------------------------------------------------+ + +----------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`section does not match previous declaration`| +----------------------------------------------------------------------------------+ @@ -9370,6 +9776,8 @@ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. |:warning:`warning:` |nbsp| :diagtext:`this` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`a prototype`| | ||:diagtext:`function declaration is not` || | | |+------------------------------------------------------------+| | +| ||:diagtext:`block declaration is not` || | +| |+------------------------------------------------------------+| | | ||:diagtext:`old-style function definition is not preceded by`|| | | |+------------------------------------------------------------+| | +---------------------------------------------------+--------------------------------------------------------------+-------------------------------+ @@ -9383,6 +9791,8 @@ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. |:warning:`warning:` |nbsp| :diagtext:`this` |nbsp| |+------------------------------------------------------------+| |nbsp| :diagtext:`a prototype`| | ||:diagtext:`function declaration is not` || | | |+------------------------------------------------------------+| | +| ||:diagtext:`block declaration is not` || | +| |+------------------------------------------------------------+| | | ||:diagtext:`old-style function definition is not preceded by`|| | | |+------------------------------------------------------------+| | +---------------------------------------------------+--------------------------------------------------------------+-------------------------------+ @@ -9576,7 +9986,7 @@ This diagnostic flag exists for GCC compatibility, and has no effect in Clang. ---------------------- Some of the diagnostics controlled by this flag are enabled by default. -Also controls `-Wtautological-constant-out-of-range-compare`_, `-Wtautological-overlap-compare`_, `-Wtautological-pointer-compare`_, `-Wtautological-undefined-compare`_. +Also controls `-Wtautological-constant-compare`_, `-Wtautological-overlap-compare`_, `-Wtautological-pointer-compare`_, `-Wtautological-undefined-compare`_. **Diagnostic text:** @@ -9598,21 +10008,22 @@ Also controls `-Wtautological-constant-out-of-range-compare`_, `-Wtautological-o | |+-----------------+| +-------------------------------------------------------------------------------------+-------------------+ -+-------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of unsigned`|+------------------------+| |nbsp| :diagtext:`expression` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is always` |nbsp| :placeholder:`B`| -| || || | -| |+------------------------+| | -| || |nbsp| :diagtext:`enum`|| | -| |+------------------------+| | -+-------------------------------------------------------------+--------------------------+-----------------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------------+--------------------------+----------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| :placeholder:`A` |nbsp| :diagtext:`unsigned`|+------------------------+| |nbsp| :diagtext:`expression is always` |nbsp| :placeholder:`B`| -| || || | -| |+------------------------+| | -| || |nbsp| :diagtext:`enum`|| | -| |+------------------------+| | -+--------------------------------------------------------------------------------------------------------+--------------------------+----------------------------------------------------------------+ +-Wtautological-constant-compare +------------------------------- +This diagnostic is enabled by default. + +Also controls `-Wtautological-constant-out-of-range-compare`_, `-Wtautological-unsigned-enum-zero-compare`_, `-Wtautological-unsigned-zero-compare`_. + +**Diagnostic text:** + ++---------------------------------------------------------+------------------+--------------------------------+------------------+-------------------------------------+-------------------+ +|:warning:`warning:` |nbsp| :diagtext:`comparison` |nbsp| |+----------------+| |nbsp| :placeholder:`C` |nbsp| |+----------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| +| ||:placeholder:`D`|| ||:placeholder:`B`|| ||:diagtext:`false`|| +| |+----------------+| |+----------------+| |+-----------------+| +| ||:placeholder:`B`|| ||:placeholder:`D`|| ||:diagtext:`true` || +| |+----------------+| |+----------------+| |+-----------------+| ++---------------------------------------------------------+------------------+--------------------------------+------------------+-------------------------------------+-------------------+ -Wtautological-constant-out-of-range-compare @@ -9695,6 +10106,36 @@ This diagnostic is enabled by default. +------------------------------------------------------------------------------------------------------------------------------------------------------+-------------------+ +-Wtautological-unsigned-enum-zero-compare +----------------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-------------------------------------+-------------------+ +|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+------------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+------------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| +| ||:placeholder:`D` || ||:diagtext:`unsigned enum expression`|| ||:diagtext:`false`|| +| |+------------------------------------+| |+------------------------------------+| |+-----------------+| +| ||:diagtext:`unsigned enum expression`|| ||:placeholder:`D` || ||:diagtext:`true` || +| |+------------------------------------+| |+------------------------------------+| |+-----------------+| ++------------------------------------------------------------+--------------------------------------+--------------------------------+--------------------------------------+-------------------------------------+-------------------+ + + +-Wtautological-unsigned-zero-compare +------------------------------------ +This diagnostic is enabled by default. + +**Diagnostic text:** + ++------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-------------------------------------+-------------------+ +|:warning:`warning:` |nbsp| :diagtext:`comparison of` |nbsp| |+-------------------------------+| |nbsp| :placeholder:`C` |nbsp| |+-------------------------------+| |nbsp| :diagtext:`is always` |nbsp| |+-----------------+| +| ||:placeholder:`D` || ||:diagtext:`unsigned expression`|| ||:diagtext:`false`|| +| |+-------------------------------+| |+-------------------------------+| |+-----------------+| +| ||:diagtext:`unsigned expression`|| ||:placeholder:`D` || ||:diagtext:`true` || +| |+-------------------------------+| |+-------------------------------+| |+-----------------+| ++------------------------------------------------------------+---------------------------------+--------------------------------+---------------------------------+-------------------------------------+-------------------+ + + -Wtentative-definition-incomplete-type -------------------------------------- This diagnostic is enabled by default. @@ -10110,6 +10551,19 @@ This diagnostic is enabled by default. +---------------------------+----------------------+-----------------------------------------------------------------------------------+ +-Wundefined-internal-type +------------------------- +**Diagnostic text:** + ++---------------------------------------------------------------------------------------------------------+----------------------+----------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ISO C++ requires a definition in this translation unit for` |nbsp| |+--------------------+| |nbsp| :placeholder:`B` |nbsp| :diagtext:`because its type does not have linkage`| +| ||:diagtext:`function`|| | +| |+--------------------+| | +| ||:diagtext:`variable`|| | +| |+--------------------+| | ++---------------------------------------------------------------------------------------------------------+----------------------+----------------------------------------------------------------------------------+ + + -Wundefined-reinterpret-cast ---------------------------- **Diagnostic text:** @@ -10149,19 +10603,22 @@ Also controls `-Wpotentially-evaluated-expression`_. -Wunguarded-availability ------------------------ +Some of the diagnostics controlled by this flag are enabled by default. + +Also controls `-Wunguarded-availability-new`_. + **Diagnostic text:** -+----------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is only available conditionally`| -+----------------------------------------------------------------------------------------------+ ++---------------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is only available on` |nbsp| :placeholder:`B` |nbsp| :placeholder:`C` |nbsp| :diagtext:`or newer`| ++---------------------------------------------------------------------------------------------------------------------------------------------------------------+ -+------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`may be partial because the receiver type is unknown`| -+------------------------------------------------------------------------------------------------------------------+ -+--------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is partial:` |nbsp| :placeholder:`B`| -+--------------------------------------------------------------------------------------------------+ +-Wunguarded-availability-new +---------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** +---------------------------------------------------------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :placeholder:`A` |nbsp| :diagtext:`is only available on` |nbsp| :placeholder:`B` |nbsp| :placeholder:`C` |nbsp| :diagtext:`or newer`| @@ -10314,10 +10771,6 @@ Some of the diagnostics controlled by this flag are enabled by default. |:warning:`warning:` |nbsp| :diagtext:`unexpected token in pragma diagnostic`| +----------------------------------------------------------------------------+ -+----------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`unknown warning group '`:placeholder:`A`:diagtext:`', ignored`| -+----------------------------------------------------------------------------------------------------+ - +-------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`unknown pragma ignored`| +-------------------------------------------------------------+ @@ -10376,6 +10829,10 @@ This diagnostic is enabled by default. **Diagnostic text:** ++----------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`unknown warning group '`:placeholder:`A`:diagtext:`', ignored`| ++----------------------------------------------------------------------------------------------------+ + +------------------------------------------------------+---------------------+---------------------------------------------------------+--------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`unknown` |nbsp| |+-------------------+| |nbsp| :diagtext:`option '`:placeholder:`B`:diagtext:`'`|+------------------------------------------------------------+| | ||:diagtext:`warning`|| || || @@ -10488,6 +10945,36 @@ This diagnostic is enabled by default. +-----------------------------------------------------------------------------------------------------+ +-Wunsupported-abs +----------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++-----------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mabs=2008' option because the '`:placeholder:`A`:diagtext:`' architecture does not support it`| ++-----------------------------------------------------------------------------------------------------------------------------------------------+ + ++-------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mabs=legacy' option because the '`:placeholder:`A`:diagtext:`' architecture does not support it`| ++-------------------------------------------------------------------------------------------------------------------------------------------------+ + + +-Wunsupported-availability-guard +-------------------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++---------------------------+------------------------------------+--------------------------------------------------------------+------------------------------------+---------------------+ +|:warning:`warning:` |nbsp| |+----------------------------------+| |nbsp| :diagtext:`does not guard availability here; use if (`|+----------------------------------+|:diagtext:`) instead`| +| ||:diagtext:`@available` || ||:diagtext:`@available` || | +| |+----------------------------------+| |+----------------------------------+| | +| ||:diagtext:`\_\_builtin\_available`|| ||:diagtext:`\_\_builtin\_available`|| | +| |+----------------------------------+| |+----------------------------------+| | ++---------------------------+------------------------------------+--------------------------------------------------------------+------------------------------------+---------------------+ + + -Wunsupported-cb ---------------- This diagnostic is enabled by default. @@ -10527,6 +11014,21 @@ This diagnostic is enabled by default. +-----------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------------+ +-Wunsupported-gpopt +------------------- +This diagnostic is enabled by default. + +**Diagnostic text:** + ++--------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ +|:warning:`warning:` |nbsp| :diagtext:`ignoring '-mgpopt' option as it cannot be used with` |nbsp| |+-----------------------------------------+|:diagtext:`-mabicalls`| +| || || | +| |+-----------------------------------------+| | +| ||:diagtext:`the implicit usage of` |nbsp| || | +| |+-----------------------------------------+| | ++--------------------------------------------------------------------------------------------------+-------------------------------------------+----------------------+ + + -Wunsupported-nan ----------------- This diagnostic is enabled by default. @@ -10585,14 +11087,14 @@ This diagnostic is enabled by default. **Diagnostic text:** ++-------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`argument '`:placeholder:`A`:diagtext:`' requires profile-guided optimization information`| ++-------------------------------------------------------------------------------------------------------------------------------+ + +---------------------------------------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`joined argument expects additional value: '`:placeholder:`A`:diagtext:`'`| +---------------------------------------------------------------------------------------------------------------+ -+-----------------------------------------------------------------------------------------------------------------------------+ -|:warning:`warning:` |nbsp| :diagtext:`argument '-fdiagnostics-show-hotness' requires profile-guided optimization information`| -+-----------------------------------------------------------------------------------------------------------------------------+ - +----------------------------------------------------------------------------------------------------+----------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :placeholder:`A`:diagtext:`: '`:placeholder:`B`:diagtext:`' input unused`|+--------------------------------------------------------------------+| | ||+------------------------------------------------------------------+|| @@ -10621,6 +11123,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`argument unused during compilation: '`:placeholder:`A`:diagtext:`'`| +---------------------------------------------------------------------------------------------------------+ ++----------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`the flag '`:placeholder:`A`:diagtext:`' has been deprecated and will be ignored`| ++----------------------------------------------------------------------------------------------------------------------+ + -Wunused-comparison ------------------- @@ -10781,6 +11287,21 @@ This diagnostic is enabled by default. +-------------------------------------------------------------------------------------------------------------------------------------------+ +-Wunused-template +----------------- +Also controls `-Wunneeded-internal-declaration`_. + +**Diagnostic text:** + ++-----------------------------------------------------+----------------------+----------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`unused` |nbsp| |+--------------------+| |nbsp| :diagtext:`template` |nbsp| :placeholder:`B`| +| ||:diagtext:`function`|| | +| |+--------------------+| | +| ||:diagtext:`variable`|| | +| |+--------------------+| | ++-----------------------------------------------------+----------------------+----------------------------------------------------+ + + -Wunused-value -------------- This diagnostic is enabled by default. @@ -10888,12 +11409,18 @@ This diagnostic is enabled by default. -Wvariadic-macros ----------------- +Some of the diagnostics controlled by this flag are enabled by default. + **Diagnostic text:** +--------------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`named variadic macros are a GNU extension`| +--------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`\_\_VA\_OPT\_\_ can only appear in the expansion of a variadic macro`| ++-----------------------------------------------------------------------------------------------------------+ + +------------------------------------------------------------------------+ |:warning:`warning:` |nbsp| :diagtext:`variadic macros are a C99 feature`| +------------------------------------------------------------------------+ @@ -10952,6 +11479,10 @@ This diagnostic is enabled by default. |:warning:`warning:` |nbsp| :diagtext:`parentheses were disambiguated as a function declaration`| +-----------------------------------------------------------------------------------------------+ ++-----------------------------------------------------------------------------------------------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`parentheses were disambiguated as redundant parentheses around declaration of variable named` |nbsp| :placeholder:`A`| ++-----------------------------------------------------------------------------------------------------------------------------------------------------------+ + -Wvisibility ------------ @@ -11037,6 +11568,15 @@ Also controls `-Wdeprecated-writable-strings`_. Synonym for `-Wwritable-strings`_. +-Wzero-as-null-pointer-constant +------------------------------- +**Diagnostic text:** + ++--------------------------------------------------------------------+ +|:warning:`warning:` |nbsp| :diagtext:`zero as null pointer constant`| ++--------------------------------------------------------------------+ + + -Wzero-length-array ------------------- **Diagnostic text:** diff --git a/docs/HardwareAssistedAddressSanitizerDesign.rst b/docs/HardwareAssistedAddressSanitizerDesign.rst new file mode 100644 index 0000000..00777ce --- /dev/null +++ b/docs/HardwareAssistedAddressSanitizerDesign.rst @@ -0,0 +1,139 @@ +======================================================= +Hardware-assisted AddressSanitizer Design Documentation +======================================================= + +This page is a design document for +**hardware-assisted AddressSanitizer** (or **HWASAN**) +a tool similar to :doc:`AddressSanitizer`, +but based on partial hardware assistance. + +The document is a draft, suggestions are welcome. + + +Introduction +============ + +:doc:`AddressSanitizer` +tags every 8 bytes of the application memory with a 1 byte tag (using *shadow memory*), +uses *redzones* to find buffer-overflows and +*quarantine* to find use-after-free. +The redzones, the quarantine, and, to a less extent, the shadow, are the +sources of AddressSanitizer's memory overhead. +See the `AddressSanitizer paper`_ for details. + +AArch64 has the `Address Tagging`_, a hardware feature that allows +software to use 8 most significant bits of a 64-bit pointer as +a tag. HWASAN uses `Address Tagging`_ +to implement a memory safety tool, similar to :doc:`AddressSanitizer`, +but with smaller memory overhead and slightly different (mostly better) +accuracy guarantees. + +Algorithm +========= +* Every heap/stack/global memory object is forcibly aligned by `N` bytes + (`N` is e.g. 16 or 64) +* For every such object a random `K`-bit tag `T` is chosen (`K` is e.g. 4 or 8) +* The pointer to the object is tagged with `T`. +* The memory for the object is also tagged with `T` + (using a `N=>1` shadow memory) +* Every load and store is instrumented to read the memory tag and compare it + with the pointer tag, exception is raised on tag mismatch. + +Instrumentation +=============== + +Memory Accesses +--------------- +All memory accesses are prefixed with a call to a run-time function. +The function encodes the type and the size of access in its name; +it receives the address as a parameter, e.g. `__hwasan_load4(void *ptr)`; +it loads the memory tag, compares it with the +pointer tag, and executes `__builtin_trap` (or calls `__hwasan_error_load4(void *ptr)`) on mismatch. + +It's possible to inline this callback too. + +Heap +---- + +Tagging the heap memory/pointers is done by `malloc`. +This can be based on any malloc that forces all objects to be N-aligned. + +Stack +----- + +Special compiler instrumentation is required to align the local variables +by N, tag the memory and the pointers. +Stack instrumentation is expected to be a major source of overhead, +but could be optional. +TODO: details. + +Globals +------- + +TODO: details. + +Error reporting +--------------- + +Errors are generated by `__builtin_trap` and are handled by a signal handler. + +Attribute +--------- + +HWASAN uses its own LLVM IR Attribute `sanitize_hwaddress` and a matching +C function attribute. An alternative would be to re-use ASAN's attribute +`sanitize_address`. The reasons to use a separate attribute are: + + * Users may need to disable ASAN but not HWASAN, or vise versa, + because the tools have different trade-offs and compatibility issues. + * LLVM (ideally) does not use flags to decide which pass is being used, + ASAN or HWASAN are being applied, based on the function attributes. + +This does mean that users of HWASAN may need to add the new attribute +to the code that already uses the old attribute. + + +Comparison with AddressSanitizer +================================ + +HWASAN: + * Is less portable than :doc:`AddressSanitizer` + as it relies on hardware `Address Tagging`_ (AArch64). + Address Tagging can be emulated with compiler instrumentation, + but it will require the instrumentation to remove the tags before + any load or store, which is infeasible in any realistic environment + that contains non-instrumented code. + * May have compatibility problems if the target code uses higher + pointer bits for other purposes. + * May require changes in the OS kernels (e.g. Linux seems to dislike + tagged pointers passed from address space: + https://www.kernel.org/doc/Documentation/arm64/tagged-pointers.txt). + * **Does not require redzones to detect buffer overflows**, + but the buffer overflow detection is probabilistic, with roughly + `(2**K-1)/(2**K)` probability of catching a bug. + * **Does not require quarantine to detect heap-use-after-free, + or stack-use-after-return**. + The detection is similarly probabilistic. + +The memory overhead of HWASAN is expected to be much smaller +than that of AddressSanitizer: +`1/N` extra memory for the shadow +and some overhead due to `N`-aligning all objects. + + +Related Work +============ +* `SPARC ADI`_ implements a similar tool mostly in hardware. +* `Effective and Efficient Memory Protection Using Dynamic Tainting`_ discusses + similar approaches ("lock & key"). +* `Watchdog`_ discussed a heavier, but still somewhat similar + "lock & key" approach. +* *TODO: add more "related work" links. Suggestions are welcome.* + + +.. _Watchdog: http://www.cis.upenn.edu/acg/papers/isca12_watchdog.pdf +.. _Effective and Efficient Memory Protection Using Dynamic Tainting: https://www.cc.gatech.edu/~orso/papers/clause.doudalis.orso.prvulovic.pdf +.. _SPARC ADI: https://lazytyped.blogspot.com/2017/09/getting-started-with-adi.html +.. _AddressSanitizer paper: https://www.usenix.org/system/files/conference/atc12/atc12-final39.pdf +.. _Address Tagging: http://infocenter.arm.com/help/index.jsp?topic=/com.arm.doc.den0024a/ch12s05s01.html + diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst index dc89d12..058c63f 100644 --- a/docs/InternalsManual.rst +++ b/docs/InternalsManual.rst @@ -49,7 +49,7 @@ when the code is incorrect or dubious. In Clang, each diagnostic produced has (at the minimum) a unique ID, an English translation associated with it, a :ref:`SourceLocation ` to "put the caret", and a severity (e.g., ``WARNING`` or ``ERROR``). They can also optionally include a number of -arguments to the dianostic (which fill in "%0"'s in the string) as well as a +arguments to the diagnostic (which fill in "%0"'s in the string) as well as a number of source ranges that related to the diagnostic. In this section, we'll be giving examples produced by the Clang command line @@ -493,11 +493,11 @@ source code of the program. Important design points include: In practice, the ``SourceLocation`` works together with the ``SourceManager`` class to encode two pieces of information about a location: its spelling -location and its instantiation location. For most tokens, these will be the +location and its expansion location. For most tokens, these will be the same. However, for a macro expansion (or tokens that came from a ``_Pragma`` directive) these will describe the location of the characters corresponding to the token and the location where the token was used (i.e., the macro -instantiation point or the location of the ``_Pragma`` itself). +expansion point or the location of the ``_Pragma`` itself). The Clang front-end inherently depends on the location of a token being tracked correctly. If it is ever incorrect, the front-end may get confused and die. @@ -795,7 +795,7 @@ preprocessor and notifies a client of the parsing progress. Historically, the parser used to talk to an abstract ``Action`` interface that had virtual methods for parse events, for example ``ActOnBinOp()``. When Clang grew C++ support, the parser stopped supporting general ``Action`` clients -- -it now always talks to the :ref:`Sema libray `. However, the Parser +it now always talks to the :ref:`Sema library `. However, the Parser still accesses AST objects only through opaque types like ``ExprResult`` and ``StmtResult``. Only :ref:`Sema ` looks at the AST node contents of these wrappers. @@ -1324,9 +1324,9 @@ range of iterators over declarations of "``f``". function ``DeclContext::getPrimaryContext`` retrieves the "primary" context for a given ``DeclContext`` instance, which is the ``DeclContext`` responsible for maintaining the lookup table used for the semantics-centric view. Given a -DeclContext, one can obtain the set of declaration contexts that are semanticaly -connected to this declaration context, in source order, including this context -(which will be the only result, for non-namespace contexts) via +DeclContext, one can obtain the set of declaration contexts that are +semantically connected to this declaration context, in source order, including +this context (which will be the only result, for non-namespace contexts) via ``DeclContext::collectAllContexts``. Note that these functions are used internally within the lookup and insertion methods of the ``DeclContext``, so the vast majority of clients can ignore them. @@ -1514,7 +1514,7 @@ use an i-c-e where one is required, but accepting the code unless running with Things get a little bit more tricky when it comes to compatibility with real-world source code. Specifically, GCC has historically accepted a huge superset of expressions as i-c-e's, and a lot of real world code depends on -this unfortuate accident of history (including, e.g., the glibc system +this unfortunate accident of history (including, e.g., the glibc system headers). GCC accepts anything its "fold" optimizer is capable of reducing to an integer constant, which means that the definition of what it accepts changes as its optimizer does. One example is that GCC accepts things like "``case @@ -1540,7 +1540,7 @@ Implementation Approach After trying several different approaches, we've finally converged on a design (Note, at the time of this writing, not all of this has been implemented, consider this a design goal!). Our basic approach is to define a single -recursive method evaluation method (``Expr::Evaluate``), which is implemented +recursive evaluation method (``Expr::Evaluate``), which is implemented in ``AST/ExprConstant.cpp``. Given an expression with "scalar" type (integer, fp, complex, or pointer) this method returns the following information: @@ -2037,7 +2037,7 @@ are similar. * ``CodeGenFunction`` contains functions ``ConvertType`` and ``ConvertTypeForMem`` that convert Clang's types (``clang::Type*`` or ``clang::QualType``) to LLVM types. Use the former for values, and the - later for memory locations: test with the C++ "``bool``" type to check + latter for memory locations: test with the C++ "``bool``" type to check this. If you find that you are having to use LLVM bitcasts to make the subexpressions of your expression have the type that your expression expects, STOP! Go fix semantic analysis and the AST so that you don't diff --git a/docs/JSONCompilationDatabase.rst b/docs/JSONCompilationDatabase.rst index 8631e83..1f3441b 100644 --- a/docs/JSONCompilationDatabase.rst +++ b/docs/JSONCompilationDatabase.rst @@ -91,3 +91,9 @@ The convention is to name the file compile\_commands.json and put it at the top of the build directory. Clang tools are pointed to the top of the build directory to detect the file and use the compilation database to parse C++ code in the source tree. + +Alternatives +============ +For simple projects, Clang tools also recognize a compile_flags.txt file. +This should contain one flag per line. The same flags will be used to compile +any file. diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 78f987c..9b407f3 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -139,6 +139,35 @@ and following ``__`` (double underscore) to avoid interference from a macro with the same name. For instance, ``gnu::__const__`` can be used instead of ``gnu::const``. +``__has_c_attribute`` +--------------------- + +This function-like macro takes a single argument that is the name of an +attribute exposed with the double square-bracket syntax in C mode. The argument +can either be a single identifier or a scoped identifier. If the attribute is +supported, a nonzero value is returned. If the attribute is not supported by the +current compilation target, this macro evaluates to 0. It can be used like this: + +.. code-block:: c + + #ifndef __has_c_attribute // Optional of course. + #define __has_c_attribute(x) 0 // Compatibility with non-clang compilers. + #endif + + ... + #if __has_c_attribute(fallthrough) + #define FALLTHROUGH [[fallthrough]] + #else + #define FALLTHROUGH + #endif + ... + +The attribute identifier (but not scope) can also be specified with a preceding +and following ``__`` (double underscore) to avoid interference from a macro with +the same name. For instance, ``gnu::__const__`` can be used instead of +``gnu::const``. + + ``__has_attribute`` ------------------- @@ -436,6 +465,49 @@ const_cast no no no no See also :ref:`langext-__builtin_shufflevector`, :ref:`langext-__builtin_convertvector`. +Half-Precision Floating Point +============================= + +Clang supports two half-precision (16-bit) floating point types: ``__fp16`` and +``_Float16``. ``__fp16`` is defined in the ARM C Language Extensions (`ACLE +`_) +and ``_Float16`` in ISO/IEC TS 18661-3:2015. + +``__fp16`` is a storage and interchange format only. This means that values of +``__fp16`` promote to (at least) float when used in arithmetic operations. +There are two ``__fp16`` formats. Clang supports the IEEE 754-2008 format and +not the ARM alternative format. + +ISO/IEC TS 18661-3:2015 defines C support for additional floating point types. +``_FloatN`` is defined as a binary floating type, where the N suffix denotes +the number of bits and is 16, 32, 64, or greater and equal to 128 and a +multiple of 32. Clang supports ``_Float16``. The difference from ``__fp16`` is +that arithmetic on ``_Float16`` is performed in half-precision, thus it is not +a storage-only format. ``_Float16`` is available as a source language type in +both C and C++ mode. + +It is recommended that portable code use the ``_Float16`` type because +``__fp16`` is an ARM C-Language Extension (ACLE), whereas ``_Float16`` is +defined by the C standards committee, so using ``_Float16`` will not prevent +code from being ported to architectures other than Arm. Also, ``_Float16`` +arithmetic and operations will directly map on half-precision instructions when +they are available (e.g. Armv8.2-A), avoiding conversions to/from +single-precision, and thus will result in more performant code. If +half-precision instructions are unavailable, values will be promoted to +single-precision, similar to the semantics of ``__fp16`` except that the +results will be stored in single-precision. + +In an arithmetic operation where one operand is of ``__fp16`` type and the +other is of ``_Float16`` type, the ``_Float16`` type is first converted to +``__fp16`` type and then the operation is completed as if both operands were of +``__fp16`` type. + +To define a ``_Float16`` literal, suffix ``f16`` can be appended to the compile-time +constant declaration. There is no default argument promotion for ``_Float16``; this +applies to the standard floating types only. As a consequence, for example, an +explicit cast is required for printing a ``_Float16`` value (there is no string +format specifier for ``_Float16``). + Messages on ``deprecated`` and ``unavailable`` Attributes ========================================================= @@ -1929,7 +2001,13 @@ provided, with values corresponding to the enumerators of C11's ``memory_order`` enumeration. (Note that Clang additionally provides GCC-compatible ``__atomic_*`` -builtins) +builtins and OpenCL 2.0 ``__opencl_atomic_*`` builtins. The OpenCL 2.0 +atomic builtins are an explicit form of the corresponding OpenCL 2.0 +builtin function, and are named with a ``__opencl_`` prefix. The macros +``__OPENCL_MEMORY_SCOPE_WORK_ITEM``, ``__OPENCL_MEMORY_SCOPE_WORK_GROUP``, +``__OPENCL_MEMORY_SCOPE_DEVICE``, ``__OPENCL_MEMORY_SCOPE_ALL_SVM_DEVICES``, +and ``__OPENCL_MEMORY_SCOPE_SUB_GROUP`` are provided, with values +corresponding to the enumerators of OpenCL's ``memory_scope`` enumeration.) Low-level ARM exclusive memory builtins --------------------------------------- diff --git a/docs/LeakSanitizer.rst b/docs/LeakSanitizer.rst index c3ccecc..3601587 100644 --- a/docs/LeakSanitizer.rst +++ b/docs/LeakSanitizer.rst @@ -17,7 +17,7 @@ detection phase. Usage ===== -LeakSanitizer is only supported on x86\_64 Linux. In order to use it, +LeakSanitizer is supported on x86\_64 Linux and OS X. In order to use it, simply build your program with :doc:`AddressSanitizer`: .. code-block:: console @@ -30,7 +30,7 @@ simply build your program with :doc:`AddressSanitizer`: p = 0; // The memory is leaked here. return 0; } - % clang -fsanitize=address -g memory-leak.c ; ./a.out + % clang -fsanitize=address -g memory-leak.c ; ASAN_OPTIONS=detect_leaks=1 ./a.out ==23646==ERROR: LeakSanitizer: detected memory leaks Direct leak of 7 byte(s) in 1 object(s) allocated from: #0 0x4af01b in __interceptor_malloc /projects/compiler-rt/lib/asan/asan_malloc_linux.cc:52:3 diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index cb5020a..ed1ec19 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -346,6 +346,24 @@ Example matches Foo (Additions) +Matcher<Decl>objcCategoryImplDeclMatcher<ObjCCategoryImplDecl>... +
Matches Objective-C category definitions.
+
+Example matches Foo (Additions)
+  @implementation Foo (Additions)
+  @end
+
+ + +Matcher<Decl>objcImplementationDeclMatcher<ObjCImplementationDecl>... +
Matches Objective-C implementation declarations.
+
+Example matches Foo
+  @implementation Foo
+  @end
+
+ + Matcher<Decl>objcInterfaceDeclMatcher<ObjCInterfaceDecl>...
Matches Objective-C interface declarations.
 
@@ -1207,6 +1225,24 @@ nullStmt()
 
+Matcher<Stmt>objcCatchStmtMatcher<ObjCAtCatchStmt>... +
Matches Objective-C @catch statements.
+
+Example matches @catch
+  @try {}
+  @catch (...) {}
+
+ + +Matcher<Stmt>objcFinallyStmtMatcher<ObjCAtFinallyStmt>... +
Matches Objective-C @finally statements.
+
+Example matches @finally
+  @try {}
+  @finally {}
+
+ + Matcher<Stmt>objcMessageExprMatcher<ObjCMessageExpr>...
Matches ObjectiveC Message invocation expressions.
 
@@ -1218,6 +1254,23 @@ NSString's "alloc". This matcher should match both message sends.
 
+Matcher<Stmt>objcThrowStmtMatcher<ObjCAtThrowStmt>... +
Matches Objective-C @throw statements.
+
+Example matches @throw
+  @throw obj;
+
+ + +Matcher<Stmt>objcTryStmtMatcher<ObjCAtTryStmt>... +
Matches Objective-C @try statements.
+
+Example matches @try
+  @try {}
+  @catch (...) {}
+
+ + Matcher<Stmt>opaqueValueExprMatcher<OpaqueValueExpr>...
Matches opaque value expressions. They are used as helpers
 to reference another expressions and can be met
@@ -1729,6 +1782,21 @@ substTemplateTypeParmType() matches the type of 't' but not '1'
 
+Matcher<Type>tagTypeMatcher<TagType>... +
Matches tag types (record and enum types).
+
+Given
+  enum E {};
+  class C {};
+
+  E e;
+  C c;
+
+tagType() matches the type of the variable declarations of both e
+and c.
+
+ + Matcher<Type>templateSpecializationTypeMatcher<TemplateSpecializationType>...
Matches template specialization types.
 
@@ -2208,6 +2276,16 @@ Given
 
+Matcher<CXXNewExpr>isArray +
Matches array new expressions.
+
+Given:
+  MyClass *p1 = new MyClass[10];
+cxxNewExpr(isArray())
+  matches the expression 'new MyClass[10]'.
+
+ + Matcher<CXXOperatorCallExpr>hasOverloadedOperatorNameStringRef Name
Matches overloaded operator names.
 
@@ -2229,6 +2307,15 @@ Usable as: Matcher<CXXRecordDecl>hasDefinition
+
Matches a class declaration that is defined.
+
+Example matches x (matcher = cxxRecordDecl(hasDefinition()))
+class x {};
+class y;
+
+ + Matcher<CXXRecordDecl>isDerivedFromstd::string BaseName
Overloaded method as shortcut for isDerivedFrom(hasName(...)).
 
@@ -2678,8 +2765,8 @@ functionDecl(isDefaulted())
-Matcher<FunctionDecl>isDefinition -
Matches if a declaration has a body attached.
+Matcher<FunctionDecl>isDefinition
+
Matches if a declaration has a body attached.
 
 Example matches A, va, fa
   class A {};
@@ -2688,8 +2775,15 @@ Example matches A, va, fa
   extern int vb;  Doesn't match, as it doesn't define the variable.
   void fa() {}
   void fb();  Doesn't match, as it has no body.
+  @interface X
+  - (void)ma; Doesn't match, interface is declaration.
+  @end
+  @implementation X
+  - (void)ma {}
+  @end
 
-Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
+Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
+  Matcher<ObjCMethodDecl>
 
@@ -2717,19 +2811,22 @@ functionDecl(isExplicitTemplateSpecialization()) Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl>
- Matcher<FunctionDecl>isExternC -
Matches extern "C" function declarations.
+
Matches extern "C" function or variable declarations.
 
 Given:
   extern "C" void f() {}
   extern "C" { void g() {} }
   void h() {}
+  extern "C" int x = 1;
+  extern "C" int y = 2;
+  int z = 3;
 functionDecl(isExternC())
-  matches the declaration of f and g, but not the declaration h
+  matches the declaration of f and g, but not the declaration of h.
+varDecl(isExternC())
+  matches the declaration of x and y, but not the declaration of z.
 
- Matcher<FunctionDecl>isInline
Matches function and namespace declarations that are marked with
 the inline keyword.
@@ -3083,6 +3180,37 @@ a substring matched by the given RegExp.
 
+Matcher<ObjCMethodDecl>isDefinition +
Matches if a declaration has a body attached.
+
+Example matches A, va, fa
+  class A {};
+  class B;  Doesn't match, as it has no body.
+  int va;
+  extern int vb;  Doesn't match, as it doesn't define the variable.
+  void fa() {}
+  void fb();  Doesn't match, as it has no body.
+  @interface X
+  - (void)ma; Doesn't match, interface is declaration.
+  @end
+  @implementation X
+  - (void)ma {}
+  @end
+
+Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
+  Matcher<ObjCMethodDecl>
+
+ + +Matcher<ParmVarDecl>hasDefaultArgument +
Matches a declaration that has default arguments.
+
+Example matches y (matcher = parmVarDecl(hasDefaultArgument()))
+void x(int val) {}
+void y(int val = 0) {}
+
+ + Matcher<QualType>asStringstd::string Name
Matches if the matched type is represented by the given string.
 
@@ -3362,8 +3490,15 @@ Example matches A, va, fa
   extern int vb;  Doesn't match, as it doesn't define the variable.
   void fa() {}
   void fb();  Doesn't match, as it has no body.
+  @interface X
+  - (void)ma; Doesn't match, interface is declaration.
+  @end
+  @implementation X
+  - (void)ma {}
+  @end
 
-Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>
+Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>,
+  Matcher<ObjCMethodDecl>
 
@@ -3625,8 +3760,15 @@ Example matches A, va, fa extern int vb; Doesn't match, as it doesn't define the variable. void fa() {} void fb(); Doesn't match, as it has no body. + @interface X + - (void)ma; Doesn't match, interface is declaration. + @end + @implementation X + - (void)ma {} + @end -Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl> +Usable as: Matcher<TagDecl>, Matcher<VarDecl>, Matcher<FunctionDecl>, + Matcher<ObjCMethodDecl>
@@ -3656,19 +3798,22 @@ functionDecl(isExplicitTemplateSpecialization()) Usable as: Matcher<FunctionDecl>, Matcher<VarDecl>, Matcher<CXXRecordDecl> - Matcher<VarDecl>isExternC -
Matches extern "C" function declarations.
+
Matches extern "C" function or variable declarations.
 
 Given:
   extern "C" void f() {}
   extern "C" { void g() {} }
   void h() {}
+  extern "C" int x = 1;
+  extern "C" int y = 2;
+  int z = 3;
 functionDecl(isExternC())
-  matches the declaration of f and g, but not the declaration h
+  matches the declaration of f and g, but not the declaration of h.
+varDecl(isExternC())
+  matches the declaration of x and y, but not the declaration of z.
 
- Matcher<VarDecl>isStaticStorageClass
Matches variablefunction declarations that have "static" storage
 class specifier ("static" keyword) written in the source.
@@ -4350,6 +4495,16 @@ Example matches A() in the last line
 
+Matcher<CXXNewExpr>hasArraySizeMatcher<Expr> InnerMatcher +
Matches array new expressions with a given array size.
+
+Given:
+  MyClass *p1 = new MyClass[10];
+cxxNewExpr(hasArraySize(intgerLiteral(equals(10))))
+  matches the expression 'new MyClass[10]'.
+
+ + Matcher<CXXNewExpr>hasDeclarationMatcher<Decl> InnerMatcher
Matches a node if the declaration associated with that node
 matches the given matcher.
@@ -4546,6 +4701,18 @@ functionDecl(hasAnyTemplateArgument(refersToType(asString("int"))))
 
+Matcher<ClassTemplateSpecializationDecl>hasSpecializedTemplateMatcher<ClassTemplateDecl> InnerMatcher +
Matches the specialized template of a specialization declaration.
+
+Given
+  tempalate<typename T> class A {};
+  typedef A<int> B;
+classTemplateSpecializationDecl(hasSpecializedTemplate(classTemplateDecl()))
+  matches 'B' with classTemplateDecl() matching the class template
+  declaration of 'A'.
+
+ + Matcher<ClassTemplateSpecializationDecl>hasTemplateArgumentunsigned N, Matcher<TemplateArgument> InnerMatcher
Matches classTemplateSpecializations, templateSpecializationType and
 functionDecl where the n'th TemplateArgument matches the given InnerMatcher.
diff --git a/docs/Modules.rst b/docs/Modules.rst
index ed6f817..757be61 100644
--- a/docs/Modules.rst
+++ b/docs/Modules.rst
@@ -213,8 +213,14 @@ Command-line parameters
 ``-fno-implicit-modules``
   All modules used by the build must be specified with ``-fmodule-file``.
 
-``-fmodule-file=``
-  Load the given precompiled module file.
+``-fmodule-file=[=]``
+  Specify the mapping of module names to precompiled module files. If the
+  name is omitted, then the module file is loaded whether actually required
+  or not. If the name is specified, then the mapping is treated as another
+  prebuilt module search mechanism (in addition to ``-fprebuilt-module-path``)
+  and the module is only loaded if required. Note that in this case the
+  specified file also overrides this module's paths that might be embedded
+  in other precompiled module files.
 
 ``-fprebuilt-module-path=``
   Specify the path to the prebuilt modules. If specified, we will look for modules in this directory for a given top-level module name. We don't need a module map for loading prebuilt modules in this directory and the compiler will not try to rebuild these modules. This can be specified multiple times.
@@ -317,11 +323,12 @@ Module map files use a simplified form of the C99 lexer, with the same rules for
 
 .. parsed-literal::
 
-  ``config_macros`` ``export``     ``private``
+  ``config_macros`` ``export_as``  ``private``
   ``conflict``      ``framework``  ``requires``
   ``exclude``       ``header``     ``textual``
   ``explicit``      ``link``       ``umbrella``
   ``extern``        ``module``     ``use``
+  ``export``
 
 Module map file
 ---------------
@@ -381,6 +388,7 @@ Modules can have a number of different kinds of members, each of which is descri
     *umbrella-dir-declaration*
     *submodule-declaration*
     *export-declaration*
+    *export-as-declaration*
     *use-declaration*
     *link-declaration*
     *config-macros-declaration*
@@ -660,6 +668,30 @@ Note that, if ``Derived.h`` includes ``Base.h``, one can simply use a wildcard e
   compatibility for programs that rely on transitive inclusion (i.e.,
   all of them).
 
+Re-export Declaration
+~~~~~~~~~~~~~~~~~~~~~
+An *export-as-declaration* specifies that the current module will have
+its interface re-exported by the named module.
+
+.. parsed-literal::
+
+  *export-as-declaration*:
+    ``export_as`` *identifier*
+
+The *export-as-declaration* names the module that the current
+module will be re-exported through. Only top-level modules
+can be re-exported, and any given module may only be re-exported
+through a single module.
+
+**Example:** In the following example, the module ``MyFrameworkCore``
+will be re-exported via the module ``MyFramework``:
+
+.. parsed-literal::
+
+  module MyFrameworkCore {
+    export_as MyFramework
+  }
+
 Use declaration
 ~~~~~~~~~~~~~~~
 A *use-declaration* specifies another module that the current top-level module
@@ -945,4 +977,3 @@ PCHInternals_
 .. [#] The preprocessing context in which the modules are parsed is actually dependent on the command-line options provided to the compiler, including the language dialect and any ``-D`` options. However, the compiled modules for different command-line options are kept distinct, and any preprocessor directives that occur within the translation unit are ignored. See the section on the `Configuration macros declaration`_ for more information.
 
 .. _PCHInternals: PCHInternals.html
- 
diff --git a/docs/RefactoringEngine.rst b/docs/RefactoringEngine.rst
new file mode 100644
index 0000000..e0d16ef
--- /dev/null
+++ b/docs/RefactoringEngine.rst
@@ -0,0 +1,253 @@
+==========================
+Clang's refactoring engine
+==========================
+
+This document describes the design of Clang's refactoring engine and provides
+a couple of examples that show how various primitives in the refactoring API
+can be used to implement different refactoring actions. The :doc:`LibTooling`
+library provides several other APIs that are used when developing a
+refactoring action.
+
+Refactoring engine can be used to implement local refactorings that are
+initiated using a selection in an editor or an IDE. You can combine
+:doc:`AST matchers` and the refactoring engine to implement
+refactorings that don't lend themselves well to source selection and/or have to
+query ASTs for some particular nodes.
+
+We assume basic knowledge about the Clang AST. See the :doc:`Introduction
+to the Clang AST ` if you want to learn more
+about how the AST is structured.
+
+..  FIXME: create new refactoring action tutorial and link to the tutorial
+
+Introduction
+------------
+
+Clang's refactoring engine defines a set refactoring actions that implement
+a number of different source transformations. The ``clang-refactor``
+command-line tool can be used to perform these refactorings. Certain
+refactorings are also available in other clients like text editors and IDEs.
+
+A refactoring action is a class that defines a list of related refactoring
+operations (rules). These rules are grouped under a common umbrella - a single
+``clang-refactor`` command. In addition to rules, the refactoring action
+provides the action's command name and description to ``clang-refactor``.
+Each action must implement the ``RefactoringAction`` interface. Here's an
+outline of a ``local-rename`` action:
+
+.. code-block:: c++
+
+  class LocalRename final : public RefactoringAction {
+  public:
+    StringRef getCommand() const override { return "local-rename"; }
+
+    StringRef getDescription() const override {
+      return "Finds and renames symbols in code with no indexer support";
+    }
+
+    RefactoringActionRules createActionRules() const override {
+      ...
+    }
+  };
+
+Refactoring Action Rules
+------------------------
+
+An individual refactoring action is responsible for creating the set of
+grouped refactoring action rules that represent one refactoring operation.
+Although the rules in one action may have a number of different implementations,
+they should strive to produce a similar result. It should be easy for users to
+identify which refactoring action produced the result regardless of which
+refactoring action rule was used.
+
+The distinction between actions and rules enables the creation of actions
+that define a set of different rules that produce similar results. For example,
+the "add missing switch cases" refactoring operation typically adds missing
+cases to one switch at a time. However, it could be useful to have a
+refactoring that works on all switches that operate on a particular enum, as
+one could then automatically update all of them after adding a new enum
+constant. To achieve that, we can create two different rules that will use one
+``clang-refactor`` subcommand. The first rule will describe a local operation
+that's initiated when the user selects a single switch. The second rule will
+describe a global operation that works across translation units and is initiated
+when the user provides the name of the enum to clang-refactor (or the user could
+select the enum declaration instead). The clang-refactor tool will then analyze
+the selection and other options passed to the refactoring action, and will pick
+the most appropriate rule for the given selection and other options.
+
+Rule Types
+^^^^^^^^^^
+
+Clang's refactoring engine supports several different refactoring rules:
+
+- ``SourceChangeRefactoringRule`` produces source replacements that are applied
+  to the source files. Subclasses that choose to implement this rule have to
+  implement the ``createSourceReplacements`` member function. This type of
+  rule is typically used to implement local refactorings that transform the
+  source in one translation unit only.
+
+- ``FindSymbolOccurrencesRefactoringRule`` produces a "partial" refactoring
+  result: a set of occurrences that refer to a particular symbol. This type
+  of rule is typically used to implement an interactive renaming action that
+  allows users to specify which occurrences should be renamed during the
+  refactoring. Subclasses that choose to implement this rule have to implement
+  the ``findSymbolOccurrences`` member function.
+
+The following set of quick checks might help if you are unsure about the type
+of rule you should use:
+
+#. If you would like to transform the source in one translation unit and if
+   you don't need any cross-TU information, then the
+   ``SourceChangeRefactoringRule`` should work for you.
+
+#. If you would like to implement a rename-like operation with potential
+   interactive components, then ``FindSymbolOccurrencesRefactoringRule`` might
+   work for you.
+
+How to Create a Rule
+^^^^^^^^^^^^^^^^^^^^
+
+Once you determine which type of rule is suitable for your needs you can
+implement the refactoring by subclassing the rule and implementing its
+interface. The subclass should have a constructor that takes the inputs that
+are needed to perform the refactoring. For example, if you want to implement a
+rule that simply deletes a selection, you should create a subclass of
+``SourceChangeRefactoringRule`` with a constructor that accepts the selection
+range:
+
+.. code-block:: c++
+
+  class DeleteSelectedRange final : public SourceChangeRefactoringRule {
+  public:
+    DeleteSelection(SourceRange Selection) : Selection(Selection) {}
+
+    Expected
+    createSourceReplacements(RefactoringRuleContext &Context) override {
+      AtomicChange Replacement(Context.getSources(), Selection.getBegin());
+      Replacement.replace(Context.getSource,
+                          CharSourceRange::getCharRange(Selection), "");
+      return { Replacement };
+    }
+  private:
+    SourceRange Selection;
+  };
+
+The rule's subclass can then be added to the list of refactoring action's
+rules for a particular action using the ``createRefactoringActionRule``
+function. For example, the class that's shown above can be added to the
+list of action rules using the following code:
+
+.. code-block:: c++
+
+  RefactoringActionRules Rules;
+  Rules.push_back(
+    createRefactoringActionRule(
+          SourceRangeSelectionRequirement())
+  );
+
+The ``createRefactoringActionRule`` function takes in a list of refactoring
+action rule requirement values. These values describe the initiation
+requirements that have to be satisfied by the refactoring engine before the
+provided action rule can be constructed and invoked. The next section
+describes how these requirements are evaluated and lists all the possible
+requirements that can be used to construct a refactoring action rule.
+
+Refactoring Action Rule Requirements
+------------------------------------
+
+A refactoring action rule requirement is a value whose type derives from the
+``RefactoringActionRuleRequirement`` class. The type must define an
+``evaluate`` member function that returns a value of type ``Expected<...>``.
+When a requirement value is used as an argument to
+``createRefactoringActionRule``, that value is evaluated during the initiation
+of the action rule. The evaluated result is then passed to the rule's
+constructor unless the evaluation produced an error. For example, the
+``DeleteSelectedRange`` sample rule that's defined in the previous section
+will be evaluated using the following steps:
+
+#. ``SourceRangeSelectionRequirement``'s ``evaluate`` member function will be
+   called first. It will return an ``Expected``.
+
+#. If the return value is an error the initiation will fail and the error
+   will be reported to the client. Note that the client may not report the
+   error to the user.
+
+#. Otherwise the source range return value will be used to construct the
+   ``DeleteSelectedRange`` rule. The rule will then be invoked as the initiation
+   succeeded (all requirements were evaluated successfully).
+
+The same series of steps applies to any refactoring rule. Firstly, the engine
+will evaluate all of the requirements. Then it will check if these requirements
+are satisfied (they should not produce an error). Then it will construct the
+rule and invoke it.
+
+The separation of requirements, their evaluation and the invocation of the
+refactoring action rule allows the refactoring clients to:
+
+- Disable refactoring action rules whose requirements are not supported.
+
+- Gather the set of options and define a command-line / visual interface
+  that allows users to input these options without ever invoking the
+  action.
+
+Selection Requirements
+^^^^^^^^^^^^^^^^^^^^^^
+
+The refactoring rule requirements that require some form of source selection
+are listed below:
+
+- ``SourceRangeSelectionRequirement`` evaluates to a source range when the
+  action is invoked with some sort of selection. This requirement should be
+  satisfied when a refactoring is initiated in an editor, even when the user
+  has not selected anything (the range will contain the cursor's location in
+  that case).
+
+..  FIXME: Future selection requirements
+
+..  FIXME: Maybe mention custom selection requirements?
+
+Other Requirements
+^^^^^^^^^^^^^^^^^^
+
+There are several other requirements types that can be used when creating
+a refactoring rule:
+
+- The ``RefactoringOptionsRequirement`` requirement is an abstract class that
+  should be subclassed by requirements working with options. The more
+  concrete ``OptionRequirement`` requirement is a simple implementation of the
+  aforementioned class that returns the value of the specified option when
+  it's evaluated. The next section talks more about refactoring options and
+  how they can be used when creating a rule.
+
+Refactoring Options
+-------------------
+
+Refactoring options are values that affect a refactoring operation and are
+specified either using command-line options or another client-specific
+mechanism. Options should be created using a class that derives either from
+the ``OptionalRequiredOption`` or ``RequiredRefactoringOption``. The following
+example shows how one can created a required string option that corresponds to
+the ``-new-name`` command-line option in clang-refactor:
+
+.. code-block:: c++
+
+  class NewNameOption : public RequiredRefactoringOption {
+  public:
+    StringRef getName() const override { return "new-name"; }
+    StringRef getDescription() const override {
+      return "The new name to change the symbol to";
+    }
+  };
+
+The option that's shown in the example above can then be used to create
+a requirement for a refactoring rule using a requirement like
+``OptionRequirement``:
+
+.. code-block:: c++
+
+  createRefactoringActionRule(
+    ...,
+    OptionRequirement())
+  );
+
+..  FIXME: Editor Bindings section
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 6e8b005..8dce923 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -1,6 +1,6 @@
-=========================
-Clang 5.0.0 Release Notes
-=========================
+=======================================
+Clang 6.0.0 (In-Progress) Release Notes
+=======================================
 
 .. contents::
    :local:
@@ -8,11 +8,17 @@ Clang 5.0.0 Release Notes
 
 Written by the `LLVM Team `_
 
+.. warning::
+
+   These are in-progress notes for the upcoming Clang 6 release.
+   Release notes for previous releases can be found on
+   `the Download Page `_.
+
 Introduction
 ============
 
 This document contains the release notes for the Clang C/C++/Objective-C
-frontend, part of the LLVM Compiler Infrastructure, release 5.0.0. Here we
+frontend, part of the LLVM Compiler Infrastructure, release 6.0.0. Here we
 describe the status of Clang in some detail, including major
 improvements from the previous release and new feature work. For the
 general LLVM release notes, see `the LLVM
@@ -24,7 +30,12 @@ For more information about Clang or LLVM, including information about the
 latest release, please see the `Clang Web Site `_ or the
 `LLVM Web Site `_.
 
-What's New in Clang 5.0.0?
+Note that if you are reading this file from a Subversion checkout or the
+main Clang web page, this document applies to the *next* release, not
+the current one. To see the release notes for a specific release, please
+see the `releases page `_.
+
+What's New in Clang 6.0.0?
 ==========================
 
 Some of the major new features and improvements to Clang are listed
@@ -35,48 +46,91 @@ sections with improvements to Clang's support for those languages.
 Major New Features
 ------------------
 
-C++ coroutines
-^^^^^^^^^^^^^^
-`C++ coroutines TS
-`_
-implementation has landed. Use ``-fcoroutines-ts -stdlib=libc++`` to enable
-coroutine support. Here is `an example
-`_ to get you started.
-
+-  ...
 
 Improvements to Clang's diagnostics
 ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
 
--  ``-Wcast-qual`` was implemented for C++. C-style casts are now properly
-   diagnosed.
+- ``-Wpragma-pack`` is a new warning that warns in the following cases:
+
+  - When a translation unit is missing terminating ``#pragma pack (pop)``
+    directives.
+
+  - When leaving an included file that changes the current alignment value,
+    i.e. when the alignment before ``#include`` is different to the alignment
+    after ``#include``.
+
+  - ``-Wpragma-pack-suspicious-include`` (disabled by default) warns on an
+    ``#include`` when the included file contains structures or unions affected by
+    a non-default alignment that has been specified using a ``#pragma pack``
+    directive prior to the ``#include``.
+
+- ``-Wobjc-messaging-id`` is a new, non-default warning that warns about
+  message sends to unqualified ``id`` in Objective-C. This warning is useful
+  for projects that would like to avoid any potential future compiler
+  errors/warnings, as the system frameworks might add a method with the same
+  selector which could make the message send to ``id`` ambiguous.
+
+- ``-Wtautological-compare`` now warns when comparing an unsigned integer and 0
+  regardless of whether the constant is signed or unsigned."
+
+- ``-Wtautological-compare`` now warns about comparing a signed integer and 0
+  when the signed integer is coerced to an unsigned type for the comparison.
+  ``-Wsign-compare`` was adjusted not to warn in this case.
+
+- ``-Wtautological-constant-compare`` is a new warning that warns on
+  tautological comparisons between integer variable of the type ``T`` and the
+  largest/smallest possible integer constant of that same type.
 
--  ``-Wunused-lambda-capture`` warns when a variable explicitly captured
-   by a lambda is not used in the body of the lambda.
+- For C code, ``-Wsign-compare``, ``-Wsign-conversion``,
+  ``-Wtautological-constant-compare`` and
+  ``-Wtautological-constant-out-of-range-compare`` were adjusted to use the
+  underlying datatype of ``enum``.
 
--  ``-Wstrict-prototypes`` is a new warning that warns about non-prototype
-   function and block declarations and types in C and Objective-C.
+- ``-Wnull-pointer-arithmetic`` now warns about performing pointer arithmetic
+  on a null pointer. Such pointer arithmetic has an undefined behavior if the
+  offset is nonzero. It also now warns about arithmetic on a null pointer
+  treated as a cast from integer to pointer (GNU extension).
 
--  ``-Wunguarded-availability`` is a new warning that warns about uses of new
-   APIs that were introduced in a system whose version is newer than the
-   deployment target version. A new Objective-C expression ``@available`` has
-   been introduced to perform system version checking at runtime. This warning
-   is off by default to prevent unexpected warnings in existing projects.
-   However, its less strict sibling ``-Wunguarded-availability-new`` is on by
-   default. It warns about unguarded uses of APIs only when they were introduced
-   in or after macOS 10.13, iOS 11, tvOS 11 or watchOS 4.
+- ``-Wzero-as-null-pointer-constant`` was adjusted not to warn on null pointer
+  constants that originate from system macros, except ``NULL`` macro.
 
--  The ``-Wdocumentation`` warning now allows the use of ``\param`` and
-   ``\returns`` documentation directives in the documentation comments for
-   declarations with a function or a block pointer type.
+Non-comprehensive list of changes in this release
+-------------------------------------------------
 
--  The compiler no longer warns about unreachable ``__builtin_unreachable``
-   statements.
+- Bitrig OS was merged back into OpenBSD, so Bitrig support has been
+  removed from Clang/LLVM.
+
+- The default value of _MSC_VER was raised from 1800 to 1911, making it
+  compatible with the Visual Studio 2015 and 2017 C++ standard library headers.
+  Users should generally expect this to be regularly raised to match the most
+  recently released version of the Visual C++ compiler.
+
+- clang now defaults to ``.init_array`` if no gcc installation can be found.
+  If a gcc installation is found, it still prefers ``.ctors`` if the found
+  gcc is older than 4.7.0.
+
+- The new builtin preprocessor macros ``__is_target_arch``,
+  ``__is_target_vendor``, ``__is_target_os``, and ``__is_target_environment``
+  can be used to to examine the individual components of the target triple.
 
 New Compiler Flags
 ------------------
 
-- ``--autocomplete`` was implemented to obtain a list of flags and its arguments.
-  This is used for shell autocompletion.
+- --autocomplete was implemented to obtain a list of flags and its arguments. This is used for shell autocompletion.
+
+- The ``-fdouble-square-bracket-attributes`` and corresponding
+  ``-fno-double-square-bracket-attributes`` flags were added to enable or
+  disable [[]] attributes in any language mode. Currently, only a limited
+  number of attributes are supported outside of C++ mode. See the Clang
+  attribute documentation for more information about which attributes are
+  supported for each syntax.
+  
+- Added the ``-std=c17``, ``-std=gnu17``, and ``-std=iso9899:2017`` language
+  mode flags for compatibility with GCC. This enables support for the next
+  version of the C standard, expected to be published by ISO in 2018. The only
+  difference between the ``-std=c17`` and ``-std=c11`` language modes is the
+  value of the ``__STDC_VERSION__`` macro, as C17 is a bug fix release.
 
 Deprecated Compiler Flags
 -------------------------
@@ -84,278 +138,194 @@ Deprecated Compiler Flags
 The following options are deprecated and ignored. They will be removed in
 future versions of Clang.
 
-- ``-fslp-vectorize-aggressive`` used to enable the BB vectorizing pass. They have been superseeded
-  by the normal SLP vectorizer.
-- ``-fno-slp-vectorize-aggressive`` used to be the default behavior of clang.
+- ...
 
 New Pragmas in Clang
 -----------------------
 
-- Clang now supports the ``clang attribute`` pragma that allows users to apply
-  an attribute to multiple declarations.
+Clang now supports the ...
 
-- ``pragma pack`` directives that are included in a precompiled header are now
-  applied correctly to the declarations in the compilation unit that includes
-  that precompiled header.
 
 Attribute Changes in Clang
 --------------------------
 
--  The ``overloadable`` attribute now allows at most one function with a given
-   name to lack the ``overloadable`` attribute. This unmarked function will not
-   have its name mangled.
--  The ``ms_abi`` attribute and the ``__builtin_ms_va_list`` types and builtins
-   are now supported on AArch64.
-
-C Language Changes in Clang
----------------------------
-
-- Added near complete support for implicit scalar to vector conversion, a GNU
-  C/C++ language extension. With this extension, the following code is
-  considered valid:
-
-.. code-block:: c
-
-    typedef unsigned v4i32 __attribute__((vector_size(16)));
+- Clang now supports the majority of its attributes under both the GNU-style
+  spelling (``__attribute((name))``) and the double square-bracket spelling
+  in the ``clang`` vendor namespace (``[[clang::name]]``). Attributes whose
+  syntax is specified by some other standard (such as CUDA and OpenCL
+  attributes) continue to follow their respective specification.
+  
+- Added the ``__has_c_attribute()`` builtin preprocessor macro which allows
+  users to dynamically detect whether a double square-bracket attribute is
+  supported in C mode. This attribute syntax can be enabled with the
+  ``-fdouble-square-bracket-attributes`` flag.
+  
+- The presence of __attribute__((availability(...))) on a declaration no longer
+  implies default visibility for that declaration on macOS.
+
+- ...
+
+Windows Support
+---------------
 
-    v4i32 foo(v4i32 a) {
-      // Here 5 is implicitly casted to an unsigned value and replicated into a
-      // vector with as many elements as 'a'.
-      return a + 5;
-    }
+Clang's support for building native Windows programs ...
 
-The implicit conversion of a scalar value to a vector value--in the context of
-a vector expression--occurs when:
 
-- The type of the vector is that of a ``__attribute__((vector_size(size)))``
-  vector, not an OpenCL ``__attribute__((ext_vector_type(size)))`` vector type.
+C Language Changes in Clang
+---------------------------
 
-- The scalar value can be casted to that of the vector element's type without
-  the loss of precision based on the type of the scalar and the type of the
-  vector's elements.
+- ...
 
-- For compile time constant values, the above rule is weakened to consider the
-  value of the scalar constant rather than the constant's type. However,
-  for compatibility with GCC, floating point constants with precise integral
-  representations are not implicitly converted to integer values.
+...
 
-Currently the basic integer and floating point types with the following
-operators are supported: ``+``, ``/``, ``-``, ``*``, ``%``, ``>``, ``<``,
-``>=``, ``<=``, ``==``, ``!=``, ``&``, ``|``, ``^`` and the corresponding
-assignment operators where applicable.
+C11 Feature Support
+^^^^^^^^^^^^^^^^^^^
 
+...
 
 C++ Language Changes in Clang
 -----------------------------
 
-- We expect this to be the last Clang release that defaults to ``-std=gnu++98``
-  when using the GCC-compatible ``clang++`` driver. From Clang 6 onwards we
-  expect to use ``-std=gnu++14`` or a later standard by default, to match the
-  behavior of recent GCC releases. Users are encouraged to change their build
-  files to explicitly specify their desired C++ standard.
-
-- Support for the C++17 standard has been completed. This mode can be enabled
-  using ``-std=c++17`` (the old flag ``-std=c++1z`` is still supported for
-  compatibility).
-
-- When targeting a platform that uses the Itanium C++ ABI, Clang implements a
-  `recent change to the ABI`__ that passes objects of class type indirectly if they
-  have a non-trivial move constructor. Previous versions of Clang only
-  considered the copy constructor, resulting in an ABI change in rare cases,
-  but GCC has already implemented this change for several releases.
-  This affects all targets other than Windows and PS4. You can opt out of this
-  ABI change with ``-fclang-abi-compat=4.0``.
+- Clang's default C++ dialect is now ``gnu++14`` instead of ``gnu++98``. This
+  means Clang will by default accept code using features from C++14 and
+  conforming GNU extensions. Projects incompatible with C++14 can add
+  ``-std=gnu++98`` to their build settings to restore the previous behaviour.
 
-- As mentioned in `C Language Changes in Clang`_, Clang's support for
-  implicit scalar to vector conversions also applies to C++. Additionally
-  the following operators are also supported: ``&&`` and ``||``.
+C++1z Feature Support
+^^^^^^^^^^^^^^^^^^^^^
 
-.. __: https://github.com/itanium-cxx-abi/cxx-abi/commit/7099637aba11fed6bdad7ee65bf4fd3f97fbf076
+...
 
 Objective-C Language Changes in Clang
 -------------------------------------
 
-- Clang now guarantees that a ``readwrite`` property is synthesized when an
-  ambiguous property (i.e. a property that's declared in multiple protocols)
-  is synthesized. The ``-Wprotocol-property-synthesis-ambiguity`` warning that
-  warns about incompatible property types is now promoted to an error when
-  there's an ambiguity between ``readwrite`` and ``readonly`` properties.
-
-- Clang now prohibits synthesis of ambiguous properties with incompatible
-  explicit property attributes. The following property attributes are
-  checked for differences: ``copy``, ``retain``/``strong``, ``atomic``,
-  ``getter`` and ``setter``.
+...
 
 OpenCL C Language Changes in Clang
 ----------------------------------
 
-Various bug fixes and improvements:
-
--  Extended OpenCL-related Clang tests.
-
--  Improved diagnostics across several areas: scoped address space
-   qualified variables, function pointers, atomics, type rank for overloading,
-   block captures, ``reserve_id_t``.
+...
 
--  Several address space related fixes for constant address space function scope variables,
-   IR generation, mangling of ``generic`` and alloca (post-fix from general Clang
-   refactoring of address spaces).
+OpenMP Support in Clang
+----------------------------------
 
--  Several improvements in extensions: fixed OpenCL version for ``cl_khr_mipmap_image``,
-   added missing ``cl_khr_3d_image_writes``.
+...
 
--  Improvements in ``enqueue_kernel``, especially the implementation of ``ndrange_t`` and blocks.
+Internal API Changes
+--------------------
 
--  OpenCL type related fixes: global samplers, the ``pipe_t`` size, internal type redefinition,
-   and type compatibility checking in ternary and other operations.
+These are major API changes that have happened since the 4.0.0 release of
+Clang. If upgrading an external codebase that uses Clang as a library,
+this section should help get you past the largest hurdles of upgrading.
 
--  The OpenCL header has been extended with missing extension guards, and direct mapping of ``as_type``
-   to ``__builtin_astype``.
+-  ...
 
--  Fixed ``kernel_arg_type_qual`` and OpenCL/SPIR version in metadata.
+AST Matchers
+------------
 
--  Added proper use of the kernel calling convention to various targets.
+The hasDeclaration matcher now works the same for Type and QualType and only
+ever looks through one level of sugaring in a limited number of cases.
 
-The following new functionalities have been added:
+There are two main patterns affected by this:
 
--  Added documentation on OpenCL to Clang user manual.
+-  qualType(hasDeclaration(recordDecl(...))): previously, we would look through
+   sugar like TypedefType to get at the underlying recordDecl; now, we need
+   to explicitly remove the sugaring:
+   qualType(hasUnqualifiedDesugaredType(hasDeclaration(recordDecl(...))))
 
--  Extended Clang builtins with required ``cl_khr_subgroups`` support.
+-  hasType(recordDecl(...)): hasType internally uses hasDeclaration; previously,
+   this matcher used to match for example TypedefTypes of the RecordType, but
+   after the change they don't; to fix, use:
 
--  Add ``intel_reqd_sub_group_size`` attribute support.
+::
+   hasType(hasUnqualifiedDesugaredType(
+       recordType(hasDeclaration(recordDecl(...)))))
 
--  Added OpenCL types to ``CIndex``.
+-  templateSpecializationType(hasDeclaration(classTemplateDecl(...))):
+   previously, we would directly match the underlying ClassTemplateDecl;
+   now, we can explicitly match the ClassTemplateSpecializationDecl, but that
+   requires to explicitly get the ClassTemplateDecl:
 
+::
+   templateSpecializationType(hasDeclaration(
+       classTemplateSpecializationDecl(
+           hasSpecializedTemplate(classTemplateDecl(...)))))
 
 clang-format
 ------------
 
-* Option **BreakBeforeInheritanceComma** added to break before ``:`` and ``,``  in case of
-  multiple inheritance in a class declaration. Enabled by default in the Mozilla coding style.
-
-  +---------------------+----------------------------------------+
-  | true                | false                                  |
-  +=====================+========================================+
-  | .. code-block:: c++ | .. code-block:: c++                    |
-  |                     |                                        |
-  |   class MyClass     |   class MyClass : public X, public Y { |
-  |       : public X    |   };                                   |
-  |       , public Y {  |                                        |
-  |   };                |                                        |
-  +---------------------+----------------------------------------+
-
-* Align block comment decorations.
-
-  +----------------------+---------------------+
-  | Before               | After               |
-  +======================+=====================+
-  |  .. code-block:: c++ | .. code-block:: c++ |
-  |                      |                     |
-  |    /* line 1         |   /* line 1         |
-  |      * line 2        |    * line 2         |
-  |     */               |    */               |
-  +----------------------+---------------------+
-
-* The :doc:`ClangFormatStyleOptions` documentation provides detailed examples for most options.
-
-* Namespace end comments are now added or updated automatically.
-
-  +---------------------+---------------------+
-  | Before              | After               |
-  +=====================+=====================+
-  | .. code-block:: c++ | .. code-block:: c++ |
-  |                     |                     |
-  |   namespace A {     |   namespace A {     |
-  |   int i;            |   int i;            |
-  |   int j;            |   int j;            |
-  |   }                 |   } // namespace A  |
-  +---------------------+---------------------+
-
-* Comment reflow support added. Overly long comment lines will now be reflown with the rest of
-  the paragraph instead of just broken. Option **ReflowComments** added and enabled by default.
+* Option *IndentPPDirectives* added to indent preprocessor directives on
+  conditionals.
+
+  +----------------------+----------------------+
+  | Before               | After                |
+  +======================+======================+
+  |  .. code-block:: c++ | .. code-block:: c++  |
+  |                      |                      |
+  |    #if FOO           |   #if FOO            |
+  |    #if BAR           |   #  if BAR          |
+  |    #include     |   #    include  |
+  |    #endif            |   #  endif           |
+  |    #endif            |   #endif             |
+  +----------------------+----------------------+
+
+* Option -verbose added to the command line.
+  Shows the list of processed files.
+
+* Option *IncludeBlocks* added to merge and regroup multiple ``#include`` blocks during sorting.
+
+  +-------------------------+-------------------------+-------------------------+
+  | Before (Preserve)       | Merge                   | Regroup                 |
+  +=========================+=========================+=========================+
+  |  .. code-block:: c++    | .. code-block:: c++     | .. code-block:: c++     |
+  |                         |                         |                         |
+  |   #include "b.h"        |   #include "a.h"        |   #include "a.h"        |
+  |                         |   #include "b.h"        |   #include "b.h"        |
+  |   #include "a.b"        |   #include  |                         |
+  |   #include  |                         |   #include  |
+  +-------------------------+-------------------------+-------------------------+
 
 libclang
 --------
 
-- Libclang now provides code-completion results for more C++ constructs
-  and keywords. The following keywords/identifiers are now included in the
-  code-completion results: ``static_assert``, ``alignas``, ``constexpr``,
-  ``final``, ``noexcept``, ``override`` and ``thread_local``.
-
-- Libclang now provides code-completion results for members from dependent
-  classes. For example:
-
-  .. code-block:: c++
-
-    template
-    void appendValue(std::vector &dest, const T &value) {
-        dest. // Relevant completion results are now shown after '.'
-    }
+...
 
-  Note that code-completion results are still not provided when the member
-  expression includes a dependent base expression. For example:
-
-  .. code-block:: c++
-
-    template
-    void appendValue(std::vector> &dest, const T &value) {
-        dest.at(0). // Libclang fails to provide completion results after '.'
-    }
 
 Static Analyzer
 ---------------
 
-- The static analyzer now supports using the
-  `z3 theorem prover `_ from Microsoft Research
-  as an external constraint solver. This allows reasoning over more complex
-  queries, but performance is ~15x slower than the default range-based
-  constraint solver. To enable the z3 solver backend, clang must be built with
-  the ``CLANG_ANALYZER_BUILD_Z3=ON`` option, and the
-  ``-Xanalyzer -analyzer-constraints=z3`` arguments passed at runtime.
+- Static Analyzer can now properly detect and diagnose unary pre-/post-
+  increment/decrement on an uninitialized value.
+
+...
 
 Undefined Behavior Sanitizer (UBSan)
 ------------------------------------
 
-- The Undefined Behavior Sanitizer has a new check for pointer overflow. This
-  check is on by default. The flag to control this functionality is
-  ``-fsanitize=pointer-overflow``.
+* A minimal runtime is now available. It is suitable for use in production
+  environments, and has a small attack surface. It only provides very basic
+  issue logging and deduplication, and does not support ``-fsanitize=vptr``
+  checking.
 
-  Pointer overflow is an indicator of undefined behavior: when a pointer
-  indexing expression wraps around the address space, or produces other
-  unexpected results, its result may not point to a valid object.
-
-- UBSan has several new checks which detect violations of nullability
-  annotations. These checks are off by default. The flag to control this group
-  of checks is ``-fsanitize=nullability``. The checks can be individially enabled
-  by ``-fsanitize=nullability-arg`` (which checks calls),
-  ``-fsanitize=nullability-assign`` (which checks assignments), and
-  ``-fsanitize=nullability-return`` (which checks return statements).
+Core Analysis Improvements
+==========================
 
-- UBSan can now detect invalid loads from bitfields and from ObjC BOOLs.
+- ...
 
-- UBSan can now avoid emitting unnecessary type checks in C++ class methods and
-  in several other cases where the result is known at compile-time. UBSan can
-  also avoid emitting unnecessary overflow checks in arithmetic expressions
-  with promoted integer operands.
+New Issues Found
+================
 
+- ...
 
 Python Binding Changes
 ----------------------
 
-Python bindings now support both Python 2 and Python 3.
-
 The following methods have been added:
 
-- ``is_scoped_enum`` has been added to ``Cursor``.
-
-- ``exception_specification_kind`` has been added to ``Cursor``.
-
-- ``get_address_space`` has been added to ``Type``.
-
-- ``get_typedef_name`` has been added to ``Type``.
-
-- ``get_exception_specification_kind`` has been added to ``Type``.
+-  ...
 
+Significant Known Problems
+==========================
 
 Additional Information
 ======================
diff --git a/docs/SanitizerCoverage.rst b/docs/SanitizerCoverage.rst
index 06bafd6..e1c3fc9 100644
--- a/docs/SanitizerCoverage.rst
+++ b/docs/SanitizerCoverage.rst
@@ -119,6 +119,53 @@ Example:
   guard: 0x71bcdc 4 PC 0x4ecdc7 in main trace-pc-guard-example.cc:4:17
   guard: 0x71bcd0 1 PC 0x4ecd20 in foo() trace-pc-guard-example.cc:2:14
 
+Inline 8bit-counters
+====================
+
+**Experimental, may change or disappear in future**
+
+With ``-fsanitize-coverage=inline-8bit-counters`` the compiler will insert
+inline counter increments on every edge.
+This is similar to ``-fsanitize-coverage=trace-pc-guard`` but instead of a
+callback the instrumentation simply increments a counter.
+
+Users need to implement a single function to capture the counters at startup.
+
+.. code-block:: c++
+
+  extern "C"
+  void __sanitizer_cov_8bit_counters_init(char *start, char *end) {
+    // [start,end) is the array of 8-bit counters created for the current DSO.
+    // Capture this array in order to read/modify the counters.
+  }
+
+PC-Table
+========
+
+**Experimental, may change or disappear in future**
+
+With ``-fsanitize-coverage=pc-table`` the compiler will create a table of
+instrumented PCs. Requires either ``-fsanitize-coverage=inline-8bit-counters`` or
+``-fsanitize-coverage=trace-pc-guard``.
+
+Users need to implement a single function to capture the PC table at startup:
+
+.. code-block:: c++
+
+  extern "C"
+  void __sanitizer_cov_pcs_init(const uintptr_t *pcs_beg,
+                                const uintptr_t *pcs_end) {
+    // [pcs_beg,pcs_end) is the array of ptr-sized integers representing
+    // pairs [PC,PCFlags] for every instrumented block in the current DSO.
+    // Capture this array in order to read the PCs and their Flags.
+    // The number of PCs and PCFlags for a given DSO is the same as the number
+    // of 8-bit counters (-fsanitize-coverage=inline-8bit-counters) or
+    // trace_pc_guard callbacks (-fsanitize-coverage=trace-pc-guard)
+    // A PCFlags describes the basic block:
+    //  * bit0: 1 if the block is the function entry block, 0 otherwise.
+  }
+
+
 Tracing PCs
 ===========
 
@@ -131,7 +178,6 @@ by the user.
 This mechanism is used for fuzzing the Linux kernel
 (https://github.com/google/syzkaller).
 
-
 Instrumentation points
 ======================
 Sanitizer Coverage offers different levels of instrumentation.
@@ -211,6 +257,14 @@ the `LLVM GEP instructions `_
   void __sanitizer_cov_trace_cmp4(uint32_t Arg1, uint32_t Arg2);
   void __sanitizer_cov_trace_cmp8(uint64_t Arg1, uint64_t Arg2);
 
+  // Called before a comparison instruction if exactly one of the arguments is constant.
+  // Arg1 and Arg2 are arguments of the comparison, Arg1 is a compile-time constant. 
+  // These callbacks are emitted by -fsanitize-coverage=trace-cmp since 2017-08-11
+  void __sanitizer_cov_trace_const_cmp1(uint8_t Arg1, uint8_t Arg2);
+  void __sanitizer_cov_trace_const_cmp2(uint16_t Arg1, uint16_t Arg2);
+  void __sanitizer_cov_trace_const_cmp4(uint32_t Arg1, uint32_t Arg2);
+  void __sanitizer_cov_trace_const_cmp8(uint64_t Arg1, uint64_t Arg2);
+
   // Called before a switch statement.
   // Val is the switch operand.
   // Cases[0] is the number of case constants.
@@ -227,9 +281,6 @@ the `LLVM GEP instructions `_
   // for every non-constant array index.
   void __sanitizer_cov_trace_gep(uintptr_t Idx);
 
-
-This interface is a subject to change.
-
 Default implementation
 ======================
 
diff --git a/docs/SanitizerSpecialCaseList.rst b/docs/SanitizerSpecialCaseList.rst
index a4165b2..a636a02 100644
--- a/docs/SanitizerSpecialCaseList.rst
+++ b/docs/SanitizerSpecialCaseList.rst
@@ -51,14 +51,23 @@ Example
 Format
 ======
 
-Each line contains an entity type, followed by a colon and a regular
-expression, specifying the names of the entities, optionally followed by
-an equals sign and a tool-specific category. Empty lines and lines starting
-with "#" are ignored. The meanining of ``*`` in regular expression for entity
-names is different - it is treated as in shell wildcarding. Two generic
-entity types are ``src`` and ``fun``, which allow user to add, respectively,
-source files and functions to special case list. Some sanitizer tools may
-introduce custom entity types - refer to tool-specific docs.
+Blacklists consist of entries, optionally grouped into sections. Empty lines and
+lines starting with "#" are ignored.
+
+Section names are regular expressions written in square brackets that denote
+which sanitizer the following entries apply to. For example, ``[address]``
+specifies AddressSanitizer while ``[cfi-vcall|cfi-icall]`` specifies Control
+Flow Integrity virtual and indirect call checking. Entries without a section
+will be placed under the ``[*]`` section applying to all enabled sanitizers.
+
+Entries contain an entity type, followed by a colon and a regular expression,
+specifying the names of the entities, optionally followed by an equals sign and
+a tool-specific category, e.g. ``fun:*ExampleFunc=example_category``.  The
+meaning of ``*`` in regular expression for entity names is different - it is
+treated as in shell wildcarding. Two generic entity types are ``src`` and
+``fun``, which allow users to specify source files and functions, respectively.
+Some sanitizer tools may introduce custom entity types and categories - refer to
+tool-specific docs.
 
 .. code-block:: bash
 
@@ -77,3 +86,10 @@ introduce custom entity types - refer to tool-specific docs.
     fun:*BadFunction*
     # Specific sanitizer tools may introduce categories.
     src:/special/path/*=special_sources
+    # Sections can be used to limit blacklist entries to specific sanitizers
+    [address]
+    fun:*BadASanFunc*
+    # Section names are regular expressions
+    [cfi-vcall|cfi-icall]
+    fun:*BadCfiCall
+    # Entries without sections are placed into [*] and apply to all sanitizers
diff --git a/docs/ThinLTO.rst b/docs/ThinLTO.rst
index 31fff51..14c098b 100644
--- a/docs/ThinLTO.rst
+++ b/docs/ThinLTO.rst
@@ -63,7 +63,7 @@ ThinLTO is currently supported for the following linkers:
 - **ld64**:
   Starting with `Xcode 8 `_.
 - **lld**:
-  Starting with r284050 (ELF only).
+  Starting with r284050 for ELF, r298942 for COFF.
 
 Usage
 =====
@@ -78,6 +78,13 @@ To utilize ThinLTO, simply add the -flto=thin option to compile and link. E.g.
   % clang -flto=thin -O2 file1.c file2.c -c
   % clang -flto=thin -O2 file1.o file2.o -o a.out
 
+When using lld-link, the -flto option need only be added to the compile step:
+
+.. code-block:: console
+
+  % clang-cl -flto=thin -O2 -c file1.c file2.c
+  % lld-link /out:a.exe file1.obj file2.obj
+
 As mentioned earlier, by default the linkers will launch the ThinLTO backend
 threads in parallel, passing the resulting native object files back to the
 linker for the final native link.  As such, the usage model the same as
@@ -111,6 +118,8 @@ be reduced to ``N`` via:
   ``-Wl,-mllvm,-threads=N``
 - lld:
   ``-Wl,--thinlto-jobs=N``
+- lld-link:
+  ``/opt:lldltojobs=N``
 
 Incremental
 -----------
@@ -119,23 +128,29 @@ Incremental
 ThinLTO supports fast incremental builds through the use of a cache,
 which currently must be enabled through a linker option.
 
-- gold (as of LLVM r279883):
+- gold (as of LLVM 4.0):
   ``-Wl,-plugin-opt,cache-dir=/path/to/cache``
 - ld64 (support in clang 3.9 and Xcode 8):
   ``-Wl,-cache_path_lto,/path/to/cache``
-- lld (as of LLVM r296702):
+- ELF lld (as of LLVM 5.0):
   ``-Wl,--thinlto-cache-dir=/path/to/cache``
+- COFF lld-link (as of LLVM 6.0):
+  ``/lldltocache:/path/to/cache``
 
 Cache Pruning
 -------------
 
 To help keep the size of the cache under control, ThinLTO supports cache
-pruning. Cache pruning is supported with ld64 and ELF lld, but currently only
-ELF lld allows you to control the policy with a policy string.  The cache
-policy must be specified with a linker option.
+pruning. Cache pruning is supported with gold, ld64 and ELF and COFF lld, but
+currently only gold, ELF and COFF lld allow you to control the policy with a
+policy string. The cache policy must be specified with a linker option.
 
-- ELF lld (as of LLVM r298036):
+- gold (as of LLVM 6.0):
+  ``-Wl,-plugin-opt,cache-policy=POLICY``
+- ELF lld (as of LLVM 5.0):
   ``-Wl,--thinlto-cache-policy,POLICY``
+- COFF lld-link (as of LLVM 6.0):
+  ``/lldltocachepolicy:POLICY``
 
 A policy string is a series of key-value pairs separated by ``:`` characters.
 Possible key-value pairs are:
@@ -158,6 +173,10 @@ Possible key-value pairs are:
   ``cache_size_bytes=1g`` on its own will cause both the 1GB and default 75%
   policies to be applied unless the default ``cache_size`` is overridden.
 
+- ``cache_size_files=X``:
+  Set the maximum number of files in the cache directory. Set to 0 to indicate
+  no limit. The default is 1000000 files.
+
 - ``prune_after=Xs``, ``prune_after=Xm``, ``prune_after=Xh``: Sets the
   expiration time for cache files to ``X`` seconds (or minutes, hours
   respectively).  When a file hasn't been accessed for ``prune_after`` seconds,
@@ -183,13 +202,20 @@ To bootstrap clang/LLVM with ThinLTO, follow these steps:
    when configuring the bootstrap compiler build:
 
   * ``-DLLVM_ENABLE_LTO=Thin``
-  * ``-DLLVM_PARALLEL_LINK_JOBS=1``
-    (since the ThinLTO link invokes parallel backend jobs)
   * ``-DCMAKE_C_COMPILER=/path/to/host/clang``
   * ``-DCMAKE_CXX_COMPILER=/path/to/host/clang++``
   * ``-DCMAKE_RANLIB=/path/to/host/llvm-ranlib``
   * ``-DCMAKE_AR=/path/to/host/llvm-ar``
 
+  Or, on Windows:
+
+  * ``-DLLVM_ENABLE_LTO=Thin``
+  * ``-DCMAKE_C_COMPILER=/path/to/host/clang-cl.exe``
+  * ``-DCMAKE_CXX_COMPILER=/path/to/host/clang-cl.exe``
+  * ``-DCMAKE_LINKER=/path/to/host/lld-link.exe``
+  * ``-DCMAKE_RANLIB=/path/to/host/llvm-ranlib.exe``
+  * ``-DCMAKE_AR=/path/to/host/llvm-ar.exe``
+
 #. To use additional linker arguments for controlling the backend
    parallelism_ or enabling incremental_ builds of the bootstrap compiler,
    after configuring the build, modify the resulting CMakeCache.txt file in the
diff --git a/docs/Toolchain.rst b/docs/Toolchain.rst
index 6ae8888..e727ccd 100644
--- a/docs/Toolchain.rst
+++ b/docs/Toolchain.rst
@@ -222,7 +222,7 @@ Unwind library
 
 The unwind library provides a family of ``_Unwind_*`` functions implementing
 the language-neutral stack unwinding portion of the Itanium C++ ABI
-(`Level I `_).
+(`Level I `_).
 It is a dependency of the C++ ABI library, and sometimes is a dependency
 of other runtimes.
 
@@ -288,9 +288,9 @@ C++ ABI library
 The C++ ABI library provides an implementation of the library portion of
 the Itanium C++ ABI, covering both the
 `support functionality in the main Itanium C++ ABI document
-`_ and
+`_ and
 `Level II of the exception handling support
-`_.
+`_.
 References to the functions and objects in this library are implicitly
 generated by Clang when compiling C++ code.
 
diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst
index 85dd549..0a08a41 100644
--- a/docs/UndefinedBehaviorSanitizer.rst
+++ b/docs/UndefinedBehaviorSanitizer.rst
@@ -75,6 +75,7 @@ Available checks are:
      of a misaligned reference.
   -  ``-fsanitize=bool``: Load of a ``bool`` value which is neither
      ``true`` nor ``false``.
+  -  ``-fsanitize=builtin``: Passing invalid values to compiler builtins.
   -  ``-fsanitize=bounds``: Out of bounds array indexing, in cases
      where the array bound can be statically determined.
   -  ``-fsanitize=enum``: Load of a value of an enumerated type which
@@ -86,7 +87,8 @@ Available checks are:
   -  ``-fsanitize=float-divide-by-zero``: Floating point division by
      zero.
   -  ``-fsanitize=function``: Indirect call of a function through a
-     function pointer of the wrong type (Linux, C++ and x86/x86_64 only).
+     function pointer of the wrong type (Darwin/Linux, C++ and x86/x86_64
+     only).
   -  ``-fsanitize=integer-divide-by-zero``: Integer division by zero.
   -  ``-fsanitize=nonnull-attribute``: Passing null pointer as a function
      parameter which is declared to never be null.
@@ -130,11 +132,11 @@ Available checks are:
      it is often unintentional, so UBSan offers to catch it.
   -  ``-fsanitize=vla-bound``: A variable-length array whose bound
      does not evaluate to a positive value.
-  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that
-     it is of the wrong dynamic type, or that its lifetime has not
-     begun or has ended. Incompatible with ``-fno-rtti``. Link must
-     be performed by ``clang++``, not ``clang``, to make sure C++-specific
-     parts of the runtime library and C++ standard libraries are present.
+  -  ``-fsanitize=vptr``: Use of an object whose vptr indicates that it is of
+     the wrong dynamic type, or that its lifetime has not begun or has ended.
+     Incompatible with ``-fno-rtti``. Link must be performed by ``clang++``, not
+     ``clang``, to make sure C++-specific parts of the runtime library and C++
+     standard libraries are present.
 
 You can also use the following check groups:
   -  ``-fsanitize=undefined``: All of the checks listed above other than
@@ -154,6 +156,19 @@ Volatile
 The ``null``, ``alignment``, ``object-size``, and ``vptr`` checks do not apply
 to pointers to types with the ``volatile`` qualifier.
 
+Minimal Runtime
+===============
+
+There is a minimal UBSan runtime available suitable for use in production
+environments. This runtime has a small attack surface. It only provides very
+basic issue logging and deduplication, and does not support ``-fsanitize=vptr``
+checking.
+
+To use the minimal runtime, add ``-fsanitize-minimal-runtime`` to the clang
+command line options. For example, if you're used to compiling with
+``-fsanitize=undefined``, you could enable the minimal runtime with
+``-fsanitize=undefined -fsanitize-minimal-runtime``.
+
 Stack traces and report symbolization
 =====================================
 If you want UBSan to print symbolized stack trace for each error report, you
diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst
index e5f33fc..023f9f5 100644
--- a/docs/UsersManual.rst
+++ b/docs/UsersManual.rst
@@ -107,7 +107,7 @@ Options to Control Error and Warning Messages
 
 .. option:: -Wno-error=foo
 
-  Turn warning "foo" into an warning even if :option:`-Werror` is specified.
+  Turn warning "foo" into a warning even if :option:`-Werror` is specified.
 
 .. option:: -Wfoo
 
@@ -677,7 +677,7 @@ Current limitations
 
 Other Options
 -------------
-Clang options that that don't fit neatly into other categories.
+Clang options that don't fit neatly into other categories.
 
 .. option:: -MV
 
@@ -1147,6 +1147,11 @@ are listed below.
    the behavior of sanitizers in the ``cfi`` group to allow checking
    of cross-DSO virtual and indirect calls.
 
+.. option:: -fsanitize-cfi-icall-generalize-pointers
+
+   Generalize pointers in return and argument types in function type signatures
+   checked by Control Flow Integrity indirect call checking. See
+   :doc:`ControlFlowIntegrity` for more details.
 
 .. option:: -fstrict-vtable-pointers
 
@@ -1438,7 +1443,7 @@ Sample Profile Text Format
 
 This section describes the ASCII text format for sampling profiles. It is,
 arguably, the easiest one to generate. If you are interested in generating any
-of the other two, consult the ``ProfileData`` library in in LLVM's source tree
+of the other two, consult the ``ProfileData`` library in LLVM's source tree
 (specifically, ``include/llvm/ProfileData/SampleProfReader.h``).
 
 .. code-block:: console
@@ -1454,7 +1459,7 @@ of the other two, consult the ``ProfileData`` library in in LLVM's source tree
       offsetB[.discriminator]: fnB:num_of_total_samples
        offsetB1[.discriminator]: number_of_samples [fn11:num fn12:num ... ]
 
-This is a nested tree in which the identation represents the nesting level
+This is a nested tree in which the indentation represents the nesting level
 of the inline stack. There are no blank lines in the file. And the spacing
 within a single line is fixed. Additional spaces will result in an error
 while reading the file.
diff --git a/docs/analyzer/DebugChecks.rst b/docs/analyzer/DebugChecks.rst
index 880dcfc..67521b8 100644
--- a/docs/analyzer/DebugChecks.rst
+++ b/docs/analyzer/DebugChecks.rst
@@ -74,7 +74,7 @@ inspects expressions.)
 ExprInspection checks
 ---------------------
 
-- void clang_analyzer_eval(bool);
+- ``void clang_analyzer_eval(bool);``
 
   Prints TRUE if the argument is known to have a non-zero value, FALSE if the
   argument is known to have a zero or null value, and UNKNOWN if the argument
@@ -93,7 +93,7 @@ ExprInspection checks
     clang_analyzer_eval(x); // expected-warning{{TRUE}}
 
 
-- void clang_analyzer_checkInlined(bool);
+- ``void clang_analyzer_checkInlined(bool);``
 
   If a call occurs within an inlined function, prints TRUE or FALSE according to
   the value of its argument. If a call occurs outside an inlined function,
@@ -125,7 +125,7 @@ ExprInspection checks
       clang_analyzer_eval(value == 42); // expected-warning{{TRUE}}
     }
 
-- void clang_analyzer_warnIfReached();
+- ``void clang_analyzer_warnIfReached();``
 
   Generate a warning if this line of code gets reached by the analyzer.
 
@@ -138,7 +138,7 @@ ExprInspection checks
       clang_analyzer_warnIfReached();  // no-warning
     }
 
-- void clang_analyzer_numTimesReached();
+- ``void clang_analyzer_numTimesReached();``
 
   Same as above, but include the number of times this call expression
   gets reached by the analyzer during the current analysis.
@@ -149,7 +149,7 @@ ExprInspection checks
       clang_analyzer_numTimesReached(); // expected-warning{{3}}
     }
 
-- void clang_analyzer_warnOnDeadSymbol(int);
+- ``void clang_analyzer_warnOnDeadSymbol(int);``
 
   Subscribe for a delayed warning when the symbol that represents the value of
   the argument is garbage-collected by the analyzer.
@@ -173,7 +173,7 @@ ExprInspection checks
     } while(0);  // expected-warning{{SYMBOL DEAD}}
 
 
-- void clang_analyzer_explain(a single argument of any type);
+- ``void clang_analyzer_explain(a single argument of any type);``
 
   This function explains the value of its argument in a human-readable manner
   in the warning message. You can make as many overrides of its prototype
@@ -197,7 +197,7 @@ ExprInspection checks
         clang_analyzer_explain(ptr); // expected-warning{{memory address '0'}}
     }
 
-- void clang_analyzer_dump(a single argument of any type);
+- ``void clang_analyzer_dump( /* a single argument of any type */);``
 
   Similar to clang_analyzer_explain, but produces a raw dump of the value,
   same as SVal::dump().
@@ -209,7 +209,7 @@ ExprInspection checks
       clang_analyzer_dump(x); // expected-warning{{reg_$0}}
     }
 
-- size_t clang_analyzer_getExtent(void *);
+- ``size_t clang_analyzer_getExtent(void *);``
 
   This function returns the value that represents the extent of a memory region
   pointed to by the argument. This value is often difficult to obtain otherwise,
@@ -226,7 +226,7 @@ ExprInspection checks
       clang_analyzer_explain(ys); // expected-warning{{'8'}}
     }
 
-- void clang_analyzer_printState();
+- ``void clang_analyzer_printState();``
 
   Dumps the current ProgramState to the stderr. Quickly lookup the program state
   at any execution point without ViewExplodedGraph or re-compiling the program.
@@ -242,6 +242,19 @@ ExprInspection checks
       clang_analyzer_printState(); // Read the stderr!
     }
 
+- ``void clang_analyzer_hashDump(int);``
+
+  The analyzer can generate a hash to identify reports. To debug what information
+  is used to calculate this hash it is possible to dump the hashed string as a
+  warning of an arbitrary expression using the function above.
+
+  Example usage::
+
+    void foo() {
+      int x = 1;
+      clang_analyzer_hashDump(x); // expected-warning{{hashed string for x}}
+    }
+
 Statistics
 ==========
 
diff --git a/docs/analyzer/DesignDiscussions/InitializerLists.rst b/docs/analyzer/DesignDiscussions/InitializerLists.rst
new file mode 100644
index 0000000..b826547
--- /dev/null
+++ b/docs/analyzer/DesignDiscussions/InitializerLists.rst
@@ -0,0 +1,321 @@
+This discussion took place in https://reviews.llvm.org/D35216
+"Escape symbols when creating std::initializer_list".
+
+It touches problems of modelling C++ standard library constructs in general,
+including modelling implementation-defined fields within C++ standard library
+objects, in particular constructing objects into pointers held by such fields,
+and separation of responsibilities between analyzer's core and checkers.
+
+**Artem:**
+
+I've seen a few false positives that appear because we construct
+C++11 std::initializer_list objects with brace initializers, and such
+construction is not properly modeled. For instance, if a new object is
+constructed on the heap only to be put into a brace-initialized STL container,
+the object is reported to be leaked.
+
+Approach (0): This can be trivially fixed by this patch, which causes pointers
+passed into initializer list expressions to immediately escape.
+
+This fix is overly conservative though. So i did a bit of investigation as to
+how model std::initializer_list better.
+
+According to the standard, std::initializer_list is an object that has
+methods begin(), end(), and size(), where begin() returns a pointer to continous
+array of size() objects of type T, and end() is equal to begin() plus size().
+The standard does hint that it should be possible to implement
+std::initializer_list as a pair of pointers, or as a pointer and a size
+integer, however specific fields that the object would contain are an
+implementation detail.
+
+Ideally, we should be able to model the initializer list's methods precisely.
+Or, at least, it should be possible to explain to the analyzer that the list
+somehow "takes hold" of the values put into it. Initializer lists can also be
+copied, which is a separate story that i'm not trying to address here.
+
+The obvious approach to modeling std::initializer_list in a checker would be to
+construct a SymbolMetadata for the memory region of the initializer list object,
+which would be of type T* and represent begin(), so we'd trivially model begin()
+as a function that returns this symbol. The array pointed to by that symbol
+would be bindLoc()ed to contain the list's contents (probably as a CompoundVal
+to produce less bindings in the store). Extent of this array would represent
+size() and would be equal to the length of the list as written.
+
+So this sounds good, however apparently it does nothing to address our false
+positives: when the list escapes, our RegionStoreManager is not magically
+guessing that the metadata symbol attached to it, together with its contents,
+should also escape. In fact, it's impossible to trigger a pointer escape from
+within the checker.
+
+Approach (1): If only we enabled ProgramState::bindLoc(..., notifyChanges=true)
+to cause pointer escapes (not only region changes) (which sounds like the right
+thing to do anyway) such checker would be able to solve the false positives by
+triggering escapes when binding list elements to the list. However, it'd be as
+conservative as the current patch's solution. Ideally, we do not want escapes to
+happen so early. Instead, we'd prefer them to be delayed until the list itself
+escapes.
+
+So i believe that escaping metadata symbols whenever their base regions escape
+would be the right thing to do. Currently we didn't think about that because we
+had neither pointer-type metadatas nor non-pointer escapes.
+
+Approach (2): We could teach the Store to scan itself for bindings to
+metadata-symbolic-based regions during scanReachableSymbols() whenever a region
+turns out to be reachable. This requires no work on checker side, but it sounds
+performance-heavy.
+
+Approach (3): We could let checkers maintain the set of active metadata symbols
+in the program state (ideally somewhere in the Store, which sounds weird but
+causes the smallest amount of layering violations), so that the core knew what
+to escape. This puts a stress on the checkers, but with a smart data map it
+wouldn't be a problem.
+
+Approach (4): We could allow checkers to trigger pointer escapes in arbitrary
+moments. If we allow doing this within checkPointerEscape callback itself, we
+would be able to express facts like "when this region escapes, that metadata
+symbol attached to it should also escape". This sounds like an ultimate freedom,
+with maximum stress on the checkers - still not too much stress when we have
+smart data maps.
+
+I'm personally liking the approach (2) - it should be possible to avoid
+performance overhead, and clarity seems nice.
+
+**Gabor:**
+
+At this point, I am a bit wondering about two questions.
+
+- When should something belong to a checker and when should something belong
+to the engine? Sometimes we model library aspects in the engine and model
+language constructs in checkers.
+- What is the checker programming model that we are aiming for? Maximum
+freedom or more easy checker development?
+
+I think if we aim for maximum freedom, we do not need to worry about the
+potential stress on checkers, and we can introduce abstractions to mitigate that
+later on.
+If we want to simplify the API, then maybe it makes more sense to move language
+construct modeling to the engine when the checker API is not sufficient instead
+of complicating the API.
+
+Right now I have no preference or objections between the alternatives but there
+are some random thoughts:
+
+- Maybe it would be great to have a guideline how to evolve the analyzer and
+follow it, so it can help us to decide in similar situations
+- I do care about performance in this case. The reason is that we have a
+limited performance budget. And I think we should not expect most of the checker
+writers to add modeling of language constructs. So, in my opinion, it is ok to
+have less nice/more verbose API for language modeling if we can have better
+performance this way, since it only needs to be done once, and is done by the
+framework developers.
+
+**Artem:** These are some great questions, i guess it'd be better to discuss
+them more openly. As a quick dump of my current mood:
+
+- To me it seems obvious that we need to aim for a checker API that is both
+simple and powerful. This can probably by keeping the API as powerful as
+necessary while providing a layer of simple ready-made solutions on top of it.
+Probably a few reusable components for assembling checkers. And this layer
+should ideally be pleasant enough to work with, so that people would prefer to
+extend it when something is lacking, instead of falling back to the complex
+omnipotent API. I'm thinking of AST matchers vs. AST visitors as a roughly
+similar situation: matchers are not omnipotent, but they're so nice.
+
+- Separation between core and checkers is usually quite strange. Once we have
+shared state traits, i generally wouldn't mind having region store or range
+constraint manager as checkers (though it's probably not worth it to transform
+them - just a mood). The main thing to avoid here would be the situation when
+the checker overwrites stuff written by the core because it thinks it has a
+better idea what's going on, so the core should provide a good default behavior.
+
+- Yeah, i totally care about performance as well, and if i try to implement
+approach, i'd make sure it's good.
+
+**Artem:**
+
+> Approach (2): We could teach the Store to scan itself for bindings to
+> metadata-symbolic-based regions during scanReachableSymbols() whenever
+> a region turns out to be reachable. This requires no work on checker side,
+> but it sounds performance-heavy.
+
+Nope, this approach is wrong. Metadata symbols may become out-of-date: when the
+object changes, metadata symbols attached to it aren't changing (because symbols
+simply don't change). The same metadata may have different symbols to denote its
+value in different moments of time, but at most one of them represents the
+actual metadata value. So we'd be escaping more stuff than necessary.
+
+If only we had "ghost fields"
+(http://lists.llvm.org/pipermail/cfe-dev/2016-May/049000.html), it would have
+been much easier, because the ghost field would only contain the actual
+metadata, and the Store would always know about it. This example adds to my
+belief that ghost fields are exactly what we need for most C++ checkers.
+
+**Devin:**
+
+In this case, I would be fine with some sort of
+AbstractStorageMemoryRegion that meant "here is a memory region and somewhere
+reachable from here exists another region of type T". Or even multiple regions
+with different identifiers. This wouldn't specify how the memory is reachable,
+but it would allow for transfer functions to get at those regions and it would
+allow for invalidation.
+
+For std::initializer_list this reachable region would the region for the backing
+array and the transfer functions for begin() and end() yield the beginning and
+end element regions for it.
+
+In my view this differs from ghost variables in that (1) this storage does
+actually exist (it is just a library implementation detail where that storage
+lives) and (2) it is perfectly valid for a pointer into that storage to be
+returned and for another part of the program to read or write from that storage.
+(Well, in this case just read since it is allowed to be read-only memory).
+
+What I'm not OK with is modeling abstract analysis state (for example, the count
+of a NSMutableArray or the typestate of a file handle) as a value stored in some
+ginned up region in the store. This takes an easy problem that the analyzer does
+well at (modeling typestate) and turns it into a hard one that the analyzer is
+bad at (reasoning about the contents of the heap).
+
+I think the key criterion here is: "is the region accessible from outside the
+library". That is, does the library expose the region as a pointer that can be
+read to or written from in the client program? If so, then it makes sense for
+this to be in the store: we are modeling reachable storage as storage. But if
+we're just modeling arbitrary analysis facts that need to be invalidated when a
+pointer escapes then we shouldn't try to gin up storage for them just to get
+invalidation for free.
+
+**Artem:**
+
+> In this case, I would be fine with some sort of AbstractStorageMemoryRegion
+> that meant "here is a memory region and somewhere reachable from here exists
+> another region of type T". Or even multiple regions with different
+> identifiers. This wouldn't specify how the memory is reachable, but it would
+> allow for transfer functions to get at those regions and it would allow for
+> invalidation.
+
+Yeah, this is what we can easily implement now as a
+symbolic-region-based-on-a-metadata-symbol (though we can make a new region
+class for that if we eg. want it typed). The problem is that the relation
+between such storage region and its parent object region is essentially
+immaterial, similarly to the relation between SymbolRegionValue and its parent
+region. Region contents are mutable: today the abstract storage is reachable
+from its parent object, tomorrow it's not, and maybe something else becomes
+reachable, something that isn't even abstract. So the parent region for the
+abstract storage is most of the time at best a "nice to know" thing - we cannot
+rely on it to do any actual work. We'd anyway need to rely on the checker to do
+the job.
+
+> For std::initializer_list this reachable region would the region for the
+> backing array and the transfer functions for begin() and end() yield the
+> beginning and end element regions for it.
+
+So maybe in fact for std::initializer_list it may work fine because you cannot
+change the data after the object is constructed - so this region's contents are
+essentially immutable. For the future, i feel as if it is a dead end.
+
+I'd like to consider another funny example. Suppose we're trying to model
+std::unique_ptr. Consider::
+
+  void bar(const std::unique_ptr &x);
+
+  void foo(std::unique_ptr &x) {
+    int *a = x.get();   // (a, 0, direct): &AbstractStorageRegion
+    *a = 1;             // (AbstractStorageRegion, 0, direct): 1 S32b
+    int *b = new int;
+    *b = 2;             // (SymRegion{conj_$0}, 0 ,direct): 2 S32b
+    x.reset(b);         // Checker map: x -> SymRegion{conj_$0}
+    bar(x);             // 'a' doesn't escape (the pointer was unique), 'b' does.
+    clang_analyzer_eval(*a == 1); // Making this true is up to the checker.
+    clang_analyzer_eval(*b == 2); // Making this unknown is up to the checker.
+  }
+
+The checker doesn't totally need to ensure that *a == 1 passes - even though the
+pointer was unique, it could theoretically have .get()-ed above and the code
+could of course break the uniqueness invariant (though we'd probably want it).
+The checker can say that "even if *a did escape, it was not because it was
+stuffed directly into bar()".
+
+The checker's direct responsibility, however, is to solve the *b == 2 thing
+(which is in fact the problem we're dealing with in this patch - escaping the
+storage region of the object).
+
+So we're talking about one more operation over the program state (scanning
+reachable symbols and regions) that cannot work without checker support.
+
+We can probably add a new callback "checkReachableSymbols" to solve this. This
+is in fact also related to the dead symbols problem (we're scanning for live
+symbols in the store and in the checkers separately, but we need to do so
+simultaneously with a single worklist). Hmm, in fact this sounds like a good
+idea; we can replace checkLiveSymbols with checkReachableSymbols.
+
+Or we could just have ghost member variables, and no checker support required at
+all. For ghost member variables, the relation with their parent region (which
+would be their superregion) is actually useful, the mutability of their contents
+is expressed naturally, and the store automagically sees reachable symbols, live
+symbols, escapes, invalidations, whatever.
+
+> In my view this differs from ghost variables in that (1) this storage does
+> actually exist (it is just a library implementation detail where that storage
+> lives) and (2) it is perfectly valid for a pointer into that storage to be
+> returned and for another part of the program to read or write from that
+> storage. (Well, in this case just read since it is allowed to be read-only
+> memory).
+
+> What I'm not OK with is modeling abstract analysis state (for example, the
+> count of a NSMutableArray or the typestate of a file handle) as a value stored
+> in some ginned up region in the store.This takes an easy problem that the
+> analyzer does well at (modeling typestate) and turns it into a hard one that
+> the analyzer is bad at (reasoning about the contents of the heap).
+
+Yeah, i tend to agree on that. For simple typestates, this is probably an
+overkill, so let's definitely put aside the idea of "ghost symbolic regions"
+that i had earlier.
+
+But, to summarize a bit, in our current case, however, the typestate we're
+looking for is the contents of the heap. And when we try to model such
+typestates (complex in this specific manner, i.e. heap-like) in any checker, we
+have a choice between re-doing this modeling in every such checker (which is
+something analyzer is indeed good at, but at a price of making checkers heavy)
+or instead relying on the Store to do exactly what it's designed to do.
+
+> I think the key criterion here is: "is the region accessible from outside
+> the library". That is, does the library expose the region as a pointer that
+> can be read to or written from in the client program? If so, then it makes
+> sense for this to be in the store: we are modeling reachable storage as
+> storage. But if we're just modeling arbitrary analysis facts that need to be
+> invalidated when a pointer escapes then we shouldn't try to gin up storage
+> for them just to get invalidation for free.
+
+As a metaphor, i'd probably compare it to body farms - the difference between
+ghost member variables and metadata symbols seems to me like the difference
+between body farms and evalCall. Both are nice to have, and body farms are very
+pleasant to work with, even if not omnipotent. I think it's fine for a
+FunctionDecl's body in a body farm to have a local variable, even if such
+variable doesn't actually exist, even if it cannot be seen from outside the
+function call. I'm not seeing immediate practical difference between "it does
+actually exist" and "it doesn't actually exist, just a handy abstraction".
+Similarly, i think it's fine if we have a CXXRecordDecl with
+implementation-defined contents, and try to farm up a member variable as a handy
+abstraction (we don't even need to know its name or offset, only that it's there
+somewhere).
+
+**Artem:**
+
+We've discussed it in person with Devin, and he provided more points to think
+about:
+
+- If the initializer list consists of non-POD data, constructors of list's
+objects need to take the sub-region of the list's region as this-region In the
+current (v2) version of this patch, these objects are constructed elsewhere and
+then trivial-copied into the list's metadata pointer region, which may be
+incorrect. This is our overall problem with C++ constructors, which manifests in
+this case as well. Additionally, objects would need to be constructed in the
+analyzer's core, which would not be able to predict that it needs to take a
+checker-specific region as this-region, which makes it harder, though it might
+be mitigated by sharing the checker state traits.
+
+- Because "ghost variables" are not material to the user, we need to somehow
+make super sure that they don't make it into the diagnostic messages.
+
+So, because this needs further digging into overall C++ support and rises too
+many questions, i'm delaying a better approach to this problem and will fall
+back to the original trivial patch.
diff --git a/docs/analyzer/conf.py b/docs/analyzer/conf.py
index c40af7a..0996759 100644
--- a/docs/analyzer/conf.py
+++ b/docs/analyzer/conf.py
@@ -49,9 +49,9 @@ copyright = u'2013-%d, Analyzer Team' % date.today().year
 # built documents.
 #
 # The short version.
-version = '5'
+version = '6'
 # The full version, including alpha/beta/rc tags.
-release = '5'
+release = '6'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/conf.py b/docs/conf.py
index a9861cd..a12f99a 100644
--- a/docs/conf.py
+++ b/docs/conf.py
@@ -49,9 +49,9 @@ copyright = u'2007-%d, The Clang Team' % date.today().year
 # built documents.
 #
 # The short version.
-version = '5'
+version = '6'
 # The full version, including alpha/beta/rc tags.
-release = '5'
+release = '6'
 
 # The language for content autogenerated by Sphinx. Refer to documentation
 # for a list of supported languages.
diff --git a/docs/index.rst b/docs/index.rst
index 0097ebb..342ab74 100644
--- a/docs/index.rst
+++ b/docs/index.rst
@@ -60,6 +60,7 @@ Using Clang as a Library
    LibASTMatchers
    HowToSetupToolingForLLVM
    JSONCompilationDatabase
+   RefactoringEngine
 
 Using Clang Tools
 =================
@@ -83,6 +84,7 @@ Design Documents
    PTHInternals
    PCHInternals
    ItaniumMangleAbiTags
+   HardwareAssistedAddressSanitizerDesign.rst
 
 
 Indices and tables
diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py
index e2571f4..1ca050e 100644
--- a/docs/tools/dump_format_style.py
+++ b/docs/tools/dump_format_style.py
@@ -177,7 +177,8 @@ def read_options(header):
   for option in options:
     if not option.type in ['bool', 'unsigned', 'int', 'std::string',
                            'std::vector',
-                           'std::vector']:
+                           'std::vector',
+                           'std::vector']:
       if enums.has_key(option.type):
         option.enum = enums[option.type]
       elif nested_structs.has_key(option.type):
diff --git a/examples/clang-interpreter/CMakeLists.txt b/examples/clang-interpreter/CMakeLists.txt
index e7e59d9..3084238 100644
--- a/examples/clang-interpreter/CMakeLists.txt
+++ b/examples/clang-interpreter/CMakeLists.txt
@@ -17,6 +17,7 @@ add_dependencies(clang-interpreter
   )
 
 target_link_libraries(clang-interpreter
+  PRIVATE
   clangBasic
   clangCodeGen
   clangDriver
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 3b5ea9f..587008a 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -32,7 +32,7 @@
  * compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
  */
 #define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 43
+#define CINDEX_VERSION_MINOR 45
 
 #define CINDEX_VERSION_ENCODE(major, minor) ( \
       ((major) * 10000)                       \
@@ -334,6 +334,16 @@ CINDEX_LINKAGE void clang_CXIndex_setGlobalOptions(CXIndex, unsigned options);
 CINDEX_LINKAGE unsigned clang_CXIndex_getGlobalOptions(CXIndex);
 
 /**
+ * \brief Sets the invocation emission path option in a CXIndex.
+ *
+ * The invocation emission path specifies a path which will contain log
+ * files for certain libclang invocations. A null value (default) implies that
+ * libclang invocations are not logged..
+ */
+CINDEX_LINKAGE void
+clang_CXIndex_setInvocationEmissionPathOption(CXIndex, const char *Path);
+
+/**
  * \defgroup CINDEX_FILES File manipulation routines
  *
  * @{
@@ -394,6 +404,21 @@ CINDEX_LINKAGE CXFile clang_getFile(CXTranslationUnit tu,
                                     const char *file_name);
 
 /**
+ * \brief Retrieve the buffer associated with the given file.
+ *
+ * \param tu the translation unit
+ *
+ * \param file the file for which to retrieve the buffer.
+ *
+ * \param size [out] if non-NULL, will be set to the size of the buffer.
+ *
+ * \returns a pointer to the buffer in memory that holds the contents of
+ * \p file, or a NULL pointer when the file is not loaded.
+ */
+CINDEX_LINKAGE const char *clang_getFileContents(CXTranslationUnit tu,
+                                                 CXFile file, size_t *size);
+
+/**
  * \brief Returns non-zero if the \c file1 and \c file2 point to the same file,
  * or they are both NULL.
  */
@@ -2837,6 +2862,22 @@ enum CXLanguageKind {
 CINDEX_LINKAGE enum CXLanguageKind clang_getCursorLanguage(CXCursor cursor);
 
 /**
+ * \brief Describe the "thread-local storage (TLS) kind" of the declaration
+ * referred to by a cursor.
+ */
+enum CXTLSKind {
+  CXTLS_None = 0,
+  CXTLS_Dynamic,
+  CXTLS_Static
+};
+
+/**
+ * \brief Determine the "thread-local storage (TLS) kind" of the declaration
+ * referred to by a cursor.
+ */
+CINDEX_LINKAGE enum CXTLSKind clang_getCursorTLSKind(CXCursor cursor);
+
+/**
  * \brief Returns the translation unit that a cursor originated from.
  */
 CINDEX_LINKAGE CXTranslationUnit clang_Cursor_getTranslationUnit(CXCursor);
@@ -3115,8 +3156,9 @@ enum CXTypeKind {
   CXType_ObjCSel = 29,
   CXType_Float128 = 30,
   CXType_Half = 31,
+  CXType_Float16 = 32,
   CXType_FirstBuiltin = CXType_Void,
-  CXType_LastBuiltin  = CXType_Half,
+  CXType_LastBuiltin  = CXType_Float16,
 
   CXType_Complex = 100,
   CXType_Pointer = 101,
@@ -4276,6 +4318,12 @@ CINDEX_LINKAGE CXString clang_Cursor_getMangling(CXCursor);
 CINDEX_LINKAGE CXStringSet *clang_Cursor_getCXXManglings(CXCursor);
 
 /**
+ * \brief Retrieve the CXStrings representing the mangled symbols of the ObjC
+ * class interface or implementation at the cursor.
+ */
+CINDEX_LINKAGE CXStringSet *clang_Cursor_getObjCManglings(CXCursor);
+
+/**
  * @}
  */
 
@@ -4419,6 +4467,12 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C);
 CINDEX_LINKAGE unsigned clang_CXXMethod_isVirtual(CXCursor C);
 
 /**
+ * \brief Determine if a C++ record is abstract, i.e. whether a class or struct
+ * has a pure virtual member function.
+ */
+CINDEX_LINKAGE unsigned clang_CXXRecord_isAbstract(CXCursor C);
+
+/**
  * \brief Determine if an enum declaration refers to a scoped enum.
  */
 CINDEX_LINKAGE unsigned clang_EnumDecl_isScoped(CXCursor C);
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 703f588..a5d0800 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1,4 +1,4 @@
-//===--- ASTContext.h - Context to hold long-lived AST nodes ----*- C++ -*-===//
+//===- ASTContext.h - Context to hold long-lived AST nodes ------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -6,10 +6,10 @@
 // License. See LICENSE.TXT for details.
 //
 //===----------------------------------------------------------------------===//
-///
+//
 /// \file
 /// \brief Defines the clang::ASTContext interface.
-///
+//
 //===----------------------------------------------------------------------===//
 
 #ifndef LLVM_CLANG_AST_ASTCONTEXT_H
@@ -19,8 +19,8 @@
 #include "clang/AST/CanonicalType.h"
 #include "clang/AST/CommentCommandTraits.h"
 #include "clang/AST/Decl.h"
-#include "clang/AST/DeclarationName.h"
 #include "clang/AST/DeclBase.h"
+#include "clang/AST/DeclarationName.h"
 #include "clang/AST/ExternalASTSource.h"
 #include "clang/AST/NestedNameSpecifier.h"
 #include "clang/AST/PrettyPrinter.h"
@@ -30,32 +30,32 @@
 #include "clang/AST/Type.h"
 #include "clang/Basic/AddressSpaces.h"
 #include "clang/Basic/IdentifierTable.h"
+#include "clang/Basic/LLVM.h"
 #include "clang/Basic/LangOptions.h"
 #include "clang/Basic/Linkage.h"
-#include "clang/Basic/LLVM.h"
-#include "clang/Basic/Module.h"
 #include "clang/Basic/OperatorKinds.h"
 #include "clang/Basic/PartialDiagnostic.h"
 #include "clang/Basic/SanitizerBlacklist.h"
 #include "clang/Basic/SourceLocation.h"
 #include "clang/Basic/Specifiers.h"
+#include "clang/Basic/TargetInfo.h"
 #include "clang/Basic/XRayLists.h"
 #include "llvm/ADT/APSInt.h"
 #include "llvm/ADT/ArrayRef.h"
 #include "llvm/ADT/DenseMap.h"
 #include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/IntrusiveRefCntPtr.h"
-#include "llvm/ADT/iterator_range.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/None.h"
 #include "llvm/ADT/Optional.h"
 #include "llvm/ADT/PointerIntPair.h"
 #include "llvm/ADT/PointerUnion.h"
-#include "llvm/ADT/SmallPtrSet.h"
 #include "llvm/ADT/SmallVector.h"
-#include "llvm/ADT/TinyPtrVector.h"
 #include "llvm/ADT/StringMap.h"
 #include "llvm/ADT/StringRef.h"
+#include "llvm/ADT/TinyPtrVector.h"
+#include "llvm/ADT/Triple.h"
+#include "llvm/ADT/iterator_range.h"
 #include "llvm/Support/AlignOf.h"
 #include "llvm/Support/Allocator.h"
 #include "llvm/Support/Casting.h"
@@ -65,7 +65,6 @@
 #include 
 #include 
 #include 
-#include 
 #include 
 #include 
 #include 
@@ -75,50 +74,72 @@ namespace llvm {
 
 struct fltSemantics;
 
-} // end namespace llvm
+} // namespace llvm
 
 namespace clang {
 
+class APValue;
 class ASTMutationListener;
 class ASTRecordLayout;
 class AtomicExpr;
 class BlockExpr;
+class BuiltinTemplateDecl;
 class CharUnits;
 class CXXABI;
+class CXXConstructorDecl;
+class CXXMethodDecl;
+class CXXRecordDecl;
 class DiagnosticsEngine;
 class Expr;
+class MangleContext;
 class MangleNumberingContext;
 class MaterializeTemporaryExpr;
-class TargetInfo;
-// Decls
-class MangleContext;
+class MemberSpecializationInfo;
+class Module;
+class ObjCCategoryDecl;
+class ObjCCategoryImplDecl;
+class ObjCContainerDecl;
+class ObjCImplDecl;
+class ObjCImplementationDecl;
+class ObjCInterfaceDecl;
 class ObjCIvarDecl;
+class ObjCMethodDecl;
 class ObjCPropertyDecl;
+class ObjCPropertyImplDecl;
+class ObjCProtocolDecl;
+class ObjCTypeParamDecl;
+class Preprocessor;
+class Stmt;
+class StoredDeclsMap;
+class TemplateDecl;
+class TemplateParameterList;
+class TemplateTemplateParmDecl;
+class TemplateTypeParmDecl;
 class UnresolvedSetIterator;
-class UsingDecl;
 class UsingShadowDecl;
+class VarTemplateDecl;
 class VTableContextBase;
 
 namespace Builtin {
 
-  class Context;
+class Context;
 
-} // end namespace Builtin
+} // namespace Builtin
 
 enum BuiltinTemplateKind : int;
 
 namespace comments {
 
-  class FullComment;
+class FullComment;
 
-} // end namespace comments
+} // namespace comments
 
 struct TypeInfo {
-  uint64_t Width;
-  unsigned Align;
+  uint64_t Width = 0;
+  unsigned Align = 0;
   bool AlignIsRequired : 1;
 
-  TypeInfo() : Width(0), Align(0), AlignIsRequired(false) {}
+  TypeInfo() : AlignIsRequired(false) {}
   TypeInfo(uint64_t Width, unsigned Align, bool AlignIsRequired)
       : Width(Width), Align(Align), AlignIsRequired(AlignIsRequired) {}
 };
@@ -126,7 +147,7 @@ struct TypeInfo {
 /// \brief Holds long-lived AST nodes (such as types and decls) that can be
 /// referred to throughout the semantic analysis of a file.
 class ASTContext : public RefCountedBase {
-  ASTContext &this_() { return *this; }
+  friend class NestedNameSpecifier;
 
   mutable SmallVector Types;
   mutable llvm::FoldingSet ExtQualNodes;
@@ -143,6 +164,8 @@ class ASTContext : public RefCountedBase {
   mutable llvm::FoldingSet DependentSizedArrayTypes;
   mutable llvm::FoldingSet
     DependentSizedExtVectorTypes;
+  mutable llvm::FoldingSet
+      DependentAddressSpaceTypes;
   mutable llvm::FoldingSet VectorTypes;
   mutable llvm::FoldingSet FunctionNoProtoTypes;
   mutable llvm::ContextualFoldingSet
@@ -187,8 +210,7 @@ class ASTContext : public RefCountedBase {
   ///
   /// This set is managed by the NestedNameSpecifier class.
   mutable llvm::FoldingSet NestedNameSpecifiers;
-  mutable NestedNameSpecifier *GlobalNestedNameSpecifier;
-  friend class NestedNameSpecifier;
+  mutable NestedNameSpecifier *GlobalNestedNameSpecifier = nullptr;
 
   /// \brief A cache mapping from RecordDecls to ASTRecordLayouts.
   ///
@@ -199,7 +221,7 @@ class ASTContext : public RefCountedBase {
     ObjCLayouts;
 
   /// \brief A cache from types to size and alignment information.
-  typedef llvm::DenseMap TypeInfoMap;
+  using TypeInfoMap = llvm::DenseMap;
   mutable TypeInfoMap MemoizedTypeInfo;
 
   /// \brief A cache mapping from CXXRecordDecls to key functions.
@@ -233,7 +255,7 @@ class ASTContext : public RefCountedBase {
 
   public:
     CanonicalTemplateTemplateParm(TemplateTemplateParmDecl *Parm)
-      : Parm(Parm) { }
+        : Parm(Parm) {}
 
     TemplateTemplateParmDecl *getParam() const { return Parm; }
 
@@ -249,32 +271,32 @@ class ASTContext : public RefCountedBase {
     getCanonicalTemplateTemplateParmDecl(TemplateTemplateParmDecl *TTP) const;
 
   /// \brief The typedef for the __int128_t type.
-  mutable TypedefDecl *Int128Decl;
+  mutable TypedefDecl *Int128Decl = nullptr;
 
   /// \brief The typedef for the __uint128_t type.
-  mutable TypedefDecl *UInt128Decl;
+  mutable TypedefDecl *UInt128Decl = nullptr;
 
   /// \brief The typedef for the target specific predefined
   /// __builtin_va_list type.
-  mutable TypedefDecl *BuiltinVaListDecl;
+  mutable TypedefDecl *BuiltinVaListDecl = nullptr;
 
   /// The typedef for the predefined \c __builtin_ms_va_list type.
-  mutable TypedefDecl *BuiltinMSVaListDecl;
+  mutable TypedefDecl *BuiltinMSVaListDecl = nullptr;
 
   /// \brief The typedef for the predefined \c id type.
-  mutable TypedefDecl *ObjCIdDecl;
+  mutable TypedefDecl *ObjCIdDecl = nullptr;
 
   /// \brief The typedef for the predefined \c SEL type.
-  mutable TypedefDecl *ObjCSelDecl;
+  mutable TypedefDecl *ObjCSelDecl = nullptr;
 
   /// \brief The typedef for the predefined \c Class type.
-  mutable TypedefDecl *ObjCClassDecl;
+  mutable TypedefDecl *ObjCClassDecl = nullptr;
 
   /// \brief The typedef for the predefined \c Protocol class in Objective-C.
-  mutable ObjCInterfaceDecl *ObjCProtocolClassDecl;
+  mutable ObjCInterfaceDecl *ObjCProtocolClassDecl = nullptr;
 
   /// \brief The typedef for the predefined 'BOOL' type.
-  mutable TypedefDecl *BOOLDecl;
+  mutable TypedefDecl *BOOLDecl = nullptr;
 
   // Typedefs which may be provided defining the structure of Objective-C
   // pseudo-builtins
@@ -298,42 +320,42 @@ class ASTContext : public RefCountedBase {
   mutable IdentifierInfo *TypePackElementName = nullptr;
 
   QualType ObjCConstantStringType;
-  mutable RecordDecl *CFConstantStringTagDecl;
-  mutable TypedefDecl *CFConstantStringTypeDecl;
+  mutable RecordDecl *CFConstantStringTagDecl = nullptr;
+  mutable TypedefDecl *CFConstantStringTypeDecl = nullptr;
 
   mutable QualType ObjCSuperType;
 
   QualType ObjCNSStringType;
 
   /// \brief The typedef declaration for the Objective-C "instancetype" type.
-  TypedefDecl *ObjCInstanceTypeDecl;
+  TypedefDecl *ObjCInstanceTypeDecl = nullptr;
 
   /// \brief The type for the C FILE type.
-  TypeDecl *FILEDecl;
+  TypeDecl *FILEDecl = nullptr;
 
   /// \brief The type for the C jmp_buf type.
-  TypeDecl *jmp_bufDecl;
+  TypeDecl *jmp_bufDecl = nullptr;
 
   /// \brief The type for the C sigjmp_buf type.
-  TypeDecl *sigjmp_bufDecl;
+  TypeDecl *sigjmp_bufDecl = nullptr;
 
   /// \brief The type for the C ucontext_t type.
-  TypeDecl *ucontext_tDecl;
+  TypeDecl *ucontext_tDecl = nullptr;
 
   /// \brief Type for the Block descriptor for Blocks CodeGen.
   ///
   /// Since this is only used for generation of debug info, it is not
   /// serialized.
-  mutable RecordDecl *BlockDescriptorType;
+  mutable RecordDecl *BlockDescriptorType = nullptr;
 
   /// \brief Type for the Block descriptor for Blocks CodeGen.
   ///
   /// Since this is only used for generation of debug info, it is not
   /// serialized.
-  mutable RecordDecl *BlockDescriptorExtendedType;
+  mutable RecordDecl *BlockDescriptorExtendedType = nullptr;
 
   /// \brief Declaration for the CUDA cudaConfigureCall function.
-  FunctionDecl *cudaConfigureCallDecl;
+  FunctionDecl *cudaConfigureCallDecl = nullptr;
 
   /// \brief Keeps track of all declaration attributes.
   ///
@@ -363,12 +385,19 @@ class ASTContext : public RefCountedBase {
   };
   llvm::DenseMap ModuleInitializers;
 
+  ASTContext &this_() { return *this; }
+
 public:
   /// \brief A type synonym for the TemplateOrInstantiation mapping.
-  typedef llvm::PointerUnion
-  TemplateOrSpecializationInfo;
+  using TemplateOrSpecializationInfo =
+      llvm::PointerUnion;
 
 private:
+  friend class ASTDeclReader;
+  friend class ASTReader;
+  friend class ASTWriter;
+  friend class CXXRecordDecl;
+
   /// \brief A mapping to contain the template or declaration that
   /// a variable declaration describes or was instantiated from,
   /// respectively.
@@ -438,7 +467,7 @@ private:
   /// Since most C++ member functions aren't virtual and therefore
   /// don't override anything, we store the overridden functions in
   /// this map on the side rather than within the CXXMethodDecl structure.
-  typedef llvm::TinyPtrVector CXXMethodVector;
+  using CXXMethodVector = llvm::TinyPtrVector;
   llvm::DenseMap OverriddenMethods;
 
   /// \brief Mapping from each declaration context to its corresponding
@@ -454,18 +483,18 @@ private:
 
   /// \brief Mapping that stores parameterIndex values for ParmVarDecls when
   /// that value exceeds the bitfield size of ParmVarDeclBits.ParameterIndex.
-  typedef llvm::DenseMap ParameterIndexTable;
+  using ParameterIndexTable = llvm::DenseMap;
   ParameterIndexTable ParamIndices;
 
-  ImportDecl *FirstLocalImport;
-  ImportDecl *LastLocalImport;
+  ImportDecl *FirstLocalImport = nullptr;
+  ImportDecl *LastLocalImport = nullptr;
 
   TranslationUnitDecl *TUDecl;
-  mutable ExternCContextDecl *ExternCContext;
-  mutable BuiltinTemplateDecl *MakeIntegerSeqDecl;
-  mutable BuiltinTemplateDecl *TypePackElementDecl;
+  mutable ExternCContextDecl *ExternCContext = nullptr;
+  mutable BuiltinTemplateDecl *MakeIntegerSeqDecl = nullptr;
+  mutable BuiltinTemplateDecl *TypePackElementDecl = nullptr;
 
-  /// \brief The associated SourceManager object.a
+  /// \brief The associated SourceManager object.
   SourceManager &SourceMgr;
 
   /// \brief The language options used to create the AST associated with
@@ -494,19 +523,14 @@ private:
   CXXABI *createCXXABI(const TargetInfo &T);
 
   /// \brief The logical -> physical address space map.
-  const LangAS::Map *AddrSpaceMap;
+  const LangASMap *AddrSpaceMap = nullptr;
 
   /// \brief Address space map mangling must be used with language specific
   /// address spaces (e.g. OpenCL/CUDA)
   bool AddrSpaceMapMangling;
 
-  friend class ASTDeclReader;
-  friend class ASTReader;
-  friend class ASTWriter;
-  friend class CXXRecordDecl;
-
-  const TargetInfo *Target;
-  const TargetInfo *AuxTarget;
+  const TargetInfo *Target = nullptr;
+  const TargetInfo *AuxTarget = nullptr;
   clang::PrintingPolicy PrintingPolicy;
 
 public:
@@ -515,31 +539,33 @@ public:
   Builtin::Context &BuiltinInfo;
   mutable DeclarationNameTable DeclarationNames;
   IntrusiveRefCntPtr ExternalSource;
-  ASTMutationListener *Listener;
+  ASTMutationListener *Listener = nullptr;
 
   /// \brief Contains parents of a node.
-  typedef llvm::SmallVector ParentVector;
+  using ParentVector = llvm::SmallVector;
 
   /// \brief Maps from a node to its parents. This is used for nodes that have
   /// pointer identity only, which are more common and we can save space by
   /// only storing a unique pointer to them.
-  typedef llvm::DenseMap> ParentMapPointers;
+  using ParentMapPointers =
+      llvm::DenseMap>;
 
   /// Parent map for nodes without pointer identity. We store a full
   /// DynTypedNode for all keys.
-  typedef llvm::DenseMap<
-      ast_type_traits::DynTypedNode,
-      llvm::PointerUnion4>
-      ParentMapOtherNodes;
+  using ParentMapOtherNodes =
+      llvm::DenseMap>;
 
   /// Container for either a single DynTypedNode or for an ArrayRef to
   /// DynTypedNode. For use with ParentMap.
   class DynTypedNodeList {
-    typedef ast_type_traits::DynTypedNode DynTypedNode;
+    using DynTypedNode = ast_type_traits::DynTypedNode;
+
     llvm::AlignedCharArrayUnion> Storage;
     bool IsSingleNode;
@@ -548,6 +574,7 @@ public:
     DynTypedNodeList(const DynTypedNode &N) : IsSingleNode(true) {
       new (Storage.buffer) DynTypedNode(N);
     }
+
     DynTypedNodeList(ArrayRef A) : IsSingleNode(false) {
       new (Storage.buffer) ArrayRef(A);
     }
@@ -626,13 +653,14 @@ public:
   template  T *Allocate(size_t Num = 1) const {
     return static_cast(Allocate(Num * sizeof(T), alignof(T)));
   }
-  void Deallocate(void *Ptr) const { }
+  void Deallocate(void *Ptr) const {}
 
   /// Return the total amount of physical memory allocated for representing
   /// AST nodes and type information.
   size_t getASTAllocatedMemory() const {
     return BumpAlloc.getTotalMemory();
   }
+
   /// Return the total memory used for various side tables.
   size_t getSideTableAllocatedMemory() const;
 
@@ -649,6 +677,7 @@ public:
   /// Returns empty type if there is no appropriate target types.
   QualType getIntTypeForBitwidth(unsigned DestWidth,
                                  unsigned Signed) const;
+
   /// getRealTypeForBitwidth -
   /// sets floating point QualTy according to specified bitwidth.
   /// Returns empty type if there is no appropriate target types.
@@ -676,7 +705,7 @@ public:
   RawCommentList Comments;
 
   /// \brief True if comments are already loaded from ExternalASTSource.
-  mutable bool CommentsLoaded;
+  mutable bool CommentsLoaded = false;
 
   class RawCommentAndCacheFlags {
   public:
@@ -759,24 +788,24 @@ public:
   }
 
   /// \brief Return the documentation comment attached to a given declaration.
-  /// Returns NULL if no comment is attached.
+  /// Returns nullptr if no comment is attached.
   ///
-  /// \param OriginalDecl if not NULL, is set to declaration AST node that had
-  /// the comment, if the comment we found comes from a redeclaration.
+  /// \param OriginalDecl if not nullptr, is set to declaration AST node that
+  /// had the comment, if the comment we found comes from a redeclaration.
   const RawComment *
   getRawCommentForAnyRedecl(const Decl *D,
                             const Decl **OriginalDecl = nullptr) const;
 
   /// Return parsed documentation comment attached to a given declaration.
-  /// Returns NULL if no comment is attached.
+  /// Returns nullptr if no comment is attached.
   ///
-  /// \param PP the Preprocessor used with this TU.  Could be NULL if
+  /// \param PP the Preprocessor used with this TU.  Could be nullptr if
   /// preprocessor is not available.
   comments::FullComment *getCommentForDecl(const Decl *D,
                                            const Preprocessor *PP) const;
 
   /// Return parsed documentation comment attached to a given declaration.
-  /// Returns NULL if no comment is attached. Does not look at any
+  /// Returns nullptr if no comment is attached. Does not look at any
   /// redeclarations of the declaration.
   comments::FullComment *getLocalCommentForDeclUncached(const Decl *D) const;
 
@@ -788,16 +817,16 @@ private:
 
   /// \brief Iterator that visits import declarations.
   class import_iterator {
-    ImportDecl *Import;
+    ImportDecl *Import = nullptr;
 
   public:
-    typedef ImportDecl               *value_type;
-    typedef ImportDecl               *reference;
-    typedef ImportDecl               *pointer;
-    typedef int                       difference_type;
-    typedef std::forward_iterator_tag iterator_category;
+    using value_type = ImportDecl *;
+    using reference = ImportDecl *;
+    using pointer = ImportDecl *;
+    using difference_type = int;
+    using iterator_category = std::forward_iterator_tag;
 
-    import_iterator() : Import() {}
+    import_iterator() = default;
     explicit import_iterator(ImportDecl *Import) : Import(Import) {}
 
     reference operator*() const { return Import; }
@@ -876,7 +905,7 @@ public:
   void setInstantiatedFromUnnamedFieldDecl(FieldDecl *Inst, FieldDecl *Tmpl);
 
   // Access to the set of methods overridden by the given C++ method.
-  typedef CXXMethodVector::const_iterator overridden_cxx_method_iterator;
+  using overridden_cxx_method_iterator = CXXMethodVector::const_iterator;
   overridden_cxx_method_iterator
   overridden_methods_begin(const CXXMethodDecl *Method) const;
 
@@ -884,8 +913,10 @@ public:
   overridden_methods_end(const CXXMethodDecl *Method) const;
 
   unsigned overridden_methods_size(const CXXMethodDecl *Method) const;
-  typedef llvm::iterator_range
-      overridden_method_range;
+
+  using overridden_method_range =
+      llvm::iterator_range;
+
   overridden_method_range overridden_methods(const CXXMethodDecl *Method) const;
 
   /// \brief Note that the given C++ \p Method overrides the given \p
@@ -912,7 +943,8 @@ public:
     return Import->NextLocalImport;
   }
 
-  typedef llvm::iterator_range import_range;
+  using import_range = llvm::iterator_range;
+
   import_range local_imports() const {
     return import_range(import_iterator(FirstLocalImport), import_iterator());
   }
@@ -929,6 +961,7 @@ public:
   /// and should be visible whenever \p M is visible.
   void mergeDefinitionIntoModule(NamedDecl *ND, Module *M,
                                  bool NotifyListeners = true);
+
   /// \brief Clean up the merged definition list. Call this if you might have
   /// added duplicates into the list.
   void deduplicateMergedDefinitonsFor(NamedDecl *ND);
@@ -973,6 +1006,7 @@ public:
   CanQualType UnsignedLongLongTy, UnsignedInt128Ty;
   CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty;
   CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON
+  CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3
   CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy;
   CanQualType Float128ComplexTy;
   CanQualType VoidPtrTy, NullPtrTy;
@@ -1067,7 +1101,14 @@ public:
   /// The resulting type has a union of the qualifiers from T and the address
   /// space. If T already has an address space specifier, it is silently
   /// replaced.
-  QualType getAddrSpaceQualType(QualType T, unsigned AddressSpace) const;
+  QualType getAddrSpaceQualType(QualType T, LangAS AddressSpace) const;
+
+  /// \brief Remove any existing address space on the type and returns the type
+  /// with qualifiers intact (or that's the idea anyway)
+  ///
+  /// The return type should be T with all prior qualifiers minus the address
+  /// space.
+  QualType removeAddrSpaceQualType(QualType T) const;
 
   /// \brief Apply Objective-C protocol qualifiers to the given type.
   /// \param allowOnPointerType specifies if we can apply protocol
@@ -1175,6 +1216,7 @@ public:
 
   /// \brief Return a read_only pipe type for the specified type.
   QualType getReadPipeType(QualType T) const;
+
   /// \brief Return a write_only pipe type for the specified type.
   QualType getWritePipeType(QualType T) const;
 
@@ -1182,9 +1224,16 @@ public:
   /// pointer to blocks.
   QualType getBlockDescriptorExtendedType() const;
 
+  /// Map an AST Type to an OpenCLTypeKind enum value.
+  TargetInfo::OpenCLTypeKind getOpenCLTypeKind(const Type *T) const;
+
+  /// Get address space for OpenCL type.
+  LangAS getOpenCLTypeAddrSpace(const Type *T) const;
+
   void setcudaConfigureCallDecl(FunctionDecl *FD) {
     cudaConfigureCallDecl = FD;
   }
+
   FunctionDecl *getcudaConfigureCallDecl() {
     return cudaConfigureCallDecl;
   }
@@ -1192,7 +1241,6 @@ public:
   /// Returns true iff we need copy/dispose helpers for the given type.
   bool BlockRequiresCopying(QualType Ty, const VarDecl *D);
 
-
   /// Returns true, if given type has a known lifetime. HasByrefExtendedLayout is set
   /// to false in this case. If HasByrefExtendedLayout returns true, byref variable
   /// has extended lifetime.
@@ -1269,6 +1317,10 @@ public:
                                           Expr *SizeExpr,
                                           SourceLocation AttrLoc) const;
 
+  QualType getDependentAddressSpaceType(QualType PointeeType,
+                                        Expr *AddrSpaceExpr,
+                                        SourceLocation AttrLoc) const;
+
   /// \brief Return a K&R style C function type like 'int()'.
   QualType getFunctionNoProtoType(QualType ResultTy,
                                   const FunctionType::ExtInfo &Info) const;
@@ -1396,6 +1448,7 @@ public:
                                 QualType Canonical = QualType()) const;
 
   bool ObjCObjectAdoptsQTypeProtocols(QualType QT, ObjCInterfaceDecl *Decl);
+
   /// QIdProtocolsAdoptObjCObjectProtocols - Checks that protocols in
   /// QT's qualified-id protocol list adopt all protocols in IDecl's list
   /// of protocols.
@@ -1426,7 +1479,7 @@ public:
   /// \brief C++11 deduction pattern for 'auto &&' type.
   QualType getAutoRRefDeductType() const;
 
-  /// \brief C++1z deduced class template specialization type.
+  /// \brief C++17 deduced class template specialization type.
   QualType getDeducedTemplateSpecializationType(TemplateName Template,
                                                 QualType DeducedType,
                                                 bool IsDependent) const;
@@ -1488,6 +1541,11 @@ public:
   /// . Pointer - pointer requires this (C99 6.5.6p9).
   QualType getPointerDiffType() const;
 
+  /// \brief Return the unique unsigned counterpart of "ptrdiff_t"
+  /// integer type. The standard (C11 7.21.6.1p7) refers to this type
+  /// in the definition of %tu format specifier.
+  QualType getUnsignedPointerDiffType() const;
+
   /// \brief Return the unique type for "pid_t" defined in
   /// . We need this to compute the correct type for vfork().
   QualType getProcessIDType() const;
@@ -1581,6 +1639,24 @@ public:
     return NSCopyingName;
   }
 
+  CanQualType getNSUIntegerType() const {
+    assert(Target && "Expected target to be initialized");
+    const llvm::Triple &T = Target->getTriple();
+    // Windows is LLP64 rather than LP64
+    if (T.isOSWindows() && T.isArch64Bit())
+      return UnsignedLongLongTy;
+    return UnsignedLongTy;
+  }
+
+  CanQualType getNSIntegerType() const {
+    assert(Target && "Expected target to be initialized");
+    const llvm::Triple &T = Target->getTriple();
+    // Windows is LLP64 rather than LP64
+    if (T.isOSWindows() && T.isArch64Bit())
+      return LongLongTy;
+    return LongTy;
+  }
+
   /// Retrieve the identifier 'bool'.
   IdentifierInfo *getBoolName() const {
     if (!BoolName)
@@ -1865,10 +1941,17 @@ public:
                                         const TemplateArgument &ArgPack) const;
 
   enum GetBuiltinTypeError {
-    GE_None,              ///< No error
-    GE_Missing_stdio,     ///< Missing a type from 
-    GE_Missing_setjmp,    ///< Missing a type from 
-    GE_Missing_ucontext   ///< Missing a type from 
+    /// No error
+    GE_None,
+
+    /// Missing a type from 
+    GE_Missing_stdio,
+
+    /// Missing a type from 
+    GE_Missing_setjmp,
+
+    /// Missing a type from 
+    GE_Missing_ucontext
   };
 
   /// \brief Return the type for the specified builtin.
@@ -2019,7 +2102,7 @@ public:
   getASTObjCImplementationLayout(const ObjCImplementationDecl *D) const;
 
   /// \brief Get our current best idea for the key function of the
-  /// given record decl, or NULL if there isn't one.
+  /// given record decl, or nullptr if there isn't one.
   ///
   /// The key function is, according to the Itanium C++ ABI section 5.2.3:
   ///   ...the first non-pure virtual function that is not inline at the
@@ -2072,6 +2155,10 @@ public:
   void CollectInheritedProtocols(const Decl *CDecl,
                           llvm::SmallPtrSet &Protocols);
 
+  /// \brief Return true if the specified type has unique object representations
+  /// according to (C++17 [meta.unary.prop]p9)
+  bool hasUniqueObjectRepresentations(QualType Ty) const;
+
   //===--------------------------------------------------------------------===//
   //                            Type Operators
   //===--------------------------------------------------------------------===//
@@ -2103,7 +2190,6 @@ public:
   bool hasSameType(QualType T1, QualType T2) const {
     return getCanonicalType(T1) == getCanonicalType(T2);
   }
-
   bool hasSameType(const Type *T1, const Type *T2) const {
     return getCanonicalType(T1) == getCanonicalType(T2);
   }
@@ -2192,7 +2278,7 @@ public:
   getCanonicalNestedNameSpecifier(NestedNameSpecifier *NNS) const;
 
   /// \brief Retrieves the default calling convention for the current target.
-  CallingConv getDefaultCallingConvention(bool isVariadic,
+  CallingConv getDefaultCallingConvention(bool IsVariadic,
                                           bool IsCXXMethod) const;
 
   /// \brief Retrieves the "canonical" template name that refers to a
@@ -2326,14 +2412,14 @@ public:
     return getTargetAddressSpace(Q.getAddressSpace());
   }
 
-  unsigned getTargetAddressSpace(unsigned AS) const;
+  unsigned getTargetAddressSpace(LangAS AS) const;
 
   /// Get target-dependent integer value for null pointer which is used for
   /// constant folding.
   uint64_t getTargetNullPointerValue(QualType QT) const;
 
-  bool addressSpaceMapManglingFor(unsigned AS) const {
-    return AddrSpaceMapMangling || AS >= LangAS::FirstTargetAddressSpace;
+  bool addressSpaceMapManglingFor(LangAS AS) const {
+    return AddrSpaceMapMangling || isTargetAddressSpace(AS);
   }
 
 private:
@@ -2355,12 +2441,15 @@ public:
   bool isObjCIdType(QualType T) const {
     return T == getObjCIdType();
   }
+
   bool isObjCClassType(QualType T) const {
     return T == getObjCClassType();
   }
+
   bool isObjCSelType(QualType T) const {
     return T == getObjCSelType();
   }
+
   bool ObjCQualifiedIdTypesAreCompatible(QualType LHS, QualType RHS,
                                          bool ForCompare);
 
@@ -2394,9 +2483,30 @@ public:
 
   QualType mergeObjCGCQualifiers(QualType, QualType);
 
-  bool doFunctionTypesMatchOnExtParameterInfos(
-         const FunctionProtoType *FromFunctionType,
-         const FunctionProtoType *ToFunctionType);
+  /// This function merges the ExtParameterInfo lists of two functions. It
+  /// returns true if the lists are compatible. The merged list is returned in
+  /// NewParamInfos.
+  ///
+  /// \param FirstFnType The type of the first function.
+  ///
+  /// \param SecondFnType The type of the second function.
+  ///
+  /// \param CanUseFirst This flag is set to true if the first function's
+  /// ExtParameterInfo list can be used as the composite list of
+  /// ExtParameterInfo.
+  ///
+  /// \param CanUseSecond This flag is set to true if the second function's
+  /// ExtParameterInfo list can be used as the composite list of
+  /// ExtParameterInfo.
+  ///
+  /// \param NewParamInfos The composite list of ExtParameterInfo. The list is
+  /// empty if none of the flags are set.
+  ///
+  bool mergeExtParameterInfo(
+      const FunctionProtoType *FirstFnType,
+      const FunctionProtoType *SecondFnType,
+      bool &CanUseFirst, bool &CanUseSecond,
+      SmallVectorImpl &NewParamInfos);
 
   void ResetObjCLayout(const ObjCContainerDecl *CD);
 
@@ -2432,12 +2542,13 @@ public:
 
   bool isSentinelNullExpr(const Expr *E);
 
-  /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or NULL if
+  /// \brief Get the implementation of the ObjCInterfaceDecl \p D, or nullptr if
   /// none exists.
   ObjCImplementationDecl *getObjCImplementation(ObjCInterfaceDecl *D);
-  /// \brief Get the implementation of the ObjCCategoryDecl \p D, or NULL if
+
+  /// \brief Get the implementation of the ObjCCategoryDecl \p D, or nullptr if
   /// none exists.
-  ObjCCategoryImplDecl   *getObjCImplementation(ObjCCategoryDecl *D);
+  ObjCCategoryImplDecl *getObjCImplementation(ObjCCategoryDecl *D);
 
   /// \brief Return true if there is at least one \@implementation in the TU.
   bool AnyObjCImplementation() {
@@ -2447,6 +2558,7 @@ public:
   /// \brief Set the implementation of ObjCInterfaceDecl.
   void setObjCImplementation(ObjCInterfaceDecl *IFaceD,
                              ObjCImplementationDecl *ImplD);
+
   /// \brief Set the implementation of ObjCCategoryDecl.
   void setObjCImplementation(ObjCCategoryDecl *CatD,
                              ObjCCategoryImplDecl *ImplD);
@@ -2466,8 +2578,9 @@ public:
 
   /// \brief Set the copy inialization expression of a block var decl.
   void setBlockVarCopyInits(VarDecl*VD, Expr* Init);
+
   /// \brief Get the copy initialization expression of the VarDecl \p VD, or
-  /// NULL if none exists.
+  /// nullptr if none exists.
   Expr *getBlockVarCopyInits(const VarDecl* VD);
 
   /// \brief Allocate an uninitialized TypeSourceInfo.
@@ -2636,6 +2749,7 @@ private:
                                        const FieldDecl *Field,
                                        bool includeVBases = true,
                                        QualType *NotEncodedT=nullptr) const;
+
 public:
   // Adds the encoding of a method parameter or return type.
   void getObjCEncodingForMethodParameter(Decl::ObjCDeclQualifier QT,
@@ -2647,11 +2761,19 @@ public:
   bool isMSStaticDataMemberInlineDefinition(const VarDecl *VD) const;
 
   enum class InlineVariableDefinitionKind {
-    None,        ///< Not an inline variable.
-    Weak,        ///< Weak definition of inline variable.
-    WeakUnknown, ///< Weak for now, might become strong later in this TU.
-    Strong       ///< Strong definition.
+    /// Not an inline variable.
+    None,
+
+    /// Weak definition of inline variable.
+    Weak,
+
+    /// Weak for now, might become strong later in this TU.
+    WeakUnknown,
+
+    /// Strong definition.
+    Strong
   };
+
   /// \brief Determine whether a definition of this inline variable should
   /// be treated as a weak or strong definition. For compatibility with
   /// C++14 and before, for a constexpr static data member, if there is an
@@ -2661,6 +2783,9 @@ public:
   getInlineVariableDefinitionKind(const VarDecl *VD) const;
 
 private:
+  friend class DeclarationNameTable;
+  friend class DeclContext;
+
   const ASTRecordLayout &
   getObjCLayout(const ObjCInterfaceDecl *D,
                 const ObjCImplementationDecl *Impl) const;
@@ -2673,26 +2798,23 @@ private:
   // into the datastructures which avoids this mess during deallocation but is
   // wasteful of memory, and here we require a lot of error prone book keeping
   // in order to track and run destructors while we're tearing things down.
-  typedef llvm::SmallVector, 16>
-      DeallocationFunctionsAndArguments;
+  using DeallocationFunctionsAndArguments =
+      llvm::SmallVector, 16>;
   DeallocationFunctionsAndArguments Deallocations;
 
   // FIXME: This currently contains the set of StoredDeclMaps used
   // by DeclContext objects.  This probably should not be in ASTContext,
   // but we include it here so that ASTContext can quickly deallocate them.
-  llvm::PointerIntPair LastSDM;
-
-  friend class DeclContext;
-  friend class DeclarationNameTable;
-
-  void ReleaseDeclContextMaps();
-  void ReleaseParentMapEntries();
+  llvm::PointerIntPair LastSDM;
 
   std::unique_ptr PointerParents;
   std::unique_ptr OtherParents;
 
   std::unique_ptr VTContext;
 
+  void ReleaseDeclContextMaps();
+  void ReleaseParentMapEntries();
+
 public:
   enum PragmaSectionFlag : unsigned {
     PSF_None = 0,
@@ -2712,27 +2834,26 @@ public:
     SectionInfo(DeclaratorDecl *Decl,
                 SourceLocation PragmaSectionLocation,
                 int SectionFlags)
-      : Decl(Decl),
-        PragmaSectionLocation(PragmaSectionLocation),
-        SectionFlags(SectionFlags) {}
+        : Decl(Decl), PragmaSectionLocation(PragmaSectionLocation),
+          SectionFlags(SectionFlags) {}
   };
 
   llvm::StringMap SectionInfos;
 };
 
 /// \brief Utility function for constructing a nullary selector.
-static inline Selector GetNullarySelector(StringRef name, ASTContext& Ctx) {
+inline Selector GetNullarySelector(StringRef name, ASTContext &Ctx) {
   IdentifierInfo* II = &Ctx.Idents.get(name);
   return Ctx.Selectors.getSelector(0, &II);
 }
 
 /// \brief Utility function for constructing an unary selector.
-static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
+inline Selector GetUnarySelector(StringRef name, ASTContext &Ctx) {
   IdentifierInfo* II = &Ctx.Idents.get(name);
   return Ctx.Selectors.getSelector(1, &II);
 }
 
-}  // end namespace clang
+} // namespace clang
 
 // operator new and delete aren't allowed inside namespaces.
 
@@ -2763,11 +2884,12 @@ static inline Selector GetUnarySelector(StringRef name, ASTContext& Ctx) {
 /// @param C The ASTContext that provides the allocator.
 /// @param Alignment The alignment of the allocated memory (if the underlying
 ///                  allocator supports it).
-/// @return The allocated memory. Could be NULL.
+/// @return The allocated memory. Could be nullptr.
 inline void *operator new(size_t Bytes, const clang::ASTContext &C,
                           size_t Alignment) {
   return C.Allocate(Bytes, Alignment);
 }
+
 /// @brief Placement delete companion to the new above.
 ///
 /// This operator is just a companion to the new above. There is no way of
@@ -2800,7 +2922,7 @@ inline void operator delete(void *Ptr, const clang::ASTContext &C, size_t) {
 /// @param C The ASTContext that provides the allocator.
 /// @param Alignment The alignment of the allocated memory (if the underlying
 ///                  allocator supports it).
-/// @return The allocated memory. Could be NULL.
+/// @return The allocated memory. Could be nullptr.
 inline void *operator new[](size_t Bytes, const clang::ASTContext& C,
                             size_t Alignment = 8) {
   return C.Allocate(Bytes, Alignment);
diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h
index a8eff1a..9395d36 100644
--- a/include/clang/AST/ASTMutationListener.h
+++ b/include/clang/AST/ASTMutationListener.h
@@ -22,6 +22,7 @@ namespace clang {
   class CXXRecordDecl;
   class Decl;
   class DeclContext;
+  class Expr;
   class FieldDecl;
   class FunctionDecl;
   class FunctionTemplateDecl;
@@ -35,6 +36,7 @@ namespace clang {
   class QualType;
   class RecordDecl;
   class TagDecl;
+  class ValueDecl;
   class VarDecl;
   class VarTemplateDecl;
   class VarTemplateSpecializationDecl;
@@ -80,13 +82,19 @@ public:
 
   /// \brief A virtual destructor's operator delete has been resolved.
   virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
-                                      const FunctionDecl *Delete) {}
+                                      const FunctionDecl *Delete,
+                                      Expr *ThisArg) {}
 
   /// \brief An implicit member got a definition.
   virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
 
-  /// \brief A static data member was implicitly instantiated.
-  virtual void StaticDataMemberInstantiated(const VarDecl *D) {}
+  /// \brief The instantiation of a templated function or variable was
+  /// requested. In particular, the point of instantiation and template
+  /// specialization kind of \p D may have changed.
+  virtual void InstantiationRequested(const ValueDecl *D) {}
+
+  /// \brief A templated variable's definition was implicitly instantiated.
+  virtual void VariableDefinitionInstantiated(const VarDecl *D) {}
 
   /// \brief A function template's definition was instantiated.
   virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
diff --git a/include/clang/AST/ASTUnresolvedSet.h b/include/clang/AST/ASTUnresolvedSet.h
index 9078a0e..3693aec 100644
--- a/include/clang/AST/ASTUnresolvedSet.h
+++ b/include/clang/AST/ASTUnresolvedSet.h
@@ -1,4 +1,4 @@
-//===-- ASTUnresolvedSet.h - Unresolved sets of declarations  ---*- C++ -*-===//
+//===- ASTUnresolvedSet.h - Unresolved sets of declarations -----*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -16,14 +16,22 @@
 #define LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
 
 #include "clang/AST/ASTVector.h"
+#include "clang/AST/DeclAccessPair.h"
 #include "clang/AST/UnresolvedSet.h"
+#include "clang/Basic/Specifiers.h"
+#include 
+#include 
 
 namespace clang {
 
+class NamedDecl;
+
 /// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
 class ASTUnresolvedSet {
+  friend class LazyASTUnresolvedSet;
+
   struct DeclsTy : ASTVector {
-    DeclsTy() {}
+    DeclsTy() = default;
     DeclsTy(ASTContext &C, unsigned N) : ASTVector(C, N) {}
 
     bool isLazy() const { return getTag(); }
@@ -32,14 +40,12 @@ class ASTUnresolvedSet {
 
   DeclsTy Decls;
 
-  friend class LazyASTUnresolvedSet;
-
 public:
-  ASTUnresolvedSet() {}
+  ASTUnresolvedSet() = default;
   ASTUnresolvedSet(ASTContext &C, unsigned N) : Decls(C, N) {}
 
-  typedef UnresolvedSetIterator iterator;
-  typedef UnresolvedSetIterator const_iterator;
+  using iterator = UnresolvedSetIterator;
+  using const_iterator = UnresolvedSetIterator;
 
   iterator begin() { return iterator(Decls.begin()); }
   iterator end() { return iterator(Decls.end()); }
@@ -98,13 +104,14 @@ public:
   }
 
   void reserve(ASTContext &C, unsigned N) { Impl.reserve(C, N); }
+
   void addLazyDecl(ASTContext &C, uintptr_t ID, AccessSpecifier AS) {
     assert(Impl.empty() || Impl.Decls.isLazy());
     Impl.Decls.setLazy(true);
-    Impl.addDecl(C, reinterpret_cast(ID << 2), AS);
+    Impl.addDecl(C, reinterpret_cast(ID << 2), AS);
   }
 };
 
 } // namespace clang
 
-#endif
+#endif // LLVM_CLANG_AST_ASTUNRESOLVEDSET_H
diff --git a/include/clang/AST/ASTVector.h b/include/clang/AST/ASTVector.h
index 717a9e9..80cd6b7 100644
--- a/include/clang/AST/ASTVector.h
+++ b/include/clang/AST/ASTVector.h
@@ -1,4 +1,4 @@
-//===- ASTVector.h - Vector that uses ASTContext for allocation  --*- C++ -*-=//
+//===- ASTVector.h - Vector that uses ASTContext for allocation ---*- C++ -*-=//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -18,22 +18,26 @@
 #ifndef LLVM_CLANG_AST_ASTVECTOR_H
 #define LLVM_CLANG_AST_ASTVECTOR_H
 
-#include "clang/AST/AttrIterator.h"
 #include "llvm/ADT/PointerIntPair.h"
-#include "llvm/Support/type_traits.h"
 #include 
+#include 
 #include 
 #include 
+#include 
 #include 
+#include 
+#include 
 
 namespace clang {
-  class ASTContext;
+
+class ASTContext;
 
 template
 class ASTVector {
 private:
-  T *Begin, *End;
-  llvm::PointerIntPair Capacity;
+  T *Begin = nullptr;
+  T *End = nullptr;
+  llvm::PointerIntPair Capacity;
 
   void setEnd(T *P) { this->End = P; }
 
@@ -45,7 +49,7 @@ protected:
 
 public:
   // Default ctor - Initialize to empty.
-  ASTVector() : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {}
+  ASTVector() : Capacity(nullptr, false) {}
 
   ASTVector(ASTVector &&O) : Begin(O.Begin), End(O.End), Capacity(O.Capacity) {
     O.Begin = O.End = nullptr;
@@ -53,14 +57,15 @@ public:
     O.Capacity.setInt(false);
   }
 
-  ASTVector(const ASTContext &C, unsigned N)
-      : Begin(nullptr), End(nullptr), Capacity(nullptr, false) {
+  ASTVector(const ASTContext &C, unsigned N) : Capacity(nullptr, false) {
     reserve(C, N);
   }
 
   ASTVector &operator=(ASTVector &&RHS) {
     ASTVector O(std::move(RHS));
+
     using std::swap;
+
     swap(Begin, O.Begin);
     swap(End, O.End);
     swap(Capacity, O.Capacity);
@@ -74,19 +79,19 @@ public:
     }
   }
 
-  typedef size_t size_type;
-  typedef ptrdiff_t difference_type;
-  typedef T value_type;
-  typedef T* iterator;
-  typedef const T* const_iterator;
+  using size_type = size_t;
+  using difference_type = ptrdiff_t;
+  using value_type = T;
+  using iterator = T *;
+  using const_iterator = const T *;
 
-  typedef std::reverse_iterator  const_reverse_iterator;
-  typedef std::reverse_iterator  reverse_iterator;
+  using const_reverse_iterator = std::reverse_iterator;
+  using reverse_iterator = std::reverse_iterator;
 
-  typedef T& reference;
-  typedef const T& const_reference;
-  typedef T* pointer;
-  typedef const T* const_pointer;
+  using reference = T &;
+  using const_reference = const T &;
+  using pointer = T *;
+  using const_pointer = const T *;
 
   // forward iterator creation methods.
   iterator begin() { return Begin; }
@@ -175,7 +180,6 @@ public:
   size_t capacity() const { return this->capacity_ptr() - Begin; }
 
   /// append - Add the specified range to the end of the SmallVector.
-  ///
   template
   void append(const ASTContext &C, in_iter in_start, in_iter in_end) {
     size_type NumInputs = std::distance(in_start, in_end);
@@ -195,7 +199,6 @@ public:
   }
 
   /// append - Add the specified range to the end of the SmallVector.
-  ///
   void append(const ASTContext &C, size_type NumInputs, const T &Elt) {
     // Grow allocated space if needed.
     if (NumInputs > size_type(this->capacity_ptr()-this->end()))
@@ -368,6 +371,7 @@ protected:
   const_iterator capacity_ptr() const {
     return (iterator) Capacity.getPointer();
   }
+
   iterator capacity_ptr() { return (iterator)Capacity.getPointer(); }
 };
 
@@ -401,5 +405,6 @@ void ASTVector::grow(const ASTContext &C, size_t MinSize) {
   Capacity.setPointer(Begin+NewCapacity);
 }
 
-} // end: clang namespace
-#endif
+} // namespace clang
+
+#endif // LLVM_CLANG_AST_ASTVECTOR_H
diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h
index fb9b049..56807b4 100644
--- a/include/clang/AST/AttrIterator.h
+++ b/include/clang/AST/AttrIterator.h
@@ -1,4 +1,4 @@
-//===--- AttrIterator.h - Classes for attribute iteration -------*- C++ -*-===//
+//===- AttrIterator.h - Classes for attribute iteration ---------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -15,16 +15,23 @@
 #define LLVM_CLANG_AST_ATTRITERATOR_H
 
 #include "clang/Basic/LLVM.h"
+#include "llvm/ADT/SmallVector.h"
+#include "llvm/Support/Casting.h"
+#include 
+#include 
 #include 
 
 namespace clang {
-  class ASTContext;
-  class Attr;
-}
+
+class ASTContext;
+class Attr;
+
+} // namespace clang
 
 // Defined in ASTContext.h
 void *operator new(size_t Bytes, const clang::ASTContext &C,
                    size_t Alignment = 8);
+
 // FIXME: Being forced to not have a default argument here due to redeclaration
 //        rules on default arguments sucks
 void *operator new[](size_t Bytes, const clang::ASTContext &C,
@@ -39,13 +46,13 @@ void operator delete[](void *Ptr, const clang::ASTContext &C, size_t);
 namespace clang {
 
 /// AttrVec - A vector of Attr, which is how they are stored on the AST.
-typedef SmallVector AttrVec;
+using AttrVec = SmallVector;
 
 /// specific_attr_iterator - Iterates over a subrange of an AttrVec, only
 /// providing attributes that are of a specific type.
 template 
 class specific_attr_iterator {
-  typedef typename Container::const_iterator Iterator;
+  using Iterator = typename Container::const_iterator;
 
   /// Current - The current, underlying iterator.
   /// In order to ensure we don't dereference an invalid iterator unless
@@ -67,14 +74,14 @@ class specific_attr_iterator {
   }
 
 public:
-  typedef SpecificAttr*             value_type;
-  typedef SpecificAttr*             reference;
-  typedef SpecificAttr*             pointer;
-  typedef std::forward_iterator_tag iterator_category;
-  typedef std::ptrdiff_t            difference_type;
+  using value_type = SpecificAttr *;
+  using reference = SpecificAttr *;
+  using pointer = SpecificAttr *;
+  using iterator_category = std::forward_iterator_tag;
+  using difference_type = std::ptrdiff_t;
 
-  specific_attr_iterator() : Current() { }
-  explicit specific_attr_iterator(Iterator i) : Current(i) { }
+  specific_attr_iterator() = default;
+  explicit specific_attr_iterator(Iterator i) : Current(i) {}
 
   reference operator*() const {
     AdvanceToNext();
@@ -136,6 +143,6 @@ inline SpecificAttr *getSpecificAttr(const Container& container) {
     return nullptr;
 }
 
-}  // end namespace clang
+} // namespace clang
 
-#endif
+#endif // LLVM_CLANG_AST_ATTRITERATOR_H
diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h
index 66af023..fdb7e71 100644
--- a/include/clang/AST/BaseSubobject.h
+++ b/include/clang/AST/BaseSubobject.h
@@ -1,4 +1,4 @@
-//===--- BaseSubobject.h - BaseSubobject class ----------------------------===//
+//===- BaseSubobject.h - BaseSubobject class --------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -15,12 +15,15 @@
 #define LLVM_CLANG_AST_BASESUBOBJECT_H
 
 #include "clang/AST/CharUnits.h"
-#include "clang/AST/DeclCXX.h"
-#include "llvm/ADT/DenseMap.h"
-#include "llvm/Support/DataTypes.h"
+#include "llvm/ADT/DenseMapInfo.h"
 #include "llvm/Support/type_traits.h"
+#include 
+#include 
 
 namespace clang {
+
+class CXXRecordDecl;
+
 // BaseSubobject - Uniquely identifies a direct or indirect base class. 
 // Stores both the base class decl and the offset from the most derived class to
 // the base class. Used for vtable and VTT generation.
@@ -32,9 +35,9 @@ class BaseSubobject {
   CharUnits BaseOffset;
   
 public:
-  BaseSubobject() { }
+  BaseSubobject() = default;
   BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset)
-    : Base(Base), BaseOffset(BaseOffset) { }
+      : Base(Base), BaseOffset(BaseOffset) {}
   
   /// getBase - Returns the base class declaration.
   const CXXRecordDecl *getBase() const { return Base; }
@@ -47,7 +50,7 @@ public:
  }
 };
 
-} // end namespace clang
+} // namespace clang
 
 namespace llvm {
 
@@ -65,7 +68,8 @@ template<> struct DenseMapInfo {
   }
 
   static unsigned getHashValue(const clang::BaseSubobject &Base) {
-    typedef std::pair PairTy;
+    using PairTy = std::pair;
+
     return DenseMapInfo::getHashValue(PairTy(Base.getBase(),
                                                      Base.getBaseOffset()));
   }
@@ -81,6 +85,6 @@ template <> struct isPodLike {
   static const bool value = true;
 };
 
-}
+} // namespace llvm
 
-#endif
+#endif // LLVM_CLANG_AST_BASESUBOBJECT_H
diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def
index 181131a..e4f5f7d 100644
--- a/include/clang/AST/BuiltinTypes.def
+++ b/include/clang/AST/BuiltinTypes.def
@@ -133,6 +133,9 @@ FLOATING_TYPE(Double, DoubleTy)
 // 'long double'
 FLOATING_TYPE(LongDouble, LongDoubleTy)
 
+// '_Float16'
+FLOATING_TYPE(Float16, HalfTy)
+
 // '__float128'
 FLOATING_TYPE(Float128, Float128Ty)
 
diff --git a/include/clang/AST/CMakeLists.txt b/include/clang/AST/CMakeLists.txt
index 260734f..942d08d 100644
--- a/include/clang/AST/CMakeLists.txt
+++ b/include/clang/AST/CMakeLists.txt
@@ -50,3 +50,6 @@ clang_tablegen(CommentCommandList.inc -gen-clang-comment-command-list
   SOURCE CommentCommands.td
   TARGET ClangCommentCommandList)
 
+clang_tablegen(StmtDataCollectors.inc -gen-clang-data-collectors
+  SOURCE StmtDataCollectors.td
+  TARGET StmtDataCollectors)
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 9806085..11fb229 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -1,4 +1,4 @@
-//===------ CXXInheritance.h - C++ Inheritance ------------------*- C++ -*-===//
+//===- CXXInheritance.h - C++ Inheritance -----------------------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -16,19 +16,23 @@
 
 #include "clang/AST/DeclBase.h"
 #include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclarationName.h"
 #include "clang/AST/Type.h"
 #include "clang/AST/TypeOrdering.h"
+#include "clang/Basic/Specifiers.h"
+#include "llvm/ADT/DenseMap.h"
+#include "llvm/ADT/DenseSet.h"
 #include "llvm/ADT/MapVector.h"
 #include "llvm/ADT/SmallSet.h"
 #include "llvm/ADT/SmallVector.h"
-#include 
+#include "llvm/ADT/iterator_range.h"
 #include 
+#include 
+#include 
 
 namespace clang {
-  
-class CXXBaseSpecifier;
-class CXXMethodDecl;
-class CXXRecordDecl;
+
+class ASTContext;
 class NamedDecl;
   
 /// \brief Represents an element in a path from a derived class to a
@@ -66,12 +70,12 @@ struct CXXBasePathElement {
 /// subobject is being used.
 class CXXBasePath : public SmallVector {
 public:
-  CXXBasePath() : Access(AS_public) {}
-
   /// \brief The access along this inheritance path.  This is only
   /// calculated when recording paths.  AS_none is a special value
   /// used to indicate a path which permits no legal access.
-  AccessSpecifier Access;
+  AccessSpecifier Access = AS_public;
+
+  CXXBasePath() = default;
 
   /// \brief The set of declarations found inside this base class
   /// subobject.
@@ -113,8 +117,10 @@ public:
 /// refer to the same base class subobject of type A (the virtual
 /// one), there is no ambiguity.
 class CXXBasePaths {
+  friend class CXXRecordDecl;
+
   /// \brief The type from which this search originated.
-  CXXRecordDecl *Origin;
+  CXXRecordDecl *Origin = nullptr;
   
   /// Paths - The actual set of paths that can be taken from the
   /// derived class to the same base class.
@@ -152,15 +158,13 @@ class CXXBasePaths {
   CXXBasePath ScratchPath;
 
   /// DetectedVirtual - The base class that is virtual.
-  const RecordType *DetectedVirtual;
+  const RecordType *DetectedVirtual = nullptr;
   
   /// \brief Array of the declarations that have been found. This
   /// array is constructed only if needed, e.g., to iterate over the
   /// results within LookupResult.
   std::unique_ptr DeclsFound;
-  unsigned NumDeclsFound;
-  
-  friend class CXXRecordDecl;
+  unsigned NumDeclsFound = 0;
   
   void ComputeDeclsFound();
 
@@ -169,17 +173,16 @@ class CXXBasePaths {
                      bool LookupInDependent = false);
 
 public:
-  typedef std::list::iterator paths_iterator;
-  typedef std::list::const_iterator const_paths_iterator;
-  typedef NamedDecl **decl_iterator;
+  using paths_iterator = std::list::iterator;
+  using const_paths_iterator = std::list::const_iterator;
+  using decl_iterator = NamedDecl **;
   
   /// BasePaths - Construct a new BasePaths structure to record the
   /// paths for a derived-to-base search.
   explicit CXXBasePaths(bool FindAmbiguities = true, bool RecordPaths = true,
                         bool DetectVirtual = true)
-      : Origin(), FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
-        DetectVirtual(DetectVirtual), DetectedVirtual(nullptr),
-        NumDeclsFound(0) {}
+      : FindAmbiguities(FindAmbiguities), RecordPaths(RecordPaths),
+        DetectVirtual(DetectVirtual) {}
 
   paths_iterator begin() { return Paths.begin(); }
   paths_iterator end()   { return Paths.end(); }
@@ -189,7 +192,8 @@ public:
   CXXBasePath&       front()       { return Paths.front(); }
   const CXXBasePath& front() const { return Paths.front(); }
   
-  typedef llvm::iterator_range decl_range;
+  using decl_range = llvm::iterator_range;
+
   decl_range found_decls();
   
   /// \brief Determine whether the path from the most-derived type to the
@@ -231,25 +235,24 @@ public:
 /// \brief Uniquely identifies a virtual method within a class
 /// hierarchy by the method itself and a class subobject number.
 struct UniqueVirtualMethod {
-  UniqueVirtualMethod()
-    : Method(nullptr), Subobject(0), InVirtualSubobject(nullptr) { }
-
-  UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
-                      const CXXRecordDecl *InVirtualSubobject)
-    : Method(Method), Subobject(Subobject), 
-      InVirtualSubobject(InVirtualSubobject) { }
-
   /// \brief The overriding virtual method.
-  CXXMethodDecl *Method;
+  CXXMethodDecl *Method = nullptr;
 
   /// \brief The subobject in which the overriding virtual method
   /// resides.
-  unsigned Subobject;
+  unsigned Subobject = 0;
 
   /// \brief The virtual base class subobject of which this overridden
   /// virtual method is a part. Note that this records the closest
   /// derived virtual base class subobject.
-  const CXXRecordDecl *InVirtualSubobject;
+  const CXXRecordDecl *InVirtualSubobject = nullptr;
+
+  UniqueVirtualMethod() = default;
+
+  UniqueVirtualMethod(CXXMethodDecl *Method, unsigned Subobject,
+                      const CXXRecordDecl *InVirtualSubobject)
+      : Method(Method), Subobject(Subobject),
+        InVirtualSubobject(InVirtualSubobject) {}
 
   friend bool operator==(const UniqueVirtualMethod &X,
                          const UniqueVirtualMethod &Y) {
@@ -271,14 +274,16 @@ struct UniqueVirtualMethod {
 /// pair is the virtual method that overrides it (including the
 /// subobject in which that virtual function occurs).
 class OverridingMethods {
-  typedef SmallVector ValuesT;
-  typedef llvm::MapVector MapType;
+  using ValuesT = SmallVector;
+  using MapType = llvm::MapVector;
+
   MapType Overrides;
 
 public:
   // Iterate over the set of subobjects that have overriding methods.
-  typedef MapType::iterator iterator;
-  typedef MapType::const_iterator const_iterator;
+  using iterator = MapType::iterator;
+  using const_iterator = MapType::const_iterator;
+
   iterator begin() { return Overrides.begin(); }
   const_iterator begin() const { return Overrides.begin(); }
   iterator end() { return Overrides.end(); }
@@ -287,10 +292,10 @@ public:
 
   // Iterate over the set of overriding virtual methods in a given
   // subobject.
-  typedef SmallVectorImpl::iterator
-    overriding_iterator;
-  typedef SmallVectorImpl::const_iterator
-    overriding_const_iterator;
+  using overriding_iterator =
+      SmallVectorImpl::iterator;
+  using overriding_const_iterator =
+      SmallVectorImpl::const_iterator;
 
   // Add a new overriding method for a particular subobject.
   void add(unsigned OverriddenSubobject, UniqueVirtualMethod Overriding);
@@ -357,12 +362,12 @@ public:
 /// subobject numbers greater than 0 refer to non-virtual base class
 /// subobjects of that type.
 class CXXFinalOverriderMap
-  : public llvm::MapVector { };
+  : public llvm::MapVector {};
 
 /// \brief A set of all the primary bases for a class.
 class CXXIndirectPrimaryBaseSet
-  : public llvm::SmallSet { };
+  : public llvm::SmallSet {};
 
-} // end namespace clang
+} // namespace clang
 
-#endif
+#endif // LLVM_CLANG_AST_CXXINHERITANCE_H
diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h
index 25f6172..6487613 100644
--- a/include/clang/AST/CanonicalType.h
+++ b/include/clang/AST/CanonicalType.h
@@ -1,4 +1,4 @@
-//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===//
+//===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -16,13 +16,29 @@
 #define LLVM_CLANG_AST_CANONICALTYPE_H
 
 #include "clang/AST/Type.h"
+#include "clang/Basic/Diagnostic.h"
+#include "clang/Basic/SourceLocation.h"
+#include "llvm/ADT/ArrayRef.h"
+#include "llvm/ADT/FoldingSet.h"
 #include "llvm/ADT/iterator.h"
 #include "llvm/Support/Casting.h"
+#include "llvm/Support/PointerLikeTypeTraits.h"
+#include 
+#include 
+#include 
 
 namespace clang {
 
 template class CanProxy;
 template struct CanProxyAdaptor;
+class CXXRecordDecl;
+class EnumDecl;
+class Expr;
+class IdentifierInfo;
+class ObjCInterfaceDecl;
+class RecordDecl;
+class TagDecl;
+class TemplateTypeParmDecl;
 
 //----------------------------------------------------------------------------//
 // Canonical, qualified type template
@@ -46,8 +62,6 @@ template struct CanProxyAdaptor;
 /// converted to @c CanQual. Note that any @c CanQual type can
 /// be implicitly converted to a QualType, but the reverse operation requires
 /// a call to ASTContext::getCanonicalType().
-///
-///
 template
 class CanQual {
   /// \brief The actual, canonical type.
@@ -55,7 +69,7 @@ class CanQual {
 
 public:
   /// \brief Constructs a NULL canonical type.
-  CanQual() : Stored() { }
+  CanQual() = default;
 
   /// \brief Converting constructor that permits implicit upcasting of
   /// canonical type pointers.
@@ -66,12 +80,11 @@ public:
   /// \brief Retrieve the underlying type pointer, which refers to a
   /// canonical type.
   ///
-  /// The underlying pointer must not be NULL.
+  /// The underlying pointer must not be nullptr.
   const T *getTypePtr() const { return cast(Stored.getTypePtr()); }
 
   /// \brief Retrieve the underlying type pointer, which refers to a
-  /// canonical type, or NULL.
-  ///
+  /// canonical type, or nullptr.
   const T *getTypePtrOrNull() const { 
     return cast_or_null(Stored.getTypePtrOrNull()); 
   }
@@ -125,9 +138,11 @@ public:
   bool isConstQualified() const {
     return Stored.isLocalConstQualified();
   }
+
   bool isVolatileQualified() const {
     return Stored.isLocalVolatileQualified();
   }
+
   bool isRestrictQualified() const {
     return Stored.isLocalRestrictQualified();
   }
@@ -195,7 +210,7 @@ inline bool operator!=(CanQual x, CanQual y) {
 }
 
 /// \brief Represents a canonical, potentially-qualified type.
-typedef CanQual CanQualType;
+using CanQualType = CanQual;
 
 inline CanQualType Type::getCanonicalTypeUnqualified() const {
   return CanQualType::CreateUnsafe(getCanonicalTypeInternal());
@@ -320,7 +335,7 @@ public:
 /// than the more typical @c QualType, to propagate the notion of "canonical"
 /// through the system.
 template
-struct CanProxyAdaptor : CanProxyBase { };
+struct CanProxyAdaptor : CanProxyBase {};
 
 /// \brief Canonical proxy type returned when retrieving the members of a
 /// canonical type or as the result of the @c CanQual::getAs member
@@ -333,7 +348,7 @@ template
 class CanProxy : public CanProxyAdaptor {
 public:
   /// \brief Build a NULL proxy.
-  CanProxy() { }
+  CanProxy() = default;
 
   /// \brief Build a proxy to the given canonical type.
   CanProxy(CanQual Stored) { this->Stored = Stored; }
@@ -342,7 +357,7 @@ public:
   operator CanQual() const { return this->Stored; }
 };
 
-} // end namespace clang
+} // namespace clang
 
 namespace llvm {
 
@@ -350,8 +365,9 @@ namespace llvm {
 /// CanQual to a specific Type class. We're prefer isa/dyn_cast/cast/etc.
 /// to return smart pointer (proxies?).
 template
-struct simplify_type< ::clang::CanQual > {
-  typedef const T *SimpleType;
+struct simplify_type< ::clang::CanQual> {
+  using SimpleType = const T *;
+
   static SimpleType getSimplifiedValue(::clang::CanQual Val) {
     return Val.getTypePtr();
   }
@@ -359,19 +375,20 @@ struct simplify_type< ::clang::CanQual > {
 
 // Teach SmallPtrSet that CanQual is "basically a pointer".
 template
-class PointerLikeTypeTraits > {
-public:
-  static inline void *getAsVoidPointer(clang::CanQual P) {
+struct PointerLikeTypeTraits> {
+  static void *getAsVoidPointer(clang::CanQual P) {
     return P.getAsOpaquePtr();
   }
-  static inline clang::CanQual getFromVoidPointer(void *P) {
+
+  static clang::CanQual getFromVoidPointer(void *P) {
     return clang::CanQual::getFromOpaquePtr(P);
   }
+
   // qualifier information is encoded in the low bits.
   enum { NumLowBitsAvailable = 0 };
 };
 
-} // end namespace llvm
+} // namespace llvm
 
 namespace clang {
 
@@ -389,7 +406,7 @@ struct CanTypeIterator
           CanQualType,
           typename std::iterator_traits::difference_type,
           CanProxy, CanQualType> {
-  CanTypeIterator() {}
+  CanTypeIterator() = default;
   explicit CanTypeIterator(InputIterator Iter)
       : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {}
 
@@ -487,6 +504,7 @@ struct CanProxyAdaptor
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(
             ArrayRef, getExtParameterInfos)
+
   CanQualType getParamType(unsigned i) const {
     return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i));
   }
@@ -494,8 +512,8 @@ struct CanProxyAdaptor
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals)
 
-  typedef CanTypeIterator
-  param_type_iterator;
+  using param_type_iterator =
+      CanTypeIterator;
 
   param_type_iterator param_type_begin() const {
     return param_type_iterator(this->getTypePtr()->param_type_begin());
@@ -567,7 +585,8 @@ struct CanProxyAdaptor
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass)
 
-  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+  using qual_iterator = ObjCObjectPointerType::qual_iterator;
+
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
@@ -585,7 +604,8 @@ struct CanProxyAdaptor
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType)
 
-  typedef ObjCObjectPointerType::qual_iterator qual_iterator;
+  using qual_iterator = ObjCObjectPointerType::qual_iterator;
+
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end)
   LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty)
@@ -662,7 +682,6 @@ CanProxy CanTypeIterator::operator->() const {
   return CanProxy(*this);
 }
 
-}
-
+} // namespace clang
 
-#endif
+#endif // LLVM_CLANG_AST_CANONICALTYPE_H
diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h
index 564c8ec..ddead60 100644
--- a/include/clang/AST/CharUnits.h
+++ b/include/clang/AST/CharUnits.h
@@ -40,14 +40,14 @@ namespace clang {
       typedef int64_t QuantityType;
 
     private:
-      QuantityType Quantity;
+      QuantityType Quantity = 0;
 
       explicit CharUnits(QuantityType C) : Quantity(C) {}
 
     public:
 
       /// CharUnits - A default constructor.
-      CharUnits() : Quantity(0) {}
+      CharUnits() = default;
 
       /// Zero - Construct a CharUnits quantity of zero.
       static CharUnits Zero() {
diff --git a/include/clang/AST/CommentVisitor.h b/include/clang/AST/CommentVisitor.h
index 21641bf..d1cc2d0 100644
--- a/include/clang/AST/CommentVisitor.h
+++ b/include/clang/AST/CommentVisitor.h
@@ -1,4 +1,4 @@
-//===--- CommentVisitor.h - Visitor for Comment subclasses ------*- C++ -*-===//
+//===- CommentVisitor.h - Visitor for Comment subclasses --------*- C++ -*-===//
 //
 //                     The LLVM Compiler Infrastructure
 //
@@ -16,8 +16,8 @@
 namespace clang {
 namespace comments {
 
-template  struct make_ptr       { typedef       T *type; };
-template  struct make_const_ptr { typedef const T *type; };
+template  struct make_ptr { using type = T *; };
+template  struct make_const_ptr { using type = const T *; };
 
 template