aboutsummaryrefslogtreecommitdiff
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(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_le(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_le(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_lt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_lt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_nge(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+ idx = vec_all_nge(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_ngt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_ngt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_nle(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_nle(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_nlt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_all_nlt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_all_nan(vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15)
+ idx = vec_all_nan(vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
+
+ idx = vec_all_numeric(vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15)
+ idx = vec_all_numeric(vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
+
+ idx = vec_any_eq(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_eq(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_ne(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfcesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_ne(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfcedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_ge(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_ge(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_gt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_gt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_le(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_le(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_lt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_lt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_nge(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_nge(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_ngt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_ngt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_nle(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchesbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_nle(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchedbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_nlt(vf, vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vfchsbs(<4 x float> %{{.*}}, <4 x float> %{{.*}})
+ idx = vec_any_nlt(vd, vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vfchdbs(<2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ idx = vec_any_nan(vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15)
+ idx = vec_any_nan(vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
+
+ idx = vec_any_numeric(vf);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 15)
+ idx = vec_any_numeric(vd);
+ // CHECK: call { <2 x i64>, i32 } @llvm.s390.vftcidb(<2 x double> %{{.*}}, i32 15)
+}
+
+void test_integer(void) {
+ vf = vec_andc(vf, vf);
+ vd = vec_andc(vd, vd);
+
+ vf = vec_nor(vf, vf);
+ vd = vec_nor(vd, vd);
+
+ vsc = vec_nand(vsc, vsc);
+ vuc = vec_nand(vuc, vuc);
+ vbc = vec_nand(vbc, vbc);
+ vss = vec_nand(vss, vss);
+ vus = vec_nand(vus, vus);
+ vbs = vec_nand(vbs, vbs);
+ vsi = vec_nand(vsi, vsi);
+ vui = vec_nand(vui, vui);
+ vbi = vec_nand(vbi, vbi);
+ vsl = vec_nand(vsl, vsl);
+ vul = vec_nand(vul, vul);
+ vbl = vec_nand(vbl, vbl);
+ vf = vec_nand(vf, vf);
+ vd = vec_nand(vd, vd);
+
+ vsc = vec_orc(vsc, vsc);
+ vuc = vec_orc(vuc, vuc);
+ vbc = vec_orc(vbc, vbc);
+ vss = vec_orc(vss, vss);
+ vus = vec_orc(vus, vus);
+ vbs = vec_orc(vbs, vbs);
+ vsi = vec_orc(vsi, vsi);
+ vui = vec_orc(vui, vui);
+ vbi = vec_orc(vbi, vbi);
+ vsl = vec_orc(vsl, vsl);
+ vul = vec_orc(vul, vul);
+ vbl = vec_orc(vbl, vbl);
+ vf = vec_orc(vf, vf);
+ vd = vec_orc(vd, vd);
+
+ vsc = vec_eqv(vsc, vsc);
+ vuc = vec_eqv(vuc, vuc);
+ vbc = vec_eqv(vbc, vbc);
+ vss = vec_eqv(vss, vss);
+ vus = vec_eqv(vus, vus);
+ vbs = vec_eqv(vbs, vbs);
+ vsi = vec_eqv(vsi, vsi);
+ vui = vec_eqv(vui, vui);
+ vbi = vec_eqv(vbi, vbi);
+ vsl = vec_eqv(vsl, vsl);
+ vul = vec_eqv(vul, vul);
+ vbl = vec_eqv(vbl, vbl);
+ vf = vec_eqv(vf, vf);
+ vd = vec_eqv(vd, vd);
+
+ vf = vec_slb(vf, vsi);
+ // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vf = vec_slb(vf, vui);
+ // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vd = vec_slb(vd, vsl);
+ // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vd = vec_slb(vd, vul);
+ // CHECK: call <16 x i8> @llvm.s390.vslb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+ vf = vec_sld(vf, vf, 0);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+ vf = vec_sld(vf, vf, 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);
+ // CHECK: call <16 x i8> @llvm.s390.vsldb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}}, i32 15)
+
+ vf = vec_srab(vf, vsi);
+ // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vf = vec_srab(vf, vui);
+ // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vd = vec_srab(vd, vsl);
+ // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vd = vec_srab(vd, vul);
+ // CHECK: call <16 x i8> @llvm.s390.vsrab(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+ vf = vec_srb(vf, vsi);
+ // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vf = vec_srb(vf, vui);
+ // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vd = vec_srb(vd, vsl);
+ // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ vd = vec_srb(vd, vul);
+ // CHECK: call <16 x i8> @llvm.s390.vsrlb(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+ idx = vec_test_mask(vf, vui);
+ // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+ idx = vec_test_mask(vd, vul);
+ // CHECK: call i32 @llvm.s390.vtm(<16 x i8> %{{.*}}, <16 x i8> %{{.*}})
+
+ vuc = vec_msum_u128(vul, vul, vuc, 0);
+ // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 0)
+ vuc = vec_msum_u128(vul, vul, vuc, 4);
+ // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 4)
+ vuc = vec_msum_u128(vul, vul, vuc, 8);
+ // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 8)
+ vuc = vec_msum_u128(vul, vul, vuc, 12);
+ // CHECK: call <16 x i8> @llvm.s390.vmslg(<2 x i64> %{{.*}}, <2 x i64> %{{.*}}, <16 x i8> %{{.*}}, i32 12)
+}
+
+void test_float(void) {
+ vf = vec_abs(vf);
+ // CHECK: call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+ vd = vec_abs(vd);
+ // CHECK: call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
+
+ vf = vec_nabs(vf);
+ // CHECK: [[ABS:%[^ ]+]] = tail call <4 x float> @llvm.fabs.v4f32(<4 x float> %{{.*}})
+ // CHECK-NEXT: fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, [[ABS]]
+ vd = vec_nabs(vd);
+ // CHECK: [[ABS:%[^ ]+]] = tail call <2 x double> @llvm.fabs.v2f64(<2 x double> %{{.*}})
+ // CHECK-NEXT: fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, [[ABS]]
+
+ vf = vec_max(vf, vf);
+ // CHECK: call <4 x float> @llvm.s390.vfmaxsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 0)
+ vd = vec_max(vd, vd);
+ // CHECK: call <2 x double> @llvm.s390.vfmaxdb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 0)
+
+ vf = vec_min(vf, vf);
+ // CHECK: call <4 x float> @llvm.s390.vfminsb(<4 x float> %{{.*}}, <4 x float> %{{.*}}, i32 0)
+ vd = vec_min(vd, vd);
+ // CHECK: call <2 x double> @llvm.s390.vfmindb(<2 x double> %{{.*}}, <2 x double> %{{.*}}, i32 0)
+
+ vf = vec_madd(vf, vf, vf);
+ // CHECK: call <4 x float> @llvm.fma.v4f32(<4 x float> %{{.*}}, <4 x float> %{{.*}}, <4 x float> %{{.*}})
+ vd = vec_madd(vd, vd, vd);
+ // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> %{{.*}})
+
+ vf = vec_msub(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]])
+ vd = vec_msub(vd, vd, vd);
+ // CHECK: [[NEG:%[^ ]+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.*}}
+ // CHECK: call <2 x double> @llvm.fma.v2f64(<2 x double> %{{.*}}, <2 x double> %{{.*}}, <2 x double> [[NEG]])
+
+ vf = vec_nmadd(vf, vf, vf);
+ // CHECK: [[RES:%[^ ]+]] = tail 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]]
+ vd = vec_nmadd(vd, vd, vd);
+ // CHECK: [[RES:%[^ ]+]] = tail 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]]
+
+ vf = vec_nmsub(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:%[^ ]+]] = tail 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]]
+ vd = vec_nmsub(vd, vd, vd);
+ // CHECK: [[NEG:%[^ ]+]] = fsub <2 x double> <double -0.000000e+00, double -0.000000e+00>, %{{.*}}
+ // CHECK: [[RES:%[^ ]+]] = tail 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]]
+
+ vf = vec_sqrt(vf);
+ // CHECK: call <4 x float> @llvm.sqrt.v4f32(<4 x float> %{{.*}})
+ vd = vec_sqrt(vd);
+ // CHECK: call <2 x double> @llvm.sqrt.v2f64(<2 x double> %{{.*}})
+
+ vd = vec_doublee(vf);
+ // CHECK: fpext <2 x float> %{{.*}} to <2 x double>
+ vf = vec_floate(vd);
+ // CHECK: fptrunc <2 x double> %{{.*}} to <2 x float>
+
+ 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>
+
+ vf = vec_roundp(vf);
+ // CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float> %{{.*}})
+ vf = vec_ceil(vf);
+ // CHECK: call <4 x float> @llvm.ceil.v4f32(<4 x float> %{{.*}})
+ vd = vec_roundp(vd);
+ // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}})
+ vd = vec_ceil(vd);
+ // CHECK: call <2 x double> @llvm.ceil.v2f64(<2 x double> %{{.*}})
+
+ vf = vec_roundm(vf);
+ // CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float> %{{.*}})
+ vf = vec_floor(vf);
+ // CHECK: call <4 x float> @llvm.floor.v4f32(<4 x float> %{{.*}})
+ vd = vec_roundm(vd);
+ // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}})
+ vd = vec_floor(vd);
+ // CHECK: call <2 x double> @llvm.floor.v2f64(<2 x double> %{{.*}})
+
+ vf = vec_roundz(vf);
+ // CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float> %{{.*}})
+ vf = vec_trunc(vf);
+ // CHECK: call <4 x float> @llvm.trunc.v4f32(<4 x float> %{{.*}})
+ vd = vec_roundz(vd);
+ // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}})
+ vd = vec_trunc(vd);
+ // CHECK: call <2 x double> @llvm.trunc.v2f64(<2 x double> %{{.*}})
+
+ vf = vec_roundc(vf);
+ // CHECK: call <4 x float> @llvm.nearbyint.v4f32(<4 x float> %{{.*}})
+ vd = vec_roundc(vd);
+ // CHECK: call <2 x double> @llvm.nearbyint.v2f64(<2 x double> %{{.*}})
+
+ vf = vec_rint(vf);
+ // CHECK: call <4 x float> @llvm.rint.v4f32(<4 x float> %{{.*}})
+ vd = vec_rint(vd);
+ // CHECK: call <2 x double> @llvm.rint.v2f64(<2 x double> %{{.*}})
+
+ vf = vec_round(vf);
+ // CHECK: call <4 x float> @llvm.s390.vfisb(<4 x float> %{{.*}}, i32 4, i32 4)
+ vd = vec_round(vd);
+ // CHECK: call <2 x double> @llvm.s390.vfidb(<2 x double> %{{.*}}, i32 4, i32 4)
+
+ vbi = vec_fp_test_data_class(vf, 0, &cc);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 0)
+ vbi = vec_fp_test_data_class(vf, 4095, &cc);
+ // CHECK: call { <4 x i32>, i32 } @llvm.s390.vftcisb(<4 x float> %{{.*}}, i32 4095)
+ vbl = vec_fp_test_data_class(vd, 0, &cc);
+ // 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)
+}
diff --git a/test/CodeGen/coff-aarch64-type-sizes.c b/test/CodeGen/coff-aarch64-type-sizes.c
new file mode 100644
index 000000000000..1d8a64520469
--- /dev/null
+++ b/test/CodeGen/coff-aarch64-type-sizes.c
@@ -0,0 +1,88 @@
+// RUN: %clang_cc1 -triple aarch64-windows -emit-llvm -w -o - %s | FileCheck %s
+
+// CHECK: target datalayout = "e-m:w-p:64:64-i32:32-i64:64-i128:128-n32:64-S128"
+// CHECK: target triple = "aarch64--windows-msvc"
+
+int check_short() {
+ return sizeof(short);
+// CHECK: ret i32 2
+}
+
+int check_int() {
+ return sizeof(int);
+// CHECK: ret i32 4
+}
+
+int check_long() {
+ return sizeof(long);
+// CHECK: ret i32 4
+}
+
+int check_longlong() {
+ return sizeof(long long);
+// CHECK: ret i32 8
+}
+
+int check_int128() {
+ return sizeof(__int128);
+// CHECK: ret i32 16
+}
+
+int check_fp16() {
+ return sizeof(__fp16);
+// CHECK: ret i32 2
+}
+
+int check_float() {
+ return sizeof(float);
+// CHECK: ret i32 4
+}
+
+int check_double() {
+ return sizeof(double);
+// CHECK: ret i32 8
+}
+
+int check_longdouble() {
+ return sizeof(long double);
+// CHECK: ret i32 8
+}
+
+int check_floatComplex() {
+ return sizeof(float _Complex);
+// CHECK: ret i32 8
+}
+
+int check_doubleComplex() {
+ return sizeof(double _Complex);
+// CHECK: ret i32 16
+}
+
+int check_longdoubleComplex() {
+ return sizeof(long double _Complex);
+// CHECK: ret i32 16
+}
+
+int check_bool() {
+ return sizeof(_Bool);
+// CHECK: ret i32 1
+}
+
+int check_wchar() {
+ return sizeof(__WCHAR_TYPE__);
+// CHECK: ret i32 2
+}
+
+int check_wchar_unsigned() {
+ return (__WCHAR_TYPE__)-1 > (__WCHAR_TYPE__)0;
+// CHECK: ret i32 1
+}
+
+enum Small {
+ Item
+};
+
+int foo() {
+ return sizeof(enum Small);
+// CHECK: ret i32 4
+}
diff --git a/test/CodeGen/debug-info-imported-entity.cpp b/test/CodeGen/debug-info-imported-entity.cpp
index c7935eda48c5..398536e581ae 100644
--- a/test/CodeGen/debug-info-imported-entity.cpp
+++ b/test/CodeGen/debug-info-imported-entity.cpp
@@ -5,5 +5,6 @@ using std::A; using ::A;
// CHECK: [[CompileUnit:![0-9]+]] = distinct !DICompileUnit({{.+}} imports: [[Imports:![0-9]+]]
// CHECK: [[Imports]] = !{[[ImportedEntity:![0-9]+]]}
-// CHECK: [[ImportedEntity]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CompileUnit]], entity: [[STDA:![0-9]+]], line: 4)
+// CHECK: [[ImportedEntity]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[CompileUnit]], entity: [[STDA:![0-9]+]], file: [[FILE:![0-9]+]], line: 4)
// CHECK: [[STDA]] = !DICompositeType(tag: DW_TAG_class_type, name: "A",
+// CHECK: [[FILE]] = !DIFile(filename: {{.*}}debug-info-imported-entity.cpp
diff --git a/test/CodeGen/ms_abi.c b/test/CodeGen/ms_abi.c
index 97f66b29c517..407087e40916 100644
--- a/test/CodeGen/ms_abi.c
+++ b/test/CodeGen/ms_abi.c
@@ -15,20 +15,20 @@ void f3(void) {
// FREEBSD-LABEL: define void @f3()
// WIN64-LABEL: define void @f3()
f1();
- // FREEBSD: call x86_64_win64cc void @f1()
+ // FREEBSD: call win64cc void @f1()
// WIN64: call void @f1()
f2();
// FREEBSD: call void @f2()
// WIN64: call x86_64_sysvcc void @f2()
}
-// FREEBSD: declare x86_64_win64cc void @f1()
+// FREEBSD: declare win64cc void @f1()
// FREEBSD: declare void @f2()
// WIN64: declare void @f1()
// WIN64: declare x86_64_sysvcc void @f2()
// Win64 ABI varargs
void __attribute__((ms_abi)) f4(int a, ...) {
- // FREEBSD-LABEL: define x86_64_win64cc void @f4
+ // FREEBSD-LABEL: define win64cc void @f4
// WIN64-LABEL: define void @f4
__builtin_ms_va_list ap;
__builtin_ms_va_start(ap, a);
diff --git a/test/CodeGen/ms_abi_aarch64.c b/test/CodeGen/ms_abi_aarch64.c
new file mode 100644
index 000000000000..4aa93f00859a
--- /dev/null
+++ b/test/CodeGen/ms_abi_aarch64.c
@@ -0,0 +1,68 @@
+// RUN: %clang_cc1 -triple aarch64-linux-gnu -emit-llvm < %s | FileCheck -check-prefix=LINUX %s
+// RUN: %clang_cc1 -triple aarch64-pc-win32 -emit-llvm < %s | FileCheck -check-prefix=WIN64 %s
+
+void __attribute__((ms_abi)) f1(void);
+void f2(void);
+void f3(void) {
+ // LINUX-LABEL: define void @f3()
+ // WIN64-LABEL: define void @f3()
+ f1();
+ // LINUX: call win64cc void @f1()
+ // WIN64: call void @f1()
+ f2();
+ // LINUX: call void @f2()
+ // WIN64: call void @f2()
+}
+// LINUX: declare win64cc void @f1()
+// LINUX: declare void @f2()
+// WIN64: declare void @f1()
+// WIN64: declare void @f2()
+
+// Win64 ABI varargs
+void __attribute__((ms_abi)) f4(int a, ...) {
+ // LINUX-LABEL: define win64cc void @f4
+ // WIN64-LABEL: define void @f4
+ __builtin_ms_va_list ap;
+ __builtin_ms_va_start(ap, a);
+ // LINUX: %[[AP:.*]] = alloca i8*
+ // LINUX: call void @llvm.va_start
+ // WIN64: %[[AP:.*]] = alloca i8*
+ // WIN64: call void @llvm.va_start
+ int b = __builtin_va_arg(ap, int);
+ // LINUX: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]]
+ // LINUX-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8
+ // LINUX-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]]
+ // LINUX-NEXT: bitcast i8* %[[AP_CUR]] to i32*
+ // WIN64: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]]
+ // WIN64-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8
+ // WIN64-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]]
+ // WIN64-NEXT: bitcast i8* %[[AP_CUR]] to i32*
+ __builtin_ms_va_list ap2;
+ __builtin_ms_va_copy(ap2, ap);
+ // LINUX: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
+ // LINUX-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
+ // WIN64: %[[AP_VAL:.*]] = load i8*, i8** %[[AP]]
+ // WIN64-NEXT: store i8* %[[AP_VAL]], i8** %[[AP2:.*]]
+ __builtin_ms_va_end(ap);
+ // LINUX: call void @llvm.va_end
+ // WIN64: call void @llvm.va_end
+}
+
+// Let's verify that normal va_lists work right on Win64, too.
+void f5(int a, ...) {
+ // WIN64-LABEL: define void @f5
+ __builtin_va_list ap;
+ __builtin_va_start(ap, a);
+ // WIN64: %[[AP:.*]] = alloca i8*
+ // WIN64: call void @llvm.va_start
+ int b = __builtin_va_arg(ap, int);
+ // WIN64: %[[AP_CUR:.*]] = load i8*, i8** %[[AP]]
+ // WIN64-NEXT: %[[AP_NEXT:.*]] = getelementptr inbounds i8, i8* %[[AP_CUR]], i64 8
+ // WIN64-NEXT: store i8* %[[AP_NEXT]], i8** %[[AP]]
+ // WIN64-NEXT: bitcast i8* %[[AP_CUR]] to i32*
+ __builtin_va_list ap2;
+ __builtin_va_copy(ap2, ap);
+ // WIN64: call void @llvm.va_copy
+ __builtin_va_end(ap);
+ // WIN64: call void @llvm.va_end
+}
diff --git a/test/CodeGen/systemz-abi-vector.c b/test/CodeGen/systemz-abi-vector.c
index 455e3bbcced2..191c2321bb1d 100644
--- a/test/CodeGen/systemz-abi-vector.c
+++ b/test/CodeGen/systemz-abi-vector.c
@@ -6,6 +6,10 @@
// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s
// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu arch11 \
// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s
+// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu z14 \
+// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s
+// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu arch12 \
+// RUN: -emit-llvm -o - %s | FileCheck --check-prefix=CHECK-VECTOR %s
// Vector types
diff --git a/test/CodeGen/systemz-abi.c b/test/CodeGen/systemz-abi.c
index 17fdb9e322c8..de5dce54b5f0 100644
--- a/test/CodeGen/systemz-abi.c
+++ b/test/CodeGen/systemz-abi.c
@@ -6,6 +6,10 @@
// RUN: -emit-llvm -o - %s | FileCheck %s
// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu arch11 \
// RUN: -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu z14 \
+// RUN: -emit-llvm -o - %s | FileCheck %s
+// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu arch12 \
+// RUN: -emit-llvm -o - %s | FileCheck %s
// Scalar types
diff --git a/test/CodeGen/target-data.c b/test/CodeGen/target-data.c
index 68ee8f02d2ee..851ce5831fa3 100644
--- a/test/CodeGen/target-data.c
+++ b/test/CodeGen/target-data.c
@@ -171,6 +171,10 @@
// RUN: FileCheck %s -check-prefix=SYSTEMZ-VECTOR
// RUN: %clang_cc1 -triple s390x-unknown -target-cpu arch11 -o - -emit-llvm %s | \
// RUN: FileCheck %s -check-prefix=SYSTEMZ-VECTOR
+// RUN: %clang_cc1 -triple s390x-unknown -target-cpu z14 -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=SYSTEMZ-VECTOR
+// RUN: %clang_cc1 -triple s390x-unknown -target-cpu arch12 -o - -emit-llvm %s | \
+// RUN: FileCheck %s -check-prefix=SYSTEMZ-VECTOR
// SYSTEMZ-VECTOR: target datalayout = "E-m:e-i1:8:16-i8:8:16-i64:64-f128:64-v128:64-a:8:16-n32:64"
// RUN: %clang_cc1 -triple msp430-unknown -o - -emit-llvm %s | \
diff --git a/test/CodeGen/ubsan-pointer-overflow.m b/test/CodeGen/ubsan-pointer-overflow.m
index da622355fdb4..977e2458384b 100644
--- a/test/CodeGen/ubsan-pointer-overflow.m
+++ b/test/CodeGen/ubsan-pointer-overflow.m
@@ -10,16 +10,20 @@ void unary_arith(char *p) {
++p;
// CHECK: ptrtoint i8* {{.*}} to i64, !nosanitize
- // CHECK-NEXT: add i64 {{.*}}, -1, !nosanitize
- // CHECK: select i1 false{{.*}}, !nosanitize
+ // CHECK-NEXT: [[COMPGEP:%.*]] = add i64 {{.*}}, -1, !nosanitize
+ // CHECK: [[NEGVALID:%.*]] = icmp ule i64 [[COMPGEP]], {{.*}}, !nosanitize
+ // CHECK-NOT: select
+ // CHECK: br i1 [[NEGVALID]]{{.*}}, !nosanitize
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}
--p;
+ // CHECK: icmp uge i64
// CHECK-NOT: select
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}
p++;
- // CHECK: select
+ // CHECK: icmp ule i64
+ // CHECK-NOT: select
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}
p--;
}
@@ -64,7 +68,8 @@ void binary_arith_unsigned(char *p, unsigned i) {
// CHECK: [[OFFSET:%.*]] = sub i64 0, {{.*}}
// CHECK-NEXT: getelementptr inbounds {{.*}} [[OFFSET]]
- // CHECK: select
+ // CHECK: icmp ule i64
+ // CHECK-NOT: select
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}
p - i;
}
@@ -121,8 +126,10 @@ void pointer_array(int **arr, int k) {
// CHECK-LABEL: define void @pointer_array_unsigned_indices
void pointer_array_unsigned_indices(int **arr, unsigned k) {
+ // CHECK: icmp uge
// CHECK-NOT: select
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}
+ // CHECK: icmp uge
// CHECK-NOT: select
// CHECK: call void @__ubsan_handle_pointer_overflow{{.*}}
arr[k][k];
diff --git a/test/CodeGen/zvector2.c b/test/CodeGen/zvector2.c
new file mode 100644
index 000000000000..909b3fd7650f
--- /dev/null
+++ b/test/CodeGen/zvector2.c
@@ -0,0 +1,194 @@
+// RUN: %clang_cc1 -triple s390x-linux-gnu -target-cpu z14 -fzvector \
+// RUN: -O -emit-llvm -o - -W -Wall -Werror %s | FileCheck %s
+
+volatile vector float ff, ff2;
+volatile vector bool int bi;
+
+void test_assign (void)
+{
+// CHECK-LABEL: test_assign
+// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: store volatile <4 x float> [[VAL]], <4 x float>* @ff
+ ff = ff2;
+}
+
+void test_pos (void)
+{
+// CHECK-LABEL: test_pos
+// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: store volatile <4 x float> [[VAL]], <4 x float>* @ff
+ ff = +ff2;
+}
+
+void test_neg (void)
+{
+// CHECK-LABEL: test_neg
+// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fsub <4 x float> <float -0.000000e+00, float -0.000000e+00, float -0.000000e+00, float -0.000000e+00>, [[VAL]]
+ ff = -ff2;
+}
+
+void test_preinc (void)
+{
+// CHECK-LABEL: test_preinc
+// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fadd <4 x float> [[VAL]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+ ++ff2;
+}
+
+void test_postinc (void)
+{
+// CHECK-LABEL: test_postinc
+// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fadd <4 x float> [[VAL]], <float 1.000000e+00, float 1.000000e+00, float 1.000000e+00, float 1.000000e+00>
+ ff2++;
+}
+
+void test_predec (void)
+{
+// CHECK-LABEL: test_predec
+// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fadd <4 x float> [[VAL]], <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>
+ --ff2;
+}
+
+void test_postdec (void)
+{
+// CHECK-LABEL: test_postdec
+// CHECK: [[VAL:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fadd <4 x float> [[VAL]], <float -1.000000e+00, float -1.000000e+00, float -1.000000e+00, float -1.000000e+00>
+ ff2--;
+}
+
+void test_add (void)
+{
+// CHECK-LABEL: test_add
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fadd <4 x float> [[VAL1]], [[VAL2]]
+ ff = ff + ff2;
+}
+
+void test_add_assign (void)
+{
+// CHECK-LABEL: test_add_assign
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: %{{.*}} = fadd <4 x float> [[VAL2]], [[VAL1]]
+ ff += ff2;
+}
+
+void test_sub (void)
+{
+// CHECK-LABEL: test_sub
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fsub <4 x float> [[VAL1]], [[VAL2]]
+ ff = ff - ff2;
+}
+
+void test_sub_assign (void)
+{
+// CHECK-LABEL: test_sub_assign
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: %{{.*}} = fsub <4 x float> [[VAL1]], [[VAL2]]
+ ff -= ff2;
+}
+
+void test_mul (void)
+{
+// CHECK-LABEL: test_mul
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fmul <4 x float> [[VAL1]], [[VAL2]]
+ ff = ff * ff2;
+}
+
+void test_mul_assign (void)
+{
+// CHECK-LABEL: test_mul_assign
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: %{{.*}} = fmul <4 x float> [[VAL2]], [[VAL1]]
+ ff *= ff2;
+}
+
+void test_div (void)
+{
+// CHECK-LABEL: test_div
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: %{{.*}} = fdiv <4 x float> [[VAL1]], [[VAL2]]
+ ff = ff / ff2;
+}
+
+void test_div_assign (void)
+{
+// CHECK-LABEL: test_div_assign
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: %{{.*}} = fdiv <4 x float> [[VAL1]], [[VAL2]]
+ ff /= ff2;
+}
+
+void test_cmpeq (void)
+{
+// CHECK-LABEL: test_cmpeq
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[CMP:%[^ ]+]] = fcmp oeq <4 x float> [[VAL1]], [[VAL2]]
+// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
+ bi = ff == ff2;
+}
+
+void test_cmpne (void)
+{
+// CHECK-LABEL: test_cmpne
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[CMP:%[^ ]+]] = fcmp une <4 x float> [[VAL1]], [[VAL2]]
+// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
+ bi = ff != ff2;
+}
+
+void test_cmpge (void)
+{
+// CHECK-LABEL: test_cmpge
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[CMP:%[^ ]+]] = fcmp oge <4 x float> [[VAL1]], [[VAL2]]
+// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
+ bi = ff >= ff2;
+}
+
+void test_cmpgt (void)
+{
+// CHECK-LABEL: test_cmpgt
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[CMP:%[^ ]+]] = fcmp ogt <4 x float> [[VAL1]], [[VAL2]]
+// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
+ bi = ff > ff2;
+}
+
+void test_cmple (void)
+{
+// CHECK-LABEL: test_cmple
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[CMP:%[^ ]+]] = fcmp ole <4 x float> [[VAL1]], [[VAL2]]
+// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
+ bi = ff <= ff2;
+}
+
+void test_cmplt (void)
+{
+// CHECK-LABEL: test_cmplt
+// CHECK: [[VAL1:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff
+// CHECK: [[VAL2:%[^ ]+]] = load volatile <4 x float>, <4 x float>* @ff2
+// CHECK: [[CMP:%[^ ]+]] = fcmp olt <4 x float> [[VAL1]], [[VAL2]]
+// CHECK: %{{.*}} = sext <4 x i1> [[CMP]] to <4 x i32>
+ bi = ff < ff2;
+}
+
diff --git a/test/CodeGenCXX/amdgcn-automatic-variable.cpp b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
index a82275206c6d..9830a7845e5b 100644
--- a/test/CodeGenCXX/amdgcn-automatic-variable.cpp
+++ b/test/CodeGenCXX/amdgcn-automatic-variable.cpp
@@ -13,31 +13,32 @@ void func1(int *x) {
// CHECK-LABEL: define void @_Z5func2v()
void func2(void) {
// CHECK: %lv1 = alloca i32, align 4, addrspace(5)
+ // CHECK: %[[r0:.*]] = addrspacecast i32 addrspace(5)* %lv1 to i32*
// CHECK: %lv2 = alloca i32, align 4, addrspace(5)
+ // CHECK: %[[r1:.*]] = addrspacecast i32 addrspace(5)* %lv2 to i32*
// CHECK: %la = alloca [100 x i32], align 4, addrspace(5)
+ // CHECK: %[[r2:.*]] = addrspacecast [100 x i32] addrspace(5)* %la to [100 x i32]*
// CHECK: %lp1 = alloca i32*, align 8, addrspace(5)
+ // CHECK: %[[r3:.*]] = addrspacecast i32* addrspace(5)* %lp1 to i32**
// CHECK: %lp2 = alloca i32*, align 8, addrspace(5)
+ // CHECK: %[[r4:.*]] = addrspacecast i32* addrspace(5)* %lp2 to i32**
// CHECK: %lvc = alloca i32, align 4, addrspace(5)
+ // CHECK: %[[r5:.*]] = addrspacecast i32 addrspace(5)* %lvc to i32*
- // CHECK: %[[r0:.*]] = addrspacecast i32 addrspace(5)* %lv1 to i32*
// CHECK: store i32 1, i32* %[[r0]]
int lv1;
lv1 = 1;
- // CHECK: %[[r1:.*]] = addrspacecast i32 addrspace(5)* %lv2 to i32*
// CHECK: store i32 2, i32* %[[r1]]
int lv2 = 2;
- // CHECK: %[[r2:.*]] = addrspacecast [100 x i32] addrspace(5)* %la to [100 x i32]*
// CHECK: %[[arrayidx:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i64 0, i64 0
// CHECK: store i32 3, i32* %[[arrayidx]], align 4
int la[100];
la[0] = 3;
- // CHECK: %[[r3:.*]] = addrspacecast i32* addrspace(5)* %lp1 to i32**
// CHECK: store i32* %[[r0]], i32** %[[r3]], align 8
int *lp1 = &lv1;
- // CHECK: %[[r4:.*]] = addrspacecast i32* addrspace(5)* %lp2 to i32**
// CHECK: %[[arraydecay:.*]] = getelementptr inbounds [100 x i32], [100 x i32]* %[[r2]], i32 0, i32 0
// CHECK: store i32* %[[arraydecay]], i32** %[[r4]], align 8
int *lp2 = la;
@@ -45,7 +46,6 @@ void func2(void) {
// CHECK: call void @_Z5func1Pi(i32* %[[r0]])
func1(&lv1);
- // CHECK: %[[r5:.*]] = addrspacecast i32 addrspace(5)* %lvc to i32*
// CHECK: store i32 4, i32* %[[r5]]
// CHECK: store i32 4, i32* %[[r0]]
const int lvc = 4;
@@ -81,4 +81,25 @@ void func4(int x) {
func1(&x);
}
+// CHECK-LABEL: define void @_Z5func5v
+void func5() {
+ return;
+ int x = 0;
+}
+
+// CHECK-LABEL: define void @_Z5func6v
+void func6() {
+ return;
+ int x;
+}
+
+// CHECK-LABEL: define void @_Z5func7v
+extern void use(int *);
+void func7() {
+ goto later;
+ int x;
+later:
+ use(&x);
+}
+
// CHECK-NOT: !opencl.ocl.version
diff --git a/test/CodeGenCXX/debug-info-anon-namespace.cpp b/test/CodeGenCXX/debug-info-anon-namespace.cpp
index 79298deaf8b1..3f4ef2a38360 100644
--- a/test/CodeGenCXX/debug-info-anon-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-anon-namespace.cpp
@@ -21,7 +21,7 @@ int *b2 = &a2;
// PS4: [[NS:![0-9]+]] = !DINamespace
// PS4: [[CU:![0-9]+]] = distinct !DICompileUnit
// PS4: [[NS2:![0-9]+]] = !DINamespace
-// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]])
-// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], line: {{[0-9]+}})
+// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[NS]], file: {{![0-9]+}})
+// PS4: !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[NS]], entity: [[NS2]], file: {{![0-9]+}}, line: {{[0-9]+}})
// NON-PS4-NOT: !DIImportedEntity
diff --git a/test/CodeGenCXX/debug-info-namespace.cpp b/test/CodeGenCXX/debug-info-namespace.cpp
index 95857e339085..296c99efc8eb 100644
--- a/test/CodeGenCXX/debug-info-namespace.cpp
+++ b/test/CodeGenCXX/debug-info-namespace.cpp
@@ -81,17 +81,17 @@ void C::c() {}
// CHECK: [[CU:![0-9]+]] = distinct !DICompileUnit(
// CHECK-SAME: imports: [[MODULES:![0-9]*]]
// CHECK: [[MODULES]] = !{[[M1:![0-9]+]], [[M2:![0-9]+]], [[M3:![0-9]+]], [[M4:![0-9]+]], [[M5:![0-9]+]], [[M6:![0-9]+]], [[M7:![0-9]+]], [[M8:![0-9]+]], [[M9:![0-9]+]], [[M10:![0-9]+]], [[M11:![0-9]+]], [[M12:![0-9]+]], [[M13:![0-9]+]], [[M14:![0-9]+]], [[M15:![0-9]+]], [[M16:![0-9]+]], [[M17:![0-9]+]]
-// CHECK: [[M1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CTXT]], entity: [[NS]], line: 15)
+// CHECK: [[M1]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CTXT]], entity: [[NS]], file: [[FOOCPP]], line: 15)
// CHECK: [[M2]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[CU]], entity: [[CTXT]],
-// CHECK: [[M3]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "E", scope: [[CU]], entity: [[CTXT]], line: 19)
-// CHECK: [[M4]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[LEX2:![0-9]+]], entity: [[NS]], line: 23)
+// CHECK: [[M3]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, name: "E", scope: [[CU]], entity: [[CTXT]], file: [[FOOCPP]], line: 19)
+// CHECK: [[M4]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[LEX2:![0-9]+]], entity: [[NS]], file: [[FOOCPP]], line: 23)
// CHECK: [[LEX2]] = distinct !DILexicalBlock(scope: [[LEX1:![0-9]+]], file: [[FOOCPP]],
// CHECK: [[LEX1]] = distinct !DILexicalBlock(scope: [[FUNC:![0-9]+]], file: [[FOOCPP]],
// CHECK: [[FUNC:![0-9]+]] = distinct !DISubprogram(name: "func",{{.*}} isDefinition: true
// CHECK: [[M5]] = !DIImportedEntity(tag: DW_TAG_imported_module, scope: [[FUNC]], entity: [[CTXT:![0-9]+]],
-// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:![0-9]+]], line: 27)
+// CHECK: [[M6]] = !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: [[FUNC]], entity: [[FOO:![0-9]+]], file: [[FOOCPP]], line: 27)
// CHECK: [[FOO]] = !DICompositeType(tag: DW_TAG_structure_type, name: "foo",
// CHECK-SAME: line: 5
// CHECK-SAME: DIFlagFwdDecl
diff --git a/test/CodeGenCXX/implicit-exception-spec.cpp b/test/CodeGenCXX/implicit-exception-spec.cpp
index cf363bd685ad..e1a969ab277f 100644
--- a/test/CodeGenCXX/implicit-exception-spec.cpp
+++ b/test/CodeGenCXX/implicit-exception-spec.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck -check-prefix=CHECK %s
+// RUN: %clang_cc1 %s -triple=x86_64-linux-gnu -emit-llvm -std=c++11 -o - -fcxx-exceptions -fexceptions | FileCheck %s
struct A {
A();
diff --git a/test/CodeGenObjC/arc-property.m b/test/CodeGenObjC/arc-property.m
index b8dc18e872bf..edc4d1e85383 100644
--- a/test/CodeGenObjC/arc-property.m
+++ b/test/CodeGenObjC/arc-property.m
@@ -131,4 +131,24 @@ void test3(Test3 *t) {
- (void) setCopyMachine: (id) x {}
@end
+// rdar://31579994
+// When synthesizing a property that's declared in multiple protocols, ensure
+// that the setter is emitted if any of these declarations is readwrite.
+@protocol ABC
+@property (copy, nonatomic, readonly) Test3 *someId;
+@end
+@protocol ABC__Mutable <ABC>
+@property (copy, nonatomic, readwrite) Test3 *someId;
+@end
+
+@interface ABC_Class <ABC, ABC__Mutable>
+@end
+
+@implementation ABC_Class
+@synthesize someId = _someId;
+// CHECK: define internal %{{.*}}* @"\01-[ABC_Class someId]"
+// CHECK: define internal void @"\01-[ABC_Class setSomeId:]"(
+@end
+
+
// CHECK: attributes [[NUW]] = { nounwind }
diff --git a/test/CodeGenObjC/attr-callconv.m b/test/CodeGenObjC/attr-callconv.m
index b0a41f74381d..8cf8d2bd71f7 100644
--- a/test/CodeGenObjC/attr-callconv.m
+++ b/test/CodeGenObjC/attr-callconv.m
@@ -9,5 +9,5 @@
// CHECK: define{{.*}}x86_stdcallcc{{.*}}Test test
- (void)test2 __attribute__((ms_abi)) {}
- // CHECK: define{{.*}}x86_64_win64cc{{.*}}Test test2
+ // CHECK: define{{.*}}win64cc{{.*}}Test test2
@end
diff --git a/test/CodeGenOpenCL/kernel-arg-info.cl b/test/CodeGenOpenCL/kernel-arg-info.cl
index f1b2f45d7d97..463cc4451114 100644
--- a/test/CodeGenOpenCL/kernel-arg-info.cl
+++ b/test/CodeGenOpenCL/kernel-arg-info.cl
@@ -1,10 +1,24 @@
// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown | FileCheck %s
// RUN: %clang_cc1 %s -cl-std=CL2.0 -emit-llvm -o - -triple spir-unknown-unknown -cl-kernel-arg-info | FileCheck %s -check-prefix ARGINFO
-kernel void foo(__global int * restrict X, const int Y,
- volatile int anotherArg, __constant float * restrict Z,
- __global volatile int * V, __global const int * C) {
- *X = Y + anotherArg;
+kernel void foo(global int * globalintp, global int * restrict globalintrestrictp,
+ global const int * globalconstintp,
+ global const int * restrict globalconstintrestrictp,
+ constant int * constantintp, constant int * restrict constantintrestrictp,
+ global const volatile int * globalconstvolatileintp,
+ global const volatile int * restrict globalconstvolatileintrestrictp,
+ global volatile int * globalvolatileintp,
+ global volatile int * restrict globalvolatileintrestrictp,
+ local int * localintp, local int * restrict localintrestrictp,
+ local const int * localconstintp,
+ local const int * restrict localconstintrestrictp,
+ local const volatile int * localconstvolatileintp,
+ local const volatile int * restrict localconstvolatileintrestrictp,
+ local volatile int * localvolatileintp,
+ local volatile int * restrict localvolatileintrestrictp,
+ int X, const int constint, const volatile int constvolatileint,
+ volatile int volatileint) {
+ *globalintrestrictp = constint + volatileint;
}
// CHECK: define spir_kernel void @foo{{[^!]+}}
// CHECK: !kernel_arg_addr_space ![[MD11:[0-9]+]]
@@ -61,11 +75,15 @@ kernel void foo5(myImage img1, write_only image1d_t img2) {
// CHECK-NOT: !kernel_arg_name
// ARGINFO: !kernel_arg_name ![[MD54:[0-9]+]]
-// CHECK: ![[MD11]] = !{i32 1, i32 0, i32 0, i32 2, i32 1, i32 1}
-// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none"}
-// CHECK: ![[MD13]] = !{!"int*", !"int", !"int", !"float*", !"int*", !"int*"}
-// CHECK: ![[MD14]] = !{!"restrict", !"", !"", !"restrict const", !"volatile", !"const"}
-// ARGINFO: ![[MD15]] = !{!"X", !"Y", !"anotherArg", !"Z", !"V", !"C"}
+typedef char char16 __attribute__((ext_vector_type(16)));
+__kernel void foo6(__global char16 arg[]) {}
+// CHECK: !kernel_arg_type ![[MD61:[0-9]+]]
+
+// CHECK: ![[MD11]] = !{i32 1, i32 1, i32 1, i32 1, i32 2, i32 2, i32 1, i32 1, i32 1, i32 1, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 3, i32 0, i32 0, i32 0, i32 0}
+// CHECK: ![[MD12]] = !{!"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none", !"none"}
+// CHECK: ![[MD13]] = !{!"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int*", !"int", !"int", !"int", !"int"}
+// CHECK: ![[MD14]] = !{!"", !"restrict", !"const", !"restrict const", !"const", !"restrict const", !"const volatile", !"restrict const volatile", !"volatile", !"restrict volatile", !"", !"restrict", !"const", !"restrict const", !"const volatile", !"restrict const volatile", !"volatile", !"restrict volatile", !"", !"", !"", !""}
+// ARGINFO: ![[MD15]] = !{!"globalintp", !"globalintrestrictp", !"globalconstintp", !"globalconstintrestrictp", !"constantintp", !"constantintrestrictp", !"globalconstvolatileintp", !"globalconstvolatileintrestrictp", !"globalvolatileintp", !"globalvolatileintrestrictp", !"localintp", !"localintrestrictp", !"localconstintp", !"localconstintrestrictp", !"localconstvolatileintp", !"localconstvolatileintrestrictp", !"localvolatileintp", !"localvolatileintrestrictp", !"X", !"constint", !"constvolatileint", !"volatileint"}
// CHECK: ![[MD21]] = !{i32 1, i32 1, i32 1, i32 1}
// CHECK: ![[MD22]] = !{!"read_only", !"read_only", !"write_only", !"read_write"}
// CHECK: ![[MD23]] = !{!"image1d_t", !"image2d_t", !"image2d_array_t", !"image1d_t"}
@@ -86,4 +104,5 @@ kernel void foo5(myImage img1, write_only image1d_t img2) {
// CHECK: ![[MD52]] = !{!"myImage", !"image1d_t"}
// CHECK: ![[MD53]] = !{!"image1d_t", !"image1d_t"}
// ARGINFO: ![[MD54]] = !{!"img1", !"img2"}
+// CHECK: ![[MD61]] = !{!"char16*"}
diff --git a/test/Driver/autocomplete.c b/test/Driver/autocomplete.c
index e9e2e992bae9..dec48bfb3596 100644
--- a/test/Driver/autocomplete.c
+++ b/test/Driver/autocomplete.c
@@ -40,3 +40,7 @@
// MRELOCMODEL_CLANG-NOT: -mrelocation-model
// RUN: %clang --autocomplete=#-mrelocation-mode | FileCheck %s -check-prefix=MRELOCMODEL_CC1
// MRELOCMODEL_CC1: -mrelocation-model
+// RUN: %clang --autocomplete=-Wma | FileCheck %s -check-prefix=WARNING
+// WARNING: -Wmacro-redefined -Wmain -Wmain-return-type -Wmalformed-warning-check -Wmany-braces-around-scalar-init -Wmax-unsigned-zero
+// RUN: %clang --autocomplete=-Wnoinvalid-pp- | FileCheck %s -check-prefix=NOWARNING
+// NOWARNING: -Wnoinvalid-pp-token
diff --git a/test/Driver/constructors.c b/test/Driver/constructors.c
index cd14ed736a28..39a199a3c6ae 100644
--- a/test/Driver/constructors.c
+++ b/test/Driver/constructors.c
@@ -74,3 +74,11 @@
// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
// RUN: -target arm64-none-none-eabi \
// RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
+//
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN: -target sparc-sun-solaris2.11 \
+// RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
+//
+// RUN: %clang -no-canonical-prefixes %s -### -fsyntax-only 2>&1 \
+// RUN: -target i386-pc-solaris2.11 \
+// RUN: | FileCheck --check-prefix=CHECK-INIT-ARRAY %s
diff --git a/test/Driver/darwin-version.c b/test/Driver/darwin-version.c
index c11a2df37f98..12c7ef6eb0b1 100644
--- a/test/Driver/darwin-version.c
+++ b/test/Driver/darwin-version.c
@@ -121,3 +121,15 @@
// RUN: %clang -target i386-apple-darwin9 -c %s -### 2>&1 | \
// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOSSIM %s
// CHECK-VERSION-WATCHOSSIM: "i386-apple-watchos2.0.0"
+
+// RUN: %clang -target x86_64-apple-ios11.0.0 -c %s -### 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-IOS-TARGET %s
+// CHECK-VERSION-IOS-TARGET: "x86_64-apple-ios11.0.0"
+
+// RUN: %clang -target x86_64-apple-tvos11.0 -c %s -### 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-TVOS-TARGET %s
+// CHECK-VERSION-TVOS-TARGET: "x86_64-apple-tvos11.0.0"
+
+// RUN: %clang -target x86_64-apple-watchos4.0 -c %s -### 2>&1 | \
+// RUN: FileCheck --check-prefix=CHECK-VERSION-WATCHOS-TARGET %s
+// CHECK-VERSION-WATCHOS-TARGET: "x86_64-apple-watchos4.0.0"
diff --git a/test/Driver/emulated-tls.cpp b/test/Driver/emulated-tls.cpp
index a18c2e220bf8..38edc98ac889 100644
--- a/test/Driver/emulated-tls.cpp
+++ b/test/Driver/emulated-tls.cpp
@@ -1,5 +1,7 @@
-// Cygwin uses emutls. Clang should pass -femulated-tls to cc1 and cc1 should pass EmulatedTLS to LLVM CodeGen.
+// Cygwin and OpenBSD use emutls. Clang should pass -femulated-tls to cc1
+// and cc1 should pass EmulatedTLS to LLVM CodeGen.
// FIXME: Add more targets here to use emutls.
// RUN: %clang -### -std=c++11 -target i686-pc-cygwin %s 2>&1 | FileCheck %s
+// RUN: %clang -### -std=c++11 -target i686-pc-openbsd %s 2>&1 | FileCheck %s
// CHECK: "-cc1" {{.*}}"-femulated-tls"
diff --git a/test/Driver/fuchsia.c b/test/Driver/fuchsia.c
index 64d31cc0d38c..405086f3f07e 100644
--- a/test/Driver/fuchsia.c
+++ b/test/Driver/fuchsia.c
@@ -5,6 +5,7 @@
// CHECK: "-isysroot" "[[SYSROOT:[^"]+]]"
// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include"
// CHECK: {{.*}}lld{{.*}}" "-flavor" "gnu"
+// CHECK: "-z" "rodynamic"
// CHECK: "--sysroot=[[SYSROOT]]"
// CHECK: "-pie"
// CHECK: "--build-id"
diff --git a/test/Driver/fuchsia.cpp b/test/Driver/fuchsia.cpp
index 4c3f7d29acd8..20299c342688 100644
--- a/test/Driver/fuchsia.cpp
+++ b/test/Driver/fuchsia.cpp
@@ -7,6 +7,7 @@
// CHECK: "-internal-isystem" "{{.*[/\\]}}x86_64-fuchsia{{/|\\\\}}include{{/|\\\\}}c++{{/|\\\\}}v1"
// CHECK: "-internal-externc-isystem" "[[SYSROOT]]{{/|\\\\}}include"
// CHECK: {{.*}}lld{{.*}}" "-flavor" "gnu"
+// CHECK: "-z" "rodynamic"
// CHECK: "--sysroot=[[SYSROOT]]"
// CHECK: "-pie"
// CHECK: "--build-id"
diff --git a/test/Driver/lto-unit.c b/test/Driver/lto-unit.c
index 8a800fa4dcd6..1f1a2861670e 100644
--- a/test/Driver/lto-unit.c
+++ b/test/Driver/lto-unit.c
@@ -2,6 +2,8 @@
// RUN: %clang -target x86_64-unknown-linux -### %s -flto=thin 2>&1 | FileCheck --check-prefix=UNIT %s
// RUN: %clang -target x86_64-apple-darwin13.3.0 -### %s -flto=full 2>&1 | FileCheck --check-prefix=UNIT %s
// RUN: %clang -target x86_64-apple-darwin13.3.0 -### %s -flto=thin 2>&1 | FileCheck --check-prefix=NOUNIT %s
+// RUN: %clang -target x86_64-scei-ps4 -### %s -flto=full 2>&1 | FileCheck --check-prefix=UNIT %s
+// RUN: %clang -target x86_64-scei-ps4 -### %s -flto=thin 2>&1 | FileCheck --check-prefix=NOUNIT %s
// UNIT: "-flto-unit"
// NOUNIT-NOT: "-flto-unit"
diff --git a/test/Driver/pic.c b/test/Driver/pic.c
index 61d752094f6e..6b01c583b8b1 100644
--- a/test/Driver/pic.c
+++ b/test/Driver/pic.c
@@ -247,6 +247,9 @@
// On OpenBSD, -nopie needs to be passed through to the linker.
// RUN: %clang %s -target i386-pc-openbsd -nopie -### 2>&1 \
// RUN: | FileCheck %s --check-prefix=CHECK-NOPIE-LD
+// Try with the alias
+// RUN: %clang %s -target i386-pc-openbsd -no-pie -### 2>&1 \
+// RUN: | FileCheck %s --check-prefix=CHECK-NOPIE-LD
//
// On Android PIC is enabled by default
// RUN: %clang -c %s -target i686-linux-android -### 2>&1 \
diff --git a/test/Driver/std.cpp b/test/Driver/std.cpp
index aceda017a4e1..52b42ab9bd4f 100644
--- a/test/Driver/std.cpp
+++ b/test/Driver/std.cpp
@@ -9,6 +9,9 @@
// RUN: not %clang -std=gnu++1y %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Y %s
// RUN: not %clang -std=c++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX1Z %s
// RUN: not %clang -std=gnu++1z %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX1Z %s
+// RUN: not %clang -std=c++2a %s -fsyntax-only 2>&1 | FileCheck -check-prefix=CXX2A %s
+// RUN: not %clang -std=gnu++2a %s -fsyntax-only 2>&1 | FileCheck -check-prefix=GNUXX2A %s
+
void f(int n) {
typeof(n)();
@@ -38,3 +41,10 @@ void f(int n) {
// GNUXX1Z-NOT: undeclared identifier 'typeof'
// GNUXX1Z-NOT: undeclared identifier 'decltype'
+
+// CXX2A: undeclared identifier 'typeof'
+// CXX2A-NOT: undeclared identifier 'decltype'
+
+// GNUXX2A-NOT: undeclared identifier 'typeof'
+// GNUXX2A-NOT: undeclared identifier 'decltype'
+
diff --git a/test/Driver/systemz-march.c b/test/Driver/systemz-march.c
index a5df1f482d1e..2fe7f89d8512 100644
--- a/test/Driver/systemz-march.c
+++ b/test/Driver/systemz-march.c
@@ -9,6 +9,8 @@
// RUN: %clang -target s390x -### -S -emit-llvm -march=arch10 %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH10 %s
// RUN: %clang -target s390x -### -S -emit-llvm -march=z13 %s 2>&1 | FileCheck --check-prefix=CHECK-Z13 %s
// RUN: %clang -target s390x -### -S -emit-llvm -march=arch11 %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH11 %s
+// RUN: %clang -target s390x -### -S -emit-llvm -march=z14 %s 2>&1 | FileCheck --check-prefix=CHECK-Z14 %s
+// RUN: %clang -target s390x -### -S -emit-llvm -march=arch12 %s 2>&1 | FileCheck --check-prefix=CHECK-ARCH12 %s
// CHECK-Z9: error: unknown target CPU 'z9'
// CHECK-Z10: "-target-cpu" "z10"
@@ -19,5 +21,7 @@
// CHECK-ARCH10: "-target-cpu" "arch10"
// CHECK-Z13: "-target-cpu" "z13"
// CHECK-ARCH11: "-target-cpu" "arch11"
+// CHECK-Z14: "-target-cpu" "z14"
+// CHECK-ARCH12: "-target-cpu" "arch12"
int x;
diff --git a/test/Driver/unknown-std.cpp b/test/Driver/unknown-std.cpp
index 4f7a5e64a6ed..195a671edadf 100644
--- a/test/Driver/unknown-std.cpp
+++ b/test/Driver/unknown-std.cpp
@@ -15,6 +15,8 @@
// CHECK-NEXT: note: use 'gnu++14' for 'ISO C++ 2014 with amendments and GNU extensions' standard
// CHECK-NEXT: note: use 'c++1z' for 'Working draft for ISO C++ 2017' standard
// CHECK-NEXT: note: use 'gnu++1z' for 'Working draft for ISO C++ 2017 with GNU extensions' standard
+// CHECK-NEXT: note: use 'c++2a' for 'Working draft for ISO C++ 2020' standard
+// CHECK-NEXT: note: use 'gnu++2a' for 'Working draft for ISO C++ 2020 with GNU extensions' standard
// CUDA-NEXT: note: use 'cuda' for 'NVIDIA CUDA(tm)' standard
// Make sure that no other output is present.
diff --git a/test/FixIt/format.m b/test/FixIt/format.m
index 7af2cfdaf71a..c3cf2b1f3c56 100644
--- a/test/FixIt/format.m
+++ b/test/FixIt/format.m
@@ -229,6 +229,19 @@ void testSignedness(long i, unsigned long u) {
// CHECK: fix-it:"{{.*}}":{[[@LINE-2]]:11-[[@LINE-2]]:14}:"%+ld"
}
+void testSizeTypes() {
+ printf("%zu", 0.f); // expected-warning-re{{format specifies type 'size_t' (aka '{{.+}}') but the argument has type 'float'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+
+ printf("%zd", 0.f); // expected-warning-re{{format specifies type 'ssize_t' (aka '{{.+}}') but the argument has type 'float'}}
+ // CHECK: fix-it:"{{.*}}":{[[@LINE-1]]:11-[[@LINE-1]]:14}:"%f"
+
+ short x;
+ printf("%zn", &x); // expected-warning-re{{format specifies type 'ssize_t *' (aka '{{.+}}') but the argument has type 'short *'}}
+ // PrintfSpecifier::fixType doesn't handle %n, so a fix-it is not emitted,
+ // see the comment in PrintfSpecifier::fixType in PrintfFormatString.cpp.
+}
+
void testEnum() {
typedef enum {
ImplicitA = 1,
diff --git a/test/Index/Core/index-source.m b/test/Index/Core/index-source.m
index c911973a70d6..1333cafd7575 100644
--- a/test/Index/Core/index-source.m
+++ b/test/Index/Core/index-source.m
@@ -438,3 +438,28 @@ void testImplicitProperties(ImplicitProperties *c) {
// CHECK: [[@LINE-1]]:22 | class-method/ObjC | classImplicit | c:objc(cs)ImplicitProperties(cm)classImplicit | +[ImplicitProperties classImplicit] | Ref,Call,RelCall,RelCont | rel: 1
// CHECK-NEXT: RelCall,RelCont | testImplicitProperties | c:@F@testImplicitProperties
}
+
+@interface EmptySelectors
+
+- (int):(int)_; // CHECK: [[@LINE]]:8 | instance-method/ObjC | : | c:objc(cs)EmptySelectors(im): | -[EmptySelectors :]
+- (void)test: (int)x :(int)y; // CHECK: [[@LINE]]:9 | instance-method/ObjC | test:: | c:objc(cs)EmptySelectors(im)test:: | -[EmptySelectors test::]
+- (void):(int)_ :(int)m:(int)z; // CHECK: [[@LINE]]:9 | instance-method/ObjC | ::: | c:objc(cs)EmptySelectors(im)::: | -[EmptySelectors :::]
+
+@end
+
+@implementation EmptySelectors
+
+- (int):(int)_ { // CHECK: [[@LINE]]:8 | instance-method/ObjC | : | c:objc(cs)EmptySelectors(im): | -[EmptySelectors :]
+ [self :2]; // CHECK: [[@LINE]]:9 | instance-method/ObjC | : | c:objc(cs)EmptySelectors(im): | -[EmptySelectors :]
+ return 0;
+}
+
+- (void)test: (int)x :(int)y { // CHECK: [[@LINE]]:9 | instance-method/ObjC | test:: | c:objc(cs)EmptySelectors(im)test:: | -[EmptySelectors test::]
+}
+
+- (void) :(int)_ :(int)m :(int)z { // CHECK: [[@LINE]]:10 | instance-method/ObjC | ::: | c:objc(cs)EmptySelectors(im)::: | -[EmptySelectors :::]
+ [self test:0:1]; // CHECK: [[@LINE]]:9 | instance-method/ObjC | test:: | c:objc(cs)EmptySelectors(im)test:: | -[EmptySelectors test::]
+ [self: 0: 1: 2]; // CHECK: [[@LINE]]:8 | instance-method/ObjC | ::: | c:objc(cs)EmptySelectors(im)::: | -[EmptySelectors :::]
+}
+
+@end
diff --git a/test/Index/Core/no-templated-canonical-decl.cpp b/test/Index/Core/no-templated-canonical-decl.cpp
new file mode 100644
index 000000000000..5434e9cb6515
--- /dev/null
+++ b/test/Index/Core/no-templated-canonical-decl.cpp
@@ -0,0 +1,4 @@
+// RUN: c-index-test core -print-source-symbols -include-locals -- %s | FileCheck %s
+
+template <template <typename> class A> class B { typedef A<int> A_int; };
+// CHECK: [[@LINE-1]]:46 | class(Gen)/C++ | B | c:@ST>1#t>1#T@B | <no-cgname> | Def | rel: 0
diff --git a/test/Index/complete-available.m b/test/Index/complete-available.m
index 8267dbdddc5c..6c0a2622be03 100644
--- a/test/Index/complete-available.m
+++ b/test/Index/complete-available.m
@@ -8,8 +8,8 @@ void atAvailable() {
}
}
-// RUN: c-index-test -code-completion-at=%s:4:18 %s | FileCheck -check-prefix=CHECK %s
-// RUN: c-index-test -code-completion-at=%s:7:27 %s | FileCheck -check-prefix=CHECK %s
+// RUN: c-index-test -code-completion-at=%s:4:18 %s | FileCheck %s
+// RUN: c-index-test -code-completion-at=%s:7:27 %s | FileCheck %s
// CHECK: {TypedText iOS} (40)
// CHECK: {TypedText iOSApplicationExtension} (40)
// CHECK: {TypedText macOS} (40)
diff --git a/test/Misc/ast-dump-decl.c b/test/Misc/ast-dump-decl.c
index 313c808c4ac8..71b98c9443cf 100644
--- a/test/Misc/ast-dump-decl.c
+++ b/test/Misc/ast-dump-decl.c
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s
+// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s
// RUN: %clang_cc1 -triple x86_64-unknown-unknown -ast-dump %s | FileCheck -check-prefix CHECK-TU -strict-whitespace %s
// RUN: %clang_cc1 -fmodules -fmodules-local-submodule-visibility -fmodule-name=X -triple x86_64-unknown-unknown -fmodule-map-file=%S/Inputs/module.modulemap -ast-dump -ast-dump-filter Test %s -DMODULES | FileCheck -check-prefix CHECK -check-prefix CHECK-MODULES -strict-whitespace %s
diff --git a/test/Misc/ast-dump-decl.cpp b/test/Misc/ast-dump-decl.cpp
index 7370f46c5b32..a48261d367d9 100644
--- a/test/Misc/ast-dump-decl.cpp
+++ b/test/Misc/ast-dump-decl.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -check-prefix CHECK -strict-whitespace %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-linux-gnu -fms-extensions -ast-dump -ast-dump-filter Test %s | FileCheck -strict-whitespace %s
class testEnumDecl {
enum class TestEnumDeclScoped;
diff --git a/test/Modules/DebugInfoTransitiveImport.m b/test/Modules/DebugInfoTransitiveImport.m
index 034a909333cd..08dfecfb7899 100644
--- a/test/Modules/DebugInfoTransitiveImport.m
+++ b/test/Modules/DebugInfoTransitiveImport.m
@@ -12,9 +12,9 @@
// Definition of left:
// CHECK: !DICompileUnit({{.*}}dwoId:
-// CHECK: !DIFile({{.*}}diamond_left
+// CHECK: ![[LEFT:[0-9]+]] = !DIFile({{.*}}diamond_left.h
// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration,
-// CHECK-SAME: entity: ![[MODULE:.*]], line: 3)
+// CHECK-SAME: entity: ![[MODULE:.*]], file: ![[LEFT]], line: 3)
// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "diamond_top"
// Skeleton for top:
diff --git a/test/Modules/ExtDebugInfo.cpp b/test/Modules/ExtDebugInfo.cpp
index fd3bb940751f..ed9d1e859d83 100644
--- a/test/Modules/ExtDebugInfo.cpp
+++ b/test/Modules/ExtDebugInfo.cpp
@@ -71,6 +71,8 @@ void foo() {
anon.i = GlobalStruct.i = GlobalUnion.i = GlobalEnum;
}
+// CHECK: ![[CPP:.*]] = !DIFile(filename: {{.*}}ExtDebugInfo.cpp"
+
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type, name: "Enum",
// CHECK-SAME: scope: ![[NS:[0-9]+]],
// CHECK-SAME: flags: DIFlagFwdDecl,
@@ -201,7 +203,7 @@ void foo() {
// CHECK-SAME: name: "InAnonymousNamespace", {{.*}}DIFlagFwdDecl)
-// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !{{[0-9]+}}, entity: ![[STRUCT]], line: 27)
+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: !{{[0-9]+}}, entity: ![[STRUCT]], file: ![[CPP]], line: 27)
// CHECK: !DICompileUnit(
// CHECK-SAME: splitDebugFilename:
diff --git a/test/Modules/Inputs/DebugObjCImport.h b/test/Modules/Inputs/DebugObjCImport.h
new file mode 100644
index 000000000000..b5ef366fca1f
--- /dev/null
+++ b/test/Modules/Inputs/DebugObjCImport.h
@@ -0,0 +1,2 @@
+@import Empty;
+struct DebugObjCImport {};
diff --git a/test/Modules/Inputs/module.map b/test/Modules/Inputs/module.map
index c0fe6c557f22..4cb3e8a02804 100644
--- a/test/Modules/Inputs/module.map
+++ b/test/Modules/Inputs/module.map
@@ -347,6 +347,12 @@ module DebugObjC {
header "DebugObjC.h"
}
+module DebugObjCImport {
+ module SubModule {
+ header "DebugObjCImport.h"
+ }
+}
+
module ImportNameInDir {
header "ImportNameInDir.h"
export *
diff --git a/test/Modules/ModuleDebugInfo.m b/test/Modules/ModuleDebugInfo.m
index d1a0e8d5e80a..9289abe08080 100644
--- a/test/Modules/ModuleDebugInfo.m
+++ b/test/Modules/ModuleDebugInfo.m
@@ -23,8 +23,10 @@
@import DebugObjC;
#endif
-// CHECK: distinct !DICompileUnit(language: DW_LANG_ObjC
-// CHECK-SAME: isOptimized: false,
+// CHECK: distinct !DICompileUnit(language: DW_LANG_ObjC, file: ![[FILE:[0-9]+]],
+// CHECK-SAME: isOptimized: false
+
+// CHECK: ![[FILE]] = !DIFile(filename: "{{DebugObjC|.*DebugObjC.h}}"
// CHECK: !DICompositeType(tag: DW_TAG_enumeration_type,
// CHECK-SAME: scope: ![[MODULE:[0-9]+]],
diff --git a/test/Modules/debug-info-moduleimport-in-module.m b/test/Modules/debug-info-moduleimport-in-module.m
new file mode 100644
index 000000000000..cde46115d288
--- /dev/null
+++ b/test/Modules/debug-info-moduleimport-in-module.m
@@ -0,0 +1,21 @@
+// Test that an @import inside a module is not represented in the debug info.
+
+// REQUIRES: asserts
+
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c -fmodules -fmodule-format=obj \
+// RUN: -fimplicit-module-maps -fmodules-cache-path=%t %s \
+// RUN: -debugger-tuning=lldb -I %S/Inputs -emit-llvm -o %t.ll \
+// RUN: -mllvm -debug-only=pchcontainer &>%t-mod.ll
+// RUN: cat %t-mod.ll | FileCheck %s
+
+@import DebugObjCImport.SubModule;
+
+// CHECK: distinct !DICompileUnit(language: DW_LANG_ObjC
+// CHECK: DW_TAG_structure_type, name: "DebugObjCImport"
+// CHECK: ![[HEADER:.*]] = !DIFile(filename: {{.*}}DebugObjCImport.h"
+// CHECK: ![[SUBMOD:.*]] = !DIModule({{.*}}name: "SubModule"
+// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration,
+// CHECK-SAME: scope: ![[SUBMOD]], entity: ![[EMPTY:[0-9]+]],
+// CHECK-SAME: file: ![[HEADER]], line: 1)
+// CHECK: ![[EMPTY]] = !DIModule(scope: null, name: "Empty"
diff --git a/test/Modules/debug-info-moduleimport.m b/test/Modules/debug-info-moduleimport.m
index bf60690be40b..16820baebe68 100644
--- a/test/Modules/debug-info-moduleimport.m
+++ b/test/Modules/debug-info-moduleimport.m
@@ -10,12 +10,13 @@
// CHECK: ![[CU:.*]] = distinct !DICompileUnit
@import DebugObjC;
// CHECK: !DIImportedEntity(tag: DW_TAG_imported_declaration, scope: ![[CU]],
-// CHECK-SAME: entity: ![[MODULE:.*]], line: [[@LINE-2]])
+// CHECK-SAME: entity: ![[MODULE:.*]], file: ![[F:[0-9]+]],
+// CHECK-SAME: line: [[@LINE-3]])
// CHECK: ![[MODULE]] = !DIModule(scope: null, name: "DebugObjC",
// CHECK-SAME: configMacros: "\22-DGREETING=Hello World\22 \22-UNDEBUG\22",
// CHECK-SAME: includePath: "{{.*}}test{{.*}}Modules{{.*}}Inputs",
// CHECK-SAME: isysroot: "/tmp/..")
-
+// CHECK: ![[F]] = !DIFile(filename: {{.*}}debug-info-moduleimport.m
// RUN: %clang_cc1 -debug-info-kind=limited -fmodules -fimplicit-module-maps -fmodules-cache-path=%t \
// RUN: %s -I %S/Inputs -isysroot /tmp/.. -I %t -emit-llvm -o - \
diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp
index ee45ae529961..68a988dc8e78 100644
--- a/test/Modules/odr_hash.cpp
+++ b/test/Modules/odr_hash.cpp
@@ -517,8 +517,91 @@ S14 s14;
// expected-error@second.h:* {{'Method::S14' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [3]'}}
// expected-note@first.h:* {{but in 'FirstModule' found method 'A' with 1st parameter of type 'int *' decayed from 'int [2]'}}
#endif
+
+#if defined(FIRST)
+struct S15 {
+ int A() { return 0; }
+};
+#elif defined(SECOND)
+struct S15 {
+ long A() { return 0; }
+};
+#else
+S15 s15;
+// expected-error@first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}}
+// expected-note@second.h:* {{declaration of 'A' does not match}}
+#endif
} // namespace Method
+namespace Constructor {
+#if defined(FIRST)
+struct S1 {
+ S1() {}
+ void foo() {}
+};
+#elif defined(SECOND)
+struct S1 {
+ void foo() {}
+ S1() {}
+};
+#else
+S1 s1;
+// expected-error@second.h:* {{'Constructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo'}}
+// expected-note@first.h:* {{but in 'FirstModule' found constructor}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+ S2(int) {}
+ S2(int, int) {}
+};
+#elif defined(SECOND)
+struct S2 {
+ S2(int, int) {}
+ S2(int) {}
+};
+#else
+S2* s2;
+// expected-error@second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}}
+// expected-note@first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}}
+#endif
+} // namespace Constructor
+
+namespace Destructor {
+#if defined(FIRST)
+struct S1 {
+ ~S1() {}
+ S1() {}
+};
+#elif defined(SECOND)
+struct S1 {
+ S1() {}
+ ~S1() {}
+};
+#else
+S1 s1;
+// expected-error@second.h:* {{'Destructor::S1' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor}}
+// expected-note@first.h:* {{but in 'FirstModule' found destructor}}
+#endif
+
+#if defined(FIRST)
+struct S2 {
+ virtual ~S2() {}
+ void foo() {}
+};
+#elif defined(SECOND)
+struct S2 {
+ ~S2() {}
+ virtual void foo() {}
+};
+#else
+S2 s2;
+// expected-error@second.h:* {{'Destructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found destructor is not virtual}}
+// expected-note@first.h:* {{but in 'FirstModule' found destructor is virtual}}
+#endif
+
+} // namespace Destructor
+
// Naive parsing of AST can lead to cycles in processing. Ensure
// self-references don't trigger an endless cycles of AST node processing.
namespace SelfReference {
diff --git a/test/OpenMP/distribute_parallel_for_if_codegen.cpp b/test/OpenMP/distribute_parallel_for_if_codegen.cpp
index e6cd7215f585..9ee909e0139c 100644
--- a/test/OpenMP/distribute_parallel_for_if_codegen.cpp
+++ b/test/OpenMP/distribute_parallel_for_if_codegen.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -fopenmp-targets=powerpc64le-ibm-linux-gnu -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
diff --git a/test/OpenMP/for_reduction_codegen.cpp b/test/OpenMP/for_reduction_codegen.cpp
index 274546b06547..d5afae990bf4 100644
--- a/test/OpenMP/for_reduction_codegen.cpp
+++ b/test/OpenMP/for_reduction_codegen.cpp
@@ -497,15 +497,12 @@ int main() {
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}**
+// CHECK: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** [[ARR_ADDR:%.+]],
+// CHECK: [[ARR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARR_ADDR]],
-// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}}
-// CHECK: [[LB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[LB1_0:%.+]] = getelementptr inbounds i32, i32* [[LB1]], i64 0
-// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}}
-// CHECK: [[UB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[UB1_UP:%.+]] = getelementptr inbounds i32, i32* [[UB1]], i64 %
-// CHECK: [[UB_CAST:%.+]] = ptrtoint i32* [[UB1_UP]] to i64
-// CHECK: [[LB_CAST:%.+]] = ptrtoint i32* [[LB1_0]] to i64
+// CHECK: [[UB_CAST:%.+]] = ptrtoint i32* [[UB1_UP:%.+]] to i64
+// CHECK: [[LB_CAST:%.+]] = ptrtoint i32* [[LB1_0:%.+]] to i64
// CHECK: [[DIFF:%.+]] = sub i64 [[UB_CAST]], [[LB_CAST]]
// CHECK: [[SIZE_1:%.+]] = sdiv exact i64 [[DIFF]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
// CHECK: [[ARR_SIZE:%.+]] = add nuw i64 [[SIZE_1]], 1
@@ -704,7 +701,7 @@ int main() {
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[ARR_SIZE:%.+]] = mul nuw i64 %{{.+}}, 4
+// CHECK: [[ARR_SIZE:%.+]] = udiv exact i64
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]],
@@ -718,7 +715,6 @@ int main() {
// CHECK: br i1 [[DONE]],
// Check initialization of private copy.
-// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*
// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0
// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40
// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]]
@@ -727,6 +723,7 @@ int main() {
// CHECK: call void @_ZN1SIfEC1Ev([[S_FLOAT_TY]]* %
// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
// CHECK: br i1 [[DONE]],
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*
// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]*
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
@@ -895,23 +892,15 @@ int main() {
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
-// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
-// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 0
-// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
-// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 1
-// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
-// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4
-// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
-// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6
-// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
-// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
-// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW:%.+]] to i64
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
@@ -932,8 +921,6 @@ int main() {
// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
-// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
@@ -941,6 +928,7 @@ int main() {
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
@@ -960,19 +948,15 @@ int main() {
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
-// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW:%.+]] to i64
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
@@ -997,11 +981,11 @@ int main() {
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
+// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: ret void
diff --git a/test/OpenMP/for_reduction_codegen_UDR.cpp b/test/OpenMP/for_reduction_codegen_UDR.cpp
index 699e06dda85a..95b04f44d468 100644
--- a/test/OpenMP/for_reduction_codegen_UDR.cpp
+++ b/test/OpenMP/for_reduction_codegen_UDR.cpp
@@ -306,15 +306,12 @@ int main() {
// CHECK: [[RED_LIST:%.+]] = alloca [4 x i8*],
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
+// CHECK: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}**
+// CHECK: store i{{[0-9]+}}* %{{.+}}, i{{[0-9]+}}** [[ARR_ADDR:%.+]],
+// CHECK: [[ARR:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[ARR_ADDR]],
-// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}}
-// CHECK: [[LB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[LB1_0:%.+]] = getelementptr inbounds i32, i32* [[LB1]], i64 0
-// CHECK: [[IDX1:%.+]] = mul nsw i64 1, %{{.+}}
-// CHECK: [[UB1:%.+]] = getelementptr inbounds i32, i32* %{{.+}}, i64 [[IDX1]]
-// CHECK: [[UB1_UP:%.+]] = getelementptr inbounds i32, i32* [[UB1]], i64 %
-// CHECK: [[UB_CAST:%.+]] = ptrtoint i32* [[UB1_UP]] to i64
-// CHECK: [[LB_CAST:%.+]] = ptrtoint i32* [[LB1_0]] to i64
+// CHECK: [[UB_CAST:%.+]] = ptrtoint i32* [[UB1_UP:%.+]] to i64
+// CHECK: [[LB_CAST:%.+]] = ptrtoint i32* [[LB1_0:%.+]] to i64
// CHECK: [[DIFF:%.+]] = sub i64 [[UB_CAST]], [[LB_CAST]]
// CHECK: [[SIZE_1:%.+]] = sdiv exact i64 [[DIFF]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64)
// CHECK: [[ARR_SIZE:%.+]] = add nuw i64 [[SIZE_1]], 1
@@ -508,7 +505,7 @@ int main() {
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
-// CHECK: [[ARR_SIZE:%.+]] = mul nuw i64 %{{.+}}, 4
+// CHECK: [[ARR_SIZE:%.+]] = udiv exact i64
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[ARR_PRIV:%.+]] = alloca i32, i64 [[ARR_SIZE]],
@@ -522,8 +519,8 @@ int main() {
// CHECK: br i1 [[DONE]],
// Check initialization of private copy.
-// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*
// CHECK: [[BEGIN:%.+]] = getelementptr inbounds [10 x [4 x [[S_FLOAT_TY]]]], [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]], i32 0, i32 0, i32 0
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*
// CHECK: [[END:%.+]] = getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* [[BEGIN]], i64 40
// CHECK: [[ISEMPTY:%.+]] = icmp eq [[S_FLOAT_TY]]* [[BEGIN]], [[END]]
// CHECK: br i1 [[ISEMPTY]],
@@ -531,6 +528,7 @@ int main() {
// CHECK: call void @_Z4initR6BaseS1RKS_(%
// CHECK: [[DONE:%.+]] = icmp eq [[S_FLOAT_TY]]* %{{.+}}, [[END]]
// CHECK: br i1 [[DONE]],
+// CHECK: [[LHS_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* %{{.+}} to [[S_FLOAT_TY]]*
// CHECK: [[ARRS_PRIV_BEGIN:%.+]] = bitcast [10 x [4 x [[S_FLOAT_TY]]]]* [[ARRS_PRIV]] to [[S_FLOAT_TY]]*
// CHECK: [[GTID_REF:%.+]] = load i{{[0-9]+}}*, i{{[0-9]+}}** [[GTID_ADDR_ADDR]]
@@ -695,23 +693,15 @@ int main() {
// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]],
// CHECK: [[VAR2_ORIG:%.+]] = load [[S_FLOAT_TY]]***, [[S_FLOAT_TY]]**** [[VAR2_ORIG_ADDR]],
-// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
-// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 0
-// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
-// CHECK: [[LOW:%.+]] = getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 1
-// CHECK: load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
-// CHECK: getelementptr inbounds [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %{{.+}}, i64 4
-// CHECK: load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** %
-// CHECK: getelementptr inbounds [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 6
-// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
-// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
-// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW:%.+]] to i64
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[LD:%.+]] = load [[S_FLOAT_TY]]**, [[S_FLOAT_TY]]*** [[VAR2_ORIG]],
+// CHECK: [[ORIG_START:%.+]] = load [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]** [[LD]],
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
@@ -732,8 +722,6 @@ int main() {
// CHECK: [[VVAR2_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VVAR2_ORIG_ADDR]],
// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 0
-// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]], i64 0, i64 4
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
@@ -741,6 +729,7 @@ int main() {
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[VVAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VVAR2_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
@@ -760,19 +749,15 @@ int main() {
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: [[LOW:%.+]] = getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 1
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], i64 0, i64 2
-// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[LAST:%.+]] = ptrtoint [[S_FLOAT_TY]]* %{{.+}} to i64
-// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
+// CHECK: [[FIRST:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW:%.+]] to i64
// CHECK: [[BYTE_DIF:%.+]] = sub i64 [[LAST]], [[FIRST]]
// CHECK: [[DIF:%.+]] = sdiv exact i64 [[BYTE_DIF]], ptrtoint ([[S_FLOAT_TY]]* getelementptr ([[S_FLOAT_TY]], [[S_FLOAT_TY]]* null, i32 1) to i64)
// CHECK: [[SIZE:%.+]] = add nuw i64 [[DIF]], 1
// CHECK: call i8* @llvm.stacksave()
// CHECK: [[VAR3_PRIV:%.+]] = alloca [[S_FLOAT_TY]], i64 [[SIZE]],
+// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
+// CHECK: [[ORIG_START:%.+]] = bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: [[START:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[ORIG_START]] to i64
// CHECK: [[LOW_BOUND:%.+]] = ptrtoint [[S_FLOAT_TY]]* [[LOW]] to i64
// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]]
@@ -797,8 +782,8 @@ int main() {
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]], [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR:%.+]],
// CHECK: [[VAR3_ORIG:%.+]] = load [2 x [[S_FLOAT_TY]]]*, [2 x [[S_FLOAT_TY]]]** [[VAR3_ORIG_ADDR]],
-// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: getelementptr inbounds [2 x [[S_FLOAT_TY]]], [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], i32 0, i32 0
+// CHECK: bitcast [2 x [[S_FLOAT_TY]]]* [[VAR3_ORIG]] to [[S_FLOAT_TY]]*
// CHECK: getelementptr [[S_FLOAT_TY]], [[S_FLOAT_TY]]* %{{.+}}, i64 2
// CHECK: store [2 x [[S_FLOAT_TY]]]* [[VAR3_PRIV]], [2 x [[S_FLOAT_TY]]]** %
diff --git a/test/OpenMP/parallel_if_codegen.cpp b/test/OpenMP/parallel_if_codegen.cpp
index af154c0e36dd..87dcf1dde943 100644
--- a/test/OpenMP/parallel_if_codegen.cpp
+++ b/test/OpenMP/parallel_if_codegen.cpp
@@ -1,6 +1,6 @@
// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -emit-llvm %s -o - | FileCheck %s
// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -std=c++11 -triple %itanium_abi_triple -emit-pch -o %t %s
-// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck --check-prefix=CHECK %s
+// RUN: %clang_cc1 -fopenmp -fopenmp-version=45 -x c++ -triple %itanium_abi_triple -std=c++11 -include-pch %t -verify %s -emit-llvm -o - | FileCheck %s
// expected-no-diagnostics
#ifndef HEADER
#define HEADER
diff --git a/test/OpenMP/taskgroup_ast_print.cpp b/test/OpenMP/taskgroup_ast_print.cpp
index 683141e686ec..4292eedfb56e 100644
--- a/test/OpenMP/taskgroup_ast_print.cpp
+++ b/test/OpenMP/taskgroup_ast_print.cpp
@@ -8,6 +8,62 @@
void foo() {}
+struct S1 {
+ S1(): a(0) {}
+ S1(int v) : a(v) {}
+ int a;
+ typedef int type;
+ S1& operator +(const S1&);
+ S1& operator *(const S1&);
+ S1& operator &&(const S1&);
+ S1& operator ^(const S1&);
+};
+
+template <typename T>
+class S7 : public T {
+protected:
+ T a;
+ T b[100];
+ S7() : a(0) {}
+
+public:
+ S7(typename T::type v) : a(v) {
+#pragma omp taskgroup task_reduction(+ : a) task_reduction(*: b[:])
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S7 &operator=(S7 &s) {
+#pragma omp taskgroup task_reduction(&& : this->a) task_reduction(^: b[s.a.a])
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp taskgroup task_reduction(+: this->a) task_reduction(*: this->b[:])
+// CHECK: #pragma omp taskgroup task_reduction(&&: this->a) task_reduction(^: this->b[s.a.a])
+// CHECK: #pragma omp taskgroup task_reduction(+: this->a) task_reduction(*: this->b[:])
+
+class S8 : public S7<S1> {
+ S8() {}
+
+public:
+ S8(int v) : S7<S1>(v){
+#pragma omp taskgroup task_reduction(^ : S7 < S1 > ::a) task_reduction(+ : S7 < S1 > ::b[ : S7 < S1 > ::a.a])
+ for (int k = 0; k < a.a; ++k)
+ ++this->a.a;
+ }
+ S8 &operator=(S8 &s) {
+#pragma omp taskgroup task_reduction(* : this->a) task_reduction(&&:this->b[a.a:])
+ for (int k = 0; k < s.a.a; ++k)
+ ++s.a.a;
+ return *this;
+ }
+};
+
+// CHECK: #pragma omp taskgroup task_reduction(^: this->S7<S1>::a) task_reduction(+: this->S7<S1>::b[:this->S7<S1>::a.a])
+// CHECK: #pragma omp taskgroup task_reduction(*: this->a) task_reduction(&&: this->b[this->a.a:])
+
int main (int argc, char **argv) {
int b = argc, c, d, e, f, g;
static int a;
@@ -18,9 +74,9 @@ int main (int argc, char **argv) {
// CHECK-NEXT: a = 2;
// CHECK-NEXT: ++a;
++a;
-#pragma omp taskgroup
+#pragma omp taskgroup task_reduction(min: a)
foo();
-// CHECK-NEXT: #pragma omp taskgroup
+// CHECK-NEXT: #pragma omp taskgroup task_reduction(min: a)
// CHECK-NEXT: foo();
// CHECK-NEXT: return 0;
return 0;
diff --git a/test/OpenMP/taskgroup_messages.cpp b/test/OpenMP/taskgroup_messages.cpp
index e893da4be3fa..23820734a551 100644
--- a/test/OpenMP/taskgroup_messages.cpp
+++ b/test/OpenMP/taskgroup_messages.cpp
@@ -63,5 +63,7 @@ int foo() {
foo();
}
+#pragma omp taskgroup init // expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}}
+ ;
return 0;
}
diff --git a/test/OpenMP/taskgroup_task_reduction_messages.cpp b/test/OpenMP/taskgroup_task_reduction_messages.cpp
new file mode 100644
index 000000000000..9c8177b0bd43
--- /dev/null
+++ b/test/OpenMP/taskgroup_task_reduction_messages.cpp
@@ -0,0 +1,258 @@
+// RUN: %clang_cc1 -verify -fopenmp -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++98 -ferror-limit 150 -o - %s
+// RUN: %clang_cc1 -verify -fopenmp -std=c++11 -ferror-limit 150 -o - %s
+
+void foo() {
+}
+
+bool foobool(int argc) {
+ return argc;
+}
+
+void foobar(int &ref) {
+#pragma omp taskgroup task_reduction(+:ref)
+ foo();
+}
+
+struct S1; // expected-note {{declared here}} expected-note 4 {{forward declaration of 'S1'}}
+extern S1 a;
+class S2 {
+ mutable int a;
+ S2 &operator+(const S2 &arg) { return (*this); } // expected-note 3 {{implicitly declared private here}}
+
+public:
+ S2() : a(0) {}
+ S2(S2 &s2) : a(s2.a) {}
+ static float S2s; // expected-note 2 {{static data member is predetermined as shared}}
+ static const float S2sc;
+};
+const float S2::S2sc = 0; // expected-note 2 {{'S2sc' defined here}}
+S2 b; // expected-note 3 {{'b' defined here}}
+const S2 ba[5]; // expected-note 2 {{'ba' defined here}}
+class S3 {
+ int a;
+
+public:
+ int b;
+ S3() : a(0) {}
+ S3(const S3 &s3) : a(s3.a) {}
+ S3 operator+(const S3 &arg1) { return arg1; }
+};
+int operator+(const S3 &arg1, const S3 &arg2) { return 5; }
+S3 c; // expected-note 3 {{'c' defined here}}
+const S3 ca[5]; // expected-note 2 {{'ca' defined here}}
+extern const int f; // expected-note 4 {{'f' declared here}}
+class S4 {
+ int a;
+ S4(); // expected-note {{implicitly declared private here}}
+ S4(const S4 &s4);
+ S4 &operator+(const S4 &arg) { return (*this); }
+
+public:
+ S4(int v) : a(v) {}
+};
+S4 &operator&=(S4 &arg1, S4 &arg2) { return arg1; }
+class S5 {
+ int a;
+ S5() : a(0) {} // expected-note {{implicitly declared private here}}
+ S5(const S5 &s5) : a(s5.a) {}
+ S5 &operator+(const S5 &arg);
+
+public:
+ S5(int v) : a(v) {}
+};
+class S6 { // expected-note 3 {{candidate function (the implicit copy assignment operator) not viable: no known conversion from 'int' to 'const S6' for 1st argument}}
+#if __cplusplus >= 201103L // C++11 or later
+// expected-note@-2 3 {{candidate function (the implicit move assignment operator) not viable}}
+#endif
+ int a;
+
+public:
+ S6() : a(6) {}
+ operator int() { return 6; }
+} o;
+
+S3 h, k;
+#pragma omp threadprivate(h) // expected-note 2 {{defined as threadprivate or thread local}}
+
+template <class T> // expected-note {{declared here}}
+T tmain(T argc) {
+ const T d = T(); // expected-note 4 {{'d' defined here}}
+ const T da[5] = {T()}; // expected-note 2 {{'da' defined here}}
+ T qa[5] = {T()};
+ T i;
+ T &j = i; // expected-note 2 {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const T &r = da[(int)i]; // expected-note 2 {{'r' defined here}}
+ T &q = qa[(int)i];
+ T fl;
+#pragma omp taskgroup task_reduction // expected-error {{expected '(' after 'task_reduction'}}
+ foo();
+#pragma omp taskgroup task_reduction + // expected-error {{expected '(' after 'task_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}}
+ foo();
+#pragma omp taskgroup task_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp taskgroup task_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp taskgroup task_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(& : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp taskgroup task_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp taskgroup task_reduction(|| : argc ? i : argc) // expected-error 2 {{expected variable name, array element or array section}}
+ foo();
+#pragma omp taskgroup task_reduction(foo : argc) //expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'float'}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max' or declare reduction for type 'int'}}
+ foo();
+#pragma omp taskgroup task_reduction(&& : argc)
+ foo();
+#pragma omp taskgroup task_reduction(^ : T) // expected-error {{'T' does not refer to a value}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 3 {{const-qualified list item cannot be reduction}} expected-error 2 {{'operator+' is a private member of 'S2'}}
+ foo();
+#pragma omp taskgroup task_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 4 {{arguments of OpenMP clause 'task_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 3 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}} expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp taskgroup task_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : h, k) // expected-error {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : o) // expected-error 2 {{no viable overloaded '='}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp taskgroup task_reduction(+ : p), task_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'task_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : p), task_reduction(+ : p) // expected-error 2 {{variable can appear only once in OpenMP 'task_reduction' clause}} expected-note 2 {{previously referenced here}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : r) // expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp taskgroup task_reduction(max : j) // expected-error 2 {{argument of OpenMP clause 'task_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+ : fl)
+ foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+ : fl)
+ foo();
+
+ return T();
+}
+
+namespace A {
+double x;
+#pragma omp threadprivate(x) // expected-note {{defined as threadprivate or thread local}}
+}
+namespace B {
+using A::x;
+}
+
+int main(int argc, char **argv) {
+ const int d = 5; // expected-note 2 {{'d' defined here}}
+ const int da[5] = {0}; // expected-note {{'da' defined here}}
+ int qa[5] = {0};
+ S4 e(4);
+ S5 g(5);
+ int i;
+ int &j = i; // expected-note {{'j' defined here}}
+ S3 &p = k; // expected-note 2 {{'p' defined here}}
+ const int &r = da[i]; // expected-note {{'r' defined here}}
+ int &q = qa[i];
+ float fl;
+#pragma omp taskgroup task_reduction // expected-error {{expected '(' after 'task_reduction'}}
+ foo();
+#pragma omp taskgroup task_reduction + // expected-error {{expected '(' after 'task_reduction'}} expected-warning {{extra tokens at the end of '#pragma omp taskgroup' are ignored}}
+ foo();
+#pragma omp taskgroup task_reduction( // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp taskgroup task_reduction(- // expected-warning {{missing ':' after reduction identifier - ignoring}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp taskgroup task_reduction() // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(*) // expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(\) // expected-error {{expected unqualified-id}} expected-warning {{missing ':' after reduction identifier - ignoring}}
+ foo();
+#pragma omp taskgroup task_reduction(foo : argc // expected-error {{expected ')'}} expected-note {{to match this '('}} expected-error {{incorrect reduction identifier, expected one of '+', '-', '*', '&', '|', '^', '&&', '||', 'min' or 'max'}}
+ foo();
+#pragma omp taskgroup task_reduction(| : argc, // expected-error {{expected expression}} expected-error {{expected ')'}} expected-note {{to match this '('}}
+ foo();
+#pragma omp taskgroup task_reduction(|| : argc > 0 ? argv[1] : argv[2]) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp taskgroup task_reduction(~ : argc) // expected-error {{expected unqualified-id}}
+ foo();
+#pragma omp taskgroup task_reduction(&& : argc)
+ foo();
+#pragma omp taskgroup task_reduction(^ : S1) // expected-error {{'S1' does not refer to a value}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{const-qualified list item cannot be reduction}} expected-error {{'operator+' is a private member of 'S2'}}
+ foo();
+#pragma omp taskgroup task_reduction(min : a, b, c, d, f) // expected-error {{a reduction list item with incomplete type 'S1'}} expected-error 2 {{arguments of OpenMP clause 'task_reduction' for 'min' or 'max' must be of arithmetic type}} expected-error 2 {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(max : h.b) // expected-error {{expected variable name, array element or array section}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : ba) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(* : ca) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(- : da) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(^ : fl) // expected-error {{invalid operands to binary expression ('float' and 'float')}}
+ foo();
+#pragma omp taskgroup task_reduction(&& : S2::S2s) // expected-error {{shared variable cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(&& : S2::S2sc) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(& : e, g) // expected-error {{calling a private constructor of class 'S4'}} expected-error {{nvalid operands to binary expression ('S4' and 'S4')}} expected-error {{calling a private constructor of class 'S5'}} expected-error {{invalid operands to binary expression ('S5' and 'S5')}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : h, k, B::x) // expected-error 2 {{threadprivate or thread local variable cannot be reduction}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : o) // expected-error {{no viable overloaded '='}}
+ foo();
+#pragma omp parallel private(k)
+#pragma omp taskgroup task_reduction(+ : p), task_reduction(+ : p) // expected-error 2 {{argument of OpenMP clause 'task_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : p), task_reduction(+ : p) // expected-error {{variable can appear only once in OpenMP 'task_reduction' clause}} expected-note {{previously referenced here}}
+ foo();
+#pragma omp taskgroup task_reduction(+ : r) // expected-error {{const-qualified list item cannot be reduction}}
+ foo();
+#pragma omp parallel shared(i)
+#pragma omp parallel reduction(min : i)
+#pragma omp taskgroup task_reduction(max : j) // expected-error {{argument of OpenMP clause 'task_reduction' must reference the same object in all threads}}
+ foo();
+#pragma omp parallel
+#pragma omp for private(fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+ : fl)
+ foo();
+#pragma omp parallel
+#pragma omp for reduction(- : fl)
+ for (int i = 0; i < 10; ++i)
+#pragma omp taskgroup task_reduction(+ : fl)
+ foo();
+ static int m;
+#pragma omp taskgroup task_reduction(+ : m) // OK
+ m++;
+
+ return tmain(argc) + tmain(fl); // expected-note {{in instantiation of function template specialization 'tmain<int>' requested here}} expected-note {{in instantiation of function template specialization 'tmain<float>' requested here}}
+}
diff --git a/test/OpenMP/taskloop_codegen.cpp b/test/OpenMP/taskloop_codegen.cpp
index b1b45455802a..8de52023f33d 100644
--- a/test/OpenMP/taskloop_codegen.cpp
+++ b/test/OpenMP/taskloop_codegen.cpp
@@ -9,7 +9,7 @@
int main(int argc, char **argv) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
// CHECK: call void @__kmpc_taskgroup(%ident_t* [[DEFLOC]], i32 [[GTID]])
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
@@ -24,7 +24,7 @@ int main(int argc, char **argv) {
#pragma omp taskloop priority(argc)
for (int i = 0; i < 10; ++i)
;
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
@@ -40,7 +40,7 @@ int main(int argc, char **argv) {
for (int i = 0; i < 10; ++i)
;
// CHECK: call void @__kmpc_taskgroup(%ident_t* [[DEFLOC]], i32 [[GTID]])
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[IF:%.+]] = icmp ne i32 %{{.+}}, 0
@@ -144,7 +144,7 @@ struct S {
int a;
S(int c) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
diff --git a/test/OpenMP/taskloop_firstprivate_codegen.cpp b/test/OpenMP/taskloop_firstprivate_codegen.cpp
index f4358db99b8c..6e8453050987 100644
--- a/test/OpenMP/taskloop_firstprivate_codegen.cpp
+++ b/test/OpenMP/taskloop_firstprivate_codegen.cpp
@@ -23,7 +23,7 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32, i8* }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}
@@ -57,7 +57,7 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
// LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
@@ -101,7 +101,7 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
// BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
@@ -190,7 +190,7 @@ int main() {
// [[KMP_TASK_T]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 120, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// Fill kmp_task_t->shareds by copying from original capture argument.
diff --git a/test/OpenMP/taskloop_lastprivate_codegen.cpp b/test/OpenMP/taskloop_lastprivate_codegen.cpp
index e689feba20ac..837977eb57c0 100644
--- a/test/OpenMP/taskloop_lastprivate_codegen.cpp
+++ b/test/OpenMP/taskloop_lastprivate_codegen.cpp
@@ -23,7 +23,7 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32, i8* }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* }
@@ -57,7 +57,7 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
@@ -98,7 +98,7 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
// BLOCKS: ret
@@ -182,7 +182,7 @@ int main() {
// [[KMP_TASK_T]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 120, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// Fill kmp_task_t->shareds by copying from original capture argument.
diff --git a/test/OpenMP/taskloop_private_codegen.cpp b/test/OpenMP/taskloop_private_codegen.cpp
index dad9a17767fc..6ca7c402a12b 100644
--- a/test/OpenMP/taskloop_private_codegen.cpp
+++ b/test/OpenMP/taskloop_private_codegen.cpp
@@ -23,7 +23,7 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32, i8* }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
@@ -55,7 +55,7 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
// LAMBDA: ret
@@ -91,7 +91,7 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
// BLOCKS: ret
@@ -157,7 +157,7 @@ int main() {
// [[KMP_TASK_T_TY]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 120, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
diff --git a/test/OpenMP/taskloop_reduction_codegen.cpp b/test/OpenMP/taskloop_reduction_codegen.cpp
new file mode 100644
index 000000000000..af071ae8bd4e
--- /dev/null
+++ b/test/OpenMP/taskloop_reduction_codegen.cpp
@@ -0,0 +1,197 @@
+// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu | FileCheck %s
+// expected-no-diagnostics
+
+struct S {
+ float a;
+ S() : a(0.0f) {}
+ ~S() {}
+};
+
+#pragma omp declare reduction(+:S:omp_out.a += omp_in.a) initializer(omp_priv = omp_orig)
+
+float g;
+
+int a;
+#pragma omp threadprivate(a)
+int main (int argc, char *argv[])
+{
+int i, n;
+float a[100], b[100], sum, e[argc + 100];
+S c[100];
+float &d = g;
+
+/* Some initializations */
+n = 100;
+for (i=0; i < n; i++)
+ a[i] = b[i] = i * 1.0;
+sum = 0.0;
+
+#pragma omp taskloop reduction(+:sum, c[:n], d, e)
+ for (i=0; i < n; i++) {
+ sum = sum + (a[i] * b[i]);
+ c[i].a = i*i;
+ d += i*i;
+ e[i] = i;
+ }
+
+}
+
+// CHECK-LABEL: @main(
+// CHECK: [[RETVAL:%.*]] = alloca i32,
+// CHECK: [[ARGC_ADDR:%.*]] = alloca i32,
+// CHECK: [[ARGV_ADDR:%.*]] = alloca i8**,
+// CHECK: [[I:%.*]] = alloca i32,
+// CHECK: [[N:%.*]] = alloca i32,
+// CHECK: [[A:%.*]] = alloca [100 x float],
+// CHECK: [[B:%.*]] = alloca [100 x float],
+// CHECK: [[SUM:%.*]] = alloca float,
+// CHECK: [[SAVED_STACK:%.*]] = alloca i8*,
+// CHECK: [[C:%.*]] = alloca [100 x %struct.S],
+// CHECK: [[D:%.*]] = alloca float*,
+// CHECK: [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON:%.*]],
+// CHECK: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%ident_t*
+// CHECK: [[DOTRD_INPUT_:%.*]] = alloca [4 x %struct.kmp_task_red_input_t],
+// CHECK: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32,
+// CHECK: [[DOTCAPTURE_EXPR_9:%.*]] = alloca i32,
+// CHECK: store i32 0, i32* [[RETVAL]],
+// CHECK: store i32 [[ARGC:%.*]], i32* [[ARGC_ADDR]],
+// CHECK: store i8** [[ARGV:%.*]], i8*** [[ARGV_ADDR]],
+// CHECK: [[TMP1:%.*]] = load i32, i32* [[ARGC_ADDR]],
+// CHECK: [[ADD:%.*]] = add nsw i32 [[TMP1]], 100
+// CHECK: [[TMP2:%.*]] = zext i32 [[ADD]] to i64
+// CHECK: [[VLA:%.+]] = alloca float, i64 %
+
+// CHECK: call void @__kmpc_taskgroup(%ident_t*
+// CHECK-DAG: [[TMP21:%.*]] = bitcast float* [[SUM]] to i8*
+// CHECK-DAG: store i8* [[TMP21]], i8** [[TMP20:%[^,]+]],
+// CHECK-DAG: [[TMP20]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T:%.+]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP22]],
+// CHECK-DAG: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT1:@.+]] to i8*), i8** [[TMP23]],
+// CHECK-DAG: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP24]],
+// CHECK-DAG: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB1:@.+]] to i8*), i8** [[TMP25]],
+// CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 5
+// CHECK-DAG: [[TMP27:%.*]] = bitcast i32* [[TMP26]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP27]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], [100 x %struct.S]* [[C]], i64 0, i64 0
+// CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, %
+// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], [100 x %struct.S]* [[C]], i64 0, i64 [[LB_ADD_LEN]]
+// CHECK-DAG: [[TMP31:%.*]] = bitcast %struct.S* [[ARRAYIDX5]] to i8*
+// CHECK-DAG: store i8* [[TMP31]], i8** [[TMP28:%[^,]+]],
+// CHECK-DAG: [[TMP28]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP32:%.*]] = ptrtoint %struct.S* [[ARRAYIDX6]] to i64
+// CHECK-DAG: [[TMP33:%.*]] = ptrtoint %struct.S* [[ARRAYIDX5]] to i64
+// CHECK-DAG: [[TMP34:%.*]] = sub i64 [[TMP32]], [[TMP33]]
+// CHECK-DAG: [[TMP35:%.*]] = sdiv exact i64 [[TMP34]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK-DAG: [[TMP36:%.*]] = add nuw i64 [[TMP35]], 1
+// CHECK-DAG: [[TMP37:%.*]] = mul nuw i64 [[TMP36]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK-DAG: store i64 [[TMP37]], i64* [[TMP38:%[^,]+]],
+// CHECK-DAG: [[TMP38]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 1
+// CHECK-DAG: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT2:@.+]] to i8*), i8** [[TMP39]],
+// CHECK-DAG: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 3
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_FINI2:@.+]] to i8*), i8** [[TMP40]],
+// CHECK-DAG: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB2:@.+]] to i8*), i8** [[TMP41]],
+// CHECK-DAG: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 5
+// CHECK-DAG: store i32 1, i32* [[TMP42]],
+// CHECK-DAG: [[TMP44:%.*]] = load float*, float** [[D]],
+// CHECK-DAG: [[TMP45:%.*]] = bitcast float* [[TMP44]] to i8*
+// CHECK-DAG: store i8* [[TMP45]], i8** [[TMP43:%[^,]+]],
+// CHECK-DAG: [[TMP43]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP46]],
+// CHECK-DAG: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT3:@.+]] to i8*), i8** [[TMP47]],
+// CHECK-DAG: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP48]],
+// CHECK-DAG: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB3:@.+]] to i8*), i8** [[TMP49]],
+// CHECK-DAG: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 5
+// CHECK-DAG: [[TMP51:%.*]] = bitcast i32* [[TMP50]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP51]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP53:%.*]] = bitcast float* [[VLA]] to i8*
+// CHECK-DAG: store i8* [[TMP53]], i8** [[TMP52:%[^,]+]],
+// CHECK-DAG: [[TMP52]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP54:%.*]] = mul nuw i64 [[TMP2]], 4
+// CHECK-DAG: [[TMP55:%.*]] = udiv exact i64 [[TMP54]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK-DAG: store i64 [[TMP54]], i64* [[TMP56:%[^,]+]],
+// CHECK-DAG: [[TMP56]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 1
+// CHECK-DAG: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT4:@.+]] to i8*), i8** [[TMP57]],
+// CHECK-DAG: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP58]],
+// CHECK-DAG: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB4:@.+]] to i8*), i8** [[TMP59]],
+// CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 5
+// CHECK-DAG: store i32 1, i32* [[TMP60]],
+// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK: [[TMP61:%.*]] = bitcast [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]] to i8*
+// CHECK: [[TMP62:%.*]] = call i8* @__kmpc_task_reduction_init(i32 [[TMP0]], i32 4, i8* [[TMP61]])
+// CHECK: [[TMP63:%.*]] = load i32, i32* [[N]],
+// CHECK: store i32 [[TMP63]], i32* [[DOTCAPTURE_EXPR_]],
+// CHECK: [[TMP64:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]],
+// CHECK: [[SUB:%.*]] = sub nsw i32 [[TMP64]], 0
+// CHECK: [[SUB10:%.*]] = sub nsw i32 [[SUB]], 1
+// CHECK: [[ADD11:%.*]] = add nsw i32 [[SUB10]], 1
+// CHECK: [[DIV:%.*]] = sdiv i32 [[ADD11]], 1
+// CHECK: [[SUB12:%.*]] = sub nsw i32 [[DIV]], 1
+// CHECK: store i32 [[SUB12]], i32* [[DOTCAPTURE_EXPR_9]],
+// CHECK: [[TMP65:%.*]] = call i8* @__kmpc_omp_task_alloc(%ident_t* %{{.+}}, i32 [[TMP0]], i32 1, i64 888, i64 72, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* @{{.+}} to i32 (i32, i8*)*))
+// CHECK: call void @__kmpc_taskloop(%ident_t* %{{.+}}, i32 [[TMP0]], i8* [[TMP65]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+// CHECK: call void @__kmpc_end_taskgroup(%ident_t*
+
+// CHECK: ret i32
+
+// CHECK: define internal void [[RED_INIT1]](i8*)
+// CHECK: store float 0.000000e+00, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB1]](i8*, i8*)
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_INIT2]](i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_FINI2]](i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: call void @
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB2]](i8*, i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_INIT3]](i8*)
+// CHECK: store float 0.000000e+00, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB3]](i8*, i8*)
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_INIT4]](i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: store float 0.000000e+00, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB4]](i8*, i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
diff --git a/test/OpenMP/taskloop_simd_codegen.cpp b/test/OpenMP/taskloop_simd_codegen.cpp
index 48c6f479e9fa..f787689688e3 100644
--- a/test/OpenMP/taskloop_simd_codegen.cpp
+++ b/test/OpenMP/taskloop_simd_codegen.cpp
@@ -9,7 +9,7 @@
int main(int argc, char **argv) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
// CHECK: call void @__kmpc_taskgroup(%ident_t* [[DEFLOC]], i32 [[GTID]])
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 33, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK1:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
@@ -24,7 +24,7 @@ int main(int argc, char **argv) {
#pragma omp taskloop simd priority(argc)
for (int i = 0; i < 10; ++i)
;
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK2:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
@@ -40,7 +40,7 @@ int main(int argc, char **argv) {
for (int i = 0; i < 10; ++i)
;
// CHECK: call void @__kmpc_taskgroup(%ident_t* [[DEFLOC]], i32 [[GTID]])
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 24, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK3:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[IF:%.+]] = icmp ne i32 %{{.+}}, 0
@@ -146,7 +146,7 @@ struct S {
int a;
S(int c) {
// CHECK: [[GTID:%.+]] = call i32 @__kmpc_global_thread_num(%ident_t* [[DEFLOC:@.+]])
-// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 72, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*))
+// CHECK: [[TASKV:%.+]] = call i8* @__kmpc_omp_task_alloc(%ident_t* [[DEFLOC]], i32 [[GTID]], i32 1, i64 80, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, [[TDP_TY:%.+]]*)* [[TASK4:@.+]] to i32 (i32, i8*)*))
// CHECK: [[TASK:%.+]] = bitcast i8* [[TASKV]] to [[TDP_TY]]*
// CHECK: [[TASK_DATA:%.+]] = getelementptr inbounds [[TDP_TY]], [[TDP_TY]]* [[TASK]], i32 0, i32 0
// CHECK: [[DOWN:%.+]] = getelementptr inbounds [[TD_TY:%.+]], [[TD_TY]]* [[TASK_DATA]], i32 0, i32 5
diff --git a/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp b/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp
index 230ef980e64d..9e268d8a1739 100644
--- a/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp
+++ b/test/OpenMP/taskloop_simd_firstprivate_codegen.cpp
@@ -23,7 +23,7 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32, i8* }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type {{.*}}{ [2 x i32]*, i32, {{.*}}[2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}
@@ -57,7 +57,7 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// LAMBDA: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
// LAMBDA: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
@@ -101,7 +101,7 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// BLOCKS: [[G_PRIVATE_ADDR:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* [[PRIVATES]], i{{.+}} 0, i{{.+}} 0
// BLOCKS: [[G_ADDR_REF:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 0
@@ -190,7 +190,7 @@ int main() {
// [[KMP_TASK_T]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 120, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// Fill kmp_task_t->shareds by copying from original capture argument.
diff --git a/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp b/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp
index 41f04f9bdb3c..8d5ebb216808 100644
--- a/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp
+++ b/test/OpenMP/taskloop_simd_lastprivate_codegen.cpp
@@ -23,7 +23,7 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32, i8* }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { [2 x i32]*, i32*, [2 x [[S_DOUBLE_TY]]]*, [[S_DOUBLE_TY]]*, i{{[0-9]+}}* }
@@ -57,7 +57,7 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
@@ -98,7 +98,7 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 16, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* bitcast (void ([[KMP_TASK_MAIN_TY:%[^*]+]]*, [[KMP_TASK_MAIN_TY]]*, i32)* [[MAIN_DUP:@.+]] to i8*))
// BLOCKS: ret
@@ -182,7 +182,7 @@ int main() {
// [[KMP_TASK_T]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 120, i64 40, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// Fill kmp_task_t->shareds by copying from original capture argument.
diff --git a/test/OpenMP/taskloop_simd_private_codegen.cpp b/test/OpenMP/taskloop_simd_private_codegen.cpp
index 493137ade65f..3833b5ea9fb3 100644
--- a/test/OpenMP/taskloop_simd_private_codegen.cpp
+++ b/test/OpenMP/taskloop_simd_private_codegen.cpp
@@ -23,7 +23,7 @@ struct S {
volatile double g;
-// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32 }
+// CHECK-DAG: [[KMP_TASK_T_TY:%.+]] = type { i8*, i32 (i32, i8*)*, i32, %union{{.+}}, %union{{.+}}, i64, i64, i64, i32, i8* }
// CHECK-DAG: [[S_DOUBLE_TY:%.+]] = type { double }
// CHECK-DAG: [[CAP_MAIN_TY:%.+]] = type { i8 }
// CHECK-DAG: [[PRIVATES_MAIN_TY:%.+]] = type {{.?}}{ [2 x [[S_DOUBLE_TY]]], [[S_DOUBLE_TY]], i32, [2 x i32]
@@ -55,7 +55,7 @@ int main() {
// LAMBDA: call{{( x86_thiscallcc)?}} void [[OUTER_LAMBDA:@.+]](
[&]() {
// LAMBDA: define{{.*}} internal{{.*}} void [[OUTER_LAMBDA]](
- // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // LAMBDA: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// LAMBDA: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// LAMBDA: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
// LAMBDA: ret
@@ -91,7 +91,7 @@ int main() {
// BLOCKS: call void {{%.+}}(i8
^{
// BLOCKS: define{{.*}} internal{{.*}} void {{.+}}(i8*
- // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 88, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+ // BLOCKS: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc(%{{[^ ]+}} @{{[^,]+}}, i32 %{{[^,]+}}, i32 1, i64 96, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, %{{[^*]+}}*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// BLOCKS: [[PRIVATES:%.+]] = getelementptr inbounds %{{.+}}, %{{.+}}* %{{.+}}, i{{.+}} 0, i{{.+}} 1
// BLOCKS: call void @__kmpc_taskloop(%{{.+}}* @{{.+}}, i32 %{{.+}}, i8* [[RES]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
// BLOCKS: ret
@@ -157,7 +157,7 @@ int main() {
// [[KMP_TASK_T_TY]] task_data;
// [[KMP_TASK_MAIN_TY]] privates;
// };
-// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 112, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
+// CHECK: [[RES:%.+]] = call i8* @__kmpc_omp_task_alloc([[LOC]], i32 [[GTID]], i32 9, i64 120, i64 1, i32 (i32, i8*)* bitcast (i32 (i32, [[KMP_TASK_MAIN_TY]]*)* [[TASK_ENTRY:@[^ ]+]] to i32 (i32, i8*)*))
// CHECK: [[RES_KMP_TASK:%.+]] = bitcast i8* [[RES]] to [[KMP_TASK_MAIN_TY]]*
// CHECK: [[TASK:%.+]] = getelementptr inbounds [[KMP_TASK_MAIN_TY]], [[KMP_TASK_MAIN_TY]]* [[RES_KMP_TASK]], i{{[0-9]+}} 0, i{{[0-9]+}} 0
diff --git a/test/OpenMP/taskloop_simd_reduction_codegen.cpp b/test/OpenMP/taskloop_simd_reduction_codegen.cpp
new file mode 100644
index 000000000000..b96c8d50a3ff
--- /dev/null
+++ b/test/OpenMP/taskloop_simd_reduction_codegen.cpp
@@ -0,0 +1,197 @@
+// RUN: %clang_cc1 -fopenmp -x c++ %s -verify -debug-info-kind=limited -emit-llvm -o - -triple powerpc64le-unknown-linux-gnu | FileCheck %s
+// expected-no-diagnostics
+
+struct S {
+ float a;
+ S() : a(0.0f) {}
+ ~S() {}
+};
+
+#pragma omp declare reduction(+:S:omp_out.a += omp_in.a) initializer(omp_priv = omp_orig)
+
+float g;
+
+int a;
+#pragma omp threadprivate(a)
+int main (int argc, char *argv[])
+{
+int i, n;
+float a[100], b[100], sum, e[argc + 100];
+S c[100];
+float &d = g;
+
+/* Some initializations */
+n = 100;
+for (i=0; i < n; i++)
+ a[i] = b[i] = i * 1.0;
+sum = 0.0;
+
+#pragma omp taskloop simd reduction(+:sum, c[:n], d, e)
+ for (i=0; i < n; i++) {
+ sum = sum + (a[i] * b[i]);
+ c[i].a = i*i;
+ d += i*i;
+ e[i] = i;
+ }
+
+}
+
+// CHECK-LABEL: @main(
+// CHECK: [[RETVAL:%.*]] = alloca i32,
+// CHECK: [[ARGC_ADDR:%.*]] = alloca i32,
+// CHECK: [[ARGV_ADDR:%.*]] = alloca i8**,
+// CHECK: [[I:%.*]] = alloca i32,
+// CHECK: [[N:%.*]] = alloca i32,
+// CHECK: [[A:%.*]] = alloca [100 x float],
+// CHECK: [[B:%.*]] = alloca [100 x float],
+// CHECK: [[SUM:%.*]] = alloca float,
+// CHECK: [[SAVED_STACK:%.*]] = alloca i8*,
+// CHECK: [[C:%.*]] = alloca [100 x %struct.S],
+// CHECK: [[D:%.*]] = alloca float*,
+// CHECK: [[AGG_CAPTURED:%.*]] = alloca [[STRUCT_ANON:%.*]],
+// CHECK: [[TMP0:%.*]] = call i32 @__kmpc_global_thread_num(%ident_t*
+// CHECK: [[DOTRD_INPUT_:%.*]] = alloca [4 x %struct.kmp_task_red_input_t],
+// CHECK: [[DOTCAPTURE_EXPR_:%.*]] = alloca i32,
+// CHECK: [[DOTCAPTURE_EXPR_9:%.*]] = alloca i32,
+// CHECK: store i32 0, i32* [[RETVAL]],
+// CHECK: store i32 [[ARGC:%.*]], i32* [[ARGC_ADDR]],
+// CHECK: store i8** [[ARGV:%.*]], i8*** [[ARGV_ADDR]],
+// CHECK: [[TMP1:%.*]] = load i32, i32* [[ARGC_ADDR]],
+// CHECK: [[ADD:%.*]] = add nsw i32 [[TMP1]], 100
+// CHECK: [[TMP2:%.*]] = zext i32 [[ADD]] to i64
+// CHECK: [[VLA:%.+]] = alloca float, i64 %
+
+// CHECK: call void @__kmpc_taskgroup(%ident_t*
+// CHECK-DAG: [[TMP21:%.*]] = bitcast float* [[SUM]] to i8*
+// CHECK-DAG: store i8* [[TMP21]], i8** [[TMP20:%[^,]+]],
+// CHECK-DAG: [[TMP20]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T:%.+]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP22:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP22]],
+// CHECK-DAG: [[TMP23:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT1:@.+]] to i8*), i8** [[TMP23]],
+// CHECK-DAG: [[TMP24:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP24]],
+// CHECK-DAG: [[TMP25:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB1:@.+]] to i8*), i8** [[TMP25]],
+// CHECK-DAG: [[TMP26:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_]], i32 0, i32 5
+// CHECK-DAG: [[TMP27:%.*]] = bitcast i32* [[TMP26]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP27]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[ARRAYIDX5:%.*]] = getelementptr inbounds [100 x %struct.S], [100 x %struct.S]* [[C]], i64 0, i64 0
+// CHECK-DAG: [[LB_ADD_LEN:%.*]] = add nsw i64 -1, %
+// CHECK-DAG: [[ARRAYIDX6:%.*]] = getelementptr inbounds [100 x %struct.S], [100 x %struct.S]* [[C]], i64 0, i64 [[LB_ADD_LEN]]
+// CHECK-DAG: [[TMP31:%.*]] = bitcast %struct.S* [[ARRAYIDX5]] to i8*
+// CHECK-DAG: store i8* [[TMP31]], i8** [[TMP28:%[^,]+]],
+// CHECK-DAG: [[TMP28]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP32:%.*]] = ptrtoint %struct.S* [[ARRAYIDX6]] to i64
+// CHECK-DAG: [[TMP33:%.*]] = ptrtoint %struct.S* [[ARRAYIDX5]] to i64
+// CHECK-DAG: [[TMP34:%.*]] = sub i64 [[TMP32]], [[TMP33]]
+// CHECK-DAG: [[TMP35:%.*]] = sdiv exact i64 [[TMP34]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK-DAG: [[TMP36:%.*]] = add nuw i64 [[TMP35]], 1
+// CHECK-DAG: [[TMP37:%.*]] = mul nuw i64 [[TMP36]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK-DAG: store i64 [[TMP37]], i64* [[TMP38:%[^,]+]],
+// CHECK-DAG: [[TMP38]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 1
+// CHECK-DAG: [[TMP39:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT2:@.+]] to i8*), i8** [[TMP39]],
+// CHECK-DAG: [[TMP40:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 3
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_FINI2:@.+]] to i8*), i8** [[TMP40]],
+// CHECK-DAG: [[TMP41:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB2:@.+]] to i8*), i8** [[TMP41]],
+// CHECK-DAG: [[TMP42:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_4]], i32 0, i32 5
+// CHECK-DAG: store i32 1, i32* [[TMP42]],
+// CHECK-DAG: [[TMP44:%.*]] = load float*, float** [[D]],
+// CHECK-DAG: [[TMP45:%.*]] = bitcast float* [[TMP44]] to i8*
+// CHECK-DAG: store i8* [[TMP45]], i8** [[TMP43:%[^,]+]],
+// CHECK-DAG: [[TMP43]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP46:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 1
+// CHECK-DAG: store i64 4, i64* [[TMP46]],
+// CHECK-DAG: [[TMP47:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT3:@.+]] to i8*), i8** [[TMP47]],
+// CHECK-DAG: [[TMP48:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP48]],
+// CHECK-DAG: [[TMP49:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB3:@.+]] to i8*), i8** [[TMP49]],
+// CHECK-DAG: [[TMP50:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_7]], i32 0, i32 5
+// CHECK-DAG: [[TMP51:%.*]] = bitcast i32* [[TMP50]] to i8*
+// CHECK-DAG: call void @llvm.memset.p0i8.i64(i8* [[TMP51]], i8 0, i64 4, i32 8, i1 false)
+// CHECK-DAG: [[TMP53:%.*]] = bitcast float* [[VLA]] to i8*
+// CHECK-DAG: store i8* [[TMP53]], i8** [[TMP52:%[^,]+]],
+// CHECK-DAG: [[TMP52]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8:%.+]], i32 0, i32 0
+// CHECK-DAG: [[TMP54:%.*]] = mul nuw i64 [[TMP2]], 4
+// CHECK-DAG: [[TMP55:%.*]] = udiv exact i64 [[TMP54]], ptrtoint (float* getelementptr (float, float* null, i32 1) to i64)
+// CHECK-DAG: store i64 [[TMP54]], i64* [[TMP56:%[^,]+]],
+// CHECK-DAG: [[TMP56]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 1
+// CHECK-DAG: [[TMP57:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 2
+// CHECK-DAG: store i8* bitcast (void (i8*)* [[RED_INIT4:@.+]] to i8*), i8** [[TMP57]],
+// CHECK-DAG: [[TMP58:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 3
+// CHECK-DAG: store i8* null, i8** [[TMP58]],
+// CHECK-DAG: [[TMP59:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 4
+// CHECK-DAG: store i8* bitcast (void (i8*, i8*)* [[RED_COMB4:@.+]] to i8*), i8** [[TMP59]],
+// CHECK-DAG: [[TMP60:%.*]] = getelementptr inbounds [[STRUCT_KMP_TASK_RED_INPUT_T]], %struct.kmp_task_red_input_t* [[DOTRD_INPUT_GEP_8]], i32 0, i32 5
+// CHECK-DAG: store i32 1, i32* [[TMP60]],
+// CHECK-DAG: [[DOTRD_INPUT_GEP_]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK-DAG: [[DOTRD_INPUT_GEP_4]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK-DAG: [[DOTRD_INPUT_GEP_7]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK-DAG: [[DOTRD_INPUT_GEP_8]] = getelementptr inbounds [4 x %struct.kmp_task_red_input_t], [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]], i64 0, i64
+// CHECK: [[TMP61:%.*]] = bitcast [4 x %struct.kmp_task_red_input_t]* [[DOTRD_INPUT_]] to i8*
+// CHECK: [[TMP62:%.*]] = call i8* @__kmpc_task_reduction_init(i32 [[TMP0]], i32 4, i8* [[TMP61]])
+// CHECK: [[TMP63:%.*]] = load i32, i32* [[N]],
+// CHECK: store i32 [[TMP63]], i32* [[DOTCAPTURE_EXPR_]],
+// CHECK: [[TMP64:%.*]] = load i32, i32* [[DOTCAPTURE_EXPR_]],
+// CHECK: [[SUB:%.*]] = sub nsw i32 [[TMP64]], 0
+// CHECK: [[SUB10:%.*]] = sub nsw i32 [[SUB]], 1
+// CHECK: [[ADD11:%.*]] = add nsw i32 [[SUB10]], 1
+// CHECK: [[DIV:%.*]] = sdiv i32 [[ADD11]], 1
+// CHECK: [[SUB12:%.*]] = sub nsw i32 [[DIV]], 1
+// CHECK: store i32 [[SUB12]], i32* [[DOTCAPTURE_EXPR_9]],
+// CHECK: [[TMP65:%.*]] = call i8* @__kmpc_omp_task_alloc(%ident_t* %{{.+}}, i32 [[TMP0]], i32 1, i64 888, i64 72, i32 (i32, i8*)* bitcast (i32 (i32, %struct.kmp_task_t_with_privates*)* @{{.+}} to i32 (i32, i8*)*))
+// CHECK: call void @__kmpc_taskloop(%ident_t* %{{.+}}, i32 [[TMP0]], i8* [[TMP65]], i32 1, i64* %{{.+}}, i64* %{{.+}}, i64 %{{.+}}, i32 0, i32 0, i64 0, i8* null)
+// CHECK: call void @__kmpc_end_taskgroup(%ident_t*
+
+// CHECK: ret i32
+
+// CHECK: define internal void [[RED_INIT1]](i8*)
+// CHECK: store float 0.000000e+00, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB1]](i8*, i8*)
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_INIT2]](i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: call void @llvm.memcpy.p0i8.p0i8.i64(
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_FINI2]](i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: call void @
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB2]](i8*, i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_INIT3]](i8*)
+// CHECK: store float 0.000000e+00, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB3]](i8*, i8*)
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_INIT4]](i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: store float 0.000000e+00, float* %
+// CHECK: ret void
+
+// CHECK: define internal void [[RED_COMB4]](i8*, i8*)
+// CHECK: call i8* @__kmpc_threadprivate_cached(
+// CHECK: fadd float %
+// CHECK: store float %{{.+}}, float* %
+// CHECK: ret void
+
diff --git a/test/Parser/MicrosoftExtensions.cpp b/test/Parser/MicrosoftExtensions.cpp
index 74f4bb3268de..c796eded1f0d 100644
--- a/test/Parser/MicrosoftExtensions.cpp
+++ b/test/Parser/MicrosoftExtensions.cpp
@@ -261,9 +261,7 @@ int __identifier(else} = __identifier(for); // expected-error {{missing ')' afte
#define identifier_weird(x) __identifier(x
int k = identifier_weird(if)); // expected-error {{use of undeclared identifier 'if'}}
-// This is a bit weird, but the alternative tokens aren't keywords, and this
-// behavior matches MSVC. FIXME: Consider supporting this anyway.
-extern int __identifier(and) r; // expected-error {{cannot convert '&&' token to an identifier}}
+extern int __identifier(and);
void f() {
__identifier(() // expected-error {{cannot convert '(' token to an identifier}}
diff --git a/test/Preprocessor/aarch64-target-features.c b/test/Preprocessor/aarch64-target-features.c
index 721246aff3a7..836d29866efe 100644
--- a/test/Preprocessor/aarch64-target-features.c
+++ b/test/Preprocessor/aarch64-target-features.c
@@ -37,6 +37,7 @@
// CHECK-NOT: __ARM_PCS_VFP 1
// CHECK-NOT: __ARM_SIZEOF_MINIMAL_ENUM 1
// CHECK-NOT: __ARM_SIZEOF_WCHAR_T 2
+// CHECK-NOT: __ARM_FEATURE_SVE
// RUN: %clang -target aarch64_be-eabi -x c -E -dM %s -o - | FileCheck %s -check-prefix CHECK-BIGENDIAN
// CHECK-BIGENDIAN: __ARM_BIG_ENDIAN 1
@@ -84,6 +85,10 @@
// CHECK-GENERIC: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon"
// RUN: %clang -target aarch64 -mtune=cyclone -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MTUNE-CYCLONE %s
+
+// RUN: %clang -target aarch64-none-linux-gnu -march=armv8-a+sve -x c -E -dM %s -o - | FileCheck --check-prefix=CHECK-SVE %s
+// CHECK-SVE: __ARM_FEATURE_SVE 1
+
// ================== Check whether -mtune accepts mixed-case features.
// RUN: %clang -target aarch64 -mtune=CYCLONE -### -c %s 2>&1 | FileCheck -check-prefix=CHECK-MTUNE-CYCLONE %s
// CHECK-MTUNE-CYCLONE: "-cc1"{{.*}} "-triple" "aarch64{{.*}}" "-target-feature" "+neon" "-target-feature" "+zcm" "-target-feature" "+zcz"
diff --git a/test/Preprocessor/cxx_oper_keyword.cpp b/test/Preprocessor/cxx_oper_keyword.cpp
index 89a094d073ca..a66e8904973f 100644
--- a/test/Preprocessor/cxx_oper_keyword.cpp
+++ b/test/Preprocessor/cxx_oper_keyword.cpp
@@ -29,3 +29,15 @@
#ifdef and
#warning and is defined
#endif
+
+#ifdef OPERATOR_NAMES
+//expected-error@+2 {{invalid token at start of a preprocessor expression}}
+#endif
+#if or
+#endif
+
+#ifdef OPERATOR_NAMES
+//expected-error@+2 {{invalid token at start of a preprocessor expression}}
+#endif
+#if and_eq
+#endif
diff --git a/test/Preprocessor/init.c b/test/Preprocessor/init.c
index 0ee7edecb3c4..5a77d06d2403 100644
--- a/test/Preprocessor/init.c
+++ b/test/Preprocessor/init.c
@@ -9,6 +9,15 @@
// BLOCKS:#define __block __attribute__((__blocks__(byref)))
//
//
+// RUN: %clang_cc1 -x c++ -std=c++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX2A %s
+//
+// CXX2A:#define __GNUG__ {{.*}}
+// CXX2A:#define __GXX_EXPERIMENTAL_CXX0X__ 1
+// CXX2A:#define __GXX_RTTI 1
+// CXX2A:#define __GXX_WEAK__ 1
+// CXX2A:#define __cplusplus 201707L
+// CXX2A:#define __private_extern__ extern
+//
// RUN: %clang_cc1 -x c++ -std=c++1z -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix CXX1Z %s
//
// CXX1Z:#define __GNUG__ {{.*}}
@@ -110,6 +119,13 @@
// RUN: %clang_cc1 -ffreestanding -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix FREESTANDING %s
// FREESTANDING:#define __STDC_HOSTED__ 0
//
+// RUN: %clang_cc1 -x c++ -std=gnu++2a -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX2A %s
+//
+// GXX2A:#define __GNUG__ {{.*}}
+// GXX2A:#define __GXX_WEAK__ 1
+// GXX2A:#define __cplusplus 201707L
+// GXX2A:#define __private_extern__ extern
+//
//
// RUN: %clang_cc1 -x c++ -std=gnu++1z -E -dM < /dev/null | FileCheck -match-full-lines -check-prefix GXX1Z %s
//
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index da4c5d03574b..8976f9e8fb27 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -2237,6 +2237,25 @@
// CHECK_SYSTEMZ_ARCH11: #define __s390x__ 1
// CHECK_SYSTEMZ_ARCH11: #define __zarch__ 1
//
+// RUN: %clang -march=arch12 -E -dM %s -o - 2>&1 \
+// RUN: -target s390x-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH12
+// RUN: %clang -march=z14 -E -dM %s -o - 2>&1 \
+// RUN: -target s390x-unknown-linux \
+// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ARCH12
+//
+// CHECK_SYSTEMZ_ARCH12: #define __ARCH__ 12
+// CHECK_SYSTEMZ_ARCH12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_1 1
+// CHECK_SYSTEMZ_ARCH12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_2 1
+// CHECK_SYSTEMZ_ARCH12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_4 1
+// CHECK_SYSTEMZ_ARCH12: #define __GCC_HAVE_SYNC_COMPARE_AND_SWAP_8 1
+// CHECK_SYSTEMZ_ARCH12: #define __HTM__ 1
+// CHECK_SYSTEMZ_ARCH12: #define __LONG_DOUBLE_128__ 1
+// CHECK_SYSTEMZ_ARCH12: #define __VX__ 1
+// CHECK_SYSTEMZ_ARCH12: #define __s390__ 1
+// CHECK_SYSTEMZ_ARCH12: #define __s390x__ 1
+// CHECK_SYSTEMZ_ARCH12: #define __zarch__ 1
+//
// RUN: %clang -mhtm -E -dM %s -o - 2>&1 \
// RUN: -target s390x-unknown-linux \
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_HTM
@@ -2256,7 +2275,7 @@
// RUN: -target s390x-unknown-linux \
// RUN: | FileCheck -match-full-lines %s -check-prefix=CHECK_SYSTEMZ_ZVECTOR
//
-// CHECK_SYSTEMZ_ZVECTOR: #define __VEC__ 10301
+// CHECK_SYSTEMZ_ZVECTOR: #define __VEC__ 10302
// Begin amdgcn tests ----------------
//
diff --git a/test/Sema/tls.c b/test/Sema/tls.c
index a3fdc8ea5132..6d10363305ff 100644
--- a/test/Sema/tls.c
+++ b/test/Sema/tls.c
@@ -12,9 +12,9 @@
// RUN: %clang_cc1 -triple x86_64-pc-win32 -fsyntax-only %s
// RUN: %clang_cc1 -triple i386-pc-win32 -fsyntax-only %s
-// OpenBSD does not suppport TLS.
-// RUN: not %clang_cc1 -triple x86_64-pc-openbsd -fsyntax-only %s
-// RUN: not %clang_cc1 -triple i386-pc-openbsd -fsyntax-only %s
+// OpenBSD suppports TLS.
+// RUN: %clang_cc1 -triple x86_64-pc-openbsd -fsyntax-only %s
+// RUN: %clang_cc1 -triple i386-pc-openbsd -fsyntax-only %s
// Haiku does not suppport TLS.
// RUN: not %clang_cc1 -triple i586-pc-haiku -fsyntax-only %s
diff --git a/test/Sema/varargs-aarch64.c b/test/Sema/varargs-aarch64.c
new file mode 100644
index 000000000000..145c82105610
--- /dev/null
+++ b/test/Sema/varargs-aarch64.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -fsyntax-only -verify %s -triple aarch64-linux-gnu
+
+void f1(int a, ...) {
+ __builtin_ms_va_list ap;
+ __builtin_ms_va_start(ap, a); // expected-error {{'__builtin_ms_va_start' used in System V ABI function}}
+}
+
+void __attribute__((ms_abi)) f2(int a, ...) {
+ __builtin_va_list ap;
+ __builtin_va_start(ap, a); // expected-error {{'va_start' used in Win64 ABI function}}
+}
diff --git a/test/Sema/varargs-x86-32.c b/test/Sema/varargs-x86-32.c
index 6f57022ffcbf..0359e65892f0 100644
--- a/test/Sema/varargs-x86-32.c
+++ b/test/Sema/varargs-x86-32.c
@@ -1,5 +1,5 @@
// RUN: %clang_cc1 -fsyntax-only -verify %s -triple i386-apple-darwin9
void foo(int a, ...) {
- __builtin_ms_va_start((void *)0, a); // expected-error {{this builtin is only available on x86-64 targets}}
+ __builtin_ms_va_start((void *)0, a); // expected-error {{this builtin is only available on x86-64 and aarch64 targets}}
}
diff --git a/test/Sema/zvector2.c b/test/Sema/zvector2.c
new file mode 100644
index 000000000000..0adc0315f0b8
--- /dev/null
+++ b/test/Sema/zvector2.c
@@ -0,0 +1,211 @@
+// RUN: %clang_cc1 -triple s390x-linux-gnu -fzvector -target-cpu z14 \
+// RUN: -fno-lax-vector-conversions -W -Wall -Wconversion \
+// RUN: -Werror -fsyntax-only -verify %s
+
+vector signed char sc, sc2;
+vector unsigned char uc, uc2;
+vector bool char bc, bc2;
+
+vector signed short ss, ss2;
+vector unsigned short us, us2;
+vector bool short bs, bs2;
+
+vector signed int si, si2;
+vector unsigned int ui, ui2;
+vector bool int bi, bi2;
+
+vector signed long long sl, sl2;
+vector unsigned long long ul, ul2;
+vector bool long long bl, bl2;
+
+vector double fd, fd2;
+
+vector float ff, ff2;
+
+void foo(void)
+{
+ // -------------------------------------------------------------------------
+ // Test assignment.
+ // -------------------------------------------------------------------------
+
+ ff = ff2;
+
+ sc = ff2; // expected-error {{incompatible type}}
+ ff = sc2; // expected-error {{incompatible type}}
+
+ uc = ff2; // expected-error {{incompatible type}}
+ ff = uc2; // expected-error {{incompatible type}}
+
+ bc = ff2; // expected-error {{incompatible type}}
+ ff = bc2; // expected-error {{incompatible type}}
+
+ fd = ff2; // expected-error {{incompatible type}}
+ ff = fd2; // expected-error {{incompatible type}}
+
+ // -------------------------------------------------------------------------
+ // Test casts to same element width.
+ // -------------------------------------------------------------------------
+
+ ui = (vector unsigned int)ff2;
+ ff = (vector float)si2;
+
+ // -------------------------------------------------------------------------
+ // Test casts to different element width.
+ // -------------------------------------------------------------------------
+
+ uc = (vector unsigned char)ff2;
+ us = (vector unsigned short)ff2;
+ ul = (vector unsigned long long)ff2;
+
+ ff = (vector float)sc2;
+ ff = (vector float)ss2;
+ ff = (vector float)sl2;
+
+ // -------------------------------------------------------------------------
+ // Test unary operators.
+ // -------------------------------------------------------------------------
+
+ ++ff2;
+ ff++;
+
+ --ff2;
+ ff--;
+
+ ff = +ff2;
+
+ ff = -ff2;
+
+ ff = ~ff2; // expected-error {{invalid argument}}
+
+ // -------------------------------------------------------------------------
+ // Test binary arithmetic operators.
+ // -------------------------------------------------------------------------
+
+ ff = ff + ff2;
+ ff = ff + ui2; // expected-error {{cannot convert}}
+ ff = si + ff2; // expected-error {{cannot convert}}
+ ff = fd + ff2; // expected-error {{cannot convert}}
+ ff += ff2;
+ ff += fd2; // expected-error {{cannot convert}}
+ sc += ff2; // expected-error {{cannot convert}}
+
+ ff = ff - ff2;
+ ff = ff - ui2; // expected-error {{cannot convert}}
+ ff = si - ff2; // expected-error {{cannot convert}}
+ ff = fd - ff2; // expected-error {{cannot convert}}
+ ff -= ff2;
+ ff -= fd2; // expected-error {{cannot convert}}
+ sc -= ff2; // expected-error {{cannot convert}}
+
+ ff = ff * ff2;
+ ff = ff * ui2; // expected-error {{cannot convert}}
+ ff = si * ff2; // expected-error {{cannot convert}}
+ ff = fd * ff2; // expected-error {{cannot convert}}
+ ff *= ff2;
+ ff *= fd2; // expected-error {{cannot convert}}
+ sc *= ff2; // expected-error {{cannot convert}}
+
+ ff = ff / ff2;
+ ff = ff / ui2; // expected-error {{cannot convert}}
+ ff = si / ff2; // expected-error {{cannot convert}}
+ ff = fd / ff2; // expected-error {{cannot convert}}
+ ff /= ff2;
+ ff /= fd2; // expected-error {{cannot convert}}
+ sc /= ff2; // expected-error {{cannot convert}}
+
+ ff = ff % ff2; // expected-error {{invalid operands}}
+ ff = ff % ui2; // expected-error {{invalid operands}}
+ ff = si % ff2; // expected-error {{invalid operands}}
+ ff = fd % ff2; // expected-error {{invalid operands}}
+ ff %= ff2; // expected-error {{invalid operands}}
+ ff %= fd2; // expected-error {{invalid operands}}
+ sc %= ff2; // expected-error {{invalid operands}}
+
+ // -------------------------------------------------------------------------
+ // Test bitwise binary operators.
+ // -------------------------------------------------------------------------
+
+ ff = ff & ff2; // expected-error {{invalid operands}}
+ ff = bi & ff2; // expected-error {{invalid operands}}
+ ff = fd & ff2; // expected-error {{invalid operands}}
+ ff = ff & bi2; // expected-error {{invalid operands}}
+ ff = ff & si2; // expected-error {{invalid operands}}
+ ff = ff & ui2; // expected-error {{invalid operands}}
+ sc &= ff2; // expected-error {{invalid operands}}
+ ff &= bc2; // expected-error {{invalid operands}}
+ ff &= fd2; // expected-error {{invalid operands}}
+
+ ff = ff | ff2; // expected-error {{invalid operands}}
+ ff = bi | ff2; // expected-error {{invalid operands}}
+ ff = fd | ff2; // expected-error {{invalid operands}}
+ ff = ff | bi2; // expected-error {{invalid operands}}
+ ff = ff | si2; // expected-error {{invalid operands}}
+ ff = ff | ui2; // expected-error {{invalid operands}}
+ sc |= ff2; // expected-error {{invalid operands}}
+ ff |= bc2; // expected-error {{invalid operands}}
+ ff |= fd2; // expected-error {{invalid operands}}
+
+ ff = ff ^ ff2; // expected-error {{invalid operands}}
+ ff = bi ^ ff2; // expected-error {{invalid operands}}
+ ff = fd ^ ff2; // expected-error {{invalid operands}}
+ ff = ff ^ bi2; // expected-error {{invalid operands}}
+ ff = ff ^ si2; // expected-error {{invalid operands}}
+ ff = ff ^ ui2; // expected-error {{invalid operands}}
+ sc ^= ff2; // expected-error {{invalid operands}}
+ ff ^= bc2; // expected-error {{invalid operands}}
+ ff ^= fd2; // expected-error {{invalid operands}}
+
+ // -------------------------------------------------------------------------
+ // Test shift operators.
+ // -------------------------------------------------------------------------
+
+ ff = ff << ff2; // expected-error {{integer is required}}
+ ff = ff << fd2; // expected-error {{integer is required}}
+ ff = ff << ui2; // expected-error {{integer is required}}
+ ff = sl << ff2; // expected-error {{integer is required}}
+ sc <<= ff2; // expected-error {{integer is required}}
+ ff <<= ff2; // expected-error {{integer is required}}
+ fd <<= ff2; // expected-error {{integer is required}}
+
+ ff = ff >> ff2; // expected-error {{integer is required}}
+ ff = ff >> fd2; // expected-error {{integer is required}}
+ ff = ff >> ui2; // expected-error {{integer is required}}
+ ff = sl >> ff2; // expected-error {{integer is required}}
+ sc >>= ff2; // expected-error {{integer is required}}
+ ff >>= ff2; // expected-error {{integer is required}}
+ fd >>= ff2; // expected-error {{integer is required}}
+
+ // -------------------------------------------------------------------------
+ // Test comparison operators.
+ // -------------------------------------------------------------------------
+
+ (void)(ff == ff2);
+ (void)(ff == fd2); // expected-error {{cannot convert}}
+ (void)(ff == ui2); // expected-error {{cannot convert}}
+ (void)(ui == ff2); // expected-error {{cannot convert}}
+
+ (void)(ff != ff2);
+ (void)(ff != fd2); // expected-error {{cannot convert}}
+ (void)(ff != ui2); // expected-error {{cannot convert}}
+ (void)(ui != ff2); // expected-error {{cannot convert}}
+
+ (void)(ff <= ff2);
+ (void)(ff <= fd2); // expected-error {{cannot convert}}
+ (void)(ff <= ui2); // expected-error {{cannot convert}}
+ (void)(ui <= ff2); // expected-error {{cannot convert}}
+
+ (void)(ff >= ff2);
+ (void)(ff >= fd2); // expected-error {{cannot convert}}
+ (void)(ff >= ui2); // expected-error {{cannot convert}}
+ (void)(ui >= ff2); // expected-error {{cannot convert}}
+
+ (void)(ff < ff2);
+ (void)(ff < fd2); // expected-error {{cannot convert}}
+ (void)(ff < ui2); // expected-error {{cannot convert}}
+ (void)(ui < ff2); // expected-error {{cannot convert}}
+
+ (void)(ff > ff2);
+ (void)(ff > fd2); // expected-error {{cannot convert}}
+ (void)(ff > ui2); // expected-error {{cannot convert}}
+ (void)(ui > ff2); // expected-error {{cannot convert}}
+}
diff --git a/test/SemaCXX/attr-x86-no_caller_saved_registers.cpp b/test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
index 48ccdec251af..ec69e986144f 100644
--- a/test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
+++ b/test/SemaCXX/attr-x86-no_caller_saved_registers.cpp
@@ -24,7 +24,7 @@ void foo6(){} // expected-note {{previous declaration is here}}
void __attribute__((no_caller_saved_registers)) foo6(); // expected-error {{function declared with 'no_caller_saved_registers' attribute was previously declared without the 'no_caller_saved_registers' attribute}}
int main(int argc, char **argv) {
- void (*fp)(int *) = foo; // expected-error {{cannot initialize a variable of type 'void (*)(int *)' with an lvalue of type 'void (int *)__attribute__((no_caller_saved_registers))'}}
+ void (*fp)(int *) = foo; // expected-error {{cannot initialize a variable of type 'void (*)(int *)' with an lvalue of type 'void (int *) __attribute__((no_caller_saved_registers))'}}
a::foo(&argc);
foo3 func = foo2;
func(&argc);
diff --git a/test/SemaCXX/cxx1z-noexcept-function-type.cpp b/test/SemaCXX/cxx1z-noexcept-function-type.cpp
index 524ea8e53c10..6578eb89b0ba 100644
--- a/test/SemaCXX/cxx1z-noexcept-function-type.cpp
+++ b/test/SemaCXX/cxx1z-noexcept-function-type.cpp
@@ -1,6 +1,7 @@
// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions %s
// RUN: %clang_cc1 -std=c++1z -verify -fexceptions -fcxx-exceptions %s -Wno-dynamic-exception-spec
// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-c++1z-compat-mangling -DNO_COMPAT_MANGLING %s
+// RUN: %clang_cc1 -std=c++14 -verify -fexceptions -fcxx-exceptions -Wno-noexcept-type -DNO_COMPAT_MANGLING %s
#if __cplusplus > 201402L
diff --git a/test/SemaObjC/arc-property-decl-attrs.m b/test/SemaObjC/arc-property-decl-attrs.m
index 6c96ba481c4a..ee48d310edc0 100644
--- a/test/SemaObjC/arc-property-decl-attrs.m
+++ b/test/SemaObjC/arc-property-decl-attrs.m
@@ -121,3 +121,107 @@ __attribute__((objc_root_class))
@implementation I2
@synthesize prop;
@end
+
+// rdar://31579994
+// Verify that the all of the property declarations in inherited protocols are
+// compatible when synthesing a property from a protocol.
+
+@protocol CopyVsAssign1
+@property (copy, nonatomic, readonly) id prop; // expected-error {{property with attribute 'copy' was selected for synthesis}}
+@end
+@protocol CopyVsAssign2
+@property (assign, nonatomic, readonly) id prop; // expected-note {{it could also be property without attribute 'copy' declared here}}
+@end
+
+@interface CopyVsAssign: Foo <CopyVsAssign1, CopyVsAssign2>
+@end
+@implementation CopyVsAssign
+@synthesize prop; // expected-note {{property synthesized here}}
+@end
+
+@protocol RetainVsNonRetain1
+@property (readonly) id prop; // expected-error {{property without attribute 'retain (or strong)' was selected for synthesis}}
+@end
+@protocol RetainVsNonRetain2
+@property (retain, readonly) id prop; // expected-note {{it could also be property with attribute 'retain (or strong)' declared here}}
+@end
+
+@interface RetainVsNonRetain: Foo <RetainVsNonRetain1, RetainVsNonRetain2>
+@end
+@implementation RetainVsNonRetain
+@synthesize prop; // expected-note {{property synthesized here}}
+@end
+
+@protocol AtomicVsNonatomic1
+@property (copy, nonatomic, readonly) id prop; // expected-error {{property without attribute 'atomic' was selected for synthesis}}
+@end
+@protocol AtomicVsNonatomic2
+@property (copy, atomic, readonly) id prop; // expected-note {{it could also be property with attribute 'atomic' declared here}}
+@end
+
+@interface AtomicVsNonAtomic: Foo <AtomicVsNonatomic1, AtomicVsNonatomic2>
+@end
+@implementation AtomicVsNonAtomic
+@synthesize prop; // expected-note {{property synthesized here}}
+@end
+
+@protocol Getter1
+@property (copy, readonly) id prop; // expected-error {{property with getter 'prop' was selected for synthesis}}
+@end
+@protocol Getter2
+@property (copy, getter=x, readonly) id prop; // expected-note {{it could also be property with getter 'x' declared here}}
+@end
+
+@interface GetterVsGetter: Foo <Getter1, Getter2>
+@end
+@implementation GetterVsGetter
+@synthesize prop; // expected-note {{property synthesized here}}
+@end
+
+@protocol Setter1
+@property (copy, readonly) id prop;
+@end
+@protocol Setter2
+@property (copy, setter=setp:, readwrite) id prop; // expected-error {{property with setter 'setp:' was selected for synthesis}}
+@end
+@protocol Setter3
+@property (copy, readwrite) id prop; // expected-note {{it could also be property with setter 'setProp:' declared here}}
+@end
+
+@interface SetterVsSetter: Foo <Setter1, Setter2, Setter3>
+@end
+@implementation SetterVsSetter
+@synthesize prop; // expected-note {{property synthesized here}}
+@end
+
+@protocol TypeVsAttribute1
+@property (assign, atomic, readonly) int prop; // expected-error {{property of type 'int' was selected for synthesis}}
+@end
+@protocol TypeVsAttribute2
+@property (assign, atomic, readonly) id prop; // expected-note {{it could also be property of type 'id' declared here}}
+@end
+@protocol TypeVsAttribute3
+@property (copy, readonly) id prop; // expected-note {{it could also be property with attribute 'copy' declared here}}
+@end
+
+@interface TypeVsAttribute: Foo <TypeVsAttribute1, TypeVsAttribute2, TypeVsAttribute3>
+@end
+@implementation TypeVsAttribute
+@synthesize prop; // expected-note {{property synthesized here}}
+@end
+
+@protocol TypeVsSetter1
+@property (assign, nonatomic, readonly) int prop; // expected-note {{it could also be property of type 'int' declared here}}
+@end
+@protocol TypeVsSetter2
+@property (assign, nonatomic, readonly) id prop; // ok
+@end
+@protocol TypeVsSetter3
+@property (assign, nonatomic, readwrite) id prop; // expected-error {{property of type 'id' was selected for synthesis}}
+@end
+
+@interface TypeVsSetter: Foo <TypeVsSetter1, TypeVsSetter2, TypeVsSetter3>
+@end
+@implementation TypeVsSetter
+@synthesize prop; // expected-note {{property synthesized here}}
+@end
diff --git a/test/SemaObjC/attr-ns_returns_retained.m b/test/SemaObjC/attr-ns_returns_retained.m
new file mode 100644
index 000000000000..83397a6556cc
--- /dev/null
+++ b/test/SemaObjC/attr-ns_returns_retained.m
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -fsyntax-only -fblocks -verify %s
+// RUN: %clang_cc1 -fsyntax-only -fobjc-arc -fblocks -verify %s
+
+// rdar://20130079
+
+#if __has_feature(objc_arc)
+__attribute__((ns_returns_retained)) id (^invalidBlockRedecl)(); // expected-note {{previous definition is here}}
+id (^invalidBlockRedecl)(); //expected-error {{redefinition of 'invalidBlockRedecl' with a different type: 'id (^__strong)()' vs 'id ((^__strong))() __attribute__((ns_returns_retained))'}}
+#else
+__attribute__((ns_returns_retained)) id (^invalidBlockRedecl)();
+id (^invalidBlockRedecl)();
+#endif
+
+typedef __attribute__((ns_returns_retained)) id (^blockType)();
+
+typedef __attribute__((ns_returns_retained)) int (^invalidBlockType)(); // expected-warning {{'ns_returns_retained' attribute only applies to functions that return an Objective-C object}}
+
+__attribute__((ns_returns_retained)) int functionDecl(); // expected-warning {{'ns_returns_retained' attribute only applies to functions that return an Objective-C object}}
diff --git a/test/SemaObjC/property-ambiguous-synthesis.m b/test/SemaObjC/property-ambiguous-synthesis.m
index 98f59450744c..5c652fa472e7 100644
--- a/test/SemaObjC/property-ambiguous-synthesis.m
+++ b/test/SemaObjC/property-ambiguous-synthesis.m
@@ -2,7 +2,7 @@
// rdar://13075400
@protocol FooAsID
-@property (copy) id foo; // expected-note 2 {{it could also be property of type 'id' declared here}} \\
+@property (assign) id foo; // expected-note 2 {{it could also be property of type 'id' declared here}} \\
// expected-warning {{property of type 'id' was selected for synthesis}}
@end
diff --git a/test/SemaObjC/warn-deprecated-implementations.m b/test/SemaObjC/warn-deprecated-implementations.m
index df2557b9cd52..440b2886f01d 100644
--- a/test/SemaObjC/warn-deprecated-implementations.m
+++ b/test/SemaObjC/warn-deprecated-implementations.m
@@ -1,9 +1,11 @@
-// RUN: %clang_cc1 -fsyntax-only -Wdeprecated-implementations -verify -Wno-objc-root-class %s
+// RUN: %clang_cc1 -triple=x86_64-apple-macos10.10 -fsyntax-only -Wdeprecated-implementations -verify -Wno-objc-root-class %s
// rdar://8973810
// rdar://12717705
@protocol P
- (void) D __attribute__((deprecated)); // expected-note {{method 'D' declared here}}
+
+- (void) unavailable __attribute__((__unavailable__)); // expected-note {{method 'unavailable' declared here}}
@end
@interface A <P>
@@ -16,8 +18,10 @@
@implementation A
+ (void)F { } // No warning, implementing its own deprecated method
-- (void) D {} // expected-warning {{Implementing deprecated method}}
+- (void) D {} // expected-warning {{implementing deprecated method}}
- (void) E {} // No warning, implementing deprecated method in its class extension.
+
+- (void) unavailable { } // expected-warning {{implementing unavailable metho}}
@end
@interface A(CAT)
@@ -32,10 +36,10 @@ __attribute__((deprecated)) // expected-note {{'CL' has been explicitly marked d
@interface CL // expected-note 2 {{class declared here}}
@end
-@implementation CL // expected-warning {{Implementing deprecated class}}
+@implementation CL // expected-warning {{implementing deprecated class}}
@end
-@implementation CL (SomeCategory) // expected-warning {{Implementing deprecated category}}
+@implementation CL (SomeCategory) // expected-warning {{implementing deprecated category}}
@end
@interface CL_SUB : CL // expected-warning {{'CL' is deprecated}}
@@ -43,13 +47,16 @@ __attribute__((deprecated)) // expected-note {{'CL' has been explicitly marked d
@interface BASE
- (void) B __attribute__((deprecated)); // expected-note {{method 'B' declared here}}
+
++ (void) unavailable __attribute__((availability(macos, unavailable))); // expected-note {{method 'unavailable' declared here}}
@end
@interface SUB : BASE
@end
@implementation SUB
-- (void) B {} // expected-warning {{Implementing deprecated method}}
+- (void) B {} // expected-warning {{implementing deprecated method}}
++ (void) unavailable { } // expected-warning {{implementing unavailable method}}
@end
@interface Test
@@ -69,5 +76,5 @@ __attribute__((deprecated))
@interface Test(DeprecatedCategory) // expected-note {{category declared here}}
@end
-@implementation Test(DeprecatedCategory) // expected-warning {{Implementing deprecated category}}
+@implementation Test(DeprecatedCategory) // expected-warning {{implementing deprecated category}}
@end
diff --git a/tools/clang-fuzzer/CMakeLists.txt b/tools/clang-fuzzer/CMakeLists.txt
index 87d21c6bf116..a4ea4ca19cdd 100644
--- a/tools/clang-fuzzer/CMakeLists.txt
+++ b/tools/clang-fuzzer/CMakeLists.txt
@@ -1,5 +1,5 @@
if( LLVM_USE_SANITIZE_COVERAGE )
- set(LLVM_LINK_COMPONENTS support)
+ set(LLVM_LINK_COMPONENTS ${LLVM_TARGETS_TO_BUILD})
add_clang_executable(clang-fuzzer
EXCLUDE_FROM_ALL
@@ -10,6 +10,7 @@ if( LLVM_USE_SANITIZE_COVERAGE )
${CLANG_FORMAT_LIB_DEPS}
clangAST
clangBasic
+ clangCodeGen
clangDriver
clangFrontend
clangRewriteFrontend
diff --git a/tools/clang-fuzzer/ClangFuzzer.cpp b/tools/clang-fuzzer/ClangFuzzer.cpp
index 1692882c0b5f..9eceb843e581 100644
--- a/tools/clang-fuzzer/ClangFuzzer.cpp
+++ b/tools/clang-fuzzer/ClangFuzzer.cpp
@@ -14,18 +14,25 @@
//===----------------------------------------------------------------------===//
#include "clang/Tooling/Tooling.h"
-#include "clang/Frontend/FrontendActions.h"
+#include "clang/CodeGen/CodeGenAction.h"
#include "clang/Frontend/CompilerInstance.h"
#include "clang/Lex/PreprocessorOptions.h"
#include "llvm/Option/Option.h"
+#include "llvm/Support/TargetSelect.h"
using namespace clang;
extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
std::string s((const char *)data, size);
+ llvm::InitializeAllTargets();
+ llvm::InitializeAllTargetMCs();
+ llvm::InitializeAllAsmPrinters();
+ llvm::InitializeAllAsmParsers();
+
llvm::opt::ArgStringList CC1Args;
CC1Args.push_back("-cc1");
CC1Args.push_back("./test.cc");
+ CC1Args.push_back("-O2");
llvm::IntrusiveRefCntPtr<FileManager> Files(
new FileManager(FileSystemOptions()));
IgnoringDiagConsumer Diags;
@@ -39,7 +46,7 @@ extern "C" int LLVMFuzzerTestOneInput(uint8_t *data, size_t size) {
llvm::MemoryBuffer::getMemBuffer(s);
Invocation->getPreprocessorOpts().addRemappedFile("./test.cc", Input.release());
std::unique_ptr<tooling::ToolAction> action(
- tooling::newFrontendActionFactory<clang::SyntaxOnlyAction>());
+ tooling::newFrontendActionFactory<clang::EmitObjAction>());
std::shared_ptr<PCHContainerOperations> PCHContainerOps =
std::make_shared<PCHContainerOperations>();
action->runInvocation(std::move(Invocation), Files.get(), PCHContainerOps,
diff --git a/tools/libclang/ARCMigrate.cpp b/tools/libclang/ARCMigrate.cpp
index 44a60c4e3e2c..0f2bd06db4b4 100644
--- a/tools/libclang/ARCMigrate.cpp
+++ b/tools/libclang/ARCMigrate.cpp
@@ -14,6 +14,7 @@
#include "clang-c/Index.h"
#include "CXString.h"
#include "clang/ARCMigrate/ARCMT.h"
+#include "clang/Config/config.h"
#include "clang/Frontend/TextDiagnosticBuffer.h"
#include "llvm/Support/FileSystem.h"
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index 236f264c1758..d527535a17c1 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -2264,6 +2264,23 @@ void OMPClauseEnqueue::VisitOMPReductionClause(const OMPReductionClause *C) {
Visitor->AddStmt(E);
}
}
+void OMPClauseEnqueue::VisitOMPTaskReductionClause(
+ const OMPTaskReductionClause *C) {
+ VisitOMPClauseList(C);
+ VisitOMPClauseWithPostUpdate(C);
+ for (auto *E : C->privates()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->lhs_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->rhs_exprs()) {
+ Visitor->AddStmt(E);
+ }
+ for (auto *E : C->reduction_ops()) {
+ Visitor->AddStmt(E);
+ }
+}
void OMPClauseEnqueue::VisitOMPLinearClause(const OMPLinearClause *C) {
VisitOMPClauseList(C);
VisitOMPClauseWithPostUpdate(C);
@@ -8195,7 +8212,7 @@ cxindex::checkForMacroInMacroDefinition(const MacroInfo *MI, const Token &Tok,
return nullptr;
// Check that the identifier is not one of the macro arguments.
- if (std::find(MI->arg_begin(), MI->arg_end(), &II) != MI->arg_end())
+ if (std::find(MI->param_begin(), MI->param_end(), &II) != MI->param_end())
return nullptr;
MacroDirective *InnerMD = PP.getLocalMacroDirectiveHistory(&II);
diff --git a/tools/libclang/CXType.cpp b/tools/libclang/CXType.cpp
index 5875459734a2..d2cb50905915 100644
--- a/tools/libclang/CXType.cpp
+++ b/tools/libclang/CXType.cpp
@@ -611,7 +611,7 @@ CXCallingConv clang_getFunctionTypeCallingConv(CXType X) {
TCALLINGCONV(X86Pascal);
TCALLINGCONV(X86RegCall);
TCALLINGCONV(X86VectorCall);
- TCALLINGCONV(X86_64Win64);
+ TCALLINGCONV(Win64);
TCALLINGCONV(X86_64SysV);
TCALLINGCONV(AAPCS);
TCALLINGCONV(AAPCS_VFP);
diff --git a/tools/scan-build-py/libscanbuild/analyze.py b/tools/scan-build-py/libscanbuild/analyze.py
index a09c72389d76..b5614b5b6da0 100644
--- a/tools/scan-build-py/libscanbuild/analyze.py
+++ b/tools/scan-build-py/libscanbuild/analyze.py
@@ -249,7 +249,7 @@ def analyzer_params(args):
if args.output_format:
result.append('-analyzer-output={0}'.format(args.output_format))
if args.analyzer_config:
- result.append(args.analyzer_config)
+ result.extend(['-analyzer-config', args.analyzer_config])
if args.verbose >= 4:
result.append('-analyzer-display-progress')
if args.plugins:
diff --git a/unittests/ASTMatchers/Dynamic/ParserTest.cpp b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
index ed184a8c1497..0c4c7dfd7802 100644
--- a/unittests/ASTMatchers/Dynamic/ParserTest.cpp
+++ b/unittests/ASTMatchers/Dynamic/ParserTest.cpp
@@ -80,8 +80,8 @@ TEST(ParserTest, ParseBoolean) {
Sema.parse("true");
Sema.parse("false");
EXPECT_EQ(2U, Sema.Values.size());
- EXPECT_EQ(true, Sema.Values[0].getBoolean());
- EXPECT_EQ(false, Sema.Values[1].getBoolean());
+ EXPECT_TRUE(Sema.Values[0].getBoolean());
+ EXPECT_FALSE(Sema.Values[1].getBoolean());
}
TEST(ParserTest, ParseDouble) {
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 937362f5c9d7..f533ebf2234b 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -333,6 +333,16 @@ TEST_F(FormatTest, RecognizesBinaryOperatorKeywords) {
verifyFormat("x = (a) xor (b);");
}
+TEST_F(FormatTest, RecognizesUnaryOperatorKeywords) {
+ verifyFormat("x = compl(a);");
+ verifyFormat("x = not(a);");
+ verifyFormat("x = bitand(a);");
+ // Unary operator must not be merged with the next identifier
+ verifyFormat("x = compl a;");
+ verifyFormat("x = not a;");
+ verifyFormat("x = bitand a;");
+}
+
//===----------------------------------------------------------------------===//
// Tests for control statements.
//===----------------------------------------------------------------------===//
@@ -5340,6 +5350,7 @@ TEST_F(FormatTest, UnderstandsUsesOfStarAndAmp) {
verifyFormat("x = *a(x) = *a(y);", Left);
verifyFormat("for (;; *a = b) {\n}", Left);
verifyFormat("return *this += 1;", Left);
+ verifyFormat("throw *x;", Left);
verifyIndependentOfContext("a = *(x + y);");
verifyIndependentOfContext("a = &(x + y);");
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index 11e386a1c7c7..c256ebe46263 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -1464,6 +1464,17 @@ TEST_F(FormatTestJS, ImportWrapping) {
" A,\n"
"} from 'some/module.js';",
Style);
+ Style.ColumnLimit = 40;
+ // Using this version of verifyFormat because test::messUp hides the issue.
+ verifyFormat("import {\n"
+ " A,\n"
+ "} from\n"
+ " 'some/path/longer/than/column/limit/module.js';",
+ " import { \n"
+ " A, \n"
+ " } from\n"
+ " 'some/path/longer/than/column/limit/module.js' ; ",
+ Style);
}
TEST_F(FormatTestJS, TemplateStrings) {
diff --git a/unittests/Format/SortImportsTestJS.cpp b/unittests/Format/SortImportsTestJS.cpp
index 7e766e1969e1..4208b29702dd 100644
--- a/unittests/Format/SortImportsTestJS.cpp
+++ b/unittests/Format/SortImportsTestJS.cpp
@@ -283,6 +283,23 @@ TEST_F(SortImportsTestJS, SortCaseInsensitive) {
"1;");
}
+TEST_F(SortImportsTestJS, SortMultiLine) {
+ // Reproduces issue where multi-line import was not parsed correctly.
+ verifySort("import {A} from 'a';\n"
+ "import {A} from 'b';\n"
+ "\n"
+ "1;",
+ "import\n"
+ "{\n"
+ "A\n"
+ "}\n"
+ "from\n"
+ "'b';\n"
+ "import {A} from 'a';\n"
+ "\n"
+ "1;");
+}
+
} // end namespace
} // end namespace format
} // end namespace clang
diff --git a/unittests/Lex/LexerTest.cpp b/unittests/Lex/LexerTest.cpp
index a887c22bd301..923aff18472b 100644
--- a/unittests/Lex/LexerTest.cpp
+++ b/unittests/Lex/LexerTest.cpp
@@ -379,11 +379,11 @@ TEST_F(LexerTest, DontOverallocateStringifyArgs) {
auto PP = CreatePP("\"StrArg\", 5, 'C'", ModLoader);
llvm::BumpPtrAllocator Allocator;
- std::array<IdentifierInfo *, 3> ArgList;
+ std::array<IdentifierInfo *, 3> ParamList;
MacroInfo *MI = PP->AllocateMacroInfo({});
MI->setIsFunctionLike();
- MI->setArgumentList(ArgList, Allocator);
- EXPECT_EQ(3u, MI->getNumArgs());
+ MI->setParameterList(ParamList, Allocator);
+ EXPECT_EQ(3u, MI->getNumParams());
EXPECT_TRUE(MI->isFunctionLike());
Token Eof;
diff --git a/unittests/Tooling/CMakeLists.txt b/unittests/Tooling/CMakeLists.txt
index 8ed35480cb88..1359c7cabd1e 100644
--- a/unittests/Tooling/CMakeLists.txt
+++ b/unittests/Tooling/CMakeLists.txt
@@ -14,6 +14,7 @@ add_clang_unittest(ToolingTests
CastExprTest.cpp
CommentHandlerTest.cpp
CompilationDatabaseTest.cpp
+ DiagnosticsYamlTest.cpp
FixItTest.cpp
LookupTest.cpp
QualTypeNamesTest.cpp
diff --git a/unittests/Tooling/DiagnosticsYamlTest.cpp b/unittests/Tooling/DiagnosticsYamlTest.cpp
new file mode 100644
index 000000000000..83e09eaeef2d
--- /dev/null
+++ b/unittests/Tooling/DiagnosticsYamlTest.cpp
@@ -0,0 +1,167 @@
+//===- unittests/Tooling/DiagnosticsYamlTest.cpp - Serialization tests ---===//
+//
+// The LLVM Compiler Infrastructure
+//
+// This file is distributed under the University of Illinois Open Source
+// License. See LICENSE.TXT for details.
+//
+//===----------------------------------------------------------------------===//
+//
+// Tests for serialization of Diagnostics.
+//
+//===----------------------------------------------------------------------===//
+
+#include "clang/Tooling/DiagnosticsYaml.h"
+#include "clang/Tooling/Core/Diagnostic.h"
+#include "clang/Tooling/ReplacementsYaml.h"
+#include "gtest/gtest.h"
+
+using namespace llvm;
+using namespace clang::tooling;
+using clang::tooling::Diagnostic;
+
+static Diagnostic makeDiagnostic(StringRef DiagnosticName,
+ const std::string &Message, int FileOffset,
+ const std::string &FilePath,
+ const StringMap<Replacements> &Fix) {
+ DiagnosticMessage DiagMessage;
+ DiagMessage.Message = Message;
+ DiagMessage.FileOffset = FileOffset;
+ DiagMessage.FilePath = FilePath;
+ return Diagnostic(DiagnosticName, DiagMessage, Fix, {}, Diagnostic::Warning,
+ "path/to/build/directory");
+}
+
+TEST(DiagnosticsYamlTest, serializesDiagnostics) {
+ TranslationUnitDiagnostics TUD;
+ TUD.MainSourceFile = "path/to/source.cpp";
+
+ StringMap<Replacements> Fix1 = {
+ {"path/to/source.cpp",
+ Replacements({"path/to/source.cpp", 100, 12, "replacement #1"})}};
+ TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#1", "message #1", 55,
+ "path/to/source.cpp", Fix1));
+
+ StringMap<Replacements> Fix2 = {
+ {"path/to/header.h",
+ Replacements({"path/to/header.h", 62, 2, "replacement #2"})}};
+ TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#2", "message #2", 60,
+ "path/to/header.h", Fix2));
+
+ TUD.Diagnostics.push_back(makeDiagnostic("diagnostic#3", "message #3", 72,
+ "path/to/source2.cpp", {}));
+
+ std::string YamlContent;
+ raw_string_ostream YamlContentStream(YamlContent);
+
+ yaml::Output YAML(YamlContentStream);
+ YAML << TUD;
+
+ EXPECT_EQ("---\n"
+ "MainSourceFile: path/to/source.cpp\n"
+ "Diagnostics: \n"
+ " - DiagnosticName: 'diagnostic#1\'\n"
+ " Message: 'message #1'\n"
+ " FileOffset: 55\n"
+ " FilePath: path/to/source.cpp\n"
+ " Replacements: \n"
+ " - FilePath: path/to/source.cpp\n"
+ " Offset: 100\n"
+ " Length: 12\n"
+ " ReplacementText: 'replacement #1'\n"
+ " - DiagnosticName: 'diagnostic#2'\n"
+ " Message: 'message #2'\n"
+ " FileOffset: 60\n"
+ " FilePath: path/to/header.h\n"
+ " Replacements: \n"
+ " - FilePath: path/to/header.h\n"
+ " Offset: 62\n"
+ " Length: 2\n"
+ " ReplacementText: 'replacement #2'\n"
+ " - DiagnosticName: 'diagnostic#3'\n"
+ " Message: 'message #3'\n"
+ " FileOffset: 72\n"
+ " FilePath: path/to/source2.cpp\n"
+ " Replacements: \n"
+ "...\n",
+ YamlContentStream.str());
+}
+
+TEST(DiagnosticsYamlTest, deserializesDiagnostics) {
+ std::string YamlContent = "---\n"
+ "MainSourceFile: path/to/source.cpp\n"
+ "Diagnostics: \n"
+ " - DiagnosticName: 'diagnostic#1'\n"
+ " Message: 'message #1'\n"
+ " FileOffset: 55\n"
+ " FilePath: path/to/source.cpp\n"
+ " Replacements: \n"
+ " - FilePath: path/to/source.cpp\n"
+ " Offset: 100\n"
+ " Length: 12\n"
+ " ReplacementText: 'replacement #1'\n"
+ " - DiagnosticName: 'diagnostic#2'\n"
+ " Message: 'message #2'\n"
+ " FileOffset: 60\n"
+ " FilePath: path/to/header.h\n"
+ " Replacements: \n"
+ " - FilePath: path/to/header.h\n"
+ " Offset: 62\n"
+ " Length: 2\n"
+ " ReplacementText: 'replacement #2'\n"
+ " - DiagnosticName: 'diagnostic#3'\n"
+ " Message: 'message #3'\n"
+ " FileOffset: 98\n"
+ " FilePath: path/to/source.cpp\n"
+ " Replacements: \n"
+ "...\n";
+ TranslationUnitDiagnostics TUDActual;
+ yaml::Input YAML(YamlContent);
+ YAML >> TUDActual;
+
+ ASSERT_FALSE(YAML.error());
+ ASSERT_EQ(3u, TUDActual.Diagnostics.size());
+ EXPECT_EQ("path/to/source.cpp", TUDActual.MainSourceFile);
+
+ auto getFixes = [](const StringMap<Replacements> &Fix) {
+ std::vector<Replacement> Fixes;
+ for (auto &Replacements : Fix) {
+ for (auto &Replacement : Replacements.second) {
+ Fixes.push_back(Replacement);
+ }
+ }
+ return Fixes;
+ };
+
+ Diagnostic D1 = TUDActual.Diagnostics[0];
+ EXPECT_EQ("diagnostic#1", D1.DiagnosticName);
+ EXPECT_EQ("message #1", D1.Message.Message);
+ EXPECT_EQ(55u, D1.Message.FileOffset);
+ EXPECT_EQ("path/to/source.cpp", D1.Message.FilePath);
+ std::vector<Replacement> Fixes1 = getFixes(D1.Fix);
+ ASSERT_EQ(1u, Fixes1.size());
+ EXPECT_EQ("path/to/source.cpp", Fixes1[0].getFilePath());
+ EXPECT_EQ(100u, Fixes1[0].getOffset());
+ EXPECT_EQ(12u, Fixes1[0].getLength());
+ EXPECT_EQ("replacement #1", Fixes1[0].getReplacementText());
+
+ Diagnostic D2 = TUDActual.Diagnostics[1];
+ EXPECT_EQ("diagnostic#2", D2.DiagnosticName);
+ EXPECT_EQ("message #2", D2.Message.Message);
+ EXPECT_EQ(60u, D2.Message.FileOffset);
+ EXPECT_EQ("path/to/header.h", D2.Message.FilePath);
+ std::vector<Replacement> Fixes2 = getFixes(D2.Fix);
+ ASSERT_EQ(1u, Fixes2.size());
+ EXPECT_EQ("path/to/header.h", Fixes2[0].getFilePath());
+ EXPECT_EQ(62u, Fixes2[0].getOffset());
+ EXPECT_EQ(2u, Fixes2[0].getLength());
+ EXPECT_EQ("replacement #2", Fixes2[0].getReplacementText());
+
+ Diagnostic D3 = TUDActual.Diagnostics[2];
+ EXPECT_EQ("diagnostic#3", D3.DiagnosticName);
+ EXPECT_EQ("message #3", D3.Message.Message);
+ EXPECT_EQ(98u, D3.Message.FileOffset);
+ EXPECT_EQ("path/to/source.cpp", D3.Message.FilePath);
+ std::vector<Replacement> Fixes3 = getFixes(D3.Fix);
+ EXPECT_TRUE(Fixes3.empty());
+}
diff --git a/utils/bash-autocomplete.sh b/utils/bash-autocomplete.sh
index 1e38bcfcaad7..72531b99e3da 100755
--- a/utils/bash-autocomplete.sh
+++ b/utils/bash-autocomplete.sh
@@ -20,18 +20,21 @@ _clang()
cur="${COMP_WORDS[$cword]}"
fi
- # bash always separates '=' as a token even if there's no space before/after '='.
- # On the other hand, '=' is just a regular character for clang options that
- # contain '='. For example, "-stdlib=" is defined as is, instead of "-stdlib" and "=".
- # So, we need to partially undo bash tokenization here for integrity.
w1="${COMP_WORDS[$cword - 1]}"
if [[ $cword > 1 ]]; then
w2="${COMP_WORDS[$cword - 2]}"
+ fi
+
# Clang want to know if -cc1 or -Xclang option is specified or not, because we don't want to show
# cc1 options otherwise.
if [[ "${COMP_WORDS[1]}" == "-cc1" || "$w1" == "-Xclang" ]]; then
arg="#"
fi
+
+ # bash always separates '=' as a token even if there's no space before/after '='.
+ # On the other hand, '=' is just a regular character for clang options that
+ # contain '='. For example, "-stdlib=" is defined as is, instead of "-stdlib" and "=".
+ # So, we need to partially undo bash tokenization here for integrity.
if [[ "$cur" == -* ]]; then
# -foo<tab>
arg="$arg$cur"
diff --git a/www/analyzer/alpha_checks.html b/www/analyzer/alpha_checks.html
index ce9392b9960c..7d84d23343f9 100644
--- a/www/analyzer/alpha_checks.html
+++ b/www/analyzer/alpha_checks.html
@@ -24,6 +24,7 @@ keep them from being on by default. They are likely to have false positives.
Bug reports are welcome but will likely not be investigated for some time.
Patches welcome!
<ul>
+<li><a href="#clone_alpha_checkers">Clone Alpha Checkers</a></li>
<li><a href="#core_alpha_checkers">Core Alpha Checkers</a></li>
<li><a href="#cplusplus_alpha_checkers">C++ Alpha Checkers</a></li>
<li><a href="#valist_alpha_checkers">Variable Argument Alpha Checkers</a></li>
@@ -33,6 +34,38 @@ Patches welcome!
<li><a href="#unix_alpha_checkers">Unix Alpha Checkers</a></li>
</ul>
+<!-- ============================= clone alpha ============================= -->
+
+<h3 id="clone_alpha_checkers">Clone Alpha Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.clone.CloneChecker</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Reports similar pieces of code.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void log();
+
+int max(int a, int b) { // warn
+ log();
+ if (a > b)
+ return a;
+ return b;
+}
+
+int maxClone(int x, int y) { // similar code here
+ log();
+ if (x > y)
+ return x;
+ return y;
+}
+</pre></div></div></td></tr>
+</tbody></table>
+
<!-- ============================= core alpha ============================= -->
<h3 id="core_alpha_checkers">Core Alpha Checkers</h3>
<table class="checkers">
@@ -53,6 +86,28 @@ void test() {
<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.CallAndMessageUnInitRefArg</span><span class="lang">
+(C, C++)</span><div class="descr">
+Check for uninitialized arguments in function calls and Objective-C
+message expressions.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(void) {
+ int t;
+ int &p = t;
+ int &s = p;
+ int &q = s;
+ foo(q); // warn
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test(void) {
+ int x;
+ foo(&x); // warn
+}
+</pre></div></div></td></tr>
+
+<tr><td><div class="namedescr expandable"><span class="name">
alpha.core.CastSize</span><span class="lang">
(C)</span><div class="descr">
Check when casting a malloc'ed type T, whether the size is a multiple of the
@@ -91,6 +146,47 @@ void test(int *p) {
<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.Conversion</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Loss of sign or precision in implicit conversions</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(unsigned U, signed S) {
+ if (S > 10) {
+ if (U < S) {
+ }
+ }
+ if (S < -10) {
+ if (U < S) { // warn (loss of sign)
+ }
+ }
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+ long long A = 1LL << 60;
+ short X = A; // warn (loss of precision)
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.DynamicTypeChecker</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for cases where the dynamic and the static type of an
+object are unrelated.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+id date = [NSDate date];
+
+// Warning: Object has a dynamic type 'NSDate *' which is
+// incompatible with static type 'NSNumber *'"
+NSNumber *number = date;
+[number doubleValue];
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
alpha.core.FixedAddr</span><span class="lang">
(C)</span><div class="descr">
Check for assignment of a fixed address to a pointer.</div></div></td>
@@ -178,6 +274,21 @@ int test(struct s *p) {
}
</pre></div></div></td></tr>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.core.TestAfterDivZero</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check for division by variable that is later compared against 0.
+Either the comparison is useless or there is division by zero.
+</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test(int x) {
+ var = 77 / x;
+ if (x == 0) { } // warn
+}
+</pre></div></div></td></tr>
+
</tbody></table>
<!-- =========================== cplusplus alpha =========================== -->
@@ -188,19 +299,6 @@ int test(struct s *p) {
<tbody>
<tr><td><div class="namedescr expandable"><span class="name">
-alpha.cplusplus.NewDeleteLeaks</span><span class="lang">
-(C++)</span><div class="descr">
-Check for memory leaks. Traces memory managed by <code>new</code>/<code>
-delete</code>.</div></div></td>
-<td><div class="exampleContainer expandable">
-<div class="example"><pre>
-void test() {
- int *p = new int;
-} // warn
-</pre></div></div></td></tr>
-
-
-<tr><td><div class="namedescr expandable"><span class="name">
alpha.cplusplus.VirtualCall</span><span class="lang">
(C++)</span><div class="descr">
Check virtual member function calls during construction or
@@ -345,66 +443,6 @@ void test(id x) {
<tbody>
<tr><td><div class="namedescr expandable"><span class="name">
-alpha.osx.cocoa.Dealloc</span><span class="lang">
-(ObjC)</span><div class="descr">
-Warn about Objective-C classes that lack a correct implementation
-of <code>-dealloc</code>.
-</div></div></td>
-<td><div class="exampleContainer expandable">
-<div class="example"><pre>
-@interface MyObject : NSObject {
- id _myproperty;
-}
-@end
-
-@implementation MyObject // warn: lacks 'dealloc'
-@end
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-@interface MyObject : NSObject {}
-@property(assign) id myproperty;
-@end
-
-@implementation MyObject // warn: does not send 'dealloc' to super
-- (void)dealloc {
- self.myproperty = 0;
-}
-@end
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-@interface MyObject : NSObject {
- id _myproperty;
-}
-@property(retain) id myproperty;
-@end
-
-@implementation MyObject
-@synthesize myproperty = _myproperty;
- // warn: var was retained but wasn't released
-- (void)dealloc {
- [super dealloc];
-}
-@end
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-@interface MyObject : NSObject {
- id _myproperty;
-}
-@property(assign) id myproperty;
-@end
-
-@implementation MyObject
-@synthesize myproperty = _myproperty;
- // warn: var wasn't retained but was released
-- (void)dealloc {
- [_myproperty release];
- [super dealloc];
-}
-@end
-</pre></div></div></td></tr>
-
-
-<tr><td><div class="namedescr expandable"><span class="name">
alpha.osx.cocoa.DirectIvarAssignment</span><span class="lang">
(ObjC)</span><div class="descr">
Check that Objective C properties follow the following rule: the property
@@ -501,6 +539,32 @@ invalidatable instance variables.</div></div></td>
@end
</pre></div></div></td></tr>
+
+<tr><td><div class="namedescr expandable"><span class="name">
+alpha.osx.cocoa.localizability.PluralMisuseChecker</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warns against using one vs. many plural pattern in code
+when generating localized strings.
+</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+NSString *reminderText =
+ NSLocalizedString(@"None", @"Indicates no reminders");
+if (reminderCount == 1) {
+ // Warning: Plural cases are not supported accross all languages.
+ // Use a .stringsdict file instead
+ reminderText =
+ NSLocalizedString(@"1 Reminder", @"Indicates single reminder");
+} else if (reminderCount >= 2) {
+ // Warning: Plural cases are not supported accross all languages.
+ // Use a .stringsdict file instead
+ reminderText =
+ [NSString stringWithFormat:
+ NSLocalizedString(@"%@ Reminders", @"Indicates multiple reminders"),
+ reminderCount];
+}
+</pre></div></div></td></tr>
+
</tbody></table>
<!-- =========================== security alpha =========================== -->
@@ -675,52 +739,6 @@ void test() {
}
</pre></div></div></td></tr>
-
-<tr><td><div class="namedescr expandable"><span class="name">
-alpha.unix.MallocWithAnnotations</span><span class="lang">
-(C)</span><div class="descr">
-Check for memory leaks, double free, and use-after-free problems. Assumes that
-all user-defined functions which might free a pointer are
-annotated.</div></div></td>
-<td><div class="exampleContainer expandable">
-<div class="example"><pre>
-void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
-
-void test() {
- int *p = my_malloc(1);
-} // warn: potential leak
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
-void __attribute((ownership_takes(malloc, 1))) my_free(void *);
-
-void test() {
- int *p = my_malloc(1);
- my_free(p);
- my_free(p); // warn: attempt to free released
-}
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-void __attribute((ownership_returns(malloc))) *my_malloc(size_t);
-void __attribute((ownership_holds(malloc, 1))) my_hold(void *);
-
-void test() {
- int *p = my_malloc(1);
- my_hold(p);
- free(p); // warn: attempt to free non-owned memory
-}
-</pre></div><div class="separator"></div>
-<div class="example"><pre>
-void __attribute((ownership_takes(malloc, 1))) my_free(void *);
-
-void test() {
- int *p = malloc(1);
- my_free(p);
- *p = 1; // warn: use after free
-}
-</pre></div></div></td></tr>
-
-
<tr><td><div class="namedescr expandable"><span class="name">
alpha.unix.PthreadLock</span><span class="lang">
(C)</span><div class="descr">
@@ -910,30 +928,6 @@ void test(char *y) {
}
</pre></div></div></td></tr>
-
-<tr><td><div class="namedescr expandable"><span class="name">
-alpha.unix.cstring.BlockInCriticalSection</span><span class="lang">
-(C)</span><div class="descr">
-Check for calls to blocking functions inside a critical section; applies
-to:<div class=functions>
-lock, unlock<br>
-sleep<br>
-getc<br>
-fgets<br>
-read<br>
-recv<br>
-pthread_mutex_lock, pthread_mutex_trylock, pthread_mutex_unlock<br>
-mtx_lock, mtx_timedlock, mtx_trylock, mtx_unlock<br>
-</div></div></div></td>
-<td><div class="exampleContainer expandable">
-<div class="example"><pre>
-void testBlockInCriticalSection() {
- std::mutex m;
- m.lock();
- sleep(3); // warn
- m.unlock();
-}
-</pre></div></div></td></tr>
</tbody></table>
</div> <!-- page -->
diff --git a/www/analyzer/available_checks.html b/www/analyzer/available_checks.html
index 7707fc0150d5..eca8dca616d2 100644
--- a/www/analyzer/available_checks.html
+++ b/www/analyzer/available_checks.html
@@ -38,12 +38,14 @@ Experimental (Alpha) Checkers</a>.
<li><a href="#core_checkers">Core Checkers</a> model core language features and perform general-purpose checks such as division by zero, null pointer dereference, usage of uninitialized values, etc.</li>
<li><a href="#cplusplus_checkers">C++ Checkers</a> perform C++-specific checks</li>
<li><a href="#deadcode_checkers">Dead Code Checkers</a> check for unused code</li>
+<li><a href="#nullability_checkers">Nullability Checkers</a> </li>
+<li><a href="#optin_checkers">Optin Checkers</a> </li>
<li><a href="#osx_checkers">OS X Checkers</a> perform Objective-C-specific checks and check the use of Apple's SDKs (OS X and iOS)</li>
<li><a href="#security_checkers">Security Checkers</a> check for insecure API usage and perform checks based on the CERT Secure Coding Standards</li>
<li><a href="#unix_checkers">Unix Checkers</a> check the use of Unix and POSIX APIs</li>
</ul>
-<!------------------------------------ core ----------------------------------->
+<!-- =========================== core =========================== -->
<h3 id="core_checkers">Core Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -360,7 +362,7 @@ int test() {
</tbody></table>
-<!------------------------------------ C++ ------------------------------------>
+<!-- =========================== C++ =========================== -->
<h3 id="cplusplus_checkers">C++ Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -421,9 +423,21 @@ void test() {
}
</pre></div></div></td></tr>
+<tr><td><div class="namedescr expandable"><span class="name">
+cplusplus.NewDeleteLeaks</span><span class="lang">
+(C++)</span><div class="descr">
+Check for memory leaks. Traces memory managed by <code>new</code>/<code>
+delete</code>.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+ int *p = new int;
+} // warn
+</pre></div></div></td></tr>
+
</tbody></table>
-<!--------------------------------- dead code --------------------------------->
+<!-- =========================== dead code =========================== -->
<h3 id="deadcode_checkers">Dead Code Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -444,7 +458,161 @@ void test() {
</tbody></table>
-<!---------------------------------- OS X ------------------------------------>
+<!-- =========================== nullability =========================== -->
+<h3 id="nullability_checkers">Nullability Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+nullability.NullPassedToNonnull</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warns when a null pointer is passed to a pointer which has a
+_Nonnull type.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+if (name != nil)
+ return;
+// Warning: nil passed to a callee that requires a non-null 1st parameter
+NSString *greeting = [@"Hello " stringByAppendingString:name];
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+nullability.NullReturnedFromNonnull</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warns when a null pointer is returned from a function that has
+_Nonnull return type.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+- (nonnull id)firstChild {
+ id result = nil;
+ if ([_children count] > 0)
+ result = _children[0];
+
+ // Warning: nil returned from a method that is expected
+ // to return a non-null value
+ return result;
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+nullability.NullableDereferenced</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warns when a nullable pointer is dereferenced.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+struct LinkedList {
+ int data;
+ struct LinkedList *next;
+};
+
+struct LinkedList * _Nullable getNext(struct LinkedList *l);
+
+void updateNextData(struct LinkedList *list, int newData) {
+ struct LinkedList *next = getNext(list);
+ // Warning: Nullable pointer is dereferenced
+ next->data = 7;
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+nullability.NullablePassedToNonnull</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warns when a nullable pointer is passed to a pointer which has a _Nonnull type.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+typedef struct Dummy { int val; } Dummy;
+Dummy *_Nullable returnsNullable();
+void takesNonnull(Dummy *_Nonnull);
+
+void test() {
+ Dummy *p = returnsNullable();
+ takesNonnull(p); // warn
+}
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!-- =========================== optin =========================== -->
+<h3 id="optin_checkers">Optin Checkers</h3>
+<table class="checkers">
+<colgroup><col class="namedescr"><col class="example"></colgroup>
+<thead><tr><td>Name, Description</td><td>Example</td></tr></thead>
+
+<tbody>
+<tr><td><div class="namedescr expandable"><span class="name">
+optin.mpi.MPI-Checker</span><span class="lang">
+(C)</span><div class="descr">
+Checks MPI code</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+void test() {
+ double buf = 0;
+ MPI_Request sendReq1;
+ MPI_Ireduce(MPI_IN_PLACE, &buf, 1, MPI_DOUBLE, MPI_SUM,
+ 0, MPI_COMM_WORLD, &sendReq1);
+} // warn: request 'sendReq1' has no matching wait.
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void test() {
+ double buf = 0;
+ MPI_Request sendReq;
+ MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq);
+ MPI_Irecv(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
+ MPI_Isend(&buf, 1, MPI_DOUBLE, 0, 0, MPI_COMM_WORLD, &sendReq); // warn
+ MPI_Wait(&sendReq, MPI_STATUS_IGNORE);
+}
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+void missingNonBlocking() {
+ int rank = 0;
+ MPI_Comm_rank(MPI_COMM_WORLD, &rank);
+ MPI_Request sendReq1[10][10][10];
+ MPI_Wait(&sendReq1[1][7][9], MPI_STATUS_IGNORE); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+optin.osx.cocoa.localizability.EmptyLocalizationContextChecker</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check that NSLocalizedString macros include a comment for context.</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+- (void)test {
+ NSString *string = NSLocalizedString(@"LocalizedString", nil); // warn
+ NSString *string2 = NSLocalizedString(@"LocalizedString", @" "); // warn
+ NSString *string3 = NSLocalizedStringWithDefaultValue(
+ @"LocalizedString", nil, [[NSBundle alloc] init], nil,@""); // warn
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
+optin.osx.cocoa.localizability.NonLocalizedStringChecker</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warns about uses of non-localized NSStrings passed to UI methods
+expecting localized NSStrings</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+NSString *alarmText =
+ NSLocalizedString(@"Enabled", @"Indicates alarm is turned on");
+if (!isEnabled) {
+ alarmText = @"Disabled";
+}
+UILabel *alarmStateLabel = [[UILabel alloc] init];
+
+// Warning: User-facing text should use localized string macro
+[alarmStateLabel setText:alarmText];
+</pre></div></div></td></tr>
+
+</tbody></table>
+
+<!-- =========================== OS X =========================== -->
<h3 id="osx_checkers">OS X Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -466,6 +634,22 @@ void test() {
<tr><td><div class="namedescr expandable"><span class="name">
+osx.NumberObjectConversion</span><span class="lang">
+(C, C++, ObjC)</span><div class="descr">
+Check for erroneous conversions of objects representing numbers
+into numbers</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+NSNumber *photoCount = [albumDescriptor objectForKey:@"PhotoCount"];
+// Warning: Comparing a pointer value of type 'NSNumber *'
+// to a scalar integer value
+if (photoCount > 0) {
+ [self displayPhotos];
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
osx.SecKeychainAPI</span><span class="lang">
(C)</span><div class="descr">
Check for improper uses of the Security framework's Keychain APIs:<div class=functions>
@@ -581,6 +765,66 @@ void test(void) {
<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.Dealloc</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about Objective-C classes that lack a correct implementation
+of <code>-dealloc</code>.
+</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@end
+
+@implementation MyObject // warn: lacks 'dealloc'
+@end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+@interface MyObject : NSObject {}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject // warn: does not send 'dealloc' to super
+- (void)dealloc {
+ self.myproperty = 0;
+}
+@end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@property(retain) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+ // warn: var was retained but wasn't released
+- (void)dealloc {
+ [super dealloc];
+}
+@end
+</pre></div><div class="separator"></div>
+<div class="example"><pre>
+@interface MyObject : NSObject {
+ id _myproperty;
+}
+@property(assign) id myproperty;
+@end
+
+@implementation MyObject
+@synthesize myproperty = _myproperty;
+ // warn: var wasn't retained but was released
+- (void)dealloc {
+ [_myproperty release];
+ [super dealloc];
+}
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
osx.cocoa.IncompatibleMethodTypes</span><span class="lang">
(ObjC)</span><div class="descr">
Check for an incompatible type signature when overriding an Objective-C method.</div></div></td>
@@ -688,6 +932,21 @@ NSComparisonResult test(NSString *s) {
<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.ObjCGenerics</span><span class="lang">
+(ObjC)</span><div class="descr">
+Check for type errors when using Objective-C generics</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+NSMutableArray<NSString *> *names = [NSMutableArray array];
+NSMutableArray *birthDates = names;
+
+// Warning: Conversion from value of type 'NSDate *'
+// to incompatible type 'NSString *'
+[birthDates addObject: [NSDate date]];
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
osx.cocoa.RetainCount</span><span class="lang">
(ObjC)</span><div class="descr">
Check for leaks and violations of the Cocoa Memory Management rules.</div></div></td>
@@ -742,6 +1001,26 @@ method.</div></div></td>
<tr><td><div class="namedescr expandable"><span class="name">
+osx.cocoa.SuperDealloc</span><span class="lang">
+(ObjC)</span><div class="descr">
+Warn about improper use of '[super dealloc]' in Objective-C</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+@interface SuperDeallocThenReleaseIvarClass : NSObject {
+ NSObject *_ivar;
+}
+@end
+
+@implementation SuperDeallocThenReleaseIvarClass
+- (void)dealloc {
+ [super dealloc];
+ [_ivar release]; // warn
+}
+@end
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
osx.cocoa.UnusedIvars</span><span class="lang">
(ObjC)</span><div class="descr">
Warn about private ivars that are never used.</div></div></td>
@@ -855,7 +1134,7 @@ void test() {
</tbody></table>
-<!------------------------------- security ------------------------------------>
+<!-- =========================== security =========================== -->
<h3 id="security_checkers">Security Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -995,7 +1274,7 @@ void test() {
</tbody></table>
-<!--------------------------------- unix -------------------------------------->
+<!-- =========================== unix =========================== -->
<h3 id="unix_checkers">Unix Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -1188,6 +1467,38 @@ void test(NSUInteger dataLength) {
<tr><td><div class="namedescr expandable"><span class="name">
+unix.Vfork</span><span class="lang">
+(C)</span><div class="descr">
+Check for proper usage of vfork</div></div></td>
+<td><div class="exampleContainer expandable">
+<div class="example"><pre>
+int test(int x) {
+ pid_t pid = vfork(); // warn
+ if (pid != 0)
+ return 0;
+
+ switch (x) {
+ case 0:
+ pid = 1;
+ execl("", "", 0);
+ _exit(1);
+ break;
+ case 1:
+ x = 0; // warn: this assignment is prohibited
+ break;
+ case 2:
+ foo(); // warn: this function call is prohibited
+ break;
+ default:
+ return 0; // warn: return is prohibited
+ }
+
+ while(1);
+}
+</pre></div></div></td></tr>
+
+
+<tr><td><div class="namedescr expandable"><span class="name">
unix.cstring.BadSizeArg</span><span class="lang">
(C)</span><div class="descr">
Check the size argument passed to <code>strncat</code> for common erroneous
diff --git a/www/analyzer/implicit_checks.html b/www/analyzer/implicit_checks.html
index a476c9bf32bc..948f4533b89b 100644
--- a/www/analyzer/implicit_checks.html
+++ b/www/analyzer/implicit_checks.html
@@ -27,7 +27,7 @@ and <a href = "alpha_checks.html">Experimental (Alpha) Checkers</a>.
<li><a href="#osx_implicit_checkers">OS X Implicit Checkers</a></li>
</ul>
-<!------------------------------- core implicit ------------------------------->
+<!-- =========================== core implicit =========================== -->
<h3 id="core_implicit_checkers">Core Implicit Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
@@ -124,7 +124,7 @@ void test() {
</tbody></table>
-<!---------------------------- OS X implicit ---------------------------------->
+<!-- =========================== OS X implicit =========================== -->
<h3 id="osx_implicit_checkers">OS X Implicit Checkers</h3>
<table class="checkers">
<colgroup><col class="namedescr"><col class="example"></colgroup>
diff --git a/www/cxx_status.html b/www/cxx_status.html
index 23d95bda67c0..39c3147ca47c 100644
--- a/www/cxx_status.html
+++ b/www/cxx_status.html
@@ -2,7 +2,7 @@
<html>
<head>
<meta http-equiv="Content-Type" content="text/html; charset=ISO-8859-1">
- <title>Clang - C++1z, C++14, C++11 and C++98 Status</title>
+ <title>Clang - C++17, C++14, C++11 and C++98 Status</title>
<link type="text/css" rel="stylesheet" href="menu.css">
<link type="text/css" rel="stylesheet" href="content.css">
<style type="text/css">
@@ -26,13 +26,13 @@
<!--*************************************************************************-->
<h1>C++ Support in Clang</h1>
<!--*************************************************************************-->
-<p>Last updated: $Date: 2017-07-06 02:29:13 +0200 (Thu, 06 Jul 2017) $</p>
+<p>Last updated: $Date: 2017-07-15 17:51:59 +0200 (Sat, 15 Jul 2017) $</p>
<p>Clang fully implements all published ISO C++ standards (<a
href="#cxx98">C++98 / C++03</a>, <a
href="#cxx11">C++11</a>, and <a
href="#cxx14">C++14</a>), and most of the upcoming <a
-href="#cxx17">C++1z</a> standard.
+href="#cxx17">C++17</a> standard.
<p>The Clang community is continually striving to improve C++ standards
compliance between releases by submitting and tracking <a
@@ -519,14 +519,12 @@ version 3.7.
</p>
</details>
-<h2 id="cxx17">C++1z implementation status</h2>
+<h2 id="cxx17">C++17 implementation status</h2>
-<p>Clang has <b>experimental</b> support for some proposed features of
-the C++ standard following C++14, provisionally named C++1z.
-Note that support for these features may change or be removed without notice,
-as the draft C++1z standard evolves.
+<p>Clang SVN implements all the features
+of the C++ 2017 Draft International Standard.
-<p>You can use Clang in C++1z mode with the <code>-std=c++1z</code> option.</p>
+<p>You can use Clang in C++17 mode with the <code>-std=c++1z</code> option.</p>
<details open>
<summary>List of features and minimum Clang version with support</summary>
@@ -534,7 +532,7 @@ as the draft C++1z standard evolves.
<table width="689" border="1" cellspacing="0">
<tr>
<th>Language Feature</th>
- <th>C++1z Proposal</th>
+ <th>C++17 Proposal</th>
<th>Available in Clang?</th>
</tr>
<!-- Issaquah 2014 papers -->
@@ -551,7 +549,7 @@ as the draft C++1z standard evolves.
</tr>
<!--
<tr>
- <td rowspan="2">Terse range-based for loops (removed from C++1z)</td>
+ <td rowspan="2">Terse range-based for loops (removed from C++17)</td>
<td rowspan="2"><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/papers/2014/n3994.htm">N3994</a></td>
<td class="none" align="center">Clang 3.5: Yes</td>
</tr>
@@ -777,6 +775,69 @@ code. This issue is expected to be rectified soon.
</p>
</details>
+<h2 id="cxx20">C++2a implementation status</h2>
+
+<p>Clang does not yet support any of the proposed features of
+<!--<p>Clang has <b>experimental</b> support for some proposed features of-->
+the C++ standard following C++17, provisionally named C++2a.
+Note that support for these features may change or be removed without notice,
+as the draft C++2a standard evolves.
+
+<!--<p>You can use Clang in C++2a mode with the <code>-std=c++2a</code> option.</p>-->
+
+<details open>
+<summary>List of features and minimum Clang version with support</summary>
+
+<table width="689" border="1" cellspacing="0">
+ <tr>
+ <th>Language Feature</th>
+ <th>C++2a Proposal</th>
+ <th>Available in Clang?</th>
+ </tr>
+ <!-- Toronto 2017 papers -->
+ <tr>
+ <td>Default member initializers for bit-fields</td>
+ <td><a href="http://wg21.link/p0683r1">P0683R1</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td><tt>const&amp;</tt>-qualified pointers to members</td>
+ <td><a href="http://wg21.link/p0704r1">P0704R1</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td>Allow <i>lambda-capture</i> <tt>[=, this]</tt></td>
+ <td><a href="http://wg21.link/p0409r2">P0409R2</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td><tt>__VA_OPT__</tt> for preprocessor comma elision</td>
+ <td><a href="http://wg21.link/p0306r4">P0306R4</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td>Designated initializers</td>
+ <td><a href="http://wg21.link/p0329r4">P0329R4</a></td>
+ <td class="partial" align="center">Partial (extension)</td>
+ </tr>
+ <tr>
+ <td><i>template-parameter-list</i> for generic lambdas</td>
+ <td><a href="http://wg21.link/p0428r2">P0428R2</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td>Initializer list constructors in class template argument deduction</td>
+ <td><a href="http://wg21.link/p0702r1">P0702R1</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+ <tr>
+ <td>Concepts</td>
+ <td><a href="http://wg21.link/p0734r0">P0734R0</a></td>
+ <td class="none" align="center">No</td>
+ </tr>
+</table>
+</details>
+
<h2 id="ts">Technical specifications and standing documents</h2>
<p>ISO C++ also publishes a number of documents describing additional language