Vendor import of clang trunk r338150:
https://llvm.org/svn/llvm-project/cfe/trunk@338150
This commit is contained in:
parent
55e6d896ad
commit
486754660b
Notes:
svn2git
2020-12-20 02:59:44 +00:00
svn path=/vendor/clang/dist/; revision=336815 svn path=/vendor/clang/clang-trunk-r338150/; revision=336816; tag=vendor/clang/clang-trunk-r338150
@ -5,8 +5,13 @@ CheckOptions:
|
||||
- key: readability-identifier-naming.EnumCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.FunctionCase
|
||||
value: lowerCase
|
||||
value: camelBack
|
||||
- key: readability-identifier-naming.MemberCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.ParameterCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.UnionCase
|
||||
value: CamelCase
|
||||
- key: readability-identifier-naming.VariableCase
|
||||
value: CamelCase
|
||||
|
||||
|
@ -212,6 +212,15 @@ set(ENABLE_LINKER_BUILD_ID OFF CACHE BOOL "pass --build-id to ld")
|
||||
set(ENABLE_X86_RELAX_RELOCATIONS OFF CACHE BOOL
|
||||
"enable x86 relax relocations by default")
|
||||
|
||||
set(ENABLE_EXPERIMENTAL_NEW_PASS_MANAGER FALSE CACHE BOOL
|
||||
"Enable the experimental new pass manager by default.")
|
||||
|
||||
# TODO: verify the values against LangStandards.def?
|
||||
set(CLANG_DEFAULT_STD_C "" CACHE STRING
|
||||
"Default standard to use for C/ObjC code (IDENT from LangStandards.def, empty for platform default)")
|
||||
set(CLANG_DEFAULT_STD_CXX "" CACHE STRING
|
||||
"Default standard to use for C++/ObjC++ code (IDENT from LangStandards.def, empty for platform default)")
|
||||
|
||||
set(CLANG_DEFAULT_LINKER "" CACHE STRING
|
||||
"Default linker to use (linker name or absolute path, empty for platform default)")
|
||||
|
||||
@ -418,11 +427,11 @@ endif()
|
||||
|
||||
# Clang version information
|
||||
set(CLANG_EXECUTABLE_VERSION
|
||||
"${CLANG_VERSION_MAJOR}.${CLANG_VERSION_MINOR}" CACHE STRING
|
||||
"Version number that will be placed into the clang executable, in the form XX.YY")
|
||||
"${CLANG_VERSION_MAJOR}" CACHE STRING
|
||||
"Major version number that will be appended to the clang executable name")
|
||||
set(LIBCLANG_LIBRARY_VERSION
|
||||
"${CLANG_VERSION_MAJOR}.${CLANG_VERSION_MINOR}" CACHE STRING
|
||||
"Version number that will be placed into the libclang library , in the form XX.YY")
|
||||
"${CLANG_VERSION_MAJOR}" CACHE STRING
|
||||
"Major version number that will be appended to the libclang library")
|
||||
mark_as_advanced(CLANG_EXECUTABLE_VERSION LIBCLANG_LIBRARY_VERSION)
|
||||
|
||||
option(CLANG_INCLUDE_TESTS
|
||||
@ -574,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
|
||||
)
|
||||
@ -608,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")
|
||||
@ -624,7 +642,8 @@ if (CLANG_ENABLE_BOOTSTRAP)
|
||||
set(COMPILER_OPTIONS
|
||||
-DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${CXX_COMPILER}
|
||||
-DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${C_COMPILER}
|
||||
-DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${C_COMPILER})
|
||||
-DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${C_COMPILER}
|
||||
-DCMAKE_ASM_COMPILER_ID=Clang)
|
||||
|
||||
if(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED)
|
||||
add_dependencies(clang-bootstrap-deps llvm-profdata)
|
||||
@ -739,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
|
||||
|
@ -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:
|
||||
|
@ -881,7 +881,7 @@ def __repr__(self):
|
||||
CursorKind.UNEXPOSED_EXPR = CursorKind(100)
|
||||
|
||||
# An expression that refers to some value declaration, such as a function,
|
||||
# varible, or enumerator.
|
||||
# variable, or enumerator.
|
||||
CursorKind.DECL_REF_EXPR = CursorKind(101)
|
||||
|
||||
# An expression that refers to a member of a struct, union, class, Objective-C
|
||||
@ -1501,7 +1501,7 @@ def get_definition(self):
|
||||
return conf.lib.clang_getCursorDefinition(self)
|
||||
|
||||
def get_usr(self):
|
||||
"""Return the Unified Symbol Resultion (USR) for the entity referenced
|
||||
"""Return the Unified Symbol Resolution (USR) for the entity referenced
|
||||
by the given cursor (or None).
|
||||
|
||||
A Unified Symbol Resolution (USR) is a string that identifies a
|
||||
@ -1511,6 +1511,12 @@ def get_usr(self):
|
||||
another translation unit."""
|
||||
return conf.lib.clang_getCursorUSR(self)
|
||||
|
||||
def get_included_file(self):
|
||||
"""Returns the File that is included by the current inclusion cursor."""
|
||||
assert self.kind == CursorKind.INCLUSION_DIRECTIVE
|
||||
|
||||
return conf.lib.clang_getIncludedFile(self)
|
||||
|
||||
@property
|
||||
def kind(self):
|
||||
"""Return the kind of this cursor."""
|
||||
@ -1644,7 +1650,7 @@ def canonical(self):
|
||||
def result_type(self):
|
||||
"""Retrieve the Type of the result for this Cursor."""
|
||||
if not hasattr(self, '_result_type'):
|
||||
self._result_type = conf.lib.clang_getResultType(self.type)
|
||||
self._result_type = conf.lib.clang_getCursorResultType(self)
|
||||
|
||||
return self._result_type
|
||||
|
||||
@ -3085,8 +3091,9 @@ def __repr__(self):
|
||||
return "<File: %s>" % (self.name)
|
||||
|
||||
@staticmethod
|
||||
def from_cursor_result(res, fn, args):
|
||||
assert isinstance(res, File)
|
||||
def from_result(res, fn, args):
|
||||
assert isinstance(res, c_object_p)
|
||||
res = File(res)
|
||||
|
||||
# Copy a reference to the TranslationUnit to prevent premature GC.
|
||||
res._tu = args[0]._tu
|
||||
@ -3568,6 +3575,11 @@ def cursor(self):
|
||||
[Cursor, c_uint, c_uint],
|
||||
SourceRange),
|
||||
|
||||
("clang_getCursorResultType",
|
||||
[Cursor],
|
||||
Type,
|
||||
Type.from_result),
|
||||
|
||||
("clang_getCursorSemanticParent",
|
||||
[Cursor],
|
||||
Cursor,
|
||||
@ -3696,8 +3708,8 @@ def cursor(self):
|
||||
|
||||
("clang_getIncludedFile",
|
||||
[Cursor],
|
||||
File,
|
||||
File.from_cursor_result),
|
||||
c_object_p,
|
||||
File.from_result),
|
||||
|
||||
("clang_getInclusions",
|
||||
[TranslationUnit, callbacks['translation_unit_includes'], py_object]),
|
||||
|
@ -5,11 +5,13 @@
|
||||
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"""
|
||||
|
@ -335,7 +335,7 @@ def test_enum_type(self):
|
||||
|
||||
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")
|
||||
@ -429,6 +429,18 @@ def test_result_type(self):
|
||||
t = foo.result_type
|
||||
self.assertEqual(t.kind, TypeKind.INT)
|
||||
|
||||
def test_result_type_objc_method_decl(self):
|
||||
code = """\
|
||||
@interface Interface : NSObject
|
||||
-(void)voidMethod;
|
||||
@end
|
||||
"""
|
||||
tu = get_tu(code, lang='objc')
|
||||
cursor = get_cursor(tu, 'voidMethod')
|
||||
result_type = cursor.result_type
|
||||
self.assertEqual(cursor.kind, CursorKind.OBJC_INSTANCE_METHOD_DECL)
|
||||
self.assertEqual(result_type.kind, TypeKind.VOID)
|
||||
|
||||
def test_availability(self):
|
||||
tu = get_tu('class A { A(A const&) = delete; };', lang='cpp')
|
||||
|
||||
@ -549,4 +561,4 @@ def test_mangled_name(self):
|
||||
# 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'))
|
||||
|
@ -1,3 +1,4 @@
|
||||
from contextlib import contextmanager
|
||||
import gc
|
||||
import os
|
||||
import tempfile
|
||||
@ -19,15 +20,15 @@
|
||||
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):
|
||||
@ -108,15 +109,26 @@ def eq(expected, actual):
|
||||
for i in zip(inc, tu.get_includes()):
|
||||
eq(i[0], i[1])
|
||||
|
||||
def test_inclusion_directive(self):
|
||||
src = os.path.join(kInputsDir, 'include.cpp')
|
||||
h1 = os.path.join(kInputsDir, "header1.h")
|
||||
h2 = os.path.join(kInputsDir, "header2.h")
|
||||
h3 = os.path.join(kInputsDir, "header3.h")
|
||||
inc = [h1, h3, h2, h3, h1]
|
||||
|
||||
tu = TranslationUnit.from_source(src, options=TranslationUnit.PARSE_DETAILED_PROCESSING_RECORD)
|
||||
inclusion_directive_files = [c.get_included_file().name for c in tu.cursor.get_children() if c.kind == CursorKind.INCLUSION_DIRECTIVE]
|
||||
for i in zip(inc, inclusion_directive_files):
|
||||
self.assert_normpaths_equal(i[0], i[1])
|
||||
|
||||
def test_save(self):
|
||||
"""Ensure TranslationUnit.save() works."""
|
||||
|
||||
tu = get_tu('int foo();')
|
||||
|
||||
path = save_tu(tu)
|
||||
self.assertTrue(os.path.exists(path))
|
||||
self.assertGreater(os.path.getsize(path), 0)
|
||||
os.unlink(path)
|
||||
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."""
|
||||
@ -137,21 +149,18 @@ def test_load(self):
|
||||
|
||||
tu = get_tu('int foo();')
|
||||
self.assertEqual(len(tu.diagnostics), 0)
|
||||
path = save_tu(tu)
|
||||
with save_tu(tu) as path:
|
||||
self.assertTrue(os.path.exists(path))
|
||||
self.assertGreater(os.path.getsize(path), 0)
|
||||
|
||||
self.assertTrue(os.path.exists(path))
|
||||
self.assertGreater(os.path.getsize(path), 0)
|
||||
tu2 = TranslationUnit.from_ast_file(filename=path)
|
||||
self.assertEqual(len(tu2.diagnostics), 0)
|
||||
|
||||
tu2 = TranslationUnit.from_ast_file(filename=path)
|
||||
self.assertEqual(len(tu2.diagnostics), 0)
|
||||
foo = get_cursor(tu2, 'foo')
|
||||
self.assertIsNotNone(foo)
|
||||
|
||||
foo = get_cursor(tu2, 'foo')
|
||||
self.assertIsNotNone(foo)
|
||||
|
||||
# Just in case there is an open file descriptor somewhere.
|
||||
del tu2
|
||||
|
||||
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')
|
||||
|
@ -21,7 +21,7 @@ set(BUG_REPORT_URL "http://developer.apple.com/bugreporter/" CACHE STRING "")
|
||||
set(LLVM_BUILD_EXTERNAL_COMPILER_RT ON CACHE BOOL "Build Compiler-RT with just-built clang")
|
||||
set(COMPILER_RT_ENABLE_IOS ON CACHE BOOL "Build iOS Compiler-RT libraries")
|
||||
|
||||
set(LLVM_CREATE_XCODE_TOOLCHAIN ON CACHE BOOL "Generate targets to create and install an Xcode compatable toolchain")
|
||||
set(LLVM_CREATE_XCODE_TOOLCHAIN ON CACHE BOOL "Generate targets to create and install an Xcode compatible toolchain")
|
||||
|
||||
# Make unit tests (if present) part of the ALL target
|
||||
set(LLVM_BUILD_TESTS ON CACHE BOOL "")
|
||||
@ -47,7 +47,7 @@ set(LLVM_CREATE_XCODE_TOOLCHAIN ON CACHE BOOL "")
|
||||
# setup toolchain
|
||||
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
|
||||
set(LLVM_TOOLCHAIN_TOOLS
|
||||
llvm-dsymutil
|
||||
dsymutil
|
||||
llvm-cov
|
||||
llvm-dwarfdump
|
||||
llvm-profdata
|
||||
|
@ -24,11 +24,11 @@ set(BUILTINS_armv7em-none-eabi_COMPILER_RT_OS_DIR "baremetal" CACHE STRING "armv
|
||||
|
||||
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
|
||||
set(LLVM_TOOLCHAIN_TOOLS
|
||||
dsymutil
|
||||
llc
|
||||
llvm-ar
|
||||
llvm-cxxfilt
|
||||
llvm-dwarfdump
|
||||
llvm-dsymutil
|
||||
llvm-nm
|
||||
llvm-objdump
|
||||
llvm-ranlib
|
||||
|
@ -10,7 +10,7 @@ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O3 -gline-tables-only -DNDEBUG" CACHE STRIN
|
||||
# setup toolchain
|
||||
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
|
||||
set(LLVM_TOOLCHAIN_TOOLS
|
||||
llvm-dsymutil
|
||||
dsymutil
|
||||
llvm-cov
|
||||
llvm-dwarfdump
|
||||
llvm-profdata
|
||||
|
@ -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 "")
|
||||
@ -17,55 +18,115 @@ set(LLVM_ENABLE_LTO ON CACHE BOOL "")
|
||||
if(NOT APPLE)
|
||||
set(LLVM_ENABLE_LLD ON CACHE BOOL "")
|
||||
set(CLANG_DEFAULT_LINKER lld CACHE STRING "")
|
||||
set(CLANG_DEFAULT_OBJCOPY llvm-objcopy CACHE STRING "")
|
||||
endif()
|
||||
|
||||
if(APPLE)
|
||||
set(LLDB_CODESIGN_IDENTITY "" CACHE STRING "")
|
||||
endif()
|
||||
set(CLANG_DEFAULT_CXX_STDLIB libc++ CACHE STRING "")
|
||||
set(CLANG_DEFAULT_RTLIB compiler-rt CACHE STRING "")
|
||||
|
||||
set(LLVM_ENABLE_ASSERTIONS ON CACHE BOOL "")
|
||||
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(LLVM_BUILTIN_TARGETS "default;x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "")
|
||||
foreach(target x86_64;aarch64)
|
||||
set(BUILTINS_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "")
|
||||
set(BUILTINS_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
|
||||
endforeach()
|
||||
if(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_RUNTIME_TARGETS "default;x86_64-fuchsia;aarch64-fuchsia;x86_64-fuchsia-asan:x86_64-fuchsia;aarch64-fuchsia-asan:aarch64-fuchsia" CACHE STRING "")
|
||||
foreach(target x86_64;aarch64)
|
||||
set(RUNTIMES_${target}-fuchsia_CMAKE_BUILD_WITH_INSTALL_RPATH ON CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "")
|
||||
set(RUNTIMES_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
|
||||
set(RUNTIMES_${target}-fuchsia_UNIX 1 CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LLVM_ENABLE_LIBCXX ON CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBUNWIND_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBUNWIND_ENABLE_STATIC OFF CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBCXXABI_ENABLE_STATIC OFF CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBCXX_ABI_VERSION 2 CACHE STRING "")
|
||||
set(RUNTIMES_${target}-fuchsia_LIBCXX_ENABLE_STATIC OFF CACHE BOOL "")
|
||||
set(RUNTIMES_${target}-fuchsia_SANITIZER_USE_COMPILER_RT ON CACHE BOOL "")
|
||||
# Set 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(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()
|
||||
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()
|
||||
|
||||
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 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(LLVM_RUNTIME_SANITIZERS "Address" CACHE STRING "")
|
||||
set(LLVM_RUNTIME_SANITIZER_Address_TARGETS "x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "")
|
||||
endif()
|
||||
|
||||
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 "")
|
||||
set(LLVM_TOOLCHAIN_TOOLS
|
||||
dsymutil
|
||||
llc
|
||||
llvm-ar
|
||||
llvm-cov
|
||||
llvm-cxxfilt
|
||||
llvm-dwarfdump
|
||||
llvm-dsymutil
|
||||
llvm-lib
|
||||
llvm-nm
|
||||
llvm-objcopy
|
||||
@ -75,6 +136,7 @@ set(LLVM_TOOLCHAIN_TOOLS
|
||||
llvm-readelf
|
||||
llvm-readobj
|
||||
llvm-size
|
||||
llvm-strip
|
||||
llvm-symbolizer
|
||||
opt
|
||||
sancov
|
||||
@ -82,12 +144,12 @@ set(LLVM_TOOLCHAIN_TOOLS
|
||||
|
||||
set(LLVM_DISTRIBUTION_COMPONENTS
|
||||
clang
|
||||
libclang
|
||||
lld
|
||||
lldb
|
||||
liblldb
|
||||
LTO
|
||||
clang-format
|
||||
clang-headers
|
||||
clang-include-fixer
|
||||
clang-refactor
|
||||
clang-tidy
|
||||
clangd
|
||||
|
@ -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,16 +54,23 @@ set(CLANG_BOOTSTRAP_TARGETS
|
||||
clang-test-depends
|
||||
distribution
|
||||
install-distribution
|
||||
install-distribution-stripped
|
||||
clang CACHE STRING "")
|
||||
|
||||
foreach(target x86_64;aarch64)
|
||||
if(FUCHSIA_${target}_SYSROOT)
|
||||
list(APPEND EXTRA_ARGS -DFUCHSIA_${target}_SYSROOT=${FUCHSIA_${target}_SYSROOT})
|
||||
get_cmake_property(variableNames VARIABLES)
|
||||
foreach(variableName ${variableNames})
|
||||
if(variableName MATCHES "^STAGE2_")
|
||||
string(REPLACE "STAGE2_" "" new_name ${variableName})
|
||||
list(APPEND EXTRA_ARGS "-D${new_name}=${${variableName}}")
|
||||
endif()
|
||||
endforeach()
|
||||
|
||||
# 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
|
||||
|
@ -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.
|
||||
|
@ -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).
|
||||
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.
|
||||
|
||||
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.
|
||||
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:
|
||||
|
||||
|
@ -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),
|
||||
|
@ -36,10 +36,18 @@ Treat source input files as Objective-C inputs
|
||||
|
||||
Treat source input files as Objective-C++ inputs
|
||||
|
||||
.. option:: -Qn
|
||||
|
||||
Do not emit metadata containing compiler name and version
|
||||
|
||||
.. option:: -Qunused-arguments
|
||||
|
||||
Don't emit warning for unused driver arguments
|
||||
|
||||
.. option:: -Qy
|
||||
|
||||
Emit metadata containing compiler name and version
|
||||
|
||||
.. option:: -Wa,<arg>,<arg2>...
|
||||
|
||||
Pass the comma separated arguments in <arg> to the assembler
|
||||
@ -61,10 +69,10 @@ Pass <arg> to the ptxas assembler
|
||||
Pass <arg> to the target offloading toolchain.
|
||||
|
||||
.. program:: clang1
|
||||
.. option:: -Xopenmp-target=<arg> <arg2>
|
||||
.. option:: -Xopenmp-target=<triple> <arg>
|
||||
.. program:: clang
|
||||
|
||||
Pass <arg> to the specified target offloading toolchain. The triple that identifies the toolchain must be provided after the equals sign.
|
||||
Pass <arg> to the target offloading toolchain identified by <triple>.
|
||||
|
||||
.. option:: -Z<arg>
|
||||
|
||||
@ -116,10 +124,18 @@ Output path for the plist report
|
||||
.. option:: -bundle\_loader <arg>
|
||||
.. program:: clang
|
||||
|
||||
.. option:: -cfguard
|
||||
|
||||
Emit tables required for Windows Control Flow Guard.
|
||||
|
||||
.. option:: -client\_name<arg>
|
||||
|
||||
.. option:: -compatibility\_version<arg>
|
||||
|
||||
.. option:: --config <arg>
|
||||
|
||||
Specifies configuration file
|
||||
|
||||
.. option:: --constant-cfstrings
|
||||
|
||||
.. option:: -coverage, --coverage
|
||||
@ -140,6 +156,10 @@ CUDA GPU architecture (e.g. sm\_35). May be specified more than once.
|
||||
|
||||
Compile CUDA code for host only. Has no effect on non-CUDA compilations.
|
||||
|
||||
.. option:: --cuda-include-ptx=<arg>, --no-cuda-include-ptx=<arg>
|
||||
|
||||
Include PTX for the follwing GPU architecture (e.g. sm\_35) or 'all'. May be specified more than once.
|
||||
|
||||
.. option:: --cuda-noopt-device-debug, --no-cuda-noopt-device-debug
|
||||
|
||||
Enable device-side debug info generation. Disables ptxas optimizations.
|
||||
@ -190,6 +210,14 @@ Use approximate transcendental functions
|
||||
|
||||
Flush denormal floating point values to zero in CUDA device mode.
|
||||
|
||||
.. option:: -fcuda-rdc, -fno-cuda-rdc
|
||||
|
||||
Generate relocatable device code, also known as separate compilation mode.
|
||||
|
||||
.. option:: -ffixed-r19
|
||||
|
||||
Reserve the r19 register (Hexagon only)
|
||||
|
||||
.. option:: -fheinous-gnu-extensions
|
||||
|
||||
.. option:: -flat\_namespace
|
||||
@ -230,6 +258,8 @@ Display available options
|
||||
|
||||
.. option:: --help-hidden
|
||||
|
||||
Display help for hidden options
|
||||
|
||||
.. option:: -image\_base <arg>
|
||||
|
||||
.. option:: -index-header-map
|
||||
@ -702,6 +732,14 @@ Print source range spans in numeric form
|
||||
|
||||
.. option:: -fdiagnostics-show-category=<arg>
|
||||
|
||||
.. option:: -fdiscard-value-names, -fno-discard-value-names
|
||||
|
||||
Discard value names in LLVM IR
|
||||
|
||||
.. option:: -fexperimental-isel, -fno-experimental-isel
|
||||
|
||||
Enables the experimental global instruction selector
|
||||
|
||||
.. option:: -fexperimental-new-pass-manager, -fno-experimental-new-pass-manager
|
||||
|
||||
Enables an experimental new pass manager in LLVM.
|
||||
@ -736,6 +774,10 @@ Level of field padding for AddressSanitizer
|
||||
|
||||
Enable linker dead stripping of globals in AddressSanitizer
|
||||
|
||||
.. option:: -fsanitize-address-poison-class-member-array-new-cookie, -fno-sanitize-address-poison-class-member-array-new-cookie
|
||||
|
||||
Enable poisoning array cookies when using class member operator new\[\] in AddressSanitizer
|
||||
|
||||
.. option:: -fsanitize-address-use-after-scope, -fno-sanitize-address-use-after-scope
|
||||
|
||||
Enable use-after-scope detection in AddressSanitizer
|
||||
@ -868,6 +910,10 @@ Add directory to include search path
|
||||
|
||||
Restrict all prior -I flags to double-quoted inclusion and remove current directory from include path
|
||||
|
||||
.. option:: --cuda-path-ignore-env
|
||||
|
||||
Ignore environment variables to detect CUDA installation
|
||||
|
||||
.. option:: --cuda-path=<arg>
|
||||
|
||||
CUDA installation path
|
||||
@ -912,7 +958,7 @@ Specify the module user build path
|
||||
|
||||
Don't verify input files for the modules if the module has been successfully validated or loaded during this build session
|
||||
|
||||
.. option:: -fmodules-validate-system-headers
|
||||
.. option:: -fmodules-validate-system-headers, -fno-modules-validate-system-headers
|
||||
|
||||
Validate the system headers that a module depends on when loading the module
|
||||
|
||||
@ -920,8 +966,6 @@ Validate the system headers that a module depends on when loading the module
|
||||
|
||||
Specify the prebuilt module path
|
||||
|
||||
.. option:: -i<arg>
|
||||
|
||||
.. option:: -idirafter<arg>, --include-directory-after <arg>, --include-directory-after=<arg>
|
||||
|
||||
Add directory to AFTER include search path
|
||||
@ -1107,6 +1151,12 @@ Target-independent compilation options
|
||||
|
||||
.. option:: -faccess-control, -fno-access-control
|
||||
|
||||
.. option:: -falign-functions, -fno-align-functions
|
||||
|
||||
.. program:: clang1
|
||||
.. option:: -falign-functions=<arg>
|
||||
.. program:: clang
|
||||
|
||||
.. program:: clang1
|
||||
.. option:: -faligned-allocation, -faligned-new, -fno-aligned-allocation
|
||||
.. program:: clang
|
||||
@ -1175,6 +1225,10 @@ Load the clang builtins module map file.
|
||||
|
||||
.. option:: -fcaret-diagnostics, -fno-caret-diagnostics
|
||||
|
||||
.. option:: -fcf-protection=<arg>, -fcf-protection (equivalent to -fcf-protection=full)
|
||||
|
||||
Instrument control-flow architecture protection. Options: return, branch, full, none.
|
||||
|
||||
.. option:: -fclasspath=<arg>, --CLASSPATH <arg>, --CLASSPATH=<arg>, --classpath <arg>, --classpath=<arg>
|
||||
|
||||
.. option:: -fcolor-diagnostics, -fno-color-diagnostics
|
||||
@ -1305,6 +1359,8 @@ Use emutls functions to access thread\_local variables
|
||||
|
||||
.. option:: -ferror-limit=<arg>
|
||||
|
||||
.. option:: -fescaping-block-tail-calls, -fno-escaping-block-tail-calls
|
||||
|
||||
.. option:: -fexceptions, -fno-exceptions
|
||||
|
||||
Enable support for exception handling
|
||||
@ -1321,6 +1377,10 @@ Allow aggressive, lossy floating-point optimizations
|
||||
|
||||
.. option:: -ffor-scope, -fno-for-scope
|
||||
|
||||
.. option:: -fforce-enable-int128, -fno-force-enable-int128
|
||||
|
||||
Enable support for int128\_t type
|
||||
|
||||
.. option:: -ffp-contract=<arg>
|
||||
|
||||
Form fused FP ops (e.g. FMAs): fast (everywhere) \| on (according to FP\_CONTRACT pragma, default) \| off (never fuse)
|
||||
@ -1409,6 +1469,8 @@ Specify the maximum alignment to enforce on pointers lacking an explicit alignme
|
||||
|
||||
.. option:: -fmerge-all-constants, -fno-merge-all-constants
|
||||
|
||||
Allow merging of constants
|
||||
|
||||
.. option:: -fmessage-length=<arg>
|
||||
|
||||
.. option:: -fmodule-file-deps, -fno-module-file-deps
|
||||
@ -1481,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
|
||||
@ -1491,15 +1561,15 @@ Do not elide types when printing diagnostics
|
||||
|
||||
Do not treat C++ operator name keywords as synonyms for operators
|
||||
|
||||
.. option:: -fno-rtti-data
|
||||
|
||||
Control emission of RTTI data
|
||||
|
||||
.. option:: -fno-strict-modules-decluse
|
||||
|
||||
.. option:: -fno-working-directory
|
||||
|
||||
.. option:: -fnoopenmp-relocatable-target
|
||||
|
||||
Do not compile OpenMP target code as relocatable.
|
||||
|
||||
.. option:: -fnoopenmp-use-tls
|
||||
.. option:: -fnoxray-link-deps
|
||||
|
||||
.. option:: -fobjc-abi-version=<arg>
|
||||
|
||||
@ -1539,13 +1609,11 @@ Enable ARC-style weak references in Objective-C
|
||||
|
||||
.. option:: -fopenmp, -fno-openmp
|
||||
|
||||
.. option:: -fopenmp-dump-offload-linker-script
|
||||
Parse OpenMP pragmas and generate parallel code.
|
||||
|
||||
.. option:: -fopenmp-relocatable-target
|
||||
.. option:: -fopenmp-simd, -fno-openmp-simd
|
||||
|
||||
OpenMP target code is compiled as relocatable using the -c flag. For OpenMP targets the code is relocatable by default.
|
||||
|
||||
.. option:: -fopenmp-use-tls
|
||||
Emit OpenMP code only for SIMD-based constructs.
|
||||
|
||||
.. option:: -fopenmp-version=<arg>
|
||||
|
||||
@ -1656,6 +1724,10 @@ Allow division operations to be reassociated
|
||||
|
||||
Override the default ABI to return small structs in registers
|
||||
|
||||
.. option:: -fregister-global-dtors-with-atexit, -fno-register-global-dtors-with-atexit
|
||||
|
||||
Use atexit or \_\_cxa\_atexit to register global destructors
|
||||
|
||||
.. option:: -frelaxed-template-template-args, -fno-relaxed-template-template-args
|
||||
|
||||
Enable C++17 relaxed template template argument matching
|
||||
@ -1732,7 +1804,7 @@ Enable the superword-level parallelism vectorization passes
|
||||
|
||||
.. option:: -fsplit-dwarf-inlining, -fno-split-dwarf-inlining
|
||||
|
||||
Place debug types in their own section (ELF Only)
|
||||
Provide minimal debug info in the object/executable to facilitate online symbolication/stack traces in the absence of .dwo/.dwp files when using Split DWARF
|
||||
|
||||
.. option:: -fsplit-stack
|
||||
|
||||
@ -1748,6 +1820,10 @@ Force the usage of stack protectors for all functions
|
||||
|
||||
Use a strong heuristic to apply stack protectors to functions
|
||||
|
||||
.. option:: -fstack-size-section, -fno-stack-size-section
|
||||
|
||||
Emit section containing metadata on function stack sizes
|
||||
|
||||
.. option:: -fstandalone-debug, -fno-limit-debug-info, -fno-standalone-debug
|
||||
|
||||
Emit full debug info for all types used by the program
|
||||
@ -1852,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
|
||||
|
||||
@ -1866,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
|
||||
@ -1878,9 +1960,17 @@ Store string literals as writable data
|
||||
|
||||
Determine whether to always emit \_\_xray\_customevent(...) calls even if the function it appears in is not always instrumented.
|
||||
|
||||
.. option:: -fxray-always-emit-typedevents, -fno-xray-always-emit-typedevents
|
||||
|
||||
Determine whether to always emit \_\_xray\_typedevent(...) calls even if the function it appears in is not always instrumented.
|
||||
|
||||
.. option:: -fxray-always-instrument=<arg>
|
||||
|
||||
Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.
|
||||
DEPRECATED: Filename defining the whitelist for imbuing the 'always instrument' XRay attribute.
|
||||
|
||||
.. option:: -fxray-attr-list=<arg>
|
||||
|
||||
Filename defining the list of functions/types for imbuing XRay attributes.
|
||||
|
||||
.. option:: -fxray-instruction-threshold<arg>
|
||||
|
||||
@ -1894,9 +1984,21 @@ Sets the minimum function size to instrument with XRay
|
||||
|
||||
Generate XRay instrumentation sleds on function entry and exit
|
||||
|
||||
.. option:: -fxray-instrumentation-bundle=<arg>
|
||||
|
||||
Select which XRay instrumentation points to emit. Options: all, none, function, custom. Default is 'all'.
|
||||
|
||||
.. option:: -fxray-link-deps
|
||||
|
||||
Tells clang to add the link dependencies for XRay.
|
||||
|
||||
.. option:: -fxray-modes=<arg>
|
||||
|
||||
List of modes to link in by default into XRay instrumented binaries.
|
||||
|
||||
.. option:: -fxray-never-instrument=<arg>
|
||||
|
||||
Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.
|
||||
DEPRECATED: Filename defining the whitelist for imbuing the 'never instrument' XRay attribute.
|
||||
|
||||
.. option:: -fzero-initialized-in-bss, -fno-zero-initialized-in-bss
|
||||
|
||||
@ -1954,6 +2056,10 @@ OpenCL language standard to compile for.
|
||||
|
||||
OpenCL only. This option is added for compatibility with OpenCL 1.0.
|
||||
|
||||
.. option:: -cl-uniform-work-group-size
|
||||
|
||||
OpenCL only. Defines that the global work-size be a multiple of the work-group size specified to clEnqueueNDRangeKernel
|
||||
|
||||
.. option:: -cl-unsafe-math-optimizations
|
||||
|
||||
OpenCL only. Allow unsafe floating-point optimizations. Also implies -cl-no-signed-zeros and -cl-mad-enable.
|
||||
@ -1998,7 +2104,7 @@ Link stack frames through backchain on System Z
|
||||
|
||||
.. option:: -mconsole<arg>
|
||||
|
||||
.. option:: -mcpu=<arg>, -mv4 (equivalent to -mcpu=hexagonv4), -mv5 (equivalent to -mcpu=hexagonv5), -mv55 (equivalent to -mcpu=hexagonv55), -mv60 (equivalent to -mcpu=hexagonv60), -mv62 (equivalent to -mcpu=hexagonv62)
|
||||
.. option:: -mcpu=<arg>, -mv4 (equivalent to -mcpu=hexagonv4), -mv5 (equivalent to -mcpu=hexagonv5), -mv55 (equivalent to -mcpu=hexagonv55), -mv60 (equivalent to -mcpu=hexagonv60), -mv62 (equivalent to -mcpu=hexagonv62), -mv65 (equivalent to -mcpu=hexagonv65)
|
||||
|
||||
.. option:: -mdefault-build-attributes<arg>, -mno-default-build-attributes<arg>
|
||||
|
||||
@ -2066,6 +2172,10 @@ Use Intel MCU ABI
|
||||
|
||||
(integrated-as) Emit an object file which can be used with an incremental linker
|
||||
|
||||
.. option:: -mindirect-jump=<arg>
|
||||
|
||||
Change indirect jump instructions to inhibit speculation
|
||||
|
||||
.. option:: -miphoneos-version-min=<arg>, -mios-version-min=<arg>
|
||||
|
||||
.. option:: -mips16
|
||||
@ -2156,6 +2266,10 @@ Use software floating point
|
||||
|
||||
Set the stack alignment
|
||||
|
||||
.. option:: -mstack-arg-probe, -mno-stack-arg-probe
|
||||
|
||||
Enable stack probes
|
||||
|
||||
.. option:: -mstack-probe-size=<arg>
|
||||
|
||||
Set the stack probe size
|
||||
@ -2196,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)
|
||||
@ -2252,16 +2370,16 @@ Hexagon
|
||||
-------
|
||||
.. option:: -mieee-rnd-near
|
||||
|
||||
.. option:: -mpackets, -mno-packets
|
||||
|
||||
Enable generation of instruction packets
|
||||
|
||||
Hexagon
|
||||
-------
|
||||
.. option:: -mhvx, -mno-hvx
|
||||
|
||||
Enable Hexagon Vector eXtensions
|
||||
|
||||
.. option:: -mhvx-double, -mno-hvx-double
|
||||
|
||||
Enable Hexagon Double Vector eXtensions
|
||||
|
||||
.. option:: -mhvx-length=<arg>
|
||||
|
||||
Set Hexagon Vector Length
|
||||
@ -2306,12 +2424,18 @@ PowerPC
|
||||
|
||||
.. option:: -mqpx, -mno-qpx
|
||||
|
||||
.. option:: -msecure-plt
|
||||
|
||||
.. option:: -mvsx, -mno-vsx
|
||||
|
||||
WebAssembly
|
||||
-----------
|
||||
.. option:: -mexception-handling, -mno-exception-handling
|
||||
|
||||
.. option:: -mnontrapping-fptoint, -mno-nontrapping-fptoint
|
||||
|
||||
.. option:: -msign-ext, -mno-sign-ext
|
||||
|
||||
.. option:: -msimd128, -mno-simd128
|
||||
|
||||
X86
|
||||
@ -2328,6 +2452,8 @@ X86
|
||||
|
||||
.. option:: -mavx2, -mno-avx2
|
||||
|
||||
.. option:: -mavx512bitalg, -mno-avx512bitalg
|
||||
|
||||
.. option:: -mavx512bw, -mno-avx512bw
|
||||
|
||||
.. option:: -mavx512cd, -mno-avx512cd
|
||||
@ -2344,14 +2470,20 @@ X86
|
||||
|
||||
.. option:: -mavx512vbmi, -mno-avx512vbmi
|
||||
|
||||
.. option:: -mavx512vbmi2, -mno-avx512vbmi2
|
||||
|
||||
.. option:: -mavx512vl, -mno-avx512vl
|
||||
|
||||
.. option:: -mavx512vnni, -mno-avx512vnni
|
||||
|
||||
.. option:: -mavx512vpopcntdq, -mno-avx512vpopcntdq
|
||||
|
||||
.. option:: -mbmi, -mno-bmi
|
||||
|
||||
.. option:: -mbmi2, -mno-bmi2
|
||||
|
||||
.. option:: -mcldemote, -mno-cldemote
|
||||
|
||||
.. option:: -mclflushopt, -mno-clflushopt
|
||||
|
||||
.. option:: -mclwb, -mno-clwb
|
||||
@ -2370,7 +2502,7 @@ X86
|
||||
|
||||
.. option:: -mfxsr, -mno-fxsr
|
||||
|
||||
.. option:: -mibt, -mno-ibt
|
||||
.. option:: -mgfni, -mno-gfni
|
||||
|
||||
.. option:: -mlwp, -mno-lwp
|
||||
|
||||
@ -2380,6 +2512,10 @@ X86
|
||||
|
||||
.. option:: -mmovbe, -mno-movbe
|
||||
|
||||
.. option:: -mmovdiri, -mno-movdiri
|
||||
|
||||
.. option:: -mmovdir64b, -mno-movdir64b
|
||||
|
||||
.. option:: -mmpx, -mno-mpx
|
||||
|
||||
.. option:: -mmwaitx, -mno-mwaitx
|
||||
@ -2394,12 +2530,20 @@ X86
|
||||
|
||||
.. option:: -mprfchw, -mno-prfchw
|
||||
|
||||
.. option:: -mrdpid, -mno-rdpid
|
||||
|
||||
.. option:: -mrdrnd, -mno-rdrnd
|
||||
|
||||
.. option:: -mrdseed, -mno-rdseed
|
||||
|
||||
.. option:: -mretpoline, -mno-retpoline
|
||||
|
||||
.. option:: -mretpoline-external-thunk, -mno-retpoline-external-thunk
|
||||
|
||||
.. option:: -mrtm, -mno-rtm
|
||||
|
||||
.. option:: -msahf, -mno-sahf
|
||||
|
||||
.. option:: -msgx, -mno-sgx
|
||||
|
||||
.. option:: -msha, -mno-sha
|
||||
@ -2424,6 +2568,14 @@ X86
|
||||
|
||||
.. option:: -mtbm, -mno-tbm
|
||||
|
||||
.. option:: -mvaes, -mno-vaes
|
||||
|
||||
.. option:: -mvpclmulqdq, -mno-vpclmulqdq
|
||||
|
||||
.. option:: -mwaitpkg, -mno-waitpkg
|
||||
|
||||
.. option:: -mwbnoinvd, -mno-wbnoinvd
|
||||
|
||||
.. option:: -mx87, -m80387, -mno-x87
|
||||
|
||||
.. option:: -mxop, -mno-xop
|
||||
@ -2515,6 +2667,10 @@ Debug information flags
|
||||
|
||||
.. option:: -gdwarf-aranges
|
||||
|
||||
.. option:: -gembed-source, -gno-embed-source
|
||||
|
||||
Embed source text in DWARF debug sections
|
||||
|
||||
.. option:: -ggnu-pubnames
|
||||
|
||||
.. option:: -grecord-gcc-switches, -gno-record-gcc-switches
|
||||
@ -2680,6 +2836,8 @@ a Fortran input.
|
||||
|
||||
.. option:: -fwhole-file, -fno-whole-file
|
||||
|
||||
.. option:: -imultilib <arg>
|
||||
|
||||
.. option:: -nocpp
|
||||
|
||||
.. option:: -static-libgfortran
|
||||
@ -2704,11 +2862,11 @@ Set starting address of BSS to <addr>
|
||||
|
||||
.. option:: -Tdata<addr>
|
||||
|
||||
Set starting address of BSS to <addr>
|
||||
Set starting address of DATA to <addr>
|
||||
|
||||
.. option:: -Ttext<addr>
|
||||
|
||||
Set starting address of BSS to <addr>
|
||||
Set starting address of TEXT to <addr>
|
||||
|
||||
.. option:: -Wl,<arg>,<arg2>...
|
||||
|
||||
|
@ -490,15 +490,50 @@ the configuration (without a prefix: ``Auto``).
|
||||
"bbbb" "cccc";
|
||||
"cccc";
|
||||
|
||||
**AlwaysBreakTemplateDeclarations** (``bool``)
|
||||
If ``true``, always break after the ``template<...>`` of a template
|
||||
declaration.
|
||||
**AlwaysBreakTemplateDeclarations** (``BreakTemplateDeclarationsStyle``)
|
||||
The template declaration breaking style to use.
|
||||
|
||||
Possible values:
|
||||
|
||||
* ``BTDS_No`` (in configuration: ``No``)
|
||||
Do not force break before declaration.
|
||||
``PenaltyBreakTemplateDeclaration`` is taken into account.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
template <typename T> T foo() {
|
||||
}
|
||||
template <typename T> T foo(int aaaaaaaaaaaaaaaaaaaaa,
|
||||
int bbbbbbbbbbbbbbbbbbbbb) {
|
||||
}
|
||||
|
||||
* ``BTDS_MultiLine`` (in configuration: ``MultiLine``)
|
||||
Force break after template declaration only when the following
|
||||
declaration spans multiple lines.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
template <typename T> T foo() {
|
||||
}
|
||||
template <typename T>
|
||||
T foo(int aaaaaaaaaaaaaaaaaaaaa,
|
||||
int bbbbbbbbbbbbbbbbbbbbb) {
|
||||
}
|
||||
|
||||
* ``BTDS_Yes`` (in configuration: ``Yes``)
|
||||
Always break after template declaration.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
template <typename T>
|
||||
T foo() {
|
||||
}
|
||||
template <typename T>
|
||||
T foo(int aaaaaaaaaaaaaaaaaaaaa,
|
||||
int bbbbbbbbbbbbbbbbbbbbb) {
|
||||
}
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
true: false:
|
||||
template <typename T> vs. template <typename T> class C {};
|
||||
class C {};
|
||||
|
||||
**BinPackArguments** (``bool``)
|
||||
If ``false``, a function call's arguments will either be all on the
|
||||
@ -629,7 +664,9 @@ the configuration (without a prefix: ``Auto``).
|
||||
int bar();
|
||||
}
|
||||
|
||||
* ``bool AfterObjCDeclaration`` Wrap ObjC definitions (``@autoreleasepool``, interfaces, ..).
|
||||
* ``bool AfterObjCDeclaration`` Wrap ObjC definitions (interfaces, implementations...).
|
||||
@autoreleasepool and @synchronized blocks are wrapped
|
||||
according to `AfterControlStatement` flag.
|
||||
|
||||
* ``bool AfterStruct`` Wrap struct definitions.
|
||||
|
||||
@ -957,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.
|
||||
|
||||
@ -994,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
|
||||
@ -1004,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
|
||||
{};
|
||||
|
||||
|
||||
|
||||
@ -1085,7 +1148,7 @@ the configuration (without a prefix: ``Auto``).
|
||||
|
||||
**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.
|
||||
@ -1201,7 +1264,8 @@ the configuration (without a prefix: ``Auto``).
|
||||
|
||||
* ``IBS_Regroup`` (in configuration: ``Regroup``)
|
||||
Merge multiple ``#include`` blocks together and sort as one.
|
||||
Then split into groups based on category priority. See ``IncludeCategories``.
|
||||
Then split into groups based on category priority. See
|
||||
``IncludeCategories``.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
@ -1216,6 +1280,10 @@ the configuration (without a prefix: ``Auto``).
|
||||
Regular expressions denoting the different ``#include`` categories
|
||||
used for ordering ``#includes``.
|
||||
|
||||
`POSIX extended
|
||||
<http://pubs.opengroup.org/onlinepubs/9699919799/basedefs/V1_chap09.html>`_
|
||||
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
|
||||
@ -1238,6 +1306,8 @@ the configuration (without a prefix: ``Auto``).
|
||||
Priority: 2
|
||||
- Regex: '^(<|"(gtest|gmock|isl|json)/)'
|
||||
Priority: 3
|
||||
- Regex: '<[[:alnum:].]+>'
|
||||
Priority: 4
|
||||
- Regex: '.*'
|
||||
Priority: 1
|
||||
|
||||
@ -1507,6 +1577,52 @@ the configuration (without a prefix: ``Auto``).
|
||||
|
||||
|
||||
|
||||
**ObjCBinPackProtocolList** (``BinPackStyle``)
|
||||
Controls bin-packing Objective-C protocol conformance list
|
||||
items into as few lines as possible when they go over ``ColumnLimit``.
|
||||
|
||||
If ``Auto`` (the default), delegates to the value in
|
||||
``BinPackParameters``. If that is ``true``, bin-packs Objective-C
|
||||
protocol conformance list items into as few lines as possible
|
||||
whenever they go over ``ColumnLimit``.
|
||||
|
||||
If ``Always``, always bin-packs Objective-C protocol conformance
|
||||
list items into as few lines as possible whenever they go over
|
||||
``ColumnLimit``.
|
||||
|
||||
If ``Never``, lays out Objective-C protocol conformance list items
|
||||
onto individual lines whenever they go over ``ColumnLimit``.
|
||||
|
||||
|
||||
.. code-block:: objc
|
||||
|
||||
Always (or Auto, if BinPackParameters=true):
|
||||
@interface ccccccccccccc () <
|
||||
ccccccccccccc, ccccccccccccc,
|
||||
ccccccccccccc, ccccccccccccc> {
|
||||
}
|
||||
|
||||
Never (or Auto, if BinPackParameters=false):
|
||||
@interface ddddddddddddd () <
|
||||
ddddddddddddd,
|
||||
ddddddddddddd,
|
||||
ddddddddddddd,
|
||||
ddddddddddddd> {
|
||||
}
|
||||
|
||||
Possible values:
|
||||
|
||||
* ``BPS_Auto`` (in configuration: ``Auto``)
|
||||
Automatically determine parameter bin-packing behavior.
|
||||
|
||||
* ``BPS_Always`` (in configuration: ``Always``)
|
||||
Always bin-pack parameters.
|
||||
|
||||
* ``BPS_Never`` (in configuration: ``Never``)
|
||||
Never bin-pack parameters.
|
||||
|
||||
|
||||
|
||||
**ObjCBlockIndentWidth** (``unsigned``)
|
||||
The number of characters to use for indentation of ObjC blocks.
|
||||
|
||||
@ -1541,6 +1657,9 @@ the configuration (without a prefix: ``Auto``).
|
||||
**PenaltyBreakString** (``unsigned``)
|
||||
The penalty for each line break introduced inside a string literal.
|
||||
|
||||
**PenaltyBreakTemplateDeclaration** (``unsigned``)
|
||||
The penalty for breaking after template declaration.
|
||||
|
||||
**PenaltyExcessCharacter** (``unsigned``)
|
||||
The penalty for each character outside of the column limit.
|
||||
|
||||
@ -1577,24 +1696,42 @@ the configuration (without a prefix: ``Auto``).
|
||||
|
||||
|
||||
**RawStringFormats** (``std::vector<RawStringFormat>``)
|
||||
Raw string delimiters denoting that the raw string contents are
|
||||
code in a particular language and can be reformatted.
|
||||
Defines hints for detecting supported languages code blocks in raw
|
||||
strings.
|
||||
|
||||
A raw string with a matching delimiter will be reformatted assuming the
|
||||
specified language based on a predefined style given by 'BasedOnStyle'.
|
||||
If 'BasedOnStyle' is not found, the formatting is based on llvm style.
|
||||
A raw string with a matching delimiter or a matching enclosing function
|
||||
name will be reformatted assuming the specified language based on the
|
||||
style for that language defined in the .clang-format file. If no style has
|
||||
been defined in the .clang-format file for the specific language, a
|
||||
predefined style given by 'BasedOnStyle' is used. If 'BasedOnStyle' is not
|
||||
found, the formatting is based on llvm style. A matching delimiter takes
|
||||
precedence over a matching enclosing function name for determining the
|
||||
language of the raw string contents.
|
||||
|
||||
If a canonical delimiter is specified, occurrences of other delimiters for
|
||||
the same language will be updated to the canonical if possible.
|
||||
|
||||
There should be at most one specification per language and each delimiter
|
||||
and enclosing function should not occur in multiple specifications.
|
||||
|
||||
To configure this in the .clang-format file, use:
|
||||
|
||||
.. code-block:: yaml
|
||||
|
||||
RawStringFormats:
|
||||
- Delimiter: 'pb'
|
||||
Language: TextProto
|
||||
BasedOnStyle: llvm
|
||||
- Delimiter: 'proto'
|
||||
Language: TextProto
|
||||
BasedOnStyle: google
|
||||
- Language: TextProto
|
||||
Delimiters:
|
||||
- 'pb'
|
||||
- 'proto'
|
||||
EnclosingFunctions:
|
||||
- 'PARSE_TEXT_PROTO'
|
||||
BasedOnStyle: google
|
||||
- Language: Cpp
|
||||
Delimiters:
|
||||
- 'cc'
|
||||
- 'cpp'
|
||||
BasedOnStyle: llvm
|
||||
CanonicalDelimiter: 'cc'
|
||||
|
||||
**ReflowComments** (``bool``)
|
||||
If ``true``, clang-format will attempt to re-flow comments.
|
||||
@ -1643,7 +1780,7 @@ the configuration (without a prefix: ``Auto``).
|
||||
.. code-block:: c++
|
||||
|
||||
true: false:
|
||||
(int)i; vs. (int) i;
|
||||
(int) i; vs. (int)i;
|
||||
|
||||
**SpaceAfterTemplateKeyword** (``bool``)
|
||||
If ``true``, a space will be inserted after the 'template' keyword.
|
||||
@ -1662,6 +1799,35 @@ 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<int> { 1, 2, 3 }; vector<int>{ 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.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
true: false:
|
||||
Foo::Foo() : a(a) {} Foo::Foo(): a(a) {}
|
||||
|
||||
**SpaceBeforeInheritanceColon** (``bool``)
|
||||
If ``false``, spaces will be removed before inheritance colon.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
true: false:
|
||||
class Foo : Bar {} vs. class Foo: Bar {}
|
||||
|
||||
**SpaceBeforeParens** (``SpaceBeforeParensOptions``)
|
||||
Defines in which cases to put a space before opening parentheses.
|
||||
|
||||
@ -1706,6 +1872,15 @@ the configuration (without a prefix: ``Auto``).
|
||||
|
||||
|
||||
|
||||
**SpaceBeforeRangeBasedForLoopColon** (``bool``)
|
||||
If ``false``, spaces will be removed before range-based for loop
|
||||
colon.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
true: false:
|
||||
for (auto v : values) {} vs. for(auto v: values) {}
|
||||
|
||||
**SpaceInEmptyParentheses** (``bool``)
|
||||
If ``true``, spaces may be inserted into ``()``.
|
||||
|
||||
|
@ -98,10 +98,129 @@ Language Selection and Mode Options
|
||||
|
||||
Treat subsequent input files as having type language.
|
||||
|
||||
.. option:: -std=<language>
|
||||
.. option:: -std=<standard>
|
||||
|
||||
Specify the language standard to compile for.
|
||||
|
||||
Supported values for the C language are:
|
||||
|
||||
| ``c89``
|
||||
| ``c90``
|
||||
| ``iso9899:1990``
|
||||
|
||||
ISO C 1990
|
||||
|
||||
| ``iso9899:199409``
|
||||
|
||||
ISO C 1990 with amendment 1
|
||||
|
||||
| ``gnu89``
|
||||
| ``gnu90``
|
||||
|
||||
ISO C 1990 with GNU extensions
|
||||
|
||||
| ``c99``
|
||||
| ``iso9899:1999``
|
||||
|
||||
ISO C 1999
|
||||
|
||||
| ``gnu99``
|
||||
|
||||
ISO C 1999 with GNU extensions
|
||||
|
||||
| ``c11``
|
||||
| ``iso9899:2011``
|
||||
|
||||
ISO C 2011
|
||||
|
||||
| ``gnu11``
|
||||
|
||||
ISO C 2011 with GNU extensions
|
||||
|
||||
| ``c17``
|
||||
| ``iso9899:2017``
|
||||
|
||||
ISO C 2017
|
||||
|
||||
| ``gnu17``
|
||||
|
||||
ISO C 2017 with GNU extensions
|
||||
|
||||
The default C language standard is ``gnu11``, except on PS4, where it is
|
||||
``gnu99``.
|
||||
|
||||
Supported values for the C++ language are:
|
||||
|
||||
| ``c++98``
|
||||
| ``c++03``
|
||||
|
||||
ISO C++ 1998 with amendments
|
||||
|
||||
| ``gnu++98``
|
||||
| ``gnu++03``
|
||||
|
||||
ISO C++ 1998 with amendments and GNU extensions
|
||||
|
||||
| ``c++11``
|
||||
|
||||
ISO C++ 2011 with amendments
|
||||
|
||||
| ``gnu++11``
|
||||
|
||||
ISO C++ 2011 with amendments and GNU extensions
|
||||
|
||||
| ``c++14``
|
||||
|
||||
ISO C++ 2014 with amendments
|
||||
|
||||
| ``gnu++14``
|
||||
|
||||
ISO C++ 2014 with amendments and GNU extensions
|
||||
|
||||
| ``c++17``
|
||||
|
||||
ISO C++ 2017 with amendments
|
||||
|
||||
| ``gnu++17``
|
||||
|
||||
ISO C++ 2017 with amendments and GNU extensions
|
||||
|
||||
| ``c++2a``
|
||||
|
||||
Working draft for ISO C++ 2020
|
||||
|
||||
| ``gnu++2a``
|
||||
|
||||
Working draft for ISO C++ 2020 with GNU extensions
|
||||
|
||||
The default C++ language standard is ``gnu++14``.
|
||||
|
||||
Supported values for the OpenCL language are:
|
||||
|
||||
| ``cl1.0``
|
||||
|
||||
OpenCL 1.0
|
||||
|
||||
| ``cl1.1``
|
||||
|
||||
OpenCL 1.1
|
||||
|
||||
| ``cl1.2``
|
||||
|
||||
OpenCL 1.2
|
||||
|
||||
| ``cl2.0``
|
||||
|
||||
OpenCL 2.0
|
||||
|
||||
The default OpenCL language standard is ``cl1.0``.
|
||||
|
||||
Supported values for the CUDA language are:
|
||||
|
||||
| ``cuda``
|
||||
|
||||
NVIDIA CUDA(tm)
|
||||
|
||||
.. option:: -stdlib=<library>
|
||||
|
||||
Specify the C++ standard library to use; supported options are libstdc++ and
|
||||
|
52
docs/CommandGuide/diagtool.rst
Normal file
52
docs/CommandGuide/diagtool.rst
Normal file
@ -0,0 +1,52 @@
|
||||
diagtool - clang diagnostics tool
|
||||
=================================
|
||||
|
||||
SYNOPSIS
|
||||
--------
|
||||
|
||||
:program:`diagtool` *command* [*args*]
|
||||
|
||||
DESCRIPTION
|
||||
-----------
|
||||
|
||||
:program:`diagtool` is a combination of four tool for dealing with diagnostics in :program:`clang`.
|
||||
|
||||
SUBCOMMANDS
|
||||
-----------
|
||||
|
||||
:program:`diagtool` is separated into several subcommands each tailored to a
|
||||
different purpose. A brief summary of each command follows, with more detail in
|
||||
the sections that follow.
|
||||
|
||||
* :ref:`find_diagnostic_id` - Print the id of the given diagnostic.
|
||||
* :ref:`list_warnings` - List warnings and their corresponding flags.
|
||||
* :ref:`show_enabled` - Show which warnings are enabled for a given command line.
|
||||
* :ref:`tree` - Show warning flags in a tree view.
|
||||
|
||||
.. _find_diagnostic_id:
|
||||
|
||||
find-diagnostic-id
|
||||
~~~~~~~~~~~~~~~~~~
|
||||
|
||||
:program:`diagtool` find-diagnostic-id *diagnostic-name*
|
||||
|
||||
.. _list_warnings:
|
||||
|
||||
list-warnings
|
||||
~~~~~~~~~~~~~
|
||||
|
||||
:program:`diagtool` list-warnings
|
||||
|
||||
.. _show_enabled:
|
||||
|
||||
show-enabled
|
||||
~~~~~~~~~~~~
|
||||
|
||||
:program:`diagtool` show-enabled [*options*] *filename ...*
|
||||
|
||||
.. _tree:
|
||||
|
||||
tree
|
||||
~~~~
|
||||
|
||||
:program:`diagtool` tree [*diagnostic-group*]
|
@ -15,3 +15,4 @@ Basic Commands
|
||||
:maxdepth: 1
|
||||
|
||||
clang
|
||||
diagtool
|
||||
|
@ -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 <cfi-blacklist>` types, must be compiled with
|
||||
``-fsanitize=cfi-vcall`` enabled and be statically linked into the program.
|
||||
of :ref:`blacklisted <cfi-blacklist>` types or types with public :doc:`LTO
|
||||
visibility <LTOVisibility>`, 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 <cfi-blacklist>`.
|
||||
|
||||
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 <cfi-blacklist>` 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 <cfi-blacklist>` types or types with public :doc:`LTO
|
||||
visibility <LTOVisibility>`, 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 <cfi-blacklist>` types, must be compiled with
|
||||
``-fsanitize=cfi-nvcall`` enabled and be statically linked into the program.
|
||||
of :ref:`blacklisted <cfi-blacklist>` types or types with public :doc:`LTO
|
||||
visibility <LTOVisibility>`, must be compiled with ``-flto`` or ``-flto=thin``
|
||||
enabled and be statically linked into the program.
|
||||
|
||||
.. _cfi-strictness:
|
||||
|
||||
@ -224,8 +228,8 @@ flag relax pointer type checking for call sites in that translation unit,
|
||||
applied across all functions compiled with ``-fsanitize=cfi-icall``.
|
||||
|
||||
Specifically, pointers in return and argument types are treated as equivalent as
|
||||
long as the qualifiers for the type they point to match. For example, ``char*``
|
||||
``char**`, and ``int*`` are considered equivalent types. However, ``char*`` and
|
||||
long as the qualifiers for the type they point to match. For example, ``char*``,
|
||||
``char**``, and ``int*`` are considered equivalent types. However, ``char*`` and
|
||||
``const char*`` are considered separate types.
|
||||
|
||||
``-fsanitize-cfi-icall-generalize-pointers`` is not compatible with
|
||||
@ -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 <cfi-blacklist>` types or types with public :doc:`LTO
|
||||
visibility <LTOVisibility>`, 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
|
||||
|
@ -7555,9 +7555,9 @@ This diagnostic is enabled by default.
|
||||
|
||||
**Diagnostic text:**
|
||||
|
||||
+------------------------------------------------------------------------------------------------------------+
|
||||
|:warning:`warning:` |nbsp| :diagtext:`default property attribute 'assign' not appropriate for non-GC object`|
|
||||
+------------------------------------------------------------------------------------------------------------+
|
||||
+-----------------------------------------------------------------------------------------------------+
|
||||
|:warning:`warning:` |nbsp| :diagtext:`default property attribute 'assign' not appropriate for object`|
|
||||
+-----------------------------------------------------------------------------------------------------+
|
||||
|
||||
+--------------------------------------------------------------------------------------------------------------------+
|
||||
|:warning:`warning:` |nbsp| :diagtext:`no 'assign', 'retain', or 'copy' attribute is specified - 'assign' is assumed`|
|
||||
|
@ -7,8 +7,6 @@ This page is a design document for
|
||||
a tool similar to :doc:`AddressSanitizer`,
|
||||
but based on partial hardware assistance.
|
||||
|
||||
The document is a draft, suggestions are welcome.
|
||||
|
||||
|
||||
Introduction
|
||||
============
|
||||
@ -30,15 +28,16 @@ accuracy guarantees.
|
||||
|
||||
Algorithm
|
||||
=========
|
||||
* Every heap/stack/global memory object is forcibly aligned by `N` bytes
|
||||
(`N` is e.g. 16 or 64). We call `N` the **granularity** of tagging.
|
||||
* For every such object a random `K`-bit tag `T` is chosen (`K` is e.g. 4 or 8)
|
||||
* Every heap/stack/global memory object is forcibly aligned by `TG` bytes
|
||||
(`TG` is e.g. 16 or 64). We call `TG` the **tagging granularity**.
|
||||
* For every such object a random `TS`-bit tag `T` is chosen (`TS`, or tag size, is e.g. 4 or 8)
|
||||
* The pointer to the object is tagged with `T`.
|
||||
* The memory for the object is also tagged with `T`
|
||||
(using a `N=>1` shadow memory)
|
||||
* The memory for the object is also tagged with `T` (using a `TG=>1` shadow memory)
|
||||
* Every load and store is instrumented to read the memory tag and compare it
|
||||
with the pointer tag, exception is raised on tag mismatch.
|
||||
|
||||
For a more detailed discussion of this approach see https://arxiv.org/pdf/1802.09517.pdf
|
||||
|
||||
Instrumentation
|
||||
===============
|
||||
|
||||
@ -53,17 +52,16 @@ verifies the tags. Currently, the following sequence is used:
|
||||
// int foo(int *a) { return *a; }
|
||||
// clang -O2 --target=aarch64-linux -fsanitize=hwaddress -c load.c
|
||||
foo:
|
||||
0: 08 dc 44 d3 ubfx x8, x0, #4, #52 // shadow address
|
||||
4: 08 01 40 39 ldrb w8, [x8] // load shadow
|
||||
8: 09 fc 78 d3 lsr x9, x0, #56 // address tag
|
||||
c: 3f 01 08 6b cmp w9, w8 // compare tags
|
||||
10: 61 00 00 54 b.ne #12 // jump on mismatch
|
||||
14: 00 00 40 b9 ldr w0, [x0] // original load
|
||||
18: c0 03 5f d6 ret
|
||||
1c: 40 20 40 d4 hlt #0x102 // halt
|
||||
20: 00 00 40 b9 ldr w0, [x0] // original load
|
||||
24: c0 03 5f d6 ret
|
||||
|
||||
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
|
||||
20: c0 03 5f d6 ret
|
||||
24: 40 20 21 d4 brk #0x902 // trap
|
||||
|
||||
Alternatively, memory accesses are prefixed with a function call.
|
||||
|
||||
@ -71,17 +69,24 @@ Heap
|
||||
----
|
||||
|
||||
Tagging the heap memory/pointers is done by `malloc`.
|
||||
This can be based on any malloc that forces all objects to be N-aligned.
|
||||
This can be based on any malloc that forces all objects to be TG-aligned.
|
||||
`free` tags the memory with a different tag.
|
||||
|
||||
Stack
|
||||
-----
|
||||
|
||||
Special compiler instrumentation is required to align the local variables
|
||||
by N, tag the memory and the pointers.
|
||||
Stack frames are instrumented by aligning all non-promotable allocas
|
||||
by `TG` and tagging stack memory in function prologue and epilogue.
|
||||
|
||||
Tags for different allocas in one function are **not** generated
|
||||
independently; doing that in a function with `M` allocas would require
|
||||
maintaining `M` live stack pointers, significantly increasing register
|
||||
pressure. Instead we generate a single base tag value in the prologue,
|
||||
and build the tag for alloca number `M` as `ReTag(BaseTag, M)`, where
|
||||
ReTag can be as simple as exclusive-or with constant `M`.
|
||||
|
||||
Stack instrumentation is expected to be a major source of overhead,
|
||||
but could be optional.
|
||||
TODO: details.
|
||||
|
||||
Globals
|
||||
-------
|
||||
@ -126,15 +131,25 @@ HWASAN:
|
||||
https://www.kernel.org/doc/Documentation/arm64/tagged-pointers.txt).
|
||||
* **Does not require redzones to detect buffer overflows**,
|
||||
but the buffer overflow detection is probabilistic, with roughly
|
||||
`(2**K-1)/(2**K)` probability of catching a bug.
|
||||
`(2**TS-1)/(2**TS)` probability of catching a bug.
|
||||
* **Does not require quarantine to detect heap-use-after-free,
|
||||
or stack-use-after-return**.
|
||||
The detection is similarly probabilistic.
|
||||
|
||||
The memory overhead of HWASAN is expected to be much smaller
|
||||
than that of AddressSanitizer:
|
||||
`1/N` extra memory for the shadow
|
||||
and some overhead due to `N`-aligning all objects.
|
||||
`1/TG` extra memory for the shadow
|
||||
and some overhead due to `TG`-aligning all objects.
|
||||
|
||||
Supported architectures
|
||||
=======================
|
||||
HWASAN relies on `Address Tagging`_ which is only available on AArch64.
|
||||
For other 64-bit architectures it is possible to remove the address tags
|
||||
before every load and store by compiler instrumentation, but this variant
|
||||
will have limited deployability since not all of the code is
|
||||
typically instrumented.
|
||||
|
||||
The HWASAN's approach is not applicable to 32-bit architectures.
|
||||
|
||||
|
||||
Related Work
|
||||
|
@ -133,7 +133,8 @@ Examples:
|
||||
if (this->ASTList.operator _Bool())
|
||||
return clang::CreateASTDeclNodeLister();
|
||||
if (this->ASTDump.operator _Bool())
|
||||
return clang::CreateASTDumper(this->ASTDumpFilter);
|
||||
return clang::CreateASTDumper(nullptr /*Dump to stdout.*/,
|
||||
this->ASTDumpFilter);
|
||||
if (this->ASTPrint.operator _Bool())
|
||||
return clang::CreateASTPrinter(&llvm::outs(), this->ASTDumpFilter);
|
||||
return new clang::ASTConsumer();
|
||||
|
@ -54,7 +54,7 @@ number of source ranges that related to the diagnostic.
|
||||
|
||||
In this section, we'll be giving examples produced by the Clang command line
|
||||
driver, but diagnostics can be :ref:`rendered in many different ways
|
||||
<DiagnosticClient>` depending on how the ``DiagnosticClient`` interface is
|
||||
<DiagnosticConsumer>` depending on how the ``DiagnosticConsumer`` interface is
|
||||
implemented. A representative example of a diagnostic is:
|
||||
|
||||
.. code-block:: text
|
||||
@ -188,7 +188,7 @@ Formatting a Diagnostic Argument
|
||||
Arguments to diagnostics are fully typed internally, and come from a couple
|
||||
different classes: integers, types, names, and random strings. Depending on
|
||||
the class of the argument, it can be optionally formatted in different ways.
|
||||
This gives the ``DiagnosticClient`` information about what the argument means
|
||||
This gives the ``DiagnosticConsumer`` information about what the argument means
|
||||
without requiring it to use a specific presentation (consider this MVC for
|
||||
Clang :).
|
||||
|
||||
@ -319,6 +319,32 @@ they should be discussed before they are added. If you are creating a lot of
|
||||
repetitive diagnostics and/or have an idea for a useful formatter, please bring
|
||||
it up on the cfe-dev mailing list.
|
||||
|
||||
**"sub" format**
|
||||
|
||||
Example:
|
||||
Given the following record definition of type ``TextSubstitution``:
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
def select_ovl_candidate : TextSubstitution<
|
||||
"%select{function|constructor}0%select{| template| %2}1">;
|
||||
|
||||
which can be used as
|
||||
|
||||
.. code-block:: text
|
||||
|
||||
def note_ovl_candidate : Note<
|
||||
"candidate %sub{select_ovl_candidate}3,2,1 not viable">;
|
||||
|
||||
and will act as if it was written
|
||||
``"candidate %select{function|constructor}3%select{| template| %1}2 not viable"``.
|
||||
Description:
|
||||
This format specifier is used to avoid repeating strings verbatim in multiple
|
||||
diagnostics. The argument to ``%sub`` must name a ``TextSubstitution`` tblgen
|
||||
record. The substitution must specify all arguments used by the substitution,
|
||||
and the modifier indexes in the substitution are re-numbered accordingly. The
|
||||
substituted text must itself be a valid format string before substitution.
|
||||
|
||||
.. _internals-producing-diag:
|
||||
|
||||
Producing the Diagnostic
|
||||
@ -387,7 +413,7 @@ exactly where those parentheses would be inserted into the source code. The
|
||||
fix-it hints themselves describe what changes to make to the source code in an
|
||||
abstract manner, which the text diagnostic printer renders as a line of
|
||||
"insertions" below the caret line. :ref:`Other diagnostic clients
|
||||
<DiagnosticClient>` might choose to render the code differently (e.g., as
|
||||
<DiagnosticConsumer>` might choose to render the code differently (e.g., as
|
||||
markup inline) or even give the user the ability to automatically fix the
|
||||
problem.
|
||||
|
||||
@ -420,26 +446,26 @@ Fix-it hints can be created with one of three constructors:
|
||||
Specifies that the code in the given source ``Range`` should be removed,
|
||||
and replaced with the given ``Code`` string.
|
||||
|
||||
.. _DiagnosticClient:
|
||||
.. _DiagnosticConsumer:
|
||||
|
||||
The ``DiagnosticClient`` Interface
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
The ``DiagnosticConsumer`` Interface
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Once code generates a diagnostic with all of the arguments and the rest of the
|
||||
relevant information, Clang needs to know what to do with it. As previously
|
||||
mentioned, the diagnostic machinery goes through some filtering to map a
|
||||
severity onto a diagnostic level, then (assuming the diagnostic is not mapped
|
||||
to "``Ignore``") it invokes an object that implements the ``DiagnosticClient``
|
||||
to "``Ignore``") it invokes an object that implements the ``DiagnosticConsumer``
|
||||
interface with the information.
|
||||
|
||||
It is possible to implement this interface in many different ways. For
|
||||
example, the normal Clang ``DiagnosticClient`` (named
|
||||
example, the normal Clang ``DiagnosticConsumer`` (named
|
||||
``TextDiagnosticPrinter``) turns the arguments into strings (according to the
|
||||
various formatting rules), prints out the file/line/column information and the
|
||||
string, then prints out the line of code, the source ranges, and the caret.
|
||||
However, this behavior isn't required.
|
||||
|
||||
Another implementation of the ``DiagnosticClient`` interface is the
|
||||
Another implementation of the ``DiagnosticConsumer`` interface is the
|
||||
``TextDiagnosticBuffer`` class, which is used when Clang is in ``-verify``
|
||||
mode. Instead of formatting and printing out the diagnostics, this
|
||||
implementation just captures and remembers the diagnostics as they fly by.
|
||||
@ -1638,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
|
||||
@ -1725,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
|
||||
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/AttributeList.h?view=markup>`_
|
||||
in `include/clang/Sema/ParsedAttr.h
|
||||
<http://llvm.org/viewvc/llvm-project/cfe/trunk/include/clang/Sema/ParsedAttr.h?view=markup>`_
|
||||
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
|
||||
<http://llvm.org/viewvc/llvm-project/cfe/trunk/utils/TableGen/ClangAttrEmitter.cpp?view=markup>`_
|
||||
@ -1823,7 +1849,7 @@ Note that setting this member to 1 will opt out of common attribute semantic
|
||||
handling, requiring extra implementation efforts to ensure the attribute
|
||||
appertains to the appropriate subject, etc.
|
||||
|
||||
If the attribute should not be propagated from from a template declaration to an
|
||||
If the attribute should not be propagated from a template declaration to an
|
||||
instantiation of the template, set the ``Clone`` member to 0. By default, all
|
||||
attributes will be cloned to template instantiations.
|
||||
|
||||
@ -1861,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
|
||||
|
@ -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
|
||||
|
@ -1096,6 +1096,11 @@ The following type trait primitives are supported by Clang:
|
||||
* ``__is_constructible`` (MSVC 2013, clang)
|
||||
* ``__is_nothrow_constructible`` (MSVC 2013, clang)
|
||||
* ``__is_assignable`` (MSVC 2015, clang)
|
||||
* ``__reference_binds_to_temporary(T, U)`` (Clang): Determines whether a
|
||||
reference of type ``T`` bound to an expression of type ``U`` would bind to a
|
||||
materialized temporary object. If ``T`` is not a reference type the result
|
||||
is false. Note this trait will also return false when the initialization of
|
||||
``T`` from ``U`` is ill-formed.
|
||||
|
||||
Blocks
|
||||
======
|
||||
@ -1186,12 +1191,59 @@ Automatic reference counting
|
||||
|
||||
Clang provides support for :doc:`automated reference counting
|
||||
<AutomaticReferenceCounting>` in Objective-C, which eliminates the need
|
||||
for manual ``retain``/``release``/``autorelease`` message sends. There are two
|
||||
for manual ``retain``/``release``/``autorelease`` message sends. There are three
|
||||
feature macros associated with automatic reference counting:
|
||||
``__has_feature(objc_arc)`` indicates the availability of automated reference
|
||||
counting in general, while ``__has_feature(objc_arc_weak)`` indicates that
|
||||
automated reference counting also includes support for ``__weak`` pointers to
|
||||
Objective-C objects.
|
||||
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 <AutomaticReferenceCounting>`.
|
||||
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:
|
||||
|
||||
@ -1968,6 +2020,32 @@ is disallowed in general).
|
||||
Support for constant expression evaluation for the above builtins be detected
|
||||
with ``__has_feature(cxx_constexpr_string_builtins)``.
|
||||
|
||||
Atomic Min/Max builtins with memory ordering
|
||||
--------------------------------------------
|
||||
|
||||
There are two atomic builtins with min/max in-memory comparison and swap.
|
||||
The syntax and semantics are similar to GCC-compatible __atomic_* builtins.
|
||||
|
||||
* ``__atomic_fetch_min``
|
||||
* ``__atomic_fetch_max``
|
||||
|
||||
The builtins work with signed and unsigned integers and require to specify memory ordering.
|
||||
The return value is the original value that was stored in memory before comparison.
|
||||
|
||||
Example:
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
unsigned int val = __atomic_fetch_min(unsigned int *pi, unsigned int ui, __ATOMIC_RELAXED);
|
||||
|
||||
The third argument is one of the memory ordering specifiers ``__ATOMIC_RELAXED``,
|
||||
``__ATOMIC_CONSUME``, ``__ATOMIC_ACQUIRE``, ``__ATOMIC_RELEASE``,
|
||||
``__ATOMIC_ACQ_REL``, or ``__ATOMIC_SEQ_CST`` following C++11 memory model semantics.
|
||||
|
||||
In terms or aquire-release ordering barriers these two operations are always
|
||||
considered as operations with *load-store* semantics, even when the original value
|
||||
is not actually modified after comparison.
|
||||
|
||||
.. _langext-__c11_atomic:
|
||||
|
||||
__c11_atomic builtins
|
||||
@ -2720,3 +2798,10 @@ The ``#pragma clang section`` directive obeys the following rules:
|
||||
* The decision about which section-kind applies to each global is taken in the back-end.
|
||||
Once the section-kind is known, appropriate section name, as specified by the user using
|
||||
``#pragma clang section`` directive, is applied to that global.
|
||||
|
||||
Specifying Linker Options on ELF Targets
|
||||
========================================
|
||||
|
||||
The ``#pragma comment(lib, ...)`` directive is supported on all ELF targets.
|
||||
The second parameter is the library name (without the traditional Unix prefix of
|
||||
``lib``). This allows you to provide an implicit link of dependent libraries.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -146,7 +146,7 @@ documentation <LibTooling.html>`_.
|
||||
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
|
||||
|
||||
// A help message for this specific tool can be added afterwards.
|
||||
static cl::extrahelp MoreHelp("\nMore help text...");
|
||||
static cl::extrahelp MoreHelp("\nMore help text...\n");
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
|
||||
|
@ -44,11 +44,11 @@ two style guides are hard-coded:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
/// \brief Returns a format style complying with the LLVM coding standards:
|
||||
/// Returns a format style complying with the LLVM coding standards:
|
||||
/// http://llvm.org/docs/CodingStandards.html.
|
||||
FormatStyle getLLVMStyle();
|
||||
|
||||
/// \brief Returns a format style complying with Google's C++ style guide:
|
||||
/// Returns a format style complying with Google's C++ style guide:
|
||||
/// http://google-styleguide.googlecode.com/svn/trunk/cppguide.xml.
|
||||
FormatStyle getGoogleStyle();
|
||||
|
||||
|
@ -130,7 +130,7 @@ version of this example tool is also checked into the clang tree at
|
||||
static cl::extrahelp CommonHelp(CommonOptionsParser::HelpMessage);
|
||||
|
||||
// A help message for this specific tool can be added afterwards.
|
||||
static cl::extrahelp MoreHelp("\nMore help text...");
|
||||
static cl::extrahelp MoreHelp("\nMore help text...\n");
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
CommonOptionsParser OptionsParser(argc, argv, MyToolCategory);
|
||||
|
@ -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
|
||||
===========
|
||||
|
@ -430,6 +430,21 @@ cplusplus
|
||||
cplusplus11
|
||||
C++11 support is available.
|
||||
|
||||
cplusplus14
|
||||
C++14 support is available.
|
||||
|
||||
cplusplus17
|
||||
C++17 support is available.
|
||||
|
||||
c99
|
||||
C99 support is available.
|
||||
|
||||
c11
|
||||
C11 support is available.
|
||||
|
||||
c17
|
||||
C17 support is available.
|
||||
|
||||
freestanding
|
||||
A freestanding environment is available.
|
||||
|
||||
|
131
docs/OpenMPSupport.rst
Normal file
131
docs/OpenMPSupport.rst
Normal file
@ -0,0 +1,131 @@
|
||||
.. raw:: html
|
||||
|
||||
<style type="text/css">
|
||||
.none { background-color: #FFCCCC }
|
||||
.partial { background-color: #FFFF99 }
|
||||
.good { background-color: #CCFF99 }
|
||||
</style>
|
||||
|
||||
.. role:: none
|
||||
.. role:: partial
|
||||
.. role:: good
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
==================
|
||||
OpenMP Support
|
||||
==================
|
||||
|
||||
Clang fully supports OpenMP 4.5. Clang supports offloading to X86_64, AArch64,
|
||||
PPC64[LE] and has `basic support for Cuda devices`_.
|
||||
|
||||
Standalone directives
|
||||
=====================
|
||||
|
||||
* #pragma omp [for] simd: :good:`Complete`.
|
||||
|
||||
* #pragma omp declare simd: :partial:`Partial`. We support parsing/semantic
|
||||
analysis + generation of special attributes for X86 target, but still
|
||||
missing the LLVM pass for vectorization.
|
||||
|
||||
* #pragma omp taskloop [simd]: :good:`Complete`.
|
||||
|
||||
* #pragma omp target [enter|exit] data: :good:`Complete`.
|
||||
|
||||
* #pragma omp target update: :good:`Complete`.
|
||||
|
||||
* #pragma omp target: :good:`Complete`.
|
||||
|
||||
* #pragma omp declare target: :good:`Complete`.
|
||||
|
||||
* #pragma omp teams: :good:`Complete`.
|
||||
|
||||
* #pragma omp distribute [simd]: :good:`Complete`.
|
||||
|
||||
* #pragma omp distribute parallel for [simd]: :good:`Complete`.
|
||||
|
||||
Combined directives
|
||||
===================
|
||||
|
||||
* #pragma omp parallel for simd: :good:`Complete`.
|
||||
|
||||
* #pragma omp target parallel: :good:`Complete`.
|
||||
|
||||
* #pragma omp target parallel for [simd]: :good:`Complete`.
|
||||
|
||||
* #pragma omp target simd: :good:`Complete`.
|
||||
|
||||
* #pragma omp target teams: :good:`Complete`.
|
||||
|
||||
* #pragma omp teams distribute [simd]: :good:`Complete`.
|
||||
|
||||
* #pragma omp target teams distribute [simd]: :good:`Complete`.
|
||||
|
||||
* #pragma omp teams distribute parallel for [simd]: :good:`Complete`.
|
||||
|
||||
* #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.
|
||||
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.
|
||||
|
@ -1,5 +1,5 @@
|
||||
=======================================
|
||||
Clang 6.0.0 (In-Progress) Release Notes
|
||||
Clang 7.0.0 (In-Progress) Release Notes
|
||||
=======================================
|
||||
|
||||
.. contents::
|
||||
@ -10,7 +10,7 @@ Written by the `LLVM Team <http://llvm.org/>`_
|
||||
|
||||
.. warning::
|
||||
|
||||
These are in-progress notes for the upcoming Clang 6 release.
|
||||
These are in-progress notes for the upcoming Clang 7 release.
|
||||
Release notes for previous releases can be found on
|
||||
`the Download Page <http://releases.llvm.org/download.html>`_.
|
||||
|
||||
@ -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 6.0.0. Here we
|
||||
frontend, part of the LLVM Compiler Infrastructure, release 7.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 <http://llvm.org/releases/>`_.
|
||||
|
||||
What's New in Clang 6.0.0?
|
||||
What's New in Clang 7.0.0?
|
||||
==========================
|
||||
|
||||
Some of the major new features and improvements to Clang are listed
|
||||
@ -51,86 +51,81 @@ Major New Features
|
||||
Improvements to Clang's diagnostics
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
- ``-Wpragma-pack`` is a new warning that warns in the following cases:
|
||||
- ``-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.
|
||||
|
||||
- When a translation unit is missing terminating ``#pragma pack (pop)``
|
||||
directives.
|
||||
- ``-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``).
|
||||
|
||||
- When leaving an included file that changes the current alignment value,
|
||||
i.e. when the alignment before ``#include`` is different to the alignment
|
||||
after ``#include``.
|
||||
|
||||
- ``-Wpragma-pack-suspicious-include`` (disabled by default) warns on an
|
||||
``#include`` when the included file contains structures or unions affected by
|
||||
a non-default alignment that has been specified using a ``#pragma pack``
|
||||
directive prior to the ``#include``.
|
||||
|
||||
- ``-Wobjc-messaging-id`` is a new, non-default warning that warns about
|
||||
message sends to unqualified ``id`` in Objective-C. This warning is useful
|
||||
for projects that would like to avoid any potential future compiler
|
||||
errors/warnings, as the system frameworks might add a method with the same
|
||||
selector which could make the message send to ``id`` ambiguous.
|
||||
|
||||
- ``-Wtautological-compare`` now warns when comparing an unsigned integer and 0
|
||||
regardless of whether the constant is signed or unsigned."
|
||||
|
||||
- ``-Wtautological-compare`` now warns about comparing a signed integer and 0
|
||||
when the signed integer is coerced to an unsigned type for the comparison.
|
||||
``-Wsign-compare`` was adjusted not to warn in this case.
|
||||
|
||||
- ``-Wtautological-constant-compare`` is a new warning that warns on
|
||||
tautological comparisons between integer variable of the type ``T`` and the
|
||||
largest/smallest possible integer constant of that same type.
|
||||
|
||||
- For C code, ``-Wsign-compare``, ``-Wsign-conversion``,
|
||||
``-Wtautological-constant-compare`` and
|
||||
``-Wtautological-constant-out-of-range-compare`` were adjusted to use the
|
||||
underlying datatype of ``enum``.
|
||||
|
||||
- ``-Wnull-pointer-arithmetic`` now warns about performing pointer arithmetic
|
||||
on a null pointer. Such pointer arithmetic has an undefined behavior if the
|
||||
offset is nonzero. It also now warns about arithmetic on a null pointer
|
||||
treated as a cast from integer to pointer (GNU extension).
|
||||
|
||||
- ``-Wzero-as-null-pointer-constant`` was adjusted not to warn on null pointer
|
||||
constants that originate from system macros, except ``NULL`` macro.
|
||||
- ``-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
|
||||
-------------------------------------------------
|
||||
|
||||
- Bitrig OS was merged back into OpenBSD, so Bitrig support has been
|
||||
removed from Clang/LLVM.
|
||||
- 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``.
|
||||
|
||||
- The default value of _MSC_VER was raised from 1800 to 1911, making it
|
||||
compatible with the Visual Studio 2015 and 2017 C++ standard library headers.
|
||||
Users should generally expect this to be regularly raised to match the most
|
||||
recently released version of the Visual C++ compiler.
|
||||
- Clang 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 now defaults to ``.init_array`` if no gcc installation can be found.
|
||||
If a gcc installation is found, it still prefers ``.ctors`` if the found
|
||||
gcc is older than 4.7.0.
|
||||
- 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.
|
||||
|
||||
- The new builtin preprocessor macros ``__is_target_arch``,
|
||||
``__is_target_vendor``, ``__is_target_os``, and ``__is_target_environment``
|
||||
can be used to to examine the individual components of the target triple.
|
||||
- Clang implements the proposed resolution of LWG issue 2358, along with the
|
||||
`corresponding change to the Itanium C++ ABI
|
||||
<https://github.com/itanium-cxx-abi/cxx-abi/pull/51>`_, 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.
|
||||
|
||||
- By default, Clang emits an address-significance table into
|
||||
every ELF object file when using the integrated assembler.
|
||||
Address-significance tables allow linkers to implement `safe ICF
|
||||
<https://research.google.com/pubs/archive/36912.pdf>`_ without the false
|
||||
positives that can result from other implementation techniques such as
|
||||
relocation scanning. The ``-faddrsig`` and ``-fno-addrsig`` flags can be
|
||||
used to control whether to emit the address-significance table.
|
||||
|
||||
- ...
|
||||
|
||||
New Compiler Flags
|
||||
------------------
|
||||
|
||||
- --autocomplete was implemented to obtain a list of flags and its arguments. This is used for shell autocompletion.
|
||||
- ``-fstrict-float-cast-overflow`` and ``-fno-strict-float-cast-overflow``.
|
||||
|
||||
- The ``-fdouble-square-bracket-attributes`` and corresponding
|
||||
``-fno-double-square-bracket-attributes`` flags were added to enable or
|
||||
disable [[]] attributes in any language mode. Currently, only a limited
|
||||
number of attributes are supported outside of C++ mode. See the Clang
|
||||
attribute documentation for more information about which attributes are
|
||||
supported for each syntax.
|
||||
|
||||
- Added the ``-std=c17``, ``-std=gnu17``, and ``-std=iso9899:2017`` language
|
||||
mode flags for compatibility with GCC. This enables support for the next
|
||||
version of the C standard, expected to be published by ISO in 2018. The only
|
||||
difference between the ``-std=c17`` and ``-std=c11`` language modes is the
|
||||
value of the ``__STDC_VERSION__`` macro, as C17 is a bug fix release.
|
||||
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.
|
||||
|
||||
- ``-fforce-emit-vtables`` and ``-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.
|
||||
|
||||
- ...
|
||||
|
||||
Deprecated Compiler Flags
|
||||
-------------------------
|
||||
@ -140,35 +135,50 @@ future versions of Clang.
|
||||
|
||||
- ...
|
||||
|
||||
New Pragmas in 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=#-<flag to be completed>`. 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
|
||||
--------------------
|
||||
|
||||
Clang now supports the ...
|
||||
|
||||
|
||||
Attribute Changes in Clang
|
||||
--------------------------
|
||||
|
||||
- Clang now supports the majority of its attributes under both the GNU-style
|
||||
spelling (``__attribute((name))``) and the double square-bracket spelling
|
||||
in the ``clang`` vendor namespace (``[[clang::name]]``). Attributes whose
|
||||
syntax is specified by some other standard (such as CUDA and OpenCL
|
||||
attributes) continue to follow their respective specification.
|
||||
|
||||
- Added the ``__has_c_attribute()`` builtin preprocessor macro which allows
|
||||
users to dynamically detect whether a double square-bracket attribute is
|
||||
supported in C mode. This attribute syntax can be enabled with the
|
||||
``-fdouble-square-bracket-attributes`` flag.
|
||||
|
||||
- The presence of __attribute__((availability(...))) on a declaration no longer
|
||||
implies default visibility for that declaration on macOS.
|
||||
- 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 ...
|
||||
- clang-cl's support for precompiled headers has been much improved:
|
||||
|
||||
- When using a pch file, clang-cl now no longer redundantly emits inline
|
||||
methods that are already stored in the obj that was built together with
|
||||
the pch file (matching cl.exe). This speeds up builds using pch files
|
||||
by around 30%.
|
||||
|
||||
- The /Ycfoo.h and /Yufoo.h flags can now be used without /FIfoo.h when
|
||||
foo.h is instead included by an explicit `#include` directive. This means
|
||||
Visual Studio's default stdafx.h setup now uses precompiled headers with
|
||||
clang-cl.
|
||||
|
||||
- ...
|
||||
|
||||
|
||||
C Language Changes in Clang
|
||||
@ -186,10 +196,7 @@ C11 Feature Support
|
||||
C++ Language Changes in Clang
|
||||
-----------------------------
|
||||
|
||||
- Clang's default C++ dialect is now ``gnu++14`` instead of ``gnu++98``. This
|
||||
means Clang will by default accept code using features from C++14 and
|
||||
conforming GNU extensions. Projects incompatible with C++14 can add
|
||||
``-std=gnu++98`` to their build settings to restore the previous behaviour.
|
||||
- ...
|
||||
|
||||
C++1z Feature Support
|
||||
^^^^^^^^^^^^^^^^^^^^^
|
||||
@ -209,12 +216,38 @@ OpenCL C Language Changes in Clang
|
||||
OpenMP Support in Clang
|
||||
----------------------------------
|
||||
|
||||
...
|
||||
- Clang gained basic support for OpenMP 4.5 offloading for NVPTX target.
|
||||
To compile your program for NVPTX target use the following options:
|
||||
`-fopenmp -fopenmp-targets=nvptx64-nvidia-cuda` for 64 bit platforms or
|
||||
`-fopenmp -fopenmp-targets=nvptx-nvidia-cuda` for 32 bit platform.
|
||||
|
||||
- Passing options to the OpenMP device offloading toolchain can be done using
|
||||
the `-Xopenmp-target=<triple> -opt=val` flag. In this way the `-opt=val`
|
||||
option will be forwarded to the respective OpenMP device offloading toolchain
|
||||
described by the triple. For example passing the compute capability to
|
||||
the OpenMP NVPTX offloading toolchain can be done as follows:
|
||||
`-Xopenmp-target=nvptx64-nvidia-cuda -march=sm_60`. For the case when only one
|
||||
target offload toolchain is specified under the `-fopenmp-targets=<triples>`
|
||||
option, then the triple can be skipped: `-Xopenmp-target -march=sm_60`.
|
||||
|
||||
- Other bugfixes.
|
||||
|
||||
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 4.0.0 release of
|
||||
These are major API changes that have happened since the 6.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.
|
||||
|
||||
@ -223,67 +256,16 @@ this section should help get you past the largest hurdles of upgrading.
|
||||
AST Matchers
|
||||
------------
|
||||
|
||||
The hasDeclaration matcher now works the same for Type and QualType and only
|
||||
ever looks through one level of sugaring in a limited number of cases.
|
||||
|
||||
There are two main patterns affected by this:
|
||||
|
||||
- qualType(hasDeclaration(recordDecl(...))): previously, we would look through
|
||||
sugar like TypedefType to get at the underlying recordDecl; now, we need
|
||||
to explicitly remove the sugaring:
|
||||
qualType(hasUnqualifiedDesugaredType(hasDeclaration(recordDecl(...))))
|
||||
|
||||
- hasType(recordDecl(...)): hasType internally uses hasDeclaration; previously,
|
||||
this matcher used to match for example TypedefTypes of the RecordType, but
|
||||
after the change they don't; to fix, use:
|
||||
|
||||
::
|
||||
hasType(hasUnqualifiedDesugaredType(
|
||||
recordType(hasDeclaration(recordDecl(...)))))
|
||||
|
||||
- templateSpecializationType(hasDeclaration(classTemplateDecl(...))):
|
||||
previously, we would directly match the underlying ClassTemplateDecl;
|
||||
now, we can explicitly match the ClassTemplateSpecializationDecl, but that
|
||||
requires to explicitly get the ClassTemplateDecl:
|
||||
|
||||
::
|
||||
templateSpecializationType(hasDeclaration(
|
||||
classTemplateSpecializationDecl(
|
||||
hasSpecializedTemplate(classTemplateDecl(...)))))
|
||||
- ...
|
||||
|
||||
clang-format
|
||||
------------
|
||||
|
||||
* Option *IndentPPDirectives* added to indent preprocessor directives on
|
||||
conditionals.
|
||||
- Clang-format will now support detecting and formatting code snippets in raw
|
||||
string literals. This is configured through the `RawStringFormats` style
|
||||
option.
|
||||
|
||||
+----------------------+----------------------+
|
||||
| Before | After |
|
||||
+======================+======================+
|
||||
| .. code-block:: c++ | .. code-block:: c++ |
|
||||
| | |
|
||||
| #if FOO | #if FOO |
|
||||
| #if BAR | # if BAR |
|
||||
| #include <foo> | # include <foo> |
|
||||
| #endif | # endif |
|
||||
| #endif | #endif |
|
||||
+----------------------+----------------------+
|
||||
|
||||
* Option -verbose added to the command line.
|
||||
Shows the list of processed files.
|
||||
|
||||
* Option *IncludeBlocks* added to merge and regroup multiple ``#include`` blocks during sorting.
|
||||
|
||||
+-------------------------+-------------------------+-------------------------+
|
||||
| Before (Preserve) | Merge | Regroup |
|
||||
+=========================+=========================+=========================+
|
||||
| .. code-block:: c++ | .. code-block:: c++ | .. code-block:: c++ |
|
||||
| | | |
|
||||
| #include "b.h" | #include "a.h" | #include "a.h" |
|
||||
| | #include "b.h" | #include "b.h" |
|
||||
| #include "a.b" | #include <lib/main.h> | |
|
||||
| #include <lib/main.h> | | #include <lib/main.h> |
|
||||
+-------------------------+-------------------------+-------------------------+
|
||||
- ...
|
||||
|
||||
libclang
|
||||
--------
|
||||
@ -294,18 +276,14 @@ libclang
|
||||
Static Analyzer
|
||||
---------------
|
||||
|
||||
- Static Analyzer can now properly detect and diagnose unary pre-/post-
|
||||
increment/decrement on an uninitialized value.
|
||||
- ...
|
||||
|
||||
...
|
||||
|
||||
Undefined Behavior Sanitizer (UBSan)
|
||||
------------------------------------
|
||||
|
||||
* A minimal runtime is now available. It is suitable for use in production
|
||||
environments, and has a small attack surface. It only provides very basic
|
||||
issue logging and deduplication, and does not support ``-fsanitize=vptr``
|
||||
checking.
|
||||
* ...
|
||||
|
||||
Core Analysis Improvements
|
||||
==========================
|
||||
|
@ -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
|
||||
======
|
||||
|
@ -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
|
||||
|
193
docs/ShadowCallStack.rst
Normal file
193
docs/ShadowCallStack.rst
Normal file
@ -0,0 +1,193 @@
|
||||
===============
|
||||
ShadowCallStack
|
||||
===============
|
||||
|
||||
.. contents::
|
||||
:local:
|
||||
|
||||
Introduction
|
||||
============
|
||||
|
||||
ShadowCallStack is an **experimental** instrumentation pass, currently only
|
||||
implemented for x86_64 and aarch64, that protects programs against return
|
||||
address overwrites (e.g. stack buffer overflows.) It works by saving a
|
||||
function's return address to a separately allocated 'shadow call stack'
|
||||
in the function prolog and checking the return address on the stack against
|
||||
the shadow call stack in the function epilog.
|
||||
|
||||
Comparison
|
||||
----------
|
||||
|
||||
To optimize for memory consumption and cache locality, the shadow call stack
|
||||
stores an index followed by an array of return addresses. This is in contrast
|
||||
to other schemes, like :doc:`SafeStack`, that mirror the entire stack and
|
||||
trade-off consuming more memory for shorter function prologs and epilogs with
|
||||
fewer memory accesses. Similarly, `Return Flow Guard`_ consumes more memory with
|
||||
shorter function prologs and epilogs than ShadowCallStack but suffers from the
|
||||
same race conditions (see `Security`_). Intel `Control-flow Enforcement Technology`_
|
||||
(CET) is a proposed hardware extension that would add native support to
|
||||
use a shadow stack to store/check return addresses at call/return time. It
|
||||
would not suffer from race conditions at calls and returns and not incur the
|
||||
overhead of function instrumentation, but it does require operating system
|
||||
support.
|
||||
|
||||
.. _`Return Flow Guard`: https://xlab.tencent.com/en/2016/11/02/return-flow-guard/
|
||||
.. _`Control-flow Enforcement Technology`: https://software.intel.com/sites/default/files/managed/4d/2a/control-flow-enforcement-technology-preview.pdf
|
||||
|
||||
Compatibility
|
||||
-------------
|
||||
|
||||
ShadowCallStack currently only supports x86_64 and aarch64. A runtime is not
|
||||
currently provided in compiler-rt so one must be provided by the compiled
|
||||
application.
|
||||
|
||||
On aarch64, the instrumentation makes use of the platform register ``x18``.
|
||||
On some platforms, ``x18`` is reserved, and on others, it is designated as
|
||||
a scratch register. This generally means that any code that may run on the
|
||||
same thread as code compiled with ShadowCallStack must either target one
|
||||
of the platforms whose ABI reserves ``x18`` (currently Darwin, Fuchsia and
|
||||
Windows) or be compiled with the flag ``-ffixed-x18``.
|
||||
|
||||
Security
|
||||
========
|
||||
|
||||
ShadowCallStack is intended to be a stronger alternative to
|
||||
``-fstack-protector``. It protects from non-linear overflows and arbitrary
|
||||
memory writes to the return address slot; however, similarly to
|
||||
``-fstack-protector`` this protection suffers from race conditions because of
|
||||
the call-return semantics on x86_64. There is a short race between the call
|
||||
instruction and the first instruction in the function that reads the return
|
||||
address where an attacker could overwrite the return address and bypass
|
||||
ShadowCallStack. Similarly, there is a time-of-check-to-time-of-use race in the
|
||||
function epilog where an attacker could overwrite the return address after it
|
||||
has been checked and before it has been returned to. Modifying the call-return
|
||||
semantics to fix this on x86_64 would incur an unacceptable performance overhead
|
||||
due to return branch prediction.
|
||||
|
||||
The instrumentation makes use of the ``gs`` segment register on x86_64,
|
||||
or the ``x18`` register on aarch64, to reference the shadow call stack
|
||||
meaning that references to the shadow call stack do not have to be stored in
|
||||
memory. This makes it possible to implement a runtime that avoids exposing
|
||||
the address of the shadow call stack to attackers that can read arbitrary
|
||||
memory. However, attackers could still try to exploit side channels exposed
|
||||
by the operating system `[1]`_ `[2]`_ or processor `[3]`_ to discover the
|
||||
address of the shadow call stack.
|
||||
|
||||
.. _`[1]`: https://eyalitkin.wordpress.com/2017/09/01/cartography-lighting-up-the-shadows/
|
||||
.. _`[2]`: https://www.blackhat.com/docs/eu-16/materials/eu-16-Goktas-Bypassing-Clangs-SafeStack.pdf
|
||||
.. _`[3]`: https://www.vusec.net/projects/anc/
|
||||
|
||||
On x86_64, leaf functions are optimized to store the return address in a
|
||||
free register and avoid writing to the shadow call stack if a register is
|
||||
available. Very short leaf functions are uninstrumented if their execution
|
||||
is judged to be shorter than the race condition window intrinsic to the
|
||||
instrumentation.
|
||||
|
||||
On aarch64, the architecture's call and return instructions (``bl`` and
|
||||
``ret``) operate on a register rather than the stack, which means that
|
||||
leaf functions are generally protected from return address overwrites even
|
||||
without ShadowCallStack. It also means that ShadowCallStack on aarch64 is not
|
||||
vulnerable to the same types of time-of-check-to-time-of-use races as x86_64.
|
||||
|
||||
Usage
|
||||
=====
|
||||
|
||||
To enable ShadowCallStack, just pass the ``-fsanitize=shadow-call-stack``
|
||||
flag to both compile and link command lines. On aarch64, you also need to pass
|
||||
``-ffixed-x18`` unless your target already reserves ``x18``.
|
||||
|
||||
Low-level API
|
||||
-------------
|
||||
|
||||
``__has_feature(shadow_call_stack)``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
In some cases one may need to execute different code depending on whether
|
||||
ShadowCallStack is enabled. The macro ``__has_feature(shadow_call_stack)`` can
|
||||
be used for this purpose.
|
||||
|
||||
.. code-block:: c
|
||||
|
||||
#if defined(__has_feature)
|
||||
# if __has_feature(shadow_call_stack)
|
||||
// code that builds only under ShadowCallStack
|
||||
# endif
|
||||
#endif
|
||||
|
||||
``__attribute__((no_sanitize("shadow-call-stack")))``
|
||||
~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~~
|
||||
|
||||
Use ``__attribute__((no_sanitize("shadow-call-stack")))`` on a function
|
||||
declaration to specify that the shadow call stack instrumentation should not be
|
||||
applied to that function, even if enabled globally.
|
||||
|
||||
Example
|
||||
=======
|
||||
|
||||
The following example code:
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
int foo() {
|
||||
return bar() + 1;
|
||||
}
|
||||
|
||||
Generates the following x86_64 assembly when compiled with ``-O2``:
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
push %rax
|
||||
callq bar
|
||||
add $0x1,%eax
|
||||
pop %rcx
|
||||
retq
|
||||
|
||||
or the following aarch64 assembly:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
bl bar
|
||||
add w0, w0, #1
|
||||
ldp x29, x30, [sp], #16
|
||||
ret
|
||||
|
||||
|
||||
Adding ``-fsanitize=shadow-call-stack`` would output the following x86_64
|
||||
assembly:
|
||||
|
||||
.. code-block:: gas
|
||||
|
||||
mov (%rsp),%r10
|
||||
xor %r11,%r11
|
||||
addq $0x8,%gs:(%r11)
|
||||
mov %gs:(%r11),%r11
|
||||
mov %r10,%gs:(%r11)
|
||||
push %rax
|
||||
callq bar
|
||||
add $0x1,%eax
|
||||
pop %rcx
|
||||
xor %r11,%r11
|
||||
mov %gs:(%r11),%r10
|
||||
mov %gs:(%r10),%r10
|
||||
subq $0x8,%gs:(%r11)
|
||||
cmp %r10,(%rsp)
|
||||
jne trap
|
||||
retq
|
||||
|
||||
trap:
|
||||
ud2
|
||||
|
||||
or the following aarch64 assembly:
|
||||
|
||||
.. code-block:: none
|
||||
|
||||
str x30, [x18], #8
|
||||
stp x29, x30, [sp, #-16]!
|
||||
mov x29, sp
|
||||
bl bar
|
||||
add w0, w0, #1
|
||||
ldp x29, x30, [sp], #16
|
||||
ldr x30, [x18, #-8]!
|
||||
ret
|
@ -156,7 +156,7 @@ A policy string is a series of key-value pairs separated by ``:`` characters.
|
||||
Possible key-value pairs are:
|
||||
|
||||
- ``cache_size=X%``: The maximum size for the cache directory is ``X`` percent
|
||||
of the available space on the the disk. Set to 100 to indicate no limit,
|
||||
of the available space on the disk. Set to 100 to indicate no limit,
|
||||
50 to indicate that the cache size will not be left over half the available
|
||||
disk space. A value over 100 is invalid. A value of 0 disables the percentage
|
||||
size-based pruning. The default is 75%.
|
||||
|
@ -17,7 +17,12 @@ Build LLVM/Clang with `CMake <http://llvm.org/docs/CMake.html>`_.
|
||||
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.
|
||||
|
||||
|
@ -106,7 +106,7 @@ Assember
|
||||
Clang can either use LLVM's integrated assembler or an external system-specific
|
||||
tool (for instance, the GNU Assembler on GNU OSes) to produce machine code from
|
||||
assembly.
|
||||
By default, Clang uses LLVM's integrataed assembler on all targets where it is
|
||||
By default, Clang uses LLVM's integrated assembler on all targets where it is
|
||||
supported. If you wish to use the system assember instead, use the
|
||||
``-fno-integrated-as`` option.
|
||||
|
||||
|
@ -180,6 +180,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 +252,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
|
||||
==============
|
||||
|
||||
|
@ -694,6 +694,79 @@ a special character, which is the convention used by GNU Make. The -MV
|
||||
option tells Clang to put double-quotes around the entire filename, which
|
||||
is the convention used by NMake and Jom.
|
||||
|
||||
Configuration files
|
||||
-------------------
|
||||
|
||||
Configuration files group command-line options and allow all of them to be
|
||||
specified just by referencing the configuration file. They may be used, for
|
||||
example, to collect options required to tune compilation for particular
|
||||
target, such as -L, -I, -l, --sysroot, codegen options, etc.
|
||||
|
||||
The command line option `--config` can be used to specify configuration
|
||||
file in a Clang invocation. For example:
|
||||
|
||||
::
|
||||
|
||||
clang --config /home/user/cfgs/testing.txt
|
||||
clang --config debug.cfg
|
||||
|
||||
If the provided argument contains a directory separator, it is considered as
|
||||
a file path, and options are read from that file. Otherwise the argument is
|
||||
treated as a file name and is searched for sequentially in the directories:
|
||||
|
||||
- user directory,
|
||||
- system directory,
|
||||
- the directory where Clang executable resides.
|
||||
|
||||
Both user and system directories for configuration files are specified during
|
||||
clang build using CMake parameters, CLANG_CONFIG_FILE_USER_DIR and
|
||||
CLANG_CONFIG_FILE_SYSTEM_DIR respectively. The first file found is used. It is
|
||||
an error if the required file cannot be found.
|
||||
|
||||
Another way to specify a configuration file is to encode it in executable name.
|
||||
For example, if the Clang executable is named `armv7l-clang` (it may be a
|
||||
symbolic link to `clang`), then Clang will search for file `armv7l.cfg` in the
|
||||
directory where Clang resides.
|
||||
|
||||
If a driver mode is specified in invocation, Clang tries to find a file specific
|
||||
for the specified mode. For example, if the executable file is named
|
||||
`x86_64-clang-cl`, Clang first looks for `x86_64-cl.cfg` and if it is not found,
|
||||
looks for `x86_64.cfg`.
|
||||
|
||||
If the command line contains options that effectively change target architecture
|
||||
(these are -m32, -EL, and some others) and the configuration file starts with an
|
||||
architecture name, Clang tries to load the configuration file for the effective
|
||||
architecture. For example, invocation:
|
||||
|
||||
::
|
||||
|
||||
x86_64-clang -m32 abc.c
|
||||
|
||||
causes Clang search for a file `i368.cfg` first, and if no such file is found,
|
||||
Clang looks for the file `x86_64.cfg`.
|
||||
|
||||
The configuration file consists of command-line options specified on one or
|
||||
more lines. Lines composed of whitespace characters only are ignored as well as
|
||||
lines in which the first non-blank character is `#`. Long options may be split
|
||||
between several lines by a trailing backslash. Here is example of a
|
||||
configuration file:
|
||||
|
||||
::
|
||||
|
||||
# Several options on line
|
||||
-c --target=x86_64-unknown-linux-gnu
|
||||
|
||||
# Long option split between lines
|
||||
-I/usr/lib/gcc/x86_64-linux-gnu/5.4.0/../../../../\
|
||||
include/c++/5.4.0
|
||||
|
||||
# other config files may be included
|
||||
@linux.options
|
||||
|
||||
Files included by `@file` directives in configuration files are resolved
|
||||
relative to the including file. For example, if a configuration file
|
||||
`~/.llvm/target.cfg` contains the directive `@os/linux.opts`, the file
|
||||
`linux.opts` is searched for in the directory `~/.llvm/os`.
|
||||
|
||||
Language and Target-Independent Features
|
||||
========================================
|
||||
@ -1002,7 +1075,7 @@ location.
|
||||
Building a relocatable precompiled header requires two additional
|
||||
arguments. First, pass the ``--relocatable-pch`` flag to indicate that
|
||||
the resulting PCH file should be relocatable. Second, pass
|
||||
`-isysroot /path/to/build`, which makes all includes for your library
|
||||
``-isysroot /path/to/build``, which makes all includes for your library
|
||||
relative to the build directory. For example:
|
||||
|
||||
.. code-block:: console
|
||||
@ -1012,9 +1085,9 @@ relative to the build directory. For example:
|
||||
When loading the relocatable PCH file, the various headers used in the
|
||||
PCH file are found from the system header root. For example, ``mylib.h``
|
||||
can be found in ``/usr/include/mylib.h``. If the headers are installed
|
||||
in some other system root, the `-isysroot` option can be used provide
|
||||
in some other system root, the ``-isysroot`` option can be used provide
|
||||
a different system root from which the headers will be based. For
|
||||
example, `-isysroot /Developer/SDKs/MacOSX10.4u.sdk` will look for
|
||||
example, ``-isysroot /Developer/SDKs/MacOSX10.4u.sdk`` will look for
|
||||
``mylib.h`` in ``/Developer/SDKs/MacOSX10.4u.sdk/usr/include/mylib.h``.
|
||||
|
||||
Relocatable precompiled headers are intended to be used in a limited
|
||||
@ -1182,12 +1255,26 @@ are listed below.
|
||||
flushed-to-zero number is preserved in the sign of 0, denormals are
|
||||
flushed to positive zero, respectively.
|
||||
|
||||
.. option:: -f[no-]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.
|
||||
|
||||
.. option:: -fwhole-program-vtables
|
||||
|
||||
Enable whole-program vtable optimizations, such as single-implementation
|
||||
devirtualization and virtual constant propagation, for classes with
|
||||
:doc:`hidden LTO visibility <LTOVisibility>`. 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.
|
||||
@ -1295,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
|
||||
<https://research.google.com/pubs/archive/36912.pdf>`_ 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
|
||||
---------------------------
|
||||
@ -1302,7 +1398,8 @@ Profile Guided Optimization
|
||||
Profile information enables better optimization. For example, knowing that a
|
||||
branch is taken very frequently helps the compiler make better decisions when
|
||||
ordering basic blocks. Knowing that a function ``foo`` is called more
|
||||
frequently than another function ``bar`` helps the inliner.
|
||||
frequently than another function ``bar`` helps the inliner. Optimization
|
||||
levels ``-O2`` and above are recommended for use of profile guided optimization.
|
||||
|
||||
Clang supports profile guided optimization with two different kinds of
|
||||
profiling. A sampling profiler can generate a profile with very low runtime
|
||||
@ -1653,11 +1750,11 @@ profile creation and use.
|
||||
.. option:: -fprofile-generate[=<dirname>]
|
||||
|
||||
The ``-fprofile-generate`` and ``-fprofile-generate=`` flags will use
|
||||
an alterantive instrumentation method for profile generation. When
|
||||
an alternative instrumentation method for profile generation. When
|
||||
given a directory name, it generates the profile file
|
||||
``default_%m.profraw`` in the directory named ``dirname`` if specified.
|
||||
If ``dirname`` does not exist, it will be created at runtime. ``%m`` specifier
|
||||
will be substibuted with a unique id documented in step 2 above. In other words,
|
||||
will be substituted with a unique id documented in step 2 above. In other words,
|
||||
with ``-fprofile-generate[=<dirname>]`` option, the "raw" profile data automatic
|
||||
merging is turned on by default, so there will no longer any risk of profile
|
||||
clobbering from different running processes. For example,
|
||||
@ -1781,6 +1878,27 @@ features. You can "tune" the debug info for one of several different debuggers.
|
||||
must come first.)
|
||||
|
||||
|
||||
Controlling LLVM IR Output
|
||||
--------------------------
|
||||
|
||||
Controlling Value Names in LLVM IR
|
||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||
|
||||
Emitting value names in LLVM IR increases the size and verbosity of the IR.
|
||||
By default, value names are only emitted in assertion-enabled builds of Clang.
|
||||
However, when reading IR it can be useful to re-enable the emission of value
|
||||
names to improve readability.
|
||||
|
||||
.. option:: -fdiscard-value-names
|
||||
|
||||
Discard value names when generating LLVM IR.
|
||||
|
||||
.. option:: -fno-discard-value-names
|
||||
|
||||
Do not discard value names when generating LLVM IR. This option can be used
|
||||
to re-enable names for release builds of Clang.
|
||||
|
||||
|
||||
Comment Parsing Options
|
||||
-----------------------
|
||||
|
||||
@ -1836,8 +1954,8 @@ Differences between various standard modes
|
||||
------------------------------------------
|
||||
|
||||
clang supports the -std option, which changes what language mode clang
|
||||
uses. The supported modes for C are c89, gnu89, c94, c99, gnu99, c11,
|
||||
gnu11, and various aliases for those modes. If no -std option is
|
||||
uses. The supported modes for C are c89, gnu89, c99, gnu99, c11, gnu11,
|
||||
c17, gnu17, and various aliases for those modes. If no -std option is
|
||||
specified, clang defaults to gnu11 mode. Many C99 and C11 features are
|
||||
supported in earlier modes as a conforming extension, with a warning. Use
|
||||
``-pedantic-errors`` to request an error if a feature from a later standard
|
||||
@ -1884,8 +2002,9 @@ Differences between ``*99`` and ``*11`` modes:
|
||||
- Warnings for use of C11 features are disabled.
|
||||
- ``__STDC_VERSION__`` is defined to ``201112L`` rather than ``199901L``.
|
||||
|
||||
c94 mode is identical to c89 mode except that digraphs are enabled in
|
||||
c94 mode (FIXME: And ``__STDC_VERSION__`` should be defined!).
|
||||
Differences between ``*11`` and ``*17`` modes:
|
||||
|
||||
- ``__STDC_VERSION__`` is defined to ``201710L`` rather than ``201112L``.
|
||||
|
||||
GCC extensions not implemented yet
|
||||
----------------------------------
|
||||
@ -2006,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
|
||||
|
||||
@ -2042,6 +2166,11 @@ directives, and ``#pragma omp taskgroup`` directive.
|
||||
Use `-fopenmp` to enable OpenMP. Support for OpenMP can be disabled with
|
||||
`-fno-openmp`.
|
||||
|
||||
Use `-fopenmp-simd` to enable OpenMP simd features only, without linking
|
||||
the runtime library; for combined constructs
|
||||
(e.g. ``#pragma omp parallel for simd``) the non-simd directives and clauses
|
||||
will be ignored. This can be disabled with `-fno-openmp-simd`.
|
||||
|
||||
Controlling implementation limits
|
||||
---------------------------------
|
||||
|
||||
@ -2079,7 +2208,7 @@ to the target, for example:
|
||||
.. code-block:: console
|
||||
|
||||
$ clang -target nvptx64-unknown-unknown test.cl
|
||||
$ clang -target amdgcn-amd-amdhsa-opencl test.cl
|
||||
$ clang -target amdgcn-amd-amdhsa -mcpu=gfx900 test.cl
|
||||
|
||||
Compiling to bitcode can be done as follows:
|
||||
|
||||
@ -2187,7 +2316,7 @@ There is a set of concrete HW architectures that OpenCL can be compiled for.
|
||||
|
||||
.. code-block:: console
|
||||
|
||||
$ clang -target amdgcn-amd-amdhsa-opencl test.cl
|
||||
$ clang -target amdgcn-amd-amdhsa -mcpu=gfx900 test.cl
|
||||
|
||||
- For Nvidia architectures:
|
||||
|
||||
@ -2584,10 +2713,37 @@ compatibility with the Visual C++ compiler, cl.exe.
|
||||
To enable clang-cl to find system headers, libraries, and the linker when run
|
||||
from the command-line, it should be executed inside a Visual Studio Native Tools
|
||||
Command Prompt or a regular Command Prompt where the environment has been set
|
||||
up using e.g. `vcvars32.bat <http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
|
||||
up using e.g. `vcvarsall.bat <http://msdn.microsoft.com/en-us/library/f2ccy3wt.aspx>`_.
|
||||
|
||||
clang-cl can also be used from inside Visual Studio by selecting the LLVM
|
||||
Platform Toolset. The toolset is installed by the LLVM installer, which can be
|
||||
downloaded from the `LLVM release <http://releases.llvm.org/download.html>`_ or
|
||||
`snapshot build <http://llvm.org/builds/>`_ web pages. To use the toolset,
|
||||
select a project in Solution Explorer, open its Property Page (Alt+F7), and in
|
||||
the "General" section of "Configuration Properties" change "Platform Toolset"
|
||||
to e.g. LLVM-vs2014.
|
||||
|
||||
To use the toolset with MSBuild directly, invoke it with e.g.
|
||||
``/p:PlatformToolset=LLVM-vs2014``. This allows trying out the clang-cl
|
||||
toolchain without modifying your project files.
|
||||
|
||||
It's also possible to point MSBuild at clang-cl without changing toolset by
|
||||
passing ``/p:CLToolPath=c:\llvm\bin /p:CLToolExe=clang-cl.exe``.
|
||||
|
||||
When using CMake and the Visual Studio generators, the toolset can be set with the ``-T`` flag:
|
||||
|
||||
::
|
||||
|
||||
cmake -G"Visual Studio 15 2017" -T LLVM-vs2014 ..
|
||||
|
||||
When using CMake with the Ninja generator, set the ``CMAKE_C_COMPILER`` and
|
||||
``CMAKE_CXX_COMPILER`` variables to clang-cl:
|
||||
|
||||
::
|
||||
|
||||
cmake -GNinja -DCMAKE_C_COMPILER="c:/Program Files (x86)/LLVM/bin/clang-cl.exe"
|
||||
-DCMAKE_CXX_COMPILER="c:/Program Files (x86)/LLVM/bin/clang-cl.exe" ..
|
||||
|
||||
clang-cl can also be used from inside Visual Studio by using an LLVM Platform
|
||||
Toolset.
|
||||
|
||||
Command-Line Options
|
||||
--------------------
|
||||
@ -2654,6 +2810,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||
/Gd Set __cdecl as a default calling convention
|
||||
/GF- Disable string pooling
|
||||
/GR- Disable emission of RTTI data
|
||||
/Gregcall Set __regcall as a default calling convention
|
||||
/GR Enable emission of RTTI data
|
||||
/Gr Set __fastcall as a default calling convention
|
||||
/GS- Disable buffer security check
|
||||
@ -2662,7 +2819,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||
/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
|
||||
/GX- Enable exception handling
|
||||
/GX- Disable exception handling
|
||||
/GX Enable exception handling
|
||||
/Gy- Don't put each function in its own section
|
||||
/Gy Put each function in its own section
|
||||
@ -2710,7 +2867,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||
/W2 Enable -Wall
|
||||
/W3 Enable -Wall
|
||||
/W4 Enable -Wall and -Wextra
|
||||
/Wall Enable -Wall and -Wextra
|
||||
/Wall Enable -Weverything
|
||||
/WX- Do not treat warnings as errors
|
||||
/WX Treat warnings as errors
|
||||
/w Disable all warnings
|
||||
@ -2767,6 +2924,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||
Disable specified features of coverage instrumentation for Sanitizers
|
||||
-fno-sanitize-memory-track-origins
|
||||
Disable origins tracking in MemorySanitizer
|
||||
-fno-sanitize-memory-use-after-dtor
|
||||
Disable use-after-destroy detection in MemorySanitizer
|
||||
-fno-sanitize-recover=<value>
|
||||
Disable recovery for specified sanitizers
|
||||
-fno-sanitize-stats Disable sanitizer statistics gathering.
|
||||
@ -2797,6 +2956,8 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||
Path to blacklist file for sanitizers
|
||||
-fsanitize-cfi-cross-dso
|
||||
Enable control flow integrity (CFI) checks for cross-DSO calls.
|
||||
-fsanitize-cfi-icall-generalize-pointers
|
||||
Generalize pointers in CFI indirect call type signature checks
|
||||
-fsanitize-coverage=<value>
|
||||
Specify the type of coverage instrumentation for Sanitizers
|
||||
-fsanitize-memory-track-origins=<value>
|
||||
@ -2820,6 +2981,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||
-fsanitize=<check> Turn on runtime checks for various forms of undefined or suspicious
|
||||
behavior. See user manual for available checks
|
||||
-fstandalone-debug Emit full debug info for all types used by the program
|
||||
-fwhole-program-vtables Enables whole-program vtable optimization. Requires -flto
|
||||
-gcodeview Generate CodeView debug information
|
||||
-gline-tables-only Emit debug line number tables only
|
||||
-miamcu Use Intel MCU ABI
|
||||
@ -2828,6 +2990,7 @@ Execute ``clang-cl /?`` to see a list of supported options:
|
||||
-Qunused-arguments Don't emit warning for unused driver arguments
|
||||
-R<remark> Enable the specified remark
|
||||
--target=<value> Generate code for the given target
|
||||
--version Print version information
|
||||
-v Show commands to run and use verbose output
|
||||
-W<warning> Enable the specified warning
|
||||
-Xclang <arg> Pass <arg> to the clang compiler
|
||||
|
@ -21,7 +21,7 @@ This fix is overly conservative though. So i did a bit of investigation as to
|
||||
how model std::initializer_list better.
|
||||
|
||||
According to the standard, std::initializer_list<T> is an object that has
|
||||
methods begin(), end(), and size(), where begin() returns a pointer to continous
|
||||
methods begin(), end(), and size(), where begin() returns a pointer to continuous
|
||||
array of size() objects of type T, and end() is equal to begin() plus size().
|
||||
The standard does hint that it should be possible to implement
|
||||
std::initializer_list<T> as a pair of pointers, or as a pointer and a size
|
||||
|
@ -49,9 +49,9 @@
|
||||
# built documents.
|
||||
#
|
||||
# The short version.
|
||||
version = '6'
|
||||
version = '7'
|
||||
# The full version, including alpha/beta/rc tags.
|
||||
release = '6'
|
||||
release = '7'
|
||||
|
||||
# The language for content autogenerated by Sphinx. Refer to documentation
|
||||
# for a list of supported languages.
|
||||
|
@ -174,7 +174,7 @@ JAVADOC_AUTOBRIEF = YES
|
||||
# If the QT_AUTOBRIEF tag is set to YES then doxygen will interpret the first
|
||||
# line (until the first dot) of a Qt-style comment as the brief description. If
|
||||
# set to NO, the Qt-style will behave just like regular Qt-style comments (thus
|
||||
# requiring an explicit \brief command for a brief description.)
|
||||
# requiring an explicit command for a brief description.)
|
||||
# The default value is: NO.
|
||||
|
||||
QT_AUTOBRIEF = YES
|
||||
@ -284,7 +284,7 @@ MARKDOWN_SUPPORT = YES
|
||||
|
||||
# When enabled doxygen tries to link words that correspond to documented
|
||||
# classes, or namespaces to their corresponding documentation. Such a link can
|
||||
# be prevented in individual cases by by putting a % sign in front of the word
|
||||
# be prevented in individual cases by putting a % sign in front of the word
|
||||
# or globally by setting AUTOLINK_SUPPORT to NO.
|
||||
# The default value is: YES.
|
||||
|
||||
@ -1065,7 +1065,7 @@ HTML_STYLESHEET =
|
||||
# defined cascading style sheet that is included after the standard style sheets
|
||||
# created by doxygen. Using this option one can overrule certain style aspects.
|
||||
# This is preferred over using HTML_STYLESHEET since it does not replace the
|
||||
# standard style sheet and is therefor more robust against future updates.
|
||||
# standard style sheet and is therefore more robust against future updates.
|
||||
# Doxygen will copy the style sheet file to the output directory. For an example
|
||||
# see the documentation.
|
||||
# This tag requires that the tag GENERATE_HTML is set to YES.
|
||||
|
@ -36,9 +36,11 @@ Using Clang as a Compiler
|
||||
ControlFlowIntegrity
|
||||
LTOVisibility
|
||||
SafeStack
|
||||
ShadowCallStack
|
||||
SourceBasedCodeCoverage
|
||||
Modules
|
||||
MSVCCompatibility
|
||||
OpenMPSupport
|
||||
ThinLTO
|
||||
CommandGuide/index
|
||||
FAQ
|
||||
|
@ -95,7 +95,7 @@ def strip_doxygen(comment):
|
||||
def unify_arguments(args):
|
||||
"""Gets rid of anything the user doesn't care about in the argument list."""
|
||||
args = re.sub(r'internal::', r'', args)
|
||||
args = re.sub(r'const\s+(.*)&', r'\1 ', args)
|
||||
args = re.sub(r'extern const\s+(.*)&', r'\1 ', args)
|
||||
args = re.sub(r'&', r' ', args)
|
||||
args = re.sub(r'(^|\s)M\d?(\s)', r'\1Matcher<*>\2', args)
|
||||
return args
|
||||
@ -150,11 +150,11 @@ def act_on_decl(declaration, comment, allowed_types):
|
||||
comment, is_dyncast=True)
|
||||
return
|
||||
|
||||
# Parse the various matcher definition macros.
|
||||
m = re.match(""".*AST_TYPE_MATCHER\(
|
||||
\s*([^\s,]+\s*),
|
||||
\s*([^\s,]+\s*)
|
||||
\)\s*;\s*$""", declaration, flags=re.X)
|
||||
# Special case of type matchers:
|
||||
# AstTypeMatcher<ArgumentType> name
|
||||
m = re.match(r""".*AstTypeMatcher\s*<
|
||||
\s*([^\s>]+)\s*>
|
||||
\s*([^\s;]+)\s*;\s*$""", declaration, flags=re.X)
|
||||
if m:
|
||||
inner, name = m.groups()
|
||||
add_matcher('Type', name, 'Matcher<%s>...' % inner,
|
||||
@ -165,7 +165,8 @@ def act_on_decl(declaration, comment, allowed_types):
|
||||
# comment, is_dyncast=True)
|
||||
return
|
||||
|
||||
m = re.match(""".*AST_TYPE(LOC)?_TRAVERSE_MATCHER\(
|
||||
# Parse the various matcher definition macros.
|
||||
m = re.match(""".*AST_TYPE(LOC)?_TRAVERSE_MATCHER(?:_DECL)?\(
|
||||
\s*([^\s,]+\s*),
|
||||
\s*(?:[^\s,]+\s*),
|
||||
\s*AST_POLYMORPHIC_SUPPORTED_TYPES\(([^)]*)\)
|
||||
@ -236,7 +237,7 @@ def act_on_decl(declaration, comment, allowed_types):
|
||||
(?:,\s*([^\s,]+)\s*
|
||||
,\s*([^\s,]+)\s*)?
|
||||
(?:,\s*\d+\s*)?
|
||||
\)\s*{\s*$""", declaration, flags=re.X)
|
||||
\)\s*{""", declaration, flags=re.X)
|
||||
if m:
|
||||
p, n, result, name = m.groups()[0:4]
|
||||
args = m.groups()[4:]
|
||||
@ -256,8 +257,8 @@ def act_on_decl(declaration, comment, allowed_types):
|
||||
|
||||
# Parse ArgumentAdapting matchers.
|
||||
m = re.match(
|
||||
r"""^.*ArgumentAdaptingMatcherFunc<.*>\s*(?:LLVM_ATTRIBUTE_UNUSED\s*)
|
||||
([a-zA-Z]*)\s*=\s*{};$""",
|
||||
r"""^.*ArgumentAdaptingMatcherFunc<.*>\s*
|
||||
([a-zA-Z]*);$""",
|
||||
declaration, flags=re.X)
|
||||
if m:
|
||||
name = m.groups()[0]
|
||||
@ -267,7 +268,7 @@ def act_on_decl(declaration, comment, allowed_types):
|
||||
# Parse Variadic functions.
|
||||
m = re.match(
|
||||
r"""^.*internal::VariadicFunction\s*<\s*([^,]+),\s*([^,]+),\s*[^>]+>\s*
|
||||
([a-zA-Z]*)\s*=\s*{.*};$""",
|
||||
([a-zA-Z]*);$""",
|
||||
declaration, flags=re.X)
|
||||
if m:
|
||||
result, arg, name = m.groups()[:3]
|
||||
@ -276,15 +277,15 @@ def act_on_decl(declaration, comment, allowed_types):
|
||||
|
||||
# Parse Variadic operator matchers.
|
||||
m = re.match(
|
||||
r"""^.*VariadicOperatorMatcherFunc\s*<\s*([^,]+),\s*([^\s>]+)\s*>\s*
|
||||
([a-zA-Z]*)\s*=\s*{.*};$""",
|
||||
r"""^.*VariadicOperatorMatcherFunc\s*<\s*([^,]+),\s*([^\s]+)\s*>\s*
|
||||
([a-zA-Z]*);$""",
|
||||
declaration, flags=re.X)
|
||||
if m:
|
||||
min_args, max_args, name = m.groups()[:3]
|
||||
if max_args == '1':
|
||||
add_matcher('*', name, 'Matcher<*>', comment)
|
||||
return
|
||||
elif max_args == 'UINT_MAX':
|
||||
elif max_args == 'std::numeric_limits<unsigned>::max()':
|
||||
add_matcher('*', name, 'Matcher<*>, ..., Matcher<*>', comment)
|
||||
return
|
||||
|
||||
|
@ -10,6 +10,7 @@
|
||||
|
||||
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 @@ class State:
|
||||
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 @@ class State:
|
||||
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))
|
||||
|
@ -1,7 +1,7 @@
|
||||
# If we don't need RTTI or EH, there's no reason to export anything
|
||||
# from the plugin.
|
||||
if( NOT MSVC ) # MSVC mangles symbols differently, and
|
||||
# PrintFunctionNames.export contains C++ symbols.
|
||||
# PrintFunctionNames.export contains C++ symbols.
|
||||
if( NOT LLVM_REQUIRES_RTTI )
|
||||
if( NOT LLVM_REQUIRES_EH )
|
||||
set(LLVM_EXPORTED_SYMBOL_FILE ${CMAKE_CURRENT_SOURCE_DIR}/PrintFunctionNames.exports)
|
||||
|
@ -16,10 +16,8 @@ class MainCallChecker : public Checker < check::PreStmt<CallExpr> > {
|
||||
} // end anonymous namespace
|
||||
|
||||
void MainCallChecker::checkPreStmt(const CallExpr *CE, CheckerContext &C) const {
|
||||
const ProgramStateRef state = C.getState();
|
||||
const LocationContext *LC = C.getLocationContext();
|
||||
const Expr *Callee = CE->getCallee();
|
||||
const FunctionDecl *FD = state->getSVal(Callee, LC).getAsFunctionDecl();
|
||||
const FunctionDecl *FD = C.getSVal(Callee).getAsFunctionDecl();
|
||||
|
||||
if (!FD)
|
||||
return;
|
||||
|
@ -3,7 +3,10 @@ set(LLVM_LINK_COMPONENTS
|
||||
ExecutionEngine
|
||||
MC
|
||||
MCJIT
|
||||
Object
|
||||
OrcJit
|
||||
Option
|
||||
RuntimeDyld
|
||||
Support
|
||||
native
|
||||
)
|
||||
@ -23,3 +26,67 @@ target_link_libraries(clang-interpreter
|
||||
clangDriver
|
||||
clangFrontend
|
||||
)
|
||||
|
||||
export_executable_symbols(clang-interpreter)
|
||||
|
||||
if (MSVC)
|
||||
# Is this a CMake bug that even with export_executable_symbols, Windows
|
||||
# needs to explictly export the type_info vtable
|
||||
set_property(TARGET clang-interpreter
|
||||
APPEND_STRING PROPERTY LINK_FLAGS " /EXPORT:??_7type_info@@6B@")
|
||||
endif()
|
||||
|
||||
function(clang_enable_exceptions TARGET)
|
||||
# Really have to jump through hoops to enable exception handling independent
|
||||
# of how LLVM is being built.
|
||||
if (NOT LLVM_REQUIRES_EH AND NOT LLVM_REQUIRES_RTTI)
|
||||
if (MSVC)
|
||||
# /EHs to allow throwing from extern "C"
|
||||
set(excptnExceptions_ON "/D _HAS_EXCEPTIONS=1 /EHs /wd4714")
|
||||
set(excptnExceptions_OFF "/D _HAS_EXCEPTIONS=0 /EHs-c-")
|
||||
set(excptnRTTI_ON "/GR")
|
||||
set(excptnRTTI_OFF "/GR-")
|
||||
set(excptnEHRTTIRegEx "(/EHs(-c-?)|_HAS_EXCEPTIONS=(0|1))")
|
||||
else()
|
||||
set(excptnExceptions_ON "-fexceptions")
|
||||
set(excptnExceptions_OFF "-fno-exceptions")
|
||||
set(excptnRTTI_ON "-frtti")
|
||||
set(excptnRTTI_OFF "-fno-rtti")
|
||||
set(excptnEHRTTIRegEx "-f(exceptions|no-exceptions)")
|
||||
endif()
|
||||
if (LLVM_REQUIRES_EH)
|
||||
set(excptnExceptions_DFLT ${excptnExceptions_ON})
|
||||
else()
|
||||
set(excptnExceptions_DFLT ${excptnExceptions_OFF})
|
||||
endif()
|
||||
if (LLVM_REQUIRES_RTTI)
|
||||
set(excptnRTTI_DFLT ${excptnRTTI_ON})
|
||||
else()
|
||||
set(excptnRTTI_DFLT ${excptnRTTI_OFF})
|
||||
endif()
|
||||
|
||||
# Strip the exception & rtti flags from the target
|
||||
get_property(addedFlags TARGET ${TARGET} PROPERTY COMPILE_FLAGS)
|
||||
string(REGEX REPLACE ${excptnEHRTTIRegEx} "" editedFlags "${addedFlags}")
|
||||
string(REPLACE ${excptnRTTI_OFF} "" editedFlags "${editedFlags}")
|
||||
set_property(TARGET ${TARGET} PROPERTY COMPILE_FLAGS "${editedFlags}")
|
||||
|
||||
get_property(addedFlags TARGET ${TARGET} PROPERTY COMPILE_DEFINITIONS)
|
||||
string(REGEX REPLACE ${excptnEHRTTIRegEx} "" editedFlags "${addedFlags}")
|
||||
string(REPLACE ${excptnRTTI_OFF} "" editedFlags "${editedFlags}")
|
||||
set_property(TARGET ${TARGET} PROPERTY COMPILE_DEFINITIONS "${editedFlags}")
|
||||
|
||||
# Re-add the exception & rtti flags from LLVM
|
||||
set_property(SOURCE main.cpp APPEND_STRING PROPERTY COMPILE_FLAGS
|
||||
" ${excptnExceptions_DFLT} ${excptnRTTI_DFLT} ")
|
||||
set_property(SOURCE Manager.cpp APPEND_STRING PROPERTY COMPILE_FLAGS
|
||||
" ${excptnExceptions_DFLT} ${excptnRTTI_DFLT} ")
|
||||
|
||||
# Invoke with exceptions & rtti
|
||||
set_property(SOURCE Invoke.cpp APPEND_STRING PROPERTY COMPILE_FLAGS
|
||||
" ${excptnExceptions_ON} ${excptnRTTI_ON} ")
|
||||
|
||||
endif()
|
||||
endfunction(clang_enable_exceptions)
|
||||
|
||||
clang_enable_exceptions(clang-interpreter)
|
||||
|
@ -1,4 +1,4 @@
|
||||
This is an example of Clang based interpreter, for executing standalone C
|
||||
This is an example of Clang based interpreter, for executing standalone C/C++
|
||||
programs.
|
||||
|
||||
It demonstrates the following features:
|
||||
@ -12,6 +12,9 @@ It demonstrates the following features:
|
||||
|
||||
4. Use the LLVM JIT functionality to execute the final module.
|
||||
|
||||
5. Intercepting a Win64 library call to allow throwing and catching exceptions
|
||||
in and from the JIT.
|
||||
|
||||
The implementation has many limitations and is not designed to be a full fledged
|
||||
C interpreter. It is designed to demonstrate a simple but functional use of the
|
||||
interpreter. It is designed to demonstrate a simple but functional use of the
|
||||
Clang compiler libraries.
|
||||
|
34
examples/clang-interpreter/Test.cxx
Normal file
34
examples/clang-interpreter/Test.cxx
Normal file
@ -0,0 +1,34 @@
|
||||
//===-- examples/clang-interpreter/Test.cxx - Clang C Interpreter Example -===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
// Example throwing in and from the JIT (particularly on Win64).
|
||||
//
|
||||
// ./bin/clang-interpreter <src>/tools/clang/examples/clang-interpreter/Test.cxx
|
||||
|
||||
#include <stdexcept>
|
||||
#include <stdio.h>
|
||||
|
||||
static void ThrowerAnError(const char* Name) {
|
||||
throw std::runtime_error(Name);
|
||||
}
|
||||
|
||||
int main(int argc, const char** argv) {
|
||||
for (int I = 0; I < argc; ++I)
|
||||
printf("arg[%d]='%s'\n", I, argv[I]);
|
||||
|
||||
try {
|
||||
ThrowerAnError("In JIT");
|
||||
} catch (const std::exception& E) {
|
||||
printf("Caught: '%s'\n", E.what());
|
||||
} catch (...) {
|
||||
printf("Unknown exception\n");
|
||||
}
|
||||
ThrowerAnError("From JIT");
|
||||
return 0;
|
||||
}
|
@ -7,8 +7,8 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#include "clang/CodeGen/CodeGenAction.h"
|
||||
#include "clang/Basic/DiagnosticOptions.h"
|
||||
#include "clang/CodeGen/CodeGenAction.h"
|
||||
#include "clang/Driver/Compilation.h"
|
||||
#include "clang/Driver/Driver.h"
|
||||
#include "clang/Driver/Tool.h"
|
||||
@ -18,7 +18,12 @@
|
||||
#include "clang/Frontend/TextDiagnosticPrinter.h"
|
||||
#include "llvm/ADT/SmallString.h"
|
||||
#include "llvm/ExecutionEngine/ExecutionEngine.h"
|
||||
#include "llvm/ExecutionEngine/MCJIT.h"
|
||||
#include "llvm/ExecutionEngine/Orc/CompileUtils.h"
|
||||
#include "llvm/ExecutionEngine/Orc/IRCompileLayer.h"
|
||||
#include "llvm/ExecutionEngine/Orc/RTDyldObjectLinkingLayer.h"
|
||||
#include "llvm/ExecutionEngine/SectionMemoryManager.h"
|
||||
#include "llvm/IR/DataLayout.h"
|
||||
#include "llvm/IR/Mangler.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/FileSystem.h"
|
||||
#include "llvm/Support/Host.h"
|
||||
@ -26,7 +31,8 @@
|
||||
#include "llvm/Support/Path.h"
|
||||
#include "llvm/Support/TargetSelect.h"
|
||||
#include "llvm/Support/raw_ostream.h"
|
||||
#include <memory>
|
||||
#include "llvm/Target/TargetMachine.h"
|
||||
|
||||
using namespace clang;
|
||||
using namespace clang::driver;
|
||||
|
||||
@ -35,51 +41,80 @@ using namespace clang::driver;
|
||||
// GetMainExecutable (since some platforms don't support taking the
|
||||
// address of main, and some platforms can't implement GetMainExecutable
|
||||
// without being given the address of a function in the main executable).
|
||||
std::string GetExecutablePath(const char *Argv0) {
|
||||
// This just needs to be some symbol in the binary; C++ doesn't
|
||||
// allow taking the address of ::main however.
|
||||
void *MainAddr = (void*) (intptr_t) GetExecutablePath;
|
||||
std::string GetExecutablePath(const char *Argv0, void *MainAddr) {
|
||||
return llvm::sys::fs::getMainExecutable(Argv0, MainAddr);
|
||||
}
|
||||
|
||||
static llvm::ExecutionEngine *
|
||||
createExecutionEngine(std::unique_ptr<llvm::Module> M, std::string *ErrorStr) {
|
||||
return llvm::EngineBuilder(std::move(M))
|
||||
.setEngineKind(llvm::EngineKind::Either)
|
||||
.setErrorStr(ErrorStr)
|
||||
.create();
|
||||
}
|
||||
namespace llvm {
|
||||
namespace orc {
|
||||
|
||||
static int Execute(std::unique_ptr<llvm::Module> Mod, char *const *envp) {
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
class SimpleJIT {
|
||||
private:
|
||||
ExecutionSession ES;
|
||||
std::shared_ptr<SymbolResolver> Resolver;
|
||||
std::unique_ptr<TargetMachine> TM;
|
||||
const DataLayout DL;
|
||||
RTDyldObjectLinkingLayer ObjectLayer;
|
||||
IRCompileLayer<decltype(ObjectLayer), SimpleCompiler> CompileLayer;
|
||||
|
||||
llvm::Module &M = *Mod;
|
||||
std::string Error;
|
||||
std::unique_ptr<llvm::ExecutionEngine> EE(
|
||||
createExecutionEngine(std::move(Mod), &Error));
|
||||
if (!EE) {
|
||||
llvm::errs() << "unable to make execution engine: " << Error << "\n";
|
||||
return 255;
|
||||
public:
|
||||
SimpleJIT()
|
||||
: Resolver(createLegacyLookupResolver(
|
||||
ES,
|
||||
[this](const std::string &Name) -> JITSymbol {
|
||||
if (auto Sym = CompileLayer.findSymbol(Name, false))
|
||||
return Sym;
|
||||
else if (auto Err = Sym.takeError())
|
||||
return std::move(Err);
|
||||
if (auto SymAddr =
|
||||
RTDyldMemoryManager::getSymbolAddressInProcess(Name))
|
||||
return JITSymbol(SymAddr, JITSymbolFlags::Exported);
|
||||
return nullptr;
|
||||
},
|
||||
[](Error Err) { cantFail(std::move(Err), "lookupFlags failed"); })),
|
||||
TM(EngineBuilder().selectTarget()), DL(TM->createDataLayout()),
|
||||
ObjectLayer(ES,
|
||||
[this](VModuleKey) {
|
||||
return RTDyldObjectLinkingLayer::Resources{
|
||||
std::make_shared<SectionMemoryManager>(), Resolver};
|
||||
}),
|
||||
CompileLayer(ObjectLayer, SimpleCompiler(*TM)) {
|
||||
llvm::sys::DynamicLibrary::LoadLibraryPermanently(nullptr);
|
||||
}
|
||||
|
||||
llvm::Function *EntryFn = M.getFunction("main");
|
||||
if (!EntryFn) {
|
||||
llvm::errs() << "'main' function not found in module.\n";
|
||||
return 255;
|
||||
const TargetMachine &getTargetMachine() const { return *TM; }
|
||||
|
||||
VModuleKey addModule(std::unique_ptr<Module> M) {
|
||||
// Add the module to the JIT with a new VModuleKey.
|
||||
auto K = ES.allocateVModule();
|
||||
cantFail(CompileLayer.addModule(K, std::move(M)));
|
||||
return K;
|
||||
}
|
||||
|
||||
// FIXME: Support passing arguments.
|
||||
std::vector<std::string> Args;
|
||||
Args.push_back(M.getModuleIdentifier());
|
||||
JITSymbol findSymbol(const StringRef &Name) {
|
||||
std::string MangledName;
|
||||
raw_string_ostream MangledNameStream(MangledName);
|
||||
Mangler::getNameWithPrefix(MangledNameStream, Name, DL);
|
||||
return CompileLayer.findSymbol(MangledNameStream.str(), true);
|
||||
}
|
||||
|
||||
EE->finalizeObject();
|
||||
return EE->runFunctionAsMain(EntryFn, Args, envp);
|
||||
}
|
||||
JITTargetAddress getSymbolAddress(const StringRef &Name) {
|
||||
return cantFail(findSymbol(Name).getAddress());
|
||||
}
|
||||
|
||||
int main(int argc, const char **argv, char * const *envp) {
|
||||
void removeModule(VModuleKey K) {
|
||||
cantFail(CompileLayer.removeModule(K));
|
||||
}
|
||||
};
|
||||
|
||||
} // end namespace orc
|
||||
} // end namespace llvm
|
||||
|
||||
int main(int argc, const char **argv) {
|
||||
// This just needs to be some symbol in the binary; C++ doesn't
|
||||
// allow taking the address of ::main however.
|
||||
void *MainAddr = (void*) (intptr_t) GetExecutablePath;
|
||||
std::string Path = GetExecutablePath(argv[0]);
|
||||
std::string Path = GetExecutablePath(argv[0], MainAddr);
|
||||
IntrusiveRefCntPtr<DiagnosticOptions> DiagOpts = new DiagnosticOptions();
|
||||
TextDiagnosticPrinter *DiagClient =
|
||||
new TextDiagnosticPrinter(llvm::errs(), &*DiagOpts);
|
||||
@ -87,11 +122,14 @@ int main(int argc, const char **argv, char * const *envp) {
|
||||
IntrusiveRefCntPtr<DiagnosticIDs> DiagID(new DiagnosticIDs());
|
||||
DiagnosticsEngine Diags(DiagID, &*DiagOpts, DiagClient);
|
||||
|
||||
// Use ELF on windows for now.
|
||||
std::string TripleStr = llvm::sys::getProcessTriple();
|
||||
const std::string TripleStr = llvm::sys::getProcessTriple();
|
||||
llvm::Triple T(TripleStr);
|
||||
|
||||
// Use ELF on Windows-32 and MingW for now.
|
||||
#ifndef CLANG_INTERPRETER_COFF_FORMAT
|
||||
if (T.isOSBinFormatCOFF())
|
||||
T.setObjectFormat(llvm::Triple::ELF);
|
||||
#endif
|
||||
|
||||
Driver TheDriver(Path, T.str(), Diags);
|
||||
TheDriver.setTitle("clang interpreter");
|
||||
@ -163,12 +201,21 @@ int main(int argc, const char **argv, char * const *envp) {
|
||||
if (!Clang.ExecuteAction(*Act))
|
||||
return 1;
|
||||
|
||||
llvm::InitializeNativeTarget();
|
||||
llvm::InitializeNativeTargetAsmPrinter();
|
||||
|
||||
int Res = 255;
|
||||
if (std::unique_ptr<llvm::Module> Module = Act->takeModule())
|
||||
Res = Execute(std::move(Module), envp);
|
||||
std::unique_ptr<llvm::Module> Module = Act->takeModule();
|
||||
|
||||
if (Module) {
|
||||
llvm::orc::SimpleJIT J;
|
||||
auto H = J.addModule(std::move(Module));
|
||||
auto Main = (int(*)(...))J.getSymbolAddress("main");
|
||||
Res = Main();
|
||||
J.removeModule(H);
|
||||
}
|
||||
|
||||
// Shutdown.
|
||||
|
||||
llvm::llvm_shutdown();
|
||||
|
||||
return Res;
|
||||
|
@ -28,19 +28,19 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief Return the timestamp for use with Clang's
|
||||
* Return the timestamp for use with Clang's
|
||||
* \c -fbuild-session-timestamp= option.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned long long clang_getBuildSessionTimestamp(void);
|
||||
|
||||
/**
|
||||
* \brief Object encapsulating information about overlaying virtual
|
||||
* Object encapsulating information about overlaying virtual
|
||||
* file/directories over the real file system.
|
||||
*/
|
||||
typedef struct CXVirtualFileOverlayImpl *CXVirtualFileOverlay;
|
||||
|
||||
/**
|
||||
* \brief Create a \c CXVirtualFileOverlay object.
|
||||
* Create a \c CXVirtualFileOverlay object.
|
||||
* Must be disposed with \c clang_VirtualFileOverlay_dispose().
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
@ -49,7 +49,7 @@ CINDEX_LINKAGE CXVirtualFileOverlay
|
||||
clang_VirtualFileOverlay_create(unsigned options);
|
||||
|
||||
/**
|
||||
* \brief Map an absolute virtual file path to an absolute real one.
|
||||
* Map an absolute virtual file path to an absolute real one.
|
||||
* The virtual path must be canonicalized (not contain "."/"..").
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
@ -59,17 +59,17 @@ clang_VirtualFileOverlay_addFileMapping(CXVirtualFileOverlay,
|
||||
const char *realPath);
|
||||
|
||||
/**
|
||||
* \brief Set the case sensitivity for the \c CXVirtualFileOverlay object.
|
||||
* Set the case sensitivity for the \c CXVirtualFileOverlay object.
|
||||
* The \c CXVirtualFileOverlay object is case-sensitive by default, this
|
||||
* option can be used to override the default.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
clang_VirtualFileOverlay_setCaseSensitivity(CXVirtualFileOverlay,
|
||||
int caseSensitive);
|
||||
int caseSensitive);
|
||||
|
||||
/**
|
||||
* \brief Write out the \c CXVirtualFileOverlay object to a char buffer.
|
||||
* Write out the \c CXVirtualFileOverlay object to a char buffer.
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
* \param out_buffer_ptr pointer to receive the buffer pointer, which should be
|
||||
@ -83,7 +83,7 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options,
|
||||
unsigned *out_buffer_size);
|
||||
|
||||
/**
|
||||
* \brief free memory allocated by libclang, such as the buffer returned by
|
||||
* free memory allocated by libclang, such as the buffer returned by
|
||||
* \c CXVirtualFileOverlay() or \c clang_ModuleMapDescriptor_writeToBuffer().
|
||||
*
|
||||
* \param buffer memory pointer to free.
|
||||
@ -91,17 +91,17 @@ clang_VirtualFileOverlay_writeToBuffer(CXVirtualFileOverlay, unsigned options,
|
||||
CINDEX_LINKAGE void clang_free(void *buffer);
|
||||
|
||||
/**
|
||||
* \brief Dispose a \c CXVirtualFileOverlay object.
|
||||
* Dispose a \c CXVirtualFileOverlay object.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_VirtualFileOverlay_dispose(CXVirtualFileOverlay);
|
||||
|
||||
/**
|
||||
* \brief Object encapsulating information about a module.map file.
|
||||
* Object encapsulating information about a module.map file.
|
||||
*/
|
||||
typedef struct CXModuleMapDescriptorImpl *CXModuleMapDescriptor;
|
||||
|
||||
/**
|
||||
* \brief Create a \c CXModuleMapDescriptor object.
|
||||
* Create a \c CXModuleMapDescriptor object.
|
||||
* Must be disposed with \c clang_ModuleMapDescriptor_dispose().
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
@ -110,7 +110,7 @@ CINDEX_LINKAGE CXModuleMapDescriptor
|
||||
clang_ModuleMapDescriptor_create(unsigned options);
|
||||
|
||||
/**
|
||||
* \brief Sets the framework module name that the module.map describes.
|
||||
* Sets the framework module name that the module.map describes.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
@ -118,7 +118,7 @@ clang_ModuleMapDescriptor_setFrameworkModuleName(CXModuleMapDescriptor,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* \brief Sets the umbrealla header name that the module.map describes.
|
||||
* Sets the umbrealla header name that the module.map describes.
|
||||
* \returns 0 for success, non-zero to indicate an error.
|
||||
*/
|
||||
CINDEX_LINKAGE enum CXErrorCode
|
||||
@ -126,7 +126,7 @@ clang_ModuleMapDescriptor_setUmbrellaHeader(CXModuleMapDescriptor,
|
||||
const char *name);
|
||||
|
||||
/**
|
||||
* \brief Write out the \c CXModuleMapDescriptor object to a char buffer.
|
||||
* Write out the \c CXModuleMapDescriptor object to a char buffer.
|
||||
*
|
||||
* \param options is reserved, always pass 0.
|
||||
* \param out_buffer_ptr pointer to receive the buffer pointer, which should be
|
||||
@ -140,7 +140,7 @@ clang_ModuleMapDescriptor_writeToBuffer(CXModuleMapDescriptor, unsigned options,
|
||||
unsigned *out_buffer_size);
|
||||
|
||||
/**
|
||||
* \brief Dispose a \c CXModuleMapDescriptor object.
|
||||
* Dispose a \c CXModuleMapDescriptor object.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_ModuleMapDescriptor_dispose(CXModuleMapDescriptor);
|
||||
|
||||
|
@ -38,7 +38,7 @@ extern "C" {
|
||||
typedef void * CXCompilationDatabase;
|
||||
|
||||
/**
|
||||
* \brief Contains the results of a search in the compilation database
|
||||
* Contains the results of a search in the compilation database
|
||||
*
|
||||
* When searching for the compile command for a file, the compilation db can
|
||||
* return several commands, as the file may have been compiled with
|
||||
@ -49,28 +49,28 @@ typedef void * CXCompilationDatabase;
|
||||
typedef void * CXCompileCommands;
|
||||
|
||||
/**
|
||||
* \brief Represents the command line invocation to compile a specific file.
|
||||
* Represents the command line invocation to compile a specific file.
|
||||
*/
|
||||
typedef void * CXCompileCommand;
|
||||
|
||||
/**
|
||||
* \brief Error codes for Compilation Database
|
||||
* Error codes for Compilation Database
|
||||
*/
|
||||
typedef enum {
|
||||
/*
|
||||
* \brief No error occurred
|
||||
* No error occurred
|
||||
*/
|
||||
CXCompilationDatabase_NoError = 0,
|
||||
|
||||
/*
|
||||
* \brief Database can not be loaded
|
||||
* Database can not be loaded
|
||||
*/
|
||||
CXCompilationDatabase_CanNotLoadDatabase = 1
|
||||
|
||||
} CXCompilationDatabase_Error;
|
||||
|
||||
/**
|
||||
* \brief Creates a compilation database from the database found in directory
|
||||
* Creates a compilation database from the database found in directory
|
||||
* buildDir. For example, CMake can output a compile_commands.json which can
|
||||
* be used to build the database.
|
||||
*
|
||||
@ -81,13 +81,13 @@ clang_CompilationDatabase_fromDirectory(const char *BuildDir,
|
||||
CXCompilationDatabase_Error *ErrorCode);
|
||||
|
||||
/**
|
||||
* \brief Free the given compilation database
|
||||
* Free the given compilation database
|
||||
*/
|
||||
CINDEX_LINKAGE void
|
||||
clang_CompilationDatabase_dispose(CXCompilationDatabase);
|
||||
|
||||
/**
|
||||
* \brief Find the compile commands used for a file. The compile commands
|
||||
* Find the compile commands used for a file. The compile commands
|
||||
* must be freed by \c clang_CompileCommands_dispose.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommands
|
||||
@ -95,24 +95,24 @@ clang_CompilationDatabase_getCompileCommands(CXCompilationDatabase,
|
||||
const char *CompleteFileName);
|
||||
|
||||
/**
|
||||
* \brief Get all the compile commands in the given compilation database.
|
||||
* Get all the compile commands in the given compilation database.
|
||||
*/
|
||||
CINDEX_LINKAGE CXCompileCommands
|
||||
clang_CompilationDatabase_getAllCompileCommands(CXCompilationDatabase);
|
||||
|
||||
/**
|
||||
* \brief Free the given CompileCommands
|
||||
* Free the given CompileCommands
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_CompileCommands_dispose(CXCompileCommands);
|
||||
|
||||
/**
|
||||
* \brief Get the number of CompileCommand we have for a file
|
||||
* Get the number of CompileCommand we have for a file
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommands_getSize(CXCompileCommands);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th CompileCommand for a file
|
||||
* Get the I'th CompileCommand for a file
|
||||
*
|
||||
* Note : 0 <= i < clang_CompileCommands_getSize(CXCompileCommands)
|
||||
*/
|
||||
@ -120,26 +120,26 @@ CINDEX_LINKAGE CXCompileCommand
|
||||
clang_CompileCommands_getCommand(CXCompileCommands, unsigned I);
|
||||
|
||||
/**
|
||||
* \brief Get the working directory where the CompileCommand was executed from
|
||||
* Get the working directory where the CompileCommand was executed from
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getDirectory(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the filename associated with the CompileCommand.
|
||||
* Get the filename associated with the CompileCommand.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getFilename(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the number of arguments in the compiler invocation.
|
||||
* Get the number of arguments in the compiler invocation.
|
||||
*
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommand_getNumArgs(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th argument value in the compiler invocations
|
||||
* Get the I'th argument value in the compiler invocations
|
||||
*
|
||||
* Invariant :
|
||||
* - argument 0 is the compiler executable
|
||||
@ -148,19 +148,19 @@ CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getArg(CXCompileCommand, unsigned I);
|
||||
|
||||
/**
|
||||
* \brief Get the number of source mappings for the compiler invocation.
|
||||
* Get the number of source mappings for the compiler invocation.
|
||||
*/
|
||||
CINDEX_LINKAGE unsigned
|
||||
clang_CompileCommand_getNumMappedSources(CXCompileCommand);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th mapped source path for the compiler invocation.
|
||||
* Get the I'th mapped source path for the compiler invocation.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getMappedSourcePath(CXCompileCommand, unsigned I);
|
||||
|
||||
/**
|
||||
* \brief Get the I'th mapped source content for the compiler invocation.
|
||||
* Get the I'th mapped source content for the compiler invocation.
|
||||
*/
|
||||
CINDEX_LINKAGE CXString
|
||||
clang_CompileCommand_getMappedSourceContent(CXCompileCommand, unsigned I);
|
||||
|
@ -21,19 +21,19 @@ extern "C" {
|
||||
#endif
|
||||
|
||||
/**
|
||||
* \brief Error codes returned by libclang routines.
|
||||
* Error codes returned by libclang routines.
|
||||
*
|
||||
* Zero (\c CXError_Success) is the only error code indicating success. Other
|
||||
* error codes, including not yet assigned non-zero values, indicate errors.
|
||||
*/
|
||||
enum CXErrorCode {
|
||||
/**
|
||||
* \brief No error.
|
||||
* No error.
|
||||
*/
|
||||
CXError_Success = 0,
|
||||
|
||||
/**
|
||||
* \brief A generic error code, no further details are available.
|
||||
* A generic error code, no further details are available.
|
||||
*
|
||||
* Errors of this kind can get their own specific error codes in future
|
||||
* libclang versions.
|
||||
@ -41,18 +41,18 @@ enum CXErrorCode {
|
||||
CXError_Failure = 1,
|
||||
|
||||
/**
|
||||
* \brief libclang crashed while performing the requested operation.
|
||||
* libclang crashed while performing the requested operation.
|
||||
*/
|
||||
CXError_Crashed = 2,
|
||||
|
||||
/**
|
||||
* \brief The function detected that the arguments violate the function
|
||||
* The function detected that the arguments violate the function
|
||||
* contract.
|
||||
*/
|
||||
CXError_InvalidArguments = 3,
|
||||
|
||||
/**
|
||||
* \brief An AST deserialization error has occurred.
|
||||
* An AST deserialization error has occurred.
|
||||
*/
|
||||
CXError_ASTReadError = 4
|
||||
};
|
||||
|
@ -28,7 +28,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief A character string.
|
||||
* A character string.
|
||||
*
|
||||
* The \c CXString type is used to return strings from the interface when
|
||||
* the ownership of that string might differ from one call to the next.
|
||||
@ -46,17 +46,17 @@ typedef struct {
|
||||
} CXStringSet;
|
||||
|
||||
/**
|
||||
* \brief Retrieve the character data associated with the given string.
|
||||
* Retrieve the character data associated with the given string.
|
||||
*/
|
||||
CINDEX_LINKAGE const char *clang_getCString(CXString string);
|
||||
|
||||
/**
|
||||
* \brief Free the given string.
|
||||
* Free the given string.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_disposeString(CXString string);
|
||||
|
||||
/**
|
||||
* \brief Free the given string set.
|
||||
* Free the given string set.
|
||||
*/
|
||||
CINDEX_LINKAGE void clang_disposeStringSet(CXStringSet *set);
|
||||
|
||||
|
@ -32,7 +32,7 @@ extern "C" {
|
||||
*/
|
||||
|
||||
/**
|
||||
* \brief A parsed comment.
|
||||
* A parsed comment.
|
||||
*/
|
||||
typedef struct {
|
||||
const void *ASTNode;
|
||||
@ -40,38 +40,38 @@ typedef struct {
|
||||
} CXComment;
|
||||
|
||||
/**
|
||||
* \brief Given a cursor that represents a documentable entity (e.g.,
|
||||
* Given a cursor that represents a documentable entity (e.g.,
|
||||
* declaration), return the associated parsed comment as a
|
||||
* \c CXComment_FullComment AST node.
|
||||
*/
|
||||
CINDEX_LINKAGE CXComment clang_Cursor_getParsedComment(CXCursor C);
|
||||
|
||||
/**
|
||||
* \brief Describes the type of the comment AST node (\c CXComment). A comment
|
||||
* Describes the type of the comment AST node (\c CXComment). A comment
|
||||
* node can be considered block content (e. g., paragraph), inline content
|
||||
* (plain text) or neither (the root AST node).
|
||||
*/
|
||||
enum CXCommentKind {
|
||||
/**
|
||||
* \brief Null comment. No AST node is constructed at the requested location
|
||||
* Null comment. No AST node is constructed at the requested location
|
||||
* because there is no text or a syntax error.
|
||||
*/
|
||||
CXComment_Null = 0,
|
||||
|
||||
/**
|
||||
* \brief Plain text. Inline content.
|
||||
* Plain text. Inline content.
|
||||
*/
|
||||
CXComment_Text = 1,
|
||||
|
||||
/**
|
||||
* \brief A command with word-like arguments that is considered inline content.
|
||||
* A command with word-like arguments that is considered inline content.
|
||||
*
|
||||
* For example: \\c command.
|
||||
*/
|
||||
CXComment_InlineCommand = 2,
|
||||
|
||||
/**
|
||||
* \brief HTML start tag with attributes (name-value pairs). Considered
|
||||
* HTML start tag with attributes (name-value pairs). Considered
|
||||
* inline content.
|
||||
*
|
||||
* For example:
|
||||
@ -82,7 +82,7 @@ enum CXCommentKind {
|
||||
CXComment_HTMLStartTag = 3,
|
||||
|
||||
/**
|
||||
* \brief HTML end tag. Considered inline content.
|
||||
* HTML end tag. Considered inline content.
|
||||
*
|
||||
* For example:
|
||||
* \verbatim
|
||||
@ -92,19 +92,19 @@ enum CXCommentKind {
|
||||
CXComment_HTMLEndTag = 4,
|
||||
|
||||
/**
|
||||
* \brief A paragraph, contains inline comment. The paragraph itself is
|
||||
* A paragraph, contains inline comment. The paragraph itself is
|
||||
* block content.
|
||||
*/
|
||||
CXComment_Paragraph = 5,
|
||||
|
||||
/**
|
||||
* \brief A command that has zero or more word-like arguments (number of
|
||||
* A command that has zero or more word-like arguments (number of
|
||||
* word-like arguments depends on command name) and a paragraph as an
|
||||
* argument. Block command is block content.
|
||||
*
|
||||
* Paragraph argument is also a child of the block command.
|
||||
*
|
||||
* For example: \\brief has 0 word-like arguments and a paragraph argument.
|
||||
* For example: \has 0 word-like arguments and a paragraph argument.
|
||||
*
|
||||
* AST nodes of special kinds that parser knows about (e. g., \\param
|
||||
* command) have their own node kinds.
|
||||
@ -112,7 +112,7 @@ enum CXCommentKind {
|
||||
CXComment_BlockCommand = 6,
|
||||
|
||||
/**
|
||||
* \brief A \\param or \\arg command that describes the function parameter
|
||||
* A \\param or \\arg command that describes the function parameter
|
||||
* (name, passing direction, description).
|
||||
*
|
||||
* For example: \\param [in] ParamName description.
|
||||
@ -120,7 +120,7 @@ enum CXCommentKind {
|
||||
CXComment_ParamCommand = 7,
|
||||
|
||||
/**
|
||||
* \brief A \\tparam command that describes a template parameter (name and
|
||||
* A \\tparam command that describes a template parameter (name and
|
||||
* description).
|
||||
*
|
||||
* For example: \\tparam T description.
|
||||
@ -128,7 +128,7 @@ enum CXCommentKind {
|
||||
CXComment_TParamCommand = 8,
|
||||
|
||||
/**
|
||||
* \brief A verbatim block command (e. g., preformatted code). Verbatim
|
||||
* A verbatim block command (e. g., preformatted code). Verbatim
|
||||
* block has an opening and a closing command and contains multiple lines of
|
||||
* text (\c CXComment_VerbatimBlockLine child nodes).
|
||||
*
|
||||
@ -140,67 +140,67 @@ enum CXCommentKind {
|
||||
CXComment_VerbatimBlockCommand = 9,
|
||||
|
||||
/**
|
||||
* \brief A line of text that is contained within a
|
||||
* A line of text that is contained within a
|
||||
* CXComment_VerbatimBlockCommand node.
|
||||
*/
|
||||
CXComment_VerbatimBlockLine = 10,
|
||||
|
||||
/**
|
||||
* \brief A verbatim line command. Verbatim line has an opening command,
|
||||
* A verbatim line command. Verbatim line has an opening command,
|
||||
* a single line of text (up to the newline after the opening command) and
|
||||
* has no closing command.
|
||||
*/
|
||||
CXComment_VerbatimLine = 11,
|
||||
|
||||
/**
|
||||
* \brief A full comment attached to a declaration, contains block content.
|
||||
* A full comment attached to a declaration, contains block content.
|
||||
*/
|
||||
CXComment_FullComment = 12
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief The most appropriate rendering mode for an inline command, chosen on
|
||||
* The most appropriate rendering mode for an inline command, chosen on
|
||||
* command semantics in Doxygen.
|
||||
*/
|
||||
enum CXCommentInlineCommandRenderKind {
|
||||
/**
|
||||
* \brief Command argument should be rendered in a normal font.
|
||||
* Command argument should be rendered in a normal font.
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Normal,
|
||||
|
||||
/**
|
||||
* \brief Command argument should be rendered in a bold font.
|
||||
* Command argument should be rendered in a bold font.
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Bold,
|
||||
|
||||
/**
|
||||
* \brief Command argument should be rendered in a monospaced font.
|
||||
* Command argument should be rendered in a monospaced font.
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Monospaced,
|
||||
|
||||
/**
|
||||
* \brief Command argument should be rendered emphasized (typically italic
|
||||
* Command argument should be rendered emphasized (typically italic
|
||||
* font).
|
||||
*/
|
||||
CXCommentInlineCommandRenderKind_Emphasized
|
||||
};
|
||||
|
||||
/**
|
||||
* \brief Describes parameter passing direction for \\param or \\arg command.
|
||||
* Describes parameter passing direction for \\param or \\arg command.
|
||||
*/
|
||||
enum CXCommentParamPassDirection {
|
||||
/**
|
||||
* \brief The parameter is an input parameter.
|
||||
* The parameter is an input parameter.
|
||||
*/
|
||||
CXCommentParamPassDirection_In,
|
||||
|
||||
/**
|
||||
* \brief The parameter is an output parameter.
|
||||
* The parameter is an output parameter.
|
||||
*/
|
||||
CXCommentParamPassDirection_Out,
|
||||
|
||||
/**
|
||||
* \brief The parameter is an input and output parameter.
|
||||
* The parameter is an input and output parameter.
|
||||
*/
|
||||
CXCommentParamPassDirection_InOut
|
||||
};
|
||||
@ -230,7 +230,7 @@ CINDEX_LINKAGE
|
||||
CXComment clang_Comment_getChild(CXComment Comment, unsigned ChildIdx);
|
||||
|
||||
/**
|
||||
* \brief A \c CXComment_Paragraph node is considered whitespace if it contains
|
||||
* A \c CXComment_Paragraph node is considered whitespace if it contains
|
||||
* only \c CXComment_Text nodes that are empty or whitespace.
|
||||
*
|
||||
* Other AST nodes (except \c CXComment_Paragraph and \c CXComment_Text) are
|
||||
@ -487,7 +487,7 @@ CXString clang_VerbatimBlockLineComment_getText(CXComment Comment);
|
||||
CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \brief Convert an HTML tag AST node to string.
|
||||
* Convert an HTML tag AST node to string.
|
||||
*
|
||||
* \param Comment a \c CXComment_HTMLStartTag or \c CXComment_HTMLEndTag AST
|
||||
* node.
|
||||
@ -497,13 +497,13 @@ CINDEX_LINKAGE CXString clang_VerbatimLineComment_getText(CXComment Comment);
|
||||
CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \brief Convert a given full parsed comment to an HTML fragment.
|
||||
* Convert a given full parsed comment to an HTML fragment.
|
||||
*
|
||||
* Specific details of HTML layout are subject to change. Don't try to parse
|
||||
* this HTML back into an AST, use other APIs instead.
|
||||
*
|
||||
* Currently the following CSS classes are used:
|
||||
* \li "para-brief" for \\brief paragraph and equivalent commands;
|
||||
* \li "para-brief" for \paragraph and equivalent commands;
|
||||
* \li "para-returns" for \\returns paragraph and equivalent commands;
|
||||
* \li "word-returns" for the "Returns" word in \\returns paragraph.
|
||||
*
|
||||
@ -530,7 +530,7 @@ CINDEX_LINKAGE CXString clang_HTMLTagComment_getAsString(CXComment Comment);
|
||||
CINDEX_LINKAGE CXString clang_FullComment_getAsHTML(CXComment Comment);
|
||||
|
||||
/**
|
||||
* \brief Convert a given full parsed comment to an XML document.
|
||||
* Convert a given full parsed comment to an XML document.
|
||||
*
|
||||
* A Relax NG schema for the XML can be found in comment-xml-schema.rng file
|
||||
* inside clang source tree.
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -22,7 +22,7 @@ namespace clang {
|
||||
namespace arcmt {
|
||||
class MigrationPass;
|
||||
|
||||
/// \brief Creates an AST with the provided CompilerInvocation but with these
|
||||
/// Creates an AST with the provided CompilerInvocation but with these
|
||||
/// changes:
|
||||
/// -if a PCH/PTH is set, the original header is used instead
|
||||
/// -Automatic Reference Counting mode is enabled
|
||||
@ -45,7 +45,7 @@ checkForManualIssues(CompilerInvocation &CI, const FrontendInputFile &Input,
|
||||
bool emitPremigrationARCErrors = false,
|
||||
StringRef plistOut = StringRef());
|
||||
|
||||
/// \brief Works similar to checkForManualIssues but instead of checking, it
|
||||
/// Works similar to checkForManualIssues but instead of checking, it
|
||||
/// applies automatic modifications to source files to conform to ARC.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
@ -55,7 +55,7 @@ applyTransformations(CompilerInvocation &origCI,
|
||||
std::shared_ptr<PCHContainerOperations> PCHContainerOps,
|
||||
DiagnosticConsumer *DiagClient);
|
||||
|
||||
/// \brief Applies automatic modifications and produces temporary files
|
||||
/// Applies automatic modifications and produces temporary files
|
||||
/// and metadata into the \p outputDir path.
|
||||
///
|
||||
/// \param emitPremigrationARCErrors if true all ARC errors will get emitted
|
||||
@ -72,7 +72,7 @@ bool migrateWithTemporaryFiles(
|
||||
DiagnosticConsumer *DiagClient, StringRef outputDir,
|
||||
bool emitPremigrationARCErrors, StringRef plistOut);
|
||||
|
||||
/// \brief Get the set of file remappings from the \p outputDir path that
|
||||
/// Get the set of file remappings from the \p outputDir path that
|
||||
/// migrateWithTemporaryFiles produced.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
@ -80,7 +80,7 @@ bool getFileRemappings(std::vector<std::pair<std::string,std::string> > &remap,
|
||||
StringRef outputDir,
|
||||
DiagnosticConsumer *DiagClient);
|
||||
|
||||
/// \brief Get the set of file remappings from a list of files with remapping
|
||||
/// Get the set of file remappings from a list of files with remapping
|
||||
/// info.
|
||||
///
|
||||
/// \returns false if no error is produced, true otherwise.
|
||||
|
@ -55,7 +55,7 @@ class MigrateAction : public WrapperFrontendAction {
|
||||
bool emitPremigrationARCErrors);
|
||||
};
|
||||
|
||||
/// \brief Migrates to modern ObjC syntax.
|
||||
/// Migrates to modern ObjC syntax.
|
||||
class ObjCMigrateAction : public WrapperFrontendAction {
|
||||
std::string MigrateDir;
|
||||
unsigned ObjCMigAction;
|
||||
|
@ -53,7 +53,58 @@ class APValue {
|
||||
MemberPointer,
|
||||
AddrLabelDiff
|
||||
};
|
||||
typedef llvm::PointerUnion<const ValueDecl *, const Expr *> LValueBase;
|
||||
|
||||
class LValueBase {
|
||||
public:
|
||||
typedef llvm::PointerUnion<const ValueDecl *, const Expr *> PtrTy;
|
||||
|
||||
LValueBase() : CallIndex(0), Version(0) {}
|
||||
|
||||
template <class T>
|
||||
LValueBase(T P, unsigned I = 0, unsigned V = 0)
|
||||
: Ptr(P), CallIndex(I), Version(V) {}
|
||||
|
||||
template <class T>
|
||||
bool is() const { return Ptr.is<T>(); }
|
||||
|
||||
template <class T>
|
||||
T get() const { return Ptr.get<T>(); }
|
||||
|
||||
template <class T>
|
||||
T dyn_cast() const { return Ptr.dyn_cast<T>(); }
|
||||
|
||||
void *getOpaqueValue() const;
|
||||
|
||||
bool isNull() const;
|
||||
|
||||
explicit operator bool () const;
|
||||
|
||||
PtrTy getPointer() const {
|
||||
return Ptr;
|
||||
}
|
||||
|
||||
unsigned getCallIndex() const {
|
||||
return CallIndex;
|
||||
}
|
||||
|
||||
void setCallIndex(unsigned Index) {
|
||||
CallIndex = Index;
|
||||
}
|
||||
|
||||
unsigned getVersion() const {
|
||||
return Version;
|
||||
}
|
||||
|
||||
bool operator==(const LValueBase &Other) const {
|
||||
return Ptr == Other.Ptr && CallIndex == Other.CallIndex &&
|
||||
Version == Other.Version;
|
||||
}
|
||||
|
||||
private:
|
||||
PtrTy Ptr;
|
||||
unsigned CallIndex, Version;
|
||||
};
|
||||
|
||||
typedef llvm::PointerIntPair<const Decl *, 1, bool> BaseOrMemberType;
|
||||
union LValuePathEntry {
|
||||
/// BaseOrMember - The FieldDecl or CXXRecordDecl indicating the next item
|
||||
@ -135,15 +186,15 @@ class APValue {
|
||||
}
|
||||
APValue(const APValue &RHS);
|
||||
APValue(APValue &&RHS) : Kind(Uninitialized) { swap(RHS); }
|
||||
APValue(LValueBase B, const CharUnits &O, NoLValuePath N, unsigned CallIndex,
|
||||
APValue(LValueBase B, const CharUnits &O, NoLValuePath N,
|
||||
bool IsNullPtr = false)
|
||||
: Kind(Uninitialized) {
|
||||
MakeLValue(); setLValue(B, O, N, CallIndex, IsNullPtr);
|
||||
MakeLValue(); setLValue(B, O, N, IsNullPtr);
|
||||
}
|
||||
APValue(LValueBase B, const CharUnits &O, ArrayRef<LValuePathEntry> Path,
|
||||
bool OnePastTheEnd, unsigned CallIndex, bool IsNullPtr = false)
|
||||
bool OnePastTheEnd, bool IsNullPtr = false)
|
||||
: Kind(Uninitialized) {
|
||||
MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, CallIndex, IsNullPtr);
|
||||
MakeLValue(); setLValue(B, O, Path, OnePastTheEnd, IsNullPtr);
|
||||
}
|
||||
APValue(UninitArray, unsigned InitElts, unsigned Size) : Kind(Uninitialized) {
|
||||
MakeArray(InitElts, Size);
|
||||
@ -168,14 +219,14 @@ class APValue {
|
||||
MakeUninit();
|
||||
}
|
||||
|
||||
/// \brief Returns whether the object performed allocations.
|
||||
/// Returns whether the object performed allocations.
|
||||
///
|
||||
/// If APValues are constructed via placement new, \c needsCleanup()
|
||||
/// indicates whether the destructor must be called in order to correctly
|
||||
/// free all allocated memory.
|
||||
bool needsCleanup() const;
|
||||
|
||||
/// \brief Swaps the contents of this and the given APValue.
|
||||
/// Swaps the contents of this and the given APValue.
|
||||
void swap(APValue &RHS);
|
||||
|
||||
ValueKind getKind() const { return Kind; }
|
||||
@ -255,6 +306,7 @@ class APValue {
|
||||
bool hasLValuePath() const;
|
||||
ArrayRef<LValuePathEntry> getLValuePath() const;
|
||||
unsigned getLValueCallIndex() const;
|
||||
unsigned getLValueVersion() const;
|
||||
bool isNullPointer() const;
|
||||
|
||||
APValue &getVectorElt(unsigned I) {
|
||||
@ -376,10 +428,10 @@ class APValue {
|
||||
((ComplexAPFloat *)(char *)Data.buffer)->Imag = std::move(I);
|
||||
}
|
||||
void setLValue(LValueBase B, const CharUnits &O, NoLValuePath,
|
||||
unsigned CallIndex, bool IsNullPtr);
|
||||
bool IsNullPtr);
|
||||
void setLValue(LValueBase B, const CharUnits &O,
|
||||
ArrayRef<LValuePathEntry> Path, bool OnePastTheEnd,
|
||||
unsigned CallIndex, bool IsNullPtr);
|
||||
bool IsNullPtr);
|
||||
void setUnion(const FieldDecl *Field, const APValue &Value) {
|
||||
assert(isUnion() && "Invalid accessor");
|
||||
((UnionData*)(char*)Data.buffer)->Field = Field;
|
||||
@ -451,4 +503,14 @@ class APValue {
|
||||
|
||||
} // end namespace clang.
|
||||
|
||||
namespace llvm {
|
||||
template<> struct DenseMapInfo<clang::APValue::LValueBase> {
|
||||
static clang::APValue::LValueBase getEmptyKey();
|
||||
static clang::APValue::LValueBase getTombstoneKey();
|
||||
static unsigned getHashValue(const clang::APValue::LValueBase &Base);
|
||||
static bool isEqual(const clang::APValue::LValueBase &LHS,
|
||||
const clang::APValue::LValueBase &RHS);
|
||||
};
|
||||
}
|
||||
|
||||
#endif
|
||||
|
@ -32,7 +32,7 @@ namespace clang {
|
||||
/// clients that read ASTs. This abstraction layer allows the client to be
|
||||
/// independent of the AST producer (e.g. parser vs AST dump file reader, etc).
|
||||
class ASTConsumer {
|
||||
/// \brief Whether this AST consumer also requires information about
|
||||
/// Whether this AST consumer also requires information about
|
||||
/// semantic analysis.
|
||||
bool SemaConsumer;
|
||||
|
||||
@ -53,7 +53,7 @@ class ASTConsumer {
|
||||
/// \returns true to continue parsing, or false to abort parsing.
|
||||
virtual bool HandleTopLevelDecl(DeclGroupRef D);
|
||||
|
||||
/// \brief This callback is invoked each time an inline (method or friend)
|
||||
/// This callback is invoked each time an inline (method or friend)
|
||||
/// function definition in a class is completed.
|
||||
virtual void HandleInlineFunctionDefinition(FunctionDecl *D) {}
|
||||
|
||||
@ -72,22 +72,22 @@ class ASTConsumer {
|
||||
/// can be defined in declspecs).
|
||||
virtual void HandleTagDeclDefinition(TagDecl *D) {}
|
||||
|
||||
/// \brief This callback is invoked the first time each TagDecl is required to
|
||||
/// This callback is invoked the first time each TagDecl is required to
|
||||
/// be complete.
|
||||
virtual void HandleTagDeclRequiredDefinition(const TagDecl *D) {}
|
||||
|
||||
/// \brief Invoked when a function is implicitly instantiated.
|
||||
/// Invoked when a function is implicitly instantiated.
|
||||
/// Note that at this point point it does not have a body, its body is
|
||||
/// instantiated at the end of the translation unit and passed to
|
||||
/// HandleTopLevelDecl.
|
||||
virtual void HandleCXXImplicitFunctionInstantiation(FunctionDecl *D) {}
|
||||
|
||||
/// \brief Handle the specified top-level declaration that occurred inside
|
||||
/// Handle the specified top-level declaration that occurred inside
|
||||
/// and ObjC container.
|
||||
/// The default implementation ignored them.
|
||||
virtual void HandleTopLevelDeclInObjCContainer(DeclGroupRef D);
|
||||
|
||||
/// \brief Handle an ImportDecl that was implicitly created due to an
|
||||
/// Handle an ImportDecl that was implicitly created due to an
|
||||
/// inclusion directive.
|
||||
/// The default implementation passes it to HandleTopLevelDecl.
|
||||
virtual void HandleImplicitImportDecl(ImportDecl *D);
|
||||
@ -103,7 +103,7 @@ class ASTConsumer {
|
||||
/// modified by the introduction of an implicit zero initializer.
|
||||
virtual void CompleteTentativeDefinition(VarDecl *D) {}
|
||||
|
||||
/// \brief Callback invoked when an MSInheritanceAttr has been attached to a
|
||||
/// Callback invoked when an MSInheritanceAttr has been attached to a
|
||||
/// CXXRecordDecl.
|
||||
virtual void AssignInheritanceModel(CXXRecordDecl *RD) {}
|
||||
|
||||
@ -111,19 +111,19 @@ class ASTConsumer {
|
||||
// variable has been instantiated.
|
||||
virtual void HandleCXXStaticMemberVarInstantiation(VarDecl *D) {}
|
||||
|
||||
/// \brief Callback involved at the end of a translation unit to
|
||||
/// Callback involved at the end of a translation unit to
|
||||
/// notify the consumer that a vtable for the given C++ class is
|
||||
/// required.
|
||||
///
|
||||
/// \param RD The class whose vtable was used.
|
||||
virtual void HandleVTable(CXXRecordDecl *RD) {}
|
||||
|
||||
/// \brief If the consumer is interested in entities getting modified after
|
||||
/// If the consumer is interested in entities getting modified after
|
||||
/// their initial creation, it should return a pointer to
|
||||
/// an ASTMutationListener here.
|
||||
virtual ASTMutationListener *GetASTMutationListener() { return nullptr; }
|
||||
|
||||
/// \brief If the consumer is interested in entities being deserialized from
|
||||
/// If the consumer is interested in entities being deserialized from
|
||||
/// AST files, it should return a pointer to a ASTDeserializationListener here
|
||||
virtual ASTDeserializationListener *GetASTDeserializationListener() {
|
||||
return nullptr;
|
||||
@ -132,7 +132,7 @@ class ASTConsumer {
|
||||
/// PrintStats - If desired, print any statistics.
|
||||
virtual void PrintStats() {}
|
||||
|
||||
/// \brief This callback is called for each function if the Parser was
|
||||
/// This callback is called for each function if the Parser was
|
||||
/// initialized with \c SkipFunctionBodies set to \c true.
|
||||
///
|
||||
/// \return \c true if the function's body should be skipped. The function
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -24,7 +24,7 @@ namespace clang {
|
||||
};
|
||||
} // end namespace diag
|
||||
|
||||
/// \brief DiagnosticsEngine argument formatting function for diagnostics that
|
||||
/// DiagnosticsEngine argument formatting function for diagnostics that
|
||||
/// involve AST nodes.
|
||||
///
|
||||
/// This function formats diagnostic arguments for various AST nodes,
|
||||
|
@ -8,7 +8,7 @@
|
||||
//===--------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief Forward declaration of all AST node types.
|
||||
/// Forward declaration of all AST node types.
|
||||
///
|
||||
//===-------------------------------------------------------------===//
|
||||
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- ASTImporter.h - Importing ASTs from other Contexts -----*- C++ -*-===//
|
||||
//===- ASTImporter.h - Importing ASTs from other Contexts -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -11,82 +11,95 @@
|
||||
// context into another context.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_ASTIMPORTER_H
|
||||
#define LLVM_CLANG_AST_ASTIMPORTER_H
|
||||
|
||||
#include "clang/AST/DeclarationName.h"
|
||||
#include "clang/AST/NestedNameSpecifier.h"
|
||||
#include "clang/AST/TemplateName.h"
|
||||
#include "clang/AST/Type.h"
|
||||
#include "clang/Basic/Diagnostic.h"
|
||||
#include "clang/Basic/IdentifierTable.h"
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "clang/Basic/SourceLocation.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/SmallVector.h"
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
class ASTContext;
|
||||
class CXXCtorInitializer;
|
||||
class CXXBaseSpecifier;
|
||||
class Decl;
|
||||
class DeclContext;
|
||||
class DiagnosticsEngine;
|
||||
class Expr;
|
||||
class FileManager;
|
||||
class IdentifierInfo;
|
||||
class NestedNameSpecifier;
|
||||
class Stmt;
|
||||
class TypeSourceInfo;
|
||||
|
||||
/// \brief Imports selected nodes from one AST context into another context,
|
||||
|
||||
class ASTContext;
|
||||
class CXXBaseSpecifier;
|
||||
class CXXCtorInitializer;
|
||||
class Decl;
|
||||
class DeclContext;
|
||||
class Expr;
|
||||
class FileManager;
|
||||
class NamedDecl;
|
||||
class Stmt;
|
||||
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<Decl*, 2> getCanonicalForwardRedeclChain(Decl* D);
|
||||
|
||||
/// Imports selected nodes from one AST context into another context,
|
||||
/// merging AST nodes where appropriate.
|
||||
class ASTImporter {
|
||||
public:
|
||||
typedef llvm::DenseSet<std::pair<Decl *, Decl *> > NonEquivalentDeclSet;
|
||||
typedef llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>
|
||||
ImportedCXXBaseSpecifierMap;
|
||||
using NonEquivalentDeclSet = llvm::DenseSet<std::pair<Decl *, Decl *>>;
|
||||
using ImportedCXXBaseSpecifierMap =
|
||||
llvm::DenseMap<const CXXBaseSpecifier *, CXXBaseSpecifier *>;
|
||||
|
||||
private:
|
||||
/// \brief The contexts we're importing to and from.
|
||||
/// The contexts we're importing to and from.
|
||||
ASTContext &ToContext, &FromContext;
|
||||
|
||||
/// \brief The file managers we're importing to and from.
|
||||
/// The file managers we're importing to and from.
|
||||
FileManager &ToFileManager, &FromFileManager;
|
||||
|
||||
/// \brief Whether to perform a minimal import.
|
||||
/// Whether to perform a minimal import.
|
||||
bool Minimal;
|
||||
|
||||
/// \brief Whether the last diagnostic came from the "from" context.
|
||||
bool LastDiagFromFrom;
|
||||
/// Whether the last diagnostic came from the "from" context.
|
||||
bool LastDiagFromFrom = false;
|
||||
|
||||
/// \brief Mapping from the already-imported types in the "from" context
|
||||
/// Mapping from the already-imported types in the "from" context
|
||||
/// to the corresponding types in the "to" context.
|
||||
llvm::DenseMap<const Type *, const Type *> ImportedTypes;
|
||||
|
||||
/// \brief Mapping from the already-imported declarations in the "from"
|
||||
/// Mapping from the already-imported declarations in the "from"
|
||||
/// context to the corresponding declarations in the "to" context.
|
||||
llvm::DenseMap<Decl *, Decl *> ImportedDecls;
|
||||
|
||||
/// \brief Mapping from the already-imported statements in the "from"
|
||||
/// Mapping from the already-imported statements in the "from"
|
||||
/// context to the corresponding statements in the "to" context.
|
||||
llvm::DenseMap<Stmt *, Stmt *> ImportedStmts;
|
||||
|
||||
/// \brief Mapping from the already-imported FileIDs in the "from" source
|
||||
/// Mapping from the already-imported FileIDs in the "from" source
|
||||
/// manager to the corresponding FileIDs in the "to" source manager.
|
||||
llvm::DenseMap<FileID, FileID> ImportedFileIDs;
|
||||
|
||||
/// \brief Mapping from the already-imported CXXBasesSpecifier in
|
||||
/// Mapping from the already-imported CXXBasesSpecifier in
|
||||
/// the "from" source manager to the corresponding CXXBasesSpecifier
|
||||
/// in the "to" source manager.
|
||||
ImportedCXXBaseSpecifierMap ImportedCXXBaseSpecifiers;
|
||||
|
||||
/// \brief Imported, anonymous tag declarations that are missing their
|
||||
/// corresponding typedefs.
|
||||
SmallVector<TagDecl *, 4> AnonTagsWithPendingTypedefs;
|
||||
|
||||
/// \brief Declaration (from, to) pairs that are known not to be equivalent
|
||||
/// Declaration (from, to) pairs that are known not to be equivalent
|
||||
/// (which we have already complained about).
|
||||
NonEquivalentDeclSet NonEquivalentDecls;
|
||||
|
||||
public:
|
||||
/// \brief Create a new AST importer.
|
||||
/// Create a new AST importer.
|
||||
///
|
||||
/// \param ToContext The context we'll be importing into.
|
||||
///
|
||||
@ -105,135 +118,144 @@ namespace clang {
|
||||
|
||||
virtual ~ASTImporter();
|
||||
|
||||
/// \brief Whether the importer will perform a minimal import, creating
|
||||
/// Whether the importer will perform a minimal import, creating
|
||||
/// to-be-completed forward declarations when possible.
|
||||
bool isMinimalImport() const { return Minimal; }
|
||||
|
||||
/// \brief Import the given type from the "from" context into the "to"
|
||||
/// Import the given type from the "from" context into the "to"
|
||||
/// context.
|
||||
///
|
||||
/// \returns the equivalent type in the "to" context, or a NULL type if
|
||||
/// an error occurred.
|
||||
QualType Import(QualType FromT);
|
||||
|
||||
/// \brief Import the given type source information from the
|
||||
/// Import the given type source information from the
|
||||
/// "from" context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent type source information in the "to"
|
||||
/// context, or NULL if an error occurred.
|
||||
TypeSourceInfo *Import(TypeSourceInfo *FromTSI);
|
||||
|
||||
/// \brief Import the given declaration from the "from" context into the
|
||||
/// Import the given attribute from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent attribute in the "to" context.
|
||||
Attr *Import(const Attr *FromAttr);
|
||||
|
||||
/// Import the given declaration from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \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) {
|
||||
return Import(const_cast<Decl *>(FromD));
|
||||
}
|
||||
|
||||
/// \brief Return the copy of the given declaration in the "to" context if
|
||||
/// Return the copy of the given declaration in the "to" context if
|
||||
/// it has already been imported from the "from" context. Otherwise return
|
||||
/// NULL.
|
||||
Decl *GetAlreadyImportedOrNull(Decl *FromD);
|
||||
|
||||
/// \brief Import the given declaration context from the "from"
|
||||
/// Import the given declaration context from the "from"
|
||||
/// AST context into the "to" AST context.
|
||||
///
|
||||
/// \returns the equivalent declaration context in the "to"
|
||||
/// context, or a NULL type if an error occurred.
|
||||
DeclContext *ImportContext(DeclContext *FromDC);
|
||||
|
||||
/// \brief Import the given expression from the "from" context into the
|
||||
/// Import the given expression from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent expression in the "to" context, or NULL if
|
||||
/// an error occurred.
|
||||
Expr *Import(Expr *FromE);
|
||||
|
||||
/// \brief Import the given statement from the "from" context into the
|
||||
/// Import the given statement from the "from" context into the
|
||||
/// "to" context.
|
||||
///
|
||||
/// \returns the equivalent statement in the "to" context, or NULL if
|
||||
/// an error occurred.
|
||||
Stmt *Import(Stmt *FromS);
|
||||
|
||||
/// \brief Import the given nested-name-specifier from the "from"
|
||||
/// Import the given nested-name-specifier from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent nested-name-specifier in the "to"
|
||||
/// context, or NULL if an error occurred.
|
||||
NestedNameSpecifier *Import(NestedNameSpecifier *FromNNS);
|
||||
|
||||
/// \brief Import the given nested-name-specifier from the "from"
|
||||
/// Import the given nested-name-specifier from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent nested-name-specifier in the "to"
|
||||
/// context.
|
||||
NestedNameSpecifierLoc Import(NestedNameSpecifierLoc FromNNS);
|
||||
|
||||
/// \brief Import the goven template name from the "from" context into the
|
||||
/// Import the goven template name from the "from" context into the
|
||||
/// "to" context.
|
||||
TemplateName Import(TemplateName From);
|
||||
|
||||
/// \brief Import the given source location from the "from" context into
|
||||
/// Import the given source location from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent source location in the "to" context, or an
|
||||
/// invalid source location if an error occurred.
|
||||
SourceLocation Import(SourceLocation FromLoc);
|
||||
|
||||
/// \brief Import the given source range from the "from" context into
|
||||
/// Import the given source range from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent source range in the "to" context, or an
|
||||
/// invalid source location if an error occurred.
|
||||
SourceRange Import(SourceRange FromRange);
|
||||
|
||||
/// \brief Import the given declaration name from the "from"
|
||||
/// Import the given declaration name from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent declaration name in the "to" context,
|
||||
/// or an empty declaration name if an error occurred.
|
||||
DeclarationName Import(DeclarationName FromName);
|
||||
|
||||
/// \brief Import the given identifier from the "from" context
|
||||
/// Import the given identifier from the "from" context
|
||||
/// into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent identifier in the "to" context.
|
||||
IdentifierInfo *Import(const IdentifierInfo *FromId);
|
||||
|
||||
/// \brief Import the given Objective-C selector from the "from"
|
||||
/// Import the given Objective-C selector from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent selector in the "to" context.
|
||||
Selector Import(Selector FromSel);
|
||||
|
||||
/// \brief 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"
|
||||
/// context.
|
||||
FileID Import(FileID);
|
||||
|
||||
/// \brief Import the given C++ constructor initializer from the "from"
|
||||
/// Import the given C++ constructor initializer from the "from"
|
||||
/// context into the "to" context.
|
||||
///
|
||||
/// \returns the equivalent initializer in the "to" context.
|
||||
CXXCtorInitializer *Import(CXXCtorInitializer *FromInit);
|
||||
|
||||
/// \brief Import the given CXXBaseSpecifier from the "from" context into
|
||||
/// Import the given CXXBaseSpecifier from the "from" context into
|
||||
/// the "to" context.
|
||||
///
|
||||
/// \returns the equivalent CXXBaseSpecifier in the source manager of the
|
||||
/// "to" context.
|
||||
CXXBaseSpecifier *Import(const CXXBaseSpecifier *FromSpec);
|
||||
|
||||
/// \brief Import the definition of the given declaration, including all of
|
||||
/// Import the definition of the given declaration, including all of
|
||||
/// the declarations it contains.
|
||||
///
|
||||
/// This routine is intended to be used
|
||||
void ImportDefinition(Decl *From);
|
||||
|
||||
/// \brief Cope with a name conflict when importing a declaration into the
|
||||
/// Cope with a name conflict when importing a declaration into the
|
||||
/// given context.
|
||||
///
|
||||
/// This routine is invoked whenever there is a name conflict while
|
||||
@ -265,41 +287,41 @@ namespace clang {
|
||||
NamedDecl **Decls,
|
||||
unsigned NumDecls);
|
||||
|
||||
/// \brief Retrieve the context that AST nodes are being imported into.
|
||||
/// Retrieve the context that AST nodes are being imported into.
|
||||
ASTContext &getToContext() const { return ToContext; }
|
||||
|
||||
/// \brief Retrieve the context that AST nodes are being imported from.
|
||||
/// Retrieve the context that AST nodes are being imported from.
|
||||
ASTContext &getFromContext() const { return FromContext; }
|
||||
|
||||
/// \brief Retrieve the file manager that AST nodes are being imported into.
|
||||
/// Retrieve the file manager that AST nodes are being imported into.
|
||||
FileManager &getToFileManager() const { return ToFileManager; }
|
||||
|
||||
/// \brief Retrieve the file manager that AST nodes are being imported from.
|
||||
/// Retrieve the file manager that AST nodes are being imported from.
|
||||
FileManager &getFromFileManager() const { return FromFileManager; }
|
||||
|
||||
/// \brief Report a diagnostic in the "to" context.
|
||||
/// Report a diagnostic in the "to" context.
|
||||
DiagnosticBuilder ToDiag(SourceLocation Loc, unsigned DiagID);
|
||||
|
||||
/// \brief Report a diagnostic in the "from" context.
|
||||
/// Report a diagnostic in the "from" context.
|
||||
DiagnosticBuilder FromDiag(SourceLocation Loc, unsigned DiagID);
|
||||
|
||||
/// \brief Return the set of declarations that we know are not equivalent.
|
||||
/// Return the set of declarations that we know are not equivalent.
|
||||
NonEquivalentDeclSet &getNonEquivalentDecls() { return NonEquivalentDecls; }
|
||||
|
||||
/// \brief Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
|
||||
/// Called for ObjCInterfaceDecl, ObjCProtocolDecl, and TagDecl.
|
||||
/// Mark the Decl as complete, filling it in as much as possible.
|
||||
///
|
||||
/// \param D A declaration in the "to" context.
|
||||
virtual void CompleteDecl(Decl* D);
|
||||
|
||||
/// \brief 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);
|
||||
|
||||
/// \brief Called by StructuralEquivalenceContext. If a RecordDecl is
|
||||
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
|
||||
/// happens especially for anonymous structs. If the original of the second
|
||||
@ -307,11 +329,12 @@ namespace clang {
|
||||
/// importation, eliminating this loop.
|
||||
virtual Decl *GetOriginalDecl(Decl *To) { return nullptr; }
|
||||
|
||||
/// \brief Determine whether the given types are structurally
|
||||
/// Determine whether the given types are structurally
|
||||
/// equivalent.
|
||||
bool IsStructurallyEquivalent(QualType From, QualType To,
|
||||
bool Complain = true);
|
||||
};
|
||||
}
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_ASTIMPORTER_H
|
||||
|
@ -8,7 +8,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file provides some common utility functions for processing
|
||||
/// This file provides some common utility functions for processing
|
||||
/// Lambda related AST Constructs.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
@ -41,86 +41,86 @@ namespace clang {
|
||||
class VarTemplateDecl;
|
||||
class VarTemplateSpecializationDecl;
|
||||
|
||||
/// \brief An abstract interface that should be implemented by listeners
|
||||
/// An abstract interface that should be implemented by listeners
|
||||
/// that want to be notified when an AST entity gets modified after its
|
||||
/// initial creation.
|
||||
class ASTMutationListener {
|
||||
public:
|
||||
virtual ~ASTMutationListener();
|
||||
|
||||
/// \brief A new TagDecl definition was completed.
|
||||
/// A new TagDecl definition was completed.
|
||||
virtual void CompletedTagDefinition(const TagDecl *D) { }
|
||||
|
||||
/// \brief A new declaration with name has been added to a DeclContext.
|
||||
/// A new declaration with name has been added to a DeclContext.
|
||||
virtual void AddedVisibleDecl(const DeclContext *DC, const Decl *D) {}
|
||||
|
||||
/// \brief An implicit member was added after the definition was completed.
|
||||
/// An implicit member was added after the definition was completed.
|
||||
virtual void AddedCXXImplicitMember(const CXXRecordDecl *RD, const Decl *D) {}
|
||||
|
||||
/// \brief A template specialization (or partial one) was added to the
|
||||
/// A template specialization (or partial one) was added to the
|
||||
/// template declaration.
|
||||
virtual void AddedCXXTemplateSpecialization(const ClassTemplateDecl *TD,
|
||||
const ClassTemplateSpecializationDecl *D) {}
|
||||
|
||||
/// \brief A template specialization (or partial one) was added to the
|
||||
/// A template specialization (or partial one) was added to the
|
||||
/// template declaration.
|
||||
virtual void
|
||||
AddedCXXTemplateSpecialization(const VarTemplateDecl *TD,
|
||||
const VarTemplateSpecializationDecl *D) {}
|
||||
|
||||
/// \brief A template specialization (or partial one) was added to the
|
||||
/// A template specialization (or partial one) was added to the
|
||||
/// template declaration.
|
||||
virtual void AddedCXXTemplateSpecialization(const FunctionTemplateDecl *TD,
|
||||
const FunctionDecl *D) {}
|
||||
|
||||
/// \brief A function's exception specification has been evaluated or
|
||||
/// A function's exception specification has been evaluated or
|
||||
/// instantiated.
|
||||
virtual void ResolvedExceptionSpec(const FunctionDecl *FD) {}
|
||||
|
||||
/// \brief A function's return type has been deduced.
|
||||
/// A function's return type has been deduced.
|
||||
virtual void DeducedReturnType(const FunctionDecl *FD, QualType ReturnType);
|
||||
|
||||
/// \brief A virtual destructor's operator delete has been resolved.
|
||||
/// A virtual destructor's operator delete has been resolved.
|
||||
virtual void ResolvedOperatorDelete(const CXXDestructorDecl *DD,
|
||||
const FunctionDecl *Delete,
|
||||
Expr *ThisArg) {}
|
||||
|
||||
/// \brief An implicit member got a definition.
|
||||
/// An implicit member got a definition.
|
||||
virtual void CompletedImplicitDefinition(const FunctionDecl *D) {}
|
||||
|
||||
/// \brief The instantiation of a templated function or variable was
|
||||
/// The instantiation of a templated function or variable was
|
||||
/// requested. In particular, the point of instantiation and template
|
||||
/// specialization kind of \p D may have changed.
|
||||
virtual void InstantiationRequested(const ValueDecl *D) {}
|
||||
|
||||
/// \brief A templated variable's definition was implicitly instantiated.
|
||||
/// A templated variable's definition was implicitly instantiated.
|
||||
virtual void VariableDefinitionInstantiated(const VarDecl *D) {}
|
||||
|
||||
/// \brief A function template's definition was instantiated.
|
||||
/// A function template's definition was instantiated.
|
||||
virtual void FunctionDefinitionInstantiated(const FunctionDecl *D) {}
|
||||
|
||||
/// \brief A default argument was instantiated.
|
||||
/// A default argument was instantiated.
|
||||
virtual void DefaultArgumentInstantiated(const ParmVarDecl *D) {}
|
||||
|
||||
/// \brief A default member initializer was instantiated.
|
||||
/// A default member initializer was instantiated.
|
||||
virtual void DefaultMemberInitializerInstantiated(const FieldDecl *D) {}
|
||||
|
||||
/// \brief A new objc category class was added for an interface.
|
||||
/// A new objc category class was added for an interface.
|
||||
virtual void AddedObjCCategoryToInterface(const ObjCCategoryDecl *CatD,
|
||||
const ObjCInterfaceDecl *IFD) {}
|
||||
|
||||
/// \brief A declaration is marked used which was not previously marked used.
|
||||
/// A declaration is marked used which was not previously marked used.
|
||||
///
|
||||
/// \param D the declaration marked used
|
||||
virtual void DeclarationMarkedUsed(const Decl *D) {}
|
||||
|
||||
/// \brief A declaration is marked as OpenMP threadprivate which was not
|
||||
/// A declaration is marked as OpenMP threadprivate which was not
|
||||
/// previously marked as threadprivate.
|
||||
///
|
||||
/// \param D the declaration marked OpenMP threadprivate.
|
||||
virtual void DeclarationMarkedOpenMPThreadPrivate(const Decl *D) {}
|
||||
|
||||
/// \brief A declaration is marked as OpenMP declaretarget which was not
|
||||
/// A declaration is marked as OpenMP declaretarget which was not
|
||||
/// previously marked as declaretarget.
|
||||
///
|
||||
/// \param D the declaration marked OpenMP declaretarget.
|
||||
@ -128,14 +128,14 @@ class ASTMutationListener {
|
||||
virtual void DeclarationMarkedOpenMPDeclareTarget(const Decl *D,
|
||||
const Attr *Attr) {}
|
||||
|
||||
/// \brief A definition has been made visible by being redefined locally.
|
||||
/// A definition has been made visible by being redefined locally.
|
||||
///
|
||||
/// \param D The definition that was previously not visible.
|
||||
/// \param M The containing module in which the definition was made visible,
|
||||
/// if any.
|
||||
virtual void RedefinedHiddenDefinition(const NamedDecl *D, Module *M) {}
|
||||
|
||||
/// \brief An attribute was added to a RecordDecl
|
||||
/// An attribute was added to a RecordDecl
|
||||
///
|
||||
/// \param Attr The attribute that was added to the Record
|
||||
///
|
||||
|
@ -1,4 +1,4 @@
|
||||
//===--- ASTStructuralEquivalence.h - ---------------------------*- C++ -*-===//
|
||||
//===- ASTStructuralEquivalence.h -------------------------------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
@ -19,6 +19,7 @@
|
||||
#include "llvm/ADT/DenseSet.h"
|
||||
#include "llvm/ADT/Optional.h"
|
||||
#include <deque>
|
||||
#include <utility>
|
||||
|
||||
namespace clang {
|
||||
|
||||
@ -29,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;
|
||||
@ -46,6 +55,8 @@ struct StructuralEquivalenceContext {
|
||||
/// (which we have already complained about).
|
||||
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls;
|
||||
|
||||
StructuralEquivalenceKind EqKind;
|
||||
|
||||
/// Whether we're being strict about the spelling of types when
|
||||
/// unifying two types.
|
||||
bool StrictTypeSpelling;
|
||||
@ -57,27 +68,35 @@ struct StructuralEquivalenceContext {
|
||||
bool Complain;
|
||||
|
||||
/// \c true if the last diagnostic came from ToCtx.
|
||||
bool LastDiagFromC2;
|
||||
bool LastDiagFromC2 = false;
|
||||
|
||||
StructuralEquivalenceContext(
|
||||
ASTContext &FromCtx, ASTContext &ToCtx,
|
||||
llvm::DenseSet<std::pair<Decl *, Decl *>> &NonEquivalentDecls,
|
||||
StructuralEquivalenceKind EqKind,
|
||||
bool StrictTypeSpelling = false, bool Complain = true,
|
||||
bool ErrorOnTagTypeMismatch = false)
|
||||
: FromCtx(FromCtx), ToCtx(ToCtx), NonEquivalentDecls(NonEquivalentDecls),
|
||||
StrictTypeSpelling(StrictTypeSpelling),
|
||||
ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain),
|
||||
LastDiagFromC2(false) {}
|
||||
EqKind(EqKind), StrictTypeSpelling(StrictTypeSpelling),
|
||||
ErrorOnTagTypeMismatch(ErrorOnTagTypeMismatch), Complain(Complain) {}
|
||||
|
||||
DiagnosticBuilder Diag1(SourceLocation Loc, unsigned DiagID);
|
||||
DiagnosticBuilder Diag2(SourceLocation Loc, unsigned DiagID);
|
||||
|
||||
/// 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.
|
||||
@ -98,6 +117,7 @@ struct StructuralEquivalenceContext {
|
||||
/// \returns true if an error occurred, false otherwise.
|
||||
bool Finish();
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_ASTSTRUCTURALEQUIVALENCE_H
|
||||
|
@ -38,62 +38,62 @@ struct PrintingPolicy;
|
||||
|
||||
namespace ast_type_traits {
|
||||
|
||||
/// \brief Kind identifier.
|
||||
/// Kind identifier.
|
||||
///
|
||||
/// It can be constructed from any node kind and allows for runtime type
|
||||
/// hierarchy checks.
|
||||
/// Use getFromNodeKind<T>() to construct them.
|
||||
class ASTNodeKind {
|
||||
public:
|
||||
/// \brief Empty identifier. It matches nothing.
|
||||
/// Empty identifier. It matches nothing.
|
||||
ASTNodeKind() : KindId(NKI_None) {}
|
||||
|
||||
/// \brief Construct an identifier for T.
|
||||
/// Construct an identifier for T.
|
||||
template <class T>
|
||||
static ASTNodeKind getFromNodeKind() {
|
||||
return ASTNodeKind(KindToKindId<T>::Id);
|
||||
}
|
||||
|
||||
/// \{
|
||||
/// \brief Construct an identifier for the dynamic type of the node
|
||||
/// Construct an identifier for the dynamic type of the node
|
||||
static ASTNodeKind getFromNode(const Decl &D);
|
||||
static ASTNodeKind getFromNode(const Stmt &S);
|
||||
static ASTNodeKind getFromNode(const Type &T);
|
||||
/// \}
|
||||
|
||||
/// \brief Returns \c true if \c this and \c Other represent the same kind.
|
||||
/// Returns \c true if \c this and \c Other represent the same kind.
|
||||
bool isSame(ASTNodeKind Other) const {
|
||||
return KindId != NKI_None && KindId == Other.KindId;
|
||||
}
|
||||
|
||||
/// \brief Returns \c true only for the default \c ASTNodeKind()
|
||||
/// Returns \c true only for the default \c ASTNodeKind()
|
||||
bool isNone() const { return KindId == NKI_None; }
|
||||
|
||||
/// \brief Returns \c true if \c this is a base kind of (or same as) \c Other.
|
||||
/// Returns \c true if \c this is a base kind of (or same as) \c Other.
|
||||
/// \param Distance If non-null, used to return the distance between \c this
|
||||
/// and \c Other in the class hierarchy.
|
||||
bool isBaseOf(ASTNodeKind Other, unsigned *Distance = nullptr) const;
|
||||
|
||||
/// \brief String representation of the kind.
|
||||
/// String representation of the kind.
|
||||
StringRef asStringRef() const;
|
||||
|
||||
/// \brief Strict weak ordering for ASTNodeKind.
|
||||
/// Strict weak ordering for ASTNodeKind.
|
||||
bool operator<(const ASTNodeKind &Other) const {
|
||||
return KindId < Other.KindId;
|
||||
}
|
||||
|
||||
/// \brief Return the most derived type between \p Kind1 and \p Kind2.
|
||||
/// Return the most derived type between \p Kind1 and \p Kind2.
|
||||
///
|
||||
/// Return ASTNodeKind() if they are not related.
|
||||
static ASTNodeKind getMostDerivedType(ASTNodeKind Kind1, ASTNodeKind Kind2);
|
||||
|
||||
/// \brief Return the most derived common ancestor between Kind1 and Kind2.
|
||||
/// Return the most derived common ancestor between Kind1 and Kind2.
|
||||
///
|
||||
/// Return ASTNodeKind() if they are not related.
|
||||
static ASTNodeKind getMostDerivedCommonAncestor(ASTNodeKind Kind1,
|
||||
ASTNodeKind Kind2);
|
||||
|
||||
/// \brief Hooks for using ASTNodeKind as a key in a DenseMap.
|
||||
/// Hooks for using ASTNodeKind as a key in a DenseMap.
|
||||
struct DenseMapInfo {
|
||||
// ASTNodeKind() is a good empty key because it is represented as a 0.
|
||||
static inline ASTNodeKind getEmptyKey() { return ASTNodeKind(); }
|
||||
@ -115,7 +115,7 @@ class ASTNodeKind {
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief Kind ids.
|
||||
/// Kind ids.
|
||||
///
|
||||
/// Includes all possible base and derived kinds.
|
||||
enum NodeKindId {
|
||||
@ -140,16 +140,16 @@ class ASTNodeKind {
|
||||
NKI_NumberOfKinds
|
||||
};
|
||||
|
||||
/// \brief Use getFromNodeKind<T>() to construct the kind.
|
||||
/// Use getFromNodeKind<T>() to construct the kind.
|
||||
ASTNodeKind(NodeKindId KindId) : KindId(KindId) {}
|
||||
|
||||
/// \brief Returns \c true if \c Base is a base kind of (or same as) \c
|
||||
/// Returns \c true if \c Base is a base kind of (or same as) \c
|
||||
/// Derived.
|
||||
/// \param Distance If non-null, used to return the distance between \c Base
|
||||
/// and \c Derived in the class hierarchy.
|
||||
static bool isBaseOf(NodeKindId Base, NodeKindId Derived, unsigned *Distance);
|
||||
|
||||
/// \brief Helper meta-function to convert a kind T to its enum value.
|
||||
/// Helper meta-function to convert a kind T to its enum value.
|
||||
///
|
||||
/// This struct is specialized below for all known kinds.
|
||||
template <class T> struct KindToKindId {
|
||||
@ -158,11 +158,11 @@ class ASTNodeKind {
|
||||
template <class T>
|
||||
struct KindToKindId<const T> : KindToKindId<T> {};
|
||||
|
||||
/// \brief Per kind info.
|
||||
/// Per kind info.
|
||||
struct KindInfo {
|
||||
/// \brief The id of the parent kind, or None if it has no parent.
|
||||
/// The id of the parent kind, or None if it has no parent.
|
||||
NodeKindId ParentId;
|
||||
/// \brief Name of the kind.
|
||||
/// Name of the kind.
|
||||
const char *Name;
|
||||
};
|
||||
static const KindInfo AllKindInfo[NKI_NumberOfKinds];
|
||||
@ -197,7 +197,7 @@ inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
|
||||
return OS;
|
||||
}
|
||||
|
||||
/// \brief A dynamically typed AST node container.
|
||||
/// A dynamically typed AST node container.
|
||||
///
|
||||
/// Stores an AST node in a type safe way. This allows writing code that
|
||||
/// works with different kinds of AST nodes, despite the fact that they don't
|
||||
@ -211,13 +211,13 @@ inline raw_ostream &operator<<(raw_ostream &OS, ASTNodeKind K) {
|
||||
/// the supported base types.
|
||||
class DynTypedNode {
|
||||
public:
|
||||
/// \brief Creates a \c DynTypedNode from \c Node.
|
||||
/// Creates a \c DynTypedNode from \c Node.
|
||||
template <typename T>
|
||||
static DynTypedNode create(const T &Node) {
|
||||
return BaseConverter<T>::create(Node);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the stored node as type \c T.
|
||||
/// Retrieve the stored node as type \c T.
|
||||
///
|
||||
/// Returns NULL if the stored node does not have a type that is
|
||||
/// convertible to \c T.
|
||||
@ -234,7 +234,7 @@ class DynTypedNode {
|
||||
return BaseConverter<T>::get(NodeKind, Storage.buffer);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the stored node as type \c T.
|
||||
/// Retrieve the stored node as type \c T.
|
||||
///
|
||||
/// Similar to \c get(), but asserts that the type is what we are expecting.
|
||||
template <typename T>
|
||||
@ -244,7 +244,7 @@ class DynTypedNode {
|
||||
|
||||
ASTNodeKind getNodeKind() const { return NodeKind; }
|
||||
|
||||
/// \brief Returns a pointer that identifies the stored AST node.
|
||||
/// Returns a pointer that identifies the stored AST node.
|
||||
///
|
||||
/// Note that this is not supported by all AST nodes. For AST nodes
|
||||
/// that don't have a pointer-defined identity inside the AST, this
|
||||
@ -255,21 +255,21 @@ class DynTypedNode {
|
||||
: nullptr;
|
||||
}
|
||||
|
||||
/// \brief Prints the node to the given output stream.
|
||||
/// Prints the node to the given output stream.
|
||||
void print(llvm::raw_ostream &OS, const PrintingPolicy &PP) const;
|
||||
|
||||
/// \brief Dumps the node to the given output stream.
|
||||
/// Dumps the node to the given output stream.
|
||||
void dump(llvm::raw_ostream &OS, SourceManager &SM) const;
|
||||
|
||||
/// \brief For nodes which represent textual entities in the source code,
|
||||
/// For nodes which represent textual entities in the source code,
|
||||
/// return their SourceRange. For all other nodes, return SourceRange().
|
||||
SourceRange getSourceRange() const;
|
||||
|
||||
/// @{
|
||||
/// \brief Imposes an order on \c DynTypedNode.
|
||||
/// Imposes an order on \c DynTypedNode.
|
||||
///
|
||||
/// Supports comparison of nodes that support memoization.
|
||||
/// FIXME: Implement comparsion for other node types (currently
|
||||
/// FIXME: Implement comparison for other node types (currently
|
||||
/// only Stmt, Decl, Type and NestedNameSpecifier return memoization data).
|
||||
bool operator<(const DynTypedNode &Other) const {
|
||||
if (!NodeKind.isSame(Other.NodeKind))
|
||||
@ -326,7 +326,7 @@ class DynTypedNode {
|
||||
}
|
||||
/// @}
|
||||
|
||||
/// \brief Hooks for using DynTypedNode as a key in a DenseMap.
|
||||
/// Hooks for using DynTypedNode as a key in a DenseMap.
|
||||
struct DenseMapInfo {
|
||||
static inline DynTypedNode getEmptyKey() {
|
||||
DynTypedNode Node;
|
||||
@ -368,10 +368,10 @@ class DynTypedNode {
|
||||
};
|
||||
|
||||
private:
|
||||
/// \brief Takes care of converting from and to \c T.
|
||||
/// Takes care of converting from and to \c T.
|
||||
template <typename T, typename EnablerT = void> struct BaseConverter;
|
||||
|
||||
/// \brief Converter that uses dyn_cast<T> from a stored BaseT*.
|
||||
/// Converter that uses dyn_cast<T> from a stored BaseT*.
|
||||
template <typename T, typename BaseT> struct DynCastPtrConverter {
|
||||
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
|
||||
if (ASTNodeKind::getFromNodeKind<T>().isBaseOf(NodeKind))
|
||||
@ -391,7 +391,7 @@ class DynTypedNode {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Converter that stores T* (by pointer).
|
||||
/// Converter that stores T* (by pointer).
|
||||
template <typename T> struct PtrConverter {
|
||||
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
|
||||
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
|
||||
@ -411,7 +411,7 @@ class DynTypedNode {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Converter that stores T (by value).
|
||||
/// Converter that stores T (by value).
|
||||
template <typename T> struct ValueConverter {
|
||||
static const T *get(ASTNodeKind NodeKind, const char Storage[]) {
|
||||
if (ASTNodeKind::getFromNodeKind<T>().isSame(NodeKind))
|
||||
@ -432,7 +432,7 @@ class DynTypedNode {
|
||||
|
||||
ASTNodeKind NodeKind;
|
||||
|
||||
/// \brief Stores the data of the node.
|
||||
/// Stores the data of the node.
|
||||
///
|
||||
/// Note that we can store \c Decls, \c Stmts, \c Types,
|
||||
/// \c NestedNameSpecifiers and \c CXXCtorInitializer by pointer as they are
|
||||
|
@ -26,7 +26,7 @@ namespace clang {
|
||||
|
||||
class NamedDecl;
|
||||
|
||||
/// \brief An UnresolvedSet-like class which uses the ASTContext's allocator.
|
||||
/// An UnresolvedSet-like class which uses the ASTContext's allocator.
|
||||
class ASTUnresolvedSet {
|
||||
friend class LazyASTUnresolvedSet;
|
||||
|
||||
@ -89,7 +89,7 @@ class ASTUnresolvedSet {
|
||||
const DeclAccessPair &operator[](unsigned I) const { return Decls[I]; }
|
||||
};
|
||||
|
||||
/// \brief An UnresolvedSet-like class that might not have been loaded from the
|
||||
/// An UnresolvedSet-like class that might not have been loaded from the
|
||||
/// external AST source yet.
|
||||
class LazyASTUnresolvedSet {
|
||||
mutable ASTUnresolvedSet Impl;
|
||||
|
@ -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 <algorithm>
|
||||
#include <cassert>
|
||||
@ -52,8 +52,10 @@ class Attr {
|
||||
unsigned Inherited : 1;
|
||||
unsigned IsPackExpansion : 1;
|
||||
unsigned Implicit : 1;
|
||||
// FIXME: These are properties of the attribute kind, not state for this
|
||||
// instance of the attribute.
|
||||
unsigned IsLateParsed : 1;
|
||||
unsigned DuplicatesAllowed : 1;
|
||||
unsigned InheritEvenIfAlreadyPresent : 1;
|
||||
|
||||
void *operator new(size_t bytes) noexcept {
|
||||
llvm_unreachable("Attrs cannot be allocated with regular 'new'.");
|
||||
@ -74,10 +76,10 @@ class Attr {
|
||||
|
||||
protected:
|
||||
Attr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
bool IsLateParsed, bool DuplicatesAllowed)
|
||||
bool IsLateParsed)
|
||||
: Range(R), AttrKind(AK), SpellingListIndex(SpellingListIndex),
|
||||
Inherited(false), IsPackExpansion(false), Implicit(false),
|
||||
IsLateParsed(IsLateParsed), DuplicatesAllowed(DuplicatesAllowed) {}
|
||||
IsLateParsed(IsLateParsed), InheritEvenIfAlreadyPresent(false) {}
|
||||
|
||||
public:
|
||||
|
||||
@ -94,7 +96,7 @@ class Attr {
|
||||
|
||||
bool isInherited() const { return Inherited; }
|
||||
|
||||
/// \brief Returns true if the attribute has been implicitly created instead
|
||||
/// Returns true if the attribute has been implicitly created instead
|
||||
/// of explicitly written by the user.
|
||||
bool isImplicit() const { return Implicit; }
|
||||
void setImplicit(bool I) { Implicit = I; }
|
||||
@ -109,18 +111,13 @@ class Attr {
|
||||
|
||||
// Pretty print this attribute.
|
||||
void printPretty(raw_ostream &OS, const PrintingPolicy &Policy) const;
|
||||
|
||||
/// \brief By default, attributes cannot be duplicated when being merged;
|
||||
/// however, an attribute can override this. Returns true if the attribute
|
||||
/// can be duplicated when merging.
|
||||
bool duplicatesAllowed() const { return DuplicatesAllowed; }
|
||||
};
|
||||
|
||||
class StmtAttr : public Attr {
|
||||
protected:
|
||||
StmtAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
bool IsLateParsed, bool DuplicatesAllowed)
|
||||
: Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
|
||||
bool IsLateParsed)
|
||||
: Attr(AK, R, SpellingListIndex, IsLateParsed) {}
|
||||
|
||||
public:
|
||||
static bool classof(const Attr *A) {
|
||||
@ -132,12 +129,20 @@ class StmtAttr : public Attr {
|
||||
class InheritableAttr : public Attr {
|
||||
protected:
|
||||
InheritableAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
bool IsLateParsed, bool DuplicatesAllowed)
|
||||
: Attr(AK, R, SpellingListIndex, IsLateParsed, DuplicatesAllowed) {}
|
||||
bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
|
||||
: Attr(AK, R, SpellingListIndex, IsLateParsed) {
|
||||
this->InheritEvenIfAlreadyPresent = InheritEvenIfAlreadyPresent;
|
||||
}
|
||||
|
||||
public:
|
||||
void setInherited(bool I) { Inherited = I; }
|
||||
|
||||
/// Should this attribute be inherited from a prior declaration even if it's
|
||||
/// explicitly provided in the current declaration?
|
||||
bool shouldInheritEvenIfAlreadyPresent() const {
|
||||
return InheritEvenIfAlreadyPresent;
|
||||
}
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
static bool classof(const Attr *A) {
|
||||
return A->getKind() >= attr::FirstInheritableAttr &&
|
||||
@ -148,9 +153,9 @@ class InheritableAttr : public Attr {
|
||||
class InheritableParamAttr : public InheritableAttr {
|
||||
protected:
|
||||
InheritableParamAttr(attr::Kind AK, SourceRange R, unsigned SpellingListIndex,
|
||||
bool IsLateParsed, bool DuplicatesAllowed)
|
||||
bool IsLateParsed, bool InheritEvenIfAlreadyPresent)
|
||||
: InheritableAttr(AK, R, SpellingListIndex, IsLateParsed,
|
||||
DuplicatesAllowed) {}
|
||||
InheritEvenIfAlreadyPresent) {}
|
||||
|
||||
public:
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
@ -166,9 +171,9 @@ class ParameterABIAttr : public InheritableParamAttr {
|
||||
protected:
|
||||
ParameterABIAttr(attr::Kind AK, SourceRange R,
|
||||
unsigned SpellingListIndex, bool IsLateParsed,
|
||||
bool DuplicatesAllowed)
|
||||
bool InheritEvenIfAlreadyPresent)
|
||||
: InheritableParamAttr(AK, R, SpellingListIndex, IsLateParsed,
|
||||
DuplicatesAllowed) {}
|
||||
InheritEvenIfAlreadyPresent) {}
|
||||
|
||||
public:
|
||||
ParameterABI getABI() const {
|
||||
@ -190,6 +195,128 @@ class ParameterABIAttr : public InheritableParamAttr {
|
||||
}
|
||||
};
|
||||
|
||||
/// A single parameter index whose accessors require each use to make explicit
|
||||
/// the parameter index encoding needed.
|
||||
class ParamIdx {
|
||||
// Idx is exposed only via accessors that specify specific encodings.
|
||||
unsigned Idx : 30;
|
||||
unsigned HasThis : 1;
|
||||
unsigned IsValid : 1;
|
||||
|
||||
void assertComparable(const ParamIdx &I) const {
|
||||
assert(isValid() && I.isValid() &&
|
||||
"ParamIdx must be valid to be compared");
|
||||
// It's possible to compare indices from separate functions, but so far
|
||||
// it's not proven useful. Moreover, it might be confusing because a
|
||||
// comparison on the results of getASTIndex might be inconsistent with a
|
||||
// comparison on the ParamIdx objects themselves.
|
||||
assert(HasThis == I.HasThis &&
|
||||
"ParamIdx must be for the same function to be compared");
|
||||
}
|
||||
|
||||
public:
|
||||
/// Construct an invalid parameter index (\c isValid returns false and
|
||||
/// accessors fail an assert).
|
||||
ParamIdx() : Idx(0), HasThis(false), IsValid(false) {}
|
||||
|
||||
/// \param Idx is the parameter index as it is normally specified in
|
||||
/// attributes in the source: one-origin including any C++ implicit this
|
||||
/// parameter.
|
||||
///
|
||||
/// \param D is the declaration containing the parameters. It is used to
|
||||
/// determine if there is a C++ implicit this parameter.
|
||||
ParamIdx(unsigned Idx, const Decl *D)
|
||||
: Idx(Idx), HasThis(false), IsValid(true) {
|
||||
assert(Idx >= 1 && "Idx must be one-origin");
|
||||
if (const auto *FD = dyn_cast<FunctionDecl>(D))
|
||||
HasThis = FD->isCXXInstanceMember();
|
||||
}
|
||||
|
||||
/// A type into which \c ParamIdx can be serialized.
|
||||
///
|
||||
/// A static assertion that it's of the correct size follows the \c ParamIdx
|
||||
/// class definition.
|
||||
typedef uint32_t SerialType;
|
||||
|
||||
/// Produce a representation that can later be passed to \c deserialize to
|
||||
/// construct an equivalent \c ParamIdx.
|
||||
SerialType serialize() const {
|
||||
return *reinterpret_cast<const SerialType *>(this);
|
||||
}
|
||||
|
||||
/// Construct from a result from \c serialize.
|
||||
static ParamIdx deserialize(SerialType S) {
|
||||
ParamIdx P(*reinterpret_cast<ParamIdx *>(&S));
|
||||
assert((!P.IsValid || P.Idx >= 1) && "valid Idx must be one-origin");
|
||||
return P;
|
||||
}
|
||||
|
||||
/// Is this parameter index valid?
|
||||
bool isValid() const { return IsValid; }
|
||||
|
||||
/// Get the parameter index as it would normally be encoded for attributes at
|
||||
/// the source level of representation: one-origin including any C++ implicit
|
||||
/// this parameter.
|
||||
///
|
||||
/// This encoding thus makes sense for diagnostics, pretty printing, and
|
||||
/// constructing new attributes from a source-like specification.
|
||||
unsigned getSourceIndex() const {
|
||||
assert(isValid() && "ParamIdx must be valid");
|
||||
return Idx;
|
||||
}
|
||||
|
||||
/// Get the parameter index as it would normally be encoded at the AST level
|
||||
/// of representation: zero-origin not including any C++ implicit this
|
||||
/// parameter.
|
||||
///
|
||||
/// This is the encoding primarily used in Sema. However, in diagnostics,
|
||||
/// Sema uses \c getSourceIndex instead.
|
||||
unsigned getASTIndex() const {
|
||||
assert(isValid() && "ParamIdx must be valid");
|
||||
assert(Idx >= 1 + HasThis &&
|
||||
"stored index must be base-1 and not specify C++ implicit this");
|
||||
return Idx - 1 - HasThis;
|
||||
}
|
||||
|
||||
/// Get the parameter index as it would normally be encoded at the LLVM level
|
||||
/// of representation: zero-origin including any C++ implicit this parameter.
|
||||
///
|
||||
/// This is the encoding primarily used in CodeGen.
|
||||
unsigned getLLVMIndex() const {
|
||||
assert(isValid() && "ParamIdx must be valid");
|
||||
assert(Idx >= 1 && "stored index must be base-1");
|
||||
return Idx - 1;
|
||||
}
|
||||
|
||||
bool operator==(const ParamIdx &I) const {
|
||||
assertComparable(I);
|
||||
return Idx == I.Idx;
|
||||
}
|
||||
bool operator!=(const ParamIdx &I) const {
|
||||
assertComparable(I);
|
||||
return Idx != I.Idx;
|
||||
}
|
||||
bool operator<(const ParamIdx &I) const {
|
||||
assertComparable(I);
|
||||
return Idx < I.Idx;
|
||||
}
|
||||
bool operator>(const ParamIdx &I) const {
|
||||
assertComparable(I);
|
||||
return Idx > I.Idx;
|
||||
}
|
||||
bool operator<=(const ParamIdx &I) const {
|
||||
assertComparable(I);
|
||||
return Idx <= I.Idx;
|
||||
}
|
||||
bool operator>=(const ParamIdx &I) const {
|
||||
assertComparable(I);
|
||||
return Idx >= I.Idx;
|
||||
}
|
||||
};
|
||||
|
||||
static_assert(sizeof(ParamIdx) == sizeof(ParamIdx::SerialType),
|
||||
"ParamIdx does not fit its serialization type");
|
||||
|
||||
#include "clang/AST/Attrs.inc"
|
||||
|
||||
inline const DiagnosticBuilder &operator<<(const DiagnosticBuilder &DB,
|
||||
|
@ -15,12 +15,12 @@
|
||||
#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 {
|
||||
|
||||
/// \brief One specifier in an @available expression.
|
||||
/// One specifier in an @available expression.
|
||||
///
|
||||
/// \code
|
||||
/// @available(macos 10.10, *)
|
||||
|
@ -72,6 +72,9 @@ UNSIGNED_TYPE(UChar, UnsignedCharTy)
|
||||
// 'wchar_t' for targets where it's unsigned
|
||||
SHARED_SINGLETON_TYPE(UNSIGNED_TYPE(WChar_U, WCharTy))
|
||||
|
||||
// 'char8_t' in C++20 (proposed)
|
||||
UNSIGNED_TYPE(Char8, Char8Ty)
|
||||
|
||||
// 'char16_t' in C++
|
||||
UNSIGNED_TYPE(Char16, Char16Ty)
|
||||
|
||||
@ -119,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.
|
||||
|
@ -35,7 +35,7 @@ namespace clang {
|
||||
class ASTContext;
|
||||
class NamedDecl;
|
||||
|
||||
/// \brief Represents an element in a path from a derived class to a
|
||||
/// Represents an element in a path from a derived class to a
|
||||
/// base class.
|
||||
///
|
||||
/// Each step in the path references the link from a
|
||||
@ -43,15 +43,15 @@ class NamedDecl;
|
||||
/// base "number" that identifies which base subobject of the
|
||||
/// original derived class we are referencing.
|
||||
struct CXXBasePathElement {
|
||||
/// \brief The base specifier that states the link from a derived
|
||||
/// The base specifier that states the link from a derived
|
||||
/// class to a base class, which will be followed by this base
|
||||
/// path element.
|
||||
const CXXBaseSpecifier *Base;
|
||||
|
||||
/// \brief The record decl of the class that the base is a base of.
|
||||
/// The record decl of the class that the base is a base of.
|
||||
const CXXRecordDecl *Class;
|
||||
|
||||
/// \brief Identifies which base class subobject (of type
|
||||
/// Identifies which base class subobject (of type
|
||||
/// \c Base->getType()) this base path element refers to.
|
||||
///
|
||||
/// This value is only valid if \c !Base->isVirtual(), because there
|
||||
@ -60,7 +60,7 @@ struct CXXBasePathElement {
|
||||
int SubobjectNumber;
|
||||
};
|
||||
|
||||
/// \brief Represents a path from a specific derived class
|
||||
/// Represents a path from a specific derived class
|
||||
/// (which is not represented as part of the path) to a particular
|
||||
/// (direct or indirect) base class subobject.
|
||||
///
|
||||
@ -70,14 +70,14 @@ struct CXXBasePathElement {
|
||||
/// subobject is being used.
|
||||
class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
|
||||
public:
|
||||
/// \brief The access along this inheritance path. This is only
|
||||
/// The access along this inheritance path. This is only
|
||||
/// calculated when recording paths. AS_none is a special value
|
||||
/// used to indicate a path which permits no legal access.
|
||||
AccessSpecifier Access = AS_public;
|
||||
|
||||
CXXBasePath() = default;
|
||||
|
||||
/// \brief The set of declarations found inside this base class
|
||||
/// The set of declarations found inside this base class
|
||||
/// subobject.
|
||||
DeclContext::lookup_result Decls;
|
||||
|
||||
@ -119,24 +119,42 @@ class CXXBasePath : public SmallVector<CXXBasePathElement, 4> {
|
||||
class CXXBasePaths {
|
||||
friend class CXXRecordDecl;
|
||||
|
||||
/// \brief The type from which this search originated.
|
||||
/// 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<CXXBasePath> 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<QualType, std::pair<bool, unsigned>, 8> ClassSubobjects;
|
||||
struct IsVirtBaseAndNumberNonVirtBases {
|
||||
unsigned IsVirtBase : 1;
|
||||
unsigned NumberOfNonVirtBases : 31;
|
||||
};
|
||||
llvm::SmallDenseMap<QualType, IsVirtBaseAndNumberNonVirtBases, 8>
|
||||
ClassSubobjects;
|
||||
|
||||
/// VisitedDependentRecords - Records the dependent records that have been
|
||||
/// already visited.
|
||||
llvm::SmallDenseSet<const CXXRecordDecl *, 4> VisitedDependentRecords;
|
||||
llvm::SmallPtrSet<const CXXRecordDecl *, 4> 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<NamedDecl *[]> DeclsFound;
|
||||
unsigned NumDeclsFound = 0;
|
||||
|
||||
/// FindAmbiguities - Whether Sema::IsDerivedFrom should try find
|
||||
/// ambiguous paths while it is looking for a path from a derived
|
||||
@ -152,20 +170,7 @@ class CXXBasePaths {
|
||||
/// 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;
|
||||
|
||||
/// \brief Array of the declarations that have been found. This
|
||||
/// array is constructed only if needed, e.g., to iterate over the
|
||||
/// results within LookupResult.
|
||||
std::unique_ptr<NamedDecl *[]> DeclsFound;
|
||||
unsigned NumDeclsFound = 0;
|
||||
|
||||
void ComputeDeclsFound();
|
||||
|
||||
bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
|
||||
@ -196,53 +201,53 @@ class CXXBasePaths {
|
||||
|
||||
decl_range found_decls();
|
||||
|
||||
/// \brief Determine whether the path from the most-derived type to the
|
||||
/// 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);
|
||||
|
||||
/// \brief Whether we are finding multiple paths to detect ambiguities.
|
||||
/// Whether we are finding multiple paths to detect ambiguities.
|
||||
bool isFindingAmbiguities() const { return FindAmbiguities; }
|
||||
|
||||
/// \brief Whether we are recording paths.
|
||||
/// Whether we are recording paths.
|
||||
bool isRecordingPaths() const { return RecordPaths; }
|
||||
|
||||
/// \brief Specify whether we should be recording paths or not.
|
||||
/// Specify whether we should be recording paths or not.
|
||||
void setRecordingPaths(bool RP) { RecordPaths = RP; }
|
||||
|
||||
/// \brief Whether we are detecting virtual bases.
|
||||
/// Whether we are detecting virtual bases.
|
||||
bool isDetectingVirtual() const { return DetectVirtual; }
|
||||
|
||||
/// \brief The virtual base discovered on the path (if we are merely
|
||||
/// The virtual base discovered on the path (if we are merely
|
||||
/// detecting virtuals).
|
||||
const RecordType* getDetectedVirtual() const {
|
||||
return DetectedVirtual;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the type from which this base-paths search
|
||||
/// Retrieve the type from which this base-paths search
|
||||
/// began
|
||||
CXXRecordDecl *getOrigin() const { return Origin; }
|
||||
void setOrigin(CXXRecordDecl *Rec) { Origin = Rec; }
|
||||
|
||||
/// \brief Clear the base-paths results.
|
||||
/// Clear the base-paths results.
|
||||
void clear();
|
||||
|
||||
/// \brief Swap this data structure's contents with another CXXBasePaths
|
||||
/// Swap this data structure's contents with another CXXBasePaths
|
||||
/// object.
|
||||
void swap(CXXBasePaths &Other);
|
||||
};
|
||||
|
||||
/// \brief Uniquely identifies a virtual method within a class
|
||||
/// Uniquely identifies a virtual method within a class
|
||||
/// hierarchy by the method itself and a class subobject number.
|
||||
struct UniqueVirtualMethod {
|
||||
/// \brief The overriding virtual method.
|
||||
/// The overriding virtual method.
|
||||
CXXMethodDecl *Method = nullptr;
|
||||
|
||||
/// \brief The subobject in which the overriding virtual method
|
||||
/// The subobject in which the overriding virtual method
|
||||
/// resides.
|
||||
unsigned Subobject = 0;
|
||||
|
||||
/// \brief The virtual base class subobject of which this overridden
|
||||
/// The virtual base class subobject of which this overridden
|
||||
/// virtual method is a part. Note that this records the closest
|
||||
/// derived virtual base class subobject.
|
||||
const CXXRecordDecl *InVirtualSubobject = nullptr;
|
||||
@ -266,7 +271,7 @@ struct UniqueVirtualMethod {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief The set of methods that override a given virtual method in
|
||||
/// The set of methods that override a given virtual method in
|
||||
/// each subobject where it occurs.
|
||||
///
|
||||
/// The first part of the pair is the subobject in which the
|
||||
@ -310,7 +315,7 @@ class OverridingMethods {
|
||||
void replaceAll(UniqueVirtualMethod Overriding);
|
||||
};
|
||||
|
||||
/// \brief A mapping from each virtual member function to its set of
|
||||
/// A mapping from each virtual member function to its set of
|
||||
/// final overriders.
|
||||
///
|
||||
/// Within a class hierarchy for a given derived class, each virtual
|
||||
@ -364,7 +369,7 @@ class OverridingMethods {
|
||||
class CXXFinalOverriderMap
|
||||
: public llvm::MapVector<const CXXMethodDecl *, OverridingMethods> {};
|
||||
|
||||
/// \brief A set of all the primary bases for a class.
|
||||
/// A set of all the primary bases for a class.
|
||||
class CXXIndirectPrimaryBaseSet
|
||||
: public llvm::SmallSet<const CXXRecordDecl*, 32> {};
|
||||
|
||||
|
@ -44,7 +44,7 @@ class TemplateTypeParmDecl;
|
||||
// Canonical, qualified type template
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/// \brief Represents a canonical, potentially-qualified type.
|
||||
/// Represents a canonical, potentially-qualified type.
|
||||
///
|
||||
/// The CanQual template is a lightweight smart pointer that provides access
|
||||
/// to the canonical representation of a type, where all typedefs and other
|
||||
@ -64,35 +64,35 @@ class TemplateTypeParmDecl;
|
||||
/// a call to ASTContext::getCanonicalType().
|
||||
template<typename T = Type>
|
||||
class CanQual {
|
||||
/// \brief The actual, canonical type.
|
||||
/// The actual, canonical type.
|
||||
QualType Stored;
|
||||
|
||||
public:
|
||||
/// \brief Constructs a NULL canonical type.
|
||||
/// Constructs a NULL canonical type.
|
||||
CanQual() = default;
|
||||
|
||||
/// \brief Converting constructor that permits implicit upcasting of
|
||||
/// Converting constructor that permits implicit upcasting of
|
||||
/// canonical type pointers.
|
||||
template <typename U>
|
||||
CanQual(const CanQual<U> &Other,
|
||||
typename std::enable_if<std::is_base_of<T, U>::value, int>::type = 0);
|
||||
|
||||
/// \brief Retrieve the underlying type pointer, which refers to a
|
||||
/// Retrieve the underlying type pointer, which refers to a
|
||||
/// canonical type.
|
||||
///
|
||||
/// The underlying pointer must not be nullptr.
|
||||
const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); }
|
||||
|
||||
/// \brief Retrieve the underlying type pointer, which refers to a
|
||||
/// Retrieve the underlying type pointer, which refers to a
|
||||
/// canonical type, or nullptr.
|
||||
const T *getTypePtrOrNull() const {
|
||||
return cast_or_null<T>(Stored.getTypePtrOrNull());
|
||||
}
|
||||
|
||||
/// \brief Implicit conversion to a qualified type.
|
||||
/// Implicit conversion to a qualified type.
|
||||
operator QualType() const { return Stored; }
|
||||
|
||||
/// \brief Implicit conversion to bool.
|
||||
/// Implicit conversion to bool.
|
||||
explicit operator bool() const { return !isNull(); }
|
||||
|
||||
bool isNull() const {
|
||||
@ -101,7 +101,7 @@ class CanQual {
|
||||
|
||||
SplitQualType split() const { return Stored.split(); }
|
||||
|
||||
/// \brief Retrieve a canonical type pointer with a different static type,
|
||||
/// Retrieve a canonical type pointer with a different static type,
|
||||
/// upcasting or downcasting as needed.
|
||||
///
|
||||
/// The getAs() function is typically used to try to downcast to a
|
||||
@ -122,17 +122,17 @@ class CanQual {
|
||||
|
||||
template<typename U> CanProxy<U> castAs() const;
|
||||
|
||||
/// \brief Overloaded arrow operator that produces a canonical type
|
||||
/// Overloaded arrow operator that produces a canonical type
|
||||
/// proxy.
|
||||
CanProxy<T> operator->() const;
|
||||
|
||||
/// \brief Retrieve all qualifiers.
|
||||
/// Retrieve all qualifiers.
|
||||
Qualifiers getQualifiers() const { return Stored.getLocalQualifiers(); }
|
||||
|
||||
/// \brief Retrieve the const/volatile/restrict qualifiers.
|
||||
/// Retrieve the const/volatile/restrict qualifiers.
|
||||
unsigned getCVRQualifiers() const { return Stored.getLocalCVRQualifiers(); }
|
||||
|
||||
/// \brief Determines whether this type has any qualifiers
|
||||
/// Determines whether this type has any qualifiers
|
||||
bool hasQualifiers() const { return Stored.hasLocalQualifiers(); }
|
||||
|
||||
bool isConstQualified() const {
|
||||
@ -147,45 +147,45 @@ class CanQual {
|
||||
return Stored.isLocalRestrictQualified();
|
||||
}
|
||||
|
||||
/// \brief Determines if this canonical type is furthermore
|
||||
/// Determines if this canonical type is furthermore
|
||||
/// canonical as a parameter. The parameter-canonicalization
|
||||
/// process decays arrays to pointers and drops top-level qualifiers.
|
||||
bool isCanonicalAsParam() const {
|
||||
return Stored.isCanonicalAsParam();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the unqualified form of this type.
|
||||
/// Retrieve the unqualified form of this type.
|
||||
CanQual<T> getUnqualifiedType() const;
|
||||
|
||||
/// \brief Retrieves a version of this type with const applied.
|
||||
/// Retrieves a version of this type with const applied.
|
||||
/// Note that this does not always yield a canonical type.
|
||||
QualType withConst() const {
|
||||
return Stored.withConst();
|
||||
}
|
||||
|
||||
/// \brief Determines whether this canonical type is more qualified than
|
||||
/// Determines whether this canonical type is more qualified than
|
||||
/// the @p Other canonical type.
|
||||
bool isMoreQualifiedThan(CanQual<T> Other) const {
|
||||
return Stored.isMoreQualifiedThan(Other.Stored);
|
||||
}
|
||||
|
||||
/// \brief Determines whether this canonical type is at least as qualified as
|
||||
/// Determines whether this canonical type is at least as qualified as
|
||||
/// the @p Other canonical type.
|
||||
bool isAtLeastAsQualifiedAs(CanQual<T> Other) const {
|
||||
return Stored.isAtLeastAsQualifiedAs(Other.Stored);
|
||||
}
|
||||
|
||||
/// \brief If the canonical type is a reference type, returns the type that
|
||||
/// If the canonical type is a reference type, returns the type that
|
||||
/// it refers to; otherwise, returns the type itself.
|
||||
CanQual<Type> getNonReferenceType() const;
|
||||
|
||||
/// \brief Retrieve the internal representation of this canonical type.
|
||||
/// Retrieve the internal representation of this canonical type.
|
||||
void *getAsOpaquePtr() const { return Stored.getAsOpaquePtr(); }
|
||||
|
||||
/// \brief Construct a canonical type from its internal representation.
|
||||
/// Construct a canonical type from its internal representation.
|
||||
static CanQual<T> getFromOpaquePtr(void *Ptr);
|
||||
|
||||
/// \brief Builds a canonical type from a QualType.
|
||||
/// Builds a canonical type from a QualType.
|
||||
///
|
||||
/// This routine is inherently unsafe, because it requires the user to
|
||||
/// ensure that the given type is a canonical type with the correct
|
||||
@ -209,7 +209,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) {
|
||||
return x.getAsOpaquePtr() != y.getAsOpaquePtr();
|
||||
}
|
||||
|
||||
/// \brief Represents a canonical, potentially-qualified type.
|
||||
/// Represents a canonical, potentially-qualified type.
|
||||
using CanQualType = CanQual<Type>;
|
||||
|
||||
inline CanQualType Type::getCanonicalTypeUnqualified() const {
|
||||
@ -234,7 +234,7 @@ return CanQualType::CreateUnsafe(this->getTypePtr()->Accessor()); \
|
||||
#define LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(Type, Accessor) \
|
||||
Type Accessor() const { return this->getTypePtr()->Accessor(); }
|
||||
|
||||
/// \brief Base class of all canonical proxy types, which is responsible for
|
||||
/// Base class of all canonical proxy types, which is responsible for
|
||||
/// storing the underlying canonical type and providing basic conversions.
|
||||
template<typename T>
|
||||
class CanProxyBase {
|
||||
@ -242,10 +242,10 @@ class CanProxyBase {
|
||||
CanQual<T> Stored;
|
||||
|
||||
public:
|
||||
/// \brief Retrieve the pointer to the underlying Type
|
||||
/// Retrieve the pointer to the underlying Type
|
||||
const T *getTypePtr() const { return Stored.getTypePtr(); }
|
||||
|
||||
/// \brief Implicit conversion to the underlying pointer.
|
||||
/// Implicit conversion to the underlying pointer.
|
||||
///
|
||||
/// Also provides the ability to use canonical type proxies in a Boolean
|
||||
// context,e.g.,
|
||||
@ -254,7 +254,7 @@ class CanProxyBase {
|
||||
/// @endcode
|
||||
operator const T*() const { return this->Stored.getTypePtrOrNull(); }
|
||||
|
||||
/// \brief Try to convert the given canonical type to a specific structural
|
||||
/// Try to convert the given canonical type to a specific structural
|
||||
/// type.
|
||||
template<typename U> CanProxy<U> getAs() const {
|
||||
return this->Stored.template getAs<U>();
|
||||
@ -313,7 +313,7 @@ class CanProxyBase {
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isSpecifierType)
|
||||
LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(CXXRecordDecl*, getAsCXXRecordDecl)
|
||||
|
||||
/// \brief Retrieve the proxy-adaptor type.
|
||||
/// Retrieve the proxy-adaptor type.
|
||||
///
|
||||
/// This arrow operator is used when CanProxyAdaptor has been specialized
|
||||
/// for the given type T. In that case, we reference members of the
|
||||
@ -324,7 +324,7 @@ class CanProxyBase {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Replacable canonical proxy adaptor class that provides the link
|
||||
/// Replaceable canonical proxy adaptor class that provides the link
|
||||
/// between a canonical type and the accessors of the type.
|
||||
///
|
||||
/// The CanProxyAdaptor is a replaceable class template that is instantiated
|
||||
@ -337,7 +337,7 @@ class CanProxyBase {
|
||||
template<typename T>
|
||||
struct CanProxyAdaptor : CanProxyBase<T> {};
|
||||
|
||||
/// \brief Canonical proxy type returned when retrieving the members of a
|
||||
/// Canonical proxy type returned when retrieving the members of a
|
||||
/// canonical type or as the result of the @c CanQual<T>::getAs member
|
||||
/// function.
|
||||
///
|
||||
@ -347,13 +347,13 @@ struct CanProxyAdaptor : CanProxyBase<T> {};
|
||||
template<typename T>
|
||||
class CanProxy : public CanProxyAdaptor<T> {
|
||||
public:
|
||||
/// \brief Build a NULL proxy.
|
||||
/// Build a NULL proxy.
|
||||
CanProxy() = default;
|
||||
|
||||
/// \brief Build a proxy to the given canonical type.
|
||||
/// Build a proxy to the given canonical type.
|
||||
CanProxy(CanQual<T> Stored) { this->Stored = Stored; }
|
||||
|
||||
/// \brief Implicit conversion to the stored canonical type.
|
||||
/// Implicit conversion to the stored canonical type.
|
||||
operator CanQual<T>() const { return this->Stored; }
|
||||
};
|
||||
|
||||
@ -396,7 +396,7 @@ namespace clang {
|
||||
// Canonical proxy adaptors for canonical type nodes.
|
||||
//----------------------------------------------------------------------------//
|
||||
|
||||
/// \brief Iterator adaptor that turns an iterator over canonical QualTypes
|
||||
/// Iterator adaptor that turns an iterator over canonical QualTypes
|
||||
/// into an iterator over CanQualTypes.
|
||||
template <typename InputIterator>
|
||||
struct CanTypeIterator
|
||||
|
@ -990,7 +990,7 @@ struct DeclInfo {
|
||||
|
||||
/// CurrentDecl is the declaration with which the FullComment is associated.
|
||||
///
|
||||
/// It can be different from \c CommentDecl. It happens when we we decide
|
||||
/// It can be different from \c CommentDecl. It happens when we decide
|
||||
/// that the comment originally attached to \c CommentDecl is fine for
|
||||
/// \c CurrentDecl too (for example, for a redeclaration or an overrider of
|
||||
/// \c CommentDecl).
|
||||
|
@ -24,7 +24,7 @@ namespace comments {
|
||||
///
|
||||
/// Due to a variety of comment styles, it considers the following as "a brief
|
||||
/// description", in order of priority:
|
||||
/// \li a \\brief or \\short command,
|
||||
/// \li a \or \\short command,
|
||||
/// \li the first paragraph,
|
||||
/// \li a \\result or \\return or \\returns paragraph.
|
||||
class BriefParser {
|
||||
|
@ -26,7 +26,7 @@
|
||||
namespace clang {
|
||||
namespace comments {
|
||||
|
||||
/// \brief Information about a single command.
|
||||
/// Information about a single command.
|
||||
///
|
||||
/// When reordering, adding or removing members please update the corresponding
|
||||
/// TableGen backend.
|
||||
@ -57,7 +57,7 @@ struct CommandInfo {
|
||||
unsigned IsBlockCommand : 1;
|
||||
|
||||
/// True if this command is introducing a brief documentation
|
||||
/// paragraph (\\brief or an alias).
|
||||
/// paragraph (\or an alias).
|
||||
unsigned IsBriefCommand : 1;
|
||||
|
||||
/// True if this command is \\returns or an alias.
|
||||
@ -77,29 +77,29 @@ struct CommandInfo {
|
||||
/// True if this command is \\deprecated or an alias.
|
||||
unsigned IsDeprecatedCommand : 1;
|
||||
|
||||
/// \brief True if this is a \\headerfile-like command.
|
||||
/// True if this is a \\headerfile-like command.
|
||||
unsigned IsHeaderfileCommand : 1;
|
||||
|
||||
/// True if we don't want to warn about this command being passed an empty
|
||||
/// paragraph. Meaningful only for block commands.
|
||||
unsigned IsEmptyParagraphAllowed : 1;
|
||||
|
||||
/// \brief True if this command is a verbatim-like block command.
|
||||
/// True if this command is a verbatim-like block command.
|
||||
///
|
||||
/// A verbatim-like block command eats every character (except line starting
|
||||
/// decorations) until matching end command is seen or comment end is hit.
|
||||
unsigned IsVerbatimBlockCommand : 1;
|
||||
|
||||
/// \brief True if this command is an end command for a verbatim-like block.
|
||||
/// True if this command is an end command for a verbatim-like block.
|
||||
unsigned IsVerbatimBlockEndCommand : 1;
|
||||
|
||||
/// \brief True if this command is a verbatim line command.
|
||||
/// True if this command is a verbatim line command.
|
||||
///
|
||||
/// A verbatim-like line command eats everything until a newline is seen or
|
||||
/// comment end is hit.
|
||||
unsigned IsVerbatimLineCommand : 1;
|
||||
|
||||
/// \brief True if this command contains a declaration for the entity being
|
||||
/// True if this command contains a declaration for the entity being
|
||||
/// documented.
|
||||
///
|
||||
/// For example:
|
||||
@ -108,17 +108,17 @@ struct CommandInfo {
|
||||
/// \endcode
|
||||
unsigned IsDeclarationCommand : 1;
|
||||
|
||||
/// \brief True if verbatim-like line command is a function declaration.
|
||||
/// True if verbatim-like line command is a function declaration.
|
||||
unsigned IsFunctionDeclarationCommand : 1;
|
||||
|
||||
/// \brief True if block command is further describing a container API; such
|
||||
/// True if block command is further describing a container API; such
|
||||
/// as \@coclass, \@classdesign, etc.
|
||||
unsigned IsRecordLikeDetailCommand : 1;
|
||||
|
||||
/// \brief True if block command is a container API; such as \@interface.
|
||||
/// True if block command is a container API; such as \@interface.
|
||||
unsigned IsRecordLikeDeclarationCommand : 1;
|
||||
|
||||
/// \brief True if this command is unknown. This \c CommandInfo object was
|
||||
/// True if this command is unknown. This \c CommandInfo object was
|
||||
/// created during parsing.
|
||||
unsigned IsUnknownCommand : 1;
|
||||
};
|
||||
|
@ -52,7 +52,7 @@ enum TokenKind {
|
||||
};
|
||||
} // end namespace tok
|
||||
|
||||
/// \brief Comment token.
|
||||
/// Comment token.
|
||||
class Token {
|
||||
friend class Lexer;
|
||||
friend class TextTokenRetokenizer;
|
||||
@ -72,7 +72,7 @@ class Token {
|
||||
|
||||
/// Integer value associated with a token.
|
||||
///
|
||||
/// If the token is a konwn command, contains command ID and TextPtr is
|
||||
/// If the token is a known command, contains command ID and TextPtr is
|
||||
/// unused (command spelling can be found with CommandTraits). Otherwise,
|
||||
/// contains the length of the string that starts at TextPtr.
|
||||
unsigned IntVal;
|
||||
@ -217,7 +217,7 @@ class Token {
|
||||
void dump(const Lexer &L, const SourceManager &SM) const;
|
||||
};
|
||||
|
||||
/// \brief Comment lexer.
|
||||
/// Comment lexer.
|
||||
class Lexer {
|
||||
private:
|
||||
Lexer(const Lexer &) = delete;
|
||||
@ -281,6 +281,11 @@ class Lexer {
|
||||
/// command, including command marker.
|
||||
SmallString<16> VerbatimBlockEndCommandName;
|
||||
|
||||
/// If true, the commands, html tags, etc will be parsed and reported as
|
||||
/// separate tokens inside the comment body. If false, the comment text will
|
||||
/// be parsed into text and newline tokens.
|
||||
bool ParseCommands;
|
||||
|
||||
/// Given a character reference name (e.g., "lt"), return the character that
|
||||
/// it stands for (e.g., "<").
|
||||
StringRef resolveHTMLNamedCharacterReference(StringRef Name) const;
|
||||
@ -315,12 +320,11 @@ class Lexer {
|
||||
/// Eat string matching regexp \code \s*\* \endcode.
|
||||
void skipLineStartingDecorations();
|
||||
|
||||
/// Lex stuff inside comments. CommentEnd should be set correctly.
|
||||
/// Lex comment text, including commands if ParseCommands is set to true.
|
||||
void lexCommentText(Token &T);
|
||||
|
||||
void setupAndLexVerbatimBlock(Token &T,
|
||||
const char *TextBegin,
|
||||
char Marker, const CommandInfo *Info);
|
||||
void setupAndLexVerbatimBlock(Token &T, const char *TextBegin, char Marker,
|
||||
const CommandInfo *Info);
|
||||
|
||||
void lexVerbatimBlockFirstLine(Token &T);
|
||||
|
||||
@ -343,14 +347,13 @@ class Lexer {
|
||||
|
||||
public:
|
||||
Lexer(llvm::BumpPtrAllocator &Allocator, DiagnosticsEngine &Diags,
|
||||
const CommandTraits &Traits,
|
||||
SourceLocation FileLoc,
|
||||
const char *BufferStart, const char *BufferEnd);
|
||||
const CommandTraits &Traits, SourceLocation FileLoc,
|
||||
const char *BufferStart, const char *BufferEnd,
|
||||
bool ParseCommands = true);
|
||||
|
||||
void lex(Token &T);
|
||||
|
||||
StringRef getSpelling(const Token &Tok,
|
||||
const SourceManager &SourceMgr,
|
||||
StringRef getSpelling(const Token &Tok, const SourceManager &SourceMgr,
|
||||
bool *Invalid = nullptr) const;
|
||||
};
|
||||
|
||||
|
@ -55,7 +55,7 @@ class Sema {
|
||||
/// Contains a valid value if \c DeclInfo->IsFilled is true.
|
||||
llvm::StringMap<TParamCommandComment *> TemplateParameterDocs;
|
||||
|
||||
/// AST node for the \\brief command and its aliases.
|
||||
/// AST node for the \command and its aliases.
|
||||
const BlockCommandComment *BriefCommand;
|
||||
|
||||
/// AST node for the \\headerfile command.
|
||||
@ -187,7 +187,7 @@ class Sema {
|
||||
void checkReturnsCommand(const BlockCommandComment *Command);
|
||||
|
||||
/// Emit diagnostics about duplicate block commands that should be
|
||||
/// used only once per comment, e.g., \\brief and \\returns.
|
||||
/// used only once per comment, e.g., \and \\returns.
|
||||
void checkBlockCommandDuplicate(const BlockCommandComment *Command);
|
||||
|
||||
void checkDeprecatedCommand(const BlockCommandComment *Comment);
|
||||
|
243
include/clang/AST/ComparisonCategories.h
Normal file
243
include/clang/AST/ComparisonCategories.h
Normal file
@ -0,0 +1,243 @@
|
||||
//===- ComparisonCategories.h - Three Way Comparison Data -------*- C++ -*-===//
|
||||
//
|
||||
// The LLVM Compiler Infrastructure
|
||||
//
|
||||
// This file is distributed under the University of Illinois Open Source
|
||||
// License. See LICENSE.TXT for details.
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
//
|
||||
// This file defines the Comparison Category enum and data types, which
|
||||
// store the types and expressions needed to support operator<=>
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
#ifndef LLVM_CLANG_AST_COMPARISONCATEGORIES_H
|
||||
#define LLVM_CLANG_AST_COMPARISONCATEGORIES_H
|
||||
|
||||
#include "clang/Basic/LLVM.h"
|
||||
#include "llvm/ADT/APSInt.h"
|
||||
#include "llvm/ADT/DenseMap.h"
|
||||
#include <array>
|
||||
#include <cassert>
|
||||
|
||||
namespace llvm {
|
||||
class StringRef;
|
||||
class APSInt;
|
||||
}
|
||||
|
||||
namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
class VarDecl;
|
||||
class CXXRecordDecl;
|
||||
class Sema;
|
||||
class QualType;
|
||||
class NamespaceDecl;
|
||||
|
||||
/// An enumeration representing the different comparison categories
|
||||
/// types.
|
||||
///
|
||||
/// C++2a [cmp.categories.pre] The types weak_equality, strong_equality,
|
||||
/// partial_ordering, weak_ordering, and strong_ordering are collectively
|
||||
/// termed the comparison category types.
|
||||
enum class ComparisonCategoryType : unsigned char {
|
||||
WeakEquality,
|
||||
StrongEquality,
|
||||
PartialOrdering,
|
||||
WeakOrdering,
|
||||
StrongOrdering,
|
||||
First = WeakEquality,
|
||||
Last = StrongOrdering
|
||||
};
|
||||
|
||||
/// An enumeration representing the possible results of a three-way
|
||||
/// comparison. These values map onto instances of comparison category types
|
||||
/// defined in the standard library. e.g. 'std::strong_ordering::less'.
|
||||
enum class ComparisonCategoryResult : unsigned char {
|
||||
Equal,
|
||||
Equivalent,
|
||||
Nonequivalent,
|
||||
Nonequal,
|
||||
Less,
|
||||
Greater,
|
||||
Unordered,
|
||||
Last = Unordered
|
||||
};
|
||||
|
||||
class ComparisonCategoryInfo {
|
||||
friend class ComparisonCategories;
|
||||
friend class Sema;
|
||||
|
||||
public:
|
||||
ComparisonCategoryInfo(const ASTContext &Ctx, CXXRecordDecl *RD,
|
||||
ComparisonCategoryType Kind)
|
||||
: Ctx(Ctx), Record(RD), Kind(Kind) {}
|
||||
|
||||
struct ValueInfo {
|
||||
ComparisonCategoryResult Kind;
|
||||
VarDecl *VD;
|
||||
|
||||
ValueInfo(ComparisonCategoryResult Kind, VarDecl *VD)
|
||||
: Kind(Kind), VD(VD) {}
|
||||
|
||||
/// True iff we've successfully evaluated the variable as a constant
|
||||
/// expression and extracted its integer value.
|
||||
bool hasValidIntValue() const;
|
||||
|
||||
/// Get the constant integer value used by this variable to represent
|
||||
/// the comparison category result type.
|
||||
llvm::APSInt getIntValue() const;
|
||||
};
|
||||
private:
|
||||
const ASTContext &Ctx;
|
||||
|
||||
/// A map containing the comparison category result decls from the
|
||||
/// standard library. The key is a value of ComparisonCategoryResult.
|
||||
mutable llvm::SmallVector<
|
||||
ValueInfo, static_cast<unsigned>(ComparisonCategoryResult::Last) + 1>
|
||||
Objects;
|
||||
|
||||
/// Lookup the ValueInfo struct for the specified ValueKind. If the
|
||||
/// VarDecl for the value cannot be found, nullptr is returned.
|
||||
///
|
||||
/// If the ValueInfo does not have a valid integer value the variable
|
||||
/// is evaluated as a constant expression to determine that value.
|
||||
ValueInfo *lookupValueInfo(ComparisonCategoryResult ValueKind) const;
|
||||
|
||||
public:
|
||||
/// The declaration for the comparison category type from the
|
||||
/// standard library.
|
||||
// FIXME: Make this const
|
||||
CXXRecordDecl *Record = nullptr;
|
||||
|
||||
/// The Kind of the comparison category type
|
||||
ComparisonCategoryType Kind;
|
||||
|
||||
public:
|
||||
QualType getType() const;
|
||||
|
||||
const ValueInfo *getValueInfo(ComparisonCategoryResult ValueKind) const {
|
||||
ValueInfo *Info = lookupValueInfo(ValueKind);
|
||||
assert(Info &&
|
||||
"comparison category does not contain the specified result kind");
|
||||
assert(Info->hasValidIntValue() &&
|
||||
"couldn't determine the integer constant for this value");
|
||||
return Info;
|
||||
}
|
||||
|
||||
/// True iff the comparison category is an equality comparison.
|
||||
bool isEquality() const { return !isOrdered(); }
|
||||
|
||||
/// True iff the comparison category is a relational comparison.
|
||||
bool isOrdered() const {
|
||||
using CCK = ComparisonCategoryType;
|
||||
return Kind == CCK::PartialOrdering || Kind == CCK::WeakOrdering ||
|
||||
Kind == CCK::StrongOrdering;
|
||||
}
|
||||
|
||||
/// True iff the comparison is "strong". i.e. it checks equality and
|
||||
/// not equivalence.
|
||||
bool isStrong() const {
|
||||
using CCK = ComparisonCategoryType;
|
||||
return Kind == CCK::StrongEquality || Kind == CCK::StrongOrdering;
|
||||
}
|
||||
|
||||
/// True iff the comparison is not totally ordered.
|
||||
bool isPartial() const {
|
||||
using CCK = ComparisonCategoryType;
|
||||
return Kind == CCK::PartialOrdering;
|
||||
}
|
||||
|
||||
/// Converts the specified result kind into the the correct result kind
|
||||
/// for this category. Specifically it lowers strong equality results to
|
||||
/// weak equivalence if needed.
|
||||
ComparisonCategoryResult makeWeakResult(ComparisonCategoryResult Res) const {
|
||||
using CCR = ComparisonCategoryResult;
|
||||
if (!isStrong()) {
|
||||
if (Res == CCR::Equal)
|
||||
return CCR::Equivalent;
|
||||
if (Res == CCR::Nonequal)
|
||||
return CCR::Nonequivalent;
|
||||
}
|
||||
return Res;
|
||||
}
|
||||
|
||||
const ValueInfo *getEqualOrEquiv() const {
|
||||
return getValueInfo(makeWeakResult(ComparisonCategoryResult::Equal));
|
||||
}
|
||||
const ValueInfo *getNonequalOrNonequiv() const {
|
||||
assert(isEquality());
|
||||
return getValueInfo(makeWeakResult(ComparisonCategoryResult::Nonequal));
|
||||
}
|
||||
const ValueInfo *getLess() const {
|
||||
assert(isOrdered());
|
||||
return getValueInfo(ComparisonCategoryResult::Less);
|
||||
}
|
||||
const ValueInfo *getGreater() const {
|
||||
assert(isOrdered());
|
||||
return getValueInfo(ComparisonCategoryResult::Greater);
|
||||
}
|
||||
const ValueInfo *getUnordered() const {
|
||||
assert(isPartial());
|
||||
return getValueInfo(ComparisonCategoryResult::Unordered);
|
||||
}
|
||||
};
|
||||
|
||||
class ComparisonCategories {
|
||||
public:
|
||||
static StringRef getCategoryString(ComparisonCategoryType Kind);
|
||||
static StringRef getResultString(ComparisonCategoryResult Kind);
|
||||
|
||||
/// Return the list of results which are valid for the specified
|
||||
/// comparison category type.
|
||||
static std::vector<ComparisonCategoryResult>
|
||||
getPossibleResultsForType(ComparisonCategoryType Type);
|
||||
|
||||
/// Return the comparison category information for the category
|
||||
/// specified by 'Kind'.
|
||||
const ComparisonCategoryInfo &getInfo(ComparisonCategoryType Kind) const {
|
||||
const ComparisonCategoryInfo *Result = lookupInfo(Kind);
|
||||
assert(Result != nullptr &&
|
||||
"information for specified comparison category has not been built");
|
||||
return *Result;
|
||||
}
|
||||
|
||||
/// Return the comparison category information as specified by
|
||||
/// `getCategoryForType(Ty)`. If the information is not already cached,
|
||||
/// the declaration is looked up and a cache entry is created.
|
||||
/// NOTE: Lookup is expected to succeed. Use lookupInfo if failure is
|
||||
/// possible.
|
||||
const ComparisonCategoryInfo &getInfoForType(QualType Ty) const;
|
||||
|
||||
public:
|
||||
/// Return the cached comparison category information for the
|
||||
/// specified 'Kind'. If no cache entry is present the comparison category
|
||||
/// type is looked up. If lookup fails nullptr is returned. Otherwise, a
|
||||
/// new cache entry is created and returned
|
||||
const ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) const;
|
||||
|
||||
ComparisonCategoryInfo *lookupInfo(ComparisonCategoryType Kind) {
|
||||
const auto &This = *this;
|
||||
return const_cast<ComparisonCategoryInfo *>(This.lookupInfo(Kind));
|
||||
}
|
||||
|
||||
private:
|
||||
const ComparisonCategoryInfo *lookupInfoForType(QualType Ty) const;
|
||||
|
||||
private:
|
||||
friend class ASTContext;
|
||||
|
||||
explicit ComparisonCategories(const ASTContext &Ctx) : Ctx(Ctx) {}
|
||||
|
||||
const ASTContext &Ctx;
|
||||
|
||||
/// A map from the ComparisonCategoryType (represented as 'char') to the
|
||||
/// cached information for the specified category.
|
||||
mutable llvm::DenseMap<char, ComparisonCategoryInfo> Data;
|
||||
mutable NamespaceDecl *StdNS = nullptr;
|
||||
};
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif
|
@ -7,12 +7,12 @@
|
||||
//
|
||||
//===----------------------------------------------------------------------===//
|
||||
/// \file
|
||||
/// \brief This file declares helper methods for collecting data from AST nodes.
|
||||
/// This file declares helper methods for collecting data from AST nodes.
|
||||
///
|
||||
/// To collect data from Stmt nodes, subclass ConstStmtVisitor and include
|
||||
/// StmtDataCollectors.inc after defining the macros that you need. This
|
||||
/// provides data collection implementations for most Stmt kinds. Note
|
||||
/// that that code requires some conditions to be met:
|
||||
/// that the code requires some conditions to be met:
|
||||
///
|
||||
/// - There must be a method addData(const T &Data) that accepts strings,
|
||||
/// integral types as well as QualType. All data is forwarded using
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -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 <algorithm>
|
||||
#include <cassert>
|
||||
#include <cstddef>
|
||||
@ -67,7 +67,7 @@ class TemplateDecl;
|
||||
class TranslationUnitDecl;
|
||||
class UsingDirectiveDecl;
|
||||
|
||||
/// \brief Captures the result of checking the availability of a
|
||||
/// Captures the result of checking the availability of a
|
||||
/// declaration.
|
||||
enum AvailabilityResult {
|
||||
AR_Available = 0,
|
||||
@ -83,9 +83,9 @@ 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:
|
||||
/// \brief Lists the kind of concrete classes of Decl.
|
||||
/// Lists the kind of concrete classes of Decl.
|
||||
enum Kind {
|
||||
#define DECL(DERIVED, BASE) DERIVED,
|
||||
#define ABSTRACT_DECL(DECL)
|
||||
@ -96,7 +96,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
#include "clang/AST/DeclNodes.inc"
|
||||
};
|
||||
|
||||
/// \brief A placeholder type used to construct an empty shell of a
|
||||
/// A placeholder type used to construct an empty shell of a
|
||||
/// decl-derived type that will be filled in later (e.g., by some
|
||||
/// deserialization method).
|
||||
struct EmptyShell {};
|
||||
@ -231,7 +231,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
};
|
||||
|
||||
protected:
|
||||
/// \brief The next declaration within the same lexical
|
||||
/// The next declaration within the same lexical
|
||||
/// DeclContext. These pointers form the linked list that is
|
||||
/// traversed via DeclContext's decls_begin()/decls_end().
|
||||
///
|
||||
@ -288,27 +288,28 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// the implementation rather than explicitly written by the user.
|
||||
unsigned Implicit : 1;
|
||||
|
||||
/// \brief Whether this declaration was "used", meaning that a definition is
|
||||
/// Whether this declaration was "used", meaning that a definition is
|
||||
/// required.
|
||||
unsigned Used : 1;
|
||||
|
||||
/// \brief Whether this declaration was "referenced".
|
||||
/// Whether this declaration was "referenced".
|
||||
/// The difference with 'Used' is whether the reference appears in a
|
||||
/// evaluated context or not, e.g. functions used in uninstantiated templates
|
||||
/// are regarded as "referenced" but not "used".
|
||||
unsigned Referenced : 1;
|
||||
|
||||
/// \brief Whether this declaration is a top-level declaration (function,
|
||||
/// Whether this declaration is a top-level declaration (function,
|
||||
/// global variable, etc.) that is lexically inside an objc container
|
||||
/// definition.
|
||||
unsigned TopLevelDeclInObjCContainer : 1;
|
||||
|
||||
/// \brief Whether statistic collection is enabled.
|
||||
/// Whether statistic collection is enabled.
|
||||
static bool StatisticsEnabled;
|
||||
|
||||
protected:
|
||||
friend class ASTDeclReader;
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTNodeImporter;
|
||||
friend class ASTReader;
|
||||
friend class CXXClassMemberWrapper;
|
||||
friend class LinkageComputer;
|
||||
@ -318,17 +319,17 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
// NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum
|
||||
unsigned Access : 2;
|
||||
|
||||
/// \brief Whether this declaration was loaded from an AST file.
|
||||
/// Whether this declaration was loaded from an AST file.
|
||||
unsigned FromASTFile : 1;
|
||||
|
||||
/// IdentifierNamespace - This specifies what IDNS_* namespace this lives in.
|
||||
unsigned IdentifierNamespace : 13;
|
||||
|
||||
/// \brief If 0, we have not computed the linkage of this declaration.
|
||||
/// If 0, we have not computed the linkage of this declaration.
|
||||
/// Otherwise, it is the linkage + 1.
|
||||
mutable unsigned CacheValidAndLinkage : 3;
|
||||
|
||||
/// \brief Allocate memory for a deserialized declaration.
|
||||
/// Allocate memory for a deserialized declaration.
|
||||
///
|
||||
/// This routine must be used to allocate memory for any declaration that is
|
||||
/// deserialized from a module file.
|
||||
@ -340,7 +341,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
void *operator new(std::size_t Size, const ASTContext &Ctx, unsigned ID,
|
||||
std::size_t Extra = 0);
|
||||
|
||||
/// \brief Allocate memory for a non-deserialized declaration.
|
||||
/// Allocate memory for a non-deserialized declaration.
|
||||
void *operator new(std::size_t Size, const ASTContext &Ctx,
|
||||
DeclContext *Parent, std::size_t Extra = 0);
|
||||
|
||||
@ -384,7 +385,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
|
||||
virtual ~Decl();
|
||||
|
||||
/// \brief Update a potentially out-of-date declaration.
|
||||
/// Update a potentially out-of-date declaration.
|
||||
void updateOutOfDate(IdentifierInfo &II) const;
|
||||
|
||||
Linkage getCachedLinkage() const {
|
||||
@ -400,7 +401,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Source range that this declaration covers.
|
||||
/// Source range that this declaration covers.
|
||||
virtual SourceRange getSourceRange() const LLVM_READONLY {
|
||||
return SourceRange(getLocation(), getLocation());
|
||||
}
|
||||
@ -462,7 +463,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
return AccessSpecifier(Access);
|
||||
}
|
||||
|
||||
/// \brief Retrieve the access specifier for this declaration, even though
|
||||
/// Retrieve the access specifier for this declaration, even though
|
||||
/// it may not yet have been properly set.
|
||||
AccessSpecifier getAccessUnsafe() const {
|
||||
return AccessSpecifier(Access);
|
||||
@ -551,7 +552,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
bool isImplicit() const { return Implicit; }
|
||||
void setImplicit(bool I = true) { Implicit = I; }
|
||||
|
||||
/// \brief Whether *any* (re-)declaration of the entity was used, meaning that
|
||||
/// Whether *any* (re-)declaration of the entity was used, meaning that
|
||||
/// a definition is required.
|
||||
///
|
||||
/// \param CheckUsedAttr When true, also consider the "used" attribute
|
||||
@ -559,28 +560,28 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// whether the function is used.
|
||||
bool isUsed(bool CheckUsedAttr = true) const;
|
||||
|
||||
/// \brief Set whether the declaration is used, in the sense of odr-use.
|
||||
/// Set whether the declaration is used, in the sense of odr-use.
|
||||
///
|
||||
/// This should only be used immediately after creating a declaration.
|
||||
/// It intentionally doesn't notify any listeners.
|
||||
void setIsUsed() { getCanonicalDecl()->Used = true; }
|
||||
|
||||
/// \brief Mark the declaration used, in the sense of odr-use.
|
||||
/// Mark the declaration used, in the sense of odr-use.
|
||||
///
|
||||
/// This notifies any mutation listeners in addition to setting a bit
|
||||
/// indicating the declaration is used.
|
||||
void markUsed(ASTContext &C);
|
||||
|
||||
/// \brief Whether any declaration of this entity was referenced.
|
||||
/// Whether any declaration of this entity was referenced.
|
||||
bool isReferenced() const;
|
||||
|
||||
/// \brief Whether this declaration was referenced. This should not be relied
|
||||
/// Whether this declaration was referenced. This should not be relied
|
||||
/// upon for anything other than debugging.
|
||||
bool isThisDeclarationReferenced() const { return Referenced; }
|
||||
|
||||
void setReferenced(bool R = true) { Referenced = R; }
|
||||
|
||||
/// \brief Whether this declaration is a top-level declaration (function,
|
||||
/// Whether this declaration is a top-level declaration (function,
|
||||
/// global variable, etc.) that is lexically inside an objc container
|
||||
/// definition.
|
||||
bool isTopLevelDeclInObjCContainer() const {
|
||||
@ -591,17 +592,17 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
TopLevelDeclInObjCContainer = V;
|
||||
}
|
||||
|
||||
/// \brief Looks on this and related declarations for an applicable
|
||||
/// Looks on this and related declarations for an applicable
|
||||
/// external source symbol attribute.
|
||||
ExternalSourceSymbolAttr *getExternalSourceSymbolAttr() const;
|
||||
|
||||
/// \brief Whether this declaration was marked as being private to the
|
||||
/// Whether this declaration was marked as being private to the
|
||||
/// module in which it was defined.
|
||||
bool isModulePrivate() const {
|
||||
return getModuleOwnershipKind() == ModuleOwnershipKind::ModulePrivate;
|
||||
}
|
||||
|
||||
/// \brief Whether this declaration is exported (by virtue of being lexically
|
||||
/// Whether this declaration is exported (by virtue of being lexically
|
||||
/// within an ExportDecl or by being a NamespaceDecl).
|
||||
bool isExported() const;
|
||||
|
||||
@ -613,7 +614,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
const Attr *getDefiningAttr() const;
|
||||
|
||||
protected:
|
||||
/// \brief Specify that this declaration was marked as being private
|
||||
/// Specify that this declaration was marked as being private
|
||||
/// to the module in which it was defined.
|
||||
void setModulePrivate() {
|
||||
// The module-private specifier has no effect on unowned declarations.
|
||||
@ -623,14 +624,14 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
setModuleOwnershipKind(ModuleOwnershipKind::ModulePrivate);
|
||||
}
|
||||
|
||||
/// \brief Set the owning module ID.
|
||||
/// Set the owning module ID.
|
||||
void setOwningModuleID(unsigned ID) {
|
||||
assert(isFromASTFile() && "Only works on a deserialized declaration");
|
||||
*((unsigned*)this - 2) = ID;
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Determine the availability of the given declaration.
|
||||
/// Determine the availability of the given declaration.
|
||||
///
|
||||
/// This routine will determine the most restrictive availability of
|
||||
/// the given declaration (e.g., preferring 'unavailable' to
|
||||
@ -643,11 +644,16 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
///
|
||||
/// \param EnclosingVersion The version to compare with. If empty, assume the
|
||||
/// deployment target version.
|
||||
///
|
||||
/// \param RealizedPlatform If non-NULL and the availability result is found
|
||||
/// in an available attribute it will set to the platform which is written in
|
||||
/// the available attribute.
|
||||
AvailabilityResult
|
||||
getAvailability(std::string *Message = nullptr,
|
||||
VersionTuple EnclosingVersion = VersionTuple()) const;
|
||||
VersionTuple EnclosingVersion = VersionTuple(),
|
||||
StringRef *RealizedPlatform = nullptr) const;
|
||||
|
||||
/// \brief Retrieve the version of the target platform in which this
|
||||
/// Retrieve the version of the target platform in which this
|
||||
/// declaration was introduced.
|
||||
///
|
||||
/// \returns An empty version tuple if this declaration has no 'introduced'
|
||||
@ -655,7 +661,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// attribute otherwise.
|
||||
VersionTuple getVersionIntroduced() const;
|
||||
|
||||
/// \brief Determine whether this declaration is marked 'deprecated'.
|
||||
/// Determine whether this declaration is marked 'deprecated'.
|
||||
///
|
||||
/// \param Message If non-NULL and the declaration is deprecated,
|
||||
/// this will be set to the message describing why the declaration
|
||||
@ -664,7 +670,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
return getAvailability(Message) == AR_Deprecated;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this declaration is marked 'unavailable'.
|
||||
/// Determine whether this declaration is marked 'unavailable'.
|
||||
///
|
||||
/// \param Message If non-NULL and the declaration is unavailable,
|
||||
/// this will be set to the message describing why the declaration
|
||||
@ -673,7 +679,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
return getAvailability(Message) == AR_Unavailable;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this is a weak-imported symbol.
|
||||
/// Determine whether this is a weak-imported symbol.
|
||||
///
|
||||
/// Weak-imported symbols are typically marked with the
|
||||
/// 'weak_import' attribute, but may also be marked with an
|
||||
@ -681,7 +687,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// the introduction of this feature.
|
||||
bool isWeakImported() const;
|
||||
|
||||
/// \brief Determines whether this symbol can be weak-imported,
|
||||
/// Determines whether this symbol can be weak-imported,
|
||||
/// e.g., whether it would be well-formed to add the weak_import
|
||||
/// attribute.
|
||||
///
|
||||
@ -689,11 +695,11 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// declaration cannot be weak-imported because it has a definition.
|
||||
bool canBeWeakImported(bool &IsDefinition) const;
|
||||
|
||||
/// \brief Determine whether this declaration came from an AST file (such as
|
||||
/// Determine whether this declaration came from an AST file (such as
|
||||
/// a precompiled header or module) rather than having been parsed.
|
||||
bool isFromASTFile() const { return FromASTFile; }
|
||||
|
||||
/// \brief Retrieve the global declaration ID associated with this
|
||||
/// Retrieve the global declaration ID associated with this
|
||||
/// declaration, which specifies where this Decl was loaded from.
|
||||
unsigned getGlobalID() const {
|
||||
if (isFromASTFile())
|
||||
@ -701,7 +707,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
return 0;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the global ID of the module that owns this particular
|
||||
/// Retrieve the global ID of the module that owns this particular
|
||||
/// declaration.
|
||||
unsigned getOwningModuleID() const {
|
||||
if (isFromASTFile())
|
||||
@ -716,7 +722,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
bool hasLocalOwningModuleStorage() const;
|
||||
|
||||
public:
|
||||
/// \brief Get the imported owning module, if this decl is from an imported
|
||||
/// Get the imported owning module, if this decl is from an imported
|
||||
/// (non-local) module.
|
||||
Module *getImportedOwningModule() const {
|
||||
if (!isFromASTFile() || !hasOwningModule())
|
||||
@ -725,7 +731,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
return getOwningModuleSlow();
|
||||
}
|
||||
|
||||
/// \brief Get the local owning module, if known. Returns nullptr if owner is
|
||||
/// Get the local owning module, if known. Returns nullptr if owner is
|
||||
/// not yet known or declaration is not from a module.
|
||||
Module *getLocalOwningModule() const {
|
||||
if (isFromASTFile() || !hasOwningModule())
|
||||
@ -759,7 +765,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// all declarations in a global module fragment are unowned.
|
||||
Module *getOwningModuleForLinkage(bool IgnoreLinkage = false) const;
|
||||
|
||||
/// \brief Determine whether this declaration might be hidden from name
|
||||
/// Determine whether this declaration might be hidden from name
|
||||
/// lookup. Note that the declaration might be visible even if this returns
|
||||
/// \c false, if the owning module is visible within the query context.
|
||||
// FIXME: Rename this to make it clearer what it does.
|
||||
@ -774,12 +780,12 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
setModuleOwnershipKind(ModuleOwnershipKind::Visible);
|
||||
}
|
||||
|
||||
/// \brief Get the kind of module ownership for this declaration.
|
||||
/// Get the kind of module ownership for this declaration.
|
||||
ModuleOwnershipKind getModuleOwnershipKind() const {
|
||||
return NextInContextAndBits.getInt();
|
||||
}
|
||||
|
||||
/// \brief Set whether this declaration is hidden from name lookup.
|
||||
/// Set whether this declaration is hidden from name lookup.
|
||||
void setModuleOwnershipKind(ModuleOwnershipKind MOK) {
|
||||
assert(!(getModuleOwnershipKind() == ModuleOwnershipKind::Unowned &&
|
||||
MOK != ModuleOwnershipKind::Unowned && !isFromASTFile() &&
|
||||
@ -836,6 +842,10 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
|
||||
void setLexicalDeclContext(DeclContext *DC);
|
||||
|
||||
/// Determine whether this declaration is a templated entity (whether it is
|
||||
// within the scope of a template parameter).
|
||||
bool isTemplated() const;
|
||||
|
||||
/// isDefinedOutsideFunctionOrMethod - This predicate returns true if this
|
||||
/// scoped decl is defined outside the current function or method. This is
|
||||
/// roughly global variables and functions, but also handles enums (which
|
||||
@ -844,7 +854,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
return getParentFunctionOrMethod() == nullptr;
|
||||
}
|
||||
|
||||
/// \brief Returns true if this declaration lexically is inside a function.
|
||||
/// Returns true if this declaration lexically is inside a function.
|
||||
/// It recognizes non-defining declarations as well as members of local
|
||||
/// classes:
|
||||
/// \code
|
||||
@ -853,7 +863,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// \endcode
|
||||
bool isLexicallyWithinFunctionOrMethod() const;
|
||||
|
||||
/// \brief If this decl is defined inside a function/method/block it returns
|
||||
/// If this decl is defined inside a function/method/block it returns
|
||||
/// the corresponding DeclContext, otherwise it returns null.
|
||||
const DeclContext *getParentFunctionOrMethod() const;
|
||||
DeclContext *getParentFunctionOrMethod() {
|
||||
@ -861,32 +871,32 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
const_cast<const Decl*>(this)->getParentFunctionOrMethod());
|
||||
}
|
||||
|
||||
/// \brief Retrieves the "canonical" declaration of the given declaration.
|
||||
/// Retrieves the "canonical" declaration of the given declaration.
|
||||
virtual Decl *getCanonicalDecl() { return this; }
|
||||
const Decl *getCanonicalDecl() const {
|
||||
return const_cast<Decl*>(this)->getCanonicalDecl();
|
||||
}
|
||||
|
||||
/// \brief Whether this particular Decl is a canonical one.
|
||||
/// Whether this particular Decl is a canonical one.
|
||||
bool isCanonicalDecl() const { return getCanonicalDecl() == this; }
|
||||
|
||||
protected:
|
||||
/// \brief Returns the next redeclaration or itself if this is the only decl.
|
||||
/// Returns the next redeclaration or itself if this is the only decl.
|
||||
///
|
||||
/// Decl subclasses that can be redeclared should override this method so that
|
||||
/// Decl::redecl_iterator can iterate over them.
|
||||
virtual Decl *getNextRedeclarationImpl() { return this; }
|
||||
|
||||
/// \brief Implementation of getPreviousDecl(), to be overridden by any
|
||||
/// Implementation of getPreviousDecl(), to be overridden by any
|
||||
/// subclass that has a redeclaration chain.
|
||||
virtual Decl *getPreviousDeclImpl() { return nullptr; }
|
||||
|
||||
/// \brief Implementation of getMostRecentDecl(), to be overridden by any
|
||||
/// Implementation of getMostRecentDecl(), to be overridden by any
|
||||
/// subclass that has a redeclaration chain.
|
||||
virtual Decl *getMostRecentDeclImpl() { return this; }
|
||||
|
||||
public:
|
||||
/// \brief Iterates through all the redeclarations of the same decl.
|
||||
/// Iterates through all the redeclarations of the same decl.
|
||||
class redecl_iterator {
|
||||
/// Current - The current declaration.
|
||||
Decl *Current = nullptr;
|
||||
@ -931,7 +941,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
|
||||
using redecl_range = llvm::iterator_range<redecl_iterator>;
|
||||
|
||||
/// \brief Returns an iterator range for all the redeclarations of the same
|
||||
/// Returns an iterator range for all the redeclarations of the same
|
||||
/// decl. It will iterate at least once (when this decl is the only one).
|
||||
redecl_range redecls() const {
|
||||
return redecl_range(redecls_begin(), redecls_end());
|
||||
@ -943,26 +953,26 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
|
||||
redecl_iterator redecls_end() const { return redecl_iterator(); }
|
||||
|
||||
/// \brief Retrieve the previous declaration that declares the same entity
|
||||
/// Retrieve the previous declaration that declares the same entity
|
||||
/// as this declaration, or NULL if there is no previous declaration.
|
||||
Decl *getPreviousDecl() { return getPreviousDeclImpl(); }
|
||||
|
||||
/// \brief Retrieve the most recent declaration that declares the same entity
|
||||
/// 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 {
|
||||
return const_cast<Decl *>(this)->getPreviousDeclImpl();
|
||||
}
|
||||
|
||||
/// \brief True if this is the first declaration in its redeclaration chain.
|
||||
/// True if this is the first declaration in its redeclaration chain.
|
||||
bool isFirstDecl() const {
|
||||
return getPreviousDecl() == nullptr;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the most recent declaration that declares the same entity
|
||||
/// Retrieve the most recent declaration that declares the same entity
|
||||
/// as this declaration (which may be this declaration).
|
||||
Decl *getMostRecentDecl() { return getMostRecentDeclImpl(); }
|
||||
|
||||
/// \brief Retrieve the most recent declaration that declares the same entity
|
||||
/// Retrieve the most recent declaration that declares the same entity
|
||||
/// as this declaration (which may be this declaration).
|
||||
const Decl *getMostRecentDecl() const {
|
||||
return const_cast<Decl *>(this)->getMostRecentDeclImpl();
|
||||
@ -973,7 +983,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// top-level Stmt* of that body. Otherwise this method returns null.
|
||||
virtual Stmt* getBody() const { return nullptr; }
|
||||
|
||||
/// \brief Returns true if this \c Decl represents a declaration for a body of
|
||||
/// Returns true if this \c Decl represents a declaration for a body of
|
||||
/// code, such as a function or method definition.
|
||||
/// Note that \c hasBody can also return true if any redeclaration of this
|
||||
/// \c Decl represents a declaration for a body of code.
|
||||
@ -996,24 +1006,24 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
/// template parameter pack.
|
||||
bool isTemplateParameterPack() const;
|
||||
|
||||
/// \brief Whether this declaration is a parameter pack.
|
||||
/// Whether this declaration is a parameter pack.
|
||||
bool isParameterPack() const;
|
||||
|
||||
/// \brief returns true if this declaration is a template
|
||||
/// returns true if this declaration is a template
|
||||
bool isTemplateDecl() const;
|
||||
|
||||
/// \brief Whether this declaration is a function or function template.
|
||||
/// Whether this declaration is a function or function template.
|
||||
bool isFunctionOrFunctionTemplate() const {
|
||||
return (DeclKind >= Decl::firstFunction &&
|
||||
DeclKind <= Decl::lastFunction) ||
|
||||
DeclKind == FunctionTemplate;
|
||||
}
|
||||
|
||||
/// \brief If this is a declaration that describes some template, this
|
||||
/// If this is a declaration that describes some template, this
|
||||
/// method returns that template declaration.
|
||||
TemplateDecl *getDescribedTemplate() const;
|
||||
|
||||
/// \brief Returns the function itself, or the templated function if this is a
|
||||
/// Returns the function itself, or the templated function if this is a
|
||||
/// function template.
|
||||
FunctionDecl *getAsFunction() LLVM_READONLY;
|
||||
|
||||
@ -1021,7 +1031,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
return const_cast<Decl *>(this)->getAsFunction();
|
||||
}
|
||||
|
||||
/// \brief Changes the namespace of this declaration to reflect that it's
|
||||
/// Changes the namespace of this declaration to reflect that it's
|
||||
/// a function-local extern declaration.
|
||||
///
|
||||
/// These declarations appear in the lexical context of the extern
|
||||
@ -1042,14 +1052,14 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
IdentifierNamespace |= IDNS_Ordinary;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this is a block-scope declaration with linkage.
|
||||
/// Determine whether this is a block-scope declaration with linkage.
|
||||
/// This will either be a local variable declaration declared 'extern', or a
|
||||
/// local function declaration.
|
||||
bool isLocalExternDecl() {
|
||||
return IdentifierNamespace & IDNS_LocalExtern;
|
||||
}
|
||||
|
||||
/// \brief Changes the namespace of this declaration to reflect that it's
|
||||
/// Changes the namespace of this declaration to reflect that it's
|
||||
/// the object of a friend declaration.
|
||||
///
|
||||
/// These declarations appear in the lexical context of the friending
|
||||
@ -1091,7 +1101,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
FOK_Undeclared ///< A friend of a previously-undeclared entity.
|
||||
};
|
||||
|
||||
/// \brief Determines whether this declaration is the object of a
|
||||
/// Determines whether this declaration is the object of a
|
||||
/// friend declaration and, if so, what kind.
|
||||
///
|
||||
/// There is currently no direct way to find the associated FriendDecl.
|
||||
@ -1131,7 +1141,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
|
||||
void dump(raw_ostream &Out, bool Deserialize = false) const;
|
||||
|
||||
/// \brief Looks through the Decl's underlying type to extract a FunctionType
|
||||
/// Looks through the Decl's underlying type to extract a FunctionType
|
||||
/// when possible. Will return null if the type underlying the Decl does not
|
||||
/// have a FunctionType.
|
||||
const FunctionType *getFunctionType(bool BlocksToo = true) const;
|
||||
@ -1145,7 +1155,7 @@ class LLVM_ALIGNAS(/*alignof(uint64_t)*/ 8) Decl {
|
||||
ASTMutationListener *getASTMutationListener() const;
|
||||
};
|
||||
|
||||
/// \brief Determine whether two declarations declare the same entity.
|
||||
/// Determine whether two declarations declare the same entity.
|
||||
inline bool declaresSameEntity(const Decl *D1, const Decl *D2) {
|
||||
if (!D1 || !D2)
|
||||
return false;
|
||||
@ -1172,7 +1182,7 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry {
|
||||
void print(raw_ostream &OS) const override;
|
||||
};
|
||||
|
||||
/// \brief The results of name lookup within a DeclContext. This is either a
|
||||
/// The results of name lookup within a DeclContext. This is either a
|
||||
/// single result (with no stable storage) or a collection of results (with
|
||||
/// stable storage provided by the lookup table).
|
||||
class DeclContextLookupResult {
|
||||
@ -1253,36 +1263,36 @@ class DeclContext {
|
||||
/// DeclKind - This indicates which class this is.
|
||||
unsigned DeclKind : 8;
|
||||
|
||||
/// \brief Whether this declaration context also has some external
|
||||
/// Whether this declaration context also has some external
|
||||
/// storage that contains additional declarations that are lexically
|
||||
/// part of this context.
|
||||
mutable bool ExternalLexicalStorage : 1;
|
||||
|
||||
/// \brief Whether this declaration context also has some external
|
||||
/// Whether this declaration context also has some external
|
||||
/// storage that contains additional declarations that are visible
|
||||
/// in this context.
|
||||
mutable bool ExternalVisibleStorage : 1;
|
||||
|
||||
/// \brief Whether this declaration context has had external visible
|
||||
/// 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;
|
||||
|
||||
/// \brief If \c true, this context may have local lexical declarations
|
||||
/// If \c true, this context may have local lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
mutable bool HasLazyLocalLexicalLookups : 1;
|
||||
|
||||
/// \brief If \c true, the external source may have lexical declarations
|
||||
/// If \c true, the external source may have lexical declarations
|
||||
/// that are missing from the lookup table.
|
||||
mutable bool HasLazyExternalLexicalLookups : 1;
|
||||
|
||||
/// \brief If \c true, lookups should only return identifier from
|
||||
/// If \c true, lookups should only return identifier from
|
||||
/// DeclContext scope (for example TranslationUnit). Used in
|
||||
/// LookupQualifiedName()
|
||||
mutable bool UseQualifiedLookup : 1;
|
||||
|
||||
/// \brief Pointer to the data structure used to lookup declarations
|
||||
/// Pointer to the data structure used to lookup declarations
|
||||
/// within this context (or a DependentStoredDeclsMap if this is a
|
||||
/// dependent context). We maintain the invariant that, if the map
|
||||
/// contains an entry for a DeclarationName (and we haven't lazily
|
||||
@ -1305,7 +1315,7 @@ class DeclContext {
|
||||
/// another pointer.
|
||||
mutable Decl *LastDecl = nullptr;
|
||||
|
||||
/// \brief Build up a chain of declarations.
|
||||
/// Build up a chain of declarations.
|
||||
///
|
||||
/// \returns the first/last pair of declarations.
|
||||
static std::pair<Decl *, Decl *>
|
||||
@ -1388,7 +1398,7 @@ class DeclContext {
|
||||
}
|
||||
}
|
||||
|
||||
/// \brief Test whether the context supports looking up names.
|
||||
/// Test whether the context supports looking up names.
|
||||
bool isLookupContext() const {
|
||||
return !isFunctionOrMethod() && DeclKind != Decl::LinkageSpec &&
|
||||
DeclKind != Decl::Export;
|
||||
@ -1414,7 +1424,7 @@ class DeclContext {
|
||||
|
||||
bool isInlineNamespace() const;
|
||||
|
||||
/// \brief Determines whether this context is dependent on a
|
||||
/// Determines whether this context is dependent on a
|
||||
/// template parameter.
|
||||
bool isDependentContext() const;
|
||||
|
||||
@ -1435,28 +1445,28 @@ class DeclContext {
|
||||
/// C++0x scoped enums), and C++ linkage specifications.
|
||||
bool isTransparentContext() const;
|
||||
|
||||
/// \brief Determines whether this context or some of its ancestors is a
|
||||
/// Determines whether this context or some of its ancestors is a
|
||||
/// linkage specification context that specifies C linkage.
|
||||
bool isExternCContext() const;
|
||||
|
||||
/// \brief Retrieve the nearest enclosing C linkage specification context.
|
||||
/// Retrieve the nearest enclosing C linkage specification context.
|
||||
const LinkageSpecDecl *getExternCContext() const;
|
||||
|
||||
/// \brief Determines whether this context or some of its ancestors is a
|
||||
/// Determines whether this context or some of its ancestors is a
|
||||
/// linkage specification context that specifies C++ linkage.
|
||||
bool isExternCXXContext() const;
|
||||
|
||||
/// \brief Determine whether this declaration context is equivalent
|
||||
/// Determine whether this declaration context is equivalent
|
||||
/// to the declaration context DC.
|
||||
bool Equals(const DeclContext *DC) const {
|
||||
return DC && this->getPrimaryContext() == DC->getPrimaryContext();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this declaration context encloses the
|
||||
/// Determine whether this declaration context encloses the
|
||||
/// declaration context DC.
|
||||
bool Encloses(const DeclContext *DC) const;
|
||||
|
||||
/// \brief Find the nearest non-closure ancestor of this context,
|
||||
/// Find the nearest non-closure ancestor of this context,
|
||||
/// i.e. the innermost semantic parent of this context which is not
|
||||
/// a closure. A context may be its own non-closure ancestor.
|
||||
Decl *getNonClosureAncestor();
|
||||
@ -1483,19 +1493,19 @@ class DeclContext {
|
||||
return const_cast<DeclContext *>(this)->getRedeclContext();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the nearest enclosing namespace context.
|
||||
/// Retrieve the nearest enclosing namespace context.
|
||||
DeclContext *getEnclosingNamespaceContext();
|
||||
const DeclContext *getEnclosingNamespaceContext() const {
|
||||
return const_cast<DeclContext *>(this)->getEnclosingNamespaceContext();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the outermost lexically enclosing record context.
|
||||
/// Retrieve the outermost lexically enclosing record context.
|
||||
RecordDecl *getOuterLexicalRecordContext();
|
||||
const RecordDecl *getOuterLexicalRecordContext() const {
|
||||
return const_cast<DeclContext *>(this)->getOuterLexicalRecordContext();
|
||||
}
|
||||
|
||||
/// \brief Test if this context is part of the enclosing namespace set of
|
||||
/// Test if this context is part of the enclosing namespace set of
|
||||
/// the context NS, as defined in C++0x [namespace.def]p9. If either context
|
||||
/// isn't a namespace, this is equivalent to Equals().
|
||||
///
|
||||
@ -1503,7 +1513,7 @@ class DeclContext {
|
||||
/// inline, its enclosing namespace, recursively.
|
||||
bool InEnclosingNamespaceSetOf(const DeclContext *NS) const;
|
||||
|
||||
/// \brief Collects all of the declaration contexts that are semantically
|
||||
/// Collects all of the declaration contexts that are semantically
|
||||
/// connected to this declaration context.
|
||||
///
|
||||
/// For declaration contexts that have multiple semantically connected but
|
||||
@ -1659,7 +1669,7 @@ class DeclContext {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Iterates over a filtered subrange of declarations stored
|
||||
/// Iterates over a filtered subrange of declarations stored
|
||||
/// in a DeclContext.
|
||||
///
|
||||
/// This iterator visits only those declarations that are of type
|
||||
@ -1735,7 +1745,7 @@ class DeclContext {
|
||||
}
|
||||
};
|
||||
|
||||
/// @brief Add the declaration D into this context.
|
||||
/// Add the declaration D into this context.
|
||||
///
|
||||
/// This routine should be invoked when the declaration D has first
|
||||
/// been declared, to place D into the context where it was
|
||||
@ -1749,7 +1759,7 @@ class DeclContext {
|
||||
/// semantic context via makeDeclVisibleInContext.
|
||||
void addDecl(Decl *D);
|
||||
|
||||
/// @brief Add the declaration D into this context, but suppress
|
||||
/// Add the declaration D into this context, but suppress
|
||||
/// searches for external declarations with the same name.
|
||||
///
|
||||
/// Although analogous in function to addDecl, this removes an
|
||||
@ -1759,7 +1769,7 @@ class DeclContext {
|
||||
/// See the ASTImporter for use cases.
|
||||
void addDeclInternal(Decl *D);
|
||||
|
||||
/// @brief Add the declaration D to this context without modifying
|
||||
/// Add the declaration D to this context without modifying
|
||||
/// any lookup tables.
|
||||
///
|
||||
/// This is useful for some operations in dependent contexts where
|
||||
@ -1767,12 +1777,16 @@ class DeclContext {
|
||||
/// only happens with friends.
|
||||
void addHiddenDecl(Decl *D);
|
||||
|
||||
/// @brief Removes a declaration from this context.
|
||||
/// Removes a declaration from this context.
|
||||
void removeDecl(Decl *D);
|
||||
|
||||
/// @brief Checks whether a declaration is in this context.
|
||||
|
||||
/// 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;
|
||||
|
||||
@ -1783,12 +1797,12 @@ class DeclContext {
|
||||
/// routine will not look into parent contexts.
|
||||
lookup_result lookup(DeclarationName Name) const;
|
||||
|
||||
/// \brief Find the declarations with the given name that are visible
|
||||
/// Find the declarations with the given name that are visible
|
||||
/// within this context; don't attempt to retrieve anything from an
|
||||
/// external source.
|
||||
lookup_result noload_lookup(DeclarationName Name);
|
||||
|
||||
/// \brief A simplistic name lookup mechanism that performs name lookup
|
||||
/// A simplistic name lookup mechanism that performs name lookup
|
||||
/// into this declaration context without consulting the external source.
|
||||
///
|
||||
/// This function should almost never be used, because it subverts the
|
||||
@ -1800,7 +1814,7 @@ class DeclContext {
|
||||
void localUncachedLookup(DeclarationName Name,
|
||||
SmallVectorImpl<NamedDecl *> &Results);
|
||||
|
||||
/// @brief Makes a declaration visible within this context.
|
||||
/// Makes a declaration visible within this context.
|
||||
///
|
||||
/// This routine makes the declaration D visible to name lookup
|
||||
/// within this context and, if this is a transparent context,
|
||||
@ -1823,13 +1837,15 @@ class DeclContext {
|
||||
using lookups_range = llvm::iterator_range<all_lookups_iterator>;
|
||||
|
||||
lookups_range lookups() const;
|
||||
lookups_range noload_lookups() const;
|
||||
// Like lookups(), but avoids loading external declarations.
|
||||
// If PreserveInternalState, avoids building lookup data structures too.
|
||||
lookups_range noload_lookups(bool PreserveInternalState) const;
|
||||
|
||||
/// \brief Iterators over all possible lookups within this context.
|
||||
/// Iterators over all possible lookups within this context.
|
||||
all_lookups_iterator lookups_begin() const;
|
||||
all_lookups_iterator lookups_end() const;
|
||||
|
||||
/// \brief Iterators over all possible lookups within this context that are
|
||||
/// Iterators over all possible lookups within this context that are
|
||||
/// currently loaded; don't attempt to retrieve anything from an external
|
||||
/// source.
|
||||
all_lookups_iterator noload_lookups_begin() const;
|
||||
@ -1861,7 +1877,7 @@ class DeclContext {
|
||||
|
||||
// Low-level accessors
|
||||
|
||||
/// \brief Mark that there are external lexical declarations that we need
|
||||
/// Mark that there are external lexical declarations that we need
|
||||
/// to include in our lookup table (and that are not available as external
|
||||
/// visible lookups). These extra lookup results will be found by walking
|
||||
/// the lexical declarations of this context. This should be used only if
|
||||
@ -1873,28 +1889,28 @@ class DeclContext {
|
||||
HasLazyExternalLexicalLookups = true;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the internal representation of the lookup structure.
|
||||
/// Retrieve the internal representation of the lookup structure.
|
||||
/// This may omit some names if we are lazily building the structure.
|
||||
StoredDeclsMap *getLookupPtr() const { return LookupPtr; }
|
||||
|
||||
/// \brief Ensure the lookup structure is fully-built and return it.
|
||||
/// Ensure the lookup structure is fully-built and return it.
|
||||
StoredDeclsMap *buildLookup();
|
||||
|
||||
/// \brief Whether this DeclContext has external storage containing
|
||||
/// Whether this DeclContext has external storage containing
|
||||
/// additional declarations that are lexically in this context.
|
||||
bool hasExternalLexicalStorage() const { return ExternalLexicalStorage; }
|
||||
|
||||
/// \brief State whether this DeclContext has external storage for
|
||||
/// State whether this DeclContext has external storage for
|
||||
/// declarations lexically in this context.
|
||||
void setHasExternalLexicalStorage(bool ES = true) {
|
||||
ExternalLexicalStorage = ES;
|
||||
}
|
||||
|
||||
/// \brief Whether this DeclContext has external storage containing
|
||||
/// Whether this DeclContext has external storage containing
|
||||
/// additional declarations that are visible in this context.
|
||||
bool hasExternalVisibleStorage() const { return ExternalVisibleStorage; }
|
||||
|
||||
/// \brief State whether this DeclContext has external storage for
|
||||
/// State whether this DeclContext has external storage for
|
||||
/// declarations visible in this context.
|
||||
void setHasExternalVisibleStorage(bool ES = true) {
|
||||
ExternalVisibleStorage = ES;
|
||||
@ -1902,7 +1918,7 @@ class DeclContext {
|
||||
NeedToReconcileExternalVisibleStorage = true;
|
||||
}
|
||||
|
||||
/// \brief Determine whether the given declaration is stored in the list of
|
||||
/// 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 ||
|
||||
@ -1933,7 +1949,7 @@ class DeclContext {
|
||||
void reconcileExternalVisibleStorage() const;
|
||||
bool LoadLexicalDeclsFromExternalStorage() const;
|
||||
|
||||
/// @brief Makes a declaration visible within this context, but
|
||||
/// Makes a declaration visible within this context, but
|
||||
/// suppresses searches for external declarations with the same
|
||||
/// name.
|
||||
///
|
||||
@ -1943,6 +1959,7 @@ class DeclContext {
|
||||
|
||||
StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const;
|
||||
|
||||
void loadLazyLocalLexicalLookups();
|
||||
void buildLookupImpl(DeclContext *DCtx, bool Internal);
|
||||
void makeDeclVisibleInContextWithFlags(NamedDecl *D, bool Internal,
|
||||
bool Rediscoverable);
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,17 +30,17 @@ namespace clang {
|
||||
|
||||
class DependentDiagnostic;
|
||||
|
||||
/// \brief An array of decls optimized for the common case of only containing
|
||||
/// An array of decls optimized for the common case of only containing
|
||||
/// one entry.
|
||||
struct StoredDeclsList {
|
||||
/// \brief When in vector form, this is what the Data pointer points to.
|
||||
/// When in vector form, this is what the Data pointer points to.
|
||||
using DeclsTy = SmallVector<NamedDecl *, 4>;
|
||||
|
||||
/// \brief A collection of declarations, with a flag to indicate if we have
|
||||
/// A collection of declarations, with a flag to indicate if we have
|
||||
/// further external declarations.
|
||||
using DeclsAndHasExternalTy = llvm::PointerIntPair<DeclsTy *, 1, bool>;
|
||||
|
||||
/// \brief The stored data, which will be either a pointer to a NamedDecl,
|
||||
/// The stored data, which will be either a pointer to a NamedDecl,
|
||||
/// or a pointer to a vector with a flag to indicate if there are further
|
||||
/// external declarations.
|
||||
llvm::PointerUnion<NamedDecl *, DeclsAndHasExternalTy> Data;
|
||||
@ -122,7 +122,7 @@ struct StoredDeclsList {
|
||||
== Vec.end() && "list still contains decl");
|
||||
}
|
||||
|
||||
/// \brief Remove any declarations which were imported from an external
|
||||
/// Remove any declarations which were imported from an external
|
||||
/// AST source.
|
||||
void removeExternalDecls() {
|
||||
if (isNull()) {
|
||||
|
@ -148,13 +148,13 @@ class FriendDecl final
|
||||
/// Retrieves the source range for the friend declaration.
|
||||
SourceRange getSourceRange() const override LLVM_READONLY {
|
||||
if (NamedDecl *ND = getFriendDecl()) {
|
||||
if (FunctionDecl *FD = dyn_cast<FunctionDecl>(ND))
|
||||
if (const auto *FD = dyn_cast<FunctionDecl>(ND))
|
||||
return FD->getSourceRange();
|
||||
if (FunctionTemplateDecl *FTD = dyn_cast<FunctionTemplateDecl>(ND))
|
||||
if (const auto *FTD = dyn_cast<FunctionTemplateDecl>(ND))
|
||||
return FTD->getSourceRange();
|
||||
if (ClassTemplateDecl *CTD = dyn_cast<ClassTemplateDecl>(ND))
|
||||
if (const auto *CTD = dyn_cast<ClassTemplateDecl>(ND))
|
||||
return CTD->getSourceRange();
|
||||
if (DeclaratorDecl *DD = dyn_cast<DeclaratorDecl>(ND)) {
|
||||
if (const auto *DD = dyn_cast<DeclaratorDecl>(ND)) {
|
||||
if (DD->getOuterLocStart() != DD->getInnerLocStart())
|
||||
return DD->getSourceRange();
|
||||
}
|
||||
|
@ -86,16 +86,11 @@ inline DeclContext::lookups_range DeclContext::lookups() const {
|
||||
return lookups_range(all_lookups_iterator(), all_lookups_iterator());
|
||||
}
|
||||
|
||||
inline DeclContext::all_lookups_iterator DeclContext::lookups_begin() const {
|
||||
return lookups().begin();
|
||||
}
|
||||
|
||||
inline DeclContext::all_lookups_iterator DeclContext::lookups_end() const {
|
||||
return lookups().end();
|
||||
}
|
||||
|
||||
inline DeclContext::lookups_range DeclContext::noload_lookups() const {
|
||||
inline DeclContext::lookups_range
|
||||
DeclContext::noload_lookups(bool PreserveInternalState) const {
|
||||
DeclContext *Primary = const_cast<DeclContext*>(this)->getPrimaryContext();
|
||||
if (!PreserveInternalState)
|
||||
Primary->loadLazyLocalLexicalLookups();
|
||||
if (StoredDeclsMap *Map = Primary->getLookupPtr())
|
||||
return lookups_range(all_lookups_iterator(Map->begin(), Map->end()),
|
||||
all_lookups_iterator(Map->end(), Map->end()));
|
||||
@ -105,16 +100,6 @@ inline DeclContext::lookups_range DeclContext::noload_lookups() const {
|
||||
return lookups_range(all_lookups_iterator(), all_lookups_iterator());
|
||||
}
|
||||
|
||||
inline
|
||||
DeclContext::all_lookups_iterator DeclContext::noload_lookups_begin() const {
|
||||
return noload_lookups().begin();
|
||||
}
|
||||
|
||||
inline
|
||||
DeclContext::all_lookups_iterator DeclContext::noload_lookups_end() const {
|
||||
return noload_lookups().end();
|
||||
}
|
||||
|
||||
} // namespace clang
|
||||
|
||||
#endif // LLVM_CLANG_AST_DECLLOOKUPS_H
|
||||
|
@ -97,7 +97,7 @@ class ObjCList : public ObjCListBase {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief A list of Objective-C protocols, along with the source
|
||||
/// A list of Objective-C protocols, along with the source
|
||||
/// locations at which they were referenced.
|
||||
class ObjCProtocolList : public ObjCList<ObjCProtocolDecl> {
|
||||
SourceLocation *Locations = nullptr;
|
||||
@ -156,10 +156,10 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
// Method has a definition.
|
||||
unsigned IsDefined : 1;
|
||||
|
||||
/// \brief Method redeclaration in the same interface.
|
||||
/// Method redeclaration in the same interface.
|
||||
unsigned IsRedeclaration : 1;
|
||||
|
||||
/// \brief Is redeclared in the same interface.
|
||||
/// Is redeclared in the same interface.
|
||||
mutable unsigned HasRedeclaration : 1;
|
||||
|
||||
// NOTE: VC++ treats enums as signed, avoid using ImplementationControl enum
|
||||
@ -170,14 +170,14 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
/// in, inout, etc.
|
||||
unsigned objcDeclQualifier : 7;
|
||||
|
||||
/// \brief Indicates whether this method has a related result type.
|
||||
/// Indicates whether this method has a related result type.
|
||||
unsigned RelatedResultType : 1;
|
||||
|
||||
/// \brief Whether the locations of the selector identifiers are in a
|
||||
/// Whether the locations of the selector identifiers are in a
|
||||
/// "standard" position, a enum SelectorLocationsKind.
|
||||
unsigned SelLocsKind : 2;
|
||||
|
||||
/// \brief Whether this method overrides any other in the class hierarchy.
|
||||
/// 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
|
||||
@ -186,7 +186,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
/// method in the interface or its categories.
|
||||
unsigned IsOverriding : 1;
|
||||
|
||||
/// \brief Indicates if the method was a definition but its body was skipped.
|
||||
/// Indicates if the method was a definition but its body was skipped.
|
||||
unsigned HasSkippedBody : 1;
|
||||
|
||||
// Return type of this method.
|
||||
@ -195,7 +195,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
// Type source information for the return type.
|
||||
TypeSourceInfo *ReturnTInfo;
|
||||
|
||||
/// \brief Array of ParmVarDecls for the formal parameters of this method
|
||||
/// Array of ParmVarDecls for the formal parameters of this method
|
||||
/// and optionally followed by selector locations.
|
||||
void *ParamsAndSelLocs = nullptr;
|
||||
unsigned NumParams = 0;
|
||||
@ -241,7 +241,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
return getSelLocsKind() != SelLoc_NonStandard;
|
||||
}
|
||||
|
||||
/// \brief Get a pointer to the stored selector identifiers locations array.
|
||||
/// Get a pointer to the stored selector identifiers locations array.
|
||||
/// No locations will be stored if HasStandardSelLocs is true.
|
||||
SourceLocation *getStoredSelLocs() {
|
||||
return reinterpret_cast<SourceLocation*>(getParams() + NumParams);
|
||||
@ -250,7 +250,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
return reinterpret_cast<const SourceLocation*>(getParams() + NumParams);
|
||||
}
|
||||
|
||||
/// \brief Get a pointer to the stored selector identifiers locations array.
|
||||
/// Get a pointer to the stored selector identifiers locations array.
|
||||
/// No locations will be stored if HasStandardSelLocs is true.
|
||||
ParmVarDecl **getParams() {
|
||||
return reinterpret_cast<ParmVarDecl **>(ParamsAndSelLocs);
|
||||
@ -259,7 +259,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
return reinterpret_cast<const ParmVarDecl *const *>(ParamsAndSelLocs);
|
||||
}
|
||||
|
||||
/// \brief Get the number of stored selector identifiers locations.
|
||||
/// Get the number of stored selector identifiers locations.
|
||||
/// No locations will be stored if HasStandardSelLocs is true.
|
||||
unsigned getNumStoredSelLocs() const {
|
||||
if (hasStandardSelLocs())
|
||||
@ -271,7 +271,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
ArrayRef<ParmVarDecl*> Params,
|
||||
ArrayRef<SourceLocation> SelLocs);
|
||||
|
||||
/// \brief A definition will return its interface declaration.
|
||||
/// A definition will return its interface declaration.
|
||||
/// An interface declaration will return its definition.
|
||||
/// Otherwise it will return itself.
|
||||
ObjCMethodDecl *getNextRedeclarationImpl() override;
|
||||
@ -301,18 +301,18 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
}
|
||||
void setObjCDeclQualifier(ObjCDeclQualifier QV) { objcDeclQualifier = QV; }
|
||||
|
||||
/// \brief Determine whether this method has a result type that is related
|
||||
/// Determine whether this method has a result type that is related
|
||||
/// to the message receiver's type.
|
||||
bool hasRelatedResultType() const { return RelatedResultType; }
|
||||
|
||||
/// \brief Note whether this method has a related result type.
|
||||
/// Note whether this method has a related result type.
|
||||
void SetRelatedResultType(bool RRT = true) { RelatedResultType = RRT; }
|
||||
|
||||
/// \brief True if this is a method redeclaration in the same interface.
|
||||
/// True if this is a method redeclaration in the same interface.
|
||||
bool isRedeclaration() const { return IsRedeclaration; }
|
||||
void setAsRedeclaration(const ObjCMethodDecl *PrevMethod);
|
||||
|
||||
/// \brief Returns the location where the declarator ends. It will be
|
||||
/// 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; }
|
||||
@ -362,7 +362,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
void setReturnType(QualType T) { MethodDeclType = T; }
|
||||
SourceRange getReturnTypeSourceRange() const;
|
||||
|
||||
/// \brief Determine the type of an expression that sends a message to this
|
||||
/// Determine the type of an expression that sends a message to this
|
||||
/// function. This replaces the type parameters with the types they would
|
||||
/// get if the receiver was parameterless (e.g. it may replace the type
|
||||
/// parameter with 'id').
|
||||
@ -407,7 +407,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
NumParams);
|
||||
}
|
||||
|
||||
/// \brief Sets the method's parameters and selector source locations.
|
||||
/// Sets the method's parameters and selector source locations.
|
||||
/// If the method is implicit (not coming from source) \p SelLocs is
|
||||
/// ignored.
|
||||
void setMethodParams(ASTContext &C,
|
||||
@ -462,7 +462,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
bool isDefined() const { return IsDefined; }
|
||||
void setDefined(bool isDefined) { IsDefined = isDefined; }
|
||||
|
||||
/// \brief Whether this method overrides any other in the class hierarchy.
|
||||
/// 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
|
||||
@ -472,7 +472,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
bool isOverriding() const { return IsOverriding; }
|
||||
void setOverriding(bool isOverriding) { IsOverriding = isOverriding; }
|
||||
|
||||
/// \brief Return overridden methods for the given \p Method.
|
||||
/// Return overridden methods for the given \p Method.
|
||||
///
|
||||
/// An ObjC method is considered to override any method in the class's
|
||||
/// base classes (and base's categories), its protocols, or its categories'
|
||||
@ -483,11 +483,11 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
void getOverriddenMethods(
|
||||
SmallVectorImpl<const ObjCMethodDecl *> &Overridden) const;
|
||||
|
||||
/// \brief True if the method was a definition but its body was skipped.
|
||||
/// True if the method was a definition but its body was skipped.
|
||||
bool hasSkippedBody() const { return HasSkippedBody; }
|
||||
void setHasSkippedBody(bool Skipped = true) { HasSkippedBody = Skipped; }
|
||||
|
||||
/// \brief Returns the property associated with this method's selector.
|
||||
/// Returns the property associated with this method's selector.
|
||||
///
|
||||
/// Note that even if this particular method is not marked as a property
|
||||
/// accessor, it is still possible for it to match a property declared in a
|
||||
@ -520,10 +520,10 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
bool isDesignatedInitializerForTheInterface(
|
||||
const ObjCMethodDecl **InitMethod = nullptr) const;
|
||||
|
||||
/// \brief Determine whether this method has a body.
|
||||
/// Determine whether this method has a body.
|
||||
bool hasBody() const override { return Body.isValid(); }
|
||||
|
||||
/// \brief Retrieve the body of this method, if it has one.
|
||||
/// Retrieve the body of this method, if it has one.
|
||||
Stmt *getBody() const override;
|
||||
|
||||
void setLazyBody(uint64_t Offset) { Body = Offset; }
|
||||
@ -531,7 +531,7 @@ class ObjCMethodDecl : public NamedDecl, public DeclContext {
|
||||
CompoundStmt *getCompoundBody() { return (CompoundStmt*)getBody(); }
|
||||
void setBody(Stmt *B) { Body = B; }
|
||||
|
||||
/// \brief Returns whether this specific method is a definition.
|
||||
/// Returns whether this specific method is a definition.
|
||||
bool isThisDeclarationADefinition() const { return hasBody(); }
|
||||
|
||||
// Implement isa/cast/dyncast/etc.
|
||||
@ -737,7 +737,7 @@ enum class ObjCPropertyQueryKind : uint8_t {
|
||||
OBJC_PR_query_class
|
||||
};
|
||||
|
||||
/// \brief Represents one property declaration in an Objective-C interface.
|
||||
/// Represents one property declaration in an Objective-C interface.
|
||||
///
|
||||
/// For example:
|
||||
/// \code{.mm}
|
||||
@ -770,7 +770,7 @@ class ObjCPropertyDecl : public NamedDecl {
|
||||
};
|
||||
|
||||
enum {
|
||||
/// \brief Number of bits fitting all the property attributes.
|
||||
/// Number of bits fitting all the property attributes.
|
||||
NumPropertyAttrsBits = 15
|
||||
};
|
||||
|
||||
@ -1163,7 +1163,7 @@ class ObjCContainerDecl : public NamedDecl, public DeclContext {
|
||||
}
|
||||
};
|
||||
|
||||
/// \brief Represents an ObjC class declaration.
|
||||
/// Represents an ObjC class declaration.
|
||||
///
|
||||
/// For example:
|
||||
///
|
||||
@ -1197,7 +1197,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
mutable const Type *TypeForDecl = nullptr;
|
||||
|
||||
struct DefinitionData {
|
||||
/// \brief The definition of this class, for quick access from any
|
||||
/// The definition of this class, for quick access from any
|
||||
/// declaration.
|
||||
ObjCInterfaceDecl *Definition = nullptr;
|
||||
|
||||
@ -1210,7 +1210,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
/// Protocols reference in both the \@interface and class extensions.
|
||||
ObjCList<ObjCProtocolDecl> AllReferencedProtocols;
|
||||
|
||||
/// \brief List of categories and class extensions defined for this class.
|
||||
/// List of categories and class extensions defined for this class.
|
||||
///
|
||||
/// Categories are stored as a linked list in the AST, since the categories
|
||||
/// and class extensions come long after the initial interface declaration,
|
||||
@ -1221,11 +1221,11 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
/// extensions and implementation. This list is built lazily.
|
||||
ObjCIvarDecl *IvarList = nullptr;
|
||||
|
||||
/// \brief Indicates that the contents of this Objective-C class will be
|
||||
/// Indicates that the contents of this Objective-C class will be
|
||||
/// completed by the external AST source when required.
|
||||
mutable unsigned ExternallyCompleted : 1;
|
||||
|
||||
/// \brief Indicates that the ivar cache does not yet include ivars
|
||||
/// Indicates that the ivar cache does not yet include ivars
|
||||
/// declared in the implementation.
|
||||
mutable unsigned IvarListMissingImplementation : 1;
|
||||
|
||||
@ -1248,7 +1248,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
/// One of the \c InheritedDesignatedInitializersState enumeratos.
|
||||
mutable unsigned InheritedDesignatedInitializers : 2;
|
||||
|
||||
/// \brief The location of the last location in this declaration, before
|
||||
/// The location of the last location in this declaration, before
|
||||
/// the properties/methods. For example, this will be the '>', '}', or
|
||||
/// identifier,
|
||||
SourceLocation EndLoc;
|
||||
@ -1262,7 +1262,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
/// The type parameters associated with this class, if any.
|
||||
ObjCTypeParamList *TypeParamList = nullptr;
|
||||
|
||||
/// \brief Contains a pointer to the data associated with this class,
|
||||
/// Contains a pointer to the data associated with this class,
|
||||
/// which will be NULL if this class has not yet been defined.
|
||||
///
|
||||
/// The bit indicates when we don't need to check for out-of-date
|
||||
@ -1283,7 +1283,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
return *Data.getPointer();
|
||||
}
|
||||
|
||||
/// \brief Allocate the definition data for this class.
|
||||
/// Allocate the definition data for this class.
|
||||
void allocateDefinitionData();
|
||||
|
||||
using redeclarable_base = Redeclarable<ObjCInterfaceDecl>;
|
||||
@ -1338,7 +1338,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
return SourceRange(getAtStartLoc(), getLocation());
|
||||
}
|
||||
|
||||
/// \brief Indicate that this Objective-C class is complete, but that
|
||||
/// Indicate that this Objective-C class is complete, but that
|
||||
/// the external AST source will be responsible for filling in its contents
|
||||
/// when a complete class is required.
|
||||
void setExternallyCompleted();
|
||||
@ -1544,13 +1544,13 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
isDesignatedInitializer(Selector Sel,
|
||||
const ObjCMethodDecl **InitMethod = nullptr) const;
|
||||
|
||||
/// \brief Determine whether this particular declaration of this class is
|
||||
/// Determine whether this particular declaration of this class is
|
||||
/// actually also a definition.
|
||||
bool isThisDeclarationADefinition() const {
|
||||
return getDefinition() == this;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this class has been defined.
|
||||
/// 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
|
||||
// might bring in a definition.
|
||||
@ -1562,21 +1562,21 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
return Data.getPointer();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the definition of this class, or NULL if this class
|
||||
/// 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;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the definition of this class, or NULL if this class
|
||||
/// 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;
|
||||
}
|
||||
|
||||
/// \brief Starts the definition of this Objective-C class, taking it from
|
||||
/// Starts the definition of this Objective-C class, taking it from
|
||||
/// a forward declaration (\@class) to a definition (\@interface).
|
||||
void startDefinition();
|
||||
|
||||
@ -1608,7 +1608,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
data().SuperClassTInfo = superClass;
|
||||
}
|
||||
|
||||
/// \brief Iterator that walks over the list of categories, filtering out
|
||||
/// Iterator that walks over the list of categories, filtering out
|
||||
/// those that do not meet specific criteria.
|
||||
///
|
||||
/// This class template is used for the various permutations of category
|
||||
@ -1655,13 +1655,13 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
};
|
||||
|
||||
private:
|
||||
/// \brief Test whether the given category is visible.
|
||||
/// Test whether the given category is visible.
|
||||
///
|
||||
/// Used in the \c visible_categories_iterator.
|
||||
static bool isVisibleCategory(ObjCCategoryDecl *Cat);
|
||||
|
||||
public:
|
||||
/// \brief Iterator that walks over the list of categories and extensions
|
||||
/// Iterator that walks over the list of categories and extensions
|
||||
/// that are visible, i.e., not hidden in a non-imported submodule.
|
||||
using visible_categories_iterator =
|
||||
filtered_category_iterator<isVisibleCategory>;
|
||||
@ -1674,30 +1674,30 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
visible_categories_end());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the beginning of the visible-categories
|
||||
/// Retrieve an iterator to the beginning of the visible-categories
|
||||
/// list.
|
||||
visible_categories_iterator visible_categories_begin() const {
|
||||
return visible_categories_iterator(getCategoryListRaw());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the end of the visible-categories list.
|
||||
/// Retrieve an iterator to the end of the visible-categories list.
|
||||
visible_categories_iterator visible_categories_end() const {
|
||||
return visible_categories_iterator();
|
||||
}
|
||||
|
||||
/// \brief Determine whether the visible-categories list is empty.
|
||||
/// Determine whether the visible-categories list is empty.
|
||||
bool visible_categories_empty() const {
|
||||
return visible_categories_begin() == visible_categories_end();
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief Test whether the given category... is a category.
|
||||
/// Test whether the given category... is a category.
|
||||
///
|
||||
/// Used in the \c known_categories_iterator.
|
||||
static bool isKnownCategory(ObjCCategoryDecl *) { return true; }
|
||||
|
||||
public:
|
||||
/// \brief Iterator that walks over all of the known categories and
|
||||
/// Iterator that walks over all of the known categories and
|
||||
/// extensions, including those that are hidden.
|
||||
using known_categories_iterator = filtered_category_iterator<isKnownCategory>;
|
||||
using known_categories_range =
|
||||
@ -1708,30 +1708,30 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
known_categories_end());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the beginning of the known-categories
|
||||
/// Retrieve an iterator to the beginning of the known-categories
|
||||
/// list.
|
||||
known_categories_iterator known_categories_begin() const {
|
||||
return known_categories_iterator(getCategoryListRaw());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the end of the known-categories list.
|
||||
/// Retrieve an iterator to the end of the known-categories list.
|
||||
known_categories_iterator known_categories_end() const {
|
||||
return known_categories_iterator();
|
||||
}
|
||||
|
||||
/// \brief Determine whether the known-categories list is empty.
|
||||
/// Determine whether the known-categories list is empty.
|
||||
bool known_categories_empty() const {
|
||||
return known_categories_begin() == known_categories_end();
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief Test whether the given category is a visible extension.
|
||||
/// Test whether the given category is a visible extension.
|
||||
///
|
||||
/// Used in the \c visible_extensions_iterator.
|
||||
static bool isVisibleExtension(ObjCCategoryDecl *Cat);
|
||||
|
||||
public:
|
||||
/// \brief Iterator that walks over all of the visible extensions, skipping
|
||||
/// Iterator that walks over all of the visible extensions, skipping
|
||||
/// any that are known but hidden.
|
||||
using visible_extensions_iterator =
|
||||
filtered_category_iterator<isVisibleExtension>;
|
||||
@ -1744,24 +1744,24 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
visible_extensions_end());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the beginning of the visible-extensions
|
||||
/// Retrieve an iterator to the beginning of the visible-extensions
|
||||
/// list.
|
||||
visible_extensions_iterator visible_extensions_begin() const {
|
||||
return visible_extensions_iterator(getCategoryListRaw());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the end of the visible-extensions list.
|
||||
/// Retrieve an iterator to the end of the visible-extensions list.
|
||||
visible_extensions_iterator visible_extensions_end() const {
|
||||
return visible_extensions_iterator();
|
||||
}
|
||||
|
||||
/// \brief Determine whether the visible-extensions list is empty.
|
||||
/// Determine whether the visible-extensions list is empty.
|
||||
bool visible_extensions_empty() const {
|
||||
return visible_extensions_begin() == visible_extensions_end();
|
||||
}
|
||||
|
||||
private:
|
||||
/// \brief Test whether the given category is an extension.
|
||||
/// Test whether the given category is an extension.
|
||||
///
|
||||
/// Used in the \c known_extensions_iterator.
|
||||
static bool isKnownExtension(ObjCCategoryDecl *Cat);
|
||||
@ -1771,7 +1771,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
friend class ASTDeclWriter;
|
||||
friend class ASTReader;
|
||||
|
||||
/// \brief Iterator that walks over all of the known extensions.
|
||||
/// Iterator that walks over all of the known extensions.
|
||||
using known_extensions_iterator =
|
||||
filtered_category_iterator<isKnownExtension>;
|
||||
using known_extensions_range =
|
||||
@ -1782,23 +1782,23 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
known_extensions_end());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the beginning of the known-extensions
|
||||
/// Retrieve an iterator to the beginning of the known-extensions
|
||||
/// list.
|
||||
known_extensions_iterator known_extensions_begin() const {
|
||||
return known_extensions_iterator(getCategoryListRaw());
|
||||
}
|
||||
|
||||
/// \brief Retrieve an iterator to the end of the known-extensions list.
|
||||
/// Retrieve an iterator to the end of the known-extensions list.
|
||||
known_extensions_iterator known_extensions_end() const {
|
||||
return known_extensions_iterator();
|
||||
}
|
||||
|
||||
/// \brief Determine whether the known-extensions list is empty.
|
||||
/// Determine whether the known-extensions list is empty.
|
||||
bool known_extensions_empty() const {
|
||||
return known_extensions_begin() == known_extensions_end();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the raw pointer to the start of the category/extension
|
||||
/// Retrieve the raw pointer to the start of the category/extension
|
||||
/// list.
|
||||
ObjCCategoryDecl* getCategoryListRaw() const {
|
||||
// FIXME: Should make sure no callers ever do this.
|
||||
@ -1811,7 +1811,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
return data().CategoryList;
|
||||
}
|
||||
|
||||
/// \brief Set the raw pointer to the start of the category/extension
|
||||
/// Set the raw pointer to the start of the category/extension
|
||||
/// list.
|
||||
void setCategoryListRaw(ObjCCategoryDecl *category) {
|
||||
data().CategoryList = category;
|
||||
@ -1874,7 +1874,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
|
||||
ObjCInterfaceDecl *lookupInheritedClass(const IdentifierInfo *ICName);
|
||||
|
||||
/// \brief Lookup a method in the classes implementation hierarchy.
|
||||
/// Lookup a method in the classes implementation hierarchy.
|
||||
ObjCMethodDecl *lookupPrivateMethod(const Selector &Sel,
|
||||
bool Instance=true) const;
|
||||
|
||||
@ -1882,7 +1882,7 @@ class ObjCInterfaceDecl : public ObjCContainerDecl
|
||||
return lookupPrivateMethod(Sel, false);
|
||||
}
|
||||
|
||||
/// \brief Lookup a setter or getter in the class hierarchy,
|
||||
/// Lookup a setter or getter in the class hierarchy,
|
||||
/// including in all categories except for category passed
|
||||
/// as argument.
|
||||
ObjCMethodDecl *lookupPropertyAccessor(const Selector Sel,
|
||||
@ -1988,7 +1988,7 @@ class ObjCIvarDecl : public FieldDecl {
|
||||
|
||||
static ObjCIvarDecl *CreateDeserialized(ASTContext &C, unsigned ID);
|
||||
|
||||
/// \brief Return the class interface that this ivar is logically contained
|
||||
/// 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
|
||||
/// ivars.
|
||||
@ -2027,7 +2027,7 @@ class ObjCIvarDecl : public FieldDecl {
|
||||
unsigned Synthesized : 1;
|
||||
};
|
||||
|
||||
/// \brief Represents a field declaration created by an \@defs(...).
|
||||
/// Represents a field declaration created by an \@defs(...).
|
||||
class ObjCAtDefsFieldDecl : public FieldDecl {
|
||||
ObjCAtDefsFieldDecl(DeclContext *DC, SourceLocation StartLoc,
|
||||
SourceLocation IdLoc, IdentifierInfo *Id,
|
||||
@ -2051,7 +2051,7 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
|
||||
static bool classofKind(Kind K) { return K == ObjCAtDefsField; }
|
||||
};
|
||||
|
||||
/// \brief Represents an Objective-C protocol declaration.
|
||||
/// Represents an Objective-C protocol declaration.
|
||||
///
|
||||
/// Objective-C protocols declare a pure abstract type (i.e., no instance
|
||||
/// variables are permitted). Protocols originally drew inspiration from
|
||||
@ -2083,14 +2083,14 @@ class ObjCAtDefsFieldDecl : public FieldDecl {
|
||||
class ObjCProtocolDecl : public ObjCContainerDecl,
|
||||
public Redeclarable<ObjCProtocolDecl> {
|
||||
struct DefinitionData {
|
||||
// \brief The declaration that defines this protocol.
|
||||
// The declaration that defines this protocol.
|
||||
ObjCProtocolDecl *Definition;
|
||||
|
||||
/// \brief Referenced protocols
|
||||
/// Referenced protocols
|
||||
ObjCProtocolList ReferencedProtocols;
|
||||
};
|
||||
|
||||
/// \brief Contains a pointer to the data associated with this class,
|
||||
/// Contains a pointer to the data associated with this class,
|
||||
/// which will be NULL if this class has not yet been defined.
|
||||
///
|
||||
/// The bit indicates when we don't need to check for out-of-date
|
||||
@ -2213,7 +2213,7 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
|
||||
return lookupMethod(Sel, false/*isInstance*/);
|
||||
}
|
||||
|
||||
/// \brief Determine whether this protocol has a definition.
|
||||
/// Determine whether this protocol has a definition.
|
||||
bool hasDefinition() const {
|
||||
// If the name of this protocol is out-of-date, bring it up-to-date, which
|
||||
// might bring in a definition.
|
||||
@ -2225,23 +2225,23 @@ class ObjCProtocolDecl : public ObjCContainerDecl,
|
||||
return Data.getPointer();
|
||||
}
|
||||
|
||||
/// \brief Retrieve the definition of this protocol, if any.
|
||||
/// Retrieve the definition of this protocol, if any.
|
||||
ObjCProtocolDecl *getDefinition() {
|
||||
return hasDefinition()? Data.getPointer()->Definition : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Retrieve the definition of this protocol, if any.
|
||||
/// Retrieve the definition of this protocol, if any.
|
||||
const ObjCProtocolDecl *getDefinition() const {
|
||||
return hasDefinition()? Data.getPointer()->Definition : nullptr;
|
||||
}
|
||||
|
||||
/// \brief Determine whether this particular declaration is also the
|
||||
/// Determine whether this particular declaration is also the
|
||||
/// definition.
|
||||
bool isThisDeclarationADefinition() const {
|
||||
return getDefinition() == this;
|
||||
}
|
||||
|
||||
/// \brief Starts the definition of this Objective-C protocol.
|
||||
/// Starts the definition of this Objective-C protocol.
|
||||
void startDefinition();
|
||||
|
||||
/// Produce a name to be used for protocol's metadata. It comes either via
|
||||
@ -2310,7 +2310,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
|
||||
/// FIXME: this should not be a singly-linked list. Move storage elsewhere.
|
||||
ObjCCategoryDecl *NextClassCategory = nullptr;
|
||||
|
||||
/// \brief The location of the category name in this declaration.
|
||||
/// The location of the category name in this declaration.
|
||||
SourceLocation CategoryNameLoc;
|
||||
|
||||
/// class extension may have private ivars.
|
||||
@ -2400,7 +2400,7 @@ class ObjCCategoryDecl : public ObjCContainerDecl {
|
||||
|
||||
ObjCCategoryDecl *getNextClassCategory() const { return NextClassCategory; }
|
||||
|
||||
/// \brief Retrieve the pointer to the next stored category (or extension),
|
||||
/// Retrieve the pointer to the next stored category (or extension),
|
||||
/// which may be hidden.
|
||||
ObjCCategoryDecl *getNextClassCategoryRaw() const {
|
||||
return NextClassCategory;
|
||||
@ -2578,7 +2578,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
||||
SourceLocation IvarRBraceLoc;
|
||||
|
||||
/// Support for ivar initialization.
|
||||
/// \brief The arguments used to initialize the ivars
|
||||
/// The arguments used to initialize the ivars
|
||||
LazyCXXCtorInitializersPtr IvarInitializers;
|
||||
unsigned NumIvarInitializers = 0;
|
||||
|
||||
@ -2694,7 +2694,7 @@ class ObjCImplementationDecl : public ObjCImplDecl {
|
||||
return getIdentifier()->getName();
|
||||
}
|
||||
|
||||
/// @brief Get the name of the class associated with this interface.
|
||||
/// Get the name of the class associated with this interface.
|
||||
//
|
||||
// FIXME: Move to StringRef API.
|
||||
std::string getNameAsString() const {
|
||||
@ -2785,7 +2785,7 @@ class ObjCPropertyImplDecl : public Decl {
|
||||
private:
|
||||
SourceLocation AtLoc; // location of \@synthesize or \@dynamic
|
||||
|
||||
/// \brief For \@synthesize, the location of the ivar, if it was written in
|
||||
/// For \@synthesize, the location of the ivar, if it was written in
|
||||
/// the source code.
|
||||
///
|
||||
/// \code
|
||||
@ -2854,7 +2854,7 @@ class ObjCPropertyImplDecl : public Decl {
|
||||
this->IvarLoc = IvarLoc;
|
||||
}
|
||||
|
||||
/// \brief For \@synthesize, returns true if an ivar name was explicitly
|
||||
/// For \@synthesize, returns true if an ivar name was explicitly
|
||||
/// specified.
|
||||
///
|
||||
/// \code
|
||||
|
@ -8,7 +8,7 @@
|
||||
//===----------------------------------------------------------------------===//
|
||||
///
|
||||
/// \file
|
||||
/// \brief This file defines OpenMP nodes for declarative directives.
|
||||
/// This file defines OpenMP nodes for declarative directives.
|
||||
///
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
@ -24,7 +24,7 @@
|
||||
|
||||
namespace clang {
|
||||
|
||||
/// \brief This represents '#pragma omp threadprivate ...' directive.
|
||||
/// This represents '#pragma omp threadprivate ...' directive.
|
||||
/// For example, in the following, both 'a' and 'A::b' are threadprivate:
|
||||
///
|
||||
/// \code
|
||||
@ -89,7 +89,7 @@ class OMPThreadPrivateDecl final
|
||||
static bool classofKind(Kind K) { return K == OMPThreadPrivate; }
|
||||
};
|
||||
|
||||
/// \brief This represents '#pragma omp declare reduction ...' directive.
|
||||
/// This represents '#pragma omp declare reduction ...' directive.
|
||||
/// For example, in the following, declared reduction 'foo' for types 'int' and
|
||||
/// 'float':
|
||||
///
|
||||
@ -109,14 +109,14 @@ class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
|
||||
|
||||
private:
|
||||
friend class ASTDeclReader;
|
||||
/// \brief Combiner for declare reduction construct.
|
||||
/// Combiner for declare reduction construct.
|
||||
Expr *Combiner;
|
||||
/// \brief Initializer for declare reduction construct.
|
||||
/// Initializer for declare reduction construct.
|
||||
Expr *Initializer;
|
||||
/// Kind of initializer - function call or omp_priv<init_expr> initializtion.
|
||||
InitKind InitializerKind = CallInit;
|
||||
|
||||
/// \brief Reference to the previous declare reduction construct in the same
|
||||
/// Reference to the previous declare reduction construct in the same
|
||||
/// scope with the same name. Required for proper templates instantiation if
|
||||
/// the declare reduction construct is declared inside compound statement.
|
||||
LazyDeclPtr PrevDeclInScope;
|
||||
@ -135,33 +135,33 @@ class OMPDeclareReductionDecl final : public ValueDecl, public DeclContext {
|
||||
}
|
||||
|
||||
public:
|
||||
/// \brief Create declare reduction node.
|
||||
/// Create declare reduction node.
|
||||
static OMPDeclareReductionDecl *
|
||||
Create(ASTContext &C, DeclContext *DC, SourceLocation L, DeclarationName Name,
|
||||
QualType T, OMPDeclareReductionDecl *PrevDeclInScope);
|
||||
/// \brief Create deserialized declare reduction node.
|
||||
/// Create deserialized declare reduction node.
|
||||
static OMPDeclareReductionDecl *CreateDeserialized(ASTContext &C,
|
||||
unsigned ID);
|
||||
|
||||
/// \brief Get combiner expression of the declare reduction construct.
|
||||
/// Get combiner expression of the declare reduction construct.
|
||||
Expr *getCombiner() { return Combiner; }
|
||||
const Expr *getCombiner() const { return Combiner; }
|
||||
/// \brief Set combiner expression for the declare reduction construct.
|
||||
/// Set combiner expression for the declare reduction construct.
|
||||
void setCombiner(Expr *E) { Combiner = E; }
|
||||
|
||||
/// \brief Get initializer expression (if specified) of the declare reduction
|
||||
/// Get initializer expression (if specified) of the declare reduction
|
||||
/// construct.
|
||||
Expr *getInitializer() { return Initializer; }
|
||||
const Expr *getInitializer() const { return Initializer; }
|
||||
/// Get initializer kind.
|
||||
InitKind getInitializerKind() const { return InitializerKind; }
|
||||
/// \brief Set initializer expression for the declare reduction construct.
|
||||
/// Set initializer expression for the declare reduction construct.
|
||||
void setInitializer(Expr *E, InitKind IK) {
|
||||
Initializer = E;
|
||||
InitializerKind = IK;
|
||||
}
|
||||
|
||||
/// \brief Get reference to previous declare reduction construct in the same
|
||||
/// Get reference to previous declare reduction construct in the same
|
||||
/// scope with the same name.
|
||||
OMPDeclareReductionDecl *getPrevDeclInScope();
|
||||
const OMPDeclareReductionDecl *getPrevDeclInScope() const;
|
||||
@ -189,9 +189,10 @@ class OMPCapturedExprDecl final : public VarDecl {
|
||||
void anchor() override;
|
||||
|
||||
OMPCapturedExprDecl(ASTContext &C, DeclContext *DC, IdentifierInfo *Id,
|
||||
QualType Type, SourceLocation StartLoc)
|
||||
: VarDecl(OMPCapturedExpr, C, DC, StartLoc, SourceLocation(), Id, Type,
|
||||
nullptr, SC_None) {
|
||||
QualType Type, TypeSourceInfo *TInfo,
|
||||
SourceLocation StartLoc)
|
||||
: VarDecl(OMPCapturedExpr, C, DC, StartLoc, StartLoc, Id, Type, TInfo,
|
||||
SC_None) {
|
||||
setImplicit();
|
||||
}
|
||||
|
||||
|
File diff suppressed because it is too large
Load Diff
@ -30,7 +30,7 @@ namespace declvisitor {
|
||||
template <typename T> struct make_ptr { using type = T *; };
|
||||
template <typename T> struct make_const_ptr { using type = const T *; };
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
/// A simple visitor class that helps create declaration visitors.
|
||||
template<template <typename> class Ptr, typename ImplClass, typename RetTy=void>
|
||||
class Base {
|
||||
public:
|
||||
@ -62,7 +62,7 @@ class Base {
|
||||
|
||||
} // namespace declvisitor
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
/// A simple visitor class that helps create declaration visitors.
|
||||
///
|
||||
/// This class does not preserve constness of Decl pointers (see also
|
||||
/// ConstDeclVisitor).
|
||||
@ -70,7 +70,7 @@ template<typename ImplClass, typename RetTy = void>
|
||||
class DeclVisitor
|
||||
: public declvisitor::Base<declvisitor::make_ptr, ImplClass, RetTy> {};
|
||||
|
||||
/// \brief A simple visitor class that helps create declaration visitors.
|
||||
/// A simple visitor class that helps create declaration visitors.
|
||||
///
|
||||
/// This class preserves constness of Decl pointers (see also DeclVisitor).
|
||||
template<typename ImplClass, typename RetTy = void>
|
||||
|
@ -194,7 +194,7 @@ class DeclarationName {
|
||||
(reinterpret_cast<IdentifierInfo *>(Ptr & ~PtrMask));
|
||||
}
|
||||
|
||||
/// \brief Evaluates true when this declaration name is empty.
|
||||
/// Evaluates true when this declaration name is empty.
|
||||
bool isEmpty() const {
|
||||
return !*this;
|
||||
}
|
||||
@ -211,7 +211,7 @@ class DeclarationName {
|
||||
/// getNameKind - Determine what kind of name this is.
|
||||
NameKind getNameKind() const;
|
||||
|
||||
/// \brief 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",
|
||||
@ -541,10 +541,10 @@ struct DeclarationNameInfo {
|
||||
LocInfo.CXXLiteralOperatorName.OpNameLoc = Loc.getRawEncoding();
|
||||
}
|
||||
|
||||
/// \brief Determine whether this name involves a template parameter.
|
||||
/// Determine whether this name involves a template parameter.
|
||||
bool isInstantiationDependent() const;
|
||||
|
||||
/// \brief Determine whether this name contains an unexpanded
|
||||
/// Determine whether this name contains an unexpanded
|
||||
/// parameter pack.
|
||||
bool containsUnexpandedParameterPack() const;
|
||||
|
||||
|
@ -24,7 +24,7 @@ namespace clang {
|
||||
|
||||
class ASTContext;
|
||||
|
||||
/// \brief Given a potentially-evaluated expression, this visitor visits all
|
||||
/// Given a potentially-evaluated expression, this visitor visits all
|
||||
/// of its potentially-evaluated subexpressions, recursively.
|
||||
template<template <typename> class Ptr, typename ImplClass>
|
||||
class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
|
||||
@ -95,7 +95,7 @@ class EvaluatedExprVisitorBase : public StmtVisitorBase<Ptr, ImplClass, void> {
|
||||
this->Visit(*I);
|
||||
}
|
||||
|
||||
/// \brief The basis case walks all of the children of the statement or
|
||||
/// The basis case walks all of the children of the statement or
|
||||
/// expression, assuming they are all potentially evaluated.
|
||||
void VisitStmt(PTR(Stmt) S) {
|
||||
for (auto *SubStmt : S->children())
|
||||
|
File diff suppressed because it is too large
Load Diff
File diff suppressed because it is too large
Load Diff
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user