diff --git a/CMakeLists.txt b/CMakeLists.txt index fc7a3889a7c19c9fd57edd212104c01236a02ecf..52b8819394994bcc2a8c050cf01ef4fd46c1c523 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -583,6 +583,10 @@ if (CLANG_ENABLE_BOOTSTRAP) endif() endif() + if(CLANG_BOOTSTRAP_EXTRA_DEPS) + add_dependencies(clang-bootstrap-deps ${CLANG_BOOTSTRAP_EXTRA_DEPS}) + endif() + add_custom_target(${NEXT_CLANG_STAGE}-clear DEPENDS ${CMAKE_CURRENT_BINARY_DIR}/${NEXT_CLANG_STAGE}-cleared ) @@ -617,10 +621,15 @@ if (CLANG_ENABLE_BOOTSTRAP) LLVM_ENABLE_PROJECTS LLVM_ENABLE_RUNTIMES) - # We don't need to depend on compiler-rt if we're building instrumented + # We don't need to depend on compiler-rt/libcxx if we're building instrumented # because the next stage will use the same compiler used to build this stage. - if(TARGET compiler-rt AND NOT LLVM_BUILD_INSTRUMENTED) - add_dependencies(clang-bootstrap-deps compiler-rt) + if(NOT LLVM_BUILD_INSTRUMENTED) + if(TARGET compiler-rt) + add_dependencies(clang-bootstrap-deps compiler-rt) + endif() + if(TARGET cxx-headers) + add_dependencies(clang-bootstrap-deps cxx-headers) + endif() endif() set(C_COMPILER "clang") @@ -749,6 +758,7 @@ endif() if (LLVM_ADD_NATIVE_VISUALIZERS_TO_SOLUTION) add_subdirectory(utils/ClangVisualizers) endif() +add_subdirectory(utils/hmaptool) configure_file( ${CLANG_SOURCE_DIR}/include/clang/Config/config.h.cmake diff --git a/LICENSE.TXT b/LICENSE.TXT index b452ca2efd8faab3ecb48c3faf666aafb7d22ff3..547f6a4893820664ac3caa03397c245bab139eaf 100644 --- a/LICENSE.TXT +++ b/LICENSE.TXT @@ -4,7 +4,7 @@ LLVM Release License University of Illinois/NCSA Open Source License -Copyright (c) 2007-2016 University of Illinois at Urbana-Champaign. +Copyright (c) 2007-2018 University of Illinois at Urbana-Champaign. All rights reserved. Developed by: diff --git a/bindings/python/tests/cindex/test_cdb.py b/bindings/python/tests/cindex/test_cdb.py index bd6e77329f6923d75338fab306a1b7dd2c9850b8..64651af317324e255163c67bd85dd1a99405d166 100644 --- a/bindings/python/tests/cindex/test_cdb.py +++ b/bindings/python/tests/cindex/test_cdb.py @@ -5,11 +5,13 @@ from clang.cindex import CompileCommand import os import gc import unittest +import sys kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') +@unittest.skipIf(sys.platform == 'win32', "TODO: Fix these tests on Windows") class TestCDB(unittest.TestCase): def test_create_fail(self): """Check we fail loading a database with an assertion""" diff --git a/bindings/python/tests/cindex/test_cursor.py b/bindings/python/tests/cindex/test_cursor.py index 2575ffb8a51c81d53186e2cbc9f3bff4cce6c4e2..f5733fd158791f2ec03d056c485c79ff3e95d991 100644 --- a/bindings/python/tests/cindex/test_cursor.py +++ b/bindings/python/tests/cindex/test_cursor.py @@ -335,7 +335,7 @@ class TestCursor(unittest.TestCase): self.assertEqual(enum.kind, CursorKind.ENUM_DECL) enum_type = enum.enum_type - self.assertEqual(enum_type.kind, TypeKind.UINT) + self.assertIn(enum_type.kind, (TypeKind.UINT, TypeKind.INT)) def test_enum_type_cpp(self): tu = get_tu('enum TEST : long long { FOO=1, BAR=2 };', lang="cpp") @@ -561,4 +561,4 @@ class TestCursor(unittest.TestCase): # 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')) + self.assertIn(foo.mangled_name, ('_Z3fooii', '__Z3fooii', '?foo@@YAHHH', '?foo@@YAHHH@Z')) diff --git a/bindings/python/tests/cindex/test_translation_unit.py b/bindings/python/tests/cindex/test_translation_unit.py index 09230d1da2dd59f5da4e95d804a765116e33f214..d3ee535f4d0dc4370b714a260c423a54be9ea674 100644 --- a/bindings/python/tests/cindex/test_translation_unit.py +++ b/bindings/python/tests/cindex/test_translation_unit.py @@ -1,3 +1,4 @@ +from contextlib import contextmanager import gc import os import tempfile @@ -19,15 +20,15 @@ from .util import get_tu kInputsDir = os.path.join(os.path.dirname(__file__), 'INPUTS') +@contextmanager def save_tu(tu): """Convenience API to save a TranslationUnit to a file. Returns the filename it was saved to. """ - _, path = tempfile.mkstemp() - tu.save(path) - - return path + with tempfile.NamedTemporaryFile() as t: + tu.save(t.name) + yield t.name class TestTranslationUnit(unittest.TestCase): @@ -125,10 +126,9 @@ int SOME_DEFINE; 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) + with save_tu(tu) as path: + self.assertTrue(os.path.exists(path)) + self.assertGreater(os.path.getsize(path), 0) def test_save_translation_errors(self): """Ensure that saving to an invalid directory raises.""" @@ -149,21 +149,18 @@ int SOME_DEFINE; tu = get_tu('int foo();') self.assertEqual(len(tu.diagnostics), 0) - path = save_tu(tu) - - self.assertTrue(os.path.exists(path)) - self.assertGreater(os.path.getsize(path), 0) - - tu2 = TranslationUnit.from_ast_file(filename=path) - self.assertEqual(len(tu2.diagnostics), 0) + with save_tu(tu) as path: + self.assertTrue(os.path.exists(path)) + self.assertGreater(os.path.getsize(path), 0) - foo = get_cursor(tu2, 'foo') - self.assertIsNotNone(foo) + tu2 = TranslationUnit.from_ast_file(filename=path) + self.assertEqual(len(tu2.diagnostics), 0) - # Just in case there is an open file descriptor somewhere. - del tu2 + foo = get_cursor(tu2, 'foo') + self.assertIsNotNone(foo) - os.unlink(path) + # Just in case there is an open file descriptor somewhere. + del tu2 def test_index_parse(self): path = os.path.join(kInputsDir, 'hello.cpp') diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake index 0a5ea37cfddee956e9dc4bf80b232cc805c97ab4..28e179513475b96bb564a56f0627abccb4f231e1 100644 --- a/cmake/caches/Fuchsia-stage2.cmake +++ b/cmake/caches/Fuchsia-stage2.cmake @@ -8,6 +8,7 @@ set(PACKAGE_VENDOR Fuchsia CACHE STRING "") set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "") set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "") set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "") +set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") set(LLVM_ENABLE_ZLIB ON CACHE BOOL "") set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "") @@ -27,69 +28,95 @@ set(CMAKE_BUILD_TYPE RelWithDebInfo 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(FUCHSIA_BUILTINS_BUILD_TYPE Release CACHE STRING "") -set(FUCHSIA_RUNTIMES_BUILD_TYPE Release CACHE STRING "") -set(FUCHSIA_RUNTIMES_ENABLE_ASSERTIONS ON CACHE BOOL "") +if(APPLE) + list(APPEND BUILTIN_TARGETS "default") + list(APPEND RUNTIME_TARGETS "default") +elseif(UNIX) + foreach(target i386;x86_64;armhf;aarch64) + if(LINUX_${target}_SYSROOT) + # Set the per-target builtins options. + list(APPEND BUILTIN_TARGETS "${target}-linux-gnu") + set(BUILTINS_${target}-linux-gnu_CMAKE_SYSTEM_NAME Linux CACHE STRING "") + set(BUILTINS_${target}-linux-gnu_CMAKE_BUILD_TYPE Release CACHE STRING "") + set(BUILTINS_${target}-linux-gnu_CMAKE_SYSROOT ${LINUX_${target}_SYSROOT} CACHE STRING "") -set(LLVM_BUILTIN_TARGETS "default;x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "") + # Set the per-target runtimes options. + list(APPEND RUNTIME_TARGETS "${target}-linux-gnu") + set(RUNTIMES_${target}-linux-gnu_CMAKE_SYSTEM_NAME Linux CACHE STRING "") + set(RUNTIMES_${target}-linux-gnu_CMAKE_BUILD_TYPE Release CACHE STRING "") + set(RUNTIMES_${target}-linux-gnu_CMAKE_SYSROOT ${LINUX_${target}_SYSROOT} CACHE STRING "") + set(RUNTIMES_${target}-linux-gnu_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXXABI_INSTALL_LIBRARY OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_SANITIZER_CXX_ABI "libc++" CACHE STRING "") + set(RUNTIMES_${target}-linux-gnu_SANITIZER_CXX_ABI_INTREE ON CACHE BOOL "") + set(RUNTIMES_${target}-linux-gnu_COMPILER_RT_USE_BUILTINS_LIBRARY ON CACHE BOOL "") + endif() + endforeach() +endif() -# Set the per-target builtins options. -foreach(target x86_64;aarch64) - set(BUILTINS_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "") - set(BUILTINS_${target}-fuchsia_CMAKE_BUILD_TYPE ${FUCHSIA_BUILTINS_BUILD_TYPE} CACHE STRING "") - set(BUILTINS_${target}-fuchsia_CMAKE_ASM_FLAGS ${FUCHSIA_${target}_C_FLAGS} CACHE PATH "") - set(BUILTINS_${target}-fuchsia_CMAKE_C_FLAGS ${FUCHSIA_${target}_C_FLAGS} CACHE PATH "") - set(BUILTINS_${target}-fuchsia_CMAKE_CXX_FLAGS ${FUCHSIA_${target}_CXX_FLAGS} CACHE PATH "") - set(BUILTINS_${target}-fuchsia_CMAKE_EXE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") - set(BUILTINS_${target}-fuchsia_CMAKE_SHARED_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") - set(BUILTINS_${target}-fuchsia_CMAKE_MODULE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") - set(BUILTINS_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") -endforeach() +if(FUCHSIA_SDK) + set(FUCHSIA_aarch64_NAME arm64) + set(FUCHSIA_x86_64_NAME x64) + foreach(target x86_64;aarch64) + set(FUCHSIA_${target}_COMPILER_FLAGS "-I${FUCHSIA_SDK}/pkg/fdio/include") + set(FUCHSIA_${target}_LINKER_FLAGS "-L${FUCHSIA_SDK}/arch/${FUCHSIA_${target}_NAME}/lib") + set(FUCHSIA_${target}_SYSROOT "${FUCHSIA_SDK}/arch/${FUCHSIA_${target}_NAME}/sysroot") + endforeach() -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 the per-target builtins options. + list(APPEND BUILTIN_TARGETS "${target}-fuchsia") + set(BUILTINS_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "") + set(BUILTINS_${target}-fuchsia_CMAKE_BUILD_TYPE Release CACHE STRING "") + set(BUILTINS_${target}-fuchsia_CMAKE_ASM_FLAGS ${FUCHSIA_${target}_COMPILER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-fuchsia_CMAKE_C_FLAGS ${FUCHSIA_${target}_COMPILER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-fuchsia_CMAKE_CXX_FLAGS ${FUCHSIA_${target}_COMPILER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-fuchsia_CMAKE_SHARED_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-fuchsia_CMAKE_MODULE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-fuchsia_CMAKE_EXE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") + set(BUILTINS_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") -# Set the default target runtimes options. -if(NOT APPLE) - set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") - set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") - set(LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "") - set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") - set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") - set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") - set(LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "") - set(LIBCXXABI_INSTALL_LIBRARY OFF CACHE BOOL "") - set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") - set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") - set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") -endif() + # Set the per-target runtimes options. + list(APPEND RUNTIME_TARGETS "${target}-fuchsia") + set(RUNTIMES_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "") + set(RUNTIMES_${target}-fuchsia_CMAKE_BUILD_TYPE Release CACHE STRING "") + set(RUNTIMES_${target}-fuchsia_CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE STRING "") + set(RUNTIMES_${target}-fuchsia_CMAKE_ASM_FLAGS ${FUCHSIA_${target}_COMPILER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-fuchsia_CMAKE_C_FLAGS ${FUCHSIA_${target}_COMPILER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-fuchsia_CMAKE_CXX_FLAGS ${FUCHSIA_${target}_COMPILER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-fuchsia_CMAKE_SHARED_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-fuchsia_CMAKE_MODULE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-fuchsia_CMAKE_EXE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") + set(RUNTIMES_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") + set(RUNTIMES_${target}-fuchsia_LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBUNWIND_INSTALL_STATIC_LIBRARY 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_UNWINDER ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBCXXABI_INSTALL_STATIC_LIBRARY OFF CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBCXXABI_STATICALLY_LINK_UNWINDER_IN_SHARED_LIBRARY OFF CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") + set(RUNTIMES_${target}-fuchsia_LIBCXX_STATICALLY_LINK_ABI_IN_SHARED_LIBRARY OFF CACHE BOOL "") + endforeach() -# Set the per-target runtimes options. -foreach(target x86_64;aarch64) - set(RUNTIMES_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "") - set(RUNTIMES_${target}-fuchsia_CMAKE_BUILD_TYPE ${FUCHSIA_RUNTIMES_BUILD_TYPE} CACHE STRING "") - set(RUNTIMES_${target}-fuchsia_CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE STRING "") - set(RUNTIMES_${target}-fuchsia_CMAKE_ASM_FLAGS ${FUCHSIA_${target}_C_FLAGS} CACHE PATH "") - set(RUNTIMES_${target}-fuchsia_CMAKE_C_FLAGS ${FUCHSIA_${target}_C_FLAGS} CACHE PATH "") - set(RUNTIMES_${target}-fuchsia_CMAKE_CXX_FLAGS ${FUCHSIA_${target}_CXX_FLAGS} CACHE PATH "") - set(RUNTIMES_${target}-fuchsia_CMAKE_EXE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") - set(RUNTIMES_${target}-fuchsia_CMAKE_SHARED_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") - set(RUNTIMES_${target}-fuchsia_CMAKE_MODULE_LINKER_FLAGS ${FUCHSIA_${target}_LINKER_FLAGS} CACHE PATH "") - set(RUNTIMES_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "") - set(RUNTIMES_${target}-fuchsia_LLVM_ENABLE_ASSERTIONS ${FUCHSIA_RUNTIMES_ENABLE_ASSERTIONS} 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_ENABLE_STATIC OFF CACHE BOOL "") - set(RUNTIMES_${target}-fuchsia_SANITIZER_USE_COMPILER_RT ON CACHE BOOL "") + set(LLVM_RUNTIME_SANITIZERS "Address" CACHE STRING "") + set(LLVM_RUNTIME_SANITIZER_Address_TARGETS "x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "") +endif() - 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() +set(LLVM_BUILTIN_TARGETS "${BUILTIN_TARGETS}" CACHE STRING "") +set(LLVM_RUNTIME_TARGETS "${RUNTIME_TARGETS}" CACHE STRING "") # Setup toolchain. set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "") diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake index 2a47ea0192ae182a239a853ea517d33c19c334e3..fc7dae8499355fb78cbaa1710be77d63c57df79c 100644 --- a/cmake/caches/Fuchsia.cmake +++ b/cmake/caches/Fuchsia.cmake @@ -7,10 +7,11 @@ set(PACKAGE_VENDOR Fuchsia CACHE STRING "") 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_BACKTRACES OFF CACHE BOOL "") +set(LLVM_ENABLE_PER_TARGET_RUNTIME_DIR ON CACHE BOOL "") set(LLVM_ENABLE_TERMINFO OFF CACHE BOOL "") set(LLVM_ENABLE_ZLIB OFF CACHE BOOL "") +set(CLANG_INCLUDE_TESTS OFF CACHE BOOL "") set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "") set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "") @@ -21,10 +22,25 @@ if(NOT APPLE) set(BOOTSTRAP_LLVM_ENABLE_LLD ON CACHE BOOL "") endif() +set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "") +set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "") + if(APPLE) set(COMPILER_RT_ENABLE_IOS OFF CACHE BOOL "") set(COMPILER_RT_ENABLE_TVOS OFF CACHE BOOL "") set(COMPILER_RT_ENABLE_WATCHOS OFF CACHE BOOL "") +elseif(UNIX) + set(LIBUNWIND_ENABLE_SHARED OFF CACHE BOOL "") + set(LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "") + set(LIBUNWIND_INSTALL_LIBRARY OFF CACHE BOOL "") + set(LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "") + set(LIBCXXABI_ENABLE_SHARED OFF CACHE BOOL "") + set(LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "") + set(LIBCXXABI_ENABLE_STATIC_UNWINDER ON CACHE BOOL "") + set(LIBCXXABI_INSTALL_LIBRARY OFF CACHE BOOL "") + set(LIBCXX_USE_COMPILER_RT ON CACHE BOOL "") + set(LIBCXX_ENABLE_SHARED OFF CACHE BOOL "") + set(LIBCXX_ENABLE_STATIC_ABI_LIBRARY ON CACHE BOOL "") endif() set(CLANG_BOOTSTRAP_TARGETS @@ -38,6 +54,7 @@ set(CLANG_BOOTSTRAP_TARGETS clang-test-depends distribution install-distribution + install-distribution-stripped clang CACHE STRING "") get_cmake_property(variableNames VARIABLES) @@ -50,6 +67,10 @@ endforeach() # Setup the bootstrap build. set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "") +set(CLANG_BOOTSTRAP_EXTRA_DEPS + builtins + runtimes + CACHE STRING "") set(CLANG_BOOTSTRAP_CMAKE_ARGS ${EXTRA_ARGS} -C ${CMAKE_CURRENT_LIST_DIR}/Fuchsia-stage2.cmake diff --git a/docs/AddressSanitizer.rst b/docs/AddressSanitizer.rst index f58995576f91a47cc10fc02ed44c1b0713afa3bf..7549159a39ab41e405f747cdd8b97ea78eb4aded 100644 --- a/docs/AddressSanitizer.rst +++ b/docs/AddressSanitizer.rst @@ -197,13 +197,17 @@ this purpose. Disabling Instrumentation with ``__attribute__((no_sanitize("address")))`` -------------------------------------------------------------------------- -Some code should not be instrumented by AddressSanitizer. One may use the -function attribute ``__attribute__((no_sanitize("address")))`` (which has -deprecated synonyms `no_sanitize_address` and `no_address_safety_analysis`) to -disable instrumentation of a particular function. This attribute may not be -supported by other compilers, so we suggest to use it together with +Some code should not be instrumented by AddressSanitizer. One may use +the attribute ``__attribute__((no_sanitize("address")))`` (which has +deprecated synonyms `no_sanitize_address` and +`no_address_safety_analysis`) to disable instrumentation of a +particular function. This attribute may not be supported by other +compilers, so we suggest to use it together with ``__has_feature(address_sanitizer)``. +The same attribute used on a global variable prevents AddressSanitizer +from adding redzones around it and detecting out of bounds accesses. + Suppressing Errors in Recompiled Code (Blacklist) ------------------------------------------------- @@ -272,6 +276,7 @@ AddressSanitizer is supported on: * OS X 10.7 - 10.11 (i386/x86\_64) * iOS Simulator * Android ARM +* NetBSD i386/x86\_64 * FreeBSD i386/x86\_64 (tested on FreeBSD 11-current) Ports to various other platforms are in progress. diff --git a/docs/AutomaticReferenceCounting.rst b/docs/AutomaticReferenceCounting.rst index fbd1ba4c4d47b666e4e29350e572c4a254eada2c..bf4d0945672a890209c7577dd0a029eec7a217e5 100644 --- a/docs/AutomaticReferenceCounting.rst +++ b/docs/AutomaticReferenceCounting.rst @@ -974,28 +974,66 @@ It is undefined behavior to access an ownership-qualified object through an lvalue of a differently-qualified type, except that any non-``__weak`` object may be read through an ``__unsafe_unretained`` lvalue. -It is undefined behavior if a managed operation is performed on a ``__strong`` -or ``__weak`` object without a guarantee that it contains a primitive zero -bit-pattern, or if the storage for such an object is freed or reused without the -object being first assigned a null pointer. +It is undefined behavior if the storage of a ``__strong`` or ``__weak`` +object is not properly initialized before the first managed operation +is performed on the object, or if the storage of such an object is freed +or reused before the object has been properly deinitialized. Storage for +a ``__strong`` or ``__weak`` object may be properly initialized by filling +it with the representation of a null pointer, e.g. by acquiring the memory +with ``calloc`` or using ``bzero`` to zero it out. A ``__strong`` or +``__weak`` object may be properly deinitialized by assigning a null pointer +into it. A ``__strong`` object may also be properly initialized +by copying into it (e.g. with ``memcpy``) the representation of a +different ``__strong`` object whose storage has been properly initialized; +doing this properly deinitializes the source object and causes its storage +to no longer be properly initialized. A ``__weak`` object may not be +representation-copied in this way. + +These requirements are followed automatically for objects whose +initialization and deinitialization are under the control of ARC: + +* objects of static, automatic, and temporary storage duration +* instance variables of Objective-C objects +* elements of arrays where the array object's initialization and + deinitialization are under the control of ARC +* fields of Objective-C struct types where the struct object's + initialization and deinitialization are under the control of ARC +* non-static data members of Objective-C++ non-union class types +* Objective-C++ objects and arrays of dynamic storage duration created + with the ``new`` or ``new[]`` operators and destroyed with the + corresponding ``delete`` or ``delete[]`` operator + +They are not followed automatically for these objects: + +* objects of dynamic storage duration created in other memory, such as + that returned by ``malloc`` +* union members .. admonition:: Rationale - ARC cannot differentiate between an assignment operator which is intended to - "initialize" dynamic memory and one which is intended to potentially replace - a value. Therefore the object's pointer must be valid before letting ARC at - it. Similarly, C and Objective-C do not provide any language hooks for - destroying objects held in dynamic memory, so it is the programmer's - responsibility to avoid leaks (``__strong`` objects) and consistency errors - (``__weak`` objects). - -These requirements are followed automatically in Objective-C++ when creating -objects of retainable object owner type with ``new`` or ``new[]`` and destroying -them with ``delete``, ``delete[]``, or a pseudo-destructor expression. Note -that arrays of nontrivially-ownership-qualified type are not ABI compatible with -non-ARC code because the element type is non-POD: such arrays that are -``new[]``'d in ARC translation units cannot be ``delete[]``'d in non-ARC -translation units and vice-versa. + ARC must perform special operations when initializing an object and + when destroying it. In many common situations, ARC knows when an + object is created and when it is destroyed and can ensure that these + operations are performed correctly. Otherwise, however, ARC requires + programmer cooperation to establish its initialization invariants + because it is infeasible for ARC to dynamically infer whether they + are intact. For example, there is no syntactic difference in C between + an assignment that is intended by the programmer to initialize a variable + and one that is intended to replace the existing value stored there, + but ARC must perform one operation or the other. ARC chooses to always + assume that objects are initialized (except when it is in charge of + initializing them) because the only workable alternative would be to + ban all code patterns that could potentially be used to access + uninitialized memory, and that would be too limiting. In practice, + this is rarely a problem because programmers do not generally need to + work with objects for which the requirements are not handled + automatically. + +Note that dynamically-allocated Objective-C++ arrays of +nontrivially-ownership-qualified type are not ABI-compatible with non-ARC +code because the non-ARC code will consider the element type to be POD. +Such arrays that are ``new[]``'d in ARC translation units cannot be +``delete[]``'d in non-ARC translation units and vice-versa. .. _arc.ownership.restrictions.pass_by_writeback: diff --git a/docs/Block-ABI-Apple.rst b/docs/Block-ABI-Apple.rst index 7f49bbd40d71cd49daba7d770c326b0fe8c803c2..e48a24b43ce52c761540b8e8e733248396ea32fd 100644 --- a/docs/Block-ABI-Apple.rst +++ b/docs/Block-ABI-Apple.rst @@ -61,6 +61,14 @@ The following flags bits are in use thusly for a possible ABI.2010.3.16: .. code-block:: c enum { + // Set to true on blocks that have captures (and thus are not true + // global blocks) but are known not to escape for various other + // reasons. For backward compatiblity with old runtimes, whenever + // BLOCK_IS_NOESCAPE is set, BLOCK_IS_GLOBAL is set too. Copying a + // non-escaping block returns the original block and releasing such a + // block is a no-op, which is exactly how global blocks are handled. + BLOCK_IS_NOESCAPE = (1 << 23), + BLOCK_HAS_COPY_DISPOSE = (1 << 25), BLOCK_HAS_CTOR = (1 << 26), // helpers have C++ code BLOCK_IS_GLOBAL = (1 << 28), diff --git a/docs/ClangCommandLineReference.rst b/docs/ClangCommandLineReference.rst index 10fc831bdf8d05580994c2c20c8d618e0434056b..5c15482cb251d9b9852c760c19ae9b371e176d2f 100644 --- a/docs/ClangCommandLineReference.rst +++ b/docs/ClangCommandLineReference.rst @@ -1543,6 +1543,14 @@ Specifies the largest alignment guaranteed by '::operator new(size\_t)' Disable implicit builtin knowledge of a specific function +.. option:: -fdelete-null-pointer-checks, -fno-delete-null-pointer-checks + +When enabled, treat null pointer dereference, creation of a reference to null, +or passing a null pointer to a function parameter annotated with the "nonnull" +attribute as undefined behavior. (And, thus the optimizer may assume that any +pointer used in such a way must not have been null and optimize away the +branches accordingly.) On by default. + .. option:: -fno-elide-type Do not elide types when printing diagnostics @@ -1920,7 +1928,7 @@ Enable the loop vectorization passes .. option:: -fvisibility-inlines-hidden -Give inline C++ member functions default visibility by default +Give inline C++ member functions hidden visibility by default .. option:: -fvisibility-ms-compat @@ -1934,6 +1942,12 @@ Set the default symbol visibility for all global declarations Enables whole-program vtable optimization. Requires -flto +.. option:: -fforce-emit-vtables, -fno-force-emit-vtables + +In order to improve devirtualization, forces emitting of vtables even in +modules where it isn't necessary. It causes more inline virtual functions +to be emitted. + .. option:: -fwrapv, -fno-wrapv Treat signed integer overflow as two's complement @@ -2296,6 +2310,10 @@ AARCH64 Reserve the x18 register (AArch64 only) +.. option:: -ffixed-x20 + +Reserve the x20 register (AArch64 only) + .. option:: -mfix-cortex-a53-835769, -mno-fix-cortex-a53-835769 Workaround Cortex-A53 erratum 835769 (AArch64 only) diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst index 487660a6ee59f8150bbf60f3a9ce41bc6d168f45..49f9f68088bc27ed52d6b4d2b22c3bed460c0726 100644 --- a/docs/ClangFormatStyleOptions.rst +++ b/docs/ClangFormatStyleOptions.rst @@ -994,18 +994,6 @@ the configuration (without a prefix: ``Auto``). -**BreakBeforeInheritanceComma** (``bool``) - If ``true``, in the class inheritance expression clang-format will - break before ``:`` and ``,`` if there is multiple inheritance. - - .. code-block:: c++ - - true: false: - class MyClass vs. class MyClass : public X, public Y { - : public X }; - , public Y { - }; - **BreakBeforeTernaryOperators** (``bool``) If ``true``, ternary operators will be placed after line breaks. @@ -1031,9 +1019,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 @@ -1041,18 +1029,56 @@ 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() + + + +**BreakInheritanceList** (``BreakInheritanceListStyle``) + The inheritance list style to use. + + Possible values: + + * ``BILS_BeforeColon`` (in configuration: ``BeforeColon``) + Break inheritance list before the colon and after the commas. + + .. code-block:: c++ + + class Foo + : Base1, + Base2 + {}; + + * ``BILS_BeforeComma`` (in configuration: ``BeforeComma``) + Break inheritance list before the colon and commas, and align + the commas with the colon. + + .. code-block:: c++ + + class Foo + : Base1 + , Base2 + {}; + + * ``BILS_AfterColon`` (in configuration: ``AfterColon``) + Break inheritance list after the colon and commas. + + .. code-block:: c++ + + class Foo : + Base1, + Base2 + {}; @@ -1108,21 +1134,25 @@ the configuration (without a prefix: ``Auto``). .. code-block:: c++ true: - SomeClass::Constructor() - : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) { - return 0; - } + FitsOnOneLine::Constructor() + : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {} + + DoesntFit::Constructor() + : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), + aaaaaaaaaaaaa(aaaaaaaaaaaaaa), + aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {} false: - SomeClass::Constructor() - : aaaaaaaa(aaaaaaaa), aaaaaaaa(aaaaaaaa), - aaaaaaaa(aaaaaaaaaaaaaaaaaaaaaaaaa) { - return 0; - } + FitsOnOneLine::Constructor() + : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {} + + DoesntFit::Constructor() + : aaaaaaaaaaaaa(aaaaaaaaaaaaaa), aaaaaaaaaaaaa(aaaaaaaaaaaaaa), + aaaaaaaaaaaaa(aaaaaaaaaaaaaa) {} **ConstructorInitializerIndentWidth** (``unsigned``) The number of characters to use for indentation of constructor - initializer lists. + initializer lists as well as inheritance lists. **ContinuationIndentWidth** (``unsigned``) Indent width for line continuations. @@ -1254,6 +1284,10 @@ the configuration (without a prefix: ``Auto``). Regular expressions denoting the different ``#include`` categories used for ordering ``#includes``. + `POSIX extended + `_ + regular expressions are supported. + These regular expressions are matched against the filename of an include (including the <> or "") in order. The value belonging to the first matching regular expression is assigned and ``#includes`` are sorted first @@ -1276,6 +1310,8 @@ the configuration (without a prefix: ``Auto``). Priority: 2 - Regex: '^(<|"(gtest|gmock|isl|json)/)' Priority: 3 + - Regex: '<[[:alnum:].]+>' + Priority: 4 - Regex: '.*' Priority: 1 @@ -1562,7 +1598,7 @@ the configuration (without a prefix: ``Auto``). onto individual lines whenever they go over ``ColumnLimit``. - .. code-block:: c++ + .. code-block:: objc Always (or Auto, if BinPackParameters=true): @interface ccccccccccccc () < @@ -1767,6 +1803,18 @@ the configuration (without a prefix: ``Auto``). int a = 5; vs. int a=5; a += 42 a+=42; +**SpaceBeforeCpp11BracedList** (``bool``) + If ``true``, a space will be inserted before a C++11 braced list + used to initialize an object (after the preceding identifier or type). + + .. code-block:: c++ + + true: false: + Foo foo { bar }; vs. Foo foo{ bar }; + Foo {}; Foo{}; + vector { 1, 2, 3 }; vector{ 1, 2, 3 }; + new int[3] { 1, 2, 3 }; new int[3]{ 1, 2, 3 }; + **SpaceBeforeCtorInitializerColon** (``bool``) If ``false``, spaces will be removed before constructor initializer colon. diff --git a/docs/ControlFlowIntegrity.rst b/docs/ControlFlowIntegrity.rst index 35b03a0e6390f2b3911373d322358fd89a24ad1f..fcc64098889791ad55eb579f3b340345e21edae3 100644 --- a/docs/ControlFlowIntegrity.rst +++ b/docs/ControlFlowIntegrity.rst @@ -66,6 +66,8 @@ Available schemes are: wrong dynamic type. - ``-fsanitize=cfi-icall``: Indirect call of a function with wrong dynamic type. + - ``-fsanitize=cfi-mfcall``: Indirect call via a member function pointer with + wrong dynamic type. You can use ``-fsanitize=cfi`` to enable all the schemes and use ``-fno-sanitize`` flag to narrow down the set of schemes as desired. @@ -106,8 +108,9 @@ This CFI scheme can be enabled on its own using ``-fsanitize=cfi-vcall``. For this scheme to work, all translation units containing the definition of a virtual member function (whether inline or not), other than members -of :ref:`blacklisted ` types, must be compiled with -``-fsanitize=cfi-vcall`` enabled and be statically linked into the program. +of :ref:`blacklisted ` types or types with public :doc:`LTO +visibility `, must be compiled with ``-flto`` or ``-flto=thin`` +enabled and be statically linked into the program. Performance ----------- @@ -152,9 +155,9 @@ functions may be :ref:`blacklisted `. For this scheme to work, all translation units containing the definition of a virtual member function (whether inline or not), other than members -of :ref:`blacklisted ` types, must be compiled with -``-fsanitize=cfi-derived-cast`` or ``-fsanitize=cfi-unrelated-cast`` enabled -and be statically linked into the program. +of :ref:`blacklisted ` types or types with public :doc:`LTO +visibility `, must be compiled with ``-flto`` or ``-flto=thin`` +enabled and be statically linked into the program. Non-Virtual Member Function Call Checking ========================================= @@ -168,8 +171,9 @@ polymorphic class type. This CFI scheme can be enabled on its own using For this scheme to work, all translation units containing the definition of a virtual member function (whether inline or not), other than members -of :ref:`blacklisted ` types, must be compiled with -``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program. +of :ref:`blacklisted ` types or types with public :doc:`LTO +visibility `, must be compiled with ``-flto`` or ``-flto=thin`` +enabled and be statically linked into the program. .. _cfi-strictness: @@ -253,6 +257,34 @@ the identity of function pointers is maintained, and calls across shared library boundaries are no different from calls within a single program or shared library. +Member Function Pointer Call Checking +===================================== + +This scheme checks that indirect calls via a member function pointer +take place using an object of the correct dynamic type. Specifically, we +check that the dynamic type of the member function referenced by the member +function pointer matches the "function pointer" part of the member function +pointer, and that the member function's class type is related to the base +type of the member function. This CFI scheme can be enabled on its own using +``-fsanitize=cfi-mfcall``. + +The compiler will only emit a full CFI check if the member function pointer's +base type is complete. This is because the complete definition of the base +type contains information that is necessary to correctly compile the CFI +check. To ensure that the compiler always emits a full CFI check, it is +recommended to also pass the flag ``-fcomplete-member-pointers``, which +enables a non-conforming language extension that requires member pointer +base types to be complete if they may be used for a call. + +For this scheme to work, all translation units containing the definition +of a virtual member function (whether inline or not), other than members +of :ref:`blacklisted ` types or types with public :doc:`LTO +visibility `, must be compiled with ``-flto`` or ``-flto=thin`` +enabled and be statically linked into the program. + +This scheme is currently not compatible with cross-DSO CFI or the +Microsoft ABI. + .. _cfi-blacklist: Blacklist diff --git a/docs/HardwareAssistedAddressSanitizerDesign.rst b/docs/HardwareAssistedAddressSanitizerDesign.rst index 2578914376ae09ff8c54b6fdc0d89cf75ccabf4b..4e6f5d14cde4cbce57d0afd2c4edadd888663036 100644 --- a/docs/HardwareAssistedAddressSanitizerDesign.rst +++ b/docs/HardwareAssistedAddressSanitizerDesign.rst @@ -47,21 +47,21 @@ All memory accesses are prefixed with an inline instruction sequence that verifies the tags. Currently, the following sequence is used: -.. code-block:: asm +.. code-block:: none // int foo(int *a) { return *a; } // clang -O2 --target=aarch64-linux -fsanitize=hwaddress -c load.c foo: 0: 08 00 00 90 adrp x8, 0 <__hwasan_shadow> - 4: 08 01 40 f9 ldr x8, [x8] // shadow base (to be resolved by the loader) - 8: 09 dc 44 d3 ubfx x9, x0, #4, #52 // shadow offset - c: 28 69 68 38 ldrb w8, [x9, x8] // load shadow tag - 10: 09 fc 78 d3 lsr x9, x0, #56 // extract address tag - 14: 3f 01 08 6b cmp w9, w8 // compare tags - 18: 61 00 00 54 b.ne 24 // jump on mismatch - 1c: 00 00 40 b9 ldr w0, [x0] // original load + 4: 08 01 40 f9 ldr x8, [x8] // shadow base (to be resolved by the loader) + 8: 09 dc 44 d3 ubfx x9, x0, #4, #52 // shadow offset + c: 28 69 68 38 ldrb w8, [x9, x8] // load shadow tag + 10: 09 fc 78 d3 lsr x9, x0, #56 // extract address tag + 14: 3f 01 08 6b cmp w9, w8 // compare tags + 18: 61 00 00 54 b.ne 24 // jump on mismatch + 1c: 00 00 40 b9 ldr w0, [x0] // original load 20: c0 03 5f d6 ret - 24: 40 20 21 d4 brk #0x902 // trap + 24: 40 20 21 d4 brk #0x902 // trap Alternatively, memory accesses are prefixed with a function call. diff --git a/docs/InternalsManual.rst b/docs/InternalsManual.rst index 940d32004dd7b99a34ccb77e83ccdb76ad22961c..af15b2e51e1c2ea73133eee3bebfc3ad1cc6b544 100644 --- a/docs/InternalsManual.rst +++ b/docs/InternalsManual.rst @@ -1664,15 +1664,15 @@ and then the semantic handling of the attribute. Parsing of the attribute is determined by the various syntactic forms attributes can take, such as GNU, C++11, and Microsoft style attributes, as well as other information provided by the table definition of the attribute. Ultimately, the -parsed representation of an attribute object is an ``AttributeList`` object. +parsed representation of an attribute object is an ``ParsedAttr`` object. These parsed attributes chain together as a list of parsed attributes attached to a declarator or declaration specifier. The parsing of attributes is handled automatically by Clang, except for attributes spelled as keywords. When implementing a keyword attribute, the parsing of the keyword and creation of the -``AttributeList`` object must be done manually. +``ParsedAttr`` object must be done manually. Eventually, ``Sema::ProcessDeclAttributeList()`` is called with a ``Decl`` and -an ``AttributeList``, at which point the parsed attribute can be transformed +an ``ParsedAttr``, at which point the parsed attribute can be transformed into a semantic attribute. The process by which a parsed attribute is converted into a semantic attribute depends on the attribute definition and semantic requirements of the attribute. The end result, however, is that the semantic @@ -1751,8 +1751,8 @@ subjects in the list, but a custom diagnostic parameter can also be specified in the ``SubjectList``. The diagnostics generated for subject list violations are either ``diag::warn_attribute_wrong_decl_type`` or ``diag::err_attribute_wrong_decl_type``, and the parameter enumeration is found -in `include/clang/Sema/AttributeList.h -`_ +in `include/clang/Sema/ParsedAttr.h +`_ If a previously unused Decl node is added to the ``SubjectList``, the logic used to automatically determine the diagnostic parameter in `utils/TableGen/ClangAttrEmitter.cpp `_ @@ -1887,15 +1887,10 @@ requirements. To support this feature, an attribute inheriting from should be the same value between all arguments sharing a spelling, and corresponds to the parsed attribute's ``Kind`` enumerator. This allows attributes to share a parsed attribute kind, but have distinct semantic -attribute classes. For instance, ``AttributeList::AT_Interrupt`` is the shared +attribute classes. For instance, ``ParsedAttr`` is the shared parsed attribute kind, but ARMInterruptAttr and MSP430InterruptAttr are the semantic attributes generated. -By default, when declarations are merging attributes, an attribute will not be -duplicated. However, if an attribute can be duplicated during this merging -stage, set ``DuplicatesAllowedWhileMerging`` to ``1``, and the attribute will -be merged. - By default, attribute arguments are parsed in an evaluated context. If the arguments for an attribute should be parsed in an unevaluated context (akin to the way the argument to a ``sizeof`` expression is parsed), set diff --git a/docs/LTOVisibility.rst b/docs/LTOVisibility.rst index e1372d667a1a2b24c9faf69da56fb0909c685f4b..ed15d8d78678442cdbe943acdd9fee1b4df26e0f 100644 --- a/docs/LTOVisibility.rst +++ b/docs/LTOVisibility.rst @@ -11,9 +11,9 @@ linkage unit's LTO unit is empty. Each linkage unit has only a single LTO unit. The LTO visibility of a class is used by the compiler to determine which classes the whole-program devirtualization (``-fwhole-program-vtables``) and -control flow integrity (``-fsanitize=cfi-vcall``) features apply to. These -features use whole-program information, so they require the entire class -hierarchy to be visible in order to work correctly. +control flow integrity (``-fsanitize=cfi-vcall`` and ``-fsanitize=cfi-mfcall``) +features apply to. These features use whole-program information, so they +require the entire class hierarchy to be visible in order to work correctly. If any translation unit in the program uses either of the whole-program devirtualization or control flow integrity features, it is effectively an ODR diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 1d6c7ec5ebb459c930d0685d7f1a9e65b1b495c5..1aef265a858920de9d66c512b04cd342b753b42e 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -1200,6 +1200,51 @@ Objective-C objects. ``__has_feature(objc_arc_fields)`` indicates that C structs are allowed to have fields that are pointers to Objective-C objects managed by automatic reference counting. +.. _objc-weak: + +Weak references +--------------- + +Clang supports ARC-style weak and unsafe references in Objective-C even +outside of ARC mode. Weak references must be explicitly enabled with +the ``-fobjc-weak`` option; use ``__has_feature((objc_arc_weak))`` +to test whether they are enabled. Unsafe references are enabled +unconditionally. ARC-style weak and unsafe references cannot be used +when Objective-C garbage collection is enabled. + +Except as noted below, the language rules for the ``__weak`` and +``__unsafe_unretained`` qualifiers (and the ``weak`` and +``unsafe_unretained`` property attributes) are just as laid out +in the :doc:`ARC specification `. +In particular, note that some classes do not support forming weak +references to their instances, and note that special care must be +taken when storing weak references in memory where initialization +and deinitialization are outside the responsibility of the compiler +(such as in ``malloc``-ed memory). + +Loading from a ``__weak`` variable always implicitly retains the +loaded value. In non-ARC modes, this retain is normally balanced +by an implicit autorelease. This autorelease can be suppressed +by performing the load in the receiver position of a ``-retain`` +message send (e.g. ``[weakReference retain]``); note that this performs +only a single retain (the retain done when primitively loading from +the weak reference). + +For the most part, ``__unsafe_unretained`` in non-ARC modes is just the +default behavior of variables and therefore is not needed. However, +it does have an effect on the semantics of block captures: normally, +copying a block which captures an Objective-C object or block pointer +causes the captured pointer to be retained or copied, respectively, +but that behavior is suppressed when the captured variable is qualified +with ``__unsafe_unretained``. + +Note that the ``__weak`` qualifier formerly meant the GC qualifier in +all non-ARC modes and was silently ignored outside of GC modes. It now +means the ARC-style qualifier in all non-GC modes and is no longer +allowed if not enabled by either ``-fobjc-arc`` or ``-fobjc-weak``. +It is expected that ``-fobjc-weak`` will eventually be enabled by default +in all non-GC Objective-C modes. + .. _objc-fixed-enum: Enumerations with a fixed underlying type diff --git a/docs/LibASTMatchersReference.html b/docs/LibASTMatchersReference.html index 6c67fd5b60e1059e47ed0f5b5c79763c74869702..cf32a5ce4a0f21810fcc764c43fd4c3c2c028fec 100644 --- a/docs/LibASTMatchersReference.html +++ b/docs/LibASTMatchersReference.html @@ -662,6 +662,18 @@ Example matches __atomic_load_n(ptr, 1) +Matcher<Stmt>autoreleasePoolStmtMatcher<ObjCAutoreleasePoolStmt>... +
Matches an Objective-C autorelease pool statement.
+
+Given
+  @autoreleasepool {
+    int x = 0;
+  }
+autoreleasePoolStmt(stmt()) matches the declaration of "x"
+inside the autorelease pool.
+
+ + Matcher<Stmt>binaryConditionalOperatorMatcher<BinaryConditionalOperator>...
Matches binary conditional operator expressions (GNU extension).
 
@@ -1255,6 +1267,20 @@ Example matches @finally
 
+Matcher<Stmt>objcIvarRefExprMatcher<ObjCIvarRefExpr>... +
Matches a reference to an ObjCIvar.
+
+Example: matches "a" in "init" method:
+@implementation A {
+  NSString *a;
+}
+- (void) init {
+  a = @"hello";
+}
+}
+
+ + Matcher<Stmt>objcMessageExprMatcher<ObjCMessageExpr>...
Matches ObjectiveC Message invocation expressions.
 
@@ -1565,6 +1591,18 @@ Example matches i[1].
 
+Matcher<Type>decltypeTypeMatcher<DecltypeType>... +
Matches types nodes representing C++11 decltype(<expr>) types.
+
+Given:
+  short i = 1;
+  int j = 42;
+  decltype(i + j) result = i + j;
+decltypeType() 
+  matches "decltype(i + j)"
+
+ + Matcher<Type>dependentSizedArrayTypeMatcher<DependentSizedArrayType>...
Matches C++ arrays whose size is a value-dependent expression.
 
@@ -2907,6 +2945,12 @@ namespaceDecl(isInline()) will match n::m.
 
+Matcher<FunctionDecl>isMain +
Determines whether the function is "main", which is the entry point
+into an executable program.
+
+ + Matcher<FunctionDecl>isNoReturn
Matches FunctionDecls that have a noreturn attribute.
 
@@ -3256,6 +3300,19 @@ represent an error condition in the tree!
 
+Matcher<ObjCMessageExpr>isInstanceMessage +
Returns true when the Objective-C message is sent to an instance.
+
+Example
+matcher = objcMessagaeExpr(isInstanceMessage())
+matches
+  NSString *x = @"hello";
+  [x containsString:@"h"];
+but not
+  [NSString stringWithFormat:@"format"];
+
+ + Matcher<ObjCMessageExpr>matchesSelectorstd::string RegExp
Matches ObjC selectors whose name contains
 a substring matched by the given RegExp.
@@ -4208,6 +4265,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -4504,6 +4562,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -4707,6 +4766,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -4857,6 +4917,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -5018,6 +5079,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -5125,6 +5187,19 @@ declaration of class D.
 
+Matcher<DecltypeType>hasUnderlyingTypeMatcher<Type> +
Matches DecltypeType nodes to find out the underlying type.
+
+Given
+  decltype(1) a = 1;
+  decltype(2.0) b = 2.0;
+decltypeType(hasUnderlyingType(isInteger()))
+  matches "auto a"
+
+Usable as: Matcher<DecltypeType>
+
+ + Matcher<DoStmt>hasBodyMatcher<Stmt> InnerMatcher
Matches a 'for', 'while', 'do while' statement or a function
 definition that has a given body.
@@ -5191,6 +5266,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -5222,8 +5298,8 @@ actual casts "explicit" casts.)
 
-Matcher<Expr>hasTypeMatcher<Decl> InnerMatcher -
Overloaded to match the declaration of the expression's or value
+Matcher<Expr>hasTypeMatcher<Decl> InnerMatcher
+
Overloaded to match the declaration of the expression's or value
 declaration's type.
 
 In case of a value declaration (for example a variable declaration),
@@ -5234,8 +5310,10 @@ declaration of x.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
+ class Y { friend class X; };
 
 Usable as: Matcher<Expr>, Matcher<ValueDecl>
 
@@ -5248,9 +5326,11 @@ matcher. Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X"))))) and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X"))))) and U (matcher = typedefDecl(hasType(asString("int"))) + and friend class X (matcher = friendDecl(hasType("X")) class X {}; void y(X &x) { x; X z; } typedef int U; + class Y { friend class X; };
@@ -5396,6 +5476,42 @@ matches 'int x = 0' in +Matcher<FriendDecl>hasTypeMatcher<Decl> InnerMatcher +
Overloaded to match the declaration of the expression's or value
+declaration's type.
+
+In case of a value declaration (for example a variable declaration),
+this resolves one layer of indirection. For example, in the value
+declaration "X x;", cxxRecordDecl(hasName("X")) matches the declaration of
+X, while varDecl(hasType(cxxRecordDecl(hasName("X")))) matches the
+declaration of x.
+
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and friend class X (matcher = friendDecl(hasType("X"))
+ class X {};
+ void y(X &x) { x; X z; }
+ class Y { friend class X; };
+
+Usable as: Matcher<Expr>, Matcher<ValueDecl>
+
+ + +Matcher<FriendDecl>hasTypeMatcher<QualType> InnerMatcher +
Matches if the expression's or declaration's type matches a type
+matcher.
+
+Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
+            and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and U (matcher = typedefDecl(hasType(asString("int")))
+            and friend class X (matcher = friendDecl(hasType("X"))
+ class X {};
+ void y(X &x) { x; X z; }
+ typedef int U;
+ class Y { friend class X; };
+
+ + Matcher<FunctionDecl>hasAnyParameterMatcher<ParmVarDecl> InnerMatcher
Matches any parameter of a function or an ObjC method declaration or a
 block.
@@ -5571,6 +5687,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -5604,6 +5721,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -5637,6 +5755,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -5823,6 +5942,18 @@ Example matches y in x(y)
 
+Matcher<ObjCMessageExpr>hasReceiverMatcher<Expr> InnerMatcher +
Matches if the Objective-C message is sent to an instance,
+and the inner matcher matches on that instance.
+
+For example the method call in
+  NSString *x = @"hello";
+  [x containsString:@"h"];
+is matched by
+objcMessageExpr(hasReceiver(declRefExpr(to(varDecl(hasName("x"))))))
+
+ + Matcher<ObjCMessageExpr>hasReceiverTypeMatcher<QualType> InnerMatcher
Matches on the receiver of an ObjectiveC Message expression.
 
@@ -5985,6 +6116,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -6066,6 +6198,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -6218,6 +6351,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -6340,6 +6474,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -6393,6 +6528,7 @@ The associated declaration is:
 - for MemberExpr, the declaration of the referenced member
 - for CXXConstructExpr, the declaration of the constructor
 - for CXXNewExpr, the declaration of the operator new
+- for ObjCIvarExpr, the declaration of the ivar
 
 For type nodes, hasDeclaration will generally match the declaration of the
 sugared type. Given
@@ -6432,16 +6568,18 @@ Usable as: Any Matcher
 
-Matcher<TypedefNameDecl>hasTypeMatcher<QualType> InnerMatcher -
Matches if the expression's or declaration's type matches a type
+Matcher<TypedefNameDecl>hasTypeMatcher<QualType> InnerMatcher
+
Matches if the expression's or declaration's type matches a type
 matcher.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
             and U (matcher = typedefDecl(hasType(asString("int")))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
  typedef int U;
+ class Y { friend class X; };
 
@@ -6455,6 +6593,7 @@ The associated declaration is: - for MemberExpr, the declaration of the referenced member - for CXXConstructExpr, the declaration of the constructor - for CXXNewExpr, the declaration of the operator new +- for ObjCIvarExpr, the declaration of the ivar For type nodes, hasDeclaration will generally match the declaration of the sugared type. Given @@ -6485,7 +6624,7 @@ type of the matched node. For example, in: class A {}; using B = A; -The matcher type(hasUnqualifeidDesugaredType(recordType())) matches +The matcher type(hasUnqualifiedDesugaredType(recordType())) matches both B and A.
@@ -6519,6 +6658,7 @@ The associated declaration is: - for MemberExpr, the declaration of the referenced member - for CXXConstructExpr, the declaration of the constructor - for CXXNewExpr, the declaration of the operator new +- for ObjCIvarExpr, the declaration of the ivar For type nodes, hasDeclaration will generally match the declaration of the sugared type. Given @@ -6564,8 +6704,8 @@ usingDecl(hasAnyUsingShadowDecl(hasTargetDecl(functionDecl()))) matches using X::b but not using X::a -Matcher<ValueDecl>hasTypeMatcher<Decl> InnerMatcher -
Overloaded to match the declaration of the expression's or value
+Matcher<ValueDecl>hasTypeMatcher<Decl> InnerMatcher
+
Overloaded to match the declaration of the expression's or value
 declaration's type.
 
 In case of a value declaration (for example a variable declaration),
@@ -6576,23 +6716,27 @@ declaration of x.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
+ class Y { friend class X; };
 
 Usable as: Matcher<Expr>, Matcher<ValueDecl>
 
-Matcher<ValueDecl>hasTypeMatcher<QualType> InnerMatcher -
Matches if the expression's or declaration's type matches a type
+Matcher<ValueDecl>hasTypeMatcher<QualType> InnerMatcher
+
Matches if the expression's or declaration's type matches a type
 matcher.
 
 Example matches x (matcher = expr(hasType(cxxRecordDecl(hasName("X")))))
             and z (matcher = varDecl(hasType(cxxRecordDecl(hasName("X")))))
             and U (matcher = typedefDecl(hasType(asString("int")))
+            and friend class X (matcher = friendDecl(hasType("X"))
  class X {};
  void y(X &x) { x; X z; }
  typedef int U;
+ class Y { friend class X; };
 
diff --git a/docs/MemorySanitizer.rst b/docs/MemorySanitizer.rst index 5bb19ed8a509128df0680399bd53f022339fd4f7..4e033fa1941d82f1218779dd9849e75f21a5d626 100644 --- a/docs/MemorySanitizer.rst +++ b/docs/MemorySanitizer.rst @@ -185,7 +185,11 @@ self-built instrumented libc++ (as a replacement for libstdc++). Supported Platforms =================== -MemorySanitizer is supported on Linux x86\_64/MIPS64/AArch64. +MemorySanitizer is supported on the following OS: + +* Linux +* NetBSD +* FreeBSD Limitations =========== diff --git a/docs/OpenMPSupport.rst b/docs/OpenMPSupport.rst index f34049473f825049941a858dee6cc35317824545..e8ec1e371b0498d941bb6839b377f091b3b4899c 100644 --- a/docs/OpenMPSupport.rst +++ b/docs/OpenMPSupport.rst @@ -10,13 +10,15 @@ .. role:: partial .. role:: good +.. contents:: + :local: + ================== OpenMP Support ================== -Clang fully supports OpenMP 3.1 + some elements of OpenMP 4.5. Clang supports offloading to X86_64, AArch64 and PPC64[LE] devices. -Support for Cuda devices is not ready yet. -The status of major OpenMP 4.5 features support in Clang. +Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64, +PPC64[LE] and has `basic support for Cuda devices`_. Standalone directives ===================== @@ -35,7 +37,7 @@ Standalone directives * #pragma omp target: :good:`Complete`. -* #pragma omp declare target: :partial:`Partial`. No full codegen support. +* #pragma omp declare target: :good:`Complete`. * #pragma omp teams: :good:`Complete`. @@ -64,5 +66,66 @@ Combined directives * #pragma omp target teams distribute parallel for [simd]: :good:`Complete`. -Clang does not support any constructs/updates from upcoming OpenMP 5.0 except for `reduction`-based clauses in the `task` and `target`-based directives. -In addition, the LLVM OpenMP runtime `libomp` supports the OpenMP Tools Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and mac OS. +Clang does not support any constructs/updates from upcoming OpenMP 5.0 except +for `reduction`-based clauses in the `task` and `target`-based directives. + +In addition, the LLVM OpenMP runtime `libomp` supports the OpenMP Tools +Interface (OMPT) on x86, x86_64, AArch64, and PPC64 on Linux, Windows, and mac OS. +ows, and mac OS. + +.. _basic support for Cuda devices: + +Cuda devices support +==================== + +Directives execution modes +-------------------------- + +Clang code generation for target regions supports two modes: the SPMD and +non-SPMD modes. Clang chooses one of these two modes automatically based on the +way directives and clauses on those directives are used. The SPMD mode uses a +simplified set of runtime functions thus increasing performance at the cost of +supporting some OpenMP features. The non-SPMD mode is the most generic mode and +supports all currently available OpenMP features. The compiler will always +attempt to use the SPMD mode wherever possible. SPMD mode will not be used if: + + - The target region contains an `if()` clause that refers to a `parallel` + directive. + + - The target region contains a `parallel` directive with a `num_threads()` + clause. + + - The target region contains user code (other than OpenMP-specific + directives) in between the `target` and the `parallel` directives. + +Data-sharing modes +------------------ + +Clang supports two data-sharing models for Cuda devices: `Generic` and `Cuda` +modes. The default mode is `Generic`. `Cuda` mode can give an additional +performance and can be activated using the `-fopenmp-cuda-mode` flag. In +`Generic` mode all local variables that can be shared in the parallel regions +are stored in the global memory. In `Cuda` mode local variables are not shared +between the threads and it is user responsibility to share the required data +between the threads in the parallel regions. + +Features not supported or with limited support for Cuda devices +--------------------------------------------------------------- + +- Reductions across the teams are not supported yet. + +- Cancellation constructs are not supported. + +- Doacross loop nest is not supported. + +- User-defined reductions are supported only for trivial types. + +- Nested parallelism: inner parallel regions are executed sequentially. + +- Static linking of libraries containing device code is not supported yet. + +- Automatic translation of math functions in target regions to device-specific + math functions is not implemented yet. + +- Debug information for OpenMP target regions is not supported yet. + diff --git a/docs/RAVFrontendAction.rst b/docs/RAVFrontendAction.rst index c37d3c0e812ec26b9d2a8748ed41d7e87c9a3933..dea23733bc4896dfb76e5e81150a080355a94704 100644 --- a/docs/RAVFrontendAction.rst +++ b/docs/RAVFrontendAction.rst @@ -128,7 +128,7 @@ locations: if (Declaration->getQualifiedNameAsString() == "n::m::C") { // getFullLoc uses the ASTContext's SourceManager to resolve the source // location and break it up into its line and column parts. - FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocStart()); + FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getBeginLoc()); if (FullLocation.isValid()) llvm::outs() << "Found declaration at " << FullLocation.getSpellingLineNumber() << ":" @@ -160,7 +160,7 @@ Now we can combine all of the above into a small example program: bool VisitCXXRecordDecl(CXXRecordDecl *Declaration) { if (Declaration->getQualifiedNameAsString() == "n::m::C") { - FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getLocStart()); + FullSourceLoc FullLocation = Context->getFullLoc(Declaration->getBeginLoc()); if (FullLocation.isValid()) llvm::outs() << "Found declaration at " << FullLocation.getSpellingLineNumber() << ":" diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 84145554647327edfa5086473794cfebb1349450..b215995e7d3242f8a7d5923b741f62f684c839bc 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -1,5 +1,5 @@ ======================================= -Clang 7.0.0 (In-Progress) Release Notes +Clang 8.0.0 (In-Progress) Release Notes ======================================= .. contents:: @@ -10,7 +10,7 @@ Written by the `LLVM Team `_ .. warning:: - These are in-progress notes for the upcoming Clang 7 release. + These are in-progress notes for the upcoming Clang 8 release. Release notes for previous releases can be found on `the Download Page `_. @@ -18,7 +18,7 @@ Introduction ============ This document contains the release notes for the Clang C/C++/Objective-C -frontend, part of the LLVM Compiler Infrastructure, release 7.0.0. Here we +frontend, part of the LLVM Compiler Infrastructure, release 8.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 @@ -35,7 +35,7 @@ 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 7.0.0? +What's New in Clang 8.0.0? ========================== Some of the major new features and improvements to Clang are listed @@ -46,72 +46,19 @@ sections with improvements to Clang's support for those languages. Major New Features ------------------ -- ... Improvements to Clang's diagnostics ^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^ -- ``-Wc++98-compat-extra-semi`` is a new flag, which was previously inseparable - from ``-Wc++98-compat-pedantic``. The latter still controls the new flag. - -- ``-Wextra-semi`` now also controls ``-Wc++98-compat-extra-semi``. - Please do note that if you pass ``-Wno-c++98-compat-pedantic``, it implies - ``-Wno-c++98-compat-extra-semi``, so if you want that diagnostic, you need - to explicitly re-enable it (e.g. by appending ``-Wextra-semi``). - -- ``-Wself-assign`` and ``-Wself-assign-field`` were extended to diagnose - self-assignment operations using overloaded operators (i.e. classes). - If you are doing such an assignment intentionally, e.g. in a unit test for - a data structure, the first warning can be disabled by passing - ``-Wno-self-assign-overloaded``, also the warning can be suppressed by adding - ``*&`` to the right-hand side or casting it to the appropriate reference type. Non-comprehensive list of changes in this release ------------------------------------------------- -- Clang binary and libraries have been renamed from 7.0 to 7. - For example, the ``clang`` binary will be called ``clang-7`` - instead of ``clang-7.0``. - -- Clang implements a collection of recent fixes to the C++ standard's definition - of "standard-layout". In particular, a class is only considered to be - standard-layout if all base classes and the first data member (or bit-field) - can be laid out at offset zero. - -- Clang's handling of the GCC ``packed`` class attribute in C++ has been fixed - to apply only to non-static data members and not to base classes. This fixes - an ABI difference between Clang and GCC, but creates an ABI difference between - Clang 7 and earlier versions. The old behavior can be restored by setting - ``-fclang-abi-compat`` to ``6`` or earlier. - -- Clang implements the proposed resolution of LWG issue 2358, along with the - `corresponding change to the Itanium C++ ABI - `_, which make classes - containing only unnamed non-zero-length bit-fields be considered non-empty. - This is an ABI break compared to prior Clang releases, but makes Clang - generate code that is ABI-compatible with other compilers. The old - behavior can be restored by setting ``-fclang-abi-compat`` to ``6`` or - lower. - -- An existing tool named ``diagtool`` has been added to the release. As the - name suggests, it helps with dealing with diagnostics in ``clang``, such as - finding out the warning hierarchy, and which of them are enabled by default - or for a particular compiler invocation. - - ... New Compiler Flags ------------------ -- :option:`-fstrict-float-cast-overflow` and - :option:`-fno-strict-float-cast-overflow`. - - When a floating-point value is not representable in a destination integer - type, the code has undefined behavior according to the language standard. By - default, Clang will not guarantee any particular result in that case. With the - 'no-strict' option, Clang attempts to match the overflowing behavior of the - target's native float-to-int conversion instructions. - - ... Deprecated Compiler Flags @@ -125,12 +72,6 @@ future versions of Clang. Modified Compiler Flags ----------------------- -- Before Clang 7, we prepended the `#` character to the `--autocomplete` - argument to enable cc1 flags. For example, when the `-cc1` or `-Xclang` flag - is in the :program:`clang` invocation, the shell executed - `clang --autocomplete=#-`. Clang 7 now requires the - whole invocation including all flags to be passed to the `--autocomplete` like - this: `clang --autocomplete=-cc1,-xc++,-fsyn`. New Pragmas in Clang -------------------- @@ -141,19 +82,12 @@ Clang now supports the ... Attribute Changes in Clang -------------------------- -- Clang now supports function multiversioning with attribute 'target' on ELF - based x86/x86-64 environments by using indirect functions. This implementation - has a few minor limitations over the GCC implementation for the sake of AST - sanity, however it is otherwise compatible with existing code using this - feature for GCC. Consult the documentation for the target attribute for more - information. - - ... Windows Support --------------- -Clang's support for building native Windows programs ... +- ... C Language Changes in Clang @@ -191,24 +125,15 @@ OpenCL C Language Changes in Clang OpenMP Support in Clang ---------------------------------- -- ... CUDA Support in Clang --------------------- -- Clang will now try to locate the CUDA installation next to :program:`ptxas` - in the `PATH` environment variable. This behavior can be turned off by passing - the new flag `--cuda-path-ignore-env`. - -- Clang now supports generating object files with relocatable device code. This - feature needs to be enabled with `-fcuda-rdc` and my result in performance - penalties compared to whole program compilation. Please note that NVIDIA's - :program:`nvcc` must be used for linking. Internal API Changes -------------------- -These are major API changes that have happened since the 6.0.0 release of +These are major API changes that have happened since the 7.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. @@ -222,9 +147,6 @@ AST Matchers clang-format ------------ -- Clang-format will now support detecting and formatting code snippets in raw - string literals. This is configured through the `RawStringFormats` style - option. - ... @@ -241,10 +163,11 @@ Static Analyzer ... +.. _release-notes-ubsan: + Undefined Behavior Sanitizer (UBSan) ------------------------------------ -* ... Core Analysis Improvements ========================== diff --git a/docs/SafeStack.rst b/docs/SafeStack.rst index f01b75f5cb37c76fb344ecde459c32ea6753d164..b046aa6168981851bf4a312fe3bfdc470f304ff7 100644 --- a/docs/SafeStack.rst +++ b/docs/SafeStack.rst @@ -126,7 +126,7 @@ and link command lines. Supported Platforms ------------------- -SafeStack was tested on Linux, FreeBSD and MacOSX. +SafeStack was tested on Linux, NetBSD, FreeBSD and MacOSX. Low-level API ------------- @@ -165,11 +165,23 @@ never be stored on the heap, as it would leak the location of the SafeStack. This builtin function returns current unsafe stack pointer of the current thread. +``__builtin___get_unsafe_stack_bottom()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This builtin function returns a pointer to the bottom of the unsafe stack of the +current thread. + +``__builtin___get_unsafe_stack_top()`` +~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ + +This builtin function returns a pointer to the top of the unsafe stack of the +current thread. + ``__builtin___get_unsafe_stack_start()`` ~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~ -This builtin function returns a pointer to the start of the unsafe stack of the -current thread. +Deprecated: This builtin function is an alias for +``__builtin___get_unsafe_stack_bottom()``. Design ====== diff --git a/docs/SanitizerStats.rst b/docs/SanitizerStats.rst index cff68f6b5d53788b58a39a34579a1cb47cc39086..cbc3b37d31c53574ae32d855bd4cdfba9bf03069 100644 --- a/docs/SanitizerStats.rst +++ b/docs/SanitizerStats.rst @@ -56,7 +56,7 @@ Example: 10 A a; 11 g(&a); 12 } - $ clang++ -fsanitize=cfi -flto -fuse-ld=gold vcall.cc -fsanitize-stats -g + $ clang++ -fsanitize=cfi -fvisibility=hidden -flto -fuse-ld=gold vcall.cc -fsanitize-stats -g $ SANITIZER_STATS_PATH=a.stats ./a.out $ sanstats a.stats vcall.cc:6 _Z1gP1A cfi-vcall 1 diff --git a/docs/ThreadSanitizer.rst b/docs/ThreadSanitizer.rst index cfbaa63d6432847debdaebeb465e2739934c5372..d1e2c65ec5f1a7651f472c415b75ba4b77af4a2e 100644 --- a/docs/ThreadSanitizer.rst +++ b/docs/ThreadSanitizer.rst @@ -17,7 +17,12 @@ Build LLVM/Clang with `CMake `_. Supported Platforms ------------------- -ThreadSanitizer is supported on Linux x86_64 (tested on Ubuntu 12.04). +ThreadSanitizer is supported on the following OS: + +* Linux +* NetBSD +* FreeBSD + Support for other 64-bit architectures is possible, contributions are welcome. Support for 32-bit platforms is problematic and is not planned. diff --git a/docs/UndefinedBehaviorSanitizer.rst b/docs/UndefinedBehaviorSanitizer.rst index e9f85c24dde0ec56b4630d6a0e8df1d3495390bf..86d0193a23c25d144f6ef92e2b5b1aad229210ea 100644 --- a/docs/UndefinedBehaviorSanitizer.rst +++ b/docs/UndefinedBehaviorSanitizer.rst @@ -89,6 +89,12 @@ Available checks are: - ``-fsanitize=function``: Indirect call of a function through a function pointer of the wrong type (Darwin/Linux, C++ and x86/x86_64 only). + - ``-fsanitize=implicit-integer-truncation``: Implicit conversion from + integer of larger bit width to smaller bit width, if that results in data + loss. That is, if the demoted value, after casting back to the original + width, is not equal to the original value before the downcast. + Issues caught by this sanitizer are not undefined behavior, + but are often unintentional. - ``-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. @@ -121,15 +127,21 @@ Available checks are: unsigned overflow in C++. You can use ``-fsanitize=shift-base`` or ``-fsanitize=shift-exponent`` to check only left-hand side or right-hand side of shift operation, respectively. - - ``-fsanitize=signed-integer-overflow``: Signed integer overflow, - including all the checks added by ``-ftrapv``, and checking for - overflow in signed division (``INT_MIN / -1``). + - ``-fsanitize=signed-integer-overflow``: Signed integer overflow, where the + result of a signed integer computation cannot be represented in its type. + This includes all the checks covered by ``-ftrapv``, as well as checks for + signed division overflow (``INT_MIN/-1``), but not checks for + lossy implicit conversions performed before the computation + (see ``-fsanitize=implicit-conversion``). Both of these two issues are + handled by ``-fsanitize=implicit-conversion`` group of checks. - ``-fsanitize=unreachable``: If control flow reaches an unreachable program point. - - ``-fsanitize=unsigned-integer-overflow``: Unsigned integer - overflows. Note that unlike signed integer overflow, unsigned integer - is not undefined behavior. However, while it has well-defined semantics, - it is often unintentional, so UBSan offers to catch it. + - ``-fsanitize=unsigned-integer-overflow``: Unsigned integer overflow, where + the result of an unsigned integer computation cannot be represented in its + type. Unlike signed integer overflow, this is not undefined behavior, but + it is often unintentional. This sanitizer does not check for lossy implicit + conversions performed before such a computation + (see ``-fsanitize=implicit-conversion``). - ``-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 @@ -140,11 +152,17 @@ Available checks are: You can also use the following check groups: - ``-fsanitize=undefined``: All of the checks listed above other than - ``unsigned-integer-overflow`` and the ``nullability-*`` checks. + ``unsigned-integer-overflow``, ``implicit-conversion`` and the + ``nullability-*`` group of checks. - ``-fsanitize=undefined-trap``: Deprecated alias of ``-fsanitize=undefined``. - ``-fsanitize=integer``: Checks for undefined or suspicious integer behavior (e.g. unsigned integer overflow). + Enables ``signed-integer-overflow``, ``unsigned-integer-overflow``, + ``shift``, ``integer-divide-by-zero``, and ``implicit-integer-truncation``. + - ``-fsanitize=implicit-conversion``: Checks for suspicious behaviours of + implicit conversions. + Currently, only ``-fsanitize=implicit-integer-truncation`` is implemented. - ``-fsanitize=nullability``: Enables ``nullability-arg``, ``nullability-assign``, and ``nullability-return``. While violating nullability does not have undefined behavior, it is often unintentional, @@ -180,6 +198,13 @@ will need to: ``UBSAN_OPTIONS=print_stacktrace=1``. #. Make sure ``llvm-symbolizer`` binary is in ``PATH``. +Silencing Unsigned Integer Overflow +=================================== +To silence reports from unsigned integer overflow, you can set +``UBSAN_OPTIONS=silence_unsigned_overflow=1``. This feature, combined with +``-fsanitize-recover=unsigned-integer-overflow``, is particularly useful for +providing fuzzing signal without blowing up logs. + Issue Suppression ================= @@ -245,17 +270,11 @@ UndefinedBehaviorSanitizer is supported on the following OS: * Android * Linux +* NetBSD * FreeBSD +* OpenBSD * OS X 10.6 onwards -and for the following architectures: - -* i386/x86\_64 -* ARM -* AArch64 -* PowerPC64 -* MIPS/MIPS64 - Current Status ============== diff --git a/docs/UsersManual.rst b/docs/UsersManual.rst index 9778b1654de9e285e3566683320b7468fcd73c65..363bb4e461a6f23b3b616915f8220f82de6a9bcc 100644 --- a/docs/UsersManual.rst +++ b/docs/UsersManual.rst @@ -1269,6 +1269,12 @@ are listed below. devirtualization and virtual constant propagation, for classes with :doc:`hidden LTO visibility `. Requires ``-flto``. +.. option:: -fforce-emit-vtables + + In order to improve devirtualization, forces emitting of vtables even in + modules where it isn't necessary. It causes more inline virtual functions + to be emitted. + .. option:: -fno-assume-sane-operator-new Don't assume that the C++'s new operator is sane. @@ -1376,6 +1382,15 @@ are listed below. // value of -fmax-type-align. } +.. option:: -faddrsig, -fno-addrsig + + Controls whether Clang emits an address-significance table into the object + file. Address-significance tables allow linkers to implement `safe ICF + `_ without the false + positives that can result from other implementation techniques such as + relocation scanning. Address-significance tables are enabled by default + on ELF targets when using the integrated assembler. This flag currently + only has an effect on ELF targets. Profile Guided Optimization --------------------------- @@ -2110,10 +2125,15 @@ Controlling implementation limits Sets the limit for recursive constexpr function invocations to N. The default is 512. +.. option:: -fconstexpr-steps=N + + Sets the limit for the number of full-expressions evaluated in a single + constant expression evaluation. The default is 1048576. + .. option:: -ftemplate-depth=N Sets the limit for recursively nested template instantiations to N. The - default is 256. + default is 1024. .. option:: -foperator-arrow-depth=N @@ -2135,13 +2155,8 @@ Objective-C++ Language Features OpenMP Features =============== -Clang supports all OpenMP 3.1 directives and clauses. In addition, some -features of OpenMP 4.0 are supported. For example, ``#pragma omp simd``, -``#pragma omp for simd``, ``#pragma omp parallel for simd`` directives, extended -set of atomic constructs, ``proc_bind`` clause for all parallel-based -directives, ``depend`` clause for ``#pragma omp task`` directive (except for -array sections), ``#pragma omp cancel`` and ``#pragma omp cancellation point`` -directives, and ``#pragma omp taskgroup`` directive. +Clang supports all OpenMP 4.5 directives and clauses. See :doc:`OpenMPSupport` +for additional details. Use `-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with `-fno-openmp`. @@ -2763,6 +2778,7 @@ Execute ``clang-cl /?`` to see a list of supported options: /Brepro Emit an object file which can be reproduced over time /C Don't discard comments when preprocessing /c Compile only + /d1PP Retain macro definitions in /E mode /d1reportAllClassLayout Dump record layout information /diagnostics:caret Enable caret and column diagnostics (on by default) /diagnostics:classic Disable column and caret diagnostics @@ -2796,6 +2812,7 @@ Execute ``clang-cl /?`` to see a list of supported options: /GS- Disable buffer security check /GS Enable buffer security check /Gs Set stack probe size + /guard: Enable Control Flow Guard with /guard:cf /Gv Set __vectorcall as a default calling convention /Gw- Don't put each data item in its own section /Gw Put each data item in its own section @@ -2851,6 +2868,7 @@ Execute ``clang-cl /?`` to see a list of supported options: /WX- Do not treat warnings as errors /WX Treat warnings as errors /w Disable all warnings + /X Don't add %INCLUDE% to the include search path /Y- Disable precompiled headers, overrides /Yc and /Yu /Yc Generate a pch file for all code up to and including /Yu Load a pch file and use it instead of all code up to and including @@ -2874,8 +2892,15 @@ Execute ``clang-cl /?`` to see a list of supported options: OPTIONS: -### Print (but do not run) the commands to run for this compilation --analyze Run the static analyzer + -faddrsig Emit an address-significance table -fansi-escape-codes Use ANSI escape codes for diagnostics + -fblocks Enable the 'blocks' language feature + -fcf-protection= Instrument control-flow architecture protection. Options: return, branch, full, none. + -fcf-protection Enable cf-protection in 'full' mode -fcolor-diagnostics Use colors in diagnostics + -fcomplete-member-pointers + Require member pointer base types to be complete if they would be significant under the Microsoft ABI + -fcoverage-mapping Generate coverage mapping to enable code coverage analysis -fdebug-macro Emit macro debug information -fdelayed-template-parsing Parse templated function definitions at the end of the translation unit @@ -2885,6 +2910,7 @@ Execute ``clang-cl /?`` to see a list of supported options: Print fix-its in machine parseable form -flto= Set LTO mode to either 'full' or 'thin' -flto Enable LTO in 'full' mode + -fmerge-all-constants Allow merging of constants -fms-compatibility-version= Dot-separated value representing the Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default)) @@ -2892,9 +2918,17 @@ Execute ``clang-cl /?`` to see a list of supported options: -fms-extensions Accept some non-standard constructs supported by the Microsoft compiler -fmsc-version= Microsoft compiler version number to report in _MSC_VER (0 = don't define it (default)) + -fno-addrsig Don't emit an address-significance table + -fno-builtin- Disable implicit builtin knowledge of a specific function + -fno-builtin Disable implicit builtin knowledge of functions + -fno-complete-member-pointers + Do not require member pointer base types to be complete if they would be significant under the Microsoft ABI + -fno-coverage-mapping Disable code coverage analysis -fno-debug-macro Do not emit macro debug information -fno-delayed-template-parsing Disable delayed template parsing + -fno-sanitize-address-poison-class-member-array-new-cookie + Disable poisoning array cookies when using class member operator new[] in AddressSanitizer -fno-sanitize-address-use-after-scope Disable use-after-scope detection in AddressSanitizer -fno-sanitize-blacklist Don't use blacklist file for sanitizers @@ -2930,6 +2964,8 @@ Execute ``clang-cl /?`` to see a list of supported options: Level of field padding for AddressSanitizer -fsanitize-address-globals-dead-stripping Enable linker dead stripping of globals in AddressSanitizer + -fsanitize-address-poison-class-member-array-new-cookie + Enable poisoning array cookies when using class member operator new[] in AddressSanitizer -fsanitize-address-use-after-scope Enable use-after-scope detection in AddressSanitizer -fsanitize-blacklist= diff --git a/docs/analyzer/RegionStore.txt b/docs/analyzer/RegionStore.txt index 5d37cf7bed99ead60081cea77c896e04ed8e103c..ef994b6401e26964577c2d532bc70ba6afe1d903 100644 --- a/docs/analyzer/RegionStore.txt +++ b/docs/analyzer/RegionStore.txt @@ -118,7 +118,7 @@ sometimes zero, for static data, or "uninitialized", for stack variables). int manyInts[10]; manyInts[1] = 42; // Creates a Direct binding for manyInts[1]. print(manyInts[1]); // Retrieves the Direct binding for manyInts[1]; - print(manyInts[0]); // There is no Direct binding for manyInts[1]. + print(manyInts[0]); // There is no Direct binding for manyInts[0]. // Is there a Default binding for the entire array? // There is not, but it is a stack variable, so we use // "uninitialized" as the default value (and emit a @@ -166,6 +166,6 @@ Here's a concrete example: return p2.x; // The binding for FieldRegion 'p2.x' is requested. // There is no Direct binding, so we look for a Default // binding to 'p2' and find the LCV. - // Because it's an LCV, we look at our requested region + // Because it's a LCV, we look at our requested region // and see that it's the '.x' field. We ask for the value // of 'p.x' within the snapshot, and get back 42. diff --git a/docs/conf.py b/docs/conf.py index b38c93af23c205dbd515e31d3522314a58ebd567..dc69f8a848ef4f5bae4317bce710d6a147e6f7c9 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 = '7' +version = '8' # The full version, including alpha/beta/rc tags. -release = '7' +release = '8' # The language for content autogenerated by Sphinx. Refer to documentation # for a list of supported languages. diff --git a/docs/tools/dump_format_style.py b/docs/tools/dump_format_style.py index 1ca050e062b7496134709b159c0f5e81a74e54af..3d61227f736172690b5a481548704ef5d6b0783f 100755 --- a/docs/tools/dump_format_style.py +++ b/docs/tools/dump_format_style.py @@ -10,6 +10,7 @@ import urllib2 CLANG_DIR = os.path.join(os.path.dirname(__file__), '../..') FORMAT_STYLE_FILE = os.path.join(CLANG_DIR, 'include/clang/Format/Format.h') +INCLUDE_STYLE_FILE = os.path.join(CLANG_DIR, 'include/clang/Tooling/Inclusions/IncludeStyle.h') DOC_FILE = os.path.join(CLANG_DIR, 'docs/ClangFormatStyleOptions.rst') @@ -115,7 +116,7 @@ def read_options(header): for line in header: line = line.strip() if state == State.BeforeStruct: - if line == 'struct FormatStyle {': + if line == 'struct FormatStyle {' or line == 'struct IncludeStyle {': state = State.InStruct elif state == State.InStruct: if line.startswith('///'): @@ -188,6 +189,7 @@ def read_options(header): return options options = read_options(open(FORMAT_STYLE_FILE)) +options += read_options(open(INCLUDE_STYLE_FILE)) options = sorted(options, key=lambda x: x.name) options_text = '\n\n'.join(map(str, options)) diff --git a/include/clang-c/BuildSystem.h b/include/clang-c/BuildSystem.h index c999dab36d93f418f4cf24968d2abfedab253280..3cfec388308c1fb6878252cbbf80925ac1414de1 100644 --- a/include/clang-c/BuildSystem.h +++ b/include/clang-c/BuildSystem.h @@ -66,7 +66,7 @@ clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay, */ CINDEX_LINKAGE enum CXErrorCode clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay, - int caseSensitive); + int caseSensitive); /** * Write out the \c CXVirtualFileOverlay object to a char buffer. diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h index ff14d6e729a5209d672164f69fd1a95a46a4b5cd..86383d13510b3cddd5d70f31a2ceae3a73166d7a 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 48 +#define CINDEX_VERSION_MINOR 50 #define CINDEX_VERSION_ENCODE(major, minor) ( \ ((major) * 10000) \ @@ -160,7 +160,7 @@ typedef struct CXVersion { int Major; /** * The minor version number, e.g., the '7' in '10.7.3'. This value - * will be negative if no minor version number was provided, e.g., for + * will be negative if no minor version number was provided, e.g., for * version '10'. */ int Minor; @@ -178,7 +178,6 @@ typedef struct CXVersion { * A negative value indicates that the cursor is not a function declaration. */ enum CXCursor_ExceptionSpecificationKind { - /** * The cursor has no exception specification. */ @@ -387,7 +386,7 @@ CINDEX_LINKAGE int clang_getFileUniqueID(CXFile file, CXFileUniqueID *outID); * multiple inclusions, either with the conventional * \#ifndef/\#define/\#endif macro guards or with \#pragma once. */ -CINDEX_LINKAGE unsigned +CINDEX_LINKAGE unsigned clang_isFileMultipleIncludeGuarded(CXTranslationUnit tu, CXFile file); /** @@ -786,7 +785,7 @@ typedef void *CXDiagnostic; * A group of CXDiagnostics. */ typedef void *CXDiagnosticSet; - + /** * Determine the number of diagnostics in a CXDiagnosticSet. */ @@ -802,7 +801,7 @@ CINDEX_LINKAGE unsigned clang_getNumDiagnosticsInSet(CXDiagnosticSet Diags); * via a call to \c clang_disposeDiagnostic(). */ CINDEX_LINKAGE CXDiagnostic clang_getDiagnosticInSet(CXDiagnosticSet Diags, - unsigned Index); + unsigned Index); /** * Describes the kind of error that occurred (if any) in a call to @@ -813,26 +812,26 @@ enum CXLoadDiag_Error { * Indicates that no error occurred. */ CXLoadDiag_None = 0, - + /** * Indicates that an unknown error occurred while attempting to * deserialize diagnostics. */ CXLoadDiag_Unknown = 1, - + /** * Indicates that the file containing the serialized diagnostics * could not be opened. */ CXLoadDiag_CannotLoad = 2, - + /** * Indicates that the serialized diagnostics file is invalid or * corrupt. */ CXLoadDiag_InvalidFile = 3 }; - + /** * Deserialize a set of diagnostics from a Clang diagnostics bitcode * file. @@ -856,7 +855,7 @@ CINDEX_LINKAGE CXDiagnosticSet clang_loadDiagnostics(const char *file, CINDEX_LINKAGE void clang_disposeDiagnosticSet(CXDiagnosticSet Diags); /** - * Retrieve the child diagnostics of a CXDiagnostic. + * Retrieve the child diagnostics of a CXDiagnostic. * * This CXDiagnosticSet does not need to be released by * clang_disposeDiagnosticSet. @@ -888,7 +887,7 @@ CINDEX_LINKAGE CXDiagnostic clang_getDiagnostic(CXTranslationUnit Unit, * \param Unit the translation unit to query. */ CINDEX_LINKAGE CXDiagnosticSet - clang_getDiagnosticSetFromTU(CXTranslationUnit Unit); + clang_getDiagnosticSetFromTU(CXTranslationUnit Unit); /** * Destroy a diagnostic. @@ -934,7 +933,7 @@ enum CXDiagnosticDisplayOptions { * \c -fdiagnostics-print-source-range-info. */ CXDiagnostic_DisplaySourceRanges = 0x04, - + /** * Display the option name associated with this diagnostic, if any. * @@ -943,12 +942,12 @@ enum CXDiagnosticDisplayOptions { * \c -fdiagnostics-show-option. */ CXDiagnostic_DisplayOption = 0x08, - + /** * Display the category number associated with this diagnostic, if any. * * The category number is displayed within brackets after the diagnostic text. - * This option corresponds to the clang flag + * This option corresponds to the clang flag * \c -fdiagnostics-show-category=id. */ CXDiagnostic_DisplayCategoryId = 0x10, @@ -957,7 +956,7 @@ enum CXDiagnosticDisplayOptions { * Display the category name associated with this diagnostic, if any. * * The category name is displayed within brackets after the diagnostic text. - * This option corresponds to the clang flag + * This option corresponds to the clang flag * \c -fdiagnostics-show-category=name. */ CXDiagnostic_DisplayCategoryName = 0x20 @@ -1019,7 +1018,7 @@ CINDEX_LINKAGE CXString clang_getDiagnosticSpelling(CXDiagnostic); * diagnostic (if any). * * \returns A string that contains the command-line option used to enable this - * warning, such as "-Wconversion" or "-pedantic". + * warning, such as "-Wconversion" or "-pedantic". */ CINDEX_LINKAGE CXString clang_getDiagnosticOption(CXDiagnostic Diag, CXString *Disable); @@ -1028,7 +1027,7 @@ CINDEX_LINKAGE CXString clang_getDiagnosticOption(CXDiagnostic Diag, * Retrieve the category number for this diagnostic. * * Diagnostics can be categorized into groups along with other, related - * diagnostics (e.g., diagnostics under the same warning flag). This routine + * diagnostics (e.g., diagnostics under the same warning flag). This routine * retrieves the category number for the given diagnostic. * * \returns The number of the category that contains this diagnostic, or zero @@ -1041,7 +1040,7 @@ CINDEX_LINKAGE unsigned clang_getDiagnosticCategory(CXDiagnostic); * is now deprecated. Use clang_getDiagnosticCategoryText() * instead. * - * \param Category A diagnostic category number, as returned by + * \param Category A diagnostic category number, as returned by * \c clang_getDiagnosticCategory(). * * \returns The name of the given diagnostic category. @@ -1055,7 +1054,7 @@ CXString clang_getDiagnosticCategoryName(unsigned Category); * \returns The text of the given diagnostic category. */ CINDEX_LINKAGE CXString clang_getDiagnosticCategoryText(CXDiagnostic); - + /** * Determine the number of source ranges associated with the given * diagnostic. @@ -1242,9 +1241,9 @@ enum CXTranslationUnit_Flags { * intent of producing a precompiled header. */ CXTranslationUnit_Incomplete = 0x02, - + /** - * Used to indicate that the translation unit should be built with an + * Used to indicate that the translation unit should be built with an * implicit precompiled header for the preamble. * * An implicit precompiled header is used as an optimization when a @@ -1258,7 +1257,7 @@ enum CXTranslationUnit_Flags { * precompiled header to improve parsing performance. */ CXTranslationUnit_PrecompiledPreamble = 0x04, - + /** * Used to indicate that the translation unit should cache some * code-completion results with each reparse of the source file. @@ -1327,12 +1326,22 @@ enum CXTranslationUnit_Flags { CXTranslationUnit_SingleFileParse = 0x400, /** - * \brief Used in combination with CXTranslationUnit_SkipFunctionBodies to + * Used in combination with CXTranslationUnit_SkipFunctionBodies to * constrain the skipping of function bodies to the preamble. * * The function bodies of the main file are not skipped. */ - CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800 + CXTranslationUnit_LimitSkipFunctionBodiesToPreamble = 0x800, + + /** + * Used to indicate that attributed types should be included in CXType. + */ + CXTranslationUnit_IncludeAttributedTypes = 0x1000, + + /** + * Used to indicate that implicit attributes should be visited. + */ + CXTranslationUnit_VisitImplicitAttributes = 0x2000 }; /** @@ -1343,7 +1352,7 @@ enum CXTranslationUnit_Flags { * to indicate that the translation unit is likely to be reparsed many times, * either explicitly (via \c clang_reparseTranslationUnit()) or implicitly * (e.g., by code completion (\c clang_codeCompletionAt())). The returned flag - * set contains an unspecified set of optimizations (e.g., the precompiled + * set contains an unspecified set of optimizations (e.g., the precompiled * preamble) geared toward improving the performance of these routines. The * set of optimizations enabled may change from one version to the next. */ @@ -1374,7 +1383,7 @@ clang_parseTranslationUnit(CXIndex CIdx, * command-line arguments so that the compilation can be configured in the same * way that the compiler is configured on the command line. * - * \param CIdx The index object with which the translation unit will be + * \param CIdx The index object with which the translation unit will be * associated. * * \param source_filename The name of the source file to load, or NULL if the @@ -1383,7 +1392,7 @@ clang_parseTranslationUnit(CXIndex CIdx, * \param command_line_args The command-line arguments that would be * passed to the \c clang executable if it were being invoked out-of-process. * These command-line options will be parsed and will affect how the translation - * unit is parsed. Note that the following options are ignored: '-c', + * unit is parsed. Note that the following options are ignored: '-c', * '-emit-ast', '-fsyntax-only' (which is the default), and '-o \'. * * \param num_command_line_args The number of command-line arguments in @@ -1463,32 +1472,32 @@ enum CXSaveError { * Indicates that no error occurred while saving a translation unit. */ CXSaveError_None = 0, - + /** * Indicates that an unknown error occurred while attempting to save * the file. * - * This error typically indicates that file I/O failed when attempting to + * This error typically indicates that file I/O failed when attempting to * write the file. */ CXSaveError_Unknown = 1, - + /** * Indicates that errors during translation prevented this attempt * to save the translation unit. - * + * * Errors that prevent the translation unit from being saved can be * extracted using \c clang_getNumDiagnostics() and \c clang_getDiagnostic(). */ CXSaveError_TranslationErrors = 2, - + /** * Indicates that the translation unit to be saved was somehow * invalid (e.g., NULL). */ CXSaveError_InvalidTU = 3 }; - + /** * Saves a translation unit into a serialized representation of * that translation unit on disk. @@ -1509,7 +1518,7 @@ enum CXSaveError { * CXSaveTranslationUnit_XXX flags. * * \returns A value that will match one of the enumerators of the CXSaveError - * enumeration. Zero (CXSaveError_None) indicates that the translation unit was + * enumeration. Zero (CXSaveError_None) indicates that the translation unit was * saved successfully, while a non-zero value indicates that a problem occurred. */ CINDEX_LINKAGE int clang_saveTranslationUnit(CXTranslationUnit TU, @@ -1543,7 +1552,7 @@ enum CXReparse_Flags { */ CXReparse_None = 0x0 }; - + /** * Returns the set of flags that is suitable for reparsing a translation * unit. @@ -1551,7 +1560,7 @@ enum CXReparse_Flags { * The set of flags returned provide options for * \c clang_reparseTranslationUnit() by default. The returned flag * set contains an unspecified set of optimizations geared toward common uses - * of reparsing. The set of optimizations enabled may change from one version + * of reparsing. The set of optimizations enabled may change from one version * to the next. */ CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU); @@ -1563,17 +1572,17 @@ CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU); * created the given translation unit, for example because those source files * have changed (either on disk or as passed via \p unsaved_files). The * source code will be reparsed with the same command-line options as it - * was originally parsed. + * was originally parsed. * * Reparsing a translation unit invalidates all cursors and source locations * that refer into that translation unit. This makes reparsing a translation * unit semantically equivalent to destroying the translation unit and then * creating a new translation unit with the same command-line arguments. - * However, it may be more efficient to reparse a translation + * However, it may be more efficient to reparse a translation * unit using this routine. * * \param TU The translation unit whose contents will be re-parsed. The - * translation unit must originally have been built with + * translation unit must originally have been built with * \c clang_createTranslationUnitFromSourceFile(). * * \param num_unsaved_files The number of unsaved file entries in \p @@ -1584,7 +1593,7 @@ CINDEX_LINKAGE unsigned clang_defaultReparseOptions(CXTranslationUnit TU); * those files. The contents and name of these files (as specified by * CXUnsavedFile) are copied when necessary, so the client only needs to * guarantee their validity until the call to this function returns. - * + * * \param options A bitset of options composed of the flags in CXReparse_Flags. * The function \c clang_defaultReparseOptions() produces a default set of * options recommended for most uses, based on the translation unit. @@ -1612,8 +1621,8 @@ enum CXTUResourceUsageKind { CXTUResourceUsage_AST_SideTables = 6, CXTUResourceUsage_SourceManager_Membuffer_Malloc = 7, CXTUResourceUsage_SourceManager_Membuffer_MMap = 8, - CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9, - CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10, + CXTUResourceUsage_ExternalASTSource_Membuffer_Malloc = 9, + CXTUResourceUsage_ExternalASTSource_Membuffer_MMap = 10, CXTUResourceUsage_Preprocessor = 11, CXTUResourceUsage_PreprocessingRecord = 12, CXTUResourceUsage_SourceManager_DataStructures = 13, @@ -1635,8 +1644,8 @@ const char *clang_getTUResourceUsageName(enum CXTUResourceUsageKind kind); typedef struct CXTUResourceUsageEntry { /* The memory usage category. */ - enum CXTUResourceUsageKind kind; - /* Amount of resources used. + enum CXTUResourceUsageKind kind; + /* Amount of resources used. The units will depend on the resource kind. */ unsigned long amount; } CXTUResourceUsageEntry; @@ -1819,7 +1828,7 @@ enum CXCursorKind { */ CXCursor_TypeRef = 43, CXCursor_CXXBaseSpecifier = 44, - /** + /** * A reference to a class template, function template, template * template parameter, or class template partial specialization. */ @@ -1829,14 +1838,14 @@ enum CXCursorKind { */ CXCursor_NamespaceRef = 46, /** - * A reference to a member of a struct, union, or class that occurs in + * A reference to a member of a struct, union, or class that occurs in * some non-expression context, e.g., a designated initializer. */ CXCursor_MemberRef = 47, /** * A reference to a labeled statement. * - * This cursor kind is used to describe the jump to "start_over" in the + * This cursor kind is used to describe the jump to "start_over" in the * goto statement in the following example: * * \code @@ -1849,7 +1858,7 @@ enum CXCursorKind { * A label reference cursor refers to a label statement. */ CXCursor_LabelRef = 48, - + /** * A reference to a set of overloaded functions or function templates * that has not yet been resolved to a specific function or function template. @@ -1882,18 +1891,18 @@ enum CXCursorKind { * argument-dependent lookup (e.g., the "swap" function at the end of the * example). * - * The functions \c clang_getNumOverloadedDecls() and + * The functions \c clang_getNumOverloadedDecls() and * \c clang_getOverloadedDecl() can be used to retrieve the definitions * referenced by this cursor. */ CXCursor_OverloadedDeclRef = 49, - + /** - * A reference to a variable that occurs in some non-expression + * A reference to a variable that occurs in some non-expression * context, e.g., a C++ lambda capture list. */ CXCursor_VariableRef = 50, - + CXCursor_LastRef = CXCursor_VariableRef, /* Error conditions */ @@ -2153,7 +2162,7 @@ enum CXCursorKind { * \endcode */ CXCursor_LambdaExpr = 144, - + /** Objective-c Boolean Literal. */ CXCursor_ObjCBoolLiteralExpr = 145, @@ -2170,7 +2179,12 @@ enum CXCursorKind { */ CXCursor_ObjCAvailabilityCheckExpr = 148, - CXCursor_LastExpr = CXCursor_ObjCAvailabilityCheckExpr, + /** + * Fixed point literal + */ + CXCursor_FixedPointLiteral = 149, + + CXCursor_LastExpr = CXCursor_FixedPointLiteral, /* Statements */ CXCursor_FirstStmt = 200, @@ -2184,10 +2198,10 @@ enum CXCursorKind { * reported. */ CXCursor_UnexposedStmt = 200, - - /** A labelled statement in a function. + + /** A labelled statement in a function. * - * This cursor kind is used to describe the "start_over:" label statement in + * This cursor kind is used to describe the "start_over:" label statement in * the following example: * * \code @@ -2554,7 +2568,25 @@ enum CXCursorKind { CXCursor_VisibilityAttr = 417, CXCursor_DLLExport = 418, CXCursor_DLLImport = 419, - CXCursor_LastAttr = CXCursor_DLLImport, + CXCursor_NSReturnsRetained = 420, + CXCursor_NSReturnsNotRetained = 421, + CXCursor_NSReturnsAutoreleased = 422, + CXCursor_NSConsumesSelf = 423, + CXCursor_NSConsumed = 424, + CXCursor_ObjCException = 425, + CXCursor_ObjCNSObject = 426, + CXCursor_ObjCIndependentClass = 427, + CXCursor_ObjCPreciseLifetime = 428, + CXCursor_ObjCReturnsInnerPointer = 429, + CXCursor_ObjCRequiresSuper = 430, + CXCursor_ObjCRootClass = 431, + CXCursor_ObjCSubclassingRestricted = 432, + CXCursor_ObjCExplicitProtocolImpl = 433, + CXCursor_ObjCDesignatedInitializer = 434, + CXCursor_ObjCRuntimeVisible = 435, + CXCursor_ObjCBoxable = 436, + CXCursor_FlagEnum = 437, + CXCursor_LastAttr = CXCursor_FlagEnum, /* Preprocessing */ CXCursor_PreprocessingDirective = 500, @@ -2645,7 +2677,7 @@ CINDEX_LINKAGE int clang_Cursor_isNull(CXCursor cursor); * Compute a hash value for the given cursor. */ CINDEX_LINKAGE unsigned clang_hashCursor(CXCursor); - + /** * Retrieve the kind of the given cursor. */ @@ -2713,7 +2745,7 @@ CINDEX_LINKAGE unsigned clang_isTranslationUnit(enum CXCursorKind); * element, such as a preprocessor directive or macro instantiation. */ CINDEX_LINKAGE unsigned clang_isPreprocessing(enum CXCursorKind); - + /*** * Determine whether the given cursor represents a currently * unexposed piece of the AST (e.g., CXCursor_UnexposedStmt). @@ -2780,7 +2812,7 @@ CINDEX_LINKAGE enum CXVisibilityKind clang_getCursorVisibility(CXCursor cursor); * * \returns The availability of the cursor. */ -CINDEX_LINKAGE enum CXAvailabilityKind +CINDEX_LINKAGE enum CXAvailabilityKind clang_getCursorAvailability(CXCursor cursor); /** @@ -2826,10 +2858,10 @@ typedef struct CXPlatformAvailability { * * \param cursor The cursor to query. * - * \param always_deprecated If non-NULL, will be set to indicate whether the + * \param always_deprecated If non-NULL, will be set to indicate whether the * entity is deprecated on all platforms. * - * \param deprecated_message If non-NULL, will be set to the message text + * \param deprecated_message If non-NULL, will be set to the message text * provided along with the unconditional deprecation of this entity. The client * is responsible for deallocating this string. * @@ -2837,7 +2869,7 @@ typedef struct CXPlatformAvailability { * entity is unavailable on all platforms. * * \param unavailable_message If non-NULL, will be set to the message text - * provided along with the unconditional unavailability of this entity. The + * provided along with the unconditional unavailability of this entity. The * client is responsible for deallocating this string. * * \param availability If non-NULL, an array of CXPlatformAvailability instances @@ -2845,15 +2877,15 @@ typedef struct CXPlatformAvailability { * the number of platforms for which availability information is available (as * returned by this function) or \c availability_size, whichever is smaller. * - * \param availability_size The number of elements available in the + * \param availability_size The number of elements available in the * \c availability array. * * \returns The number of platforms (N) for which availability information is * available (which is unrelated to \c availability_size). * - * Note that the client is responsible for calling - * \c clang_disposeCXPlatformAvailability to free each of the - * platform-availability structures returned. There are + * Note that the client is responsible for calling + * \c clang_disposeCXPlatformAvailability to free each of the + * platform-availability structures returned. There are * \c min(N, availability_size) such structures. */ CINDEX_LINKAGE int @@ -2870,7 +2902,7 @@ clang_getCursorPlatformAvailability(CXCursor cursor, */ CINDEX_LINKAGE void clang_disposeCXPlatformAvailability(CXPlatformAvailability *availability); - + /** * Describe the "language" of the entity referred to by a cursor. */ @@ -2943,7 +2975,7 @@ CINDEX_LINKAGE unsigned clang_CXCursorSet_insert(CXCursorSet cset, * * The semantic parent of a cursor is the cursor that semantically contains * the given \p cursor. For many declarations, the lexical and semantic parents - * are equivalent (the lexical parent is returned by + * are equivalent (the lexical parent is returned by * \c clang_getCursorLexicalParent()). They diverge when declarations or * definitions are provided out-of-line. For example: * @@ -2978,7 +3010,7 @@ CINDEX_LINKAGE CXCursor clang_getCursorSemanticParent(CXCursor cursor); * * The lexical parent of a cursor is the cursor in which the given \p cursor * was actually written. For many declarations, the lexical and semantic parents - * are equivalent (the semantic parent is returned by + * are equivalent (the semantic parent is returned by * \c clang_getCursorSemanticParent()). They diverge when declarations or * definitions are provided out-of-line. For example: * @@ -3041,18 +3073,18 @@ CINDEX_LINKAGE CXCursor clang_getCursorLexicalParent(CXCursor cursor); * \param cursor A cursor representing an Objective-C or C++ * method. This routine will compute the set of methods that this * method overrides. - * + * * \param overridden A pointer whose pointee will be replaced with a * pointer to an array of cursors, representing the set of overridden * methods. If there are no overridden methods, the pointee will be - * set to NULL. The pointee must be freed via a call to + * set to NULL. The pointee must be freed via a call to * \c clang_disposeOverriddenCursors(). * * \param num_overridden A pointer to the number of overridden * functions, will be set to the number of overridden functions in the * array pointed to by \p overridden. */ -CINDEX_LINKAGE void clang_getOverriddenCursors(CXCursor cursor, +CINDEX_LINKAGE void clang_getOverriddenCursors(CXCursor cursor, CXCursor **overridden, unsigned *num_overridden); @@ -3067,7 +3099,7 @@ CINDEX_LINKAGE void clang_disposeOverriddenCursors(CXCursor *overridden); * cursor. */ CINDEX_LINKAGE CXFile clang_getIncludedFile(CXCursor cursor); - + /** * @} */ @@ -3128,7 +3160,7 @@ CINDEX_LINKAGE CXSourceRange clang_getCursorExtent(CXCursor); /** * @} */ - + /** * \defgroup CINDEX_TYPES Type information for CXCursors * @@ -3182,8 +3214,14 @@ enum CXTypeKind { CXType_Float128 = 30, CXType_Half = 31, CXType_Float16 = 32, + CXType_ShortAccum = 33, + CXType_Accum = 34, + CXType_LongAccum = 35, + CXType_UShortAccum = 36, + CXType_UAccum = 37, + CXType_ULongAccum = 38, CXType_FirstBuiltin = CXType_Void, - CXType_LastBuiltin = CXType_Float16, + CXType_LastBuiltin = CXType_ULongAccum, CXType_Complex = 100, CXType_Pointer = 101, @@ -3255,7 +3293,11 @@ enum CXTypeKind { CXType_OCLSampler = 157, CXType_OCLEvent = 158, CXType_OCLQueue = 159, - CXType_OCLReserveID = 160 + CXType_OCLReserveID = 160, + + CXType_ObjCObject = 161, + CXType_ObjCTypeParam = 162, + CXType_Attributed = 163 }; /** @@ -3571,7 +3613,7 @@ CINDEX_LINKAGE CXString clang_getDeclObjCTypeEncoding(CXCursor C); /** * Returns the Objective-C type encoding for the specified CXType. */ -CINDEX_LINKAGE CXString clang_Type_getObjCEncoding(CXType type); +CINDEX_LINKAGE CXString clang_Type_getObjCEncoding(CXType type); /** * Retrieve the spelling of a given CXTypeKind. @@ -3616,6 +3658,43 @@ CINDEX_LINKAGE int clang_getNumArgTypes(CXType T); */ CINDEX_LINKAGE CXType clang_getArgType(CXType T, unsigned i); +/** + * Retrieves the base type of the ObjCObjectType. + * + * If the type is not an ObjC object, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getObjCObjectBaseType(CXType T); + +/** + * Retrieve the number of protocol references associated with an ObjC object/id. + * + * If the type is not an ObjC object, 0 is returned. + */ +CINDEX_LINKAGE unsigned clang_Type_getNumObjCProtocolRefs(CXType T); + +/** + * Retrieve the decl for a protocol reference for an ObjC object/id. + * + * If the type is not an ObjC object or there are not enough protocol + * references, an invalid cursor is returned. + */ +CINDEX_LINKAGE CXCursor clang_Type_getObjCProtocolDecl(CXType T, unsigned i); + +/** + * Retreive the number of type arguments associated with an ObjC object. + * + * If the type is not an ObjC object, 0 is returned. + */ +CINDEX_LINKAGE unsigned clang_Type_getNumObjCTypeArgs(CXType T); + +/** + * Retrieve a type argument associated with an ObjC object. + * + * If the type is not an ObjC or the index is not valid, + * an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getObjCTypeArg(CXType T, unsigned i); + /** * Return 1 if the CXType is a variadic function type, and 0 otherwise. */ @@ -3689,6 +3768,33 @@ CINDEX_LINKAGE CXType clang_Type_getNamedType(CXType T); */ CINDEX_LINKAGE unsigned clang_Type_isTransparentTagTypedef(CXType T); +enum CXTypeNullabilityKind { + /** + * Values of this type can never be null. + */ + CXTypeNullability_NonNull = 0, + /** + * Values of this type can be null. + */ + CXTypeNullability_Nullable = 1, + /** + * Whether values of this type can be null is (explicitly) + * unspecified. This captures a (fairly rare) case where we + * can't conclude anything about the nullability of the type even + * though it has been considered. + */ + CXTypeNullability_Unspecified = 2, + /** + * Nullability is not applicable to this type. + */ + CXTypeNullability_Invalid = 3 +}; + +/** + * Retrieve the nullability kind of a pointer type. + */ +CINDEX_LINKAGE enum CXTypeNullabilityKind clang_Type_getNullability(CXType T); + /** * List the possible error codes for \c clang_Type_getSizeOf, * \c clang_Type_getAlignOf, \c clang_Type_getOffsetOf and @@ -3767,6 +3873,13 @@ CINDEX_LINKAGE long long clang_Type_getSizeOf(CXType T); */ CINDEX_LINKAGE long long clang_Type_getOffsetOf(CXType T, const char *S); +/** + * Return the type that was modified by this attributed type. + * + * If the type is not an attributed type, an invalid type is returned. + */ +CINDEX_LINKAGE CXType clang_Type_getModifiedType(CXType T); + /** * Return the offset of the field represented by the Cursor. * @@ -3831,7 +3944,7 @@ CINDEX_LINKAGE unsigned clang_Cursor_isBitField(CXCursor C); * CX_CXXBaseSpecifier is virtual. */ CINDEX_LINKAGE unsigned clang_isVirtualBase(CXCursor); - + /** * Represents the C++ access control level to a base class for a * cursor with kind CX_CXXBaseSpecifier. @@ -3876,7 +3989,7 @@ enum CX_StorageClass { CINDEX_LINKAGE enum CX_StorageClass clang_Cursor_getStorageClass(CXCursor); /** - * Determine the number of overloaded declarations referenced by a + * Determine the number of overloaded declarations referenced by a * \c CXCursor_OverloadedDeclRef cursor. * * \param cursor The cursor whose overloaded declarations are being queried. @@ -3895,18 +4008,18 @@ CINDEX_LINKAGE unsigned clang_getNumOverloadedDecls(CXCursor cursor); * \param index The zero-based index into the set of overloaded declarations in * the cursor. * - * \returns A cursor representing the declaration referenced by the given - * \c cursor at the specified \c index. If the cursor does not have an + * \returns A cursor representing the declaration referenced by the given + * \c cursor at the specified \c index. If the cursor does not have an * associated set of overloaded declarations, or if the index is out of bounds, * returns \c clang_getNullCursor(); */ -CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor, +CINDEX_LINKAGE CXCursor clang_getOverloadedDecl(CXCursor cursor, unsigned index); - + /** * @} */ - + /** * \defgroup CINDEX_ATTRIBUTES Information for attributes * @@ -4010,7 +4123,7 @@ CINDEX_LINKAGE unsigned clang_visitChildren(CXCursor parent, * The visitor should return one of the \c CXChildVisitResult values * to direct clang_visitChildrenWithBlock(). */ -typedef enum CXChildVisitResult +typedef enum CXChildVisitResult (^CXCursorVisitorBlock)(CXCursor cursor, CXCursor parent); /** @@ -4098,10 +4211,10 @@ CINDEX_LINKAGE CXString clang_getCursorSpelling(CXCursor); * Most of the times there is only one range for the complete spelling but for * Objective-C methods and Objective-C message expressions, there are multiple * pieces for each selector identifier. - * + * * \param pieceIndex the index of the spelling name piece. If this is greater * than the actual number of pieces, it will return a NULL (invalid) range. - * + * * \param options Reserved. */ CINDEX_LINKAGE CXSourceRange clang_Cursor_getSpellingNameRange(CXCursor, @@ -4195,11 +4308,11 @@ CINDEX_LINKAGE CXString clang_getCursorPrettyPrinted(CXCursor Cursor, * Retrieve the display name for the entity referenced by this cursor. * * The display name contains extra information that helps identify the cursor, - * such as the parameters of a function or template or the arguments of a + * such as the parameters of a function or template or the arguments of a * class template specialization. */ CINDEX_LINKAGE CXString clang_getCursorDisplayName(CXCursor); - + /** For a cursor that is a reference, retrieve a cursor representing the * entity that it references. * @@ -4263,10 +4376,10 @@ CINDEX_LINKAGE unsigned clang_isCursorDefinition(CXCursor); * }; * \endcode * - * The declarations and the definition of \c X are represented by three - * different cursors, all of which are declarations of the same underlying + * The declarations and the definition of \c X are represented by three + * different cursors, all of which are declarations of the same underlying * entity. One of these cursor is considered the "canonical" cursor, which - * is effectively the representative for the underlying entity. One can + * is effectively the representative for the underlying entity. One can * determine if two cursors are declarations of the same underlying entity by * comparing their canonical cursors. * @@ -4290,11 +4403,11 @@ CINDEX_LINKAGE int clang_Cursor_getObjCSelectorIndex(CXCursor); /** * Given a cursor pointing to a C++ method call or an Objective-C * message, returns non-zero if the method/message is "dynamic", meaning: - * + * * For a C++ method: the call is virtual. * For an Objective-C message: the receiver is an object instance, not 'super' * or a specific class. - * + * * If the method/message is "static" or the cursor does not point to a * method/message, it will return zero. */ @@ -4336,6 +4449,18 @@ typedef enum { CINDEX_LINKAGE unsigned clang_Cursor_getObjCPropertyAttributes(CXCursor C, unsigned reserved); +/** + * Given a cursor that represents a property declaration, return the + * name of the method that implements the getter. + */ +CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertyGetterName(CXCursor C); + +/** + * Given a cursor that represents a property declaration, return the + * name of the method that implements the setter, if any. + */ +CINDEX_LINKAGE CXString clang_Cursor_getObjCPropertySetterName(CXCursor C); + /** * 'Qualifiers' written next to the return and parameter types in * Objective-C method declarations. @@ -4564,7 +4689,7 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isDefaulted(CXCursor C); CINDEX_LINKAGE unsigned clang_CXXMethod_isPureVirtual(CXCursor C); /** - * Determine if a C++ member function or member function template is + * Determine if a C++ member function or member function template is * declared 'static'. */ CINDEX_LINKAGE unsigned clang_CXXMethod_isStatic(CXCursor C); @@ -4611,16 +4736,16 @@ CINDEX_LINKAGE unsigned clang_CXXMethod_isConst(CXCursor C); * \c CXCursor_NoDeclFound. */ CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C); - + /** * Given a cursor that may represent a specialization or instantiation * of a template, retrieve the cursor that represents the template that it * specializes or from which it was instantiated. * - * This routine determines the template involved both for explicit + * This routine determines the template involved both for explicit * specializations of templates and for implicit instantiations of the template, * both of which are referred to as "specializations". For a class template - * specialization (e.g., \c std::vector), this routine will return + * specialization (e.g., \c std::vector), this routine will return * either the primary template (\c std::vector) or, if the specialization was * instantiated from a class template partial specialization, the class template * partial specialization. For a class template partial specialization and a @@ -4628,7 +4753,7 @@ CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C); * this routine will return the specialized template. * * For members of a class template (e.g., member functions, member classes, or - * static data members), returns the specialized or instantiated member. + * static data members), returns the specialized or instantiated member. * Although not strictly "templates" in the C++ language, members of class * templates have the same notions of specializations and instantiations that * templates do, so this routine treats them similarly. @@ -4636,7 +4761,7 @@ CINDEX_LINKAGE enum CXCursorKind clang_getTemplateCursorKind(CXCursor C); * \param C A cursor that may be a specialization of a template or a member * of a template. * - * \returns If the given cursor is a specialization or instantiation of a + * \returns If the given cursor is a specialization or instantiation of a * template or a member thereof, the template or member that it specializes or * from which it was instantiated. Otherwise, returns a NULL cursor. */ @@ -4648,11 +4773,11 @@ CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C); * * \param C A cursor pointing to a member reference, a declaration reference, or * an operator call. - * \param NameFlags A bitset with three independent flags: + * \param NameFlags A bitset with three independent flags: * CXNameRange_WantQualifier, CXNameRange_WantTemplateArgs, and * CXNameRange_WantSinglePiece. - * \param PieceIndex For contiguous names or when passing the flag - * CXNameRange_WantSinglePiece, only one piece with index 0 is + * \param PieceIndex For contiguous names or when passing the flag + * CXNameRange_WantSinglePiece, only one piece with index 0 is * available. When the CXNameRange_WantSinglePiece flag is not passed for a * non-contiguous names, this index can be used to retrieve the individual * pieces of the name. See also CXNameRange_WantSinglePiece. @@ -4661,7 +4786,7 @@ CINDEX_LINKAGE CXCursor clang_getSpecializedCursorTemplate(CXCursor C); * name, or if the PieceIndex is out-of-range, a null-cursor will be returned. */ CINDEX_LINKAGE CXSourceRange clang_getCursorReferenceNameRange(CXCursor C, - unsigned NameFlags, + unsigned NameFlags, unsigned PieceIndex); enum CXNameRefFlags { @@ -4670,7 +4795,7 @@ enum CXNameRefFlags { * range. */ CXNameRange_WantQualifier = 0x1, - + /** * Include the explicit template arguments, e.g. \ in x.f, * in the range. @@ -4689,7 +4814,7 @@ enum CXNameRefFlags { */ CXNameRange_WantSinglePiece = 0x4 }; - + /** * @} */ @@ -4742,6 +4867,20 @@ typedef struct { void *ptr_data; } CXToken; +/** + * Get the raw lexical token starting with the given location. + * + * \param TU the translation unit whose text is being tokenized. + * + * \param Location the source location with which the token starts. + * + * \returns The token starting with the given location or NULL if no such token + * exist. The returned pointer must be freed with clang_disposeTokens before the + * translation unit is destroyed. + */ +CINDEX_LINKAGE CXToken *clang_getToken(CXTranslationUnit TU, + CXSourceLocation Location); + /** * Determine the kind of the given token. */ @@ -5128,7 +5267,7 @@ clang_getNumCompletionChunks(CXCompletionString completion_string); /** * Determine the priority of this code completion. * - * The priority of a code completion indicates how likely it is that this + * The priority of a code completion indicates how likely it is that this * particular completion is the completion that the user will select. The * priority is selected by various internal heuristics. * @@ -5139,7 +5278,7 @@ clang_getNumCompletionChunks(CXCompletionString completion_string); */ CINDEX_LINKAGE unsigned clang_getCompletionPriority(CXCompletionString completion_string); - + /** * Determine the availability of the entity that this code-completion * string refers to. @@ -5148,7 +5287,7 @@ clang_getCompletionPriority(CXCompletionString completion_string); * * \returns The availability of the completion string. */ -CINDEX_LINKAGE enum CXAvailabilityKind +CINDEX_LINKAGE enum CXAvailabilityKind clang_getCompletionAvailability(CXCompletionString completion_string); /** @@ -5181,7 +5320,7 @@ clang_getCompletionAnnotation(CXCompletionString completion_string, /** * Retrieve the parent context of the given completion string. * - * The parent context of a completion string is the semantic parent of + * The parent context of a completion string is the semantic parent of * the declaration (if any) that the code completion represents. For example, * a code completion for an Objective-C method would have the method's class * or protocol as its context. @@ -5216,7 +5355,7 @@ clang_getCompletionBriefComment(CXCompletionString completion_string); */ CINDEX_LINKAGE CXCompletionString clang_getCursorCompletionString(CXCursor cursor); - + /** * Contains the results of code-completion. * @@ -5237,6 +5376,70 @@ typedef struct { unsigned NumResults; } CXCodeCompleteResults; +/** + * Retrieve the number of fix-its for the given completion index. + * + * Calling this makes sense only if CXCodeComplete_IncludeCompletionsWithFixIts + * option was set. + * + * \param results The structure keeping all completion results + * + * \param completion_index The index of the completion + * + * \return The number of fix-its which must be applied before the completion at + * completion_index can be applied + */ +CINDEX_LINKAGE unsigned +clang_getCompletionNumFixIts(CXCodeCompleteResults *results, + unsigned completion_index); + +/** + * Fix-its that *must* be applied before inserting the text for the + * corresponding completion. + * + * By default, clang_codeCompleteAt() only returns completions with empty + * fix-its. Extra completions with non-empty fix-its should be explicitly + * requested by setting CXCodeComplete_IncludeCompletionsWithFixIts. + * + * For the clients to be able to compute position of the cursor after applying + * fix-its, the following conditions are guaranteed to hold for + * replacement_range of the stored fix-its: + * - Ranges in the fix-its are guaranteed to never contain the completion + * point (or identifier under completion point, if any) inside them, except + * at the start or at the end of the range. + * - If a fix-it range starts or ends with completion point (or starts or + * ends after the identifier under completion point), it will contain at + * least one character. It allows to unambiguously recompute completion + * point after applying the fix-it. + * + * The intuition is that provided fix-its change code around the identifier we + * complete, but are not allowed to touch the identifier itself or the + * completion point. One example of completions with corrections are the ones + * replacing '.' with '->' and vice versa: + * + * std::unique_ptr> vec_ptr; + * In 'vec_ptr.^', one of the completions is 'push_back', it requires + * replacing '.' with '->'. + * In 'vec_ptr->^', one of the completions is 'release', it requires + * replacing '->' with '.'. + * + * \param results The structure keeping all completion results + * + * \param completion_index The index of the completion + * + * \param fixit_index The index of the fix-it for the completion at + * completion_index + * + * \param replacement_range The fix-it range that must be replaced before the + * completion at completion_index can be applied + * + * \returns The fix-it string that must replace the code at replacement_range + * before the completion at completion_index can be applied + */ +CINDEX_LINKAGE CXString clang_getCompletionFixIt( + CXCodeCompleteResults *results, unsigned completion_index, + unsigned fixit_index, CXSourceRange *replacement_range); + /** * Flags that can be passed to \c clang_codeCompleteAt() to * modify its behavior. @@ -5268,7 +5471,13 @@ enum CXCodeComplete_Flags { * defined in the preamble. There's no guarantee any particular entity is * omitted. This may be useful if the headers are indexed externally. */ - CXCodeComplete_SkipPreamble = 0x08 + CXCodeComplete_SkipPreamble = 0x08, + + /** + * Whether to include completions with small + * fix-its, e.g. change '.' to '->' on member access, etc. + */ + CXCodeComplete_IncludeCompletionsWithFixIts = 0x10 }; /** @@ -5283,12 +5492,12 @@ enum CXCompletionContext { * should be included. (This is equivalent to having no context bits set.) */ CXCompletionContext_Unexposed = 0, - + /** * Completions for any possible type should be included in the results. */ CXCompletionContext_AnyType = 1 << 0, - + /** * Completions for any possible value (variables, function calls, etc.) * should be included in the results. @@ -5309,7 +5518,7 @@ enum CXCompletionContext { * included in the results. */ CXCompletionContext_CXXClassTypeValue = 1 << 4, - + /** * Completions for fields of the member being accessed using the dot * operator should be included in the results. @@ -5325,7 +5534,7 @@ enum CXCompletionContext { * using the dot operator should be included in the results. */ CXCompletionContext_ObjCPropertyAccess = 1 << 7, - + /** * Completions for enum tags should be included in the results. */ @@ -5338,7 +5547,7 @@ enum CXCompletionContext { * Completions for struct tags should be included in the results. */ CXCompletionContext_StructTag = 1 << 10, - + /** * Completions for C++ class names should be included in the results. */ @@ -5353,7 +5562,7 @@ enum CXCompletionContext { * the results. */ CXCompletionContext_NestedNameSpecifier = 1 << 13, - + /** * Completions for Objective-C interfaces (classes) should be included * in the results. @@ -5384,27 +5593,27 @@ enum CXCompletionContext { * the results. */ CXCompletionContext_ObjCSelectorName = 1 << 19, - + /** * Completions for preprocessor macro names should be included in * the results. */ CXCompletionContext_MacroName = 1 << 20, - + /** * Natural language completions should be included in the results. */ CXCompletionContext_NaturalLanguage = 1 << 21, - + /** * The current context is unknown, so set all contexts. */ CXCompletionContext_Unknown = ((1 << 22) - 1) }; - + /** * Returns a default set of code-completion options that can be - * passed to\c clang_codeCompleteAt(). + * passed to\c clang_codeCompleteAt(). */ CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void); @@ -5467,7 +5676,7 @@ CINDEX_LINKAGE unsigned clang_defaultCodeCompleteOptions(void); * * \param options Extra options that control the behavior of code * completion, expressed as a bitwise OR of the enumerators of the - * CXCodeComplete_Flags enumeration. The + * CXCodeComplete_Flags enumeration. The * \c clang_defaultCodeCompleteOptions() function returns a default set * of code-completion options. * @@ -5486,7 +5695,7 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, unsigned options); /** - * Sort the code-completion results in case-insensitive alphabetical + * Sort the code-completion results in case-insensitive alphabetical * order. * * \param Results The set of results to sort. @@ -5495,13 +5704,13 @@ CXCodeCompleteResults *clang_codeCompleteAt(CXTranslationUnit TU, CINDEX_LINKAGE void clang_sortCodeCompletionResults(CXCompletionResult *Results, unsigned NumResults); - + /** * Free the given set of code-completion results. */ CINDEX_LINKAGE void clang_disposeCodeCompleteResults(CXCodeCompleteResults *Results); - + /** * Determine the number of diagnostics produced prior to the * location where code completion was performed. @@ -5525,7 +5734,7 @@ CXDiagnostic clang_codeCompleteGetDiagnostic(CXCodeCompleteResults *Results, /** * Determines what completions are appropriate for the context * the given code completion. - * + * * \param Results the code completion results to query * * \returns the kinds of completions that are appropriate for use @@ -5581,7 +5790,7 @@ CXString clang_codeCompleteGetContainerUSR(CXCodeCompleteResults *Results); */ CINDEX_LINKAGE CXString clang_codeCompleteGetObjCSelector(CXCodeCompleteResults *Results); - + /** * @} */ @@ -5605,7 +5814,7 @@ CINDEX_LINKAGE CXString clang_getClangVersion(void); * value enables crash recovery, while 0 disables it. */ CINDEX_LINKAGE void clang_toggleCrashRecovery(unsigned isEnabled); - + /** * Visitor invoked for each file in a translation unit * (used with clang_getInclusions()). @@ -5650,7 +5859,7 @@ typedef enum { typedef void * CXEvalResult; /** - * If cursor is a statement declaration tries to evaluate the + * If cursor is a statement declaration tries to evaluate the * statement and if its variable, tries to evaluate its initializer, * into its corresponding type. */ @@ -5749,7 +5958,7 @@ CINDEX_LINKAGE unsigned clang_remap_getNumFiles(CXRemapping); /** * Get the original and the associated filename from the remapping. - * + * * \param original If non-NULL, will be set to the original filename. * * \param transformed If non-NULL, will be set to the filename that the original @@ -5801,7 +6010,7 @@ typedef enum { /** * Find references of a declaration in a specific file. - * + * * \param cursor pointing to a declaration or a reference of one. * * \param file to search for references. @@ -6160,11 +6369,11 @@ typedef struct { const CXIdxEntityInfo *referencedEntity; /** * Immediate "parent" of the reference. For example: - * + * * \code * Foo *var; * \endcode - * + * * The parent of reference of type 'Foo' is the variable 'var'. * For references inside statement bodies of functions/methods, * the parentEntity will be the function/method. @@ -6199,16 +6408,16 @@ typedef struct { CXIdxClientFile (*enteredMainFile)(CXClientData client_data, CXFile mainFile, void *reserved); - + /** * Called when a file gets \#included/\#imported. */ CXIdxClientFile (*ppIncludedFile)(CXClientData client_data, const CXIdxIncludedFileInfo *); - + /** * Called when a AST file (PCH or module) gets imported. - * + * * AST files will not get indexed (there will not be callbacks to index all * the entities in an AST file). The recommended action is that, if the AST * file is not already indexed, to initiate a new indexing job specific to @@ -6310,7 +6519,7 @@ typedef enum { * Used to indicate that no special indexing options are needed. */ CXIndexOpt_None = 0x0, - + /** * Used to indicate that IndexerCallbacks#indexEntityReference should * be invoked for only one reference of an entity per source file that does @@ -6397,16 +6606,16 @@ CINDEX_LINKAGE int clang_indexSourceFileFullArgv( /** * Index the given translation unit via callbacks implemented through * #IndexerCallbacks. - * + * * The order of callback invocations is not guaranteed to be the same as * when indexing a source file. The high level order will be: - * + * * -Preprocessor callbacks invocations * -Declaration/reference callbacks invocations * -Diagnostic callback invocations * * The parameters are the same as #clang_indexSourceFile. - * + * * \returns If there is a failure from which there is no recovery, returns * non-zero, otherwise returns 0. */ diff --git a/include/clang/ARCMigrate/FileRemapper.h b/include/clang/ARCMigrate/FileRemapper.h index 53b88e9eb5e527578303e5f652d06c982c9ce4a3..731307f24e224faa5f25574f313b4d7d0f6b3aeb 100644 --- a/include/clang/ARCMigrate/FileRemapper.h +++ b/include/clang/ARCMigrate/FileRemapper.h @@ -41,7 +41,7 @@ class FileRemapper { public: FileRemapper(); ~FileRemapper(); - + bool initFromDisk(StringRef outputDir, DiagnosticsEngine &Diag, bool ignoreIfFilesChanged); bool initFromFile(StringRef filePath, DiagnosticsEngine &Diag, diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h index d70e455a5a8e801e78c69740fbf544819bf869a0..889857488f747f47051e3134a378efc20115c155 100644 --- a/include/clang/AST/ASTContext.h +++ b/include/clang/AST/ASTContext.h @@ -79,6 +79,7 @@ struct fltSemantics; namespace clang { +class APFixedPoint; class APValue; class ASTMutationListener; class ASTRecordLayout; @@ -92,6 +93,7 @@ class CXXMethodDecl; class CXXRecordDecl; class DiagnosticsEngine; class Expr; +class FixedPointSemantics; class MangleContext; class MangleNumberingContext; class MaterializeTemporaryExpr; @@ -168,6 +170,7 @@ class ASTContext : public RefCountedBase { mutable llvm::FoldingSet DependentAddressSpaceTypes; mutable llvm::FoldingSet VectorTypes; + mutable llvm::FoldingSet DependentVectorTypes; mutable llvm::FoldingSet FunctionNoProtoTypes; mutable llvm::ContextualFoldingSet FunctionProtoTypes; @@ -225,6 +228,12 @@ class ASTContext : public RefCountedBase { using TypeInfoMap = llvm::DenseMap; mutable TypeInfoMap MemoizedTypeInfo; + /// A cache from types to unadjusted alignment information. Only ARM and + /// AArch64 targets need this information, keeping it separate prevents + /// imposing overhead on TypeInfo size. + using UnadjustedAlignMap = llvm::DenseMap; + mutable UnadjustedAlignMap MemoizedUnadjustedAlign; + /// A cache mapping from CXXRecordDecls to key functions. llvm::DenseMap KeyFunctions; @@ -1007,6 +1016,17 @@ public: CanQualType UnsignedCharTy, UnsignedShortTy, UnsignedIntTy, UnsignedLongTy; CanQualType UnsignedLongLongTy, UnsignedInt128Ty; CanQualType FloatTy, DoubleTy, LongDoubleTy, Float128Ty; + CanQualType ShortAccumTy, AccumTy, + LongAccumTy; // ISO/IEC JTC1 SC22 WG14 N1169 Extension + CanQualType UnsignedShortAccumTy, UnsignedAccumTy, UnsignedLongAccumTy; + CanQualType ShortFractTy, FractTy, LongFractTy; + CanQualType UnsignedShortFractTy, UnsignedFractTy, UnsignedLongFractTy; + CanQualType SatShortAccumTy, SatAccumTy, SatLongAccumTy; + CanQualType SatUnsignedShortAccumTy, SatUnsignedAccumTy, + SatUnsignedLongAccumTy; + CanQualType SatShortFractTy, SatFractTy, SatLongFractTy; + CanQualType SatUnsignedShortFractTy, SatUnsignedFractTy, + SatUnsignedLongFractTy; CanQualType HalfTy; // [OpenCL 6.1.1.1], ARM NEON CanQualType Float16Ty; // C11 extension ISO/IEC TS 18661-3 CanQualType FloatComplexTy, DoubleComplexTy, LongDoubleComplexTy; @@ -1310,6 +1330,11 @@ public: /// \pre \p VectorType must be a built-in type. QualType getVectorType(QualType VectorType, unsigned NumElts, VectorType::VectorKind VecKind) const; + /// Return the unique reference to the type for a dependently sized vector of + /// the specified element type. + QualType getDependentVectorType(QualType VectorType, Expr *SizeExpr, + SourceLocation AttrLoc, + VectorType::VectorKind VecKind) const; /// Return the unique reference to an extended vector type /// of the specified element type and size. @@ -1505,7 +1530,7 @@ public: /// The sizeof operator requires this (C99 6.5.3.4p4). CanQualType getSizeType() const; - /// Return the unique signed counterpart of + /// Return the unique signed counterpart of /// the integer type corresponding to size_t. CanQualType getSignedSizeType() const; @@ -1936,6 +1961,12 @@ public: return getQualifiedType(type.getUnqualifiedType(), Qs); } + unsigned char getFixedPointScale(QualType Ty) const; + unsigned char getFixedPointIBits(QualType Ty) const; + FixedPointSemantics getFixedPointSemantics(QualType Ty) const; + APFixedPoint getFixedPointMax(QualType Ty) const; + APFixedPoint getFixedPointMin(QualType Ty) const; + DeclarationNameInfo getNameForTemplate(TemplateName Name, SourceLocation NameLoc) const; @@ -2047,6 +2078,16 @@ public: unsigned getTypeAlign(QualType T) const { return getTypeInfo(T).Align; } unsigned getTypeAlign(const Type *T) const { return getTypeInfo(T).Align; } + /// Return the ABI-specified natural alignment of a (complete) type \p T, + /// before alignment adjustments, in bits. + /// + /// This alignment is curently used only by ARM and AArch64 when passing + /// arguments of a composite type. + unsigned getTypeUnadjustedAlign(QualType T) const { + return getTypeUnadjustedAlign(T.getTypePtr()); + } + unsigned getTypeUnadjustedAlign(const Type *T) const; + /// Return the ABI-specified alignment of a type, in bits, or 0 if /// the type is incomplete and we cannot determine the alignment (for /// example, from alignment attributes). @@ -2057,6 +2098,12 @@ public: CharUnits getTypeAlignInChars(QualType T) const; CharUnits getTypeAlignInChars(const Type *T) const; + /// getTypeUnadjustedAlignInChars - Return the ABI-specified alignment of a type, + /// in characters, before alignment adjustments. This method does not work on + /// incomplete types. + CharUnits getTypeUnadjustedAlignInChars(QualType T) const; + CharUnits getTypeUnadjustedAlignInChars(const Type *T) const; + // getTypeInfoDataSizeInChars - Return the size of a type, in chars. If the // type is a record, its data size is returned. std::pair getTypeInfoDataSizeInChars(QualType T) const; @@ -2268,7 +2315,20 @@ public: bool ObjCMethodsAreEqual(const ObjCMethodDecl *MethodDecl, const ObjCMethodDecl *MethodImp); - bool UnwrapSimilarPointerTypes(QualType &T1, QualType &T2); + bool UnwrapSimilarTypes(QualType &T1, QualType &T2); + bool UnwrapSimilarArrayTypes(QualType &T1, QualType &T2); + + /// Determine if two types are similar, according to the C++ rules. That is, + /// determine if they are the same other than qualifiers on the initial + /// sequence of pointer / pointer-to-member / array (and in Clang, object + /// pointer) types and their element types. + /// + /// Clang offers a number of qualifiers in addition to the C++ qualifiers; + /// those qualifiers are also ignored in the 'similarity' check. + bool hasSimilarType(QualType T1, QualType T2); + + /// Determine if two types are similar, ignoring only CVR qualifiers. + bool hasCvrSimilarType(QualType T1, QualType T2); /// Retrieves the "canonical" nested name specifier for a /// given nested name specifier. @@ -2433,6 +2493,8 @@ public: unsigned getTargetAddressSpace(LangAS AS) const; + LangAS getLangASForBuiltinAddressSpace(unsigned AS) const; + /// Get target-dependent integer value for null pointer which is used for /// constant folding. uint64_t getTargetNullPointerValue(QualType QT) const; @@ -2540,8 +2602,15 @@ public: // Per C99 6.2.5p6, for every signed integer type, there is a corresponding // unsigned integer type. This method takes a signed type, and returns the // corresponding unsigned integer type. + // With the introduction of fixed point types in ISO N1169, this method also + // accepts fixed point types and returns the corresponding unsigned type for + // a given fixed point type. QualType getCorrespondingUnsignedType(QualType T) const; + // Per ISO N1169, this method accepts fixed point types and returns the + // corresponding saturated type for a given fixed point type. + QualType getCorrespondingSaturatedType(QualType Ty) const; + //===--------------------------------------------------------------------===// // Integer Values //===--------------------------------------------------------------------===// diff --git a/include/clang/AST/ASTDiagnostic.h b/include/clang/AST/ASTDiagnostic.h index b08865dde3c108b41e93ce21b316ed22d1d781e8..2534272da3a301ee62490fca0080c446d8760422 100644 --- a/include/clang/AST/ASTDiagnostic.h +++ b/include/clang/AST/ASTDiagnostic.h @@ -23,11 +23,11 @@ namespace clang { NUM_BUILTIN_AST_DIAGNOSTICS }; } // end namespace diag - + /// DiagnosticsEngine argument formatting function for diagnostics that /// involve AST nodes. /// - /// This function formats diagnostic arguments for various AST nodes, + /// This function formats diagnostic arguments for various AST nodes, /// including types, declaration names, nested name specifiers, and /// declaration contexts, into strings that can be printed as part of /// diagnostics. It is meant to be used as the argument to diff --git a/include/clang/AST/ASTImporter.h b/include/clang/AST/ASTImporter.h index 42f99f3f3f53ca02f8ca3b314cce73c12d2bc421..311d64e7cbf8728a558821efcbeec3a679aad23f 100644 --- a/include/clang/AST/ASTImporter.h +++ b/include/clang/AST/ASTImporter.h @@ -43,6 +43,15 @@ class TagDecl; class TypeSourceInfo; class Attr; + // \brief Returns with a list of declarations started from the canonical decl + // then followed by subsequent decls in the translation unit. + // This gives a canonical list for each entry in the redecl chain. + // `Decl::redecls()` gives a list of decls which always start from the + // previous decl and the next item is actually the previous item in the order + // of source locations. Thus, `Decl::redecls()` gives different lists for + // the different entries in a given redecl chain. + llvm::SmallVector getCanonicalForwardRedeclChain(Decl* D); + /// Imports selected nodes from one AST context into another context, /// merging AST nodes where appropriate. class ASTImporter { @@ -54,7 +63,7 @@ class Attr; private: /// The contexts we're importing to and from. ASTContext &ToContext, &FromContext; - + /// The file managers we're importing to and from. FileManager &ToFileManager, &FromFileManager; @@ -63,11 +72,11 @@ class Attr; /// Whether the last diagnostic came from the "from" context. bool LastDiagFromFrom = false; - + /// Mapping from the already-imported types in the "from" context /// to the corresponding types in the "to" context. llvm::DenseMap ImportedTypes; - + /// Mapping from the already-imported declarations in the "from" /// context to the corresponding declarations in the "to" context. llvm::DenseMap ImportedDecls; @@ -84,11 +93,11 @@ class Attr; /// the "from" source manager to the corresponding CXXBasesSpecifier /// in the "to" source manager. ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers; - + /// Declaration (from, to) pairs that are known not to be equivalent /// (which we have already complained about). NonEquivalentDeclSet NonEquivalentDecls; - + public: /// Create a new AST importer. /// @@ -106,13 +115,13 @@ class Attr; ASTImporter(ASTContext &ToContext, FileManager &ToFileManager, ASTContext &FromContext, FileManager &FromFileManager, bool MinimalImport); - + virtual ~ASTImporter(); - + /// Whether the importer will perform a minimal import, creating /// to-be-completed forward declarations when possible. bool isMinimalImport() const { return Minimal; } - + /// Import the given type from the "from" context into the "to" /// context. /// @@ -133,10 +142,10 @@ class Attr; /// \returns the equivalent attribute in the "to" context. Attr *Import(const Attr *FromAttr); - /// Import the given declaration from the "from" context into the + /// Import the given declaration from the "from" context into the /// "to" context. /// - /// \returns the equivalent declaration in the "to" context, or a NULL type + /// \returns the equivalent declaration in the "to" context, or a NULL type /// if an error occurred. Decl *Import(Decl *FromD); Decl *Import(const Decl *FromD) { @@ -154,7 +163,7 @@ class Attr; /// \returns the equivalent declaration context in the "to" /// context, or a NULL type if an error occurred. DeclContext *ImportContext(DeclContext *FromDC); - + /// Import the given expression from the "from" context into the /// "to" context. /// @@ -186,7 +195,7 @@ class Attr; /// Import the goven template name from the "from" context into the /// "to" context. TemplateName Import(TemplateName From); - + /// Import the given source location from the "from" context into /// the "to" context. /// @@ -220,7 +229,7 @@ class Attr; /// \returns the equivalent selector in the "to" context. Selector Import(Selector FromSel); - /// Import the given file ID from the "from" context into the + /// Import the given file ID from the "from" context into the /// "to" context. /// /// \returns the equivalent file ID in the source manager of the "to" @@ -243,13 +252,13 @@ class Attr; /// Import the definition of the given declaration, including all of /// the declarations it contains. /// - /// This routine is intended to be used + /// This routine is intended to be used void ImportDefinition(Decl *From); /// Cope with a name conflict when importing a declaration into the /// given context. /// - /// This routine is invoked whenever there is a name conflict while + /// This routine is invoked whenever there is a name conflict while /// importing a declaration. The returned name will become the name of the /// imported declaration. By default, the returned name is the same as the /// original name, leaving the conflict unresolve such that name lookup @@ -261,7 +270,7 @@ class Attr; /// \param Name the name of the declaration being imported, which conflicts /// with other declarations. /// - /// \param DC the declaration context (in the "to" AST context) in which + /// \param DC the declaration context (in the "to" AST context) in which /// the name is being imported. /// /// \param IDNS the identifier namespace in which the name will be found. @@ -277,25 +286,25 @@ class Attr; unsigned IDNS, NamedDecl **Decls, unsigned NumDecls); - + /// Retrieve the context that AST nodes are being imported into. ASTContext &getToContext() const { return ToContext; } - + /// Retrieve the context that AST nodes are being imported from. ASTContext &getFromContext() const { return FromContext; } - + /// Retrieve the file manager that AST nodes are being imported into. FileManager &getToFileManager() const { return ToFileManager; } /// Retrieve the file manager that AST nodes are being imported from. FileManager &getFromFileManager() const { return FromFileManager; } - + /// Report a diagnostic in the "to" context. DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID); - + /// Report a diagnostic in the "from" context. DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID); - + /// Return the set of declarations that we know are not equivalent. NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; } @@ -304,14 +313,14 @@ class Attr; /// /// \param D A declaration in the "to" context. virtual void CompleteDecl(Decl* D); - - /// Note that we have imported the "from" declaration by mapping it - /// to the (potentially-newly-created) "to" declaration. - /// + /// Subclasses can override this function to observe all of the \c From -> /// \c To declaration mappings as they are imported. - virtual Decl *Imported(Decl *From, Decl *To); - + virtual Decl *Imported(Decl *From, Decl *To) { return To; } + + /// Store and assign the imported declaration to its counterpart. + Decl *MapImported(Decl *From, Decl *To); + /// Called by StructuralEquivalenceContext. If a RecordDecl is /// being compared to another RecordDecl as part of import, completing the /// other RecordDecl may trigger importation of the first RecordDecl. This @@ -319,11 +328,18 @@ class Attr; /// RecordDecl can be found, we can complete it without the need for /// importation, eliminating this loop. virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; } - + /// Determine whether the given types are structurally /// equivalent. bool IsStructurallyEquivalent(QualType From, QualType To, bool Complain = true); + + /// Determine the index of a field in its parent record. + /// F should be a field (or indirect field) declaration. + /// \returns The index of the field in its parent context, starting from 1. + /// 0 is returned on error (parent context is non-record). + static unsigned getFieldIndex(Decl *F); + }; } // namespace clang diff --git a/include/clang/AST/ASTLambda.h b/include/clang/AST/ASTLambda.h index 2fe4e2563b36f8852cf9bc87232d5bf78824604a..6fedcb8d3801115b8e90352406c8ef2b930d7935 100644 --- a/include/clang/AST/ASTLambda.h +++ b/include/clang/AST/ASTLambda.h @@ -40,7 +40,7 @@ inline bool isGenericLambdaCallOperatorSpecialization(const CXXMethodDecl *MD) { if (!MD) return false; const CXXRecordDecl *LambdaClass = MD->getParent(); if (LambdaClass && LambdaClass->isGenericLambda()) - return isLambdaCallOperator(MD) && + return isLambdaCallOperator(MD) && MD->isFunctionTemplateSpecialization(); return false; } @@ -51,11 +51,11 @@ inline bool isLambdaConversionOperator(CXXConversionDecl *C) { inline bool isLambdaConversionOperator(Decl *D) { if (!D) return false; - if (CXXConversionDecl *Conv = dyn_cast(D)) - return isLambdaConversionOperator(Conv); - if (FunctionTemplateDecl *F = dyn_cast(D)) - if (CXXConversionDecl *Conv = - dyn_cast_or_null(F->getTemplatedDecl())) + if (CXXConversionDecl *Conv = dyn_cast(D)) + return isLambdaConversionOperator(Conv); + if (FunctionTemplateDecl *F = dyn_cast(D)) + if (CXXConversionDecl *Conv = + dyn_cast_or_null(F->getTemplatedDecl())) return isLambdaConversionOperator(Conv); return false; } @@ -71,7 +71,7 @@ inline bool isGenericLambdaCallOperatorSpecialization(DeclContext *DC) { inline DeclContext *getLambdaAwareParentOfDeclContext(DeclContext *DC) { if (isLambdaCallOperator(DC)) return DC->getParent()->getParent(); - else + else return DC->getParent(); } diff --git a/include/clang/AST/ASTMutationListener.h b/include/clang/AST/ASTMutationListener.h index 31ae2b111e0134331d9e7f193f3d2ae219500a75..80184e1cc7402af1ce7f05fe02cbb1b61867fadc 100644 --- a/include/clang/AST/ASTMutationListener.h +++ b/include/clang/AST/ASTMutationListener.h @@ -134,13 +134,13 @@ public: /// \param M The containing module in which the definition was made visible, /// if any. virtual void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {} - + /// An attribute was added to a RecordDecl /// /// \param Attr The attribute that was added to the Record /// /// \param Record The RecordDecl that got a new attribute - virtual void AddedAttributeToRecord(const Attr *Attr, + virtual void AddedAttributeToRecord(const Attr *Attr, const RecordDecl *Record) {} // NOTE: If new methods are added they should also be added to diff --git a/include/clang/AST/ASTStructuralEquivalence.h b/include/clang/AST/ASTStructuralEquivalence.h index d21be992c41ab9c715f8f8fc70d1da4b27c55993..2037796cd5526132451bade4ddcc0da0ecd920e8 100644 --- a/include/clang/AST/ASTStructuralEquivalence.h +++ b/include/clang/AST/ASTStructuralEquivalence.h @@ -30,6 +30,14 @@ class QualType; class RecordDecl; class SourceLocation; +/// \brief Whether to perform a normal or minimal equivalence check. +/// In case of `Minimal`, we do not perform a recursive check of decls with +/// external storage. +enum class StructuralEquivalenceKind { + Default, + Minimal, +}; + struct StructuralEquivalenceContext { /// AST contexts for which we are checking structural equivalence. ASTContext &FromCtx, &ToCtx; @@ -47,6 +55,8 @@ struct StructuralEquivalenceContext { /// (which we have already complained about). llvm::DenseSet> &NonEquivalentDecls; + StructuralEquivalenceKind EqKind; + /// Whether we're being strict about the spelling of types when /// unifying two types. bool StrictTypeSpelling; @@ -63,10 +73,11 @@ struct StructuralEquivalenceContext { StructuralEquivalenceContext( ASTContext &FromCtx, ASTContext &ToCtx, llvm::DenseSet> &NonEquivalentDecls, + StructuralEquivalenceKind EqKind, bool StrictTypeSpelling = false, bool Complain = true, bool ErrorOnTagTypeMismatch = false) : FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls), - StrictTypeSpelling(StrictTypeSpelling), + EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling), ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {} DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID); @@ -74,10 +85,18 @@ struct StructuralEquivalenceContext { /// Determine whether the two declarations are structurally /// equivalent. - bool IsStructurallyEquivalent(Decl *D1, Decl *D2); + /// Implementation functions (all static functions in + /// ASTStructuralEquivalence.cpp) must never call this function because that + /// will wreak havoc the internal state (\c DeclsToCheck and + /// \c TentativeEquivalences members) and can cause faulty equivalent results. + bool IsEquivalent(Decl *D1, Decl *D2); /// Determine whether the two types are structurally equivalent. - bool IsStructurallyEquivalent(QualType T1, QualType T2); + /// Implementation functions (all static functions in + /// ASTStructuralEquivalence.cpp) must never call this function because that + /// will wreak havoc the internal state (\c DeclsToCheck and + /// \c TentativeEquivalences members) and can cause faulty equivalent results. + bool IsEquivalent(QualType T1, QualType T2); /// Find the index of the given anonymous struct/union within its /// context. @@ -95,8 +114,19 @@ struct StructuralEquivalenceContext { private: /// Finish checking all of the structural equivalences. /// - /// \returns true if an error occurred, false otherwise. + /// \returns true if the equivalence check failed (non-equivalence detected), + /// false if equivalence was detected. bool Finish(); + + /// Check for common properties at Finish. + /// \returns true if D1 and D2 may be equivalent, + /// false if they are for sure not. + bool CheckCommonEquivalence(Decl *D1, Decl *D2); + + /// Check for class dependent properties at Finish. + /// \returns true if D1 and D2 may be equivalent, + /// false if they are for sure not. + bool CheckKindSpecificEquivalence(Decl *D1, Decl *D2); }; } // namespace clang diff --git a/include/clang/AST/Attr.h b/include/clang/AST/Attr.h index 390e840b330c8c49f25a65c0e7bbaae675c8f1a3..20922742f687b0c39be953d5b67d82db72769cd5 100644 --- a/include/clang/AST/Attr.h +++ b/include/clang/AST/Attr.h @@ -23,9 +23,9 @@ #include "clang/Basic/OpenMPKinds.h" #include "clang/Basic/Sanitizers.h" #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/StringSwitch.h" #include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/VersionTuple.h" #include "llvm/Support/raw_ostream.h" #include #include @@ -86,7 +86,7 @@ public: attr::Kind getKind() const { return static_cast(AttrKind); } - + unsigned getSpellingListIndex() const { return SpellingListIndex; } const char *getSpelling() const; diff --git a/include/clang/AST/AttrIterator.h b/include/clang/AST/AttrIterator.h index 56807b4590d378d824bbb15f991c894c77d9fc98..2087ecc0e70c751d2ffef8032f0f851f87519253 100644 --- a/include/clang/AST/AttrIterator.h +++ b/include/clang/AST/AttrIterator.h @@ -106,7 +106,7 @@ public: specific_attr_iterator Right) { assert((Left.Current == nullptr) == (Right.Current == nullptr)); if (Left.Current < Right.Current) - Left.AdvanceToNext(Right.Current); + Left.AdvanceToNext(Right.Current); else Right.AdvanceToNext(Left.Current); return Left.Current == Right.Current; diff --git a/include/clang/AST/Availability.h b/include/clang/AST/Availability.h index e1f5671b8c592f2349c3ba82f3078c66d451760f..28f3c3c01d200012b0a8c662d026bca7414f4370 100644 --- a/include/clang/AST/Availability.h +++ b/include/clang/AST/Availability.h @@ -15,8 +15,8 @@ #define LLVM_CLANG_AST_AVAILABILITY_H #include "clang/Basic/SourceLocation.h" -#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/StringRef.h" +#include "llvm/Support/VersionTuple.h" namespace clang { diff --git a/include/clang/AST/BaseSubobject.h b/include/clang/AST/BaseSubobject.h index fdb7e718fe9e4602c3b9823981ef00328ce248d7..2b702c76b2fabeebef3c1de0207d58f9e5220991 100644 --- a/include/clang/AST/BaseSubobject.h +++ b/include/clang/AST/BaseSubobject.h @@ -24,21 +24,21 @@ namespace clang { class CXXRecordDecl; -// BaseSubobject - Uniquely identifies a direct or indirect base class. +// 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. class BaseSubobject { /// Base - The base class declaration. const CXXRecordDecl *Base; - + /// BaseOffset - The offset from the most derived class to the base class. CharUnits BaseOffset; - + public: BaseSubobject() = default; BaseSubobject(const CXXRecordDecl *Base, CharUnits BaseOffset) : Base(Base), BaseOffset(BaseOffset) {} - + /// getBase - Returns the base class declaration. const CXXRecordDecl *getBase() const { return Base; } @@ -74,7 +74,7 @@ template<> struct DenseMapInfo { Base.getBaseOffset())); } - static bool isEqual(const clang::BaseSubobject &LHS, + static bool isEqual(const clang::BaseSubobject &LHS, const clang::BaseSubobject &RHS) { return LHS == RHS; } diff --git a/include/clang/AST/BuiltinTypes.def b/include/clang/AST/BuiltinTypes.def index 4d4ed79220846500c09230c0a1dacf81cef0b653..400efcb1981f173bb215fb3078cecf3da26b0cb8 100644 --- a/include/clang/AST/BuiltinTypes.def +++ b/include/clang/AST/BuiltinTypes.def @@ -122,6 +122,80 @@ SIGNED_TYPE(LongLong, LongLongTy) // '__int128_t' SIGNED_TYPE(Int128, Int128Ty) +//===- Fixed point types --------------------------------------------------===// + +// 'short _Accum' +SIGNED_TYPE(ShortAccum, ShortAccumTy) + +// '_Accum' +SIGNED_TYPE(Accum, AccumTy) + +// 'long _Accum' +SIGNED_TYPE(LongAccum, LongAccumTy) + +// 'unsigned short _Accum' +UNSIGNED_TYPE(UShortAccum, UnsignedShortAccumTy) + +// 'unsigned _Accum' +UNSIGNED_TYPE(UAccum, UnsignedAccumTy) + +// 'unsigned long _Accum' +UNSIGNED_TYPE(ULongAccum, UnsignedLongAccumTy) + +// 'short _Fract' +SIGNED_TYPE(ShortFract, ShortFractTy) + +// '_Fract' +SIGNED_TYPE(Fract, FractTy) + +// 'long _Fract' +SIGNED_TYPE(LongFract, LongFractTy) + +// 'unsigned short _Fract' +UNSIGNED_TYPE(UShortFract, UnsignedShortFractTy) + +// 'unsigned _Fract' +UNSIGNED_TYPE(UFract, UnsignedFractTy) + +// 'unsigned long _Fract' +UNSIGNED_TYPE(ULongFract, UnsignedLongFractTy) + +// '_Sat short _Accum' +SIGNED_TYPE(SatShortAccum, SatShortAccumTy) + +// '_Sat _Accum' +SIGNED_TYPE(SatAccum, SatAccumTy) + +// '_Sat long _Accum' +SIGNED_TYPE(SatLongAccum, SatLongAccumTy) + +// '_Sat unsigned short _Accum' +UNSIGNED_TYPE(SatUShortAccum, SatUnsignedShortAccumTy) + +// '_Sat unsigned _Accum' +UNSIGNED_TYPE(SatUAccum, SatUnsignedAccumTy) + +// '_Sat unsigned long _Accum' +UNSIGNED_TYPE(SatULongAccum, SatUnsignedLongAccumTy) + +// '_Sat short _Fract' +SIGNED_TYPE(SatShortFract, SatShortFractTy) + +// '_Sat _Fract' +SIGNED_TYPE(SatFract, SatFractTy) + +// '_Sat long _Fract' +SIGNED_TYPE(SatLongFract, SatLongFractTy) + +// '_Sat unsigned short _Fract' +UNSIGNED_TYPE(SatUShortFract, SatUnsignedShortFractTy) + +// '_Sat unsigned _Fract' +UNSIGNED_TYPE(SatUFract, SatUnsignedFractTy) + +// '_Sat unsigned long _Fract' +UNSIGNED_TYPE(SatULongFract, SatUnsignedLongFractTy) + //===- Floating point types -----------------------------------------------===// // 'half' in OpenCL, '__fp16' in ARM NEON. diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h index 4c031c450b1157d468a54080e45831c68be98649..f5e23f8e8505dc9746ca5a65f60c542e757396b0 100644 --- a/include/clang/AST/CXXInheritance.h +++ b/include/clang/AST/CXXInheritance.h @@ -34,10 +34,10 @@ namespace clang { class ASTContext; class NamedDecl; - + /// Represents an element in a path from a derived class to a -/// base class. -/// +/// base class. +/// /// Each step in the path references the link from a /// derived class to one of its direct base classes, along with a /// base "number" that identifies which base subobject of the @@ -47,12 +47,12 @@ struct CXXBasePathElement { /// class to a base class, which will be followed by this base /// path element. const CXXBaseSpecifier *Base; - + /// The record decl of the class that the base is a base of. const CXXRecordDecl *Class; - + /// Identifies which base class subobject (of type - /// \c Base->getType()) this base path element refers to. + /// \c Base->getType()) this base path element refers to. /// /// This value is only valid if \c !Base->isVirtual(), because there /// is no base numbering for the zero or one virtual bases of a @@ -64,7 +64,7 @@ struct CXXBasePathElement { /// (which is not represented as part of the path) to a particular /// (direct or indirect) base class subobject. /// -/// Individual elements in the path are described by the \c CXXBasePathElement +/// Individual elements in the path are described by the \c CXXBasePathElement /// structure, which captures both the link from a derived class to one of its /// direct bases and identification describing which base class /// subobject is being used. @@ -121,51 +121,56 @@ class CXXBasePaths { /// The type from which this search originated. CXXRecordDecl *Origin = nullptr; - + /// Paths - The actual set of paths that can be taken from the /// derived class to the same base class. std::list Paths; - + /// ClassSubobjects - Records the class subobjects for each class - /// type that we've seen. The first element in the pair says + /// type that we've seen. The first element IsVirtBase says /// whether we found a path to a virtual base for that class type, - /// while the element contains the number of non-virtual base + /// while NumberOfNonVirtBases contains the number of non-virtual base /// class subobjects for that class type. The key of the map is /// the cv-unqualified canonical type of the base class subobject. - llvm::SmallDenseMap, 8> ClassSubobjects; + struct IsVirtBaseAndNumberNonVirtBases { + unsigned IsVirtBase : 1; + unsigned NumberOfNonVirtBases : 31; + }; + llvm::SmallDenseMap + ClassSubobjects; /// VisitedDependentRecords - Records the dependent records that have been /// already visited. - llvm::SmallDenseSet VisitedDependentRecords; + llvm::SmallPtrSet VisitedDependentRecords; + + /// DetectedVirtual - The base class that is virtual. + const RecordType *DetectedVirtual = nullptr; + + /// ScratchPath - A BasePath that is used by Sema::lookupInBases + /// to help build the set of paths. + CXXBasePath ScratchPath; + + /// 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 = 0; /// FindAmbiguities - Whether Sema::IsDerivedFrom should try find /// ambiguous paths while it is looking for a path from a derived /// type to a base type. bool FindAmbiguities; - + /// RecordPaths - Whether Sema::IsDerivedFrom should record paths /// while it is determining whether there are paths from a derived /// type to a base type. bool RecordPaths; - + /// DetectVirtual - Whether Sema::IsDerivedFrom should abort the search /// if it finds a path that goes across a virtual base. The virtual class /// is also recorded. bool DetectVirtual; - - /// ScratchPath - A BasePath that is used by Sema::lookupInBases - /// to help build the set of paths. - CXXBasePath ScratchPath; - /// DetectedVirtual - The base class that is virtual. - const RecordType *DetectedVirtual = nullptr; - - /// 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 = 0; - void ComputeDeclsFound(); bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record, @@ -176,7 +181,7 @@ public: 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, @@ -188,31 +193,31 @@ public: paths_iterator end() { return Paths.end(); } const_paths_iterator begin() const { return Paths.begin(); } const_paths_iterator end() const { return Paths.end(); } - + CXXBasePath& front() { return Paths.front(); } const CXXBasePath& front() const { return Paths.front(); } - + using decl_range = llvm::iterator_range; decl_range found_decls(); - + /// Determine whether the path from the most-derived type to the /// given base type is ambiguous (i.e., it refers to multiple subobjects of /// the same base type). bool isAmbiguous(CanQualType BaseType); - + /// Whether we are finding multiple paths to detect ambiguities. bool isFindingAmbiguities() const { return FindAmbiguities; } - + /// Whether we are recording paths. bool isRecordingPaths() const { return RecordPaths; } - + /// Specify whether we should be recording paths or not. void setRecordingPaths(bool RP) { RecordPaths = RP; } - + /// Whether we are detecting virtual bases. bool isDetectingVirtual() const { return DetectVirtual; } - + /// The virtual base discovered on the path (if we are merely /// detecting virtuals). const RecordType* getDetectedVirtual() const { @@ -223,11 +228,11 @@ public: /// began CXXRecordDecl *getOrigin() const { return Origin; } void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; } - + /// Clear the base-paths results. void clear(); - - /// Swap this data structure's contents with another CXXBasePaths + + /// Swap this data structure's contents with another CXXBasePaths /// object. void swap(CXXBasePaths &Other); }; diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 63a0af66eec3775fed0f4ce30b49884ef90a93bf..0e738da43ad41b3ada1d8c77c8c3ac82657c7d57 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -85,8 +85,8 @@ public: /// Retrieve the underlying type pointer, which refers to a /// canonical type, or nullptr. - const T *getTypePtrOrNull() const { - return cast_or_null(Stored.getTypePtrOrNull()); + const T *getTypePtrOrNull() const { + return cast_or_null(Stored.getTypePtrOrNull()); } /// Implicit conversion to a qualified type. @@ -94,7 +94,7 @@ public: /// Implicit conversion to bool. explicit operator bool() const { return !isNull(); } - + bool isNull() const { return Stored.isNull(); } diff --git a/include/clang/AST/CharUnits.h b/include/clang/AST/CharUnits.h index ddead6046a147ce91b3c63010bf3db9d146076a8..0aadf06fffc9856d2f11629edbc5fd3f446ffdbd 100644 --- a/include/clang/AST/CharUnits.h +++ b/include/clang/AST/CharUnits.h @@ -61,7 +61,7 @@ namespace clang { /// fromQuantity - Construct a CharUnits quantity from a raw integer type. static CharUnits fromQuantity(QuantityType Quantity) { - return CharUnits(Quantity); + return CharUnits(Quantity); } // Compound assignment. @@ -87,7 +87,7 @@ namespace clang { CharUnits operator-- (int) { return CharUnits(Quantity--); } - + // Comparison operators. bool operator== (const CharUnits &Other) const { return Quantity == Other.Quantity; @@ -97,21 +97,21 @@ namespace clang { } // Relational operators. - bool operator< (const CharUnits &Other) const { - return Quantity < Other.Quantity; + bool operator< (const CharUnits &Other) const { + return Quantity < Other.Quantity; } - bool operator<= (const CharUnits &Other) const { + bool operator<= (const CharUnits &Other) const { return Quantity <= Other.Quantity; } - bool operator> (const CharUnits &Other) const { - return Quantity > Other.Quantity; + bool operator> (const CharUnits &Other) const { + return Quantity > Other.Quantity; } - bool operator>= (const CharUnits &Other) const { - return Quantity >= Other.Quantity; + bool operator>= (const CharUnits &Other) const { + return Quantity >= Other.Quantity; } // Other predicates. - + /// isZero - Test whether the quantity equals zero. bool isZero() const { return Quantity == 0; } @@ -172,7 +172,7 @@ namespace clang { return CharUnits(-Quantity); } - + // Conversions. /// getQuantity - Get the raw integer representation of this quantity. @@ -205,7 +205,7 @@ namespace clang { }; // class CharUnit } // namespace clang -inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, +inline clang::CharUnits operator* (clang::CharUnits::QuantityType Scale, const clang::CharUnits &CU) { return CU * Scale; } @@ -223,8 +223,8 @@ template<> struct DenseMapInfo { static clang::CharUnits getTombstoneKey() { clang::CharUnits::QuantityType Quantity = DenseMapInfo::getTombstoneKey(); - - return clang::CharUnits::fromQuantity(Quantity); + + return clang::CharUnits::fromQuantity(Quantity); } static unsigned getHashValue(const clang::CharUnits &CU) { @@ -232,7 +232,7 @@ template<> struct DenseMapInfo { return DenseMapInfo::getHashValue(Quantity); } - static bool isEqual(const clang::CharUnits &LHS, + static bool isEqual(const clang::CharUnits &LHS, const clang::CharUnits &RHS) { return LHS == RHS; } @@ -241,7 +241,7 @@ template<> struct DenseMapInfo { template <> struct isPodLike { static const bool value = true; }; - + } // end namespace llvm #endif // LLVM_CLANG_AST_CHARUNITS_H diff --git a/include/clang/AST/Comment.h b/include/clang/AST/Comment.h index e3a427d8aa0d831e03b854f43f7270371ef147c1..8660f1a6bc23a0c70cd396ebdfb363cfab28eba8 100644 --- a/include/clang/AST/Comment.h +++ b/include/clang/AST/Comment.h @@ -98,7 +98,7 @@ protected: unsigned RenderKind : 2; unsigned CommandID : CommandInfo::NumCommandIDBits; }; - enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 + + enum { NumInlineCommandCommentBits = NumInlineContentCommentBits + 2 + CommandInfo::NumCommandIDBits }; class HTMLTagCommentBitfields { @@ -146,7 +146,7 @@ protected: /// Contains values from CommandMarkerKind enum. unsigned CommandMarker : 1; }; - enum { NumBlockCommandCommentBits = NumCommentBits + + enum { NumBlockCommandCommentBits = NumCommentBits + CommandInfo::NumCommandIDBits + 1 }; class ParamCommandCommentBitfields { @@ -215,13 +215,17 @@ public: SourceRange getSourceRange() const LLVM_READONLY { return Range; } - SourceLocation getLocStart() const LLVM_READONLY { - return Range.getBegin(); + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); } + SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } - SourceLocation getLocEnd() const LLVM_READONLY { - return Range.getEnd(); + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocEnd() const LLVM_READONLY, + "Use getEndLoc instead") { + return getEndLoc(); } + SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } SourceLocation getLocation() const LLVM_READONLY { return Loc; } @@ -351,8 +355,7 @@ public: } SourceRange getCommandNameRange() const { - return SourceRange(getLocStart().getLocWithOffset(-1), - getLocEnd()); + return SourceRange(getBeginLoc().getLocWithOffset(-1), getEndLoc()); } RenderKind getRenderKind() const { @@ -566,9 +569,9 @@ public: ParagraphCommentBits.IsWhitespaceValid = false; - setSourceRange(SourceRange(Content.front()->getLocStart(), - Content.back()->getLocEnd())); - setLocation(Content.front()->getLocStart()); + setSourceRange(SourceRange(Content.front()->getBeginLoc(), + Content.back()->getEndLoc())); + setLocation(Content.front()->getBeginLoc()); } static bool classof(const Comment *C) { @@ -662,13 +665,13 @@ public: } SourceLocation getCommandNameBeginLoc() const { - return getLocStart().getLocWithOffset(1); + return getBeginLoc().getLocWithOffset(1); } SourceRange getCommandNameRange(const CommandTraits &Traits) const { StringRef Name = getCommandName(Traits); return SourceRange(getCommandNameBeginLoc(), - getLocStart().getLocWithOffset(1 + Name.size())); + getBeginLoc().getLocWithOffset(1 + Name.size())); } unsigned getNumArgs() const { @@ -688,7 +691,7 @@ public: if (Args.size() > 0) { SourceLocation NewLocEnd = Args.back().Range.getEnd(); if (NewLocEnd.isValid()) - setSourceRange(SourceRange(getLocStart(), NewLocEnd)); + setSourceRange(SourceRange(getBeginLoc(), NewLocEnd)); } } @@ -702,9 +705,9 @@ public: void setParagraph(ParagraphComment *PC) { Paragraph = PC; - SourceLocation NewLocEnd = PC->getLocEnd(); + SourceLocation NewLocEnd = PC->getEndLoc(); if (NewLocEnd.isValid()) - setSourceRange(SourceRange(getLocStart(), NewLocEnd)); + setSourceRange(SourceRange(getBeginLoc(), NewLocEnd)); } CommandMarkerKind getCommandMarker() const LLVM_READONLY { @@ -978,7 +981,7 @@ public: } SourceRange getTextRange() const { - return SourceRange(TextBegin, getLocEnd()); + return SourceRange(TextBegin, getEndLoc()); } }; @@ -987,7 +990,7 @@ struct DeclInfo { /// Declaration the comment is actually attached to (in the source). /// Should not be NULL. const Decl *CommentDecl; - + /// CurrentDecl is the declaration with which the FullComment is associated. /// /// It can be different from \c CommentDecl. It happens when we decide @@ -997,7 +1000,7 @@ struct DeclInfo { /// /// The information in the DeclInfo corresponds to CurrentDecl. const Decl *CurrentDecl; - + /// Parameters that can be referenced by \\param if \c CommentDecl is something /// that we consider a "function". ArrayRef ParamVars; @@ -1105,9 +1108,9 @@ public: if (Blocks.empty()) return; - setSourceRange(SourceRange(Blocks.front()->getLocStart(), - Blocks.back()->getLocEnd())); - setLocation(Blocks.front()->getLocStart()); + setSourceRange( + SourceRange(Blocks.front()->getBeginLoc(), Blocks.back()->getEndLoc())); + setLocation(Blocks.front()->getBeginLoc()); } static bool classof(const Comment *C) { @@ -1119,21 +1122,21 @@ public: } child_iterator child_end() const { - return reinterpret_cast(Blocks.end()); + return reinterpret_cast(Blocks.end()); } const Decl *getDecl() const LLVM_READONLY { return ThisDeclInfo->CommentDecl; } - + const DeclInfo *getDeclInfo() const LLVM_READONLY { if (!ThisDeclInfo->IsFilled) ThisDeclInfo->fill(); return ThisDeclInfo; } - + ArrayRef getBlocks() const { return Blocks; } - + }; } // end namespace comments } // end namespace clang diff --git a/include/clang/AST/CommentCommandTraits.h b/include/clang/AST/CommentCommandTraits.h index bac4e99dc7a4c509d56741df5baf23c70bdcb519..4fd007872c0134e3bd3f8d2f94e99d630c83901c 100644 --- a/include/clang/AST/CommentCommandTraits.h +++ b/include/clang/AST/CommentCommandTraits.h @@ -107,17 +107,17 @@ struct CommandInfo { /// \fn void f(int a); /// \endcode unsigned IsDeclarationCommand : 1; - + /// True if verbatim-like line command is a function declaration. unsigned IsFunctionDeclarationCommand : 1; /// True if block command is further describing a container API; such /// as \@coclass, \@classdesign, etc. unsigned IsRecordLikeDetailCommand : 1; - + /// True if block command is a container API; such as \@interface. unsigned IsRecordLikeDeclarationCommand : 1; - + /// True if this command is unknown. This \c CommandInfo object was /// created during parsing. unsigned IsUnknownCommand : 1; @@ -150,7 +150,7 @@ public: } const CommandInfo *getTypoCorrectCommandInfo(StringRef Typo) const; - + const CommandInfo *getCommandInfo(unsigned CommandID) const; const CommandInfo *registerUnknownCommand(StringRef CommandName); diff --git a/include/clang/AST/CommentLexer.h b/include/clang/AST/CommentLexer.h index 52c4eb9e309a1cda2b11cd027fa43b353c6e9752..3ef5b7c8c998c4178311d6a4610d7d89a97b6cbb 100644 --- a/include/clang/AST/CommentLexer.h +++ b/include/clang/AST/CommentLexer.h @@ -76,7 +76,7 @@ class Token { /// unused (command spelling can be found with CommandTraits). Otherwise, /// contains the length of the string that starts at TextPtr. unsigned IntVal; - + public: SourceLocation getLocation() const LLVM_READONLY { return Loc; } void setLocation(SourceLocation SL) { Loc = SL; } @@ -228,7 +228,7 @@ private: llvm::BumpPtrAllocator &Allocator; DiagnosticsEngine &Diags; - + const CommandTraits &Traits; const char *const BufferStart; diff --git a/include/clang/AST/CommentSema.h b/include/clang/AST/CommentSema.h index 0e94c33970caf9c4154eacd7aa47771d314740b2..632eba782b9244cbad9287eefd97931271eeec1e 100644 --- a/include/clang/AST/CommentSema.h +++ b/include/clang/AST/CommentSema.h @@ -191,11 +191,11 @@ public: void checkBlockCommandDuplicate(const BlockCommandComment *Command); void checkDeprecatedCommand(const BlockCommandComment *Comment); - + void checkFunctionDeclVerbatimLine(const BlockCommandComment *Comment); - + void checkContainerDeclVerbatimLine(const BlockCommandComment *Comment); - + void checkContainerDecl(const BlockCommandComment *Comment); /// Resolve parameter names to parameter indexes in function declaration. diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h index c10ca9e9670b7d327137c8d2d8416df9c3ac3659..0c910e0ffbf8b5316acf4d6cb006e88e6a7da532 100644 --- a/include/clang/AST/Decl.h +++ b/include/clang/AST/Decl.h @@ -81,9 +81,9 @@ class VarTemplateDecl; /// A client can read the relevant info using TypeLoc wrappers, e.g: /// @code /// TypeLoc TL = TypeSourceInfo->getTypeLoc(); -/// TL.getStartLoc().print(OS, SrcMgr); +/// TL.getBeginLoc().print(OS, SrcMgr); /// @endcode -class LLVM_ALIGNAS(8) TypeSourceInfo { +class alignas(8) TypeSourceInfo { // Contains a memory block after the class, used for type source information, // allocated by ASTContext. friend class ASTContext; @@ -98,7 +98,7 @@ public: /// Return the TypeLoc wrapper for the type source info. TypeLoc getTypeLoc() const; // implemented in TypeLoc.h - + /// Override the type stored in this TypeSourceInfo. Use with caution! void overrideType(QualType T) { Ty = T; } }; @@ -488,7 +488,7 @@ public: SourceLocation IdentL, IdentifierInfo *II, SourceLocation GnuLabelL); static LabelDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + LabelStmt *getStmt() const { return TheStmt; } void setStmt(LabelStmt *T) { TheStmt = T; } @@ -511,8 +511,8 @@ public: }; /// Represent a C++ namespace. -class NamespaceDecl : public NamedDecl, public DeclContext, - public Redeclarable +class NamespaceDecl : public NamedDecl, public DeclContext, + public Redeclarable { /// The starting location of the source range, pointing /// to either the namespace or the inline keyword. @@ -523,7 +523,7 @@ class NamespaceDecl : public NamedDecl, public DeclContext, /// A pointer to either the anonymous namespace that lives just inside /// this namespace or to the first namespace in the chain (the latter case - /// only when this is not the first in the chain), along with a + /// only when this is not the first in the chain), along with a /// boolean value indicating whether this is an inline namespace. llvm::PointerIntPair AnonOrFirstNamespaceAndInline; @@ -614,7 +614,11 @@ public: return SourceRange(LocStart, RBraceLoc); } - SourceLocation getLocStart() const LLVM_READONLY { return LocStart; } + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); + } + SourceLocation getBeginLoc() const LLVM_READONLY { return LocStart; } SourceLocation getRBraceLoc() const { return RBraceLoc; } void setLocStart(SourceLocation L) { LocStart = L; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } @@ -735,7 +739,11 @@ public: SourceRange getSourceRange() const override LLVM_READONLY; - SourceLocation getLocStart() const LLVM_READONLY { + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); + } + SourceLocation getBeginLoc() const LLVM_READONLY { return getOuterLocStart(); } @@ -1711,8 +1719,11 @@ private: /// contains all of the information known about the function. Other, /// previous declarations of the function are available via the /// getPreviousDecl() chain. -class FunctionDecl : public DeclaratorDecl, public DeclContext, +class FunctionDecl : public DeclaratorDecl, + public DeclContext, public Redeclarable { + // This class stores some data in DeclContext::FunctionDeclBits + // to save some space. Use the provided accessors to access it. public: /// The kind of templated function a FunctionDecl can be. enum TemplatedKind { @@ -1731,64 +1742,6 @@ private: LazyDeclStmtPtr Body; - // FIXME: This can be packed into the bitfields in DeclContext. - // NOTE: VC++ packs bitfields poorly if the types differ. - unsigned SClass : 3; - unsigned IsInline : 1; - unsigned IsInlineSpecified : 1; - -protected: - // This is shared by CXXConstructorDecl, CXXConversionDecl, and - // CXXDeductionGuideDecl. - unsigned IsExplicitSpecified : 1; - -private: - unsigned IsVirtualAsWritten : 1; - unsigned IsPure : 1; - unsigned HasInheritedPrototype : 1; - unsigned HasWrittenPrototype : 1; - unsigned IsDeleted : 1; - unsigned IsTrivial : 1; // sunk from CXXMethodDecl - - /// This flag indicates whether this function is trivial for the purpose of - /// calls. This is meaningful only when this function is a copy/move - /// constructor or a destructor. - unsigned IsTrivialForCall : 1; - - unsigned IsDefaulted : 1; // sunk from CXXMethoDecl - unsigned IsExplicitlyDefaulted : 1; //sunk from CXXMethodDecl - unsigned HasImplicitReturnZero : 1; - unsigned IsLateTemplateParsed : 1; - unsigned IsConstexpr : 1; - unsigned InstantiationIsPending : 1; - - /// Indicates if the function uses __try. - unsigned UsesSEHTry : 1; - - /// Indicates if the function was a definition but its body was - /// skipped. - unsigned HasSkippedBody : 1; - - /// Indicates if the function declaration will have a body, once we're done - /// parsing it. - unsigned WillHaveBody : 1; - - /// Indicates that this function is a multiversioned function using attribute - /// 'target'. - unsigned IsMultiVersion : 1; - -protected: - /// [C++17] Only used by CXXDeductionGuideDecl. Declared here to avoid - /// increasing the size of CXXDeductionGuideDecl by the size of an unsigned - /// int as opposed to adding a single bit to FunctionDecl. - /// Indicates that the Deduction Guide is the implicitly generated 'copy - /// deduction candidate' (is used during overload resolution). - unsigned IsCopyDeductionCandidate : 1; - -private: - - /// Store the ODRHash after first calculation. - unsigned HasODRHash : 1; unsigned ODRHash; /// End part of this FunctionDecl's source range. @@ -1858,25 +1811,22 @@ private: void setParams(ASTContext &C, ArrayRef NewParamInfo); + // This is unfortunately needed because ASTDeclWriter::VisitFunctionDecl + // need to access this bit but we want to avoid making ASTDeclWriter + // a friend of FunctionDeclBitfields just for this. + bool isDeletedBit() const { return FunctionDeclBits.IsDeleted; } + + /// Whether an ODRHash has been stored. + bool hasODRHash() const { return FunctionDeclBits.HasODRHash; } + + /// State that an ODRHash has been stored. + void setHasODRHash(bool B = true) { FunctionDeclBits.HasODRHash = B; } + protected: FunctionDecl(Kind DK, ASTContext &C, DeclContext *DC, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, StorageClass S, bool isInlineSpecified, - bool isConstexprSpecified) - : DeclaratorDecl(DK, DC, NameInfo.getLoc(), NameInfo.getName(), T, TInfo, - StartLoc), - DeclContext(DK), redeclarable_base(C), SClass(S), - IsInline(isInlineSpecified), IsInlineSpecified(isInlineSpecified), - IsExplicitSpecified(false), IsVirtualAsWritten(false), IsPure(false), - HasInheritedPrototype(false), HasWrittenPrototype(true), - IsDeleted(false), IsTrivial(false), IsTrivialForCall(false), - IsDefaulted(false), - IsExplicitlyDefaulted(false), HasImplicitReturnZero(false), - IsLateTemplateParsed(false), IsConstexpr(isConstexprSpecified), - InstantiationIsPending(false), UsesSEHTry(false), HasSkippedBody(false), - WillHaveBody(false), IsMultiVersion(false), - IsCopyDeductionCandidate(false), HasODRHash(false), ODRHash(0), - EndRangeLoc(NameInfo.getEndLoc()), DNLoc(NameInfo.getInfo()) {} + bool isConstexprSpecified); using redeclarable_base = Redeclarable; @@ -1931,7 +1881,7 @@ public: bool isConstexprSpecified = false); static FunctionDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + DeclarationNameInfo getNameInfo() const { return DeclarationNameInfo(getDeclName(), getLocation(), DNLoc); } @@ -2015,13 +1965,13 @@ public: /// This does not determine whether the function has been defined (e.g., in a /// previous definition); for that information, use isDefined. bool isThisDeclarationADefinition() const { - return IsDeleted || IsDefaulted || Body || HasSkippedBody || - IsLateTemplateParsed || WillHaveBody || hasDefiningAttr(); + return isDeletedAsWritten() || isDefaulted() || Body || hasSkippedBody() || + isLateTemplateParsed() || willHaveBody() || hasDefiningAttr(); } /// Returns whether this specific declaration of the function has a body. bool doesThisDeclarationHaveABody() const { - return Body || IsLateTemplateParsed; + return Body || isLateTemplateParsed(); } void setBody(Stmt *B); @@ -2031,62 +1981,102 @@ public: bool isVariadic() const; /// Whether this function is marked as virtual explicitly. - bool isVirtualAsWritten() const { return IsVirtualAsWritten; } - void setVirtualAsWritten(bool V) { IsVirtualAsWritten = V; } + bool isVirtualAsWritten() const { + return FunctionDeclBits.IsVirtualAsWritten; + } + + /// State that this function is marked as virtual explicitly. + void setVirtualAsWritten(bool V) { FunctionDeclBits.IsVirtualAsWritten = V; } /// Whether this virtual function is pure, i.e. makes the containing class /// abstract. - bool isPure() const { return IsPure; } + bool isPure() const { return FunctionDeclBits.IsPure; } void setPure(bool P = true); /// Whether this templated function will be late parsed. - bool isLateTemplateParsed() const { return IsLateTemplateParsed; } - void setLateTemplateParsed(bool ILT = true) { IsLateTemplateParsed = ILT; } + bool isLateTemplateParsed() const { + return FunctionDeclBits.IsLateTemplateParsed; + } + + /// State that this templated function will be late parsed. + void setLateTemplateParsed(bool ILT = true) { + FunctionDeclBits.IsLateTemplateParsed = ILT; + } /// Whether this function is "trivial" in some specialized C++ senses. /// Can only be true for default constructors, copy constructors, /// copy assignment operators, and destructors. Not meaningful until /// the class has been fully built by Sema. - bool isTrivial() const { return IsTrivial; } - void setTrivial(bool IT) { IsTrivial = IT; } + bool isTrivial() const { return FunctionDeclBits.IsTrivial; } + void setTrivial(bool IT) { FunctionDeclBits.IsTrivial = IT; } - bool isTrivialForCall() const { return IsTrivialForCall; } - void setTrivialForCall(bool IT) { IsTrivialForCall = IT; } + bool isTrivialForCall() const { return FunctionDeclBits.IsTrivialForCall; } + void setTrivialForCall(bool IT) { FunctionDeclBits.IsTrivialForCall = IT; } /// Whether this function is defaulted per C++0x. Only valid for /// special member functions. - bool isDefaulted() const { return IsDefaulted; } - void setDefaulted(bool D = true) { IsDefaulted = D; } + bool isDefaulted() const { return FunctionDeclBits.IsDefaulted; } + void setDefaulted(bool D = true) { FunctionDeclBits.IsDefaulted = D; } /// Whether this function is explicitly defaulted per C++0x. Only valid /// for special member functions. - bool isExplicitlyDefaulted() const { return IsExplicitlyDefaulted; } - void setExplicitlyDefaulted(bool ED = true) { IsExplicitlyDefaulted = ED; } + bool isExplicitlyDefaulted() const { + return FunctionDeclBits.IsExplicitlyDefaulted; + } + + /// State that this function is explicitly defaulted per C++0x. Only valid + /// for special member functions. + void setExplicitlyDefaulted(bool ED = true) { + FunctionDeclBits.IsExplicitlyDefaulted = ED; + } /// Whether falling off this function implicitly returns null/zero. /// If a more specific implicit return value is required, front-ends /// should synthesize the appropriate return statements. - bool hasImplicitReturnZero() const { return HasImplicitReturnZero; } - void setHasImplicitReturnZero(bool IRZ) { HasImplicitReturnZero = IRZ; } + bool hasImplicitReturnZero() const { + return FunctionDeclBits.HasImplicitReturnZero; + } + + /// State that falling off this function implicitly returns null/zero. + /// If a more specific implicit return value is required, front-ends + /// should synthesize the appropriate return statements. + void setHasImplicitReturnZero(bool IRZ) { + FunctionDeclBits.HasImplicitReturnZero = IRZ; + } /// Whether this function has a prototype, either because one /// was explicitly written or because it was "inherited" by merging /// a declaration without a prototype with a declaration that has a /// prototype. bool hasPrototype() const { - return HasWrittenPrototype || HasInheritedPrototype; + return hasWrittenPrototype() || hasInheritedPrototype(); } - bool hasWrittenPrototype() const { return HasWrittenPrototype; } + /// Whether this function has a written prototype. + bool hasWrittenPrototype() const { + return FunctionDeclBits.HasWrittenPrototype; + } + + /// State that this function has a written prototype. + void setHasWrittenPrototype(bool P = true) { + FunctionDeclBits.HasWrittenPrototype = P; + } /// Whether this function inherited its prototype from a /// previous declaration. - bool hasInheritedPrototype() const { return HasInheritedPrototype; } - void setHasInheritedPrototype(bool P = true) { HasInheritedPrototype = P; } + bool hasInheritedPrototype() const { + return FunctionDeclBits.HasInheritedPrototype; + } + + /// State that this function inherited its prototype from a + /// previous declaration. + void setHasInheritedPrototype(bool P = true) { + FunctionDeclBits.HasInheritedPrototype = P; + } /// Whether this is a (C++11) constexpr function or constexpr constructor. - bool isConstexpr() const { return IsConstexpr; } - void setConstexpr(bool IC) { IsConstexpr = IC; } + bool isConstexpr() const { return FunctionDeclBits.IsConstexpr; } + void setConstexpr(bool IC) { FunctionDeclBits.IsConstexpr = IC; } /// Whether the instantiation of this function is pending. /// This bit is set when the decision to instantiate this function is made @@ -2094,12 +2084,19 @@ public: /// cases where instantiation did not happen because the template definition /// was not seen in this TU. This bit remains set in those cases, under the /// assumption that the instantiation will happen in some other TU. - bool instantiationIsPending() const { return InstantiationIsPending; } - void setInstantiationIsPending(bool IC) { InstantiationIsPending = IC; } + bool instantiationIsPending() const { + return FunctionDeclBits.InstantiationIsPending; + } + + /// State that the instantiation of this function is pending. + /// (see instantiationIsPending) + void setInstantiationIsPending(bool IC) { + FunctionDeclBits.InstantiationIsPending = IC; + } /// Indicates the function uses __try. - bool usesSEHTry() const { return UsesSEHTry; } - void setUsesSEHTry(bool UST) { UsesSEHTry = UST; } + bool usesSEHTry() const { return FunctionDeclBits.UsesSEHTry; } + void setUsesSEHTry(bool UST) { FunctionDeclBits.UsesSEHTry = UST; } /// Whether this function has been deleted. /// @@ -2120,9 +2117,15 @@ public: /// }; /// @endcode // If a function is deleted, its first declaration must be. - bool isDeleted() const { return getCanonicalDecl()->IsDeleted; } - bool isDeletedAsWritten() const { return IsDeleted && !IsDefaulted; } - void setDeletedAsWritten(bool D = true) { IsDeleted = D; } + bool isDeleted() const { + return getCanonicalDecl()->FunctionDeclBits.IsDeleted; + } + + bool isDeletedAsWritten() const { + return FunctionDeclBits.IsDeleted && !isDefaulted(); + } + + void setDeletedAsWritten(bool D = true) { FunctionDeclBits.IsDeleted = D; } /// Determines whether this function is "main", which is the /// entry point into an executable program. @@ -2193,22 +2196,33 @@ public: bool isNoReturn() const; /// True if the function was a definition but its body was skipped. - bool hasSkippedBody() const { return HasSkippedBody; } - void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + bool hasSkippedBody() const { return FunctionDeclBits.HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { + FunctionDeclBits.HasSkippedBody = Skipped; + } /// True if this function will eventually have a body, once it's fully parsed. - bool willHaveBody() const { return WillHaveBody; } - void setWillHaveBody(bool V = true) { WillHaveBody = V; } + bool willHaveBody() const { return FunctionDeclBits.WillHaveBody; } + void setWillHaveBody(bool V = true) { FunctionDeclBits.WillHaveBody = V; } /// True if this function is considered a multiversioned function. - bool isMultiVersion() const { return getCanonicalDecl()->IsMultiVersion; } + bool isMultiVersion() const { + return getCanonicalDecl()->FunctionDeclBits.IsMultiVersion; + } /// Sets the multiversion state for this declaration and all of its /// redeclarations. void setIsMultiVersion(bool V = true) { - getCanonicalDecl()->IsMultiVersion = V; + getCanonicalDecl()->FunctionDeclBits.IsMultiVersion = V; } + /// True if this function is a multiversioned dispatch function as a part of + /// the cpu_specific/cpu_dispatch functionality. + bool isCPUDispatchMultiVersion() const; + /// True if this function is a multiversioned processor specific function as a + /// part of the cpu_specific/cpu_dispatch functionality. + bool isCPUSpecificMultiVersion() const; + void setPreviousDeclaration(FunctionDecl * PrevDecl); FunctionDecl *getCanonicalDecl() override; @@ -2289,27 +2303,42 @@ public: /// Returns the storage class as written in the source. For the /// computed linkage of symbol, see getLinkage. - StorageClass getStorageClass() const { return StorageClass(SClass); } + StorageClass getStorageClass() const { + return static_cast(FunctionDeclBits.SClass); + } + + /// Sets the storage class as written in the source. + void setStorageClass(StorageClass SClass) { + FunctionDeclBits.SClass = SClass; + } /// Determine whether the "inline" keyword was specified for this /// function. - bool isInlineSpecified() const { return IsInlineSpecified; } + bool isInlineSpecified() const { return FunctionDeclBits.IsInlineSpecified; } /// Set whether the "inline" keyword was specified for this function. void setInlineSpecified(bool I) { - IsInlineSpecified = I; - IsInline = I; + FunctionDeclBits.IsInlineSpecified = I; + FunctionDeclBits.IsInline = I; } /// Flag that this function is implicitly inline. - void setImplicitlyInline() { - IsInline = true; - } + void setImplicitlyInline(bool I = true) { FunctionDeclBits.IsInline = I; } /// Determine whether this function should be inlined, because it is /// either marked "inline" or "constexpr" or is a member function of a class /// that was defined in the class body. - bool isInlined() const { return IsInline; } + bool isInlined() const { return FunctionDeclBits.IsInline; } + + /// Whether this function is marked as explicit explicitly. + bool isExplicitSpecified() const { + return FunctionDeclBits.IsExplicitSpecified; + } + + /// State that this function is marked as explicit explicitly. + void setExplicitSpecified(bool ExpSpec = true) { + FunctionDeclBits.IsExplicitSpecified = ExpSpec; + } bool isInlineDefinitionExternallyVisible() const; @@ -2504,6 +2533,10 @@ public: /// stored on first call, then the stored value returned on the other calls. unsigned getODRHash(); + /// Returns cached ODRHash of the function. This must have been previously + /// computed and stored. + unsigned getODRHash() const; + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { @@ -2587,7 +2620,7 @@ public: InClassInitStyle InitStyle); static FieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + /// Returns the index of this field within its record, /// as appropriate for passing to ASTRecordLayout::getFieldOffset. unsigned getFieldIndex() const; @@ -2743,7 +2776,7 @@ public: QualType T, Expr *E, const llvm::APSInt &V); static EnumConstantDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + const Expr *getInitExpr() const { return (const Expr*) Init; } Expr *getInitExpr() { return (Expr*) Init; } const llvm::APSInt &getInitVal() const { return Val; } @@ -2840,7 +2873,11 @@ public: const Type *getTypeForDecl() const { return TypeForDecl; } void setTypeForDecl(const Type *TD) { TypeForDecl = TD; } - SourceLocation getLocStart() const LLVM_READONLY { return LocStart; } + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); + } + SourceLocation getBeginLoc() const LLVM_READONLY { return LocStart; } void setLocStart(SourceLocation L) { LocStart = L; } SourceRange getSourceRange() const override LLVM_READONLY { if (LocStart.isValid()) @@ -2856,7 +2893,7 @@ public: /// Base class for declarations which introduce a typedef-name. class TypedefNameDecl : public TypeDecl, public Redeclarable { - struct LLVM_ALIGNAS(8) ModedTInfo { + struct alignas(8) ModedTInfo { TypeSourceInfo *first; QualType second; }; @@ -3003,63 +3040,15 @@ public: }; /// Represents the declaration of a struct/union/class/enum. -class TagDecl - : public TypeDecl, public DeclContext, public Redeclarable { +class TagDecl : public TypeDecl, + public DeclContext, + public Redeclarable { + // This class stores some data in DeclContext::TagDeclBits + // to save some space. Use the provided accessors to access it. public: // This is really ugly. using TagKind = TagTypeKind; -private: - // FIXME: This can be packed into the bitfields in Decl. - /// The TagKind enum. - unsigned TagDeclKind : 3; - - /// True if this is a definition ("struct foo {};"), false if it is a - /// declaration ("struct foo;"). It is not considered a definition - /// until the definition has been fully processed. - unsigned IsCompleteDefinition : 1; - -protected: - /// True if this is currently being defined. - unsigned IsBeingDefined : 1; - -private: - /// True if this tag declaration is "embedded" (i.e., defined or declared - /// for the very first time) in the syntax of a declarator. - unsigned IsEmbeddedInDeclarator : 1; - - /// True if this tag is free standing, e.g. "struct foo;". - unsigned IsFreeStanding : 1; - -protected: - // These are used by (and only defined for) EnumDecl. - unsigned NumPositiveBits : 8; - unsigned NumNegativeBits : 8; - - /// True if this tag declaration is a scoped enumeration. Only - /// possible in C++11 mode. - unsigned IsScoped : 1; - - /// If this tag declaration is a scoped enum, - /// then this is true if the scoped enum was declared using the class - /// tag, false if it was declared with the struct tag. No meaning is - /// associated if this tag declaration is not a scoped enum. - unsigned IsScopedUsingClassTag : 1; - - /// True if this is an enumeration with fixed underlying type. Only - /// possible in C++11, Microsoft extensions, or Objective C mode. - unsigned IsFixed : 1; - - /// Indicates whether it is possible for declarations of this kind - /// to have an out-of-date definition. - /// - /// This option is only enabled when modules are enabled. - unsigned MayHaveOutOfDateDef : 1; - - /// Has the full definition of this type been required by a use somewhere in - /// the TU. - unsigned IsCompleteDefinitionRequired : 1; - private: SourceRange BraceRange; @@ -3086,16 +3075,7 @@ private: protected: TagDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation L, IdentifierInfo *Id, TagDecl *PrevDecl, - SourceLocation StartL) - : TypeDecl(DK, DC, L, Id, StartL), DeclContext(DK), redeclarable_base(C), - TagDeclKind(TK), IsCompleteDefinition(false), IsBeingDefined(false), - IsEmbeddedInDeclarator(false), IsFreeStanding(false), - IsCompleteDefinitionRequired(false), - TypedefNameDeclOrQualifier((TypedefNameDecl *)nullptr) { - assert((DK != Enum || TK == TTK_Enum) && - "EnumDecl not matched with TTK_Enum"); - setPreviousDecl(PrevDecl); - } + SourceLocation StartL); using redeclarable_base = Redeclarable; @@ -3116,6 +3096,17 @@ protected: /// This is a helper function for derived classes. void completeDefinition(); + /// True if this decl is currently being defined. + void setBeingDefined(bool V = true) { TagDeclBits.IsBeingDefined = V; } + + /// Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + void setMayHaveOutOfDateDef(bool V = true) { + TagDeclBits.MayHaveOutOfDateDef = V; + } + public: friend class ASTDeclReader; friend class ASTDeclWriter; @@ -3135,7 +3126,7 @@ public: /// Return SourceLocation representing start of source /// range ignoring outer template declarations. - SourceLocation getInnerLocStart() const { return getLocStart(); } + SourceLocation getInnerLocStart() const { return getBeginLoc(); } /// Return SourceLocation representing start of source /// range taking into account any outer template declarations. @@ -3154,33 +3145,54 @@ public: } /// Return true if this decl has its body fully specified. - bool isCompleteDefinition() const { - return IsCompleteDefinition; + bool isCompleteDefinition() const { return TagDeclBits.IsCompleteDefinition; } + + /// True if this decl has its body fully specified. + void setCompleteDefinition(bool V = true) { + TagDeclBits.IsCompleteDefinition = V; } /// Return true if this complete decl is /// required to be complete for some existing use. bool isCompleteDefinitionRequired() const { - return IsCompleteDefinitionRequired; + return TagDeclBits.IsCompleteDefinitionRequired; } - /// Return true if this decl is currently being defined. - bool isBeingDefined() const { - return IsBeingDefined; + /// True if this complete decl is + /// required to be complete for some existing use. + void setCompleteDefinitionRequired(bool V = true) { + TagDeclBits.IsCompleteDefinitionRequired = V; } + /// Return true if this decl is currently being defined. + bool isBeingDefined() const { return TagDeclBits.IsBeingDefined; } + + /// True if this tag declaration is "embedded" (i.e., defined or declared + /// for the very first time) in the syntax of a declarator. bool isEmbeddedInDeclarator() const { - return IsEmbeddedInDeclarator; + return TagDeclBits.IsEmbeddedInDeclarator; } + + /// True if this tag declaration is "embedded" (i.e., defined or declared + /// for the very first time) in the syntax of a declarator. void setEmbeddedInDeclarator(bool isInDeclarator) { - IsEmbeddedInDeclarator = isInDeclarator; + TagDeclBits.IsEmbeddedInDeclarator = isInDeclarator; } - bool isFreeStanding() const { return IsFreeStanding; } + /// True if this tag is free standing, e.g. "struct foo;". + bool isFreeStanding() const { return TagDeclBits.IsFreeStanding; } + + /// True if this tag is free standing, e.g. "struct foo;". void setFreeStanding(bool isFreeStanding = true) { - IsFreeStanding = isFreeStanding; + TagDeclBits.IsFreeStanding = isFreeStanding; } + /// Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + bool mayHaveOutOfDateDef() const { return TagDeclBits.MayHaveOutOfDateDef; } + /// Whether this declaration declares a type that is /// dependent, i.e., a type that somehow depends on template /// parameters. @@ -3203,21 +3215,15 @@ public: /// the struct/union/class/enum. TagDecl *getDefinition() const; - void setCompleteDefinition(bool V) { IsCompleteDefinition = V; } - - void setCompleteDefinitionRequired(bool V = true) { - IsCompleteDefinitionRequired = V; - } - StringRef getKindName() const { return TypeWithKeyword::getTagTypeKindName(getTagKind()); } TagKind getTagKind() const { - return TagKind(TagDeclKind); + return static_cast(TagDeclBits.TagDeclKind); } - void setTagKind(TagKind TK) { TagDeclKind = TK; } + void setTagKind(TagKind TK) { TagDeclBits.TagDeclKind = TK; } bool isStruct() const { return getTagKind() == TTK_Struct; } bool isInterface() const { return getTagKind() == TTK_Interface; } @@ -3297,6 +3303,9 @@ public: /// with a fixed underlying type, and in C we allow them to be forward-declared /// with no underlying type as an extension. class EnumDecl : public TagDecl { + // This class stores some data in DeclContext::EnumDeclBits + // to save some space. Use the provided accessors to access it. + /// This represent the integer type that the enum corresponds /// to for code generation purposes. Note that the enumerator constants may /// have a different type than this does. @@ -3324,23 +3333,51 @@ class EnumDecl : public TagDecl { /// information. MemberSpecializationInfo *SpecializationInfo = nullptr; + /// Store the ODRHash after first calculation. + /// The corresponding flag HasODRHash is in EnumDeclBits + /// and can be accessed with the provided accessors. + unsigned ODRHash; + EnumDecl(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, IdentifierInfo *Id, EnumDecl *PrevDecl, - bool Scoped, bool ScopedUsingClassTag, bool Fixed) - : TagDecl(Enum, TTK_Enum, C, DC, IdLoc, Id, PrevDecl, StartLoc) { - assert(Scoped || !ScopedUsingClassTag); - IntegerType = (const Type *)nullptr; - NumNegativeBits = 0; - NumPositiveBits = 0; - IsScoped = Scoped; - IsScopedUsingClassTag = ScopedUsingClassTag; - IsFixed = Fixed; - } + bool Scoped, bool ScopedUsingClassTag, bool Fixed); void anchor() override; void setInstantiationOfMemberEnum(ASTContext &C, EnumDecl *ED, TemplateSpecializationKind TSK); + + /// Sets the width in bits required to store all the + /// non-negative enumerators of this enum. + void setNumPositiveBits(unsigned Num) { + EnumDeclBits.NumPositiveBits = Num; + assert(EnumDeclBits.NumPositiveBits == Num && "can't store this bitcount"); + } + + /// Returns the width in bits required to store all the + /// negative enumerators of this enum. (see getNumNegativeBits) + void setNumNegativeBits(unsigned Num) { EnumDeclBits.NumNegativeBits = Num; } + + /// True if this tag declaration is a scoped enumeration. Only + /// possible in C++11 mode. + void setScoped(bool Scoped = true) { EnumDeclBits.IsScoped = Scoped; } + + /// If this tag declaration is a scoped enum, + /// then this is true if the scoped enum was declared using the class + /// tag, false if it was declared with the struct tag. No meaning is + /// associated if this tag declaration is not a scoped enum. + void setScopedUsingClassTag(bool ScopedUCT = true) { + EnumDeclBits.IsScopedUsingClassTag = ScopedUCT; + } + + /// True if this is an Objective-C, C++11, or + /// Microsoft-style enumeration with a fixed underlying type. + void setFixed(bool Fixed = true) { EnumDeclBits.IsFixed = Fixed; } + + /// True if a valid hash is stored in ODRHash. + bool hasODRHash() const { return EnumDeclBits.HasODRHash; } + void setHasODRHash(bool Hash = true) { EnumDeclBits.HasODRHash = Hash; } + public: friend class ASTDeclReader; @@ -3445,13 +3482,7 @@ public: /// Returns the width in bits required to store all the /// non-negative enumerators of this enum. - unsigned getNumPositiveBits() const { - return NumPositiveBits; - } - void setNumPositiveBits(unsigned Num) { - NumPositiveBits = Num; - assert(NumPositiveBits == Num && "can't store this bitcount"); - } + unsigned getNumPositiveBits() const { return EnumDeclBits.NumPositiveBits; } /// Returns the width in bits required to store all the /// negative enumerators of this enum. These widths include @@ -3462,28 +3493,21 @@ public: /// -1 1111111 1 /// -10 1110110 5 /// -101 1001011 8 - unsigned getNumNegativeBits() const { - return NumNegativeBits; - } - void setNumNegativeBits(unsigned Num) { - NumNegativeBits = Num; - } + unsigned getNumNegativeBits() const { return EnumDeclBits.NumNegativeBits; } /// Returns true if this is a C++11 scoped enumeration. - bool isScoped() const { - return IsScoped; - } + bool isScoped() const { return EnumDeclBits.IsScoped; } /// Returns true if this is a C++11 scoped enumeration. bool isScopedUsingClassTag() const { - return IsScopedUsingClassTag; + return EnumDeclBits.IsScopedUsingClassTag; } /// Returns true if this is an Objective-C, C++11, or /// Microsoft-style enumeration with a fixed underlying type. - bool isFixed() const { - return IsFixed; - } + bool isFixed() const { return EnumDeclBits.IsFixed; } + + unsigned getODRHash(); /// Returns true if this can be considered a complete type. bool isComplete() const { @@ -3546,7 +3570,10 @@ public: /// union Y { int A, B; }; // Has body with members A and B (FieldDecls). /// This decl will be marked invalid if *any* members are invalid. class RecordDecl : public TagDecl { + // This class stores some data in DeclContext::RecordDeclBits + // to save some space. Use the provided accessors to access it. public: + friend class DeclContext; /// Enum that represents the different ways arguments are passed to and /// returned from function calls. This takes into account the target-specific /// and version-specific rules along with the rules determined by the @@ -3570,46 +3597,6 @@ public: APK_CanNeverPassInRegs }; -private: - friend class DeclContext; - - // FIXME: This can be packed into the bitfields in Decl. - /// This is true if this struct ends with a flexible - /// array member (e.g. int X[]) or if this union contains a struct that does. - /// If so, this cannot be contained in arrays or other structs as a member. - unsigned HasFlexibleArrayMember : 1; - - /// Whether this is the type of an anonymous struct or union. - unsigned AnonymousStructOrUnion : 1; - - /// This is true if this struct has at least one member - /// containing an Objective-C object pointer type. - unsigned HasObjectMember : 1; - - /// This is true if struct has at least one member of - /// 'volatile' type. - unsigned HasVolatileMember : 1; - - /// Whether the field declarations of this record have been loaded - /// from external storage. To avoid unnecessary deserialization of - /// methods/nested types we allow deserialization of just the fields - /// when needed. - mutable unsigned LoadedFieldsFromExternalStorage : 1; - - /// Basic properties of non-trivial C structs. - unsigned NonTrivialToPrimitiveDefaultInitialize : 1; - unsigned NonTrivialToPrimitiveCopy : 1; - unsigned NonTrivialToPrimitiveDestroy : 1; - - /// Indicates whether this struct is destroyed in the callee. - /// - /// Please note that MSVC won't merge adjacent bitfields if they don't have - /// the same type. - unsigned ParamDestroyedInCallee : 1; - - /// Represents the way this type is passed to a function. - unsigned ArgPassingRestrictions : 2; - protected: RecordDecl(Kind DK, TagKind TK, const ASTContext &C, DeclContext *DC, SourceLocation StartLoc, SourceLocation IdLoc, @@ -3636,8 +3623,13 @@ public: return const_cast(this)->getMostRecentDecl(); } - bool hasFlexibleArrayMember() const { return HasFlexibleArrayMember; } - void setHasFlexibleArrayMember(bool V) { HasFlexibleArrayMember = V; } + bool hasFlexibleArrayMember() const { + return RecordDeclBits.HasFlexibleArrayMember; + } + + void setHasFlexibleArrayMember(bool V) { + RecordDeclBits.HasFlexibleArrayMember = V; + } /// Whether this is an anonymous struct or union. To be an anonymous /// struct or union, it must have been declared without a name and @@ -3650,47 +3642,54 @@ public: /// union X { int i; float f; }; /// union { int i; float f; } obj; /// @endcode - bool isAnonymousStructOrUnion() const { return AnonymousStructOrUnion; } + bool isAnonymousStructOrUnion() const { + return RecordDeclBits.AnonymousStructOrUnion; + } + void setAnonymousStructOrUnion(bool Anon) { - AnonymousStructOrUnion = Anon; + RecordDeclBits.AnonymousStructOrUnion = Anon; } - bool hasObjectMember() const { return HasObjectMember; } - void setHasObjectMember (bool val) { HasObjectMember = val; } + bool hasObjectMember() const { return RecordDeclBits.HasObjectMember; } + void setHasObjectMember(bool val) { RecordDeclBits.HasObjectMember = val; } - bool hasVolatileMember() const { return HasVolatileMember; } - void setHasVolatileMember (bool val) { HasVolatileMember = val; } + bool hasVolatileMember() const { return RecordDeclBits.HasVolatileMember; } + + void setHasVolatileMember(bool val) { + RecordDeclBits.HasVolatileMember = val; + } bool hasLoadedFieldsFromExternalStorage() const { - return LoadedFieldsFromExternalStorage; + return RecordDeclBits.LoadedFieldsFromExternalStorage; } - void setHasLoadedFieldsFromExternalStorage(bool val) { - LoadedFieldsFromExternalStorage = val; + + void setHasLoadedFieldsFromExternalStorage(bool val) const { + RecordDeclBits.LoadedFieldsFromExternalStorage = val; } /// Functions to query basic properties of non-trivial C structs. bool isNonTrivialToPrimitiveDefaultInitialize() const { - return NonTrivialToPrimitiveDefaultInitialize; + return RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize; } void setNonTrivialToPrimitiveDefaultInitialize(bool V) { - NonTrivialToPrimitiveDefaultInitialize = V; + RecordDeclBits.NonTrivialToPrimitiveDefaultInitialize = V; } bool isNonTrivialToPrimitiveCopy() const { - return NonTrivialToPrimitiveCopy; + return RecordDeclBits.NonTrivialToPrimitiveCopy; } void setNonTrivialToPrimitiveCopy(bool V) { - NonTrivialToPrimitiveCopy = V; + RecordDeclBits.NonTrivialToPrimitiveCopy = V; } bool isNonTrivialToPrimitiveDestroy() const { - return NonTrivialToPrimitiveDestroy; + return RecordDeclBits.NonTrivialToPrimitiveDestroy; } void setNonTrivialToPrimitiveDestroy(bool V) { - NonTrivialToPrimitiveDestroy = V; + RecordDeclBits.NonTrivialToPrimitiveDestroy = V; } /// Determine whether this class can be passed in registers. In C++ mode, @@ -3701,19 +3700,19 @@ public: } ArgPassingKind getArgPassingRestrictions() const { - return static_cast(ArgPassingRestrictions); + return static_cast(RecordDeclBits.ArgPassingRestrictions); } void setArgPassingRestrictions(ArgPassingKind Kind) { - ArgPassingRestrictions = static_cast(Kind); + RecordDeclBits.ArgPassingRestrictions = Kind; } bool isParamDestroyedInCallee() const { - return ParamDestroyedInCallee; + return RecordDeclBits.ParamDestroyedInCallee; } void setParamDestroyedInCallee(bool V) { - ParamDestroyedInCallee = V; + RecordDeclBits.ParamDestroyedInCallee = V; } /// Determines whether this declaration represents the @@ -3793,7 +3792,7 @@ public: /// Finds the first data member which has a name. /// nullptr is returned if no named data member exists. - const FieldDecl *findFirstNamedDataMember() const; + const FieldDecl *findFirstNamedDataMember() const; private: /// Deserialize just the fields. @@ -3816,7 +3815,7 @@ public: SourceLocation RParenLoc); static FileScopeAsmDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + SourceLocation getAsmLoc() const { return getLocation(); } SourceLocation getRParenLoc() const { return RParenLoc; } void setRParenLoc(SourceLocation L) { RParenLoc = L; } @@ -3836,6 +3835,8 @@ public: /// unnamed FunctionDecl. For example: /// ^{ statement-body } or ^(int arg1, float arg2){ statement-body } class BlockDecl : public Decl, public DeclContext { + // This class stores some data in DeclContext::BlockDeclBits + // to save some space. Use the provided accessors to access it. public: /// A class which contains all the information about a particular /// captured value. @@ -3876,16 +3877,6 @@ public: }; private: - // FIXME: This can be packed into the bitfields in Decl. - bool IsVariadic : 1; - bool CapturesCXXThis : 1; - bool BlockMissingReturnType : 1; - bool IsConversionFromLambda : 1; - - /// A bit that indicates this block is passed directly to a function as a - /// non-escaping parameter. - bool DoesNotEscape : 1; - /// A new[]'d array of pointers to ParmVarDecls for the formal /// parameters of this function. This is null if a prototype or if there are /// no formals. @@ -3902,19 +3893,16 @@ private: Decl *ManglingContextDecl = nullptr; protected: - BlockDecl(DeclContext *DC, SourceLocation CaretLoc) - : Decl(Block, DC, CaretLoc), DeclContext(Block), IsVariadic(false), - CapturesCXXThis(false), BlockMissingReturnType(true), - IsConversionFromLambda(false), DoesNotEscape(false) {} + BlockDecl(DeclContext *DC, SourceLocation CaretLoc); public: - static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); + static BlockDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation L); static BlockDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + SourceLocation getCaretLocation() const { return getLocation(); } - bool isVariadic() const { return IsVariadic; } - void setIsVariadic(bool value) { IsVariadic = value; } + bool isVariadic() const { return BlockDeclBits.IsVariadic; } + void setIsVariadic(bool value) { BlockDeclBits.IsVariadic = value; } CompoundStmt *getCompoundBody() const { return (CompoundStmt*) Body; } Stmt *getBody() const override { return (Stmt*) Body; } @@ -3957,7 +3945,7 @@ public: /// True if this block (or its nested blocks) captures /// anything of local storage from its enclosing scopes. - bool hasCaptures() const { return NumCaptures != 0 || CapturesCXXThis; } + bool hasCaptures() const { return NumCaptures || capturesCXXThis(); } /// Returns the number of captured variables. /// Does not include an entry for 'this'. @@ -3970,15 +3958,27 @@ public: capture_const_iterator capture_begin() const { return captures().begin(); } capture_const_iterator capture_end() const { return captures().end(); } - bool capturesCXXThis() const { return CapturesCXXThis; } - bool blockMissingReturnType() const { return BlockMissingReturnType; } - void setBlockMissingReturnType(bool val) { BlockMissingReturnType = val; } + bool capturesCXXThis() const { return BlockDeclBits.CapturesCXXThis; } + void setCapturesCXXThis(bool B = true) { BlockDeclBits.CapturesCXXThis = B; } + + bool blockMissingReturnType() const { + return BlockDeclBits.BlockMissingReturnType; + } + + void setBlockMissingReturnType(bool val = true) { + BlockDeclBits.BlockMissingReturnType = val; + } + + bool isConversionFromLambda() const { + return BlockDeclBits.IsConversionFromLambda; + } - bool isConversionFromLambda() const { return IsConversionFromLambda; } - void setIsConversionFromLambda(bool val) { IsConversionFromLambda = val; } + void setIsConversionFromLambda(bool val = true) { + BlockDeclBits.IsConversionFromLambda = val; + } - bool doesNotEscape() const { return DoesNotEscape; } - void setDoesNotEscape() { DoesNotEscape = true; } + bool doesNotEscape() const { return BlockDeclBits.DoesNotEscape; } + void setDoesNotEscape(bool B = true) { BlockDeclBits.DoesNotEscape = B; } bool capturesVariable(const VarDecl *var) const; @@ -3990,7 +3990,7 @@ public: } Decl *getBlockManglingContextDecl() const { - return ManglingContextDecl; + return ManglingContextDecl; } void setBlockMangling(unsigned Number, Decl *Ctx) { @@ -4126,16 +4126,16 @@ class ImportDecl final : public Decl, /// The imported module, along with a bit that indicates whether /// we have source-location information for each identifier in the module - /// name. + /// name. /// /// When the bit is false, we only have a single source location for the /// end of the import declaration. llvm::PointerIntPair ImportedAndComplete; - + /// The next import in the list of imports local to the translation /// unit being parsed (not loaded from an AST file). ImportDecl *NextLocalImport = nullptr; - + ImportDecl(DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef IdentifierLocs); @@ -4143,26 +4143,26 @@ class ImportDecl final : public Decl, SourceLocation EndLoc); ImportDecl(EmptyShell Empty) : Decl(Import, Empty) {} - + public: /// Create a new module import declaration. - static ImportDecl *Create(ASTContext &C, DeclContext *DC, + static ImportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation StartLoc, Module *Imported, ArrayRef IdentifierLocs); - + /// Create a new module import declaration for an implicitly-generated /// import. - static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC, - SourceLocation StartLoc, Module *Imported, + static ImportDecl *CreateImplicit(ASTContext &C, DeclContext *DC, + SourceLocation StartLoc, Module *Imported, SourceLocation EndLoc); - + /// Create a new, deserialized module import declaration. - static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID, + static ImportDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumLocations); - + /// Retrieve the module that was imported by the import declaration. Module *getImportedModule() const { return ImportedAndComplete.getPointer(); } - + /// Retrieves the locations of each of the identifiers that make up /// the complete module name in the import declaration. /// @@ -4199,21 +4199,25 @@ public: static ExportDecl *Create(ASTContext &C, DeclContext *DC, SourceLocation ExportLoc); static ExportDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + SourceLocation getExportLoc() const { return getLocation(); } SourceLocation getRBraceLoc() const { return RBraceLoc; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; } - SourceLocation getLocEnd() const LLVM_READONLY { + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocEnd() const LLVM_READONLY, + "Use getEndLoc instead") { + return getEndLoc(); + } + SourceLocation getEndLoc() const LLVM_READONLY { if (RBraceLoc.isValid()) return RBraceLoc; // No braces: get the end location of the (only) declaration in context // (if present). - return decls_empty() ? getLocation() : decls_begin()->getLocEnd(); + return decls_empty() ? getLocation() : decls_begin()->getEndLoc(); } SourceRange getSourceRange() const override LLVM_READONLY { - return SourceRange(getLocation(), getLocEnd()); + return SourceRange(getLocation(), getEndLoc()); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -4260,7 +4264,7 @@ template void Redeclarable::setPreviousDecl(decl_type *PrevDecl) { // Note: This routine is implemented here because we need both NamedDecl // and Redeclarable to be defined. - assert(RedeclLink.NextIsLatest() && + assert(RedeclLink.isFirst() && "setPreviousDecl on a decl already in a redeclaration chain"); if (PrevDecl) { @@ -4268,7 +4272,7 @@ void Redeclarable::setPreviousDecl(decl_type *PrevDecl) { // redeclaration, or we can build invalid chains. If the most recent // redeclaration is invalid, it won't be PrevDecl, but we want it anyway. First = PrevDecl->getFirstDecl(); - assert(First->RedeclLink.NextIsLatest() && "Expected first"); + assert(First->RedeclLink.isFirst() && "Expected first"); decl_type *MostRecent = First->getNextRedeclaration(); RedeclLink = PreviousDeclLink(cast(MostRecent)); diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index ae7cd4d10db087f4bd2c785a21a1d14a6d6f1964..647d52f0e1b5a9c86a40da9328625c506bfa6f0a 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -19,7 +19,6 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" -#include "clang/Basic/VersionTuple.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" @@ -28,6 +27,7 @@ #include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" +#include "llvm/Support/VersionTuple.h" #include #include #include @@ -83,7 +83,7 @@ enum AvailabilityResult { /// (and its subclasses) in its Decl::operator new(). Proper alignment /// of all subclasses (not requiring more than the alignment of Decl) is /// asserted in DeclBase.cpp. -class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl { +class alignas(8) Decl { public: /// Lists the kind of concrete classes of Decl. enum Kind { @@ -302,14 +302,14 @@ private: /// global variable, etc.) that is lexically inside an objc container /// definition. unsigned TopLevelDeclInObjCContainer : 1; - + /// Whether statistic collection is enabled. static bool StatisticsEnabled; protected: friend class ASTDeclReader; friend class ASTDeclWriter; - friend class ASTImporter; + friend class ASTNodeImporter; friend class ASTReader; friend class CXXClassMemberWrapper; friend class LinkageComputer; @@ -406,11 +406,19 @@ public: return SourceRange(getLocation(), getLocation()); } - SourceLocation getLocStart() const LLVM_READONLY { + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); + } + SourceLocation getBeginLoc() const LLVM_READONLY { return getSourceRange().getBegin(); } - SourceLocation getLocEnd() const LLVM_READONLY { + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocEnd() const LLVM_READONLY, + "Use getEndLoc instead") { + return getEndLoc(); + } + SourceLocation getEndLoc() const LLVM_READONLY { return getSourceRange().getEnd(); } @@ -629,7 +637,7 @@ protected: assert(isFromASTFile() && "Only works on a deserialized declaration"); *((unsigned*)this - 2) = ID; } - + public: /// Determine the availability of the given declaration. /// @@ -879,7 +887,7 @@ public: /// Whether this particular Decl is a canonical one. bool isCanonicalDecl() const { return getCanonicalDecl() == this; } - + protected: /// Returns the next redeclaration or itself if this is the only decl. /// @@ -956,10 +964,10 @@ public: /// Retrieve the previous declaration that declares the same entity /// as this declaration, or NULL if there is no previous declaration. Decl *getPreviousDecl() { return getPreviousDeclImpl(); } - + /// Retrieve the most recent declaration that declares the same entity /// as this declaration, or NULL if there is no previous declaration. - const Decl *getPreviousDecl() const { + const Decl *getPreviousDecl() const { return const_cast(this)->getPreviousDeclImpl(); } @@ -974,7 +982,7 @@ public: /// Retrieve the most recent declaration that declares the same entity /// as this declaration (which may be this declaration). - const Decl *getMostRecentDecl() const { + const Decl *getMostRecentDecl() const { return const_cast(this)->getMostRecentDeclImpl(); } @@ -1159,13 +1167,13 @@ protected: inline bool declaresSameEntity(const Decl *D1, const Decl *D2) { if (!D1 || !D2) return false; - + if (D1 == D2) return true; - + return D1->getCanonicalDecl() == D2->getCanonicalDecl(); } - + /// PrettyStackTraceDecl - If a crash occurs, indicate that it happened when /// doing something to a specific decl. class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { @@ -1250,47 +1258,431 @@ public: /// that directly derive from DeclContext are mentioned, not their subclasses): /// /// TranslationUnitDecl +/// ExternCContext /// NamespaceDecl -/// FunctionDecl /// TagDecl +/// OMPDeclareReductionDecl +/// FunctionDecl /// ObjCMethodDecl /// ObjCContainerDecl /// LinkageSpecDecl /// ExportDecl /// BlockDecl -/// OMPDeclareReductionDecl +/// CapturedDecl class DeclContext { - /// DeclKind - This indicates which class this is. - unsigned DeclKind : 8; + /// For makeDeclVisibleInContextImpl + friend class ASTDeclReader; + /// For reconcileExternalVisibleStorage, CreateStoredDeclsMap, + /// hasNeedToReconcileExternalVisibleStorage + friend class ExternalASTSource; + /// For CreateStoredDeclsMap + friend class DependentDiagnostic; + /// For hasNeedToReconcileExternalVisibleStorage, + /// hasLazyLocalLexicalLookups, hasLazyExternalLexicalLookups + friend class ASTWriter; - /// Whether this declaration context also has some external - /// storage that contains additional declarations that are lexically - /// part of this context. - mutable bool ExternalLexicalStorage : 1; + // We use uint64_t in the bit-fields below since some bit-fields + // cross the unsigned boundary and this breaks the packing. + + /// Stores the bits used by DeclContext. + /// If modified NumDeclContextBit, the ctor of DeclContext and the accessor + /// methods in DeclContext should be updated appropriately. + class DeclContextBitfields { + friend class DeclContext; + /// DeclKind - This indicates which class this is. + uint64_t DeclKind : 7; + + /// Whether this declaration context also has some external + /// storage that contains additional declarations that are lexically + /// part of this context. + mutable uint64_t ExternalLexicalStorage : 1; + + /// Whether this declaration context also has some external + /// storage that contains additional declarations that are visible + /// in this context. + mutable uint64_t ExternalVisibleStorage : 1; + + /// Whether this declaration context has had externally visible + /// storage added since the last lookup. In this case, \c LookupPtr's + /// invariant may not hold and needs to be fixed before we perform + /// another lookup. + mutable uint64_t NeedToReconcileExternalVisibleStorage : 1; + + /// If \c true, this context may have local lexical declarations + /// that are missing from the lookup table. + mutable uint64_t HasLazyLocalLexicalLookups : 1; + + /// If \c true, the external source may have lexical declarations + /// that are missing from the lookup table. + mutable uint64_t HasLazyExternalLexicalLookups : 1; + + /// If \c true, lookups should only return identifier from + /// DeclContext scope (for example TranslationUnit). Used in + /// LookupQualifiedName() + mutable uint64_t UseQualifiedLookup : 1; + }; - /// Whether this declaration context also has some external - /// storage that contains additional declarations that are visible - /// in this context. - mutable bool ExternalVisibleStorage : 1; + /// Number of bits in DeclContextBitfields. + enum { NumDeclContextBits = 13 }; - /// Whether this declaration context has had external visible - /// storage added since the last lookup. In this case, \c LookupPtr's - /// invariant may not hold and needs to be fixed before we perform - /// another lookup. - mutable bool NeedToReconcileExternalVisibleStorage : 1; + /// Stores the bits used by TagDecl. + /// If modified NumTagDeclBits and the accessor + /// methods in TagDecl should be updated appropriately. + class TagDeclBitfields { + friend class TagDecl; + /// For the bits in DeclContextBitfields + uint64_t : NumDeclContextBits; - /// If \c true, this context may have local lexical declarations - /// that are missing from the lookup table. - mutable bool HasLazyLocalLexicalLookups : 1; + /// The TagKind enum. + uint64_t TagDeclKind : 3; - /// If \c true, the external source may have lexical declarations - /// that are missing from the lookup table. - mutable bool HasLazyExternalLexicalLookups : 1; + /// True if this is a definition ("struct foo {};"), false if it is a + /// declaration ("struct foo;"). It is not considered a definition + /// until the definition has been fully processed. + uint64_t IsCompleteDefinition : 1; + + /// True if this is currently being defined. + uint64_t IsBeingDefined : 1; + + /// True if this tag declaration is "embedded" (i.e., defined or declared + /// for the very first time) in the syntax of a declarator. + uint64_t IsEmbeddedInDeclarator : 1; + + /// True if this tag is free standing, e.g. "struct foo;". + uint64_t IsFreeStanding : 1; + + /// Indicates whether it is possible for declarations of this kind + /// to have an out-of-date definition. + /// + /// This option is only enabled when modules are enabled. + uint64_t MayHaveOutOfDateDef : 1; + + /// Has the full definition of this type been required by a use somewhere in + /// the TU. + uint64_t IsCompleteDefinitionRequired : 1; + }; + + /// Number of non-inherited bits in TagDeclBitfields. + enum { NumTagDeclBits = 9 }; + + /// Stores the bits used by EnumDecl. + /// If modified NumEnumDeclBit and the accessor + /// methods in EnumDecl should be updated appropriately. + class EnumDeclBitfields { + friend class EnumDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + /// For the bits in TagDeclBitfields. + uint64_t : NumTagDeclBits; + + /// Width in bits required to store all the non-negative + /// enumerators of this enum. + uint64_t NumPositiveBits : 8; + + /// Width in bits required to store all the negative + /// enumerators of this enum. + uint64_t NumNegativeBits : 8; + + /// True if this tag declaration is a scoped enumeration. Only + /// possible in C++11 mode. + uint64_t IsScoped : 1; + + /// If this tag declaration is a scoped enum, + /// then this is true if the scoped enum was declared using the class + /// tag, false if it was declared with the struct tag. No meaning is + /// associated if this tag declaration is not a scoped enum. + uint64_t IsScopedUsingClassTag : 1; + + /// True if this is an enumeration with fixed underlying type. Only + /// possible in C++11, Microsoft extensions, or Objective C mode. + uint64_t IsFixed : 1; + + /// True if a valid hash is stored in ODRHash. + uint64_t HasODRHash : 1; + }; + + /// Number of non-inherited bits in EnumDeclBitfields. + enum { NumEnumDeclBits = 20 }; + + /// Stores the bits used by RecordDecl. + /// If modified NumRecordDeclBits and the accessor + /// methods in RecordDecl should be updated appropriately. + class RecordDeclBitfields { + friend class RecordDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + /// For the bits in TagDeclBitfields. + uint64_t : NumTagDeclBits; + + /// This is true if this struct ends with a flexible + /// array member (e.g. int X[]) or if this union contains a struct that does. + /// If so, this cannot be contained in arrays or other structs as a member. + uint64_t HasFlexibleArrayMember : 1; + + /// Whether this is the type of an anonymous struct or union. + uint64_t AnonymousStructOrUnion : 1; + + /// This is true if this struct has at least one member + /// containing an Objective-C object pointer type. + uint64_t HasObjectMember : 1; + + /// This is true if struct has at least one member of + /// 'volatile' type. + uint64_t HasVolatileMember : 1; + + /// Whether the field declarations of this record have been loaded + /// from external storage. To avoid unnecessary deserialization of + /// methods/nested types we allow deserialization of just the fields + /// when needed. + mutable uint64_t LoadedFieldsFromExternalStorage : 1; + + /// Basic properties of non-trivial C structs. + uint64_t NonTrivialToPrimitiveDefaultInitialize : 1; + uint64_t NonTrivialToPrimitiveCopy : 1; + uint64_t NonTrivialToPrimitiveDestroy : 1; + + /// Indicates whether this struct is destroyed in the callee. + uint64_t ParamDestroyedInCallee : 1; + + /// Represents the way this type is passed to a function. + uint64_t ArgPassingRestrictions : 2; + }; + + /// Number of non-inherited bits in RecordDeclBitfields. + enum { NumRecordDeclBits = 11 }; + + /// Stores the bits used by OMPDeclareReductionDecl. + /// If modified NumOMPDeclareReductionDeclBits and the accessor + /// methods in OMPDeclareReductionDecl should be updated appropriately. + class OMPDeclareReductionDeclBitfields { + friend class OMPDeclareReductionDecl; + /// For the bits in DeclContextBitfields + uint64_t : NumDeclContextBits; + + /// Kind of initializer, + /// function call or omp_priv initializtion. + uint64_t InitializerKind : 2; + }; + + /// Number of non-inherited bits in OMPDeclareReductionDeclBitfields. + enum { NumOMPDeclareReductionDeclBits = 2 }; + + /// Stores the bits used by FunctionDecl. + /// If modified NumFunctionDeclBits and the accessor + /// methods in FunctionDecl and CXXDeductionGuideDecl + /// (for IsCopyDeductionCandidate) should be updated appropriately. + class FunctionDeclBitfields { + friend class FunctionDecl; + /// For IsCopyDeductionCandidate + friend class CXXDeductionGuideDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + uint64_t SClass : 3; + uint64_t IsInline : 1; + uint64_t IsInlineSpecified : 1; + + /// This is shared by CXXConstructorDecl, + /// CXXConversionDecl, and CXXDeductionGuideDecl. + uint64_t IsExplicitSpecified : 1; + + uint64_t IsVirtualAsWritten : 1; + uint64_t IsPure : 1; + uint64_t HasInheritedPrototype : 1; + uint64_t HasWrittenPrototype : 1; + uint64_t IsDeleted : 1; + /// Used by CXXMethodDecl + uint64_t IsTrivial : 1; + + /// This flag indicates whether this function is trivial for the purpose of + /// calls. This is meaningful only when this function is a copy/move + /// constructor or a destructor. + uint64_t IsTrivialForCall : 1; + + /// Used by CXXMethodDecl + uint64_t IsDefaulted : 1; + /// Used by CXXMethodDecl + uint64_t IsExplicitlyDefaulted : 1; + uint64_t HasImplicitReturnZero : 1; + uint64_t IsLateTemplateParsed : 1; + uint64_t IsConstexpr : 1; + uint64_t InstantiationIsPending : 1; + + /// Indicates if the function uses __try. + uint64_t UsesSEHTry : 1; + + /// Indicates if the function was a definition + /// but its body was skipped. + uint64_t HasSkippedBody : 1; + + /// Indicates if the function declaration will + /// have a body, once we're done parsing it. + uint64_t WillHaveBody : 1; + + /// Indicates that this function is a multiversioned + /// function using attribute 'target'. + uint64_t IsMultiVersion : 1; + + /// [C++17] Only used by CXXDeductionGuideDecl. Indicates that + /// the Deduction Guide is the implicitly generated 'copy + /// deduction candidate' (is used during overload resolution). + uint64_t IsCopyDeductionCandidate : 1; + + /// Store the ODRHash after first calculation. + uint64_t HasODRHash : 1; + }; + + /// Number of non-inherited bits in FunctionDeclBitfields. + enum { NumFunctionDeclBits = 25 }; + + /// Stores the bits used by CXXConstructorDecl. If modified + /// NumCXXConstructorDeclBits and the accessor + /// methods in CXXConstructorDecl should be updated appropriately. + class CXXConstructorDeclBitfields { + friend class CXXConstructorDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + /// For the bits in FunctionDeclBitfields. + uint64_t : NumFunctionDeclBits; + + /// 25 bits to fit in the remaining availible space. + /// Note that this makes CXXConstructorDeclBitfields take + /// exactly 64 bits and thus the width of NumCtorInitializers + /// will need to be shrunk if some bit is added to NumDeclContextBitfields, + /// NumFunctionDeclBitfields or CXXConstructorDeclBitfields. + uint64_t NumCtorInitializers : 25; + uint64_t IsInheritingConstructor : 1; + }; + + /// Number of non-inherited bits in CXXConstructorDeclBitfields. + enum { NumCXXConstructorDeclBits = 26 }; + + /// Stores the bits used by ObjCMethodDecl. + /// If modified NumObjCMethodDeclBits and the accessor + /// methods in ObjCMethodDecl should be updated appropriately. + class ObjCMethodDeclBitfields { + friend class ObjCMethodDecl; + + /// This is needed for the bitwidth of Family below but + /// is defined in Basic/IdentifierTable.h which we do not include. + /// To avoid mismatches between the two definitions we have + /// a static_assert in the ctor of ObjCMethodDecl which checks + /// that these two ObjCMethodFamilyBitWidth are equal. + enum { ObjCMethodFamilyBitWidth = 4 }; + + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + /// The conventional meaning of this method; an ObjCMethodFamily. + /// This is not serialized; instead, it is computed on demand and + /// cached. + mutable uint64_t Family : ObjCMethodFamilyBitWidth; + + /// instance (true) or class (false) method. + uint64_t IsInstance : 1; + uint64_t IsVariadic : 1; + + /// True if this method is the getter or setter for an explicit property. + uint64_t IsPropertyAccessor : 1; + + /// Method has a definition. + uint64_t IsDefined : 1; + + /// Method redeclaration in the same interface. + uint64_t IsRedeclaration : 1; + + /// Is redeclared in the same interface. + mutable uint64_t HasRedeclaration : 1; + + /// \@required/\@optional + uint64_t DeclImplementation : 2; - /// If \c true, lookups should only return identifier from - /// DeclContext scope (for example TranslationUnit). Used in - /// LookupQualifiedName() - mutable bool UseQualifiedLookup : 1; + /// in, inout, etc. + uint64_t objcDeclQualifier : 7; + + /// Indicates whether this method has a related result type. + uint64_t RelatedResultType : 1; + + /// Whether the locations of the selector identifiers are in a + /// "standard" position, a enum SelectorLocationsKind. + uint64_t SelLocsKind : 2; + + /// Whether this method overrides any other in the class hierarchy. + /// + /// A method is said to override any method in the class's + /// base classes, its protocols, or its categories' protocols, that has + /// the same selector and is of the same kind (class or instance). + /// A method in an implementation is not considered as overriding the same + /// method in the interface or its categories. + uint64_t IsOverriding : 1; + + /// Indicates if the method was a definition but its body was skipped. + uint64_t HasSkippedBody : 1; + }; + + /// Number of non-inherited bits in ObjCMethodDeclBitfields. + enum { NumObjCMethodDeclBits = 24 }; + + /// Stores the bits used by ObjCContainerDecl. + /// If modified NumObjCContainerDeclBits and the accessor + /// methods in ObjCContainerDecl should be updated appropriately. + class ObjCContainerDeclBitfields { + friend class ObjCContainerDecl; + /// For the bits in DeclContextBitfields + uint32_t : NumDeclContextBits; + + // Not a bitfield but this saves space. + // Note that ObjCContainerDeclBitfields is full. + SourceLocation AtStart; + }; + + /// Number of non-inherited bits in ObjCContainerDeclBitfields. + /// Note that here we rely on the fact that SourceLocation is 32 bits + /// wide. We check this with the static_assert in the ctor of DeclContext. + enum { NumObjCContainerDeclBits = 64 - NumDeclContextBits }; + + /// Stores the bits used by LinkageSpecDecl. + /// If modified NumLinkageSpecDeclBits and the accessor + /// methods in LinkageSpecDecl should be updated appropriately. + class LinkageSpecDeclBitfields { + friend class LinkageSpecDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + /// The language for this linkage specification with values + /// in the enum LinkageSpecDecl::LanguageIDs. + uint64_t Language : 3; + + /// True if this linkage spec has braces. + /// This is needed so that hasBraces() returns the correct result while the + /// linkage spec body is being parsed. Once RBraceLoc has been set this is + /// not used, so it doesn't need to be serialized. + uint64_t HasBraces : 1; + }; + + /// Number of non-inherited bits in LinkageSpecDeclBitfields. + enum { NumLinkageSpecDeclBits = 4 }; + + /// Stores the bits used by BlockDecl. + /// If modified NumBlockDeclBits and the accessor + /// methods in BlockDecl should be updated appropriately. + class BlockDeclBitfields { + friend class BlockDecl; + /// For the bits in DeclContextBitfields. + uint64_t : NumDeclContextBits; + + uint64_t IsVariadic : 1; + uint64_t CapturesCXXThis : 1; + uint64_t BlockMissingReturnType : 1; + uint64_t IsConversionFromLambda : 1; + + /// A bit that indicates this block is passed directly to a function as a + /// non-escaping parameter. + uint64_t DoesNotEscape : 1; + }; + + /// Number of non-inherited bits in BlockDeclBitfields. + enum { NumBlockDeclBits = 5 }; /// Pointer to the data structure used to lookup declarations /// within this context (or a DependentStoredDeclsMap if this is a @@ -1301,9 +1693,50 @@ class DeclContext { mutable StoredDeclsMap *LookupPtr = nullptr; protected: - friend class ASTDeclReader; - friend class ASTWriter; - friend class ExternalASTSource; + /// This anonymous union stores the bits belonging to DeclContext and classes + /// deriving from it. The goal is to use otherwise wasted + /// space in DeclContext to store data belonging to derived classes. + /// The space saved is especially significient when pointers are aligned + /// to 8 bytes. In this case due to alignment requirements we have a + /// little less than 8 bytes free in DeclContext which we can use. + /// We check that none of the classes in this union is larger than + /// 8 bytes with static_asserts in the ctor of DeclContext. + union { + DeclContextBitfields DeclContextBits; + TagDeclBitfields TagDeclBits; + EnumDeclBitfields EnumDeclBits; + RecordDeclBitfields RecordDeclBits; + OMPDeclareReductionDeclBitfields OMPDeclareReductionDeclBits; + FunctionDeclBitfields FunctionDeclBits; + CXXConstructorDeclBitfields CXXConstructorDeclBits; + ObjCMethodDeclBitfields ObjCMethodDeclBits; + ObjCContainerDeclBitfields ObjCContainerDeclBits; + LinkageSpecDeclBitfields LinkageSpecDeclBits; + BlockDeclBitfields BlockDeclBits; + + static_assert(sizeof(DeclContextBitfields) <= 8, + "DeclContextBitfields is larger than 8 bytes!"); + static_assert(sizeof(TagDeclBitfields) <= 8, + "TagDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(EnumDeclBitfields) <= 8, + "EnumDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(RecordDeclBitfields) <= 8, + "RecordDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(OMPDeclareReductionDeclBitfields) <= 8, + "OMPDeclareReductionDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(FunctionDeclBitfields) <= 8, + "FunctionDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(CXXConstructorDeclBitfields) <= 8, + "CXXConstructorDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(ObjCMethodDeclBitfields) <= 8, + "ObjCMethodDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(ObjCContainerDeclBitfields) <= 8, + "ObjCContainerDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(LinkageSpecDeclBitfields) <= 8, + "LinkageSpecDeclBitfields is larger than 8 bytes!"); + static_assert(sizeof(BlockDeclBitfields) <= 8, + "BlockDeclBitfields is larger than 8 bytes!"); + }; /// FirstDecl - The first declaration stored within this declaration /// context. @@ -1321,18 +1754,13 @@ protected: static std::pair BuildDeclChain(ArrayRef Decls, bool FieldsAlreadyLoaded); - DeclContext(Decl::Kind K) - : DeclKind(K), ExternalLexicalStorage(false), - ExternalVisibleStorage(false), - NeedToReconcileExternalVisibleStorage(false), - HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), - UseQualifiedLookup(false) {} + DeclContext(Decl::Kind K); public: ~DeclContext(); Decl::Kind getDeclKind() const { - return static_cast(DeclKind); + return static_cast(DeclContextBits.DeclKind); } const char *getDeclKindName() const; @@ -1371,54 +1799,54 @@ public: return cast(this)->getASTContext(); } - bool isClosure() const { - return DeclKind == Decl::Block; - } + bool isClosure() const { return getDeclKind() == Decl::Block; } bool isObjCContainer() const { - switch (DeclKind) { - case Decl::ObjCCategory: - case Decl::ObjCCategoryImpl: - case Decl::ObjCImplementation: - case Decl::ObjCInterface: - case Decl::ObjCProtocol: - return true; + switch (getDeclKind()) { + case Decl::ObjCCategory: + case Decl::ObjCCategoryImpl: + case Decl::ObjCImplementation: + case Decl::ObjCInterface: + case Decl::ObjCProtocol: + return true; + default: + return false; } - return false; } bool isFunctionOrMethod() const { - switch (DeclKind) { + switch (getDeclKind()) { case Decl::Block: case Decl::Captured: case Decl::ObjCMethod: return true; default: - return DeclKind >= Decl::firstFunction && DeclKind <= Decl::lastFunction; + return getDeclKind() >= Decl::firstFunction && + getDeclKind() <= Decl::lastFunction; } } /// Test whether the context supports looking up names. bool isLookupContext() const { - return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec && - DeclKind != Decl::Export; + return !isFunctionOrMethod() && getDeclKind() != Decl::LinkageSpec && + getDeclKind() != Decl::Export; } bool isFileContext() const { - return DeclKind == Decl::TranslationUnit || DeclKind == Decl::Namespace; + return getDeclKind() == Decl::TranslationUnit || + getDeclKind() == Decl::Namespace; } bool isTranslationUnit() const { - return DeclKind == Decl::TranslationUnit; + return getDeclKind() == Decl::TranslationUnit; } bool isRecord() const { - return DeclKind >= Decl::firstRecord && DeclKind <= Decl::lastRecord; + return getDeclKind() >= Decl::firstRecord && + getDeclKind() <= Decl::lastRecord; } - bool isNamespace() const { - return DeclKind == Decl::Namespace; - } + bool isNamespace() const { return getDeclKind() == Decl::Namespace; } bool isStdNamespace() const; @@ -1517,7 +1945,7 @@ public: /// connected to this declaration context. /// /// For declaration contexts that have multiple semantically connected but - /// syntactically distinct contexts, such as C++ namespaces, this routine + /// syntactically distinct contexts, such as C++ namespaces, this routine /// retrieves the complete set of such declaration contexts in source order. /// For example, given: /// @@ -1779,10 +2207,14 @@ public: /// Removes a declaration from this context. void removeDecl(Decl *D); - + /// Checks whether a declaration is in this context. bool containsDecl(Decl *D) const; + /// Checks whether a declaration is in this context. + /// This also loads the Decls from the external source before the check. + bool containsDeclAndLoad(Decl *D) const; + using lookup_result = DeclContextLookupResult; using lookup_iterator = lookup_result::iterator; @@ -1882,7 +2314,7 @@ public: void setMustBuildLookupTable() { assert(this == getPrimaryContext() && "should only be called on primary context"); - HasLazyExternalLexicalLookups = true; + DeclContextBits.HasLazyExternalLexicalLookups = true; } /// Retrieve the internal representation of the lookup structure. @@ -1894,41 +2326,45 @@ public: /// Whether this DeclContext has external storage containing /// additional declarations that are lexically in this context. - bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; } + bool hasExternalLexicalStorage() const { + return DeclContextBits.ExternalLexicalStorage; + } /// State whether this DeclContext has external storage for /// declarations lexically in this context. - void setHasExternalLexicalStorage(bool ES = true) { - ExternalLexicalStorage = ES; + void setHasExternalLexicalStorage(bool ES = true) const { + DeclContextBits.ExternalLexicalStorage = ES; } /// Whether this DeclContext has external storage containing /// additional declarations that are visible in this context. - bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; } + bool hasExternalVisibleStorage() const { + return DeclContextBits.ExternalVisibleStorage; + } /// State whether this DeclContext has external storage for /// declarations visible in this context. - void setHasExternalVisibleStorage(bool ES = true) { - ExternalVisibleStorage = ES; + void setHasExternalVisibleStorage(bool ES = true) const { + DeclContextBits.ExternalVisibleStorage = ES; if (ES && LookupPtr) - NeedToReconcileExternalVisibleStorage = true; + DeclContextBits.NeedToReconcileExternalVisibleStorage = true; } /// Determine whether the given declaration is stored in the list of /// declarations lexically within this context. bool isDeclInLexicalTraversal(const Decl *D) const { - return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || + return D && (D->NextInContextAndBits.getPointer() || D == FirstDecl || D == LastDecl); } - bool setUseQualifiedLookup(bool use = true) { - bool old_value = UseQualifiedLookup; - UseQualifiedLookup = use; + bool setUseQualifiedLookup(bool use = true) const { + bool old_value = DeclContextBits.UseQualifiedLookup; + DeclContextBits.UseQualifiedLookup = use; return old_value; } bool shouldUseQualifiedLookup() const { - return UseQualifiedLookup; + return DeclContextBits.UseQualifiedLookup; } static bool classof(const Decl *D); @@ -1940,7 +2376,45 @@ public: bool Deserialize = false) const; private: - friend class DependentDiagnostic; + /// Whether this declaration context has had externally visible + /// storage added since the last lookup. In this case, \c LookupPtr's + /// invariant may not hold and needs to be fixed before we perform + /// another lookup. + bool hasNeedToReconcileExternalVisibleStorage() const { + return DeclContextBits.NeedToReconcileExternalVisibleStorage; + } + + /// State that this declaration context has had externally visible + /// storage added since the last lookup. In this case, \c LookupPtr's + /// invariant may not hold and needs to be fixed before we perform + /// another lookup. + void setNeedToReconcileExternalVisibleStorage(bool Need = true) const { + DeclContextBits.NeedToReconcileExternalVisibleStorage = Need; + } + + /// If \c true, this context may have local lexical declarations + /// that are missing from the lookup table. + bool hasLazyLocalLexicalLookups() const { + return DeclContextBits.HasLazyLocalLexicalLookups; + } + + /// If \c true, this context may have local lexical declarations + /// that are missing from the lookup table. + void setHasLazyLocalLexicalLookups(bool HasLLLL = true) const { + DeclContextBits.HasLazyLocalLexicalLookups = HasLLLL; + } + + /// If \c true, the external source may have lexical declarations + /// that are missing from the lookup table. + bool hasLazyExternalLexicalLookups() const { + return DeclContextBits.HasLazyExternalLexicalLookups; + } + + /// If \c true, the external source may have lexical declarations + /// that are missing from the lookup table. + void setHasLazyExternalLexicalLookups(bool HasLELL = true) const { + DeclContextBits.HasLazyExternalLexicalLookups = HasLELL; + } void reconcileExternalVisibleStorage() const; bool LoadLexicalDeclsFromExternalStorage() const; diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h index a64593c79d9bd25a12fc3bc5f4b53e7e79ef0f2a..07bb59bae275a3d1227542c7631d1e6a0c4abd3a 100644 --- a/include/clang/AST/DeclCXX.h +++ b/include/clang/AST/DeclCXX.h @@ -233,12 +233,20 @@ public: /// Retrieves the source range that contains the entire base specifier. SourceRange getSourceRange() const LLVM_READONLY { return Range; } - SourceLocation getLocStart() const LLVM_READONLY { return Range.getBegin(); } - SourceLocation getLocEnd() const LLVM_READONLY { return Range.getEnd(); } + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); + } + SourceLocation getBeginLoc() const LLVM_READONLY { return Range.getBegin(); } + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocEnd() const LLVM_READONLY, + "Use getEndLoc instead") { + return getEndLoc(); + } + SourceLocation getEndLoc() const LLVM_READONLY { return Range.getEnd(); } /// Get the location at which the base class type was written. SourceLocation getBaseTypeLoc() const LLVM_READONLY { - return BaseTypeInfo->getTypeLoc().getLocStart(); + return BaseTypeInfo->getTypeLoc().getBeginLoc(); } /// Determines whether the base class is a virtual base class (or not). @@ -264,7 +272,7 @@ public: return EllipsisLoc; } - /// Returns the access specifier for this base specifier. + /// Returns the access specifier for this base specifier. /// /// This is the actual base specifier as used for semantic analysis, so /// the result can never be AS_none. To retrieve the access specifier as @@ -564,7 +572,7 @@ class CXXRecordDecl : public RecordDecl { CXXRecordDecl *Definition; /// The first friend declaration in this class, or null if there - /// aren't any. + /// aren't any. /// /// This is actually currently stored in reverse order. LazyDeclPtr FirstFriend; @@ -606,14 +614,14 @@ class CXXRecordDecl : public RecordDecl { /// Whether this lambda is known to be dependent, even if its /// context isn't dependent. - /// + /// /// A lambda with a non-dependent context can be dependent if it occurs /// within the default argument of a function template, because the /// lambda will have been created with the enclosing context as its /// declaration context, rather than function. This is an unfortunate - /// artifact of having to parse the default arguments before. + /// artifact of having to parse the default arguments before. unsigned Dependent : 1; - + /// Whether this lambda is a generic lambda. unsigned IsGenericLambda : 1; @@ -626,28 +634,28 @@ class CXXRecordDecl : public RecordDecl { /// The number of explicit captures in this lambda. unsigned NumExplicitCaptures : 13; - /// The number used to indicate this lambda expression for name + /// The number used to indicate this lambda expression for name /// mangling in the Itanium C++ ABI. unsigned ManglingNumber = 0; - + /// The declaration that provides context for this lambda, if the /// actual DeclContext does not suffice. This is used for lambdas that /// occur within default arguments of function parameters within the class /// or within a data member initializer. LazyDeclPtr ContextDecl; - - /// The list of captures, both explicit and implicit, for this + + /// The list of captures, both explicit and implicit, for this /// lambda. Capture *Captures = nullptr; /// The type of the call method. TypeSourceInfo *MethodTyInfo; - LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, - bool Dependent, bool IsGeneric, - LambdaCaptureDefault CaptureDefault) - : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), - CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), + LambdaDefinitionData(CXXRecordDecl *D, TypeSourceInfo *Info, + bool Dependent, bool IsGeneric, + LambdaCaptureDefault CaptureDefault) + : DefinitionData(D), Dependent(Dependent), IsGenericLambda(IsGeneric), + CaptureDefault(CaptureDefault), NumCaptures(0), NumExplicitCaptures(0), MethodTyInfo(Info) { IsLambda = true; @@ -790,6 +798,18 @@ public: return data().Polymorphic || data().NumVBases != 0; } + /// @returns true if class is dynamic or might be dynamic because the + /// definition is incomplete of dependent. + bool mayBeDynamicClass() const { + return !hasDefinition() || isDynamicClass() || hasAnyDependentBases(); + } + + /// @returns true if class is non dynamic or might be non dynamic because the + /// definition is incomplete of dependent. + bool mayBeNonDynamicClass() const { + return !hasDefinition() || !isDynamicClass() || hasAnyDependentBases(); + } + void setIsParsingBaseSpecifiers() { data().IsParsingBaseSpecifiers = true; } bool isParsingBaseSpecifiers() const { @@ -1193,22 +1213,22 @@ public: return DD && DD->IsLambda; } - /// Determine whether this class describes a generic + /// Determine whether this class describes a generic /// lambda function object (i.e. function call operator is - /// a template). - bool isGenericLambda() const; + /// a template). + bool isGenericLambda() const; /// Retrieve the lambda call operator of the closure type /// if this is a closure type. - CXXMethodDecl *getLambdaCallOperator() const; + CXXMethodDecl *getLambdaCallOperator() const; /// Retrieve the lambda static invoker, the address of which /// is returned by the conversion operator, and the body of which - /// is forwarded to the lambda call operator. - CXXMethodDecl *getLambdaStaticInvoker() const; + /// is forwarded to the lambda call operator. + CXXMethodDecl *getLambdaStaticInvoker() const; /// Retrieve the generic lambda's template parameter list. - /// Returns null if the class does not represent a lambda or a generic + /// Returns null if the class does not represent a lambda or a generic /// lambda. TemplateParameterList *getGenericLambdaTemplateParameterList() const; @@ -1333,11 +1353,11 @@ public: /// not overridden. bool isAbstract() const { return data().Abstract; } - /// Determine whether this class is standard-layout per + /// Determine whether this class is standard-layout per /// C++ [class]p7. bool isStandardLayout() const { return data().IsStandardLayout; } - /// Determine whether this class was standard-layout per + /// Determine whether this class was standard-layout per /// C++11 [class]p7, specifically using the C++11 rules without any DRs. bool isCXX11StandardLayout() const { return data().IsCXX11StandardLayout; } @@ -1888,25 +1908,25 @@ public: /// If this is the closure type of a lambda expression, retrieve the /// number to be used for name mangling in the Itanium C++ ABI. /// - /// Zero indicates that this closure type has internal linkage, so the + /// Zero indicates that this closure type has internal linkage, so the /// mangling number does not matter, while a non-zero value indicates which /// lambda expression this is in this particular context. unsigned getLambdaManglingNumber() const { assert(isLambda() && "Not a lambda closure type!"); return getLambdaData().ManglingNumber; } - - /// Retrieve the declaration that provides additional context for a + + /// Retrieve the declaration that provides additional context for a /// lambda, when the normal declaration context is not specific enough. /// - /// Certain contexts (default arguments of in-class function parameters and + /// Certain contexts (default arguments of in-class function parameters and /// the initializers of data members) have separate name mangling rules for /// lambdas within the Itanium C++ ABI. For these cases, this routine provides - /// the declaration in which the lambda occurs, e.g., the function parameter + /// the declaration in which the lambda occurs, e.g., the function parameter /// or the non-static data member. Otherwise, it returns NULL to imply that /// the declaration context suffices. Decl *getLambdaContextDecl() const; - + /// Set the mangling number and context declaration for a lambda /// class. void setLambdaMangling(unsigned ManglingNumber, Decl *ContextDecl) { @@ -1987,7 +2007,8 @@ private: SC_None, false, false) { if (EndLocation.isValid()) setRangeEnd(EndLocation); - IsExplicitSpecified = IsExplicit; + setExplicitSpecified(IsExplicit); + setIsCopyDeductionCandidate(false); } public: @@ -2003,21 +2024,20 @@ public: static CXXDeductionGuideDecl *CreateDeserialized(ASTContext &C, unsigned ID); /// Whether this deduction guide is explicit. - bool isExplicit() const { return IsExplicitSpecified; } - - /// Whether this deduction guide was declared with the 'explicit' specifier. - bool isExplicitSpecified() const { return IsExplicitSpecified; } + bool isExplicit() const { return isExplicitSpecified(); } /// Get the template for which this guide performs deduction. TemplateDecl *getDeducedTemplate() const { return getDeclName().getCXXDeductionGuideTemplate(); } - void setIsCopyDeductionCandidate() { - IsCopyDeductionCandidate = true; + void setIsCopyDeductionCandidate(bool isCDC = true) { + FunctionDeclBits.IsCopyDeductionCandidate = isCDC; } - bool isCopyDeductionCandidate() const { return IsCopyDeductionCandidate; } + bool isCopyDeductionCandidate() const { + return FunctionDeclBits.IsCopyDeductionCandidate; + } // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -2463,31 +2483,20 @@ public: class CXXConstructorDecl final : public CXXMethodDecl, private llvm::TrailingObjects { + // This class stores some data in DeclContext::CXXConstructorDeclBits + // to save some space. Use the provided accessors to access it. + /// \name Support for base and member initializers. /// \{ /// The arguments used to initialize the base or member. LazyCXXCtorInitializersPtr CtorInitializers; - unsigned NumCtorInitializers : 31; - /// \} - - /// Whether this constructor declaration is an implicitly-declared - /// inheriting constructor. - unsigned IsInheritingConstructor : 1; CXXConstructorDecl(ASTContext &C, CXXRecordDecl *RD, SourceLocation StartLoc, const DeclarationNameInfo &NameInfo, QualType T, TypeSourceInfo *TInfo, bool isExplicitSpecified, bool isInline, bool isImplicitlyDeclared, bool isConstexpr, - InheritedConstructor Inherited) - : CXXMethodDecl(CXXConstructor, C, RD, StartLoc, NameInfo, T, TInfo, - SC_None, isInline, isConstexpr, SourceLocation()), - NumCtorInitializers(0), IsInheritingConstructor((bool)Inherited) { - setImplicit(isImplicitlyDeclared); - if (Inherited) - *getTrailingObjects() = Inherited; - IsExplicitSpecified = isExplicitSpecified; - } + InheritedConstructor Inherited); void anchor() override; @@ -2530,12 +2539,12 @@ public: /// Retrieve an iterator past the last initializer. init_iterator init_end() { - return init_begin() + NumCtorInitializers; + return init_begin() + getNumCtorInitializers(); } /// Retrieve an iterator past the last initializer. init_const_iterator init_end() const { - return init_begin() + NumCtorInitializers; + return init_begin() + getNumCtorInitializers(); } using init_reverse_iterator = std::reverse_iterator; @@ -2559,20 +2568,22 @@ public: /// Determine the number of arguments used to initialize the member /// or base. unsigned getNumCtorInitializers() const { - return NumCtorInitializers; + return CXXConstructorDeclBits.NumCtorInitializers; } void setNumCtorInitializers(unsigned numCtorInitializers) { - NumCtorInitializers = numCtorInitializers; + CXXConstructorDeclBits.NumCtorInitializers = numCtorInitializers; + // This assert added because NumCtorInitializers is stored + // in CXXConstructorDeclBits as a bitfield and its width has + // been shrunk from 32 bits to fit into CXXConstructorDeclBitfields. + assert(CXXConstructorDeclBits.NumCtorInitializers == + numCtorInitializers && "NumCtorInitializers overflow!"); } void setCtorInitializers(CXXCtorInitializer **Initializers) { CtorInitializers = Initializers; } - /// Whether this function is marked as explicit explicitly. - bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// Whether this function is explicit. bool isExplicit() const { return getCanonicalDecl()->isExplicitSpecified(); @@ -2653,12 +2664,20 @@ public: /// Determine whether this is an implicit constructor synthesized to /// model a call to a constructor inherited from a base class. - bool isInheritingConstructor() const { return IsInheritingConstructor; } + bool isInheritingConstructor() const { + return CXXConstructorDeclBits.IsInheritingConstructor; + } + + /// State that this is an implicit constructor synthesized to + /// model a call to a constructor inherited from a base class. + void setInheritingConstructor(bool isIC = true) { + CXXConstructorDeclBits.IsInheritingConstructor = isIC; + } /// Get the constructor that this inheriting constructor is based on. InheritedConstructor getInheritedConstructor() const { - return IsInheritingConstructor ? *getTrailingObjects() - : InheritedConstructor(); + return isInheritingConstructor() ? + *getTrailingObjects() : InheritedConstructor(); } CXXConstructorDecl *getCanonicalDecl() override { @@ -2753,7 +2772,7 @@ class CXXConversionDecl : public CXXMethodDecl { SourceLocation EndLocation) : CXXMethodDecl(CXXConversion, C, RD, StartLoc, NameInfo, T, TInfo, SC_None, isInline, isConstexpr, EndLocation) { - IsExplicitSpecified = isExplicitSpecified; + setExplicitSpecified(isExplicitSpecified); } void anchor() override; @@ -2771,9 +2790,6 @@ public: SourceLocation EndLocation); static CXXConversionDecl *CreateDeserialized(ASTContext &C, unsigned ID); - /// Whether this function is marked as explicit explicitly. - bool isExplicitSpecified() const { return IsExplicitSpecified; } - /// Whether this function is explicit. bool isExplicit() const { return getCanonicalDecl()->isExplicitSpecified(); @@ -2787,7 +2803,7 @@ public: /// Determine whether this conversion function is a conversion from /// a lambda closure type to a block pointer. bool isLambdaToBlockPointerConversion() const; - + CXXConversionDecl *getCanonicalDecl() override { return cast(FunctionDecl::getCanonicalDecl()); } @@ -2800,7 +2816,7 @@ public: static bool classofKind(Kind K) { return K == CXXConversion; } }; -/// Represents a linkage specification. +/// Represents a linkage specification. /// /// For example: /// \code @@ -2808,7 +2824,8 @@ public: /// \endcode class LinkageSpecDecl : public Decl, public DeclContext { virtual void anchor(); - + // This class stores some data in DeclContext::LinkageSpecDeclBits to save + // some space. Use the provided accessors to access it. public: /// Represents the language in a linkage specification. /// @@ -2822,16 +2839,6 @@ public: }; private: - /// The language for this linkage specification. - unsigned Language : 3; - - /// True if this linkage spec has braces. - /// - /// This is needed so that hasBraces() returns the correct result while the - /// linkage spec body is being parsed. Once RBraceLoc has been set this is - /// not used, so it doesn't need to be serialized. - unsigned HasBraces : 1; - /// The source location for the extern keyword. SourceLocation ExternLoc; @@ -2839,10 +2846,7 @@ private: SourceLocation RBraceLoc; LinkageSpecDecl(DeclContext *DC, SourceLocation ExternLoc, - SourceLocation LangLoc, LanguageIDs lang, bool HasBraces) - : Decl(LinkageSpec, DC, LangLoc), DeclContext(LinkageSpec), - Language(lang), HasBraces(HasBraces), ExternLoc(ExternLoc), - RBraceLoc(SourceLocation()) {} + SourceLocation LangLoc, LanguageIDs lang, bool HasBraces); public: static LinkageSpecDecl *Create(ASTContext &C, DeclContext *DC, @@ -2850,18 +2854,20 @@ public: SourceLocation LangLoc, LanguageIDs Lang, bool HasBraces); static LinkageSpecDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + /// Return the language specified by this linkage specification. - LanguageIDs getLanguage() const { return LanguageIDs(Language); } + LanguageIDs getLanguage() const { + return static_cast(LinkageSpecDeclBits.Language); + } /// Set the language specified by this linkage specification. - void setLanguage(LanguageIDs L) { Language = L; } + void setLanguage(LanguageIDs L) { LinkageSpecDeclBits.Language = L; } /// Determines whether this linkage specification had braces in /// its syntactic form. bool hasBraces() const { - assert(!RBraceLoc.isValid() || HasBraces); - return HasBraces; + assert(!RBraceLoc.isValid() || LinkageSpecDeclBits.HasBraces); + return LinkageSpecDeclBits.HasBraces; } SourceLocation getExternLoc() const { return ExternLoc; } @@ -2869,19 +2875,23 @@ public: void setExternLoc(SourceLocation L) { ExternLoc = L; } void setRBraceLoc(SourceLocation L) { RBraceLoc = L; - HasBraces = RBraceLoc.isValid(); + LinkageSpecDeclBits.HasBraces = RBraceLoc.isValid(); } - SourceLocation getLocEnd() const LLVM_READONLY { + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocEnd() const LLVM_READONLY, + "Use getEndLoc instead") { + return getEndLoc(); + } + SourceLocation getEndLoc() const LLVM_READONLY { if (hasBraces()) return getRBraceLoc(); // No braces: get the end location of the (only) declaration in context // (if present). - return decls_empty() ? getLocation() : decls_begin()->getLocEnd(); + return decls_empty() ? getLocation() : decls_begin()->getEndLoc(); } SourceRange getSourceRange() const override LLVM_READONLY { - return SourceRange(ExternLoc, getLocEnd()); + return SourceRange(ExternLoc, getEndLoc()); } static bool classof(const Decl *D) { return classofKind(D->getKind()); } @@ -3686,7 +3696,7 @@ class UnresolvedUsingTypenameDecl public: /// Returns the source location of the 'using' keyword. - SourceLocation getUsingLoc() const { return getLocStart(); } + SourceLocation getUsingLoc() const { return getBeginLoc(); } /// Returns the source location of the 'typename' keyword. SourceLocation getTypenameLoc() const { return TypenameLocation; } @@ -3758,7 +3768,7 @@ public: Expr *AssertExpr, StringLiteral *Message, SourceLocation RParenLoc, bool Failed); static StaticAssertDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + Expr *getAssertExpr() { return AssertExprAndFailed.getPointer(); } const Expr *getAssertExpr() const { return AssertExprAndFailed.getPointer(); } diff --git a/include/clang/AST/DeclFriend.h b/include/clang/AST/DeclFriend.h index 47fb68bf42d3ecc48030857f630b095bfd348118..b5808f23de6fedc4bcb0ba03664dbcbdb358d529 100644 --- a/include/clang/AST/DeclFriend.h +++ b/include/clang/AST/DeclFriend.h @@ -158,7 +158,7 @@ public: if (DD->getOuterLocStart() != DD->getInnerLocStart()) return DD->getSourceRange(); } - return SourceRange(getFriendLoc(), ND->getLocEnd()); + return SourceRange(getFriendLoc(), ND->getEndLoc()); } else if (TypeSourceInfo *TInfo = getFriendType()) { SourceLocation StartL = @@ -254,7 +254,7 @@ inline void CXXRecordDecl::pushFriendDecl(FriendDecl *FD) { FD->NextFriend = data().FirstFriend; data().FirstFriend = FD; } - + } // namespace clang #endif // LLVM_CLANG_AST_DECLFRIEND_H diff --git a/include/clang/AST/DeclLookups.h b/include/clang/AST/DeclLookups.h index 64eb3f24b37010a843d956812ceca986d6c684c1..9627f440d406c4380fda79b4a9fd1f91c957a4fc 100644 --- a/include/clang/AST/DeclLookups.h +++ b/include/clang/AST/DeclLookups.h @@ -54,7 +54,7 @@ public: ++It; } while (It != End && It->first == DeclarationName::getUsingDirectiveName()); - + return *this; } diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h index c81a5f805fc039e7f68767344c8bb844167b34b1..d6ec91b8cdcc9653a23fb35d61f32cf4371ea90b 100644 --- a/include/clang/AST/DeclObjC.h +++ b/include/clang/AST/DeclObjC.h @@ -137,62 +137,17 @@ public: /// the above methods are setMenu:, menu, replaceSubview:with:, and defaultMenu. /// class ObjCMethodDecl : public NamedDecl, public DeclContext { + // This class stores some data in DeclContext::ObjCMethodDeclBits + // to save some space. Use the provided accessors to access it. + public: enum ImplementationControl { None, Required, Optional }; private: - // The conventional meaning of this method; an ObjCMethodFamily. - // This is not serialized; instead, it is computed on demand and - // cached. - mutable unsigned Family : ObjCMethodFamilyBitWidth; - - /// instance (true) or class (false) method. - unsigned IsInstance : 1; - unsigned IsVariadic : 1; - - /// True if this method is the getter or setter for an explicit property. - unsigned IsPropertyAccessor : 1; - - // Method has a definition. - unsigned IsDefined : 1; - - /// Method redeclaration in the same interface. - unsigned IsRedeclaration : 1; - - /// Is redeclared in the same interface. - mutable unsigned HasRedeclaration : 1; - - // NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum - /// \@required/\@optional - unsigned DeclImplementation : 2; - - // NOTE: VC++ treats enums as signed, avoid using the ObjCDeclQualifier enum - /// in, inout, etc. - unsigned objcDeclQualifier : 7; - - /// Indicates whether this method has a related result type. - unsigned RelatedResultType : 1; - - /// Whether the locations of the selector identifiers are in a - /// "standard" position, a enum SelectorLocationsKind. - unsigned SelLocsKind : 2; - - /// Whether this method overrides any other in the class hierarchy. - /// - /// A method is said to override any method in the class's - /// base classes, its protocols, or its categories' protocols, that has - /// the same selector and is of the same kind (class or instance). - /// A method in an implementation is not considered as overriding the same - /// method in the interface or its categories. - unsigned IsOverriding : 1; - - /// Indicates if the method was a definition but its body was skipped. - unsigned HasSkippedBody : 1; - - // Return type of this method. + /// Return type of this method. QualType MethodDeclType; - // Type source information for the return type. + /// Type source information for the return type. TypeSourceInfo *ReturnTInfo; /// Array of ParmVarDecls for the formal parameters of this method @@ -203,7 +158,7 @@ private: /// List of attributes for this method declaration. SourceLocation DeclEndLoc; // the location of the ';' or '{'. - // The following are only used for method definitions, null otherwise. + /// The following are only used for method definitions, null otherwise. LazyDeclStmtPtr Body; /// SelfDecl - Decl for the implicit self parameter. This is lazily @@ -220,21 +175,14 @@ private: bool isVariadic = false, bool isPropertyAccessor = false, bool isImplicitlyDeclared = false, bool isDefined = false, ImplementationControl impControl = None, - bool HasRelatedResultType = false) - : NamedDecl(ObjCMethod, contextDecl, beginLoc, SelInfo), - DeclContext(ObjCMethod), Family(InvalidObjCMethodFamily), - IsInstance(isInstance), IsVariadic(isVariadic), - IsPropertyAccessor(isPropertyAccessor), IsDefined(isDefined), - IsRedeclaration(0), HasRedeclaration(0), DeclImplementation(impControl), - objcDeclQualifier(OBJC_TQ_None), - RelatedResultType(HasRelatedResultType), - SelLocsKind(SelLoc_StandardNoSpace), IsOverriding(0), HasSkippedBody(0), - MethodDeclType(T), ReturnTInfo(ReturnTInfo), DeclEndLoc(endLoc) { - setImplicit(isImplicitlyDeclared); - } + bool HasRelatedResultType = false); SelectorLocationsKind getSelLocsKind() const { - return (SelectorLocationsKind)SelLocsKind; + return static_cast(ObjCMethodDeclBits.SelLocsKind); + } + + void setSelLocsKind(SelectorLocationsKind Kind) { + ObjCMethodDeclBits.SelLocsKind = Kind; } bool hasStandardSelLocs() const { @@ -244,10 +192,10 @@ private: /// Get a pointer to the stored selector identifiers locations array. /// No locations will be stored if HasStandardSelLocs is true. SourceLocation *getStoredSelLocs() { - return reinterpret_cast(getParams() + NumParams); + return reinterpret_cast(getParams() + NumParams); } const SourceLocation *getStoredSelLocs() const { - return reinterpret_cast(getParams() + NumParams); + return reinterpret_cast(getParams() + NumParams); } /// Get a pointer to the stored selector identifiers locations array. @@ -297,36 +245,58 @@ public: } ObjCDeclQualifier getObjCDeclQualifier() const { - return ObjCDeclQualifier(objcDeclQualifier); + return static_cast(ObjCMethodDeclBits.objcDeclQualifier); + } + + void setObjCDeclQualifier(ObjCDeclQualifier QV) { + ObjCMethodDeclBits.objcDeclQualifier = QV; } - void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; } /// Determine whether this method has a result type that is related /// to the message receiver's type. - bool hasRelatedResultType() const { return RelatedResultType; } + bool hasRelatedResultType() const { + return ObjCMethodDeclBits.RelatedResultType; + } /// Note whether this method has a related result type. - void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; } + void setRelatedResultType(bool RRT = true) { + ObjCMethodDeclBits.RelatedResultType = RRT; + } /// True if this is a method redeclaration in the same interface. - bool isRedeclaration() const { return IsRedeclaration; } + bool isRedeclaration() const { return ObjCMethodDeclBits.IsRedeclaration; } + void setIsRedeclaration(bool RD) { ObjCMethodDeclBits.IsRedeclaration = RD; } void setAsRedeclaration(const ObjCMethodDecl *PrevMethod); + /// True if redeclared in the same interface. + bool hasRedeclaration() const { return ObjCMethodDeclBits.HasRedeclaration; } + void setHasRedeclaration(bool HRD) const { + ObjCMethodDeclBits.HasRedeclaration = HRD; + } + /// Returns the location where the declarator ends. It will be /// the location of ';' for a method declaration and the location of '{' /// for a method definition. SourceLocation getDeclaratorEndLoc() const { return DeclEndLoc; } // Location information, modeled after the Stmt API. - SourceLocation getLocStart() const LLVM_READONLY { return getLocation(); } - SourceLocation getLocEnd() const LLVM_READONLY; + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); + } + SourceLocation getBeginLoc() const LLVM_READONLY { return getLocation(); } + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocEnd() const LLVM_READONLY, + "Use getEndLoc instead") { + return getEndLoc(); + } + SourceLocation getEndLoc() const LLVM_READONLY; SourceRange getSourceRange() const override LLVM_READONLY { - return SourceRange(getLocation(), getLocEnd()); + return SourceRange(getLocation(), getEndLoc()); } SourceLocation getSelectorStartLoc() const { if (isImplicit()) - return getLocStart(); + return getBeginLoc(); return getSelectorLoc(0); } @@ -449,18 +419,26 @@ public: /// Determines the family of this method. ObjCMethodFamily getMethodFamily() const; - bool isInstanceMethod() const { return IsInstance; } - void setInstanceMethod(bool isInst) { IsInstance = isInst; } - bool isVariadic() const { return IsVariadic; } - void setVariadic(bool isVar) { IsVariadic = isVar; } + bool isInstanceMethod() const { return ObjCMethodDeclBits.IsInstance; } + void setInstanceMethod(bool isInst) { + ObjCMethodDeclBits.IsInstance = isInst; + } + + bool isVariadic() const { return ObjCMethodDeclBits.IsVariadic; } + void setVariadic(bool isVar) { ObjCMethodDeclBits.IsVariadic = isVar; } + + bool isClassMethod() const { return !isInstanceMethod(); } - bool isClassMethod() const { return !IsInstance; } + bool isPropertyAccessor() const { + return ObjCMethodDeclBits.IsPropertyAccessor; + } - bool isPropertyAccessor() const { return IsPropertyAccessor; } - void setPropertyAccessor(bool isAccessor) { IsPropertyAccessor = isAccessor; } + void setPropertyAccessor(bool isAccessor) { + ObjCMethodDeclBits.IsPropertyAccessor = isAccessor; + } - bool isDefined() const { return IsDefined; } - void setDefined(bool isDefined) { IsDefined = isDefined; } + bool isDefined() const { return ObjCMethodDeclBits.IsDefined; } + void setDefined(bool isDefined) { ObjCMethodDeclBits.IsDefined = isDefined; } /// Whether this method overrides any other in the class hierarchy. /// @@ -469,8 +447,8 @@ public: /// the same selector and is of the same kind (class or instance). /// A method in an implementation is not considered as overriding the same /// method in the interface or its categories. - bool isOverriding() const { return IsOverriding; } - void setOverriding(bool isOverriding) { IsOverriding = isOverriding; } + bool isOverriding() const { return ObjCMethodDeclBits.IsOverriding; } + void setOverriding(bool IsOver) { ObjCMethodDeclBits.IsOverriding = IsOver; } /// Return overridden methods for the given \p Method. /// @@ -484,8 +462,10 @@ public: SmallVectorImpl &Overridden) const; /// True if the method was a definition but its body was skipped. - bool hasSkippedBody() const { return HasSkippedBody; } - void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; } + bool hasSkippedBody() const { return ObjCMethodDeclBits.HasSkippedBody; } + void setHasSkippedBody(bool Skipped = true) { + ObjCMethodDeclBits.HasSkippedBody = Skipped; + } /// Returns the property associated with this method's selector. /// @@ -496,11 +476,11 @@ public: // Related to protocols declared in \@protocol void setDeclImplementation(ImplementationControl ic) { - DeclImplementation = ic; + ObjCMethodDeclBits.DeclImplementation = ic; } ImplementationControl getImplementationControl() const { - return ImplementationControl(DeclImplementation); + return ImplementationControl(ObjCMethodDeclBits.DeclImplementation); } bool isOptional() const { @@ -587,7 +567,7 @@ class ObjCTypeParamDecl : public TypedefNameDecl { /// explicitly specified. SourceLocation ColonLoc; - ObjCTypeParamDecl(ASTContext &ctx, DeclContext *dc, + ObjCTypeParamDecl(ASTContext &ctx, DeclContext *dc, ObjCTypeParamVariance variance, SourceLocation varianceLoc, unsigned index, SourceLocation nameLoc, IdentifierInfo *name, @@ -659,7 +639,7 @@ class ObjCTypeParamList final unsigned End; }; - union { + union { /// Location of the left and right angle brackets. PODSourceRange Brackets; @@ -984,7 +964,8 @@ public: /// ObjCProtocolDecl, and ObjCImplDecl. /// class ObjCContainerDecl : public NamedDecl, public DeclContext { - SourceLocation AtStart; + // This class stores some data in DeclContext::ObjCContainerDeclBits + // to save some space. Use the provided accessors to access it. // These two locations in the range mark the end of the method container. // The first points to the '@' token, and the second to the 'end' token. @@ -993,10 +974,8 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext { void anchor() override; public: - ObjCContainerDecl(Kind DK, DeclContext *DC, - IdentifierInfo *Id, SourceLocation nameLoc, - SourceLocation atStartLoc) - : NamedDecl(DK, DC, nameLoc, Id), DeclContext(DK), AtStart(atStartLoc) {} + ObjCContainerDecl(Kind DK, DeclContext *DC, IdentifierInfo *Id, + SourceLocation nameLoc, SourceLocation atStartLoc); // Iterator access to instance/class properties. using prop_iterator = specific_decl_iterator; @@ -1123,27 +1102,26 @@ public: ObjCPropertyDecl *>; using ProtocolPropertySet = llvm::SmallDenseSet; using PropertyDeclOrder = llvm::SmallVector; - + /// This routine collects list of properties to be implemented in the class. /// This includes, class's and its conforming protocols' properties. /// Note, the superclass's properties are not included in the list. virtual void collectPropertiesToImplement(PropertyMap &PM, PropertyDeclOrder &PO) const {} - SourceLocation getAtStartLoc() const { return AtStart; } - void setAtStartLoc(SourceLocation Loc) { AtStart = Loc; } + SourceLocation getAtStartLoc() const { return ObjCContainerDeclBits.AtStart; } - // Marks the end of the container. - SourceRange getAtEndRange() const { - return AtEnd; + void setAtStartLoc(SourceLocation Loc) { + ObjCContainerDeclBits.AtStart = Loc; } - void setAtEndRange(SourceRange atEnd) { - AtEnd = atEnd; - } + // Marks the end of the container. + SourceRange getAtEndRange() const { return AtEnd; } + + void setAtEndRange(SourceRange atEnd) { AtEnd = atEnd; } SourceRange getSourceRange() const override LLVM_READONLY { - return SourceRange(AtStart, getAtEndRange().getEnd()); + return SourceRange(getAtStartLoc(), getAtEndRange().getEnd()); } // Implement isa/cast/dyncast/etc. @@ -1195,15 +1173,15 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// TypeForDecl - This indicates the Type object that represents this /// TypeDecl. It is a cache maintained by ASTContext::getObjCInterfaceType mutable const Type *TypeForDecl = nullptr; - + struct DefinitionData { - /// The definition of this class, for quick access from any + /// The definition of this class, for quick access from any /// declaration. ObjCInterfaceDecl *Definition = nullptr; - + /// When non-null, this is always an ObjCObjectType. TypeSourceInfo *SuperClassTInfo = nullptr; - + /// Protocols referenced in the \@interface declaration ObjCProtocolList ReferencedProtocols; @@ -1247,11 +1225,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// One of the \c InheritedDesignatedInitializersState enumeratos. mutable unsigned InheritedDesignatedInitializers : 2; - + /// The location of the last location in this declaration, before - /// the properties/methods. For example, this will be the '>', '}', or - /// identifier, - SourceLocation EndLoc; + /// the properties/methods. For example, this will be the '>', '}', or + /// identifier, + SourceLocation EndLoc; DefinitionData() : ExternallyCompleted(false), IvarListMissingImplementation(true), @@ -1285,7 +1263,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl /// Allocate the definition data for this class. void allocateDefinitionData(); - + using redeclarable_base = Redeclarable; ObjCInterfaceDecl *getNextRedeclarationImpl() override { @@ -1334,7 +1312,7 @@ public: SourceRange getSourceRange() const override LLVM_READONLY { if (isThisDeclarationADefinition()) return ObjCContainerDecl::getSourceRange(); - + return SourceRange(getAtStartLoc(), getLocation()); } @@ -1390,7 +1368,7 @@ public: // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return protocol_iterator(); - + if (data().ExternallyCompleted) LoadExternalDefinition(); @@ -1453,7 +1431,7 @@ public: if (data().ExternallyCompleted) LoadExternalDefinition(); - return data().AllReferencedProtocols.empty() + return data().AllReferencedProtocols.empty() ? protocol_begin() : data().AllReferencedProtocols.begin(); } @@ -1462,11 +1440,11 @@ public: // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return all_protocol_iterator(); - + if (data().ExternallyCompleted) LoadExternalDefinition(); - return data().AllReferencedProtocols.empty() + return data().AllReferencedProtocols.empty() ? protocol_end() : data().AllReferencedProtocols.end(); } @@ -1476,17 +1454,17 @@ public: ivar_range ivars() const { return ivar_range(ivar_begin(), ivar_end()); } - ivar_iterator ivar_begin() const { + ivar_iterator ivar_begin() const { if (const ObjCInterfaceDecl *Def = getDefinition()) - return ivar_iterator(Def->decls_begin()); - + return ivar_iterator(Def->decls_begin()); + // FIXME: Should make sure no callers ever do this. return ivar_iterator(); } - ivar_iterator ivar_end() const { + ivar_iterator ivar_end() const { if (const ObjCInterfaceDecl *Def = getDefinition()) - return ivar_iterator(Def->decls_end()); + return ivar_iterator(Def->decls_end()); // FIXME: Should make sure no callers ever do this. return ivar_iterator(); @@ -1546,10 +1524,10 @@ public: /// Determine whether this particular declaration of this class is /// actually also a definition. - bool isThisDeclarationADefinition() const { + bool isThisDeclarationADefinition() const { return getDefinition() == this; } - + /// Determine whether this class has been defined. bool hasDefinition() const { // If the name of this class is out-of-date, bring it up-to-date, which @@ -1561,16 +1539,16 @@ public: return Data.getPointer(); } - - /// Retrieve the definition of this class, or NULL if this class - /// has been forward-declared (with \@class) but not yet defined (with + + /// Retrieve the definition of this class, or NULL if this class + /// has been forward-declared (with \@class) but not yet defined (with /// \@interface). ObjCInterfaceDecl *getDefinition() { return hasDefinition()? Data.getPointer()->Definition : nullptr; } - /// Retrieve the definition of this class, or NULL if this class - /// has been forward-declared (with \@class) but not yet defined (with + /// Retrieve the definition of this class, or NULL if this class + /// has been forward-declared (with \@class) but not yet defined (with /// \@interface). const ObjCInterfaceDecl *getDefinition() const { return hasDefinition()? Data.getPointer()->Definition : nullptr; @@ -1579,7 +1557,7 @@ public: /// Starts the definition of this Objective-C class, taking it from /// a forward declaration (\@class) to a definition (\@interface). void startDefinition(); - + /// Retrieve the superclass type. const ObjCObjectType *getSuperClassType() const { if (TypeSourceInfo *TInfo = getSuperClassTInfo()) @@ -1593,7 +1571,7 @@ public: // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return nullptr; - + if (data().ExternallyCompleted) LoadExternalDefinition(); @@ -1604,7 +1582,7 @@ public: // does not include any type arguments that apply to the superclass. ObjCInterfaceDecl *getSuperClass() const; - void setSuperClass(TypeSourceInfo *superClass) { + void setSuperClass(TypeSourceInfo *superClass) { data().SuperClassTInfo = superClass; } @@ -1618,7 +1596,7 @@ public: ObjCCategoryDecl *Current = nullptr; void findAcceptableCategory(); - + public: using value_type = ObjCCategoryDecl *; using reference = value_type; @@ -1659,7 +1637,7 @@ private: /// /// Used in the \c visible_categories_iterator. static bool isVisibleCategory(ObjCCategoryDecl *Cat); - + public: /// Iterator that walks over the list of categories and extensions /// that are visible, i.e., not hidden in a non-imported submodule. @@ -1765,7 +1743,7 @@ private: /// /// Used in the \c known_extensions_iterator. static bool isKnownExtension(ObjCCategoryDecl *Cat); - + public: friend class ASTDeclReader; friend class ASTDeclWriter; @@ -1787,7 +1765,7 @@ public: known_extensions_iterator known_extensions_begin() const { return known_extensions_iterator(getCategoryListRaw()); } - + /// Retrieve an iterator to the end of the known-extensions list. known_extensions_iterator known_extensions_end() const { return known_extensions_iterator(); @@ -1804,7 +1782,7 @@ public: // FIXME: Should make sure no callers ever do this. if (!hasDefinition()) return nullptr; - + if (data().ExternallyCompleted) LoadExternalDefinition(); @@ -1831,7 +1809,7 @@ public: while (I != nullptr) { if (declaresSameEntity(this, I)) return true; - + I = I->getSuperClass(); } return false; @@ -1841,7 +1819,7 @@ public: /// to be incompatible with __weak references. Returns true if it is. bool isArcWeakrefUnavailable() const; - /// isObjCRequiresPropertyDefs - Checks that a class or one of its super + /// isObjCRequiresPropertyDefs - Checks that a class or one of its super /// classes must not be auto-synthesized. Returns class decl. if it must not /// be; 0, otherwise. const ObjCInterfaceDecl *isObjCRequiresPropertyDefs() const; @@ -1854,7 +1832,7 @@ public: } ObjCProtocolDecl *lookupNestedProtocol(IdentifierInfo *Name); - + // Lookup a method. First, we search locally. If a method isn't // found, we search referenced protocols and class categories. ObjCMethodDecl *lookupMethod(Selector Sel, bool isInstance, @@ -1893,14 +1871,14 @@ public: true /* followsSuper */, Cat); } - - SourceLocation getEndOfDefinitionLoc() const { + + SourceLocation getEndOfDefinitionLoc() const { if (!hasDefinition()) return getLocation(); - - return data().EndLoc; + + return data().EndLoc; } - + void setEndOfDefinitionLoc(SourceLocation LE) { data().EndLoc = LE; } /// Retrieve the starting location of the superclass. @@ -1909,7 +1887,7 @@ public: /// isImplicitInterfaceDecl - check that this is an implicitly declared /// ObjCInterfaceDecl node. This is for legacy objective-c \@implementation /// declaration without an \@interface declaration. - bool isImplicitInterfaceDecl() const { + bool isImplicitInterfaceDecl() const { return hasDefinition() ? data().Definition->isImplicit() : isImplicit(); } @@ -1987,7 +1965,7 @@ public: bool synthesized=false); static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + /// Return the class interface that this ivar is logically contained /// in; this is either the interface where the ivar was declared, or the /// interface the ivar is conceptually a part of in the case of synthesized @@ -2045,7 +2023,7 @@ public: QualType T, Expr *BW); static ObjCAtDefsFieldDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } static bool classofKind(Kind K) { return K == ObjCAtDefsField; } @@ -2087,7 +2065,7 @@ class ObjCProtocolDecl : public ObjCContainerDecl, ObjCProtocolDecl *Definition; /// Referenced protocols - ObjCProtocolList ReferencedProtocols; + ObjCProtocolList ReferencedProtocols; }; /// Contains a pointer to the data associated with this class, @@ -2107,7 +2085,7 @@ class ObjCProtocolDecl : public ObjCContainerDecl, assert(Data.getPointer() && "Objective-C protocol has no definition!"); return *Data.getPointer(); } - + void allocateDefinitionData(); using redeclarable_base = Redeclarable; @@ -2152,15 +2130,15 @@ public: protocol_iterator protocol_begin() const { if (!hasDefinition()) return protocol_iterator(); - + return data().ReferencedProtocols.begin(); } - protocol_iterator protocol_end() const { + protocol_iterator protocol_end() const { if (!hasDefinition()) return protocol_iterator(); - - return data().ReferencedProtocols.end(); + + return data().ReferencedProtocols.end(); } using protocol_loc_iterator = ObjCProtocolList::loc_iterator; @@ -2173,22 +2151,22 @@ public: protocol_loc_iterator protocol_loc_begin() const { if (!hasDefinition()) return protocol_loc_iterator(); - + return data().ReferencedProtocols.loc_begin(); } protocol_loc_iterator protocol_loc_end() const { if (!hasDefinition()) return protocol_loc_iterator(); - + return data().ReferencedProtocols.loc_end(); } - unsigned protocol_size() const { + unsigned protocol_size() const { if (!hasDefinition()) return 0; - - return data().ReferencedProtocols.size(); + + return data().ReferencedProtocols.size(); } /// setProtocolList - Set the list of protocols that this interface @@ -2235,12 +2213,12 @@ public: return hasDefinition()? Data.getPointer()->Definition : nullptr; } - /// Determine whether this particular declaration is also the + /// Determine whether this particular declaration is also the /// definition. bool isThisDeclarationADefinition() const { return getDefinition() == this; } - + /// Starts the definition of this Objective-C protocol. void startDefinition(); @@ -2251,10 +2229,10 @@ public: SourceRange getSourceRange() const override LLVM_READONLY { if (isThisDeclarationADefinition()) return ObjCContainerDecl::getSourceRange(); - + return SourceRange(getAtStartLoc(), getLocation()); } - + using redecl_range = redeclarable_base::redecl_range; using redecl_iterator = redeclarable_base::redecl_iterator; @@ -2316,7 +2294,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl { /// class extension may have private ivars. SourceLocation IvarLBraceLoc; SourceLocation IvarRBraceLoc; - + ObjCCategoryDecl(DeclContext *DC, SourceLocation AtLoc, SourceLocation ClassNameLoc, SourceLocation CategoryNameLoc, IdentifierInfo *Id, ObjCInterfaceDecl *IDecl, @@ -2431,7 +2409,7 @@ public: SourceLocation getCategoryNameLoc() const { return CategoryNameLoc; } void setCategoryNameLoc(SourceLocation Loc) { CategoryNameLoc = Loc; } - + void setIvarLBraceLoc(SourceLocation Loc) { IvarLBraceLoc = Loc; } SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } @@ -2576,7 +2554,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { /// \@implementation may have private ivars. SourceLocation IvarLBraceLoc; SourceLocation IvarRBraceLoc; - + /// Support for ivar initialization. /// The arguments used to initialize the ivars LazyCXXCtorInitializersPtr IvarInitializers; @@ -2594,7 +2572,7 @@ class ObjCImplementationDecl : public ObjCImplDecl { ObjCInterfaceDecl *superDecl, SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation superLoc = SourceLocation(), - SourceLocation IvarLBraceLoc=SourceLocation(), + SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()) : ObjCImplDecl(ObjCImplementation, DC, classInterface, classInterface ? classInterface->getIdentifier() @@ -2616,7 +2594,7 @@ public: SourceLocation nameLoc, SourceLocation atStartLoc, SourceLocation superLoc = SourceLocation(), - SourceLocation IvarLBraceLoc=SourceLocation(), + SourceLocation IvarLBraceLoc=SourceLocation(), SourceLocation IvarRBraceLoc=SourceLocation()); static ObjCImplementationDecl *CreateDeserialized(ASTContext &C, unsigned ID); @@ -2700,7 +2678,7 @@ public: std::string getNameAsString() const { return getName(); } - + /// Produce a name to be used for class's metadata. It comes either via /// class's objc_runtime_name attribute or class name. StringRef getObjCRuntimeNameAsString() const; @@ -2715,7 +2693,7 @@ public: SourceLocation getIvarLBraceLoc() const { return IvarLBraceLoc; } void setIvarRBraceLoc(SourceLocation Loc) { IvarRBraceLoc = Loc; } SourceLocation getIvarRBraceLoc() const { return IvarRBraceLoc; } - + using ivar_iterator = specific_decl_iterator; using ivar_range = llvm::iterator_range>; @@ -2760,9 +2738,9 @@ public: SourceLocation L, IdentifierInfo *Id, ObjCInterfaceDecl* aliasedClass); - static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, + static ObjCCompatibleAliasDecl *CreateDeserialized(ASTContext &C, unsigned ID); - + const ObjCInterfaceDecl *getClassInterface() const { return AliasedClass; } ObjCInterfaceDecl *getClassInterface() { return AliasedClass; } void setClassInterface(ObjCInterfaceDecl *D) { AliasedClass = D; } @@ -2831,7 +2809,11 @@ public: SourceRange getSourceRange() const override LLVM_READONLY; - SourceLocation getLocStart() const LLVM_READONLY { return AtLoc; } + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { + return getBeginLoc(); + } + SourceLocation getBeginLoc() const LLVM_READONLY { return AtLoc; } void setAtLoc(SourceLocation Loc) { AtLoc = Loc; } ObjCPropertyDecl *getPropertyDecl() const { diff --git a/include/clang/AST/DeclOpenMP.h b/include/clang/AST/DeclOpenMP.h index bec3acffc43326c3e2ff009e97e1803930cbad4d..1f2aaa151e4be7b64719f92ee64bf4755e71584e 100644 --- a/include/clang/AST/DeclOpenMP.h +++ b/include/clang/AST/DeclOpenMP.h @@ -100,6 +100,8 @@ public: /// /// Here 'omp_out += omp_in' is a combiner and 'omp_priv = 0' is an initializer. class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext { + // This class stores some data in DeclContext::OMPDeclareReductionDeclBits + // to save some space. Use the provided accessors to access it. public: enum InitKind { CallInit, // Initialized by function call. @@ -113,8 +115,6 @@ private: Expr *Combiner; /// Initializer for declare reduction construct. Expr *Initializer; - /// Kind of initializer - function call or omp_priv initializtion. - InitKind InitializerKind = CallInit; /// Reference to the previous declare reduction construct in the same /// scope with the same name. Required for proper templates instantiation if @@ -125,10 +125,7 @@ private: OMPDeclareReductionDecl(Kind DK, DeclContext *DC, SourceLocation L, DeclarationName Name, QualType Ty, - OMPDeclareReductionDecl *PrevDeclInScope) - : ValueDecl(DK, DC, L, Name, Ty), DeclContext(DK), Combiner(nullptr), - Initializer(nullptr), InitializerKind(CallInit), - PrevDeclInScope(PrevDeclInScope) {} + OMPDeclareReductionDecl *PrevDeclInScope); void setPrevDeclInScope(OMPDeclareReductionDecl *Prev) { PrevDeclInScope = Prev; @@ -154,11 +151,13 @@ public: Expr *getInitializer() { return Initializer; } const Expr *getInitializer() const { return Initializer; } /// Get initializer kind. - InitKind getInitializerKind() const { return InitializerKind; } + InitKind getInitializerKind() const { + return static_cast(OMPDeclareReductionDeclBits.InitializerKind); + } /// Set initializer expression for the declare reduction construct. void setInitializer(Expr *E, InitKind IK) { Initializer = E; - InitializerKind = IK; + OMPDeclareReductionDeclBits.InitializerKind = IK; } /// Get reference to previous declare reduction construct in the same diff --git a/include/clang/AST/DeclTemplate.h b/include/clang/AST/DeclTemplate.h index a2f00ec9ffa228ae8d971318d61260fdb4beeabb..e0ea7cb8b1b83cf26625e37ea811986cac5abbe6 100644 --- a/include/clang/AST/DeclTemplate.h +++ b/include/clang/AST/DeclTemplate.h @@ -734,8 +734,8 @@ public: }; /// Declaration of a redeclarable template. -class RedeclarableTemplateDecl : public TemplateDecl, - public Redeclarable +class RedeclarableTemplateDecl : public TemplateDecl, + public Redeclarable { using redeclarable_base = Redeclarable; @@ -823,7 +823,7 @@ protected: /// Pointer to the common data shared by all declarations of this /// template. mutable CommonBase *Common = nullptr; - + /// Retrieves the "common" pointer shared by all (re-)declarations of /// the same template. Calling this routine may implicitly allocate memory /// for the common pointer. @@ -888,10 +888,10 @@ public: } /// Retrieve the member template from which this template was - /// instantiated, or nullptr if this template was not instantiated from a + /// instantiated, or nullptr if this template was not instantiated from a /// member template. /// - /// A template is instantiated from a member template when the member + /// A template is instantiated from a member template when the member /// template itself is part of a class template (or member thereof). For /// example, given /// @@ -1178,7 +1178,7 @@ public: unsigned D, unsigned P, IdentifierInfo *Id, bool Typename, bool ParameterPack); - static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, + static TemplateTypeParmDecl *CreateDeserialized(const ASTContext &C, unsigned ID); /// Whether this template type parameter was declared with @@ -1312,12 +1312,12 @@ public: QualType T, TypeSourceInfo *TInfo, ArrayRef ExpandedTypes, ArrayRef ExpandedTInfos); - static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, + static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID); - static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, + static NonTypeTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumExpandedTypes); - + using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; using TemplateParmPosition::getPosition; @@ -1495,7 +1495,7 @@ public: static TemplateTemplateParmDecl *CreateDeserialized(ASTContext &C, unsigned ID, unsigned NumExpansions); - + using TemplateParmPosition::getDepth; using TemplateParmPosition::setDepth; using TemplateParmPosition::getPosition; @@ -2442,7 +2442,7 @@ public: static ClassScopeFunctionSpecializationDecl * CreateDeserialized(ASTContext &Context, unsigned ID); - + // Implement isa/cast/dyncast/etc. static bool classof(const Decl *D) { return classofKind(D->getKind()); } diff --git a/include/clang/AST/DeclarationName.h b/include/clang/AST/DeclarationName.h index 9d3dad6bbd9d2a2bf05e5e02b8c7c6cb228bffa6..d544579cda30dafc230fe78d8677687d783457a7 100644 --- a/include/clang/AST/DeclarationName.h +++ b/include/clang/AST/DeclarationName.h @@ -14,11 +14,13 @@ #ifndef LLVM_CLANG_AST_DECLARATIONNAME_H #define LLVM_CLANG_AST_DECLARATIONNAME_H +#include "clang/AST/Type.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/IdentifierTable.h" #include "clang/Basic/PartialDiagnostic.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/DenseMapInfo.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/type_traits.h" #include @@ -39,9 +41,7 @@ class IdentifierInfo; class MultiKeywordSelector; enum OverloadedOperatorKind : int; struct PrintingPolicy; -class QualType; class TemplateDecl; -class Type; class TypeSourceInfo; class UsingDirectiveDecl; @@ -211,14 +211,14 @@ public: /// getNameKind - Determine what kind of name this is. NameKind getNameKind() const; - /// Determines whether the name itself is dependent, e.g., because it + /// Determines whether the name itself is dependent, e.g., because it /// involves a C++ type that is itself dependent. /// /// Note that this does not capture all of the notions of "dependent name", - /// because an identifier can be a dependent name if it is used as the + /// because an identifier can be a dependent name if it is used as the /// callee in a call expression with dependent arguments. bool isDependentName() const; - + /// getNameAsString - Retrieve the human-readable string for this name. std::string getAsString() const; @@ -343,33 +343,113 @@ inline bool operator>=(DeclarationName LHS, DeclarationName RHS) { return DeclarationName::compare(LHS, RHS) >= 0; } +/// CXXSpecialName - Records the type associated with one of the +/// "special" kinds of declaration names in C++, e.g., constructors, +/// destructors, and conversion functions. +class CXXSpecialName : public DeclarationNameExtra, + public llvm::FoldingSetNode { +public: + /// Type - The type associated with this declaration name. + QualType Type; + + /// FETokenInfo - Extra information associated with this declaration + /// name that can be used by the front end. All bits are really needed + /// so it is not possible to stash something in the low order bits. + void *FETokenInfo; + + void Profile(llvm::FoldingSetNodeID &ID) { + ID.AddInteger(ExtraKindOrNumArgs); + ID.AddPointer(Type.getAsOpaquePtr()); + } +}; + +/// Contains extra information for the name of a C++ deduction guide. +class CXXDeductionGuideNameExtra : public DeclarationNameExtra, + public llvm::FoldingSetNode { +public: + /// The template named by the deduction guide. + TemplateDecl *Template; + + /// FETokenInfo - Extra information associated with this operator + /// name that can be used by the front end. All bits are really needed + /// so it is not possible to stash something in the low order bits. + void *FETokenInfo; + + void Profile(llvm::FoldingSetNodeID &ID) { ID.AddPointer(Template); } +}; + +/// CXXOperatorIdName - Contains extra information for the name of an +/// overloaded operator in C++, such as "operator+. +class CXXOperatorIdName : public DeclarationNameExtra { +public: + /// FETokenInfo - Extra information associated with this operator + /// name that can be used by the front end. All bits are really needed + /// so it is not possible to stash something in the low order bits. + void *FETokenInfo; +}; + +/// CXXLiteralOperatorName - Contains the actual identifier that makes up the +/// name. +/// +/// This identifier is stored here rather than directly in DeclarationName so as +/// to allow Objective-C selectors, which are about a million times more common, +/// to consume minimal memory. +class CXXLiteralOperatorIdName : public DeclarationNameExtra, + public llvm::FoldingSetNode { +public: + IdentifierInfo *ID; + + /// FETokenInfo - Extra information associated with this operator + /// name that can be used by the front end. All bits are really needed + /// so it is not possible to stash something in the low order bits. + void *FETokenInfo; + + void Profile(llvm::FoldingSetNodeID &FSID) { FSID.AddPointer(ID); } +}; + /// DeclarationNameTable - Used to store and retrieve DeclarationName /// instances for the various kinds of declaration names, e.g., normal /// identifiers, C++ constructor names, etc. This class contains /// uniqued versions of each of the C++ special names, which can be -/// retrieved using its member functions (e.g., -/// getCXXConstructorName). +/// retrieved using its member functions (e.g., getCXXConstructorName). class DeclarationNameTable { + /// Used to allocate elements in the FoldingSets and + /// in the array of CXXOperatorIdName below. const ASTContext &Ctx; - // Actually a FoldingSet * - void *CXXSpecialNamesImpl; - - // Operator names + /// Manage the uniqued CXXSpecialName, which contain extra information + /// for the "special" kinds of declaration names in C++ such as constructors, + /// destructors and conversion functions. getCXXConstructorName, + /// getCXXDestructorName, getCXXConversionFunctionName, and getCXXSpecialName + /// can be used to obtain a DeclarationName from the corresponding type. + llvm::FoldingSet CXXSpecialNames; + + /// Manage the uniqued CXXOperatorIdName, which contain extra information + /// for the name of overloaded C++ operators. getCXXOperatorName + /// can be used to obtain a DeclarationName from the operator kind. + /// This points to the first element of an array of NUM_OVERLOADED_OPERATORS + /// CXXOperatorIdName which is constructed by DeclarationNameTable. CXXOperatorIdName *CXXOperatorNames; - // Actually a CXXOperatorIdName* - void *CXXLiteralOperatorNames; + /// Manage the uniqued CXXLiteralOperatorIdName, which contain extra + /// information for the name of C++ literal operators. + /// getCXXLiteralOperatorName can be used to obtain a DeclarationName + /// from the corresponding IdentifierInfo. + llvm::FoldingSet CXXLiteralOperatorNames; - // FoldingSet * - void *CXXDeductionGuideNames; + /// Manage the uniqued CXXDeductionGuideNameExtra, which contain + /// extra information for the name of a C++ deduction guide. + /// getCXXDeductionGuideName can be used to obtain a DeclarationName + /// from the corresponding template declaration. + llvm::FoldingSet CXXDeductionGuideNames; public: DeclarationNameTable(const ASTContext &C); DeclarationNameTable(const DeclarationNameTable &) = delete; DeclarationNameTable &operator=(const DeclarationNameTable &) = delete; - - ~DeclarationNameTable(); + DeclarationNameTable(DeclarationNameTable &&) = delete; + DeclarationNameTable &operator=(DeclarationNameTable &&) = delete; + ~DeclarationNameTable() = default; /// getIdentifier - Create a declaration name that is a simple /// identifier. @@ -543,7 +623,7 @@ public: /// Determine whether this name involves a template parameter. bool isInstantiationDependent() const; - + /// Determine whether this name contains an unexpanded /// parameter pack. bool containsUnexpandedParameterPack() const; @@ -557,22 +637,27 @@ public: /// getBeginLoc - Retrieve the location of the first token. SourceLocation getBeginLoc() const { return NameLoc; } - /// getEndLoc - Retrieve the location of the last token. - SourceLocation getEndLoc() const; - /// getSourceRange - The range of the declaration name. SourceRange getSourceRange() const LLVM_READONLY { - return SourceRange(getLocStart(), getLocEnd()); + return SourceRange(getBeginLoc(), getEndLoc()); } - SourceLocation getLocStart() const LLVM_READONLY { + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocStart() const LLVM_READONLY, + "Use getBeginLoc instead") { return getBeginLoc(); } - SourceLocation getLocEnd() const LLVM_READONLY { - SourceLocation EndLoc = getEndLoc(); - return EndLoc.isValid() ? EndLoc : getLocStart(); + LLVM_ATTRIBUTE_DEPRECATED(SourceLocation getLocEnd() const LLVM_READONLY, + "Use getEndLoc instead") { + return getEndLoc(); } + SourceLocation getEndLoc() const LLVM_READONLY { + SourceLocation EndLoc = getEndLocPrivate(); + return EndLoc.isValid() ? EndLoc : getBeginLoc(); + } + +private: + SourceLocation getEndLocPrivate() const; }; /// Insertion operator for diagnostics. This allows sending DeclarationName's diff --git a/include/clang/AST/DependentDiagnostic.h b/include/clang/AST/DependentDiagnostic.h index a514326c6cb10dd27c9a693eb4b47ee0481352c2..c21ef7907b8ae9b2152f6b8e65dcdb161f3bc15e 100644 --- a/include/clang/AST/DependentDiagnostic.h +++ b/include/clang/AST/DependentDiagnostic.h @@ -101,9 +101,9 @@ private: friend class DependentStoredDeclsMap; DependentDiagnostic(const PartialDiagnostic &PDiag, - PartialDiagnostic::Storage *Storage) + PartialDiagnostic::Storage *Storage) : Diag(PDiag, Storage) {} - + static DependentDiagnostic *Create(ASTContext &Context, DeclContext *Parent, const PartialDiagnostic &PDiag); diff --git a/include/clang/AST/EvaluatedExprVisitor.h b/include/clang/AST/EvaluatedExprVisitor.h index e00986dbe9c8664a8fdd4d01adc129b2fabb9a30..1aec5ae842d48759f8dc13c935c287f8ac24bf11 100644 --- a/include/clang/AST/EvaluatedExprVisitor.h +++ b/include/clang/AST/EvaluatedExprVisitor.h @@ -21,9 +21,9 @@ #include "clang/AST/StmtVisitor.h" namespace clang { - + class ASTContext; - + /// Given a potentially-evaluated expression, this visitor visits all /// of its potentially-evaluated subexpressions, recursively. template