aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-07-19 07:02:30 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-07-19 07:02:30 +0000
commitde51d671486b6ac9a2ad9ee5fcfdb1a23cc59238 (patch)
tree17ff629bd1f00b82d8dbb66a022e2f59e218c3c2
parent8746d127c04f5bbaf6c6e88cef8606ca5a6a54e9 (diff)
downloadsrc-de51d671486b6ac9a2ad9ee5fcfdb1a23cc59238.tar.gz
src-de51d671486b6ac9a2ad9ee5fcfdb1a23cc59238.zip
Vendor import of clang trunk r308421:vendor/clang/clang-trunk-r308421
Notes
Notes: svn path=/vendor/clang/dist/; revision=321186 svn path=/vendor/clang/clang-trunk-r308421/; revision=321187; tag=vendor/clang/clang-trunk-r308421
-rw-r--r--CMakeLists.txt6
-rw-r--r--cmake/caches/Fuchsia-stage2.cmake33
-rw-r--r--cmake/caches/Fuchsia.cmake8
-rw-r--r--docs/LanguageExtensions.rst83
-rw-r--r--docs/ReleaseNotes.rst4
-rw-r--r--include/clang-c/Index.h2
-rw-r--r--include/clang/AST/ASTContext.h4
-rw-r--r--include/clang/AST/DeclObjC.h10
-rw-r--r--include/clang/AST/OpenMPClause.h211
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h22
-rw-r--r--include/clang/AST/StmtOpenMP.h34
-rw-r--r--include/clang/AST/Type.h1
-rw-r--r--include/clang/Analysis/Analyses/Dominators.h6
-rw-r--r--include/clang/Basic/Attr.td24
-rw-r--r--include/clang/Basic/AttrDocs.td25
-rw-r--r--include/clang/Basic/Builtins.def5
-rw-r--r--include/clang/Basic/BuiltinsHexagon.def6
-rw-r--r--include/clang/Basic/BuiltinsSystemZ.def24
-rw-r--r--include/clang/Basic/BuiltinsX86.def5
-rw-r--r--include/clang/Basic/DiagnosticGroups.td2
-rw-r--r--include/clang/Basic/DiagnosticIDs.h8
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td25
-rw-r--r--include/clang/Basic/DiagnosticSerializationKinds.td70
-rw-r--r--include/clang/Basic/IdentifierTable.h11
-rw-r--r--include/clang/Basic/LangOptions.def1
-rw-r--r--include/clang/Basic/OpenMPKinds.def8
-rw-r--r--include/clang/Basic/Specifiers.h2
-rw-r--r--include/clang/Basic/TargetInfo.h14
-rw-r--r--include/clang/Config/config.h.cmake5
-rw-r--r--include/clang/Driver/Options.td1
-rw-r--r--include/clang/Frontend/LangStandard.h15
-rw-r--r--include/clang/Frontend/LangStandards.def10
-rw-r--r--include/clang/Index/IndexingAction.h10
-rw-r--r--include/clang/Lex/MacroInfo.h50
-rw-r--r--include/clang/Lex/Preprocessor.h19
-rw-r--r--include/clang/Sema/Sema.h32
-rw-r--r--include/clang/Tooling/DiagnosticsYaml.h15
-rw-r--r--include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h122
-rw-r--r--include/clang/Tooling/Refactoring/Rename/USRFinder.h34
-rw-r--r--include/clang/module.modulemap1
-rw-r--r--lib/AST/ASTContext.cpp6
-rw-r--r--lib/AST/ASTDumper.cpp8
-rw-r--r--lib/AST/DeclObjC.cpp18
-rw-r--r--lib/AST/ItaniumMangle.cpp2
-rw-r--r--lib/AST/MicrosoftMangle.cpp2
-rw-r--r--lib/AST/ODRHash.cpp8
-rw-r--r--lib/AST/OpenMPClause.cpp57
-rw-r--r--lib/AST/StmtOpenMP.cpp21
-rw-r--r--lib/AST/StmtPrinter.cpp25
-rw-r--r--lib/AST/StmtProfile.cpp24
-rw-r--r--lib/AST/Type.cpp4
-rw-r--r--lib/AST/TypePrinter.cpp75
-rw-r--r--lib/Analysis/PrintfFormatString.cpp5
-rw-r--r--lib/Basic/CMakeLists.txt17
-rw-r--r--lib/Basic/DiagnosticIDs.cpp12
-rw-r--r--lib/Basic/OpenMPKinds.cpp16
-rw-r--r--lib/Basic/Targets.cpp45
-rw-r--r--lib/CodeGen/CGBuiltin.cpp154
-rw-r--r--lib/CodeGen/CGCall.cpp8
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp24
-rw-r--r--lib/CodeGen/CGExpr.cpp7
-rw-r--r--lib/CodeGen/CGExprScalar.cpp38
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp822
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.h162
-rw-r--r--lib/CodeGen/CGStmtOpenMP.cpp529
-rw-r--r--lib/CodeGen/CodeGenFunction.h7
-rw-r--r--lib/CodeGen/CodeGenModule.cpp9
-rw-r--r--lib/CodeGen/MacroPPCallbacks.cpp4
-rw-r--r--lib/CodeGen/ObjectFilePCHContainerOperations.cpp3
-rw-r--r--lib/CodeGen/TargetInfo.cpp21
-rw-r--r--lib/Driver/Driver.cpp7
-rw-r--r--lib/Driver/ToolChains/Clang.cpp16
-rw-r--r--lib/Driver/ToolChains/Darwin.cpp68
-rw-r--r--lib/Driver/ToolChains/Fuchsia.cpp3
-rw-r--r--lib/Driver/ToolChains/Gnu.cpp3
-rw-r--r--lib/Driver/ToolChains/Solaris.cpp2
-rw-r--r--lib/Driver/ToolChains/Solaris.h2
-rw-r--r--lib/Format/TokenAnnotator.cpp3
-rw-r--r--lib/Format/UnwrappedLineParser.cpp2
-rw-r--r--lib/Frontend/CompilerInvocation.cpp1
-rw-r--r--lib/Frontend/InitPreprocessor.cpp5
-rw-r--r--lib/Frontend/PrintPreprocessedOutput.cpp4
-rw-r--r--lib/Frontend/Rewrite/FrontendActions.cpp1
-rw-r--r--lib/Frontend/Rewrite/RewriteModernObjC.cpp1
-rw-r--r--lib/Frontend/Rewrite/RewriteObjC.cpp1
-rw-r--r--lib/FrontendTool/ExecuteCompilerInvocation.cpp1
-rw-r--r--lib/Headers/vecintrin.h1572
-rw-r--r--lib/Index/IndexingAction.cpp12
-rw-r--r--lib/Index/IndexingContext.cpp6
-rw-r--r--lib/Lex/MacroArgs.cpp10
-rw-r--r--lib/Lex/MacroInfo.cpp19
-rw-r--r--lib/Lex/PPDirectives.cpp96
-rw-r--r--lib/Lex/PPExpressions.cpp59
-rw-r--r--lib/Lex/PPMacroExpansion.cpp10
-rw-r--r--lib/Lex/Preprocessor.cpp8
-rw-r--r--lib/Lex/TokenLexer.cpp12
-rw-r--r--lib/Parse/ParseObjc.cpp4
-rw-r--r--lib/Parse/ParseOpenMP.cpp23
-rw-r--r--lib/Sema/DeclSpec.cpp6
-rw-r--r--lib/Sema/Sema.cpp3
-rw-r--r--lib/Sema/SemaChecking.cpp24
-rw-r--r--lib/Sema/SemaCodeComplete.cpp6
-rw-r--r--lib/Sema/SemaDeclAttr.cpp126
-rw-r--r--lib/Sema/SemaDeclObjC.cpp58
-rw-r--r--lib/Sema/SemaExpr.cpp79
-rw-r--r--lib/Sema/SemaObjCProperty.cpp187
-rw-r--r--lib/Sema/SemaOpenMP.cpp350
-rw-r--r--lib/Sema/SemaType.cpp39
-rw-r--r--lib/Sema/TreeTransform.h60
-rw-r--r--lib/Serialization/ASTReader.cpp86
-rw-r--r--lib/Serialization/ASTReaderStmt.cpp42
-rw-r--r--lib/Serialization/ASTWriter.cpp6
-rw-r--r--lib/Serialization/ASTWriterStmt.cpp20
-rw-r--r--lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp69
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp35
-rw-r--r--lib/Tooling/Refactoring/Rename/USRFinder.cpp179
-rw-r--r--lib/Tooling/Refactoring/Rename/USRLocFinder.cpp90
-rw-r--r--lib/Tooling/Tooling.cpp1
-rw-r--r--test/Analysis/localization-aggressive.m19
-rw-r--r--test/Analysis/retain-release-inline.m56
-rw-r--r--test/Analysis/retain-release.m2
-rw-r--r--test/CodeGen/aarch64-type-sizes.c2
-rw-r--r--test/CodeGen/aarch64-varargs-ms.c11
-rw-r--r--test/CodeGen/builtins-hexagon.c12
-rw-r--r--test/CodeGen/builtins-systemz-vector2-error.c61
-rw-r--r--test/CodeGen/builtins-systemz-vector2.c136
-rw-r--r--test/CodeGen/builtins-systemz-zvector-error.c38
-rw-r--r--test/CodeGen/builtins-systemz-zvector.c88
-rw-r--r--test/CodeGen/builtins-systemz-zvector2-error.c153
-rw-r--r--test/CodeGen/builtins-systemz-zvector2.c545
-rw-r--r--test/CodeGen/coff-aarch64-type-sizes.c88
-rw-r--r--test/CodeGen/debug-info-imported-entity.cpp3
-rw-r--r--test/CodeGen/ms_abi.c6
-rw-r--r--test/CodeGen/ms_abi_aarch64.c68
-rw-r--r--test/CodeGen/systemz-abi-vector.c4
-rw-r--r--test/CodeGen/systemz-abi.c4
-rw-r--r--test/CodeGen/target-data.c4
-rw-r--r--test/CodeGen/ubsan-pointer-overflow.m15
-rw-r--r--test/CodeGen/zvector2.c194
-rw-r--r--test/CodeGenCXX/amdgcn-automatic-variable.cpp33
-rw-r--r--test/CodeGenCXX/debug-info-anon-namespace.cpp4
-rw-r--r--test/CodeGenCXX/debug-info-namespace.cpp8
-rw-r--r--test/CodeGenCXX/implicit-exception-spec.cpp2
-rw-r--r--test/CodeGenObjC/arc-property.m20
-rw-r--r--test/CodeGenObjC/attr-callconv.m2
-rw-r--r--test/CodeGenOpenCL/kernel-arg-info.cl37
-rw-r--r--test/Driver/autocomplete.c4
-rw-r--r--test/Driver/constructors.c8
-rw-r--r--test/Driver/darwin-version.c12
-rw-r--r--test/Driver/emulated-tls.cpp4
-rw-r--r--test/Driver/fuchsia.c1
-rw-r--r--test/Driver/fuchsia.cpp1
-rw-r--r--test/Driver/lto-unit.c2
-rw-r--r--test/Driver/pic.c3
-rw-r--r--test/Driver/std.cpp10
-rw-r--r--test/Driver/systemz-march.c4
-rw-r--r--test/Driver/unknown-std.cpp2
-rw-r--r--test/FixIt/format.m13
-rw-r--r--test/Index/Core/index-source.m25
-rw-r--r--test/Index/Core/no-templated-canonical-decl.cpp4
-rw-r--r--test/Index/complete-available.m4
-rw-r--r--test/Misc/ast-dump-decl.c2
-rw-r--r--test/Misc/ast-dump-decl.cpp2
-rw-r--r--test/Modules/DebugInfoTransitiveImport.m4
-rw-r--r--test/Modules/ExtDebugInfo.cpp4
-rw-r--r--test/Modules/Inputs/DebugObjCImport.h2
-rw-r--r--test/Modules/Inputs/module.map6
-rw-r--r--test/Modules/ModuleDebugInfo.m6
-rw-r--r--test/Modules/debug-info-moduleimport-in-module.m21
-rw-r--r--test/Modules/debug-info-moduleimport.m5
-rw-r--r--test/Modules/odr_hash.cpp83
-rw-r--r--test/OpenMP/distribute_parallel_for_if_codegen.cpp2
-rw-r--r--test/OpenMP/for_reduction_codegen.cpp46
-rw-r--r--test/OpenMP/for_reduction_codegen_UDR.cpp47
-rw-r--r--test/OpenMP/parallel_if_codegen.cpp2
-rw-r--r--test/OpenMP/taskgroup_ast_print.cpp60
-rw-r--r--test/OpenMP/taskgroup_messages.cpp2
-rw-r--r--test/OpenMP/taskgroup_task_reduction_messages.cpp258
-rw-r--r--test/OpenMP/taskloop_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_firstprivate_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_lastprivate_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_private_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_reduction_codegen.cpp197
-rw-r--r--test/OpenMP/taskloop_simd_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_simd_firstprivate_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_simd_lastprivate_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_simd_private_codegen.cpp8
-rw-r--r--test/OpenMP/taskloop_simd_reduction_codegen.cpp197
-rw-r--r--test/Parser/MicrosoftExtensions.cpp4
-rw-r--r--test/Preprocessor/aarch64-target-features.c5
-rw-r--r--test/Preprocessor/cxx_oper_keyword.cpp12
-rw-r--r--test/Preprocessor/init.c16
-rw-r--r--test/Preprocessor/predefined-arch-macros.c21
-rw-r--r--test/Sema/tls.c6
-rw-r--r--test/Sema/varargs-aarch64.c11
-rw-r--r--test/Sema/varargs-x86-32.c2
-rw-r--r--test/Sema/zvector2.c211
-rw-r--r--test/SemaCXX/attr-x86-no_caller_saved_registers.cpp2
-rw-r--r--test/SemaCXX/cxx1z-noexcept-function-type.cpp1
-rw-r--r--test/SemaObjC/arc-property-decl-attrs.m104
-rw-r--r--test/SemaObjC/attr-ns_returns_retained.m18
-rw-r--r--test/SemaObjC/property-ambiguous-synthesis.m2
-rw-r--r--test/SemaObjC/warn-deprecated-implementations.m19
-rw-r--r--tools/clang-fuzzer/CMakeLists.txt3
-rw-r--r--tools/clang-fuzzer/ClangFuzzer.cpp11
-rw-r--r--tools/libclang/ARCMigrate.cpp1
-rw-r--r--tools/libclang/CIndex.cpp19
-rw-r--r--tools/libclang/CXType.cpp2
-rw-r--r--tools/scan-build-py/libscanbuild/analyze.py2
-rw-r--r--unittests/ASTMatchers/Dynamic/ParserTest.cpp4
-rw-r--r--unittests/Format/FormatTest.cpp11
-rw-r--r--unittests/Format/FormatTestJS.cpp11
-rw-r--r--unittests/Format/SortImportsTestJS.cpp17
-rw-r--r--unittests/Lex/LexerTest.cpp6
-rw-r--r--unittests/Tooling/CMakeLists.txt1
-rw-r--r--unittests/Tooling/DiagnosticsYamlTest.cpp167
-rwxr-xr-xutils/bash-autocomplete.sh11
-rw-r--r--www/analyzer/alpha_checks.html280
-rw-r--r--www/analyzer/available_checks.html323
-rw-r--r--www/analyzer/implicit_checks.html4
-rw-r--r--www/cxx_status.html83
221 files changed, 8808 insertions, 1822 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index c163a2b50429..2667b1d6892e 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -389,11 +389,7 @@ if(CLANG_ANALYZER_BUILD_Z3)
endif()
if(CLANG_ENABLE_ARCMT)
- add_definitions(-DCLANG_ENABLE_ARCMT)
- add_definitions(-DCLANG_ENABLE_OBJC_REWRITER)
-endif()
-if(CLANG_ENABLE_STATIC_ANALYZER)
- add_definitions(-DCLANG_ENABLE_STATIC_ANALYZER)
+ set(CLANG_ENABLE_OBJC_REWRITER ON)
endif()
# Clang version information
diff --git a/cmake/caches/Fuchsia-stage2.cmake b/cmake/caches/Fuchsia-stage2.cmake
index ca43e603a631..1b7b636fef3e 100644
--- a/cmake/caches/Fuchsia-stage2.cmake
+++ b/cmake/caches/Fuchsia-stage2.cmake
@@ -7,7 +7,6 @@ set(PACKAGE_VENDOR Fuchsia CACHE STRING "")
set(LLVM_INCLUDE_EXAMPLES OFF CACHE BOOL "")
set(LLVM_INCLUDE_DOCS OFF CACHE BOOL "")
-set(LLVM_TOOL_CLANG_TOOLS_EXTRA_BUILD OFF CACHE BOOL "")
set(LLVM_ENABLE_ZLIB ON CACHE BOOL "")
set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
@@ -27,11 +26,27 @@ set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
-set(LLVM_BUILTIN_TARGETS "x86_64-fuchsia-none;aarch64-fuchsia-none" CACHE STRING "")
-set(BUILTINS_x86_64-fuchsia-none_CMAKE_SYSROOT ${FUCHSIA_SYSROOT} CACHE STRING "")
-set(BUILTINS_x86_64-fuchsia-none_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
-set(BUILTINS_aarch64-fuchsia-none_CMAKE_SYSROOT ${FUCHSIA_SYSROOT} CACHE STRING "")
-set(BUILTINS_aarch64-fuchsia-none_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
+set(LLVM_BUILTIN_TARGETS "x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "")
+foreach(target x86_64;aarch64)
+ set(BUILTINS_${target}-fuchsia_CMAKE_SYSROOT ${FUCHSIA_${target}_SYSROOT} CACHE PATH "")
+ set(BUILTINS_${target}-fuchsia_CMAKE_SYSTEM_NAME Fuchsia CACHE STRING "")
+endforeach()
+if(NOT APPLE)
+ list(APPEND LLVM_BUILTIN_TARGETS "default")
+endif()
+
+set(LLVM_RUNTIME_TARGETS "default;x86_64-fuchsia;aarch64-fuchsia" CACHE STRING "")
+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_LIBCXXABI_USE_COMPILER_RT ON CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia_LIBCXXABI_USE_LLVM_UNWINDER ON CACHE BOOL "")
+ set(RUNTIMES_${target}-fuchsia_LIBCXX_USE_COMPILER_RT ON CACHE BOOL "")
+endforeach()
# Setup toolchain.
set(LLVM_INSTALL_TOOLCHAIN_ONLY ON CACHE BOOL "")
@@ -47,6 +62,7 @@ set(LLVM_TOOLCHAIN_TOOLS
llvm-objdump
llvm-profdata
llvm-ranlib
+ llvm-readelf
llvm-readobj
llvm-size
llvm-symbolizer
@@ -61,8 +77,9 @@ set(LLVM_DISTRIBUTION_COMPONENTS
LTO
clang-format
clang-headers
- builtins-x86_64-fuchsia-none
- builtins-aarch64-fuchsia-none
+ clang-tidy
+ clangd
+ builtins
runtimes
${LLVM_TOOLCHAIN_TOOLS}
CACHE STRING "")
diff --git a/cmake/caches/Fuchsia.cmake b/cmake/caches/Fuchsia.cmake
index c8a8cf6d58b7..0932c046f628 100644
--- a/cmake/caches/Fuchsia.cmake
+++ b/cmake/caches/Fuchsia.cmake
@@ -38,9 +38,11 @@ set(CLANG_BOOTSTRAP_TARGETS
install-distribution
clang CACHE STRING "")
-if(FUCHSIA_SYSROOT)
- set(EXTRA_ARGS -DFUCHSIA_SYSROOT=${FUCHSIA_SYSROOT})
-endif()
+foreach(target x86_64;aarch64)
+ if(FUCHSIA_${target}_SYSROOT)
+ list(APPEND EXTRA_ARGS -DFUCHSIA_${target}_SYSROOT=${FUCHSIA_${target}_SYSROOT})
+ endif()
+endforeach()
# Setup the bootstrap build.
set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "")
diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst
index dab538f3a983..78f987c4a8e8 100644
--- a/docs/LanguageExtensions.rst
+++ b/docs/LanguageExtensions.rst
@@ -1271,6 +1271,87 @@ Further examples of these attributes are available in the static analyzer's `lis
Query for these features with ``__has_attribute(ns_consumed)``,
``__has_attribute(ns_returns_retained)``, etc.
+Objective-C @available
+----------------------
+
+It is possible to use the newest SDK but still build a program that can run on
+older versions of macOS and iOS by passing ``-mmacosx-version-min=`` /
+``-miphoneos-version-min=``.
+
+Before LLVM 5.0, when calling a function that exists only in the OS that's
+newer than the target OS (as determined by the minimum deployment version),
+programmers had to carefully check if the function exists at runtime, using
+null checks for weakly-linked C functions, ``+class`` for Objective-C classes,
+and ``-respondsToSelector:`` or ``+instancesRespondToSelector:`` for
+Objective-C methods. If such a check was missed, the program would compile
+fine, run fine on newer systems, but crash on older systems.
+
+As of LLVM 5.0, ``-Wunguarded-availability`` uses the `availability attributes
+<http://clang.llvm.org/docs/AttributeReference.html#availability>`_ together
+with the new ``@available()`` keyword to assist with this issue.
+When a method that's introduced in the OS newer than the target OS is called, a
+-Wunguarded-availability warning is emitted if that call is not guarded:
+
+.. code-block:: objc
+
+ void my_fun(NSSomeClass* var) {
+ // If fancyNewMethod was added in e.g. macOS 10.12, but the code is
+ // built with -mmacosx-version-min=10.11, then this unconditional call
+ // will emit a -Wunguarded-availability warning:
+ [var fancyNewMethod];
+ }
+
+To fix the warning and to avoid the crash on macOS 10.11, wrap it in
+``if(@available())``:
+
+.. code-block:: objc
+
+ void my_fun(NSSomeClass* var) {
+ if (@available(macOS 10.12, *)) {
+ [var fancyNewMethod];
+ } else {
+ // Put fallback behavior for old macOS versions (and for non-mac
+ // platforms) here.
+ }
+ }
+
+The ``*`` is required and means that platforms not explicitly listed will take
+the true branch, and the compiler will emit ``-Wunguarded-availability``
+warnings for unlisted platforms based on those platform's deployment target.
+More than one platform can be listed in ``@available()``:
+
+.. code-block:: objc
+
+ void my_fun(NSSomeClass* var) {
+ if (@available(macOS 10.12, iOS 10, *)) {
+ [var fancyNewMethod];
+ }
+ }
+
+If the caller of ``my_fun()`` already checks that ``my_fun()`` is only called
+on 10.12, then add an `availability attribute
+<http://clang.llvm.org/docs/AttributeReference.html#availability>`_ to it,
+which will also suppress the warning and require that calls to my_fun() are
+checked:
+
+.. code-block:: objc
+
+ API_AVAILABLE(macos(10.12)) void my_fun(NSSomeClass* var) {
+ [var fancyNewMethod]; // Now ok.
+ }
+
+``@available()`` is only available in Objective-C code. To use the feature
+in C and C++ code, use the ``__builtin_available()`` spelling instead.
+
+If existing code uses null checks or ``-respondsToSelector:``, it should
+be changed to use ``@available()`` (or ``__builtin_available``) instead.
+
+``-Wunguarded-availability`` is disabled by default, but
+``-Wunguarded-availability-new``, which only emits this warning for APIs
+that have been introduced in macOS >= 10.13, iOS >= 11, watchOS >= 4 and
+tvOS >= 11, is enabled by default.
+
+.. _langext-overloading:
Objective-C++ ABI: protocol-qualifier mangling of parameters
------------------------------------------------------------
@@ -1287,8 +1368,6 @@ parameters of protocol-qualified type.
Query the presence of this new mangling with
``__has_feature(objc_protocol_qualifier_mangling)``.
-.. _langext-overloading:
-
Initializer lists for complex numbers in C
==========================================
diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst
index 8f1515dafd97..deffa24c4e42 100644
--- a/docs/ReleaseNotes.rst
+++ b/docs/ReleaseNotes.rst
@@ -82,7 +82,9 @@ Clang now supports the ...
Attribute Changes in Clang
--------------------------
-- ...
+- The ``overloadable`` attribute now allows at most one function with a given
+ name to lack the ``overloadable`` attribute. This unmarked function will not
+ have its name mangled.
Windows Support
---------------
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index 09f4403556c8..b35f436e91b6 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -3205,7 +3205,7 @@ enum CXCallingConv {
CXCallingConv_AAPCS_VFP = 7,
CXCallingConv_X86RegCall = 8,
CXCallingConv_IntelOclBicc = 9,
- CXCallingConv_X86_64Win64 = 10,
+ CXCallingConv_Win64 = 10,
CXCallingConv_X86_64SysV = 11,
CXCallingConv_X86VectorCall = 12,
CXCallingConv_Swift = 13,
diff --git a/include/clang/AST/ASTContext.h b/include/clang/AST/ASTContext.h
index 3b46d31458ce..703f588c5663 100644
--- a/include/clang/AST/ASTContext.h
+++ b/include/clang/AST/ASTContext.h
@@ -1441,6 +1441,10 @@ public:
/// The sizeof operator requires this (C99 6.5.3.4p4).
CanQualType getSizeType() const;
+ /// \brief Return the unique signed counterpart of
+ /// the integer type corresponding to size_t.
+ CanQualType getSignedSizeType() const;
+
/// \brief Return the unique type for "intmax_t" (C99 7.18.1.5), defined in
/// <stdint.h>.
CanQualType getIntMaxType() const;
diff --git a/include/clang/AST/DeclObjC.h b/include/clang/AST/DeclObjC.h
index 26c0cbe82d17..1cd6e004f751 100644
--- a/include/clang/AST/DeclObjC.h
+++ b/include/clang/AST/DeclObjC.h
@@ -1039,10 +1039,9 @@ public:
typedef llvm::DenseMap<std::pair<IdentifierInfo*,
unsigned/*isClassProperty*/>,
ObjCPropertyDecl*> PropertyMap;
-
- typedef llvm::DenseMap<const ObjCProtocolDecl *, ObjCPropertyDecl*>
- ProtocolPropertyMap;
-
+
+ typedef llvm::SmallDenseSet<const ObjCProtocolDecl *, 8> ProtocolPropertySet;
+
typedef llvm::SmallVector<ObjCPropertyDecl*, 8> PropertyDeclOrder;
/// This routine collects list of properties to be implemented in the class.
@@ -2159,7 +2158,8 @@ public:
PropertyDeclOrder &PO) const override;
void collectInheritedProtocolProperties(const ObjCPropertyDecl *Property,
- ProtocolPropertyMap &PM) const;
+ ProtocolPropertySet &PS,
+ PropertyDeclOrder &PO) const;
static bool classof(const Decl *D) { return classofKind(D->getKind()); }
static bool classofKind(Kind K) { return K == ObjCProtocol; }
diff --git a/include/clang/AST/OpenMPClause.h b/include/clang/AST/OpenMPClause.h
index 14e73819f53d..a1cae8e18f84 100644
--- a/include/clang/AST/OpenMPClause.h
+++ b/include/clang/AST/OpenMPClause.h
@@ -1890,6 +1890,217 @@ public:
}
};
+/// This represents clause 'task_reduction' in the '#pragma omp taskgroup'
+/// directives.
+///
+/// \code
+/// #pragma omp taskgroup task_reduction(+:a,b)
+/// \endcode
+/// In this example directive '#pragma omp taskgroup' has clause
+/// 'task_reduction' with operator '+' and the variables 'a' and 'b'.
+///
+class OMPTaskReductionClause final
+ : public OMPVarListClause<OMPTaskReductionClause>,
+ public OMPClauseWithPostUpdate,
+ private llvm::TrailingObjects<OMPTaskReductionClause, Expr *> {
+ friend TrailingObjects;
+ friend OMPVarListClause;
+ friend class OMPClauseReader;
+ /// Location of ':'.
+ SourceLocation ColonLoc;
+ /// Nested name specifier for C++.
+ NestedNameSpecifierLoc QualifierLoc;
+ /// Name of custom operator.
+ DeclarationNameInfo NameInfo;
+
+ /// Build clause with number of variables \a N.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param EndLoc Ending location of the clause.
+ /// \param ColonLoc Location of ':'.
+ /// \param N Number of the variables in the clause.
+ /// \param QualifierLoc The nested-name qualifier with location information
+ /// \param NameInfo The full name info for reduction identifier.
+ ///
+ OMPTaskReductionClause(SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ unsigned N, NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo)
+ : OMPVarListClause<OMPTaskReductionClause>(OMPC_task_reduction, StartLoc,
+ LParenLoc, EndLoc, N),
+ OMPClauseWithPostUpdate(this), ColonLoc(ColonLoc),
+ QualifierLoc(QualifierLoc), NameInfo(NameInfo) {}
+
+ /// Build an empty clause.
+ ///
+ /// \param N Number of variables.
+ ///
+ explicit OMPTaskReductionClause(unsigned N)
+ : OMPVarListClause<OMPTaskReductionClause>(
+ OMPC_task_reduction, SourceLocation(), SourceLocation(),
+ SourceLocation(), N),
+ OMPClauseWithPostUpdate(this), ColonLoc(), QualifierLoc(), NameInfo() {}
+
+ /// Sets location of ':' symbol in clause.
+ void setColonLoc(SourceLocation CL) { ColonLoc = CL; }
+ /// Sets the name info for specified reduction identifier.
+ void setNameInfo(DeclarationNameInfo DNI) { NameInfo = DNI; }
+ /// Sets the nested name specifier.
+ void setQualifierLoc(NestedNameSpecifierLoc NSL) { QualifierLoc = NSL; }
+
+ /// Set list of helper expressions, required for proper codegen of the clause.
+ /// These expressions represent private copy of the reduction variable.
+ void setPrivates(ArrayRef<Expr *> Privates);
+
+ /// Get the list of helper privates.
+ MutableArrayRef<Expr *> getPrivates() {
+ return MutableArrayRef<Expr *>(varlist_end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getPrivates() const {
+ return llvm::makeArrayRef(varlist_end(), varlist_size());
+ }
+
+ /// Set list of helper expressions, required for proper codegen of the clause.
+ /// These expressions represent LHS expression in the final reduction
+ /// expression performed by the reduction clause.
+ void setLHSExprs(ArrayRef<Expr *> LHSExprs);
+
+ /// Get the list of helper LHS expressions.
+ MutableArrayRef<Expr *> getLHSExprs() {
+ return MutableArrayRef<Expr *>(getPrivates().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getLHSExprs() const {
+ return llvm::makeArrayRef(getPrivates().end(), varlist_size());
+ }
+
+ /// Set list of helper expressions, required for proper codegen of the clause.
+ /// These expressions represent RHS expression in the final reduction
+ /// expression performed by the reduction clause. Also, variables in these
+ /// expressions are used for proper initialization of reduction copies.
+ void setRHSExprs(ArrayRef<Expr *> RHSExprs);
+
+ /// Get the list of helper destination expressions.
+ MutableArrayRef<Expr *> getRHSExprs() {
+ return MutableArrayRef<Expr *>(getLHSExprs().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getRHSExprs() const {
+ return llvm::makeArrayRef(getLHSExprs().end(), varlist_size());
+ }
+
+ /// Set list of helper reduction expressions, required for proper
+ /// codegen of the clause. These expressions are binary expressions or
+ /// operator/custom reduction call that calculates new value from source
+ /// helper expressions to destination helper expressions.
+ void setReductionOps(ArrayRef<Expr *> ReductionOps);
+
+ /// Get the list of helper reduction expressions.
+ MutableArrayRef<Expr *> getReductionOps() {
+ return MutableArrayRef<Expr *>(getRHSExprs().end(), varlist_size());
+ }
+ ArrayRef<const Expr *> getReductionOps() const {
+ return llvm::makeArrayRef(getRHSExprs().end(), varlist_size());
+ }
+
+public:
+ /// Creates clause with a list of variables \a VL.
+ ///
+ /// \param StartLoc Starting location of the clause.
+ /// \param LParenLoc Location of '('.
+ /// \param ColonLoc Location of ':'.
+ /// \param EndLoc Ending location of the clause.
+ /// \param VL The variables in the clause.
+ /// \param QualifierLoc The nested-name qualifier with location information
+ /// \param NameInfo The full name info for reduction identifier.
+ /// \param Privates List of helper expressions for proper generation of
+ /// private copies.
+ /// \param LHSExprs List of helper expressions for proper generation of
+ /// assignment operation required for copyprivate clause. This list represents
+ /// LHSs of the reduction expressions.
+ /// \param RHSExprs List of helper expressions for proper generation of
+ /// assignment operation required for copyprivate clause. This list represents
+ /// RHSs of the reduction expressions.
+ /// Also, variables in these expressions are used for proper initialization of
+ /// reduction copies.
+ /// \param ReductionOps List of helper expressions that represents reduction
+ /// expressions:
+ /// \code
+ /// LHSExprs binop RHSExprs;
+ /// operator binop(LHSExpr, RHSExpr);
+ /// <CutomReduction>(LHSExpr, RHSExpr);
+ /// \endcode
+ /// Required for proper codegen of final reduction operation performed by the
+ /// reduction clause.
+ /// \param PreInit Statement that must be executed before entering the OpenMP
+ /// region with this clause.
+ /// \param PostUpdate Expression that must be executed after exit from the
+ /// OpenMP region with this clause.
+ ///
+ static OMPTaskReductionClause *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc,
+ const DeclarationNameInfo &NameInfo, ArrayRef<Expr *> Privates,
+ ArrayRef<Expr *> LHSExprs, ArrayRef<Expr *> RHSExprs,
+ ArrayRef<Expr *> ReductionOps, Stmt *PreInit, Expr *PostUpdate);
+
+ /// Creates an empty clause with the place for \a N variables.
+ ///
+ /// \param C AST context.
+ /// \param N The number of variables.
+ ///
+ static OMPTaskReductionClause *CreateEmpty(const ASTContext &C, unsigned N);
+
+ /// Gets location of ':' symbol in clause.
+ SourceLocation getColonLoc() const { return ColonLoc; }
+ /// Gets the name info for specified reduction identifier.
+ const DeclarationNameInfo &getNameInfo() const { return NameInfo; }
+ /// Gets the nested name specifier.
+ NestedNameSpecifierLoc getQualifierLoc() const { return QualifierLoc; }
+
+ typedef MutableArrayRef<Expr *>::iterator helper_expr_iterator;
+ typedef ArrayRef<const Expr *>::iterator helper_expr_const_iterator;
+ typedef llvm::iterator_range<helper_expr_iterator> helper_expr_range;
+ typedef llvm::iterator_range<helper_expr_const_iterator>
+ helper_expr_const_range;
+
+ helper_expr_const_range privates() const {
+ return helper_expr_const_range(getPrivates().begin(), getPrivates().end());
+ }
+ helper_expr_range privates() {
+ return helper_expr_range(getPrivates().begin(), getPrivates().end());
+ }
+ helper_expr_const_range lhs_exprs() const {
+ return helper_expr_const_range(getLHSExprs().begin(), getLHSExprs().end());
+ }
+ helper_expr_range lhs_exprs() {
+ return helper_expr_range(getLHSExprs().begin(), getLHSExprs().end());
+ }
+ helper_expr_const_range rhs_exprs() const {
+ return helper_expr_const_range(getRHSExprs().begin(), getRHSExprs().end());
+ }
+ helper_expr_range rhs_exprs() {
+ return helper_expr_range(getRHSExprs().begin(), getRHSExprs().end());
+ }
+ helper_expr_const_range reduction_ops() const {
+ return helper_expr_const_range(getReductionOps().begin(),
+ getReductionOps().end());
+ }
+ helper_expr_range reduction_ops() {
+ return helper_expr_range(getReductionOps().begin(),
+ getReductionOps().end());
+ }
+
+ child_range children() {
+ return child_range(reinterpret_cast<Stmt **>(varlist_begin()),
+ reinterpret_cast<Stmt **>(varlist_end()));
+ }
+
+ static bool classof(const OMPClause *T) {
+ return T->getClauseKind() == OMPC_task_reduction;
+ }
+};
+
/// \brief This represents clause 'linear' in the '#pragma omp ...'
/// directives.
///
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 917b240428e7..e7f271cc0812 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -3017,6 +3017,28 @@ RecursiveASTVisitor<Derived>::VisitOMPReductionClause(OMPReductionClause *C) {
}
template <typename Derived>
+bool RecursiveASTVisitor<Derived>::VisitOMPTaskReductionClause(
+ OMPTaskReductionClause *C) {
+ TRY_TO(TraverseNestedNameSpecifierLoc(C->getQualifierLoc()));
+ TRY_TO(TraverseDeclarationNameInfo(C->getNameInfo()));
+ TRY_TO(VisitOMPClauseList(C));
+ TRY_TO(VisitOMPClauseWithPostUpdate(C));
+ for (auto *E : C->privates()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->lhs_exprs()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->rhs_exprs()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ for (auto *E : C->reduction_ops()) {
+ TRY_TO(TraverseStmt(E));
+ }
+ return true;
+}
+
+template <typename Derived>
bool RecursiveASTVisitor<Derived>::VisitOMPFlushClause(OMPFlushClause *C) {
TRY_TO(VisitOMPClauseList(C));
return true;
diff --git a/include/clang/AST/StmtOpenMP.h b/include/clang/AST/StmtOpenMP.h
index 463af06fddab..09dd87fdc8bc 100644
--- a/include/clang/AST/StmtOpenMP.h
+++ b/include/clang/AST/StmtOpenMP.h
@@ -1895,7 +1895,7 @@ public:
}
};
-/// \brief This represents '#pragma omp taskgroup' directive.
+/// This represents '#pragma omp taskgroup' directive.
///
/// \code
/// #pragma omp taskgroup
@@ -1903,39 +1903,45 @@ public:
///
class OMPTaskgroupDirective : public OMPExecutableDirective {
friend class ASTStmtReader;
- /// \brief Build directive with the given start and end location.
+ /// Build directive with the given start and end location.
///
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending location of the directive.
+ /// \param NumClauses Number of clauses.
///
- OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc)
+ OMPTaskgroupDirective(SourceLocation StartLoc, SourceLocation EndLoc,
+ unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- StartLoc, EndLoc, 0, 1) {}
+ StartLoc, EndLoc, NumClauses, 1) {}
- /// \brief Build an empty directive.
+ /// Build an empty directive.
+ /// \param NumClauses Number of clauses.
///
- explicit OMPTaskgroupDirective()
+ explicit OMPTaskgroupDirective(unsigned NumClauses)
: OMPExecutableDirective(this, OMPTaskgroupDirectiveClass, OMPD_taskgroup,
- SourceLocation(), SourceLocation(), 0, 1) {}
+ SourceLocation(), SourceLocation(), NumClauses,
+ 1) {}
public:
- /// \brief Creates directive.
+ /// Creates directive.
///
/// \param C AST context.
/// \param StartLoc Starting location of the directive kind.
/// \param EndLoc Ending Location of the directive.
+ /// \param Clauses List of clauses.
/// \param AssociatedStmt Statement, associated with the directive.
///
- static OMPTaskgroupDirective *Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt);
+ static OMPTaskgroupDirective *
+ Create(const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt);
- /// \brief Creates an empty directive.
+ /// Creates an empty directive.
///
/// \param C AST context.
+ /// \param NumClauses Number of clauses.
///
- static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C, EmptyShell);
+ static OMPTaskgroupDirective *CreateEmpty(const ASTContext &C,
+ unsigned NumClauses, EmptyShell);
static bool classof(const Stmt *T) {
return T->getStmtClass() == OMPTaskgroupDirectiveClass;
diff --git a/include/clang/AST/Type.h b/include/clang/AST/Type.h
index 9eb6d81296d8..64bd3c701985 100644
--- a/include/clang/AST/Type.h
+++ b/include/clang/AST/Type.h
@@ -3878,6 +3878,7 @@ public:
attr_sptr,
attr_uptr,
attr_nonnull,
+ attr_ns_returns_retained,
attr_nullable,
attr_null_unspecified,
attr_objc_kindof,
diff --git a/include/clang/Analysis/Analyses/Dominators.h b/include/clang/Analysis/Analyses/Dominators.h
index 1229f8a8efac..38010e1ee1d8 100644
--- a/include/clang/Analysis/Analyses/Dominators.h
+++ b/include/clang/Analysis/Analyses/Dominators.h
@@ -38,15 +38,15 @@ typedef llvm::DomTreeNodeBase<CFGBlock> DomTreeNode;
class DominatorTree : public ManagedAnalysis {
virtual void anchor();
public:
- llvm::DominatorTreeBase<CFGBlock>* DT;
+ llvm::DomTreeBase<CFGBlock>* DT;
DominatorTree() {
- DT = new llvm::DominatorTreeBase<CFGBlock>(false);
+ DT = new llvm::DomTreeBase<CFGBlock>();
}
~DominatorTree() override { delete DT; }
- llvm::DominatorTreeBase<CFGBlock>& getBase() { return *DT; }
+ llvm::DomTreeBase<CFGBlock>& getBase() { return *DT; }
/// \brief This method returns the root CFGBlock of the dominators tree.
///
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index bc36fd8c8297..f13e13b0107b 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -1802,11 +1802,18 @@ def Target : InheritableAttr {
let Subjects = SubjectList<[Function], ErrorDiag>;
let Documentation = [TargetDocs];
let AdditionalMembers = [{
- typedef std::pair<std::vector<std::string>, StringRef> ParsedTargetAttr;
+ struct ParsedTargetAttr {
+ std::vector<std::string> Features;
+ StringRef Architecture;
+ bool DuplicateArchitecture = false;
+ };
ParsedTargetAttr parse() const {
+ return parse(getFeaturesStr());
+ }
+ static ParsedTargetAttr parse(StringRef Features) {
ParsedTargetAttr Ret;
SmallVector<StringRef, 1> AttrFeatures;
- getFeaturesStr().split(AttrFeatures, ",");
+ Features.split(AttrFeatures, ",");
// Grab the various features and prepend a "+" to turn on the feature to
// the backend and add them to our existing set of features.
@@ -1823,12 +1830,15 @@ def Target : InheritableAttr {
continue;
// While we're here iterating check for a different target cpu.
- if (Feature.startswith("arch="))
- Ret.second = Feature.split("=").second.trim();
- else if (Feature.startswith("no-"))
- Ret.first.push_back("-" + Feature.split("-").second.str());
+ if (Feature.startswith("arch=")) {
+ if (!Ret.Architecture.empty())
+ Ret.DuplicateArchitecture = true;
+ else
+ Ret.Architecture = Feature.split("=").second.trim();
+ } else if (Feature.startswith("no-"))
+ Ret.Features.push_back("-" + Feature.split("-").second.str());
else
- Ret.first.push_back("+" + Feature.str());
+ Ret.Features.push_back("+" + Feature.str());
}
return Ret;
}
diff --git a/include/clang/Basic/AttrDocs.td b/include/clang/Basic/AttrDocs.td
index 2987f07d8bb4..33ef3ea4cade 100644
--- a/include/clang/Basic/AttrDocs.td
+++ b/include/clang/Basic/AttrDocs.td
@@ -910,13 +910,13 @@ the function declaration for a hypothetical function ``f``:
void f(void) __attribute__((availability(macos,introduced=10.4,deprecated=10.6,obsoleted=10.7)));
-The availability attribute states that ``f`` was introduced in Mac OS X 10.4,
-deprecated in Mac OS X 10.6, and obsoleted in Mac OS X 10.7. This information
+The availability attribute states that ``f`` was introduced in macOS 10.4,
+deprecated in macOS 10.6, and obsoleted in macOS 10.7. This information
is used by Clang to determine when it is safe to use ``f``: for example, if
-Clang is instructed to compile code for Mac OS X 10.5, a call to ``f()``
-succeeds. If Clang is instructed to compile code for Mac OS X 10.6, the call
+Clang is instructed to compile code for macOS 10.5, a call to ``f()``
+succeeds. If Clang is instructed to compile code for macOS 10.6, the call
succeeds but Clang emits a warning specifying that the function is deprecated.
-Finally, if Clang is instructed to compile code for Mac OS X 10.7, the call
+Finally, if Clang is instructed to compile code for macOS 10.7, the call
fails because ``f()`` is no longer available.
The availability attribute is a comma-separated list starting with the
@@ -961,7 +961,7 @@ are:
command-line arguments.
``macos``
- Apple's Mac OS X operating system. The minimum deployment target is
+ Apple's macOS operating system. The minimum deployment target is
specified by the ``-mmacosx-version-min=*version*`` command-line argument.
``macosx`` is supported for backward-compatibility reasons, but it is
deprecated.
@@ -1015,6 +1015,19 @@ When one method overrides another, the overriding method can be more widely avai
- (id)method __attribute__((availability(macos,introduced=10.3))); // okay: method moved into base class later
- (id)method __attribute__((availability(macos,introduced=10.5))); // error: this method was available via the base class in 10.4
@end
+
+Starting with the macOS 10.12 SDK, the ``API_AVAILABLE`` macro from
+``<os/availability.h>`` can simplify the spelling:
+
+.. code-block:: objc
+
+ @interface A
+ - (id)method API_AVAILABLE(macos(10.11)));
+ - (id)otherMethod API_AVAILABLE(macos(10.11), ios(11.0));
+ @end
+
+Also see the documentation for `@available
+<http://clang.llvm.org/docs/LanguageExtensions.html#objective-c-available>`_
}];
}
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 75781dc7491d..1ddb9beaf913 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -1413,6 +1413,11 @@ BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
// Builtins for XRay
BUILTIN(__xray_customevent, "vcC*z", "")
+// Win64-compatible va_list functions
+BUILTIN(__builtin_ms_va_start, "vc*&.", "nt")
+BUILTIN(__builtin_ms_va_end, "vc*&", "n")
+BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n")
+
#undef BUILTIN
#undef LIBBUILTIN
#undef LANGBUILTIN
diff --git a/include/clang/Basic/BuiltinsHexagon.def b/include/clang/Basic/BuiltinsHexagon.def
index 85936cbfc08e..14fc4adc25bc 100644
--- a/include/clang/Basic/BuiltinsHexagon.def
+++ b/include/clang/Basic/BuiltinsHexagon.def
@@ -882,6 +882,12 @@ BUILTIN(__builtin_HEXAGON_S2_ct0p,"iLLi","")
BUILTIN(__builtin_HEXAGON_S2_ct1p,"iLLi","")
BUILTIN(__builtin_HEXAGON_S2_interleave,"LLiLLi","")
BUILTIN(__builtin_HEXAGON_S2_deinterleave,"LLiLLi","")
+BUILTIN(__builtin_HEXAGON_Y2_dccleana,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y2_dccleaninva,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y2_dcinva,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y2_dczeroa,"vv*","")
+BUILTIN(__builtin_HEXAGON_Y4_l2fetch,"vv*Ui","")
+BUILTIN(__builtin_HEXAGON_Y5_l2fetch,"vv*LLUi","")
BUILTIN(__builtin_HEXAGON_S6_rol_i_r,"iii","v:60:")
BUILTIN(__builtin_HEXAGON_S6_rol_i_p,"LLiLLii","v:60:")
diff --git a/include/clang/Basic/BuiltinsSystemZ.def b/include/clang/Basic/BuiltinsSystemZ.def
index fa96e10b3990..ac92286af0b5 100644
--- a/include/clang/Basic/BuiltinsSystemZ.def
+++ b/include/clang/Basic/BuiltinsSystemZ.def
@@ -253,5 +253,29 @@ TARGET_BUILTIN(__builtin_s390_vfmsdb, "V2dV2dV2dV2d", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vfsqdb, "V2dV2d", "nc", "vector")
TARGET_BUILTIN(__builtin_s390_vftcidb, "V2SLLiV2dIii*", "nc", "vector")
+// Vector-enhancements facility 1 intrinsics.
+TARGET_BUILTIN(__builtin_s390_vlrl, "V16ScUivC*", "", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vstrl, "vV16ScUiv*", "", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vbperm, "V2ULLiV16UcV16Uc", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vmslg, "V16UcV2ULLiV2ULLiV16UcIi", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfmaxdb, "V2dV2dV2dIi", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfmindb, "V2dV2dV2dIi", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfnmadb, "V2dV2dV2dV2d", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfnmsdb, "V2dV2dV2dV2d", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfcesbs, "V4SiV4fV4fi*", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfchsbs, "V4SiV4fV4fi*", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfchesbs, "V4SiV4fV4fi*", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfisb, "V4fV4fIiIi", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfmaxsb, "V4fV4fV4fIi", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfminsb, "V4fV4fV4fIi", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vflnsb, "V4fV4f", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vflpsb, "V4fV4f", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfmasb, "V4fV4fV4fV4f", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfmssb, "V4fV4fV4fV4f", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfnmasb, "V4fV4fV4fV4f", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfnmssb, "V4fV4fV4fV4f", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vfsqsb, "V4fV4f", "nc", "vector-enhancements-1")
+TARGET_BUILTIN(__builtin_s390_vftcisb, "V4SiV4fIii*", "nc", "vector-enhancements-1")
+
#undef BUILTIN
#undef TARGET_BUILTIN
diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def
index 4cd3f1d46473..a516bf6bf06c 100644
--- a/include/clang/Basic/BuiltinsX86.def
+++ b/include/clang/Basic/BuiltinsX86.def
@@ -34,11 +34,6 @@
// can use it?
BUILTIN(__builtin_cpu_supports, "bcC*", "nc")
-// Win64-compatible va_list functions
-BUILTIN(__builtin_ms_va_start, "vc*&.", "nt")
-BUILTIN(__builtin_ms_va_end, "vc*&", "n")
-BUILTIN(__builtin_ms_va_copy, "vc*&c*&", "n")
-
// Undefined Values
//
TARGET_BUILTIN(__builtin_ia32_undef128, "V2d", "nc", "")
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 3a0564806b32..53d8f36ecd00 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -152,6 +152,8 @@ def GNUFoldingConstant : DiagGroup<"gnu-folding-constant">;
def FormatExtraArgs : DiagGroup<"format-extra-args">;
def FormatZeroLength : DiagGroup<"format-zero-length">;
def CXX1zCompatMangling : DiagGroup<"c++1z-compat-mangling">;
+// Name of this warning in GCC.
+def NoexceptType : DiagGroup<"noexcept-type", [CXX1zCompatMangling]>;
// Warnings for C++1y code which is not compatible with prior C++ standards.
def CXXPre14Compat : DiagGroup<"c++98-c++11-compat">;
diff --git a/include/clang/Basic/DiagnosticIDs.h b/include/clang/Basic/DiagnosticIDs.h
index 479d1978c62d..cdd358542a0d 100644
--- a/include/clang/Basic/DiagnosticIDs.h
+++ b/include/clang/Basic/DiagnosticIDs.h
@@ -18,6 +18,7 @@
#include "clang/Basic/LLVM.h"
#include "llvm/ADT/IntrusiveRefCntPtr.h"
#include "llvm/ADT/StringRef.h"
+#include <vector>
namespace clang {
class DiagnosticsEngine;
@@ -263,6 +264,13 @@ public:
/// are not SFINAE errors.
static SFINAEResponse getDiagnosticSFINAEResponse(unsigned DiagID);
+ /// \brief Get the string of all diagnostic flags.
+ ///
+ /// \returns A list of all diagnostics flags as they would be written in a
+ /// command line invocation including their `no-` variants. For example:
+ /// `{"-Wempty-body", "-Wno-empty-body", ...}`
+ static std::vector<std::string> getDiagnosticFlags();
+
/// \brief Get the set of all diagnostic IDs in the group with the given name.
///
/// \param[out] Diags - On return, the diagnostics in the group.
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index 5a8750e4dab6..af14638e1d61 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -808,8 +808,10 @@ def warn_property_types_are_incompatible : Warning<
"property type %0 is incompatible with type %1 inherited from %2">,
InGroup<DiagGroup<"incompatible-property-type">>;
def warn_protocol_property_mismatch : Warning<
- "property of type %0 was selected for synthesis">,
+ "property %select{of type %1|with attribute '%1'|without attribute '%1'|with "
+ "getter %1|with setter %1}0 was selected for synthesis">,
InGroup<DiagGroup<"protocol-property-synthesis-ambiguity">>;
+def err_protocol_property_mismatch: Error<warn_protocol_property_mismatch.Text>;
def err_undef_interface : Error<"cannot find interface declaration for %0">;
def err_category_forward_interface : Error<
"cannot define %select{category|class extension}0 for undefined class %1">;
@@ -1088,7 +1090,9 @@ def err_category_property : Error<
def note_property_declare : Note<
"property declared here">;
def note_protocol_property_declare : Note<
- "it could also be property of type %0 declared here">;
+ "it could also be property "
+ "%select{of type %1|without attribute '%1'|with attribute '%1'|with getter "
+ "%1|with setter %1}0 declared here">;
def note_property_synthesize : Note<
"property synthesized here">;
def err_synthesize_category_decl : Error<
@@ -4575,8 +4579,11 @@ def warn_deprecated_fwdclass_message : Warning<
"%0 may be deprecated because the receiver type is unknown">,
InGroup<DeprecatedDeclarations>;
def warn_deprecated_def : Warning<
- "Implementing deprecated %select{method|class|category}0">,
- InGroup<DeprecatedImplementations>, DefaultIgnore;
+ "implementing deprecated %select{method|class|category}0">,
+ InGroup<DeprecatedImplementations>, DefaultIgnore;
+def warn_unavailable_def : Warning<
+ "implementing unavailable method">,
+ InGroup<DeprecatedImplementations>, DefaultIgnore;
def err_unavailable : Error<"%0 is unavailable">;
def err_property_method_unavailable :
Error<"property access is using %0 method which is unavailable">;
@@ -8106,10 +8113,10 @@ def err_systemz_invalid_tabort_code : Error<
"invalid transaction abort code">;
def err_64_bit_builtin_32_bit_tgt : Error<
"this builtin is only available on 64-bit targets">;
+def err_builtin_x64_aarch64_only : Error<
+ "this builtin is only available on x86-64 and aarch64 targets">;
def err_ppc_builtin_only_on_pwr7 : Error<
"this builtin is only valid on POWER7 or later CPUs">;
-def err_x86_builtin_64_only : Error<
- "this builtin is only available on x86-64 targets">;
def err_x86_builtin_invalid_rounding : Error<
"invalid rounding argument">;
def err_x86_builtin_invalid_scale : Error<
@@ -8648,11 +8655,11 @@ def err_omp_unknown_reduction_identifier : Error<
def err_omp_not_resolved_reduction_identifier : Error<
"unable to resolve declare reduction construct for type %0">;
def err_omp_reduction_ref_type_arg : Error<
- "argument of OpenMP clause 'reduction' must reference the same object in all threads">;
+ "argument of OpenMP clause '%0' must reference the same object in all threads">;
def err_omp_clause_not_arithmetic_type_arg : Error<
- "arguments of OpenMP clause 'reduction' for 'min' or 'max' must be of %select{scalar|arithmetic}0 type">;
+ "arguments of OpenMP clause '%0' for 'min' or 'max' must be of %select{scalar|arithmetic}1 type">;
def err_omp_clause_floating_type_arg : Error<
- "arguments of OpenMP clause 'reduction' with bitwise operators cannot be of floating type">;
+ "arguments of OpenMP clause '%0' with bitwise operators cannot be of floating type">;
def err_omp_once_referenced : Error<
"variable can appear only once in OpenMP '%0' clause">;
def err_omp_once_referenced_in_target_update : Error<
diff --git a/include/clang/Basic/DiagnosticSerializationKinds.td b/include/clang/Basic/DiagnosticSerializationKinds.td
index 0fc54848581c..420ccebbfaf0 100644
--- a/include/clang/Basic/DiagnosticSerializationKinds.td
+++ b/include/clang/Basic/DiagnosticSerializationKinds.td
@@ -147,18 +147,29 @@ def err_module_odr_violation_mismatch_decl_diff : Error<
"%select{non-|}5mutable field %4|"
"field %4 with %select{no|an}5 initalizer|"
"field %4 with an initializer|"
- "method %4|"
- "method %4 is %select{not deleted|deleted}5|"
- "method %4 is %select{|pure }5%select{not virtual|virtual}6|"
- "method %4 is %select{not static|static}5|"
- "method %4 is %select{not volatile|volatile}5|"
- "method %4 is %select{not const|const}5|"
- "method %4 is %select{not inline|inline}5|"
- "method %4 that has %5 parameter%s5|"
- "method %4 with %ordinal5 parameter of type %6%select{| decayed from %8}7|"
- "method %4 with %ordinal5 parameter named %6|"
- "method %4 with %ordinal5 parameter with%select{out|}6 a default argument|"
- "method %4 with %ordinal5 parameter with a default argument|"
+ "%select{method %5|constructor|destructor}4|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not deleted|deleted}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{|pure }6%select{not virtual|virtual}7|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not static|static}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not volatile|volatile}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not const|const}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "is %select{not inline|inline}6|"
+ "%select{method %5|constructor|destructor}4 "
+ "that has %6 parameter%s6|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter of type %7%select{| decayed from %9}8|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter named %7|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter with%select{out|}7 a default argument|"
+ "%select{method %5|constructor|destructor}4 "
+ "with %ordinal6 parameter with a default argument|"
"%select{typedef|type alias}4 name %5|"
"%select{typedef|type alias}4 %5 with underlying type %6|"
"data member with name %4|"
@@ -183,18 +194,29 @@ def note_module_odr_violation_mismatch_decl_diff : Note<"but in '%0' found "
"%select{non-|}3mutable field %2|"
"field %2 with %select{no|an}3 initializer|"
"field %2 with a different initializer|"
- "method %2|"
- "method %2 is %select{not deleted|deleted}3|"
- "method %2 is %select{|pure }3%select{not virtual|virtual}4|"
- "method %2 is %select{not static|static}3|"
- "method %2 is %select{not volatile|volatile}3|"
- "method %2 is %select{not const|const}3|"
- "method %2 is %select{not inline|inline}3|"
- "method %2 that has %3 parameter%s3|"
- "method %2 with %ordinal3 parameter of type %4%select{| decayed from %6}5|"
- "method %2 with %ordinal3 parameter named %4|"
- "method %2 with %ordinal3 parameter with%select{out|}4 a default argument|"
- "method %2 with %ordinal3 parameter with a different default argument|"
+ "%select{method %3|constructor|destructor}2|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not deleted|deleted}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{|pure }4%select{not virtual|virtual}5|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not static|static}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not volatile|volatile}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not const|const}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "is %select{not inline|inline}4|"
+ "%select{method %3|constructor|destructor}2 "
+ "that has %4 parameter%s4|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %ordinal4 parameter of type %5%select{| decayed from %7}6|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %ordinal4 parameter named %5|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %ordinal4 parameter with%select{out|}5 a default argument|"
+ "%select{method %3|constructor|destructor}2 "
+ "with %ordinal4 parameter with a different default argument|"
"%select{typedef|type alias}2 name %3|"
"%select{typedef|type alias}2 %3 with different underlying type %4|"
"data member with name %2|"
diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h
index 9b1ba4a98e6f..f94b2c9b2f42 100644
--- a/include/clang/Basic/IdentifierTable.h
+++ b/include/clang/Basic/IdentifierTable.h
@@ -272,10 +272,6 @@ public:
/// this identifier is a C++ alternate representation of an operator.
void setIsCPlusPlusOperatorKeyword(bool Val = true) {
IsCPPOperatorKeyword = Val;
- if (Val)
- NeedsHandleIdentifier = true;
- else
- RecomputeNeedsHandleIdentifier();
}
bool isCPlusPlusOperatorKeyword() const { return IsCPPOperatorKeyword; }
@@ -381,10 +377,9 @@ private:
/// This method is very tied to the definition of HandleIdentifier. Any
/// change to it should be reflected here.
void RecomputeNeedsHandleIdentifier() {
- NeedsHandleIdentifier =
- (isPoisoned() | hasMacroDefinition() | isCPlusPlusOperatorKeyword() |
- isExtensionToken() | isFutureCompatKeyword() || isOutOfDate() ||
- isModulesImport());
+ NeedsHandleIdentifier = isPoisoned() || hasMacroDefinition() ||
+ isExtensionToken() || isFutureCompatKeyword() ||
+ isOutOfDate() || isModulesImport();
}
};
diff --git a/include/clang/Basic/LangOptions.def b/include/clang/Basic/LangOptions.def
index dfdad108922a..c9230e0aaa6f 100644
--- a/include/clang/Basic/LangOptions.def
+++ b/include/clang/Basic/LangOptions.def
@@ -90,6 +90,7 @@ LANGOPT(CPlusPlus , 1, 0, "C++")
LANGOPT(CPlusPlus11 , 1, 0, "C++11")
LANGOPT(CPlusPlus14 , 1, 0, "C++14")
LANGOPT(CPlusPlus1z , 1, 0, "C++1z")
+LANGOPT(CPlusPlus2a , 1, 0, "C++2a")
LANGOPT(ObjC1 , 1, 0, "Objective-C 1")
LANGOPT(ObjC2 , 1, 0, "Objective-C 2")
BENIGN_LANGOPT(ObjCDefaultSynthProperties , 1, 0,
diff --git a/include/clang/Basic/OpenMPKinds.def b/include/clang/Basic/OpenMPKinds.def
index aae1c3a9b8c5..645ed52b59ca 100644
--- a/include/clang/Basic/OpenMPKinds.def
+++ b/include/clang/Basic/OpenMPKinds.def
@@ -168,6 +168,9 @@
#ifndef OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE
#define OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(Name)
#endif
+#ifndef OPENMP_TASKGROUP_CLAUSE
+#define OPENMP_TASKGROUP_CLAUSE(Name)
+#endif
// OpenMP directives.
OPENMP_DIRECTIVE(threadprivate)
@@ -270,6 +273,7 @@ OPENMP_CLAUSE(to, OMPToClause)
OPENMP_CLAUSE(from, OMPFromClause)
OPENMP_CLAUSE(use_device_ptr, OMPUseDevicePtrClause)
OPENMP_CLAUSE(is_device_ptr, OMPIsDevicePtrClause)
+OPENMP_CLAUSE(task_reduction, OMPTaskReductionClause)
// Clauses allowed for OpenMP directive 'parallel'.
OPENMP_PARALLEL_CLAUSE(if)
@@ -848,6 +852,10 @@ OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(aligned)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(safelen)
OPENMP_TARGET_TEAMS_DISTRIBUTE_SIMD_CLAUSE(simdlen)
+// Clauses allowed for OpenMP directive 'taskgroup'.
+OPENMP_TASKGROUP_CLAUSE(task_reduction)
+
+#undef OPENMP_TASKGROUP_CLAUSE
#undef OPENMP_TASKLOOP_SIMD_CLAUSE
#undef OPENMP_TASKLOOP_CLAUSE
#undef OPENMP_LINEAR_KIND
diff --git a/include/clang/Basic/Specifiers.h b/include/clang/Basic/Specifiers.h
index 33952f83ff23..50fb936e01d1 100644
--- a/include/clang/Basic/Specifiers.h
+++ b/include/clang/Basic/Specifiers.h
@@ -236,7 +236,7 @@ namespace clang {
CC_X86ThisCall, // __attribute__((thiscall))
CC_X86VectorCall, // __attribute__((vectorcall))
CC_X86Pascal, // __attribute__((pascal))
- CC_X86_64Win64, // __attribute__((ms_abi))
+ CC_Win64, // __attribute__((ms_abi))
CC_X86_64SysV, // __attribute__((sysv_abi))
CC_X86RegCall, // __attribute__((regcall))
CC_AAPCS, // __attribute__((pcs("aapcs")))
diff --git a/include/clang/Basic/TargetInfo.h b/include/clang/Basic/TargetInfo.h
index 5885532b91db..d1a9ea85dbe9 100644
--- a/include/clang/Basic/TargetInfo.h
+++ b/include/clang/Basic/TargetInfo.h
@@ -226,6 +226,20 @@ protected:
public:
IntType getSizeType() const { return SizeType; }
+ IntType getSignedSizeType() const {
+ switch (SizeType) {
+ case UnsignedShort:
+ return SignedShort;
+ case UnsignedInt:
+ return SignedInt;
+ case UnsignedLong:
+ return SignedLong;
+ case UnsignedLongLong:
+ return SignedLongLong;
+ default:
+ llvm_unreachable("Invalid SizeType");
+ }
+ }
IntType getIntMaxType() const { return IntMaxType; }
IntType getUIntMaxType() const {
return getCorrespondingUnsignedType(IntMaxType);
diff --git a/include/clang/Config/config.h.cmake b/include/clang/Config/config.h.cmake
index 6971b4e9f06d..b138b5fcd828 100644
--- a/include/clang/Config/config.h.cmake
+++ b/include/clang/Config/config.h.cmake
@@ -56,4 +56,9 @@
/* enable x86 relax relocations by default */
#cmakedefine01 ENABLE_X86_RELAX_RELOCATIONS
+/* Enable each functionality of modules */
+#cmakedefine CLANG_ENABLE_ARCMT
+#cmakedefine CLANG_ENABLE_OBJC_REWRITER
+#cmakedefine CLANG_ENABLE_STATIC_ANALYZER
+
#endif
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 861dfbf1916e..753c178eec6a 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -2119,6 +2119,7 @@ def nofixprebinding : Flag<["-"], "nofixprebinding">;
def nolibc : Flag<["-"], "nolibc">;
def nomultidefs : Flag<["-"], "nomultidefs">;
def nopie : Flag<["-"], "nopie">;
+def no_pie : Flag<["-"], "no-pie">, Alias<nopie>;
def noprebind : Flag<["-"], "noprebind">;
def noseglinkedit : Flag<["-"], "noseglinkedit">;
def nostartfiles : Flag<["-"], "nostartfiles">;
diff --git a/include/clang/Frontend/LangStandard.h b/include/clang/Frontend/LangStandard.h
index ec32aa8d161f..6731e08bcae8 100644
--- a/include/clang/Frontend/LangStandard.h
+++ b/include/clang/Frontend/LangStandard.h
@@ -26,11 +26,12 @@ enum LangFeatures {
CPlusPlus11 = (1 << 4),
CPlusPlus14 = (1 << 5),
CPlusPlus1z = (1 << 6),
- Digraphs = (1 << 7),
- GNUMode = (1 << 8),
- HexFloat = (1 << 9),
- ImplicitInt = (1 << 10),
- OpenCL = (1 << 11)
+ CPlusPlus2a = (1 << 7),
+ Digraphs = (1 << 8),
+ GNUMode = (1 << 9),
+ HexFloat = (1 << 10),
+ ImplicitInt = (1 << 11),
+ OpenCL = (1 << 12)
};
}
@@ -81,6 +82,10 @@ public:
/// isCPlusPlus1z - Language is a C++17 variant (or later).
bool isCPlusPlus1z() const { return Flags & frontend::CPlusPlus1z; }
+ /// isCPlusPlus2a - Language is a post-C++17 variant (or later).
+ bool isCPlusPlus2a() const { return Flags & frontend::CPlusPlus2a; }
+
+
/// hasDigraphs - Language supports digraphs.
bool hasDigraphs() const { return Flags & frontend::Digraphs; }
diff --git a/include/clang/Frontend/LangStandards.def b/include/clang/Frontend/LangStandards.def
index 1d214fd2a2be..669e487023a5 100644
--- a/include/clang/Frontend/LangStandards.def
+++ b/include/clang/Frontend/LangStandards.def
@@ -119,6 +119,16 @@ LANGSTANDARD(gnucxx1z, "gnu++1z",
LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
Digraphs | HexFloat | GNUMode)
+LANGSTANDARD(cxx2a, "c++2a",
+ CXX, "Working draft for ISO C++ 2020",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
+ CPlusPlus2a | Digraphs | HexFloat)
+
+LANGSTANDARD(gnucxx2a, "gnu++2a",
+ CXX, "Working draft for ISO C++ 2020 with GNU extensions",
+ LineComment | CPlusPlus | CPlusPlus11 | CPlusPlus14 | CPlusPlus1z |
+ CPlusPlus2a | Digraphs | HexFloat | GNUMode)
+
// OpenCL
LANGSTANDARD(opencl10, "cl1.0",
OpenCL, "OpenCL 1.0",
diff --git a/include/clang/Index/IndexingAction.h b/include/clang/Index/IndexingAction.h
index 8eed33c61227..fb703be4e5f5 100644
--- a/include/clang/Index/IndexingAction.h
+++ b/include/clang/Index/IndexingAction.h
@@ -11,11 +11,14 @@
#define LLVM_CLANG_INDEX_INDEXINGACTION_H
#include "clang/Basic/LLVM.h"
+#include "llvm/ADT/ArrayRef.h"
#include <memory>
namespace clang {
+ class ASTContext;
class ASTReader;
class ASTUnit;
+ class Decl;
class FrontendAction;
namespace serialization {
@@ -47,8 +50,11 @@ void indexASTUnit(ASTUnit &Unit,
std::shared_ptr<IndexDataConsumer> DataConsumer,
IndexingOptions Opts);
-void indexModuleFile(serialization::ModuleFile &Mod,
- ASTReader &Reader,
+void indexTopLevelDecls(ASTContext &Ctx, ArrayRef<const Decl *> Decls,
+ std::shared_ptr<IndexDataConsumer> DataConsumer,
+ IndexingOptions Opts);
+
+void indexModuleFile(serialization::ModuleFile &Mod, ASTReader &Reader,
std::shared_ptr<IndexDataConsumer> DataConsumer,
IndexingOptions Opts);
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 7da1e7b41ab8..d25431b55fdc 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -42,14 +42,14 @@ class MacroInfo {
/// \brief The list of arguments for a function-like macro.
///
- /// ArgumentList points to the first of NumArguments pointers.
+ /// ParameterList points to the first of NumParameters pointers.
///
/// This can be empty, for, e.g. "#define X()". In a C99-style variadic
/// macro, this includes the \c __VA_ARGS__ identifier on the list.
- IdentifierInfo **ArgumentList;
+ IdentifierInfo **ParameterList;
- /// \see ArgumentList
- unsigned NumArguments;
+ /// \see ParameterList
+ unsigned NumParameters;
/// \brief This is the list of tokens that the macro is defined to.
SmallVector<Token, 8> ReplacementTokens;
@@ -153,37 +153,37 @@ public:
/// \brief Set the value of the IsWarnIfUnused flag.
void setIsWarnIfUnused(bool val) { IsWarnIfUnused = val; }
- /// \brief Set the specified list of identifiers as the argument list for
+ /// \brief Set the specified list of identifiers as the parameter list for
/// this macro.
- void setArgumentList(ArrayRef<IdentifierInfo *> List,
+ void setParameterList(ArrayRef<IdentifierInfo *> List,
llvm::BumpPtrAllocator &PPAllocator) {
- assert(ArgumentList == nullptr && NumArguments == 0 &&
- "Argument list already set!");
+ assert(ParameterList == nullptr && NumParameters == 0 &&
+ "Parameter list already set!");
if (List.empty())
return;
- NumArguments = List.size();
- ArgumentList = PPAllocator.Allocate<IdentifierInfo *>(List.size());
- std::copy(List.begin(), List.end(), ArgumentList);
+ NumParameters = List.size();
+ ParameterList = PPAllocator.Allocate<IdentifierInfo *>(List.size());
+ std::copy(List.begin(), List.end(), ParameterList);
}
- /// Arguments - The list of arguments for a function-like macro. This can be
- /// empty, for, e.g. "#define X()".
- typedef IdentifierInfo *const *arg_iterator;
- bool arg_empty() const { return NumArguments == 0; }
- arg_iterator arg_begin() const { return ArgumentList; }
- arg_iterator arg_end() const { return ArgumentList + NumArguments; }
- unsigned getNumArgs() const { return NumArguments; }
- ArrayRef<const IdentifierInfo *> args() const {
- return ArrayRef<const IdentifierInfo *>(ArgumentList, NumArguments);
+ /// Parameters - The list of parameters for a function-like macro. This can
+ /// be empty, for, e.g. "#define X()".
+ typedef IdentifierInfo *const *param_iterator;
+ bool param_empty() const { return NumParameters == 0; }
+ param_iterator param_begin() const { return ParameterList; }
+ param_iterator param_end() const { return ParameterList + NumParameters; }
+ unsigned getNumParams() const { return NumParameters; }
+ ArrayRef<const IdentifierInfo *> params() const {
+ return ArrayRef<const IdentifierInfo *>(ParameterList, NumParameters);
}
- /// \brief Return the argument number of the specified identifier,
- /// or -1 if the identifier is not a formal argument identifier.
- int getArgumentNum(const IdentifierInfo *Arg) const {
- for (arg_iterator I = arg_begin(), E = arg_end(); I != E; ++I)
+ /// \brief Return the parameter number of the specified identifier,
+ /// or -1 if the identifier is not a formal parameter identifier.
+ int getParameterNum(const IdentifierInfo *Arg) const {
+ for (param_iterator I = param_begin(), E = param_end(); I != E; ++I)
if (*I == Arg)
- return I - arg_begin();
+ return I - param_begin();
return -1;
}
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 62090d6496ed..a058fbfbb4cf 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -1813,11 +1813,24 @@ private:
void ReadMacroName(Token &MacroNameTok, MacroUse IsDefineUndef = MU_Other,
bool *ShadowFlag = nullptr);
+ /// ReadOptionalMacroParameterListAndBody - This consumes all (i.e. the
+ /// entire line) of the macro's tokens and adds them to MacroInfo, and while
+ /// doing so performs certain validity checks including (but not limited to):
+ /// - # (stringization) is followed by a macro parameter
+ /// \param MacroNameTok - Token that represents the macro name
+ /// \param ImmediatelyAfterHeaderGuard - Macro follows an #ifdef header guard
+ ///
+ /// Either returns a pointer to a MacroInfo object OR emits a diagnostic and
+ /// returns a nullptr if an invalid sequence of tokens is encountered.
+
+ MacroInfo *ReadOptionalMacroParameterListAndBody(
+ const Token &MacroNameTok, bool ImmediatelyAfterHeaderGuard);
+
/// The ( starting an argument list of a macro definition has just been read.
- /// Lex the rest of the arguments and the closing ), updating \p MI with
+ /// Lex the rest of the parameters and the closing ), updating \p MI with
/// what we learn and saving in \p LastTok the last token read.
/// Return true if an error occurs parsing the arg list.
- bool ReadMacroDefinitionArgList(MacroInfo *MI, Token& LastTok);
+ bool ReadMacroParameterList(MacroInfo *MI, Token& LastTok);
/// We just read a \#if or related directive and decided that the
/// subsequent tokens are in the \#if'd out portion of the
@@ -1878,7 +1891,7 @@ private:
/// After reading "MACRO(", this method is invoked to read all of the formal
/// arguments specified for the macro invocation. Returns null on error.
- MacroArgs *ReadFunctionLikeMacroArgs(Token &MacroName, MacroInfo *MI,
+ MacroArgs *ReadMacroCallArgumentList(Token &MacroName, MacroInfo *MI,
SourceLocation &ExpansionEnd);
/// \brief If an identifier token is read that is to be expanded
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index 95629a2591cf..5a708545705c 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -3881,13 +3881,10 @@ public:
void redelayDiagnostics(sema::DelayedDiagnosticPool &pool);
- void EmitAvailabilityWarning(AvailabilityResult AR,
- const NamedDecl *ReferringDecl,
- const NamedDecl *OffendingDecl,
- StringRef Message, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
- bool ObjCPropertyAccess);
+ void DiagnoseAvailabilityOfDecl(NamedDecl *D, SourceLocation Loc,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ bool ObjCPropertyAccess,
+ bool AvoidPartialAvailabilityChecks = false);
bool makeUnavailableInSystemHeader(SourceLocation loc,
UnavailableAttr::ImplicitReason reason);
@@ -8380,6 +8377,8 @@ public:
unsigned SpellingListIndex, bool isNSConsumed,
bool isTemplateInstantiation);
+ bool checkNSReturnsRetainedReturnType(SourceLocation loc, QualType type);
+
//===--------------------------------------------------------------------===//
// C++ Coroutines TS
//
@@ -8680,7 +8679,8 @@ public:
StmtResult ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed '\#pragma omp taskgroup'.
- StmtResult ActOnOpenMPTaskgroupDirective(Stmt *AStmt, SourceLocation StartLoc,
+ StmtResult ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt, SourceLocation StartLoc,
SourceLocation EndLoc);
/// \brief Called on well-formed '\#pragma omp flush'.
StmtResult ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
@@ -9022,6 +9022,13 @@ public:
CXXScopeSpec &ReductionIdScopeSpec,
const DeclarationNameInfo &ReductionId,
ArrayRef<Expr *> UnresolvedReductions = llvm::None);
+ /// Called on well-formed 'task_reduction' clause.
+ OMPClause *ActOnOpenMPTaskReductionClause(
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
+ CXXScopeSpec &ReductionIdScopeSpec,
+ const DeclarationNameInfo &ReductionId,
+ ArrayRef<Expr *> UnresolvedReductions = llvm::None);
/// \brief Called on well-formed 'linear' clause.
OMPClause *
ActOnOpenMPLinearClause(ArrayRef<Expr *> VarList, Expr *Step,
@@ -10416,15 +10423,6 @@ public:
return OriginalLexicalContext ? OriginalLexicalContext : CurContext;
}
- /// The diagnostic we should emit for \c D, and the declaration that
- /// originated it, or \c AR_Available.
- ///
- /// \param D The declaration to check.
- /// \param Message If non-null, this will be populated with the message from
- /// the availability attribute that is selected.
- std::pair<AvailabilityResult, const NamedDecl *>
- ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message);
-
const DeclContext *getCurObjCLexicalContext() const {
const DeclContext *DC = getCurLexicalContext();
// A category implicitly has the attribute of the interface.
diff --git a/include/clang/Tooling/DiagnosticsYaml.h b/include/clang/Tooling/DiagnosticsYaml.h
index f32b9fa9c94b..4d6ff063641b 100644
--- a/include/clang/Tooling/DiagnosticsYaml.h
+++ b/include/clang/Tooling/DiagnosticsYaml.h
@@ -56,6 +56,9 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> {
MappingNormalization<NormalizedDiagnostic, clang::tooling::Diagnostic> Keys(
Io, D);
Io.mapRequired("DiagnosticName", Keys->DiagnosticName);
+ Io.mapRequired("Message", Keys->Message.Message);
+ Io.mapRequired("FileOffset", Keys->Message.FileOffset);
+ Io.mapRequired("FilePath", Keys->Message.FilePath);
// FIXME: Export properly all the different fields.
@@ -82,17 +85,7 @@ template <> struct MappingTraits<clang::tooling::Diagnostic> {
template <> struct MappingTraits<clang::tooling::TranslationUnitDiagnostics> {
static void mapping(IO &Io, clang::tooling::TranslationUnitDiagnostics &Doc) {
Io.mapRequired("MainSourceFile", Doc.MainSourceFile);
-
- std::vector<clang::tooling::Diagnostic> Diagnostics;
- for (auto &Diagnostic : Doc.Diagnostics) {
- // FIXME: Export all diagnostics, not just the ones with fixes.
- // Update MappingTraits<clang::tooling::Diagnostic>::mapping.
- if (Diagnostic.Fix.size() > 0) {
- Diagnostics.push_back(Diagnostic);
- }
- }
- Io.mapRequired("Diagnostics", Diagnostics);
- Doc.Diagnostics = Diagnostics;
+ Io.mapRequired("Diagnostics", Doc.Diagnostics);
}
};
} // end namespace yaml
diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
new file mode 100644
index 000000000000..8b01a61256f6
--- /dev/null
+++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h
@@ -0,0 +1,122 @@
+//===--- RecursiveSymbolVisitor.h - Clang refactoring library -------------===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+///
+/// \file
+/// \brief A wrapper class around \c RecursiveASTVisitor that visits each
+/// occurrences of a named symbol.
+///
+//===----------------------------------------------------------------------===//
+
+#ifndef LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
+#define LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
+
+#include "clang/AST/AST.h"
+#include "clang/AST/RecursiveASTVisitor.h"
+#include "clang/Lex/Lexer.h"
+
+namespace clang {
+namespace tooling {
+
+/// Traverses the AST and visits the occurrence of each named symbol in the
+/// given nodes.
+template <typename T>
+class RecursiveSymbolVisitor
+ : public RecursiveASTVisitor<RecursiveSymbolVisitor<T>> {
+ using BaseType = RecursiveASTVisitor<RecursiveSymbolVisitor<T>>;
+
+public:
+ RecursiveSymbolVisitor(const SourceManager &SM, const LangOptions &LangOpts)
+ : SM(SM), LangOpts(LangOpts) {}
+
+ bool visitSymbolOccurrence(const NamedDecl *ND,
+ ArrayRef<SourceRange> NameRanges) {
+ return true;
+ }
+
+ // Declaration visitors:
+
+ bool VisitNamedDecl(const NamedDecl *D) {
+ return isa<CXXConversionDecl>(D) ? true : visit(D, D->getLocation());
+ }
+
+ bool VisitCXXConstructorDecl(const CXXConstructorDecl *CD) {
+ for (const auto *Initializer : CD->inits()) {
+ // Ignore implicit initializers.
+ if (!Initializer->isWritten())
+ continue;
+ if (const FieldDecl *FD = Initializer->getMember()) {
+ if (!visit(FD, Initializer->getSourceLocation(),
+ Lexer::getLocForEndOfToken(Initializer->getSourceLocation(),
+ 0, SM, LangOpts)))
+ return false;
+ }
+ }
+ return true;
+ }
+
+ // Expression visitors:
+
+ bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
+ return visit(Expr->getFoundDecl(), Expr->getLocation());
+ }
+
+ bool VisitMemberExpr(const MemberExpr *Expr) {
+ return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc());
+ }
+
+ // Other visitors:
+
+ bool VisitTypeLoc(const TypeLoc Loc) {
+ const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
+ const SourceLocation TypeEndLoc =
+ Lexer::getLocForEndOfToken(TypeBeginLoc, 0, SM, LangOpts);
+ if (const auto *TemplateTypeParm =
+ dyn_cast<TemplateTypeParmType>(Loc.getType())) {
+ if (!visit(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc))
+ return false;
+ }
+ if (const auto *TemplateSpecType =
+ dyn_cast<TemplateSpecializationType>(Loc.getType())) {
+ if (!visit(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
+ TypeBeginLoc, TypeEndLoc))
+ return false;
+ }
+ return visit(Loc.getType()->getAsCXXRecordDecl(), TypeBeginLoc, TypeEndLoc);
+ }
+
+ bool TraverseNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS) {
+ // The base visitor will visit NNSL prefixes, so we should only look at
+ // the current NNS.
+ if (NNS) {
+ const NamespaceDecl *ND = NNS.getNestedNameSpecifier()->getAsNamespace();
+ if (!visit(ND, NNS.getLocalBeginLoc(), NNS.getLocalEndLoc()))
+ return false;
+ }
+ return BaseType::TraverseNestedNameSpecifierLoc(NNS);
+ }
+
+private:
+ const SourceManager &SM;
+ const LangOptions &LangOpts;
+
+ bool visit(const NamedDecl *ND, SourceLocation BeginLoc,
+ SourceLocation EndLoc) {
+ return static_cast<T *>(this)->visitSymbolOccurrence(
+ ND, SourceRange(BeginLoc, EndLoc));
+ }
+ bool visit(const NamedDecl *ND, SourceLocation Loc) {
+ return visit(ND, Loc,
+ Loc.getLocWithOffset(ND->getNameAsString().length() - 1));
+ }
+};
+
+} // end namespace tooling
+} // end namespace clang
+
+#endif // LLVM_CLANG_TOOLING_REFACTOR_RECURSIVE_SYMBOL_VISITOR_H
diff --git a/include/clang/Tooling/Refactoring/Rename/USRFinder.h b/include/clang/Tooling/Refactoring/Rename/USRFinder.h
index 28d541af43c0..b74a5d7f70af 100644
--- a/include/clang/Tooling/Refactoring/Rename/USRFinder.h
+++ b/include/clang/Tooling/Refactoring/Rename/USRFinder.h
@@ -18,13 +18,9 @@
#include "clang/AST/AST.h"
#include "clang/AST/ASTContext.h"
-#include "clang/ASTMatchers/ASTMatchFinder.h"
#include <string>
#include <vector>
-using namespace llvm;
-using namespace clang::ast_matchers;
-
namespace clang {
class ASTContext;
@@ -48,36 +44,6 @@ const NamedDecl *getNamedDeclFor(const ASTContext &Context,
// Converts a Decl into a USR.
std::string getUSRForDecl(const Decl *Decl);
-// FIXME: Implement RecursiveASTVisitor<T>::VisitNestedNameSpecifier instead.
-class NestedNameSpecifierLocFinder : public MatchFinder::MatchCallback {
-public:
- explicit NestedNameSpecifierLocFinder(ASTContext &Context)
- : Context(Context) {}
-
- std::vector<NestedNameSpecifierLoc> getNestedNameSpecifierLocations() {
- addMatchers();
- Finder.matchAST(Context);
- return Locations;
- }
-
-private:
- void addMatchers() {
- const auto NestedNameSpecifierLocMatcher =
- nestedNameSpecifierLoc().bind("nestedNameSpecifierLoc");
- Finder.addMatcher(NestedNameSpecifierLocMatcher, this);
- }
-
- void run(const MatchFinder::MatchResult &Result) override {
- const auto *NNS = Result.Nodes.getNodeAs<NestedNameSpecifierLoc>(
- "nestedNameSpecifierLoc");
- Locations.push_back(*NNS);
- }
-
- ASTContext &Context;
- std::vector<NestedNameSpecifierLoc> Locations;
- MatchFinder Finder;
-};
-
} // end namespace tooling
} // end namespace clang
diff --git a/include/clang/module.modulemap b/include/clang/module.modulemap
index f7e338d93399..d850bd552e1f 100644
--- a/include/clang/module.modulemap
+++ b/include/clang/module.modulemap
@@ -138,5 +138,4 @@ module Clang_Tooling {
// importing the AST matchers library gives a link dependency on the AST
// matchers (and thus the AST), which clang-format should not have.
exclude header "Tooling/RefactoringCallbacks.h"
- exclude header "Tooling/Refactoring/Rename/USRFinder.h"
}
diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp
index fd9723298fca..c60373c5a90a 100644
--- a/lib/AST/ASTContext.cpp
+++ b/lib/AST/ASTContext.cpp
@@ -4525,6 +4525,12 @@ CanQualType ASTContext::getSizeType() const {
return getFromTargetType(Target->getSizeType());
}
+/// Return the unique signed counterpart of the integer type
+/// corresponding to size_t.
+CanQualType ASTContext::getSignedSizeType() const {
+ return getFromTargetType(Target->getSignedSizeType());
+}
+
/// getIntMaxType - Return the unique type for "intmax_t" (C99 7.18.1.5).
CanQualType ASTContext::getIntMaxType() const {
return getFromTargetType(Target->getIntMaxType());
diff --git a/lib/AST/ASTDumper.cpp b/lib/AST/ASTDumper.cpp
index 4758109fbcf7..92ed7da94d8e 100644
--- a/lib/AST/ASTDumper.cpp
+++ b/lib/AST/ASTDumper.cpp
@@ -1189,12 +1189,8 @@ void ASTDumper::VisitFunctionDecl(const FunctionDecl *D) {
auto dumpOverride =
[=](const CXXMethodDecl *D) {
SplitQualType T_split = D->getType().split();
- OS << D << " " << D->getParent()->getName() << "::";
- if (isa<CXXDestructorDecl>(D))
- OS << "~" << D->getParent()->getName();
- else
- OS << D->getName();
- OS << " '" << QualType::getAsString(T_split) << "'";
+ OS << D << " " << D->getParent()->getName() << "::"
+ << D->getNameAsString() << " '" << QualType::getAsString(T_split) << "'";
};
dumpChild([=] {
diff --git a/lib/AST/DeclObjC.cpp b/lib/AST/DeclObjC.cpp
index a0ec0c2b251e..d8bdb6369e94 100644
--- a/lib/AST/DeclObjC.cpp
+++ b/lib/AST/DeclObjC.cpp
@@ -1889,25 +1889,23 @@ void ObjCProtocolDecl::collectPropertiesToImplement(PropertyMap &PM,
}
}
-
void ObjCProtocolDecl::collectInheritedProtocolProperties(
- const ObjCPropertyDecl *Property,
- ProtocolPropertyMap &PM) const {
+ const ObjCPropertyDecl *Property, ProtocolPropertySet &PS,
+ PropertyDeclOrder &PO) const {
if (const ObjCProtocolDecl *PDecl = getDefinition()) {
- bool MatchFound = false;
+ if (!PS.insert(PDecl).second)
+ return;
for (auto *Prop : PDecl->properties()) {
if (Prop == Property)
continue;
if (Prop->getIdentifier() == Property->getIdentifier()) {
- PM[PDecl] = Prop;
- MatchFound = true;
- break;
+ PO.push_back(Prop);
+ return;
}
}
// Scan through protocol's protocols which did not have a matching property.
- if (!MatchFound)
- for (const auto *PI : PDecl->protocols())
- PI->collectInheritedProtocolProperties(Property, PM);
+ for (const auto *PI : PDecl->protocols())
+ PI->collectInheritedProtocolProperties(Property, PS, PO);
}
}
diff --git a/lib/AST/ItaniumMangle.cpp b/lib/AST/ItaniumMangle.cpp
index dc25e5213bae..4e7c6c4edf37 100644
--- a/lib/AST/ItaniumMangle.cpp
+++ b/lib/AST/ItaniumMangle.cpp
@@ -2529,7 +2529,7 @@ StringRef CXXNameMangler::getCallingConvQualifierName(CallingConv CC) {
case CC_X86ThisCall:
case CC_X86VectorCall:
case CC_X86Pascal:
- case CC_X86_64Win64:
+ case CC_Win64:
case CC_X86_64SysV:
case CC_X86RegCall:
case CC_AAPCS:
diff --git a/lib/AST/MicrosoftMangle.cpp b/lib/AST/MicrosoftMangle.cpp
index 3a899bdbb6d2..24b16f892e7a 100644
--- a/lib/AST/MicrosoftMangle.cpp
+++ b/lib/AST/MicrosoftMangle.cpp
@@ -2122,7 +2122,7 @@ void MicrosoftCXXNameMangler::mangleCallingConvention(CallingConv CC) {
switch (CC) {
default:
llvm_unreachable("Unsupported CC for mangling");
- case CC_X86_64Win64:
+ case CC_Win64:
case CC_X86_64SysV:
case CC_C: Out << 'A'; break;
case CC_X86Pascal: Out << 'C'; break;
diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp
index 66b9940b8b08..b19135384cfd 100644
--- a/lib/AST/ODRHash.cpp
+++ b/lib/AST/ODRHash.cpp
@@ -246,7 +246,9 @@ public:
}
void VisitValueDecl(const ValueDecl *D) {
- AddQualType(D->getType());
+ if (!isa<FunctionDecl>(D)) {
+ AddQualType(D->getType());
+ }
Inherited::VisitValueDecl(D);
}
@@ -305,6 +307,8 @@ public:
Hash.AddSubDecl(Param);
}
+ AddQualType(D->getReturnType());
+
Inherited::VisitFunctionDecl(D);
}
@@ -350,6 +354,8 @@ bool ODRHash::isWhitelistedDecl(const Decl *D, const CXXRecordDecl *Parent) {
default:
return false;
case Decl::AccessSpec:
+ case Decl::CXXConstructor:
+ case Decl::CXXDestructor:
case Decl::CXXMethod:
case Decl::Field:
case Decl::Friend:
diff --git a/lib/AST/OpenMPClause.cpp b/lib/AST/OpenMPClause.cpp
index 77470a9b76d0..2c4d159a1bc8 100644
--- a/lib/AST/OpenMPClause.cpp
+++ b/lib/AST/OpenMPClause.cpp
@@ -46,6 +46,8 @@ const OMPClauseWithPreInit *OMPClauseWithPreInit::get(const OMPClause *C) {
return static_cast<const OMPLastprivateClause *>(C);
case OMPC_reduction:
return static_cast<const OMPReductionClause *>(C);
+ case OMPC_task_reduction:
+ return static_cast<const OMPTaskReductionClause *>(C);
case OMPC_linear:
return static_cast<const OMPLinearClause *>(C);
case OMPC_if:
@@ -112,6 +114,8 @@ const OMPClauseWithPostUpdate *OMPClauseWithPostUpdate::get(const OMPClause *C)
return static_cast<const OMPLastprivateClause *>(C);
case OMPC_reduction:
return static_cast<const OMPReductionClause *>(C);
+ case OMPC_task_reduction:
+ return static_cast<const OMPTaskReductionClause *>(C);
case OMPC_linear:
return static_cast<const OMPLinearClause *>(C);
case OMPC_schedule:
@@ -505,6 +509,59 @@ OMPReductionClause *OMPReductionClause::CreateEmpty(const ASTContext &C,
return new (Mem) OMPReductionClause(N);
}
+void OMPTaskReductionClause::setPrivates(ArrayRef<Expr *> Privates) {
+ assert(Privates.size() == varlist_size() &&
+ "Number of private copies is not the same as the preallocated buffer");
+ std::copy(Privates.begin(), Privates.end(), varlist_end());
+}
+
+void OMPTaskReductionClause::setLHSExprs(ArrayRef<Expr *> LHSExprs) {
+ assert(
+ LHSExprs.size() == varlist_size() &&
+ "Number of LHS expressions is not the same as the preallocated buffer");
+ std::copy(LHSExprs.begin(), LHSExprs.end(), getPrivates().end());
+}
+
+void OMPTaskReductionClause::setRHSExprs(ArrayRef<Expr *> RHSExprs) {
+ assert(
+ RHSExprs.size() == varlist_size() &&
+ "Number of RHS expressions is not the same as the preallocated buffer");
+ std::copy(RHSExprs.begin(), RHSExprs.end(), getLHSExprs().end());
+}
+
+void OMPTaskReductionClause::setReductionOps(ArrayRef<Expr *> ReductionOps) {
+ assert(ReductionOps.size() == varlist_size() && "Number of task reduction "
+ "expressions is not the same "
+ "as the preallocated buffer");
+ std::copy(ReductionOps.begin(), ReductionOps.end(), getRHSExprs().end());
+}
+
+OMPTaskReductionClause *OMPTaskReductionClause::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation EndLoc, SourceLocation ColonLoc, ArrayRef<Expr *> VL,
+ NestedNameSpecifierLoc QualifierLoc, const DeclarationNameInfo &NameInfo,
+ ArrayRef<Expr *> Privates, ArrayRef<Expr *> LHSExprs,
+ ArrayRef<Expr *> RHSExprs, ArrayRef<Expr *> ReductionOps, Stmt *PreInit,
+ Expr *PostUpdate) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * VL.size()));
+ OMPTaskReductionClause *Clause = new (Mem) OMPTaskReductionClause(
+ StartLoc, LParenLoc, EndLoc, ColonLoc, VL.size(), QualifierLoc, NameInfo);
+ Clause->setVarRefs(VL);
+ Clause->setPrivates(Privates);
+ Clause->setLHSExprs(LHSExprs);
+ Clause->setRHSExprs(RHSExprs);
+ Clause->setReductionOps(ReductionOps);
+ Clause->setPreInitStmt(PreInit);
+ Clause->setPostUpdateExpr(PostUpdate);
+ return Clause;
+}
+
+OMPTaskReductionClause *OMPTaskReductionClause::CreateEmpty(const ASTContext &C,
+ unsigned N) {
+ void *Mem = C.Allocate(totalSizeToAlloc<Expr *>(5 * N));
+ return new (Mem) OMPTaskReductionClause(N);
+}
+
OMPFlushClause *OMPFlushClause::Create(const ASTContext &C,
SourceLocation StartLoc,
SourceLocation LParenLoc,
diff --git a/lib/AST/StmtOpenMP.cpp b/lib/AST/StmtOpenMP.cpp
index cccb2f075b65..1dcb4fd5196b 100644
--- a/lib/AST/StmtOpenMP.cpp
+++ b/lib/AST/StmtOpenMP.cpp
@@ -522,23 +522,28 @@ OMPTaskwaitDirective *OMPTaskwaitDirective::CreateEmpty(const ASTContext &C,
return new (Mem) OMPTaskwaitDirective();
}
-OMPTaskgroupDirective *OMPTaskgroupDirective::Create(const ASTContext &C,
- SourceLocation StartLoc,
- SourceLocation EndLoc,
- Stmt *AssociatedStmt) {
- unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective), alignof(Stmt *));
+OMPTaskgroupDirective *OMPTaskgroupDirective::Create(
+ const ASTContext &C, SourceLocation StartLoc, SourceLocation EndLoc,
+ ArrayRef<OMPClause *> Clauses, Stmt *AssociatedStmt) {
+ unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) +
+ sizeof(OMPClause *) * Clauses.size(),
+ alignof(Stmt *));
void *Mem = C.Allocate(Size + sizeof(Stmt *));
OMPTaskgroupDirective *Dir =
- new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc);
+ new (Mem) OMPTaskgroupDirective(StartLoc, EndLoc, Clauses.size());
Dir->setAssociatedStmt(AssociatedStmt);
+ Dir->setClauses(Clauses);
return Dir;
}
OMPTaskgroupDirective *OMPTaskgroupDirective::CreateEmpty(const ASTContext &C,
+ unsigned NumClauses,
EmptyShell) {
- unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective), alignof(Stmt *));
+ unsigned Size = llvm::alignTo(sizeof(OMPTaskgroupDirective) +
+ sizeof(OMPClause *) * NumClauses,
+ alignof(Stmt *));
void *Mem = C.Allocate(Size + sizeof(Stmt *));
- return new (Mem) OMPTaskgroupDirective();
+ return new (Mem) OMPTaskgroupDirective(NumClauses);
}
OMPCancellationPointDirective *OMPCancellationPointDirective::Create(
diff --git a/lib/AST/StmtPrinter.cpp b/lib/AST/StmtPrinter.cpp
index 21f5259c3ca8..5ebaa32b49c8 100644
--- a/lib/AST/StmtPrinter.cpp
+++ b/lib/AST/StmtPrinter.cpp
@@ -836,6 +836,29 @@ void OMPClausePrinter::VisitOMPReductionClause(OMPReductionClause *Node) {
}
}
+void OMPClausePrinter::VisitOMPTaskReductionClause(
+ OMPTaskReductionClause *Node) {
+ if (!Node->varlist_empty()) {
+ OS << "task_reduction(";
+ NestedNameSpecifier *QualifierLoc =
+ Node->getQualifierLoc().getNestedNameSpecifier();
+ OverloadedOperatorKind OOK =
+ Node->getNameInfo().getName().getCXXOverloadedOperator();
+ if (QualifierLoc == nullptr && OOK != OO_None) {
+ // Print reduction identifier in C format
+ OS << getOperatorSpelling(OOK);
+ } else {
+ // Use C++ format
+ if (QualifierLoc != nullptr)
+ QualifierLoc->print(OS, Policy);
+ OS << Node->getNameInfo();
+ }
+ OS << ":";
+ VisitOMPClauseList(Node, ' ');
+ OS << ")";
+ }
+}
+
void OMPClausePrinter::VisitOMPLinearClause(OMPLinearClause *Node) {
if (!Node->varlist_empty()) {
OS << "linear";
@@ -1081,7 +1104,7 @@ void StmtPrinter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *Node) {
}
void StmtPrinter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *Node) {
- Indent() << "#pragma omp taskgroup";
+ Indent() << "#pragma omp taskgroup ";
PrintOMPExecutableDirective(Node);
}
diff --git a/lib/AST/StmtProfile.cpp b/lib/AST/StmtProfile.cpp
index f1fbe2806b5d..e06386018d68 100644
--- a/lib/AST/StmtProfile.cpp
+++ b/lib/AST/StmtProfile.cpp
@@ -549,6 +549,30 @@ void OMPClauseProfiler::VisitOMPReductionClause(
Profiler->VisitStmt(E);
}
}
+void OMPClauseProfiler::VisitOMPTaskReductionClause(
+ const OMPTaskReductionClause *C) {
+ Profiler->VisitNestedNameSpecifier(
+ C->getQualifierLoc().getNestedNameSpecifier());
+ Profiler->VisitName(C->getNameInfo().getName());
+ VisitOMPClauseList(C);
+ VistOMPClauseWithPostUpdate(C);
+ for (auto *E : C->privates()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+ for (auto *E : C->lhs_exprs()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+ for (auto *E : C->rhs_exprs()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+ for (auto *E : C->reduction_ops()) {
+ if (E)
+ Profiler->VisitStmt(E);
+ }
+}
void OMPClauseProfiler::VisitOMPLinearClause(const OMPLinearClause *C) {
VisitOMPClauseList(C);
VistOMPClauseWithPostUpdate(C);
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index a62ca5f9b4d7..eac02c0102bc 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2630,7 +2630,7 @@ StringRef FunctionType::getNameForCallConv(CallingConv CC) {
case CC_X86ThisCall: return "thiscall";
case CC_X86Pascal: return "pascal";
case CC_X86VectorCall: return "vectorcall";
- case CC_X86_64Win64: return "ms_abi";
+ case CC_Win64: return "ms_abi";
case CC_X86_64SysV: return "sysv_abi";
case CC_X86RegCall : return "regcall";
case CC_AAPCS: return "aapcs";
@@ -3023,6 +3023,7 @@ bool AttributedType::isQualifier() const {
case AttributedType::attr_sptr:
case AttributedType::attr_uptr:
case AttributedType::attr_objc_kindof:
+ case AttributedType::attr_ns_returns_retained:
return false;
}
llvm_unreachable("bad attributed type kind");
@@ -3056,6 +3057,7 @@ bool AttributedType::isCallingConv() const {
case attr_objc_inert_unsafe_unretained:
case attr_noreturn:
case attr_nonnull:
+ case attr_ns_returns_retained:
case attr_nullable:
case attr_null_unspecified:
case attr_objc_kindof:
diff --git a/lib/AST/TypePrinter.cpp b/lib/AST/TypePrinter.cpp
index 0551340c37a1..15c63bf4ed98 100644
--- a/lib/AST/TypePrinter.cpp
+++ b/lib/AST/TypePrinter.cpp
@@ -104,6 +104,7 @@ namespace {
void printAfter(QualType T, raw_ostream &OS);
void AppendScope(DeclContext *DC, raw_ostream &OS);
void printTag(TagDecl *T, raw_ostream &OS);
+ void printFunctionAfter(const FunctionType::ExtInfo &Info, raw_ostream &OS);
#define ABSTRACT_TYPE(CLASS, PARENT)
#define TYPE(CLASS, PARENT) \
void print##CLASS##Before(const CLASS##Type *T, raw_ostream &OS); \
@@ -685,6 +686,36 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
FunctionType::ExtInfo Info = T->getExtInfo();
+ printFunctionAfter(Info, OS);
+
+ if (unsigned quals = T->getTypeQuals()) {
+ OS << ' ';
+ AppendTypeQualList(OS, quals, Policy.Restrict);
+ }
+
+ switch (T->getRefQualifier()) {
+ case RQ_None:
+ break;
+
+ case RQ_LValue:
+ OS << " &";
+ break;
+
+ case RQ_RValue:
+ OS << " &&";
+ break;
+ }
+ T->printExceptionSpecification(OS, Policy);
+
+ if (T->hasTrailingReturn()) {
+ OS << " -> ";
+ print(T->getReturnType(), OS, StringRef());
+ } else
+ printAfter(T->getReturnType(), OS);
+}
+
+void TypePrinter::printFunctionAfter(const FunctionType::ExtInfo &Info,
+ raw_ostream &OS) {
if (!InsideCCAttribute) {
switch (Info.getCC()) {
case CC_C:
@@ -720,7 +751,7 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
case CC_IntelOclBicc:
OS << " __attribute__((intel_ocl_bicc))";
break;
- case CC_X86_64Win64:
+ case CC_Win64:
OS << " __attribute__((ms_abi))";
break;
case CC_X86_64SysV:
@@ -747,36 +778,13 @@ void TypePrinter::printFunctionProtoAfter(const FunctionProtoType *T,
if (Info.getNoReturn())
OS << " __attribute__((noreturn))";
+ if (Info.getProducesResult())
+ OS << " __attribute__((ns_returns_retained))";
if (Info.getRegParm())
OS << " __attribute__((regparm ("
<< Info.getRegParm() << ")))";
if (Info.getNoCallerSavedRegs())
- OS << "__attribute__((no_caller_saved_registers))";
-
- if (unsigned quals = T->getTypeQuals()) {
- OS << ' ';
- AppendTypeQualList(OS, quals, Policy.Restrict);
- }
-
- switch (T->getRefQualifier()) {
- case RQ_None:
- break;
-
- case RQ_LValue:
- OS << " &";
- break;
-
- case RQ_RValue:
- OS << " &&";
- break;
- }
- T->printExceptionSpecification(OS, Policy);
-
- if (T->hasTrailingReturn()) {
- OS << " -> ";
- print(T->getReturnType(), OS, StringRef());
- } else
- printAfter(T->getReturnType(), OS);
+ OS << " __attribute__((no_caller_saved_registers))";
}
void TypePrinter::printFunctionNoProtoBefore(const FunctionNoProtoType *T,
@@ -795,8 +803,7 @@ void TypePrinter::printFunctionNoProtoAfter(const FunctionNoProtoType *T,
SaveAndRestore<bool> NonEmptyPH(HasEmptyPlaceHolder, false);
OS << "()";
- if (T->getNoReturnAttr())
- OS << " __attribute__((noreturn))";
+ printFunctionAfter(T->getExtInfo(), OS);
printAfter(T->getReturnType(), OS);
}
@@ -1270,6 +1277,12 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
if (T->getAttrKind() == AttributedType::attr_objc_inert_unsafe_unretained)
return;
+ // Don't print ns_returns_retained unless it had an effect.
+ if (T->getAttrKind() == AttributedType::attr_ns_returns_retained &&
+ !T->getEquivalentType()->castAs<FunctionType>()
+ ->getExtInfo().getProducesResult())
+ return;
+
// Print nullability type specifiers that occur after
if (T->getAttrKind() == AttributedType::attr_nonnull ||
T->getAttrKind() == AttributedType::attr_nullable ||
@@ -1361,6 +1374,10 @@ void TypePrinter::printAttributedAfter(const AttributedType *T,
OS << ')';
break;
+ case AttributedType::attr_ns_returns_retained:
+ OS << "ns_returns_retained";
+ break;
+
// FIXME: When Sema learns to form this AttributedType, avoid printing the
// attribute again in printFunctionProtoAfter.
case AttributedType::attr_noreturn: OS << "noreturn"; break;
diff --git a/lib/Analysis/PrintfFormatString.cpp b/lib/Analysis/PrintfFormatString.cpp
index 60556697113a..50a3aa20bd19 100644
--- a/lib/Analysis/PrintfFormatString.cpp
+++ b/lib/Analysis/PrintfFormatString.cpp
@@ -466,8 +466,7 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
case LengthModifier::AsIntMax:
return ArgType(Ctx.getIntMaxType(), "intmax_t");
case LengthModifier::AsSizeT:
- // FIXME: How to get the corresponding signed version of size_t?
- return ArgType();
+ return ArgType(Ctx.getSignedSizeType(), "ssize_t");
case LengthModifier::AsInt3264:
return Ctx.getTargetInfo().getTriple().isArch64Bit()
? ArgType(Ctx.LongLongTy, "__int64")
@@ -537,7 +536,7 @@ ArgType PrintfSpecifier::getArgType(ASTContext &Ctx,
case LengthModifier::AsIntMax:
return ArgType::PtrTo(ArgType(Ctx.getIntMaxType(), "intmax_t"));
case LengthModifier::AsSizeT:
- return ArgType(); // FIXME: ssize_t
+ return ArgType::PtrTo(ArgType(Ctx.getSignedSizeType(), "ssize_t"));
case LengthModifier::AsPtrDiff:
return ArgType::PtrTo(ArgType(Ctx.getPointerDiffType(), "ptrdiff_t"));
case LengthModifier::AsLongDouble:
diff --git a/lib/Basic/CMakeLists.txt b/lib/Basic/CMakeLists.txt
index 2feb31851cfe..e971b55e8585 100644
--- a/lib/Basic/CMakeLists.txt
+++ b/lib/Basic/CMakeLists.txt
@@ -15,8 +15,23 @@ function(find_first_existing_file out_var)
endfunction()
macro(find_first_existing_vc_file out_var path)
+ set(git_path "${path}/.git")
+
+ # Normally '.git' is a directory that contains a 'logs/HEAD' file that
+ # is updated as modifications are made to the repository. In case the
+ # repository is a Git submodule, '.git' is a file that contains text that
+ # indicates where the repository's Git directory exists.
+ if (EXISTS "${git_path}" AND NOT IS_DIRECTORY "${git_path}")
+ FILE(READ "${git_path}" file_contents)
+ if("${file_contents}" MATCHES "^gitdir: ([^\n]+)")
+ # '.git' is indeed a link to the submodule's Git directory.
+ # Use the path to that Git directory.
+ set(git_path "${path}/${CMAKE_MATCH_1}")
+ endif()
+ endif()
+
find_first_existing_file(${out_var}
- "${path}/.git/logs/HEAD" # Git
+ "${git_path}/logs/HEAD" # Git or Git submodule
"${path}/.svn/wc.db" # SVN 1.7
"${path}/.svn/entries" # SVN 1.6
)
diff --git a/lib/Basic/DiagnosticIDs.cpp b/lib/Basic/DiagnosticIDs.cpp
index ce493c1e5cab..932b3f1934cc 100644
--- a/lib/Basic/DiagnosticIDs.cpp
+++ b/lib/Basic/DiagnosticIDs.cpp
@@ -510,6 +510,18 @@ StringRef DiagnosticIDs::getWarningOptionForDiag(unsigned DiagID) {
return StringRef();
}
+std::vector<std::string> DiagnosticIDs::getDiagnosticFlags() {
+ std::vector<std::string> Res;
+ for (size_t I = 1; DiagGroupNames[I] != '\0';) {
+ std::string Diag(DiagGroupNames + I + 1, DiagGroupNames[I]);
+ I += DiagGroupNames[I] + 1;
+ Res.push_back("-W" + Diag);
+ Res.push_back("-Wno" + Diag);
+ }
+
+ return Res;
+}
+
/// Return \c true if any diagnostics were found in this group, even if they
/// were filtered out due to having the wrong flavor.
static bool getDiagnosticsInGroup(diag::Flavor Flavor,
diff --git a/lib/Basic/OpenMPKinds.cpp b/lib/Basic/OpenMPKinds.cpp
index 76a0e18c2d73..050c0cc466db 100644
--- a/lib/Basic/OpenMPKinds.cpp
+++ b/lib/Basic/OpenMPKinds.cpp
@@ -138,6 +138,7 @@ unsigned clang::getOpenMPSimpleClauseType(OpenMPClauseKind Kind,
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_aligned:
case OMPC_copyin:
case OMPC_copyprivate:
@@ -277,6 +278,7 @@ const char *clang::getOpenMPSimpleClauseTypeName(OpenMPClauseKind Kind,
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_aligned:
case OMPC_copyin:
case OMPC_copyprivate:
@@ -710,6 +712,16 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
break;
}
break;
+ case OMPD_taskgroup:
+ switch (CKind) {
+#define OPENMP_TASKGROUP_CLAUSE(Name) \
+ case OMPC_##Name: \
+ return true;
+#include "clang/Basic/OpenMPKinds.def"
+ default:
+ break;
+ }
+ break;
case OMPD_declare_target:
case OMPD_end_declare_target:
case OMPD_unknown:
@@ -719,7 +731,6 @@ bool clang::isAllowedClauseForDirective(OpenMPDirectiveKind DKind,
case OMPD_taskyield:
case OMPD_barrier:
case OMPD_taskwait:
- case OMPD_taskgroup:
case OMPD_cancellation_point:
case OMPD_declare_reduction:
break;
@@ -840,7 +851,8 @@ bool clang::isOpenMPDistributeDirective(OpenMPDirectiveKind Kind) {
bool clang::isOpenMPPrivate(OpenMPClauseKind Kind) {
return Kind == OMPC_private || Kind == OMPC_firstprivate ||
Kind == OMPC_lastprivate || Kind == OMPC_linear ||
- Kind == OMPC_reduction; // TODO add next clauses like 'reduction'.
+ Kind == OMPC_reduction ||
+ Kind == OMPC_task_reduction; // TODO add next clauses like 'reduction'.
}
bool clang::isOpenMPThreadPrivate(OpenMPClauseKind Kind) {
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 50b4fc34ad3a..5d75aa5a7528 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -571,8 +571,6 @@ protected:
public:
OpenBSDTargetInfo(const llvm::Triple &Triple, const TargetOptions &Opts)
: OSTargetInfo<Target>(Triple, Opts) {
- this->TLSSupported = false;
-
switch (Triple.getArch()) {
case llvm::Triple::x86:
case llvm::Triple::x86_64:
@@ -3401,6 +3399,7 @@ bool X86TargetInfo::initFeatureMap(
setFeatureEnabledImpl(Features, "bmi", true);
setFeatureEnabledImpl(Features, "f16c", true);
setFeatureEnabledImpl(Features, "xsaveopt", true);
+ setFeatureEnabledImpl(Features, "movbe", true);
LLVM_FALLTHROUGH;
case CK_BTVER1:
setFeatureEnabledImpl(Features, "ssse3", true);
@@ -4900,7 +4899,7 @@ public:
case CC_Swift:
case CC_X86VectorCall:
case CC_IntelOclBicc:
- case CC_X86_64Win64:
+ case CC_Win64:
case CC_PreserveMost:
case CC_PreserveAll:
case CC_X86RegCall:
@@ -6251,7 +6250,8 @@ class AArch64TargetInfo : public TargetInfo {
enum FPUModeEnum {
FPUMode,
- NeonMode
+ NeonMode = (1 << 0),
+ SveMode = (1 << 1)
};
unsigned FPU;
@@ -6290,6 +6290,9 @@ public:
LongDoubleWidth = LongDoubleAlign = SuitableAlign = 128;
LongDoubleFormat = &llvm::APFloat::IEEEquad();
+ // Make __builtin_ms_va_list available.
+ HasBuiltinMSVaList = true;
+
// {} in inline assembly are neon specifiers, not assembly variant
// specifiers.
NoAsmVariants = true;
@@ -6385,12 +6388,15 @@ public:
Builder.defineMacro("__ARM_SIZEOF_MINIMAL_ENUM",
Opts.ShortEnums ? "1" : "4");
- if (FPU == NeonMode) {
+ if (FPU & NeonMode) {
Builder.defineMacro("__ARM_NEON", "1");
// 64-bit NEON supports half, single and double precision operations.
Builder.defineMacro("__ARM_NEON_FP", "0xE");
}
+ if (FPU & SveMode)
+ Builder.defineMacro("__ARM_FEATURE_SVE", "1");
+
if (CRC)
Builder.defineMacro("__ARM_FEATURE_CRC32", "1");
@@ -6426,7 +6432,8 @@ public:
return Feature == "aarch64" ||
Feature == "arm64" ||
Feature == "arm" ||
- (Feature == "neon" && FPU == NeonMode);
+ (Feature == "neon" && (FPU & NeonMode)) ||
+ (Feature == "sve" && (FPU & SveMode));
}
bool handleTargetFeatures(std::vector<std::string> &Features,
@@ -6440,7 +6447,9 @@ public:
for (const auto &Feature : Features) {
if (Feature == "+neon")
- FPU = NeonMode;
+ FPU |= NeonMode;
+ if (Feature == "+sve")
+ FPU |= SveMode;
if (Feature == "+crc")
CRC = 1;
if (Feature == "+crypto")
@@ -6467,6 +6476,7 @@ public:
case CC_PreserveMost:
case CC_PreserveAll:
case CC_OpenCLKernel:
+ case CC_Win64:
return CCCR_OK;
default:
return CCCR_Warning;
@@ -6644,13 +6654,26 @@ public:
MicrosoftARM64TargetInfo(const llvm::Triple &Triple,
const TargetOptions &Opts)
: WindowsTargetInfo<AArch64leTargetInfo>(Triple, Opts), Triple(Triple) {
+
+ // This is an LLP64 platform.
+ // int:4, long:4, long long:8, long double:8.
WCharType = UnsignedShort;
+ IntWidth = IntAlign = 32;
+ LongWidth = LongAlign = 32;
+ DoubleAlign = LongLongAlign = 64;
+ LongDoubleWidth = LongDoubleAlign = 64;
+ LongDoubleFormat = &llvm::APFloat::IEEEdouble();
+ IntMaxType = SignedLongLong;
+ Int64Type = SignedLongLong;
SizeType = UnsignedLongLong;
+ PtrDiffType = SignedLongLong;
+ IntPtrType = SignedLongLong;
+
TheCXXABI.set(TargetCXXABI::Microsoft);
}
void setDataLayout() override {
- resetDataLayout("e-m:w-i64:64-i128:128-n32:64-S128");
+ resetDataLayout("e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128");
}
void getVisualStudioDefines(const LangOptions &Opts,
@@ -7470,7 +7493,7 @@ public:
if (HasVector)
Builder.defineMacro("__VX__");
if (Opts.ZVector)
- Builder.defineMacro("__VEC__", "10301");
+ Builder.defineMacro("__VEC__", "10302");
}
ArrayRef<Builtin::Info> getTargetBuiltins() const override {
return llvm::makeArrayRef(BuiltinInfo,
@@ -7497,6 +7520,7 @@ public:
.Cases("arch9", "z196", 9)
.Cases("arch10", "zEC12", 10)
.Cases("arch11", "z13", 11)
+ .Cases("arch12", "z14", 12)
.Default(-1);
}
bool setCPU(const std::string &Name) override {
@@ -7513,6 +7537,8 @@ public:
Features["transactional-execution"] = true;
if (ISARevision >= 11)
Features["vector"] = true;
+ if (ISARevision >= 12)
+ Features["vector-enhancements-1"] = true;
return TargetInfo::initFeatureMap(Features, Diags, CPU, FeaturesVec);
}
@@ -7542,6 +7568,7 @@ public:
.Case("arch9", ISARevision >= 9)
.Case("arch10", ISARevision >= 10)
.Case("arch11", ISARevision >= 11)
+ .Case("arch12", ISARevision >= 12)
.Case("htm", HasTransactionalExecution)
.Case("vx", HasVector)
.Default(false);
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index bc902507c46e..f3527b0f39d1 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -2795,6 +2795,33 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
}
+
+ case Builtin::BI__builtin_ms_va_start:
+ case Builtin::BI__builtin_ms_va_end:
+ return RValue::get(
+ EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(),
+ BuiltinID == Builtin::BI__builtin_ms_va_start));
+
+ case Builtin::BI__builtin_ms_va_copy: {
+ // Lower this manually. We can't reliably determine whether or not any
+ // given va_copy() is for a Win64 va_list from the calling convention
+ // alone, because it's legal to do this from a System V ABI function.
+ // With opaque pointer types, we won't have enough information in LLVM
+ // IR to determine this from the argument types, either. Best to do it
+ // now, while we have enough information.
+ Address DestAddr = EmitMSVAListRef(E->getArg(0));
+ Address SrcAddr = EmitMSVAListRef(E->getArg(1));
+
+ llvm::Type *BPP = Int8PtrPtrTy;
+
+ DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"),
+ DestAddr.getAlignment());
+ SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"),
+ SrcAddr.getAlignment());
+
+ Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val");
+ return RValue::get(Builder.CreateStore(ArgPtr, DestAddr));
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
@@ -7223,31 +7250,6 @@ static Value *EmitX86SExtMask(CodeGenFunction &CGF, Value *Op,
Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
const CallExpr *E) {
- if (BuiltinID == X86::BI__builtin_ms_va_start ||
- BuiltinID == X86::BI__builtin_ms_va_end)
- return EmitVAStartEnd(EmitMSVAListRef(E->getArg(0)).getPointer(),
- BuiltinID == X86::BI__builtin_ms_va_start);
- if (BuiltinID == X86::BI__builtin_ms_va_copy) {
- // Lower this manually. We can't reliably determine whether or not any
- // given va_copy() is for a Win64 va_list from the calling convention
- // alone, because it's legal to do this from a System V ABI function.
- // With opaque pointer types, we won't have enough information in LLVM
- // IR to determine this from the argument types, either. Best to do it
- // now, while we have enough information.
- Address DestAddr = EmitMSVAListRef(E->getArg(0));
- Address SrcAddr = EmitMSVAListRef(E->getArg(1));
-
- llvm::Type *BPP = Int8PtrPtrTy;
-
- DestAddr = Address(Builder.CreateBitCast(DestAddr.getPointer(), BPP, "cp"),
- DestAddr.getAlignment());
- SrcAddr = Address(Builder.CreateBitCast(SrcAddr.getPointer(), BPP, "ap"),
- SrcAddr.getAlignment());
-
- Value *ArgPtr = Builder.CreateLoad(SrcAddr, "ap.val");
- return Builder.CreateStore(ArgPtr, DestAddr);
- }
-
SmallVector<Value*, 4> Ops;
// Find out if any arguments are required to be integer constant expressions.
@@ -8790,12 +8792,14 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
return Builder.CreateCall(F, {X, Undef});
}
+ case SystemZ::BI__builtin_s390_vfsqsb:
case SystemZ::BI__builtin_s390_vfsqdb: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
Function *F = CGM.getIntrinsic(Intrinsic::sqrt, ResultType);
return Builder.CreateCall(F, X);
}
+ case SystemZ::BI__builtin_s390_vfmasb:
case SystemZ::BI__builtin_s390_vfmadb: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
@@ -8804,6 +8808,7 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
return Builder.CreateCall(F, {X, Y, Z});
}
+ case SystemZ::BI__builtin_s390_vfmssb:
case SystemZ::BI__builtin_s390_vfmsdb: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
@@ -8813,12 +8818,35 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
return Builder.CreateCall(F, {X, Y, Builder.CreateFSub(Zero, Z, "sub")});
}
+ case SystemZ::BI__builtin_s390_vfnmasb:
+ case SystemZ::BI__builtin_s390_vfnmadb: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Y = EmitScalarExpr(E->getArg(1));
+ Value *Z = EmitScalarExpr(E->getArg(2));
+ Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
+ return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, Z}), "sub");
+ }
+ case SystemZ::BI__builtin_s390_vfnmssb:
+ case SystemZ::BI__builtin_s390_vfnmsdb: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Y = EmitScalarExpr(E->getArg(1));
+ Value *Z = EmitScalarExpr(E->getArg(2));
+ Value *Zero = llvm::ConstantFP::getZeroValueForNegation(ResultType);
+ Function *F = CGM.getIntrinsic(Intrinsic::fma, ResultType);
+ Value *NegZ = Builder.CreateFSub(Zero, Z, "sub");
+ return Builder.CreateFSub(Zero, Builder.CreateCall(F, {X, Y, NegZ}));
+ }
+ case SystemZ::BI__builtin_s390_vflpsb:
case SystemZ::BI__builtin_s390_vflpdb: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
return Builder.CreateCall(F, X);
}
+ case SystemZ::BI__builtin_s390_vflnsb:
case SystemZ::BI__builtin_s390_vflndb: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
@@ -8826,6 +8854,7 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(Intrinsic::fabs, ResultType);
return Builder.CreateFSub(Zero, Builder.CreateCall(F, X), "sub");
}
+ case SystemZ::BI__builtin_s390_vfisb:
case SystemZ::BI__builtin_s390_vfidb: {
llvm::Type *ResultType = ConvertType(E->getType());
Value *X = EmitScalarExpr(E->getArg(0));
@@ -8835,8 +8864,8 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
bool IsConstM5 = E->getArg(2)->isIntegerConstantExpr(M5, getContext());
assert(IsConstM4 && IsConstM5 && "Constant arg isn't actually constant?");
(void)IsConstM4; (void)IsConstM5;
- // Check whether this instance of vfidb can be represented via a LLVM
- // standard intrinsic. We only support some combinations of M4 and M5.
+ // Check whether this instance can be represented via a LLVM standard
+ // intrinsic. We only support some combinations of M4 and M5.
Intrinsic::ID ID = Intrinsic::not_intrinsic;
switch (M4.getZExtValue()) {
default: break;
@@ -8861,11 +8890,76 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(ID, ResultType);
return Builder.CreateCall(F, X);
}
- Function *F = CGM.getIntrinsic(Intrinsic::s390_vfidb);
+ switch (BuiltinID) {
+ case SystemZ::BI__builtin_s390_vfisb: ID = Intrinsic::s390_vfisb; break;
+ case SystemZ::BI__builtin_s390_vfidb: ID = Intrinsic::s390_vfidb; break;
+ default: llvm_unreachable("Unknown BuiltinID");
+ }
+ Function *F = CGM.getIntrinsic(ID);
Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
Value *M5Value = llvm::ConstantInt::get(getLLVMContext(), M5);
return Builder.CreateCall(F, {X, M4Value, M5Value});
}
+ case SystemZ::BI__builtin_s390_vfmaxsb:
+ case SystemZ::BI__builtin_s390_vfmaxdb: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Y = EmitScalarExpr(E->getArg(1));
+ // Constant-fold the M4 mask argument.
+ llvm::APSInt M4;
+ bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
+ assert(IsConstM4 && "Constant arg isn't actually constant?");
+ (void)IsConstM4;
+ // Check whether this instance can be represented via a LLVM standard
+ // intrinsic. We only support some values of M4.
+ Intrinsic::ID ID = Intrinsic::not_intrinsic;
+ switch (M4.getZExtValue()) {
+ default: break;
+ case 4: ID = Intrinsic::maxnum; break;
+ }
+ if (ID != Intrinsic::not_intrinsic) {
+ Function *F = CGM.getIntrinsic(ID, ResultType);
+ return Builder.CreateCall(F, {X, Y});
+ }
+ switch (BuiltinID) {
+ case SystemZ::BI__builtin_s390_vfmaxsb: ID = Intrinsic::s390_vfmaxsb; break;
+ case SystemZ::BI__builtin_s390_vfmaxdb: ID = Intrinsic::s390_vfmaxdb; break;
+ default: llvm_unreachable("Unknown BuiltinID");
+ }
+ Function *F = CGM.getIntrinsic(ID);
+ Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
+ return Builder.CreateCall(F, {X, Y, M4Value});
+ }
+ case SystemZ::BI__builtin_s390_vfminsb:
+ case SystemZ::BI__builtin_s390_vfmindb: {
+ llvm::Type *ResultType = ConvertType(E->getType());
+ Value *X = EmitScalarExpr(E->getArg(0));
+ Value *Y = EmitScalarExpr(E->getArg(1));
+ // Constant-fold the M4 mask argument.
+ llvm::APSInt M4;
+ bool IsConstM4 = E->getArg(2)->isIntegerConstantExpr(M4, getContext());
+ assert(IsConstM4 && "Constant arg isn't actually constant?");
+ (void)IsConstM4;
+ // Check whether this instance can be represented via a LLVM standard
+ // intrinsic. We only support some values of M4.
+ Intrinsic::ID ID = Intrinsic::not_intrinsic;
+ switch (M4.getZExtValue()) {
+ default: break;
+ case 4: ID = Intrinsic::minnum; break;
+ }
+ if (ID != Intrinsic::not_intrinsic) {
+ Function *F = CGM.getIntrinsic(ID, ResultType);
+ return Builder.CreateCall(F, {X, Y});
+ }
+ switch (BuiltinID) {
+ case SystemZ::BI__builtin_s390_vfminsb: ID = Intrinsic::s390_vfminsb; break;
+ case SystemZ::BI__builtin_s390_vfmindb: ID = Intrinsic::s390_vfmindb; break;
+ default: llvm_unreachable("Unknown BuiltinID");
+ }
+ Function *F = CGM.getIntrinsic(ID);
+ Value *M4Value = llvm::ConstantInt::get(getLLVMContext(), M4);
+ return Builder.CreateCall(F, {X, Y, M4Value});
+ }
// Vector intrisincs that output the post-instruction CC value.
@@ -8932,10 +9026,14 @@ Value *CodeGenFunction::EmitSystemZBuiltinExpr(unsigned BuiltinID,
INTRINSIC_WITH_CC(s390_vstrczhs);
INTRINSIC_WITH_CC(s390_vstrczfs);
+ INTRINSIC_WITH_CC(s390_vfcesbs);
INTRINSIC_WITH_CC(s390_vfcedbs);
+ INTRINSIC_WITH_CC(s390_vfchsbs);
INTRINSIC_WITH_CC(s390_vfchdbs);
+ INTRINSIC_WITH_CC(s390_vfchesbs);
INTRINSIC_WITH_CC(s390_vfchedbs);
+ INTRINSIC_WITH_CC(s390_vftcisb);
INTRINSIC_WITH_CC(s390_vftcidb);
#undef INTRINSIC_WITH_CC
diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp
index cee656a62fe7..316bf44cb1c3 100644
--- a/lib/CodeGen/CGCall.cpp
+++ b/lib/CodeGen/CGCall.cpp
@@ -50,7 +50,7 @@ unsigned CodeGenTypes::ClangCallConvToLLVMCallConv(CallingConv CC) {
case CC_X86FastCall: return llvm::CallingConv::X86_FastCall;
case CC_X86RegCall: return llvm::CallingConv::X86_RegCall;
case CC_X86ThisCall: return llvm::CallingConv::X86_ThisCall;
- case CC_X86_64Win64: return llvm::CallingConv::X86_64_Win64;
+ case CC_Win64: return llvm::CallingConv::Win64;
case CC_X86_64SysV: return llvm::CallingConv::X86_64_SysV;
case CC_AAPCS: return llvm::CallingConv::ARM_AAPCS;
case CC_AAPCS_VFP: return llvm::CallingConv::ARM_AAPCS_VFP;
@@ -218,7 +218,7 @@ static CallingConv getCallingConventionForDecl(const Decl *D, bool IsWindows) {
return CC_IntelOclBicc;
if (D->hasAttr<MSABIAttr>())
- return IsWindows ? CC_C : CC_X86_64Win64;
+ return IsWindows ? CC_C : CC_Win64;
if (D->hasAttr<SysVABIAttr>())
return IsWindows ? CC_X86_64SysV : CC_C;
@@ -1877,8 +1877,8 @@ void CodeGenModule::ConstructAttributeList(
// the function.
const auto *TD = FD->getAttr<TargetAttr>();
TargetAttr::ParsedTargetAttr ParsedAttr = TD->parse();
- if (ParsedAttr.second != "")
- TargetCPU = ParsedAttr.second;
+ if (ParsedAttr.Architecture != "")
+ TargetCPU = ParsedAttr.Architecture;
if (TargetCPU != "")
FuncAttrs.addAttribute("target-cpu", TargetCPU);
if (!Features.empty()) {
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index b00d296fe34a..c9c450c32e3b 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -956,7 +956,7 @@ static unsigned getDwarfCC(CallingConv CC) {
return llvm::dwarf::DW_CC_BORLAND_pascal;
// FIXME: Create new DW_CC_ codes for these calling conventions.
- case CC_X86_64Win64:
+ case CC_Win64:
case CC_X86_64SysV:
case CC_AAPCS:
case CC_AAPCS_VFP:
@@ -3970,10 +3970,10 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) {
const NamespaceDecl *NSDecl = UD.getNominatedNamespace();
if (!NSDecl->isAnonymousNamespace() ||
CGM.getCodeGenOpts().DebugExplicitImport) {
+ auto Loc = UD.getLocation();
DBuilder.createImportedModule(
getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())),
- getOrCreateNamespace(NSDecl),
- getLineNumber(UD.getLocation()));
+ getOrCreateNamespace(NSDecl), getOrCreateFile(Loc), getLineNumber(Loc));
}
}
@@ -3996,10 +3996,12 @@ void CGDebugInfo::EmitUsingDecl(const UsingDecl &UD) {
if (AT->getDeducedType().isNull())
return;
if (llvm::DINode *Target =
- getDeclarationOrDefinition(USD.getUnderlyingDecl()))
+ getDeclarationOrDefinition(USD.getUnderlyingDecl())) {
+ auto Loc = USD.getLocation();
DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(USD.getDeclContext())), Target,
- getLineNumber(USD.getLocation()));
+ getOrCreateFile(Loc), getLineNumber(Loc));
+ }
}
void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) {
@@ -4007,10 +4009,11 @@ void CGDebugInfo::EmitImportDecl(const ImportDecl &ID) {
return;
if (Module *M = ID.getImportedModule()) {
auto Info = ExternalASTSource::ASTSourceDescriptor(*M);
+ auto Loc = ID.getLocation();
DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(ID.getDeclContext())),
- getOrCreateModuleRef(Info, DebugTypeExtRefs),
- getLineNumber(ID.getLocation()));
+ getOrCreateModuleRef(Info, DebugTypeExtRefs), getOrCreateFile(Loc),
+ getLineNumber(Loc));
}
}
@@ -4022,18 +4025,19 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
if (VH)
return cast<llvm::DIImportedEntity>(VH);
llvm::DIImportedEntity *R;
+ auto Loc = NA.getLocation();
if (const auto *Underlying =
dyn_cast<NamespaceAliasDecl>(NA.getAliasedNamespace()))
// This could cache & dedup here rather than relying on metadata deduping.
R = DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
- EmitNamespaceAlias(*Underlying), getLineNumber(NA.getLocation()),
- NA.getName());
+ EmitNamespaceAlias(*Underlying), getOrCreateFile(Loc),
+ getLineNumber(Loc), NA.getName());
else
R = DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
getOrCreateNamespace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
- getLineNumber(NA.getLocation()), NA.getName());
+ getOrCreateFile(Loc), getLineNumber(Loc), NA.getName());
VH.reset(R);
return R;
}
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 9f40ee5a00a3..9572bd3543bd 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -73,9 +73,12 @@ Address CodeGenFunction::CreateTempAlloca(llvm::Type *Ty, CharUnits Align,
// cast alloca to the default address space when necessary.
if (CastToDefaultAddrSpace && getASTAllocaAddressSpace() != LangAS::Default) {
auto DestAddrSpace = getContext().getTargetAddressSpace(LangAS::Default);
+ auto CurIP = Builder.saveIP();
+ Builder.SetInsertPoint(AllocaInsertPt);
V = getTargetHooks().performAddrSpaceCast(
*this, V, getASTAllocaAddressSpace(), LangAS::Default,
Ty->getPointerTo(DestAddrSpace), /*non-null*/ true);
+ Builder.restoreIP(CurIP);
}
return Address(V, Align);
@@ -3052,7 +3055,9 @@ static llvm::Value *emitArraySubscriptGEP(CodeGenFunction &CGF,
SourceLocation loc,
const llvm::Twine &name = "arrayidx") {
if (inbounds) {
- return CGF.EmitCheckedInBoundsGEP(ptr, indices, signedIndices, loc, name);
+ return CGF.EmitCheckedInBoundsGEP(ptr, indices, signedIndices,
+ CodeGenFunction::NotSubtraction, loc,
+ name);
} else {
return CGF.Builder.CreateGEP(ptr, indices, name);
}
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 43c86495f3d3..1170b014ec7f 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -1851,7 +1851,7 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
llvm::Value *input;
int amount = (isInc ? 1 : -1);
- bool signedIndex = !isInc;
+ bool isSubtraction = !isInc;
if (const AtomicType *atomicTy = type->getAs<AtomicType>()) {
type = atomicTy->getValueType();
@@ -1941,8 +1941,9 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, numElts, "vla.inc");
else
- value = CGF.EmitCheckedInBoundsGEP(value, numElts, signedIndex,
- E->getExprLoc(), "vla.inc");
+ value = CGF.EmitCheckedInBoundsGEP(
+ value, numElts, /*SignedIndices=*/false, isSubtraction,
+ E->getExprLoc(), "vla.inc");
// Arithmetic on function pointers (!) is just +-1.
} else if (type->isFunctionType()) {
@@ -1952,8 +1953,9 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, amt, "incdec.funcptr");
else
- value = CGF.EmitCheckedInBoundsGEP(value, amt, signedIndex,
- E->getExprLoc(), "incdec.funcptr");
+ value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false,
+ isSubtraction, E->getExprLoc(),
+ "incdec.funcptr");
value = Builder.CreateBitCast(value, input->getType());
// For everything else, we can just do a simple increment.
@@ -1962,8 +1964,9 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, amt, "incdec.ptr");
else
- value = CGF.EmitCheckedInBoundsGEP(value, amt, signedIndex,
- E->getExprLoc(), "incdec.ptr");
+ value = CGF.EmitCheckedInBoundsGEP(value, amt, /*SignedIndices=*/false,
+ isSubtraction, E->getExprLoc(),
+ "incdec.ptr");
}
// Vector increment/decrement.
@@ -2044,7 +2047,8 @@ ScalarExprEmitter::EmitScalarPrePostIncDec(const UnaryOperator *E, LValue LV,
if (CGF.getLangOpts().isSignedOverflowDefined())
value = Builder.CreateGEP(value, sizeValue, "incdec.objptr");
else
- value = CGF.EmitCheckedInBoundsGEP(value, sizeValue, signedIndex,
+ value = CGF.EmitCheckedInBoundsGEP(value, sizeValue,
+ /*SignedIndices=*/false, isSubtraction,
E->getExprLoc(), "incdec.objptr");
value = Builder.CreateBitCast(value, input->getType());
}
@@ -2663,7 +2667,6 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
}
bool isSigned = indexOperand->getType()->isSignedIntegerOrEnumerationType();
- bool mayHaveNegativeGEPIndex = isSigned || isSubtraction;
unsigned width = cast<llvm::IntegerType>(index->getType())->getBitWidth();
auto &DL = CGF.CGM.getDataLayout();
@@ -2715,7 +2718,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
} else {
index = CGF.Builder.CreateNSWMul(index, numElements, "vla.index");
pointer =
- CGF.EmitCheckedInBoundsGEP(pointer, index, mayHaveNegativeGEPIndex,
+ CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction,
op.E->getExprLoc(), "add.ptr");
}
return pointer;
@@ -2733,7 +2736,7 @@ static Value *emitPointerArithmetic(CodeGenFunction &CGF,
if (CGF.getLangOpts().isSignedOverflowDefined())
return CGF.Builder.CreateGEP(pointer, index, "add.ptr");
- return CGF.EmitCheckedInBoundsGEP(pointer, index, mayHaveNegativeGEPIndex,
+ return CGF.EmitCheckedInBoundsGEP(pointer, index, isSigned, isSubtraction,
op.E->getExprLoc(), "add.ptr");
}
@@ -2807,7 +2810,7 @@ static Value* tryEmitFMulAdd(const BinOpInfo &op,
Value *ScalarExprEmitter::EmitAdd(const BinOpInfo &op) {
if (op.LHS->getType()->isPointerTy() ||
op.RHS->getType()->isPointerTy())
- return emitPointerArithmetic(CGF, op, /*subtraction*/ false);
+ return emitPointerArithmetic(CGF, op, CodeGenFunction::NotSubtraction);
if (op.Ty->isSignedIntegerOrEnumerationType()) {
switch (CGF.getLangOpts().getSignedOverflowBehavior()) {
@@ -2878,7 +2881,7 @@ Value *ScalarExprEmitter::EmitSub(const BinOpInfo &op) {
// If the RHS is not a pointer, then we have normal pointer
// arithmetic.
if (!op.RHS->getType()->isPointerTy())
- return emitPointerArithmetic(CGF, op, /*subtraction*/ true);
+ return emitPointerArithmetic(CGF, op, CodeGenFunction::IsSubtraction);
// Otherwise, this is a pointer subtraction.
@@ -3853,6 +3856,7 @@ LValue CodeGenFunction::EmitCompoundAssignmentLValue(
Value *CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr,
ArrayRef<Value *> IdxList,
bool SignedIndices,
+ bool IsSubtraction,
SourceLocation Loc,
const Twine &Name) {
Value *GEPVal = Builder.CreateInBoundsGEP(Ptr, IdxList, Name);
@@ -3958,15 +3962,19 @@ Value *CodeGenFunction::EmitCheckedInBoundsGEP(Value *Ptr,
// pointer matches the sign of the total offset.
llvm::Value *ValidGEP;
auto *NoOffsetOverflow = Builder.CreateNot(OffsetOverflows);
- auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
if (SignedIndices) {
+ auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
auto *PosOrZeroOffset = Builder.CreateICmpSGE(TotalOffset, Zero);
llvm::Value *NegValid = Builder.CreateICmpULT(ComputedGEP, IntPtr);
ValidGEP = Builder.CreateAnd(
Builder.CreateSelect(PosOrZeroOffset, PosOrZeroValid, NegValid),
NoOffsetOverflow);
- } else {
+ } else if (!SignedIndices && !IsSubtraction) {
+ auto *PosOrZeroValid = Builder.CreateICmpUGE(ComputedGEP, IntPtr);
ValidGEP = Builder.CreateAnd(PosOrZeroValid, NoOffsetOverflow);
+ } else {
+ auto *NegOrZeroValid = Builder.CreateICmpULE(ComputedGEP, IntPtr);
+ ValidGEP = Builder.CreateAnd(NegOrZeroValid, NoOffsetOverflow);
}
llvm::Constant *StaticArgs[] = {EmitCheckSourceLocation(Loc)};
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index a2ea0dec3e9d..d488bd4b30bf 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -643,6 +643,12 @@ enum OpenMPRTLFunction {
// Call to void __kmpc_doacross_wait(ident_t *loc, kmp_int32 gtid, kmp_int64
// *vec);
OMPRTL__kmpc_doacross_wait,
+ // Call to void *__kmpc_task_reduction_init(int gtid, int num_data, void
+ // *data);
+ OMPRTL__kmpc_task_reduction_init,
+ // Call to void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
+ // *d);
+ OMPRTL__kmpc_task_reduction_get_th_data,
//
// Offloading related calls
@@ -697,6 +703,414 @@ void RegionCodeGenTy::operator()(CodeGenFunction &CGF) const {
}
}
+/// Check if the combiner is a call to UDR combiner and if it is so return the
+/// UDR decl used for reduction.
+static const OMPDeclareReductionDecl *
+getReductionInit(const Expr *ReductionOp) {
+ if (auto *CE = dyn_cast<CallExpr>(ReductionOp))
+ if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
+ if (auto *DRE =
+ dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
+ if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
+ return DRD;
+ return nullptr;
+}
+
+static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
+ const OMPDeclareReductionDecl *DRD,
+ const Expr *InitOp,
+ Address Private, Address Original,
+ QualType Ty) {
+ if (DRD->getInitializer()) {
+ std::pair<llvm::Function *, llvm::Function *> Reduction =
+ CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
+ auto *CE = cast<CallExpr>(InitOp);
+ auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
+ const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
+ const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
+ auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
+ auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
+ CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
+ PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
+ [=]() -> Address { return Private; });
+ PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
+ [=]() -> Address { return Original; });
+ (void)PrivateScope.Privatize();
+ RValue Func = RValue::get(Reduction.second);
+ CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
+ CGF.EmitIgnoredExpr(InitOp);
+ } else {
+ llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
+ auto *GV = new llvm::GlobalVariable(
+ CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
+ llvm::GlobalValue::PrivateLinkage, Init, ".init");
+ LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
+ RValue InitRVal;
+ switch (CGF.getEvaluationKind(Ty)) {
+ case TEK_Scalar:
+ InitRVal = CGF.EmitLoadOfLValue(LV, SourceLocation());
+ break;
+ case TEK_Complex:
+ InitRVal =
+ RValue::getComplex(CGF.EmitLoadOfComplex(LV, SourceLocation()));
+ break;
+ case TEK_Aggregate:
+ InitRVal = RValue::getAggregate(LV.getAddress());
+ break;
+ }
+ OpaqueValueExpr OVE(SourceLocation(), Ty, VK_RValue);
+ CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
+ CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
+ /*IsInitializer=*/false);
+ }
+}
+
+/// \brief Emit initialization of arrays of complex types.
+/// \param DestAddr Address of the array.
+/// \param Type Type of array.
+/// \param Init Initial expression of array.
+/// \param SrcAddr Address of the original array.
+static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
+ QualType Type, const Expr *Init,
+ const OMPDeclareReductionDecl *DRD,
+ Address SrcAddr = Address::invalid()) {
+ // Perform element-by-element initialization.
+ QualType ElementTy;
+
+ // Drill down to the base element type on both arrays.
+ auto ArrayTy = Type->getAsArrayTypeUnsafe();
+ auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
+ DestAddr =
+ CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
+ if (DRD)
+ SrcAddr =
+ CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
+
+ llvm::Value *SrcBegin = nullptr;
+ if (DRD)
+ SrcBegin = SrcAddr.getPointer();
+ auto DestBegin = DestAddr.getPointer();
+ // Cast from pointer to array type to pointer to single element.
+ auto DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);
+ // The basic structure here is a while-do loop.
+ auto BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
+ auto DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
+ auto IsEmpty =
+ CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
+ CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
+
+ // Enter the loop body, making that address the current address.
+ auto EntryBB = CGF.Builder.GetInsertBlock();
+ CGF.EmitBlock(BodyBB);
+
+ CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
+
+ llvm::PHINode *SrcElementPHI = nullptr;
+ Address SrcElementCurrent = Address::invalid();
+ if (DRD) {
+ SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
+ "omp.arraycpy.srcElementPast");
+ SrcElementPHI->addIncoming(SrcBegin, EntryBB);
+ SrcElementCurrent =
+ Address(SrcElementPHI,
+ SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
+ }
+ llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
+ DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
+ DestElementPHI->addIncoming(DestBegin, EntryBB);
+ Address DestElementCurrent =
+ Address(DestElementPHI,
+ DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
+
+ // Emit copy.
+ {
+ CodeGenFunction::RunCleanupsScope InitScope(CGF);
+ if (DRD && (DRD->getInitializer() || !Init)) {
+ emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
+ SrcElementCurrent, ElementTy);
+ } else
+ CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
+ /*IsInitializer=*/false);
+ }
+
+ if (DRD) {
+ // Shift the address forward by one element.
+ auto SrcElementNext = CGF.Builder.CreateConstGEP1_32(
+ SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
+ SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
+ }
+
+ // Shift the address forward by one element.
+ auto DestElementNext = CGF.Builder.CreateConstGEP1_32(
+ DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
+ // Check whether we've reached the end.
+ auto Done =
+ CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
+ CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
+ DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
+
+ // Done.
+ CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
+}
+
+LValue ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, const Expr *E) {
+ if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
+ return CGF.EmitOMPArraySectionExpr(OASE);
+ if (const auto *ASE = dyn_cast<ArraySubscriptExpr>(E))
+ return CGF.EmitLValue(ASE);
+ auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(E)->getDecl());
+ DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
+ CGF.CapturedStmtInfo &&
+ CGF.CapturedStmtInfo->lookup(OrigVD) != nullptr,
+ E->getType(), VK_LValue, E->getExprLoc());
+ // Store the address of the original variable associated with the LHS
+ // implicit variable.
+ return CGF.EmitLValue(&DRE);
+}
+
+LValue ReductionCodeGen::emitSharedLValueUB(CodeGenFunction &CGF,
+ const Expr *E) {
+ if (const auto *OASE = dyn_cast<OMPArraySectionExpr>(E))
+ return CGF.EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
+ return LValue();
+}
+
+void ReductionCodeGen::emitAggregateInitialization(
+ CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
+ const OMPDeclareReductionDecl *DRD) {
+ // Emit VarDecl with copy init for arrays.
+ // Get the address of the original variable captured in current
+ // captured region.
+ auto *PrivateVD =
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+ EmitOMPAggregateInit(CGF, PrivateAddr, PrivateVD->getType(),
+ DRD ? ClausesData[N].ReductionOp : PrivateVD->getInit(),
+ DRD, SharedLVal.getAddress());
+}
+
+ReductionCodeGen::ReductionCodeGen(ArrayRef<const Expr *> Shareds,
+ ArrayRef<const Expr *> Privates,
+ ArrayRef<const Expr *> ReductionOps) {
+ ClausesData.reserve(Shareds.size());
+ SharedAddresses.reserve(Shareds.size());
+ Sizes.reserve(Shareds.size());
+ BaseDecls.reserve(Shareds.size());
+ auto IPriv = Privates.begin();
+ auto IRed = ReductionOps.begin();
+ for (const auto *Ref : Shareds) {
+ ClausesData.emplace_back(Ref, *IPriv, *IRed);
+ std::advance(IPriv, 1);
+ std::advance(IRed, 1);
+ }
+}
+
+void ReductionCodeGen::emitSharedLValue(CodeGenFunction &CGF, unsigned N) {
+ assert(SharedAddresses.size() == N &&
+ "Number of generated lvalues must be exactly N.");
+ SharedAddresses.emplace_back(emitSharedLValue(CGF, ClausesData[N].Ref),
+ emitSharedLValueUB(CGF, ClausesData[N].Ref));
+}
+
+void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N) {
+ auto *PrivateVD =
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+ QualType PrivateType = PrivateVD->getType();
+ bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
+ if (!AsArraySection && !PrivateType->isVariablyModifiedType()) {
+ Sizes.emplace_back(
+ CGF.getTypeSize(
+ SharedAddresses[N].first.getType().getNonReferenceType()),
+ nullptr);
+ return;
+ }
+ llvm::Value *Size;
+ llvm::Value *SizeInChars;
+ llvm::Type *ElemType =
+ cast<llvm::PointerType>(SharedAddresses[N].first.getPointer()->getType())
+ ->getElementType();
+ auto *ElemSizeOf = llvm::ConstantExpr::getSizeOf(ElemType);
+ if (AsArraySection) {
+ Size = CGF.Builder.CreatePtrDiff(SharedAddresses[N].second.getPointer(),
+ SharedAddresses[N].first.getPointer());
+ Size = CGF.Builder.CreateNUWAdd(
+ Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
+ SizeInChars = CGF.Builder.CreateNUWMul(Size, ElemSizeOf);
+ } else {
+ SizeInChars = CGF.getTypeSize(
+ SharedAddresses[N].first.getType().getNonReferenceType());
+ Size = CGF.Builder.CreateExactUDiv(SizeInChars, ElemSizeOf);
+ }
+ Sizes.emplace_back(SizeInChars, Size);
+ CodeGenFunction::OpaqueValueMapping OpaqueMap(
+ CGF,
+ cast<OpaqueValueExpr>(
+ CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
+ RValue::get(Size));
+ CGF.EmitVariablyModifiedType(PrivateType);
+}
+
+void ReductionCodeGen::emitAggregateType(CodeGenFunction &CGF, unsigned N,
+ llvm::Value *Size) {
+ auto *PrivateVD =
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+ QualType PrivateType = PrivateVD->getType();
+ bool AsArraySection = isa<OMPArraySectionExpr>(ClausesData[N].Ref);
+ if (!AsArraySection && !PrivateType->isVariablyModifiedType()) {
+ assert(!Size && !Sizes[N].second &&
+ "Size should be nullptr for non-variably modified redution "
+ "items.");
+ return;
+ }
+ CodeGenFunction::OpaqueValueMapping OpaqueMap(
+ CGF,
+ cast<OpaqueValueExpr>(
+ CGF.getContext().getAsVariableArrayType(PrivateType)->getSizeExpr()),
+ RValue::get(Size));
+ CGF.EmitVariablyModifiedType(PrivateType);
+}
+
+void ReductionCodeGen::emitInitialization(
+ CodeGenFunction &CGF, unsigned N, Address PrivateAddr, LValue SharedLVal,
+ llvm::function_ref<bool(CodeGenFunction &)> DefaultInit) {
+ assert(SharedAddresses.size() > N && "No variable was generated");
+ auto *PrivateVD =
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+ auto *DRD = getReductionInit(ClausesData[N].ReductionOp);
+ QualType PrivateType = PrivateVD->getType();
+ PrivateAddr = CGF.Builder.CreateElementBitCast(
+ PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
+ QualType SharedType = SharedAddresses[N].first.getType();
+ SharedLVal = CGF.MakeAddrLValue(
+ CGF.Builder.CreateElementBitCast(SharedLVal.getAddress(),
+ CGF.ConvertTypeForMem(SharedType)),
+ SharedType, SharedAddresses[N].first.getBaseInfo());
+ if (isa<OMPArraySectionExpr>(ClausesData[N].Ref) ||
+ CGF.getContext().getAsArrayType(PrivateVD->getType())) {
+ emitAggregateInitialization(CGF, N, PrivateAddr, SharedLVal, DRD);
+ } else if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
+ emitInitWithReductionInitializer(CGF, DRD, ClausesData[N].ReductionOp,
+ PrivateAddr, SharedLVal.getAddress(),
+ SharedLVal.getType());
+ } else if (!DefaultInit(CGF) && PrivateVD->hasInit() &&
+ !CGF.isTrivialInitializer(PrivateVD->getInit())) {
+ CGF.EmitAnyExprToMem(PrivateVD->getInit(), PrivateAddr,
+ PrivateVD->getType().getQualifiers(),
+ /*IsInitializer=*/false);
+ }
+}
+
+bool ReductionCodeGen::needCleanups(unsigned N) {
+ auto *PrivateVD =
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+ QualType PrivateType = PrivateVD->getType();
+ QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
+ return DTorKind != QualType::DK_none;
+}
+
+void ReductionCodeGen::emitCleanups(CodeGenFunction &CGF, unsigned N,
+ Address PrivateAddr) {
+ auto *PrivateVD =
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Private)->getDecl());
+ QualType PrivateType = PrivateVD->getType();
+ QualType::DestructionKind DTorKind = PrivateType.isDestructedType();
+ if (needCleanups(N)) {
+ PrivateAddr = CGF.Builder.CreateElementBitCast(
+ PrivateAddr, CGF.ConvertTypeForMem(PrivateType));
+ CGF.pushDestroy(DTorKind, PrivateAddr, PrivateType);
+ }
+}
+
+static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
+ LValue BaseLV) {
+ BaseTy = BaseTy.getNonReferenceType();
+ while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
+ !CGF.getContext().hasSameType(BaseTy, ElTy)) {
+ if (auto *PtrTy = BaseTy->getAs<PointerType>())
+ BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
+ else {
+ BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),
+ BaseTy->castAs<ReferenceType>());
+ }
+ BaseTy = BaseTy->getPointeeType();
+ }
+ return CGF.MakeAddrLValue(
+ CGF.Builder.CreateElementBitCast(BaseLV.getAddress(),
+ CGF.ConvertTypeForMem(ElTy)),
+ BaseLV.getType(), BaseLV.getBaseInfo());
+}
+
+static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
+ llvm::Type *BaseLVType, CharUnits BaseLVAlignment,
+ llvm::Value *Addr) {
+ Address Tmp = Address::invalid();
+ Address TopTmp = Address::invalid();
+ Address MostTopTmp = Address::invalid();
+ BaseTy = BaseTy.getNonReferenceType();
+ while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
+ !CGF.getContext().hasSameType(BaseTy, ElTy)) {
+ Tmp = CGF.CreateMemTemp(BaseTy);
+ if (TopTmp.isValid())
+ CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
+ else
+ MostTopTmp = Tmp;
+ TopTmp = Tmp;
+ BaseTy = BaseTy->getPointeeType();
+ }
+ llvm::Type *Ty = BaseLVType;
+ if (Tmp.isValid())
+ Ty = Tmp.getElementType();
+ Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
+ if (Tmp.isValid()) {
+ CGF.Builder.CreateStore(Addr, Tmp);
+ return MostTopTmp;
+ }
+ return Address(Addr, BaseLVAlignment);
+}
+
+Address ReductionCodeGen::adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
+ Address PrivateAddr) {
+ const DeclRefExpr *DE;
+ const VarDecl *OrigVD = nullptr;
+ if (auto *OASE = dyn_cast<OMPArraySectionExpr>(ClausesData[N].Ref)) {
+ auto *Base = OASE->getBase()->IgnoreParenImpCasts();
+ while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
+ Base = TempOASE->getBase()->IgnoreParenImpCasts();
+ while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
+ Base = TempASE->getBase()->IgnoreParenImpCasts();
+ DE = cast<DeclRefExpr>(Base);
+ OrigVD = cast<VarDecl>(DE->getDecl());
+ } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(ClausesData[N].Ref)) {
+ auto *Base = ASE->getBase()->IgnoreParenImpCasts();
+ while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
+ Base = TempASE->getBase()->IgnoreParenImpCasts();
+ DE = cast<DeclRefExpr>(Base);
+ OrigVD = cast<VarDecl>(DE->getDecl());
+ }
+ if (OrigVD) {
+ BaseDecls.emplace_back(OrigVD);
+ auto OriginalBaseLValue = CGF.EmitLValue(DE);
+ LValue BaseLValue =
+ loadToBegin(CGF, OrigVD->getType(), SharedAddresses[N].first.getType(),
+ OriginalBaseLValue);
+ llvm::Value *Adjustment = CGF.Builder.CreatePtrDiff(
+ BaseLValue.getPointer(), SharedAddresses[N].first.getPointer());
+ llvm::Value *Ptr =
+ CGF.Builder.CreateGEP(PrivateAddr.getPointer(), Adjustment);
+ return castToBase(CGF, OrigVD->getType(),
+ SharedAddresses[N].first.getType(),
+ OriginalBaseLValue.getPointer()->getType(),
+ OriginalBaseLValue.getAlignment(), Ptr);
+ }
+ BaseDecls.emplace_back(
+ cast<VarDecl>(cast<DeclRefExpr>(ClausesData[N].Ref)->getDecl()));
+ return PrivateAddr;
+}
+
+bool ReductionCodeGen::usesReductionInitializer(unsigned N) const {
+ auto *DRD = getReductionInit(ClausesData[N].ReductionOp);
+ return DRD && DRD->getInitializer();
+}
+
LValue CGOpenMPRegionInfo::getThreadIDVariableLValue(CodeGenFunction &CGF) {
return CGF.EmitLoadOfPointerLValue(
CGF.GetAddrOfLocalVar(getThreadIDVariable()),
@@ -1554,6 +1968,26 @@ CGOpenMPRuntime::createRuntimeFunction(unsigned Function) {
RTLFn = CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_doacross_wait");
break;
}
+ case OMPRTL__kmpc_task_reduction_init: {
+ // Build void *__kmpc_task_reduction_init(int gtid, int num_data, void
+ // *data);
+ llvm::Type *TypeParams[] = {CGM.IntTy, CGM.IntTy, CGM.VoidPtrTy};
+ llvm::FunctionType *FnTy =
+ llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
+ RTLFn =
+ CGM.CreateRuntimeFunction(FnTy, /*Name=*/"__kmpc_task_reduction_init");
+ break;
+ }
+ case OMPRTL__kmpc_task_reduction_get_th_data: {
+ // Build void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
+ // *d);
+ llvm::Type *TypeParams[] = {CGM.IntTy, CGM.VoidPtrTy, CGM.VoidPtrTy};
+ llvm::FunctionType *FnTy =
+ llvm::FunctionType::get(CGM.VoidPtrTy, TypeParams, /*isVarArg=*/false);
+ RTLFn = CGM.CreateRuntimeFunction(
+ FnTy, /*Name=*/"__kmpc_task_reduction_get_th_data");
+ break;
+ }
case OMPRTL__tgt_target: {
// Build int32_t __tgt_target(int32_t device_id, void *host_ptr, int32_t
// arg_num, void** args_base, void **args, size_t *arg_sizes, int32_t
@@ -1904,6 +2338,27 @@ llvm::Function *CGOpenMPRuntime::emitThreadPrivateVarDefinition(
return nullptr;
}
+Address CGOpenMPRuntime::getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
+ QualType VarType,
+ StringRef Name) {
+ llvm::Twine VarName(Name, ".artificial.");
+ llvm::Type *VarLVType = CGF.ConvertTypeForMem(VarType);
+ llvm::Value *GAddr = getOrCreateInternalVariable(VarLVType, VarName);
+ llvm::Value *Args[] = {
+ emitUpdateLocation(CGF, SourceLocation()),
+ getThreadID(CGF, SourceLocation()),
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(GAddr, CGM.VoidPtrTy),
+ CGF.Builder.CreateIntCast(CGF.getTypeSize(VarType), CGM.SizeTy,
+ /*IsSigned=*/false),
+ getOrCreateInternalVariable(CGM.VoidPtrPtrTy, VarName + ".cache.")};
+ return Address(
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+ CGF.EmitRuntimeCall(
+ createRuntimeFunction(OMPRTL__kmpc_threadprivate_cached), Args),
+ VarLVType->getPointerTo(/*AddrSpace=*/0)),
+ CGM.getPointerAlign());
+}
+
/// \brief Emits code for OpenMP 'if' clause using specified \a CodeGen
/// function. Here is the logic:
/// if (Cond) {
@@ -2699,6 +3154,8 @@ enum KmpTaskTFields {
KmpTaskTStride,
/// (Taskloops only) Is last iteration flag.
KmpTaskTLastIter,
+ /// (Taskloops only) Reduction data.
+ KmpTaskTReductions,
};
} // anonymous namespace
@@ -3250,6 +3707,7 @@ createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
// kmp_uint64 ub;
// kmp_int64 st;
// kmp_int32 liter;
+ // void * reductions;
// };
auto *UD = C.buildImplicitRecord("kmp_cmplrdata_t", TTK_Union);
UD->startDefinition();
@@ -3273,6 +3731,7 @@ createKmpTaskTRecordDecl(CodeGenModule &CGM, OpenMPDirectiveKind Kind,
addFieldToRecordDecl(C, RD, KmpUInt64Ty);
addFieldToRecordDecl(C, RD, KmpInt64Ty);
addFieldToRecordDecl(C, RD, KmpInt32Ty);
+ addFieldToRecordDecl(C, RD, C.VoidPtrTy);
}
RD->completeDefinition();
return RD;
@@ -3303,7 +3762,7 @@ createKmpTaskTWithPrivatesRecordDecl(CodeGenModule &CGM, QualType KmpTaskTQTy,
/// TaskFunction(gtid, tt->part_id, &tt->privates, task_privates_map, tt,
/// For taskloops:
/// tt->task_data.lb, tt->task_data.ub, tt->task_data.st, tt->task_data.liter,
-/// tt->shareds);
+/// tt->reductions, tt->shareds);
/// return 0;
/// }
/// \endcode
@@ -3389,10 +3848,14 @@ emitProxyTaskFunction(CodeGenModule &CGM, SourceLocation Loc,
auto LIFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTLastIter);
auto LILVal = CGF.EmitLValueForField(Base, *LIFI);
auto *LIParam = CGF.EmitLoadOfLValue(LILVal, Loc).getScalarVal();
+ auto RFI = std::next(KmpTaskTQTyRD->field_begin(), KmpTaskTReductions);
+ auto RLVal = CGF.EmitLValueForField(Base, *RFI);
+ auto *RParam = CGF.EmitLoadOfLValue(RLVal, Loc).getScalarVal();
CallArgs.push_back(LBParam);
CallArgs.push_back(UBParam);
CallArgs.push_back(StParam);
CallArgs.push_back(LIParam);
+ CallArgs.push_back(RParam);
}
CallArgs.push_back(SharedsParam);
@@ -4155,6 +4618,16 @@ void CGOpenMPRuntime::emitTaskLoopCall(CodeGenFunction &CGF, SourceLocation Loc,
cast<VarDecl>(cast<DeclRefExpr>(D.getStrideVariable())->getDecl());
CGF.EmitAnyExprToMem(StVar->getInit(), StLVal.getAddress(), StLVal.getQuals(),
/*IsInitializer=*/true);
+ // Store reductions address.
+ LValue RedLVal = CGF.EmitLValueForField(
+ Result.TDBase,
+ *std::next(Result.KmpTaskTQTyRD->field_begin(), KmpTaskTReductions));
+ if (Data.Reductions)
+ CGF.EmitStoreOfScalar(Data.Reductions, RedLVal);
+ else {
+ CGF.EmitNullInitialization(RedLVal.getAddress(),
+ CGF.getContext().VoidPtrTy);
+ }
enum { NoSchedule = 0, Grainsize = 1, NumTasks = 2 };
llvm::Value *TaskArgs[] = {
UpLoc,
@@ -4680,6 +5153,353 @@ void CGOpenMPRuntime::emitReduction(CodeGenFunction &CGF, SourceLocation Loc,
CGF.EmitBlock(DefaultBB, /*IsFinished=*/true);
}
+/// Generates unique name for artificial threadprivate variables.
+/// Format is: <Prefix> "." <Loc_raw_encoding> "_" <N>
+static std::string generateUniqueName(StringRef Prefix, SourceLocation Loc,
+ unsigned N) {
+ SmallString<256> Buffer;
+ llvm::raw_svector_ostream Out(Buffer);
+ Out << Prefix << "." << Loc.getRawEncoding() << "_" << N;
+ return Out.str();
+}
+
+/// Emits reduction initializer function:
+/// \code
+/// void @.red_init(void* %arg) {
+/// %0 = bitcast void* %arg to <type>*
+/// store <type> <init>, <type>* %0
+/// ret void
+/// }
+/// \endcode
+static llvm::Value *emitReduceInitFunction(CodeGenModule &CGM,
+ SourceLocation Loc,
+ ReductionCodeGen &RCG, unsigned N) {
+ auto &C = CGM.getContext();
+ FunctionArgList Args;
+ ImplicitParamDecl Param(C, C.VoidPtrTy, ImplicitParamDecl::Other);
+ Args.emplace_back(&Param);
+ auto &FnInfo =
+ CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+ auto *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
+ auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
+ ".red_init.", &CGM.getModule());
+ CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo);
+ CodeGenFunction CGF(CGM);
+ CGF.disableDebugInfo();
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args);
+ Address PrivateAddr = CGF.EmitLoadOfPointer(
+ CGF.GetAddrOfLocalVar(&Param),
+ C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
+ llvm::Value *Size = nullptr;
+ // If the size of the reduction item is non-constant, load it from global
+ // threadprivate variable.
+ if (RCG.getSizes(N).second) {
+ Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
+ CGF, CGM.getContext().getSizeType(),
+ generateUniqueName("reduction_size", Loc, N));
+ Size =
+ CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
+ CGM.getContext().getSizeType(), SourceLocation());
+ }
+ RCG.emitAggregateType(CGF, N, Size);
+ LValue SharedLVal;
+ // If initializer uses initializer from declare reduction construct, emit a
+ // pointer to the address of the original reduction item (reuired by reduction
+ // initializer)
+ if (RCG.usesReductionInitializer(N)) {
+ Address SharedAddr =
+ CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
+ CGF, CGM.getContext().VoidPtrTy,
+ generateUniqueName("reduction", Loc, N));
+ SharedLVal = CGF.MakeAddrLValue(SharedAddr, CGM.getContext().VoidPtrTy);
+ } else {
+ SharedLVal = CGF.MakeNaturalAlignAddrLValue(
+ llvm::ConstantPointerNull::get(CGM.VoidPtrTy),
+ CGM.getContext().VoidPtrTy);
+ }
+ // Emit the initializer:
+ // %0 = bitcast void* %arg to <type>*
+ // store <type> <init>, <type>* %0
+ RCG.emitInitialization(CGF, N, PrivateAddr, SharedLVal,
+ [](CodeGenFunction &) { return false; });
+ CGF.FinishFunction();
+ return Fn;
+}
+
+/// Emits reduction combiner function:
+/// \code
+/// void @.red_comb(void* %arg0, void* %arg1) {
+/// %lhs = bitcast void* %arg0 to <type>*
+/// %rhs = bitcast void* %arg1 to <type>*
+/// %2 = <ReductionOp>(<type>* %lhs, <type>* %rhs)
+/// store <type> %2, <type>* %lhs
+/// ret void
+/// }
+/// \endcode
+static llvm::Value *emitReduceCombFunction(CodeGenModule &CGM,
+ SourceLocation Loc,
+ ReductionCodeGen &RCG, unsigned N,
+ const Expr *ReductionOp,
+ const Expr *LHS, const Expr *RHS,
+ const Expr *PrivateRef) {
+ auto &C = CGM.getContext();
+ auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(LHS)->getDecl());
+ auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(RHS)->getDecl());
+ FunctionArgList Args;
+ ImplicitParamDecl ParamInOut(C, C.VoidPtrTy, ImplicitParamDecl::Other);
+ ImplicitParamDecl ParamIn(C, C.VoidPtrTy, ImplicitParamDecl::Other);
+ Args.emplace_back(&ParamInOut);
+ Args.emplace_back(&ParamIn);
+ auto &FnInfo =
+ CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+ auto *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
+ auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
+ ".red_comb.", &CGM.getModule());
+ CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo);
+ CodeGenFunction CGF(CGM);
+ CGF.disableDebugInfo();
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args);
+ llvm::Value *Size = nullptr;
+ // If the size of the reduction item is non-constant, load it from global
+ // threadprivate variable.
+ if (RCG.getSizes(N).second) {
+ Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
+ CGF, CGM.getContext().getSizeType(),
+ generateUniqueName("reduction_size", Loc, N));
+ Size =
+ CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
+ CGM.getContext().getSizeType(), SourceLocation());
+ }
+ RCG.emitAggregateType(CGF, N, Size);
+ // Remap lhs and rhs variables to the addresses of the function arguments.
+ // %lhs = bitcast void* %arg0 to <type>*
+ // %rhs = bitcast void* %arg1 to <type>*
+ CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
+ PrivateScope.addPrivate(LHSVD, [&C, &CGF, &ParamInOut, LHSVD]() -> Address {
+ // Pull out the pointer to the variable.
+ Address PtrAddr = CGF.EmitLoadOfPointer(
+ CGF.GetAddrOfLocalVar(&ParamInOut),
+ C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
+ return CGF.Builder.CreateElementBitCast(
+ PtrAddr, CGF.ConvertTypeForMem(LHSVD->getType()));
+ });
+ PrivateScope.addPrivate(RHSVD, [&C, &CGF, &ParamIn, RHSVD]() -> Address {
+ // Pull out the pointer to the variable.
+ Address PtrAddr = CGF.EmitLoadOfPointer(
+ CGF.GetAddrOfLocalVar(&ParamIn),
+ C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
+ return CGF.Builder.CreateElementBitCast(
+ PtrAddr, CGF.ConvertTypeForMem(RHSVD->getType()));
+ });
+ PrivateScope.Privatize();
+ // Emit the combiner body:
+ // %2 = <ReductionOp>(<type> *%lhs, <type> *%rhs)
+ // store <type> %2, <type>* %lhs
+ CGM.getOpenMPRuntime().emitSingleReductionCombiner(
+ CGF, ReductionOp, PrivateRef, cast<DeclRefExpr>(LHS),
+ cast<DeclRefExpr>(RHS));
+ CGF.FinishFunction();
+ return Fn;
+}
+
+/// Emits reduction finalizer function:
+/// \code
+/// void @.red_fini(void* %arg) {
+/// %0 = bitcast void* %arg to <type>*
+/// <destroy>(<type>* %0)
+/// ret void
+/// }
+/// \endcode
+static llvm::Value *emitReduceFiniFunction(CodeGenModule &CGM,
+ SourceLocation Loc,
+ ReductionCodeGen &RCG, unsigned N) {
+ if (!RCG.needCleanups(N))
+ return nullptr;
+ auto &C = CGM.getContext();
+ FunctionArgList Args;
+ ImplicitParamDecl Param(C, C.VoidPtrTy, ImplicitParamDecl::Other);
+ Args.emplace_back(&Param);
+ auto &FnInfo =
+ CGM.getTypes().arrangeBuiltinFunctionDeclaration(C.VoidTy, Args);
+ auto *FnTy = CGM.getTypes().GetFunctionType(FnInfo);
+ auto *Fn = llvm::Function::Create(FnTy, llvm::GlobalValue::InternalLinkage,
+ ".red_fini.", &CGM.getModule());
+ CGM.SetInternalFunctionAttributes(/*D=*/nullptr, Fn, FnInfo);
+ CodeGenFunction CGF(CGM);
+ CGF.disableDebugInfo();
+ CGF.StartFunction(GlobalDecl(), C.VoidTy, Fn, FnInfo, Args);
+ Address PrivateAddr = CGF.EmitLoadOfPointer(
+ CGF.GetAddrOfLocalVar(&Param),
+ C.getPointerType(C.VoidPtrTy).castAs<PointerType>());
+ llvm::Value *Size = nullptr;
+ // If the size of the reduction item is non-constant, load it from global
+ // threadprivate variable.
+ if (RCG.getSizes(N).second) {
+ Address SizeAddr = CGM.getOpenMPRuntime().getAddrOfArtificialThreadPrivate(
+ CGF, CGM.getContext().getSizeType(),
+ generateUniqueName("reduction_size", Loc, N));
+ Size =
+ CGF.EmitLoadOfScalar(SizeAddr, /*Volatile=*/false,
+ CGM.getContext().getSizeType(), SourceLocation());
+ }
+ RCG.emitAggregateType(CGF, N, Size);
+ // Emit the finalizer body:
+ // <destroy>(<type>* %0)
+ RCG.emitCleanups(CGF, N, PrivateAddr);
+ CGF.FinishFunction();
+ return Fn;
+}
+
+llvm::Value *CGOpenMPRuntime::emitTaskReductionInit(
+ CodeGenFunction &CGF, SourceLocation Loc, ArrayRef<const Expr *> LHSExprs,
+ ArrayRef<const Expr *> RHSExprs, const OMPTaskDataTy &Data) {
+ if (!CGF.HaveInsertPoint() || Data.ReductionVars.empty())
+ return nullptr;
+
+ // Build typedef struct:
+ // kmp_task_red_input {
+ // void *reduce_shar; // shared reduction item
+ // size_t reduce_size; // size of data item
+ // void *reduce_init; // data initialization routine
+ // void *reduce_fini; // data finalization routine
+ // void *reduce_comb; // data combiner routine
+ // kmp_task_red_flags_t flags; // flags for additional info from compiler
+ // } kmp_task_red_input_t;
+ ASTContext &C = CGM.getContext();
+ auto *RD = C.buildImplicitRecord("kmp_task_red_input_t");
+ RD->startDefinition();
+ const FieldDecl *SharedFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
+ const FieldDecl *SizeFD = addFieldToRecordDecl(C, RD, C.getSizeType());
+ const FieldDecl *InitFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
+ const FieldDecl *FiniFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
+ const FieldDecl *CombFD = addFieldToRecordDecl(C, RD, C.VoidPtrTy);
+ const FieldDecl *FlagsFD = addFieldToRecordDecl(
+ C, RD, C.getIntTypeForBitwidth(/*DestWidth=*/32, /*Signed=*/false));
+ RD->completeDefinition();
+ QualType RDType = C.getRecordType(RD);
+ unsigned Size = Data.ReductionVars.size();
+ llvm::APInt ArraySize(/*numBits=*/64, Size);
+ QualType ArrayRDType = C.getConstantArrayType(
+ RDType, ArraySize, ArrayType::Normal, /*IndexTypeQuals=*/0);
+ // kmp_task_red_input_t .rd_input.[Size];
+ Address TaskRedInput = CGF.CreateMemTemp(ArrayRDType, ".rd_input.");
+ ReductionCodeGen RCG(Data.ReductionVars, Data.ReductionCopies,
+ Data.ReductionOps);
+ for (unsigned Cnt = 0; Cnt < Size; ++Cnt) {
+ // kmp_task_red_input_t &ElemLVal = .rd_input.[Cnt];
+ llvm::Value *Idxs[] = {llvm::ConstantInt::get(CGM.SizeTy, /*V=*/0),
+ llvm::ConstantInt::get(CGM.SizeTy, Cnt)};
+ llvm::Value *GEP = CGF.EmitCheckedInBoundsGEP(
+ TaskRedInput.getPointer(), Idxs,
+ /*SignedIndices=*/false, /*IsSubtraction=*/false, Loc,
+ ".rd_input.gep.");
+ LValue ElemLVal = CGF.MakeNaturalAlignAddrLValue(GEP, RDType);
+ // ElemLVal.reduce_shar = &Shareds[Cnt];
+ LValue SharedLVal = CGF.EmitLValueForField(ElemLVal, SharedFD);
+ RCG.emitSharedLValue(CGF, Cnt);
+ llvm::Value *CastedShared =
+ CGF.EmitCastToVoidPtr(RCG.getSharedLValue(Cnt).getPointer());
+ CGF.EmitStoreOfScalar(CastedShared, SharedLVal);
+ RCG.emitAggregateType(CGF, Cnt);
+ llvm::Value *SizeValInChars;
+ llvm::Value *SizeVal;
+ std::tie(SizeValInChars, SizeVal) = RCG.getSizes(Cnt);
+ // We use delayed creation/initialization for VLAs, array sections and
+ // custom reduction initializations. It is required because runtime does not
+ // provide the way to pass the sizes of VLAs/array sections to
+ // initializer/combiner/finalizer functions and does not pass the pointer to
+ // original reduction item to the initializer. Instead threadprivate global
+ // variables are used to store these values and use them in the functions.
+ bool DelayedCreation = !!SizeVal;
+ SizeValInChars = CGF.Builder.CreateIntCast(SizeValInChars, CGM.SizeTy,
+ /*isSigned=*/false);
+ LValue SizeLVal = CGF.EmitLValueForField(ElemLVal, SizeFD);
+ CGF.EmitStoreOfScalar(SizeValInChars, SizeLVal);
+ // ElemLVal.reduce_init = init;
+ LValue InitLVal = CGF.EmitLValueForField(ElemLVal, InitFD);
+ llvm::Value *InitAddr =
+ CGF.EmitCastToVoidPtr(emitReduceInitFunction(CGM, Loc, RCG, Cnt));
+ CGF.EmitStoreOfScalar(InitAddr, InitLVal);
+ DelayedCreation = DelayedCreation || RCG.usesReductionInitializer(Cnt);
+ // ElemLVal.reduce_fini = fini;
+ LValue FiniLVal = CGF.EmitLValueForField(ElemLVal, FiniFD);
+ llvm::Value *Fini = emitReduceFiniFunction(CGM, Loc, RCG, Cnt);
+ llvm::Value *FiniAddr = Fini
+ ? CGF.EmitCastToVoidPtr(Fini)
+ : llvm::ConstantPointerNull::get(CGM.VoidPtrTy);
+ CGF.EmitStoreOfScalar(FiniAddr, FiniLVal);
+ // ElemLVal.reduce_comb = comb;
+ LValue CombLVal = CGF.EmitLValueForField(ElemLVal, CombFD);
+ llvm::Value *CombAddr = CGF.EmitCastToVoidPtr(emitReduceCombFunction(
+ CGM, Loc, RCG, Cnt, Data.ReductionOps[Cnt], LHSExprs[Cnt],
+ RHSExprs[Cnt], Data.ReductionCopies[Cnt]));
+ CGF.EmitStoreOfScalar(CombAddr, CombLVal);
+ // ElemLVal.flags = 0;
+ LValue FlagsLVal = CGF.EmitLValueForField(ElemLVal, FlagsFD);
+ if (DelayedCreation) {
+ CGF.EmitStoreOfScalar(
+ llvm::ConstantInt::get(CGM.Int32Ty, /*V=*/1, /*IsSigned=*/true),
+ FlagsLVal);
+ } else
+ CGF.EmitNullInitialization(FlagsLVal.getAddress(), FlagsLVal.getType());
+ }
+ // Build call void *__kmpc_task_reduction_init(int gtid, int num_data, void
+ // *data);
+ llvm::Value *Args[] = {
+ CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
+ /*isSigned=*/true),
+ llvm::ConstantInt::get(CGM.IntTy, Size, /*isSigned=*/true),
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(TaskRedInput.getPointer(),
+ CGM.VoidPtrTy)};
+ return CGF.EmitRuntimeCall(
+ createRuntimeFunction(OMPRTL__kmpc_task_reduction_init), Args);
+}
+
+void CGOpenMPRuntime::emitTaskReductionFixups(CodeGenFunction &CGF,
+ SourceLocation Loc,
+ ReductionCodeGen &RCG,
+ unsigned N) {
+ auto Sizes = RCG.getSizes(N);
+ // Emit threadprivate global variable if the type is non-constant
+ // (Sizes.second = nullptr).
+ if (Sizes.second) {
+ llvm::Value *SizeVal = CGF.Builder.CreateIntCast(Sizes.second, CGM.SizeTy,
+ /*isSigned=*/false);
+ Address SizeAddr = getAddrOfArtificialThreadPrivate(
+ CGF, CGM.getContext().getSizeType(),
+ generateUniqueName("reduction_size", Loc, N));
+ CGF.Builder.CreateStore(SizeVal, SizeAddr, /*IsVolatile=*/false);
+ }
+ // Store address of the original reduction item if custom initializer is used.
+ if (RCG.usesReductionInitializer(N)) {
+ Address SharedAddr = getAddrOfArtificialThreadPrivate(
+ CGF, CGM.getContext().VoidPtrTy,
+ generateUniqueName("reduction", Loc, N));
+ CGF.Builder.CreateStore(
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
+ RCG.getSharedLValue(N).getPointer(), CGM.VoidPtrTy),
+ SharedAddr, /*IsVolatile=*/false);
+ }
+}
+
+Address CGOpenMPRuntime::getTaskReductionItem(CodeGenFunction &CGF,
+ SourceLocation Loc,
+ llvm::Value *ReductionsPtr,
+ LValue SharedLVal) {
+ // Build call void *__kmpc_task_reduction_get_th_data(int gtid, void *tg, void
+ // *d);
+ llvm::Value *Args[] = {
+ CGF.Builder.CreateIntCast(getThreadID(CGF, Loc), CGM.IntTy,
+ /*isSigned=*/true),
+ ReductionsPtr,
+ CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(SharedLVal.getPointer(),
+ CGM.VoidPtrTy)};
+ return Address(
+ CGF.EmitRuntimeCall(
+ createRuntimeFunction(OMPRTL__kmpc_task_reduction_get_th_data), Args),
+ SharedLVal.getAlignment());
+}
+
void CGOpenMPRuntime::emitTaskwaitCall(CodeGenFunction &CGF,
SourceLocation Loc) {
if (!CGF.HaveInsertPoint())
diff --git a/lib/CodeGen/CGOpenMPRuntime.h b/lib/CodeGen/CGOpenMPRuntime.h
index 6f460f121791..5dcf999bea37 100644
--- a/lib/CodeGen/CGOpenMPRuntime.h
+++ b/lib/CodeGen/CGOpenMPRuntime.h
@@ -96,15 +96,106 @@ struct OMPTaskDataTy final {
SmallVector<const Expr *, 4> FirstprivateInits;
SmallVector<const Expr *, 4> LastprivateVars;
SmallVector<const Expr *, 4> LastprivateCopies;
+ SmallVector<const Expr *, 4> ReductionVars;
+ SmallVector<const Expr *, 4> ReductionCopies;
+ SmallVector<const Expr *, 4> ReductionOps;
SmallVector<std::pair<OpenMPDependClauseKind, const Expr *>, 4> Dependences;
llvm::PointerIntPair<llvm::Value *, 1, bool> Final;
llvm::PointerIntPair<llvm::Value *, 1, bool> Schedule;
llvm::PointerIntPair<llvm::Value *, 1, bool> Priority;
+ llvm::Value *Reductions = nullptr;
unsigned NumberOfParts = 0;
bool Tied = true;
bool Nogroup = false;
};
+/// Class intended to support codegen of all kind of the reduction clauses.
+class ReductionCodeGen {
+private:
+ /// Data required for codegen of reduction clauses.
+ struct ReductionData {
+ /// Reference to the original shared item.
+ const Expr *Ref = nullptr;
+ /// Helper expression for generation of private copy.
+ const Expr *Private = nullptr;
+ /// Helper expression for generation reduction operation.
+ const Expr *ReductionOp = nullptr;
+ ReductionData(const Expr *Ref, const Expr *Private, const Expr *ReductionOp)
+ : Ref(Ref), Private(Private), ReductionOp(ReductionOp) {}
+ };
+ /// List of reduction-based clauses.
+ SmallVector<ReductionData, 4> ClausesData;
+
+ /// List of addresses of original shared variables/expressions.
+ SmallVector<std::pair<LValue, LValue>, 4> SharedAddresses;
+ /// Sizes of the reduction items in chars.
+ SmallVector<std::pair<llvm::Value *, llvm::Value *>, 4> Sizes;
+ /// Base declarations for the reduction items.
+ SmallVector<const VarDecl *, 4> BaseDecls;
+
+ /// Emits lvalue for shared expresion.
+ LValue emitSharedLValue(CodeGenFunction &CGF, const Expr *E);
+ /// Emits upper bound for shared expression (if array section).
+ LValue emitSharedLValueUB(CodeGenFunction &CGF, const Expr *E);
+ /// Performs aggregate initialization.
+ /// \param N Number of reduction item in the common list.
+ /// \param PrivateAddr Address of the corresponding private item.
+ /// \param SharedLVal Address of the original shared variable.
+ /// \param DRD Declare reduction construct used for reduction item.
+ void emitAggregateInitialization(CodeGenFunction &CGF, unsigned N,
+ Address PrivateAddr, LValue SharedLVal,
+ const OMPDeclareReductionDecl *DRD);
+
+public:
+ ReductionCodeGen(ArrayRef<const Expr *> Shareds,
+ ArrayRef<const Expr *> Privates,
+ ArrayRef<const Expr *> ReductionOps);
+ /// Emits lvalue for a reduction item.
+ /// \param N Number of the reduction item.
+ void emitSharedLValue(CodeGenFunction &CGF, unsigned N);
+ /// Emits the code for the variable-modified type, if required.
+ /// \param N Number of the reduction item.
+ void emitAggregateType(CodeGenFunction &CGF, unsigned N);
+ /// Emits the code for the variable-modified type, if required.
+ /// \param N Number of the reduction item.
+ /// \param Size Size of the type in chars.
+ void emitAggregateType(CodeGenFunction &CGF, unsigned N, llvm::Value *Size);
+ /// Performs initialization of the private copy for the reduction item.
+ /// \param N Number of the reduction item.
+ /// \param PrivateAddr Address of the corresponding private item.
+ /// \param DefaultInit Default initialization sequence that should be
+ /// performed if no reduction specific initialization is found.
+ /// \param SharedLVal Address of the original shared variable.
+ void
+ emitInitialization(CodeGenFunction &CGF, unsigned N, Address PrivateAddr,
+ LValue SharedLVal,
+ llvm::function_ref<bool(CodeGenFunction &)> DefaultInit);
+ /// Returns true if the private copy requires cleanups.
+ bool needCleanups(unsigned N);
+ /// Emits cleanup code for the reduction item.
+ /// \param N Number of the reduction item.
+ /// \param PrivateAddr Address of the corresponding private item.
+ void emitCleanups(CodeGenFunction &CGF, unsigned N, Address PrivateAddr);
+ /// Adjusts \p PrivatedAddr for using instead of the original variable
+ /// address in normal operations.
+ /// \param N Number of the reduction item.
+ /// \param PrivateAddr Address of the corresponding private item.
+ Address adjustPrivateAddress(CodeGenFunction &CGF, unsigned N,
+ Address PrivateAddr);
+ /// Returns LValue for the reduction item.
+ LValue getSharedLValue(unsigned N) const { return SharedAddresses[N].first; }
+ /// Returns the size of the reduction item (in chars and total number of
+ /// elements in the item), or nullptr, if the size is a constant.
+ std::pair<llvm::Value *, llvm::Value *> getSizes(unsigned N) const {
+ return Sizes[N];
+ }
+ /// Returns the base declaration of the reduction item.
+ const VarDecl *getBaseDecl(unsigned N) const { return BaseDecls[N]; }
+ /// Returns true if the initialization of the reduction item uses initializer
+ /// from declare reduction construct.
+ bool usesReductionInitializer(unsigned N) const;
+};
+
class CGOpenMPRuntime {
protected:
CodeGenModule &CGM;
@@ -121,7 +212,7 @@ protected:
/// \param OutlinedFnID Outlined function ID value to be defined by this call.
/// \param IsOffloadEntry True if the outlined function is an offload entry.
/// \param CodeGen Lambda codegen specific to an accelerator device.
- /// An oulined function may not be an entry if, e.g. the if clause always
+ /// An outlined function may not be an entry if, e.g. the if clause always
/// evaluates to false.
virtual void emitTargetOutlinedFunctionHelper(const OMPExecutableDirective &D,
StringRef ParentName,
@@ -699,7 +790,7 @@ public:
/// \param Loc Clang source location.
/// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
/// \param IVSize Size of the iteration variable in bits.
- /// \param IVSigned Sign of the interation variable.
+ /// \param IVSigned Sign of the iteration variable.
/// \param Ordered true if loop is ordered, false otherwise.
/// \param DispatchValues struct containing llvm values for lower bound, upper
/// bound, and chunk expression.
@@ -723,7 +814,7 @@ public:
/// \param Loc Clang source location.
/// \param ScheduleKind Schedule kind, specified by the 'schedule' clause.
/// \param IVSize Size of the iteration variable in bits.
- /// \param IVSigned Sign of the interation variable.
+ /// \param IVSigned Sign of the iteration variable.
/// \param Ordered true if loop is ordered, false otherwise.
/// \param IL Address of the output variable in which the flag of the
/// last iteration is returned.
@@ -732,7 +823,7 @@ public:
/// \param UB Address of the output variable in which the upper iteration
/// number is returned.
/// \param ST Address of the output variable in which the stride value is
- /// returned nesessary to generated the static_chunked scheduled loop.
+ /// returned necessary to generated the static_chunked scheduled loop.
/// \param Chunk Value of the chunk for the static_chunked scheduled loop.
/// For the default (nullptr) value, the chunk 1 will be used.
///
@@ -747,7 +838,7 @@ public:
/// \param Loc Clang source location.
/// \param SchedKind Schedule kind, specified by the 'dist_schedule' clause.
/// \param IVSize Size of the iteration variable in bits.
- /// \param IVSigned Sign of the interation variable.
+ /// \param IVSigned Sign of the iteration variable.
/// \param Ordered true if loop is ordered, false otherwise.
/// \param IL Address of the output variable in which the flag of the
/// last iteration is returned.
@@ -756,7 +847,7 @@ public:
/// \param UB Address of the output variable in which the upper iteration
/// number is returned.
/// \param ST Address of the output variable in which the stride value is
- /// returned nesessary to generated the static_chunked scheduled loop.
+ /// returned necessary to generated the static_chunked scheduled loop.
/// \param Chunk Value of the chunk for the static_chunked scheduled loop.
/// For the default (nullptr) value, the chunk 1 will be used.
///
@@ -773,7 +864,7 @@ public:
/// \param CGF Reference to current CodeGenFunction.
/// \param Loc Clang source location.
/// \param IVSize Size of the iteration variable in bits.
- /// \param IVSigned Sign of the interation variable.
+ /// \param IVSigned Sign of the iteration variable.
///
virtual void emitForOrderedIterationEnd(CodeGenFunction &CGF,
SourceLocation Loc, unsigned IVSize,
@@ -792,7 +883,7 @@ public:
/// kmp_int[32|64] *p_lower, kmp_int[32|64] *p_upper,
/// kmp_int[32|64] *p_stride);
/// \param IVSize Size of the iteration variable in bits.
- /// \param IVSigned Sign of the interation variable.
+ /// \param IVSigned Sign of the iteration variable.
/// \param IL Address of the output variable in which the flag of the
/// last iteration is returned.
/// \param LB Address of the output variable in which the lower iteration
@@ -844,6 +935,14 @@ public:
SourceLocation Loc, bool PerformInit,
CodeGenFunction *CGF = nullptr);
+ /// Creates artificial threadprivate variable with name \p Name and type \p
+ /// VarType.
+ /// \param VarType Type of the artificial threadprivate variable.
+ /// \param Name Name of the artificial threadprivate variable.
+ virtual Address getAddrOfArtificialThreadPrivate(CodeGenFunction &CGF,
+ QualType VarType,
+ StringRef Name);
+
/// \brief Emit flush of the variables specified in 'omp flush' directive.
/// \param Vars List of variables to flush.
virtual void emitFlush(CodeGenFunction &CGF, ArrayRef<const Expr *> Vars,
@@ -1002,6 +1101,51 @@ public:
ArrayRef<const Expr *> ReductionOps,
ReductionOptionsTy Options);
+ /// Emit a code for initialization of task reduction clause. Next code
+ /// should be emitted for reduction:
+ /// \code
+ ///
+ /// _task_red_item_t red_data[n];
+ /// ...
+ /// red_data[i].shar = &origs[i];
+ /// red_data[i].size = sizeof(origs[i]);
+ /// red_data[i].f_init = (void*)RedInit<i>;
+ /// red_data[i].f_fini = (void*)RedDest<i>;
+ /// red_data[i].f_comb = (void*)RedOp<i>;
+ /// red_data[i].flags = <Flag_i>;
+ /// ...
+ /// void* tg1 = __kmpc_task_reduction_init(gtid, n, red_data);
+ /// \endcode
+ ///
+ /// \param LHSExprs List of LHS in \a Data.ReductionOps reduction operations.
+ /// \param RHSExprs List of RHS in \a Data.ReductionOps reduction operations.
+ /// \param Data Additional data for task generation like tiedness, final
+ /// state, list of privates, reductions etc.
+ virtual llvm::Value *emitTaskReductionInit(CodeGenFunction &CGF,
+ SourceLocation Loc,
+ ArrayRef<const Expr *> LHSExprs,
+ ArrayRef<const Expr *> RHSExprs,
+ const OMPTaskDataTy &Data);
+
+ /// Required to resolve existing problems in the runtime. Emits threadprivate
+ /// variables to store the size of the VLAs/array sections for
+ /// initializer/combiner/finalizer functions + emits threadprivate variable to
+ /// store the pointer to the original reduction item for the custom
+ /// initializer defined by declare reduction construct.
+ /// \param RCG Allows to reuse an existing data for the reductions.
+ /// \param N Reduction item for which fixups must be emitted.
+ virtual void emitTaskReductionFixups(CodeGenFunction &CGF, SourceLocation Loc,
+ ReductionCodeGen &RCG, unsigned N);
+
+ /// Get the address of `void *` type of the privatue copy of the reduction
+ /// item specified by the \p SharedLVal.
+ /// \param ReductionsPtr Pointer to the reduction data returned by the
+ /// emitTaskReductionInit function.
+ /// \param SharedLVal Address of the original reduction item.
+ virtual Address getTaskReductionItem(CodeGenFunction &CGF, SourceLocation Loc,
+ llvm::Value *ReductionsPtr,
+ LValue SharedLVal);
+
/// \brief Emit code for 'taskwait' directive.
virtual void emitTaskwaitCall(CodeGenFunction &CGF, SourceLocation Loc);
@@ -1029,7 +1173,7 @@ public:
/// \param OutlinedFnID Outlined function ID value to be defined by this call.
/// \param IsOffloadEntry True if the outlined function is an offload entry.
/// \param CodeGen Code generation sequence for the \a D directive.
- /// An oulined function may not be an entry if, e.g. the if clause always
+ /// An outlined function may not be an entry if, e.g. the if clause always
/// evaluates to false.
virtual void emitTargetOutlinedFunction(const OMPExecutableDirective &D,
StringRef ParentName,
diff --git a/lib/CodeGen/CGStmtOpenMP.cpp b/lib/CodeGen/CGStmtOpenMP.cpp
index 71797e2e6fbe..6135cf31d176 100644
--- a/lib/CodeGen/CGStmtOpenMP.cpp
+++ b/lib/CodeGen/CGStmtOpenMP.cpp
@@ -549,156 +549,6 @@ void CodeGenFunction::EmitOMPAggregateAssign(
EmitBlock(DoneBB, /*IsFinished=*/true);
}
-/// Check if the combiner is a call to UDR combiner and if it is so return the
-/// UDR decl used for reduction.
-static const OMPDeclareReductionDecl *
-getReductionInit(const Expr *ReductionOp) {
- if (auto *CE = dyn_cast<CallExpr>(ReductionOp))
- if (auto *OVE = dyn_cast<OpaqueValueExpr>(CE->getCallee()))
- if (auto *DRE =
- dyn_cast<DeclRefExpr>(OVE->getSourceExpr()->IgnoreImpCasts()))
- if (auto *DRD = dyn_cast<OMPDeclareReductionDecl>(DRE->getDecl()))
- return DRD;
- return nullptr;
-}
-
-static void emitInitWithReductionInitializer(CodeGenFunction &CGF,
- const OMPDeclareReductionDecl *DRD,
- const Expr *InitOp,
- Address Private, Address Original,
- QualType Ty) {
- if (DRD->getInitializer()) {
- std::pair<llvm::Function *, llvm::Function *> Reduction =
- CGF.CGM.getOpenMPRuntime().getUserDefinedReduction(DRD);
- auto *CE = cast<CallExpr>(InitOp);
- auto *OVE = cast<OpaqueValueExpr>(CE->getCallee());
- const Expr *LHS = CE->getArg(/*Arg=*/0)->IgnoreParenImpCasts();
- const Expr *RHS = CE->getArg(/*Arg=*/1)->IgnoreParenImpCasts();
- auto *LHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(LHS)->getSubExpr());
- auto *RHSDRE = cast<DeclRefExpr>(cast<UnaryOperator>(RHS)->getSubExpr());
- CodeGenFunction::OMPPrivateScope PrivateScope(CGF);
- PrivateScope.addPrivate(cast<VarDecl>(LHSDRE->getDecl()),
- [=]() -> Address { return Private; });
- PrivateScope.addPrivate(cast<VarDecl>(RHSDRE->getDecl()),
- [=]() -> Address { return Original; });
- (void)PrivateScope.Privatize();
- RValue Func = RValue::get(Reduction.second);
- CodeGenFunction::OpaqueValueMapping Map(CGF, OVE, Func);
- CGF.EmitIgnoredExpr(InitOp);
- } else {
- llvm::Constant *Init = CGF.CGM.EmitNullConstant(Ty);
- auto *GV = new llvm::GlobalVariable(
- CGF.CGM.getModule(), Init->getType(), /*isConstant=*/true,
- llvm::GlobalValue::PrivateLinkage, Init, ".init");
- LValue LV = CGF.MakeNaturalAlignAddrLValue(GV, Ty);
- RValue InitRVal;
- switch (CGF.getEvaluationKind(Ty)) {
- case TEK_Scalar:
- InitRVal = CGF.EmitLoadOfLValue(LV, SourceLocation());
- break;
- case TEK_Complex:
- InitRVal =
- RValue::getComplex(CGF.EmitLoadOfComplex(LV, SourceLocation()));
- break;
- case TEK_Aggregate:
- InitRVal = RValue::getAggregate(LV.getAddress());
- break;
- }
- OpaqueValueExpr OVE(SourceLocation(), Ty, VK_RValue);
- CodeGenFunction::OpaqueValueMapping OpaqueMap(CGF, &OVE, InitRVal);
- CGF.EmitAnyExprToMem(&OVE, Private, Ty.getQualifiers(),
- /*IsInitializer=*/false);
- }
-}
-
-/// \brief Emit initialization of arrays of complex types.
-/// \param DestAddr Address of the array.
-/// \param Type Type of array.
-/// \param Init Initial expression of array.
-/// \param SrcAddr Address of the original array.
-static void EmitOMPAggregateInit(CodeGenFunction &CGF, Address DestAddr,
- QualType Type, const Expr *Init,
- Address SrcAddr = Address::invalid()) {
- auto *DRD = getReductionInit(Init);
- // Perform element-by-element initialization.
- QualType ElementTy;
-
- // Drill down to the base element type on both arrays.
- auto ArrayTy = Type->getAsArrayTypeUnsafe();
- auto NumElements = CGF.emitArrayLength(ArrayTy, ElementTy, DestAddr);
- DestAddr =
- CGF.Builder.CreateElementBitCast(DestAddr, DestAddr.getElementType());
- if (DRD)
- SrcAddr =
- CGF.Builder.CreateElementBitCast(SrcAddr, DestAddr.getElementType());
-
- llvm::Value *SrcBegin = nullptr;
- if (DRD)
- SrcBegin = SrcAddr.getPointer();
- auto DestBegin = DestAddr.getPointer();
- // Cast from pointer to array type to pointer to single element.
- auto DestEnd = CGF.Builder.CreateGEP(DestBegin, NumElements);
- // The basic structure here is a while-do loop.
- auto BodyBB = CGF.createBasicBlock("omp.arrayinit.body");
- auto DoneBB = CGF.createBasicBlock("omp.arrayinit.done");
- auto IsEmpty =
- CGF.Builder.CreateICmpEQ(DestBegin, DestEnd, "omp.arrayinit.isempty");
- CGF.Builder.CreateCondBr(IsEmpty, DoneBB, BodyBB);
-
- // Enter the loop body, making that address the current address.
- auto EntryBB = CGF.Builder.GetInsertBlock();
- CGF.EmitBlock(BodyBB);
-
- CharUnits ElementSize = CGF.getContext().getTypeSizeInChars(ElementTy);
-
- llvm::PHINode *SrcElementPHI = nullptr;
- Address SrcElementCurrent = Address::invalid();
- if (DRD) {
- SrcElementPHI = CGF.Builder.CreatePHI(SrcBegin->getType(), 2,
- "omp.arraycpy.srcElementPast");
- SrcElementPHI->addIncoming(SrcBegin, EntryBB);
- SrcElementCurrent =
- Address(SrcElementPHI,
- SrcAddr.getAlignment().alignmentOfArrayElement(ElementSize));
- }
- llvm::PHINode *DestElementPHI = CGF.Builder.CreatePHI(
- DestBegin->getType(), 2, "omp.arraycpy.destElementPast");
- DestElementPHI->addIncoming(DestBegin, EntryBB);
- Address DestElementCurrent =
- Address(DestElementPHI,
- DestAddr.getAlignment().alignmentOfArrayElement(ElementSize));
-
- // Emit copy.
- {
- CodeGenFunction::RunCleanupsScope InitScope(CGF);
- if (DRD && (DRD->getInitializer() || !Init)) {
- emitInitWithReductionInitializer(CGF, DRD, Init, DestElementCurrent,
- SrcElementCurrent, ElementTy);
- } else
- CGF.EmitAnyExprToMem(Init, DestElementCurrent, ElementTy.getQualifiers(),
- /*IsInitializer=*/false);
- }
-
- if (DRD) {
- // Shift the address forward by one element.
- auto SrcElementNext = CGF.Builder.CreateConstGEP1_32(
- SrcElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
- SrcElementPHI->addIncoming(SrcElementNext, CGF.Builder.GetInsertBlock());
- }
-
- // Shift the address forward by one element.
- auto DestElementNext = CGF.Builder.CreateConstGEP1_32(
- DestElementPHI, /*Idx0=*/1, "omp.arraycpy.dest.element");
- // Check whether we've reached the end.
- auto Done =
- CGF.Builder.CreateICmpEQ(DestElementNext, DestEnd, "omp.arraycpy.done");
- CGF.Builder.CreateCondBr(Done, DoneBB, BodyBB);
- DestElementPHI->addIncoming(DestElementNext, CGF.Builder.GetInsertBlock());
-
- // Done.
- CGF.EmitBlock(DoneBB, /*IsFinished=*/true);
-}
-
void CodeGenFunction::EmitOMPCopy(QualType OriginalType, Address DestAddr,
Address SrcAddr, const VarDecl *DestVD,
const VarDecl *SrcVD, const Expr *Copy) {
@@ -1051,253 +901,106 @@ void CodeGenFunction::EmitOMPLastprivateClauseFinal(
EmitBlock(DoneBB, /*IsFinished=*/true);
}
-static Address castToBase(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
- LValue BaseLV, llvm::Value *Addr) {
- Address Tmp = Address::invalid();
- Address TopTmp = Address::invalid();
- Address MostTopTmp = Address::invalid();
- BaseTy = BaseTy.getNonReferenceType();
- while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
- !CGF.getContext().hasSameType(BaseTy, ElTy)) {
- Tmp = CGF.CreateMemTemp(BaseTy);
- if (TopTmp.isValid())
- CGF.Builder.CreateStore(Tmp.getPointer(), TopTmp);
- else
- MostTopTmp = Tmp;
- TopTmp = Tmp;
- BaseTy = BaseTy->getPointeeType();
- }
- llvm::Type *Ty = BaseLV.getPointer()->getType();
- if (Tmp.isValid())
- Ty = Tmp.getElementType();
- Addr = CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(Addr, Ty);
- if (Tmp.isValid()) {
- CGF.Builder.CreateStore(Addr, Tmp);
- return MostTopTmp;
- }
- return Address(Addr, BaseLV.getAlignment());
-}
-
-static LValue loadToBegin(CodeGenFunction &CGF, QualType BaseTy, QualType ElTy,
- LValue BaseLV) {
- BaseTy = BaseTy.getNonReferenceType();
- while ((BaseTy->isPointerType() || BaseTy->isReferenceType()) &&
- !CGF.getContext().hasSameType(BaseTy, ElTy)) {
- if (auto *PtrTy = BaseTy->getAs<PointerType>())
- BaseLV = CGF.EmitLoadOfPointerLValue(BaseLV.getAddress(), PtrTy);
- else {
- BaseLV = CGF.EmitLoadOfReferenceLValue(BaseLV.getAddress(),
- BaseTy->castAs<ReferenceType>());
- }
- BaseTy = BaseTy->getPointeeType();
- }
- return CGF.MakeAddrLValue(
- Address(
- CGF.Builder.CreatePointerBitCastOrAddrSpaceCast(
- BaseLV.getPointer(), CGF.ConvertTypeForMem(ElTy)->getPointerTo()),
- BaseLV.getAlignment()),
- BaseLV.getType(), BaseLV.getBaseInfo());
-}
-
void CodeGenFunction::EmitOMPReductionClauseInit(
const OMPExecutableDirective &D,
CodeGenFunction::OMPPrivateScope &PrivateScope) {
if (!HaveInsertPoint())
return;
+ SmallVector<const Expr *, 4> Shareds;
+ SmallVector<const Expr *, 4> Privates;
+ SmallVector<const Expr *, 4> ReductionOps;
+ SmallVector<const Expr *, 4> LHSs;
+ SmallVector<const Expr *, 4> RHSs;
for (const auto *C : D.getClausesOfKind<OMPReductionClause>()) {
- auto ILHS = C->lhs_exprs().begin();
- auto IRHS = C->rhs_exprs().begin();
auto IPriv = C->privates().begin();
auto IRed = C->reduction_ops().begin();
- for (auto IRef : C->varlists()) {
- auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
- auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
- auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
- auto *DRD = getReductionInit(*IRed);
- if (auto *OASE = dyn_cast<OMPArraySectionExpr>(IRef)) {
- auto *Base = OASE->getBase()->IgnoreParenImpCasts();
- while (auto *TempOASE = dyn_cast<OMPArraySectionExpr>(Base))
- Base = TempOASE->getBase()->IgnoreParenImpCasts();
- while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
- Base = TempASE->getBase()->IgnoreParenImpCasts();
- auto *DE = cast<DeclRefExpr>(Base);
- auto *OrigVD = cast<VarDecl>(DE->getDecl());
- auto OASELValueLB = EmitOMPArraySectionExpr(OASE);
- auto OASELValueUB =
- EmitOMPArraySectionExpr(OASE, /*IsLowerBound=*/false);
- auto OriginalBaseLValue = EmitLValue(DE);
- LValue BaseLValue =
- loadToBegin(*this, OrigVD->getType(), OASELValueLB.getType(),
- OriginalBaseLValue);
- // Store the address of the original variable associated with the LHS
- // implicit variable.
- PrivateScope.addPrivate(LHSVD, [OASELValueLB]() -> Address {
- return OASELValueLB.getAddress();
- });
- // Emit reduction copy.
- bool IsRegistered = PrivateScope.addPrivate(
- OrigVD, [this, OrigVD, PrivateVD, BaseLValue, OASELValueLB,
- OASELValueUB, OriginalBaseLValue, DRD, IRed]() -> Address {
- // Emit VarDecl with copy init for arrays.
- // Get the address of the original variable captured in current
- // captured region.
- auto *Size = Builder.CreatePtrDiff(OASELValueUB.getPointer(),
- OASELValueLB.getPointer());
- Size = Builder.CreateNUWAdd(
- Size, llvm::ConstantInt::get(Size->getType(), /*V=*/1));
- CodeGenFunction::OpaqueValueMapping OpaqueMap(
- *this, cast<OpaqueValueExpr>(
- getContext()
- .getAsVariableArrayType(PrivateVD->getType())
- ->getSizeExpr()),
- RValue::get(Size));
- EmitVariablyModifiedType(PrivateVD->getType());
- auto Emission = EmitAutoVarAlloca(*PrivateVD);
- auto Addr = Emission.getAllocatedAddress();
- auto *Init = PrivateVD->getInit();
- EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),
- DRD ? *IRed : Init,
- OASELValueLB.getAddress());
- EmitAutoVarCleanups(Emission);
- // Emit private VarDecl with reduction init.
- auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
- OASELValueLB.getPointer());
- auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
- return castToBase(*this, OrigVD->getType(),
- OASELValueLB.getType(), OriginalBaseLValue,
- Ptr);
- });
- assert(IsRegistered && "private var already registered as private");
- // Silence the warning about unused variable.
- (void)IsRegistered;
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
- return GetAddrOfLocalVar(PrivateVD);
- });
- } else if (auto *ASE = dyn_cast<ArraySubscriptExpr>(IRef)) {
- auto *Base = ASE->getBase()->IgnoreParenImpCasts();
- while (auto *TempASE = dyn_cast<ArraySubscriptExpr>(Base))
- Base = TempASE->getBase()->IgnoreParenImpCasts();
- auto *DE = cast<DeclRefExpr>(Base);
- auto *OrigVD = cast<VarDecl>(DE->getDecl());
- auto ASELValue = EmitLValue(ASE);
- auto OriginalBaseLValue = EmitLValue(DE);
- LValue BaseLValue = loadToBegin(
- *this, OrigVD->getType(), ASELValue.getType(), OriginalBaseLValue);
- // Store the address of the original variable associated with the LHS
- // implicit variable.
- PrivateScope.addPrivate(
- LHSVD, [ASELValue]() -> Address { return ASELValue.getAddress(); });
- // Emit reduction copy.
- bool IsRegistered = PrivateScope.addPrivate(
- OrigVD, [this, OrigVD, PrivateVD, BaseLValue, ASELValue,
- OriginalBaseLValue, DRD, IRed]() -> Address {
- // Emit private VarDecl with reduction init.
- AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
- auto Addr = Emission.getAllocatedAddress();
- if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
- emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,
- ASELValue.getAddress(),
- ASELValue.getType());
- } else
- EmitAutoVarInit(Emission);
- EmitAutoVarCleanups(Emission);
- auto *Offset = Builder.CreatePtrDiff(BaseLValue.getPointer(),
- ASELValue.getPointer());
- auto *Ptr = Builder.CreateGEP(Addr.getPointer(), Offset);
- return castToBase(*this, OrigVD->getType(), ASELValue.getType(),
- OriginalBaseLValue, Ptr);
- });
- assert(IsRegistered && "private var already registered as private");
- // Silence the warning about unused variable.
- (void)IsRegistered;
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {
- return Builder.CreateElementBitCast(
- GetAddrOfLocalVar(PrivateVD), ConvertTypeForMem(RHSVD->getType()),
- "rhs.begin");
- });
- } else {
- auto *OrigVD = cast<VarDecl>(cast<DeclRefExpr>(IRef)->getDecl());
- QualType Type = PrivateVD->getType();
- if (getContext().getAsArrayType(Type)) {
- // Store the address of the original variable associated with the LHS
- // implicit variable.
- DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
- CapturedStmtInfo->lookup(OrigVD) != nullptr,
- IRef->getType(), VK_LValue, IRef->getExprLoc());
- Address OriginalAddr = EmitLValue(&DRE).getAddress();
- PrivateScope.addPrivate(LHSVD, [this, &OriginalAddr,
- LHSVD]() -> Address {
- OriginalAddr = Builder.CreateElementBitCast(
- OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
- return OriginalAddr;
- });
- bool IsRegistered = PrivateScope.addPrivate(OrigVD, [&]() -> Address {
- if (Type->isVariablyModifiedType()) {
- CodeGenFunction::OpaqueValueMapping OpaqueMap(
- *this, cast<OpaqueValueExpr>(
- getContext()
- .getAsVariableArrayType(PrivateVD->getType())
- ->getSizeExpr()),
- RValue::get(
- getTypeSize(OrigVD->getType().getNonReferenceType())));
- EmitVariablyModifiedType(Type);
- }
- auto Emission = EmitAutoVarAlloca(*PrivateVD);
- auto Addr = Emission.getAllocatedAddress();
- auto *Init = PrivateVD->getInit();
- EmitOMPAggregateInit(*this, Addr, PrivateVD->getType(),
- DRD ? *IRed : Init, OriginalAddr);
- EmitAutoVarCleanups(Emission);
- return Emission.getAllocatedAddress();
- });
- assert(IsRegistered && "private var already registered as private");
- // Silence the warning about unused variable.
- (void)IsRegistered;
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {
- return Builder.CreateElementBitCast(
- GetAddrOfLocalVar(PrivateVD),
- ConvertTypeForMem(RHSVD->getType()), "rhs.begin");
- });
- } else {
- // Store the address of the original variable associated with the LHS
- // implicit variable.
- Address OriginalAddr = Address::invalid();
- PrivateScope.addPrivate(LHSVD, [this, OrigVD, IRef,
- &OriginalAddr]() -> Address {
- DeclRefExpr DRE(const_cast<VarDecl *>(OrigVD),
- CapturedStmtInfo->lookup(OrigVD) != nullptr,
- IRef->getType(), VK_LValue, IRef->getExprLoc());
- OriginalAddr = EmitLValue(&DRE).getAddress();
- return OriginalAddr;
- });
- // Emit reduction copy.
- bool IsRegistered = PrivateScope.addPrivate(
- OrigVD, [this, PrivateVD, OriginalAddr, DRD, IRed]() -> Address {
- // Emit private VarDecl with reduction init.
- AutoVarEmission Emission = EmitAutoVarAlloca(*PrivateVD);
- auto Addr = Emission.getAllocatedAddress();
- if (DRD && (DRD->getInitializer() || !PrivateVD->hasInit())) {
- emitInitWithReductionInitializer(*this, DRD, *IRed, Addr,
- OriginalAddr,
- PrivateVD->getType());
- } else
- EmitAutoVarInit(Emission);
- EmitAutoVarCleanups(Emission);
- return Addr;
- });
- assert(IsRegistered && "private var already registered as private");
- // Silence the warning about unused variable.
- (void)IsRegistered;
- PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
- return GetAddrOfLocalVar(PrivateVD);
- });
- }
+ auto ILHS = C->lhs_exprs().begin();
+ auto IRHS = C->rhs_exprs().begin();
+ for (const auto *Ref : C->varlists()) {
+ Shareds.emplace_back(Ref);
+ Privates.emplace_back(*IPriv);
+ ReductionOps.emplace_back(*IRed);
+ LHSs.emplace_back(*ILHS);
+ RHSs.emplace_back(*IRHS);
+ std::advance(IPriv, 1);
+ std::advance(IRed, 1);
+ std::advance(ILHS, 1);
+ std::advance(IRHS, 1);
+ }
+ }
+ ReductionCodeGen RedCG(Shareds, Privates, ReductionOps);
+ unsigned Count = 0;
+ auto ILHS = LHSs.begin();
+ auto IRHS = RHSs.begin();
+ auto IPriv = Privates.begin();
+ for (const auto *IRef : Shareds) {
+ auto *PrivateVD = cast<VarDecl>(cast<DeclRefExpr>(*IPriv)->getDecl());
+ // Emit private VarDecl with reduction init.
+ RedCG.emitSharedLValue(*this, Count);
+ RedCG.emitAggregateType(*this, Count);
+ auto Emission = EmitAutoVarAlloca(*PrivateVD);
+ RedCG.emitInitialization(*this, Count, Emission.getAllocatedAddress(),
+ RedCG.getSharedLValue(Count),
+ [&Emission](CodeGenFunction &CGF) {
+ CGF.EmitAutoVarInit(Emission);
+ return true;
+ });
+ EmitAutoVarCleanups(Emission);
+ Address BaseAddr = RedCG.adjustPrivateAddress(
+ *this, Count, Emission.getAllocatedAddress());
+ bool IsRegistered = PrivateScope.addPrivate(
+ RedCG.getBaseDecl(Count), [BaseAddr]() -> Address { return BaseAddr; });
+ assert(IsRegistered && "private var already registered as private");
+ // Silence the warning about unused variable.
+ (void)IsRegistered;
+
+ auto *LHSVD = cast<VarDecl>(cast<DeclRefExpr>(*ILHS)->getDecl());
+ auto *RHSVD = cast<VarDecl>(cast<DeclRefExpr>(*IRHS)->getDecl());
+ if (isa<OMPArraySectionExpr>(IRef)) {
+ // Store the address of the original variable associated with the LHS
+ // implicit variable.
+ PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() -> Address {
+ return RedCG.getSharedLValue(Count).getAddress();
+ });
+ PrivateScope.addPrivate(RHSVD, [this, PrivateVD]() -> Address {
+ return GetAddrOfLocalVar(PrivateVD);
+ });
+ } else if (isa<ArraySubscriptExpr>(IRef)) {
+ // Store the address of the original variable associated with the LHS
+ // implicit variable.
+ PrivateScope.addPrivate(LHSVD, [&RedCG, Count]() -> Address {
+ return RedCG.getSharedLValue(Count).getAddress();
+ });
+ PrivateScope.addPrivate(RHSVD, [this, PrivateVD, RHSVD]() -> Address {
+ return Builder.CreateElementBitCast(GetAddrOfLocalVar(PrivateVD),
+ ConvertTypeForMem(RHSVD->getType()),
+ "rhs.begin");
+ });
+ } else {
+ QualType Type = PrivateVD->getType();
+ bool IsArray = getContext().getAsArrayType(Type) != nullptr;
+ Address OriginalAddr = RedCG.getSharedLValue(Count).getAddress();
+ // Store the address of the original variable associated with the LHS
+ // implicit variable.
+ if (IsArray) {
+ OriginalAddr = Builder.CreateElementBitCast(
+ OriginalAddr, ConvertTypeForMem(LHSVD->getType()), "lhs.begin");
}
- ++ILHS;
- ++IRHS;
- ++IPriv;
- ++IRed;
+ PrivateScope.addPrivate(
+ LHSVD, [OriginalAddr]() -> Address { return OriginalAddr; });
+ PrivateScope.addPrivate(
+ RHSVD, [this, PrivateVD, RHSVD, IsArray]() -> Address {
+ return IsArray
+ ? Builder.CreateElementBitCast(
+ GetAddrOfLocalVar(PrivateVD),
+ ConvertTypeForMem(RHSVD->getType()), "rhs.begin")
+ : GetAddrOfLocalVar(PrivateVD);
+ });
}
+ ++ILHS;
+ ++IRHS;
+ ++IPriv;
+ ++Count;
}
}
@@ -2994,11 +2697,32 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
++ID;
}
}
+ SmallVector<const Expr *, 4> LHSs;
+ SmallVector<const Expr *, 4> RHSs;
+ for (const auto *C : S.getClausesOfKind<OMPReductionClause>()) {
+ auto IPriv = C->privates().begin();
+ auto IRed = C->reduction_ops().begin();
+ auto ILHS = C->lhs_exprs().begin();
+ auto IRHS = C->rhs_exprs().begin();
+ for (const auto *Ref : C->varlists()) {
+ Data.ReductionVars.emplace_back(Ref);
+ Data.ReductionCopies.emplace_back(*IPriv);
+ Data.ReductionOps.emplace_back(*IRed);
+ LHSs.emplace_back(*ILHS);
+ RHSs.emplace_back(*IRHS);
+ std::advance(IPriv, 1);
+ std::advance(IRed, 1);
+ std::advance(ILHS, 1);
+ std::advance(IRHS, 1);
+ }
+ }
+ Data.Reductions = CGM.getOpenMPRuntime().emitTaskReductionInit(
+ *this, S.getLocStart(), LHSs, RHSs, Data);
// Build list of dependences.
for (const auto *C : S.getClausesOfKind<OMPDependClause>())
for (auto *IRef : C->varlists())
Data.Dependences.push_back(std::make_pair(C->getDependencyKind(), IRef));
- auto &&CodeGen = [&Data, CS, &BodyGen, &LastprivateDstsOrigs](
+ auto &&CodeGen = [&Data, &S, CS, &BodyGen, &LastprivateDstsOrigs](
CodeGenFunction &CGF, PrePostActionTy &Action) {
// Set proper addresses for generated private copies.
OMPPrivateScope Scope(CGF);
@@ -3053,6 +2777,34 @@ void CodeGenFunction::EmitOMPTaskBasedDirective(const OMPExecutableDirective &S,
Scope.addPrivate(Pair.first, [Replacement]() { return Replacement; });
}
}
+ if (Data.Reductions) {
+ OMPLexicalScope LexScope(CGF, S, /*AsInlined=*/true);
+ ReductionCodeGen RedCG(Data.ReductionVars, Data.ReductionCopies,
+ Data.ReductionOps);
+ llvm::Value *ReductionsPtr = CGF.Builder.CreateLoad(
+ CGF.GetAddrOfLocalVar(CS->getCapturedDecl()->getParam(9)));
+ for (unsigned Cnt = 0, E = Data.ReductionVars.size(); Cnt < E; ++Cnt) {
+ RedCG.emitSharedLValue(CGF, Cnt);
+ RedCG.emitAggregateType(CGF, Cnt);
+ Address Replacement = CGF.CGM.getOpenMPRuntime().getTaskReductionItem(
+ CGF, S.getLocStart(), ReductionsPtr, RedCG.getSharedLValue(Cnt));
+ Replacement =
+ Address(CGF.EmitScalarConversion(
+ Replacement.getPointer(), CGF.getContext().VoidPtrTy,
+ CGF.getContext().getPointerType(
+ Data.ReductionCopies[Cnt]->getType()),
+ SourceLocation()),
+ Replacement.getAlignment());
+ Replacement = RedCG.adjustPrivateAddress(CGF, Cnt, Replacement);
+ Scope.addPrivate(RedCG.getBaseDecl(Cnt),
+ [Replacement]() { return Replacement; });
+ // FIXME: This must removed once the runtime library is fixed.
+ // Emit required threadprivate variables for
+ // initilizer/combiner/finalizer.
+ CGF.CGM.getOpenMPRuntime().emitTaskReductionFixups(CGF, S.getLocStart(),
+ RedCG, Cnt);
+ }
+ }
(void)Scope.Privatize();
Action.Enter(CGF);
@@ -3714,6 +3466,7 @@ static void EmitOMPAtomicExpr(CodeGenFunction &CGF, OpenMPClauseKind Kind,
case OMPC_firstprivate:
case OMPC_lastprivate:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_safelen:
case OMPC_simdlen:
case OMPC_collapse:
diff --git a/lib/CodeGen/CodeGenFunction.h b/lib/CodeGen/CodeGenFunction.h
index 5933e029be8d..753dd92f3071 100644
--- a/lib/CodeGen/CodeGenFunction.h
+++ b/lib/CodeGen/CodeGenFunction.h
@@ -3589,12 +3589,19 @@ public:
/// nonnull, if \p LHS is marked _Nonnull.
void EmitNullabilityCheck(LValue LHS, llvm::Value *RHS, SourceLocation Loc);
+ /// An enumeration which makes it easier to specify whether or not an
+ /// operation is a subtraction.
+ enum { NotSubtraction = false, IsSubtraction = true };
+
/// Same as IRBuilder::CreateInBoundsGEP, but additionally emits a check to
/// detect undefined behavior when the pointer overflow sanitizer is enabled.
/// \p SignedIndices indicates whether any of the GEP indices are signed.
+ /// \p IsSubtraction indicates whether the expression used to form the GEP
+ /// is a subtraction.
llvm::Value *EmitCheckedInBoundsGEP(llvm::Value *Ptr,
ArrayRef<llvm::Value *> IdxList,
bool SignedIndices,
+ bool IsSubtraction,
SourceLocation Loc,
const Twine &Name = "");
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index 4b15b8ac4c71..5561d4520cc8 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -4499,18 +4499,19 @@ void CodeGenModule::getFunctionFeatureMap(llvm::StringMap<bool> &FeatureMap,
// Make a copy of the features as passed on the command line into the
// beginning of the additional features from the function to override.
- ParsedAttr.first.insert(ParsedAttr.first.begin(),
+ ParsedAttr.Features.insert(ParsedAttr.Features.begin(),
Target.getTargetOpts().FeaturesAsWritten.begin(),
Target.getTargetOpts().FeaturesAsWritten.end());
- if (ParsedAttr.second != "")
- TargetCPU = ParsedAttr.second;
+ if (ParsedAttr.Architecture != "")
+ TargetCPU = ParsedAttr.Architecture ;
// Now populate the feature map, first with the TargetCPU which is either
// the default or a new one from the target attribute string. Then we'll use
// the passed in features (FeaturesAsWritten) along with the new ones from
// the attribute.
- Target.initFeatureMap(FeatureMap, getDiags(), TargetCPU, ParsedAttr.first);
+ Target.initFeatureMap(FeatureMap, getDiags(), TargetCPU,
+ ParsedAttr.Features);
} else {
Target.initFeatureMap(FeatureMap, getDiags(), TargetCPU,
Target.getTargetOpts().Features);
diff --git a/lib/CodeGen/MacroPPCallbacks.cpp b/lib/CodeGen/MacroPPCallbacks.cpp
index 6a31dfe53d64..a6f21d8ddcfb 100644
--- a/lib/CodeGen/MacroPPCallbacks.cpp
+++ b/lib/CodeGen/MacroPPCallbacks.cpp
@@ -26,8 +26,8 @@ void MacroPPCallbacks::writeMacroDefinition(const IdentifierInfo &II,
if (MI.isFunctionLike()) {
Name << '(';
- if (!MI.arg_empty()) {
- MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
+ if (!MI.param_empty()) {
+ MacroInfo::param_iterator AI = MI.param_begin(), E = MI.param_end();
for (; AI + 1 != E; ++AI) {
Name << (*AI)->getName();
Name << ',';
diff --git a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
index 37ecc05aa1ee..d0760b9cc2a6 100644
--- a/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
+++ b/lib/CodeGen/ObjectFilePCHContainerOperations.cpp
@@ -152,6 +152,9 @@ public:
CodeGenOpts.CodeModel = "default";
CodeGenOpts.ThreadModel = "single";
CodeGenOpts.DebugTypeExtRefs = true;
+ // When building a module MainFileName is the name of the modulemap file.
+ CodeGenOpts.MainFileName =
+ LangOpts.CurrentModule.empty() ? MainFileName : LangOpts.CurrentModule;
CodeGenOpts.setDebugInfo(codegenoptions::FullDebugInfo);
CodeGenOpts.setDebuggerTuning(CI.getCodeGenOpts().getDebuggerTuning());
}
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index eeebd60a2d20..c17828974e92 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -4785,7 +4785,8 @@ class AArch64ABIInfo : public SwiftABIInfo {
public:
enum ABIKind {
AAPCS = 0,
- DarwinPCS
+ DarwinPCS,
+ Win64
};
private:
@@ -4823,10 +4824,14 @@ private:
Address EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
QualType Ty) const override {
- return isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF)
- : EmitAAPCSVAArg(VAListAddr, Ty, CGF);
+ return Kind == Win64 ? EmitMSVAArg(CGF, VAListAddr, Ty)
+ : isDarwinPCS() ? EmitDarwinVAArg(VAListAddr, Ty, CGF)
+ : EmitAAPCSVAArg(VAListAddr, Ty, CGF);
}
+ Address EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
+ QualType Ty) const override;
+
bool shouldPassIndirectlyForSwift(CharUnits totalSize,
ArrayRef<llvm::Type*> scalars,
bool asReturnValue) const override {
@@ -5332,6 +5337,14 @@ Address AArch64ABIInfo::EmitDarwinVAArg(Address VAListAddr, QualType Ty,
TyInfo, SlotSize, /*AllowHigherAlign*/ true);
}
+Address AArch64ABIInfo::EmitMSVAArg(CodeGenFunction &CGF, Address VAListAddr,
+ QualType Ty) const {
+ return emitVoidPtrVAArg(CGF, VAListAddr, Ty, /*indirect*/ false,
+ CGF.getContext().getTypeInfoInChars(Ty),
+ CharUnits::fromQuantity(8),
+ /*allowHigherAlign*/ false);
+}
+
//===----------------------------------------------------------------------===//
// ARM ABI Implementation
//===----------------------------------------------------------------------===//
@@ -8494,6 +8507,8 @@ const TargetCodeGenInfo &CodeGenModule::getTargetCodeGenInfo() {
AArch64ABIInfo::ABIKind Kind = AArch64ABIInfo::AAPCS;
if (getTarget().getABI() == "darwinpcs")
Kind = AArch64ABIInfo::DarwinPCS;
+ else if (Triple.isOSWindows())
+ Kind = AArch64ABIInfo::Win64;
return SetCGInfo(new AArch64TargetCodeGenInfo(Types, Kind));
}
diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp
index 42478013ccec..1d35d6e78cca 100644
--- a/lib/Driver/Driver.cpp
+++ b/lib/Driver/Driver.cpp
@@ -1275,6 +1275,13 @@ bool Driver::HandleImmediateArgs(const Compilation &C) {
// we were requested to print out all option names that start with "-foo".
// For example, "--autocomplete=-fsyn" is expanded to "-fsyntax-only".
SuggestedCompletions = Opts->findByPrefix(PassedFlags, DisableFlags);
+
+ // We have to query the -W flags manually as they're not in the OptTable.
+ // TODO: Find a good way to add them to OptTable instead and them remove
+ // this code.
+ for (StringRef S : DiagnosticIDs::getDiagnosticFlags())
+ if (S.startswith(PassedFlags))
+ SuggestedCompletions.push_back(S);
} else {
// If the flag is in the form of "--autocomplete=foo,bar", we were
// requested to print out all option values for "-foo" that start with
diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp
index e759e3ec619a..b82cc2d4fa5d 100644
--- a/lib/Driver/ToolChains/Clang.cpp
+++ b/lib/Driver/ToolChains/Clang.cpp
@@ -2070,10 +2070,11 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
if (D.isUsingLTO()) {
Args.AddLastArg(CmdArgs, options::OPT_flto, options::OPT_flto_EQ);
- // The Darwin linker currently uses the legacy LTO API, which does not
- // support LTO unit features (CFI, whole program vtable opt) under
- // ThinLTO.
- if (!getToolChain().getTriple().isOSDarwin() ||
+ // The Darwin and PS4 linkers currently use the legacy LTO API, which
+ // does not support LTO unit features (CFI, whole program vtable opt)
+ // under ThinLTO.
+ if (!(getToolChain().getTriple().isOSDarwin() ||
+ getToolChain().getTriple().isPS4()) ||
D.getLTOMode() == LTOK_Full)
CmdArgs.push_back("-flto-unit");
}
@@ -3200,9 +3201,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA,
Args.AddLastArg(CmdArgs, options::OPT_femit_all_decls);
Args.AddLastArg(CmdArgs, options::OPT_fheinous_gnu_extensions);
Args.AddLastArg(CmdArgs, options::OPT_fno_operator_names);
- // Emulated TLS is enabled by default on Android, and can be enabled manually
- // with -femulated-tls.
- bool EmulatedTLSDefault = Triple.isAndroid() || Triple.isWindowsCygwinEnvironment();
+ // Emulated TLS is enabled by default on Android and OpenBSD, and can be enabled
+ // manually with -femulated-tls.
+ bool EmulatedTLSDefault = Triple.isAndroid() || Triple.isOSOpenBSD() ||
+ Triple.isWindowsCygwinEnvironment();
if (Args.hasFlag(options::OPT_femulated_tls, options::OPT_fno_emulated_tls,
EmulatedTLSDefault))
CmdArgs.push_back("-femulated-tls");
diff --git a/lib/Driver/ToolChains/Darwin.cpp b/lib/Driver/ToolChains/Darwin.cpp
index ba1a5ee95594..0d63858f2cd4 100644
--- a/lib/Driver/ToolChains/Darwin.cpp
+++ b/lib/Driver/ToolChains/Darwin.cpp
@@ -1262,28 +1262,58 @@ void Darwin::AddDeploymentTarget(DerivedArgList &Args) const {
}
}
- // If no OSX or iOS target has been specified, try to guess platform
- // from arch name and compute the version from the triple.
+ // If no OS targets have been specified, try to guess platform from -target
+ // or arch name and compute the version from the triple.
if (OSXTarget.empty() && iOSTarget.empty() && TvOSTarget.empty() &&
WatchOSTarget.empty()) {
- StringRef MachOArchName = getMachOArchName(Args);
- unsigned Major, Minor, Micro;
- if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
- MachOArchName == "arm64") {
- getTriple().getiOSVersion(Major, Minor, Micro);
- llvm::raw_string_ostream(iOSTarget) << Major << '.' << Minor << '.'
- << Micro;
- } else if (MachOArchName == "armv7k") {
- getTriple().getWatchOSVersion(Major, Minor, Micro);
- llvm::raw_string_ostream(WatchOSTarget) << Major << '.' << Minor << '.'
- << Micro;
- } else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
- MachOArchName != "armv7em") {
- if (!getTriple().getMacOSXVersion(Major, Minor, Micro)) {
- getDriver().Diag(diag::err_drv_invalid_darwin_version)
- << getTriple().getOSName();
+ llvm::Triple::OSType OSTy = llvm::Triple::UnknownOS;
+
+ // Set the OSTy based on -target if -arch isn't present.
+ if (Args.hasArg(options::OPT_target) && !Args.hasArg(options::OPT_arch)) {
+ OSTy = getTriple().getOS();
+ } else {
+ StringRef MachOArchName = getMachOArchName(Args);
+ if (MachOArchName == "armv7" || MachOArchName == "armv7s" ||
+ MachOArchName == "arm64")
+ OSTy = llvm::Triple::IOS;
+ else if (MachOArchName == "armv7k")
+ OSTy = llvm::Triple::WatchOS;
+ else if (MachOArchName != "armv6m" && MachOArchName != "armv7m" &&
+ MachOArchName != "armv7em")
+ OSTy = llvm::Triple::MacOSX;
+ }
+
+
+ if (OSTy != llvm::Triple::UnknownOS) {
+ unsigned Major, Minor, Micro;
+ std::string *OSTarget;
+
+ switch (OSTy) {
+ case llvm::Triple::Darwin:
+ case llvm::Triple::MacOSX:
+ if (!getTriple().getMacOSXVersion(Major, Minor, Micro))
+ getDriver().Diag(diag::err_drv_invalid_darwin_version)
+ << getTriple().getOSName();
+ OSTarget = &OSXTarget;
+ break;
+ case llvm::Triple::IOS:
+ getTriple().getiOSVersion(Major, Minor, Micro);
+ OSTarget = &iOSTarget;
+ break;
+ case llvm::Triple::TvOS:
+ getTriple().getOSVersion(Major, Minor, Micro);
+ OSTarget = &TvOSTarget;
+ break;
+ case llvm::Triple::WatchOS:
+ getTriple().getWatchOSVersion(Major, Minor, Micro);
+ OSTarget = &WatchOSTarget;
+ break;
+ default:
+ llvm_unreachable("Unexpected OS type");
+ break;
}
- llvm::raw_string_ostream(OSXTarget) << Major << '.' << Minor << '.'
+
+ llvm::raw_string_ostream(*OSTarget) << Major << '.' << Minor << '.'
<< Micro;
}
}
diff --git a/lib/Driver/ToolChains/Fuchsia.cpp b/lib/Driver/ToolChains/Fuchsia.cpp
index d8b8fe8f0bfe..78053aafd16e 100644
--- a/lib/Driver/ToolChains/Fuchsia.cpp
+++ b/lib/Driver/ToolChains/Fuchsia.cpp
@@ -46,6 +46,9 @@ void fuchsia::Linker::ConstructJob(Compilation &C, const JobAction &JA,
if (llvm::sys::path::stem(Exec).equals_lower("lld")) {
CmdArgs.push_back("-flavor");
CmdArgs.push_back("gnu");
+
+ CmdArgs.push_back("-z");
+ CmdArgs.push_back("rodynamic");
}
if (!D.SysRoot.empty())
diff --git a/lib/Driver/ToolChains/Gnu.cpp b/lib/Driver/ToolChains/Gnu.cpp
index ad5f7df50d2e..bc26ee1de46d 100644
--- a/lib/Driver/ToolChains/Gnu.cpp
+++ b/lib/Driver/ToolChains/Gnu.cpp
@@ -2471,7 +2471,8 @@ void Generic_ELF::addClangTargetOptions(const ArgList &DriverArgs,
(!V.isOlderThan(4, 7, 0) || getTriple().isAndroid())) ||
getTriple().getOS() == llvm::Triple::NaCl ||
(getTriple().getVendor() == llvm::Triple::MipsTechnologies &&
- !getTriple().hasEnvironment());
+ !getTriple().hasEnvironment()) ||
+ getTriple().getOS() == llvm::Triple::Solaris;
if (DriverArgs.hasFlag(options::OPT_fuse_init_array,
options::OPT_fno_use_init_array, UseInitArrayDefault))
diff --git a/lib/Driver/ToolChains/Solaris.cpp b/lib/Driver/ToolChains/Solaris.cpp
index 78797c49d7b6..de98d11b2dc7 100644
--- a/lib/Driver/ToolChains/Solaris.cpp
+++ b/lib/Driver/ToolChains/Solaris.cpp
@@ -126,7 +126,7 @@ void solaris::Linker::ConstructJob(Compilation &C, const JobAction &JA,
Solaris::Solaris(const Driver &D, const llvm::Triple &Triple,
const ArgList &Args)
- : Generic_GCC(D, Triple, Args) {
+ : Generic_ELF(D, Triple, Args) {
GCCInstallation.init(Triple, Args);
diff --git a/lib/Driver/ToolChains/Solaris.h b/lib/Driver/ToolChains/Solaris.h
index edb44373b31d..787917afab6e 100644
--- a/lib/Driver/ToolChains/Solaris.h
+++ b/lib/Driver/ToolChains/Solaris.h
@@ -50,7 +50,7 @@ public:
namespace toolchains {
-class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_GCC {
+class LLVM_LIBRARY_VISIBILITY Solaris : public Generic_ELF {
public:
Solaris(const Driver &D, const llvm::Triple &Triple,
const llvm::opt::ArgList &Args);
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index c6e90a9175e1..46ea06b880ed 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -1383,7 +1383,8 @@ private:
if (PrevToken->isOneOf(tok::l_paren, tok::l_square, tok::l_brace,
tok::comma, tok::semi, tok::kw_return, tok::colon,
- tok::equal, tok::kw_delete, tok::kw_sizeof) ||
+ tok::equal, tok::kw_delete, tok::kw_sizeof,
+ tok::kw_throw) ||
PrevToken->isOneOf(TT_BinaryOperator, TT_ConditionalExpr,
TT_UnaryOperator, TT_CastRParen))
return TT_UnaryOperator;
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 4b57919d1929..faac5a371c26 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -747,7 +747,7 @@ static bool mustBeJSIdent(const AdditionalKeywords &Keywords,
Keywords.kw_let, Keywords.kw_var, tok::kw_const,
Keywords.kw_abstract, Keywords.kw_extends, Keywords.kw_implements,
Keywords.kw_instanceof, Keywords.kw_interface,
- Keywords.kw_throws));
+ Keywords.kw_throws, Keywords.kw_from));
}
static bool mustBeJSIdentOrValue(const AdditionalKeywords &Keywords,
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 00f6b9b46f03..b2c14554a4b5 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -1683,6 +1683,7 @@ void CompilerInvocation::setLangDefaults(LangOptions &Opts, InputKind IK,
Opts.CPlusPlus11 = Std.isCPlusPlus11();
Opts.CPlusPlus14 = Std.isCPlusPlus14();
Opts.CPlusPlus1z = Std.isCPlusPlus1z();
+ Opts.CPlusPlus2a = Std.isCPlusPlus2a();
Opts.Digraphs = Std.hasDigraphs();
Opts.GNUMode = Std.isGNUMode();
Opts.GNUInline = !Opts.C99 && !Opts.CPlusPlus;
diff --git a/lib/Frontend/InitPreprocessor.cpp b/lib/Frontend/InitPreprocessor.cpp
index 71420df00025..64128dfdf534 100644
--- a/lib/Frontend/InitPreprocessor.cpp
+++ b/lib/Frontend/InitPreprocessor.cpp
@@ -374,10 +374,13 @@ static void InitializeStandardPredefinedMacros(const TargetInfo &TI,
else if (!LangOpts.GNUMode && LangOpts.Digraphs)
Builder.defineMacro("__STDC_VERSION__", "199409L");
} else {
+ // FIXME: Use correct value for C++20.
+ if (LangOpts.CPlusPlus2a)
+ Builder.defineMacro("__cplusplus", "201707L");
// C++17 [cpp.predefined]p1:
// The name __cplusplus is defined to the value 201703L when compiling a
// C++ translation unit.
- if (LangOpts.CPlusPlus1z)
+ else if (LangOpts.CPlusPlus1z)
Builder.defineMacro("__cplusplus", "201703L");
// C++1y [cpp.predefined]p1:
// The name __cplusplus is defined to the value 201402L when compiling a
diff --git a/lib/Frontend/PrintPreprocessedOutput.cpp b/lib/Frontend/PrintPreprocessedOutput.cpp
index 5336de1f7468..914039ad5bb1 100644
--- a/lib/Frontend/PrintPreprocessedOutput.cpp
+++ b/lib/Frontend/PrintPreprocessedOutput.cpp
@@ -38,8 +38,8 @@ static void PrintMacroDefinition(const IdentifierInfo &II, const MacroInfo &MI,
if (MI.isFunctionLike()) {
OS << '(';
- if (!MI.arg_empty()) {
- MacroInfo::arg_iterator AI = MI.arg_begin(), E = MI.arg_end();
+ if (!MI.param_empty()) {
+ MacroInfo::param_iterator AI = MI.param_begin(), E = MI.param_end();
for (; AI+1 != E; ++AI) {
OS << (*AI)->getName();
OS << ',';
diff --git a/lib/Frontend/Rewrite/FrontendActions.cpp b/lib/Frontend/Rewrite/FrontendActions.cpp
index e93f737c47fd..5efa6aeaf760 100644
--- a/lib/Frontend/Rewrite/FrontendActions.cpp
+++ b/lib/Frontend/Rewrite/FrontendActions.cpp
@@ -10,6 +10,7 @@
#include "clang/Rewrite/Frontend/FrontendActions.h"
#include "clang/AST/ASTConsumer.h"
#include "clang/Basic/CharInfo.h"
+#include "clang/Config/config.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/FrontendActions.h"
#include "clang/Frontend/FrontendDiagnostic.h"
diff --git a/lib/Frontend/Rewrite/RewriteModernObjC.cpp b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
index 38be684cec86..21686b8c78ea 100644
--- a/lib/Frontend/Rewrite/RewriteModernObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteModernObjC.cpp
@@ -21,6 +21,7 @@
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
#include "clang/Basic/TargetInfo.h"
+#include "clang/Config/config.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/ADT/DenseSet.h"
diff --git a/lib/Frontend/Rewrite/RewriteObjC.cpp b/lib/Frontend/Rewrite/RewriteObjC.cpp
index 5a1e001d65b8..e0d813df70f8 100644
--- a/lib/Frontend/Rewrite/RewriteObjC.cpp
+++ b/lib/Frontend/Rewrite/RewriteObjC.cpp
@@ -20,6 +20,7 @@
#include "clang/Basic/Diagnostic.h"
#include "clang/Basic/IdentifierTable.h"
#include "clang/Basic/SourceManager.h"
+#include "clang/Config/config.h"
#include "clang/Lex/Lexer.h"
#include "clang/Rewrite/Core/Rewriter.h"
#include "llvm/ADT/DenseSet.h"
diff --git a/lib/FrontendTool/ExecuteCompilerInvocation.cpp b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
index a7c140188b35..166631558806 100644
--- a/lib/FrontendTool/ExecuteCompilerInvocation.cpp
+++ b/lib/FrontendTool/ExecuteCompilerInvocation.cpp
@@ -15,6 +15,7 @@
#include "clang/FrontendTool/Utils.h"
#include "clang/ARCMigrate/ARCMTActions.h"
#include "clang/CodeGen/CodeGenAction.h"
+#include "clang/Config/config.h"
#include "clang/Driver/Options.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Frontend/CompilerInvocation.h"
diff --git a/lib/Headers/vecintrin.h b/lib/Headers/vecintrin.h
index ca7acb4731f9..f7061e88949f 100644
--- a/lib/Headers/vecintrin.h
+++ b/lib/Headers/vecintrin.h
@@ -116,6 +116,13 @@ vec_extract(vector unsigned long long __vec, int __index) {
return __vec[__index & 1];
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai float
+vec_extract(vector float __vec, int __index) {
+ return __vec[__index & 3];
+}
+#endif
+
static inline __ATTRS_o_ai double
vec_extract(vector double __vec, int __index) {
return __vec[__index & 1];
@@ -129,6 +136,7 @@ vec_insert(signed char __scalar, vector signed char __vec, int __index) {
return __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_insert(unsigned char __scalar, vector bool char __vec, int __index) {
vector unsigned char __newvec = (vector unsigned char)__vec;
@@ -148,6 +156,7 @@ vec_insert(signed short __scalar, vector signed short __vec, int __index) {
return __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_insert(unsigned short __scalar, vector bool short __vec, int __index) {
vector unsigned short __newvec = (vector unsigned short)__vec;
@@ -167,6 +176,7 @@ vec_insert(signed int __scalar, vector signed int __vec, int __index) {
return __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_insert(unsigned int __scalar, vector bool int __vec, int __index) {
vector unsigned int __newvec = (vector unsigned int)__vec;
@@ -187,6 +197,7 @@ vec_insert(signed long long __scalar, vector signed long long __vec,
return __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_insert(unsigned long long __scalar, vector bool long long __vec,
int __index) {
@@ -202,6 +213,14 @@ vec_insert(unsigned long long __scalar, vector unsigned long long __vec,
return __vec;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_insert(float __scalar, vector float __vec, int __index) {
+ __vec[__index & 1] = __scalar;
+ return __vec;
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_insert(double __scalar, vector double __vec, int __index) {
__vec[__index & 1] = __scalar;
@@ -282,6 +301,16 @@ vec_promote(unsigned long long __scalar, int __index) {
return __vec;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_promote(float __scalar, int __index) {
+ const vector float __zero = (vector float)0;
+ vector float __vec = __builtin_shufflevector(__zero, __zero, -1, -1, -1, -1);
+ __vec[__index & 3] = __scalar;
+ return __vec;
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_promote(double __scalar, int __index) {
const vector double __zero = (vector double)0;
@@ -348,6 +377,15 @@ vec_insert_and_zero(const unsigned long long *__ptr) {
return __vec;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_insert_and_zero(const float *__ptr) {
+ vector float __vec = (vector float)0;
+ __vec[0] = *__ptr;
+ return __vec;
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_insert_and_zero(const double *__ptr) {
vector double __vec = (vector double)0;
@@ -441,6 +479,15 @@ vec_perm(vector bool long long __a, vector bool long long __b,
(vector unsigned char)__a, (vector unsigned char)__b, __c);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_perm(vector float __a, vector float __b,
+ vector unsigned char __c) {
+ return (vector float)__builtin_s390_vperm(
+ (vector unsigned char)__a, (vector unsigned char)__b, __c);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_perm(vector double __a, vector double __b,
vector unsigned char __c) {
@@ -450,18 +497,22 @@ vec_perm(vector double __a, vector double __b,
/*-- vec_permi --------------------------------------------------------------*/
+// This prototype is deprecated.
extern __ATTRS_o vector signed long long
vec_permi(vector signed long long __a, vector signed long long __b, int __c)
__constant_range(__c, 0, 3);
+// This prototype is deprecated.
extern __ATTRS_o vector unsigned long long
vec_permi(vector unsigned long long __a, vector unsigned long long __b, int __c)
__constant_range(__c, 0, 3);
+// This prototype is deprecated.
extern __ATTRS_o vector bool long long
vec_permi(vector bool long long __a, vector bool long long __b, int __c)
__constant_range(__c, 0, 3);
+// This prototype is deprecated.
extern __ATTRS_o vector double
vec_permi(vector double __a, vector double __b, int __c)
__constant_range(__c, 0, 3);
@@ -471,6 +522,15 @@ vec_permi(vector double __a, vector double __b, int __c)
(vector unsigned long long)(Y), \
(((Z) & 2) << 1) | ((Z) & 1)))
+/*-- vec_bperm_u128 ---------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_ai vector unsigned long long
+vec_bperm_u128(vector unsigned char __a, vector unsigned char __b) {
+ return __builtin_s390_vbperm(__a, __b);
+}
+#endif
+
/*-- vec_sel ----------------------------------------------------------------*/
static inline __ATTRS_o_ai vector signed char
@@ -614,6 +674,22 @@ vec_sel(vector unsigned long long __a, vector unsigned long long __b,
(~(vector unsigned long long)__c & __a));
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_sel(vector float __a, vector float __b, vector unsigned int __c) {
+ return (vector float)((__c & (vector unsigned int)__b) |
+ (~__c & (vector unsigned int)__a));
+}
+
+static inline __ATTRS_o_ai vector float
+vec_sel(vector float __a, vector float __b, vector bool int __c) {
+ vector unsigned int __ac = (vector unsigned int)__a;
+ vector unsigned int __bc = (vector unsigned int)__b;
+ vector unsigned int __cc = (vector unsigned int)__c;
+ return (vector float)((__cc & __bc) | (~__cc & __ac));
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_sel(vector double __a, vector double __b, vector unsigned long long __c) {
return (vector double)((__c & (vector unsigned long long)__b) |
@@ -687,6 +763,17 @@ vec_gather_element(vector unsigned long long __vec,
return __vec;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_gather_element(vector float __vec, vector unsigned int __offset,
+ const float *__ptr, int __index)
+ __constant_range(__index, 0, 3) {
+ __vec[__index] = *(const float *)(
+ (__INTPTR_TYPE__)__ptr + (__INTPTR_TYPE__)__offset[__index]);
+ return __vec;
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_gather_element(vector double __vec, vector unsigned long long __offset,
const double *__ptr, int __index)
@@ -749,6 +836,16 @@ vec_scatter_element(vector unsigned long long __vec,
__vec[__index];
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai void
+vec_scatter_element(vector float __vec, vector unsigned int __offset,
+ float *__ptr, int __index)
+ __constant_range(__index, 0, 3) {
+ *(float *)((__INTPTR_TYPE__)__ptr + __offset[__index]) =
+ __vec[__index];
+}
+#endif
+
static inline __ATTRS_o_ai void
vec_scatter_element(vector double __vec, vector unsigned long long __offset,
double *__ptr, int __index)
@@ -757,48 +854,111 @@ vec_scatter_element(vector double __vec, vector unsigned long long __offset,
__vec[__index];
}
+/*-- vec_xl -----------------------------------------------------------------*/
+
+static inline __ATTRS_o_ai vector signed char
+vec_xl(long __offset, const signed char *__ptr) {
+ return *(const vector signed char *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+static inline __ATTRS_o_ai vector unsigned char
+vec_xl(long __offset, const unsigned char *__ptr) {
+ return *(const vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+static inline __ATTRS_o_ai vector signed short
+vec_xl(long __offset, const signed short *__ptr) {
+ return *(const vector signed short *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+static inline __ATTRS_o_ai vector unsigned short
+vec_xl(long __offset, const unsigned short *__ptr) {
+ return *(const vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+static inline __ATTRS_o_ai vector signed int
+vec_xl(long __offset, const signed int *__ptr) {
+ return *(const vector signed int *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+static inline __ATTRS_o_ai vector unsigned int
+vec_xl(long __offset, const unsigned int *__ptr) {
+ return *(const vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+static inline __ATTRS_o_ai vector signed long long
+vec_xl(long __offset, const signed long long *__ptr) {
+ return *(const vector signed long long *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+static inline __ATTRS_o_ai vector unsigned long long
+vec_xl(long __offset, const unsigned long long *__ptr) {
+ return *(const vector unsigned long long *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_xl(long __offset, const float *__ptr) {
+ return *(const vector float *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
+vec_xl(long __offset, const double *__ptr) {
+ return *(const vector double *)((__INTPTR_TYPE__)__ptr + __offset);
+}
+
/*-- vec_xld2 ---------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_xld2(long __offset, const signed char *__ptr) {
return *(const vector signed char *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_xld2(long __offset, const unsigned char *__ptr) {
return *(const vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_xld2(long __offset, const signed short *__ptr) {
return *(const vector signed short *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_xld2(long __offset, const unsigned short *__ptr) {
return *(const vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_xld2(long __offset, const signed int *__ptr) {
return *(const vector signed int *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_xld2(long __offset, const unsigned int *__ptr) {
return *(const vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_xld2(long __offset, const signed long long *__ptr) {
return *(const vector signed long long *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_xld2(long __offset, const unsigned long long *__ptr) {
return *(const vector unsigned long long *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector double
vec_xld2(long __offset, const double *__ptr) {
return *(const vector double *)((__INTPTR_TYPE__)__ptr + __offset);
@@ -806,74 +966,145 @@ vec_xld2(long __offset, const double *__ptr) {
/*-- vec_xlw4 ---------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_xlw4(long __offset, const signed char *__ptr) {
return *(const vector signed char *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_xlw4(long __offset, const unsigned char *__ptr) {
return *(const vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_xlw4(long __offset, const signed short *__ptr) {
return *(const vector signed short *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_xlw4(long __offset, const unsigned short *__ptr) {
return *(const vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_xlw4(long __offset, const signed int *__ptr) {
return *(const vector signed int *)((__INTPTR_TYPE__)__ptr + __offset);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_xlw4(long __offset, const unsigned int *__ptr) {
return *(const vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset);
}
+/*-- vec_xst ----------------------------------------------------------------*/
+
+static inline __ATTRS_o_ai void
+vec_xst(vector signed char __vec, long __offset, signed char *__ptr) {
+ *(vector signed char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
+static inline __ATTRS_o_ai void
+vec_xst(vector unsigned char __vec, long __offset, unsigned char *__ptr) {
+ *(vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
+static inline __ATTRS_o_ai void
+vec_xst(vector signed short __vec, long __offset, signed short *__ptr) {
+ *(vector signed short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
+static inline __ATTRS_o_ai void
+vec_xst(vector unsigned short __vec, long __offset, unsigned short *__ptr) {
+ *(vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
+static inline __ATTRS_o_ai void
+vec_xst(vector signed int __vec, long __offset, signed int *__ptr) {
+ *(vector signed int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
+static inline __ATTRS_o_ai void
+vec_xst(vector unsigned int __vec, long __offset, unsigned int *__ptr) {
+ *(vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
+static inline __ATTRS_o_ai void
+vec_xst(vector signed long long __vec, long __offset,
+ signed long long *__ptr) {
+ *(vector signed long long *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
+static inline __ATTRS_o_ai void
+vec_xst(vector unsigned long long __vec, long __offset,
+ unsigned long long *__ptr) {
+ *(vector unsigned long long *)((__INTPTR_TYPE__)__ptr + __offset) =
+ __vec;
+}
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai void
+vec_xst(vector float __vec, long __offset, float *__ptr) {
+ *(vector float *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+#endif
+
+static inline __ATTRS_o_ai void
+vec_xst(vector double __vec, long __offset, double *__ptr) {
+ *(vector double *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
+}
+
/*-- vec_xstd2 --------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector signed char __vec, long __offset, signed char *__ptr) {
*(vector signed char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector unsigned char __vec, long __offset, unsigned char *__ptr) {
*(vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector signed short __vec, long __offset, signed short *__ptr) {
*(vector signed short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector unsigned short __vec, long __offset, unsigned short *__ptr) {
*(vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector signed int __vec, long __offset, signed int *__ptr) {
*(vector signed int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector unsigned int __vec, long __offset, unsigned int *__ptr) {
*(vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector signed long long __vec, long __offset,
signed long long *__ptr) {
*(vector signed long long *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector unsigned long long __vec, long __offset,
unsigned long long *__ptr) {
@@ -881,6 +1112,7 @@ vec_xstd2(vector unsigned long long __vec, long __offset,
__vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstd2(vector double __vec, long __offset, double *__ptr) {
*(vector double *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
@@ -888,31 +1120,37 @@ vec_xstd2(vector double __vec, long __offset, double *__ptr) {
/*-- vec_xstw4 --------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstw4(vector signed char __vec, long __offset, signed char *__ptr) {
*(vector signed char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstw4(vector unsigned char __vec, long __offset, unsigned char *__ptr) {
*(vector unsigned char *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstw4(vector signed short __vec, long __offset, signed short *__ptr) {
*(vector signed short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstw4(vector unsigned short __vec, long __offset, unsigned short *__ptr) {
*(vector unsigned short *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstw4(vector signed int __vec, long __offset, signed int *__ptr) {
*(vector signed int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai void
vec_xstw4(vector unsigned int __vec, long __offset, unsigned int *__ptr) {
*(vector unsigned int *)((__INTPTR_TYPE__)__ptr + __offset) = __vec;
@@ -952,6 +1190,12 @@ extern __ATTRS_o vector unsigned long long
vec_load_bndry(const unsigned long long *__ptr, unsigned short __len)
__constant_pow2_range(__len, 64, 4096);
+#if __ARCH__ >= 12
+extern __ATTRS_o vector float
+vec_load_bndry(const float *__ptr, unsigned short __len)
+ __constant_pow2_range(__len, 64, 4096);
+#endif
+
extern __ATTRS_o vector double
vec_load_bndry(const double *__ptr, unsigned short __len)
__constant_pow2_range(__len, 64, 4096);
@@ -1007,11 +1251,27 @@ vec_load_len(const unsigned long long *__ptr, unsigned int __len) {
return (vector unsigned long long)__builtin_s390_vll(__len, __ptr);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_load_len(const float *__ptr, unsigned int __len) {
+ return (vector float)__builtin_s390_vll(__len, __ptr);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_load_len(const double *__ptr, unsigned int __len) {
return (vector double)__builtin_s390_vll(__len, __ptr);
}
+/*-- vec_load_len_r ---------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_ai vector unsigned char
+vec_load_len_r(const unsigned char *__ptr, unsigned int __len) {
+ return (vector unsigned char)__builtin_s390_vlrl(__len, __ptr);
+}
+#endif
+
/*-- vec_store_len ----------------------------------------------------------*/
static inline __ATTRS_o_ai void
@@ -1062,12 +1322,30 @@ vec_store_len(vector unsigned long long __vec, unsigned long long *__ptr,
__builtin_s390_vstl((vector signed char)__vec, __len, __ptr);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai void
+vec_store_len(vector float __vec, float *__ptr,
+ unsigned int __len) {
+ __builtin_s390_vstl((vector signed char)__vec, __len, __ptr);
+}
+#endif
+
static inline __ATTRS_o_ai void
vec_store_len(vector double __vec, double *__ptr,
unsigned int __len) {
__builtin_s390_vstl((vector signed char)__vec, __len, __ptr);
}
+/*-- vec_store_len_r --------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_ai void
+vec_store_len_r(vector unsigned char __vec, unsigned char *__ptr,
+ unsigned int __len) {
+ __builtin_s390_vstrl((vector signed char)__vec, __len, __ptr);
+}
+#endif
+
/*-- vec_load_pair ----------------------------------------------------------*/
static inline __ATTRS_o_ai vector signed long long
@@ -1232,6 +1510,14 @@ vec_splat(vector unsigned long long __vec, int __index)
return (vector unsigned long long)__vec[__index];
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_splat(vector float __vec, int __index)
+ __constant_range(__index, 0, 3) {
+ return (vector float)__vec[__index];
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_splat(vector double __vec, int __index)
__constant_range(__index, 0, 1) {
@@ -1332,6 +1618,13 @@ vec_splats(unsigned long long __scalar) {
return (vector unsigned long long)__scalar;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_splats(float __scalar) {
+ return (vector float)__scalar;
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_splats(double __scalar) {
return (vector double)__scalar;
@@ -1425,6 +1718,13 @@ vec_mergeh(vector unsigned long long __a, vector unsigned long long __b) {
return (vector unsigned long long)(__a[0], __b[0]);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_mergeh(vector float __a, vector float __b) {
+ return (vector float)(__a[0], __b[0], __a[1], __b[1]);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_mergeh(vector double __a, vector double __b) {
return (vector double)(__a[0], __b[0]);
@@ -1501,6 +1801,13 @@ vec_mergel(vector unsigned long long __a, vector unsigned long long __b) {
return (vector unsigned long long)(__a[1], __b[1]);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_mergel(vector float __a, vector float __b) {
+ return (vector float)(__a[2], __b[2], __a[3], __b[3]);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_mergel(vector double __a, vector double __b) {
return (vector double)(__a[1], __b[1]);
@@ -1866,6 +2173,13 @@ vec_cmpeq(vector unsigned long long __a, vector unsigned long long __b) {
return (vector bool long long)(__a == __b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool int
+vec_cmpeq(vector float __a, vector float __b) {
+ return (vector bool int)(__a == __b);
+}
+#endif
+
static inline __ATTRS_o_ai vector bool long long
vec_cmpeq(vector double __a, vector double __b) {
return (vector bool long long)(__a == __b);
@@ -1913,6 +2227,13 @@ vec_cmpge(vector unsigned long long __a, vector unsigned long long __b) {
return (vector bool long long)(__a >= __b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool int
+vec_cmpge(vector float __a, vector float __b) {
+ return (vector bool int)(__a >= __b);
+}
+#endif
+
static inline __ATTRS_o_ai vector bool long long
vec_cmpge(vector double __a, vector double __b) {
return (vector bool long long)(__a >= __b);
@@ -1960,6 +2281,13 @@ vec_cmpgt(vector unsigned long long __a, vector unsigned long long __b) {
return (vector bool long long)(__a > __b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool int
+vec_cmpgt(vector float __a, vector float __b) {
+ return (vector bool int)(__a > __b);
+}
+#endif
+
static inline __ATTRS_o_ai vector bool long long
vec_cmpgt(vector double __a, vector double __b) {
return (vector bool long long)(__a > __b);
@@ -2007,6 +2335,13 @@ vec_cmple(vector unsigned long long __a, vector unsigned long long __b) {
return (vector bool long long)(__a <= __b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool int
+vec_cmple(vector float __a, vector float __b) {
+ return (vector bool int)(__a <= __b);
+}
+#endif
+
static inline __ATTRS_o_ai vector bool long long
vec_cmple(vector double __a, vector double __b) {
return (vector bool long long)(__a <= __b);
@@ -2054,6 +2389,13 @@ vec_cmplt(vector unsigned long long __a, vector unsigned long long __b) {
return (vector bool long long)(__a < __b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool int
+vec_cmplt(vector float __a, vector float __b) {
+ return (vector bool int)(__a < __b);
+}
+#endif
+
static inline __ATTRS_o_ai vector bool long long
vec_cmplt(vector double __a, vector double __b) {
return (vector bool long long)(__a < __b);
@@ -2068,6 +2410,7 @@ vec_all_eq(vector signed char __a, vector signed char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector signed char __a, vector bool char __b) {
int __cc;
@@ -2075,6 +2418,7 @@ vec_all_eq(vector signed char __a, vector bool char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool char __a, vector signed char __b) {
int __cc;
@@ -2090,6 +2434,7 @@ vec_all_eq(vector unsigned char __a, vector unsigned char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -2098,6 +2443,7 @@ vec_all_eq(vector unsigned char __a, vector bool char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -2121,6 +2467,7 @@ vec_all_eq(vector signed short __a, vector signed short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector signed short __a, vector bool short __b) {
int __cc;
@@ -2128,6 +2475,7 @@ vec_all_eq(vector signed short __a, vector bool short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool short __a, vector signed short __b) {
int __cc;
@@ -2143,6 +2491,7 @@ vec_all_eq(vector unsigned short __a, vector unsigned short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -2151,6 +2500,7 @@ vec_all_eq(vector unsigned short __a, vector bool short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -2174,6 +2524,7 @@ vec_all_eq(vector signed int __a, vector signed int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector signed int __a, vector bool int __b) {
int __cc;
@@ -2181,6 +2532,7 @@ vec_all_eq(vector signed int __a, vector bool int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool int __a, vector signed int __b) {
int __cc;
@@ -2196,6 +2548,7 @@ vec_all_eq(vector unsigned int __a, vector unsigned int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -2204,6 +2557,7 @@ vec_all_eq(vector unsigned int __a, vector bool int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -2227,6 +2581,7 @@ vec_all_eq(vector signed long long __a, vector signed long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -2234,6 +2589,7 @@ vec_all_eq(vector signed long long __a, vector bool long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -2249,6 +2605,7 @@ vec_all_eq(vector unsigned long long __a, vector unsigned long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -2257,6 +2614,7 @@ vec_all_eq(vector unsigned long long __a, vector bool long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_eq(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -2273,6 +2631,15 @@ vec_all_eq(vector bool long long __a, vector bool long long __b) {
return __cc == 0;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_eq(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfcesbs(__a, __b, &__cc);
+ return __cc == 0;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_all_eq(vector double __a, vector double __b) {
int __cc;
@@ -2289,6 +2656,7 @@ vec_all_ne(vector signed char __a, vector signed char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector signed char __a, vector bool char __b) {
int __cc;
@@ -2296,6 +2664,7 @@ vec_all_ne(vector signed char __a, vector bool char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool char __a, vector signed char __b) {
int __cc;
@@ -2311,6 +2680,7 @@ vec_all_ne(vector unsigned char __a, vector unsigned char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -2319,6 +2689,7 @@ vec_all_ne(vector unsigned char __a, vector bool char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -2342,6 +2713,7 @@ vec_all_ne(vector signed short __a, vector signed short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector signed short __a, vector bool short __b) {
int __cc;
@@ -2349,6 +2721,7 @@ vec_all_ne(vector signed short __a, vector bool short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool short __a, vector signed short __b) {
int __cc;
@@ -2364,6 +2737,7 @@ vec_all_ne(vector unsigned short __a, vector unsigned short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -2372,6 +2746,7 @@ vec_all_ne(vector unsigned short __a, vector bool short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -2395,6 +2770,7 @@ vec_all_ne(vector signed int __a, vector signed int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector signed int __a, vector bool int __b) {
int __cc;
@@ -2402,6 +2778,7 @@ vec_all_ne(vector signed int __a, vector bool int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool int __a, vector signed int __b) {
int __cc;
@@ -2417,6 +2794,7 @@ vec_all_ne(vector unsigned int __a, vector unsigned int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -2425,6 +2803,7 @@ vec_all_ne(vector unsigned int __a, vector bool int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -2448,6 +2827,7 @@ vec_all_ne(vector signed long long __a, vector signed long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -2455,6 +2835,7 @@ vec_all_ne(vector signed long long __a, vector bool long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -2470,6 +2851,7 @@ vec_all_ne(vector unsigned long long __a, vector unsigned long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -2478,6 +2860,7 @@ vec_all_ne(vector unsigned long long __a, vector bool long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ne(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -2494,6 +2877,15 @@ vec_all_ne(vector bool long long __a, vector bool long long __b) {
return __cc == 3;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_ne(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfcesbs(__a, __b, &__cc);
+ return __cc == 3;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_all_ne(vector double __a, vector double __b) {
int __cc;
@@ -2510,6 +2902,7 @@ vec_all_ge(vector signed char __a, vector signed char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector signed char __a, vector bool char __b) {
int __cc;
@@ -2517,6 +2910,7 @@ vec_all_ge(vector signed char __a, vector bool char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool char __a, vector signed char __b) {
int __cc;
@@ -2531,6 +2925,7 @@ vec_all_ge(vector unsigned char __a, vector unsigned char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -2538,6 +2933,7 @@ vec_all_ge(vector unsigned char __a, vector bool char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -2545,6 +2941,7 @@ vec_all_ge(vector bool char __a, vector unsigned char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool char __a, vector bool char __b) {
int __cc;
@@ -2560,6 +2957,7 @@ vec_all_ge(vector signed short __a, vector signed short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector signed short __a, vector bool short __b) {
int __cc;
@@ -2567,6 +2965,7 @@ vec_all_ge(vector signed short __a, vector bool short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool short __a, vector signed short __b) {
int __cc;
@@ -2581,6 +2980,7 @@ vec_all_ge(vector unsigned short __a, vector unsigned short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -2588,6 +2988,7 @@ vec_all_ge(vector unsigned short __a, vector bool short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -2595,6 +2996,7 @@ vec_all_ge(vector bool short __a, vector unsigned short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool short __a, vector bool short __b) {
int __cc;
@@ -2610,6 +3012,7 @@ vec_all_ge(vector signed int __a, vector signed int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector signed int __a, vector bool int __b) {
int __cc;
@@ -2617,6 +3020,7 @@ vec_all_ge(vector signed int __a, vector bool int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool int __a, vector signed int __b) {
int __cc;
@@ -2631,6 +3035,7 @@ vec_all_ge(vector unsigned int __a, vector unsigned int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -2638,6 +3043,7 @@ vec_all_ge(vector unsigned int __a, vector bool int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -2645,6 +3051,7 @@ vec_all_ge(vector bool int __a, vector unsigned int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool int __a, vector bool int __b) {
int __cc;
@@ -2660,6 +3067,7 @@ vec_all_ge(vector signed long long __a, vector signed long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -2667,6 +3075,7 @@ vec_all_ge(vector signed long long __a, vector bool long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -2681,6 +3090,7 @@ vec_all_ge(vector unsigned long long __a, vector unsigned long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -2688,6 +3098,7 @@ vec_all_ge(vector unsigned long long __a, vector bool long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -2695,6 +3106,7 @@ vec_all_ge(vector bool long long __a, vector unsigned long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_ge(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -2703,6 +3115,15 @@ vec_all_ge(vector bool long long __a, vector bool long long __b) {
return __cc == 3;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_ge(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__a, __b, &__cc);
+ return __cc == 0;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_all_ge(vector double __a, vector double __b) {
int __cc;
@@ -2719,6 +3140,7 @@ vec_all_gt(vector signed char __a, vector signed char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector signed char __a, vector bool char __b) {
int __cc;
@@ -2726,6 +3148,7 @@ vec_all_gt(vector signed char __a, vector bool char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool char __a, vector signed char __b) {
int __cc;
@@ -2740,6 +3163,7 @@ vec_all_gt(vector unsigned char __a, vector unsigned char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -2747,6 +3171,7 @@ vec_all_gt(vector unsigned char __a, vector bool char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -2754,6 +3179,7 @@ vec_all_gt(vector bool char __a, vector unsigned char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool char __a, vector bool char __b) {
int __cc;
@@ -2769,6 +3195,7 @@ vec_all_gt(vector signed short __a, vector signed short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector signed short __a, vector bool short __b) {
int __cc;
@@ -2776,6 +3203,7 @@ vec_all_gt(vector signed short __a, vector bool short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool short __a, vector signed short __b) {
int __cc;
@@ -2790,6 +3218,7 @@ vec_all_gt(vector unsigned short __a, vector unsigned short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -2797,6 +3226,7 @@ vec_all_gt(vector unsigned short __a, vector bool short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -2804,6 +3234,7 @@ vec_all_gt(vector bool short __a, vector unsigned short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool short __a, vector bool short __b) {
int __cc;
@@ -2819,6 +3250,7 @@ vec_all_gt(vector signed int __a, vector signed int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector signed int __a, vector bool int __b) {
int __cc;
@@ -2826,6 +3258,7 @@ vec_all_gt(vector signed int __a, vector bool int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool int __a, vector signed int __b) {
int __cc;
@@ -2840,6 +3273,7 @@ vec_all_gt(vector unsigned int __a, vector unsigned int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -2847,6 +3281,7 @@ vec_all_gt(vector unsigned int __a, vector bool int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -2854,6 +3289,7 @@ vec_all_gt(vector bool int __a, vector unsigned int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool int __a, vector bool int __b) {
int __cc;
@@ -2869,6 +3305,7 @@ vec_all_gt(vector signed long long __a, vector signed long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -2876,6 +3313,7 @@ vec_all_gt(vector signed long long __a, vector bool long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -2890,6 +3328,7 @@ vec_all_gt(vector unsigned long long __a, vector unsigned long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -2897,6 +3336,7 @@ vec_all_gt(vector unsigned long long __a, vector bool long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -2904,6 +3344,7 @@ vec_all_gt(vector bool long long __a, vector unsigned long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_gt(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -2912,6 +3353,15 @@ vec_all_gt(vector bool long long __a, vector bool long long __b) {
return __cc == 0;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_gt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__a, __b, &__cc);
+ return __cc == 0;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_all_gt(vector double __a, vector double __b) {
int __cc;
@@ -2928,6 +3378,7 @@ vec_all_le(vector signed char __a, vector signed char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector signed char __a, vector bool char __b) {
int __cc;
@@ -2935,6 +3386,7 @@ vec_all_le(vector signed char __a, vector bool char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool char __a, vector signed char __b) {
int __cc;
@@ -2949,6 +3401,7 @@ vec_all_le(vector unsigned char __a, vector unsigned char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -2956,6 +3409,7 @@ vec_all_le(vector unsigned char __a, vector bool char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -2963,6 +3417,7 @@ vec_all_le(vector bool char __a, vector unsigned char __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool char __a, vector bool char __b) {
int __cc;
@@ -2978,6 +3433,7 @@ vec_all_le(vector signed short __a, vector signed short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector signed short __a, vector bool short __b) {
int __cc;
@@ -2985,6 +3441,7 @@ vec_all_le(vector signed short __a, vector bool short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool short __a, vector signed short __b) {
int __cc;
@@ -2999,6 +3456,7 @@ vec_all_le(vector unsigned short __a, vector unsigned short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -3006,6 +3464,7 @@ vec_all_le(vector unsigned short __a, vector bool short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -3013,6 +3472,7 @@ vec_all_le(vector bool short __a, vector unsigned short __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool short __a, vector bool short __b) {
int __cc;
@@ -3028,6 +3488,7 @@ vec_all_le(vector signed int __a, vector signed int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector signed int __a, vector bool int __b) {
int __cc;
@@ -3035,6 +3496,7 @@ vec_all_le(vector signed int __a, vector bool int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool int __a, vector signed int __b) {
int __cc;
@@ -3049,6 +3511,7 @@ vec_all_le(vector unsigned int __a, vector unsigned int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -3056,6 +3519,7 @@ vec_all_le(vector unsigned int __a, vector bool int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -3063,6 +3527,7 @@ vec_all_le(vector bool int __a, vector unsigned int __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool int __a, vector bool int __b) {
int __cc;
@@ -3078,6 +3543,7 @@ vec_all_le(vector signed long long __a, vector signed long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -3085,6 +3551,7 @@ vec_all_le(vector signed long long __a, vector bool long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -3099,6 +3566,7 @@ vec_all_le(vector unsigned long long __a, vector unsigned long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -3106,6 +3574,7 @@ vec_all_le(vector unsigned long long __a, vector bool long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -3113,6 +3582,7 @@ vec_all_le(vector bool long long __a, vector unsigned long long __b) {
return __cc == 3;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_le(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -3121,6 +3591,15 @@ vec_all_le(vector bool long long __a, vector bool long long __b) {
return __cc == 3;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_le(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__b, __a, &__cc);
+ return __cc == 0;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_all_le(vector double __a, vector double __b) {
int __cc;
@@ -3137,6 +3616,7 @@ vec_all_lt(vector signed char __a, vector signed char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector signed char __a, vector bool char __b) {
int __cc;
@@ -3144,6 +3624,7 @@ vec_all_lt(vector signed char __a, vector bool char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool char __a, vector signed char __b) {
int __cc;
@@ -3158,6 +3639,7 @@ vec_all_lt(vector unsigned char __a, vector unsigned char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -3165,6 +3647,7 @@ vec_all_lt(vector unsigned char __a, vector bool char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -3172,6 +3655,7 @@ vec_all_lt(vector bool char __a, vector unsigned char __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool char __a, vector bool char __b) {
int __cc;
@@ -3187,6 +3671,7 @@ vec_all_lt(vector signed short __a, vector signed short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector signed short __a, vector bool short __b) {
int __cc;
@@ -3194,6 +3679,7 @@ vec_all_lt(vector signed short __a, vector bool short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool short __a, vector signed short __b) {
int __cc;
@@ -3208,6 +3694,7 @@ vec_all_lt(vector unsigned short __a, vector unsigned short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -3215,6 +3702,7 @@ vec_all_lt(vector unsigned short __a, vector bool short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -3222,6 +3710,7 @@ vec_all_lt(vector bool short __a, vector unsigned short __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool short __a, vector bool short __b) {
int __cc;
@@ -3237,6 +3726,7 @@ vec_all_lt(vector signed int __a, vector signed int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector signed int __a, vector bool int __b) {
int __cc;
@@ -3244,6 +3734,7 @@ vec_all_lt(vector signed int __a, vector bool int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool int __a, vector signed int __b) {
int __cc;
@@ -3258,6 +3749,7 @@ vec_all_lt(vector unsigned int __a, vector unsigned int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -3265,6 +3757,7 @@ vec_all_lt(vector unsigned int __a, vector bool int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -3272,6 +3765,7 @@ vec_all_lt(vector bool int __a, vector unsigned int __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool int __a, vector bool int __b) {
int __cc;
@@ -3287,6 +3781,7 @@ vec_all_lt(vector signed long long __a, vector signed long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -3294,6 +3789,7 @@ vec_all_lt(vector signed long long __a, vector bool long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -3308,6 +3804,7 @@ vec_all_lt(vector unsigned long long __a, vector unsigned long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -3315,6 +3812,7 @@ vec_all_lt(vector unsigned long long __a, vector bool long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -3322,6 +3820,7 @@ vec_all_lt(vector bool long long __a, vector unsigned long long __b) {
return __cc == 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_all_lt(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -3330,6 +3829,15 @@ vec_all_lt(vector bool long long __a, vector bool long long __b) {
return __cc == 0;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_lt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__b, __a, &__cc);
+ return __cc == 0;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_all_lt(vector double __a, vector double __b) {
int __cc;
@@ -3339,7 +3847,16 @@ vec_all_lt(vector double __a, vector double __b) {
/*-- vec_all_nge ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_nge(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__a, __b, &__cc);
+ return __cc == 3;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_all_nge(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchedbs(__a, __b, &__cc);
@@ -3348,7 +3865,16 @@ vec_all_nge(vector double __a, vector double __b) {
/*-- vec_all_ngt ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_ngt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__a, __b, &__cc);
+ return __cc == 3;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_all_ngt(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchdbs(__a, __b, &__cc);
@@ -3357,7 +3883,16 @@ vec_all_ngt(vector double __a, vector double __b) {
/*-- vec_all_nle ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_nle(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__b, __a, &__cc);
+ return __cc == 3;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_all_nle(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchedbs(__b, __a, &__cc);
@@ -3366,7 +3901,16 @@ vec_all_nle(vector double __a, vector double __b) {
/*-- vec_all_nlt ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_nlt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__b, __a, &__cc);
+ return __cc == 3;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_all_nlt(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchdbs(__b, __a, &__cc);
@@ -3375,7 +3919,16 @@ vec_all_nlt(vector double __a, vector double __b) {
/*-- vec_all_nan ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_nan(vector float __a) {
+ int __cc;
+ __builtin_s390_vftcisb(__a, 15, &__cc);
+ return __cc == 0;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_all_nan(vector double __a) {
int __cc;
__builtin_s390_vftcidb(__a, 15, &__cc);
@@ -3384,7 +3937,16 @@ vec_all_nan(vector double __a) {
/*-- vec_all_numeric --------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_all_numeric(vector float __a) {
+ int __cc;
+ __builtin_s390_vftcisb(__a, 15, &__cc);
+ return __cc == 3;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_all_numeric(vector double __a) {
int __cc;
__builtin_s390_vftcidb(__a, 15, &__cc);
@@ -3400,6 +3962,7 @@ vec_any_eq(vector signed char __a, vector signed char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector signed char __a, vector bool char __b) {
int __cc;
@@ -3407,6 +3970,7 @@ vec_any_eq(vector signed char __a, vector bool char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool char __a, vector signed char __b) {
int __cc;
@@ -3422,6 +3986,7 @@ vec_any_eq(vector unsigned char __a, vector unsigned char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -3430,6 +3995,7 @@ vec_any_eq(vector unsigned char __a, vector bool char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -3453,6 +4019,7 @@ vec_any_eq(vector signed short __a, vector signed short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector signed short __a, vector bool short __b) {
int __cc;
@@ -3460,6 +4027,7 @@ vec_any_eq(vector signed short __a, vector bool short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool short __a, vector signed short __b) {
int __cc;
@@ -3475,6 +4043,7 @@ vec_any_eq(vector unsigned short __a, vector unsigned short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -3483,6 +4052,7 @@ vec_any_eq(vector unsigned short __a, vector bool short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -3506,6 +4076,7 @@ vec_any_eq(vector signed int __a, vector signed int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector signed int __a, vector bool int __b) {
int __cc;
@@ -3513,6 +4084,7 @@ vec_any_eq(vector signed int __a, vector bool int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool int __a, vector signed int __b) {
int __cc;
@@ -3528,6 +4100,7 @@ vec_any_eq(vector unsigned int __a, vector unsigned int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -3536,6 +4109,7 @@ vec_any_eq(vector unsigned int __a, vector bool int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -3559,6 +4133,7 @@ vec_any_eq(vector signed long long __a, vector signed long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -3566,6 +4141,7 @@ vec_any_eq(vector signed long long __a, vector bool long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -3581,6 +4157,7 @@ vec_any_eq(vector unsigned long long __a, vector unsigned long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -3589,6 +4166,7 @@ vec_any_eq(vector unsigned long long __a, vector bool long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_eq(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -3605,6 +4183,15 @@ vec_any_eq(vector bool long long __a, vector bool long long __b) {
return __cc <= 1;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_eq(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfcesbs(__a, __b, &__cc);
+ return __cc <= 1;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_any_eq(vector double __a, vector double __b) {
int __cc;
@@ -3621,6 +4208,7 @@ vec_any_ne(vector signed char __a, vector signed char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector signed char __a, vector bool char __b) {
int __cc;
@@ -3628,6 +4216,7 @@ vec_any_ne(vector signed char __a, vector bool char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool char __a, vector signed char __b) {
int __cc;
@@ -3643,6 +4232,7 @@ vec_any_ne(vector unsigned char __a, vector unsigned char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -3651,6 +4241,7 @@ vec_any_ne(vector unsigned char __a, vector bool char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -3674,6 +4265,7 @@ vec_any_ne(vector signed short __a, vector signed short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector signed short __a, vector bool short __b) {
int __cc;
@@ -3681,6 +4273,7 @@ vec_any_ne(vector signed short __a, vector bool short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool short __a, vector signed short __b) {
int __cc;
@@ -3696,6 +4289,7 @@ vec_any_ne(vector unsigned short __a, vector unsigned short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -3704,6 +4298,7 @@ vec_any_ne(vector unsigned short __a, vector bool short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -3727,6 +4322,7 @@ vec_any_ne(vector signed int __a, vector signed int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector signed int __a, vector bool int __b) {
int __cc;
@@ -3734,6 +4330,7 @@ vec_any_ne(vector signed int __a, vector bool int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool int __a, vector signed int __b) {
int __cc;
@@ -3749,6 +4346,7 @@ vec_any_ne(vector unsigned int __a, vector unsigned int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -3757,6 +4355,7 @@ vec_any_ne(vector unsigned int __a, vector bool int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -3780,6 +4379,7 @@ vec_any_ne(vector signed long long __a, vector signed long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -3787,6 +4387,7 @@ vec_any_ne(vector signed long long __a, vector bool long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -3802,6 +4403,7 @@ vec_any_ne(vector unsigned long long __a, vector unsigned long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -3810,6 +4412,7 @@ vec_any_ne(vector unsigned long long __a, vector bool long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ne(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -3826,6 +4429,15 @@ vec_any_ne(vector bool long long __a, vector bool long long __b) {
return __cc != 0;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_ne(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfcesbs(__a, __b, &__cc);
+ return __cc != 0;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_any_ne(vector double __a, vector double __b) {
int __cc;
@@ -3842,6 +4454,7 @@ vec_any_ge(vector signed char __a, vector signed char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector signed char __a, vector bool char __b) {
int __cc;
@@ -3849,6 +4462,7 @@ vec_any_ge(vector signed char __a, vector bool char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool char __a, vector signed char __b) {
int __cc;
@@ -3863,6 +4477,7 @@ vec_any_ge(vector unsigned char __a, vector unsigned char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -3870,6 +4485,7 @@ vec_any_ge(vector unsigned char __a, vector bool char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -3877,6 +4493,7 @@ vec_any_ge(vector bool char __a, vector unsigned char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool char __a, vector bool char __b) {
int __cc;
@@ -3892,6 +4509,7 @@ vec_any_ge(vector signed short __a, vector signed short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector signed short __a, vector bool short __b) {
int __cc;
@@ -3899,6 +4517,7 @@ vec_any_ge(vector signed short __a, vector bool short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool short __a, vector signed short __b) {
int __cc;
@@ -3913,6 +4532,7 @@ vec_any_ge(vector unsigned short __a, vector unsigned short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -3920,6 +4540,7 @@ vec_any_ge(vector unsigned short __a, vector bool short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -3927,6 +4548,7 @@ vec_any_ge(vector bool short __a, vector unsigned short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool short __a, vector bool short __b) {
int __cc;
@@ -3942,6 +4564,7 @@ vec_any_ge(vector signed int __a, vector signed int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector signed int __a, vector bool int __b) {
int __cc;
@@ -3949,6 +4572,7 @@ vec_any_ge(vector signed int __a, vector bool int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool int __a, vector signed int __b) {
int __cc;
@@ -3963,6 +4587,7 @@ vec_any_ge(vector unsigned int __a, vector unsigned int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -3970,6 +4595,7 @@ vec_any_ge(vector unsigned int __a, vector bool int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -3977,6 +4603,7 @@ vec_any_ge(vector bool int __a, vector unsigned int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool int __a, vector bool int __b) {
int __cc;
@@ -3992,6 +4619,7 @@ vec_any_ge(vector signed long long __a, vector signed long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -3999,6 +4627,7 @@ vec_any_ge(vector signed long long __a, vector bool long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -4013,6 +4642,7 @@ vec_any_ge(vector unsigned long long __a, vector unsigned long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -4020,6 +4650,7 @@ vec_any_ge(vector unsigned long long __a, vector bool long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -4027,6 +4658,7 @@ vec_any_ge(vector bool long long __a, vector unsigned long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_ge(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -4035,6 +4667,15 @@ vec_any_ge(vector bool long long __a, vector bool long long __b) {
return __cc != 0;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_ge(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__a, __b, &__cc);
+ return __cc <= 1;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_any_ge(vector double __a, vector double __b) {
int __cc;
@@ -4051,6 +4692,7 @@ vec_any_gt(vector signed char __a, vector signed char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector signed char __a, vector bool char __b) {
int __cc;
@@ -4058,6 +4700,7 @@ vec_any_gt(vector signed char __a, vector bool char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool char __a, vector signed char __b) {
int __cc;
@@ -4072,6 +4715,7 @@ vec_any_gt(vector unsigned char __a, vector unsigned char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -4079,6 +4723,7 @@ vec_any_gt(vector unsigned char __a, vector bool char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -4086,6 +4731,7 @@ vec_any_gt(vector bool char __a, vector unsigned char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool char __a, vector bool char __b) {
int __cc;
@@ -4101,6 +4747,7 @@ vec_any_gt(vector signed short __a, vector signed short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector signed short __a, vector bool short __b) {
int __cc;
@@ -4108,6 +4755,7 @@ vec_any_gt(vector signed short __a, vector bool short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool short __a, vector signed short __b) {
int __cc;
@@ -4122,6 +4770,7 @@ vec_any_gt(vector unsigned short __a, vector unsigned short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -4129,6 +4778,7 @@ vec_any_gt(vector unsigned short __a, vector bool short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -4136,6 +4786,7 @@ vec_any_gt(vector bool short __a, vector unsigned short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool short __a, vector bool short __b) {
int __cc;
@@ -4151,6 +4802,7 @@ vec_any_gt(vector signed int __a, vector signed int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector signed int __a, vector bool int __b) {
int __cc;
@@ -4158,6 +4810,7 @@ vec_any_gt(vector signed int __a, vector bool int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool int __a, vector signed int __b) {
int __cc;
@@ -4172,6 +4825,7 @@ vec_any_gt(vector unsigned int __a, vector unsigned int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -4179,6 +4833,7 @@ vec_any_gt(vector unsigned int __a, vector bool int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -4186,6 +4841,7 @@ vec_any_gt(vector bool int __a, vector unsigned int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool int __a, vector bool int __b) {
int __cc;
@@ -4201,6 +4857,7 @@ vec_any_gt(vector signed long long __a, vector signed long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -4208,6 +4865,7 @@ vec_any_gt(vector signed long long __a, vector bool long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -4222,6 +4880,7 @@ vec_any_gt(vector unsigned long long __a, vector unsigned long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -4229,6 +4888,7 @@ vec_any_gt(vector unsigned long long __a, vector bool long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -4236,6 +4896,7 @@ vec_any_gt(vector bool long long __a, vector unsigned long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_gt(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -4244,6 +4905,15 @@ vec_any_gt(vector bool long long __a, vector bool long long __b) {
return __cc <= 1;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_gt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__a, __b, &__cc);
+ return __cc <= 1;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_any_gt(vector double __a, vector double __b) {
int __cc;
@@ -4260,6 +4930,7 @@ vec_any_le(vector signed char __a, vector signed char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector signed char __a, vector bool char __b) {
int __cc;
@@ -4267,6 +4938,7 @@ vec_any_le(vector signed char __a, vector bool char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool char __a, vector signed char __b) {
int __cc;
@@ -4281,6 +4953,7 @@ vec_any_le(vector unsigned char __a, vector unsigned char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -4288,6 +4961,7 @@ vec_any_le(vector unsigned char __a, vector bool char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -4295,6 +4969,7 @@ vec_any_le(vector bool char __a, vector unsigned char __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool char __a, vector bool char __b) {
int __cc;
@@ -4310,6 +4985,7 @@ vec_any_le(vector signed short __a, vector signed short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector signed short __a, vector bool short __b) {
int __cc;
@@ -4317,6 +4993,7 @@ vec_any_le(vector signed short __a, vector bool short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool short __a, vector signed short __b) {
int __cc;
@@ -4331,6 +5008,7 @@ vec_any_le(vector unsigned short __a, vector unsigned short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -4338,6 +5016,7 @@ vec_any_le(vector unsigned short __a, vector bool short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -4345,6 +5024,7 @@ vec_any_le(vector bool short __a, vector unsigned short __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool short __a, vector bool short __b) {
int __cc;
@@ -4360,6 +5040,7 @@ vec_any_le(vector signed int __a, vector signed int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector signed int __a, vector bool int __b) {
int __cc;
@@ -4367,6 +5048,7 @@ vec_any_le(vector signed int __a, vector bool int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool int __a, vector signed int __b) {
int __cc;
@@ -4381,6 +5063,7 @@ vec_any_le(vector unsigned int __a, vector unsigned int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -4388,6 +5071,7 @@ vec_any_le(vector unsigned int __a, vector bool int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -4395,6 +5079,7 @@ vec_any_le(vector bool int __a, vector unsigned int __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool int __a, vector bool int __b) {
int __cc;
@@ -4410,6 +5095,7 @@ vec_any_le(vector signed long long __a, vector signed long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -4417,6 +5103,7 @@ vec_any_le(vector signed long long __a, vector bool long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -4431,6 +5118,7 @@ vec_any_le(vector unsigned long long __a, vector unsigned long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -4438,6 +5126,7 @@ vec_any_le(vector unsigned long long __a, vector bool long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -4445,6 +5134,7 @@ vec_any_le(vector bool long long __a, vector unsigned long long __b) {
return __cc != 0;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_le(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -4453,6 +5143,15 @@ vec_any_le(vector bool long long __a, vector bool long long __b) {
return __cc != 0;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_le(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__b, __a, &__cc);
+ return __cc <= 1;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_any_le(vector double __a, vector double __b) {
int __cc;
@@ -4469,6 +5168,7 @@ vec_any_lt(vector signed char __a, vector signed char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector signed char __a, vector bool char __b) {
int __cc;
@@ -4476,6 +5176,7 @@ vec_any_lt(vector signed char __a, vector bool char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool char __a, vector signed char __b) {
int __cc;
@@ -4490,6 +5191,7 @@ vec_any_lt(vector unsigned char __a, vector unsigned char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector unsigned char __a, vector bool char __b) {
int __cc;
@@ -4497,6 +5199,7 @@ vec_any_lt(vector unsigned char __a, vector bool char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool char __a, vector unsigned char __b) {
int __cc;
@@ -4504,6 +5207,7 @@ vec_any_lt(vector bool char __a, vector unsigned char __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool char __a, vector bool char __b) {
int __cc;
@@ -4519,6 +5223,7 @@ vec_any_lt(vector signed short __a, vector signed short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector signed short __a, vector bool short __b) {
int __cc;
@@ -4526,6 +5231,7 @@ vec_any_lt(vector signed short __a, vector bool short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool short __a, vector signed short __b) {
int __cc;
@@ -4540,6 +5246,7 @@ vec_any_lt(vector unsigned short __a, vector unsigned short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector unsigned short __a, vector bool short __b) {
int __cc;
@@ -4547,6 +5254,7 @@ vec_any_lt(vector unsigned short __a, vector bool short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool short __a, vector unsigned short __b) {
int __cc;
@@ -4554,6 +5262,7 @@ vec_any_lt(vector bool short __a, vector unsigned short __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool short __a, vector bool short __b) {
int __cc;
@@ -4569,6 +5278,7 @@ vec_any_lt(vector signed int __a, vector signed int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector signed int __a, vector bool int __b) {
int __cc;
@@ -4576,6 +5286,7 @@ vec_any_lt(vector signed int __a, vector bool int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool int __a, vector signed int __b) {
int __cc;
@@ -4590,6 +5301,7 @@ vec_any_lt(vector unsigned int __a, vector unsigned int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector unsigned int __a, vector bool int __b) {
int __cc;
@@ -4597,6 +5309,7 @@ vec_any_lt(vector unsigned int __a, vector bool int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool int __a, vector unsigned int __b) {
int __cc;
@@ -4604,6 +5317,7 @@ vec_any_lt(vector bool int __a, vector unsigned int __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool int __a, vector bool int __b) {
int __cc;
@@ -4619,6 +5333,7 @@ vec_any_lt(vector signed long long __a, vector signed long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector signed long long __a, vector bool long long __b) {
int __cc;
@@ -4626,6 +5341,7 @@ vec_any_lt(vector signed long long __a, vector bool long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool long long __a, vector signed long long __b) {
int __cc;
@@ -4640,6 +5356,7 @@ vec_any_lt(vector unsigned long long __a, vector unsigned long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector unsigned long long __a, vector bool long long __b) {
int __cc;
@@ -4647,6 +5364,7 @@ vec_any_lt(vector unsigned long long __a, vector bool long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool long long __a, vector unsigned long long __b) {
int __cc;
@@ -4654,6 +5372,7 @@ vec_any_lt(vector bool long long __a, vector unsigned long long __b) {
return __cc <= 1;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai int
vec_any_lt(vector bool long long __a, vector bool long long __b) {
int __cc;
@@ -4662,6 +5381,15 @@ vec_any_lt(vector bool long long __a, vector bool long long __b) {
return __cc <= 1;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_lt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__b, __a, &__cc);
+ return __cc <= 1;
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_any_lt(vector double __a, vector double __b) {
int __cc;
@@ -4671,7 +5399,16 @@ vec_any_lt(vector double __a, vector double __b) {
/*-- vec_any_nge ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_nge(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__a, __b, &__cc);
+ return __cc != 0;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_any_nge(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchedbs(__a, __b, &__cc);
@@ -4680,7 +5417,16 @@ vec_any_nge(vector double __a, vector double __b) {
/*-- vec_any_ngt ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_ngt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__a, __b, &__cc);
+ return __cc != 0;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_any_ngt(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchdbs(__a, __b, &__cc);
@@ -4689,7 +5435,16 @@ vec_any_ngt(vector double __a, vector double __b) {
/*-- vec_any_nle ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_nle(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchesbs(__b, __a, &__cc);
+ return __cc != 0;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_any_nle(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchedbs(__b, __a, &__cc);
@@ -4698,7 +5453,16 @@ vec_any_nle(vector double __a, vector double __b) {
/*-- vec_any_nlt ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_nlt(vector float __a, vector float __b) {
+ int __cc;
+ __builtin_s390_vfchsbs(__b, __a, &__cc);
+ return __cc != 0;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_any_nlt(vector double __a, vector double __b) {
int __cc;
__builtin_s390_vfchdbs(__b, __a, &__cc);
@@ -4707,7 +5471,16 @@ vec_any_nlt(vector double __a, vector double __b) {
/*-- vec_any_nan ------------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_nan(vector float __a) {
+ int __cc;
+ __builtin_s390_vftcisb(__a, 15, &__cc);
+ return __cc != 3;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_any_nan(vector double __a) {
int __cc;
__builtin_s390_vftcidb(__a, 15, &__cc);
@@ -4716,7 +5489,16 @@ vec_any_nan(vector double __a) {
/*-- vec_any_numeric --------------------------------------------------------*/
-static inline __ATTRS_ai int
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_any_numeric(vector float __a) {
+ int __cc;
+ __builtin_s390_vftcisb(__a, 15, &__cc);
+ return __cc != 0;
+}
+#endif
+
+static inline __ATTRS_o_ai int
vec_any_numeric(vector double __a) {
int __cc;
__builtin_s390_vftcidb(__a, 15, &__cc);
@@ -4735,11 +5517,13 @@ vec_andc(vector signed char __a, vector signed char __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_andc(vector bool char __a, vector signed char __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_andc(vector signed char __a, vector bool char __b) {
return __a & ~__b;
@@ -4750,11 +5534,13 @@ vec_andc(vector unsigned char __a, vector unsigned char __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_andc(vector bool char __a, vector unsigned char __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_andc(vector unsigned char __a, vector bool char __b) {
return __a & ~__b;
@@ -4770,11 +5556,13 @@ vec_andc(vector signed short __a, vector signed short __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_andc(vector bool short __a, vector signed short __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_andc(vector signed short __a, vector bool short __b) {
return __a & ~__b;
@@ -4785,11 +5573,13 @@ vec_andc(vector unsigned short __a, vector unsigned short __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_andc(vector bool short __a, vector unsigned short __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_andc(vector unsigned short __a, vector bool short __b) {
return __a & ~__b;
@@ -4805,11 +5595,13 @@ vec_andc(vector signed int __a, vector signed int __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_andc(vector bool int __a, vector signed int __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_andc(vector signed int __a, vector bool int __b) {
return __a & ~__b;
@@ -4820,11 +5612,13 @@ vec_andc(vector unsigned int __a, vector unsigned int __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_andc(vector bool int __a, vector unsigned int __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_andc(vector unsigned int __a, vector bool int __b) {
return __a & ~__b;
@@ -4840,11 +5634,13 @@ vec_andc(vector signed long long __a, vector signed long long __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_andc(vector bool long long __a, vector signed long long __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_andc(vector signed long long __a, vector bool long long __b) {
return __a & ~__b;
@@ -4855,28 +5651,40 @@ vec_andc(vector unsigned long long __a, vector unsigned long long __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_andc(vector bool long long __a, vector unsigned long long __b) {
return __a & ~__b;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_andc(vector unsigned long long __a, vector bool long long __b) {
return __a & ~__b;
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_andc(vector float __a, vector float __b) {
+ return (vector float)((vector unsigned int)__a &
+ ~(vector unsigned int)__b);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_andc(vector double __a, vector double __b) {
return (vector double)((vector unsigned long long)__a &
~(vector unsigned long long)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector double
vec_andc(vector bool long long __a, vector double __b) {
return (vector double)((vector unsigned long long)__a &
~(vector unsigned long long)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector double
vec_andc(vector double __a, vector bool long long __b) {
return (vector double)((vector unsigned long long)__a &
@@ -4895,11 +5703,13 @@ vec_nor(vector signed char __a, vector signed char __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_nor(vector bool char __a, vector signed char __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_nor(vector signed char __a, vector bool char __b) {
return ~(__a | __b);
@@ -4910,11 +5720,13 @@ vec_nor(vector unsigned char __a, vector unsigned char __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_nor(vector bool char __a, vector unsigned char __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_nor(vector unsigned char __a, vector bool char __b) {
return ~(__a | __b);
@@ -4930,11 +5742,13 @@ vec_nor(vector signed short __a, vector signed short __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_nor(vector bool short __a, vector signed short __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_nor(vector signed short __a, vector bool short __b) {
return ~(__a | __b);
@@ -4945,11 +5759,13 @@ vec_nor(vector unsigned short __a, vector unsigned short __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_nor(vector bool short __a, vector unsigned short __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_nor(vector unsigned short __a, vector bool short __b) {
return ~(__a | __b);
@@ -4965,11 +5781,13 @@ vec_nor(vector signed int __a, vector signed int __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_nor(vector bool int __a, vector signed int __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_nor(vector signed int __a, vector bool int __b) {
return ~(__a | __b);
@@ -4980,11 +5798,13 @@ vec_nor(vector unsigned int __a, vector unsigned int __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_nor(vector bool int __a, vector unsigned int __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_nor(vector unsigned int __a, vector bool int __b) {
return ~(__a | __b);
@@ -5000,11 +5820,13 @@ vec_nor(vector signed long long __a, vector signed long long __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_nor(vector bool long long __a, vector signed long long __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_nor(vector signed long long __a, vector bool long long __b) {
return ~(__a | __b);
@@ -5015,34 +5837,274 @@ vec_nor(vector unsigned long long __a, vector unsigned long long __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_nor(vector bool long long __a, vector unsigned long long __b) {
return ~(__a | __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_nor(vector unsigned long long __a, vector bool long long __b) {
return ~(__a | __b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_nor(vector float __a, vector float __b) {
+ return (vector float)~((vector unsigned int)__a |
+ (vector unsigned int)__b);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_nor(vector double __a, vector double __b) {
return (vector double)~((vector unsigned long long)__a |
(vector unsigned long long)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector double
vec_nor(vector bool long long __a, vector double __b) {
return (vector double)~((vector unsigned long long)__a |
(vector unsigned long long)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector double
vec_nor(vector double __a, vector bool long long __b) {
return (vector double)~((vector unsigned long long)__a |
(vector unsigned long long)__b);
}
+/*-- vec_orc ----------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool char
+vec_orc(vector bool char __a, vector bool char __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector signed char
+vec_orc(vector signed char __a, vector signed char __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector unsigned char
+vec_orc(vector unsigned char __a, vector unsigned char __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector bool short
+vec_orc(vector bool short __a, vector bool short __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector signed short
+vec_orc(vector signed short __a, vector signed short __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector unsigned short
+vec_orc(vector unsigned short __a, vector unsigned short __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector bool int
+vec_orc(vector bool int __a, vector bool int __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector signed int
+vec_orc(vector signed int __a, vector signed int __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector unsigned int
+vec_orc(vector unsigned int __a, vector unsigned int __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector bool long long
+vec_orc(vector bool long long __a, vector bool long long __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector signed long long
+vec_orc(vector signed long long __a, vector signed long long __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector unsigned long long
+vec_orc(vector unsigned long long __a, vector unsigned long long __b) {
+ return __a | ~__b;
+}
+
+static inline __ATTRS_o_ai vector float
+vec_orc(vector float __a, vector float __b) {
+ return (vector float)((vector unsigned int)__a &
+ ~(vector unsigned int)__b);
+}
+
+static inline __ATTRS_o_ai vector double
+vec_orc(vector double __a, vector double __b) {
+ return (vector double)((vector unsigned long long)__a &
+ ~(vector unsigned long long)__b);
+}
+#endif
+
+/*-- vec_nand ---------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool char
+vec_nand(vector bool char __a, vector bool char __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector signed char
+vec_nand(vector signed char __a, vector signed char __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned char
+vec_nand(vector unsigned char __a, vector unsigned char __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector bool short
+vec_nand(vector bool short __a, vector bool short __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector signed short
+vec_nand(vector signed short __a, vector signed short __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned short
+vec_nand(vector unsigned short __a, vector unsigned short __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector bool int
+vec_nand(vector bool int __a, vector bool int __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector signed int
+vec_nand(vector signed int __a, vector signed int __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned int
+vec_nand(vector unsigned int __a, vector unsigned int __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector bool long long
+vec_nand(vector bool long long __a, vector bool long long __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector signed long long
+vec_nand(vector signed long long __a, vector signed long long __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned long long
+vec_nand(vector unsigned long long __a, vector unsigned long long __b) {
+ return ~(__a & __b);
+}
+
+static inline __ATTRS_o_ai vector float
+vec_nand(vector float __a, vector float __b) {
+ return (vector float)~((vector unsigned int)__a &
+ (vector unsigned int)__b);
+}
+
+static inline __ATTRS_o_ai vector double
+vec_nand(vector double __a, vector double __b) {
+ return (vector double)~((vector unsigned long long)__a &
+ (vector unsigned long long)__b);
+}
+#endif
+
+/*-- vec_eqv ----------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector bool char
+vec_eqv(vector bool char __a, vector bool char __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector signed char
+vec_eqv(vector signed char __a, vector signed char __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned char
+vec_eqv(vector unsigned char __a, vector unsigned char __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector bool short
+vec_eqv(vector bool short __a, vector bool short __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector signed short
+vec_eqv(vector signed short __a, vector signed short __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned short
+vec_eqv(vector unsigned short __a, vector unsigned short __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector bool int
+vec_eqv(vector bool int __a, vector bool int __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector signed int
+vec_eqv(vector signed int __a, vector signed int __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned int
+vec_eqv(vector unsigned int __a, vector unsigned int __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector bool long long
+vec_eqv(vector bool long long __a, vector bool long long __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector signed long long
+vec_eqv(vector signed long long __a, vector signed long long __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector unsigned long long
+vec_eqv(vector unsigned long long __a, vector unsigned long long __b) {
+ return ~(__a ^ __b);
+}
+
+static inline __ATTRS_o_ai vector float
+vec_eqv(vector float __a, vector float __b) {
+ return (vector float)~((vector unsigned int)__a ^
+ (vector unsigned int)__b);
+}
+
+static inline __ATTRS_o_ai vector double
+vec_eqv(vector double __a, vector double __b) {
+ return (vector double)~((vector unsigned long long)__a ^
+ (vector unsigned long long)__b);
+}
+#endif
+
/*-- vec_cntlz --------------------------------------------------------------*/
static inline __ATTRS_o_ai vector unsigned char
@@ -5323,30 +6385,35 @@ vec_sll(vector signed char __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_sll(vector signed char __a, vector unsigned short __b) {
return (vector signed char)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_sll(vector signed char __a, vector unsigned int __b) {
return (vector signed char)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_sll(vector bool char __a, vector unsigned char __b) {
return (vector bool char)__builtin_s390_vsl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_sll(vector bool char __a, vector unsigned short __b) {
return (vector bool char)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_sll(vector bool char __a, vector unsigned int __b) {
return (vector bool char)__builtin_s390_vsl(
@@ -5358,11 +6425,13 @@ vec_sll(vector unsigned char __a, vector unsigned char __b) {
return __builtin_s390_vsl(__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_sll(vector unsigned char __a, vector unsigned short __b) {
return __builtin_s390_vsl(__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_sll(vector unsigned char __a, vector unsigned int __b) {
return __builtin_s390_vsl(__a, (vector unsigned char)__b);
@@ -5374,30 +6443,35 @@ vec_sll(vector signed short __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_sll(vector signed short __a, vector unsigned short __b) {
return (vector signed short)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_sll(vector signed short __a, vector unsigned int __b) {
return (vector signed short)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_sll(vector bool short __a, vector unsigned char __b) {
return (vector bool short)__builtin_s390_vsl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_sll(vector bool short __a, vector unsigned short __b) {
return (vector bool short)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_sll(vector bool short __a, vector unsigned int __b) {
return (vector bool short)__builtin_s390_vsl(
@@ -5410,12 +6484,14 @@ vec_sll(vector unsigned short __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_sll(vector unsigned short __a, vector unsigned short __b) {
return (vector unsigned short)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_sll(vector unsigned short __a, vector unsigned int __b) {
return (vector unsigned short)__builtin_s390_vsl(
@@ -5428,30 +6504,35 @@ vec_sll(vector signed int __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_sll(vector signed int __a, vector unsigned short __b) {
return (vector signed int)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_sll(vector signed int __a, vector unsigned int __b) {
return (vector signed int)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_sll(vector bool int __a, vector unsigned char __b) {
return (vector bool int)__builtin_s390_vsl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_sll(vector bool int __a, vector unsigned short __b) {
return (vector bool int)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_sll(vector bool int __a, vector unsigned int __b) {
return (vector bool int)__builtin_s390_vsl(
@@ -5464,12 +6545,14 @@ vec_sll(vector unsigned int __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_sll(vector unsigned int __a, vector unsigned short __b) {
return (vector unsigned int)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_sll(vector unsigned int __a, vector unsigned int __b) {
return (vector unsigned int)__builtin_s390_vsl(
@@ -5482,30 +6565,35 @@ vec_sll(vector signed long long __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_sll(vector signed long long __a, vector unsigned short __b) {
return (vector signed long long)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_sll(vector signed long long __a, vector unsigned int __b) {
return (vector signed long long)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_sll(vector bool long long __a, vector unsigned char __b) {
return (vector bool long long)__builtin_s390_vsl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_sll(vector bool long long __a, vector unsigned short __b) {
return (vector bool long long)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_sll(vector bool long long __a, vector unsigned int __b) {
return (vector bool long long)__builtin_s390_vsl(
@@ -5518,12 +6606,14 @@ vec_sll(vector unsigned long long __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_sll(vector unsigned long long __a, vector unsigned short __b) {
return (vector unsigned long long)__builtin_s390_vsl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_sll(vector unsigned long long __a, vector unsigned int __b) {
return (vector unsigned long long)__builtin_s390_vsl(
@@ -5626,6 +6716,20 @@ vec_slb(vector unsigned long long __a, vector unsigned long long __b) {
(vector unsigned char)__a, (vector unsigned char)__b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_slb(vector float __a, vector signed int __b) {
+ return (vector float)__builtin_s390_vslb(
+ (vector unsigned char)__a, (vector unsigned char)__b);
+}
+
+static inline __ATTRS_o_ai vector float
+vec_slb(vector float __a, vector unsigned int __b) {
+ return (vector float)__builtin_s390_vslb(
+ (vector unsigned char)__a, (vector unsigned char)__b);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_slb(vector double __a, vector signed long long __b) {
return (vector double)__builtin_s390_vslb(
@@ -5644,6 +6748,10 @@ extern __ATTRS_o vector signed char
vec_sld(vector signed char __a, vector signed char __b, int __c)
__constant_range(__c, 0, 15);
+extern __ATTRS_o vector bool char
+vec_sld(vector bool char __a, vector bool char __b, int __c)
+ __constant_range(__c, 0, 15);
+
extern __ATTRS_o vector unsigned char
vec_sld(vector unsigned char __a, vector unsigned char __b, int __c)
__constant_range(__c, 0, 15);
@@ -5652,6 +6760,10 @@ extern __ATTRS_o vector signed short
vec_sld(vector signed short __a, vector signed short __b, int __c)
__constant_range(__c, 0, 15);
+extern __ATTRS_o vector bool short
+vec_sld(vector bool short __a, vector bool short __b, int __c)
+ __constant_range(__c, 0, 15);
+
extern __ATTRS_o vector unsigned short
vec_sld(vector unsigned short __a, vector unsigned short __b, int __c)
__constant_range(__c, 0, 15);
@@ -5660,6 +6772,10 @@ extern __ATTRS_o vector signed int
vec_sld(vector signed int __a, vector signed int __b, int __c)
__constant_range(__c, 0, 15);
+extern __ATTRS_o vector bool int
+vec_sld(vector bool int __a, vector bool int __b, int __c)
+ __constant_range(__c, 0, 15);
+
extern __ATTRS_o vector unsigned int
vec_sld(vector unsigned int __a, vector unsigned int __b, int __c)
__constant_range(__c, 0, 15);
@@ -5668,10 +6784,20 @@ extern __ATTRS_o vector signed long long
vec_sld(vector signed long long __a, vector signed long long __b, int __c)
__constant_range(__c, 0, 15);
+extern __ATTRS_o vector bool long long
+vec_sld(vector bool long long __a, vector bool long long __b, int __c)
+ __constant_range(__c, 0, 15);
+
extern __ATTRS_o vector unsigned long long
vec_sld(vector unsigned long long __a, vector unsigned long long __b, int __c)
__constant_range(__c, 0, 15);
+#if __ARCH__ >= 12
+extern __ATTRS_o vector float
+vec_sld(vector float __a, vector float __b, int __c)
+ __constant_range(__c, 0, 15);
+#endif
+
extern __ATTRS_o vector double
vec_sld(vector double __a, vector double __b, int __c)
__constant_range(__c, 0, 15);
@@ -5714,6 +6840,7 @@ extern __ATTRS_o vector unsigned long long
vec_sldw(vector unsigned long long __a, vector unsigned long long __b, int __c)
__constant_range(__c, 0, 3);
+// This prototype is deprecated.
extern __ATTRS_o vector double
vec_sldw(vector double __a, vector double __b, int __c)
__constant_range(__c, 0, 3);
@@ -5730,30 +6857,35 @@ vec_sral(vector signed char __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_sral(vector signed char __a, vector unsigned short __b) {
return (vector signed char)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_sral(vector signed char __a, vector unsigned int __b) {
return (vector signed char)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_sral(vector bool char __a, vector unsigned char __b) {
return (vector bool char)__builtin_s390_vsra(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_sral(vector bool char __a, vector unsigned short __b) {
return (vector bool char)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_sral(vector bool char __a, vector unsigned int __b) {
return (vector bool char)__builtin_s390_vsra(
@@ -5765,11 +6897,13 @@ vec_sral(vector unsigned char __a, vector unsigned char __b) {
return __builtin_s390_vsra(__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_sral(vector unsigned char __a, vector unsigned short __b) {
return __builtin_s390_vsra(__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_sral(vector unsigned char __a, vector unsigned int __b) {
return __builtin_s390_vsra(__a, (vector unsigned char)__b);
@@ -5781,30 +6915,35 @@ vec_sral(vector signed short __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_sral(vector signed short __a, vector unsigned short __b) {
return (vector signed short)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_sral(vector signed short __a, vector unsigned int __b) {
return (vector signed short)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_sral(vector bool short __a, vector unsigned char __b) {
return (vector bool short)__builtin_s390_vsra(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_sral(vector bool short __a, vector unsigned short __b) {
return (vector bool short)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_sral(vector bool short __a, vector unsigned int __b) {
return (vector bool short)__builtin_s390_vsra(
@@ -5817,12 +6956,14 @@ vec_sral(vector unsigned short __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_sral(vector unsigned short __a, vector unsigned short __b) {
return (vector unsigned short)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_sral(vector unsigned short __a, vector unsigned int __b) {
return (vector unsigned short)__builtin_s390_vsra(
@@ -5835,30 +6976,35 @@ vec_sral(vector signed int __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_sral(vector signed int __a, vector unsigned short __b) {
return (vector signed int)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_sral(vector signed int __a, vector unsigned int __b) {
return (vector signed int)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_sral(vector bool int __a, vector unsigned char __b) {
return (vector bool int)__builtin_s390_vsra(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_sral(vector bool int __a, vector unsigned short __b) {
return (vector bool int)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_sral(vector bool int __a, vector unsigned int __b) {
return (vector bool int)__builtin_s390_vsra(
@@ -5871,12 +7017,14 @@ vec_sral(vector unsigned int __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_sral(vector unsigned int __a, vector unsigned short __b) {
return (vector unsigned int)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_sral(vector unsigned int __a, vector unsigned int __b) {
return (vector unsigned int)__builtin_s390_vsra(
@@ -5889,30 +7037,35 @@ vec_sral(vector signed long long __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_sral(vector signed long long __a, vector unsigned short __b) {
return (vector signed long long)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_sral(vector signed long long __a, vector unsigned int __b) {
return (vector signed long long)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_sral(vector bool long long __a, vector unsigned char __b) {
return (vector bool long long)__builtin_s390_vsra(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_sral(vector bool long long __a, vector unsigned short __b) {
return (vector bool long long)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_sral(vector bool long long __a, vector unsigned int __b) {
return (vector bool long long)__builtin_s390_vsra(
@@ -5925,12 +7078,14 @@ vec_sral(vector unsigned long long __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_sral(vector unsigned long long __a, vector unsigned short __b) {
return (vector unsigned long long)__builtin_s390_vsra(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_sral(vector unsigned long long __a, vector unsigned int __b) {
return (vector unsigned long long)__builtin_s390_vsra(
@@ -6033,6 +7188,20 @@ vec_srab(vector unsigned long long __a, vector unsigned long long __b) {
(vector unsigned char)__a, (vector unsigned char)__b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_srab(vector float __a, vector signed int __b) {
+ return (vector float)__builtin_s390_vsrab(
+ (vector unsigned char)__a, (vector unsigned char)__b);
+}
+
+static inline __ATTRS_o_ai vector float
+vec_srab(vector float __a, vector unsigned int __b) {
+ return (vector float)__builtin_s390_vsrab(
+ (vector unsigned char)__a, (vector unsigned char)__b);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_srab(vector double __a, vector signed long long __b) {
return (vector double)__builtin_s390_vsrab(
@@ -6053,30 +7222,35 @@ vec_srl(vector signed char __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_srl(vector signed char __a, vector unsigned short __b) {
return (vector signed char)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_srl(vector signed char __a, vector unsigned int __b) {
return (vector signed char)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_srl(vector bool char __a, vector unsigned char __b) {
return (vector bool char)__builtin_s390_vsrl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_srl(vector bool char __a, vector unsigned short __b) {
return (vector bool char)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool char
vec_srl(vector bool char __a, vector unsigned int __b) {
return (vector bool char)__builtin_s390_vsrl(
@@ -6088,11 +7262,13 @@ vec_srl(vector unsigned char __a, vector unsigned char __b) {
return __builtin_s390_vsrl(__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_srl(vector unsigned char __a, vector unsigned short __b) {
return __builtin_s390_vsrl(__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_srl(vector unsigned char __a, vector unsigned int __b) {
return __builtin_s390_vsrl(__a, (vector unsigned char)__b);
@@ -6104,30 +7280,35 @@ vec_srl(vector signed short __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_srl(vector signed short __a, vector unsigned short __b) {
return (vector signed short)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_srl(vector signed short __a, vector unsigned int __b) {
return (vector signed short)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_srl(vector bool short __a, vector unsigned char __b) {
return (vector bool short)__builtin_s390_vsrl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_srl(vector bool short __a, vector unsigned short __b) {
return (vector bool short)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool short
vec_srl(vector bool short __a, vector unsigned int __b) {
return (vector bool short)__builtin_s390_vsrl(
@@ -6140,12 +7321,14 @@ vec_srl(vector unsigned short __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_srl(vector unsigned short __a, vector unsigned short __b) {
return (vector unsigned short)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_srl(vector unsigned short __a, vector unsigned int __b) {
return (vector unsigned short)__builtin_s390_vsrl(
@@ -6158,30 +7341,35 @@ vec_srl(vector signed int __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_srl(vector signed int __a, vector unsigned short __b) {
return (vector signed int)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_srl(vector signed int __a, vector unsigned int __b) {
return (vector signed int)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_srl(vector bool int __a, vector unsigned char __b) {
return (vector bool int)__builtin_s390_vsrl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_srl(vector bool int __a, vector unsigned short __b) {
return (vector bool int)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool int
vec_srl(vector bool int __a, vector unsigned int __b) {
return (vector bool int)__builtin_s390_vsrl(
@@ -6194,12 +7382,14 @@ vec_srl(vector unsigned int __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_srl(vector unsigned int __a, vector unsigned short __b) {
return (vector unsigned int)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_srl(vector unsigned int __a, vector unsigned int __b) {
return (vector unsigned int)__builtin_s390_vsrl(
@@ -6212,30 +7402,35 @@ vec_srl(vector signed long long __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_srl(vector signed long long __a, vector unsigned short __b) {
return (vector signed long long)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_srl(vector signed long long __a, vector unsigned int __b) {
return (vector signed long long)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_srl(vector bool long long __a, vector unsigned char __b) {
return (vector bool long long)__builtin_s390_vsrl(
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_srl(vector bool long long __a, vector unsigned short __b) {
return (vector bool long long)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector bool long long
vec_srl(vector bool long long __a, vector unsigned int __b) {
return (vector bool long long)__builtin_s390_vsrl(
@@ -6248,12 +7443,14 @@ vec_srl(vector unsigned long long __a, vector unsigned char __b) {
(vector unsigned char)__a, __b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_srl(vector unsigned long long __a, vector unsigned short __b) {
return (vector unsigned long long)__builtin_s390_vsrl(
(vector unsigned char)__a, (vector unsigned char)__b);
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_srl(vector unsigned long long __a, vector unsigned int __b) {
return (vector unsigned long long)__builtin_s390_vsrl(
@@ -6356,6 +7553,20 @@ vec_srb(vector unsigned long long __a, vector unsigned long long __b) {
(vector unsigned char)__a, (vector unsigned char)__b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_srb(vector float __a, vector signed int __b) {
+ return (vector float)__builtin_s390_vsrlb(
+ (vector unsigned char)__a, (vector unsigned char)__b);
+}
+
+static inline __ATTRS_o_ai vector float
+vec_srb(vector float __a, vector unsigned int __b) {
+ return (vector float)__builtin_s390_vsrlb(
+ (vector unsigned char)__a, (vector unsigned char)__b);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_srb(vector double __a, vector signed long long __b) {
return (vector double)__builtin_s390_vsrlb(
@@ -6390,6 +7601,13 @@ vec_abs(vector signed long long __a) {
return vec_sel(__a, -__a, vec_cmplt(__a, (vector signed long long)0));
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_abs(vector float __a) {
+ return __builtin_s390_vflpsb(__a);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_abs(vector double __a) {
return __builtin_s390_vflpdb(__a);
@@ -6397,7 +7615,14 @@ vec_abs(vector double __a) {
/*-- vec_nabs ---------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_nabs(vector float __a) {
+ return __builtin_s390_vflnsb(__a);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_nabs(vector double __a) {
return __builtin_s390_vflndb(__a);
}
@@ -6409,12 +7634,14 @@ vec_max(vector signed char __a, vector signed char __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_max(vector signed char __a, vector bool char __b) {
vector signed char __bc = (vector signed char)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_max(vector bool char __a, vector signed char __b) {
vector signed char __ac = (vector signed char)__a;
@@ -6426,12 +7653,14 @@ vec_max(vector unsigned char __a, vector unsigned char __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_max(vector unsigned char __a, vector bool char __b) {
vector unsigned char __bc = (vector unsigned char)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_max(vector bool char __a, vector unsigned char __b) {
vector unsigned char __ac = (vector unsigned char)__a;
@@ -6443,12 +7672,14 @@ vec_max(vector signed short __a, vector signed short __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_max(vector signed short __a, vector bool short __b) {
vector signed short __bc = (vector signed short)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_max(vector bool short __a, vector signed short __b) {
vector signed short __ac = (vector signed short)__a;
@@ -6460,12 +7691,14 @@ vec_max(vector unsigned short __a, vector unsigned short __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_max(vector unsigned short __a, vector bool short __b) {
vector unsigned short __bc = (vector unsigned short)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_max(vector bool short __a, vector unsigned short __b) {
vector unsigned short __ac = (vector unsigned short)__a;
@@ -6477,12 +7710,14 @@ vec_max(vector signed int __a, vector signed int __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_max(vector signed int __a, vector bool int __b) {
vector signed int __bc = (vector signed int)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_max(vector bool int __a, vector signed int __b) {
vector signed int __ac = (vector signed int)__a;
@@ -6494,12 +7729,14 @@ vec_max(vector unsigned int __a, vector unsigned int __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_max(vector unsigned int __a, vector bool int __b) {
vector unsigned int __bc = (vector unsigned int)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_max(vector bool int __a, vector unsigned int __b) {
vector unsigned int __ac = (vector unsigned int)__a;
@@ -6511,12 +7748,14 @@ vec_max(vector signed long long __a, vector signed long long __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_max(vector signed long long __a, vector bool long long __b) {
vector signed long long __bc = (vector signed long long)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_max(vector bool long long __a, vector signed long long __b) {
vector signed long long __ac = (vector signed long long)__a;
@@ -6528,21 +7767,34 @@ vec_max(vector unsigned long long __a, vector unsigned long long __b) {
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_max(vector unsigned long long __a, vector bool long long __b) {
vector unsigned long long __bc = (vector unsigned long long)__b;
return vec_sel(__bc, __a, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_max(vector bool long long __a, vector unsigned long long __b) {
vector unsigned long long __ac = (vector unsigned long long)__a;
return vec_sel(__b, __ac, vec_cmpgt(__ac, __b));
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_max(vector float __a, vector float __b) {
+ return __builtin_s390_vfmaxsb(__a, __b, 0);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_max(vector double __a, vector double __b) {
+#if __ARCH__ >= 12
+ return __builtin_s390_vfmaxdb(__a, __b, 0);
+#else
return vec_sel(__b, __a, vec_cmpgt(__a, __b));
+#endif
}
/*-- vec_min ----------------------------------------------------------------*/
@@ -6552,12 +7804,14 @@ vec_min(vector signed char __a, vector signed char __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_min(vector signed char __a, vector bool char __b) {
vector signed char __bc = (vector signed char)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed char
vec_min(vector bool char __a, vector signed char __b) {
vector signed char __ac = (vector signed char)__a;
@@ -6569,12 +7823,14 @@ vec_min(vector unsigned char __a, vector unsigned char __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_min(vector unsigned char __a, vector bool char __b) {
vector unsigned char __bc = (vector unsigned char)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned char
vec_min(vector bool char __a, vector unsigned char __b) {
vector unsigned char __ac = (vector unsigned char)__a;
@@ -6586,12 +7842,14 @@ vec_min(vector signed short __a, vector signed short __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_min(vector signed short __a, vector bool short __b) {
vector signed short __bc = (vector signed short)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed short
vec_min(vector bool short __a, vector signed short __b) {
vector signed short __ac = (vector signed short)__a;
@@ -6603,12 +7861,14 @@ vec_min(vector unsigned short __a, vector unsigned short __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_min(vector unsigned short __a, vector bool short __b) {
vector unsigned short __bc = (vector unsigned short)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned short
vec_min(vector bool short __a, vector unsigned short __b) {
vector unsigned short __ac = (vector unsigned short)__a;
@@ -6620,12 +7880,14 @@ vec_min(vector signed int __a, vector signed int __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_min(vector signed int __a, vector bool int __b) {
vector signed int __bc = (vector signed int)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed int
vec_min(vector bool int __a, vector signed int __b) {
vector signed int __ac = (vector signed int)__a;
@@ -6637,12 +7899,14 @@ vec_min(vector unsigned int __a, vector unsigned int __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_min(vector unsigned int __a, vector bool int __b) {
vector unsigned int __bc = (vector unsigned int)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned int
vec_min(vector bool int __a, vector unsigned int __b) {
vector unsigned int __ac = (vector unsigned int)__a;
@@ -6654,12 +7918,14 @@ vec_min(vector signed long long __a, vector signed long long __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_min(vector signed long long __a, vector bool long long __b) {
vector signed long long __bc = (vector signed long long)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_min(vector bool long long __a, vector signed long long __b) {
vector signed long long __ac = (vector signed long long)__a;
@@ -6671,21 +7937,34 @@ vec_min(vector unsigned long long __a, vector unsigned long long __b) {
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_min(vector unsigned long long __a, vector bool long long __b) {
vector unsigned long long __bc = (vector unsigned long long)__b;
return vec_sel(__a, __bc, vec_cmpgt(__a, __bc));
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_min(vector bool long long __a, vector unsigned long long __b) {
vector unsigned long long __ac = (vector unsigned long long)__a;
return vec_sel(__ac, __b, vec_cmpgt(__ac, __b));
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_min(vector float __a, vector float __b) {
+ return __builtin_s390_vfminsb(__a, __b, 0);
+}
+#endif
+
static inline __ATTRS_o_ai vector double
vec_min(vector double __a, vector double __b) {
+#if __ARCH__ >= 12
+ return __builtin_s390_vfmindb(__a, __b, 0);
+#else
return vec_sel(__a, __b, vec_cmpgt(__a, __b));
+#endif
}
/*-- vec_add_u128 -----------------------------------------------------------*/
@@ -7126,6 +8405,13 @@ vec_mulo(vector unsigned int __a, vector unsigned int __b) {
return __builtin_s390_vmlof(__a, __b);
}
+/*-- vec_msum_u128 ----------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+#define vec_msum_u128(X, Y, Z, W) \
+ ((vector unsigned char)__builtin_s390_vmslg((X), (Y), (Z), (W)));
+#endif
+
/*-- vec_sub_u128 -----------------------------------------------------------*/
static inline __ATTRS_ai vector unsigned char
@@ -7263,6 +8549,14 @@ vec_test_mask(vector unsigned long long __a, vector unsigned long long __b) {
(vector unsigned char)__b);
}
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai int
+vec_test_mask(vector float __a, vector unsigned int __b) {
+ return __builtin_s390_vtm((vector unsigned char)__a,
+ (vector unsigned char)__b);
+}
+#endif
+
static inline __ATTRS_o_ai int
vec_test_mask(vector double __a, vector unsigned long long __b) {
return __builtin_s390_vtm((vector unsigned char)__a,
@@ -7271,27 +8565,77 @@ vec_test_mask(vector double __a, vector unsigned long long __b) {
/*-- vec_madd ---------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_madd(vector float __a, vector float __b, vector float __c) {
+ return __builtin_s390_vfmasb(__a, __b, __c);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_madd(vector double __a, vector double __b, vector double __c) {
return __builtin_s390_vfmadb(__a, __b, __c);
}
/*-- vec_msub ---------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_msub(vector float __a, vector float __b, vector float __c) {
+ return __builtin_s390_vfmssb(__a, __b, __c);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_msub(vector double __a, vector double __b, vector double __c) {
return __builtin_s390_vfmsdb(__a, __b, __c);
}
+/*-- vec_nmadd ---------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_nmadd(vector float __a, vector float __b, vector float __c) {
+ return __builtin_s390_vfnmasb(__a, __b, __c);
+}
+
+static inline __ATTRS_o_ai vector double
+vec_nmadd(vector double __a, vector double __b, vector double __c) {
+ return __builtin_s390_vfnmadb(__a, __b, __c);
+}
+#endif
+
+/*-- vec_nmsub ---------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_nmsub(vector float __a, vector float __b, vector float __c) {
+ return __builtin_s390_vfnmssb(__a, __b, __c);
+}
+
+static inline __ATTRS_o_ai vector double
+vec_nmsub(vector double __a, vector double __b, vector double __c) {
+ return __builtin_s390_vfnmsdb(__a, __b, __c);
+}
+#endif
+
/*-- vec_sqrt ---------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_sqrt(vector float __a) {
+ return __builtin_s390_vfsqsb(__a);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_sqrt(vector double __a) {
return __builtin_s390_vfsqdb(__a);
}
/*-- vec_ld2f ---------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_ai vector double
vec_ld2f(const float *__ptr) {
typedef float __v2f32 __attribute__((__vector_size__(8)));
@@ -7300,6 +8644,7 @@ vec_ld2f(const float *__ptr) {
/*-- vec_st2f ---------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_ai void
vec_st2f(vector double __a, float *__ptr) {
typedef float __v2f32 __attribute__((__vector_size__(8)));
@@ -7308,6 +8653,7 @@ vec_st2f(vector double __a, float *__ptr) {
/*-- vec_ctd ----------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector double
vec_ctd(vector signed long long __a, int __b)
__constant_range(__b, 0, 31) {
@@ -7316,6 +8662,7 @@ vec_ctd(vector signed long long __a, int __b)
return __conv;
}
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector double
vec_ctd(vector unsigned long long __a, int __b)
__constant_range(__b, 0, 31) {
@@ -7326,6 +8673,7 @@ vec_ctd(vector unsigned long long __a, int __b)
/*-- vec_ctsl ---------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector signed long long
vec_ctsl(vector double __a, int __b)
__constant_range(__b, 0, 31) {
@@ -7335,6 +8683,7 @@ vec_ctsl(vector double __a, int __b)
/*-- vec_ctul ---------------------------------------------------------------*/
+// This prototype is deprecated.
static inline __ATTRS_o_ai vector unsigned long long
vec_ctul(vector double __a, int __b)
__constant_range(__b, 0, 31) {
@@ -7342,16 +8691,79 @@ vec_ctul(vector double __a, int __b)
return __builtin_convertvector(__a, vector unsigned long long);
}
-/*-- vec_roundp -------------------------------------------------------------*/
+/*-- vec_doublee ------------------------------------------------------------*/
+#if __ARCH__ >= 12
static inline __ATTRS_ai vector double
+vec_doublee(vector float __a) {
+ typedef float __v2f32 __attribute__((__vector_size__(8)));
+ __v2f32 __pack = __builtin_shufflevector(__a, __a, 0, 2);
+ return __builtin_convertvector(__pack, vector double);
+}
+#endif
+
+/*-- vec_floate -------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_ai vector float
+vec_floate(vector double __a) {
+ typedef float __v2f32 __attribute__((__vector_size__(8)));
+ __v2f32 __pack = __builtin_convertvector(__a, __v2f32);
+ return __builtin_shufflevector(__pack, __pack, 0, -1, 1, -1);
+}
+#endif
+
+/*-- vec_double -------------------------------------------------------------*/
+
+static inline __ATTRS_o_ai vector double
+vec_double(vector signed long long __a) {
+ return __builtin_convertvector(__a, vector double);
+}
+
+static inline __ATTRS_o_ai vector double
+vec_double(vector unsigned long long __a) {
+ return __builtin_convertvector(__a, vector double);
+}
+
+/*-- vec_signed -------------------------------------------------------------*/
+
+static inline __ATTRS_o_ai vector signed long long
+vec_signed(vector double __a) {
+ return __builtin_convertvector(__a, vector signed long long);
+}
+
+/*-- vec_unsigned -----------------------------------------------------------*/
+
+static inline __ATTRS_o_ai vector unsigned long long
+vec_unsigned(vector double __a) {
+ return __builtin_convertvector(__a, vector unsigned long long);
+}
+
+/*-- vec_roundp -------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_roundp(vector float __a) {
+ return __builtin_s390_vfisb(__a, 4, 6);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_roundp(vector double __a) {
return __builtin_s390_vfidb(__a, 4, 6);
}
/*-- vec_ceil ---------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_ceil(vector float __a) {
+ // On this platform, vec_ceil never triggers the IEEE-inexact exception.
+ return __builtin_s390_vfisb(__a, 4, 6);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_ceil(vector double __a) {
// On this platform, vec_ceil never triggers the IEEE-inexact exception.
return __builtin_s390_vfidb(__a, 4, 6);
@@ -7359,14 +8771,29 @@ vec_ceil(vector double __a) {
/*-- vec_roundm -------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_roundm(vector float __a) {
+ return __builtin_s390_vfisb(__a, 4, 7);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_roundm(vector double __a) {
return __builtin_s390_vfidb(__a, 4, 7);
}
/*-- vec_floor --------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_floor(vector float __a) {
+ // On this platform, vec_floor never triggers the IEEE-inexact exception.
+ return __builtin_s390_vfisb(__a, 4, 7);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_floor(vector double __a) {
// On this platform, vec_floor never triggers the IEEE-inexact exception.
return __builtin_s390_vfidb(__a, 4, 7);
@@ -7374,14 +8801,29 @@ vec_floor(vector double __a) {
/*-- vec_roundz -------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_roundz(vector float __a) {
+ return __builtin_s390_vfisb(__a, 4, 5);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_roundz(vector double __a) {
return __builtin_s390_vfidb(__a, 4, 5);
}
/*-- vec_trunc --------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_trunc(vector float __a) {
+ // On this platform, vec_trunc never triggers the IEEE-inexact exception.
+ return __builtin_s390_vfisb(__a, 4, 5);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_trunc(vector double __a) {
// On this platform, vec_trunc never triggers the IEEE-inexact exception.
return __builtin_s390_vfidb(__a, 4, 5);
@@ -7389,22 +8831,104 @@ vec_trunc(vector double __a) {
/*-- vec_roundc -------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_roundc(vector float __a) {
+ return __builtin_s390_vfisb(__a, 4, 0);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_roundc(vector double __a) {
return __builtin_s390_vfidb(__a, 4, 0);
}
+/*-- vec_rint ---------------------------------------------------------------*/
+
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_rint(vector float __a) {
+ // vec_rint may trigger the IEEE-inexact exception.
+ return __builtin_s390_vfisb(__a, 0, 0);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
+vec_rint(vector double __a) {
+ // vec_rint may trigger the IEEE-inexact exception.
+ return __builtin_s390_vfidb(__a, 0, 0);
+}
+
/*-- vec_round --------------------------------------------------------------*/
-static inline __ATTRS_ai vector double
+#if __ARCH__ >= 12
+static inline __ATTRS_o_ai vector float
+vec_round(vector float __a) {
+ return __builtin_s390_vfisb(__a, 4, 4);
+}
+#endif
+
+static inline __ATTRS_o_ai vector double
vec_round(vector double __a) {
return __builtin_s390_vfidb(__a, 4, 4);
}
/*-- vec_fp_test_data_class -------------------------------------------------*/
+#if __ARCH__ >= 12
+extern __ATTRS_o vector bool int
+vec_fp_test_data_class(vector float __a, int __b, int *__c)
+ __constant_range(__b, 0, 4095);
+
+extern __ATTRS_o vector bool long long
+vec_fp_test_data_class(vector double __a, int __b, int *__c)
+ __constant_range(__b, 0, 4095);
+
+#define vec_fp_test_data_class(X, Y, Z) \
+ ((__typeof__((vec_fp_test_data_class)((X), (Y), (Z)))) \
+ __extension__ ({ \
+ vector unsigned char __res; \
+ vector unsigned char __x = (vector unsigned char)(X); \
+ int *__z = (Z); \
+ switch (sizeof ((X)[0])) { \
+ case 4: __res = (vector unsigned char) \
+ __builtin_s390_vftcisb((vector float)__x, (Y), __z); \
+ break; \
+ default: __res = (vector unsigned char) \
+ __builtin_s390_vftcidb((vector double)__x, (Y), __z); \
+ break; \
+ } __res; }))
+#else
#define vec_fp_test_data_class(X, Y, Z) \
((vector bool long long)__builtin_s390_vftcidb((X), (Y), (Z)))
+#endif
+
+#define __VEC_CLASS_FP_ZERO_P (1 << 11)
+#define __VEC_CLASS_FP_ZERO_N (1 << 10)
+#define __VEC_CLASS_FP_ZERO (__VEC_CLASS_FP_ZERO_P | __VEC_CLASS_FP_ZERO_N)
+#define __VEC_CLASS_FP_NORMAL_P (1 << 9)
+#define __VEC_CLASS_FP_NORMAL_N (1 << 8)
+#define __VEC_CLASS_FP_NORMAL (__VEC_CLASS_FP_NORMAL_P | \
+ __VEC_CLASS_FP_NORMAL_N)
+#define __VEC_CLASS_FP_SUBNORMAL_P (1 << 7)
+#define __VEC_CLASS_FP_SUBNORMAL_N (1 << 6)
+#define __VEC_CLASS_FP_SUBNORMAL (__VEC_CLASS_FP_SUBNORMAL_P | \
+ __VEC_CLASS_FP_SUBNORMAL_N)
+#define __VEC_CLASS_FP_INFINITY_P (1 << 5)
+#define __VEC_CLASS_FP_INFINITY_N (1 << 4)
+#define __VEC_CLASS_FP_INFINITY (__VEC_CLASS_FP_INFINITY_P | \
+ __VEC_CLASS_FP_INFINITY_N)
+#define __VEC_CLASS_FP_QNAN_P (1 << 3)
+#define __VEC_CLASS_FP_QNAN_N (1 << 2)
+#define __VEC_CLASS_FP_QNAN (__VEC_CLASS_FP_QNAN_P | __VEC_CLASS_FP_QNAN_N)
+#define __VEC_CLASS_FP_SNAN_P (1 << 1)
+#define __VEC_CLASS_FP_SNAN_N (1 << 0)
+#define __VEC_CLASS_FP_SNAN (__VEC_CLASS_FP_SNAN_P | __VEC_CLASS_FP_SNAN_N)
+#define __VEC_CLASS_FP_NAN (__VEC_CLASS_FP_QNAN | __VEC_CLASS_FP_SNAN)
+#define __VEC_CLASS_FP_NOT_NORMAL (__VEC_CLASS_FP_NAN | \
+ __VEC_CLASS_FP_SUBNORMAL | \
+ __VEC_CLASS_FP_ZERO | \
+ __VEC_CLASS_FP_INFINITY)
/*-- vec_cp_until_zero ------------------------------------------------------*/
diff --git a/lib/Index/IndexingAction.cpp b/lib/Index/IndexingAction.cpp
index cac24d4b9c4c..84d31200bab4 100644
--- a/lib/Index/IndexingAction.cpp
+++ b/lib/Index/IndexingAction.cpp
@@ -177,6 +177,18 @@ void index::indexASTUnit(ASTUnit &Unit,
DataConsumer->finish();
}
+void index::indexTopLevelDecls(ASTContext &Ctx, ArrayRef<const Decl *> Decls,
+ std::shared_ptr<IndexDataConsumer> DataConsumer,
+ IndexingOptions Opts) {
+ IndexingContext IndexCtx(Opts, *DataConsumer);
+ IndexCtx.setASTContext(Ctx);
+
+ DataConsumer->initialize(Ctx);
+ for (const Decl *D : Decls)
+ IndexCtx.indexTopLevelDecl(D);
+ DataConsumer->finish();
+}
+
void index::indexModuleFile(serialization::ModuleFile &Mod,
ASTReader &Reader,
std::shared_ptr<IndexDataConsumer> DataConsumer,
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index c4aa51d62f02..addee691e804 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -260,8 +260,10 @@ static const Decl *adjustParent(const Decl *Parent) {
static const Decl *getCanonicalDecl(const Decl *D) {
D = D->getCanonicalDecl();
if (auto TD = dyn_cast<TemplateDecl>(D)) {
- D = TD->getTemplatedDecl();
- assert(D->isCanonicalDecl());
+ if (auto TTD = TD->getTemplatedDecl()) {
+ D = TTD;
+ assert(D->isCanonicalDecl());
+ }
}
return D;
diff --git a/lib/Lex/MacroArgs.cpp b/lib/Lex/MacroArgs.cpp
index a201d1659073..f791d8d4bacc 100644
--- a/lib/Lex/MacroArgs.cpp
+++ b/lib/Lex/MacroArgs.cpp
@@ -52,14 +52,14 @@ MacroArgs *MacroArgs::create(const MacroInfo *MI,
UnexpArgTokens.size() * sizeof(Token));
// Construct the MacroArgs object.
new (Result)
- MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumArgs());
+ MacroArgs(UnexpArgTokens.size(), VarargsElided, MI->getNumParams());
} else {
Result = *ResultEnt;
// Unlink this node from the preprocessors singly linked list.
*ResultEnt = Result->ArgCache;
Result->NumUnexpArgTokens = UnexpArgTokens.size();
Result->VarargsElided = VarargsElided;
- Result->NumMacroArgs = MI->getNumArgs();
+ Result->NumMacroArgs = MI->getNumParams();
}
// Copy the actual unexpanded tokens to immediately after the result ptr.
@@ -148,11 +148,11 @@ bool MacroArgs::ArgNeedsPreexpansion(const Token *ArgTok,
const std::vector<Token> &
MacroArgs::getPreExpArgument(unsigned Arg, const MacroInfo *MI,
Preprocessor &PP) {
- assert(Arg < MI->getNumArgs() && "Invalid argument number!");
+ assert(Arg < MI->getNumParams() && "Invalid argument number!");
// If we have already computed this, return it.
- if (PreExpArgTokens.size() < MI->getNumArgs())
- PreExpArgTokens.resize(MI->getNumArgs());
+ if (PreExpArgTokens.size() < MI->getNumParams())
+ PreExpArgTokens.resize(MI->getNumParams());
std::vector<Token> &Result = PreExpArgTokens[Arg];
if (!Result.empty()) return Result;
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index 1e5deeb1919b..6dc7841bc160 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -17,8 +17,8 @@ using namespace clang;
MacroInfo::MacroInfo(SourceLocation DefLoc)
: Location(DefLoc),
- ArgumentList(nullptr),
- NumArguments(0),
+ ParameterList(nullptr),
+ NumParameters(0),
IsDefinitionLengthCached(false),
IsFunctionLike(false),
IsC99Varargs(false),
@@ -74,7 +74,7 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
// Check # tokens in replacement, number of args, and various flags all match.
if (ReplacementTokens.size() != Other.ReplacementTokens.size() ||
- getNumArgs() != Other.getNumArgs() ||
+ getNumParams() != Other.getNumParams() ||
isFunctionLike() != Other.isFunctionLike() ||
isC99Varargs() != Other.isC99Varargs() ||
isGNUVarargs() != Other.isGNUVarargs())
@@ -82,7 +82,8 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
if (Lexically) {
// Check arguments.
- for (arg_iterator I = arg_begin(), OI = Other.arg_begin(), E = arg_end();
+ for (param_iterator I = param_begin(), OI = Other.param_begin(),
+ E = param_end();
I != E; ++I, ++OI)
if (*I != *OI) return false;
}
@@ -109,10 +110,10 @@ bool MacroInfo::isIdenticalTo(const MacroInfo &Other, Preprocessor &PP,
return false;
// With syntactic equivalence the parameter names can be different as long
// as they are used in the same place.
- int AArgNum = getArgumentNum(A.getIdentifierInfo());
+ int AArgNum = getParameterNum(A.getIdentifierInfo());
if (AArgNum == -1)
return false;
- if (AArgNum != Other.getArgumentNum(B.getIdentifierInfo()))
+ if (AArgNum != Other.getParameterNum(B.getIdentifierInfo()))
return false;
continue;
}
@@ -141,12 +142,12 @@ LLVM_DUMP_METHOD void MacroInfo::dump() const {
Out << "\n #define <macro>";
if (IsFunctionLike) {
Out << "(";
- for (unsigned I = 0; I != NumArguments; ++I) {
+ for (unsigned I = 0; I != NumParameters; ++I) {
if (I) Out << ", ";
- Out << ArgumentList[I]->getName();
+ Out << ParameterList[I]->getName();
}
if (IsC99Varargs || IsGNUVarargs) {
- if (NumArguments && IsC99Varargs) Out << ", ";
+ if (NumParameters && IsC99Varargs) Out << ", ";
Out << "...";
}
Out << ")";
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 8c79e50176e1..b2450f516ba2 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -220,26 +220,18 @@ bool Preprocessor::CheckMacroName(Token &MacroNameTok, MacroUse isDefineUndef,
return Diag(MacroNameTok, diag::err_pp_missing_macro_name);
IdentifierInfo *II = MacroNameTok.getIdentifierInfo();
- if (!II) {
- bool Invalid = false;
- std::string Spelling = getSpelling(MacroNameTok, &Invalid);
- if (Invalid)
- return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
- II = getIdentifierInfo(Spelling);
-
- if (!II->isCPlusPlusOperatorKeyword())
- return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
+ if (!II)
+ return Diag(MacroNameTok, diag::err_pp_macro_not_identifier);
+ if (II->isCPlusPlusOperatorKeyword()) {
// C++ 2.5p2: Alternative tokens behave the same as its primary token
// except for their spellings.
Diag(MacroNameTok, getLangOpts().MicrosoftExt
? diag::ext_pp_operator_used_as_macro_name
: diag::err_pp_operator_used_as_macro_name)
<< II << MacroNameTok.getKind();
-
// Allow #defining |and| and friends for Microsoft compatibility or
// recovery when legacy C headers are included in C++.
- MacroNameTok.setIdentifierInfo(II);
}
if ((isDefineUndef != MU_Other) && II->getPPKeywordID() == tok::pp_defined) {
@@ -2143,11 +2135,11 @@ void Preprocessor::HandleIncludeMacrosDirective(SourceLocation HashLoc,
// Preprocessor Macro Directive Handling.
//===----------------------------------------------------------------------===//
-/// ReadMacroDefinitionArgList - The ( starting an argument list of a macro
+/// ReadMacroParameterList - The ( starting an argument list of a macro
/// definition has just been read. Lex the rest of the arguments and the
/// closing ), updating MI with what we learn. Return true if an error occurs
/// parsing the arg list.
-bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
+bool Preprocessor::ReadMacroParameterList(MacroInfo *MI, Token &Tok) {
SmallVector<IdentifierInfo*, 32> Arguments;
while (true) {
@@ -2181,7 +2173,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
// Add the __VA_ARGS__ identifier as an argument.
Arguments.push_back(Ident__VA_ARGS__);
MI->setIsC99Varargs();
- MI->setArgumentList(Arguments, BP);
+ MI->setParameterList(Arguments, BP);
return false;
case tok::eod: // #define X(
Diag(Tok, diag::err_pp_missing_rparen_in_macro_def);
@@ -2215,7 +2207,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
Diag(Tok, diag::err_pp_expected_comma_in_arg_list);
return true;
case tok::r_paren: // #define X(A)
- MI->setArgumentList(Arguments, BP);
+ MI->setParameterList(Arguments, BP);
return false;
case tok::comma: // #define X(A,
break;
@@ -2231,7 +2223,7 @@ bool Preprocessor::ReadMacroDefinitionArgList(MacroInfo *MI, Token &Tok) {
}
MI->setIsGNUVarargs();
- MI->setArgumentList(Arguments, BP);
+ MI->setParameterList(Arguments, BP);
return false;
}
}
@@ -2280,28 +2272,20 @@ static bool isConfigurationPattern(Token &MacroName, MacroInfo *MI,
MI->getNumTokens() == 0;
}
-/// HandleDefineDirective - Implements \#define. This consumes the entire macro
-/// line then lets the caller lex the next real token.
-void Preprocessor::HandleDefineDirective(Token &DefineTok,
- bool ImmediatelyAfterHeaderGuard) {
- ++NumDefined;
+// ReadOptionalMacroParameterListAndBody - This consumes all (i.e. the
+// entire line) of the macro's tokens and adds them to MacroInfo, and while
+// doing so performs certain validity checks including (but not limited to):
+// - # (stringization) is followed by a macro parameter
+//
+// Returns a nullptr if an invalid sequence of tokens is encountered or returns
+// a pointer to a MacroInfo object.
- Token MacroNameTok;
- bool MacroShadowsKeyword;
- ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword);
-
- // Error reading macro name? If so, diagnostic already issued.
- if (MacroNameTok.is(tok::eod))
- return;
+MacroInfo *Preprocessor::ReadOptionalMacroParameterListAndBody(
+ const Token &MacroNameTok, const bool ImmediatelyAfterHeaderGuard) {
Token LastTok = MacroNameTok;
-
- // If we are supposed to keep comments in #defines, reenable comment saving
- // mode.
- if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
-
// Create the new macro.
- MacroInfo *MI = AllocateMacroInfo(MacroNameTok.getLocation());
+ MacroInfo *const MI = AllocateMacroInfo(MacroNameTok.getLocation());
Token Tok;
LexUnexpandedToken(Tok);
@@ -2323,11 +2307,11 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
} else if (Tok.is(tok::l_paren)) {
// This is a function-like macro definition. Read the argument list.
MI->setIsFunctionLike();
- if (ReadMacroDefinitionArgList(MI, LastTok)) {
+ if (ReadMacroParameterList(MI, LastTok)) {
// Throw away the rest of the line.
if (CurPPLexer->ParsingPreprocessorDirective)
DiscardUntilEndOfDirective();
- return;
+ return nullptr;
}
// If this is a definition of a variadic C99 function-like macro, not using
@@ -2434,7 +2418,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
// Check for a valid macro arg identifier.
if (Tok.getIdentifierInfo() == nullptr ||
- MI->getArgumentNum(Tok.getIdentifierInfo()) == -1) {
+ MI->getParameterNum(Tok.getIdentifierInfo()) == -1) {
// If this is assembler-with-cpp mode, we accept random gibberish after
// the '#' because '#' is often a comment character. However, change
@@ -2450,7 +2434,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
// Disable __VA_ARGS__ again.
Ident__VA_ARGS__->setIsPoisoned(true);
- return;
+ return nullptr;
}
}
@@ -2463,15 +2447,39 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
LexUnexpandedToken(Tok);
}
}
+ MI->setDefinitionEndLoc(LastTok.getLocation());
+ // Disable __VA_ARGS__ again.
+ Ident__VA_ARGS__->setIsPoisoned(true);
+
+ return MI;
+}
+/// HandleDefineDirective - Implements \#define. This consumes the entire macro
+/// line then lets the caller lex the next real token.
+void Preprocessor::HandleDefineDirective(
+ Token &DefineTok, const bool ImmediatelyAfterHeaderGuard) {
+ ++NumDefined;
+
+ Token MacroNameTok;
+ bool MacroShadowsKeyword;
+ ReadMacroName(MacroNameTok, MU_Define, &MacroShadowsKeyword);
+
+ // Error reading macro name? If so, diagnostic already issued.
+ if (MacroNameTok.is(tok::eod))
+ return;
+
+ // If we are supposed to keep comments in #defines, reenable comment saving
+ // mode.
+ if (CurLexer) CurLexer->SetCommentRetentionState(KeepMacroComments);
+
+ MacroInfo *const MI = ReadOptionalMacroParameterListAndBody(
+ MacroNameTok, ImmediatelyAfterHeaderGuard);
+
+ if (!MI) return;
if (MacroShadowsKeyword &&
!isConfigurationPattern(MacroNameTok, MI, getLangOpts())) {
Diag(MacroNameTok, diag::warn_pp_macro_hides_keyword);
- }
-
- // Disable __VA_ARGS__ again.
- Ident__VA_ARGS__->setIsPoisoned(true);
-
+ }
// Check that there is no paste (##) operator at the beginning or end of the
// replacement list.
unsigned NumTokens = MI->getNumTokens();
@@ -2486,7 +2494,7 @@ void Preprocessor::HandleDefineDirective(Token &DefineTok,
}
}
- MI->setDefinitionEndLoc(LastTok.getLocation());
+
// Finally, if this identifier already had a macro defined for it, verify that
// the macro bodies are identical, and issue diagnostics if they are not.
diff --git a/lib/Lex/PPExpressions.cpp b/lib/Lex/PPExpressions.cpp
index 12f5084298df..d8431827e9cd 100644
--- a/lib/Lex/PPExpressions.cpp
+++ b/lib/Lex/PPExpressions.cpp
@@ -237,35 +237,32 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
PP.setCodeCompletionReached();
PP.LexNonComment(PeekTok);
}
-
- // If this token's spelling is a pp-identifier, check to see if it is
- // 'defined' or if it is a macro. Note that we check here because many
- // keywords are pp-identifiers, so we can't check the kind.
- if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
- // Handle "defined X" and "defined(X)".
- if (II->isStr("defined"))
- return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);
-
- // If this identifier isn't 'defined' or one of the special
- // preprocessor keywords and it wasn't macro expanded, it turns
- // into a simple 0, unless it is the C++ keyword "true", in which case it
- // turns into "1".
- if (ValueLive &&
- II->getTokenID() != tok::kw_true &&
- II->getTokenID() != tok::kw_false)
- PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
- Result.Val = II->getTokenID() == tok::kw_true;
- Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
- Result.setIdentifier(II);
- Result.setRange(PeekTok.getLocation());
- DT.IncludedUndefinedIds = (II->getTokenID() != tok::kw_true &&
- II->getTokenID() != tok::kw_false);
- PP.LexNonComment(PeekTok);
- return false;
- }
switch (PeekTok.getKind()) {
- default: // Non-value token.
+ default:
+ // If this token's spelling is a pp-identifier, check to see if it is
+ // 'defined' or if it is a macro. Note that we check here because many
+ // keywords are pp-identifiers, so we can't check the kind.
+ if (IdentifierInfo *II = PeekTok.getIdentifierInfo()) {
+ // Handle "defined X" and "defined(X)".
+ if (II->isStr("defined"))
+ return EvaluateDefined(Result, PeekTok, DT, ValueLive, PP);
+
+ if (!II->isCPlusPlusOperatorKeyword()) {
+ // If this identifier isn't 'defined' or one of the special
+ // preprocessor keywords and it wasn't macro expanded, it turns
+ // into a simple 0
+ if (ValueLive)
+ PP.Diag(PeekTok, diag::warn_pp_undef_identifier) << II;
+ Result.Val = 0;
+ Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
+ Result.setIdentifier(II);
+ Result.setRange(PeekTok.getLocation());
+ DT.IncludedUndefinedIds = true;
+ PP.LexNonComment(PeekTok);
+ return false;
+ }
+ }
PP.Diag(PeekTok, diag::err_pp_expr_bad_token_start_expr);
return true;
case tok::eod:
@@ -481,6 +478,14 @@ static bool EvaluateValue(PPValue &Result, Token &PeekTok, DefinedTracker &DT,
DT.State = DefinedTracker::DefinedMacro;
return false;
}
+ case tok::kw_true:
+ case tok::kw_false:
+ Result.Val = PeekTok.getKind() == tok::kw_true;
+ Result.Val.setIsUnsigned(false); // "0" is signed intmax_t 0.
+ Result.setIdentifier(PeekTok.getIdentifierInfo());
+ Result.setRange(PeekTok.getLocation());
+ PP.LexNonComment(PeekTok);
+ return false;
// FIXME: Handle #assert
}
diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp
index 8af9a50cc204..3f8ede23da56 100644
--- a/lib/Lex/PPMacroExpansion.cpp
+++ b/lib/Lex/PPMacroExpansion.cpp
@@ -412,7 +412,7 @@ static bool isTrivialSingleTokenExpansion(const MacroInfo *MI,
// If this is a function-like macro invocation, it's safe to trivially expand
// as long as the identifier is not a macro argument.
- return std::find(MI->arg_begin(), MI->arg_end(), II) == MI->arg_end();
+ return std::find(MI->param_begin(), MI->param_end(), II) == MI->param_end();
}
/// isNextPPTokenLParen - Determine whether the next preprocessor token to be
@@ -492,7 +492,7 @@ bool Preprocessor::HandleMacroExpandedIdentifier(Token &Identifier,
// Preprocessor directives used inside macro arguments are not portable, and
// this enables the warning.
InMacroArgs = true;
- Args = ReadFunctionLikeMacroArgs(Identifier, MI, ExpansionEnd);
+ Args = ReadMacroCallArgumentList(Identifier, MI, ExpansionEnd);
// Finished parsing args.
InMacroArgs = false;
@@ -745,11 +745,11 @@ static bool GenerateNewArgTokens(Preprocessor &PP,
/// token is the '(' of the macro, this method is invoked to read all of the
/// actual arguments specified for the macro invocation. This returns null on
/// error.
-MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
+MacroArgs *Preprocessor::ReadMacroCallArgumentList(Token &MacroName,
MacroInfo *MI,
SourceLocation &MacroEnd) {
// The number of fixed arguments to parse.
- unsigned NumFixedArgsLeft = MI->getNumArgs();
+ unsigned NumFixedArgsLeft = MI->getNumParams();
bool isVariadic = MI->isVariadic();
// Outer loop, while there are more arguments, keep reading them.
@@ -889,7 +889,7 @@ MacroArgs *Preprocessor::ReadFunctionLikeMacroArgs(Token &MacroName,
// Okay, we either found the r_paren. Check to see if we parsed too few
// arguments.
- unsigned MinArgsExpected = MI->getNumArgs();
+ unsigned MinArgsExpected = MI->getNumParams();
// If this is not a variadic macro, and too many args were specified, emit
// an error.
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index 63f39524d12a..d1dc8e1c0010 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -712,14 +712,6 @@ bool Preprocessor::HandleIdentifier(Token &Identifier) {
II.setIsFutureCompatKeyword(false);
}
- // C++ 2.11p2: If this is an alternative representation of a C++ operator,
- // then we act as if it is the actual operator and not the textual
- // representation of it.
- if (II.isCPlusPlusOperatorKeyword() &&
- !(getLangOpts().MSVCCompat &&
- getSourceManager().isInSystemHeader(Identifier.getLocation())))
- Identifier.setIdentifierInfo(nullptr);
-
// If this is an extension token, diagnose its use.
// We avoid diagnosing tokens that originate from macro definitions.
// FIXME: This warning is disabled in cases where it shouldn't be,
diff --git a/lib/Lex/TokenLexer.cpp b/lib/Lex/TokenLexer.cpp
index 049e046cece1..c2e49ba919a9 100644
--- a/lib/Lex/TokenLexer.cpp
+++ b/lib/Lex/TokenLexer.cpp
@@ -67,7 +67,7 @@ void TokenLexer::Init(Token &Tok, SourceLocation ELEnd, MacroInfo *MI,
// If this is a function-like macro, expand the arguments and change
// Tokens to point to the expanded tokens.
- if (Macro->isFunctionLike() && Macro->getNumArgs())
+ if (Macro->isFunctionLike() && Macro->getNumParams())
ExpandFunctionArguments();
// Mark the macro as currently disabled, so that it is not recursively
@@ -122,7 +122,7 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs(
SmallVectorImpl<Token> &ResultToks, bool HasPasteOperator, MacroInfo *Macro,
unsigned MacroArgNo, Preprocessor &PP) {
// Is the macro argument __VA_ARGS__?
- if (!Macro->isVariadic() || MacroArgNo != Macro->getNumArgs()-1)
+ if (!Macro->isVariadic() || MacroArgNo != Macro->getNumParams()-1)
return false;
// In Microsoft-compatibility mode, a comma is removed in the expansion
@@ -137,7 +137,7 @@ bool TokenLexer::MaybeRemoveCommaBeforeVaArgs(
// with GNU extensions, it is removed regardless of named arguments.
// Microsoft also appears to support this extension, unofficially.
if (PP.getLangOpts().C99 && !PP.getLangOpts().GNUMode
- && Macro->getNumArgs() < 2)
+ && Macro->getNumParams() < 2)
return false;
// Is a comma available to be removed?
@@ -193,7 +193,7 @@ void TokenLexer::ExpandFunctionArguments() {
NextTokGetsSpace = true;
if (CurTok.isOneOf(tok::hash, tok::hashat)) {
- int ArgNo = Macro->getArgumentNum(Tokens[i+1].getIdentifierInfo());
+ int ArgNo = Macro->getParameterNum(Tokens[i+1].getIdentifierInfo());
assert(ArgNo != -1 && "Token following # is not an argument?");
SourceLocation ExpansionLocStart =
@@ -237,7 +237,7 @@ void TokenLexer::ExpandFunctionArguments() {
// Otherwise, if this is not an argument token, just add the token to the
// output buffer.
IdentifierInfo *II = CurTok.getIdentifierInfo();
- int ArgNo = II ? Macro->getArgumentNum(II) : -1;
+ int ArgNo = II ? Macro->getParameterNum(II) : -1;
if (ArgNo == -1) {
// This isn't an argument, just add it.
ResultToks.push_back(CurTok);
@@ -330,7 +330,7 @@ void TokenLexer::ExpandFunctionArguments() {
// expansion.
if (NonEmptyPasteBefore && ResultToks.size() >= 2 &&
ResultToks[ResultToks.size()-2].is(tok::comma) &&
- (unsigned)ArgNo == Macro->getNumArgs()-1 &&
+ (unsigned)ArgNo == Macro->getNumParams()-1 &&
Macro->isVariadic()) {
VaArgsPseudoPaste = true;
// Remove the paste operator, report use of the extension.
diff --git a/lib/Parse/ParseObjc.cpp b/lib/Parse/ParseObjc.cpp
index f7410b8a092a..01b1bf48e473 100644
--- a/lib/Parse/ParseObjc.cpp
+++ b/lib/Parse/ParseObjc.cpp
@@ -1007,6 +1007,10 @@ IdentifierInfo *Parser::ParseObjCSelectorPiece(SourceLocation &SelectorLoc) {
switch (Tok.getKind()) {
default:
return nullptr;
+ case tok::colon:
+ // Empty selector piece uses the location of the ':'.
+ SelectorLoc = Tok.getLocation();
+ return nullptr;
case tok::ampamp:
case tok::ampequal:
case tok::amp:
diff --git a/lib/Parse/ParseOpenMP.cpp b/lib/Parse/ParseOpenMP.cpp
index 2e5e36242ed5..d9a088595ab7 100644
--- a/lib/Parse/ParseOpenMP.cpp
+++ b/lib/Parse/ParseOpenMP.cpp
@@ -1102,7 +1102,7 @@ bool Parser::ParseOpenMPSimpleVarList(
/// simdlen-clause | threads-clause | simd-clause | num_teams-clause |
/// thread_limit-clause | priority-clause | grainsize-clause |
/// nogroup-clause | num_tasks-clause | hint-clause | to-clause |
-/// from-clause | is_device_ptr-clause
+/// from-clause | is_device_ptr-clause | task_reduction-clause
///
OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
OpenMPClauseKind CKind, bool FirstClause) {
@@ -1220,6 +1220,7 @@ OMPClause *Parser::ParseOpenMPClause(OpenMPDirectiveKind DKind,
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
@@ -1585,7 +1586,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
BalancedDelimiterTracker LinearT(*this, tok::l_paren,
tok::annot_pragma_openmp_end);
// Handle reduction-identifier for reduction clause.
- if (Kind == OMPC_reduction) {
+ if (Kind == OMPC_reduction || Kind == OMPC_task_reduction) {
ColonProtectionRAIIObject ColonRAII(*this);
if (getLangOpts().CPlusPlus)
ParseOptionalCXXScopeSpecifier(Data.ReductionIdScopeSpec,
@@ -1733,13 +1734,13 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
Diag(Tok, diag::warn_pragma_expected_colon) << "map type";
}
- bool IsComma =
- (Kind != OMPC_reduction && Kind != OMPC_depend && Kind != OMPC_map) ||
- (Kind == OMPC_reduction && !InvalidReductionId) ||
- (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown &&
- (!MapTypeModifierSpecified ||
- Data.MapTypeModifier == OMPC_MAP_always)) ||
- (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
+ bool IsComma = (Kind != OMPC_reduction && Kind != OMPC_task_reduction &&
+ Kind != OMPC_depend && Kind != OMPC_map) ||
+ (Kind == OMPC_reduction && !InvalidReductionId) ||
+ (Kind == OMPC_map && Data.MapType != OMPC_MAP_unknown &&
+ (!MapTypeModifierSpecified ||
+ Data.MapTypeModifier == OMPC_MAP_always)) ||
+ (Kind == OMPC_depend && Data.DepKind != OMPC_DEPEND_unknown);
const bool MayHaveTail = (Kind == OMPC_linear || Kind == OMPC_aligned);
while (IsComma || (Tok.isNot(tok::r_paren) && Tok.isNot(tok::colon) &&
Tok.isNot(tok::annot_pragma_openmp_end))) {
@@ -1795,7 +1796,7 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
}
/// \brief Parsing of OpenMP clause 'private', 'firstprivate', 'lastprivate',
-/// 'shared', 'copyin', 'copyprivate', 'flush' or 'reduction'.
+/// 'shared', 'copyin', 'copyprivate', 'flush', 'reduction' or 'task_reduction'.
///
/// private-clause:
/// 'private' '(' list ')'
@@ -1811,6 +1812,8 @@ bool Parser::ParseOpenMPVarList(OpenMPDirectiveKind DKind,
/// 'aligned' '(' list [ ':' alignment ] ')'
/// reduction-clause:
/// 'reduction' '(' reduction-identifier ':' list ')'
+/// task_reduction-clause:
+/// 'task_reduction' '(' reduction-identifier ':' list ')'
/// copyprivate-clause:
/// 'copyprivate' '(' list ')'
/// flush-clause:
diff --git a/lib/Sema/DeclSpec.cpp b/lib/Sema/DeclSpec.cpp
index a55cdcccee5d..e4e84fcec954 100644
--- a/lib/Sema/DeclSpec.cpp
+++ b/lib/Sema/DeclSpec.cpp
@@ -1082,8 +1082,10 @@ void DeclSpec::Finish(Sema &S, const PrintingPolicy &Policy) {
!S.getLangOpts().ZVector)
S.Diag(TSTLoc, diag::err_invalid_vector_double_decl_spec);
} else if (TypeSpecType == TST_float) {
- // vector float is unsupported for ZVector.
- if (S.getLangOpts().ZVector)
+ // vector float is unsupported for ZVector unless we have the
+ // vector-enhancements facility 1 (ISA revision 12).
+ if (S.getLangOpts().ZVector &&
+ !S.Context.getTargetInfo().hasFeature("arch12"))
S.Diag(TSTLoc, diag::err_invalid_vector_float_decl_spec);
} else if (TypeSpecWidth == TSW_long) {
// vector long is unsupported for ZVector and deprecated for AltiVec.
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index dc9f977d41ac..6f0db6ce1c6a 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -850,7 +850,8 @@ void Sema::ActOnEndOfTranslationUnit() {
emitAndClearUnusedLocalTypedefWarnings();
// Modules don't need any of the checking below.
- TUScope = nullptr;
+ if (!PP.isIncrementalProcessingEnabled())
+ TUScope = nullptr;
return;
}
diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp
index 8446601334ee..b2223b755061 100644
--- a/lib/Sema/SemaChecking.cpp
+++ b/lib/Sema/SemaChecking.cpp
@@ -760,6 +760,7 @@ Sema::CheckBuiltinFunctionCall(FunctionDecl *FDecl, unsigned BuiltinID,
if (CheckObjCString(TheCall->getArg(0)))
return ExprError();
break;
+ case Builtin::BI__builtin_ms_va_start:
case Builtin::BI__builtin_stdarg_start:
case Builtin::BI__builtin_va_start:
if (SemaBuiltinVAStart(BuiltinID, TheCall))
@@ -1739,9 +1740,11 @@ bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID,
case SystemZ::BI__builtin_s390_vfaezbs:
case SystemZ::BI__builtin_s390_vfaezhs:
case SystemZ::BI__builtin_s390_vfaezfs: i = 2; l = 0; u = 15; break;
+ case SystemZ::BI__builtin_s390_vfisb:
case SystemZ::BI__builtin_s390_vfidb:
return SemaBuiltinConstantArgRange(TheCall, 1, 0, 15) ||
SemaBuiltinConstantArgRange(TheCall, 2, 0, 15);
+ case SystemZ::BI__builtin_s390_vftcisb:
case SystemZ::BI__builtin_s390_vftcidb: i = 1; l = 0; u = 4095; break;
case SystemZ::BI__builtin_s390_vlbb: i = 1; l = 0; u = 15; break;
case SystemZ::BI__builtin_s390_vpdi: i = 2; l = 0; u = 15; break;
@@ -1758,6 +1761,11 @@ bool Sema::CheckSystemZBuiltinFunctionCall(unsigned BuiltinID,
case SystemZ::BI__builtin_s390_vstrczbs:
case SystemZ::BI__builtin_s390_vstrczhs:
case SystemZ::BI__builtin_s390_vstrczfs: i = 3; l = 0; u = 15; break;
+ case SystemZ::BI__builtin_s390_vmslg: i = 3; l = 0; u = 15; break;
+ case SystemZ::BI__builtin_s390_vfminsb:
+ case SystemZ::BI__builtin_s390_vfmaxsb:
+ case SystemZ::BI__builtin_s390_vfmindb:
+ case SystemZ::BI__builtin_s390_vfmaxdb: i = 2; l = 0; u = 15; break;
}
return SemaBuiltinConstantArgRange(TheCall, i, l, u);
}
@@ -2095,9 +2103,6 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) {
if (BuiltinID == X86::BI__builtin_cpu_supports)
return SemaBuiltinCpuSupports(*this, TheCall);
- if (BuiltinID == X86::BI__builtin_ms_va_start)
- return SemaBuiltinVAStart(BuiltinID, TheCall);
-
// If the intrinsic has rounding or SAE make sure its valid.
if (CheckX86BuiltinRoundingOrSAE(BuiltinID, TheCall))
return true;
@@ -3622,24 +3627,25 @@ ExprResult Sema::CheckOSLogFormatStringArg(Expr *Arg) {
static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) {
const llvm::Triple &TT = S.Context.getTargetInfo().getTriple();
bool IsX64 = TT.getArch() == llvm::Triple::x86_64;
+ bool IsAArch64 = TT.getArch() == llvm::Triple::aarch64;
bool IsWindows = TT.isOSWindows();
- bool IsMSVAStart = BuiltinID == X86::BI__builtin_ms_va_start;
- if (IsX64) {
+ bool IsMSVAStart = BuiltinID == Builtin::BI__builtin_ms_va_start;
+ if (IsX64 || IsAArch64) {
clang::CallingConv CC = CC_C;
if (const FunctionDecl *FD = S.getCurFunctionDecl())
CC = FD->getType()->getAs<FunctionType>()->getCallConv();
if (IsMSVAStart) {
// Don't allow this in System V ABI functions.
- if (CC == CC_X86_64SysV || (!IsWindows && CC != CC_X86_64Win64))
+ if (CC == CC_X86_64SysV || (!IsWindows && CC != CC_Win64))
return S.Diag(Fn->getLocStart(),
diag::err_ms_va_start_used_in_sysv_function);
} else {
- // On x86-64 Unix, don't allow this in Win64 ABI functions.
+ // On x86-64/AArch64 Unix, don't allow this in Win64 ABI functions.
// On x64 Windows, don't allow this in System V ABI functions.
// (Yes, that means there's no corresponding way to support variadic
// System V ABI functions on Windows.)
if ((IsWindows && CC == CC_X86_64SysV) ||
- (!IsWindows && CC == CC_X86_64Win64))
+ (!IsWindows && CC == CC_Win64))
return S.Diag(Fn->getLocStart(),
diag::err_va_start_used_in_wrong_abi_function)
<< !IsWindows;
@@ -3648,7 +3654,7 @@ static bool checkVAStartABI(Sema &S, unsigned BuiltinID, Expr *Fn) {
}
if (IsMSVAStart)
- return S.Diag(Fn->getLocStart(), diag::err_x86_builtin_64_only);
+ return S.Diag(Fn->getLocStart(), diag::err_builtin_x64_aarch64_only);
return false;
}
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index 83c3bd27596c..3a53f251b096 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -2738,7 +2738,7 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
// Format a function-like macro with placeholders for the arguments.
Result.AddChunk(CodeCompletionString::CK_LeftParen);
- MacroInfo::arg_iterator A = MI->arg_begin(), AEnd = MI->arg_end();
+ MacroInfo::param_iterator A = MI->param_begin(), AEnd = MI->param_end();
// C99 variadic macros add __VA_ARGS__ at the end. Skip it.
if (MI->isC99Varargs()) {
@@ -2749,8 +2749,8 @@ CodeCompletionResult::CreateCodeCompletionString(ASTContext &Ctx,
}
}
- for (MacroInfo::arg_iterator A = MI->arg_begin(); A != AEnd; ++A) {
- if (A != MI->arg_begin())
+ for (MacroInfo::param_iterator A = MI->param_begin(); A != AEnd; ++A) {
+ if (A != MI->param_begin())
Result.AddChunk(CodeCompletionString::CK_Comma);
if (MI->isVariadic() && (A+1) == AEnd) {
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 5fb79a6bf630..2a310bf41c70 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -4280,7 +4280,7 @@ bool Sema::CheckCallingConvAttr(const AttributeList &attr, CallingConv &CC,
case AttributeList::AT_RegCall: CC = CC_X86RegCall; break;
case AttributeList::AT_MSABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_C :
- CC_X86_64Win64;
+ CC_Win64;
break;
case AttributeList::AT_SysVABI:
CC = Context.getTargetInfo().getTriple().isOSWindows() ? CC_X86_64SysV :
@@ -4679,6 +4679,16 @@ void Sema::AddNSConsumedAttr(SourceRange attrRange, Decl *D,
CFConsumedAttr(attrRange, Context, spellingIndex));
}
+bool Sema::checkNSReturnsRetainedReturnType(SourceLocation loc,
+ QualType type) {
+ if (isValidSubjectOfNSReturnsRetainedAttribute(type))
+ return false;
+
+ Diag(loc, diag::warn_ns_attribute_wrong_return_type)
+ << "'ns_returns_retained'" << 0 << 0;
+ return true;
+}
+
static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
const AttributeList &Attr) {
QualType returnType;
@@ -4700,6 +4710,8 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
<< Attr.getRange();
return;
}
+ } else if (Attr.isUsedAsTypeAttr()) {
+ return;
} else {
AttributeDeclKind ExpectedDeclKind;
switch (Attr.getKind()) {
@@ -4743,6 +4755,9 @@ static void handleNSReturnsRetainedAttr(Sema &S, Decl *D,
}
if (!typeOK) {
+ if (Attr.isUsedAsTypeAttr())
+ return;
+
if (isa<ParmVarDecl>(D)) {
S.Diag(D->getLocStart(), diag::warn_ns_attribute_wrong_parameter_type)
<< Attr.getName() << /*pointer-to-CF*/2
@@ -6838,6 +6853,50 @@ static const AvailabilityAttr *getAttrForPlatform(ASTContext &Context,
return nullptr;
}
+/// The diagnostic we should emit for \c D, and the declaration that
+/// originated it, or \c AR_Available.
+///
+/// \param D The declaration to check.
+/// \param Message If non-null, this will be populated with the message from
+/// the availability attribute that is selected.
+static std::pair<AvailabilityResult, const NamedDecl *>
+ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D, std::string *Message) {
+ AvailabilityResult Result = D->getAvailability(Message);
+
+ // For typedefs, if the typedef declaration appears available look
+ // to the underlying type to see if it is more restrictive.
+ while (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
+ if (Result == AR_Available) {
+ if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
+ D = TT->getDecl();
+ Result = D->getAvailability(Message);
+ continue;
+ }
+ }
+ break;
+ }
+
+ // Forward class declarations get their attributes from their definition.
+ if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
+ if (IDecl->getDefinition()) {
+ D = IDecl->getDefinition();
+ Result = D->getAvailability(Message);
+ }
+ }
+
+ if (const auto *ECD = dyn_cast<EnumConstantDecl>(D))
+ if (Result == AR_Available) {
+ const DeclContext *DC = ECD->getDeclContext();
+ if (const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {
+ Result = TheEnumDecl->getAvailability(Message);
+ D = TheEnumDecl;
+ }
+ }
+
+ return {Result, D};
+}
+
+
/// \brief whether we should emit a diagnostic for \c K and \c DeclVersion in
/// the context of \c Ctx. For example, we should emit an unavailable diagnostic
/// in a deprecated context, but not the other way around.
@@ -7205,24 +7264,24 @@ void Sema::redelayDiagnostics(DelayedDiagnosticPool &pool) {
curPool->steal(pool);
}
-void Sema::EmitAvailabilityWarning(AvailabilityResult AR,
- const NamedDecl *ReferringDecl,
- const NamedDecl *OffendingDecl,
- StringRef Message, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass,
- const ObjCPropertyDecl *ObjCProperty,
- bool ObjCPropertyAccess) {
+static void EmitAvailabilityWarning(Sema &S, AvailabilityResult AR,
+ const NamedDecl *ReferringDecl,
+ const NamedDecl *OffendingDecl,
+ StringRef Message, SourceLocation Loc,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ const ObjCPropertyDecl *ObjCProperty,
+ bool ObjCPropertyAccess) {
// Delay if we're currently parsing a declaration.
- if (DelayedDiagnostics.shouldDelayDiagnostics()) {
- DelayedDiagnostics.add(
+ if (S.DelayedDiagnostics.shouldDelayDiagnostics()) {
+ S.DelayedDiagnostics.add(
DelayedDiagnostic::makeAvailability(
AR, Loc, ReferringDecl, OffendingDecl, UnknownObjCClass,
ObjCProperty, Message, ObjCPropertyAccess));
return;
}
- Decl *Ctx = cast<Decl>(getCurLexicalContext());
- DoEmitAvailabilityWarning(*this, AR, Ctx, ReferringDecl, OffendingDecl,
+ Decl *Ctx = cast<Decl>(S.getCurLexicalContext());
+ DoEmitAvailabilityWarning(S, AR, Ctx, ReferringDecl, OffendingDecl,
Message, Loc, UnknownObjCClass, ObjCProperty,
ObjCPropertyAccess);
}
@@ -7379,7 +7438,7 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
AvailabilityResult Result;
const NamedDecl *OffendingDecl;
std::tie(Result, OffendingDecl) =
- SemaRef.ShouldDiagnoseAvailabilityOfDecl(D, nullptr);
+ ShouldDiagnoseAvailabilityOfDecl(D, nullptr);
if (Result != AR_Available) {
// All other diagnostic kinds have already been handled in
// DiagnoseAvailabilityOfDecl.
@@ -7557,3 +7616,44 @@ void Sema::DiagnoseUnguardedAvailabilityViolations(Decl *D) {
DiagnoseUnguardedAvailability(*this, D).IssueDiagnostics(Body);
}
+
+void Sema::DiagnoseAvailabilityOfDecl(NamedDecl *D, SourceLocation Loc,
+ const ObjCInterfaceDecl *UnknownObjCClass,
+ bool ObjCPropertyAccess,
+ bool AvoidPartialAvailabilityChecks) {
+ std::string Message;
+ AvailabilityResult Result;
+ const NamedDecl* OffendingDecl;
+ // See if this declaration is unavailable, deprecated, or partial.
+ std::tie(Result, OffendingDecl) = ShouldDiagnoseAvailabilityOfDecl(D, &Message);
+ if (Result == AR_Available)
+ return;
+
+ if (Result == AR_NotYetIntroduced) {
+ if (AvoidPartialAvailabilityChecks)
+ return;
+
+ // We need to know the @available context in the current function to
+ // diagnose this use, let DiagnoseUnguardedAvailabilityViolations do that
+ // when we're done parsing the current function.
+ if (getCurFunctionOrMethodDecl()) {
+ getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
+ return;
+ } else if (getCurBlock() || getCurLambda()) {
+ getCurFunction()->HasPotentialAvailabilityViolations = true;
+ return;
+ }
+ }
+
+ const ObjCPropertyDecl *ObjCPDecl = nullptr;
+ if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
+ if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
+ AvailabilityResult PDeclResult = PD->getAvailability(nullptr);
+ if (PDeclResult == Result)
+ ObjCPDecl = PD;
+ }
+ }
+
+ EmitAvailabilityWarning(*this, Result, D, OffendingDecl, Message, Loc,
+ UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess);
+}
diff --git a/lib/Sema/SemaDeclObjC.cpp b/lib/Sema/SemaDeclObjC.cpp
index 778b8062f68c..967573011d0d 100644
--- a/lib/Sema/SemaDeclObjC.cpp
+++ b/lib/Sema/SemaDeclObjC.cpp
@@ -248,19 +248,41 @@ bool Sema::CheckARCMethodDecl(ObjCMethodDecl *method) {
return false;
}
-static void DiagnoseObjCImplementedDeprecations(Sema &S,
- NamedDecl *ND,
- SourceLocation ImplLoc,
- int select) {
- if (ND && ND->isDeprecated()) {
- S.Diag(ImplLoc, diag::warn_deprecated_def) << select;
- if (select == 0)
+static void DiagnoseObjCImplementedDeprecations(Sema &S, const NamedDecl *ND,
+ SourceLocation ImplLoc) {
+ if (!ND)
+ return;
+ bool IsCategory = false;
+ AvailabilityResult Availability = ND->getAvailability();
+ if (Availability != AR_Deprecated) {
+ if (isa<ObjCMethodDecl>(ND)) {
+ if (Availability != AR_Unavailable)
+ return;
+ // Warn about implementing unavailable methods.
+ S.Diag(ImplLoc, diag::warn_unavailable_def);
S.Diag(ND->getLocation(), diag::note_method_declared_at)
- << ND->getDeclName();
- else
- S.Diag(ND->getLocation(), diag::note_previous_decl)
- << (isa<ObjCCategoryDecl>(ND) ? "category" : "class");
+ << ND->getDeclName();
+ return;
+ }
+ if (const auto *CD = dyn_cast<ObjCCategoryDecl>(ND)) {
+ if (!CD->getClassInterface()->isDeprecated())
+ return;
+ ND = CD->getClassInterface();
+ IsCategory = true;
+ } else
+ return;
}
+ S.Diag(ImplLoc, diag::warn_deprecated_def)
+ << (isa<ObjCMethodDecl>(ND)
+ ? /*Method*/ 0
+ : isa<ObjCCategoryDecl>(ND) || IsCategory ? /*Category*/ 2
+ : /*Class*/ 1);
+ if (isa<ObjCMethodDecl>(ND))
+ S.Diag(ND->getLocation(), diag::note_method_declared_at)
+ << ND->getDeclName();
+ else
+ S.Diag(ND->getLocation(), diag::note_previous_decl)
+ << (isa<ObjCCategoryDecl>(ND) ? "category" : "class");
}
/// AddAnyMethodToGlobalPool - Add any method, instance or factory to global
@@ -385,9 +407,7 @@ void Sema::ActOnStartOfObjCMethodDef(Scope *FnBodyScope, Decl *D) {
// No need to issue deprecated warning if deprecated mehod in class/category
// is being implemented in its own implementation (no overriding is involved).
if (!ImplDeclOfMethodDecl || ImplDeclOfMethodDecl != ImplDeclOfMethodDef)
- DiagnoseObjCImplementedDeprecations(*this,
- dyn_cast<NamedDecl>(IMD),
- MDecl->getLocation(), 0);
+ DiagnoseObjCImplementedDeprecations(*this, IMD, MDecl->getLocation());
}
if (MDecl->getMethodFamily() == OMF_init) {
@@ -1873,10 +1893,8 @@ Decl *Sema::ActOnStartCategoryImplementation(
CatIDecl->setImplementation(CDecl);
// Warn on implementating category of deprecated class under
// -Wdeprecated-implementations flag.
- DiagnoseObjCImplementedDeprecations(
- *this,
- CatIDecl->isDeprecated() ? CatIDecl : dyn_cast<NamedDecl>(IDecl),
- CDecl->getLocation(), 2);
+ DiagnoseObjCImplementedDeprecations(*this, CatIDecl,
+ CDecl->getLocation());
}
}
@@ -1996,9 +2014,7 @@ Decl *Sema::ActOnStartClassImplementation(
PushOnScopeChains(IMPDecl, TUScope);
// Warn on implementating deprecated class under
// -Wdeprecated-implementations flag.
- DiagnoseObjCImplementedDeprecations(*this,
- dyn_cast<NamedDecl>(IDecl),
- IMPDecl->getLocation(), 1);
+ DiagnoseObjCImplementedDeprecations(*this, IDecl, IMPDecl->getLocation());
}
// If the superclass has the objc_runtime_visible attribute, we
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 8016bf99889f..ead80b61586a 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -87,82 +87,6 @@ static void DiagnoseUnusedOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc) {
}
}
-std::pair<AvailabilityResult, const NamedDecl *>
-Sema::ShouldDiagnoseAvailabilityOfDecl(const NamedDecl *D,
- std::string *Message) {
- AvailabilityResult Result = D->getAvailability(Message);
-
- // For typedefs, if the typedef declaration appears available look
- // to the underlying type to see if it is more restrictive.
- while (const TypedefNameDecl *TD = dyn_cast<TypedefNameDecl>(D)) {
- if (Result == AR_Available) {
- if (const TagType *TT = TD->getUnderlyingType()->getAs<TagType>()) {
- D = TT->getDecl();
- Result = D->getAvailability(Message);
- continue;
- }
- }
- break;
- }
-
- // Forward class declarations get their attributes from their definition.
- if (const ObjCInterfaceDecl *IDecl = dyn_cast<ObjCInterfaceDecl>(D)) {
- if (IDecl->getDefinition()) {
- D = IDecl->getDefinition();
- Result = D->getAvailability(Message);
- }
- }
-
- if (const auto *ECD = dyn_cast<EnumConstantDecl>(D))
- if (Result == AR_Available) {
- const DeclContext *DC = ECD->getDeclContext();
- if (const auto *TheEnumDecl = dyn_cast<EnumDecl>(DC)) {
- Result = TheEnumDecl->getAvailability(Message);
- D = TheEnumDecl;
- }
- }
-
- return {Result, D};
-}
-
-static void
-DiagnoseAvailabilityOfDecl(Sema &S, NamedDecl *D, SourceLocation Loc,
- const ObjCInterfaceDecl *UnknownObjCClass,
- bool ObjCPropertyAccess,
- bool AvoidPartialAvailabilityChecks = false) {
- std::string Message;
- AvailabilityResult Result;
- const NamedDecl* OffendingDecl;
- // See if this declaration is unavailable, deprecated, or partial.
- std::tie(Result, OffendingDecl) = S.ShouldDiagnoseAvailabilityOfDecl(D, &Message);
- if (Result == AR_Available)
- return;
-
- if (Result == AR_NotYetIntroduced) {
- if (AvoidPartialAvailabilityChecks)
- return;
- if (S.getCurFunctionOrMethodDecl()) {
- S.getEnclosingFunction()->HasPotentialAvailabilityViolations = true;
- return;
- } else if (S.getCurBlock() || S.getCurLambda()) {
- S.getCurFunction()->HasPotentialAvailabilityViolations = true;
- return;
- }
- }
-
- const ObjCPropertyDecl *ObjCPDecl = nullptr;
- if (const ObjCMethodDecl *MD = dyn_cast<ObjCMethodDecl>(D)) {
- if (const ObjCPropertyDecl *PD = MD->findPropertyDecl()) {
- AvailabilityResult PDeclResult = PD->getAvailability(nullptr);
- if (PDeclResult == Result)
- ObjCPDecl = PD;
- }
- }
-
- S.EmitAvailabilityWarning(Result, D, OffendingDecl, Message, Loc,
- UnknownObjCClass, ObjCPDecl, ObjCPropertyAccess);
-}
-
/// \brief Emit a note explaining that this function is deleted.
void Sema::NoteDeletedFunction(FunctionDecl *Decl) {
assert(Decl->isDeleted());
@@ -363,8 +287,7 @@ bool Sema::DiagnoseUseOfDecl(NamedDecl *D, SourceLocation Loc,
return true;
}
- DiagnoseAvailabilityOfDecl(*this, D, Loc, UnknownObjCClass,
- ObjCPropertyAccess,
+ DiagnoseAvailabilityOfDecl(D, Loc, UnknownObjCClass, ObjCPropertyAccess,
AvoidPartialAvailabilityChecks);
DiagnoseUnusedOfDecl(*this, D, Loc);
diff --git a/lib/Sema/SemaObjCProperty.cpp b/lib/Sema/SemaObjCProperty.cpp
index 62a771bcffa0..e1e85dfd5e55 100644
--- a/lib/Sema/SemaObjCProperty.cpp
+++ b/lib/Sema/SemaObjCProperty.cpp
@@ -814,53 +814,185 @@ static void setImpliedPropertyAttributeForReadOnlyProperty(
property->setPropertyAttributes(ObjCPropertyDecl::OBJC_PR_weak);
}
-/// DiagnosePropertyMismatchDeclInProtocols - diagnose properties declared
-/// in inherited protocols with mismatched types. Since any of them can
-/// be candidate for synthesis.
-static void
-DiagnosePropertyMismatchDeclInProtocols(Sema &S, SourceLocation AtLoc,
+static bool
+isIncompatiblePropertyAttribute(unsigned Attr1, unsigned Attr2,
+ ObjCPropertyDecl::PropertyAttributeKind Kind) {
+ return (Attr1 & Kind) != (Attr2 & Kind);
+}
+
+static bool areIncompatiblePropertyAttributes(unsigned Attr1, unsigned Attr2,
+ unsigned Kinds) {
+ return ((Attr1 & Kinds) != 0) != ((Attr2 & Kinds) != 0);
+}
+
+/// SelectPropertyForSynthesisFromProtocols - Finds the most appropriate
+/// property declaration that should be synthesised in all of the inherited
+/// protocols. It also diagnoses properties declared in inherited protocols with
+/// mismatched types or attributes, since any of them can be candidate for
+/// synthesis.
+static ObjCPropertyDecl *
+SelectPropertyForSynthesisFromProtocols(Sema &S, SourceLocation AtLoc,
ObjCInterfaceDecl *ClassDecl,
ObjCPropertyDecl *Property) {
- ObjCInterfaceDecl::ProtocolPropertyMap PropMap;
+ assert(isa<ObjCProtocolDecl>(Property->getDeclContext()) &&
+ "Expected a property from a protocol");
+ ObjCInterfaceDecl::ProtocolPropertySet ProtocolSet;
+ ObjCInterfaceDecl::PropertyDeclOrder Properties;
for (const auto *PI : ClassDecl->all_referenced_protocols()) {
if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
- PDecl->collectInheritedProtocolProperties(Property, PropMap);
+ PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
+ Properties);
}
- if (ObjCInterfaceDecl *SDecl = ClassDecl->getSuperClass())
+ if (ObjCInterfaceDecl *SDecl = ClassDecl->getSuperClass()) {
while (SDecl) {
for (const auto *PI : SDecl->all_referenced_protocols()) {
if (const ObjCProtocolDecl *PDecl = PI->getDefinition())
- PDecl->collectInheritedProtocolProperties(Property, PropMap);
+ PDecl->collectInheritedProtocolProperties(Property, ProtocolSet,
+ Properties);
}
SDecl = SDecl->getSuperClass();
}
-
- if (PropMap.empty())
- return;
-
+ }
+
+ if (Properties.empty())
+ return Property;
+
+ ObjCPropertyDecl *OriginalProperty = Property;
+ size_t SelectedIndex = 0;
+ for (const auto &Prop : llvm::enumerate(Properties)) {
+ // Select the 'readwrite' property if such property exists.
+ if (Property->isReadOnly() && !Prop.value()->isReadOnly()) {
+ Property = Prop.value();
+ SelectedIndex = Prop.index();
+ }
+ }
+ if (Property != OriginalProperty) {
+ // Check that the old property is compatible with the new one.
+ Properties[SelectedIndex] = OriginalProperty;
+ }
+
QualType RHSType = S.Context.getCanonicalType(Property->getType());
- bool FirsTime = true;
- for (ObjCInterfaceDecl::ProtocolPropertyMap::iterator
- I = PropMap.begin(), E = PropMap.end(); I != E; I++) {
- ObjCPropertyDecl *Prop = I->second;
+ unsigned OriginalAttributes = Property->getPropertyAttributes();
+ enum MismatchKind {
+ IncompatibleType = 0,
+ HasNoExpectedAttribute,
+ HasUnexpectedAttribute,
+ DifferentGetter,
+ DifferentSetter
+ };
+ // Represents a property from another protocol that conflicts with the
+ // selected declaration.
+ struct MismatchingProperty {
+ const ObjCPropertyDecl *Prop;
+ MismatchKind Kind;
+ StringRef AttributeName;
+ };
+ SmallVector<MismatchingProperty, 4> Mismatches;
+ for (ObjCPropertyDecl *Prop : Properties) {
+ // Verify the property attributes.
+ unsigned Attr = Prop->getPropertyAttributes();
+ if (Attr != OriginalAttributes) {
+ auto Diag = [&](bool OriginalHasAttribute, StringRef AttributeName) {
+ MismatchKind Kind = OriginalHasAttribute ? HasNoExpectedAttribute
+ : HasUnexpectedAttribute;
+ Mismatches.push_back({Prop, Kind, AttributeName});
+ };
+ if (isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
+ ObjCPropertyDecl::OBJC_PR_copy)) {
+ Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_copy, "copy");
+ continue;
+ }
+ if (areIncompatiblePropertyAttributes(
+ OriginalAttributes, Attr, ObjCPropertyDecl::OBJC_PR_retain |
+ ObjCPropertyDecl::OBJC_PR_strong)) {
+ Diag(OriginalAttributes & (ObjCPropertyDecl::OBJC_PR_retain |
+ ObjCPropertyDecl::OBJC_PR_strong),
+ "retain (or strong)");
+ continue;
+ }
+ if (isIncompatiblePropertyAttribute(OriginalAttributes, Attr,
+ ObjCPropertyDecl::OBJC_PR_atomic)) {
+ Diag(OriginalAttributes & ObjCPropertyDecl::OBJC_PR_atomic, "atomic");
+ continue;
+ }
+ }
+ if (Property->getGetterName() != Prop->getGetterName()) {
+ Mismatches.push_back({Prop, DifferentGetter, ""});
+ continue;
+ }
+ if (!Property->isReadOnly() && !Prop->isReadOnly() &&
+ Property->getSetterName() != Prop->getSetterName()) {
+ Mismatches.push_back({Prop, DifferentSetter, ""});
+ continue;
+ }
QualType LHSType = S.Context.getCanonicalType(Prop->getType());
if (!S.Context.propertyTypesAreCompatible(LHSType, RHSType)) {
bool IncompatibleObjC = false;
QualType ConvertedType;
if (!S.isObjCPointerConversion(RHSType, LHSType, ConvertedType, IncompatibleObjC)
|| IncompatibleObjC) {
- if (FirsTime) {
- S.Diag(Property->getLocation(), diag::warn_protocol_property_mismatch)
- << Property->getType();
- FirsTime = false;
- }
- S.Diag(Prop->getLocation(), diag::note_protocol_property_declare)
- << Prop->getType();
+ Mismatches.push_back({Prop, IncompatibleType, ""});
+ continue;
}
}
}
- if (!FirsTime && AtLoc.isValid())
+
+ if (Mismatches.empty())
+ return Property;
+
+ // Diagnose incompability.
+ {
+ bool HasIncompatibleAttributes = false;
+ for (const auto &Note : Mismatches)
+ HasIncompatibleAttributes =
+ Note.Kind != IncompatibleType ? true : HasIncompatibleAttributes;
+ // Promote the warning to an error if there are incompatible attributes or
+ // incompatible types together with readwrite/readonly incompatibility.
+ auto Diag = S.Diag(Property->getLocation(),
+ Property != OriginalProperty || HasIncompatibleAttributes
+ ? diag::err_protocol_property_mismatch
+ : diag::warn_protocol_property_mismatch);
+ Diag << Mismatches[0].Kind;
+ switch (Mismatches[0].Kind) {
+ case IncompatibleType:
+ Diag << Property->getType();
+ break;
+ case HasNoExpectedAttribute:
+ case HasUnexpectedAttribute:
+ Diag << Mismatches[0].AttributeName;
+ break;
+ case DifferentGetter:
+ Diag << Property->getGetterName();
+ break;
+ case DifferentSetter:
+ Diag << Property->getSetterName();
+ break;
+ }
+ }
+ for (const auto &Note : Mismatches) {
+ auto Diag =
+ S.Diag(Note.Prop->getLocation(), diag::note_protocol_property_declare)
+ << Note.Kind;
+ switch (Note.Kind) {
+ case IncompatibleType:
+ Diag << Note.Prop->getType();
+ break;
+ case HasNoExpectedAttribute:
+ case HasUnexpectedAttribute:
+ Diag << Note.AttributeName;
+ break;
+ case DifferentGetter:
+ Diag << Note.Prop->getGetterName();
+ break;
+ case DifferentSetter:
+ Diag << Note.Prop->getSetterName();
+ break;
+ }
+ }
+ if (AtLoc.isValid())
S.Diag(AtLoc, diag::note_property_synthesize);
+
+ return Property;
}
/// Determine whether any storage attributes were written on the property.
@@ -996,8 +1128,9 @@ Decl *Sema::ActOnPropertyImplDecl(Scope *S,
}
}
if (Synthesize && isa<ObjCProtocolDecl>(property->getDeclContext()))
- DiagnosePropertyMismatchDeclInProtocols(*this, AtLoc, IDecl, property);
-
+ property = SelectPropertyForSynthesisFromProtocols(*this, AtLoc, IDecl,
+ property);
+
} else if ((CatImplClass = dyn_cast<ObjCCategoryImplDecl>(ClassImpDecl))) {
if (Synthesize) {
Diag(AtLoc, diag::err_synthesize_category_decl);
diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp
index 1e0b6c158348..01f574b6aeeb 100644
--- a/lib/Sema/SemaOpenMP.cpp
+++ b/lib/Sema/SemaOpenMP.cpp
@@ -1807,6 +1807,8 @@ void Sema::ActOnOpenMPRegionStart(OpenMPDirectiveKind DKind, Scope *CurScope) {
std::make_pair(".lb.", KmpUInt64Ty),
std::make_pair(".ub.", KmpUInt64Ty), std::make_pair(".st.", KmpInt64Ty),
std::make_pair(".liter.", KmpInt32Ty),
+ std::make_pair(".reductions.",
+ Context.VoidPtrTy.withConst().withRestrict()),
std::make_pair(StringRef(), QualType()) // __context with shared vars
};
ActOnCapturedRegionStart(DSAStack->getConstructLoc(), CurScope, CR_OpenMP,
@@ -2498,9 +2500,8 @@ StmtResult Sema::ActOnOpenMPExecutableDirective(
Res = ActOnOpenMPTaskwaitDirective(StartLoc, EndLoc);
break;
case OMPD_taskgroup:
- assert(ClausesWithImplicit.empty() &&
- "No clauses are allowed for 'omp taskgroup' directive");
- Res = ActOnOpenMPTaskgroupDirective(AStmt, StartLoc, EndLoc);
+ Res = ActOnOpenMPTaskgroupDirective(ClausesWithImplicit, AStmt, StartLoc,
+ EndLoc);
break;
case OMPD_flush:
assert(AStmt == nullptr &&
@@ -5067,7 +5068,8 @@ StmtResult Sema::ActOnOpenMPTaskwaitDirective(SourceLocation StartLoc,
return OMPTaskwaitDirective::Create(Context, StartLoc, EndLoc);
}
-StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt,
+StmtResult Sema::ActOnOpenMPTaskgroupDirective(ArrayRef<OMPClause *> Clauses,
+ Stmt *AStmt,
SourceLocation StartLoc,
SourceLocation EndLoc) {
if (!AStmt)
@@ -5077,7 +5079,8 @@ StmtResult Sema::ActOnOpenMPTaskgroupDirective(Stmt *AStmt,
getCurFunction()->setHasBranchProtectedScope();
- return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, AStmt);
+ return OMPTaskgroupDirective::Create(Context, StartLoc, EndLoc, Clauses,
+ AStmt);
}
StmtResult Sema::ActOnOpenMPFlushDirective(ArrayRef<OMPClause *> Clauses,
@@ -6849,6 +6852,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprClause(OpenMPClauseKind Kind, Expr *Expr,
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
@@ -7152,6 +7156,7 @@ static OpenMPDirectiveKind getOpenMPCaptureRegionForClause(
case OMPC_firstprivate:
case OMPC_lastprivate:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_linear:
case OMPC_default:
case OMPC_proc_bind:
@@ -7467,6 +7472,7 @@ OMPClause *Sema::ActOnOpenMPSimpleClause(
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
@@ -7624,6 +7630,7 @@ OMPClause *Sema::ActOnOpenMPSingleExprWithArgClause(
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
@@ -7821,6 +7828,7 @@ OMPClause *Sema::ActOnOpenMPClause(OpenMPClauseKind Kind,
case OMPC_lastprivate:
case OMPC_shared:
case OMPC_reduction:
+ case OMPC_task_reduction:
case OMPC_linear:
case OMPC_aligned:
case OMPC_copyin:
@@ -7933,6 +7941,11 @@ OMPClause *Sema::ActOnOpenMPVarListClause(
Res = ActOnOpenMPReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
EndLoc, ReductionIdScopeSpec, ReductionId);
break;
+ case OMPC_task_reduction:
+ Res = ActOnOpenMPTaskReductionClause(VarList, StartLoc, LParenLoc, ColonLoc,
+ EndLoc, ReductionIdScopeSpec,
+ ReductionId);
+ break;
case OMPC_linear:
Res = ActOnOpenMPLinearClause(VarList, TailExpr, StartLoc, LParenLoc,
LinKind, DepLinMapLoc, ColonLoc, EndLoc);
@@ -8901,15 +8914,66 @@ buildDeclareReductionRef(Sema &SemaRef, SourceLocation Loc, SourceRange Range,
return ExprEmpty();
}
-OMPClause *Sema::ActOnOpenMPReductionClause(
+namespace {
+/// Data for the reduction-based clauses.
+struct ReductionData {
+ /// List of original reduction items.
+ SmallVector<Expr *, 8> Vars;
+ /// List of private copies of the reduction items.
+ SmallVector<Expr *, 8> Privates;
+ /// LHS expressions for the reduction_op expressions.
+ SmallVector<Expr *, 8> LHSs;
+ /// RHS expressions for the reduction_op expressions.
+ SmallVector<Expr *, 8> RHSs;
+ /// Reduction operation expression.
+ SmallVector<Expr *, 8> ReductionOps;
+ /// List of captures for clause.
+ SmallVector<Decl *, 4> ExprCaptures;
+ /// List of postupdate expressions.
+ SmallVector<Expr *, 4> ExprPostUpdates;
+ ReductionData() = delete;
+ /// Reserves required memory for the reduction data.
+ ReductionData(unsigned Size) {
+ Vars.reserve(Size);
+ Privates.reserve(Size);
+ LHSs.reserve(Size);
+ RHSs.reserve(Size);
+ ReductionOps.reserve(Size);
+ ExprCaptures.reserve(Size);
+ ExprPostUpdates.reserve(Size);
+ }
+ /// Stores reduction item and reduction operation only (required for dependent
+ /// reduction item).
+ void push(Expr *Item, Expr *ReductionOp) {
+ Vars.emplace_back(Item);
+ Privates.emplace_back(nullptr);
+ LHSs.emplace_back(nullptr);
+ RHSs.emplace_back(nullptr);
+ ReductionOps.emplace_back(ReductionOp);
+ }
+ /// Stores reduction data.
+ void push(Expr *Item, Expr *Private, Expr *LHS, Expr *RHS,
+ Expr *ReductionOp) {
+ Vars.emplace_back(Item);
+ Privates.emplace_back(Private);
+ LHSs.emplace_back(LHS);
+ RHSs.emplace_back(RHS);
+ ReductionOps.emplace_back(ReductionOp);
+ }
+};
+} // namespace
+
+static bool ActOnOMPReductionKindClause(
+ Sema &S, DSAStackTy *Stack, OpenMPClauseKind ClauseKind,
ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
SourceLocation ColonLoc, SourceLocation EndLoc,
CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
- ArrayRef<Expr *> UnresolvedReductions) {
+ ArrayRef<Expr *> UnresolvedReductions, ReductionData &RD) {
auto DN = ReductionId.getName();
auto OOK = DN.getCXXOverloadedOperator();
BinaryOperatorKind BOK = BO_Comma;
+ ASTContext &Context = S.Context;
// OpenMP [2.14.3.6, reduction clause]
// C
// reduction-identifier is either an identifier or one of the following
@@ -8993,13 +9057,6 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
ReductionIdRange.setBegin(ReductionIdScopeSpec.getBeginLoc());
ReductionIdRange.setEnd(ReductionId.getEndLoc());
- SmallVector<Expr *, 8> Vars;
- SmallVector<Expr *, 8> Privates;
- SmallVector<Expr *, 8> LHSs;
- SmallVector<Expr *, 8> RHSs;
- SmallVector<Expr *, 8> ReductionOps;
- SmallVector<Decl *, 4> ExprCaptures;
- SmallVector<Expr *, 4> ExprPostUpdates;
auto IR = UnresolvedReductions.begin(), ER = UnresolvedReductions.end();
bool FirstIter = true;
for (auto RefExpr : VarList) {
@@ -9017,27 +9074,23 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
SourceLocation ELoc;
SourceRange ERange;
Expr *SimpleRefExpr = RefExpr;
- auto Res = getPrivateItem(*this, SimpleRefExpr, ELoc, ERange,
+ auto Res = getPrivateItem(S, SimpleRefExpr, ELoc, ERange,
/*AllowArraySection=*/true);
if (Res.second) {
- // It will be analyzed later.
- Vars.push_back(RefExpr);
- Privates.push_back(nullptr);
- LHSs.push_back(nullptr);
- RHSs.push_back(nullptr);
// Try to find 'declare reduction' corresponding construct before using
// builtin/overloaded operators.
QualType Type = Context.DependentTy;
CXXCastPath BasePath;
ExprResult DeclareReductionRef = buildDeclareReductionRef(
- *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec,
+ S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
- if (CurContext->isDependentContext() &&
+ Expr *ReductionOp = nullptr;
+ if (S.CurContext->isDependentContext() &&
(DeclareReductionRef.isUnset() ||
isa<UnresolvedLookupExpr>(DeclareReductionRef.get())))
- ReductionOps.push_back(DeclareReductionRef.get());
- else
- ReductionOps.push_back(nullptr);
+ ReductionOp = DeclareReductionRef.get();
+ // It will be analyzed later.
+ RD.push(RefExpr, ReductionOp);
}
ValueDecl *D = Res.first;
if (!D)
@@ -9062,21 +9115,19 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
// OpenMP [2.9.3.3, Restrictions, C/C++, p.3]
// A variable that appears in a private clause must not have an incomplete
// type or a reference type.
- if (RequireCompleteType(ELoc, Type,
- diag::err_omp_reduction_incomplete_type))
+ if (S.RequireCompleteType(ELoc, Type,
+ diag::err_omp_reduction_incomplete_type))
continue;
// OpenMP [2.14.3.6, reduction clause, Restrictions]
// A list item that appears in a reduction clause must not be
// const-qualified.
if (Type.getNonReferenceType().isConstant(Context)) {
- Diag(ELoc, diag::err_omp_const_reduction_list_item)
- << getOpenMPClauseName(OMPC_reduction) << Type << ERange;
+ S.Diag(ELoc, diag::err_omp_const_reduction_list_item) << ERange;
if (!ASE && !OASE) {
- bool IsDecl = !VD ||
- VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(D->getLocation(),
- IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ S.Diag(D->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
<< D;
}
continue;
@@ -9087,10 +9138,11 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
if (!ASE && !OASE && VD) {
VarDecl *VDDef = VD->getDefinition();
if (VD->getType()->isReferenceType() && VDDef && VDDef->hasInit()) {
- DSARefChecker Check(DSAStack);
+ DSARefChecker Check(Stack);
if (Check.Visit(VDDef->getInit())) {
- Diag(ELoc, diag::err_omp_reduction_ref_type_arg) << ERange;
- Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
+ S.Diag(ELoc, diag::err_omp_reduction_ref_type_arg)
+ << getOpenMPClauseName(ClauseKind) << ERange;
+ S.Diag(VDDef->getLocation(), diag::note_defined_here) << VDDef;
continue;
}
}
@@ -9108,17 +9160,17 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
// but a list item can appear only once in the reduction clauses for that
// directive.
DSAStackTy::DSAVarData DVar;
- DVar = DSAStack->getTopDSA(D, false);
+ DVar = Stack->getTopDSA(D, false);
if (DVar.CKind == OMPC_reduction) {
- Diag(ELoc, diag::err_omp_once_referenced)
- << getOpenMPClauseName(OMPC_reduction);
+ S.Diag(ELoc, diag::err_omp_once_referenced)
+ << getOpenMPClauseName(ClauseKind);
if (DVar.RefExpr)
- Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
+ S.Diag(DVar.RefExpr->getExprLoc(), diag::note_omp_referenced);
} else if (DVar.CKind != OMPC_unknown) {
- Diag(ELoc, diag::err_omp_wrong_dsa)
+ S.Diag(ELoc, diag::err_omp_wrong_dsa)
<< getOpenMPClauseName(DVar.CKind)
<< getOpenMPClauseName(OMPC_reduction);
- ReportOriginalDSA(*this, DSAStack, D, DVar);
+ ReportOriginalDSA(S, Stack, D, DVar);
continue;
}
@@ -9126,16 +9178,16 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
// A list item that appears in a reduction clause of a worksharing
// construct must be shared in the parallel regions to which any of the
// worksharing regions arising from the worksharing construct bind.
- OpenMPDirectiveKind CurrDir = DSAStack->getCurrentDirective();
+ OpenMPDirectiveKind CurrDir = Stack->getCurrentDirective();
if (isOpenMPWorksharingDirective(CurrDir) &&
!isOpenMPParallelDirective(CurrDir) &&
!isOpenMPTeamsDirective(CurrDir)) {
- DVar = DSAStack->getImplicitDSA(D, true);
+ DVar = Stack->getImplicitDSA(D, true);
if (DVar.CKind != OMPC_shared) {
- Diag(ELoc, diag::err_omp_required_access)
+ S.Diag(ELoc, diag::err_omp_required_access)
<< getOpenMPClauseName(OMPC_reduction)
<< getOpenMPClauseName(OMPC_shared);
- ReportOriginalDSA(*this, DSAStack, D, DVar);
+ ReportOriginalDSA(S, Stack, D, DVar);
continue;
}
}
@@ -9144,24 +9196,20 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
// builtin/overloaded operators.
CXXCastPath BasePath;
ExprResult DeclareReductionRef = buildDeclareReductionRef(
- *this, ELoc, ERange, DSAStack->getCurScope(), ReductionIdScopeSpec,
+ S, ELoc, ERange, Stack->getCurScope(), ReductionIdScopeSpec,
ReductionId, Type, BasePath, IR == ER ? nullptr : *IR);
if (DeclareReductionRef.isInvalid())
continue;
- if (CurContext->isDependentContext() &&
+ if (S.CurContext->isDependentContext() &&
(DeclareReductionRef.isUnset() ||
isa<UnresolvedLookupExpr>(DeclareReductionRef.get()))) {
- Vars.push_back(RefExpr);
- Privates.push_back(nullptr);
- LHSs.push_back(nullptr);
- RHSs.push_back(nullptr);
- ReductionOps.push_back(DeclareReductionRef.get());
+ RD.push(RefExpr, DeclareReductionRef.get());
continue;
}
if (BOK == BO_Comma && DeclareReductionRef.isUnset()) {
// Not allowed reduction identifier is found.
- Diag(ReductionId.getLocStart(),
- diag::err_omp_unknown_reduction_identifier)
+ S.Diag(ReductionId.getLocStart(),
+ diag::err_omp_unknown_reduction_identifier)
<< Type << ReductionIdRange;
continue;
}
@@ -9177,28 +9225,27 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
if (DeclareReductionRef.isUnset()) {
if ((BOK == BO_GT || BOK == BO_LT) &&
!(Type->isScalarType() ||
- (getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
- Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
- << getLangOpts().CPlusPlus;
+ (S.getLangOpts().CPlusPlus && Type->isArithmeticType()))) {
+ S.Diag(ELoc, diag::err_omp_clause_not_arithmetic_type_arg)
+ << getOpenMPClauseName(ClauseKind) << S.getLangOpts().CPlusPlus;
if (!ASE && !OASE) {
- bool IsDecl = !VD ||
- VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(D->getLocation(),
- IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ S.Diag(D->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
<< D;
}
continue;
}
if ((BOK == BO_OrAssign || BOK == BO_AndAssign || BOK == BO_XorAssign) &&
- !getLangOpts().CPlusPlus && Type->isFloatingType()) {
- Diag(ELoc, diag::err_omp_clause_floating_type_arg);
+ !S.getLangOpts().CPlusPlus && Type->isFloatingType()) {
+ S.Diag(ELoc, diag::err_omp_clause_floating_type_arg)
+ << getOpenMPClauseName(ClauseKind);
if (!ASE && !OASE) {
- bool IsDecl = !VD ||
- VD->isThisDeclarationADefinition(Context) ==
- VarDecl::DeclarationOnly;
- Diag(D->getLocation(),
- IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ S.Diag(D->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
<< D;
}
continue;
@@ -9206,9 +9253,9 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
}
Type = Type.getNonLValueExprType(Context).getUnqualifiedType();
- auto *LHSVD = buildVarDecl(*this, ELoc, Type, ".reduction.lhs",
+ auto *LHSVD = buildVarDecl(S, ELoc, Type, ".reduction.lhs",
D->hasAttrs() ? &D->getAttrs() : nullptr);
- auto *RHSVD = buildVarDecl(*this, ELoc, Type, D->getName(),
+ auto *RHSVD = buildVarDecl(S, ELoc, Type, D->getName(),
D->hasAttrs() ? &D->getAttrs() : nullptr);
auto PrivateTy = Type;
if (OASE ||
@@ -9220,19 +9267,20 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
// For array subscripts or single variables Private Ty is the same as Type
// (type of the variable or single array element).
PrivateTy = Context.getVariableArrayType(
- Type, new (Context) OpaqueValueExpr(SourceLocation(),
- Context.getSizeType(), VK_RValue),
+ Type,
+ new (Context) OpaqueValueExpr(SourceLocation(), Context.getSizeType(),
+ VK_RValue),
ArrayType::Normal, /*IndexTypeQuals=*/0, SourceRange());
} else if (!ASE && !OASE &&
Context.getAsArrayType(D->getType().getNonReferenceType()))
PrivateTy = D->getType().getNonReferenceType();
// Private copy.
- auto *PrivateVD = buildVarDecl(*this, ELoc, PrivateTy, D->getName(),
+ auto *PrivateVD = buildVarDecl(S, ELoc, PrivateTy, D->getName(),
D->hasAttrs() ? &D->getAttrs() : nullptr);
// Add initializer for private variable.
Expr *Init = nullptr;
- auto *LHSDRE = buildDeclRefExpr(*this, LHSVD, Type, ELoc);
- auto *RHSDRE = buildDeclRefExpr(*this, RHSVD, Type, ELoc);
+ auto *LHSDRE = buildDeclRefExpr(S, LHSVD, Type, ELoc);
+ auto *RHSDRE = buildDeclRefExpr(S, RHSVD, Type, ELoc);
if (DeclareReductionRef.isUsable()) {
auto *DRDRef = DeclareReductionRef.getAs<DeclRefExpr>();
auto *DRD = cast<OMPDeclareReductionDecl>(DRDRef->getDecl());
@@ -9249,13 +9297,13 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
case BO_LOr:
// '+', '-', '^', '|', '||' reduction ops - initializer is '0'.
if (Type->isScalarType() || Type->isAnyComplexType())
- Init = ActOnIntegerConstant(ELoc, /*Val=*/0).get();
+ Init = S.ActOnIntegerConstant(ELoc, /*Val=*/0).get();
break;
case BO_Mul:
case BO_LAnd:
if (Type->isScalarType() || Type->isAnyComplexType()) {
// '*' and '&&' reduction ops - initializer is '1'.
- Init = ActOnIntegerConstant(ELoc, /*Val=*/1).get();
+ Init = S.ActOnIntegerConstant(ELoc, /*Val=*/1).get();
}
break;
case BO_And: {
@@ -9278,7 +9326,7 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
if (Init && OrigType->isAnyComplexType()) {
// Init = 0xFFFF + 0xFFFFi;
auto *Im = new (Context) ImaginaryLiteral(Init, OrigType);
- Init = CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
+ Init = S.CreateBuiltinBinOp(ELoc, BO_Add, Init, Im).get();
}
Type = OrigType;
break;
@@ -9295,15 +9343,14 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
QualType IntTy =
Context.getIntTypeForBitwidth(Size, /*Signed=*/IsSigned);
llvm::APInt InitValue =
- (BOK != BO_LT)
- ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
- : llvm::APInt::getMinValue(Size)
- : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
- : llvm::APInt::getMaxValue(Size);
+ (BOK != BO_LT) ? IsSigned ? llvm::APInt::getSignedMinValue(Size)
+ : llvm::APInt::getMinValue(Size)
+ : IsSigned ? llvm::APInt::getSignedMaxValue(Size)
+ : llvm::APInt::getMaxValue(Size);
Init = IntegerLiteral::Create(Context, InitValue, IntTy, ELoc);
if (Type->isPointerType()) {
// Cast to pointer type.
- auto CastExpr = BuildCStyleCastExpr(
+ auto CastExpr = S.BuildCStyleCastExpr(
SourceLocation(), Context.getTrivialTypeSourceInfo(Type, ELoc),
SourceLocation(), Init);
if (CastExpr.isInvalid())
@@ -9344,20 +9391,19 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
llvm_unreachable("Unexpected reduction operation");
}
}
- if (Init && DeclareReductionRef.isUnset()) {
- AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
- } else if (!Init)
- ActOnUninitializedDecl(RHSVD);
+ if (Init && DeclareReductionRef.isUnset())
+ S.AddInitializerToDecl(RHSVD, Init, /*DirectInit=*/false);
+ else if (!Init)
+ S.ActOnUninitializedDecl(RHSVD);
if (RHSVD->isInvalidDecl())
continue;
if (!RHSVD->hasInit() && DeclareReductionRef.isUnset()) {
- Diag(ELoc, diag::err_omp_reduction_id_not_compatible) << Type
- << ReductionIdRange;
- bool IsDecl =
- !VD ||
- VD->isThisDeclarationADefinition(Context) == VarDecl::DeclarationOnly;
- Diag(D->getLocation(),
- IsDecl ? diag::note_previous_decl : diag::note_defined_here)
+ S.Diag(ELoc, diag::err_omp_reduction_id_not_compatible)
+ << Type << ReductionIdRange;
+ bool IsDecl = !VD || VD->isThisDeclarationADefinition(Context) ==
+ VarDecl::DeclarationOnly;
+ S.Diag(D->getLocation(),
+ IsDecl ? diag::note_previous_decl : diag::note_defined_here)
<< D;
continue;
}
@@ -9365,16 +9411,16 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
// codegen.
PrivateVD->setInit(RHSVD->getInit());
PrivateVD->setInitStyle(RHSVD->getInitStyle());
- auto *PrivateDRE = buildDeclRefExpr(*this, PrivateVD, PrivateTy, ELoc);
+ auto *PrivateDRE = buildDeclRefExpr(S, PrivateVD, PrivateTy, ELoc);
ExprResult ReductionOp;
if (DeclareReductionRef.isUsable()) {
QualType RedTy = DeclareReductionRef.get()->getType();
QualType PtrRedTy = Context.getPointerType(RedTy);
- ExprResult LHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
- ExprResult RHS = CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
+ ExprResult LHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, LHSDRE);
+ ExprResult RHS = S.CreateBuiltinUnaryOp(ELoc, UO_AddrOf, RHSDRE);
if (!BasePath.empty()) {
- LHS = DefaultLvalueConversion(LHS.get());
- RHS = DefaultLvalueConversion(RHS.get());
+ LHS = S.DefaultLvalueConversion(LHS.get());
+ RHS = S.DefaultLvalueConversion(RHS.get());
LHS = ImplicitCastExpr::Create(Context, PtrRedTy,
CK_UncheckedDerivedToBase, LHS.get(),
&BasePath, LHS.get()->getValueKind());
@@ -9387,27 +9433,27 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
QualType FnTy = Context.getFunctionType(Context.VoidTy, Params, EPI);
auto *OVE = new (Context) OpaqueValueExpr(
ELoc, Context.getPointerType(FnTy), VK_RValue, OK_Ordinary,
- DefaultLvalueConversion(DeclareReductionRef.get()).get());
+ S.DefaultLvalueConversion(DeclareReductionRef.get()).get());
Expr *Args[] = {LHS.get(), RHS.get()};
ReductionOp = new (Context)
CallExpr(Context, OVE, Args, Context.VoidTy, VK_RValue, ELoc);
} else {
- ReductionOp = BuildBinOp(DSAStack->getCurScope(),
- ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
+ ReductionOp = S.BuildBinOp(
+ Stack->getCurScope(), ReductionId.getLocStart(), BOK, LHSDRE, RHSDRE);
if (ReductionOp.isUsable()) {
if (BOK != BO_LT && BOK != BO_GT) {
ReductionOp =
- BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
- BO_Assign, LHSDRE, ReductionOp.get());
+ S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
+ BO_Assign, LHSDRE, ReductionOp.get());
} else {
auto *ConditionalOp = new (Context) ConditionalOperator(
ReductionOp.get(), SourceLocation(), LHSDRE, SourceLocation(),
RHSDRE, Type, VK_LValue, OK_Ordinary);
ReductionOp =
- BuildBinOp(DSAStack->getCurScope(), ReductionId.getLocStart(),
- BO_Assign, LHSDRE, ConditionalOp);
+ S.BuildBinOp(Stack->getCurScope(), ReductionId.getLocStart(),
+ BO_Assign, LHSDRE, ConditionalOp);
}
- ReductionOp = ActOnFinishFullExpr(ReductionOp.get());
+ ReductionOp = S.ActOnFinishFullExpr(ReductionOp.get());
}
if (ReductionOp.isInvalid())
continue;
@@ -9415,54 +9461,86 @@ OMPClause *Sema::ActOnOpenMPReductionClause(
DeclRefExpr *Ref = nullptr;
Expr *VarsExpr = RefExpr->IgnoreParens();
- if (!VD && !CurContext->isDependentContext()) {
+ if (!VD && !S.CurContext->isDependentContext()) {
if (ASE || OASE) {
- TransformExprToCaptures RebuildToCapture(*this, D);
+ TransformExprToCaptures RebuildToCapture(S, D);
VarsExpr =
RebuildToCapture.TransformExpr(RefExpr->IgnoreParens()).get();
Ref = RebuildToCapture.getCapturedExpr();
} else {
- VarsExpr = Ref =
- buildCapture(*this, D, SimpleRefExpr, /*WithInit=*/false);
+ VarsExpr = Ref = buildCapture(S, D, SimpleRefExpr, /*WithInit=*/false);
}
- if (!IsOpenMPCapturedDecl(D)) {
- ExprCaptures.push_back(Ref->getDecl());
+ if (!S.IsOpenMPCapturedDecl(D)) {
+ RD.ExprCaptures.emplace_back(Ref->getDecl());
if (Ref->getDecl()->hasAttr<OMPCaptureNoInitAttr>()) {
- ExprResult RefRes = DefaultLvalueConversion(Ref);
+ ExprResult RefRes = S.DefaultLvalueConversion(Ref);
if (!RefRes.isUsable())
continue;
ExprResult PostUpdateRes =
- BuildBinOp(DSAStack->getCurScope(), ELoc, BO_Assign,
- SimpleRefExpr, RefRes.get());
+ S.BuildBinOp(Stack->getCurScope(), ELoc, BO_Assign, SimpleRefExpr,
+ RefRes.get());
if (!PostUpdateRes.isUsable())
continue;
- if (isOpenMPTaskingDirective(DSAStack->getCurrentDirective())) {
- Diag(RefExpr->getExprLoc(),
- diag::err_omp_reduction_non_addressable_expression)
+ if (isOpenMPTaskingDirective(Stack->getCurrentDirective()) ||
+ Stack->getCurrentDirective() == OMPD_taskgroup) {
+ S.Diag(RefExpr->getExprLoc(),
+ diag::err_omp_reduction_non_addressable_expression)
<< RefExpr->getSourceRange();
continue;
}
- ExprPostUpdates.push_back(
- IgnoredValueConversions(PostUpdateRes.get()).get());
+ RD.ExprPostUpdates.emplace_back(
+ S.IgnoredValueConversions(PostUpdateRes.get()).get());
}
}
}
- DSAStack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
- Vars.push_back(VarsExpr);
- Privates.push_back(PrivateDRE);
- LHSs.push_back(LHSDRE);
- RHSs.push_back(RHSDRE);
- ReductionOps.push_back(ReductionOp.get());
+ // All reduction items are still marked as reduction (to do not increase
+ // code base size).
+ Stack->addDSA(D, RefExpr->IgnoreParens(), OMPC_reduction, Ref);
+ RD.push(VarsExpr, PrivateDRE, LHSDRE, RHSDRE, ReductionOp.get());
}
+ return RD.Vars.empty();
+}
- if (Vars.empty())
+OMPClause *Sema::ActOnOpenMPReductionClause(
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
+ ArrayRef<Expr *> UnresolvedReductions) {
+ ReductionData RD(VarList.size());
+
+ if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_reduction, VarList,
+ StartLoc, LParenLoc, ColonLoc, EndLoc,
+ ReductionIdScopeSpec, ReductionId,
+ UnresolvedReductions, RD))
return nullptr;
return OMPReductionClause::Create(
- Context, StartLoc, LParenLoc, ColonLoc, EndLoc, Vars,
- ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId, Privates,
- LHSs, RHSs, ReductionOps, buildPreInits(Context, ExprCaptures),
- buildPostUpdate(*this, ExprPostUpdates));
+ Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
+ ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
+ RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
+ buildPreInits(Context, RD.ExprCaptures),
+ buildPostUpdate(*this, RD.ExprPostUpdates));
+}
+
+OMPClause *Sema::ActOnOpenMPTaskReductionClause(
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc, SourceLocation LParenLoc,
+ SourceLocation ColonLoc, SourceLocation EndLoc,
+ CXXScopeSpec &ReductionIdScopeSpec, const DeclarationNameInfo &ReductionId,
+ ArrayRef<Expr *> UnresolvedReductions) {
+ ReductionData RD(VarList.size());
+
+ if (ActOnOMPReductionKindClause(*this, DSAStack, OMPC_task_reduction,
+ VarList, StartLoc, LParenLoc, ColonLoc,
+ EndLoc, ReductionIdScopeSpec, ReductionId,
+ UnresolvedReductions, RD))
+ return nullptr;
+
+ return OMPTaskReductionClause::Create(
+ Context, StartLoc, LParenLoc, ColonLoc, EndLoc, RD.Vars,
+ ReductionIdScopeSpec.getWithLocInContext(Context), ReductionId,
+ RD.Privates, RD.LHSs, RD.RHSs, RD.ReductionOps,
+ buildPreInits(Context, RD.ExprCaptures),
+ buildPostUpdate(*this, RD.ExprPostUpdates));
}
bool Sema::CheckOpenMPLinearModifier(OpenMPLinearClauseKind LinKind,
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index b19dcb2a5099..598a11300b87 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -120,6 +120,7 @@ static void diagnoseBadTypeAttribute(Sema &S, const AttributeList &attr,
// Function type attributes.
#define FUNCTION_TYPE_ATTRS_CASELIST \
+ case AttributeList::AT_NSReturnsRetained: \
case AttributeList::AT_NoReturn: \
case AttributeList::AT_Regparm: \
case AttributeList::AT_AnyX86NoCallerSavedRegisters: \
@@ -640,12 +641,6 @@ static void distributeTypeAttrsFromDeclarator(TypeProcessingState &state,
distributeObjCPointerTypeAttrFromDeclarator(state, *attr, declSpecType);
break;
- case AttributeList::AT_NSReturnsRetained:
- if (!state.getSema().getLangOpts().ObjCAutoRefCount)
- break;
- // fallthrough
- LLVM_FALLTHROUGH;
-
FUNCTION_TYPE_ATTRS_CASELIST:
distributeFunctionTypeAttrFromDeclarator(state, *attr, declSpecType);
break;
@@ -2385,6 +2380,11 @@ QualType Sema::BuildFunctionType(QualType T,
[=](unsigned i) { return Loc; });
}
+ if (EPI.ExtInfo.getProducesResult()) {
+ // This is just a warning, so we can't fail to build if we see it.
+ checkNSReturnsRetainedReturnType(Loc, T);
+ }
+
if (Invalid)
return QualType();
@@ -5017,6 +5017,8 @@ static AttributeList::Kind getAttrListKind(AttributedType::Kind kind) {
return AttributeList::AT_TypeNullUnspecified;
case AttributedType::attr_objc_kindof:
return AttributeList::AT_ObjCKindOf;
+ case AttributedType::attr_ns_returns_retained:
+ return AttributeList::AT_NSReturnsRetained;
}
llvm_unreachable("unexpected attribute kind!");
}
@@ -6373,17 +6375,26 @@ static bool handleFunctionTypeAttr(TypeProcessingState &state,
// ns_returns_retained is not always a type attribute, but if we got
// here, we're treating it as one right now.
if (attr.getKind() == AttributeList::AT_NSReturnsRetained) {
- assert(S.getLangOpts().ObjCAutoRefCount &&
- "ns_returns_retained treated as type attribute in non-ARC");
if (attr.getNumArgs()) return true;
// Delay if this is not a function type.
if (!unwrapped.isFunctionType())
return false;
- FunctionType::ExtInfo EI
- = unwrapped.get()->getExtInfo().withProducesResult(true);
- type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
+ // Check whether the return type is reasonable.
+ if (S.checkNSReturnsRetainedReturnType(attr.getLoc(),
+ unwrapped.get()->getReturnType()))
+ return true;
+
+ // Only actually change the underlying type in ARC builds.
+ QualType origType = type;
+ if (state.getSema().getLangOpts().ObjCAutoRefCount) {
+ FunctionType::ExtInfo EI
+ = unwrapped.get()->getExtInfo().withProducesResult(true);
+ type = unwrapped.wrap(S, S.Context.adjustFunctionType(unwrapped.get(), EI));
+ }
+ type = S.Context.getAttributedType(AttributedType::attr_ns_returns_retained,
+ origType, type);
return true;
}
@@ -6945,12 +6956,6 @@ static void processTypeAttrs(TypeProcessingState &state, QualType &type,
attr.setUsedAsTypeAttr();
break;
- case AttributeList::AT_NSReturnsRetained:
- if (!state.getSema().getLangOpts().ObjCAutoRefCount)
- break;
- // fallthrough into the function attrs
- LLVM_FALLTHROUGH;
-
FUNCTION_TYPE_ATTRS_CASELIST:
attr.setUsedAsTypeAttr();
diff --git a/lib/Sema/TreeTransform.h b/lib/Sema/TreeTransform.h
index 7aa8f64d5081..91da9f88c59b 100644
--- a/lib/Sema/TreeTransform.h
+++ b/lib/Sema/TreeTransform.h
@@ -1651,6 +1651,21 @@ public:
ReductionId, UnresolvedReductions);
}
+ /// Build a new OpenMP 'task_reduction' clause.
+ ///
+ /// By default, performs semantic analysis to build the new statement.
+ /// Subclasses may override this routine to provide different behavior.
+ OMPClause *RebuildOMPTaskReductionClause(
+ ArrayRef<Expr *> VarList, SourceLocation StartLoc,
+ SourceLocation LParenLoc, SourceLocation ColonLoc, SourceLocation EndLoc,
+ CXXScopeSpec &ReductionIdScopeSpec,
+ const DeclarationNameInfo &ReductionId,
+ ArrayRef<Expr *> UnresolvedReductions) {
+ return getSema().ActOnOpenMPTaskReductionClause(
+ VarList, StartLoc, LParenLoc, ColonLoc, EndLoc, ReductionIdScopeSpec,
+ ReductionId, UnresolvedReductions);
+ }
+
/// \brief Build a new OpenMP 'linear' clause.
///
/// By default, performs semantic analysis to build the new OpenMP clause.
@@ -8400,6 +8415,51 @@ TreeTransform<Derived>::TransformOMPReductionClause(OMPReductionClause *C) {
}
template <typename Derived>
+OMPClause *TreeTransform<Derived>::TransformOMPTaskReductionClause(
+ OMPTaskReductionClause *C) {
+ llvm::SmallVector<Expr *, 16> Vars;
+ Vars.reserve(C->varlist_size());
+ for (auto *VE : C->varlists()) {
+ ExprResult EVar = getDerived().TransformExpr(cast<Expr>(VE));
+ if (EVar.isInvalid())
+ return nullptr;
+ Vars.push_back(EVar.get());
+ }
+ CXXScopeSpec ReductionIdScopeSpec;
+ ReductionIdScopeSpec.Adopt(C->getQualifierLoc());
+
+ DeclarationNameInfo NameInfo = C->getNameInfo();
+ if (NameInfo.getName()) {
+ NameInfo = getDerived().TransformDeclarationNameInfo(NameInfo);
+ if (!NameInfo.getName())
+ return nullptr;
+ }
+ // Build a list of all UDR decls with the same names ranged by the Scopes.
+ // The Scope boundary is a duplication of the previous decl.
+ llvm::SmallVector<Expr *, 16> UnresolvedReductions;
+ for (auto *E : C->reduction_ops()) {
+ // Transform all the decls.
+ if (E) {
+ auto *ULE = cast<UnresolvedLookupExpr>(E);
+ UnresolvedSet<8> Decls;
+ for (auto *D : ULE->decls()) {
+ NamedDecl *InstD =
+ cast<NamedDecl>(getDerived().TransformDecl(E->getExprLoc(), D));
+ Decls.addDecl(InstD, InstD->getAccess());
+ }
+ UnresolvedReductions.push_back(UnresolvedLookupExpr::Create(
+ SemaRef.Context, /*NamingClass=*/nullptr,
+ ReductionIdScopeSpec.getWithLocInContext(SemaRef.Context), NameInfo,
+ /*ADL=*/true, ULE->isOverloaded(), Decls.begin(), Decls.end()));
+ } else
+ UnresolvedReductions.push_back(nullptr);
+ }
+ return getDerived().RebuildOMPTaskReductionClause(
+ Vars, C->getLocStart(), C->getLParenLoc(), C->getColonLoc(),
+ C->getLocEnd(), ReductionIdScopeSpec, NameInfo, UnresolvedReductions);
+}
+
+template <typename Derived>
OMPClause *
TreeTransform<Derived>::TransformOMPLinearClause(OMPLinearClause *C) {
llvm::SmallVector<Expr *, 16> Vars;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 678ecfc9a3d9..50be74f6bf6e 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1520,7 +1520,7 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
Stream.JumpToBit(Offset);
RecordData Record;
- SmallVector<IdentifierInfo*, 16> MacroArgs;
+ SmallVector<IdentifierInfo*, 16> MacroParams;
MacroInfo *Macro = nullptr;
while (true) {
@@ -1571,17 +1571,17 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
bool isC99VarArgs = Record[NextIndex++];
bool isGNUVarArgs = Record[NextIndex++];
bool hasCommaPasting = Record[NextIndex++];
- MacroArgs.clear();
+ MacroParams.clear();
unsigned NumArgs = Record[NextIndex++];
for (unsigned i = 0; i != NumArgs; ++i)
- MacroArgs.push_back(getLocalIdentifier(F, Record[NextIndex++]));
+ MacroParams.push_back(getLocalIdentifier(F, Record[NextIndex++]));
// Install function-like macro info.
MI->setIsFunctionLike();
if (isC99VarArgs) MI->setIsC99Varargs();
if (isGNUVarArgs) MI->setIsGNUVarargs();
if (hasCommaPasting) MI->setHasCommaPasting();
- MI->setArgumentList(MacroArgs, PP.getPreprocessorAllocator());
+ MI->setParameterList(MacroParams, PP.getPreprocessorAllocator());
}
// Remember that we saw this macro last so that we add the tokens that
@@ -9341,6 +9341,8 @@ void ASTReader::diagnoseOdrViolations() {
case Decl::Field:
return Field;
case Decl::CXXMethod:
+ case Decl::CXXConstructor:
+ case Decl::CXXDestructor:
return CXXMethod;
case Decl::TypeAlias:
return TypeAlias;
@@ -9669,17 +9671,30 @@ void ASTReader::diagnoseOdrViolations() {
break;
}
case CXXMethod: {
+ enum {
+ DiagMethod,
+ DiagConstructor,
+ DiagDestructor,
+ } FirstMethodType,
+ SecondMethodType;
+ auto GetMethodTypeForDiagnostics = [](const CXXMethodDecl* D) {
+ if (isa<CXXConstructorDecl>(D)) return DiagConstructor;
+ if (isa<CXXDestructorDecl>(D)) return DiagDestructor;
+ return DiagMethod;
+ };
const CXXMethodDecl *FirstMethod = cast<CXXMethodDecl>(FirstDecl);
const CXXMethodDecl *SecondMethod = cast<CXXMethodDecl>(SecondDecl);
+ FirstMethodType = GetMethodTypeForDiagnostics(FirstMethod);
+ SecondMethodType = GetMethodTypeForDiagnostics(SecondMethod);
auto FirstName = FirstMethod->getDeclName();
auto SecondName = SecondMethod->getDeclName();
- if (FirstName != SecondName) {
+ if (FirstMethodType != SecondMethodType || FirstName != SecondName) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodName)
- << FirstName;
+ << FirstMethodType << FirstName;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodName)
- << SecondName;
+ << SecondMethodType << SecondName;
Diagnosed = true;
break;
@@ -9690,11 +9705,11 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstDeleted != SecondDeleted) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodDeleted)
- << FirstName << FirstDeleted;
+ << FirstMethodType << FirstName << FirstDeleted;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodDeleted)
- << SecondName << SecondDeleted;
+ << SecondMethodType << SecondName << SecondDeleted;
Diagnosed = true;
break;
}
@@ -9707,10 +9722,10 @@ void ASTReader::diagnoseOdrViolations() {
(FirstVirtual != SecondVirtual || FirstPure != SecondPure)) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodVirtual)
- << FirstName << FirstPure << FirstVirtual;
+ << FirstMethodType << FirstName << FirstPure << FirstVirtual;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodVirtual)
- << SecondName << SecondPure << SecondVirtual;
+ << SecondMethodType << SecondName << SecondPure << SecondVirtual;
Diagnosed = true;
break;
}
@@ -9725,10 +9740,10 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstStatic != SecondStatic) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodStatic)
- << FirstName << FirstStatic;
+ << FirstMethodType << FirstName << FirstStatic;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodStatic)
- << SecondName << SecondStatic;
+ << SecondMethodType << SecondName << SecondStatic;
Diagnosed = true;
break;
}
@@ -9738,10 +9753,10 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstVolatile != SecondVolatile) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodVolatile)
- << FirstName << FirstVolatile;
+ << FirstMethodType << FirstName << FirstVolatile;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodVolatile)
- << SecondName << SecondVolatile;
+ << SecondMethodType << SecondName << SecondVolatile;
Diagnosed = true;
break;
}
@@ -9751,10 +9766,10 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstConst != SecondConst) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodConst)
- << FirstName << FirstConst;
+ << FirstMethodType << FirstName << FirstConst;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodConst)
- << SecondName << SecondConst;
+ << SecondMethodType << SecondName << SecondConst;
Diagnosed = true;
break;
}
@@ -9764,10 +9779,10 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstInline != SecondInline) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodInline)
- << FirstName << FirstInline;
+ << FirstMethodType << FirstName << FirstInline;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodInline)
- << SecondName << SecondInline;
+ << SecondMethodType << SecondName << SecondInline;
Diagnosed = true;
break;
}
@@ -9777,10 +9792,10 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstNumParameters != SecondNumParameters) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodNumberParameters)
- << FirstName << FirstNumParameters;
+ << FirstMethodType << FirstName << FirstNumParameters;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodNumberParameters)
- << SecondName << SecondNumParameters;
+ << SecondMethodType << SecondName << SecondNumParameters;
Diagnosed = true;
break;
}
@@ -9800,24 +9815,27 @@ void ASTReader::diagnoseOdrViolations() {
FirstParamType->getAs<DecayedType>()) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodParameterType)
- << FirstName << (I + 1) << FirstParamType << true
- << ParamDecayedType->getOriginalType();
+ << FirstMethodType << FirstName << (I + 1) << FirstParamType
+ << true << ParamDecayedType->getOriginalType();
} else {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodParameterType)
- << FirstName << (I + 1) << FirstParamType << false;
+ << FirstMethodType << FirstName << (I + 1) << FirstParamType
+ << false;
}
if (const DecayedType *ParamDecayedType =
SecondParamType->getAs<DecayedType>()) {
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodParameterType)
- << SecondName << (I + 1) << SecondParamType << true
+ << SecondMethodType << SecondName << (I + 1)
+ << SecondParamType << true
<< ParamDecayedType->getOriginalType();
} else {
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodParameterType)
- << SecondName << (I + 1) << SecondParamType << false;
+ << SecondMethodType << SecondName << (I + 1)
+ << SecondParamType << false;
}
ParameterMismatch = true;
break;
@@ -9828,10 +9846,10 @@ void ASTReader::diagnoseOdrViolations() {
if (FirstParamName != SecondParamName) {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(), MethodParameterName)
- << FirstName << (I + 1) << FirstParamName;
+ << FirstMethodType << FirstName << (I + 1) << FirstParamName;
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(), MethodParameterName)
- << SecondName << (I + 1) << SecondParamName;
+ << SecondMethodType << SecondName << (I + 1) << SecondParamName;
ParameterMismatch = true;
break;
}
@@ -9842,12 +9860,14 @@ void ASTReader::diagnoseOdrViolations() {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(),
MethodParameterSingleDefaultArgument)
- << FirstName << (I + 1) << (FirstInit == nullptr)
+ << FirstMethodType << FirstName << (I + 1)
+ << (FirstInit == nullptr)
<< (FirstInit ? FirstInit->getSourceRange() : SourceRange());
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(),
MethodParameterSingleDefaultArgument)
- << SecondName << (I + 1) << (SecondInit == nullptr)
+ << SecondMethodType << SecondName << (I + 1)
+ << (SecondInit == nullptr)
<< (SecondInit ? SecondInit->getSourceRange() : SourceRange());
ParameterMismatch = true;
break;
@@ -9858,11 +9878,13 @@ void ASTReader::diagnoseOdrViolations() {
ODRDiagError(FirstMethod->getLocation(),
FirstMethod->getSourceRange(),
MethodParameterDifferentDefaultArgument)
- << FirstName << (I + 1) << FirstInit->getSourceRange();
+ << FirstMethodType << FirstName << (I + 1)
+ << FirstInit->getSourceRange();
ODRDiagNote(SecondMethod->getLocation(),
SecondMethod->getSourceRange(),
MethodParameterDifferentDefaultArgument)
- << SecondName << (I + 1) << SecondInit->getSourceRange();
+ << SecondMethodType << SecondName << (I + 1)
+ << SecondInit->getSourceRange();
ParameterMismatch = true;
break;
diff --git a/lib/Serialization/ASTReaderStmt.cpp b/lib/Serialization/ASTReaderStmt.cpp
index afee50ffa3b9..21adcddd3a4a 100644
--- a/lib/Serialization/ASTReaderStmt.cpp
+++ b/lib/Serialization/ASTReaderStmt.cpp
@@ -1834,6 +1834,9 @@ OMPClause *OMPClauseReader::readClause() {
case OMPC_reduction:
C = OMPReductionClause::CreateEmpty(Context, Reader->Record.readInt());
break;
+ case OMPC_task_reduction:
+ C = OMPTaskReductionClause::CreateEmpty(Context, Reader->Record.readInt());
+ break;
case OMPC_linear:
C = OMPLinearClause::CreateEmpty(Context, Reader->Record.readInt());
break;
@@ -2138,6 +2141,40 @@ void OMPClauseReader::VisitOMPReductionClause(OMPReductionClause *C) {
C->setReductionOps(Vars);
}
+void OMPClauseReader::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
+ VisitOMPClauseWithPostUpdate(C);
+ C->setLParenLoc(Reader->ReadSourceLocation());
+ C->setColonLoc(Reader->ReadSourceLocation());
+ NestedNameSpecifierLoc NNSL = Reader->Record.readNestedNameSpecifierLoc();
+ DeclarationNameInfo DNI;
+ Reader->ReadDeclarationNameInfo(DNI);
+ C->setQualifierLoc(NNSL);
+ C->setNameInfo(DNI);
+
+ unsigned NumVars = C->varlist_size();
+ SmallVector<Expr *, 16> Vars;
+ Vars.reserve(NumVars);
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setVarRefs(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setPrivates(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setLHSExprs(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setRHSExprs(Vars);
+ Vars.clear();
+ for (unsigned I = 0; I != NumVars; ++I)
+ Vars.push_back(Reader->Record.readSubExpr());
+ C->setReductionOps(Vars);
+}
+
void OMPClauseReader::VisitOMPLinearClause(OMPLinearClause *C) {
VisitOMPClauseWithPostUpdate(C);
C->setLParenLoc(Reader->ReadSourceLocation());
@@ -2709,6 +2746,8 @@ void ASTStmtReader::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
void ASTStmtReader::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
VisitStmt(D);
+ // The NumClauses field was read in ReadStmtFromStream.
+ Record.skipInts(1);
VisitOMPExecutableDirective(D);
}
@@ -3479,7 +3518,8 @@ Stmt *ASTReader::ReadStmtFromStream(ModuleFile &F) {
break;
case STMT_OMP_TASKGROUP_DIRECTIVE:
- S = OMPTaskgroupDirective::CreateEmpty(Context, Empty);
+ S = OMPTaskgroupDirective::CreateEmpty(
+ Context, Record[ASTStmtReader::NumStmtFields], Empty);
break;
case STMT_OMP_FLUSH_DIRECTIVE:
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index f7a49e41009d..a875e627bdfb 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2521,9 +2521,9 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
Record.push_back(MI->isC99Varargs());
Record.push_back(MI->isGNUVarargs());
Record.push_back(MI->hasCommaPasting());
- Record.push_back(MI->getNumArgs());
- for (const IdentifierInfo *Arg : MI->args())
- AddIdentifierRef(Arg, Record);
+ Record.push_back(MI->getNumParams());
+ for (const IdentifierInfo *Param : MI->params())
+ AddIdentifierRef(Param, Record);
}
// If we have a detailed preprocessing record, record the macro definition
diff --git a/lib/Serialization/ASTWriterStmt.cpp b/lib/Serialization/ASTWriterStmt.cpp
index 90a732e575e2..ae2e0b88c311 100644
--- a/lib/Serialization/ASTWriterStmt.cpp
+++ b/lib/Serialization/ASTWriterStmt.cpp
@@ -1963,6 +1963,25 @@ void OMPClauseWriter::VisitOMPReductionClause(OMPReductionClause *C) {
Record.AddStmt(E);
}
+void OMPClauseWriter::VisitOMPTaskReductionClause(OMPTaskReductionClause *C) {
+ Record.push_back(C->varlist_size());
+ VisitOMPClauseWithPostUpdate(C);
+ Record.AddSourceLocation(C->getLParenLoc());
+ Record.AddSourceLocation(C->getColonLoc());
+ Record.AddNestedNameSpecifierLoc(C->getQualifierLoc());
+ Record.AddDeclarationNameInfo(C->getNameInfo());
+ for (auto *VE : C->varlists())
+ Record.AddStmt(VE);
+ for (auto *VE : C->privates())
+ Record.AddStmt(VE);
+ for (auto *E : C->lhs_exprs())
+ Record.AddStmt(E);
+ for (auto *E : C->rhs_exprs())
+ Record.AddStmt(E);
+ for (auto *E : C->reduction_ops())
+ Record.AddStmt(E);
+}
+
void OMPClauseWriter::VisitOMPLinearClause(OMPLinearClause *C) {
Record.push_back(C->varlist_size());
VisitOMPClauseWithPostUpdate(C);
@@ -2440,6 +2459,7 @@ void ASTStmtWriter::VisitOMPTaskwaitDirective(OMPTaskwaitDirective *D) {
void ASTStmtWriter::VisitOMPTaskgroupDirective(OMPTaskgroupDirective *D) {
VisitStmt(D);
+ Record.push_back(D->getNumClauses());
VisitOMPExecutableDirective(D);
Code = serialization::STMT_OMP_TASKGROUP_DIRECTIVE;
}
diff --git a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
index 6bbaaac05e6b..655ce33390c9 100644
--- a/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/LocalizationChecker.cpp
@@ -57,7 +57,7 @@ public:
};
class NonLocalizedStringChecker
- : public Checker<check::PostCall, check::PreObjCMessage,
+ : public Checker<check::PreCall, check::PostCall, check::PreObjCMessage,
check::PostObjCMessage,
check::PostStmt<ObjCStringLiteral>> {
@@ -79,9 +79,10 @@ class NonLocalizedStringChecker
void setNonLocalizedState(SVal S, CheckerContext &C) const;
void setLocalizedState(SVal S, CheckerContext &C) const;
- bool isAnnotatedAsLocalized(const Decl *D) const;
- void reportLocalizationError(SVal S, const ObjCMethodCall &M,
- CheckerContext &C, int argumentNumber = 0) const;
+ bool isAnnotatedAsReturningLocalized(const Decl *D) const;
+ bool isAnnotatedAsTakingLocalized(const Decl *D) const;
+ void reportLocalizationError(SVal S, const CallEvent &M, CheckerContext &C,
+ int argumentNumber = 0) const;
int getLocalizedArgumentForSelector(const IdentifierInfo *Receiver,
Selector S) const;
@@ -97,6 +98,7 @@ public:
void checkPreObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
void checkPostObjCMessage(const ObjCMethodCall &msg, CheckerContext &C) const;
void checkPostStmt(const ObjCStringLiteral *SL, CheckerContext &C) const;
+ void checkPreCall(const CallEvent &Call, CheckerContext &C) const;
void checkPostCall(const CallEvent &Call, CheckerContext &C) const;
};
@@ -644,7 +646,8 @@ void NonLocalizedStringChecker::initLocStringsMethods(ASTContext &Ctx) const {
/// Checks to see if the method / function declaration includes
/// __attribute__((annotate("returns_localized_nsstring")))
-bool NonLocalizedStringChecker::isAnnotatedAsLocalized(const Decl *D) const {
+bool NonLocalizedStringChecker::isAnnotatedAsReturningLocalized(
+ const Decl *D) const {
if (!D)
return false;
return std::any_of(
@@ -654,6 +657,19 @@ bool NonLocalizedStringChecker::isAnnotatedAsLocalized(const Decl *D) const {
});
}
+/// Checks to see if the method / function declaration includes
+/// __attribute__((annotate("takes_localized_nsstring")))
+bool NonLocalizedStringChecker::isAnnotatedAsTakingLocalized(
+ const Decl *D) const {
+ if (!D)
+ return false;
+ return std::any_of(
+ D->specific_attr_begin<AnnotateAttr>(),
+ D->specific_attr_end<AnnotateAttr>(), [](const AnnotateAttr *Ann) {
+ return Ann->getAnnotation() == "takes_localized_nsstring";
+ });
+}
+
/// Returns true if the given SVal is marked as Localized in the program state
bool NonLocalizedStringChecker::hasLocalizedState(SVal S,
CheckerContext &C) const {
@@ -733,8 +749,7 @@ static bool isDebuggingContext(CheckerContext &C) {
/// Reports a localization error for the passed in method call and SVal
void NonLocalizedStringChecker::reportLocalizationError(
- SVal S, const ObjCMethodCall &M, CheckerContext &C,
- int argumentNumber) const {
+ SVal S, const CallEvent &M, CheckerContext &C, int argumentNumber) const {
// Don't warn about localization errors in classes and methods that
// may be debug code.
@@ -832,7 +847,21 @@ void NonLocalizedStringChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
}
}
- if (argumentNumber < 0) // There was no match in UIMethods
+ if (argumentNumber < 0) { // There was no match in UIMethods
+ if (const Decl *D = msg.getDecl()) {
+ if (const ObjCMethodDecl *OMD = dyn_cast_or_null<ObjCMethodDecl>(D)) {
+ auto formals = OMD->parameters();
+ for (unsigned i = 0, ei = formals.size(); i != ei; ++i) {
+ if (isAnnotatedAsTakingLocalized(formals[i])) {
+ argumentNumber = i;
+ break;
+ }
+ }
+ }
+ }
+ }
+
+ if (argumentNumber < 0) // Still no match
return;
SVal svTitle = msg.getArgSVal(argumentNumber);
@@ -855,6 +884,25 @@ void NonLocalizedStringChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
}
}
+void NonLocalizedStringChecker::checkPreCall(const CallEvent &Call,
+ CheckerContext &C) const {
+ const Decl *D = Call.getDecl();
+ if (D && isa<FunctionDecl>(D)) {
+ const FunctionDecl *FD = dyn_cast<FunctionDecl>(D);
+ auto formals = FD->parameters();
+ for (unsigned i = 0,
+ ei = std::min(unsigned(formals.size()), Call.getNumArgs());
+ i != ei; ++i) {
+ if (isAnnotatedAsTakingLocalized(formals[i])) {
+ auto actual = Call.getArgSVal(i);
+ if (hasNonLocalizedState(actual, C)) {
+ reportLocalizationError(actual, Call, C, i + 1);
+ }
+ }
+ }
+ }
+}
+
static inline bool isNSStringType(QualType T, ASTContext &Ctx) {
const ObjCObjectPointerType *PT = T->getAs<ObjCObjectPointerType>();
@@ -906,7 +954,7 @@ void NonLocalizedStringChecker::checkPostCall(const CallEvent &Call,
const IdentifierInfo *Identifier = Call.getCalleeIdentifier();
SVal sv = Call.getReturnValue();
- if (isAnnotatedAsLocalized(D) || LSF.count(Identifier) != 0) {
+ if (isAnnotatedAsReturningLocalized(D) || LSF.count(Identifier) != 0) {
setLocalizedState(sv, C);
} else if (isNSStringType(RT, C.getASTContext()) &&
!hasLocalizedState(sv, C)) {
@@ -940,7 +988,8 @@ void NonLocalizedStringChecker::checkPostObjCMessage(const ObjCMethodCall &msg,
std::pair<const IdentifierInfo *, Selector> MethodDescription = {odInfo, S};
- if (LSM.count(MethodDescription) || isAnnotatedAsLocalized(msg.getDecl())) {
+ if (LSM.count(MethodDescription) ||
+ isAnnotatedAsReturningLocalized(msg.getDecl())) {
SVal sv = msg.getReturnValue();
setLocalizedState(sv, C);
}
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 89b1291c4f46..21ccf21515b3 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -1304,6 +1304,21 @@ RetainSummaryManager::getCFSummaryGetRule(const FunctionDecl *FD) {
DoNothing, DoNothing);
}
+/// Returns true if the declaration 'D' is annotated with 'rcAnnotation'.
+static bool hasRCAnnotation(const Decl *D, StringRef rcAnnotation) {
+ for (const auto *Ann : D->specific_attrs<AnnotateAttr>()) {
+ if (Ann->getAnnotation() == rcAnnotation)
+ return true;
+ }
+ return false;
+}
+
+/// Returns true if the function declaration 'FD' contains
+/// 'rc_ownership_trusted_implementation' annotate attribute.
+static bool isTrustedReferenceCountImplementation(const FunctionDecl *FD) {
+ return hasRCAnnotation(FD, "rc_ownership_trusted_implementation");
+}
+
//===----------------------------------------------------------------------===//
// Summary creation for Selectors.
//===----------------------------------------------------------------------===//
@@ -3380,6 +3395,9 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// See if it's one of the specific functions we know how to eval.
bool canEval = false;
+ // See if the function has 'rc_ownership_trusted_implementation'
+ // annotate attribute. If it does, we will not inline it.
+ bool hasTrustedImplementationAnnotation = false;
QualType ResultTy = CE->getCallReturnType(C.getASTContext());
if (ResultTy->isObjCIdType()) {
@@ -3395,6 +3413,11 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
cocoa::isRefType(ResultTy, "CV", FName)) {
canEval = isRetain(FD, FName) || isAutorelease(FD, FName) ||
isMakeCollectable(FD, FName);
+ } else {
+ if (FD->getDefinition()) {
+ canEval = isTrustedReferenceCountImplementation(FD->getDefinition());
+ hasTrustedImplementationAnnotation = canEval;
+ }
}
}
@@ -3404,8 +3427,11 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
// Bind the return value.
const LocationContext *LCtx = C.getLocationContext();
SVal RetVal = state->getSVal(CE->getArg(0), LCtx);
- if (RetVal.isUnknown()) {
- // If the receiver is unknown, conjure a return value.
+ if (RetVal.isUnknown() ||
+ (hasTrustedImplementationAnnotation && !ResultTy.isNull())) {
+ // If the receiver is unknown or the function has
+ // 'rc_ownership_trusted_implementation' annotate attribute, conjure a
+ // return value.
SValBuilder &SVB = C.getSValBuilder();
RetVal = SVB.conjureSymbolVal(nullptr, CE, LCtx, ResultTy, C.blockCount());
}
@@ -3421,8 +3447,9 @@ bool RetainCountChecker::evalCall(const CallExpr *CE, CheckerContext &C) const {
Binding = getRefBinding(state, Sym);
// Invalidate the argument region.
- state = state->invalidateRegions(ArgRegion, CE, C.blockCount(), LCtx,
- /*CausesPointerEscape*/ false);
+ state = state->invalidateRegions(
+ ArgRegion, CE, C.blockCount(), LCtx,
+ /*CausesPointerEscape*/ hasTrustedImplementationAnnotation);
// Restore the refcount status of the argument.
if (Binding)
diff --git a/lib/Tooling/Refactoring/Rename/USRFinder.cpp b/lib/Tooling/Refactoring/Rename/USRFinder.cpp
index f36387dafdbf..3bfb5bbe35e4 100644
--- a/lib/Tooling/Refactoring/Rename/USRFinder.cpp
+++ b/lib/Tooling/Refactoring/Rename/USRFinder.cpp
@@ -18,6 +18,7 @@
#include "clang/AST/RecursiveASTVisitor.h"
#include "clang/Index/USRGeneration.h"
#include "clang/Lex/Lexer.h"
+#include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
#include "llvm/ADT/SmallVector.h"
using namespace llvm;
@@ -25,132 +26,38 @@ using namespace llvm;
namespace clang {
namespace tooling {
-// NamedDeclFindingASTVisitor recursively visits each AST node to find the
-// symbol underneath the cursor.
-// FIXME: move to separate .h/.cc file if this gets too large.
namespace {
-class NamedDeclFindingASTVisitor
- : public clang::RecursiveASTVisitor<NamedDeclFindingASTVisitor> {
+
+/// Recursively visits each AST node to find the symbol underneath the cursor.
+class NamedDeclOccurrenceFindingVisitor
+ : public RecursiveSymbolVisitor<NamedDeclOccurrenceFindingVisitor> {
public:
// \brief Finds the NamedDecl at a point in the source.
// \param Point the location in the source to search for the NamedDecl.
- explicit NamedDeclFindingASTVisitor(const SourceLocation Point,
- const ASTContext &Context)
- : Result(nullptr), Point(Point), Context(Context) {}
-
- // \brief Finds the NamedDecl for a name in the source.
- // \param Name the fully qualified name.
- explicit NamedDeclFindingASTVisitor(const std::string &Name,
- const ASTContext &Context)
- : Result(nullptr), Name(Name), Context(Context) {}
-
- // Declaration visitors:
-
- // \brief Checks if the point falls within the NameDecl. This covers every
- // declaration of a named entity that we may come across. Usually, just
- // checking if the point lies within the length of the name of the declaration
- // and the start location is sufficient.
- bool VisitNamedDecl(const NamedDecl *Decl) {
- return dyn_cast<CXXConversionDecl>(Decl)
- ? true
- : setResult(Decl, Decl->getLocation(),
- Decl->getNameAsString().length());
- }
-
- // Expression visitors:
-
- bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl();
- return setResult(Decl, Expr->getLocation(),
- Decl->getNameAsString().length());
- }
-
- bool VisitMemberExpr(const MemberExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl().getDecl();
- return setResult(Decl, Expr->getMemberLoc(),
- Decl->getNameAsString().length());
- }
-
- // Other visitors:
-
- bool VisitTypeLoc(const TypeLoc Loc) {
- const SourceLocation TypeBeginLoc = Loc.getBeginLoc();
- const SourceLocation TypeEndLoc = Lexer::getLocForEndOfToken(
- TypeBeginLoc, 0, Context.getSourceManager(), Context.getLangOpts());
- if (const auto *TemplateTypeParm =
- dyn_cast<TemplateTypeParmType>(Loc.getType()))
- return setResult(TemplateTypeParm->getDecl(), TypeBeginLoc, TypeEndLoc);
- if (const auto *TemplateSpecType =
- dyn_cast<TemplateSpecializationType>(Loc.getType())) {
- return setResult(TemplateSpecType->getTemplateName().getAsTemplateDecl(),
- TypeBeginLoc, TypeEndLoc);
- }
- return setResult(Loc.getType()->getAsCXXRecordDecl(), TypeBeginLoc,
- TypeEndLoc);
- }
-
- bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
- for (const auto *Initializer : ConstructorDecl->inits()) {
- // Ignore implicit initializers.
- if (!Initializer->isWritten())
- continue;
- if (const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
- const SourceLocation InitBeginLoc = Initializer->getSourceLocation(),
- InitEndLoc = Lexer::getLocForEndOfToken(
- InitBeginLoc, 0, Context.getSourceManager(),
- Context.getLangOpts());
- if (!setResult(FieldDecl, InitBeginLoc, InitEndLoc))
- return false;
- }
- }
- return true;
- }
-
- // Other:
-
- const NamedDecl *getNamedDecl() { return Result; }
-
- // \brief Determines if a namespace qualifier contains the point.
- // \returns false on success and sets Result.
- void handleNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
- while (NameLoc) {
- const NamespaceDecl *Decl =
- NameLoc.getNestedNameSpecifier()->getAsNamespace();
- setResult(Decl, NameLoc.getLocalBeginLoc(), NameLoc.getLocalEndLoc());
- NameLoc = NameLoc.getPrefix();
- }
- }
-
-private:
- // \brief Sets Result to Decl if the Point is within Start and End.
- // \returns false on success.
- bool setResult(const NamedDecl *Decl, SourceLocation Start,
- SourceLocation End) {
- if (!Decl)
+ explicit NamedDeclOccurrenceFindingVisitor(const SourceLocation Point,
+ const ASTContext &Context)
+ : RecursiveSymbolVisitor(Context.getSourceManager(),
+ Context.getLangOpts()),
+ Point(Point), Context(Context) {}
+
+ bool visitSymbolOccurrence(const NamedDecl *ND,
+ ArrayRef<SourceRange> NameRanges) {
+ if (!ND)
return true;
- if (Name.empty()) {
- // Offset is used to find the declaration.
+ for (const auto &Range : NameRanges) {
+ SourceLocation Start = Range.getBegin();
+ SourceLocation End = Range.getEnd();
if (!Start.isValid() || !Start.isFileID() || !End.isValid() ||
!End.isFileID() || !isPointWithin(Start, End))
return true;
- } else {
- // Fully qualified name is used to find the declaration.
- if (Name != Decl->getQualifiedNameAsString() &&
- Name != "::" + Decl->getQualifiedNameAsString())
- return true;
}
- Result = Decl;
+ Result = ND;
return false;
}
- // \brief Sets Result to Decl if Point is within Loc and Loc + Offset.
- // \returns false on success.
- bool setResult(const NamedDecl *Decl, SourceLocation Loc, unsigned Offset) {
- // FIXME: Add test for Offset == 0. Add test for Offset - 1 (vs -2 etc).
- return Offset == 0 ||
- setResult(Decl, Loc, Loc.getLocWithOffset(Offset - 1));
- }
+ const NamedDecl *getNamedDecl() const { return Result; }
+private:
// \brief Determines if the Point is within Start and End.
bool isPointWithin(const SourceLocation Start, const SourceLocation End) {
// FIXME: Add tests for Point == End.
@@ -160,17 +67,17 @@ private:
Context.getSourceManager().isBeforeInTranslationUnit(Point, End));
}
- const NamedDecl *Result;
+ const NamedDecl *Result = nullptr;
const SourceLocation Point; // The location to find the NamedDecl.
- const std::string Name;
const ASTContext &Context;
};
-} // namespace
+
+} // end anonymous namespace
const NamedDecl *getNamedDeclAt(const ASTContext &Context,
const SourceLocation Point) {
const SourceManager &SM = Context.getSourceManager();
- NamedDeclFindingASTVisitor Visitor(Point, Context);
+ NamedDeclOccurrenceFindingVisitor Visitor(Point, Context);
// Try to be clever about pruning down the number of top-level declarations we
// see. If both start and end is either before or after the point we're
@@ -184,18 +91,44 @@ const NamedDecl *getNamedDeclAt(const ASTContext &Context,
Visitor.TraverseDecl(CurrDecl);
}
- NestedNameSpecifierLocFinder Finder(const_cast<ASTContext &>(Context));
- for (const auto &Location : Finder.getNestedNameSpecifierLocations())
- Visitor.handleNestedNameSpecifierLoc(Location);
-
return Visitor.getNamedDecl();
}
+namespace {
+
+/// Recursively visits each NamedDecl node to find the declaration with a
+/// specific name.
+class NamedDeclFindingVisitor
+ : public RecursiveASTVisitor<NamedDeclFindingVisitor> {
+public:
+ explicit NamedDeclFindingVisitor(StringRef Name) : Name(Name) {}
+
+ // We don't have to traverse the uses to find some declaration with a
+ // specific name, so just visit the named declarations.
+ bool VisitNamedDecl(const NamedDecl *ND) {
+ if (!ND)
+ return true;
+ // Fully qualified name is used to find the declaration.
+ if (Name != ND->getQualifiedNameAsString() &&
+ Name != "::" + ND->getQualifiedNameAsString())
+ return true;
+ Result = ND;
+ return false;
+ }
+
+ const NamedDecl *getNamedDecl() const { return Result; }
+
+private:
+ const NamedDecl *Result = nullptr;
+ StringRef Name;
+};
+
+} // end anonymous namespace
+
const NamedDecl *getNamedDeclFor(const ASTContext &Context,
const std::string &Name) {
- NamedDeclFindingASTVisitor Visitor(Name, Context);
+ NamedDeclFindingVisitor Visitor(Name);
Visitor.TraverseDecl(Context.getTranslationUnitDecl());
-
return Visitor.getNamedDecl();
}
diff --git a/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp b/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
index 934507fe6eae..dc21a94610cb 100644
--- a/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
+++ b/lib/Tooling/Refactoring/Rename/USRLocFinder.cpp
@@ -22,6 +22,7 @@
#include "clang/Basic/SourceManager.h"
#include "clang/Lex/Lexer.h"
#include "clang/Tooling/Core/Lookup.h"
+#include "clang/Tooling/Refactoring/RecursiveSymbolVisitor.h"
#include "clang/Tooling/Refactoring/Rename/USRFinder.h"
#include "llvm/ADT/StringRef.h"
#include "llvm/Support/Casting.h"
@@ -40,70 +41,27 @@ namespace {
// \brief This visitor recursively searches for all instances of a USR in a
// translation unit and stores them for later usage.
class USRLocFindingASTVisitor
- : public clang::RecursiveASTVisitor<USRLocFindingASTVisitor> {
+ : public RecursiveSymbolVisitor<USRLocFindingASTVisitor> {
public:
explicit USRLocFindingASTVisitor(const std::vector<std::string> &USRs,
StringRef PrevName,
const ASTContext &Context)
- : USRSet(USRs.begin(), USRs.end()), PrevName(PrevName), Context(Context) {
+ : RecursiveSymbolVisitor(Context.getSourceManager(),
+ Context.getLangOpts()),
+ USRSet(USRs.begin(), USRs.end()), PrevName(PrevName), Context(Context) {
}
- // Declaration visitors:
-
- bool VisitCXXConstructorDecl(clang::CXXConstructorDecl *ConstructorDecl) {
- for (const auto *Initializer : ConstructorDecl->inits()) {
- // Ignore implicit initializers.
- if (!Initializer->isWritten())
- continue;
- if (const clang::FieldDecl *FieldDecl = Initializer->getMember()) {
- if (USRSet.find(getUSRForDecl(FieldDecl)) != USRSet.end())
- LocationsFound.push_back(Initializer->getSourceLocation());
- }
- }
- return true;
- }
-
- bool VisitNamedDecl(const NamedDecl *Decl) {
- if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end())
- checkAndAddLocation(Decl->getLocation());
- return true;
- }
-
- // Expression visitors:
-
- bool VisitDeclRefExpr(const DeclRefExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl();
-
- if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end()) {
- const SourceManager &Manager = Decl->getASTContext().getSourceManager();
- SourceLocation Location = Manager.getSpellingLoc(Expr->getLocation());
- checkAndAddLocation(Location);
- }
-
- return true;
- }
-
- bool VisitMemberExpr(const MemberExpr *Expr) {
- const NamedDecl *Decl = Expr->getFoundDecl().getDecl();
- if (USRSet.find(getUSRForDecl(Decl)) != USRSet.end()) {
- const SourceManager &Manager = Decl->getASTContext().getSourceManager();
- SourceLocation Location = Manager.getSpellingLoc(Expr->getMemberLoc());
- checkAndAddLocation(Location);
- }
- return true;
- }
-
- // Other visitors:
-
- bool VisitTypeLoc(const TypeLoc Loc) {
- if (USRSet.find(getUSRForDecl(Loc.getType()->getAsCXXRecordDecl())) !=
- USRSet.end())
- checkAndAddLocation(Loc.getBeginLoc());
- if (const auto *TemplateTypeParm =
- dyn_cast<TemplateTypeParmType>(Loc.getType())) {
- if (USRSet.find(getUSRForDecl(TemplateTypeParm->getDecl())) !=
- USRSet.end())
- checkAndAddLocation(Loc.getBeginLoc());
+ bool visitSymbolOccurrence(const NamedDecl *ND,
+ ArrayRef<SourceRange> NameRanges) {
+ if (USRSet.find(getUSRForDecl(ND)) != USRSet.end()) {
+ assert(NameRanges.size() == 1 &&
+ "Multiple name pieces are not supported yet!");
+ SourceLocation Loc = NameRanges[0].getBegin();
+ const SourceManager &SM = Context.getSourceManager();
+ // TODO: Deal with macro occurrences correctly.
+ if (Loc.isMacroID())
+ Loc = SM.getSpellingLoc(Loc);
+ checkAndAddLocation(Loc);
}
return true;
}
@@ -116,17 +74,6 @@ public:
return LocationsFound;
}
- // Namespace traversal:
- void handleNestedNameSpecifierLoc(NestedNameSpecifierLoc NameLoc) {
- while (NameLoc) {
- const NamespaceDecl *Decl =
- NameLoc.getNestedNameSpecifier()->getAsNamespace();
- if (Decl && USRSet.find(getUSRForDecl(Decl)) != USRSet.end())
- checkAndAddLocation(NameLoc.getLocalBeginLoc());
- NameLoc = NameLoc.getPrefix();
- }
- }
-
private:
void checkAndAddLocation(SourceLocation Loc) {
const SourceLocation BeginLoc = Loc;
@@ -449,11 +396,6 @@ getLocationsOfUSRs(const std::vector<std::string> &USRs, StringRef PrevName,
Decl *Decl) {
USRLocFindingASTVisitor Visitor(USRs, PrevName, Decl->getASTContext());
Visitor.TraverseDecl(Decl);
- NestedNameSpecifierLocFinder Finder(Decl->getASTContext());
-
- for (const auto &Location : Finder.getNestedNameSpecifierLocations())
- Visitor.handleNestedNameSpecifierLoc(Location);
-
return Visitor.getLocationsFound();
}
diff --git a/lib/Tooling/Tooling.cpp b/lib/Tooling/Tooling.cpp
index c84fbf473753..662f02dca2a6 100644
--- a/lib/Tooling/Tooling.cpp
+++ b/lib/Tooling/Tooling.cpp
@@ -336,6 +336,7 @@ ClangTool::ClangTool(const CompilationDatabase &Compilations,
OverlayFileSystem->pushOverlay(InMemoryFileSystem);
appendArgumentsAdjuster(getClangStripOutputAdjuster());
appendArgumentsAdjuster(getClangSyntaxOnlyAdjuster());
+ appendArgumentsAdjuster(getClangStripDependencyFileAdjuster());
}
ClangTool::~ClangTool() {}
diff --git a/test/Analysis/localization-aggressive.m b/test/Analysis/localization-aggressive.m
index 346cf3ef22e2..ea5e0b152945 100644
--- a/test/Analysis/localization-aggressive.m
+++ b/test/Analysis/localization-aggressive.m
@@ -61,8 +61,16 @@ int random();
NSString *CFNumberFormatterCreateStringWithNumber(float x);
+ (NSString *)forceLocalized:(NSString *)str
__attribute__((annotate("returns_localized_nsstring")));
++ (NSString *)takesLocalizedString:
+ (NSString *)__attribute__((annotate("takes_localized_nsstring")))str;
@end
+NSString *
+takesLocalizedString(NSString *str
+ __attribute__((annotate("takes_localized_nsstring")))) {
+ return str;
+}
+
// Test cases begin here
@implementation LocalizationTestSuite
@@ -75,6 +83,8 @@ NSString *ForceLocalized(NSString *str) { return str; }
return str;
}
++ (NSString *) takesLocalizedString:(NSString *)str { return str; }
+
// An ObjC method that returns a localized string
+ (NSString *)unLocalizedStringMethod {
return @"UnlocalizedString";
@@ -269,4 +279,13 @@ NSString *ForceLocalized(NSString *str) { return str; }
NSString *string2 = POSSIBLE_FALSE_POSITIVE(@"Hello", @"Hello"); // no-warning
}
+- (void)testTakesLocalizedString {
+ NSString *localized = NSLocalizedString(@"Hello", @"World");
+ NSString *alsoLocalized = [LocalizationTestSuite takesLocalizedString:localized]; // no-warning
+ NSString *stillLocalized = [LocalizationTestSuite takesLocalizedString:alsoLocalized]; // no-warning
+ takesLocalizedString(stillLocalized); // no-warning
+
+ [LocalizationTestSuite takesLocalizedString:@"not localized"]; // expected-warning {{User-facing text should use localized string macro}}
+ takesLocalizedString(@"not localized"); // expected-warning {{User-facing text should use localized string macro}}
+}
@end
diff --git a/test/Analysis/retain-release-inline.m b/test/Analysis/retain-release-inline.m
index 0cde2c1cf5af..388c55f6be23 100644
--- a/test/Analysis/retain-release-inline.m
+++ b/test/Analysis/retain-release-inline.m
@@ -12,7 +12,7 @@
//
// It includes the basic definitions for the test cases below.
//===----------------------------------------------------------------------===//
-
+#define NULL 0
typedef unsigned int __darwin_natural_t;
typedef unsigned long uintptr_t;
typedef unsigned int uint32_t;
@@ -267,6 +267,10 @@ typedef NSUInteger NSStringEncoding;
extern CFStringRef CFStringCreateWithCStringNoCopy(CFAllocatorRef alloc, const char *cStr, CFStringEncoding encoding, CFAllocatorRef contentsDeallocator);
+typedef struct {
+ int ref;
+} isl_basic_map;
+
//===----------------------------------------------------------------------===//
// Test cases.
//===----------------------------------------------------------------------===//
@@ -285,6 +289,7 @@ void test() {
foo(s);
bar(s);
}
+
void test_neg() {
NSString *s = [[NSString alloc] init]; // no-warning
foo(s);
@@ -294,6 +299,55 @@ void test_neg() {
bar(s);
}
+__attribute__((cf_returns_retained)) isl_basic_map *isl_basic_map_cow(__attribute__((cf_consumed)) isl_basic_map *bmap);
+void free(void *);
+
+// As 'isl_basic_map_free' is annotated with 'rc_ownership_trusted_implementation', RetainCountChecker trusts its
+// implementation and doesn't analyze its body. If the annotation 'rc_ownership_trusted_implementation' is removed,
+// a leak warning is raised by RetainCountChecker as the analyzer is unable to detect a decrement in the reference
+// count of 'bmap' along the path in 'isl_basic_map_free' assuming the predicate of the second 'if' branch to be
+// true or assuming both the predicates in the function to be false.
+__attribute__((annotate("rc_ownership_trusted_implementation"))) isl_basic_map *isl_basic_map_free(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+ if (!bmap)
+ return NULL;
+
+ if (--bmap->ref > 0)
+ return NULL;
+
+ free(bmap);
+ return NULL;
+}
+
+// As 'isl_basic_map_copy' is annotated with 'rc_ownership_trusted_implementation', RetainCountChecker trusts its
+// implementation and doesn't analyze its body. If that annotation is removed, a 'use-after-release' warning might
+// be raised by RetainCountChecker as the pointer which is passed as an argument to this function and the pointer
+// which is returned from the function point to the same memory location.
+__attribute__((annotate("rc_ownership_trusted_implementation"))) __attribute__((cf_returns_retained)) isl_basic_map *isl_basic_map_copy(isl_basic_map *bmap) {
+ if (!bmap)
+ return NULL;
+
+ bmap->ref++;
+ return bmap;
+}
+
+void test_use_after_release_with_trusted_implementation_annotate_attribute(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+ // After this call, 'bmap' has a +1 reference count.
+ bmap = isl_basic_map_cow(bmap);
+ // After the call to 'isl_basic_map_copy', 'bmap' has a +1 reference count.
+ isl_basic_map *temp = isl_basic_map_cow(isl_basic_map_copy(bmap));
+ // After this call, 'bmap' has a +0 reference count.
+ isl_basic_map *temp2 = isl_basic_map_cow(bmap); // no-warning
+ isl_basic_map_free(temp2);
+ isl_basic_map_free(temp);
+}
+
+void test_leak_with_trusted_implementation_annotate_attribute(__attribute__((cf_consumed)) isl_basic_map *bmap) {
+ // After this call, 'bmap' has a +1 reference count.
+ bmap = isl_basic_map_cow(bmap); // no-warning
+ // After this call, 'bmap' has a +0 reference count.
+ isl_basic_map_free(bmap);
+}
+
//===----------------------------------------------------------------------===//
// Test returning retained and not-retained values.
//===----------------------------------------------------------------------===//
diff --git a/test/Analysis/retain-release.m b/test/Analysis/retain-release.m
index 39a3baa8960c..29af194a3d67 100644
--- a/test/Analysis/retain-release.m
+++ b/test/Analysis/retain-release.m
@@ -1447,7 +1447,7 @@ typedef NSString* MyStringTy;
+ (void) consume2:(id) CF_CONSUMED x;
@end
-static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' attribute only applies to functions and methods}}
+static int ownership_attribute_doesnt_go_here NS_RETURNS_RETAINED; // expected-warning{{'ns_returns_retained' only applies to function types; type here is 'int'}}
void test_attr_1(TestOwnershipAttr *X) {
NSString *str = [X returnsAnOwnedString]; // expected-warning{{leak}}
diff --git a/test/CodeGen/aarch64-type-sizes.c b/test/CodeGen/aarch64-type-sizes.c
index ce8b51fc4085..195e8968ecb1 100644
--- a/test/CodeGen/aarch64-type-sizes.c
+++ b/test/CodeGen/aarch64-type-sizes.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -emit-llvm -w -o - %s | FileCheck --check-prefix=CHECK %s
+// RUN: %clang_cc1 -triple aarch64_be-none-linux-gnu -emit-llvm -w -o - %s | FileCheck %s
// char by definition has size 1
// CHECK: target datalayout = "E-m:e-i8:8:32-i16:16:32-i64:64-i128:128-n32:64-S128"
diff --git a/test/CodeGen/aarch64-varargs-ms.c b/test/CodeGen/aarch64-varargs-ms.c
new file mode 100644
index 000000000000..f3ff9603c9c2
--- /dev/null
+++ b/test/CodeGen/aarch64-varargs-ms.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple arm64-windows-msvc -emit-llvm -o - %s | FileCheck %s
+
+#include <stdarg.h>
+
+int simple_int(va_list ap) {
+// CHECK-LABEL: define i32 @simple_int
+ return va_arg(ap, int);
+// CHECK: [[ADDR:%[a-z_0-9]+]] = bitcast i8* %argp.cur to i32*
+// CHECK: [[RESULT:%[a-z_0-9]+]] = load i32, i32* [[ADDR]]
+// CHECK: ret i32 [[RESULT]]
+}
diff --git a/test/CodeGen/builtins-hexagon.c b/test/CodeGen/builtins-hexagon.c
index e2eda2afafd5..f9f5d495d02a 100644
--- a/test/CodeGen/builtins-hexagon.c
+++ b/test/CodeGen/builtins-hexagon.c
@@ -2962,4 +2962,16 @@ void foo() {
// CHECK: @llvm.hexagon.V6.vzh.128B
__builtin_HEXAGON_V6_vzh(v16);
// CHECK: @llvm.hexagon.V6.vzh
+ __builtin_HEXAGON_Y2_dccleana(0);
+ // CHECK: @llvm.hexagon.Y2.dccleana
+ __builtin_HEXAGON_Y2_dccleaninva(0);
+ // CHECK: @llvm.hexagon.Y2.dccleaninva
+ __builtin_HEXAGON_Y2_dcinva(0);
+ // CHECK: @llvm.hexagon.Y2.dcinva
+ __builtin_HEXAGON_Y2_dczeroa(0);
+ // CHECK: @llvm.hexagon.Y2.dczeroa
+ __builtin_HEXAGON_Y4_l2fetch(0, 0);
+ // CHECK: @llvm.hexagon.Y4.l2fetch
+ __builtin_HEXAGON_Y5_l2fetch(0, 0);
+ // CHECK: @llvm.hexagon.Y5.l2fetch
}
diff --git a/test/CodeGen/builtins-systemz-vector2-error.c b/test/CodeGen/builtins-systemz-vector2-error.c
new file mode 100644
index 000000000000..ceebaf8cc72f
--- /dev/null
+++ b/test/CodeGen/builtins-systemz-vector2-error.c
@@ -0,0 +1,61 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z14 -triple s390x-unknown-unknown \
+// RUN: -Wall -Wno-unused -Werror -fsyntax-only -verify %s
+
+typedef __attribute__((vector_size(16))) signed char vec_schar;
+typedef __attribute__((vector_size(16))) signed short vec_sshort;
+typedef __attribute__((vector_size(16))) signed int vec_sint;
+typedef __attribute__((vector_size(16))) signed long long vec_slong;
+typedef __attribute__((vector_size(16))) unsigned char vec_uchar;
+typedef __attribute__((vector_size(16))) unsigned short vec_ushort;
+typedef __attribute__((vector_size(16))) unsigned int vec_uint;
+typedef __attribute__((vector_size(16))) unsigned long long vec_ulong;
+typedef __attribute__((vector_size(16))) double vec_double;
+typedef __attribute__((vector_size(16))) float vec_float;
+
+volatile vec_schar vsc;
+volatile vec_sshort vss;
+volatile vec_sint vsi;
+volatile vec_slong vsl;
+volatile vec_uchar vuc;
+volatile vec_ushort vus;
+volatile vec_uint vui;
+volatile vec_ulong vul;
+volatile vec_double vd;
+volatile vec_float vf;
+
+volatile unsigned int len;
+int cc;
+
+void test_integer(void) {
+ __builtin_s390_vmslg(vul, vul, vuc, -1); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vmslg(vul, vul, vuc, 16); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vmslg(vul, vul, vuc, len); // expected-error {{must be a constant integer}}
+}
+
+void test_float(void) {
+ __builtin_s390_vfmaxdb(vd, vd, -1); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfmaxdb(vd, vd, 16); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfmaxdb(vd, vd, len); // expected-error {{must be a constant integer}}
+ __builtin_s390_vfmindb(vd, vd, -1); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfmindb(vd, vd, 16); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfmindb(vd, vd, len); // expected-error {{must be a constant integer}}
+
+ __builtin_s390_vftcisb(vf, -1, &cc); // expected-error {{argument should be a value from 0 to 4095}}
+ __builtin_s390_vftcisb(vf, 4096, &cc); // expected-error {{argument should be a value from 0 to 4095}}
+ __builtin_s390_vftcisb(vf, len, &cc); // expected-error {{must be a constant integer}}
+
+ __builtin_s390_vfisb(vf, -1, 0); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfisb(vf, 16, 0); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfisb(vf, len, 0); // expected-error {{must be a constant integer}}
+ __builtin_s390_vfisb(vf, 0, -1); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfisb(vf, 0, 16); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfisb(vf, 0, len); // expected-error {{must be a constant integer}}
+
+ __builtin_s390_vfmaxsb(vf, vf, -1); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfmaxsb(vf, vf, 16); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfmaxsb(vf, vf, len); // expected-error {{must be a constant integer}}
+ __builtin_s390_vfminsb(vf, vf, -1); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfminsb(vf, vf, 16); // expected-error {{argument should be a value from 0 to 15}}
+ __builtin_s390_vfminsb(vf, vf, len); // expected-error {{must be a constant integer}}
+}
diff --git a/test/CodeGen/builtins-systemz-vector2.c b/test/CodeGen/builtins-systemz-vector2.c
new file mode 100644
index 000000000000..8f0b8aee8c2d
--- /dev/null
+++ b/test/CodeGen/builtins-systemz-vector2.c
@@ -0,0 +1,136 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z14 -triple s390x-ibm-linux -fno-lax-vector-conversions \
+// RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
+
+typedef __attribute__((vector_size(16))) signed char vec_schar;
+typedef __attribute__((vector_size(16))) signed short vec_sshort;
+typedef __attribute__((vector_size(16))) signed int vec_sint;
+typedef __attribute__((vector_size(16))) signed long long vec_slong;
+typedef __attribute__((vector_size(16))) unsigned char vec_uchar;
+typedef __attribute__((vector_size(16))) unsigned short vec_ushort;
+typedef __attribute__((vector_size(16))) unsigned int vec_uint;
+typedef __attribute__((vector_size(16))) unsigned long long vec_ulong;
+typedef __attribute__((vector_size(16))) double vec_double;
+typedef __attribute__((vector_size(16))) float vec_float;
+
+volatile vec_schar vsc;
+volatile vec_sshort vss;
+volatile vec_sint vsi;
+volatile vec_slong vsl;
+volatile vec_uchar vuc;
+volatile vec_ushort vus;
+volatile vec_uint vui;
+volatile vec_ulong vul;
+volatile vec_double vd;
+volatile vec_float vf;
+
+volatile unsigned int len;
+const void * volatile cptr;
+void * volatile ptr;
+int cc;
+
+void test_core(void) {
+ vul = __builtin_s390_vbperm(vuc, vuc);
+ // CHECK: call <2 x i64> @llvm.s390.vbperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+ vsc = __builtin_s390_vlrl(len, cptr);
+ // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, i8* %{{.*}})
+
+ __builtin_s390_vstrl(vsc, len, ptr);
+ // CHECK: call void @llvm.s390.vstrl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}})
+}
+
+void test_integer(void) {
+ vuc = __builtin_s390_vmslg(vul, vul, vuc, 0);
+ // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+ vuc = __builtin_s390_vmslg(vul, vul, vuc, 15);
+ // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+}
+
+void test_float(void) {
+ vd = __builtin_s390_vfmaxdb(vd, vd, 4);
+ // CHECK: call <2 x double> @llvm.maxnum.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+ vd = __builtin_s390_vfmaxdb(vd, vd, 0);
+ // CHECK: call <2 x double> @llvm.s390.vfmaxdb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 0)
+ vd = __builtin_s390_vfmaxdb(vd, vd, 15);
+ // CHECK: call <2 x double> @llvm.s390.vfmaxdb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 15)
+
+ vd = __builtin_s390_vfmindb(vd, vd, 4);
+ // CHECK: call <2 x double> @llvm.minnum.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+ vd = __builtin_s390_vfmindb(vd, vd, 0);
+ // CHECK: call <2 x double> @llvm.s390.vfmindb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 0)
+ vd = __builtin_s390_vfmindb(vd, vd, 15);
+ // CHECK: call <2 x double> @llvm.s390.vfmindb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 15)
+
+ vd = __builtin_s390_vfnmadb(vd, vd, vd);
+ // CHECK: [[RES:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}})
+ // CHECK: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[RES]]
+ vd = __builtin_s390_vfnmsdb(vd, vd, vd);
+ // CHECK: [[NEG:%[^ ]+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.*}}
+ // CHECK: [[RES:%[^ ]+]] = call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]])
+ // CHECK: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[RES]]
+
+ vsi = __builtin_s390_vfcesbs(vf, vf, &cc);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ vsi = __builtin_s390_vfchsbs(vf, vf, &cc);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ vsi = __builtin_s390_vfchesbs(vf, vf, &cc);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+
+ vsi = __builtin_s390_vftcisb(vf, 0, &cc);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 0)
+ vsi = __builtin_s390_vftcisb(vf, 4095, &cc);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 4095)
+
+ vf = __builtin_s390_vfmaxsb(vf, vf, 4);
+ // CHECK: call <4 x float> @llvm.maxnum.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ vf = __builtin_s390_vfmaxsb(vf, vf, 0);
+ // CHECK: call <4 x float> @llvm.s390.vfmaxsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 0)
+ vf = __builtin_s390_vfmaxsb(vf, vf, 15);
+ // CHECK: call <4 x float> @llvm.s390.vfmaxsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 15)
+
+ vf = __builtin_s390_vfminsb(vf, vf, 4);
+ // CHECK: call <4 x float> @llvm.minnum.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ vf = __builtin_s390_vfminsb(vf, vf, 0);
+ // CHECK: call <4 x float> @llvm.s390.vfminsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 0)
+ vf = __builtin_s390_vfminsb(vf, vf, 15);
+ // CHECK: call <4 x float> @llvm.s390.vfminsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 15)
+
+ vf = __builtin_s390_vfsqsb(vf);
+ // CHECK: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %{{.*}})
+
+ vf = __builtin_s390_vfmasb(vf, vf, vf);
+ // CHECK: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
+ vf = __builtin_s390_vfmssb(vf, vf, vf);
+ // CHECK: [[NEG:%[^ ]+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[NEG]])
+ vf = __builtin_s390_vfnmasb(vf, vf, vf);
+ // CHECK: [[RES:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
+ // CHECK: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, [[RES]]
+ vf = __builtin_s390_vfnmssb(vf, vf, vf);
+ // CHECK: [[NEG:%[^ ]+]] = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, %{{.*}}
+ // CHECK: [[RES:%[^ ]+]] = call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> [[NEG]])
+ // CHECK: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, [[RES]]
+
+ vf = __builtin_s390_vflpsb(vf);
+ // CHECK: call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+ vf = __builtin_s390_vflnsb(vf);
+ // CHECK: [[ABS:%[^ ]+]] = call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+ // CHECK: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, [[ABS]]
+
+ vf = __builtin_s390_vfisb(vf, 0, 0);
+ // CHECK: call <4 x float> @llvm.rint.v4f32(<4 x float> %{{.*}})
+ vf = __builtin_s390_vfisb(vf, 4, 0);
+ // CHECK: call <4 x float> @llvm.nearbyint.v4f32(<4 x float> %{{.*}})
+ vf = __builtin_s390_vfisb(vf, 4, 1);
+ // CHECK: call <4 x float> @llvm.round.v4f32(<4 x float> %{{.*}})
+ vf = __builtin_s390_vfisb(vf, 4, 5);
+ // CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float> %{{.*}})
+ vf = __builtin_s390_vfisb(vf, 4, 6);
+ // CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float> %{{.*}})
+ vf = __builtin_s390_vfisb(vf, 4, 7);
+ // CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float> %{{.*}})
+ vf = __builtin_s390_vfisb(vf, 4, 4);
+ // CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 4)
+}
+
diff --git a/test/CodeGen/builtins-systemz-zvector-error.c b/test/CodeGen/builtins-systemz-zvector-error.c
index b28e8d9bc1fc..8d5aaabfbac3 100644
--- a/test/CodeGen/builtins-systemz-zvector-error.c
+++ b/test/CodeGen/builtins-systemz-zvector-error.c
@@ -446,43 +446,43 @@ void test_integer(void) {
// expected-note@vecintrin.h:* 1 {{must be a constant integer}}
vsc = vec_sld(vsc, vsc, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
// expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
vsc = vec_sld(vsc, vsc, -1); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
// expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
vsc = vec_sld(vsc, vsc, 16); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
// expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
vuc = vec_sld(vuc, vuc, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
- // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+ // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
vuc = vec_sld(vuc, vuc, -1); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
- // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+ // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
vuc = vec_sld(vuc, vuc, 16); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
- // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+ // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
vss = vec_sld(vss, vss, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
// expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
vus = vec_sld(vus, vus, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
- // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+ // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
vsi = vec_sld(vsi, vsi, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
// expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
vui = vec_sld(vui, vui, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
- // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+ // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
vsl = vec_sld(vsl, vsl, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
// expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
vul = vec_sld(vul, vul, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
- // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+ // expected-note@vecintrin.h:* 11 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 2 {{must be a constant integer from 0 to 15}}
vd = vec_sld(vd, vd, idx); // expected-error {{no matching function}}
- // expected-note@vecintrin.h:* 8 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 12 {{candidate function not viable}}
// expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
vsc = vec_sldw(vsc, vsc, idx); // expected-error {{no matching function}}
diff --git a/test/CodeGen/builtins-systemz-zvector.c b/test/CodeGen/builtins-systemz-zvector.c
index 6d554af44e93..a8adbd717ea1 100644
--- a/test/CodeGen/builtins-systemz-zvector.c
+++ b/test/CodeGen/builtins-systemz-zvector.c
@@ -294,6 +294,16 @@ void test_core(void) {
vec_scatter_element(vd, vul, ptrd, 0);
vec_scatter_element(vd, vul, ptrd, 1);
+ vsc = vec_xl(idx, cptrsc);
+ vuc = vec_xl(idx, cptruc);
+ vss = vec_xl(idx, cptrss);
+ vus = vec_xl(idx, cptrus);
+ vsi = vec_xl(idx, cptrsi);
+ vui = vec_xl(idx, cptrui);
+ vsl = vec_xl(idx, cptrsl);
+ vul = vec_xl(idx, cptrul);
+ vd = vec_xl(idx, cptrd);
+
vsc = vec_xld2(idx, cptrsc);
vuc = vec_xld2(idx, cptruc);
vss = vec_xld2(idx, cptrss);
@@ -311,6 +321,16 @@ void test_core(void) {
vsi = vec_xlw4(idx, cptrsi);
vui = vec_xlw4(idx, cptrui);
+ vec_xst(vsc, idx, ptrsc);
+ vec_xst(vuc, idx, ptruc);
+ vec_xst(vss, idx, ptrss);
+ vec_xst(vus, idx, ptrus);
+ vec_xst(vsi, idx, ptrsi);
+ vec_xst(vui, idx, ptrui);
+ vec_xst(vsl, idx, ptrsl);
+ vec_xst(vul, idx, ptrul);
+ vec_xst(vd, idx, ptrd);
+
vec_xstd2(vsc, idx, ptrsc);
vec_xstd2(vuc, idx, ptruc);
vec_xstd2(vss, idx, ptrss);
@@ -1841,6 +1861,10 @@ void test_integer(void) {
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vuc = vec_sld(vuc, vuc, 15);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+ vbc = vec_sld(vbc, vbc, 0);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+ vbc = vec_sld(vbc, vbc, 15);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
vss = vec_sld(vss, vss, 0);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vss = vec_sld(vss, vss, 15);
@@ -1849,6 +1873,10 @@ void test_integer(void) {
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vus = vec_sld(vus, vus, 15);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+ vbs = vec_sld(vbs, vbs, 0);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+ vbs = vec_sld(vbs, vbs, 15);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
vsi = vec_sld(vsi, vsi, 0);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vsi = vec_sld(vsi, vsi, 15);
@@ -1857,6 +1885,10 @@ void test_integer(void) {
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vui = vec_sld(vui, vui, 15);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+ vbi = vec_sld(vbi, vbi, 0);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+ vbi = vec_sld(vbi, vbi, 15);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
vsl = vec_sld(vsl, vsl, 0);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vsl = vec_sld(vsl, vsl, 15);
@@ -1865,6 +1897,10 @@ void test_integer(void) {
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vul = vec_sld(vul, vul, 15);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+ vbl = vec_sld(vbl, vbl, 0);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+ vbl = vec_sld(vbl, vbl, 15);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
vd = vec_sld(vd, vd, 0);
// CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
vd = vec_sld(vd, vd, 15);
@@ -2943,6 +2979,16 @@ void test_float(void) {
// CHECK: [[VAL:%[^ ]+]] = fmul <2 x double> %{{.*}}, <double 0x41E0000000000000, double 0x41E0000000000000>
// CHECK: fptoui <2 x double> [[VAL]] to <2 x i64>
+ vd = vec_double(vsl);
+ // CHECK: sitofp <2 x i64> %{{.*}} to <2 x double>
+ vd = vec_double(vul);
+ // CHECK: uitofp <2 x i64> %{{.*}} to <2 x double>
+
+ vsl = vec_signed(vd);
+ // CHECK: fptosi <2 x double> %{{.*}} to <2 x i64>
+ vul = vec_unsigned(vd);
+ // CHECK: fptoui <2 x double> %{{.*}} to <2 x i64>
+
vd = vec_roundp(vd);
// CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}})
vd = vec_ceil(vd);
@@ -2957,6 +3003,8 @@ void test_float(void) {
// CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}})
vd = vec_roundc(vd);
// CHECK: call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %{{.*}})
+ vd = vec_rint(vd);
+ // CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double> %{{.*}})
vd = vec_round(vd);
// CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
@@ -2964,4 +3012,44 @@ void test_float(void) {
// CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 0)
vbl = vec_fp_test_data_class(vd, 4095, &cc);
// CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 4095)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_ZERO_P, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 2048)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_ZERO_N, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 1024)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_ZERO, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 3072)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NORMAL_P, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 512)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NORMAL_N, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 256)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NORMAL, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 768)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SUBNORMAL_P, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 128)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SUBNORMAL_N, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 64)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SUBNORMAL, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 192)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_INFINITY_P, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 32)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_INFINITY_N, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 16)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_INFINITY, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 48)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_QNAN_P, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 8)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_QNAN_N, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 4)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_QNAN, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 12)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SNAN_P, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 2)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SNAN_N, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 1)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_SNAN, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 3)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NAN, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
+ vbl = vec_fp_test_data_class(vd, __VEC_CLASS_FP_NOT_NORMAL, &cc);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 3327)
}
diff --git a/test/CodeGen/builtins-systemz-zvector2-error.c b/test/CodeGen/builtins-systemz-zvector2-error.c
new file mode 100644
index 000000000000..823d6374dc0e
--- /dev/null
+++ b/test/CodeGen/builtins-systemz-zvector2-error.c
@@ -0,0 +1,153 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z14 -triple s390x-linux-gnu \
+// RUN: -fzvector -fno-lax-vector-conversions \
+// RUN: -Wall -Wno-unused -Werror -fsyntax-only -verify %s
+
+#include <vecintrin.h>
+
+volatile vector signed char vsc;
+volatile vector signed short vss;
+volatile vector signed int vsi;
+volatile vector signed long long vsl;
+volatile vector unsigned char vuc;
+volatile vector unsigned short vus;
+volatile vector unsigned int vui;
+volatile vector unsigned long long vul;
+volatile vector bool char vbc;
+volatile vector bool short vbs;
+volatile vector bool int vbi;
+volatile vector bool long long vbl;
+volatile vector float vf;
+volatile vector double vd;
+
+volatile signed char sc;
+volatile signed short ss;
+volatile signed int si;
+volatile signed long long sl;
+volatile unsigned char uc;
+volatile unsigned short us;
+volatile unsigned int ui;
+volatile unsigned long long ul;
+volatile float f;
+volatile double d;
+
+const void * volatile cptr;
+const signed char * volatile cptrsc;
+const signed short * volatile cptrss;
+const signed int * volatile cptrsi;
+const signed long long * volatile cptrsl;
+const unsigned char * volatile cptruc;
+const unsigned short * volatile cptrus;
+const unsigned int * volatile cptrui;
+const unsigned long long * volatile cptrul;
+const float * volatile cptrf;
+const double * volatile cptrd;
+
+void * volatile ptr;
+signed char * volatile ptrsc;
+signed short * volatile ptrss;
+signed int * volatile ptrsi;
+signed long long * volatile ptrsl;
+unsigned char * volatile ptruc;
+unsigned short * volatile ptrus;
+unsigned int * volatile ptrui;
+unsigned long long * volatile ptrul;
+float * volatile ptrf;
+double * volatile ptrd;
+
+volatile unsigned int len;
+volatile int idx;
+int cc;
+
+void test_core(void) {
+ vf = vec_gather_element(vf, vui, cptrf, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vf = vec_gather_element(vf, vui, cptrf, -1); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vf = vec_gather_element(vf, vui, cptrf, 4); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vd = vec_gather_element(vd, vul, cptrd, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+ vd = vec_gather_element(vd, vul, cptrd, -1); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+ vd = vec_gather_element(vd, vul, cptrd, 2); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+
+ vec_scatter_element(vf, vui, ptrf, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vec_scatter_element(vf, vui, ptrf, -1); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vec_scatter_element(vf, vui, ptrf, 4); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vec_scatter_element(vd, vul, ptrd, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+ vec_scatter_element(vd, vul, ptrd, -1); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+ vec_scatter_element(vd, vul, ptrd, 2); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 7 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+
+ vf = vec_splat(vf, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vf = vec_splat(vf, -1); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vf = vec_splat(vf, 4); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 3}}
+ vd = vec_splat(vd, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+ vd = vec_splat(vd, -1); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+ vd = vec_splat(vd, 2); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 1}}
+}
+
+void test_integer(void) {
+ vf = vec_sld(vf, vf, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+ vd = vec_sld(vd, vd, idx); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 13 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 15}}
+
+ vuc = vec_msum_u128(vul, vul, vuc, idx); // expected-error {{must be a constant integer}}
+ vuc = vec_msum_u128(vul, vul, vuc, -1); // expected-error {{should be a value from 0 to 15}}
+ vuc = vec_msum_u128(vul, vul, vuc, 16); // expected-error {{should be a value from 0 to 15}}
+}
+
+void test_float(void) {
+ vbi = vec_fp_test_data_class(vf, idx, &cc); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
+ vbi = vec_fp_test_data_class(vf, -1, &cc); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
+ vbi = vec_fp_test_data_class(vf, 4096, &cc); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
+ vbl = vec_fp_test_data_class(vd, idx, &cc); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
+ vbl = vec_fp_test_data_class(vd, -1, &cc); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
+ vbl = vec_fp_test_data_class(vd, 4096, &cc); // expected-error {{no matching function}}
+ // expected-note@vecintrin.h:* 1 {{candidate function not viable}}
+ // expected-note@vecintrin.h:* 1 {{must be a constant integer from 0 to 4095}}
+}
diff --git a/test/CodeGen/builtins-systemz-zvector2.c b/test/CodeGen/builtins-systemz-zvector2.c
new file mode 100644
index 000000000000..d9607b3a8788
--- /dev/null
+++ b/test/CodeGen/builtins-systemz-zvector2.c
@@ -0,0 +1,545 @@
+// REQUIRES: systemz-registered-target
+// RUN: %clang_cc1 -target-cpu z14 -triple s390x-linux-gnu \
+// RUN: -O -fzvector -fno-lax-vector-conversions \
+// RUN: -Wall -Wno-unused -Werror -emit-llvm %s -o - | FileCheck %s
+
+#include <vecintrin.h>
+
+volatile vector signed char vsc;
+volatile vector signed short vss;
+volatile vector signed int vsi;
+volatile vector signed long long vsl;
+volatile vector unsigned char vuc;
+volatile vector unsigned short vus;
+volatile vector unsigned int vui;
+volatile vector unsigned long long vul;
+volatile vector bool char vbc;
+volatile vector bool short vbs;
+volatile vector bool int vbi;
+volatile vector bool long long vbl;
+volatile vector float vf;
+volatile vector double vd;
+
+volatile signed char sc;
+volatile signed short ss;
+volatile signed int si;
+volatile signed long long sl;
+volatile unsigned char uc;
+volatile unsigned short us;
+volatile unsigned int ui;
+volatile unsigned long long ul;
+volatile float f;
+volatile double d;
+
+const void * volatile cptr;
+const signed char * volatile cptrsc;
+const signed short * volatile cptrss;
+const signed int * volatile cptrsi;
+const signed long long * volatile cptrsl;
+const unsigned char * volatile cptruc;
+const unsigned short * volatile cptrus;
+const unsigned int * volatile cptrui;
+const unsigned long long * volatile cptrul;
+const float * volatile cptrf;
+const double * volatile cptrd;
+
+void * volatile ptr;
+signed char * volatile ptrsc;
+signed short * volatile ptrss;
+signed int * volatile ptrsi;
+signed long long * volatile ptrsl;
+unsigned char * volatile ptruc;
+unsigned short * volatile ptrus;
+unsigned int * volatile ptrui;
+unsigned long long * volatile ptrul;
+float * volatile ptrf;
+double * volatile ptrd;
+
+volatile unsigned int len;
+volatile int idx;
+int cc;
+
+void test_core(void) {
+ f = vec_extract(vf, idx);
+ // CHECK: extractelement <4 x float> %{{.*}}, i32 %{{.*}}
+ d = vec_extract(vd, idx);
+ // CHECK: extractelement <2 x double> %{{.*}}, i32 %{{.*}}
+
+ vf = vec_insert(d, vf, idx);
+ // CHECK: insertelement <4 x float> %{{.*}}, float %{{.*}}, i32 %{{.*}}
+ vd = vec_insert(f, vd, idx);
+ // CHECK: insertelement <2 x double> %{{.*}}, double %{{.*}}, i32 %{{.*}}
+
+ vf = vec_promote(f, idx);
+ // CHECK: insertelement <4 x float> undef, float %{{.*}}, i32 %{{.*}}
+ vd = vec_promote(d, idx);
+ // CHECK: insertelement <2 x double> undef, double %{{.*}}, i32 %{{.*}}
+
+ vf = vec_insert_and_zero(cptrf);
+ // CHECK: insertelement <4 x float> <float undef, float 0.000000e+00, float 0.000000e+00, float 0.000000e+00>, float %{{.*}}, i32 0
+ vd = vec_insert_and_zero(cptrd);
+ // CHECK: insertelement <2 x double> <double undef, double 0.000000e+00>, double %{{.*}}, i32 0
+
+ vf = vec_perm(vf, vf, vuc);
+ // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vd = vec_perm(vd, vd, vuc);
+ // CHECK: call <16 x i8> @llvm.s390.vperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+ vul = vec_bperm_u128(vuc, vuc);
+ // CHECK: call <2 x i64> @llvm.s390.vbperm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+ vf = vec_sel(vf, vf, vui);
+ vf = vec_sel(vf, vf, vbi);
+ vd = vec_sel(vd, vd, vul);
+ vd = vec_sel(vd, vd, vbl);
+
+ vf = vec_gather_element(vf, vui, cptrf, 0);
+ vf = vec_gather_element(vf, vui, cptrf, 1);
+ vf = vec_gather_element(vf, vui, cptrf, 2);
+ vf = vec_gather_element(vf, vui, cptrf, 3);
+ vd = vec_gather_element(vd, vul, cptrd, 0);
+ vd = vec_gather_element(vd, vul, cptrd, 1);
+
+ vec_scatter_element(vf, vui, ptrf, 0);
+ vec_scatter_element(vf, vui, ptrf, 1);
+ vec_scatter_element(vf, vui, ptrf, 2);
+ vec_scatter_element(vf, vui, ptrf, 3);
+ vec_scatter_element(vd, vul, ptrd, 0);
+ vec_scatter_element(vd, vul, ptrd, 1);
+
+ vf = vec_xl(idx, cptrf);
+ vd = vec_xl(idx, cptrd);
+
+ vec_xst(vf, idx, ptrf);
+ vec_xst(vd, idx, ptrd);
+
+ vd = vec_load_bndry(cptrd, 64);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0)
+ vf = vec_load_bndry(cptrf, 64);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 0)
+ vf = vec_load_bndry(cptrf, 128);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 1)
+ vf = vec_load_bndry(cptrf, 256);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 2)
+ vf = vec_load_bndry(cptrf, 512);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 3)
+ vf = vec_load_bndry(cptrf, 1024);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 4)
+ vf = vec_load_bndry(cptrf, 2048);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 5)
+ vf = vec_load_bndry(cptrf, 4096);
+ // CHECK: call <16 x i8> @llvm.s390.vlbb(i8* %{{.*}}, i32 6)
+
+ vf = vec_load_len(cptrf, idx);
+ // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}})
+ vd = vec_load_len(cptrd, idx);
+ // CHECK: call <16 x i8> @llvm.s390.vll(i32 %{{.*}}, i8* %{{.*}})
+
+ vec_store_len(vf, ptrf, idx);
+ // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}})
+ vec_store_len(vd, ptrd, idx);
+ // CHECK: call void @llvm.s390.vstl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}})
+
+ vuc = vec_load_len_r(cptruc, idx);
+ // CHECK: call <16 x i8> @llvm.s390.vlrl(i32 %{{.*}}, i8* %{{.*}})
+
+ vec_store_len_r(vuc, ptruc, idx);
+ // CHECK: call void @llvm.s390.vstrl(<16 x i8> %{{.*}}, i32 %{{.*}}, i8* %{{.*}})
+
+ vf = vec_splat(vf, 0);
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> zeroinitializer
+ vf = vec_splat(vf, 1);
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> <i32 1, i32 1, i32 1, i32 1>
+ vd = vec_splat(vd, 0);
+ // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer
+ vd = vec_splat(vd, 1);
+ // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> <i32 1, i32 1>
+
+ vf = vec_splats(f);
+ // CHECK: shufflevector <4 x float> %{{.*}}, <4 x float> undef, <4 x i32> zeroinitializer
+ vd = vec_splats(d);
+ // CHECK: shufflevector <2 x double> %{{.*}}, <2 x double> undef, <2 x i32> zeroinitializer
+
+ vf = vec_mergeh(vf, vf);
+ // shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x i32> <i32 0, i32 4, i32 1, i32 5>
+ vd = vec_mergeh(vd, vd);
+ // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x i32> <i32 0, i32 2>
+
+ vf = vec_mergel(vf, vf);
+ // shufflevector <4 x float> %{{.*}}, <4 x float> %{{.*}}, <i32 2, i32 6, i32 3, i32 7>
+ vd = vec_mergel(vd, vd);
+ // shufflevector <2 x double> %{{.*}}, <2 x double> %{{.*}}, <i32 1, i32 3>
+}
+
+void test_compare(void) {
+ vbi = vec_cmpeq(vf, vf);
+ // CHECK: fcmp oeq <4 x float> %{{.*}}, %{{.*}}
+ vbl = vec_cmpeq(vd, vd);
+ // CHECK: fcmp oeq <2 x double> %{{.*}}, %{{.*}}
+
+ vbi = vec_cmpge(vf, vf);
+ // CHECK: fcmp oge <4 x float> %{{.*}}, %{{.*}}
+ vbl = vec_cmpge(vd, vd);
+ // CHECK: fcmp oge <2 x double> %{{.*}}, %{{.*}}
+
+ vbi = vec_cmpgt(vf, vf);
+ // CHECK: fcmp ogt <4 x float> %{{.*}}, %{{.*}}
+ vbl = vec_cmpgt(vd, vd);
+ // CHECK: fcmp ogt <2 x double> %{{.*}}, %{{.*}}
+
+ vbi = vec_cmple(vf, vf);
+ // CHECK: fcmp ole <4 x float> %{{.*}}, %{{.*}}
+ vbl = vec_cmple(vd, vd);
+ // CHECK: fcmp ole <2 x double> %{{.*}}, %{{.*}}
+
+ vbi = vec_cmplt(vf, vf);
+ // CHECK: fcmp olt <4 x float> %{{.*}}, %{{.*}}
+ vbl = vec_cmplt(vd, vd);
+ // CHECK: fcmp olt <2 x double> %{{.*}}, %{{.*}}
+
+ idx = vec_all_eq(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_eq(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_ne(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_ne(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_ge(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_ge(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_gt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_gt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<