aboutsummaryrefslogtreecommitdiffstats
diff options
context:
space:
mode:
authorDimitry Andric <dim@FreeBSD.org>2017-05-16 19:47:09 +0000
committerDimitry Andric <dim@FreeBSD.org>2017-05-16 19:47:09 +0000
commit2410013d9382b8129702fa3a3bf19a370ae7afc3 (patch)
treedf038b6418b19d03437950dcee799c1483c6246a
parent0a5fb09b599c1bdea3cd11168bb8f4ff4040316e (diff)
downloadsrc-2410013d9382b8129702fa3a3bf19a370ae7afc3.tar.gz
src-2410013d9382b8129702fa3a3bf19a370ae7afc3.zip
Vendor import of clang trunk r303197:vendor/clang/clang-trunk-r303197
Notes
Notes: svn path=/vendor/clang/dist/; revision=318370 svn path=/vendor/clang/clang-trunk-r303197/; revision=318371; tag=vendor/clang/clang-trunk-r303197
-rw-r--r--CMakeLists.txt13
-rw-r--r--cmake/caches/Apple-stage2.cmake7
-rw-r--r--cmake/caches/DistributionExample.cmake13
-rw-r--r--docs/CMakeLists.txt2
-rw-r--r--docs/ClangFormatStyleOptions.rst52
-rw-r--r--docs/ThreadSafetyAnalysis.rst4
-rw-r--r--include/clang-c/Index.h19
-rw-r--r--include/clang/AST/CXXInheritance.h3
-rw-r--r--include/clang/AST/Decl.h11
-rw-r--r--include/clang/AST/DeclCXX.h25
-rw-r--r--include/clang/AST/ExternalASTMerger.h2
-rw-r--r--include/clang/AST/RecursiveASTVisitor.h2
-rw-r--r--include/clang/Basic/Attr.td24
-rw-r--r--include/clang/Basic/Builtins.def3
-rw-r--r--include/clang/Basic/DiagnosticGroups.td2
-rw-r--r--include/clang/Basic/DiagnosticSemaKinds.td28
-rw-r--r--include/clang/Basic/TargetOptions.h3
-rw-r--r--include/clang/Driver/Options.td3
-rw-r--r--include/clang/Driver/SanitizerArgs.h1
-rw-r--r--include/clang/Format/Format.h51
-rw-r--r--include/clang/Frontend/CodeGenOptions.def2
-rw-r--r--include/clang/Lex/MacroInfo.h21
-rw-r--r--include/clang/Lex/Preprocessor.h15
-rw-r--r--include/clang/Parse/Parser.h7
-rw-r--r--include/clang/Sema/Sema.h41
-rw-r--r--include/clang/Tooling/RefactoringCallbacks.h50
-rw-r--r--lib/AST/ASTImporter.cpp14
-rw-r--r--lib/AST/ASTStructuralEquivalence.cpp5
-rw-r--r--lib/AST/CXXInheritance.cpp114
-rw-r--r--lib/AST/DeclCXX.cpp5
-rw-r--r--lib/AST/ExternalASTMerger.cpp6
-rw-r--r--lib/AST/ODRHash.cpp2
-rw-r--r--lib/AST/Stmt.cpp2
-rw-r--r--lib/AST/Type.cpp7
-rw-r--r--lib/Basic/Targets.cpp5
-rw-r--r--lib/CodeGen/BackendUtil.cpp5
-rw-r--r--lib/CodeGen/CGBlocks.cpp13
-rw-r--r--lib/CodeGen/CGBuiltin.cpp34
-rw-r--r--lib/CodeGen/CGCUDANV.cpp2
-rw-r--r--lib/CodeGen/CGCleanup.cpp3
-rw-r--r--lib/CodeGen/CGDebugInfo.cpp23
-rw-r--r--lib/CodeGen/CGDebugInfo.h5
-rw-r--r--lib/CodeGen/CGDecl.cpp13
-rw-r--r--lib/CodeGen/CGException.cpp13
-rw-r--r--lib/CodeGen/CGExpr.cpp4
-rw-r--r--lib/CodeGen/CGExprAgg.cpp20
-rw-r--r--lib/CodeGen/CGExprConstant.cpp10
-rw-r--r--lib/CodeGen/CGExprScalar.cpp8
-rw-r--r--lib/CodeGen/CGObjCGNU.cpp134
-rw-r--r--lib/CodeGen/CGObjCMac.cpp170
-rw-r--r--lib/CodeGen/CGOpenMPRuntime.cpp2
-rw-r--r--lib/CodeGen/CodeGenAction.cpp10
-rw-r--r--lib/CodeGen/CodeGenModule.cpp2
-rw-r--r--lib/CodeGen/CodeGenTypes.cpp2
-rw-r--r--lib/CodeGen/ItaniumCXXABI.cpp2
-rw-r--r--lib/CodeGen/TargetInfo.cpp24
-rw-r--r--lib/Driver/SanitizerArgs.cpp33
-rw-r--r--lib/Driver/ToolChains/Arch/Mips.cpp16
-rw-r--r--lib/Driver/ToolChains/Myriad.cpp8
-rw-r--r--lib/Driver/ToolChains/WebAssembly.cpp5
-rw-r--r--lib/Format/ContinuationIndenter.cpp16
-rw-r--r--lib/Format/Format.cpp26
-rw-r--r--lib/Format/TokenAnnotator.cpp34
-rw-r--r--lib/Format/UnwrappedLineParser.cpp34
-rw-r--r--lib/Format/WhitespaceManager.cpp11
-rw-r--r--lib/Frontend/CompilerInvocation.cpp2
-rw-r--r--lib/Headers/avxintrin.h184
-rw-r--r--lib/Headers/emmintrin.h281
-rw-r--r--lib/Headers/intrin.h6
-rw-r--r--lib/Headers/mmintrin.h101
-rw-r--r--lib/Headers/opencl-c.h14
-rw-r--r--lib/Headers/pmmintrin.h8
-rw-r--r--lib/Headers/prfchwintrin.h6
-rw-r--r--lib/Headers/smmintrin.h10
-rw-r--r--lib/Headers/tmmintrin.h88
-rw-r--r--lib/Headers/x86intrin.h2
-rw-r--r--lib/Headers/xmmintrin.h28
-rw-r--r--lib/Index/IndexBody.cpp47
-rw-r--r--lib/Index/IndexDecl.cpp30
-rw-r--r--lib/Index/IndexTypeSourceInfo.cpp30
-rw-r--r--lib/Index/IndexingContext.cpp15
-rw-r--r--lib/Lex/MacroInfo.cpp2
-rw-r--r--lib/Lex/ModuleMap.cpp20
-rw-r--r--lib/Lex/PPDirectives.cpp27
-rw-r--r--lib/Lex/Preprocessor.cpp7
-rw-r--r--lib/Parse/ParseDecl.cpp11
-rw-r--r--lib/Parse/ParseDeclCXX.cpp8
-rw-r--r--lib/Parse/ParseExpr.cpp45
-rw-r--r--lib/Parse/ParseExprCXX.cpp7
-rw-r--r--lib/Parse/ParseTemplate.cpp16
-rw-r--r--lib/Sema/CMakeLists.txt1
-rw-r--r--lib/Sema/Sema.cpp32
-rw-r--r--lib/Sema/SemaCast.cpp3
-rw-r--r--lib/Sema/SemaCodeComplete.cpp94
-rw-r--r--lib/Sema/SemaDecl.cpp259
-rw-r--r--lib/Sema/SemaDeclAttr.cpp13
-rw-r--r--lib/Sema/SemaExpr.cpp242
-rw-r--r--lib/Sema/SemaExprCXX.cpp29
-rw-r--r--lib/Sema/SemaExprObjC.cpp3
-rw-r--r--lib/Sema/SemaInit.cpp40
-rw-r--r--lib/Sema/SemaLookup.cpp52
-rw-r--r--lib/Sema/SemaOverload.cpp6
-rw-r--r--lib/Sema/SemaStmt.cpp54
-rw-r--r--lib/Sema/SemaTemplate.cpp196
-rw-r--r--lib/Sema/SemaTemplateInstantiateDecl.cpp14
-rw-r--r--lib/Sema/SemaType.cpp5
-rw-r--r--lib/Serialization/ASTReader.cpp3
-rw-r--r--lib/Serialization/ASTWriter.cpp1
-rw-r--r--lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp46
-rw-r--r--lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp16
-rw-r--r--lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp4
-rw-r--r--lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp47
-rw-r--r--lib/StaticAnalyzer/Checkers/SelectorExtras.h40
-rw-r--r--lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp5
-rw-r--r--lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp3
-rw-r--r--lib/Tooling/RefactoringCallbacks.cpp154
-rw-r--r--test/Analysis/builtin-assume.c8
-rw-r--r--test/CXX/drs/dr20xx.cpp30
-rw-r--r--test/CXX/drs/dr4xx.cpp7
-rw-r--r--test/CodeCompletion/member-access.cpp80
-rw-r--r--test/CodeGen/asan-globals-gc.cpp15
-rw-r--r--test/CodeGen/asan-no-globals-no-comdat.cpp11
-rw-r--r--test/CodeGen/mips-aggregate-arg.c38
-rw-r--r--test/CodeGen/sanitize-recover.c10
-rw-r--r--test/CodeGen/sparcv8-inline-asm.c11
-rw-r--r--test/CodeGen/thinlto_backend.ll6
-rw-r--r--test/CodeGen/x86_64-mno-sse.c15
-rw-r--r--test/CodeGen/xray-customevent.cpp28
-rw-r--r--test/CodeGenCXX/array-default-argument.cpp36
-rw-r--r--test/CodeGenCXX/linetable-virtual-variadic.cpp6
-rw-r--r--test/CodeGenCXX/vla.cpp59
-rw-r--r--test/CodeGenObjC/arc-blocks.m10
-rw-r--r--test/CodeGenObjC/arc-foreach.m6
-rw-r--r--test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl20
-rw-r--r--test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl30
-rw-r--r--test/CodeGenOpenCL/constant-addr-space-globals.cl8
-rw-r--r--test/Driver/fsanitize.c9
-rw-r--r--test/Driver/myriad-toolchain.c4
-rw-r--r--test/Driver/wasm-toolchain.c6
-rw-r--r--test/FixIt/fixit-availability.c2
-rw-r--r--test/FixIt/fixit-availability.mm42
-rw-r--r--test/Import/conflicting-struct/Inputs/S1.cpp6
-rw-r--r--test/Import/conflicting-struct/Inputs/S2.cpp7
-rw-r--r--test/Import/conflicting-struct/test.cpp7
-rw-r--r--test/Index/Core/index-dependent-source.cpp143
-rw-r--r--test/Index/Core/index-instantiated-source.cpp39
-rw-r--r--test/Index/Core/index-source.cpp52
-rw-r--r--test/Index/complete-available.m20
-rw-r--r--test/Index/get-cursor.m11
-rw-r--r--test/Misc/warning-flags.c4
-rw-r--r--test/Modules/DebugInfoNamespace.cpp19
-rw-r--r--test/Modules/DebugInfoSubmoduleImport.c5
-rw-r--r--test/Modules/Inputs/DebugInfoNamespace/A.h3
-rw-r--r--test/Modules/Inputs/DebugInfoNamespace/B.h3
-rw-r--r--test/Modules/Inputs/DebugInfoNamespace/module.modulemap8
-rw-r--r--test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/B.h1
-rw-r--r--test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/Sub.h2
-rw-r--r--test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h1
-rw-r--r--test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h1
-rw-r--r--test/Modules/Inputs/MainA.framework/Headers/A.h1
-rw-r--r--test/Modules/Inputs/MainA.framework/Headers/Main.h2
-rw-r--r--test/Modules/Inputs/MainA.framework/Modules/module.modulemap12
-rw-r--r--test/Modules/Inputs/MainA.framework/Modules/module.private.modulemap12
-rw-r--r--test/Modules/Inputs/MainA.framework/PrivateHeaders/APriv.h1
-rw-r--r--test/Modules/Inputs/MainA.framework/PrivateHeaders/MainPriv.h1
-rw-r--r--test/Modules/Inputs/SameHeader/A.h3
-rw-r--r--test/Modules/Inputs/SameHeader/B.h4
-rw-r--r--test/Modules/Inputs/SameHeader/C.h12
-rw-r--r--test/Modules/Inputs/SameHeader/module.modulemap11
-rw-r--r--test/Modules/find-privateheaders.m13
-rw-r--r--test/Modules/odr_hash.cpp33
-rw-r--r--test/Modules/preprocess-module.cpp5
-rw-r--r--test/Modules/redefinition-same-header.m20
-rw-r--r--test/OpenMP/report_default_DSA.cpp18
-rw-r--r--test/PCH/cxx-templates.cpp8
-rw-r--r--test/PCH/cxx-templates.h3
-rw-r--r--test/Parser/objc-available.m6
-rw-r--r--test/Preprocessor/predefined-arch-macros.c8
-rw-r--r--test/Preprocessor/x86_target_features.c8
-rw-r--r--test/Sema/overloadable.c15
-rw-r--r--test/Sema/redefinition-same-header.c14
-rw-r--r--test/Sema/typo-correction.c7
-rw-r--r--test/Sema/vector-cast.c5
-rw-r--r--test/Sema/vector-gcc-compat.c330
-rw-r--r--test/Sema/vector-gcc-compat.cpp328
-rw-r--r--test/Sema/vector-ops.c140
-rw-r--r--test/Sema/zvector.c24
-rw-r--r--test/SemaCXX/constructor-initializer.cpp19
-rw-r--r--test/SemaCXX/cxx1y-generic-lambdas.cpp7
-rw-r--r--test/SemaCXX/cxx1y-variable-templates_top_level.cpp7
-rw-r--r--test/SemaCXX/enable_if.cpp14
-rw-r--r--test/SemaCXX/for-range-examples.cpp34
-rw-r--r--test/SemaCXX/invalid-member-expr.cpp4
-rw-r--r--test/SemaCXX/modules-ts.cppm3
-rw-r--r--test/SemaCXX/type-traits.cpp2
-rw-r--r--test/SemaCXX/typo-correction.cpp11
-rw-r--r--test/SemaCXX/vector-no-lax.cpp2
-rw-r--r--test/SemaCXX/warn-unused-filescoped.cpp18
-rw-r--r--test/SemaObjC/method-bad-param.m6
-rw-r--r--test/SemaObjC/unguarded-availability.m21
-rw-r--r--test/SemaObjCXX/interface-return-type.mm7
-rw-r--r--test/SemaObjCXX/is-base-of.mm25
-rw-r--r--test/SemaOpenCL/array-init.cl20
-rw-r--r--test/SemaOpenCL/storageclass.cl11
-rw-r--r--test/SemaTemplate/deduction-crash.cpp2
-rw-r--r--test/SemaTemplate/default-arguments.cpp16
-rw-r--r--test/SemaTemplate/explicit-instantiation.cpp2
-rw-r--r--test/SemaTemplate/explicit-specialization-member.cpp11
-rw-r--r--test/SemaTemplate/ms-lookup-template-base-classes.cpp3
-rw-r--r--test/SemaTemplate/typo-template-name.cpp43
-rw-r--r--tools/c-index-test/c-index-test.c13
-rw-r--r--tools/clang-import-test/clang-import-test.cpp46
-rw-r--r--tools/libclang/CIndex.cpp29
-rw-r--r--tools/libclang/libclang.exports1
-rw-r--r--unittests/Format/FormatTest.cpp104
-rw-r--r--unittests/Format/FormatTestJS.cpp69
-rw-r--r--unittests/Format/FormatTestSelective.cpp4
-rw-r--r--unittests/Tooling/RecursiveASTVisitorTest.cpp8
-rw-r--r--unittests/Tooling/RefactoringCallbacksTest.cpp91
-rw-r--r--www/cxx_dr_status.html690
220 files changed, 5201 insertions, 1618 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt
index ca696b1ce79f..9e43a103b2bc 100644
--- a/CMakeLists.txt
+++ b/CMakeLists.txt
@@ -579,10 +579,17 @@ if (CLANG_ENABLE_BOOTSTRAP)
add_dependencies(clang-bootstrap-deps compiler-rt)
endif()
+ set(C_COMPILER "clang")
+ set(CXX_COMPILER "clang++")
+ if(WIN32)
+ set(C_COMPILER "clang-cl.exe")
+ set(CXX_COMPILER "clang-cl.exe")
+ endif()
+
set(COMPILER_OPTIONS
- -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang++
- -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang
- -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/clang)
+ -DCMAKE_CXX_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${CXX_COMPILER}
+ -DCMAKE_C_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${C_COMPILER}
+ -DCMAKE_ASM_COMPILER=${LLVM_RUNTIME_OUTPUT_INTDIR}/${C_COMPILER})
if(BOOTSTRAP_LLVM_BUILD_INSTRUMENTED)
add_dependencies(clang-bootstrap-deps llvm-profdata)
diff --git a/cmake/caches/Apple-stage2.cmake b/cmake/caches/Apple-stage2.cmake
index 11c595c1530f..f07973dc0ab2 100644
--- a/cmake/caches/Apple-stage2.cmake
+++ b/cmake/caches/Apple-stage2.cmake
@@ -13,6 +13,7 @@ set(CLANG_LINKS_TO_CREATE clang++ cc c++ CACHE STRING "")
set(CMAKE_MACOSX_RPATH ON CACHE BOOL "")
set(LLVM_ENABLE_ZLIB ON CACHE BOOL "")
set(LLVM_ENABLE_BACKTRACES OFF CACHE BOOL "")
+set(LLVM_ENABLE_MODULES ON CACHE BOOL "")
set(LLVM_EXTERNALIZE_DEBUGINFO ON CACHE BOOL "")
set(CLANG_PLUGIN_SUPPORT OFF CACHE BOOL "")
set(BUG_REPORT_URL "http://developer.apple.com/bugreporter/" CACHE STRING "")
@@ -28,8 +29,10 @@ set(LLVM_BUILD_TESTS ON CACHE BOOL "")
set(LLVM_ENABLE_LTO ON CACHE BOOL "")
set(CMAKE_C_FLAGS "-fno-stack-protector -fno-common -Wno-profile-instr-unprofiled" CACHE STRING "")
set(CMAKE_CXX_FLAGS "-fno-stack-protector -fno-common -Wno-profile-instr-unprofiled" 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 "")
+if(LLVM_ENABLE_LTO AND NOT LLVM_ENABLE_LTO STREQUAL "THIN")
+ set(CMAKE_C_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
+ set(CMAKE_CXX_FLAGS_RELWITHDEBINFO "-O2 -gline-tables-only -DNDEBUG" CACHE STRING "")
+endif()
set(CMAKE_BUILD_TYPE RelWithDebInfo CACHE STRING "")
set(LIBCXX_INSTALL_LIBRARY OFF CACHE BOOL "")
diff --git a/cmake/caches/DistributionExample.cmake b/cmake/caches/DistributionExample.cmake
index 862f547c1656..551f4ee07eac 100644
--- a/cmake/caches/DistributionExample.cmake
+++ b/cmake/caches/DistributionExample.cmake
@@ -29,6 +29,13 @@ set(CLANG_BOOTSTRAP_TARGETS
# Setup the bootstrap build.
set(CLANG_ENABLE_BOOTSTRAP ON CACHE BOOL "")
-set(CLANG_BOOTSTRAP_CMAKE_ARGS
- -C ${CMAKE_CURRENT_LIST_DIR}/DistributionExample-stage2.cmake
- CACHE STRING "")
+
+if(STAGE2_CACHE_FILE)
+ set(CLANG_BOOTSTRAP_CMAKE_ARGS
+ -C ${STAGE2_CACHE_FILE}
+ CACHE STRING "")
+else()
+ set(CLANG_BOOTSTRAP_CMAKE_ARGS
+ -C ${CMAKE_CURRENT_LIST_DIR}/DistributionExample-stage2.cmake
+ CACHE STRING "")
+endif()
diff --git a/docs/CMakeLists.txt b/docs/CMakeLists.txt
index 13b79fdfa534..d2956c18f80c 100644
--- a/docs/CMakeLists.txt
+++ b/docs/CMakeLists.txt
@@ -91,8 +91,8 @@ endif()
endif()
if (LLVM_ENABLE_SPHINX)
+ include(AddSphinxTarget)
if (SPHINX_FOUND)
- include(AddSphinxTarget)
if (${SPHINX_OUTPUT_HTML})
add_sphinx_target(html clang)
add_custom_command(TARGET docs-clang-html POST_BUILD
diff --git a/docs/ClangFormatStyleOptions.rst b/docs/ClangFormatStyleOptions.rst
index ed628e370087..f54acd9b81dd 100644
--- a/docs/ClangFormatStyleOptions.rst
+++ b/docs/ClangFormatStyleOptions.rst
@@ -209,23 +209,45 @@ the configuration (without a prefix: ``Auto``).
float b = 23;
std::string ccc = 23;
-**AlignEscapedNewlinesLeft** (``bool``)
- If ``true``, aligns escaped newlines as far left as possible.
- Otherwise puts them into the right-most column.
+**AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``)
+ Options for aligning backslashes in escaped newlines.
- .. code-block:: c++
+ Possible values:
+
+ * ``ENAS_DontAlign`` (in configuration: ``DontAlign``)
+ Don't align escaped newlines.
+
+ .. code-block:: c++
+
+ #define A \
+ int aaaa; \
+ int b; \
+ int dddddddddd;
+
+ * ``ENAS_Left`` (in configuration: ``Left``)
+ Align escaped newlines as far left as possible.
+
+ .. code-block:: c++
+
+ true:
+ #define A \
+ int aaaa; \
+ int b; \
+ int dddddddddd;
+
+ false:
+
+ * ``ENAS_Right`` (in configuration: ``Right``)
+ Align escaped newlines in the right-most column.
+
+ .. code-block:: c++
+
+ #define A \
+ int aaaa; \
+ int b; \
+ int dddddddddd;
- true:
- #define A \
- int aaaa; \
- int b; \
- int dddddddddd;
- false:
- #define A \
- int aaaa; \
- int b; \
- int dddddddddd;
**AlignOperands** (``bool``)
If ``true``, horizontally align operands of binary and ternary
@@ -1525,7 +1547,7 @@ the configuration (without a prefix: ``Auto``).
Use C++03-compatible syntax.
* ``LS_Cpp11`` (in configuration: ``Cpp11``)
- Use features of C++11, C++14 and C++1z (e.g. ``A<A<int>>`` instead of
+ Use features of C++11, C++14 and C++1z (e.g. ``A<A<int>>`` instead of
``A<A<int> >``).
* ``LS_Auto`` (in configuration: ``Auto``)
diff --git a/docs/ThreadSafetyAnalysis.rst b/docs/ThreadSafetyAnalysis.rst
index 47cf4ef3994e..ea8e98a1884b 100644
--- a/docs/ThreadSafetyAnalysis.rst
+++ b/docs/ThreadSafetyAnalysis.rst
@@ -884,11 +884,11 @@ implementation.
// Deprecated.
#define PT_GUARDED_VAR \
- THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded)
+ THREAD_ANNOTATION_ATTRIBUTE__(pt_guarded_var)
// Deprecated.
#define GUARDED_VAR \
- THREAD_ANNOTATION_ATTRIBUTE__(guarded)
+ THREAD_ANNOTATION_ATTRIBUTE__(guarded_var)
// Replaced by REQUIRES
#define EXCLUSIVE_LOCKS_REQUIRED(...) \
diff --git a/include/clang-c/Index.h b/include/clang-c/Index.h
index c50ac1b6d248..462d9269f7ad 100644
--- a/include/clang-c/Index.h
+++ b/include/clang-c/Index.h
@@ -32,7 +32,7 @@
* compatible, thus CINDEX_VERSION_MAJOR is expected to remain stable.
*/
#define CINDEX_VERSION_MAJOR 0
-#define CINDEX_VERSION_MINOR 38
+#define CINDEX_VERSION_MINOR 39
#define CINDEX_VERSION_ENCODE(major, minor) ( \
((major) * 10000) \
@@ -4081,6 +4081,23 @@ CINDEX_LINKAGE unsigned clang_Cursor_isObjCOptional(CXCursor C);
CINDEX_LINKAGE unsigned clang_Cursor_isVariadic(CXCursor C);
/**
+ * \brief Returns non-zero if the given cursor points to a symbol marked with
+ * external_source_symbol attribute.
+ *
+ * \param language If non-NULL, and the attribute is present, will be set to
+ * the 'language' string from the attribute.
+ *
+ * \param definedIn If non-NULL, and the attribute is present, will be set to
+ * the 'definedIn' string from the attribute.
+ *
+ * \param isGenerated If non-NULL, and the attribute is present, will be set to
+ * non-zero if the 'generated_declaration' is set in the attribute.
+ */
+CINDEX_LINKAGE unsigned clang_Cursor_isExternalSymbol(CXCursor C,
+ CXString *language, CXString *definedIn,
+ unsigned *isGenerated);
+
+/**
* \brief Given a cursor that represents a declaration, return the associated
* comment's source range. The range may include multiple consecutive comments
* with whitespace in between.
diff --git a/include/clang/AST/CXXInheritance.h b/include/clang/AST/CXXInheritance.h
index 3cf058f26bc6..a7961ebe8ce6 100644
--- a/include/clang/AST/CXXInheritance.h
+++ b/include/clang/AST/CXXInheritance.h
@@ -161,7 +161,8 @@ class CXXBasePaths {
void ComputeDeclsFound();
bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
- CXXRecordDecl::BaseMatchesCallback BaseMatches);
+ CXXRecordDecl::BaseMatchesCallback BaseMatches,
+ bool LookupInDependent = false);
public:
typedef std::list<CXXBasePath>::iterator paths_iterator;
diff --git a/include/clang/AST/Decl.h b/include/clang/AST/Decl.h
index 573ea55de1fd..facef8e55f7a 100644
--- a/include/clang/AST/Decl.h
+++ b/include/clang/AST/Decl.h
@@ -966,9 +966,16 @@ public:
/// hasLocalStorage - Returns true if a variable with function scope
/// is a non-static local variable.
bool hasLocalStorage() const {
- if (getStorageClass() == SC_None)
+ if (getStorageClass() == SC_None) {
+ // OpenCL v1.2 s6.5.3: The __constant or constant address space name is
+ // used to describe variables allocated in global memory and which are
+ // accessed inside a kernel(s) as read-only variables. As such, variables
+ // in constant address space cannot have local storage.
+ if (getType().getAddressSpace() == LangAS::opencl_constant)
+ return false;
// Second check is for C++11 [dcl.stc]p4.
return !isFileVarDecl() && getTSCSpec() == TSCS_unspecified;
+ }
// Global Named Register (GNU extension)
if (getStorageClass() == SC_Register && !isLocalVarDeclOrParm())
@@ -2478,7 +2485,7 @@ public:
void setCapturedVLAType(const VariableArrayType *VLAType);
/// getParent - Returns the parent of this field declaration, which
- /// is the struct in which this method is defined.
+ /// is the struct in which this field is defined.
const RecordDecl *getParent() const {
return cast<RecordDecl>(getDeclContext());
}
diff --git a/include/clang/AST/DeclCXX.h b/include/clang/AST/DeclCXX.h
index 13921a132cfb..6965e8143ff6 100644
--- a/include/clang/AST/DeclCXX.h
+++ b/include/clang/AST/DeclCXX.h
@@ -1563,10 +1563,13 @@ public:
/// \param Paths used to record the paths from this class to its base class
/// subobjects that match the search criteria.
///
+ /// \param LookupInDependent can be set to true to extend the search to
+ /// dependent base classes.
+ ///
/// \returns true if there exists any path from this class to a base class
/// subobject that matches the search criteria.
- bool lookupInBases(BaseMatchesCallback BaseMatches,
- CXXBasePaths &Paths) const;
+ bool lookupInBases(BaseMatchesCallback BaseMatches, CXXBasePaths &Paths,
+ bool LookupInDependent = false) const;
/// \brief Base-class lookup callback that determines whether the given
/// base class specifier refers to a specific class declaration.
@@ -1608,6 +1611,16 @@ public:
CXXBasePath &Path, DeclarationName Name);
/// \brief Base-class lookup callback that determines whether there exists
+ /// a member with the given name.
+ ///
+ /// This callback can be used with \c lookupInBases() to find members
+ /// of the given name within a C++ class hierarchy, including dependent
+ /// classes.
+ static bool
+ FindOrdinaryMemberInDependentClasses(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path, DeclarationName Name);
+
+ /// \brief Base-class lookup callback that determines whether there exists
/// an OpenMP declare reduction member with the given name.
///
/// This callback can be used with \c lookupInBases() to find members
@@ -1633,6 +1646,14 @@ public:
/// \brief Get the indirect primary bases for this class.
void getIndirectPrimaryBases(CXXIndirectPrimaryBaseSet& Bases) const;
+ /// Performs an imprecise lookup of a dependent name in this class.
+ ///
+ /// This function does not follow strict semantic rules and should be used
+ /// only when lookup rules can be relaxed, e.g. indexing.
+ std::vector<const NamedDecl *>
+ lookupDependentName(const DeclarationName &Name,
+ llvm::function_ref<bool(const NamedDecl *ND)> Filter);
+
/// Renders and displays an inheritance diagram
/// for this C++ class and all of its base classes (transitively) using
/// GraphViz.
diff --git a/include/clang/AST/ExternalASTMerger.h b/include/clang/AST/ExternalASTMerger.h
index 51d0c30ad23b..55459df1fe6b 100644
--- a/include/clang/AST/ExternalASTMerger.h
+++ b/include/clang/AST/ExternalASTMerger.h
@@ -44,6 +44,8 @@ public:
FindExternalLexicalDecls(const DeclContext *DC,
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
SmallVectorImpl<Decl *> &Result) override;
+
+ void CompleteType(TagDecl *Tag) override;
};
} // end namespace clang
diff --git a/include/clang/AST/RecursiveASTVisitor.h b/include/clang/AST/RecursiveASTVisitor.h
index 1b5850a05b37..cd2a39449825 100644
--- a/include/clang/AST/RecursiveASTVisitor.h
+++ b/include/clang/AST/RecursiveASTVisitor.h
@@ -2326,7 +2326,7 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
}
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
- FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
+ FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
// Visit the whole type.
diff --git a/include/clang/Basic/Attr.td b/include/clang/Basic/Attr.td
index 3eeeb1bdc971..4eb958e3f4d5 100644
--- a/include/clang/Basic/Attr.td
+++ b/include/clang/Basic/Attr.td
@@ -652,6 +652,30 @@ def Availability : InheritableAttr {
.Case("tvos_app_extension", "tvOS (App Extension)")
.Case("watchos_app_extension", "watchOS (App Extension)")
.Default(llvm::StringRef());
+}
+static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
+ return llvm::StringSwitch<llvm::StringRef>(Platform)
+ .Case("ios", "iOS")
+ .Case("macos", "macOS")
+ .Case("tvos", "tvOS")
+ .Case("watchos", "watchOS")
+ .Case("ios_app_extension", "iOSApplicationExtension")
+ .Case("macos_app_extension", "macOSApplicationExtension")
+ .Case("tvos_app_extension", "tvOSApplicationExtension")
+ .Case("watchos_app_extension", "watchOSApplicationExtension")
+ .Default(Platform);
+}
+static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
+ return llvm::StringSwitch<llvm::StringRef>(Platform)
+ .Case("iOS", "ios")
+ .Case("macOS", "macos")
+ .Case("tvOS", "tvos")
+ .Case("watchOS", "watchos")
+ .Case("iOSApplicationExtension", "ios_app_extension")
+ .Case("macOSApplicationExtension", "macos_app_extension")
+ .Case("tvOSApplicationExtension", "tvos_app_extension")
+ .Case("watchOSApplicationExtension", "watchos_app_extension")
+ .Default(Platform);
} }];
let HasCustomParsing = 1;
let DuplicatesAllowedWhileMerging = 1;
diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def
index 816ea156f979..a9ec172422ab 100644
--- a/include/clang/Basic/Builtins.def
+++ b/include/clang/Basic/Builtins.def
@@ -1409,6 +1409,9 @@ LANGBUILTIN(to_private, "v*v*", "tn", OCLC20_LANG)
BUILTIN(__builtin_os_log_format_buffer_size, "zcC*.", "p:0:nut")
BUILTIN(__builtin_os_log_format, "v*v*cC*.", "p:0:nt")
+// Builtins for XRay
+BUILTIN(__xray_customevent, "vcC*z", "")
+
#undef BUILTIN
#undef LIBBUILTIN
#undef LANGBUILTIN
diff --git a/include/clang/Basic/DiagnosticGroups.td b/include/clang/Basic/DiagnosticGroups.td
index 05e03fab40fa..e1a41584023c 100644
--- a/include/clang/Basic/DiagnosticGroups.td
+++ b/include/clang/Basic/DiagnosticGroups.td
@@ -486,6 +486,7 @@ def UnneededInternalDecl : DiagGroup<"unneeded-internal-declaration">;
def UnneededMemberFunction : DiagGroup<"unneeded-member-function">;
def UnusedPrivateField : DiagGroup<"unused-private-field">;
def UnusedFunction : DiagGroup<"unused-function", [UnneededInternalDecl]>;
+def UnusedTemplate : DiagGroup<"unused-template", [UnneededInternalDecl]>;
def UnusedMemberFunction : DiagGroup<"unused-member-function",
[UnneededMemberFunction]>;
def UnusedLabel : DiagGroup<"unused-label">;
@@ -627,6 +628,7 @@ def Conversion : DiagGroup<"conversion",
def Unused : DiagGroup<"unused",
[UnusedArgument, UnusedFunction, UnusedLabel,
// UnusedParameter, (matches GCC's behavior)
+ // UnusedTemplate, (clean-up libc++ before enabling)
// UnusedMemberFunction, (clean-up llvm before enabling)
UnusedPrivateField, UnusedLambdaCapture,
UnusedLocalTypedef, UnusedValue, UnusedVariable,
diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td
index a0c0e5f86449..1db6704f6d1f 100644
--- a/include/clang/Basic/DiagnosticSemaKinds.td
+++ b/include/clang/Basic/DiagnosticSemaKinds.td
@@ -303,6 +303,8 @@ def note_empty_parens_zero_initialize : Note<
"replace parentheses with an initializer to declare a variable">;
def warn_unused_function : Warning<"unused function %0">,
InGroup<UnusedFunction>, DefaultIgnore;
+def warn_unused_template : Warning<"unused %select{function|variable}0 template %1">,
+ InGroup<UnusedTemplate>, DefaultIgnore;
def warn_unused_member_function : Warning<"unused member function %0">,
InGroup<UnusedMemberFunction>, DefaultIgnore;
def warn_used_but_marked_unused: Warning<"%0 was marked unused but was used">,
@@ -2463,6 +2465,9 @@ def err_attribute_invalid_size : Error<
"vector size not an integral multiple of component size">;
def err_attribute_zero_size : Error<"zero vector size">;
def err_attribute_size_too_large : Error<"vector size too large">;
+def err_typecheck_vector_not_convertable_implict_truncation : Error<
+ "cannot convert between %select{scalar|vector}0 type %1 and vector type"
+ " %2 as implicit conversion would cause truncation">;
def err_typecheck_vector_not_convertable : Error<
"cannot convert between vector values of different size (%0 and %1)">;
def err_typecheck_vector_not_convertable_non_scalar : Error<
@@ -4607,6 +4612,8 @@ def err_abi_tag_on_redeclaration : Error<
"cannot add 'abi_tag' attribute in a redeclaration">;
def err_new_abi_tag_on_redeclaration : Error<
"'abi_tag' %0 missing in original declaration">;
+def note_use_ifdef_guards : Note<
+ "unguarded header; consider using #ifdef guards or #pragma once">;
def note_deleted_dtor_no_operator_delete : Note<
"virtual destructor requires an unambiguous, accessible 'operator delete'">;
@@ -5775,6 +5782,9 @@ def err_objc_object_assignment : Error<
"cannot assign to class object (%0 invalid)">;
def err_typecheck_invalid_operands : Error<
"invalid operands to binary expression (%0 and %1)">;
+def err_typecheck_logical_vector_expr_gnu_cpp_restrict : Error<
+ "logical expression with vector %select{type %1 and non-vector type %2|types"
+ " %1 and %2}0 is only supported in C++">;
def err_typecheck_sub_ptr_compatible : Error<
"%diff{$ and $ are not pointers to compatible types|"
"pointers to incompatible types}0,1">;
@@ -8186,9 +8196,20 @@ def err_undeclared_use_suggest : Error<
"use of undeclared %0; did you mean %1?">;
def err_undeclared_var_use_suggest : Error<
"use of undeclared identifier %0; did you mean %1?">;
+def err_no_template : Error<"no template named %0">;
def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
+def err_no_member_template : Error<"no template named %0 in %1">;
def err_no_member_template_suggest : Error<
"no template named %0 in %1; did you mean %select{|simply }2%3?">;
+def err_non_template_in_template_id : Error<
+ "%0 does not name a template but is followed by template arguments">;
+def err_non_template_in_template_id_suggest : Error<
+ "%0 does not name a template but is followed by template arguments; "
+ "did you mean %1?">;
+def err_non_template_in_member_template_id_suggest : Error<
+ "member %0 of %1 is not a template; did you mean %select{|simply }2%3?">;
+def note_non_template_in_template_id_found : Note<
+ "non-template declaration found by name lookup">;
def err_mem_init_not_member_or_class_suggest : Error<
"initializer %0 does not name a non-static data member or base "
"class; did you mean the %select{base class|member}1 %2?">;
@@ -8875,6 +8896,13 @@ def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
InGroup<DiagGroup<"modules-ambiguous-internal-linkage">>;
def note_equivalent_internal_linkage_decl : Note<
"declared here%select{ in module '%1'|}0">;
+
+def note_redefinition_modules_same_file : Note<
+ "'%0' included multiple times, additional include site in header from module '%1'">;
+def note_redefinition_modules_same_file_modulemap : Note<
+ "consider adding '%0' as part of '%1' definition">;
+def note_redefinition_include_same_file : Note<
+ "'%0' included multiple times, additional include site here">;
}
let CategoryName = "Coroutines Issue" in {
diff --git a/include/clang/Basic/TargetOptions.h b/include/clang/Basic/TargetOptions.h
index 2889cce5963b..6ca1ba39c8fb 100644
--- a/include/clang/Basic/TargetOptions.h
+++ b/include/clang/Basic/TargetOptions.h
@@ -24,8 +24,7 @@ namespace clang {
/// \brief Options for controlling the target.
class TargetOptions {
public:
- /// If given, the name of the target triple to compile for. If not given the
- /// target will be selected to match the host.
+ /// The name of the target triple to compile for.
std::string Triple;
/// When compiling for the device side, contains the triple used to compile
diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td
index 31015228f362..d812bd8ec032 100644
--- a/include/clang/Driver/Options.td
+++ b/include/clang/Driver/Options.td
@@ -827,6 +827,9 @@ def fno_sanitize_address_use_after_scope : Flag<["-"], "fno-sanitize-address-use
Group<f_clang_Group>,
Flags<[CoreOption, DriverOption]>,
HelpText<"Disable use-after-scope detection in AddressSanitizer">;
+def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">,
+ Group<f_clang_Group>,
+ HelpText<"Enable linker dead stripping of globals in AddressSanitizer">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>;
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
Flags<[CoreOption, DriverOption]>,
diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h
index c7b3e8006dd5..a9645d463fa1 100644
--- a/include/clang/Driver/SanitizerArgs.h
+++ b/include/clang/Driver/SanitizerArgs.h
@@ -35,6 +35,7 @@ class SanitizerArgs {
int AsanFieldPadding = 0;
bool AsanSharedRuntime = false;
bool AsanUseAfterScope = true;
+ bool AsanGlobalsDeadStripping = false;
bool LinkCXXRuntimes = false;
bool NeedPIE = false;
bool Stats = false;
diff --git a/include/clang/Format/Format.h b/include/clang/Format/Format.h
index 9bed253baca2..a963c6369aa9 100644
--- a/include/clang/Format/Format.h
+++ b/include/clang/Format/Format.h
@@ -98,22 +98,39 @@ struct FormatStyle {
/// \endcode
bool AlignConsecutiveDeclarations;
- /// \brief If ``true``, aligns escaped newlines as far left as possible.
- /// Otherwise puts them into the right-most column.
- /// \code
- /// true:
- /// #define A \
- /// int aaaa; \
- /// int b; \
- /// int dddddddddd;
- ///
- /// false:
- /// #define A \
- /// int aaaa; \
- /// int b; \
- /// int dddddddddd;
- /// \endcode
- bool AlignEscapedNewlinesLeft;
+ /// \brief Different styles for aligning escaped newlines.
+ enum EscapedNewlineAlignmentStyle {
+ /// \brief Don't align escaped newlines.
+ /// \code
+ /// #define A \
+ /// int aaaa; \
+ /// int b; \
+ /// int dddddddddd;
+ /// \endcode
+ ENAS_DontAlign,
+ /// \brief Align escaped newlines as far left as possible.
+ /// \code
+ /// true:
+ /// #define A \
+ /// int aaaa; \
+ /// int b; \
+ /// int dddddddddd;
+ ///
+ /// false:
+ /// \endcode
+ ENAS_Left,
+ /// \brief Align escaped newlines in the right-most column.
+ /// \code
+ /// #define A \
+ /// int aaaa; \
+ /// int b; \
+ /// int dddddddddd;
+ /// \endcode
+ ENAS_Right,
+ };
+
+ /// \brief Options for aligning backslashes in escaped newlines.
+ EscapedNewlineAlignmentStyle AlignEscapedNewlines;
/// \brief If ``true``, horizontally align operands of binary and ternary
/// expressions.
@@ -1347,7 +1364,7 @@ struct FormatStyle {
AlignAfterOpenBracket == R.AlignAfterOpenBracket &&
AlignConsecutiveAssignments == R.AlignConsecutiveAssignments &&
AlignConsecutiveDeclarations == R.AlignConsecutiveDeclarations &&
- AlignEscapedNewlinesLeft == R.AlignEscapedNewlinesLeft &&
+ AlignEscapedNewlines == R.AlignEscapedNewlines &&
AlignOperands == R.AlignOperands &&
AlignTrailingComments == R.AlignTrailingComments &&
AllowAllParametersOfDeclarationOnNextLine ==
diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def
index 7495ad808c99..251441d38ff8 100644
--- a/include/clang/Frontend/CodeGenOptions.def
+++ b/include/clang/Frontend/CodeGenOptions.def
@@ -137,6 +137,8 @@ CODEGENOPT(StructPathTBAA , 1, 0) ///< Whether or not to use struct-path TBAA
CODEGENOPT(SaveTempLabels , 1, 0) ///< Save temporary labels.
CODEGENOPT(SanitizeAddressUseAfterScope , 1, 0) ///< Enable use-after-scope detection
///< in AddressSanitizer
+CODEGENOPT(SanitizeAddressGlobalsDeadStripping, 1, 0) ///< Enable linker dead stripping
+ ///< of globals in AddressSanitizer
CODEGENOPT(SanitizeMemoryTrackOrigins, 2, 0) ///< Enable tracking origins in
///< MemorySanitizer
CODEGENOPT(SanitizeMemoryUseAfterDtor, 1, 0) ///< Enable use-after-delete detection
diff --git a/include/clang/Lex/MacroInfo.h b/include/clang/Lex/MacroInfo.h
index 44b7b2e4a474..7da1e7b41ab8 100644
--- a/include/clang/Lex/MacroInfo.h
+++ b/include/clang/Lex/MacroInfo.h
@@ -105,9 +105,6 @@ class MacroInfo {
/// \brief Must warn if the macro is unused at the end of translation unit.
bool IsWarnIfUnused : 1;
- /// \brief Whether this macro info was loaded from an AST file.
- bool FromASTFile : 1;
-
/// \brief Whether this macro was used as header guard.
bool UsedForHeaderGuard : 1;
@@ -264,34 +261,16 @@ public:
IsDisabled = true;
}
- /// \brief Determine whether this macro info came from an AST file (such as
- /// a precompiled header or module) rather than having been parsed.
- bool isFromASTFile() const { return FromASTFile; }
-
/// \brief Determine whether this macro was used for a header guard.
bool isUsedForHeaderGuard() const { return UsedForHeaderGuard; }
void setUsedForHeaderGuard(bool Val) { UsedForHeaderGuard = Val; }
- /// \brief Retrieve the global ID of the module that owns this particular
- /// macro info.
- unsigned getOwningModuleID() const {
- if (isFromASTFile())
- return *(const unsigned *)(this + 1);
-
- return 0;
- }
-
void dump() const;
private:
unsigned getDefinitionLengthSlow(const SourceManager &SM) const;
- void setOwningModuleID(unsigned ID) {
- assert(isFromASTFile());
- *(unsigned *)(this + 1) = ID;
- }
-
friend class Preprocessor;
};
diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h
index 0e3f563785d4..114bf70ad59a 100644
--- a/include/clang/Lex/Preprocessor.h
+++ b/include/clang/Lex/Preprocessor.h
@@ -644,14 +644,6 @@ class Preprocessor {
/// of that list.
MacroInfoChain *MIChainHead;
- struct DeserializedMacroInfoChain {
- MacroInfo MI;
- unsigned OwningModuleID; // MUST be immediately after the MacroInfo object
- // so it can be accessed by MacroInfo::getOwningModuleID().
- DeserializedMacroInfoChain *Next;
- };
- DeserializedMacroInfoChain *DeserialMIChainHead;
-
void updateOutOfDateIdentifier(IdentifierInfo &II) const;
public:
@@ -1669,10 +1661,6 @@ public:
/// \brief Allocate a new MacroInfo object with the provided SourceLocation.
MacroInfo *AllocateMacroInfo(SourceLocation L);
- /// \brief Allocate a new MacroInfo object loaded from an AST file.
- MacroInfo *AllocateDeserializedMacroInfo(SourceLocation L,
- unsigned SubModuleID);
-
/// \brief Turn the specified lexer token into a fully checked and spelled
/// filename, e.g. as an operand of \#include.
///
@@ -1764,9 +1752,6 @@ private:
/// macro name.
void updateModuleMacroInfo(const IdentifierInfo *II, ModuleMacroInfo &Info);
- /// \brief Allocate a new MacroInfo object.
- MacroInfo *AllocateMacroInfo();
-
DefMacroDirective *AllocateDefMacroDirective(MacroInfo *MI,
SourceLocation Loc);
UndefMacroDirective *AllocateUndefMacroDirective(SourceLocation UndefLoc);
diff --git a/include/clang/Parse/Parser.h b/include/clang/Parse/Parser.h
index 8d0935dec1b6..f5a7e02941a7 100644
--- a/include/clang/Parse/Parser.h
+++ b/include/clang/Parse/Parser.h
@@ -1488,6 +1488,8 @@ private:
K == tok::plusplus || K == tok::minusminus);
}
+ bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
+
ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
ExprResult ParseUnaryExprOrTypeTraitExpression();
ExprResult ParseBuiltinPrimaryExpression();
@@ -2723,10 +2725,7 @@ private:
bool ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
bool ConsumeLastToken,
bool ObjCGenericList);
- bool ParseTemplateIdAfterTemplateName(TemplateTy Template,
- SourceLocation TemplateNameLoc,
- const CXXScopeSpec &SS,
- bool ConsumeLastToken,
+ bool ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
SourceLocation &LAngleLoc,
TemplateArgList &TemplateArgs,
SourceLocation &RAngleLoc);
diff --git a/include/clang/Sema/Sema.h b/include/clang/Sema/Sema.h
index e5961079f7c2..e910be14f969 100644
--- a/include/clang/Sema/Sema.h
+++ b/include/clang/Sema/Sema.h
@@ -1074,6 +1074,10 @@ public:
/// correctly named definition after the renamed definition.
llvm::SmallPtrSet<const NamedDecl *, 4> TypoCorrectedFunctionDefinitions;
+ /// Stack of types that correspond to the parameter entities that are
+ /// currently being copy-initialized. Can be empty.
+ llvm::SmallVector<QualType, 4> CurrentParameterCopyTypes;
+
void ReadMethodPool(Selector Sel);
void updateOutOfDateSelector(Selector Sel);
@@ -1456,6 +1460,11 @@ private:
/// The modules we're currently parsing.
llvm::SmallVector<ModuleScope, 16> ModuleScopes;
+ /// Get the module whose scope we are currently within.
+ Module *getCurrentModule() const {
+ return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module;
+ }
+
VisibleModuleSet VisibleModules;
Module *CachedFakeTopLevelModule;
@@ -1466,7 +1475,7 @@ public:
/// \brief Make a merged definition of an existing hidden definition \p ND
/// visible at the specified location.
- void makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc);
+ void makeMergedDefinitionVisible(NamedDecl *ND);
bool isModuleVisible(Module *M) { return VisibleModules.isVisible(M); }
@@ -1593,7 +1602,7 @@ public:
Scope *S,
CXXScopeSpec *SS,
ParsedType &SuggestedType,
- bool AllowClassTemplates = false);
+ bool IsTemplateName = false);
/// Attempt to behave like MSVC in situations where lookup of an unqualified
/// type name has failed in a dependent context. In these situations, we
@@ -1738,6 +1747,23 @@ public:
TemplateNameKindForDiagnostics
getTemplateNameKindForDiagnostics(TemplateName Name);
+ /// Determine whether it's plausible that E was intended to be a
+ /// template-name.
+ bool mightBeIntendedToBeTemplateName(ExprResult E) {
+ if (!getLangOpts().CPlusPlus || E.isInvalid())
+ return false;
+ if (auto *DRE = dyn_cast<DeclRefExpr>(E.get()))
+ return !DRE->hasExplicitTemplateArgs();
+ if (auto *ME = dyn_cast<MemberExpr>(E.get()))
+ return !ME->hasExplicitTemplateArgs();
+ // Any additional cases recognized here should also be handled by
+ // diagnoseExprIntendedAsTemplateName.
+ return false;
+ }
+ void diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName,
+ SourceLocation Less,
+ SourceLocation Greater);
+
Decl *ActOnDeclarator(Scope *S, Declarator &D);
NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
@@ -2336,6 +2362,7 @@ public:
void MergeVarDeclTypes(VarDecl *New, VarDecl *Old, bool MergeTypeWithOld);
void MergeVarDeclExceptionSpecs(VarDecl *New, VarDecl *Old);
bool checkVarDeclRedefinition(VarDecl *OldDefn, VarDecl *NewDefn);
+ void notePreviousDefinition(SourceLocation Old, SourceLocation New);
bool MergeCXXFunctionDecl(FunctionDecl *New, FunctionDecl *Old, Scope *S);
// AssignmentAction - This is used by all the assignment diagnostic functions
@@ -2726,7 +2753,8 @@ public:
resolveAddressOfOnlyViableOverloadCandidate(Expr *E,
DeclAccessPair &FoundResult);
- bool resolveAndFixAddressOfOnlyViableOverloadCandidate(ExprResult &SrcExpr);
+ bool resolveAndFixAddressOfOnlyViableOverloadCandidate(
+ ExprResult &SrcExpr, bool DoFunctionPointerConversion = false);
FunctionDecl *
ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
@@ -3049,7 +3077,8 @@ public:
bool IncludeGlobalScope = true);
void LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
VisibleDeclConsumer &Consumer,
- bool IncludeGlobalScope = true);
+ bool IncludeGlobalScope = true,
+ bool IncludeDependentBases = false);
enum CorrectTypoKind {
CTK_NonError, // CorrectTypo used in a non error recovery situation.
@@ -6084,6 +6113,7 @@ public:
TemplateArgumentListInfo *ExplicitTemplateArgs,
LookupResult &Previous);
bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
+ void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
DeclResult
ActOnExplicitInstantiation(Scope *S,
@@ -9259,6 +9289,8 @@ public:
/// type checking binary operators (subroutines of CreateBuiltinBinOp).
QualType InvalidOperands(SourceLocation Loc, ExprResult &LHS,
ExprResult &RHS);
+ QualType InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,
+ ExprResult &RHS);
QualType CheckPointerToMemberOperands( // C++ 5.5
ExprResult &LHS, ExprResult &RHS, ExprValueKind &VK,
SourceLocation OpLoc, bool isIndirect);
@@ -10008,6 +10040,7 @@ public:
MacroInfo *MacroInfo,
unsigned Argument);
void CodeCompleteNaturalLanguage();
+ void CodeCompleteAvailabilityPlatformName();
void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo,
SmallVectorImpl<CodeCompletionResult> &Results);
diff --git a/include/clang/Tooling/RefactoringCallbacks.h b/include/clang/Tooling/RefactoringCallbacks.h
index 6ef9ea11f0ae..9862951149a3 100644
--- a/include/clang/Tooling/RefactoringCallbacks.h
+++ b/include/clang/Tooling/RefactoringCallbacks.h
@@ -47,6 +47,33 @@ protected:
Replacements Replace;
};
+/// \brief Adaptor between \c ast_matchers::MatchFinder and \c
+/// tooling::RefactoringTool.
+///
+/// Runs AST matchers and stores the \c tooling::Replacements in a map.
+class ASTMatchRefactorer {
+public:
+ explicit ASTMatchRefactorer(
+ std::map<std::string, Replacements> &FileToReplaces);
+
+ template <typename T>
+ void addMatcher(const T &Matcher, RefactoringCallback *Callback) {
+ MatchFinder.addMatcher(Matcher, Callback);
+ Callbacks.push_back(Callback);
+ }
+
+ void addDynamicMatcher(const ast_matchers::internal::DynTypedMatcher &Matcher,
+ RefactoringCallback *Callback);
+
+ std::unique_ptr<ASTConsumer> newASTConsumer();
+
+private:
+ friend class RefactoringASTConsumer;
+ std::vector<RefactoringCallback *> Callbacks;
+ ast_matchers::MatchFinder MatchFinder;
+ std::map<std::string, Replacements> &FileToReplaces;
+};
+
/// \brief Replace the text of the statement bound to \c FromId with the text in
/// \c ToText.
class ReplaceStmtWithText : public RefactoringCallback {
@@ -59,6 +86,29 @@ private:
std::string ToText;
};
+/// \brief Replace the text of an AST node bound to \c FromId with the result of
+/// evaluating the template in \c ToTemplate.
+///
+/// Expressions of the form ${NodeName} in \c ToTemplate will be
+/// replaced by the text of the node bound to ${NodeName}. The string
+/// "$$" will be replaced by "$".
+class ReplaceNodeWithTemplate : public RefactoringCallback {
+public:
+ static llvm::Expected<std::unique_ptr<ReplaceNodeWithTemplate>>
+ create(StringRef FromId, StringRef ToTemplate);
+ void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
+
+private:
+ struct TemplateElement {
+ enum { Literal, Identifier } Type;
+ std::string Value;
+ };
+ ReplaceNodeWithTemplate(llvm::StringRef FromId,
+ std::vector<TemplateElement> Template);
+ std::string FromId;
+ std::vector<TemplateElement> Template;
+};
+
/// \brief Replace the text of the statement bound to \c FromId with the text of
/// the statement bound to \c ToId.
class ReplaceStmtWithStmt : public RefactoringCallback {
diff --git a/lib/AST/ASTImporter.cpp b/lib/AST/ASTImporter.cpp
index 4fb6051d6f58..847638b7bbeb 100644
--- a/lib/AST/ASTImporter.cpp
+++ b/lib/AST/ASTImporter.cpp
@@ -1622,10 +1622,18 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
// We may already have a record of the same name; try to find and match it.
RecordDecl *AdoptDecl = nullptr;
+ RecordDecl *PrevDecl = nullptr;
if (!DC->isFunctionOrMethod()) {
SmallVector<NamedDecl *, 4> ConflictingDecls;
SmallVector<NamedDecl *, 2> FoundDecls;
DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
+
+ if (!FoundDecls.empty()) {
+ // We're going to have to compare D against potentially conflicting Decls, so complete it.
+ if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
+ D->getASTContext().getExternalSource()->CompleteType(D);
+ }
+
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
continue;
@@ -1652,6 +1660,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
}
}
+ PrevDecl = FoundRecord;
+
if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
if ((SearchName && !D->isCompleteDefinition())
|| (D->isCompleteDefinition() &&
@@ -1744,6 +1754,10 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
LexicalDC->addDeclInternal(D2);
if (D->isAnonymousStructOrUnion())
D2->setAnonymousStructOrUnion(true);
+ if (PrevDecl) {
+ // FIXME: do this for all Redeclarables, not just RecordDecls.
+ D2->setPreviousDecl(PrevDecl);
+ }
}
Importer.Imported(D, D2);
diff --git a/lib/AST/ASTStructuralEquivalence.cpp b/lib/AST/ASTStructuralEquivalence.cpp
index 8fe72eac4133..9376ee1d4ee4 100644
--- a/lib/AST/ASTStructuralEquivalence.cpp
+++ b/lib/AST/ASTStructuralEquivalence.cpp
@@ -855,6 +855,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
+ if (D1CXX->hasExternalLexicalStorage() &&
+ !D1CXX->isCompleteDefinition()) {
+ D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
+ }
+
if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
if (Context.Complain) {
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
diff --git a/lib/AST/CXXInheritance.cpp b/lib/AST/CXXInheritance.cpp
index 56fb0464078f..746602d47be5 100644
--- a/lib/AST/CXXInheritance.cpp
+++ b/lib/AST/CXXInheritance.cpp
@@ -13,6 +13,7 @@
#include "clang/AST/CXXInheritance.h"
#include "clang/AST/ASTContext.h"
#include "clang/AST/DeclCXX.h"
+#include "clang/AST/DeclTemplate.h"
#include "clang/AST/RecordLayout.h"
#include "llvm/ADT/SetVector.h"
#include <algorithm>
@@ -174,9 +175,10 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches,
return AllMatches;
}
-bool CXXBasePaths::lookupInBases(
- ASTContext &Context, const CXXRecordDecl *Record,
- CXXRecordDecl::BaseMatchesCallback BaseMatches) {
+bool CXXBasePaths::lookupInBases(ASTContext &Context,
+ const CXXRecordDecl *Record,
+ CXXRecordDecl::BaseMatchesCallback BaseMatches,
+ bool LookupInDependent) {
bool FoundPath = false;
// The access of the path down to this record.
@@ -194,7 +196,7 @@ bool CXXBasePaths::lookupInBases(
// the base class scope is not examined during unqualified name lookup
// either at the point of definition of the class template or member or
// during an instantiation of the class tem- plate or member.
- if (BaseType->isDependentType())
+ if (!LookupInDependent && BaseType->isDependentType())
continue;
// Determine whether we need to visit this base class at all,
@@ -262,10 +264,28 @@ bool CXXBasePaths::lookupInBases(
return FoundPath;
}
} else if (VisitBase) {
- CXXRecordDecl *BaseRecord
- = cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
- ->getDecl());
- if (lookupInBases(Context, BaseRecord, BaseMatches)) {
+ CXXRecordDecl *BaseRecord;
+ if (LookupInDependent) {
+ BaseRecord = nullptr;
+ const TemplateSpecializationType *TST =
+ BaseSpec.getType()->getAs<TemplateSpecializationType>();
+ if (!TST) {
+ if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
+ BaseRecord = cast<CXXRecordDecl>(RT->getDecl());
+ } else {
+ TemplateName TN = TST->getTemplateName();
+ if (auto *TD =
+ dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()))
+ BaseRecord = TD->getTemplatedDecl();
+ }
+ if (BaseRecord && !BaseRecord->hasDefinition())
+ BaseRecord = nullptr;
+ } else {
+ BaseRecord = cast<CXXRecordDecl>(
+ BaseSpec.getType()->castAs<RecordType>()->getDecl());
+ }
+ if (BaseRecord &&
+ lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) {
// C++ [class.member.lookup]p2:
// A member name f in one sub-object B hides a member name f in
// a sub-object A if A is a base class sub-object of B. Any
@@ -299,9 +319,11 @@ bool CXXBasePaths::lookupInBases(
}
bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
- CXXBasePaths &Paths) const {
+ CXXBasePaths &Paths,
+ bool LookupInDependent) const {
// If we didn't find anything, report that.
- if (!Paths.lookupInBases(getASTContext(), this, BaseMatches))
+ if (!Paths.lookupInBases(getASTContext(), this, BaseMatches,
+ LookupInDependent))
return false;
// If we're not recording paths or we won't ever find ambiguities,
@@ -387,23 +409,49 @@ bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
return false;
}
-bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
- CXXBasePath &Path,
- DeclarationName Name) {
- RecordDecl *BaseRecord =
- Specifier->getType()->castAs<RecordType>()->getDecl();
-
- const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
+static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path,
+ DeclarationName Name) {
+ const unsigned IDNS = clang::Decl::IDNS_Ordinary | clang::Decl::IDNS_Tag |
+ clang::Decl::IDNS_Member;
for (Path.Decls = BaseRecord->lookup(Name);
!Path.Decls.empty();
Path.Decls = Path.Decls.slice(1)) {
if (Path.Decls.front()->isInIdentifierNamespace(IDNS))
return true;
}
-
+
return false;
}
+bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
+ CXXBasePath &Path,
+ DeclarationName Name) {
+ RecordDecl *BaseRecord =
+ Specifier->getType()->castAs<RecordType>()->getDecl();
+ return findOrdinaryMember(BaseRecord, Path, Name);
+}
+
+bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
+ const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
+ DeclarationName Name) {
+ const TemplateSpecializationType *TST =
+ Specifier->getType()->getAs<TemplateSpecializationType>();
+ if (!TST) {
+ auto *RT = Specifier->getType()->getAs<RecordType>();
+ if (!RT)
+ return false;
+ return findOrdinaryMember(RT->getDecl(), Path, Name);
+ }
+ TemplateName TN = TST->getTemplateName();
+ const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+ if (!TD)
+ return false;
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ if (!RD)
+ return false;
+ return findOrdinaryMember(RD, Path, Name);
+}
+
bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
CXXBasePath &Path,
DeclarationName Name) {
@@ -438,6 +486,36 @@ FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
return false;
}
+std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName(
+ const DeclarationName &Name,
+ llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
+ std::vector<const NamedDecl *> Results;
+ // Lookup in the class.
+ DeclContext::lookup_result DirectResult = lookup(Name);
+ if (!DirectResult.empty()) {
+ for (const NamedDecl *ND : DirectResult) {
+ if (Filter(ND))
+ Results.push_back(ND);
+ }
+ return Results;
+ }
+ // Perform lookup into our base classes.
+ CXXBasePaths Paths;
+ Paths.setOrigin(this);
+ if (!lookupInBases(
+ [&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
+ return CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
+ Specifier, Path, Name);
+ },
+ Paths, /*LookupInDependent=*/true))
+ return Results;
+ for (const NamedDecl *ND : Paths.front().Decls) {
+ if (Filter(ND))
+ Results.push_back(ND);
+ }
+ return Results;
+}
+
void OverridingMethods::add(unsigned OverriddenSubobject,
UniqueVirtualMethod Overriding) {
SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides
diff --git a/lib/AST/DeclCXX.cpp b/lib/AST/DeclCXX.cpp
index dd8f768c5711..9f87fe12a9cd 100644
--- a/lib/AST/DeclCXX.cpp
+++ b/lib/AST/DeclCXX.cpp
@@ -1432,8 +1432,9 @@ bool CXXRecordDecl::isAnyDestructorNoReturn() const {
// Check base classes destructor for noreturn.
for (const auto &Base : bases())
- if (Base.getType()->getAsCXXRecordDecl()->isAnyDestructorNoReturn())
- return true;
+ if (const CXXRecordDecl *RD = Base.getType()->getAsCXXRecordDecl())
+ if (RD->isAnyDestructorNoReturn())
+ return true;
// Check fields for noreturn.
for (const auto *Field : fields())
diff --git a/lib/AST/ExternalASTMerger.cpp b/lib/AST/ExternalASTMerger.cpp
index 8849cfc3c80b..1dc472a5f753 100644
--- a/lib/AST/ExternalASTMerger.cpp
+++ b/lib/AST/ExternalASTMerger.cpp
@@ -178,3 +178,9 @@ void ExternalASTMerger::FindExternalLexicalDecls(
}
});
}
+
+void ExternalASTMerger::CompleteType(TagDecl *Tag) {
+ SmallVector<Decl *, 0> Result;
+ FindExternalLexicalDecls(Tag, [](Decl::Kind) { return true; }, Result);
+ Tag->setHasExternalLexicalStorage(false);
+}
diff --git a/lib/AST/ODRHash.cpp b/lib/AST/ODRHash.cpp
index 83168d0924f6..f4d314a6dd0d 100644
--- a/lib/AST/ODRHash.cpp
+++ b/lib/AST/ODRHash.cpp
@@ -411,7 +411,7 @@ public:
void VisitTypedefType(const TypedefType *T) {
AddDecl(T->getDecl());
- Hash.AddQualType(T->getDecl()->getUnderlyingType());
+ AddQualType(T->getDecl()->getUnderlyingType().getCanonicalType());
VisitType(T);
}
};
diff --git a/lib/AST/Stmt.cpp b/lib/AST/Stmt.cpp
index 69e65f558f89..2367cadf645c 100644
--- a/lib/AST/Stmt.cpp
+++ b/lib/AST/Stmt.cpp
@@ -1112,7 +1112,7 @@ void CapturedStmt::setCapturedRegionKind(CapturedRegionKind Kind) {
bool CapturedStmt::capturesVariable(const VarDecl *Var) const {
for (const auto &I : captures()) {
- if (!I.capturesVariable())
+ if (!I.capturesVariable() && !I.capturesVariableByCopy())
continue;
// This does not handle variable redeclarations. This should be
diff --git a/lib/AST/Type.cpp b/lib/AST/Type.cpp
index df26233b4796..22d52bcd3f31 100644
--- a/lib/AST/Type.cpp
+++ b/lib/AST/Type.cpp
@@ -2114,18 +2114,15 @@ bool QualType::isTriviallyCopyableType(const ASTContext &Context) const {
if (hasNonTrivialObjCLifetime())
return false;
- // C++11 [basic.types]p9
+ // C++11 [basic.types]p9 - See Core 2094
// Scalar types, trivially copyable class types, arrays of such types, and
- // non-volatile const-qualified versions of these types are collectively
+ // cv-qualified versions of these types are collectively
// called trivially copyable types.
QualType CanonicalType = getCanonicalType();
if (CanonicalType->isDependentType())
return false;
- if (CanonicalType.isVolatileQualified())
- return false;
-
// Return false for incomplete types after skipping any incomplete array types
// which are expressly allowed by the standard and thus our API.
if (CanonicalType->isIncompleteType())
diff --git a/lib/Basic/Targets.cpp b/lib/Basic/Targets.cpp
index 33eb0b05ddcd..92c561aa9413 100644
--- a/lib/Basic/Targets.cpp
+++ b/lib/Basic/Targets.cpp
@@ -6862,6 +6862,11 @@ public:
case 'N': // Same as 'K' but zext (required for SIMode)
case 'O': // The constant 4096
return true;
+
+ case 'f':
+ case 'e':
+ info.setAllowsRegister();
+ return true;
}
return false;
}
diff --git a/lib/CodeGen/BackendUtil.cpp b/lib/CodeGen/BackendUtil.cpp
index 0d96f2efa60a..0f07169ac8b0 100644
--- a/lib/CodeGen/BackendUtil.cpp
+++ b/lib/CodeGen/BackendUtil.cpp
@@ -194,6 +194,8 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
// where this is not a factor). Also, on ELF this feature requires an assembler
// extension that only works with -integrated-as at the moment.
static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
+ if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
+ return false;
switch (T.getObjectFormat()) {
case Triple::MachO:
case Triple::COFF:
@@ -1071,7 +1073,8 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
// into memory and pass it into runThinLTOBackend, which will run the
// function importer and invoke LTO passes.
Expected<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
- llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile);
+ llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile,
+ /*IgnoreEmptyThinLTOIndexFile*/true);
if (!IndexOrErr) {
logAllUnhandledErrors(IndexOrErr.takeError(), errs(),
"Error loading index file '" +
diff --git a/lib/CodeGen/CGBlocks.cpp b/lib/CodeGen/CGBlocks.cpp
index 2b2a92dd6019..f1c20e9df1f3 100644
--- a/lib/CodeGen/CGBlocks.cpp
+++ b/lib/CodeGen/CGBlocks.cpp
@@ -878,7 +878,8 @@ llvm::Value *CodeGenFunction::EmitBlockLiteral(const CGBlockInfo &blockInfo) {
// If type is const-qualified, copy the value into the block field.
} else if (type.isConstQualified() &&
- type.getObjCLifetime() == Qualifiers::OCL_Strong) {
+ type.getObjCLifetime() == Qualifiers::OCL_Strong &&
+ CGM.getCodeGenOpts().OptimizationLevel != 0) {
llvm::Value *value = Builder.CreateLoad(src, "captured");
Builder.CreateStore(value, blockField);
@@ -960,9 +961,8 @@ llvm::Type *CodeGenModule::getBlockDescriptorType() {
// const char *signature; // the block signature
// const char *layout; // reserved
// };
- BlockDescriptorType =
- llvm::StructType::create("struct.__block_descriptor",
- UnsignedLongTy, UnsignedLongTy, nullptr);
+ BlockDescriptorType = llvm::StructType::create(
+ "struct.__block_descriptor", UnsignedLongTy, UnsignedLongTy);
// Now form a pointer to that.
unsigned AddrSpace = 0;
@@ -986,9 +986,8 @@ llvm::Type *CodeGenModule::getGenericBlockLiteralType() {
// struct __block_descriptor *__descriptor;
// };
GenericBlockLiteralType =
- llvm::StructType::create("struct.__block_literal_generic",
- VoidPtrTy, IntTy, IntTy, VoidPtrTy,
- BlockDescPtrTy, nullptr);
+ llvm::StructType::create("struct.__block_literal_generic", VoidPtrTy,
+ IntTy, IntTy, VoidPtrTy, BlockDescPtrTy);
return GenericBlockLiteralType;
}
diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp
index 2f05c0e910e5..50c9e22801c7 100644
--- a/lib/CodeGen/CGBuiltin.cpp
+++ b/lib/CodeGen/CGBuiltin.cpp
@@ -2769,6 +2769,32 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
return RValue::get(ConstantInt::get(ConvertType(E->getType()),
Layout.size().getQuantity()));
}
+
+ case Builtin::BI__xray_customevent: {
+ if (!ShouldXRayInstrumentFunction())
+ return RValue::getIgnored();
+ if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
+ if (XRayAttr->neverXRayInstrument())
+ return RValue::getIgnored();
+ }
+ Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
+ auto FTy = F->getFunctionType();
+ auto Arg0 = E->getArg(0);
+ auto Arg0Val = EmitScalarExpr(Arg0);
+ auto Arg0Ty = Arg0->getType();
+ auto PTy0 = FTy->getParamType(0);
+ if (PTy0 != Arg0Val->getType()) {
+ if (Arg0Ty->isArrayType())
+ Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer();
+ else
+ Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0);
+ }
+ auto Arg1 = EmitScalarExpr(E->getArg(1));
+ auto PTy1 = FTy->getParamType(1);
+ if (PTy1 != Arg1->getType())
+ Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
+ return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
+ }
}
// If this is an alias for a lib function (e.g. __builtin_sin), emit
@@ -4545,7 +4571,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
? Intrinsic::arm_stlexd
: Intrinsic::arm_strexd);
- llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, nullptr);
+ llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty);
Address Tmp = CreateMemTemp(E->getArg(0)->getType());
Value *Val = EmitScalarExpr(E->getArg(0));
@@ -5375,7 +5401,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
? Intrinsic::aarch64_stlxp
: Intrinsic::aarch64_stxp);
- llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty, nullptr);
+ llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty);
Address Tmp = CreateMemTemp(E->getArg(0)->getType());
EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true);
@@ -7347,8 +7373,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
// unsigned int __cpu_type;
// unsigned int __cpu_subtype;
// unsigned int __cpu_features[1];
- llvm::Type *STy = llvm::StructType::get(
- Int32Ty, Int32Ty, Int32Ty, llvm::ArrayType::get(Int32Ty, 1), nullptr);
+ llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
+ llvm::ArrayType::get(Int32Ty, 1));
// Grab the global __cpu_model.
llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
diff --git a/lib/CodeGen/CGCUDANV.cpp b/lib/CodeGen/CGCUDANV.cpp
index 813cd7400186..d24ef0a8a974 100644
--- a/lib/CodeGen/CGCUDANV.cpp
+++ b/lib/CodeGen/CGCUDANV.cpp
@@ -265,7 +265,7 @@ llvm::Function *CGNVCUDARuntime::makeModuleCtorFunction() {
"__cudaRegisterFatBinary");
// struct { int magic, int version, void * gpu_binary, void * dont_care };
llvm::StructType *FatbinWrapperTy =
- llvm::StructType::get(IntTy, IntTy, VoidPtrTy, VoidPtrTy, nullptr);
+ llvm::StructType::get(IntTy, IntTy, VoidPtrTy, VoidPtrTy);
llvm::Function *ModuleCtorFunc = llvm::Function::Create(
llvm::FunctionType::get(VoidTy, VoidPtrTy, false),
diff --git a/lib/CodeGen/CGCleanup.cpp b/lib/CodeGen/CGCleanup.cpp
index 437ab7dd4649..e8bcf0a3ac56 100644
--- a/lib/CodeGen/CGCleanup.cpp
+++ b/lib/CodeGen/CGCleanup.cpp
@@ -51,8 +51,7 @@ DominatingValue<RValue>::saved_type::save(CodeGenFunction &CGF, RValue rv) {
if (rv.isComplex()) {
CodeGenFunction::ComplexPairTy V = rv.getComplexVal();
llvm::Type *ComplexTy =
- llvm::StructType::get(V.first->getType(), V.second->getType(),
- (void*) nullptr);
+ llvm::StructType::get(V.first->getType(), V.second->getType());
Address addr = CGF.CreateDefaultAlignTempAlloca(ComplexTy, "saved-complex");
CGF.Builder.CreateStore(V.first,
CGF.Builder.CreateStructGEP(addr, 0, CharUnits()));
diff --git a/lib/CodeGen/CGDebugInfo.cpp b/lib/CodeGen/CGDebugInfo.cpp
index 3e5434660567..9d77c61bd52c 100644
--- a/lib/CodeGen/CGDebugInfo.cpp
+++ b/lib/CodeGen/CGDebugInfo.cpp
@@ -209,7 +209,7 @@ llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context,
// Check namespace.
if (const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
- return getOrCreateNameSpace(NSDecl);
+ return getOrCreateNamespace(NSDecl);
if (const auto *RDecl = dyn_cast<RecordDecl>(Context))
if (!RDecl->isDependentType())
@@ -2860,8 +2860,8 @@ void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
if (DebugKind >= codegenoptions::LimitedDebugInfo) {
if (const NamespaceDecl *NSDecl =
- dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))
- FDContext = getOrCreateNameSpace(NSDecl);
+ dyn_cast_or_null<NamespaceDecl>(FD->getLexicalDeclContext()))
+ FDContext = getOrCreateNamespace(NSDecl);
else if (const RecordDecl *RDecl =
dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) {
llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
@@ -3961,7 +3961,7 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) {
CGM.getCodeGenOpts().DebugExplicitImport) {
DBuilder.createImportedModule(
getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())),
- getOrCreateNameSpace(NSDecl),
+ getOrCreateNamespace(NSDecl),
getLineNumber(UD.getLocation()));
}
}
@@ -4021,23 +4021,26 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
else
R = DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
- getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
+ getOrCreateNamespace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
getLineNumber(NA.getLocation()), NA.getName());
VH.reset(R);
return R;
}
llvm::DINamespace *
-CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) {
- NSDecl = NSDecl->getCanonicalDecl();
- auto I = NameSpaceCache.find(NSDecl);
- if (I != NameSpaceCache.end())
+CGDebugInfo::getOrCreateNamespace(const NamespaceDecl *NSDecl) {
+ // Don't canonicalize the NamespaceDecl here: The DINamespace will be uniqued
+ // if necessary, and this way multiple declarations of the same namespace in
+ // different parent modules stay distinct.
+ auto I = NamespaceCache.find(NSDecl);
+ if (I != NamespaceCache.end())
return cast<llvm::DINamespace>(I->second);
llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
+ // Don't trust the context if it is a DIModule (see comment above).
llvm::DINamespace *NS =
DBuilder.createNameSpace(Context, NSDecl->getName(), NSDecl->isInline());
- NameSpaceCache[NSDecl].reset(NS);
+ NamespaceCache[NSDecl].reset(NS);
return NS;
}
diff --git a/lib/CodeGen/CGDebugInfo.h b/lib/CodeGen/CGDebugInfo.h
index 5050ca0ad3fa..7de48f278994 100644
--- a/lib/CodeGen/CGDebugInfo.h
+++ b/lib/CodeGen/CGDebugInfo.h
@@ -125,7 +125,7 @@ class CGDebugInfo {
/// Cache declarations relevant to DW_TAG_imported_declarations (C++
/// using declarations) that aren't covered by other more specific caches.
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
- llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NameSpaceCache;
+ llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NamespaceCache;
llvm::DenseMap<const NamespaceAliasDecl *, llvm::TrackingMDRef>
NamespaceAliasCache;
llvm::DenseMap<const Decl *, llvm::TypedTrackingMDRef<llvm::DIDerivedType>>
@@ -194,8 +194,9 @@ class CGDebugInfo {
getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
/// \return debug info descriptor for vtable.
llvm::DIType *getOrCreateVTablePtrType(llvm::DIFile *F);
+
/// \return namespace descriptor for the given namespace decl.
- llvm::DINamespace *getOrCreateNameSpace(const NamespaceDecl *N);
+ llvm::DINamespace *getOrCreateNamespace(const NamespaceDecl *N);
llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty,
QualType PointeeTy, llvm::DIFile *F);
llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache);
diff --git a/lib/CodeGen/CGDecl.cpp b/lib/CodeGen/CGDecl.cpp
index 10a0b46d9028..0fa8eeb1c3e1 100644
--- a/lib/CodeGen/CGDecl.cpp
+++ b/lib/CodeGen/CGDecl.cpp
@@ -152,7 +152,14 @@ void CodeGenFunction::EmitDecl(const Decl &D) {
/// EmitVarDecl - This method handles emission of any variable declaration
/// inside a function, including static vars etc.
void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
- if (D.isStaticLocal()) {
+ if (D.hasExternalStorage())
+ // Don't emit it now, allow it to be emitted lazily on its first use.
+ return;
+
+ // Some function-scope variable does not have static storage but still
+ // needs to be emitted like a static variable, e.g. a function-scope
+ // variable in constant address space in OpenCL.
+ if (D.getStorageDuration() != SD_Automatic) {
llvm::GlobalValue::LinkageTypes Linkage =
CGM.getLLVMLinkageVarDefinition(&D, /*isConstant=*/false);
@@ -163,10 +170,6 @@ void CodeGenFunction::EmitVarDecl(const VarDecl &D) {
return EmitStaticVarDecl(D, Linkage);
}
- if (D.hasExternalStorage())
- // Don't emit it now, allow it to be emitted lazily on its first use.
- return;
-
if (D.getType().getAddressSpace() == LangAS::opencl_local)
return CGM.getOpenCLRuntime().EmitWorkGroupLocalVarDecl(*this, D);
diff --git a/lib/CodeGen/CGException.cpp b/lib/CodeGen/CGException.cpp
index ca1535182ec1..e65fa863fe31 100644
--- a/lib/CodeGen/CGException.cpp
+++ b/lib/CodeGen/CGException.cpp
@@ -765,8 +765,8 @@ llvm::BasicBlock *CodeGenFunction::EmitLandingPad() {
llvm::BasicBlock *lpad = createBasicBlock("lpad");
EmitBlock(lpad);
- llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(
- llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr), 0);
+ llvm::LandingPadInst *LPadInst =
+ Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
llvm::Value *LPadExn = Builder.CreateExtractValue(LPadInst, 0);
Builder.CreateStore(LPadExn, getExceptionSlot());
@@ -1310,8 +1310,8 @@ llvm::BasicBlock *CodeGenFunction::getTerminateLandingPad() {
if (!CurFn->hasPersonalityFn())
CurFn->setPersonalityFn(getOpaquePersonalityFn(CGM, Personality));
- llvm::LandingPadInst *LPadInst = Builder.CreateLandingPad(
- llvm::StructType::get(Int8PtrTy, Int32Ty, nullptr), 0);
+ llvm::LandingPadInst *LPadInst =
+ Builder.CreateLandingPad(llvm::StructType::get(Int8PtrTy, Int32Ty), 0);
LPadInst->addClause(getCatchAllValue(*this));
llvm::Value *Exn = nullptr;
@@ -1387,8 +1387,7 @@ llvm::BasicBlock *CodeGenFunction::getEHResumeBlock(bool isCleanup) {
llvm::Value *Exn = getExceptionFromSlot();
llvm::Value *Sel = getSelectorFromSlot();
- llvm::Type *LPadType = llvm::StructType::get(Exn->getType(),
- Sel->getType(), nullptr);
+ llvm::Type *LPadType = llvm::StructType::get(Exn->getType(), Sel->getType());
llvm::Value *LPadVal = llvm::UndefValue::get(LPadType);
LPadVal = Builder.CreateInsertValue(LPadVal, Exn, 0, "lpad.val");
LPadVal = Builder.CreateInsertValue(LPadVal, Sel, 1, "lpad.val");
@@ -1747,7 +1746,7 @@ void CodeGenFunction::EmitSEHExceptionCodeSave(CodeGenFunction &ParentCGF,
// };
// int exceptioncode = exception_pointers->ExceptionRecord->ExceptionCode;
llvm::Type *RecordTy = CGM.Int32Ty->getPointerTo();
- llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy, nullptr);
+ llvm::Type *PtrsTy = llvm::StructType::get(RecordTy, CGM.VoidPtrTy);
llvm::Value *Ptrs = Builder.CreateBitCast(SEHInfo, PtrsTy->getPointerTo());
llvm::Value *Rec = Builder.CreateStructGEP(PtrsTy, Ptrs, 0);
Rec = Builder.CreateAlignedLoad(Rec, getPointerAlign());
diff --git a/lib/CodeGen/CGExpr.cpp b/lib/CodeGen/CGExpr.cpp
index 863b4380da47..cef6292c0e4d 100644
--- a/lib/CodeGen/CGExpr.cpp
+++ b/lib/CodeGen/CGExpr.cpp
@@ -2859,9 +2859,9 @@ void CodeGenFunction::EmitCfiCheckFail() {
EmitTrapCheck(DataIsNotNullPtr);
llvm::StructType *SourceLocationTy =
- llvm::StructType::get(VoidPtrTy, Int32Ty, Int32Ty, nullptr);
+ llvm::StructType::get(VoidPtrTy, Int32Ty, Int32Ty);
llvm::StructType *CfiCheckFailDataTy =
- llvm::StructType::get(Int8Ty, SourceLocationTy, VoidPtrTy, nullptr);
+ llvm::StructType::get(Int8Ty, SourceLocationTy, VoidPtrTy);
llvm::Value *V = Builder.CreateConstGEP2_32(
CfiCheckFailDataTy,
diff --git a/lib/CodeGen/CGExprAgg.cpp b/lib/CodeGen/CGExprAgg.cpp
index 49bbb4808eaa..a05a088f0919 100644
--- a/lib/CodeGen/CGExprAgg.cpp
+++ b/lib/CodeGen/CGExprAgg.cpp
@@ -512,12 +512,20 @@ void AggExprEmitter::EmitArrayInit(Address DestPtr, llvm::ArrayType *AType,
currentElement->addIncoming(element, entryBB);
// Emit the actual filler expression.
- LValue elementLV =
- CGF.MakeAddrLValue(Address(currentElement, elementAlign), elementType);
- if (filler)
- EmitInitializationToLValue(filler, elementLV);
- else
- EmitNullInitializationToLValue(elementLV);
+ {
+ // C++1z [class.temporary]p5:
+ // when a default constructor is called to initialize an element of
+ // an array with no corresponding initializer [...] the destruction of
+ // every temporary created in a default argument is sequenced before
+ // the construction of the next array element, if any
+ CodeGenFunction::RunCleanupsScope CleanupsScope(CGF);
+ LValue elementLV =
+ CGF.MakeAddrLValue(Address(currentElement, elementAlign), elementType);
+ if (filler)
+ EmitInitializationToLValue(filler, elementLV);
+ else
+ EmitNullInitializationToLValue(elementLV);
+ }
// Move on to the next element.
llvm::Value *nextElement =
diff --git a/lib/CodeGen/CGExprConstant.cpp b/lib/CodeGen/CGExprConstant.cpp
index 53c184130709..6b72774c10a5 100644
--- a/lib/CodeGen/CGExprConstant.cpp
+++ b/lib/CodeGen/CGExprConstant.cpp
@@ -1361,9 +1361,8 @@ llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value,
Value.getComplexIntImag());
// FIXME: the target may want to specify that this is packed.
- llvm::StructType *STy = llvm::StructType::get(Complex[0]->getType(),
- Complex[1]->getType(),
- nullptr);
+ llvm::StructType *STy =
+ llvm::StructType::get(Complex[0]->getType(), Complex[1]->getType());
return llvm::ConstantStruct::get(STy, Complex);
}
case APValue::Float: {
@@ -1384,9 +1383,8 @@ llvm::Constant *CodeGenModule::EmitConstantValue(const APValue &Value,
Value.getComplexFloatImag());
// FIXME: the target may want to specify that this is packed.
- llvm::StructType *STy = llvm::StructType::get(Complex[0]->getType(),
- Complex[1]->getType(),
- nullptr);
+ llvm::StructType *STy =
+ llvm::StructType::get(Complex[0]->getType(), Complex[1]->getType());
return llvm::ConstantStruct::get(STy, Complex);
}
case APValue::Vector: {
diff --git a/lib/CodeGen/CGExprScalar.cpp b/lib/CodeGen/CGExprScalar.cpp
index 70b741651fd1..b8d830ee9f3f 100644
--- a/lib/CodeGen/CGExprScalar.cpp
+++ b/lib/CodeGen/CGExprScalar.cpp
@@ -89,14 +89,14 @@ struct BinOpInfo {
}
/// Check if the binop computes a division or a remainder.
- bool isDivisionLikeOperation() const {
+ bool isDivremOp() const {
return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
Opcode == BO_RemAssign;
}
/// Check if the binop can result in an integer division by zero.
bool mayHaveIntegerDivisionByZero() const {
- if (isDivisionLikeOperation())
+ if (isDivremOp())
if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
return CI->isZero();
return true;
@@ -104,7 +104,7 @@ struct BinOpInfo {
/// Check if the binop can result in a float division by zero.
bool mayHaveFloatDivisionByZero() const {
- if (isDivisionLikeOperation())
+ if (isDivremOp())
if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
return CFP->isZero();
return true;
@@ -2552,6 +2552,7 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
if (isSigned)
OpID |= 1;
+ CodeGenFunction::SanitizerScope SanScope(&CGF);
llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
@@ -2567,7 +2568,6 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
// If the signed-integer-overflow sanitizer is enabled, emit a call to its
// runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
- CodeGenFunction::SanitizerScope SanScope(&CGF);
llvm::Value *NotOverflow = Builder.CreateNot(overflow);
SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
: SanitizerKind::UnsignedIntegerOverflow;
diff --git a/lib/CodeGen/CGObjCGNU.cpp b/lib/CodeGen/CGObjCGNU.cpp
index 821629c50d4a..c8b8be7f4552 100644
--- a/lib/CodeGen/CGObjCGNU.cpp
+++ b/lib/CodeGen/CGObjCGNU.cpp
@@ -34,7 +34,6 @@
#include "llvm/IR/LLVMContext.h"
#include "llvm/IR/Module.h"
#include "llvm/Support/Compiler.h"
-#include <cstdarg>
using namespace clang;
using namespace CodeGen;
@@ -58,18 +57,19 @@ public:
/// Initialises the lazy function with the name, return type, and the types
/// of the arguments.
- LLVM_END_WITH_NULL
- void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy, ...) {
+ template <typename... Tys>
+ void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy,
+ Tys *... Types) {
CGM = Mod;
FunctionName = name;
Function = nullptr;
- std::vector<llvm::Type *> ArgTys;
- va_list Args;
- va_start(Args, RetTy);
- while (llvm::Type *ArgTy = va_arg(Args, llvm::Type *))
- ArgTys.push_back(ArgTy);
- va_end(Args);
- FTy = llvm::FunctionType::get(RetTy, ArgTys, false);
+ if(sizeof...(Tys)) {
+ SmallVector<llvm::Type *, 8> ArgTys({Types...});
+ FTy = llvm::FunctionType::get(RetTy, ArgTys, false);
+ }
+ else {
+ FTy = llvm::FunctionType::get(RetTy, None, false);
+ }
}
llvm::FunctionType *getType() { return FTy; }
@@ -603,11 +603,10 @@ protected:
public:
CGObjCGCC(CodeGenModule &Mod) : CGObjCGNU(Mod, 8, 2) {
// IMP objc_msg_lookup(id, SEL);
- MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy,
- nullptr);
+ MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy);
// IMP objc_msg_lookup_super(struct objc_super*, SEL);
MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
- PtrToObjCSuperTy, SelectorTy, nullptr);
+ PtrToObjCSuperTy, SelectorTy);
}
};
@@ -702,52 +701,51 @@ class CGObjCGNUstep : public CGObjCGNU {
CGObjCGNUstep(CodeGenModule &Mod) : CGObjCGNU(Mod, 9, 3) {
const ObjCRuntime &R = CGM.getLangOpts().ObjCRuntime;
- llvm::StructType *SlotStructTy = llvm::StructType::get(PtrTy,
- PtrTy, PtrTy, IntTy, IMPTy, nullptr);
+ llvm::StructType *SlotStructTy =
+ llvm::StructType::get(PtrTy, PtrTy, PtrTy, IntTy, IMPTy);
SlotTy = llvm::PointerType::getUnqual(SlotStructTy);
// Slot_t objc_msg_lookup_sender(id *receiver, SEL selector, id sender);
SlotLookupFn.init(&CGM, "objc_msg_lookup_sender", SlotTy, PtrToIdTy,
- SelectorTy, IdTy, nullptr);
+ SelectorTy, IdTy);
// Slot_t objc_msg_lookup_super(struct objc_super*, SEL);
SlotLookupSuperFn.init(&CGM, "objc_slot_lookup_super", SlotTy,
- PtrToObjCSuperTy, SelectorTy, nullptr);
+ PtrToObjCSuperTy, SelectorTy);
// If we're in ObjC++ mode, then we want to make
if (CGM.getLangOpts().CPlusPlus) {
llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
// void *__cxa_begin_catch(void *e)
- EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy, nullptr);
+ EnterCatchFn.init(&CGM, "__cxa_begin_catch", PtrTy, PtrTy);
// void __cxa_end_catch(void)
- ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy, nullptr);
+ ExitCatchFn.init(&CGM, "__cxa_end_catch", VoidTy);
// void _Unwind_Resume_or_Rethrow(void*)
ExceptionReThrowFn.init(&CGM, "_Unwind_Resume_or_Rethrow", VoidTy,
- PtrTy, nullptr);
+ PtrTy);
} else if (R.getVersion() >= VersionTuple(1, 7)) {
llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
// id objc_begin_catch(void *e)
- EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy, nullptr);
+ EnterCatchFn.init(&CGM, "objc_begin_catch", IdTy, PtrTy);
// void objc_end_catch(void)
- ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy, nullptr);
+ ExitCatchFn.init(&CGM, "objc_end_catch", VoidTy);
// void _Unwind_Resume_or_Rethrow(void*)
- ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy,
- PtrTy, nullptr);
+ ExceptionReThrowFn.init(&CGM, "objc_exception_rethrow", VoidTy, PtrTy);
}
llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
SetPropertyAtomic.init(&CGM, "objc_setProperty_atomic", VoidTy, IdTy,
- SelectorTy, IdTy, PtrDiffTy, nullptr);
+ SelectorTy, IdTy, PtrDiffTy);
SetPropertyAtomicCopy.init(&CGM, "objc_setProperty_atomic_copy", VoidTy,
- IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
+ IdTy, SelectorTy, IdTy, PtrDiffTy);
SetPropertyNonAtomic.init(&CGM, "objc_setProperty_nonatomic", VoidTy,
- IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
+ IdTy, SelectorTy, IdTy, PtrDiffTy);
SetPropertyNonAtomicCopy.init(&CGM, "objc_setProperty_nonatomic_copy",
- VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy, nullptr);
+ VoidTy, IdTy, SelectorTy, IdTy, PtrDiffTy);
// void objc_setCppObjectAtomic(void *dest, const void *src, void
// *helper);
CxxAtomicObjectSetFn.init(&CGM, "objc_setCppObjectAtomic", VoidTy, PtrTy,
- PtrTy, PtrTy, nullptr);
+ PtrTy, PtrTy);
// void objc_getCppObjectAtomic(void *dest, const void *src, void
// *helper);
CxxAtomicObjectGetFn.init(&CGM, "objc_getCppObjectAtomic", VoidTy, PtrTy,
- PtrTy, PtrTy, nullptr);
+ PtrTy, PtrTy);
}
llvm::Constant *GetCppAtomicObjectGetFunction() override {
@@ -849,14 +847,14 @@ protected:
public:
CGObjCObjFW(CodeGenModule &Mod): CGObjCGNU(Mod, 9, 3) {
// IMP objc_msg_lookup(id, SEL);
- MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy, nullptr);
+ MsgLookupFn.init(&CGM, "objc_msg_lookup", IMPTy, IdTy, SelectorTy);
MsgLookupFnSRet.init(&CGM, "objc_msg_lookup_stret", IMPTy, IdTy,
- SelectorTy, nullptr);
+ SelectorTy);
// IMP objc_msg_lookup_super(struct objc_super*, SEL);
MsgLookupSuperFn.init(&CGM, "objc_msg_lookup_super", IMPTy,
- PtrToObjCSuperTy, SelectorTy, nullptr);
+ PtrToObjCSuperTy, SelectorTy);
MsgLookupSuperFnSRet.init(&CGM, "objc_msg_lookup_super_stret", IMPTy,
- PtrToObjCSuperTy, SelectorTy, nullptr);
+ PtrToObjCSuperTy, SelectorTy);
}
};
} // end anonymous namespace
@@ -945,35 +943,34 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
}
PtrToIdTy = llvm::PointerType::getUnqual(IdTy);
- ObjCSuperTy = llvm::StructType::get(IdTy, IdTy, nullptr);
+ ObjCSuperTy = llvm::StructType::get(IdTy, IdTy);
PtrToObjCSuperTy = llvm::PointerType::getUnqual(ObjCSuperTy);
llvm::Type *VoidTy = llvm::Type::getVoidTy(VMContext);
// void objc_exception_throw(id);
- ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, nullptr);
- ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy, nullptr);
+ ExceptionThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy);
+ ExceptionReThrowFn.init(&CGM, "objc_exception_throw", VoidTy, IdTy);
// int objc_sync_enter(id);
- SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy, nullptr);
+ SyncEnterFn.init(&CGM, "objc_sync_enter", IntTy, IdTy);
// int objc_sync_exit(id);
- SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy, nullptr);
+ SyncExitFn.init(&CGM, "objc_sync_exit", IntTy, IdTy);
// void objc_enumerationMutation (id)
- EnumerationMutationFn.init(&CGM, "objc_enumerationMutation", VoidTy,
- IdTy, nullptr);
+ EnumerationMutationFn.init(&CGM, "objc_enumerationMutation", VoidTy, IdTy);
// id objc_getProperty(id, SEL, ptrdiff_t, BOOL)
GetPropertyFn.init(&CGM, "objc_getProperty", IdTy, IdTy, SelectorTy,
- PtrDiffTy, BoolTy, nullptr);
+ PtrDiffTy, BoolTy);
// void objc_setProperty(id, SEL, ptrdiff_t, id, BOOL, BOOL)
SetPropertyFn.init(&CGM, "objc_setProperty", VoidTy, IdTy, SelectorTy,
- PtrDiffTy, IdTy, BoolTy, BoolTy, nullptr);
+ PtrDiffTy, IdTy, BoolTy, BoolTy);
// void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL)
- GetStructPropertyFn.init(&CGM, "objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
- PtrDiffTy, BoolTy, BoolTy, nullptr);
+ GetStructPropertyFn.init(&CGM, "objc_getPropertyStruct", VoidTy, PtrTy, PtrTy,
+ PtrDiffTy, BoolTy, BoolTy);
// void objc_setPropertyStruct(void*, void*, ptrdiff_t, BOOL, BOOL)
- SetStructPropertyFn.init(&CGM, "objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
- PtrDiffTy, BoolTy, BoolTy, nullptr);
+ SetStructPropertyFn.init(&CGM, "objc_setPropertyStruct", VoidTy, PtrTy, PtrTy,
+ PtrDiffTy, BoolTy, BoolTy);
// IMP type
llvm::Type *IMPArgs[] = { IdTy, SelectorTy };
@@ -997,21 +994,19 @@ CGObjCGNU::CGObjCGNU(CodeGenModule &cgm, unsigned runtimeABIVersion,
// Get functions needed in GC mode
// id objc_assign_ivar(id, id, ptrdiff_t);
- IvarAssignFn.init(&CGM, "objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy,
- nullptr);
+ IvarAssignFn.init(&CGM, "objc_assign_ivar", IdTy, IdTy, IdTy, PtrDiffTy);
// id objc_assign_strongCast (id, id*)
StrongCastAssignFn.init(&CGM, "objc_assign_strongCast", IdTy, IdTy,
- PtrToIdTy, nullptr);
+ PtrToIdTy);
// id objc_assign_global(id, id*);
- GlobalAssignFn.init(&CGM, "objc_assign_global", IdTy, IdTy, PtrToIdTy,
- nullptr);
+ GlobalAssignFn.init(&CGM, "objc_assign_global", IdTy, IdTy, PtrToIdTy);
// id objc_assign_weak(id, id*);
- WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy, nullptr);
+ WeakAssignFn.init(&CGM, "objc_assign_weak", IdTy, IdTy, PtrToIdTy);
// id objc_read_weak(id*);
- WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy, nullptr);
+ WeakReadFn.init(&CGM, "objc_read_weak", IdTy, PtrToIdTy);
// void *objc_memmove_collectable(void*, void *, size_t);
MemMoveFn.init(&CGM, "objc_memmove_collectable", PtrTy, PtrTy, PtrTy,
- SizeTy, nullptr);
+ SizeTy);
}
}
@@ -1317,7 +1312,7 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
}
}
// Cast the pointer to a simplified version of the class structure
- llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy, nullptr);
+ llvm::Type *CastTy = llvm::StructType::get(IdTy, IdTy);
ReceiverClass = Builder.CreateBitCast(ReceiverClass,
llvm::PointerType::getUnqual(CastTy));
// Get the superclass pointer
@@ -1326,8 +1321,8 @@ CGObjCGNU::GenerateMessageSendSuper(CodeGenFunction &CGF,
ReceiverClass =
Builder.CreateAlignedLoad(ReceiverClass, CGF.getPointerAlign());
// Construct the structure used to look up the IMP
- llvm::StructType *ObjCSuperTy = llvm::StructType::get(
- Receiver->getType(), IdTy, nullptr);
+ llvm::StructType *ObjCSuperTy =
+ llvm::StructType::get(Receiver->getType(), IdTy);
// FIXME: Is this really supposed to be a dynamic alloca?
Address ObjCSuper = Address(Builder.CreateAlloca(ObjCSuperTy),
@@ -1565,11 +1560,8 @@ GenerateIvarList(ArrayRef<llvm::Constant *> IvarNames,
IvarList.addInt(IntTy, (int)IvarNames.size());
// Get the ivar structure type.
- llvm::StructType *ObjCIvarTy = llvm::StructType::get(
- PtrToInt8Ty,
- PtrToInt8Ty,
- IntTy,
- nullptr);
+ llvm::StructType *ObjCIvarTy =
+ llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
// Array of ivar structures.
auto Ivars = IvarList.beginArray(ObjCIvarTy);
@@ -1611,7 +1603,7 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
// anyway; the classes will still work with the GNU runtime, they will just
// be ignored.
llvm::StructType *ClassTy = llvm::StructType::get(
- PtrToInt8Ty, // isa
+ PtrToInt8Ty, // isa
PtrToInt8Ty, // super_class
PtrToInt8Ty, // name
LongTy, // version
@@ -1620,18 +1612,18 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
IVars->getType(), // ivars
Methods->getType(), // methods
// These are all filled in by the runtime, so we pretend
- PtrTy, // dtable
- PtrTy, // subclass_list
- PtrTy, // sibling_class
- PtrTy, // protocols
- PtrTy, // gc_object_type
+ PtrTy, // dtable
+ PtrTy, // subclass_list
+ PtrTy, // sibling_class
+ PtrTy, // protocols
+ PtrTy, // gc_object_type
// New ABI:
LongTy, // abi_version
IvarOffsets->getType(), // ivar_offsets
Properties->getType(), // properties
IntPtrTy, // strong_pointers
- IntPtrTy, // weak_pointers
- nullptr);
+ IntPtrTy // weak_pointers
+ );
ConstantInitBuilder Builder(CGM);
auto Elements = Builder.beginStruct(ClassTy);
diff --git a/lib/CodeGen/CGObjCMac.cpp b/lib/CodeGen/CGObjCMac.cpp
index 70d24b791334..9c048423285b 100644
--- a/lib/CodeGen/CGObjCMac.cpp
+++ b/lib/CodeGen/CGObjCMac.cpp
@@ -105,8 +105,8 @@ private:
llvm::Constant *getMessageSendFp2retFn() const {
llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
llvm::Type *longDoubleType = llvm::Type::getX86_FP80Ty(VMContext);
- llvm::Type *resultType =
- llvm::StructType::get(longDoubleType, longDoubleType, nullptr);
+ llvm::Type *resultType =
+ llvm::StructType::get(longDoubleType, longDoubleType);
return CGM.CreateRuntimeFunction(llvm::FunctionType::get(resultType,
params, true),
@@ -5506,17 +5506,15 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
// char *name;
// char *attributes;
// }
- PropertyTy = llvm::StructType::create("struct._prop_t",
- Int8PtrTy, Int8PtrTy, nullptr);
+ PropertyTy = llvm::StructType::create("struct._prop_t", Int8PtrTy, Int8PtrTy);
// struct _prop_list_t {
// uint32_t entsize; // sizeof(struct _prop_t)
// uint32_t count_of_properties;
// struct _prop_t prop_list[count_of_properties];
// }
- PropertyListTy =
- llvm::StructType::create("struct._prop_list_t", IntTy, IntTy,
- llvm::ArrayType::get(PropertyTy, 0), nullptr);
+ PropertyListTy = llvm::StructType::create(
+ "struct._prop_list_t", IntTy, IntTy, llvm::ArrayType::get(PropertyTy, 0));
// struct _prop_list_t *
PropertyListPtrTy = llvm::PointerType::getUnqual(PropertyListTy);
@@ -5525,9 +5523,8 @@ ObjCCommonTypesHelper::ObjCCommonTypesHelper(CodeGen::CodeGenModule &cgm)
// char *method_type;
// char *_imp;
// }
- MethodTy = llvm::StructType::create("struct._objc_method",
- SelectorPtrTy, Int8PtrTy, Int8PtrTy,
- nullptr);
+ MethodTy = llvm::StructType::create("struct._objc_method", SelectorPtrTy,
+ Int8PtrTy, Int8PtrTy);
// struct _objc_cache *
CacheTy = llvm::StructType::create(VMContext, "struct._objc_cache");
@@ -5540,17 +5537,16 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// SEL name;
// char *types;
// }
- MethodDescriptionTy =
- llvm::StructType::create("struct._objc_method_description",
- SelectorPtrTy, Int8PtrTy, nullptr);
+ MethodDescriptionTy = llvm::StructType::create(
+ "struct._objc_method_description", SelectorPtrTy, Int8PtrTy);
// struct _objc_method_description_list {
// int count;
// struct _objc_method_description[1];
// }
- MethodDescriptionListTy = llvm::StructType::create(
- "struct._objc_method_description_list", IntTy,
- llvm::ArrayType::get(MethodDescriptionTy, 0), nullptr);
+ MethodDescriptionListTy =
+ llvm::StructType::create("struct._objc_method_description_list", IntTy,
+ llvm::ArrayType::get(MethodDescriptionTy, 0));
// struct _objc_method_description_list *
MethodDescriptionListPtrTy =
@@ -5566,11 +5562,10 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// const char ** extendedMethodTypes;
// struct _objc_property_list *class_properties;
// }
- ProtocolExtensionTy =
- llvm::StructType::create("struct._objc_protocol_extension",
- IntTy, MethodDescriptionListPtrTy,
- MethodDescriptionListPtrTy, PropertyListPtrTy,
- Int8PtrPtrTy, PropertyListPtrTy, nullptr);
+ ProtocolExtensionTy = llvm::StructType::create(
+ "struct._objc_protocol_extension", IntTy, MethodDescriptionListPtrTy,
+ MethodDescriptionListPtrTy, PropertyListPtrTy, Int8PtrPtrTy,
+ PropertyListPtrTy);
// struct _objc_protocol_extension *
ProtocolExtensionPtrTy = llvm::PointerType::getUnqual(ProtocolExtensionTy);
@@ -5582,10 +5577,8 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
ProtocolListTy =
llvm::StructType::create(VMContext, "struct._objc_protocol_list");
- ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy),
- LongTy,
- llvm::ArrayType::get(ProtocolTy, 0),
- nullptr);
+ ProtocolListTy->setBody(llvm::PointerType::getUnqual(ProtocolListTy), LongTy,
+ llvm::ArrayType::get(ProtocolTy, 0));
// struct _objc_protocol {
// struct _objc_protocol_extension *isa;
@@ -5596,9 +5589,7 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// }
ProtocolTy->setBody(ProtocolExtensionPtrTy, Int8PtrTy,
llvm::PointerType::getUnqual(ProtocolListTy),
- MethodDescriptionListPtrTy,
- MethodDescriptionListPtrTy,
- nullptr);
+ MethodDescriptionListPtrTy, MethodDescriptionListPtrTy);
// struct _objc_protocol_list *
ProtocolListPtrTy = llvm::PointerType::getUnqual(ProtocolListTy);
@@ -5612,8 +5603,8 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// char *ivar_type;
// int ivar_offset;
// }
- IvarTy = llvm::StructType::create("struct._objc_ivar",
- Int8PtrTy, Int8PtrTy, IntTy, nullptr);
+ IvarTy = llvm::StructType::create("struct._objc_ivar", Int8PtrTy, Int8PtrTy,
+ IntTy);
// struct _objc_ivar_list *
IvarListTy =
@@ -5626,9 +5617,8 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
MethodListPtrTy = llvm::PointerType::getUnqual(MethodListTy);
// struct _objc_class_extension *
- ClassExtensionTy =
- llvm::StructType::create("struct._objc_class_extension",
- IntTy, Int8PtrTy, PropertyListPtrTy, nullptr);
+ ClassExtensionTy = llvm::StructType::create(
+ "struct._objc_class_extension", IntTy, Int8PtrTy, PropertyListPtrTy);
ClassExtensionPtrTy = llvm::PointerType::getUnqual(ClassExtensionTy);
ClassTy = llvm::StructType::create(VMContext, "struct._objc_class");
@@ -5648,18 +5638,9 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// struct _objc_class_ext *ext;
// };
ClassTy->setBody(llvm::PointerType::getUnqual(ClassTy),
- llvm::PointerType::getUnqual(ClassTy),
- Int8PtrTy,
- LongTy,
- LongTy,
- LongTy,
- IvarListPtrTy,
- MethodListPtrTy,
- CachePtrTy,
- ProtocolListPtrTy,
- Int8PtrTy,
- ClassExtensionPtrTy,
- nullptr);
+ llvm::PointerType::getUnqual(ClassTy), Int8PtrTy, LongTy,
+ LongTy, LongTy, IvarListPtrTy, MethodListPtrTy, CachePtrTy,
+ ProtocolListPtrTy, Int8PtrTy, ClassExtensionPtrTy);
ClassPtrTy = llvm::PointerType::getUnqual(ClassTy);
@@ -5673,12 +5654,10 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// struct _objc_property_list *instance_properties;// category's @property
// struct _objc_property_list *class_properties;
// }
- CategoryTy =
- llvm::StructType::create("struct._objc_category",
- Int8PtrTy, Int8PtrTy, MethodListPtrTy,
- MethodListPtrTy, ProtocolListPtrTy,
- IntTy, PropertyListPtrTy, PropertyListPtrTy,
- nullptr);
+ CategoryTy = llvm::StructType::create(
+ "struct._objc_category", Int8PtrTy, Int8PtrTy, MethodListPtrTy,
+ MethodListPtrTy, ProtocolListPtrTy, IntTy, PropertyListPtrTy,
+ PropertyListPtrTy);
// Global metadata structures
@@ -5689,10 +5668,9 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// short cat_def_cnt;
// char *defs[cls_def_cnt + cat_def_cnt];
// }
- SymtabTy =
- llvm::StructType::create("struct._objc_symtab",
- LongTy, SelectorPtrTy, ShortTy, ShortTy,
- llvm::ArrayType::get(Int8PtrTy, 0), nullptr);
+ SymtabTy = llvm::StructType::create("struct._objc_symtab", LongTy,
+ SelectorPtrTy, ShortTy, ShortTy,
+ llvm::ArrayType::get(Int8PtrTy, 0));
SymtabPtrTy = llvm::PointerType::getUnqual(SymtabTy);
// struct _objc_module {
@@ -5701,10 +5679,8 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// char *name;
// struct _objc_symtab* symtab;
// }
- ModuleTy =
- llvm::StructType::create("struct._objc_module",
- LongTy, LongTy, Int8PtrTy, SymtabPtrTy, nullptr);
-
+ ModuleTy = llvm::StructType::create("struct._objc_module", LongTy, LongTy,
+ Int8PtrTy, SymtabPtrTy);
// FIXME: This is the size of the setjmp buffer and should be target
// specific. 18 is what's used on 32-bit X86.
@@ -5713,10 +5689,9 @@ ObjCTypesHelper::ObjCTypesHelper(CodeGen::CodeGenModule &cgm)
// Exceptions
llvm::Type *StackPtrTy = llvm::ArrayType::get(CGM.Int8PtrTy, 4);
- ExceptionDataTy =
- llvm::StructType::create("struct._objc_exception_data",
- llvm::ArrayType::get(CGM.Int32Ty,SetJmpBufferSize),
- StackPtrTy, nullptr);
+ ExceptionDataTy = llvm::StructType::create(
+ "struct._objc_exception_data",
+ llvm::ArrayType::get(CGM.Int32Ty, SetJmpBufferSize), StackPtrTy);
}
ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModule &cgm)
@@ -5727,8 +5702,8 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// struct _objc_method method_list[method_count];
// }
MethodListnfABITy =
- llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
- llvm::ArrayType::get(MethodTy, 0), nullptr);
+ llvm::StructType::create("struct.__method_list_t", IntTy, IntTy,
+ llvm::ArrayType::get(MethodTy, 0));
// struct method_list_t *
MethodListnfABIPtrTy = llvm::PointerType::getUnqual(MethodListnfABITy);
@@ -5752,14 +5727,12 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
ProtocolListnfABITy =
llvm::StructType::create(VMContext, "struct._objc_protocol_list");
- ProtocolnfABITy =
- llvm::StructType::create("struct._protocol_t", ObjectPtrTy, Int8PtrTy,
- llvm::PointerType::getUnqual(ProtocolListnfABITy),
- MethodListnfABIPtrTy, MethodListnfABIPtrTy,
- MethodListnfABIPtrTy, MethodListnfABIPtrTy,
- PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy,
- Int8PtrTy, PropertyListPtrTy,
- nullptr);
+ ProtocolnfABITy = llvm::StructType::create(
+ "struct._protocol_t", ObjectPtrTy, Int8PtrTy,
+ llvm::PointerType::getUnqual(ProtocolListnfABITy), MethodListnfABIPtrTy,
+ MethodListnfABIPtrTy, MethodListnfABIPtrTy, MethodListnfABIPtrTy,
+ PropertyListPtrTy, IntTy, IntTy, Int8PtrPtrTy, Int8PtrTy,
+ PropertyListPtrTy);
// struct _protocol_t*
ProtocolnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolnfABITy);
@@ -5769,8 +5742,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// struct _protocol_t *[protocol_count];
// }
ProtocolListnfABITy->setBody(LongTy,
- llvm::ArrayType::get(ProtocolnfABIPtrTy, 0),
- nullptr);
+ llvm::ArrayType::get(ProtocolnfABIPtrTy, 0));
// struct _objc_protocol_list*
ProtocolListnfABIPtrTy = llvm::PointerType::getUnqual(ProtocolListnfABITy);
@@ -5784,7 +5756,7 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// }
IvarnfABITy = llvm::StructType::create(
"struct._ivar_t", llvm::PointerType::getUnqual(IvarOffsetVarTy),
- Int8PtrTy, Int8PtrTy, IntTy, IntTy, nullptr);
+ Int8PtrTy, Int8PtrTy, IntTy, IntTy);
// struct _ivar_list_t {
// uint32 entsize; // sizeof(struct _ivar_t)
@@ -5792,8 +5764,8 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// struct _iver_t list[count];
// }
IvarListnfABITy =
- llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
- llvm::ArrayType::get(IvarnfABITy, 0), nullptr);
+ llvm::StructType::create("struct._ivar_list_t", IntTy, IntTy,
+ llvm::ArrayType::get(IvarnfABITy, 0));
IvarListnfABIPtrTy = llvm::PointerType::getUnqual(IvarListnfABITy);
@@ -5812,13 +5784,10 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// }
// FIXME. Add 'reserved' field in 64bit abi mode!
- ClassRonfABITy = llvm::StructType::create("struct._class_ro_t",
- IntTy, IntTy, IntTy, Int8PtrTy,
- Int8PtrTy, MethodListnfABIPtrTy,
- ProtocolListnfABIPtrTy,
- IvarListnfABIPtrTy,
- Int8PtrTy, PropertyListPtrTy,
- nullptr);
+ ClassRonfABITy = llvm::StructType::create(
+ "struct._class_ro_t", IntTy, IntTy, IntTy, Int8PtrTy, Int8PtrTy,
+ MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, IvarListnfABIPtrTy,
+ Int8PtrTy, PropertyListPtrTy);
// ImpnfABITy - LLVM for id (*)(id, SEL, ...)
llvm::Type *params[] = { ObjectPtrTy, SelectorPtrTy };
@@ -5835,11 +5804,9 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
ClassnfABITy = llvm::StructType::create(VMContext, "struct._class_t");
ClassnfABITy->setBody(llvm::PointerType::getUnqual(ClassnfABITy),
- llvm::PointerType::getUnqual(ClassnfABITy),
- CachePtrTy,
+ llvm::PointerType::getUnqual(ClassnfABITy), CachePtrTy,
llvm::PointerType::getUnqual(ImpnfABITy),
- llvm::PointerType::getUnqual(ClassRonfABITy),
- nullptr);
+ llvm::PointerType::getUnqual(ClassRonfABITy));
// LLVM for struct _class_t *
ClassnfABIPtrTy = llvm::PointerType::getUnqual(ClassnfABITy);
@@ -5854,15 +5821,10 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// const struct _prop_list_t * const class_properties;
// const uint32_t size;
// }
- CategorynfABITy = llvm::StructType::create("struct._category_t",
- Int8PtrTy, ClassnfABIPtrTy,
- MethodListnfABIPtrTy,
- MethodListnfABIPtrTy,
- ProtocolListnfABIPtrTy,
- PropertyListPtrTy,
- PropertyListPtrTy,
- IntTy,
- nullptr);
+ CategorynfABITy = llvm::StructType::create(
+ "struct._category_t", Int8PtrTy, ClassnfABIPtrTy, MethodListnfABIPtrTy,
+ MethodListnfABIPtrTy, ProtocolListnfABIPtrTy, PropertyListPtrTy,
+ PropertyListPtrTy, IntTy);
// New types for nonfragile abi messaging.
CodeGen::CodeGenTypes &Types = CGM.getTypes();
@@ -5899,9 +5861,8 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// SUPER_IMP messenger;
// SEL name;
// };
- SuperMessageRefTy =
- llvm::StructType::create("struct._super_message_ref_t",
- ImpnfABITy, SelectorPtrTy, nullptr);
+ SuperMessageRefTy = llvm::StructType::create("struct._super_message_ref_t",
+ ImpnfABITy, SelectorPtrTy);
// SuperMessageRefPtrTy - LLVM for struct _super_message_ref_t*
SuperMessageRefPtrTy = llvm::PointerType::getUnqual(SuperMessageRefTy);
@@ -5912,10 +5873,9 @@ ObjCNonFragileABITypesHelper::ObjCNonFragileABITypesHelper(CodeGen::CodeGenModul
// const char* name; // c++ typeinfo string
// Class cls;
// };
- EHTypeTy =
- llvm::StructType::create("struct._objc_typeinfo",
- llvm::PointerType::getUnqual(Int8PtrTy),
- Int8PtrTy, ClassnfABIPtrTy, nullptr);
+ EHTypeTy = llvm::StructType::create("struct._objc_typeinfo",
+ llvm::PointerType::getUnqual(Int8PtrTy),
+ Int8PtrTy, ClassnfABIPtrTy);
EHTypePtrTy = llvm::PointerType::getUnqual(EHTypeTy);
}
diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp
index d1a706b8821e..b256a88c47ad 100644
--- a/lib/CodeGen/CGOpenMPRuntime.cpp
+++ b/lib/CodeGen/CGOpenMPRuntime.cpp
@@ -728,7 +728,7 @@ CGOpenMPRuntime::CGOpenMPRuntime(CodeGenModule &CGM)
IdentTy = llvm::StructType::create(
"ident_t", CGM.Int32Ty /* reserved_1 */, CGM.Int32Ty /* flags */,
CGM.Int32Ty /* reserved_2 */, CGM.Int32Ty /* reserved_3 */,
- CGM.Int8PtrTy /* psource */, nullptr);
+ CGM.Int8PtrTy /* psource */);
KmpCriticalNameTy = llvm::ArrayType::get(CGM.Int32Ty, /*NumElements*/ 8);
loadOffloadInfoMetadata();
diff --git a/lib/CodeGen/CodeGenAction.cpp b/lib/CodeGen/CodeGenAction.cpp
index f57cbe86c413..c7e30fad7575 100644
--- a/lib/CodeGen/CodeGenAction.cpp
+++ b/lib/CodeGen/CodeGenAction.cpp
@@ -548,9 +548,9 @@ void BackendConsumer::UnsupportedDiagHandler(
StringRef Filename;
unsigned Line, Column;
- bool BadDebugInfo;
- FullSourceLoc Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename,
- Line, Column);
+ bool BadDebugInfo = false;
+ FullSourceLoc Loc =
+ getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
Diags.Report(Loc, diag::err_fe_backend_unsupported) << D.getMessage().str();
@@ -572,8 +572,8 @@ void BackendConsumer::EmitOptimizationMessage(
StringRef Filename;
unsigned Line, Column;
bool BadDebugInfo = false;
- FullSourceLoc Loc = getBestLocationFromDebugLoc(D, BadDebugInfo, Filename,
- Line, Column);
+ FullSourceLoc Loc =
+ getBestLocationFromDebugLoc(D, BadDebugInfo, Filename, Line, Column);
std::string Msg;
raw_string_ostream MsgStream(Msg);
diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp
index ff26d80fe2b6..a0254797ea43 100644
--- a/lib/CodeGen/CodeGenModule.cpp
+++ b/lib/CodeGen/CodeGenModule.cpp
@@ -751,7 +751,7 @@ void CodeGenModule::EmitCtorList(CtorList &Fns, const char *GlobalName) {
// Get the type of a ctor entry, { i32, void ()*, i8* }.
llvm::StructType *CtorStructTy = llvm::StructType::get(
- Int32Ty, llvm::PointerType::getUnqual(CtorFTy), VoidPtrTy, nullptr);
+ Int32Ty, llvm::PointerType::getUnqual(CtorFTy), VoidPtrTy);
// Construct the constructor and destructor arrays.
ConstantInitBuilder builder(*this);
diff --git a/lib/CodeGen/CodeGenTypes.cpp b/lib/CodeGen/CodeGenTypes.cpp
index dc24b2040f04..5ed929135880 100644
--- a/lib/CodeGen/CodeGenTypes.cpp
+++ b/lib/CodeGen/CodeGenTypes.cpp
@@ -490,7 +490,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
llvm_unreachable("Unexpected undeduced type!");
case Type::Complex: {
llvm::Type *EltTy = ConvertType(cast<ComplexType>(Ty)->getElementType());
- ResultType = llvm::StructType::get(EltTy, EltTy, nullptr);
+ ResultType = llvm::StructType::get(EltTy, EltTy);
break;
}
case Type::LValueReference:
diff --git a/lib/CodeGen/ItaniumCXXABI.cpp b/lib/CodeGen/ItaniumCXXABI.cpp
index dac2d15fa406..66f51305430a 100644
--- a/lib/CodeGen/ItaniumCXXABI.cpp
+++ b/lib/CodeGen/ItaniumCXXABI.cpp
@@ -499,7 +499,7 @@ llvm::Type *
ItaniumCXXABI::ConvertMemberPointerType(const MemberPointerType *MPT) {
if (MPT->isMemberDataPointer())
return CGM.PtrDiffTy;
- return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy, nullptr);
+ return llvm::StructType::get(CGM.PtrDiffTy, CGM.PtrDiffTy);
}
/// In the Itanium and ARM ABIs, method pointers have the form:
diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp
index 4ebbef7dfb5b..18367d1602ba 100644
--- a/lib/CodeGen/TargetInfo.cpp
+++ b/lib/CodeGen/TargetInfo.cpp
@@ -3159,8 +3159,7 @@ GetX86_64ByValArgumentPair(llvm::Type *Lo, llvm::Type *Hi,
}
}
- llvm::StructType *Result = llvm::StructType::get(Lo, Hi, nullptr);
-
+ llvm::StructType *Result = llvm::StructType::get(Lo, Hi);
// Verify that the second element is at an 8-byte offset.
assert(TD.getStructLayout(Result)->getElementOffset(1) == 8 &&
@@ -3235,8 +3234,7 @@ classifyReturnType(QualType RetTy) const {
case ComplexX87:
assert(Hi == ComplexX87 && "Unexpected ComplexX87 classification.");
ResType = llvm::StructType::get(llvm::Type::getX86_FP80Ty(getVMContext()),
- llvm::Type::getX86_FP80Ty(getVMContext()),
- nullptr);
+ llvm::Type::getX86_FP80Ty(getVMContext()));
break;
}
@@ -3732,7 +3730,7 @@ Address X86_64ABIInfo::EmitVAArg(CodeGenFunction &CGF, Address VAListAddr,
CGF.Builder.CreateConstInBoundsByteGEP(RegAddrLo,
CharUnits::fromQuantity(16));
llvm::Type *DoubleTy = CGF.DoubleTy;
- llvm::StructType *ST = llvm::StructType::get(DoubleTy, DoubleTy, nullptr);
+ llvm::StructType *ST = llvm::StructType::get(DoubleTy, DoubleTy);
llvm::Value *V;
Address Tmp = CGF.CreateMemTemp(Ty);
Tmp = CGF.Builder.CreateElementBitCast(Tmp, ST);
@@ -4637,7 +4635,7 @@ PPC64_SVR4_ABIInfo::classifyReturnType(QualType RetTy) const {
llvm::Type *CoerceTy;
if (Bits > GPRBits) {
CoerceTy = llvm::IntegerType::get(getVMContext(), GPRBits);
- CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy, nullptr);
+ CoerceTy = llvm::StructType::get(CoerceTy, CoerceTy);
} else
CoerceTy =
llvm::IntegerType::get(getVMContext(), llvm::alignTo(Bits, 8));
@@ -6695,6 +6693,14 @@ MipsABIInfo::classifyArgumentType(QualType Ty, uint64_t &Offset) const {
return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
}
+ // Use indirect if the aggregate cannot fit into registers for
+ // passing arguments according to the ABI
+ unsigned Threshold = IsO32 ? 16 : 64;
+
+ if(getContext().getTypeSizeInChars(Ty) > CharUnits::fromQuantity(Threshold))
+ return ABIArgInfo::getIndirect(CharUnits::fromQuantity(Align), true,
+ getContext().getTypeAlign(Ty) / 8 > Align);
+
// If we have reached here, aggregates are passed directly by coercing to
// another structure type. Padding is inserted if the offset of the
// aggregate is unaligned.
@@ -7037,13 +7043,13 @@ ABIArgInfo HexagonABIInfo::classifyArgumentType(QualType Ty) const {
ABIArgInfo::getExtend() : ABIArgInfo::getDirect());
}
+ if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
+ return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
+
// Ignore empty records.
if (isEmptyRecord(getContext(), Ty, true))
return ABIArgInfo::getIgnore();
- if (CGCXXABI::RecordArgABI RAA = getRecordArgABI(Ty, getCXXABI()))
- return getNaturalAlignIndirect(Ty, RAA == CGCXXABI::RAA_DirectInMemory);
-
uint64_t Size = getContext().getTypeSize(Ty);
if (Size > 64)
return getNaturalAlignIndirect(Ty, /*ByVal=*/true);
diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp
index c298302c477c..9ab2e176845c 100644
--- a/lib/Driver/SanitizerArgs.cpp
+++ b/lib/Driver/SanitizerArgs.cpp
@@ -563,12 +563,18 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC,
}
}
- if (Arg *A = Args.getLastArg(
- options::OPT_fsanitize_address_use_after_scope,
- options::OPT_fno_sanitize_address_use_after_scope)) {
- AsanUseAfterScope = A->getOption().getID() ==
- options::OPT_fsanitize_address_use_after_scope;
- }
+ AsanUseAfterScope = Args.hasFlag(
+ options::OPT_fsanitize_address_use_after_scope,
+ options::OPT_fno_sanitize_address_use_after_scope, AsanUseAfterScope);
+
+ // As a workaround for a bug in gold 2.26 and earlier, dead stripping of
+ // globals in ASan is disabled by default on ELF targets.
+ // See https://sourceware.org/bugzilla/show_bug.cgi?id=19002
+ AsanGlobalsDeadStripping =
+ !TC.getTriple().isOSBinFormatELF() ||
+ Args.hasArg(options::OPT_fsanitize_address_globals_dead_stripping);
+ } else {
+ AsanUseAfterScope = false;
}
// Parse -link-cxx-sanitizer flag.
@@ -634,7 +640,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
std::make_pair(CoverageNoPrune, "-fsanitize-coverage-no-prune")};
for (auto F : CoverageFlags) {
if (CoverageFeatures & F.first)
- CmdArgs.push_back(Args.MakeArgString(F.second));
+ CmdArgs.push_back(F.second);
}
if (TC.getTriple().isOSWindows() && needsUbsanRt()) {
@@ -687,7 +693,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
llvm::utostr(MsanTrackOrigins)));
if (MsanUseAfterDtor)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-memory-use-after-dtor"));
+ CmdArgs.push_back("-fsanitize-memory-use-after-dtor");
// FIXME: Pass these parameters as function attributes, not as -llvm flags.
if (!TsanMemoryAccess) {
@@ -706,17 +712,20 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
}
if (CfiCrossDso)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-cfi-cross-dso"));
+ CmdArgs.push_back("-fsanitize-cfi-cross-dso");
if (Stats)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-stats"));
+ CmdArgs.push_back("-fsanitize-stats");
if (AsanFieldPadding)
CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-field-padding=" +
llvm::utostr(AsanFieldPadding)));
if (AsanUseAfterScope)
- CmdArgs.push_back(Args.MakeArgString("-fsanitize-address-use-after-scope"));
+ CmdArgs.push_back("-fsanitize-address-use-after-scope");
+
+ if (AsanGlobalsDeadStripping)
+ CmdArgs.push_back("-fsanitize-address-globals-dead-stripping");
// MSan: Workaround for PR16386.
// ASan: This is mainly to help LSan with cases such as
@@ -724,7 +733,7 @@ void SanitizerArgs::addArgs(const ToolChain &TC, const llvm::opt::ArgList &Args,
// We can't make this conditional on -fsanitize=leak, as that flag shouldn't
// affect compilation.
if (Sanitizers.has(Memory) || Sanitizers.has(Address))
- CmdArgs.push_back(Args.MakeArgString("-fno-assume-sane-operator-new"));
+ CmdArgs.push_back("-fno-assume-sane-operator-new");
// Require -fvisibility= flag on non-Windows when compiling if vptr CFI is
// enabled.
diff --git a/lib/Driver/ToolChains/Arch/Mips.cpp b/lib/Driver/ToolChains/Arch/Mips.cpp
index cd791af83220..f33542477fb5 100644
--- a/lib/Driver/ToolChains/Arch/Mips.cpp
+++ b/lib/Driver/ToolChains/Arch/Mips.cpp
@@ -282,18 +282,18 @@ void mips::getMIPSTargetFeatures(const Driver &D, const llvm::Triple &Triple,
if (Arg *A = Args.getLastArg(options::OPT_mfp32, options::OPT_mfpxx,
options::OPT_mfp64)) {
if (A->getOption().matches(options::OPT_mfp32))
- Features.push_back(Args.MakeArgString("-fp64"));
+ Features.push_back("-fp64");
else if (A->getOption().matches(options::OPT_mfpxx)) {
- Features.push_back(Args.MakeArgString("+fpxx"));
- Features.push_back(Args.MakeArgString("+nooddspreg"));
+ Features.push_back("+fpxx");
+ Features.push_back("+nooddspreg");
} else
- Features.push_back(Args.MakeArgString("+fp64"));
+ Features.push_back("+fp64");
} else if (mips::shouldUseFPXX(Args, Triple, CPUName, ABIName, FloatABI)) {
- Features.push_back(Args.MakeArgString("+fpxx"));
- Features.push_back(Args.MakeArgString("+nooddspreg"));
+ Features.push_back("+fpxx");
+ Features.push_back("+nooddspreg");
} else if (mips::isFP64ADefault(Triple, CPUName)) {
- Features.push_back(Args.MakeArgString("+fp64"));
- Features.push_back(Args.MakeArgString("+nooddspreg"));
+ Features.push_back("+fp64");
+ Features.push_back("+nooddspreg");
}
AddTargetFeature(Args, Features, options::OPT_mno_odd_spreg,
diff --git a/lib/Driver/ToolChains/Myriad.cpp b/lib/Driver/ToolChains/Myriad.cpp
index 2935755c12be..f70ce93c45ce 100644
--- a/lib/Driver/ToolChains/Myriad.cpp
+++ b/lib/Driver/ToolChains/Myriad.cpp
@@ -43,15 +43,17 @@ void tools::SHAVE::Compiler::ConstructJob(Compilation &C, const JobAction &JA,
}
CmdArgs.push_back("-DMYRIAD2");
- // Append all -I, -iquote, -isystem paths, defines/undefines,
- // 'f' flags, optimize flags, and warning options.
+ // Append all -I, -iquote, -isystem paths, defines/undefines, 'f'
+ // flags, 'g' flags, 'M' flags, optimize flags, warning options,
+ // mcpu flags, mllvm flags, and Xclang flags.
// These are spelled the same way in clang and moviCompile.
Args.AddAllArgsExcept(
CmdArgs,
{options::OPT_I_Group, options::OPT_clang_i_Group, options::OPT_std_EQ,
options::OPT_D, options::OPT_U, options::OPT_f_Group,
options::OPT_f_clang_Group, options::OPT_g_Group, options::OPT_M_Group,
- options::OPT_O_Group, options::OPT_W_Group, options::OPT_mcpu_EQ},
+ options::OPT_O_Group, options::OPT_W_Group, options::OPT_mcpu_EQ,
+ options::OPT_mllvm, options::OPT_Xclang},
{options::OPT_fno_split_dwarf_inlining});
Args.hasArg(options::OPT_fno_split_dwarf_inlining); // Claim it if present.
diff --git a/lib/Driver/ToolChains/WebAssembly.cpp b/lib/Driver/ToolChains/WebAssembly.cpp
index 123a1516f1e7..3471569b6884 100644
--- a/lib/Driver/ToolChains/WebAssembly.cpp
+++ b/lib/Driver/ToolChains/WebAssembly.cpp
@@ -42,7 +42,7 @@ void wasm::Linker::ConstructJob(Compilation &C, const JobAction &JA,
const char *Linker = Args.MakeArgString(ToolChain.GetLinkerPath());
ArgStringList CmdArgs;
CmdArgs.push_back("-flavor");
- CmdArgs.push_back("ld");
+ CmdArgs.push_back("wasm");
// Enable garbage collection of unused input sections by default, since code
// size is of particular importance. This is significantly facilitated by
@@ -101,6 +101,9 @@ WebAssembly::WebAssembly(const Driver &D, const llvm::Triple &Triple,
: ToolChain(D, Triple, Args) {
assert(Triple.isArch32Bit() != Triple.isArch64Bit());
+
+ getProgramPaths().push_back(getDriver().getInstalledDir());
+
getFilePaths().push_back(
getDriver().SysRoot + "/lib" + (Triple.isArch32Bit() ? "32" : "64"));
}
diff --git a/lib/Format/ContinuationIndenter.cpp b/lib/Format/ContinuationIndenter.cpp
index 3adb72c11da8..488f9dd582f9 100644
--- a/lib/Format/ContinuationIndenter.cpp
+++ b/lib/Format/ContinuationIndenter.cpp
@@ -674,6 +674,8 @@ unsigned ContinuationIndenter::getNewLineColumn(const LineState &State) {
return State.Stack[State.Stack.size() - 2].LastSpace;
return State.FirstIndent;
}
+ if (Current.is(tok::r_paren) && State.Stack.size() > 1)
+ return State.Stack[State.Stack.size() - 2].LastSpace;
if (NextNonComment->is(TT_TemplateString) && NextNonComment->closesScope())
return State.Stack[State.Stack.size() - 2].LastSpace;
if (Current.is(tok::identifier) && Current.Next &&
@@ -920,6 +922,10 @@ void ContinuationIndenter::moveStatePastFakeLParens(LineState &State,
NewParenState.NoLineBreak =
NewParenState.NoLineBreak || State.Stack.back().NoLineBreakInOperand;
+ // Don't propagate AvoidBinPacking into subexpressions of arg/param lists.
+ if (*I > prec::Comma)
+ NewParenState.AvoidBinPacking = false;
+
// Indent from 'LastSpace' unless these are fake parentheses encapsulating
// a builder type call after 'return' or, if the alignment after opening
// brackets is disabled.
@@ -1034,13 +1040,20 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
NestedBlockIndent = Column;
}
+ bool EndsInComma =
+ Current.MatchingParen &&
+ Current.MatchingParen->getPreviousNonComment() &&
+ Current.MatchingParen->getPreviousNonComment()->is(tok::comma);
+
AvoidBinPacking =
+ (Style.Language == FormatStyle::LK_JavaScript && EndsInComma) ||
(State.Line->MustBeDeclaration && !Style.BinPackParameters) ||
(!State.Line->MustBeDeclaration && !Style.BinPackArguments) ||
(Style.ExperimentalAutoDetectBinPacking &&
(Current.PackingKind == PPK_OnePerLine ||
(!BinPackInconclusiveFunctions &&
Current.PackingKind == PPK_Inconclusive)));
+
if (Current.is(TT_ObjCMethodExpr) && Current.MatchingParen) {
if (Style.ColumnLimit) {
// If this '[' opens an ObjC call, determine whether all parameters fit
@@ -1061,6 +1074,9 @@ void ContinuationIndenter::moveStatePastScopeOpener(LineState &State,
}
}
}
+
+ if (Style.Language == FormatStyle::LK_JavaScript && EndsInComma)
+ BreakBeforeParameter = true;
}
// Generally inherit NoLineBreak from the current scope to nested scope.
// However, don't do this for non-empty nested blocks, dict literals and
diff --git a/lib/Format/Format.cpp b/lib/Format/Format.cpp
index f55a623a8d1f..c8677e805179 100644
--- a/lib/Format/Format.cpp
+++ b/lib/Format/Format.cpp
@@ -171,6 +171,18 @@ template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {
}
};
+template <> struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
+ static void enumeration(IO &IO, FormatStyle::EscapedNewlineAlignmentStyle &Value) {
+ IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
+ IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
+ IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
+
+ // For backward compatibility.
+ IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
+ IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
+ }
+};
+
template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
@@ -233,6 +245,7 @@ template <> struct MappingTraits<FormatStyle> {
// For backward compatibility.
if (!IO.outputting()) {
+ IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
IO.mapOptional("IndentFunctionDeclarationAfterType",
Style.IndentWrappedFunctionNames);
@@ -247,7 +260,7 @@ template <> struct MappingTraits<FormatStyle> {
Style.AlignConsecutiveAssignments);
IO.mapOptional("AlignConsecutiveDeclarations",
Style.AlignConsecutiveDeclarations);
- IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft);
+ IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
IO.mapOptional("AlignOperands", Style.AlignOperands);
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
@@ -498,7 +511,7 @@ FormatStyle getLLVMStyle() {
FormatStyle LLVMStyle;
LLVMStyle.Language = FormatStyle::LK_Cpp;
LLVMStyle.AccessModifierOffset = -2;
- LLVMStyle.AlignEscapedNewlinesLeft = false;
+ LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
LLVMStyle.AlignOperands = true;
LLVMStyle.AlignTrailingComments = true;
@@ -587,7 +600,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.Language = Language;
GoogleStyle.AccessModifierOffset = -1;
- GoogleStyle.AlignEscapedNewlinesLeft = true;
+ GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
GoogleStyle.AllowShortLoopsOnASingleLine = true;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
@@ -624,9 +637,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
GoogleStyle.BreakBeforeTernaryOperators = false;
- // taze:, @tag followed by { for a lot of JSDoc tags, and @see, which is
- // commonly followed by overlong URLs.
- GoogleStyle.CommentPragmas = "(taze:|(@[A-Za-z_0-9-]+[ \\t]*{)|@see)";
+ // taze:, triple slash directives (`/// <...`), @tag followed by { for a lot
+ // of JSDoc tags, and @see, which is commonly followed by overlong URLs.
+ GoogleStyle.CommentPragmas =
+ "(taze:|^/[ \t]*<|(@[A-Za-z_0-9-]+[ \\t]*{)|@see)";
GoogleStyle.MaxEmptyLinesToKeep = 3;
GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
GoogleStyle.SpacesInContainerLiterals = false;
diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp
index c274d7bf07f8..387768a6ee56 100644
--- a/lib/Format/TokenAnnotator.cpp
+++ b/lib/Format/TokenAnnotator.cpp
@@ -576,9 +576,12 @@ private:
}
break;
case tok::kw_for:
- if (Style.Language == FormatStyle::LK_JavaScript && Tok->Previous &&
- Tok->Previous->is(tok::period))
- break;
+ if (Style.Language == FormatStyle::LK_JavaScript)
+ if (Tok->Previous && Tok->Previous->is(tok::period))
+ break;
+ // JS' for async ( ...
+ if (CurrentToken->is(Keywords.kw_async))
+ next();
Contexts.back().ColonIsForRangeExpr = true;
next();
if (!parseParens())
@@ -1034,8 +1037,9 @@ private:
if (Style.Language == FormatStyle::LK_JavaScript) {
if (Current.is(tok::exclaim)) {
if (Current.Previous &&
- (Current.Previous->isOneOf(tok::identifier, tok::r_paren,
- tok::r_square, tok::r_brace) ||
+ (Current.Previous->isOneOf(tok::identifier, tok::kw_namespace,
+ tok::r_paren, tok::r_square,
+ tok::r_brace) ||
Current.Previous->Tok.isLiteral())) {
Current.Type = TT_JsNonNullAssertion;
return;
@@ -2248,6 +2252,10 @@ bool TokenAnnotator::spaceRequiredBefore(const AnnotatedLine &Line,
} else if (Style.Language == FormatStyle::LK_JavaScript) {
if (Left.is(TT_JsFatArrow))
return true;
+ // for async ( ...
+ if (Right.is(tok::l_paren) && Left.is(Keywords.kw_async) &&
+ Left.Previous && Left.Previous->is(tok::kw_for))
+ return true;
if (Left.is(Keywords.kw_async) && Right.is(tok::l_paren) &&
Right.MatchingParen) {
const FormatToken *Next = Right.MatchingParen->getNextNonComment();
@@ -2462,16 +2470,20 @@ bool TokenAnnotator::mustBreakBefore(const AnnotatedLine &Line,
return true;
}
- // If the last token before a '}' is a comma or a trailing comment, the
- // intention is to insert a line break after it in order to make shuffling
- // around entries easier.
+ // If the last token before a '}', ']', or ')' is a comma or a trailing
+ // comment, the intention is to insert a line break after it in order to make
+ // shuffling around entries easier.
const FormatToken *BeforeClosingBrace = nullptr;
- if (Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) &&
+ if ((Left.isOneOf(tok::l_brace, TT_ArrayInitializerLSquare) ||
+ (Style.Language == FormatStyle::LK_JavaScript &&
+ Left.is(tok::l_paren))) &&
Left.BlockKind != BK_Block && Left.MatchingParen)
BeforeClosingBrace = Left.MatchingParen->Previous;
else if (Right.MatchingParen &&
- Right.MatchingParen->isOneOf(tok::l_brace,
- TT_ArrayInitializerLSquare))
+ (Right.MatchingParen->isOneOf(tok::l_brace,
+ TT_ArrayInitializerLSquare) ||
+ (Style.Language == FormatStyle::LK_JavaScript &&
+ Right.MatchingParen->is(tok::l_paren))))
BeforeClosingBrace = &Left;
if (BeforeClosingBrace && (BeforeClosingBrace->is(tok::comma) ||
BeforeClosingBrace->isTrailingComment()))
diff --git a/lib/Format/UnwrappedLineParser.cpp b/lib/Format/UnwrappedLineParser.cpp
index 2d788b52dfda..31c66ffb00a1 100644
--- a/lib/Format/UnwrappedLineParser.cpp
+++ b/lib/Format/UnwrappedLineParser.cpp
@@ -368,9 +368,10 @@ void UnwrappedLineParser::calculateBraceTypes(bool ExpectClassBody) {
(Style.Language == FormatStyle::LK_JavaScript &&
NextTok->isOneOf(Keywords.kw_of, Keywords.kw_in,
Keywords.kw_as)) ||
+ (Style.isCpp() && NextTok->is(tok::l_paren)) ||
NextTok->isOneOf(tok::comma, tok::period, tok::colon,
tok::r_paren, tok::r_square, tok::l_brace,
- tok::l_square, tok::l_paren, tok::ellipsis) ||
+ tok::l_square, tok::ellipsis) ||
(NextTok->is(tok::identifier) &&
!PrevTok->isOneOf(tok::semi, tok::r_brace, tok::l_brace)) ||
(NextTok->is(tok::semi) &&
@@ -476,6 +477,24 @@ static bool isGoogScope(const UnwrappedLine &Line) {
return I->Tok->is(tok::l_paren);
}
+static bool isIIFE(const UnwrappedLine &Line,
+ const AdditionalKeywords &Keywords) {
+ // Look for the start of an immediately invoked anonymous function.
+ // https://en.wikipedia.org/wiki/Immediately-invoked_function_expression
+ // This is commonly done in JavaScript to create a new, anonymous scope.
+ // Example: (function() { ... })()
+ if (Line.Tokens.size() < 3)
+ return false;
+ auto I = Line.Tokens.begin();
+ if (I->Tok->isNot(tok::l_paren))
+ return false;
+ ++I;
+ if (I->Tok->isNot(Keywords.kw_function))
+ return false;
+ ++I;
+ return I->Tok->is(tok::l_paren);
+}
+
static bool ShouldBreakBeforeBrace(const FormatStyle &Style,
const FormatToken &InitialToken) {
if (InitialToken.is(tok::kw_namespace))
@@ -493,15 +512,16 @@ void UnwrappedLineParser::parseChildBlock() {
FormatTok->BlockKind = BK_Block;
nextToken();
{
- bool GoogScope =
- Style.Language == FormatStyle::LK_JavaScript && isGoogScope(*Line);
+ bool SkipIndent =
+ (Style.Language == FormatStyle::LK_JavaScript &&
+ (isGoogScope(*Line) || isIIFE(*Line, Keywords)));
ScopedLineState LineState(*this);
ScopedDeclarationState DeclarationState(*Line, DeclarationScopeStack,
/*MustBeDeclaration=*/false);
- Line->Level += GoogScope ? 0 : 1;
+ Line->Level += SkipIndent ? 0 : 1;
parseLevel(/*HasOpeningBrace=*/true);
flushComments(isOnNewLine(*FormatTok));
- Line->Level -= GoogScope ? 0 : 1;
+ Line->Level -= SkipIndent ? 0 : 1;
}
nextToken();
}
@@ -1615,6 +1635,10 @@ void UnwrappedLineParser::parseForOrWhileLoop() {
assert(FormatTok->isOneOf(tok::kw_for, tok::kw_while, TT_ForEachMacro) &&
"'for', 'while' or foreach macro expected");
nextToken();
+ // JS' for async ( ...
+ if (Style.Language == FormatStyle::LK_JavaScript &&
+ FormatTok->is(Keywords.kw_async))
+ nextToken();
if (FormatTok->Tok.is(tok::l_paren))
parseParens();
if (FormatTok->Tok.is(tok::l_brace)) {
diff --git a/lib/Format/WhitespaceManager.cpp b/lib/Format/WhitespaceManager.cpp
index 2c1f59324971..3b6311d15487 100644
--- a/lib/Format/WhitespaceManager.cpp
+++ b/lib/Format/WhitespaceManager.cpp
@@ -517,8 +517,11 @@ void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
}
void WhitespaceManager::alignEscapedNewlines() {
- unsigned MaxEndOfLine =
- Style.AlignEscapedNewlinesLeft ? 0 : Style.ColumnLimit;
+ if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign)
+ return;
+
+ bool AlignLeft = Style.AlignEscapedNewlines == FormatStyle::ENAS_Left;
+ unsigned MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
unsigned StartOfMacro = 0;
for (unsigned i = 1, e = Changes.size(); i < e; ++i) {
Change &C = Changes[i];
@@ -527,7 +530,7 @@ void WhitespaceManager::alignEscapedNewlines() {
MaxEndOfLine = std::max(C.PreviousEndOfTokenColumn + 2, MaxEndOfLine);
} else {
alignEscapedNewlines(StartOfMacro + 1, i, MaxEndOfLine);
- MaxEndOfLine = Style.AlignEscapedNewlinesLeft ? 0 : Style.ColumnLimit;
+ MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
StartOfMacro = i;
}
}
@@ -602,7 +605,7 @@ void WhitespaceManager::appendNewlineText(std::string &Text, unsigned Newlines,
unsigned EscapedNewlineColumn) {
if (Newlines > 0) {
unsigned Offset =
- std::min<int>(EscapedNewlineColumn - 1, PreviousEndOfTokenColumn);
+ std::min<int>(EscapedNewlineColumn - 2, PreviousEndOfTokenColumn);
for (unsigned i = 0; i < Newlines; ++i) {
Text.append(EscapedNewlineColumn - Offset - 1, ' ');
Text.append(UseCRLF ? "\\\r\n" : "\\\n");
diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp
index 96854b8fbc1a..51147b6f9499 100644
--- a/lib/Frontend/CompilerInvocation.cpp
+++ b/lib/Frontend/CompilerInvocation.cpp
@@ -778,6 +778,8 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK,
Opts.SanitizeAddressUseAfterScope =
A->getOption().getID() == OPT_fsanitize_address_use_after_scope;
}
+ Opts.SanitizeAddressGlobalsDeadStripping =
+ Args.hasArg(OPT_fsanitize_address_globals_dead_stripping);
Opts.SSPBufferSize =
getLastArgIntValue(Args, OPT_stack_protector_buffer_size, 8, Diags);
Opts.StackRealignment = Args.hasArg(OPT_mstackrealign);
diff --git a/lib/Headers/avxintrin.h b/lib/Headers/avxintrin.h
index cdb7aa4fb626..15d28259dcc0 100644
--- a/lib/Headers/avxintrin.h
+++ b/lib/Headers/avxintrin.h
@@ -1458,12 +1458,13 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/// \brief Computes two dot products in parallel, using the lower and upper
/// halves of two [8 x float] vectors as input to the two computations, and
/// returning the two dot products in the lower and upper halves of the
-/// [8 x float] result. The immediate integer operand controls which input
-/// elements will contribute to the dot product, and where the final results
-/// are returned. In general, for each dot product, the four corresponding
-/// elements of the input vectors are multiplied; the first two and second
-/// two products are summed, then the two sums are added to form the final
-/// result.
+/// [8 x float] result.
+///
+/// The immediate integer operand controls which input elements will
+/// contribute to the dot product, and where the final results are returned.
+/// In general, for each dot product, the four corresponding elements of the
+/// input vectors are multiplied; the first two and second two products are
+/// summed, then the two sums are added to form the final result.
///
/// \headerfile <x86intrin.h>
///
@@ -1497,15 +1498,16 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/* Vector shuffle */
/// \brief Selects 8 float values from the 256-bit operands of [8 x float], as
-/// specified by the immediate value operand. The four selected elements in
-/// each operand are copied to the destination according to the bits
-/// specified in the immediate operand. The selected elements from the first
-/// 256-bit operand are copied to bits [63:0] and bits [191:128] of the
-/// destination, and the selected elements from the second 256-bit operand
-/// are copied to bits [127:64] and bits [255:192] of the destination. For
-/// example, if bits [7:0] of the immediate operand contain a value of 0xFF,
-/// the 256-bit destination vector would contain the following values: b[7],
-/// b[7], a[7], a[7], b[3], b[3], a[3], a[3].
+/// specified by the immediate value operand.
+///
+/// The four selected elements in each operand are copied to the destination
+/// according to the bits specified in the immediate operand. The selected
+/// elements from the first 256-bit operand are copied to bits [63:0] and
+/// bits [191:128] of the destination, and the selected elements from the
+/// second 256-bit operand are copied to bits [127:64] and bits [255:192] of
+/// the destination. For example, if bits [7:0] of the immediate operand
+/// contain a value of 0xFF, the 256-bit destination vector would contain the
+/// following values: b[7], b[7], a[7], a[7], b[3], b[3], a[3], a[3].
///
/// \headerfile <x86intrin.h>
///
@@ -1557,13 +1559,14 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
12 + (((mask) >> 6) & 0x3)); })
/// \brief Selects four double-precision values from the 256-bit operands of
-/// [4 x double], as specified by the immediate value operand. The selected
-/// elements from the first 256-bit operand are copied to bits [63:0] and
-/// bits [191:128] in the destination, and the selected elements from the
-/// second 256-bit operand are copied to bits [127:64] and bits [255:192] in
-/// the destination. For example, if bits [3:0] of the immediate operand
-/// contain a value of 0xF, the 256-bit destination vector would contain the
-/// following values: b[3], a[3], b[1], a[1].
+/// [4 x double], as specified by the immediate value operand.
+///
+/// The selected elements from the first 256-bit operand are copied to bits
+/// [63:0] and bits [191:128] in the destination, and the selected elements
+/// from the second 256-bit operand are copied to bits [127:64] and bits
+/// [255:192] in the destination. For example, if bits [3:0] of the immediate
+/// operand contain a value of 0xF, the 256-bit destination vector would
+/// contain the following values: b[3], a[3], b[1], a[1].
///
/// \headerfile <x86intrin.h>
///
@@ -1641,9 +1644,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/// \brief Compares each of the corresponding double-precision values of two
/// 128-bit vectors of [2 x double], using the operation specified by the
-/// immediate integer operand. Returns a [2 x double] vector consisting of
-/// two doubles corresponding to the two comparison results: zero if the
-/// comparison is false, and all 1's if the comparison is true.
+/// immediate integer operand.
+///
+/// Returns a [2 x double] vector consisting of two doubles corresponding to
+/// the two comparison results: zero if the comparison is false, and all 1's
+/// if the comparison is true.
///
/// \headerfile <x86intrin.h>
///
@@ -1699,9 +1704,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/// \brief Compares each of the corresponding values of two 128-bit vectors of
/// [4 x float], using the operation specified by the immediate integer
-/// operand. Returns a [4 x float] vector consisting of four floats
-/// corresponding to the four comparison results: zero if the comparison is
-/// false, and all 1's if the comparison is true.
+/// operand.
+///
+/// Returns a [4 x float] vector consisting of four floats corresponding to
+/// the four comparison results: zero if the comparison is false, and all 1's
+/// if the comparison is true.
///
/// \headerfile <x86intrin.h>
///
@@ -1757,9 +1764,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/// \brief Compares each of the corresponding double-precision values of two
/// 256-bit vectors of [4 x double], using the operation specified by the
-/// immediate integer operand. Returns a [4 x double] vector consisting of
-/// four doubles corresponding to the four comparison results: zero if the
-/// comparison is false, and all 1's if the comparison is true.
+/// immediate integer operand.
+///
+/// Returns a [4 x double] vector consisting of four doubles corresponding to
+/// the four comparison results: zero if the comparison is false, and all 1's
+/// if the comparison is true.
///
/// \headerfile <x86intrin.h>
///
@@ -1815,9 +1824,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/// \brief Compares each of the corresponding values of two 256-bit vectors of
/// [8 x float], using the operation specified by the immediate integer
-/// operand. Returns a [8 x float] vector consisting of eight floats
-/// corresponding to the eight comparison results: zero if the comparison is
-/// false, and all 1's if the comparison is true.
+/// operand.
+///
+/// Returns a [8 x float] vector consisting of eight floats corresponding to
+/// the eight comparison results: zero if the comparison is false, and all
+/// 1's if the comparison is true.
///
/// \headerfile <x86intrin.h>
///
@@ -1873,8 +1884,10 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/// \brief Compares each of the corresponding scalar double-precision values of
/// two 128-bit vectors of [2 x double], using the operation specified by the
-/// immediate integer operand. If the result is true, all 64 bits of the
-/// destination vector are set; otherwise they are cleared.
+/// immediate integer operand.
+///
+/// If the result is true, all 64 bits of the destination vector are set;
+/// otherwise they are cleared.
///
/// \headerfile <x86intrin.h>
///
@@ -1930,8 +1943,10 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
/// \brief Compares each of the corresponding scalar values of two 128-bit
/// vectors of [4 x float], using the operation specified by the immediate
-/// integer operand. If the result is true, all 32 bits of the destination
-/// vector are set; otherwise they are cleared.
+/// integer operand.
+///
+/// If the result is true, all 32 bits of the destination vector are set;
+/// otherwise they are cleared.
///
/// \headerfile <x86intrin.h>
///
@@ -2536,7 +2551,9 @@ _mm256_unpacklo_ps(__m256 __a, __m256 __b)
/// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
/// element-by-element comparison of the double-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of double-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2563,7 +2580,9 @@ _mm_testz_pd(__m128d __a, __m128d __b)
/// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
/// element-by-element comparison of the double-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of double-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2590,7 +2609,9 @@ _mm_testc_pd(__m128d __a, __m128d __b)
/// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
/// element-by-element comparison of the double-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of double-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2618,7 +2639,9 @@ _mm_testnzc_pd(__m128d __a, __m128d __b)
/// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
/// element-by-element comparison of the single-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of single-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2645,7 +2668,9 @@ _mm_testz_ps(__m128 __a, __m128 __b)
/// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
/// element-by-element comparison of the single-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of single-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2672,7 +2697,9 @@ _mm_testc_ps(__m128 __a, __m128 __b)
/// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
/// element-by-element comparison of the single-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of single-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2700,7 +2727,9 @@ _mm_testnzc_ps(__m128 __a, __m128 __b)
/// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
/// element-by-element comparison of the double-precision elements in the
/// first source vector and the corresponding elements in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of double-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2727,7 +2756,9 @@ _mm256_testz_pd(__m256d __a, __m256d __b)
/// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
/// element-by-element comparison of the double-precision elements in the
/// first source vector and the corresponding elements in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of double-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2754,7 +2785,9 @@ _mm256_testc_pd(__m256d __a, __m256d __b)
/// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
/// element-by-element comparison of the double-precision elements in the
/// first source vector and the corresponding elements in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of double-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2782,7 +2815,9 @@ _mm256_testnzc_pd(__m256d __a, __m256d __b)
/// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
/// element-by-element comparison of the single-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of single-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2809,7 +2844,9 @@ _mm256_testz_ps(__m256 __a, __m256 __b)
/// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
/// element-by-element comparison of the single-precision element in the
/// first source vector and the corresponding element in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of single-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2836,7 +2873,9 @@ _mm256_testc_ps(__m256 __a, __m256 __b)
/// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
/// element-by-element comparison of the single-precision elements in the
/// first source vector and the corresponding elements in the second source
-/// vector. The EFLAGS register is updated as follows: \n
+/// vector.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of single-precision elements where the
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
/// ZF flag is set to 1. \n
@@ -2862,7 +2901,9 @@ _mm256_testnzc_ps(__m256 __a, __m256 __b)
}
/// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
-/// of the two source vectors and update the EFLAGS register as follows: \n
+/// of the two source vectors.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of bits where both bits are 1, the ZF flag
/// is set to 0. Otherwise the ZF flag is set to 1. \n
/// If there is at least one pair of bits where the bit from the first source
@@ -2886,7 +2927,9 @@ _mm256_testz_si256(__m256i __a, __m256i __b)
}
/// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
-/// of the two source vectors and update the EFLAGS register as follows: \n
+/// of the two source vectors.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of bits where both bits are 1, the ZF flag
/// is set to 0. Otherwise the ZF flag is set to 1. \n
/// If there is at least one pair of bits where the bit from the first source
@@ -2910,7 +2953,9 @@ _mm256_testc_si256(__m256i __a, __m256i __b)
}
/// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
-/// of the two source vectors and update the EFLAGS register as follows: \n
+/// of the two source vectors.
+///
+/// The EFLAGS register is updated as follows: \n
/// If there is at least one pair of bits where both bits are 1, the ZF flag
/// is set to 0. Otherwise the ZF flag is set to 1. \n
/// If there is at least one pair of bits where the bit from the first source
@@ -4466,9 +4511,10 @@ _mm256_castsi256_si128(__m256i __a)
}
/// \brief Constructs a 256-bit floating-point vector of [4 x double] from a
-/// 128-bit floating-point vector of [2 x double]. The lower 128 bits
-/// contain the value of the source vector. The contents of the upper 128
-/// bits are undefined.
+/// 128-bit floating-point vector of [2 x double].
+///
+/// The lower 128 bits contain the value of the source vector. The contents
+/// of the upper 128 bits are undefined.
///
/// \headerfile <x86intrin.h>
///
@@ -4486,9 +4532,10 @@ _mm256_castpd128_pd256(__m128d __a)
}
/// \brief Constructs a 256-bit floating-point vector of [8 x float] from a
-/// 128-bit floating-point vector of [4 x float]. The lower 128 bits contain
-/// the value of the source vector. The contents of the upper 128 bits are
-/// undefined.
+/// 128-bit floating-point vector of [4 x float].
+///
+/// The lower 128 bits contain the value of the source vector. The contents
+/// of the upper 128 bits are undefined.
///
/// \headerfile <x86intrin.h>
///
@@ -4506,6 +4553,7 @@ _mm256_castps128_ps256(__m128 __a)
}
/// \brief Constructs a 256-bit integer vector from a 128-bit integer vector.
+///
/// The lower 128 bits contain the value of the source vector. The contents
/// of the upper 128 bits are undefined.
///
@@ -4586,8 +4634,10 @@ _mm256_zextsi128_si256(__m128i __a)
/// \brief Constructs a new 256-bit vector of [8 x float] by first duplicating
/// a 256-bit vector of [8 x float] given in the first parameter, and then
/// replacing either the upper or the lower 128 bits with the contents of a
-/// 128-bit vector of [4 x float] in the second parameter. The immediate
-/// integer parameter determines between the upper or the lower 128 bits.
+/// 128-bit vector of [4 x float] in the second parameter.
+///
+/// The immediate integer parameter determines between the upper or the lower
+/// 128 bits.
///
/// \headerfile <x86intrin.h>
///
@@ -4631,8 +4681,10 @@ _mm256_zextsi128_si256(__m128i __a)
/// \brief Constructs a new 256-bit vector of [4 x double] by first duplicating
/// a 256-bit vector of [4 x double] given in the first parameter, and then
/// replacing either the upper or the lower 128 bits with the contents of a
-/// 128-bit vector of [2 x double] in the second parameter. The immediate
-/// integer parameter determines between the upper or the lower 128 bits.
+/// 128-bit vector of [2 x double] in the second parameter.
+///
+/// The immediate integer parameter determines between the upper or the lower
+/// 128 bits.
///
/// \headerfile <x86intrin.h>
///
@@ -4672,8 +4724,10 @@ _mm256_zextsi128_si256(__m128i __a)
/// \brief Constructs a new 256-bit integer vector by first duplicating a
/// 256-bit integer vector given in the first parameter, and then replacing
/// either the upper or the lower 128 bits with the contents of a 128-bit
-/// integer vector in the second parameter. The immediate integer parameter
-/// determines between the upper or the lower 128 bits.
+/// integer vector in the second parameter.
+///
+/// The immediate integer parameter determines between the upper or the lower
+/// 128 bits.
///
/// \headerfile <x86intrin.h>
///
diff --git a/lib/Headers/emmintrin.h b/lib/Headers/emmintrin.h
index 13b0db22ec44..fa5cefadc52c 100644
--- a/lib/Headers/emmintrin.h
+++ b/lib/Headers/emmintrin.h
@@ -462,8 +462,9 @@ _mm_cmplt_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are less than or equal to those in the second operand. Each
-/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// operand are less than or equal to those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -482,8 +483,9 @@ _mm_cmple_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are greater than those in the second operand. Each comparison
-/// yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// operand are greater than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -502,8 +504,9 @@ _mm_cmpgt_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are greater than or equal to those in the second operand. Each
-/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// operand are greater than or equal to those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -522,9 +525,10 @@ _mm_cmpge_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are ordered with respect to those in the second operand. A pair
-/// of double-precision values are "ordered" with respect to each other if
-/// neither value is a NaN. Each comparison yields 0h for false,
+/// operand are ordered with respect to those in the second operand.
+///
+/// A pair of double-precision values are "ordered" with respect to each
+/// other if neither value is a NaN. Each comparison yields 0h for false,
/// FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
@@ -544,9 +548,10 @@ _mm_cmpord_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are unordered with respect to those in the second operand. A pair
-/// of double-precision values are "unordered" with respect to each other if
-/// one or both values are NaN. Each comparison yields 0h for false,
+/// operand are unordered with respect to those in the second operand.
+///
+/// A pair of double-precision values are "unordered" with respect to each
+/// other if one or both values are NaN. Each comparison yields 0h for false,
/// FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
@@ -567,8 +572,9 @@ _mm_cmpunord_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are unequal to those in the second operand. Each comparison
-/// yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// operand are unequal to those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -587,8 +593,9 @@ _mm_cmpneq_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are not less than those in the second operand. Each comparison
-/// yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// operand are not less than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -607,8 +614,9 @@ _mm_cmpnlt_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are not less than or equal to those in the second operand. Each
-/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// operand are not less than or equal to those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -627,8 +635,9 @@ _mm_cmpnle_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
-/// operand are not greater than those in the second operand. Each
-/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// operand are not greater than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -648,6 +657,7 @@ _mm_cmpngt_pd(__m128d __a, __m128d __b)
/// \brief Compares each of the corresponding double-precision values of the
/// 128-bit vectors of [2 x double] to determine if the values in the first
/// operand are not greater than or equal to those in the second operand.
+///
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
@@ -666,8 +676,9 @@ _mm_cmpnge_pd(__m128d __a, __m128d __b)
}
/// \brief Compares the lower double-precision floating-point values in each of
-/// the two 128-bit floating-point vectors of [2 x double] for equality. The
-/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
+/// the two 128-bit floating-point vectors of [2 x double] for equality.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -690,8 +701,9 @@ _mm_cmpeq_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is less than the corresponding value in
-/// the second parameter. The comparison yields 0h for false,
-/// FFFFFFFFFFFFFFFFh for true.
+/// the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -714,8 +726,9 @@ _mm_cmplt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is less than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0h for
-/// false, FFFFFFFFFFFFFFFFh for true.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -738,8 +751,9 @@ _mm_cmple_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is greater than the corresponding value
-/// in the second parameter. The comparison yields 0h for false,
-/// FFFFFFFFFFFFFFFFh for true.
+/// in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -763,8 +777,9 @@ _mm_cmpgt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is greater than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0h for
-/// false, FFFFFFFFFFFFFFFFh for true.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -788,9 +803,11 @@ _mm_cmpge_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is "ordered" with respect to the
-/// corresponding value in the second parameter. The comparison yields 0h for
-/// false, FFFFFFFFFFFFFFFFh for true. A pair of double-precision values are
-/// "ordered" with respect to each other if neither value is a NaN.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true. A pair of
+/// double-precision values are "ordered" with respect to each other if
+/// neither value is a NaN.
///
/// \headerfile <x86intrin.h>
///
@@ -813,9 +830,11 @@ _mm_cmpord_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is "unordered" with respect to the
-/// corresponding value in the second parameter. The comparison yields 0h
-/// for false, FFFFFFFFFFFFFFFFh for true. A pair of double-precision values
-/// are "unordered" with respect to each other if one or both values are NaN.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true. A pair of
+/// double-precision values are "unordered" with respect to each other if one
+/// or both values are NaN.
///
/// \headerfile <x86intrin.h>
///
@@ -839,8 +858,9 @@ _mm_cmpunord_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is unequal to the corresponding value in
-/// the second parameter. The comparison yields 0h for false,
-/// FFFFFFFFFFFFFFFFh for true.
+/// the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -863,8 +883,9 @@ _mm_cmpneq_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is not less than the corresponding
-/// value in the second parameter. The comparison yields 0h for false,
-/// FFFFFFFFFFFFFFFFh for true.
+/// value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -887,8 +908,9 @@ _mm_cmpnlt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is not less than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0h
-/// for false, FFFFFFFFFFFFFFFFh for true.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -911,8 +933,9 @@ _mm_cmpnle_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is not greater than the corresponding
-/// value in the second parameter. The comparison yields 0h for false,
-/// FFFFFFFFFFFFFFFFh for true.
+/// value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -936,8 +959,9 @@ _mm_cmpngt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is not greater than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0h
-/// for false, FFFFFFFFFFFFFFFFh for true.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -982,7 +1006,9 @@ _mm_comieq_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is less than the corresponding value in
-/// the second parameter. The comparison yields 0 for false, 1 for true.
+/// the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1004,8 +1030,9 @@ _mm_comilt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is less than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0 for
-/// false, 1 for true.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1027,7 +1054,9 @@ _mm_comile_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is greater than the corresponding value
-/// in the second parameter. The comparison yields 0 for false, 1 for true.
+/// in the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1049,8 +1078,9 @@ _mm_comigt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is greater than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0 for
-/// false, 1 for true.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1072,7 +1102,9 @@ _mm_comige_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is unequal to the corresponding value in
-/// the second parameter. The comparison yields 0 for false, 1 for true.
+/// the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1093,8 +1125,9 @@ _mm_comineq_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] for equality. The
-/// comparison yields 0 for false, 1 for true. If either of the two lower
-/// double-precision values is NaN, 1 is returned.
+/// comparison yields 0 for false, 1 for true.
+///
+/// If either of the two lower double-precision values is NaN, 1 is returned.
///
/// \headerfile <x86intrin.h>
///
@@ -1117,8 +1150,10 @@ _mm_ucomieq_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is less than the corresponding value in
-/// the second parameter. The comparison yields 0 for false, 1 for true. If
-/// either of the two lower double-precision values is NaN, 1 is returned.
+/// the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true. If either of the two lower
+/// double-precision values is NaN, 1 is returned.
///
/// \headerfile <x86intrin.h>
///
@@ -1141,9 +1176,10 @@ _mm_ucomilt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is less than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0 for
-/// false, 1 for true. If either of the two lower double-precision values is
-/// NaN, 1 is returned.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true. If either of the two lower
+/// double-precision values is NaN, 1 is returned.
///
/// \headerfile <x86intrin.h>
///
@@ -1166,8 +1202,10 @@ _mm_ucomile_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is greater than the corresponding value
-/// in the second parameter. The comparison yields 0 for false, 1 for true.
-/// If either of the two lower double-precision values is NaN, 0 is returned.
+/// in the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true. If either of the two lower
+/// double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@@ -1190,9 +1228,10 @@ _mm_ucomigt_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is greater than or equal to the
-/// corresponding value in the second parameter. The comparison yields 0 for
-/// false, 1 for true. If either of the two lower double-precision values
-/// is NaN, 0 is returned.
+/// corresponding value in the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true. If either of the two
+/// lower double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@@ -1215,8 +1254,10 @@ _mm_ucomige_sd(__m128d __a, __m128d __b)
/// \brief Compares the lower double-precision floating-point values in each of
/// the two 128-bit floating-point vectors of [2 x double] to determine if
/// the value in the first parameter is unequal to the corresponding value in
-/// the second parameter. The comparison yields 0 for false, 1 for true. If
-/// either of the two lower double-precision values is NaN, 0 is returned.
+/// the second parameter.
+///
+/// The comparison yields 0 for false, 1 for true. If either of the two lower
+/// double-precision values is NaN, 0 is returned.
///
/// \headerfile <x86intrin.h>
///
@@ -1278,8 +1319,9 @@ _mm_cvtps_pd(__m128 __a)
/// \brief Converts the lower two integer elements of a 128-bit vector of
/// [4 x i32] into two double-precision floating-point values, returned in a
-/// 128-bit vector of [2 x double]. The upper two elements of the input
-/// vector are unused.
+/// 128-bit vector of [2 x double].
+///
+/// The upper two elements of the input vector are unused.
///
/// \headerfile <x86intrin.h>
///
@@ -1287,7 +1329,9 @@ _mm_cvtps_pd(__m128 __a)
///
/// \param __a
/// A 128-bit integer vector of [4 x i32]. The lower two integer elements are
-/// converted to double-precision values. The upper two elements are unused.
+/// converted to double-precision values.
+///
+/// The upper two elements are unused.
/// \returns A 128-bit vector of [2 x double] containing the converted values.
static __inline__ __m128d __DEFAULT_FN_ATTRS
_mm_cvtepi32_pd(__m128i __a)
@@ -1409,10 +1453,11 @@ _mm_cvtss_sd(__m128d __a, __m128 __b)
/// \brief Converts the two double-precision floating-point elements of a
/// 128-bit vector of [2 x double] into two signed 32-bit integer values,
-/// returned in the lower 64 bits of a 128-bit vector of [4 x i32]. If the
-/// result of either conversion is inexact, the result is truncated (rounded
-/// towards zero) regardless of the current MXCSR setting. The upper 64 bits
-/// of the result vector are set to zero.
+/// returned in the lower 64 bits of a 128-bit vector of [4 x i32].
+///
+/// If the result of either conversion is inexact, the result is truncated
+/// (rounded towards zero) regardless of the current MXCSR setting. The upper
+/// 64 bits of the result vector are set to zero.
///
/// \headerfile <x86intrin.h>
///
@@ -1466,9 +1511,10 @@ _mm_cvtpd_pi32(__m128d __a)
/// \brief Converts the two double-precision floating-point elements of a
/// 128-bit vector of [2 x double] into two signed 32-bit integer values,
-/// returned in a 64-bit vector of [2 x i32]. If the result of either
-/// conversion is inexact, the result is truncated (rounded towards zero)
-/// regardless of the current MXCSR setting.
+/// returned in a 64-bit vector of [2 x i32].
+///
+/// If the result of either conversion is inexact, the result is truncated
+/// (rounded towards zero) regardless of the current MXCSR setting.
///
/// \headerfile <x86intrin.h>
///
@@ -1980,8 +2026,9 @@ _mm_storel_pd(double *__dp, __m128d __a)
/// \brief Adds the corresponding elements of two 128-bit vectors of [16 x i8],
/// saving the lower 8 bits of each sum in the corresponding element of a
-/// 128-bit result vector of [16 x i8]. The integer elements of both
-/// parameters can be either signed or unsigned.
+/// 128-bit result vector of [16 x i8].
+///
+/// The integer elements of both parameters can be either signed or unsigned.
///
/// \headerfile <x86intrin.h>
///
@@ -2001,8 +2048,9 @@ _mm_add_epi8(__m128i __a, __m128i __b)
/// \brief Adds the corresponding elements of two 128-bit vectors of [8 x i16],
/// saving the lower 16 bits of each sum in the corresponding element of a
-/// 128-bit result vector of [8 x i16]. The integer elements of both
-/// parameters can be either signed or unsigned.
+/// 128-bit result vector of [8 x i16].
+///
+/// The integer elements of both parameters can be either signed or unsigned.
///
/// \headerfile <x86intrin.h>
///
@@ -2022,8 +2070,9 @@ _mm_add_epi16(__m128i __a, __m128i __b)
/// \brief Adds the corresponding elements of two 128-bit vectors of [4 x i32],
/// saving the lower 32 bits of each sum in the corresponding element of a
-/// 128-bit result vector of [4 x i32]. The integer elements of both
-/// parameters can be either signed or unsigned.
+/// 128-bit result vector of [4 x i32].
+///
+/// The integer elements of both parameters can be either signed or unsigned.
///
/// \headerfile <x86intrin.h>
///
@@ -2061,8 +2110,9 @@ _mm_add_si64(__m64 __a, __m64 __b)
/// \brief Adds the corresponding elements of two 128-bit vectors of [2 x i64],
/// saving the lower 64 bits of each sum in the corresponding element of a
-/// 128-bit result vector of [2 x i64]. The integer elements of both
-/// parameters can be either signed or unsigned.
+/// 128-bit result vector of [2 x i64].
+///
+/// The integer elements of both parameters can be either signed or unsigned.
///
/// \headerfile <x86intrin.h>
///
@@ -2208,10 +2258,12 @@ _mm_avg_epu16(__m128i __a, __m128i __b)
/// \brief Multiplies the corresponding elements of two 128-bit signed [8 x i16]
/// vectors, producing eight intermediate 32-bit signed integer products, and
/// adds the consecutive pairs of 32-bit products to form a 128-bit signed
-/// [4 x i32] vector. For example, bits [15:0] of both parameters are
-/// multiplied producing a 32-bit product, bits [31:16] of both parameters
-/// are multiplied producing a 32-bit product, and the sum of those two
-/// products becomes bits [31:0] of the result.
+/// [4 x i32] vector.
+///
+/// For example, bits [15:0] of both parameters are multiplied producing a
+/// 32-bit product, bits [31:16] of both parameters are multiplied producing
+/// a 32-bit product, and the sum of those two products becomes bits [31:0]
+/// of the result.
///
/// \headerfile <x86intrin.h>
///
@@ -3146,8 +3198,9 @@ _mm_cmpgt_epi8(__m128i __a, __m128i __b)
/// \brief Compares each of the corresponding signed 16-bit values of the
/// 128-bit integer vectors to determine if the values in the first operand
-/// are greater than those in the second operand. Each comparison yields 0h
-/// for false, FFFFh for true.
+/// are greater than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -3166,8 +3219,9 @@ _mm_cmpgt_epi16(__m128i __a, __m128i __b)
/// \brief Compares each of the corresponding signed 32-bit values of the
/// 128-bit integer vectors to determine if the values in the first operand
-/// are greater than those in the second operand. Each comparison yields 0h
-/// for false, FFFFFFFFh for true.
+/// are greater than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -3186,8 +3240,9 @@ _mm_cmpgt_epi32(__m128i __a, __m128i __b)
/// \brief Compares each of the corresponding signed 8-bit values of the 128-bit
/// integer vectors to determine if the values in the first operand are less
-/// than those in the second operand. Each comparison yields 0h for false,
-/// FFh for true.
+/// than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -3206,8 +3261,9 @@ _mm_cmplt_epi8(__m128i __a, __m128i __b)
/// \brief Compares each of the corresponding signed 16-bit values of the
/// 128-bit integer vectors to determine if the values in the first operand
-/// are less than those in the second operand. Each comparison yields 0h for
-/// false, FFFFh for true.
+/// are less than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -3226,8 +3282,9 @@ _mm_cmplt_epi16(__m128i __a, __m128i __b)
/// \brief Compares each of the corresponding signed 32-bit values of the
/// 128-bit integer vectors to determine if the values in the first operand
-/// are less than those in the second operand. Each comparison yields 0h for
-/// false, FFFFFFFFh for true.
+/// are less than those in the second operand.
+///
+/// Each comparison yields 0h for false, FFFFFFFFh for true.
///
/// \headerfile <x86intrin.h>
///
@@ -3925,10 +3982,11 @@ _mm_storeu_si128(__m128i *__p, __m128i __b)
/// \brief Moves bytes selected by the mask from the first operand to the
/// specified unaligned memory location. When a mask bit is 1, the
-/// corresponding byte is written, otherwise it is not written. To minimize
-/// caching, the date is flagged as non-temporal (unlikely to be used again
-/// soon). Exception and trap behavior for elements not selected for storage
-/// to memory are implementation dependent.
+/// corresponding byte is written, otherwise it is not written.
+///
+/// To minimize caching, the date is flagged as non-temporal (unlikely to be
+/// used again soon). Exception and trap behavior for elements not selected
+/// for storage to memory are implementation dependent.
///
/// \headerfile <x86intrin.h>
///
@@ -3972,8 +4030,10 @@ _mm_storel_epi64(__m128i *__p, __m128i __a)
}
/// \brief Stores a 128-bit floating point vector of [2 x double] to a 128-bit
-/// aligned memory location. To minimize caching, the data is flagged as
-/// non-temporal (unlikely to be used again soon).
+/// aligned memory location.
+///
+/// To minimize caching, the data is flagged as non-temporal (unlikely to be
+/// used again soon).
///
/// \headerfile <x86intrin.h>
///
@@ -3990,6 +4050,7 @@ _mm_stream_pd(double *__p, __m128d __a)
}
/// \brief Stores a 128-bit integer vector to a 128-bit aligned memory location.
+///
/// To minimize caching, the data is flagged as non-temporal (unlikely to be
/// used again soon).
///
@@ -4007,8 +4068,9 @@ _mm_stream_si128(__m128i *__p, __m128i __a)
__builtin_nontemporal_store((__v2di)__a, (__v2di*)__p);
}
-/// \brief Stores a 32-bit integer value in the specified memory location. To
-/// minimize caching, the data is flagged as non-temporal (unlikely to be
+/// \brief Stores a 32-bit integer value in the specified memory location.
+///
+/// To minimize caching, the data is flagged as non-temporal (unlikely to be
/// used again soon).
///
/// \headerfile <x86intrin.h>
@@ -4026,8 +4088,9 @@ _mm_stream_si32(int *__p, int __a)
}
#ifdef __x86_64__
-/// \brief Stores a 64-bit integer value in the specified memory location. To
-/// minimize caching, the data is flagged as non-temporal (unlikely to be
+/// \brief Stores a 64-bit integer value in the specified memory location.
+///
+/// To minimize caching, the data is flagged as non-temporal (unlikely to be
/// used again soon).
///
/// \headerfile <x86intrin.h>
diff --git a/lib/Headers/intrin.h b/lib/Headers/intrin.h
index 38d9407abed9..881d05c0d164 100644
--- a/lib/Headers/intrin.h
+++ b/lib/Headers/intrin.h
@@ -85,9 +85,6 @@ void __inwordstring(unsigned short, unsigned short *, unsigned long);
void __lidt(void *);
unsigned __int64 __ll_lshift(unsigned __int64, int);
__int64 __ll_rshift(__int64, int);
-void __llwpcb(void *);
-unsigned char __lwpins32(unsigned int, unsigned int, unsigned int);
-void __lwpval32(unsigned int, unsigned int, unsigned int);
unsigned int __lzcnt(unsigned int);
unsigned short __lzcnt16(unsigned short);
static __inline__
@@ -126,7 +123,6 @@ unsigned __int64 __readmsr(unsigned long);
unsigned __int64 __readpmc(unsigned long);
unsigned long __segmentlimit(unsigned long);
void __sidt(void *);
-void *__slwpcb(void);
static __inline__
void __stosb(unsigned char *, unsigned char, size_t);
static __inline__
@@ -227,8 +223,6 @@ void __incgsbyte(unsigned long);
void __incgsdword(unsigned long);
void __incgsqword(unsigned long);
void __incgsword(unsigned long);
-unsigned char __lwpins64(unsigned __int64, unsigned int, unsigned int);
-void __lwpval64(unsigned __int64, unsigned int, unsigned int);
unsigned __int64 __lzcnt64(unsigned __int64);
static __inline__
void __movsq(unsigned long long *, unsigned long long const *, size_t);
diff --git a/lib/Headers/mmintrin.h b/lib/Headers/mmintrin.h
index 2b3618398cbf..5a7968bec842 100644
--- a/lib/Headers/mmintrin.h
+++ b/lib/Headers/mmintrin.h
@@ -608,10 +608,11 @@ _mm_subs_pi16(__m64 __m1, __m64 __m2)
/// \brief Subtracts each 8-bit unsigned integer element of the second 64-bit
/// integer vector of [8 x i8] from the corresponding 8-bit unsigned integer
-/// element of the first 64-bit integer vector of [8 x i8]. If an element of
-/// the first vector is less than the corresponding element of the second
-/// vector, the result is saturated to 0. The results are packed into a
-/// 64-bit integer vector of [8 x i8].
+/// element of the first 64-bit integer vector of [8 x i8].
+///
+/// If an element of the first vector is less than the corresponding element
+/// of the second vector, the result is saturated to 0. The results are
+/// packed into a 64-bit integer vector of [8 x i8].
///
/// \headerfile <x86intrin.h>
///
@@ -631,10 +632,11 @@ _mm_subs_pu8(__m64 __m1, __m64 __m2)
/// \brief Subtracts each 16-bit unsigned integer element of the second 64-bit
/// integer vector of [4 x i16] from the corresponding 16-bit unsigned
-/// integer element of the first 64-bit integer vector of [4 x i16]. If an
-/// element of the first vector is less than the corresponding element of the
-/// second vector, the result is saturated to 0. The results are packed into
-/// a 64-bit integer vector of [4 x i16].
+/// integer element of the first 64-bit integer vector of [4 x i16].
+///
+/// If an element of the first vector is less than the corresponding element
+/// of the second vector, the result is saturated to 0. The results are
+/// packed into a 64-bit integer vector of [4 x i16].
///
/// \headerfile <x86intrin.h>
///
@@ -657,9 +659,11 @@ _mm_subs_pu16(__m64 __m1, __m64 __m2)
/// element of the second 64-bit integer vector of [4 x i16] and get four
/// 32-bit products. Adds adjacent pairs of products to get two 32-bit sums.
/// The lower 32 bits of these two sums are packed into a 64-bit integer
-/// vector of [2 x i32]. For example, bits [15:0] of both parameters are
-/// multiplied, bits [31:16] of both parameters are multiplied, and the sum
-/// of both results is written to bits [31:0] of the result.
+/// vector of [2 x i32].
+///
+/// For example, bits [15:0] of both parameters are multiplied, bits [31:16]
+/// of both parameters are multiplied, and the sum of both results is written
+/// to bits [31:0] of the result.
///
/// \headerfile <x86intrin.h>
///
@@ -851,10 +855,11 @@ _mm_slli_si64(__m64 __m, int __count)
/// \brief Right-shifts each 16-bit integer element of the first parameter,
/// which is a 64-bit integer vector of [4 x i16], by the number of bits
-/// specified by the second parameter, which is a 64-bit integer. High-order
-/// bits are filled with the sign bit of the initial value of each 16-bit
-/// element. The 16-bit results are packed into a 64-bit integer vector of
-/// [4 x i16].
+/// specified by the second parameter, which is a 64-bit integer.
+///
+/// High-order bits are filled with the sign bit of the initial value of each
+/// 16-bit element. The 16-bit results are packed into a 64-bit integer
+/// vector of [4 x i16].
///
/// \headerfile <x86intrin.h>
///
@@ -874,6 +879,7 @@ _mm_sra_pi16(__m64 __m, __m64 __count)
/// \brief Right-shifts each 16-bit integer element of a 64-bit integer vector
/// of [4 x i16] by the number of bits specified by a 32-bit integer.
+///
/// High-order bits are filled with the sign bit of the initial value of each
/// 16-bit element. The 16-bit results are packed into a 64-bit integer
/// vector of [4 x i16].
@@ -896,10 +902,11 @@ _mm_srai_pi16(__m64 __m, int __count)
/// \brief Right-shifts each 32-bit integer element of the first parameter,
/// which is a 64-bit integer vector of [2 x i32], by the number of bits
-/// specified by the second parameter, which is a 64-bit integer. High-order
-/// bits are filled with the sign bit of the initial value of each 32-bit
-/// element. The 32-bit results are packed into a 64-bit integer vector of
-/// [2 x i32].
+/// specified by the second parameter, which is a 64-bit integer.
+///
+/// High-order bits are filled with the sign bit of the initial value of each
+/// 32-bit element. The 32-bit results are packed into a 64-bit integer
+/// vector of [2 x i32].
///
/// \headerfile <x86intrin.h>
///
@@ -919,6 +926,7 @@ _mm_sra_pi32(__m64 __m, __m64 __count)
/// \brief Right-shifts each 32-bit integer element of a 64-bit integer vector
/// of [2 x i32] by the number of bits specified by a 32-bit integer.
+///
/// High-order bits are filled with the sign bit of the initial value of each
/// 32-bit element. The 32-bit results are packed into a 64-bit integer
/// vector of [2 x i32].
@@ -941,9 +949,10 @@ _mm_srai_pi32(__m64 __m, int __count)
/// \brief Right-shifts each 16-bit integer element of the first parameter,
/// which is a 64-bit integer vector of [4 x i16], by the number of bits
-/// specified by the second parameter, which is a 64-bit integer. High-order
-/// bits are cleared. The 16-bit results are packed into a 64-bit integer
-/// vector of [4 x i16].
+/// specified by the second parameter, which is a 64-bit integer.
+///
+/// High-order bits are cleared. The 16-bit results are packed into a 64-bit
+/// integer vector of [4 x i16].
///
/// \headerfile <x86intrin.h>
///
@@ -963,6 +972,7 @@ _mm_srl_pi16(__m64 __m, __m64 __count)
/// \brief Right-shifts each 16-bit integer element of a 64-bit integer vector
/// of [4 x i16] by the number of bits specified by a 32-bit integer.
+///
/// High-order bits are cleared. The 16-bit results are packed into a 64-bit
/// integer vector of [4 x i16].
///
@@ -984,9 +994,10 @@ _mm_srli_pi16(__m64 __m, int __count)
/// \brief Right-shifts each 32-bit integer element of the first parameter,
/// which is a 64-bit integer vector of [2 x i32], by the number of bits
-/// specified by the second parameter, which is a 64-bit integer. High-order
-/// bits are cleared. The 32-bit results are packed into a 64-bit integer
-/// vector of [2 x i32].
+/// specified by the second parameter, which is a 64-bit integer.
+///
+/// High-order bits are cleared. The 32-bit results are packed into a 64-bit
+/// integer vector of [2 x i32].
///
/// \headerfile <x86intrin.h>
///
@@ -1006,6 +1017,7 @@ _mm_srl_pi32(__m64 __m, __m64 __count)
/// \brief Right-shifts each 32-bit integer element of a 64-bit integer vector
/// of [2 x i32] by the number of bits specified by a 32-bit integer.
+///
/// High-order bits are cleared. The 32-bit results are packed into a 64-bit
/// integer vector of [2 x i32].
///
@@ -1026,8 +1038,9 @@ _mm_srli_pi32(__m64 __m, int __count)
}
/// \brief Right-shifts the first 64-bit integer parameter by the number of bits
-/// specified by the second 64-bit integer parameter. High-order bits are
-/// cleared.
+/// specified by the second 64-bit integer parameter.
+///
+/// High-order bits are cleared.
///
/// \headerfile <x86intrin.h>
///
@@ -1046,7 +1059,9 @@ _mm_srl_si64(__m64 __m, __m64 __count)
/// \brief Right-shifts the first parameter, which is a 64-bit integer, by the
/// number of bits specified by the second parameter, which is a 32-bit
-/// integer. High-order bits are cleared.
+/// integer.
+///
+/// High-order bits are cleared.
///
/// \headerfile <x86intrin.h>
///
@@ -1140,8 +1155,9 @@ _mm_xor_si64(__m64 __m1, __m64 __m2)
/// \brief Compares the 8-bit integer elements of two 64-bit integer vectors of
/// [8 x i8] to determine if the element of the first vector is equal to the
-/// corresponding element of the second vector. The comparison yields 0 for
-/// false, 0xFF for true.
+/// corresponding element of the second vector.
+///
+/// The comparison yields 0 for false, 0xFF for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1161,8 +1177,9 @@ _mm_cmpeq_pi8(__m64 __m1, __m64 __m2)
/// \brief Compares the 16-bit integer elements of two 64-bit integer vectors of
/// [4 x i16] to determine if the element of the first vector is equal to the
-/// corresponding element of the second vector. The comparison yields 0 for
-/// false, 0xFFFF for true.
+/// corresponding element of the second vector.
+///
+/// The comparison yields 0 for false, 0xFFFF for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1182,8 +1199,9 @@ _mm_cmpeq_pi16(__m64 __m1, __m64 __m2)
/// \brief Compares the 32-bit integer elements of two 64-bit integer vectors of
/// [2 x i32] to determine if the element of the first vector is equal to the
-/// corresponding element of the second vector. The comparison yields 0 for
-/// false, 0xFFFFFFFF for true.
+/// corresponding element of the second vector.
+///
+/// The comparison yields 0 for false, 0xFFFFFFFF for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1203,8 +1221,9 @@ _mm_cmpeq_pi32(__m64 __m1, __m64 __m2)
/// \brief Compares the 8-bit integer elements of two 64-bit integer vectors of
/// [8 x i8] to determine if the element of the first vector is greater than
-/// the corresponding element of the second vector. The comparison yields 0
-/// for false, 0xFF for true.
+/// the corresponding element of the second vector.
+///
+/// The comparison yields 0 for false, 0xFF for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1224,8 +1243,9 @@ _mm_cmpgt_pi8(__m64 __m1, __m64 __m2)
/// \brief Compares the 16-bit integer elements of two 64-bit integer vectors of
/// [4 x i16] to determine if the element of the first vector is greater than
-/// the corresponding element of the second vector. The comparison yields 0
-/// for false, 0xFFFF for true.
+/// the corresponding element of the second vector.
+///
+/// The comparison yields 0 for false, 0xFFFF for true.
///
/// \headerfile <x86intrin.h>
///
@@ -1245,8 +1265,9 @@ _mm_cmpgt_pi16(__m64 __m1, __m64 __m2)
/// \brief Compares the 32-bit integer elements of two 64-bit integer vectors of
/// [2 x i32] to determine if the element of the first vector is greater than
-/// the corresponding element of the second vector. The comparison yields 0
-/// for false, 0xFFFFFFFF for true.
+/// the corresponding element of the second vector.
+///
+/// The comparison yields 0 for false, 0xFFFFFFFF for true.
///
/// \headerfile <x86intrin.h>
///
diff --git a/lib/Headers/opencl-c.h b/lib/Headers/opencl-c.h
index 6452d5c987f0..58c8daf3a536 100644
--- a/lib/Headers/opencl-c.h
+++ b/lib/Headers/opencl-c.h
@@ -14962,6 +14962,7 @@ float __purefn __ovld read_imagef(read_only image2d_array_msaa_depth_t image, in
#endif //cl_khr_gl_msaa_sharing
// OpenCL Extension v2.0 s9.18 - Mipmaps
+#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
#ifdef cl_khr_mipmap_image
float4 __purefn __ovld read_imagef(read_only image1d_t image, sampler_t sampler, float coord, float lod);
@@ -15037,6 +15038,7 @@ int4 __purefn __ovld read_imagei(read_only image3d_t image, sampler_t sampler, f
uint4 __purefn __ovld read_imageui(read_only image3d_t image, sampler_t sampler, float4 coord, float lod);
#endif //cl_khr_mipmap_image
+#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
/**
* Sampler-less Image Access
@@ -15135,6 +15137,7 @@ float __purefn __ovld read_imagef(read_write image2d_msaa_depth_t image, int2 co
float __purefn __ovld read_imagef(read_write image2d_array_msaa_depth_t image, int4 coord, int sample);
#endif //cl_khr_gl_msaa_sharing
+#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
#ifdef cl_khr_mipmap_image
float4 __purefn __ovld read_imagef(read_write image1d_t image, sampler_t sampler, float coord, float lod);
int4 __purefn __ovld read_imagei(read_write image1d_t image, sampler_t sampler, float coord, float lod);
@@ -15208,6 +15211,7 @@ float4 __purefn __ovld read_imagef(read_write image3d_t image, sampler_t sampler
int4 __purefn __ovld read_imagei(read_write image3d_t image, sampler_t sampler, float4 coord, float lod);
uint4 __purefn __ovld read_imageui(read_write image3d_t image, sampler_t sampler, float4 coord, float lod);
#endif //cl_khr_mipmap_image
+#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
// Image read functions returning half4 type
#ifdef cl_khr_fp16
@@ -15319,6 +15323,7 @@ void __ovld write_imagef(write_only image2d_array_depth_t image, int4 coord, flo
#endif //cl_khr_depth_images
// OpenCL Extension v2.0 s9.18 - Mipmaps
+#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
#ifdef cl_khr_mipmap_image
void __ovld write_imagef(write_only image1d_t image, int coord, int lod, float4 color);
void __ovld write_imagei(write_only image1d_t image, int coord, int lod, int4 color);
@@ -15345,6 +15350,7 @@ void __ovld write_imagei(write_only image3d_t image, int4 coord, int lod, int4 c
void __ovld write_imageui(write_only image3d_t image, int4 coord, int lod, uint4 color);
#endif
#endif //cl_khr_mipmap_image
+#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
// Image write functions for half4 type
#ifdef cl_khr_fp16
@@ -15391,6 +15397,7 @@ void __ovld write_imagef(read_write image2d_depth_t image, int2 coord, float col
void __ovld write_imagef(read_write image2d_array_depth_t image, int4 coord, float color);
#endif //cl_khr_depth_images
+#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
#ifdef cl_khr_mipmap_image
void __ovld write_imagef(read_write image1d_t image, int coord, int lod, float4 color);
void __ovld write_imagei(read_write image1d_t image, int coord, int lod, int4 color);
@@ -15417,6 +15424,7 @@ void __ovld write_imagei(read_write image3d_t image, int4 coord, int lod, int4 c
void __ovld write_imageui(read_write image3d_t image, int4 coord, int lod, uint4 color);
#endif
#endif //cl_khr_mipmap_image
+#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
// Image write functions for half4 type
#ifdef cl_khr_fp16
@@ -15559,6 +15567,7 @@ int __ovld __cnfn get_image_depth(read_write image3d_t image);
#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
// OpenCL Extension v2.0 s9.18 - Mipmaps
+#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
#ifdef cl_khr_mipmap_image
/**
* Return the image miplevels.
@@ -15574,11 +15583,9 @@ int __ovld get_image_num_mip_levels(write_only image2d_t image);
int __ovld get_image_num_mip_levels(write_only image3d_t image);
#endif
-#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
int __ovld get_image_num_mip_levels(read_write image1d_t image);
int __ovld get_image_num_mip_levels(read_write image2d_t image);
int __ovld get_image_num_mip_levels(read_write image3d_t image);
-#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
int __ovld get_image_num_mip_levels(read_only image1d_array_t image);
int __ovld get_image_num_mip_levels(read_only image2d_array_t image);
@@ -15590,14 +15597,13 @@ int __ovld get_image_num_mip_levels(write_only image2d_array_t image);
int __ovld get_image_num_mip_levels(write_only image2d_array_depth_t image);
int __ovld get_image_num_mip_levels(write_only image2d_depth_t image);
-#if __OPENCL_C_VERSION__ >= CL_VERSION_2_0
int __ovld get_image_num_mip_levels(read_write image1d_array_t image);
int __ovld get_image_num_mip_levels(read_write image2d_array_t image);
int __ovld get_image_num_mip_levels(read_write image2d_array_depth_t image);
int __ovld get_image_num_mip_levels(read_write image2d_depth_t image);
-#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
#endif //cl_khr_mipmap_image
+#endif //__OPENCL_C_VERSION__ >= CL_VERSION_2_0
/**
* Return the channel data type. Valid values are:
diff --git a/lib/Headers/pmmintrin.h b/lib/Headers/pmmintrin.h
index a479d9ed2911..559ece2e3974 100644
--- a/lib/Headers/pmmintrin.h
+++ b/lib/Headers/pmmintrin.h
@@ -31,9 +31,11 @@
__attribute__((__always_inline__, __nodebug__, __target__("sse3")))
/// \brief Loads data from an unaligned memory location to elements in a 128-bit
-/// vector. If the address of the data is not 16-byte aligned, the
-/// instruction may read two adjacent aligned blocks of memory to retrieve
-/// the requested data.
+/// vector.
+///
+/// If the address of the data is not 16-byte aligned, the instruction may
+/// read two adjacent aligned blocks of memory to retrieve the requested
+/// data.
///
/// \headerfile <x86intrin.h>
///
diff --git a/lib/Headers/prfchwintrin.h b/lib/Headers/prfchwintrin.h
index a3789126ef07..b52f31da2706 100644
--- a/lib/Headers/prfchwintrin.h
+++ b/lib/Headers/prfchwintrin.h
@@ -50,8 +50,10 @@ _m_prefetch(void *__P)
/// the L1 data cache and sets the cache-coherency to modified. This
/// provides a hint to the processor that the cache line will be modified.
/// It is intended for use when the cache line will be written to shortly
-/// after the prefetch is performed. Note that the effect of this intrinsic
-/// is dependent on the processor implementation.
+/// after the prefetch is performed.
+///
+/// Note that the effect of this intrinsic is dependent on the processor
+/// implementation.
///
/// \headerfile <x86intrin.h>
///
diff --git a/lib/Headers/smmintrin.h b/lib/Headers/smmintrin.h
index 1c94aca69381..c2fa5a452bce 100644
--- a/lib/Headers/smmintrin.h
+++ b/lib/Headers/smmintrin.h
@@ -586,7 +586,9 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
/* SSE4 Floating Point Dot Product Instructions. */
/// \brief Computes the dot product of the two 128-bit vectors of [4 x float]
/// and returns it in the elements of the 128-bit result vector of
-/// [4 x float]. The immediate integer operand controls which input elements
+/// [4 x float].
+///
+/// The immediate integer operand controls which input elements
/// will contribute to the dot product, and where the final results are
/// returned.
///
@@ -620,7 +622,9 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
/// \brief Computes the dot product of the two 128-bit vectors of [2 x double]
/// and returns it in the elements of the 128-bit result vector of
-/// [2 x double]. The immediate integer operand controls which input
+/// [2 x double].
+///
+/// The immediate integer operand controls which input
/// elements will contribute to the dot product, and where the final results
/// are returned.
///
@@ -875,7 +879,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
/// int _mm_extract_ps(__m128 X, const int N);
/// \endcode
///
-/// This intrinsic corresponds to the <c> VEXTRACTPS / EXTRACTPS </c>
+/// This intrinsic corresponds to the <c> VEXTRACTPS / EXTRACTPS </c>
/// instruction.
///
/// \param X
diff --git a/lib/Headers/tmmintrin.h b/lib/Headers/tmmintrin.h
index 80664043a06f..042bfc7e3b0d 100644
--- a/lib/Headers/tmmintrin.h
+++ b/lib/Headers/tmmintrin.h
@@ -469,10 +469,11 @@ _mm_hsubs_pi16(__m64 __a, __m64 __b)
/// values contained in the first source operand and packed 8-bit signed
/// integer values contained in the second source operand, adds pairs of
/// contiguous products with signed saturation, and writes the 16-bit sums to
-/// the corresponding bits in the destination. For example, bits [7:0] of
-/// both operands are multiplied, bits [15:8] of both operands are
-/// multiplied, and the sum of both results is written to bits [15:0] of the
-/// destination.
+/// the corresponding bits in the destination.
+///
+/// For example, bits [7:0] of both operands are multiplied, bits [15:8] of
+/// both operands are multiplied, and the sum of both results is written to
+/// bits [15:0] of the destination.
///
/// \headerfile <x86intrin.h>
///
@@ -502,10 +503,11 @@ _mm_maddubs_epi16(__m128i __a, __m128i __b)
/// values contained in the first source operand and packed 8-bit signed
/// integer values contained in the second source operand, adds pairs of
/// contiguous products with signed saturation, and writes the 16-bit sums to
-/// the corresponding bits in the destination. For example, bits [7:0] of
-/// both operands are multiplied, bits [15:8] of both operands are
-/// multiplied, and the sum of both results is written to bits [15:0] of the
-/// destination.
+/// the corresponding bits in the destination.
+///
+/// For example, bits [7:0] of both operands are multiplied, bits [15:8] of
+/// both operands are multiplied, and the sum of both results is written to
+/// bits [15:0] of the destination.
///
/// \headerfile <x86intrin.h>
///
@@ -619,13 +621,14 @@ _mm_shuffle_pi8(__m64 __a, __m64 __b)
}
/// \brief For each 8-bit integer in the first source operand, perform one of
-/// the following actions as specified by the second source operand: If the
-/// byte in the second source is negative, calculate the two's complement of
-/// the corresponding byte in the first source, and write that value to the
-/// destination. If the byte in the second source is positive, copy the
-/// corresponding byte from the first source to the destination. If the byte
-/// in the second source is zero, clear the corresponding byte in the
-/// destination.
+/// the following actions as specified by the second source operand.
+///
+/// If the byte in the second source is negative, calculate the two's
+/// complement of the corresponding byte in the first source, and write that
+/// value to the destination. If the byte in the second source is positive,
+/// copy the corresponding byte from the first source to the destination. If
+/// the byte in the second source is zero, clear the corresponding byte in
+/// the destination.
///
/// \headerfile <x86intrin.h>
///
@@ -644,13 +647,14 @@ _mm_sign_epi8(__m128i __a, __m128i __b)
}
/// \brief For each 16-bit integer in the first source operand, perform one of
-/// the following actions as specified by the second source operand: If the
-/// word in the second source is negative, calculate the two's complement of
-/// the corresponding word in the first source, and write that value to the
-/// destination. If the word in the second source is positive, copy the
-/// corresponding word from the first source to the destination. If the word
-/// in the second source is zero, clear the corresponding word in the
-/// destination.
+/// the following actions as specified by the second source operand.
+///
+/// If the word in the second source is negative, calculate the two's
+/// complement of the corresponding word in the first source, and write that
+/// value to the destination. If the word in the second source is positive,
+/// copy the corresponding word from the first source to the destination. If
+/// the word in the second source is zero, clear the corresponding word in
+/// the destination.
///
/// \headerfile <x86intrin.h>
///
@@ -669,8 +673,9 @@ _mm_sign_epi16(__m128i __a, __m128i __b)
}
/// \brief For each 32-bit integer in the first source operand, perform one of
-/// the following actions as specified by the second source operand: If the
-/// doubleword in the second source is negative, calculate the two's
+/// the following actions as specified by the second source operand.
+///
+/// If the doubleword in the second source is negative, calculate the two's
/// complement of the corresponding word in the first source, and write that
/// value to the destination. If the doubleword in the second source is
/// positive, copy the corresponding word from the first source to the
@@ -694,13 +699,14 @@ _mm_sign_epi32(__m128i __a, __m128i __b)
}
/// \brief For each 8-bit integer in the first source operand, perform one of
-/// the following actions as specified by the second source operand: If the
-/// byte in the second source is negative, calculate the two's complement of
-/// the corresponding byte in the first source, and write that value to the
-/// destination. If the byte in the second source is positive, copy the
-/// corresponding byte from the first source to the destination. If the byte
-/// in the second source is zero, clear the corresponding byte in the
-/// destination.
+/// the following actions as specified by the second source operand.
+///
+/// If the byte in the second source is negative, calculate the two's
+/// complement of the corresponding byte in the first source, and write that
+/// value to the destination. If the byte in the second source is positive,
+/// copy the corresponding byte from the first source to the destination. If
+/// the byte in the second source is zero, clear the corresponding byte in
+/// the destination.
///
/// \headerfile <x86intrin.h>
///
@@ -719,13 +725,14 @@ _mm_sign_pi8(__m64 __a, __m64 __b)
}
/// \brief For each 16-bit integer in the first source operand, perform one of
-/// the following actions as specified by the second source operand: If the
-/// word in the second source is negative, calculate the two's complement of
-/// the corresponding word in the first source, and write that value to the
-/// destination. If the word in the second source is positive, copy the
-/// corresponding word from the first source to the destination. If the word
-/// in the second source is zero, clear the corresponding word in the
-/// destination.
+/// the following actions as specified by the second source operand.
+///
+/// If the word in the second source is negative, calculate the two's
+/// complement of the corresponding word in the first source, and write that
+/// value to the destination. If the word in the second source is positive,
+/// copy the corresponding word from the first source to the destination. If
+/// the word in the second source is zero, clear the corresponding word in
+/// the destination.
///
/// \headerfile <x86intrin.h>
///
@@ -744,8 +751,9 @@ _mm_sign_pi16(__m64 __a, __m64 __b)
}
/// \brief For each 32-bit integer in the first source operand, perform one of
-/// the following actions as specified by the second source operand: If the
-/// doubleword in the second source is negative, calculate the two's
+/// the following actions as specified by the second source operand.
+///
+/// If the doubleword in the second source is negative, calculate the two's
/// complement of the corresponding doubleword in the first source, and
/// write that value to the destination. If the doubleword in the second
/// source is positive, copy the corresponding doubleword from the first
diff --git a/lib/Headers/x86intrin.h b/lib/Headers/x86intrin.h
index ef1d02948c8b..31ee7b82dd53 100644
--- a/lib/Headers/x86intrin.h
+++ b/lib/Headers/x86intrin.h
@@ -88,6 +88,4 @@
#include <clzerointrin.h>
#endif
-/* FIXME: LWP */
-
#endif /* __X86INTRIN_H */
diff --git a/lib/Headers/xmmintrin.h b/lib/Headers/xmmintrin.h
index 5c312c08efb6..9773acb840a5 100644
--- a/lib/Headers/xmmintrin.h
+++ b/lib/Headers/xmmintrin.h
@@ -2331,8 +2331,10 @@ _mm_mulhi_pu16(__m64 __a, __m64 __b)
/// \brief Conditionally copies the values from each 8-bit element in the first
/// 64-bit integer vector operand to the specified memory location, as
/// specified by the most significant bit in the corresponding element in the
-/// second 64-bit integer vector operand. To minimize caching, the data is
-/// flagged as non-temporal (unlikely to be used again soon).
+/// second 64-bit integer vector operand.
+///
+/// To minimize caching, the data is flagged as non-temporal
+/// (unlikely to be used again soon).
///
/// \headerfile <x86intrin.h>
///
@@ -2815,11 +2817,12 @@ _mm_cvtpi32x2_ps(__m64 __a, __m64 __b)
/// \brief Converts each single-precision floating-point element of a 128-bit
/// floating-point vector of [4 x float] into a 16-bit signed integer, and
-/// packs the results into a 64-bit integer vector of [4 x i16]. If the
-/// floating-point element is NaN or infinity, or if the floating-point
-/// element is greater than 0x7FFFFFFF or less than -0x8000, it is converted
-/// to 0x8000. Otherwise if the floating-point element is greater than
-/// 0x7FFF, it is converted to 0x7FFF.
+/// packs the results into a 64-bit integer vector of [4 x i16].
+///
+/// If the floating-point element is NaN or infinity, or if the
+/// floating-point element is greater than 0x7FFFFFFF or less than -0x8000,
+/// it is converted to 0x8000. Otherwise if the floating-point element is
+/// greater than 0x7FFF, it is converted to 0x7FFF.
///
/// \headerfile <x86intrin.h>
///
@@ -2845,11 +2848,12 @@ _mm_cvtps_pi16(__m128 __a)
/// \brief Converts each single-precision floating-point element of a 128-bit
/// floating-point vector of [4 x float] into an 8-bit signed integer, and
/// packs the results into the lower 32 bits of a 64-bit integer vector of
-/// [8 x i8]. The upper 32 bits of the vector are set to 0. If the
-/// floating-point element is NaN or infinity, or if the floating-point
-/// element is greater than 0x7FFFFFFF or less than -0x80, it is converted
-/// to 0x80. Otherwise if the floating-point element is greater than 0x7F,
-/// it is converted to 0x7F.
+/// [8 x i8]. The upper 32 bits of the vector are set to 0.
+///
+/// If the floating-point element is NaN or infinity, or if the
+/// floating-point element is greater than 0x7FFFFFFF or less than -0x80, it
+/// is converted to 0x80. Otherwise if the floating-point element is greater
+/// than 0x7F, it is converted to 0x7F.
///
/// \headerfile <x86intrin.h>
///
diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp
index 7f09290de40f..08d233fb83e0 100644
--- a/lib/Index/IndexBody.cpp
+++ b/lib/Index/IndexBody.cpp
@@ -150,6 +150,53 @@ public:
Parent, ParentDC, Roles, Relations, E);
}
+ bool indexDependentReference(
+ const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
+ llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
+ if (!T)
+ return true;
+ const TemplateSpecializationType *TST =
+ T->getAs<TemplateSpecializationType>();
+ if (!TST)
+ return true;
+ TemplateName TN = TST->getTemplateName();
+ const ClassTemplateDecl *TD =
+ dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+ if (!TD)
+ return true;
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ if (!RD->hasDefinition())
+ return true;
+ RD = RD->getDefinition();
+ std::vector<const NamedDecl *> Symbols =
+ RD->lookupDependentName(NameInfo.getName(), Filter);
+ // FIXME: Improve overload handling.
+ if (Symbols.size() != 1)
+ return true;
+ SourceLocation Loc = NameInfo.getLoc();
+ if (Loc.isInvalid())
+ Loc = E->getLocStart();
+ SmallVector<SymbolRelation, 4> Relations;
+ SymbolRoleSet Roles = getRolesForRef(E, Relations);
+ return IndexCtx.handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
+ Relations, E);
+ }
+
+ bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
+ const DeclarationNameInfo &Info = E->getMemberNameInfo();
+ return indexDependentReference(
+ E, E->getBaseType().getTypePtrOrNull(), Info,
+ [](const NamedDecl *D) { return D->isCXXInstanceMember(); });
+ }
+
+ bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
+ const DeclarationNameInfo &Info = E->getNameInfo();
+ const NestedNameSpecifier *NNS = E->getQualifier();
+ return indexDependentReference(
+ E, NNS->getAsType(), Info,
+ [](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
+ }
+
bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
if (D.isFieldDesignator() && D.getField())
diff --git a/lib/Index/IndexDecl.cpp b/lib/Index/IndexDecl.cpp
index 7de70a10b692..203862c46e98 100644
--- a/lib/Index/IndexDecl.cpp
+++ b/lib/Index/IndexDecl.cpp
@@ -52,6 +52,22 @@ public:
return MD && !MD->isImplicit() && MD->isThisDeclarationADefinition();
}
+ void handleTemplateArgumentLoc(const TemplateArgumentLoc &TALoc,
+ const NamedDecl *Parent,
+ const DeclContext *DC) {
+ const TemplateArgumentLocInfo &LocInfo = TALoc.getLocInfo();
+ switch (TALoc.getArgument().getKind()) {
+ case TemplateArgument::Expression:
+ IndexCtx.indexBody(LocInfo.getAsExpr(), Parent, DC);
+ break;
+ case TemplateArgument::Type:
+ IndexCtx.indexTypeSourceInfo(LocInfo.getAsTypeSourceInfo(), Parent, DC);
+ break;
+ default:
+ break;
+ }
+ }
+
void handleDeclarator(const DeclaratorDecl *D,
const NamedDecl *Parent = nullptr,
bool isIBType = false) {
@@ -233,6 +249,12 @@ public:
Dtor->getParent(), Dtor->getDeclContext());
}
}
+ // Template specialization arguments.
+ if (const ASTTemplateArgumentListInfo *TemplateArgInfo =
+ D->getTemplateSpecializationArgsAsWritten()) {
+ for (const auto &Arg : TemplateArgInfo->arguments())
+ handleTemplateArgumentLoc(Arg, D, D->getLexicalDeclContext());
+ }
if (D->isThisDeclarationADefinition()) {
const Stmt *Body = D->getBody();
@@ -522,6 +544,14 @@ public:
return true;
}
+ bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
+ TRY_DECL(D, IndexCtx.handleDecl(D));
+ IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
+ IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
+ D->getLexicalDeclContext());
+ return true;
+ }
+
bool VisitUsingDecl(const UsingDecl *D) {
const DeclContext *DC = D->getDeclContext()->getRedeclContext();
const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
diff --git a/lib/Index/IndexTypeSourceInfo.cpp b/lib/Index/IndexTypeSourceInfo.cpp
index 44d1241fb930..ae27ebe6ea4c 100644
--- a/lib/Index/IndexTypeSourceInfo.cpp
+++ b/lib/Index/IndexTypeSourceInfo.cpp
@@ -141,6 +141,34 @@ public:
return true;
}
+ bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
+ const DependentNameType *DNT = TL.getTypePtr();
+ const NestedNameSpecifier *NNS = DNT->getQualifier();
+ const Type *T = NNS->getAsType();
+ if (!T)
+ return true;
+ const TemplateSpecializationType *TST =
+ T->getAs<TemplateSpecializationType>();
+ if (!TST)
+ return true;
+ TemplateName TN = TST->getTemplateName();
+ const ClassTemplateDecl *TD =
+ dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+ if (!TD)
+ return true;
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ if (!RD->hasDefinition())
+ return true;
+ RD = RD->getDefinition();
+ DeclarationName Name(DNT->getIdentifier());
+ std::vector<const NamedDecl *> Symbols = RD->lookupDependentName(
+ Name, [](const NamedDecl *ND) { return isa<TypeDecl>(ND); });
+ if (Symbols.size() != 1)
+ return true;
+ return IndexCtx.handleReference(Symbols[0], TL.getNameLoc(), Parent,
+ ParentDC, SymbolRoleSet(), Relations);
+ }
+
bool TraverseStmt(Stmt *S) {
IndexCtx.indexBody(S, Parent, ParentDC);
return true;
@@ -184,7 +212,7 @@ void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
if (!DC)
DC = Parent->getLexicalDeclContext();
- SourceLocation Loc = NNS.getSourceRange().getBegin();
+ SourceLocation Loc = NNS.getLocalBeginLoc();
switch (NNS.getNestedNameSpecifier()->getKind()) {
case NestedNameSpecifier::Identifier:
diff --git a/lib/Index/IndexingContext.cpp b/lib/Index/IndexingContext.cpp
index 709a23657b07..5cebb198460f 100644
--- a/lib/Index/IndexingContext.cpp
+++ b/lib/Index/IndexingContext.cpp
@@ -124,6 +124,10 @@ bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
TKind = FD->getTemplateSpecializationKind();
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
TKind = VD->getTemplateSpecializationKind();
+ } else if (isa<FieldDecl>(D)) {
+ if (const auto *Parent =
+ dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
+ TKind = Parent->getSpecializationKind();
}
switch (TKind) {
case TSK_Undeclared:
@@ -159,6 +163,17 @@ static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
return FD->getTemplateInstantiationPattern();
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
return VD->getTemplateInstantiationPattern();
+ } else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
+ if (const auto *Parent =
+ dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext())) {
+ const CXXRecordDecl *Pattern = Parent->getTemplateInstantiationPattern();
+ for (const NamedDecl *ND : Pattern->lookup(FD->getDeclName())) {
+ if (ND->isImplicit())
+ continue;
+ if (isa<FieldDecl>(ND))
+ return ND;
+ }
+ }
}
return nullptr;
}
diff --git a/lib/Lex/MacroInfo.cpp b/lib/Lex/MacroInfo.cpp
index bec434085e3a..1e5deeb1919b 100644
--- a/lib/Lex/MacroInfo.cpp
+++ b/lib/Lex/MacroInfo.cpp
@@ -29,7 +29,6 @@ MacroInfo::MacroInfo(SourceLocation DefLoc)
IsUsed(false),
IsAllowRedefinitionsWithoutWarning(false),
IsWarnIfUnused(false),
- FromASTFile(false),
UsedForHeaderGuard(false) {
}
@@ -137,7 +136,6 @@ LLVM_DUMP_METHOD void MacroInfo::dump() const {
if (IsAllowRedefinitionsWithoutWarning)
Out << " allow_redefinitions_without_warning";
if (IsWarnIfUnused) Out << " warn_if_unused";
- if (FromASTFile) Out << " imported";
if (UsedForHeaderGuard) Out << " header_guard";
Out << "\n #define <macro>";
diff --git a/lib/Lex/ModuleMap.cpp b/lib/Lex/ModuleMap.cpp
index 70d37d3d7082..6f44dc757e85 100644
--- a/lib/Lex/ModuleMap.cpp
+++ b/lib/Lex/ModuleMap.cpp
@@ -1485,7 +1485,19 @@ void ModuleMapParser::parseModuleDecl() {
// Determine whether this (sub)module has already been defined.
if (Module *Existing = Map.lookupModuleQualified(ModuleName, ActiveModule)) {
- if (Existing->DefinitionLoc.isInvalid() && !ActiveModule) {
+ // We might see a (re)definition of a module that we already have a
+ // definition for in two cases:
+ // - If we loaded one definition from an AST file and we've just found a
+ // corresponding definition in a module map file, or
+ bool LoadedFromASTFile = Existing->DefinitionLoc.isInvalid();
+ // - If we're building a (preprocessed) module and we've just loaded the
+ // module map file from which it was created.
+ bool ParsedAsMainInput =
+ Map.LangOpts.getCompilingModule() == LangOptions::CMK_ModuleMap &&
+ Map.LangOpts.CurrentModule == ModuleName &&
+ SourceMgr.getDecomposedLoc(ModuleNameLoc).first !=
+ SourceMgr.getDecomposedLoc(Existing->DefinitionLoc).first;
+ if (!ActiveModule && (LoadedFromASTFile || ParsedAsMainInput)) {
// Skip the module definition.
skipUntil(MMToken::RBrace);
if (Tok.is(MMToken::RBrace))
@@ -1901,8 +1913,10 @@ void ModuleMapParser::parseHeaderDecl(MMToken::TokenKind LeadingToken,
// 'framework module FrameworkName.Private', since a 'Private.Framework'
// does not usually exist. However, since both are currently widely used
// for private modules, make sure we find the right path in both cases.
- RelativePathName.resize(ActiveModule->IsFramework ? 0
- : RelativePathLength);
+ if (ActiveModule->IsFramework && ActiveModule->Name == "Private")
+ RelativePathName.clear();
+ else
+ RelativePathName.resize(RelativePathLength);
FullPathName.resize(FullPathLength);
llvm::sys::path::append(RelativePathName, "PrivateHeaders",
Header.FileName);
diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp
index 06fee8e5b0a8..faf8809e4eb4 100644
--- a/lib/Lex/PPDirectives.cpp
+++ b/lib/Lex/PPDirectives.cpp
@@ -54,35 +54,12 @@ using namespace clang;
// Utility Methods for Preprocessor Directive Handling.
//===----------------------------------------------------------------------===//
-MacroInfo *Preprocessor::AllocateMacroInfo() {
- MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>();
- MIChain->Next = MIChainHead;
+MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
+ auto *MIChain = new (BP) MacroInfoChain{L, MIChainHead};
MIChainHead = MIChain;
return &MIChain->MI;
}
-MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
- MacroInfo *MI = AllocateMacroInfo();
- new (MI) MacroInfo(L);
- return MI;
-}
-
-MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L,
- unsigned SubModuleID) {
- static_assert(alignof(MacroInfo) >= sizeof(SubModuleID),
- "alignment for MacroInfo is less than the ID");
- DeserializedMacroInfoChain *MIChain =
- BP.Allocate<DeserializedMacroInfoChain>();
- MIChain->Next = DeserialMIChainHead;
- DeserialMIChainHead = MIChain;
-
- MacroInfo *MI = &MIChain->MI;
- new (MI) MacroInfo(L);
- MI->FromASTFile = true;
- MI->setOwningModuleID(SubModuleID);
- return MI;
-}
-
DefMacroDirective *Preprocessor::AllocateDefMacroDirective(MacroInfo *MI,
SourceLocation Loc) {
return new (BP) DefMacroDirective(MI, Loc);
diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp
index e409ab036535..dce8c1efda23 100644
--- a/lib/Lex/Preprocessor.cpp
+++ b/lib/Lex/Preprocessor.cpp
@@ -88,7 +88,7 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
CurDirLookup(nullptr), CurLexerKind(CLK_Lexer),
CurLexerSubmodule(nullptr), Callbacks(nullptr),
CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr),
- Record(nullptr), MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
+ Record(nullptr), MIChainHead(nullptr) {
OwnsHeaderSearch = OwnsHeaders;
CounterValue = 0; // __COUNTER__ starts at 0.
@@ -169,11 +169,6 @@ Preprocessor::~Preprocessor() {
std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers, nullptr);
CurTokenLexer.reset();
- while (DeserializedMacroInfoChain *I = DeserialMIChainHead) {
- DeserialMIChainHead = I->Next;
- I->~DeserializedMacroInfoChain();
- }
-
// Free any cached MacroArgs.
for (MacroArgs *ArgList = MacroArgCache; ArgList;)
ArgList = ArgList->deallocate();
diff --git a/lib/Parse/ParseDecl.cpp b/lib/Parse/ParseDecl.cpp
index 1465d21ac5ee..4ccee74eaa90 100644
--- a/lib/Parse/ParseDecl.cpp
+++ b/lib/Parse/ParseDecl.cpp
@@ -2577,9 +2577,9 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
// and attempt to recover.
ParsedType T;
IdentifierInfo *II = Tok.getIdentifierInfo();
+ bool IsTemplateName = getLangOpts().CPlusPlus && NextToken().is(tok::less);
Actions.DiagnoseUnknownTypeName(II, Loc, getCurScope(), SS, T,
- getLangOpts().CPlusPlus &&
- NextToken().is(tok::less));
+ IsTemplateName);
if (T) {
// The action has suggested that the type T could be used. Set that as
// the type in the declaration specifiers, consume the would-be type
@@ -2604,6 +2604,13 @@ bool Parser::ParseImplicitInt(DeclSpec &DS, CXXScopeSpec *SS,
DS.SetRangeEnd(Tok.getLocation());
ConsumeToken();
+ // Eat any following template arguments.
+ if (IsTemplateName) {
+ SourceLocation LAngle, RAngle;
+ TemplateArgList Args;
+ ParseTemplateIdAfterTemplateName(true, LAngle, Args, RAngle);
+ }
+
// TODO: Could inject an invalid typedef decl in an enclosing scope to
// avoid rippling error messages on subsequent uses of the same type,
// could be useful if #include was forgotten.
diff --git a/lib/Parse/ParseDeclCXX.cpp b/lib/Parse/ParseDeclCXX.cpp
index ad7b319676e9..e6cf65e36cfa 100644
--- a/lib/Parse/ParseDeclCXX.cpp
+++ b/lib/Parse/ParseDeclCXX.cpp
@@ -1137,8 +1137,8 @@ TypeResult Parser::ParseBaseTypeSpecifier(SourceLocation &BaseLoc,
if (!Template) {
TemplateArgList TemplateArgs;
SourceLocation LAngleLoc, RAngleLoc;
- ParseTemplateIdAfterTemplateName(nullptr, IdLoc, SS, true, LAngleLoc,
- TemplateArgs, RAngleLoc);
+ ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs,
+ RAngleLoc);
return true;
}
@@ -1530,8 +1530,8 @@ void Parser::ParseClassSpecifier(tok::TokenKind TagTokKind,
// a class (or template thereof).
TemplateArgList TemplateArgs;
SourceLocation LAngleLoc, RAngleLoc;
- if (ParseTemplateIdAfterTemplateName(
- nullptr, NameLoc, SS, true, LAngleLoc, TemplateArgs, RAngleLoc)) {
+ if (ParseTemplateIdAfterTemplateName(true, LAngleLoc, TemplateArgs,
+ RAngleLoc)) {
// We couldn't parse the template argument list at all, so don't
// try to give any location information for the list.
LAngleLoc = RAngleLoc = SourceLocation();
diff --git a/lib/Parse/ParseExpr.cpp b/lib/Parse/ParseExpr.cpp
index 3e02e46ddc7d..727fd3500991 100644
--- a/lib/Parse/ParseExpr.cpp
+++ b/lib/Parse/ParseExpr.cpp
@@ -235,6 +235,30 @@ bool Parser::isNotExpressionStart() {
return isKnownToBeDeclarationSpecifier();
}
+/// We've parsed something that could plausibly be intended to be a template
+/// name (\p LHS) followed by a '<' token, and the following code can't possibly
+/// be an expression. Determine if this is likely to be a template-id and if so,
+/// diagnose it.
+bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {
+ TentativeParsingAction TPA(*this);
+ // FIXME: We could look at the token sequence in a lot more detail here.
+ if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
+ StopAtSemi | StopBeforeMatch)) {
+ TPA.Commit();
+
+ SourceLocation Greater;
+ ParseGreaterThanInTemplateList(Greater, true, false);
+ Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS,
+ Less, Greater);
+ return true;
+ }
+
+ // There's no matching '>' token, this probably isn't supposed to be
+ // interpreted as a template-id. Parse it as an (ill-formed) comparison.
+ TPA.Revert();
+ return false;
+}
+
static bool isFoldOperator(prec::Level Level) {
return Level > prec::Unknown && Level != prec::Conditional;
}
@@ -276,6 +300,16 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
return LHS;
}
+ // If a '<' token is followed by a type that can be a template argument and
+ // cannot be an expression, then this is ill-formed, but might be intended
+ // to be a template-id.
+ if (OpToken.is(tok::less) && Actions.mightBeIntendedToBeTemplateName(LHS) &&
+ (isKnownToBeDeclarationSpecifier() ||
+ Tok.isOneOf(tok::greater, tok::greatergreater,
+ tok::greatergreatergreater)) &&
+ diagnoseUnknownTemplateId(LHS, OpToken.getLocation()))
+ return ExprError();
+
// If the next token is an ellipsis, then this is a fold-expression. Leave
// it alone so we can handle it in the paren expression.
if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) {
@@ -2989,6 +3023,11 @@ Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
return AvailabilitySpec(ConsumeToken());
} else {
// Parse the platform name.
+ if (Tok.is(tok::code_completion)) {
+ Actions.CodeCompleteAvailabilityPlatformName();
+ cutOffParsing();
+ return None;
+ }
if (Tok.isNot(tok::identifier)) {
Diag(Tok, diag::err_avail_query_expected_platform_name);
return None;
@@ -3001,12 +3040,14 @@ Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
if (Version.empty())
return None;
- StringRef Platform = PlatformIdentifier->Ident->getName();
+ StringRef GivenPlatform = PlatformIdentifier->Ident->getName();
+ StringRef Platform =
+ AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) {
Diag(PlatformIdentifier->Loc,
diag::err_avail_query_unrecognized_platform_name)
- << Platform;
+ << GivenPlatform;
return None;
}
diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp
index 671a815911f3..56093f685617 100644
--- a/lib/Parse/ParseExprCXX.cpp
+++ b/lib/Parse/ParseExprCXX.cpp
@@ -2114,11 +2114,8 @@ bool Parser::ParseUnqualifiedIdTemplateId(CXXScopeSpec &SS,
// Parse the enclosed template argument list.
SourceLocation LAngleLoc, RAngleLoc;
TemplateArgList TemplateArgs;
- if (Tok.is(tok::less) &&
- ParseTemplateIdAfterTemplateName(Template, Id.StartLocation,
- SS, true, LAngleLoc,
- TemplateArgs,
- RAngleLoc))
+ if (Tok.is(tok::less) && ParseTemplateIdAfterTemplateName(
+ true, LAngleLoc, TemplateArgs, RAngleLoc))
return true;
if (Id.getKind() == UnqualifiedId::IK_Identifier ||
diff --git a/lib/Parse/ParseTemplate.cpp b/lib/Parse/ParseTemplate.cpp
index d2b18e7c0a81..6a81e14ed496 100644
--- a/lib/Parse/ParseTemplate.cpp
+++ b/lib/Parse/ParseTemplate.cpp
@@ -886,22 +886,12 @@ bool Parser::ParseGreaterThanInTemplateList(SourceLocation &RAngleLoc,
/// list ('<' template-parameter-list [opt] '>') and placing the
/// results into a form that can be transferred to semantic analysis.
///
-/// \param Template the template declaration produced by isTemplateName
-///
-/// \param TemplateNameLoc the source location of the template name
-///
-/// \param SS if non-NULL, the nested-name-specifier preceding the
-/// template name.
-///
/// \param ConsumeLastToken if true, then we will consume the last
/// token that forms the template-id. Otherwise, we will leave the
/// last token in the stream (e.g., so that it can be replaced with an
/// annotation token).
bool
-Parser::ParseTemplateIdAfterTemplateName(TemplateTy Template,
- SourceLocation TemplateNameLoc,
- const CXXScopeSpec &SS,
- bool ConsumeLastToken,
+Parser::ParseTemplateIdAfterTemplateName(bool ConsumeLastToken,
SourceLocation &LAngleLoc,
TemplateArgList &TemplateArgs,
SourceLocation &RAngleLoc) {
@@ -983,9 +973,7 @@ bool Parser::AnnotateTemplateIdToken(TemplateTy Template, TemplateNameKind TNK,
// Parse the enclosed template argument list.
SourceLocation LAngleLoc, RAngleLoc;
TemplateArgList TemplateArgs;
- bool Invalid = ParseTemplateIdAfterTemplateName(Template,
- TemplateNameLoc,
- SS, false, LAngleLoc,
+ bool Invalid = ParseTemplateIdAfterTemplateName(false, LAngleLoc,
TemplateArgs,
RAngleLoc);
diff --git a/lib/Sema/CMakeLists.txt b/lib/Sema/CMakeLists.txt
index 7a5973299f91..7d9ae621c93d 100644
--- a/lib/Sema/CMakeLists.txt
+++ b/lib/Sema/CMakeLists.txt
@@ -3,6 +3,7 @@ set(LLVM_LINK_COMPONENTS
)
if (MSVC)
+ set_source_files_properties(SemaDeclAttr.cpp PROPERTIES COMPILE_FLAGS /bigobj)
set_source_files_properties(SemaExpr.cpp PROPERTIES COMPILE_FLAGS /bigobj)
endif()
diff --git a/lib/Sema/Sema.cpp b/lib/Sema/Sema.cpp
index 2f493fa5fbef..ca1d27e9505f 100644
--- a/lib/Sema/Sema.cpp
+++ b/lib/Sema/Sema.cpp
@@ -477,6 +477,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
return true;
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
+ // If this is a function template and none of its specializations is used,
+ // we should warn.
+ if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
+ for (const auto *Spec : Template->specializations())
+ if (ShouldRemoveFromUnused(SemaRef, Spec))
+ return true;
+
// UnusedFileScopedDecls stores the first declaration.
// The declaration may have become definition so check again.
const FunctionDecl *DeclToCheck;
@@ -500,6 +507,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
VD->isUsableInConstantExpressions(SemaRef->Context))
return true;
+ if (VarTemplateDecl *Template = VD->getDescribedVarTemplate())
+ // If this is a variable template and none of its specializations is used,
+ // we should warn.
+ for (const auto *Spec : Template->specializations())
+ if (ShouldRemoveFromUnused(SemaRef, Spec))
+ return true;
+
// UnusedFileScopedDecls stores the first declaration.
// The declaration may have become definition so check again.
const VarDecl *DeclToCheck = VD->getDefinition();
@@ -905,10 +919,14 @@ void Sema::ActOnEndOfTranslationUnit() {
<< /*function*/0 << DiagD->getDeclName();
}
} else {
- Diag(DiagD->getLocation(),
- isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
- : diag::warn_unused_function)
- << DiagD->getDeclName();
+ if (FD->getDescribedFunctionTemplate())
+ Diag(DiagD->getLocation(), diag::warn_unused_template)
+ << /*function*/0 << DiagD->getDeclName();
+ else
+ Diag(DiagD->getLocation(),
+ isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
+ : diag::warn_unused_function)
+ << DiagD->getDeclName();
}
} else {
const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
@@ -924,7 +942,11 @@ void Sema::ActOnEndOfTranslationUnit() {
Diag(DiagD->getLocation(), diag::warn_unused_const_variable)
<< DiagD->getDeclName();
} else {
- Diag(DiagD->getLocation(), diag::warn_unused_variable)
+ if (DiagD->getDescribedVarTemplate())
+ Diag(DiagD->getLocation(), diag::warn_unused_template)
+ << /*variable*/1 << DiagD->getDeclName();
+ else
+ Diag(DiagD->getLocation(), diag::warn_unused_variable)
<< DiagD->getDeclName();
}
}
diff --git a/lib/Sema/SemaCast.cpp b/lib/Sema/SemaCast.cpp
index 7e91709e67da..7d534263f468 100644
--- a/lib/Sema/SemaCast.cpp
+++ b/lib/Sema/SemaCast.cpp
@@ -1871,7 +1871,8 @@ static bool fixOverloadedReinterpretCastExpr(Sema &Self, QualType DestType,
// No guarantees that ResolveAndFixSingleFunctionTemplateSpecialization
// preserves Result.
Result = E;
- if (!Self.resolveAndFixAddressOfOnlyViableOverloadCandidate(Result))
+ if (!Self.resolveAndFixAddressOfOnlyViableOverloadCandidate(
+ Result, /*DoFunctionPointerConversion=*/true))
return false;
return Result.isUsable();
}
diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp
index cfac3f1dc1de..8fb2f4139236 100644
--- a/lib/Sema/SemaCodeComplete.cpp
+++ b/lib/Sema/SemaCodeComplete.cpp
@@ -3869,6 +3869,41 @@ static void AddObjCProperties(
}
}
+static void AddRecordMembersCompletionResults(Sema &SemaRef,
+ ResultBuilder &Results, Scope *S,
+ QualType BaseType,
+ RecordDecl *RD) {
+ // Indicate that we are performing a member access, and the cv-qualifiers
+ // for the base object type.
+ Results.setObjectTypeQualifiers(BaseType.getQualifiers());
+
+ // Access to a C/C++ class, struct, or union.
+ Results.allowNestedNameSpecifiers();
+ CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
+ SemaRef.LookupVisibleDecls(RD, Sema::LookupMemberName, Consumer,
+ SemaRef.CodeCompleter->includeGlobals(),
+ /*IncludeDependentBases=*/true);
+
+ if (SemaRef.getLangOpts().CPlusPlus) {
+ if (!Results.empty()) {
+ // The "template" keyword can follow "->" or "." in the grammar.
+ // However, we only want to suggest the template keyword if something
+ // is dependent.
+ bool IsDependent = BaseType->isDependentType();
+ if (!IsDependent) {
+ for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
+ if (DeclContext *Ctx = DepScope->getEntity()) {
+ IsDependent = Ctx->isDependentContext();
+ break;
+ }
+ }
+
+ if (IsDependent)
+ Results.AddResult(CodeCompletionResult("template"));
+ }
+ }
+}
+
void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
SourceLocation OpLoc, bool IsArrow,
bool IsBaseExprStatement) {
@@ -3879,8 +3914,6 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
if (ConvertedBase.isInvalid())
return;
Base = ConvertedBase.get();
-
- typedef CodeCompletionResult Result;
QualType BaseType = Base->getType();
@@ -3915,34 +3948,18 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
&ResultBuilder::IsMember);
Results.EnterNewScope();
if (const RecordType *Record = BaseType->getAs<RecordType>()) {
- // Indicate that we are performing a member access, and the cv-qualifiers
- // for the base object type.
- Results.setObjectTypeQualifiers(BaseType.getQualifiers());
-
- // Access to a C/C++ class, struct, or union.
- Results.allowNestedNameSpecifiers();
- CodeCompletionDeclConsumer Consumer(Results, CurContext);
- LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
- CodeCompleter->includeGlobals());
-
- if (getLangOpts().CPlusPlus) {
- if (!Results.empty()) {
- // The "template" keyword can follow "->" or "." in the grammar.
- // However, we only want to suggest the template keyword if something
- // is dependent.
- bool IsDependent = BaseType->isDependentType();
- if (!IsDependent) {
- for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
- if (DeclContext *Ctx = DepScope->getEntity()) {
- IsDependent = Ctx->isDependentContext();
- break;
- }
- }
-
- if (IsDependent)
- Results.AddResult(Result("template"));
- }
- }
+ AddRecordMembersCompletionResults(*this, Results, S, BaseType,
+ Record->getDecl());
+ } else if (const auto *TST = BaseType->getAs<TemplateSpecializationType>()) {
+ TemplateName TN = TST->getTemplateName();
+ if (const auto *TD =
+ dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl())) {
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ AddRecordMembersCompletionResults(*this, Results, S, BaseType, RD);
+ }
+ } else if (const auto *ICNT = BaseType->getAs<InjectedClassNameType>()) {
+ if (auto *RD = ICNT->getDecl())
+ AddRecordMembersCompletionResults(*this, Results, S, BaseType, RD);
} else if (!IsArrow && BaseType->isObjCObjectPointerType()) {
// Objective-C property reference.
AddedPropertiesSet AddedProperties;
@@ -7811,6 +7828,23 @@ void Sema::CodeCompleteNaturalLanguage() {
nullptr, 0);
}
+void Sema::CodeCompleteAvailabilityPlatformName() {
+ ResultBuilder Results(*this, CodeCompleter->getAllocator(),
+ CodeCompleter->getCodeCompletionTUInfo(),
+ CodeCompletionContext::CCC_Other);
+ Results.EnterNewScope();
+ static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
+ for (const char *Platform : llvm::makeArrayRef(Platforms)) {
+ Results.AddResult(CodeCompletionResult(Platform));
+ Results.AddResult(CodeCompletionResult(Results.getAllocator().CopyString(
+ Twine(Platform) + "ApplicationExtension")));
+ }
+ Results.ExitScope();
+ HandleCodeCompleteResults(this, CodeCompleter,
+ CodeCompletionContext::CCC_Other, Results.data(),
+ Results.size());
+}
+
void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo,
SmallVectorImpl<CodeCompletionResult> &Results) {
diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp
index 2612023f59db..2e069a9defaa 100644
--- a/lib/Sema/SemaDecl.cpp
+++ b/lib/Sema/SemaDecl.cpp
@@ -64,22 +64,45 @@ namespace {
class TypeNameValidatorCCC : public CorrectionCandidateCallback {
public:
- TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false,
- bool AllowTemplates=false)
- : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
- AllowTemplates(AllowTemplates) {
- WantExpressionKeywords = false;
- WantCXXNamedCasts = false;
- WantRemainingKeywords = false;
+ TypeNameValidatorCCC(bool AllowInvalid, bool WantClass = false,
+ bool AllowTemplates = false,
+ bool AllowNonTemplates = true)
+ : AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
+ AllowTemplates(AllowTemplates), AllowNonTemplates(AllowNonTemplates) {
+ WantExpressionKeywords = false;
+ WantCXXNamedCasts = false;
+ WantRemainingKeywords = false;
}
bool ValidateCandidate(const TypoCorrection &candidate) override {
if (NamedDecl *ND = candidate.getCorrectionDecl()) {
+ if (!AllowInvalidDecl && ND->isInvalidDecl())
+ return false;
+
+ if (getAsTypeTemplateDecl(ND))
+ return AllowTemplates;
+
bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
- bool AllowedTemplate = AllowTemplates && getAsTypeTemplateDecl(ND);
- return (IsType || AllowedTemplate) &&
- (AllowInvalidDecl || !ND->isInvalidDecl());
+ if (!IsType)
+ return false;
+
+ if (AllowNonTemplates)
+ return true;
+
+ // An injected-class-name of a class template (specialization) is valid
+ // as a template or as a non-template.
+ if (AllowTemplates) {
+ auto *RD = dyn_cast<CXXRecordDecl>(ND);
+ if (!RD || !RD->isInjectedClassName())
+ return false;
+ RD = cast<CXXRecordDecl>(RD->getDeclContext());
+ return RD->getDescribedClassTemplate() ||
+ isa<ClassTemplateSpecializationDecl>(RD);
+ }
+
+ return false;
}
+
return !WantClassName && candidate.isKeyword();
}
@@ -87,6 +110,7 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
bool AllowInvalidDecl;
bool WantClassName;
bool AllowTemplates;
+ bool AllowNonTemplates;
};
} // end anonymous namespace
@@ -627,7 +651,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
Scope *S,
CXXScopeSpec *SS,
ParsedType &SuggestedType,
- bool AllowClassTemplates) {
+ bool IsTemplateName) {
// Don't report typename errors for editor placeholders.
if (II->isEditorPlaceholder())
return;
@@ -639,28 +663,41 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
if (TypoCorrection Corrected =
CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS,
llvm::make_unique<TypeNameValidatorCCC>(
- false, false, AllowClassTemplates),
+ false, false, IsTemplateName, !IsTemplateName),
CTK_ErrorRecovery)) {
+ // FIXME: Support error recovery for the template-name case.
+ bool CanRecover = !IsTemplateName;
if (Corrected.isKeyword()) {
// We corrected to a keyword.
- diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II);
+ diagnoseTypo(Corrected,
+ PDiag(IsTemplateName ? diag::err_no_template_suggest
+ : diag::err_unknown_typename_suggest)
+ << II);
II = Corrected.getCorrectionAsIdentifierInfo();
} else {
// We found a similarly-named type or interface; suggest that.
if (!SS || !SS->isSet()) {
diagnoseTypo(Corrected,
- PDiag(diag::err_unknown_typename_suggest) << II);
+ PDiag(IsTemplateName ? diag::err_no_template_suggest
+ : diag::err_unknown_typename_suggest)
+ << II, CanRecover);
} else if (DeclContext *DC = computeDeclContext(*SS, false)) {
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
II->getName().equals(CorrectedStr);
diagnoseTypo(Corrected,
- PDiag(diag::err_unknown_nested_typename_suggest)
- << II << DC << DroppedSpecifier << SS->getRange());
+ PDiag(IsTemplateName
+ ? diag::err_no_member_template_suggest
+ : diag::err_unknown_nested_typename_suggest)
+ << II << DC << DroppedSpecifier << SS->getRange(),
+ CanRecover);
} else {
llvm_unreachable("could not have corrected a typo here");
}
+ if (!CanRecover)
+ return;
+
CXXScopeSpec tmpSS;
if (Corrected.getCorrectionSpecifier())
tmpSS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(),
@@ -675,7 +712,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
return;
}
- if (getLangOpts().CPlusPlus) {
+ if (getLangOpts().CPlusPlus && !IsTemplateName) {
// See if II is a class template that the user forgot to pass arguments to.
UnqualifiedId Name;
Name.setIdentifier(II, IILoc);
@@ -700,10 +737,13 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
// (struct, union, enum) from Parser::ParseImplicitInt here, instead?
if (!SS || (!SS->isSet() && !SS->isInvalid()))
- Diag(IILoc, diag::err_unknown_typename) << II;
+ Diag(IILoc, IsTemplateName ? diag::err_no_template
+ : diag::err_unknown_typename)
+ << II;
else if (DeclContext *DC = computeDeclContext(*SS, false))
- Diag(IILoc, diag::err_typename_nested_not_found)
- << II << DC << SS->getRange();
+ Diag(IILoc, IsTemplateName ? diag::err_no_member_template
+ : diag::err_typename_nested_not_found)
+ << II << DC << SS->getRange();
else if (isDependentScopeSpecifier(*SS)) {
unsigned DiagID = diag::err_typename_missing;
if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S))
@@ -1488,6 +1528,11 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return false;
+ // A non-out-of-line declaration of a member specialization was implicitly
+ // instantiated; it's the out-of-line declaration that we're interested in.
+ if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
+ FD->getMemberSpecializationInfo() && !FD->isOutOfLine())
+ return false;
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD))
@@ -1514,6 +1559,10 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
if (VD->isStaticDataMember() &&
VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
return false;
+ if (VD->isStaticDataMember() &&
+ VD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
+ VD->getMemberSpecializationInfo() && !VD->isOutOfLine())
+ return false;
if (VD->isInline() && !isMainFileLoc(*this, VD->getLocation()))
return false;
@@ -1972,7 +2021,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
Diag(New->getLocation(), diag::err_redefinition_variably_modified_typedef)
<< Kind << NewType;
if (Old->getLocation().isValid())
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
New->setInvalidDecl();
return true;
}
@@ -1985,7 +2034,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
Diag(New->getLocation(), diag::err_redefinition_different_typedef)
<< Kind << NewType << OldType;
if (Old->getLocation().isValid())
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
New->setInvalidDecl();
return true;
}
@@ -2052,7 +2101,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
NamedDecl *OldD = OldDecls.getRepresentativeDecl();
if (OldD->getLocation().isValid())
- Diag(OldD->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(OldD->getLocation(), New->getLocation());
return New->setInvalidDecl();
}
@@ -2078,7 +2127,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
New->setTypeSourceInfo(OldTD->getTypeSourceInfo());
// Make the old tag definition visible.
- makeMergedDefinitionVisible(Hidden, NewTag->getLocation());
+ makeMergedDefinitionVisible(Hidden);
// If this was an unscoped enumeration, yank all of its enumerators
// out of the scope.
@@ -2144,7 +2193,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
Diag(New->getLocation(), diag::err_redefinition)
<< New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
return New->setInvalidDecl();
}
@@ -2165,7 +2214,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
Diag(New->getLocation(), diag::ext_redefinition_of_typedef)
<< New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
}
/// DeclhasAttr - returns true if decl Declaration already has the target
@@ -2452,7 +2501,10 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
? diag::err_alias_after_tentative
: diag::err_redefinition;
S.Diag(VD->getLocation(), Diag) << VD->getDeclName();
- S.Diag(Def->getLocation(), diag::note_previous_definition);
+ if (Diag == diag::err_redefinition)
+ S.notePreviousDefinition(Def->getLocation(), VD->getLocation());
+ else
+ S.Diag(Def->getLocation(), diag::note_previous_definition);
VD->setInvalidDecl();
}
++I;
@@ -2839,7 +2891,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
} else {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
<< New->getDeclName();
- Diag(OldD->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(OldD->getLocation(), New->getLocation());
return true;
}
}
@@ -2876,7 +2928,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
!Old->hasAttr<InternalLinkageAttr>()) {
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
<< New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
New->dropAttr<InternalLinkageAttr>();
}
@@ -3604,9 +3656,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
}
if (!Old) {
Diag(New->getLocation(), diag::err_redefinition_different_kind)
- << New->getDeclName();
- Diag(Previous.getRepresentativeDecl()->getLocation(),
- diag::note_previous_definition);
+ << New->getDeclName();
+ notePreviousDefinition(Previous.getRepresentativeDecl()->getLocation(),
+ New->getLocation());
return New->setInvalidDecl();
}
@@ -3635,7 +3687,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
Old->getStorageClass() == SC_None &&
!Old->hasAttr<WeakImportAttr>()) {
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
// Remove weak_import attribute on new declaration.
New->dropAttr<WeakImportAttr>();
}
@@ -3644,7 +3696,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
!Old->hasAttr<InternalLinkageAttr>()) {
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
<< New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
New->dropAttr<InternalLinkageAttr>();
}
@@ -3801,6 +3853,67 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
New->setImplicitlyInline();
}
+void Sema::notePreviousDefinition(SourceLocation Old, SourceLocation New) {
+ SourceManager &SrcMgr = getSourceManager();
+ auto FNewDecLoc = SrcMgr.getDecomposedLoc(New);
+ auto FOldDecLoc = SrcMgr.getDecomposedLoc(Old);
+ auto *FNew = SrcMgr.getFileEntryForID(FNewDecLoc.first);
+ auto *FOld = SrcMgr.getFileEntryForID(FOldDecLoc.first);
+ auto &HSI = PP.getHeaderSearchInfo();
+ StringRef HdrFilename = SrcMgr.getFilename(SrcMgr.getSpellingLoc(Old));
+
+ auto noteFromModuleOrInclude = [&](SourceLocation &Loc,
+ SourceLocation &IncLoc) -> bool {
+ Module *Mod = nullptr;
+ // Redefinition errors with modules are common with non modular mapped
+ // headers, example: a non-modular header H in module A that also gets
+ // included directly in a TU. Pointing twice to the same header/definition
+ // is confusing, try to get better diagnostics when modules is on.
+ if (getLangOpts().Modules) {
+ auto ModLoc = SrcMgr.getModuleImportLoc(Old);
+ if (!ModLoc.first.isInvalid())
+ Mod = HSI.getModuleMap().inferModuleFromLocation(
+ FullSourceLoc(Loc, SrcMgr));
+ }
+
+ if (IncLoc.isValid()) {
+ if (Mod) {
+ Diag(IncLoc, diag::note_redefinition_modules_same_file)
+ << HdrFilename.str() << Mod->getFullModuleName();
+ if (!Mod->DefinitionLoc.isInvalid())
+ Diag(Mod->DefinitionLoc, diag::note_defined_here)
+ << Mod->getFullModuleName();
+ } else {
+ Diag(IncLoc, diag::note_redefinition_include_same_file)
+ << HdrFilename.str();
+ }
+ return true;
+ }
+
+ return false;
+ };
+
+ // Is it the same file and same offset? Provide more information on why
+ // this leads to a redefinition error.
+ bool EmittedDiag = false;
+ if (FNew == FOld && FNewDecLoc.second == FOldDecLoc.second) {
+ SourceLocation OldIncLoc = SrcMgr.getIncludeLoc(FOldDecLoc.first);
+ SourceLocation NewIncLoc = SrcMgr.getIncludeLoc(FNewDecLoc.first);
+ EmittedDiag = noteFromModuleOrInclude(Old, OldIncLoc);
+ EmittedDiag |= noteFromModuleOrInclude(New, NewIncLoc);
+
+ // If the header has no guards, emit a note suggesting one.
+ if (FOld && !HSI.isFileMultipleIncludeGuarded(FOld))
+ Diag(Old, diag::note_use_ifdef_guards);
+
+ if (EmittedDiag)
+ return;
+ }
+
+ // Redefinition coming from different files or couldn't do better above.
+ Diag(Old, diag::note_previous_definition);
+}
+
/// We've just determined that \p Old and \p New both appear to be definitions
/// of the same variable. Either diagnose or fix the problem.
bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
@@ -3816,12 +3929,12 @@ bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
// Make the canonical definition visible.
if (auto *OldTD = Old->getDescribedVarTemplate())
- makeMergedDefinitionVisible(OldTD, New->getLocation());
- makeMergedDefinitionVisible(Old, New->getLocation());
+ makeMergedDefinitionVisible(OldTD);
+ makeMergedDefinitionVisible(Old);
return false;
} else {
Diag(New->getLocation(), diag::err_redefinition) << New;
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
New->setInvalidDecl();
return true;
}
@@ -6706,6 +6819,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
return NewTemplate;
}
+ if (IsMemberSpecialization && !NewVD->isInvalidDecl())
+ CompleteMemberSpecialization(NewVD, Previous);
+
return NewVD;
}
@@ -8919,12 +9035,17 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
}
+ MarkUnusedFileScopedDecl(NewFD);
+
if (getLangOpts().CPlusPlus) {
if (FunctionTemplate) {
if (NewFD->isInvalidDecl())
FunctionTemplate->setInvalidDecl();
return FunctionTemplate;
}
+
+ if (isMemberSpecialization && !NewFD->isInvalidDecl())
+ CompleteMemberSpecialization(NewFD, Previous);
}
if (NewFD->hasAttr<OpenCLKernelAttr>()) {
@@ -8964,8 +9085,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
}
}
- MarkUnusedFileScopedDecl(NewFD);
-
// Here we have an function template explicit specialization at class scope.
// The actually specialization will be postponed to template instatiation
// time via the ClassScopeFunctionSpecializationDecl node.
@@ -9182,7 +9301,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
if (OldTemplateDecl->getTemplatedDecl()->isDeleted()) {
FunctionDecl *const OldTemplatedDecl =
OldTemplateDecl->getTemplatedDecl();
+ // FIXME: This assert will not hold in the presence of modules.
assert(OldTemplatedDecl->getCanonicalDecl() == OldTemplatedDecl);
+ // FIXME: We need an update record for this AST mutation.
OldTemplatedDecl->setDeletedAsWritten(false);
}
}
@@ -10273,23 +10394,36 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
VDecl->setInit(Init);
if (VDecl->isLocalVarDecl()) {
+ // Don't check the initializer if the declaration is malformed.
+ if (VDecl->isInvalidDecl()) {
+ // do nothing
+
+ // OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
+ // This is true even in OpenCL C++.
+ } else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
+ CheckForConstantInitializer(Init, DclT);
+
+ // Otherwise, C++ does not restrict the initializer.
+ } else if (getLangOpts().CPlusPlus) {
+ // do nothing
+
// C99 6.7.8p4: All the expressions in an initializer for an object that has
// static storage duration shall be constant expressions or string literals.
- // C++ does not have this restriction.
- if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) {
+ } else if (VDecl->getStorageClass() == SC_Static) {
+ CheckForConstantInitializer(Init, DclT);
+
+ // C89 is stricter than C99 for aggregate initializers.
+ // C89 6.5.7p3: All the expressions [...] in an initializer list
+ // for an object that has aggregate or union type shall be
+ // constant expressions.
+ } else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
+ isa<InitListExpr>(Init)) {
const Expr *Culprit;
- if (VDecl->getStorageClass() == SC_Static)
- CheckForConstantInitializer(Init, DclT);
- // C89 is stricter than C99 for non-static aggregate types.
- // C89 6.5.7p3: All the expressions [...] in an initializer list
- // for an object that has aggregate or union type shall be
- // constant expressions.
- else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
- isa<InitListExpr>(Init) &&
- !Init->isConstantInitializer(Context, false, &Culprit))
+ if (!Init->isConstantInitializer(Context, false, &Culprit)) {
Diag(Culprit->getExprLoc(),
diag::ext_aggregate_init_not_constant)
<< Culprit->getSourceRange();
+ }
}
} else if (VDecl->isStaticDataMember() && !VDecl->isInline() &&
VDecl->getLexicalDeclContext()->isRecord()) {
@@ -11023,8 +11157,7 @@ static bool hasDependentAlignment(VarDecl *VD) {
/// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform
/// any semantic actions necessary after any initializer has been attached.
-void
-Sema::FinalizeDeclaration(Decl *ThisDecl) {
+void Sema::FinalizeDeclaration(Decl *ThisDecl) {
// Note that we are no longer parsing the initializer for this declaration.
ParsingInitForAutoVars.erase(ThisDecl);
@@ -11189,9 +11322,8 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
if (DC->getRedeclContext()->isFileContext() && VD->isExternallyVisible())
AddPushedVisibilityAttribute(VD);
- // FIXME: Warn on unused templates.
- if (VD->isFileVarDecl() && !VD->getDescribedVarTemplate() &&
- !isa<VarTemplatePartialSpecializationDecl>(VD))
+ // FIXME: Warn on unused var template partial specializations.
+ if (VD->isFileVarDecl() && !isa<VarTemplatePartialSpecializationDecl>(VD))
MarkUnusedFileScopedDecl(VD);
// Now we have parsed the initializer and can update the table of magic
@@ -11765,9 +11897,8 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
Definition->getNumTemplateParameterLists())) {
SkipBody->ShouldSkip = true;
if (auto *TD = Definition->getDescribedFunctionTemplate())
- makeMergedDefinitionVisible(TD, FD->getLocation());
- makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
- FD->getLocation());
+ makeMergedDefinitionVisible(TD);
+ makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition));
return;
}
@@ -13421,7 +13552,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// we already have. Make the existing definition visible and
// use it in place of this one.
SkipBody->ShouldSkip = true;
- makeMergedDefinitionVisible(Hidden, KWLoc);
+ makeMergedDefinitionVisible(Hidden);
return Def;
} else if (!IsExplicitSpecializationAfterInstantiation) {
// A redeclaration in function prototype scope in C isn't
@@ -13430,7 +13561,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name;
else
Diag(NameLoc, diag::err_redefinition) << Name;
- Diag(Def->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Def->getLocation(),
+ NameLoc.isValid() ? NameLoc : KWLoc);
// If this is a redefinition, recover by making this
// struct be anonymous, which will make any later
// references get the previous definition.
@@ -13520,7 +13652,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// The tag name clashes with something else in the target scope,
// issue an error and recover by making this tag be anonymous.
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
- Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(PrevDecl->getLocation(), NameLoc);
Name = nullptr;
Invalid = true;
}
@@ -13753,6 +13885,9 @@ CreateNewDecl:
// record.
AddPushedVisibilityAttribute(New);
+ if (isMemberSpecialization && !New->isInvalidDecl())
+ CompleteMemberSpecialization(New, Previous);
+
OwnedDecl = true;
// In C++, don't return an invalid declaration. We can't recover well from
// the cases where we make the type anonymous.
@@ -15221,7 +15356,7 @@ Decl *Sema::ActOnEnumConstant(Scope *S, Decl *theEnumDecl, Decl *lastEnumConst,
Diag(IdLoc, diag::err_redefinition_of_enumerator) << Id;
else
Diag(IdLoc, diag::err_redefinition) << Id;
- Diag(PrevDecl->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(PrevDecl->getLocation(), IdLoc);
return nullptr;
}
}
diff --git a/lib/Sema/SemaDeclAttr.cpp b/lib/Sema/SemaDeclAttr.cpp
index 97d273f6ddb6..3de792e4e406 100644
--- a/lib/Sema/SemaDeclAttr.cpp
+++ b/lib/Sema/SemaDeclAttr.cpp
@@ -7230,6 +7230,13 @@ public:
SemaRef.Context.getTargetInfo().getPlatformMinVersion());
}
+ bool TraverseDecl(Decl *D) {
+ // Avoid visiting nested functions to prevent duplicate warnings.
+ if (!D || isa<FunctionDecl>(D))
+ return true;
+ return Base::TraverseDecl(D);
+ }
+
bool TraverseStmt(Stmt *S) {
if (!S)
return true;
@@ -7243,6 +7250,8 @@ public:
bool TraverseIfStmt(IfStmt *If);
+ bool TraverseLambdaExpr(LambdaExpr *E) { return true; }
+
bool VisitObjCMessageExpr(ObjCMessageExpr *Msg) {
if (ObjCMethodDecl *D = Msg->getMethodDecl())
DiagnoseDeclAvailability(
@@ -7346,7 +7355,9 @@ void DiagnoseUnguardedAvailability::DiagnoseDeclAvailability(
llvm::raw_string_ostream FixItOS(FixItString);
FixItOS << "if (" << (SemaRef.getLangOpts().ObjC1 ? "@available"
: "__builtin_available")
- << "(" << SemaRef.getASTContext().getTargetInfo().getPlatformName()
+ << "("
+ << AvailabilityAttr::getPlatformNameSourceSpelling(
+ SemaRef.getASTContext().getTargetInfo().getPlatformName())
<< " " << Introduced.getAsString() << ", *)) {\n"
<< Indentation << ExtraIndentation;
FixitDiag << FixItHint::CreateInsertion(IfInsertionLoc, FixItOS.str());
diff --git a/lib/Sema/SemaExpr.cpp b/lib/Sema/SemaExpr.cpp
index 849e978e2d86..14efc9672061 100644
--- a/lib/Sema/SemaExpr.cpp
+++ b/lib/Sema/SemaExpr.cpp
@@ -5277,6 +5277,9 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
// We aren't supposed to apply this logic if there's an '&' involved.
if (!find.HasFormOfMemberPointer) {
+ if (Expr::hasAnyTypeDependentArguments(ArgExprs))
+ return new (Context) CallExpr(
+ Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
OverloadExpr *ovl = find.Expression;
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl))
return BuildOverloadedCallExpr(
@@ -8028,6 +8031,33 @@ QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &LHS,
return QualType();
}
+// Diagnose cases where a scalar was implicitly converted to a vector and
+// diagnose the underlying types. Otherwise, diagnose the error
+// as invalid vector logical operands for non-C++ cases.
+QualType Sema::InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,
+ ExprResult &RHS) {
+ QualType LHSType = LHS.get()->IgnoreImpCasts()->getType();
+ QualType RHSType = RHS.get()->IgnoreImpCasts()->getType();
+
+ bool LHSNatVec = LHSType->isVectorType();
+ bool RHSNatVec = RHSType->isVectorType();
+
+ if (!(LHSNatVec && RHSNatVec)) {
+ Expr *Vector = LHSNatVec ? LHS.get() : RHS.get();
+ Expr *NonVector = !LHSNatVec ? LHS.get() : RHS.get();
+ Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)
+ << 0 << Vector->getType() << NonVector->IgnoreImpCasts()->getType()
+ << Vector->getSourceRange();
+ return QualType();
+ }
+
+ Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)
+ << 1 << LHSType << RHSType << LHS.get()->getSourceRange()
+ << RHS.get()->getSourceRange();
+
+ return QualType();
+}
+
/// Try to convert a value of non-vector type to a vector type by converting
/// the type to the element type of the vector and then performing a splat.
/// If the language is OpenCL, we only use conversions that promote scalar
@@ -8075,6 +8105,162 @@ static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
return false;
}
+/// Test if a (constant) integer Int can be casted to another integer type
+/// IntTy without losing precision.
+static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
+ QualType OtherIntTy) {
+ QualType IntTy = Int->get()->getType().getUnqualifiedType();
+
+ // Reject cases where the value of the Int is unknown as that would
+ // possibly cause truncation, but accept cases where the scalar can be
+ // demoted without loss of precision.
+ llvm::APSInt Result;
+ bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
+ int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy);
+ bool IntSigned = IntTy->hasSignedIntegerRepresentation();
+ bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation();
+
+ if (CstInt) {
+ // If the scalar is constant and is of a higher order and has more active
+ // bits that the vector element type, reject it.
+ unsigned NumBits = IntSigned
+ ? (Result.isNegative() ? Result.getMinSignedBits()
+ : Result.getActiveBits())
+ : Result.getActiveBits();
+ if (Order < 0 && S.Context.getIntWidth(OtherIntTy) < NumBits)
+ return true;
+
+ // If the signedness of the scalar type and the vector element type
+ // differs and the number of bits is greater than that of the vector
+ // element reject it.
+ return (IntSigned != OtherIntSigned &&
+ NumBits > S.Context.getIntWidth(OtherIntTy));
+ }
+
+ // Reject cases where the value of the scalar is not constant and it's
+ // order is greater than that of the vector element type.
+ return (Order < 0);
+}
+
+/// Test if a (constant) integer Int can be casted to floating point type
+/// FloatTy without losing precision.
+static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
+ QualType FloatTy) {
+ QualType IntTy = Int->get()->getType().getUnqualifiedType();
+
+ // Determine if the integer constant can be expressed as a floating point
+ // number of the appropiate type.
+ llvm::APSInt Result;
+ bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
+ uint64_t Bits = 0;
+ if (CstInt) {
+ // Reject constants that would be truncated if they were converted to
+ // the floating point type. Test by simple to/from conversion.
+ // FIXME: Ideally the conversion to an APFloat and from an APFloat
+ // could be avoided if there was a convertFromAPInt method
+ // which could signal back if implicit truncation occurred.
+ llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy));
+ Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(),
+ llvm::APFloat::rmTowardZero);
+ llvm::APSInt ConvertBack(S.Context.getIntWidth(IntTy),
+ !IntTy->hasSignedIntegerRepresentation());
+ bool Ignored = false;
+ Float.convertToInteger(ConvertBack, llvm::APFloat::rmNearestTiesToEven,
+ &Ignored);
+ if (Result != ConvertBack)
+ return true;
+ } else {
+ // Reject types that cannot be fully encoded into the mantissa of
+ // the float.
+ Bits = S.Context.getTypeSize(IntTy);
+ unsigned FloatPrec = llvm::APFloat::semanticsPrecision(
+ S.Context.getFloatTypeSemantics(FloatTy));
+ if (Bits > FloatPrec)
+ return true;
+ }
+
+ return false;
+}
+
+/// Attempt to convert and splat Scalar into a vector whose types matches
+/// Vector following GCC conversion rules. The rule is that implicit
+/// conversion can occur when Scalar can be casted to match Vector's element
+/// type without causing truncation of Scalar.
+static bool tryGCCVectorConvertAndSplat(Sema &S, ExprResult *Scalar,
+ ExprResult *Vector) {
+ QualType ScalarTy = Scalar->get()->getType().getUnqualifiedType();
+ QualType VectorTy = Vector->get()->getType().getUnqualifiedType();
+ const VectorType *VT = VectorTy->getAs<VectorType>();
+
+ assert(!isa<ExtVectorType>(VT) &&
+ "ExtVectorTypes should not be handled here!");
+
+ QualType VectorEltTy = VT->getElementType();
+
+ // Reject cases where the vector element type or the scalar element type are
+ // not integral or floating point types.
+ if (!VectorEltTy->isArithmeticType() || !ScalarTy->isArithmeticType())
+ return true;
+
+ // The conversion to apply to the scalar before splatting it,
+ // if necessary.
+ CastKind ScalarCast = CK_NoOp;
+
+ // Accept cases where the vector elements are integers and the scalar is
+ // an integer.
+ // FIXME: Notionally if the scalar was a floating point value with a precise
+ // integral representation, we could cast it to an appropriate integer
+ // type and then perform the rest of the checks here. GCC will perform
+ // this conversion in some cases as determined by the input language.
+ // We should accept it on a language independent basis.
+ if (VectorEltTy->isIntegralType(S.Context) &&
+ ScalarTy->isIntegralType(S.Context) &&
+ S.Context.getIntegerTypeOrder(VectorEltTy, ScalarTy)) {
+
+ if (canConvertIntToOtherIntTy(S, Scalar, VectorEltTy))
+ return true;
+
+ ScalarCast = CK_IntegralCast;
+ } else if (VectorEltTy->isRealFloatingType()) {
+ if (ScalarTy->isRealFloatingType()) {
+
+ // Reject cases where the scalar type is not a constant and has a higher
+ // Order than the vector element type.
+ llvm::APFloat Result(0.0);
+ bool CstScalar = Scalar->get()->EvaluateAsFloat(Result, S.Context);
+ int Order = S.Context.getFloatingTypeOrder(VectorEltTy, ScalarTy);
+ if (!CstScalar && Order < 0)
+ return true;
+
+ // If the scalar cannot be safely casted to the vector element type,
+ // reject it.
+ if (CstScalar) {
+ bool Truncated = false;
+ Result.convert(S.Context.getFloatTypeSemantics(VectorEltTy),
+ llvm::APFloat::rmNearestTiesToEven, &Truncated);
+ if (Truncated)
+ return true;
+ }
+
+ ScalarCast = CK_FloatingCast;
+ } else if (ScalarTy->isIntegralType(S.Context)) {
+ if (canConvertIntTyToFloatTy(S, Scalar, VectorEltTy))
+ return true;
+
+ ScalarCast = CK_IntegralToFloating;
+ } else
+ return true;
+ }
+
+ // Adjust scalar if desired.
+ if (Scalar) {
+ if (ScalarCast != CK_NoOp)
+ *Scalar = S.ImpCastExprToType(Scalar->get(), VectorEltTy, ScalarCast);
+ *Scalar = S.ImpCastExprToType(Scalar->get(), VectorTy, CK_VectorSplat);
+ }
+ return false;
+}
+
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
SourceLocation Loc, bool IsCompAssign,
bool AllowBothBool,
@@ -8143,19 +8329,29 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
}
}
- // If there's an ext-vector type and a scalar, try to convert the scalar to
+ // If there's a vector type and a scalar, try to convert the scalar to
// the vector element type and splat.
- // FIXME: this should also work for regular vector types as supported in GCC.
- if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
- if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
- LHSVecType->getElementType(), LHSType))
- return LHSType;
+ if (!RHSVecType) {
+ if (isa<ExtVectorType>(LHSVecType)) {
+ if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
+ LHSVecType->getElementType(), LHSType))
+ return LHSType;
+ } else {
+ if (!tryGCCVectorConvertAndSplat(*this, &RHS, &LHS))
+ return LHSType;
+ }
}
- if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
- if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
- LHSType, RHSVecType->getElementType(),
- RHSType))
- return RHSType;
+ if (!LHSVecType) {
+ if (isa<ExtVectorType>(RHSVecType)) {
+ if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
+ LHSType, RHSVecType->getElementType(),
+ RHSType))
+ return RHSType;
+ } else {
+ if (LHS.get()->getValueKind() == VK_LValue ||
+ !tryGCCVectorConvertAndSplat(*this, &LHS, &RHS))
+ return RHSType;
+ }
}
// FIXME: The code below also handles conversion between vectors and
@@ -8208,6 +8404,22 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
return QualType();
}
+
+ // If there is a vector type that is not a ExtVector and a scalar, we reach
+ // this point if scalar could not be converted to the vector's element type
+ // without truncation.
+ if ((RHSVecType && !isa<ExtVectorType>(RHSVecType)) ||
+ (LHSVecType && !isa<ExtVectorType>(LHSVecType))) {
+ QualType Scalar = LHSVecType ? RHSType : LHSType;
+ QualType Vector = LHSVecType ? LHSType : RHSType;
+ unsigned ScalarOrVector = LHSVecType && RHSVecType ? 1 : 0;
+ Diag(Loc,
+ diag::err_typecheck_vector_not_convertable_implict_truncation)
+ << ScalarOrVector << Scalar << Vector;
+
+ return QualType();
+ }
+
// Otherwise, use the generic diagnostic.
Diag(Loc, diag::err_typecheck_vector_not_convertable)
<< LHSType << RHSType
@@ -9827,6 +10039,12 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 &&
vType->hasFloatingRepresentation())
return InvalidOperands(Loc, LHS, RHS);
+ // FIXME: The check for C++ here is for GCC compatibility. GCC rejects the
+ // usage of the logical operators && and || with vectors in C. This
+ // check could be notionally dropped.
+ if (!getLangOpts().CPlusPlus &&
+ !(isa<ExtVectorType>(vType->getAs<VectorType>())))
+ return InvalidLogicalVectorOperands(Loc, LHS, RHS);
return GetSignedVectorType(LHS.get()->getType());
}
@@ -11770,6 +11988,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
resultType = GetSignedVectorType(resultType);
break;
} else {
+ // FIXME: GCC's vector extension permits the usage of '!' with a vector
+ // type in C++. We should allow that here too.
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
<< resultType << Input.get()->getSourceRange());
}
diff --git a/lib/Sema/SemaExprCXX.cpp b/lib/Sema/SemaExprCXX.cpp
index 9b88cddbc969..8500b748a3ec 100644
--- a/lib/Sema/SemaExprCXX.cpp
+++ b/lib/Sema/SemaExprCXX.cpp
@@ -4720,10 +4720,24 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
// regard to cv-qualifiers.
const RecordType *lhsRecord = LhsT->getAs<RecordType>();
- if (!lhsRecord) return false;
-
const RecordType *rhsRecord = RhsT->getAs<RecordType>();
- if (!rhsRecord) return false;
+ if (!rhsRecord || !lhsRecord) {
+ const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
+ const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
+ if (!LHSObjTy || !RHSObjTy)
+ return false;
+
+ ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
+ ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
+ if (!BaseInterface || !DerivedInterface)
+ return false;
+
+ if (Self.RequireCompleteType(
+ KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr))
+ return false;
+
+ return BaseInterface->isSuperClassOf(DerivedInterface);
+ }
assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT)
== (lhsRecord == rhsRecord));
@@ -5342,6 +5356,15 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
// C++11 [expr.cond]p1
// The first expression is contextually converted to bool.
+ //
+ // FIXME; GCC's vector extension permits the use of a?b:c where the type of
+ // a is that of a integer vector with the same number of elements and
+ // size as the vectors of b and c. If one of either b or c is a scalar
+ // it is implicitly converted to match the type of the vector.
+ // Otherwise the expression is ill-formed. If both b and c are scalars,
+ // then b and c are checked and converted to the type of a if possible.
+ // Unlike the OpenCL ?: operator, the expression is evaluated as
+ // (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
if (!Cond.get()->isTypeDependent()) {
ExprResult CondRes = CheckCXXBooleanCondition(Cond.get());
if (CondRes.isInvalid())
diff --git a/lib/Sema/SemaExprObjC.cpp b/lib/Sema/SemaExprObjC.cpp
index a44e9243e3c5..28581bad1a7a 100644
--- a/lib/Sema/SemaExprObjC.cpp
+++ b/lib/Sema/SemaExprObjC.cpp
@@ -4241,8 +4241,7 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) {
castType = cast->getTypeAsWritten();
CCK = CCK_OtherCast;
} else {
- castType = cast->getType();
- CCK = CCK_ImplicitConversion;
+ llvm_unreachable("Unexpected ImplicitCastExpr");
}
ARCConversionTypeClass castACTC =
diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp
index d0f530010a0d..32024cb335dc 100644
--- a/lib/Sema/SemaInit.cpp
+++ b/lib/Sema/SemaInit.cpp
@@ -1209,7 +1209,7 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
} else {
assert((ElemType->isRecordType() || ElemType->isVectorType() ||
- ElemType->isClkEventT()) && "Unexpected type");
+ ElemType->isOpenCLSpecificType()) && "Unexpected type");
// C99 6.7.8p13:
//
@@ -8296,8 +8296,46 @@ Sema::PerformCopyInitialization(const InitializedEntity &Entity,
AllowExplicit);
InitializationSequence Seq(*this, Entity, Kind, InitE, TopLevelOfInitList);
+ // Prevent infinite recursion when performing parameter copy-initialization.
+ const bool ShouldTrackCopy =
+ Entity.isParameterKind() && Seq.isConstructorInitialization();
+ if (ShouldTrackCopy) {
+ if (llvm::find(CurrentParameterCopyTypes, Entity.getType()) !=
+ CurrentParameterCopyTypes.end()) {
+ Seq.SetOverloadFailure(
+ InitializationSequence::FK_ConstructorOverloadFailed,
+ OR_No_Viable_Function);
+
+ // Try to give a meaningful diagnostic note for the problematic
+ // constructor.
+ const auto LastStep = Seq.step_end() - 1;
+ assert(LastStep->Kind ==
+ InitializationSequence::SK_ConstructorInitialization);
+ const FunctionDecl *Function = LastStep->Function.Function;
+ auto Candidate =
+ llvm::find_if(Seq.getFailedCandidateSet(),
+ [Function](const OverloadCandidate &Candidate) -> bool {
+ return Candidate.Viable &&
+ Candidate.Function == Function &&
+ Candidate.Conversions.size() > 0;
+ });
+ if (Candidate != Seq.getFailedCandidateSet().end() &&
+ Function->getNumParams() > 0) {
+ Candidate->Viable = false;
+ Candidate->FailureKind = ovl_fail_bad_conversion;
+ Candidate->Conversions[0].setBad(BadConversionSequence::no_conversion,
+ InitE,
+ Function->getParamDecl(0)->getType());
+ }
+ }
+ CurrentParameterCopyTypes.push_back(Entity.getType());
+ }
+
ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
+ if (ShouldTrackCopy)
+ CurrentParameterCopyTypes.pop_back();
+
return Result;
}
diff --git a/lib/Sema/SemaLookup.cpp b/lib/Sema/SemaLookup.cpp
index ce76e14982db..c5b579a4b2e9 100644
--- a/lib/Sema/SemaLookup.cpp
+++ b/lib/Sema/SemaLookup.cpp
@@ -1382,8 +1382,8 @@ Module *Sema::getOwningModule(Decl *Entity) {
return M;
}
-void Sema::makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc) {
- if (auto *M = PP.getModuleContainingLocation(Loc))
+void Sema::makeMergedDefinitionVisible(NamedDecl *ND) {
+ if (auto *M = getCurrentModule())
Context.mergeDefinitionIntoModule(ND, M);
else
// We're not building a module; just make the definition visible.
@@ -1393,7 +1393,7 @@ void Sema::makeMergedDefinitionVisible(NamedDecl *ND, SourceLocation Loc) {
// visible too. They're not (necessarily) within a mergeable DeclContext.
if (auto *TD = dyn_cast<TemplateDecl>(ND))
for (auto *Param : *TD->getTemplateParameters())
- makeMergedDefinitionVisible(Param, Loc);
+ makeMergedDefinitionVisible(Param);
}
/// \brief Find the module in which the given declaration was defined.
@@ -3445,7 +3445,8 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
bool QualifiedNameLookup,
bool InBaseClass,
VisibleDeclConsumer &Consumer,
- VisibleDeclsRecord &Visited) {
+ VisibleDeclsRecord &Visited,
+ bool IncludeDependentBases = false) {
if (!Ctx)
return;
@@ -3501,7 +3502,8 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
ShadowContextRAII Shadow(Visited);
for (auto I : Ctx->using_directives()) {
LookupVisibleDecls(I->getNominatedNamespace(), Result,
- QualifiedNameLookup, InBaseClass, Consumer, Visited);
+ QualifiedNameLookup, InBaseClass, Consumer, Visited,
+ IncludeDependentBases);
}
}
@@ -3513,14 +3515,28 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
for (const auto &B : Record->bases()) {
QualType BaseType = B.getType();
- // Don't look into dependent bases, because name lookup can't look
- // there anyway.
- if (BaseType->isDependentType())
- continue;
-
- const RecordType *Record = BaseType->getAs<RecordType>();
- if (!Record)
- continue;
+ RecordDecl *RD;
+ if (BaseType->isDependentType()) {
+ if (!IncludeDependentBases) {
+ // Don't look into dependent bases, because name lookup can't look
+ // there anyway.
+ continue;
+ }
+ const auto *TST = BaseType->getAs<TemplateSpecializationType>();
+ if (!TST)
+ continue;
+ TemplateName TN = TST->getTemplateName();
+ const auto *TD =
+ dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
+ if (!TD)
+ continue;
+ RD = TD->getTemplatedDecl();
+ } else {
+ const auto *Record = BaseType->getAs<RecordType>();
+ if (!Record)
+ continue;
+ RD = Record->getDecl();
+ }
// FIXME: It would be nice to be able to determine whether referencing
// a particular member would be ambiguous. For example, given
@@ -3543,8 +3559,8 @@ static void LookupVisibleDecls(DeclContext *Ctx, LookupResult &Result,
// Find results in this base class (and its bases).
ShadowContextRAII Shadow(Visited);
- LookupVisibleDecls(Record->getDecl(), Result, QualifiedNameLookup,
- true, Consumer, Visited);
+ LookupVisibleDecls(RD, Result, QualifiedNameLookup, true, Consumer,
+ Visited, IncludeDependentBases);
}
}
@@ -3713,7 +3729,8 @@ void Sema::LookupVisibleDecls(Scope *S, LookupNameKind Kind,
void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
VisibleDeclConsumer &Consumer,
- bool IncludeGlobalScope) {
+ bool IncludeGlobalScope,
+ bool IncludeDependentBases) {
LookupResult Result(*this, DeclarationName(), SourceLocation(), Kind);
Result.setAllowHidden(Consumer.includeHiddenDecls());
VisibleDeclsRecord Visited;
@@ -3721,7 +3738,8 @@ void Sema::LookupVisibleDecls(DeclContext *Ctx, LookupNameKind Kind,
Visited.visitedContext(Context.getTranslationUnitDecl());
ShadowContextRAII Shadow(Visited);
::LookupVisibleDecls(Ctx, Result, /*QualifiedNameLookup=*/true,
- /*InBaseClass=*/false, Consumer, Visited);
+ /*InBaseClass=*/false, Consumer, Visited,
+ IncludeDependentBases);
}
/// LookupOrCreateLabel - Do a name lookup of a label with the specified name.
diff --git a/lib/Sema/SemaOverload.cpp b/lib/Sema/SemaOverload.cpp
index 782c377e3202..51794160278c 100644
--- a/lib/Sema/SemaOverload.cpp
+++ b/lib/Sema/SemaOverload.cpp
@@ -11210,12 +11210,12 @@ Sema::resolveAddressOfOnlyViableOverloadCandidate(Expr *E,
/// \brief Given an overloaded function, tries to turn it into a non-overloaded
/// function reference using resolveAddressOfOnlyViableOverloadCandidate. This
/// will perform access checks, diagnose the use of the resultant decl, and, if
-/// necessary, perform a function-to-pointer decay.
+/// requested, potentially perform a function-to-pointer decay.
///
/// Returns false if resolveAddressOfOnlyViableOverloadCandidate fails.
/// Otherwise, returns true. This may emit diagnostics and return true.
bool Sema::resolveAndFixAddressOfOnlyViableOverloadCandidate(
- ExprResult &SrcExpr) {
+ ExprResult &SrcExpr, bool DoFunctionPointerConverion) {
Expr *E = SrcExpr.get();
assert(E->getType() == Context.OverloadTy && "SrcExpr must be an overload");
@@ -11230,7 +11230,7 @@ bool Sema::resolveAndFixAddressOfOnlyViableOverloadCandidate(
DiagnoseUseOfDecl(Found, E->getExprLoc());
CheckAddressOfMemberAccess(E, DAP);
Expr *Fixed = FixOverloadedFunctionReference(E, DAP, Found);
- if (Fixed->getType()->isFunctionType())
+ if (DoFunctionPointerConverion && Fixed->getType()->isFunctionType())
SrcExpr = DefaultFunctionArrayConversion(Fixed, /*Diagnose=*/false);
else
SrcExpr = Fixed;
diff --git a/lib/Sema/SemaStmt.cpp b/lib/Sema/SemaStmt.cpp
index 5d7eada28717..33a8f9c4afa3 100644
--- a/lib/Sema/SemaStmt.cpp
+++ b/lib/Sema/SemaStmt.cpp
@@ -2268,9 +2268,57 @@ Sema::BuildCXXForRangeStmt(SourceLocation ForLoc, SourceLocation CoawaitLoc,
BoundExpr = IntegerLiteral::Create(
Context, CAT->getSize(), Context.getPointerDiffType(), RangeLoc);
else if (const VariableArrayType *VAT =
- dyn_cast<VariableArrayType>(UnqAT))
- BoundExpr = VAT->getSizeExpr();
- else {
+ dyn_cast<VariableArrayType>(UnqAT)) {
+ // For a variably modified type we can't just use the expression within
+ // the array bounds, since we don't want that to be re-evaluated here.
+ // Rather, we need to determine what it was when the array was first
+ // created - so we resort to using sizeof(vla)/sizeof(element).
+ // For e.g.
+ // void f(int b) {
+ // int vla[b];
+ // b = -1; <-- This should not affect the num of iterations below
+ // for (int &c : vla) { .. }
+ // }
+
+ // FIXME: This results in codegen generating IR that recalculates the
+ // run-time number of elements (as opposed to just using the IR Value
+ // that corresponds to the run-time value of each bound that was
+ // generated when the array was created.) If this proves too embarassing
+ // even for unoptimized IR, consider passing a magic-value/cookie to
+ // codegen that then knows to simply use that initial llvm::Value (that
+ // corresponds to the bound at time of array creation) within
+ // getelementptr. But be prepared to pay the price of increasing a
+ // customized form of coupling between the two components - which could
+ // be hard to maintain as the codebase evolves.
+
+ ExprResult SizeOfVLAExprR = ActOnUnaryExprOrTypeTraitExpr(
+ EndVar->getLocation(), UETT_SizeOf,
+ /*isType=*/true,
+ CreateParsedType(VAT->desugar(), Context.getTrivialTypeSourceInfo(
+ VAT->desugar(), RangeLoc))
+ .getAsOpaquePtr(),
+ EndVar->getSourceRange());
+ if (SizeOfVLAExprR.isInvalid())
+ return StmtError();
+
+ ExprResult SizeOfEachElementExprR = ActOnUnaryExprOrTypeTraitExpr(
+ EndVar->getLocation(), UETT_SizeOf,
+ /*isType=*/true,
+ CreateParsedType(VAT->desugar(),
+ Context.getTrivialTypeSourceInfo(
+ VAT->getElementType(), RangeLoc))
+ .getAsOpaquePtr(),
+ EndVar->getSourceRange());
+ if (SizeOfEachElementExprR.isInvalid())
+ return StmtError();
+
+ BoundExpr =
+ ActOnBinOp(S, EndVar->getLocation(), tok::slash,
+ SizeOfVLAExprR.get(), SizeOfEachElementExprR.get());
+ if (BoundExpr.isInvalid())
+ return StmtError();
+
+ } else {
// Can't be a DependentSizedArrayType or an IncompleteArrayType since
// UnqAT is not incomplete and Range is not type-dependent.
llvm_unreachable("Unexpected array type in for-range");
diff --git a/lib/Sema/SemaTemplate.cpp b/lib/Sema/SemaTemplate.cpp
index 61b4df40964c..a479d1027533 100644
--- a/lib/Sema/SemaTemplate.cpp
+++ b/lib/Sema/SemaTemplate.cpp
@@ -455,6 +455,85 @@ void Sema::LookupTemplateName(LookupResult &Found,
}
}
+void Sema::diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName,
+ SourceLocation Less,
+ SourceLocation Greater) {
+ if (TemplateName.isInvalid())
+ return;
+
+ DeclarationNameInfo NameInfo;
+ CXXScopeSpec SS;
+ LookupNameKind LookupKind;
+
+ DeclContext *LookupCtx = nullptr;
+ NamedDecl *Found = nullptr;
+
+ // Figure out what name we looked up.
+ if (auto *ME = dyn_cast<MemberExpr>(TemplateName.get())) {
+ NameInfo = ME->getMemberNameInfo();
+ SS.Adopt(ME->getQualifierLoc());
+ LookupKind = LookupMemberName;
+ LookupCtx = ME->getBase()->getType()->getAsCXXRecordDecl();
+ Found = ME->getMemberDecl();
+ } else {
+ auto *DRE = cast<DeclRefExpr>(TemplateName.get());
+ NameInfo = DRE->getNameInfo();
+ SS.Adopt(DRE->getQualifierLoc());
+ LookupKind = LookupOrdinaryName;
+ Found = DRE->getFoundDecl();
+ }
+
+ // Try to correct the name by looking for templates and C++ named casts.
+ struct TemplateCandidateFilter : CorrectionCandidateCallback {
+ TemplateCandidateFilter() {
+ WantTypeSpecifiers = false;
+ WantExpressionKeywords = false;
+ WantRemainingKeywords = false;
+ WantCXXNamedCasts = true;
+ };
+ bool ValidateCandidate(const TypoCorrection &Candidate) override {
+ if (auto *ND = Candidate.getCorrectionDecl())
+ return isAcceptableTemplateName(ND->getASTContext(), ND, true);
+ return Candidate.isKeyword();
+ }
+ };
+
+ DeclarationName Name = NameInfo.getName();
+ if (TypoCorrection Corrected =
+ CorrectTypo(NameInfo, LookupKind, S, &SS,
+ llvm::make_unique<TemplateCandidateFilter>(),
+ CTK_ErrorRecovery, LookupCtx)) {
+ auto *ND = Corrected.getFoundDecl();
+ if (ND)
+ ND = isAcceptableTemplateName(Context, ND,
+ /*AllowFunctionTemplates*/ true);
+ if (ND || Corrected.isKeyword()) {
+ if (LookupCtx) {
+ std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
+ bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
+ Name.getAsString() == CorrectedStr;
+ diagnoseTypo(Corrected,
+ PDiag(diag::err_non_template_in_member_template_id_suggest)
+ << Name << LookupCtx << DroppedSpecifier
+ << SS.getRange(), false);
+ } else {
+ diagnoseTypo(Corrected,
+ PDiag(diag::err_non_template_in_template_id_suggest)
+ << Name, false);
+ }
+ if (Found)
+ Diag(Found->getLocation(),
+ diag::note_non_template_in_template_id_found);
+ return;
+ }
+ }
+
+ Diag(NameInfo.getLoc(), diag::err_non_template_in_template_id)
+ << Name << SourceRange(Less, Greater);
+ if (Found)
+ Diag(Found->getLocation(), diag::note_non_template_in_template_id_found);
+}
+
/// ActOnDependentIdExpression - Handle a dependent id-expression that
/// was just parsed. This is only possible with an explicit scope
/// specifier naming a dependent type.
@@ -1251,8 +1330,8 @@ Sema::CheckClassTemplate(Scope *S, unsigned TagSpec, TagUseKind TUK,
auto *Tmpl = cast<CXXRecordDecl>(Hidden)->getDescribedClassTemplate();
assert(Tmpl && "original definition of a class template is not a "
"class template?");
- makeMergedDefinitionVisible(Hidden, KWLoc);
- makeMergedDefinitionVisible(Tmpl, KWLoc);
+ makeMergedDefinitionVisible(Hidden);
+ makeMergedDefinitionVisible(Tmpl);
return Def;
}
@@ -7352,7 +7431,7 @@ Sema::ActOnClassTemplateSpecialization(Scope *S, unsigned TagSpec,
NamedDecl *Hidden = nullptr;
if (Def && SkipBody && !hasVisibleDefinition(Def, &Hidden)) {
SkipBody->ShouldSkip = true;
- makeMergedDefinitionVisible(Hidden, KWLoc);
+ makeMergedDefinitionVisible(Hidden);
// From here on out, treat this as just a redeclaration.
TUK = TUK_Declaration;
} else if (Def) {
@@ -7825,6 +7904,9 @@ bool Sema::CheckFunctionTemplateSpecialization(
// C++11 [dcl.constexpr]p1: An explicit specialization of a constexpr
// function can differ from the template declaration with respect to
// the constexpr specifier.
+ // FIXME: We need an update record for this AST mutation.
+ // FIXME: What if there are multiple such prior declarations (for instance,
+ // from different modules)?
Specialization->setConstexpr(FD->isConstexpr());
}
@@ -7872,9 +7954,11 @@ bool Sema::CheckFunctionTemplateSpecialization(
// flag to not-deleted, so that we can inherit that information from 'FD'.
if (Specialization->isDeleted() && !SpecInfo->isExplicitSpecialization() &&
!Specialization->getCanonicalDecl()->isReferenced()) {
+ // FIXME: This assert will not hold in the presence of modules.
assert(
Specialization->getCanonicalDecl() == Specialization &&
"This must be the only existing declaration of this specialization");
+ // FIXME: We need an update record for this AST mutation.
Specialization->setDeletedAsWritten(false);
}
SpecInfo->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
@@ -7987,8 +8071,11 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
return false;
}
- // If this is a friend, just bail out here before we start turning
- // things into explicit specializations.
+ // A member specialization in a friend declaration isn't really declaring
+ // an explicit specialization, just identifying a specific (possibly implicit)
+ // specialization. Don't change the template specialization kind.
+ //
+ // FIXME: Is this really valid? Other compilers reject.
if (Member->getFriendObjectKind() != Decl::FOK_None) {
// Preserve instantiation information.
if (InstantiatedFrom && isa<CXXMethodDecl>(Member)) {
@@ -8038,66 +8125,36 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
false))
return true;
- // Note that this is an explicit instantiation of a member.
- // the original declaration to note that it is an explicit specialization
- // (if it was previously an implicit instantiation). This latter step
- // makes bookkeeping easier.
- if (isa<FunctionDecl>(Member)) {
+ // Note that this member specialization is an "instantiation of" the
+ // corresponding member of the original template.
+ if (auto *MemberFunction = dyn_cast<FunctionDecl>(Member)) {
FunctionDecl *InstantiationFunction = cast<FunctionDecl>(Instantiation);
if (InstantiationFunction->getTemplateSpecializationKind() ==
TSK_ImplicitInstantiation) {
- InstantiationFunction->setTemplateSpecializationKind(
- TSK_ExplicitSpecialization);
- InstantiationFunction->setLocation(Member->getLocation());
// Explicit specializations of member functions of class templates do not
// inherit '=delete' from the member function they are specializing.
if (InstantiationFunction->isDeleted()) {
+ // FIXME: This assert will not hold in the presence of modules.
assert(InstantiationFunction->getCanonicalDecl() ==
InstantiationFunction);
+ // FIXME: We need an update record for this AST mutation.
InstantiationFunction->setDeletedAsWritten(false);
}
}
- cast<FunctionDecl>(Member)->setInstantiationOfMemberFunction(
- cast<CXXMethodDecl>(InstantiatedFrom),
- TSK_ExplicitSpecialization);
- MarkUnusedFileScopedDecl(InstantiationFunction);
- } else if (isa<VarDecl>(Member)) {
- VarDecl *InstantiationVar = cast<VarDecl>(Instantiation);
- if (InstantiationVar->getTemplateSpecializationKind() ==
- TSK_ImplicitInstantiation) {
- InstantiationVar->setTemplateSpecializationKind(
- TSK_ExplicitSpecialization);
- InstantiationVar->setLocation(Member->getLocation());
- }
-
- cast<VarDecl>(Member)->setInstantiationOfStaticDataMember(
+ MemberFunction->setInstantiationOfMemberFunction(
+ cast<CXXMethodDecl>(InstantiatedFrom), TSK_ExplicitSpecialization);
+ } else if (auto *MemberVar = dyn_cast<VarDecl>(Member)) {
+ MemberVar->setInstantiationOfStaticDataMember(
cast<VarDecl>(InstantiatedFrom), TSK_ExplicitSpecialization);
- MarkUnusedFileScopedDecl(InstantiationVar);
- } else if (isa<CXXRecordDecl>(Member)) {
- CXXRecordDecl *InstantiationClass = cast<CXXRecordDecl>(Instantiation);
- if (InstantiationClass->getTemplateSpecializationKind() ==
- TSK_ImplicitInstantiation) {
- InstantiationClass->setTemplateSpecializationKind(
- TSK_ExplicitSpecialization);
- InstantiationClass->setLocation(Member->getLocation());
- }
-
- cast<CXXRecordDecl>(Member)->setInstantiationOfMemberClass(
- cast<CXXRecordDecl>(InstantiatedFrom),
- TSK_ExplicitSpecialization);
- } else {
- assert(isa<EnumDecl>(Member) && "Only member enums remain");
- EnumDecl *InstantiationEnum = cast<EnumDecl>(Instantiation);
- if (InstantiationEnum->getTemplateSpecializationKind() ==
- TSK_ImplicitInstantiation) {
- InstantiationEnum->setTemplateSpecializationKind(
- TSK_ExplicitSpecialization);
- InstantiationEnum->setLocation(Member->getLocation());
- }
-
- cast<EnumDecl>(Member)->setInstantiationOfMemberEnum(
+ } else if (auto *MemberClass = dyn_cast<CXXRecordDecl>(Member)) {
+ MemberClass->setInstantiationOfMemberClass(
+ cast<CXXRecordDecl>(InstantiatedFrom), TSK_ExplicitSpecialization);
+ } else if (auto *MemberEnum = dyn_cast<EnumDecl>(Member)) {
+ MemberEnum->setInstantiationOfMemberEnum(
cast<EnumDecl>(InstantiatedFrom), TSK_ExplicitSpecialization);
+ } else {
+ llvm_unreachable("unknown member specialization kind");
}
// Save the caller the trouble of having to figure out which declaration
@@ -8107,6 +8164,43 @@ Sema::CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous) {
return false;
}
+/// Complete the explicit specialization of a member of a class template by
+/// updating the instantiated member to be marked as an explicit specialization.
+///
+/// \param OrigD The member declaration instantiated from the template.
+/// \param Loc The location of the explicit specialization of the member.
+template<typename DeclT>
+static void completeMemberSpecializationImpl(Sema &S, DeclT *OrigD,
+ SourceLocation Loc) {
+ if (OrigD->getTemplateSpecializationKind() != TSK_ImplicitInstantiation)
+ return;
+
+ // FIXME: Inform AST mutation listeners of this AST mutation.
+ // FIXME: If there are multiple in-class declarations of the member (from
+ // multiple modules, or a declaration and later definition of a member type),
+ // should we update all of them?
+ OrigD->setTemplateSpecializationKind(TSK_ExplicitSpecialization);
+ OrigD->setLocation(Loc);
+}
+
+void Sema::CompleteMemberSpecialization(NamedDecl *Member,
+ LookupResult &Previous) {
+ NamedDecl *Instantiation = cast<NamedDecl>(Member->getCanonicalDecl());
+ if (Instantiation == Member)
+ return;
+
+ if (auto *Function = dyn_cast<CXXMethodDecl>(Instantiation))
+ completeMemberSpecializationImpl(*this, Function, Member->getLocation());
+ else if (auto *Var = dyn_cast<VarDecl>(Instantiation))
+ completeMemberSpecializationImpl(*this, Var, Member->getLocation());
+ else if (auto *Record = dyn_cast<CXXRecordDecl>(Instantiation))
+ completeMemberSpecializationImpl(*this, Record, Member->getLocation());
+ else if (auto *Enum = dyn_cast<EnumDecl>(Instantiation))
+ completeMemberSpecializationImpl(*this, Enum, Member->getLocation());
+ else
+ llvm_unreachable("unknown member specialization kind");
+}
+
/// \brief Check the scope of an explicit instantiation.
///
/// \returns true if a serious error occurs, false otherwise.
diff --git a/lib/Sema/SemaTemplateInstantiateDecl.cpp b/lib/Sema/SemaTemplateInstantiateDecl.cpp
index 9a71a17561c7..03df6fde6c80 100644
--- a/lib/Sema/SemaTemplateInstantiateDecl.cpp
+++ b/lib/Sema/SemaTemplateInstantiateDecl.cpp
@@ -1849,6 +1849,19 @@ Decl *TemplateDeclInstantiator::VisitFunctionDecl(FunctionDecl *D,
}
}
}
+
+ // Check the template parameter list against the previous declaration. The
+ // goal here is to pick up default arguments added since the friend was
+ // declared; we know the template parameter lists match, since otherwise
+ // we would not have picked this template as the previous declaration.
+ if (TemplateParams && FunctionTemplate->getPreviousDecl()) {
+ SemaRef.CheckTemplateParameterList(
+ TemplateParams,
+ FunctionTemplate->getPreviousDecl()->getTemplateParameters(),
+ Function->isThisDeclarationADefinition()
+ ? Sema::TPC_FriendFunctionTemplateDefinition
+ : Sema::TPC_FriendFunctionTemplate);
+ }
}
if (Function->isLocalExternDecl() && !Function->getPreviousDecl())
@@ -3660,6 +3673,7 @@ TemplateDeclInstantiator::InitFunctionInstantiation(FunctionDecl *New,
New->setType(SemaRef.Context.getFunctionType(
NewProto->getReturnType(), NewProto->getParamTypes(), EPI));
} else {
+ Sema::ContextRAII SwitchContext(SemaRef, New);
SemaRef.SubstExceptionSpec(New, Proto, TemplateArgs);
}
}
diff --git a/lib/Sema/SemaType.cpp b/lib/Sema/SemaType.cpp
index bcc66bbd1c0a..3992179fabae 100644
--- a/lib/Sema/SemaType.cpp
+++ b/lib/Sema/SemaType.cpp
@@ -2285,8 +2285,9 @@ bool Sema::CheckFunctionReturnType(QualType T, SourceLocation Loc) {
// Methods cannot return interface types. All ObjC objects are
// passed by reference.
if (T->isObjCObjectType()) {
- Diag(Loc, diag::err_object_cannot_be_passed_returned_by_value) << 0 << T;
- return 0;
+ Diag(Loc, diag::err_object_cannot_be_passed_returned_by_value)
+ << 0 << T << FixItHint::CreateInsertion(Loc, "*");
+ return true;
}
return false;
diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp
index 61b5a822c552..ef8481488302 100644
--- a/lib/Serialization/ASTReader.cpp
+++ b/lib/Serialization/ASTReader.cpp
@@ -1534,9 +1534,8 @@ MacroInfo *ASTReader::ReadMacroRecord(ModuleFile &F, uint64_t Offset) {
return Macro;
unsigned NextIndex = 1; // Skip identifier ID.
- SubmoduleID SubModID = getGlobalSubmoduleID(F, Record[NextIndex++]);
SourceLocation Loc = ReadSourceLocation(F, Record, NextIndex);
- MacroInfo *MI = PP.AllocateDeserializedMacroInfo(Loc, SubModID);
+ MacroInfo *MI = PP.AllocateMacroInfo(Loc);
MI->setDefinitionEndLoc(ReadSourceLocation(F, Record, NextIndex));
MI->setIsUsed(Record[NextIndex++]);
MI->setUsedForHeaderGuard(Record[NextIndex++]);
diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp
index 8e4b217a44cd..b6c0cb2815fb 100644
--- a/lib/Serialization/ASTWriter.cpp
+++ b/lib/Serialization/ASTWriter.cpp
@@ -2413,7 +2413,6 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) {
}
AddIdentifierRef(Name, Record);
- Record.push_back(inferSubmoduleIDFromLocation(MI->getDefinitionLoc()));
AddSourceLocation(MI->getDefinitionLoc(), Record);
AddSourceLocation(MI->getDefinitionEndLoc(), Record);
Record.push_back(MI->isUsed());
diff --git a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
index 1ea85d60c9e9..371187747f03 100644
--- a/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
+++ b/lib/StaticAnalyzer/Checkers/BasicObjCFoundationChecks.cpp
@@ -233,19 +233,16 @@ void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
if (StringSelectors.empty()) {
ASTContext &Ctx = C.getASTContext();
Selector Sels[] = {
- getKeywordSelector(Ctx, "caseInsensitiveCompare", nullptr),
- getKeywordSelector(Ctx, "compare", nullptr),
- getKeywordSelector(Ctx, "compare", "options", nullptr),
- getKeywordSelector(Ctx, "compare", "options", "range", nullptr),
- getKeywordSelector(Ctx, "compare", "options", "range", "locale",
- nullptr),
- getKeywordSelector(Ctx, "componentsSeparatedByCharactersInSet",
- nullptr),
- getKeywordSelector(Ctx, "initWithFormat",
- nullptr),
- getKeywordSelector(Ctx, "localizedCaseInsensitiveCompare", nullptr),
- getKeywordSelector(Ctx, "localizedCompare", nullptr),
- getKeywordSelector(Ctx, "localizedStandardCompare", nullptr),
+ getKeywordSelector(Ctx, "caseInsensitiveCompare"),
+ getKeywordSelector(Ctx, "compare"),
+ getKeywordSelector(Ctx, "compare", "options"),
+ getKeywordSelector(Ctx, "compare", "options", "range"),
+ getKeywordSelector(Ctx, "compare", "options", "range", "locale"),
+ getKeywordSelector(Ctx, "componentsSeparatedByCharactersInSet"),
+ getKeywordSelector(Ctx, "initWithFormat"),
+ getKeywordSelector(Ctx, "localizedCaseInsensitiveCompare"),
+ getKeywordSelector(Ctx, "localizedCompare"),
+ getKeywordSelector(Ctx, "localizedStandardCompare"),
};
for (Selector KnownSel : Sels)
StringSelectors[KnownSel] = 0;
@@ -262,16 +259,15 @@ void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
if (ArrayWithObjectSel.isNull()) {
ASTContext &Ctx = C.getASTContext();
- ArrayWithObjectSel = getKeywordSelector(Ctx, "arrayWithObject", nullptr);
- AddObjectSel = getKeywordSelector(Ctx, "addObject", nullptr);
+ ArrayWithObjectSel = getKeywordSelector(Ctx, "arrayWithObject");
+ AddObjectSel = getKeywordSelector(Ctx, "addObject");
InsertObjectAtIndexSel =
- getKeywordSelector(Ctx, "insertObject", "atIndex", nullptr);
+ getKeywordSelector(Ctx, "insertObject", "atIndex");
ReplaceObjectAtIndexWithObjectSel =
- getKeywordSelector(Ctx, "replaceObjectAtIndex", "withObject", nullptr);
+ getKeywordSelector(Ctx, "replaceObjectAtIndex", "withObject");
SetObjectAtIndexedSubscriptSel =
- getKeywordSelector(Ctx, "setObject", "atIndexedSubscript", nullptr);
- ArrayByAddingObjectSel =
- getKeywordSelector(Ctx, "arrayByAddingObject", nullptr);
+ getKeywordSelector(Ctx, "setObject", "atIndexedSubscript");
+ ArrayByAddingObjectSel = getKeywordSelector(Ctx, "arrayByAddingObject");
}
if (S == ArrayWithObjectSel || S == AddObjectSel ||
@@ -292,13 +288,11 @@ void NilArgChecker::checkPreObjCMessage(const ObjCMethodCall &msg,
if (DictionaryWithObjectForKeySel.isNull()) {
ASTContext &Ctx = C.getASTContext();
DictionaryWithObjectForKeySel =
- getKeywordSelector(Ctx, "dictionaryWithObject", "forKey", nullptr);
- SetObjectForKeySel =
- getKeywordSelector(Ctx, "setObject", "forKey", nullptr);
+ getKeywordSelector(Ctx, "dictionaryWithObject", "forKey");
+ SetObjectForKeySel = getKeywordSelector(Ctx, "setObject", "forKey");
SetObjectForKeyedSubscriptSel =
- getKeywordSelector(Ctx, "setObject", "forKeyedSubscript", nullptr);
- RemoveObjectForKeySel =
- getKeywordSelector(Ctx, "removeObjectForKey", nullptr);
+ getKeywordSelector(Ctx, "setObject", "forKeyedSubscript");
+ RemoveObjectForKeySel = getKeywordSelector(Ctx, "removeObjectForKey");
}
if (S == DictionaryWithObjectForKeySel || S == SetObjectForKeySel) {
diff --git a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
index 8c2aef21b3ca..48d6cd8a527c 100644
--- a/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/BuiltinFunctionChecker.cpp
@@ -41,6 +41,22 @@ bool BuiltinFunctionChecker::evalCall(const CallExpr *CE,
default:
return false;
+ case Builtin::BI__builtin_assume: {
+ assert (CE->arg_begin() != CE->arg_end());
+ SVal ArgSVal = state->getSVal(CE->getArg(0), LCtx);
+ if (ArgSVal.isUndef())
+ return true; // Return true to model purity.
+
+ state = state->assume(ArgSVal.castAs<DefinedOrUnknownSVal>(), true);
+ // FIXME: do we want to warn here? Not right now. The most reports might
+ // come from infeasible paths, thus being false positives.
+ if (!state)
+ return true;
+
+ C.addTransition(state);
+ return true;
+ }
+
case Builtin::BI__builtin_unpredictable:
case Builtin::BI__builtin_expect:
case Builtin::BI__builtin_assume_aligned:
diff --git a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
index c1deadef4202..8a5c769b6b50 100644
--- a/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/NoReturnFunctionChecker.cpp
@@ -123,14 +123,14 @@ void NoReturnFunctionChecker::checkPostObjCMessage(const ObjCMethodCall &Msg,
case 4:
lazyInitKeywordSelector(HandleFailureInFunctionSel, C.getASTContext(),
"handleFailureInFunction", "file", "lineNumber",
- "description", nullptr);
+ "description");
if (Sel != HandleFailureInFunctionSel)
return;
break;
case 5:
lazyInitKeywordSelector(HandleFailureInMethodSel, C.getASTContext(),
"handleFailureInMethod", "object", "file",
- "lineNumber", "description", nullptr);
+ "lineNumber", "description");
if (Sel != HandleFailureInMethodSel)
return;
break;
diff --git a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
index 3f6ae6222ce0..89b1291c4f46 100644
--- a/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/RetainCountChecker.cpp
@@ -703,31 +703,30 @@ private:
ObjCMethodSummaries[ObjCSummaryKey(ClsII, S)] = Summ;
}
+ template <typename... Keywords>
void addMethodSummary(IdentifierInfo *ClsII, ObjCMethodSummariesTy &Summaries,
- const RetainSummary *Summ, va_list argp) {
- Selector S = getKeywordSelector(Ctx, argp);
+ const RetainSummary *Summ, Keywords *... Kws) {
+ Selector S = getKeywordSelector(Ctx, Kws...);
Summaries[ObjCSummaryKey(ClsII, S)] = Summ;
}
- void addInstMethSummary(const char* Cls, const RetainSummary * Summ, ...) {
- va_list argp;
- va_start(argp, Summ);
- addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, argp);
- va_end(argp);
+ template <typename... Keywords>
+ void addInstMethSummary(const char *Cls, const RetainSummary *Summ,
+ Keywords *... Kws) {
+ addMethodSummary(&Ctx.Idents.get(Cls), ObjCMethodSummaries, Summ, Kws...);
}
- void addClsMethSummary(const char* Cls, const RetainSummary * Summ, ...) {
- va_list argp;
- va_start(argp, Summ);
- addMethodSummary(&Ctx.Idents.get(Cls),ObjCClassMethodSummaries, Summ, argp);
- va_end(argp);
+ template <typename... Keywords>
+ void addClsMethSummary(const char *Cls, const RetainSummary *Summ,
+ Keywords *... Kws) {
+ addMethodSummary(&Ctx.Idents.get(Cls), ObjCClassMethodSummaries, Summ,
+ Kws...);
}
- void addClsMethSummary(IdentifierInfo *II, const RetainSummary * Summ, ...) {
- va_list argp;
- va_start(argp, Summ);
- addMethodSummary(II, ObjCClassMethodSummaries, Summ, argp);
- va_end(argp);
+ template <typename... Keywords>
+ void addClsMethSummary(IdentifierInfo *II, const RetainSummary *Summ,
+ Keywords *... Kws) {
+ addMethodSummary(II, ObjCClassMethodSummaries, Summ, Kws...);
}
public:
@@ -1640,20 +1639,16 @@ void RetainSummaryManager::InitializeMethodSummaries() {
addClassMethSummary("NSAutoreleasePool", "new", NoTrackYet);
// Create summaries QCRenderer/QCView -createSnapShotImageOfType:
- addInstMethSummary("QCRenderer", AllocSumm,
- "createSnapshotImageOfType", nullptr);
- addInstMethSummary("QCView", AllocSumm,
- "createSnapshotImageOfType", nullptr);
+ addInstMethSummary("QCRenderer", AllocSumm, "createSnapshotImageOfType");
+ addInstMethSummary("QCView", AllocSumm, "createSnapshotImageOfType");
// Create summaries for CIContext, 'createCGImage' and
// 'createCGLayerWithSize'. These objects are CF objects, and are not
// automatically garbage collected.
- addInstMethSummary("CIContext", CFAllocSumm,
- "createCGImage", "fromRect", nullptr);
+ addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect");
addInstMethSummary("CIContext", CFAllocSumm, "createCGImage", "fromRect",
- "format", "colorSpace", nullptr);
- addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info",
- nullptr);
+ "format", "colorSpace");
+ addInstMethSummary("CIContext", CFAllocSumm, "createCGLayerWithSize", "info");
}
//===----------------------------------------------------------------------===//
diff --git a/lib/StaticAnalyzer/Checkers/SelectorExtras.h b/lib/StaticAnalyzer/Checkers/SelectorExtras.h
index 41f70d7d5b69..b11d070c629b 100644
--- a/lib/StaticAnalyzer/Checkers/SelectorExtras.h
+++ b/lib/StaticAnalyzer/Checkers/SelectorExtras.h
@@ -11,48 +11,26 @@
#define LLVM_CLANG_LIB_STATICANALYZER_CHECKERS_SELECTOREXTRAS_H
#include "clang/AST/ASTContext.h"
-#include <cstdarg>
namespace clang {
namespace ento {
-static inline Selector getKeywordSelectorImpl(ASTContext &Ctx,
- const char *First,
- va_list argp) {
- SmallVector<IdentifierInfo*, 10> II;
- II.push_back(&Ctx.Idents.get(First));
-
- while (const char *s = va_arg(argp, const char *))
- II.push_back(&Ctx.Idents.get(s));
+template <typename... IdentifierInfos>
+static inline Selector getKeywordSelector(ASTContext &Ctx,
+ IdentifierInfos *... IIs) {
+ static_assert(sizeof...(IdentifierInfos),
+ "keyword selectors must have at least one argument");
+ SmallVector<IdentifierInfo *, 10> II({&Ctx.Idents.get(IIs)...});
return Ctx.Selectors.getSelector(II.size(), &II[0]);
}
-static inline Selector getKeywordSelector(ASTContext &Ctx, va_list argp) {
- const char *First = va_arg(argp, const char *);
- assert(First && "keyword selectors must have at least one argument");
- return getKeywordSelectorImpl(Ctx, First, argp);
-}
-
-LLVM_END_WITH_NULL
-static inline Selector getKeywordSelector(ASTContext &Ctx,
- const char *First, ...) {
- va_list argp;
- va_start(argp, First);
- Selector result = getKeywordSelectorImpl(Ctx, First, argp);
- va_end(argp);
- return result;
-}
-
-LLVM_END_WITH_NULL
+template <typename... IdentifierInfos>
static inline void lazyInitKeywordSelector(Selector &Sel, ASTContext &Ctx,
- const char *First, ...) {
+ IdentifierInfos *... IIs) {
if (!Sel.isNull())
return;
- va_list argp;
- va_start(argp, First);
- Sel = getKeywordSelectorImpl(Ctx, First, argp);
- va_end(argp);
+ Sel = getKeywordSelector(Ctx, IIs...);
}
static inline void lazyInitNullarySelector(Selector &Sel, ASTContext &Ctx,
diff --git a/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp b/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
index 93ad17cffb34..2f9f5d2d9cf8 100644
--- a/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
+++ b/lib/StaticAnalyzer/Checkers/StdLibraryFunctionsChecker.cpp
@@ -440,7 +440,10 @@ StdLibraryFunctionsChecker::findFunctionSummary(const FunctionDecl *FD,
BasicValueFactory &BVF = SVB.getBasicValueFactory();
initFunctionSummaries(BVF);
- std::string Name = FD->getQualifiedNameAsString();
+ IdentifierInfo *II = FD->getIdentifier();
+ if (!II)
+ return None;
+ StringRef Name = II->getName();
if (Name.empty() || !C.isCLibraryFunction(FD, Name))
return None;
diff --git a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
index 39d88bfda148..caf86b26b66d 100644
--- a/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
+++ b/lib/StaticAnalyzer/Core/ExprEngineCallAndReturn.cpp
@@ -447,6 +447,7 @@ bool ExprEngine::inlineCall(const CallEvent &Call, const Decl *D,
Bldr.takeNodes(Pred);
NumInlinedCalls++;
+ Engine.FunctionSummaries->bumpNumTimesInlined(D);
// Mark the decl as visited.
if (VisitedCallees)
@@ -868,8 +869,6 @@ bool ExprEngine::shouldInlineCall(const CallEvent &Call, const Decl *D,
|| IsRecursive))
return false;
- Engine.FunctionSummaries->bumpNumTimesInlined(D);
-
return true;
}
diff --git a/lib/Tooling/RefactoringCallbacks.cpp b/lib/Tooling/RefactoringCallbacks.cpp
index e900c23e4f64..9fd333ca554e 100644
--- a/lib/Tooling/RefactoringCallbacks.cpp
+++ b/lib/Tooling/RefactoringCallbacks.cpp
@@ -9,8 +9,13 @@
//
//
//===----------------------------------------------------------------------===//
-#include "clang/Lex/Lexer.h"
#include "clang/Tooling/RefactoringCallbacks.h"
+#include "clang/ASTMatchers/ASTMatchFinder.h"
+#include "clang/Basic/SourceLocation.h"
+#include "clang/Lex/Lexer.h"
+
+using llvm::StringError;
+using llvm::make_error;
namespace clang {
namespace tooling {
@@ -20,18 +25,62 @@ tooling::Replacements &RefactoringCallback::getReplacements() {
return Replace;
}
-static Replacement replaceStmtWithText(SourceManager &Sources,
- const Stmt &From,
+ASTMatchRefactorer::ASTMatchRefactorer(
+ std::map<std::string, Replacements> &FileToReplaces)
+ : FileToReplaces(FileToReplaces) {}
+
+void ASTMatchRefactorer::addDynamicMatcher(
+ const ast_matchers::internal::DynTypedMatcher &Matcher,
+ RefactoringCallback *Callback) {
+ MatchFinder.addDynamicMatcher(Matcher, Callback);
+ Callbacks.push_back(Callback);
+}
+
+class RefactoringASTConsumer : public ASTConsumer {
+public:
+ explicit RefactoringASTConsumer(ASTMatchRefactorer &Refactoring)
+ : Refactoring(Refactoring) {}
+
+ void HandleTranslationUnit(ASTContext &Context) override {
+ // The ASTMatchRefactorer is re-used between translation units.
+ // Clear the matchers so that each Replacement is only emitted once.
+ for (const auto &Callback : Refactoring.Callbacks) {
+ Callback->getReplacements().clear();
+ }
+ Refactoring.MatchFinder.matchAST(Context);
+ for (const auto &Callback : Refactoring.Callbacks) {
+ for (const auto &Replacement : Callback->getReplacements()) {
+ llvm::Error Err =
+ Refactoring.FileToReplaces[Replacement.getFilePath()].add(
+ Replacement);
+ if (Err) {
+ llvm::errs() << "Skipping replacement " << Replacement.toString()
+ << " due to this error:\n"
+ << toString(std::move(Err)) << "\n";
+ }
+ }
+ }
+ }
+
+private:
+ ASTMatchRefactorer &Refactoring;
+};
+
+std::unique_ptr<ASTConsumer> ASTMatchRefactorer::newASTConsumer() {
+ return llvm::make_unique<RefactoringASTConsumer>(*this);
+}
+
+static Replacement replaceStmtWithText(SourceManager &Sources, const Stmt &From,
StringRef Text) {
- return tooling::Replacement(Sources, CharSourceRange::getTokenRange(
- From.getSourceRange()), Text);
+ return tooling::Replacement(
+ Sources, CharSourceRange::getTokenRange(From.getSourceRange()), Text);
}
-static Replacement replaceStmtWithStmt(SourceManager &Sources,
- const Stmt &From,
+static Replacement replaceStmtWithStmt(SourceManager &Sources, const Stmt &From,
const Stmt &To) {
- return replaceStmtWithText(Sources, From, Lexer::getSourceText(
- CharSourceRange::getTokenRange(To.getSourceRange()),
- Sources, LangOptions()));
+ return replaceStmtWithText(
+ Sources, From,
+ Lexer::getSourceText(CharSourceRange::getTokenRange(To.getSourceRange()),
+ Sources, LangOptions()));
}
ReplaceStmtWithText::ReplaceStmtWithText(StringRef FromId, StringRef ToText)
@@ -103,5 +152,90 @@ void ReplaceIfStmtWithItsBody::run(
}
}
+ReplaceNodeWithTemplate::ReplaceNodeWithTemplate(
+ llvm::StringRef FromId, std::vector<TemplateElement> Template)
+ : FromId(FromId), Template(std::move(Template)) {}
+
+llvm::Expected<std::unique_ptr<ReplaceNodeWithTemplate>>
+ReplaceNodeWithTemplate::create(StringRef FromId, StringRef ToTemplate) {
+ std::vector<TemplateElement> ParsedTemplate;
+ for (size_t Index = 0; Index < ToTemplate.size();) {
+ if (ToTemplate[Index] == '$') {
+ if (ToTemplate.substr(Index, 2) == "$$") {
+ Index += 2;
+ ParsedTemplate.push_back(
+ TemplateElement{TemplateElement::Literal, "$"});
+ } else if (ToTemplate.substr(Index, 2) == "${") {
+ size_t EndOfIdentifier = ToTemplate.find("}", Index);
+ if (EndOfIdentifier == std::string::npos) {
+ return make_error<StringError>(
+ "Unterminated ${...} in replacement template near " +
+ ToTemplate.substr(Index),
+ llvm::inconvertibleErrorCode());
+ }
+ std::string SourceNodeName =
+ ToTemplate.substr(Index + 2, EndOfIdentifier - Index - 2);
+ ParsedTemplate.push_back(
+ TemplateElement{TemplateElement::Identifier, SourceNodeName});
+ Index = EndOfIdentifier + 1;
+ } else {
+ return make_error<StringError>(
+ "Invalid $ in replacement template near " +
+ ToTemplate.substr(Index),
+ llvm::inconvertibleErrorCode());
+ }
+ } else {
+ size_t NextIndex = ToTemplate.find('$', Index + 1);
+ ParsedTemplate.push_back(
+ TemplateElement{TemplateElement::Literal,
+ ToTemplate.substr(Index, NextIndex - Index)});
+ Index = NextIndex;
+ }
+ }
+ return std::unique_ptr<ReplaceNodeWithTemplate>(
+ new ReplaceNodeWithTemplate(FromId, std::move(ParsedTemplate)));
+}
+
+void ReplaceNodeWithTemplate::run(
+ const ast_matchers::MatchFinder::MatchResult &Result) {
+ const auto &NodeMap = Result.Nodes.getMap();
+
+ std::string ToText;
+ for (const auto &Element : Template) {
+ switch (Element.Type) {
+ case TemplateElement::Literal:
+ ToText += Element.Value;
+ break;
+ case TemplateElement::Identifier: {
+ auto NodeIter = NodeMap.find(Element.Value);
+ if (NodeIter == NodeMap.end()) {
+ llvm::errs() << "Node " << Element.Value
+ << " used in replacement template not bound in Matcher \n";
+ llvm::report_fatal_error("Unbound node in replacement template.");
+ }
+ CharSourceRange Source =
+ CharSourceRange::getTokenRange(NodeIter->second.getSourceRange());
+ ToText += Lexer::getSourceText(Source, *Result.SourceManager,
+ Result.Context->getLangOpts());
+ break;
+ }
+ }
+ }
+ if (NodeMap.count(FromId) == 0) {
+ llvm::errs() << "Node to be replaced " << FromId
+ << " not bound in query.\n";
+ llvm::report_fatal_error("FromId node not bound in MatchResult");
+ }
+ auto Replacement =
+ tooling::Replacement(*Result.SourceManager, &NodeMap.at(FromId), ToText,
+ Result.Context->getLangOpts());
+ llvm::Error Err = Replace.add(Replacement);
+ if (Err) {
+ llvm::errs() << "Query and replace failed in " << Replacement.getFilePath()
+ << "! " << llvm::toString(std::move(Err)) << "\n";
+ llvm::report_fatal_error("Replacement failed");
+ }
+}
+
} // end namespace tooling
} // end namespace clang
diff --git a/test/Analysis/builtin-assume.c b/test/Analysis/builtin-assume.c
new file mode 100644
index 000000000000..00d651d9e3be
--- /dev/null
+++ b/test/Analysis/builtin-assume.c
@@ -0,0 +1,8 @@
+// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s
+
+void clang_analyzer_eval(int);
+
+void f(int i) {
+ __builtin_assume(i < 10);
+ clang_analyzer_eval(i < 15); // expected-warning {{TRUE}}
+}
diff --git a/test/CXX/drs/dr20xx.cpp b/test/CXX/drs/dr20xx.cpp
new file mode 100644
index 000000000000..b97a9a46bc85
--- /dev/null
+++ b/test/CXX/drs/dr20xx.cpp
@@ -0,0 +1,30 @@
+// RUN: %clang_cc1 -std=c++98 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors \
+// RUN: -Wno-variadic-macros -Wno-c11-extensions
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++14 -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+// RUN: %clang_cc1 -std=c++1z -triple x86_64-unknown-unknown %s -verify -fexceptions -fcxx-exceptions -pedantic-errors
+
+// expected-no-diagnostics
+
+#if __cplusplus < 201103L
+#define static_assert(...) _Static_assert(__VA_ARGS__)
+#endif
+
+namespace dr2094 { // dr2094: 5.0
+ struct A { int n; };
+ struct B { volatile int n; };
+ static_assert(__is_trivially_copyable(volatile int), "");
+ static_assert(__is_trivially_copyable(const volatile int), "");
+ static_assert(__is_trivially_copyable(const volatile int[]), "");
+ static_assert(__is_trivially_copyable(A), "");
+ static_assert(__is_trivially_copyable(volatile A), "");
+ static_assert(__is_trivially_copyable(const volatile A), "");
+ static_assert(__is_trivially_copyable(const volatile A[]), "");
+ static_assert(__is_trivially_copyable(B), "");
+
+ static_assert(__is_trivially_constructible(A, A const&), "");
+ static_assert(__is_trivially_constructible(B, B const&), "");
+
+ static_assert(__is_trivially_assignable(A, const A&), "");
+ static_assert(__is_trivially_assignable(B, const B&), "");
+}
diff --git a/test/CXX/drs/dr4xx.cpp b/test/CXX/drs/dr4xx.cpp
index 3ea226a745f6..a55bb91be558 100644
--- a/test/CXX/drs/dr4xx.cpp
+++ b/test/CXX/drs/dr4xx.cpp
@@ -1202,16 +1202,15 @@ namespace dr495 { // dr495: 3.5
long n2 = s2;
}
-namespace dr496 { // dr496: no
+namespace dr496 { // dr496: sup dr2094
struct A { int n; };
struct B { volatile int n; };
int check1[ __is_trivially_copyable(const int) ? 1 : -1];
- int check2[!__is_trivially_copyable(volatile int) ? 1 : -1];
+ // This checks the dr2094 behavior, not dr496
+ int check2[ __is_trivially_copyable(volatile int) ? 1 : -1];
int check3[ __is_trivially_constructible(A, const A&) ? 1 : -1];
- // FIXME: This is wrong.
int check4[ __is_trivially_constructible(B, const B&) ? 1 : -1];
int check5[ __is_trivially_assignable(A, const A&) ? 1 : -1];
- // FIXME: This is wrong.
int check6[ __is_trivially_assignable(B, const B&) ? 1 : -1];
}
diff --git a/test/CodeCompletion/member-access.cpp b/test/CodeCompletion/member-access.cpp
index 66872272ee6d..53af121951bb 100644
--- a/test/CodeCompletion/member-access.cpp
+++ b/test/CodeCompletion/member-access.cpp
@@ -66,3 +66,83 @@ struct Bar {
// Make sure this also doesn't crash
// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:47:14 %s
+
+
+template<typename T>
+class BaseTemplate {
+public:
+ T baseTemplateFunction();
+
+ T baseTemplateField;
+};
+
+template<typename T, typename S>
+class TemplateClass: public Base1 , public BaseTemplate<T> {
+public:
+ T function() { }
+ T field;
+
+ void overload1(const T &);
+ void overload1(const S &);
+};
+
+template<typename T, typename S>
+void completeDependentMembers(TemplateClass<T, S> &object,
+ TemplateClass<int, S> *object2) {
+ object.field;
+ object2->field;
+// CHECK-CC2: baseTemplateField : [#T#][#BaseTemplate<T>::#]baseTemplateField
+// CHECK-CC2: baseTemplateFunction : [#T#][#BaseTemplate<T>::#]baseTemplateFunction()
+// CHECK-CC2: field : [#T#]field
+// CHECK-CC2: function : [#T#]function()
+// CHECK-CC2: member1 : [#int#][#Base1::#]member1
+// CHECK-CC2: member2 : [#float#][#Base1::#]member2
+// CHECK-CC2: overload1 : [#void#]overload1(<#const T &#>)
+// CHECK-CC2: overload1 : [#void#]overload1(<#const S &#>)
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:92:10 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:93:12 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s
+}
+
+
+void completeDependentSpecializedMembers(TemplateClass<int, double> &object,
+ TemplateClass<int, double> *object2) {
+ object.field;
+ object2->field;
+// CHECK-CC3: baseTemplateField : [#int#][#BaseTemplate<int>::#]baseTemplateField
+// CHECK-CC3: baseTemplateFunction : [#int#][#BaseTemplate<int>::#]baseTemplateFunction()
+// CHECK-CC3: field : [#int#]field
+// CHECK-CC3: function : [#int#]function()
+// CHECK-CC3: member1 : [#int#][#Base1::#]member1
+// CHECK-CC3: member2 : [#float#][#Base1::#]member2
+// CHECK-CC3: overload1 : [#void#]overload1(<#const int &#>)
+// CHECK-CC3: overload1 : [#void#]overload1(<#const double &#>)
+
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:110:10 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:111:12 %s -o - | FileCheck -check-prefix=CHECK-CC3 %s
+}
+
+template <typename T>
+class Template {
+public:
+ BaseTemplate<int> o1;
+ BaseTemplate<T> o2;
+
+ void function() {
+ o1.baseTemplateField;
+// CHECK-CC4: BaseTemplate : BaseTemplate::
+// CHECK-CC4: baseTemplateField : [#int#]baseTemplateField
+// CHECK-CC4: baseTemplateFunction : [#int#]baseTemplateFunction()
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:132:8 %s -o - | FileCheck -check-prefix=CHECK-CC4 %s
+ o2.baseTemplateField;
+// CHECK-CC5: BaseTemplate : BaseTemplate::
+// CHECK-CC5: baseTemplateField : [#T#]baseTemplateField
+// CHECK-CC5: baseTemplateFunction : [#T#]baseTemplateFunction()
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:137:8 %s -o - | FileCheck -check-prefix=CHECK-CC5 %s
+ this->o1;
+// CHECK-CC6: [#void#]function()
+// CHECK-CC6: o1 : [#BaseTemplate<int>#]o1
+// CHECK-CC6: o2 : [#BaseTemplate<T>#]o2
+// RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:142:11 %s -o - | FileCheck -check-prefix=CHECK-CC6 %s
+ }
+};
diff --git a/test/CodeGen/asan-globals-gc.cpp b/test/CodeGen/asan-globals-gc.cpp
index 6d64f41dda8d..58ce5f067563 100644
--- a/test/CodeGen/asan-globals-gc.cpp
+++ b/test/CodeGen/asan-globals-gc.cpp
@@ -1,5 +1,16 @@
-// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITH-GC
-// RUN: %clang_cc1 -fsanitize=address -emit-llvm -o - -triple x86_64-windows-msvc -fdata-sections %s | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fno-integrated-as -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fno-integrated-as -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fno-data-sections -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fdata-sections -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-windows-msvc %s | FileCheck %s --check-prefix=WITHOUT-GC
+
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fno-data-sections -emit-llvm -o - -triple x86_64-apple-macosx11 %s | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fdata-sections -emit-llvm -o - -triple x86_64-apple-macosx11 %s | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-apple-macosx11 %s | FileCheck %s --check-prefix=WITHOUT-GC
int global;
diff --git a/test/CodeGen/asan-no-globals-no-comdat.cpp b/test/CodeGen/asan-no-globals-no-comdat.cpp
new file mode 100644
index 000000000000..4637346f9c41
--- /dev/null
+++ b/test/CodeGen/asan-no-globals-no-comdat.cpp
@@ -0,0 +1,11 @@
+// Test that on Linux asan constructor is placed in a comdat iff globals-gc is on.
+// Even if there are no globals in the module.
+
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITH-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fno-integrated-as -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -fsanitize-address-globals-dead-stripping -fno-integrated-as -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+// RUN: %clang_cc1 -fsanitize=address -fdata-sections -emit-llvm -o - -triple x86_64-linux %s | FileCheck %s --check-prefix=WITHOUT-GC
+
+// WITH-GC: define internal void @asan.module_ctor() comdat {
+// WITHOUT-GC: define internal void @asan.module_ctor() {
diff --git a/test/CodeGen/mips-aggregate-arg.c b/test/CodeGen/mips-aggregate-arg.c
new file mode 100644
index 000000000000..ccf30df7c22a
--- /dev/null
+++ b/test/CodeGen/mips-aggregate-arg.c
@@ -0,0 +1,38 @@
+// RUN: %clang_cc1 -triple mipsel-unknown-linux-gnu -S -emit-llvm -o - %s | FileCheck -check-prefix=O32 %s
+// RUN: %clang_cc1 -triple mips64el-unknown-linux-gnu -S -emit-llvm -o - %s -target-abi n32 | FileCheck -check-prefix=N32-N64 %s
+// RUN: %clang_cc1 -triple mips64el-unknown-linux-gnu -S -emit-llvm -o - %s -target-abi n64 | FileCheck -check-prefix=N32-N64 %s
+
+struct t1 {
+ char t1[10];
+};
+
+struct t2 {
+ char t2[20];
+};
+
+struct t3 {
+ char t3[65];
+};
+
+extern struct t1 g1;
+extern struct t2 g2;
+extern struct t3 g3;
+extern void f1(struct t1);
+extern void f2(struct t2);
+extern void f3(struct t3);
+
+void f() {
+
+// O32: call void @f1(i32 inreg %{{[0-9]+}}, i32 inreg %{{[0-9]+}}, i16 inreg %{{[0-9]+}})
+// O32: call void @f2(%struct.t2* byval align 4 %{{.*}})
+// O32: call void @f3(%struct.t3* byval align 4 %{{.*}})
+
+// N32-N64: call void @f1(i64 inreg %{{[0-9]+}}, i16 inreg %{{[0-9]+}})
+// N32-N64: call void @f2(i64 inreg %{{[0-9]+}}, i64 inreg %{{[0-9]+}}, i32 inreg %{{[0-9]+}})
+// N32-N64: call void @f3(%struct.t3* byval align 8 %{{.*}})
+
+ f1(g1);
+ f2(g2);
+ f3(g3);
+}
+
diff --git a/test/CodeGen/sanitize-recover.c b/test/CodeGen/sanitize-recover.c
index d714d58c7f26..6358d9d04aa1 100644
--- a/test/CodeGen/sanitize-recover.c
+++ b/test/CodeGen/sanitize-recover.c
@@ -7,12 +7,12 @@
void test() {
extern volatile unsigned x, y, z;
- // RECOVER: uadd.with.overflow.i32
- // RECOVER: ubsan_handle_add_overflow(
+ // RECOVER: uadd.with.overflow.i32{{.*}}, !nosanitize
+ // RECOVER: ubsan_handle_add_overflow({{.*}}, !nosanitize
// RECOVER-NOT: unreachable
- // ABORT: uadd.with.overflow.i32
- // ABORT: ubsan_handle_add_overflow_abort(
- // ABORT: unreachable
+ // ABORT: uadd.with.overflow.i32{{.*}}, !nosanitize
+ // ABORT: ubsan_handle_add_overflow_abort({{.*}}, !nosanitize
+ // ABORT: unreachable{{.*}}, !nosanitize
x = y + z;
}
diff --git a/test/CodeGen/sparcv8-inline-asm.c b/test/CodeGen/sparcv8-inline-asm.c
new file mode 100644
index 000000000000..711a2a0afbb0
--- /dev/null
+++ b/test/CodeGen/sparcv8-inline-asm.c
@@ -0,0 +1,11 @@
+// RUN: %clang_cc1 -triple sparc-unknown-unknown -emit-llvm %s -o - | FileCheck %s
+
+// CHECK: define float @fabsf(float %a)
+// CHECK: %{{.*}} = call float asm sideeffect "fabss $1, $0;", "=e,f"(float %{{.*}}) #1
+float fabsf(float a) {
+ float res;
+ __asm __volatile__("fabss %1, %0;"
+ : /* reg out*/ "=e"(res)
+ : /* reg in */ "f"(a));
+ return res;
+}
diff --git a/test/CodeGen/thinlto_backend.ll b/test/CodeGen/thinlto_backend.ll
index 813bb62c1a29..86f30c0374fc 100644
--- a/test/CodeGen/thinlto_backend.ll
+++ b/test/CodeGen/thinlto_backend.ll
@@ -12,10 +12,10 @@
; RUN: %clang -O2 -o %t4.o -x ir %t1.o -c -fthinlto-index=bad.thinlto.bc 2>&1 | FileCheck %s -check-prefix=CHECK-ERROR1
; CHECK-ERROR1: Error loading index file 'bad.thinlto.bc'
-; Ensure we ignore empty index file under -ignore-empty-index-file, and run
-; non-ThinLTO compilation which would not import f2
+; Ensure we ignore empty index file, and run non-ThinLTO compilation which
+; would not import f2
; RUN: touch %t4.thinlto.bc
-; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t4.o -x ir %t1.o -c -fthinlto-index=%t4.thinlto.bc -mllvm -ignore-empty-index-file
+; RUN: %clang -target x86_64-unknown-linux-gnu -O2 -o %t4.o -x ir %t1.o -c -fthinlto-index=%t4.thinlto.bc
; RUN: llvm-nm %t4.o | FileCheck --check-prefix=CHECK-OBJ-IGNORE-EMPTY %s
; CHECK-OBJ-IGNORE-EMPTY: T f1
; CHECK-OBJ-IGNORE-EMPTY: U f2
diff --git a/test/CodeGen/x86_64-mno-sse.c b/test/CodeGen/x86_64-mno-sse.c
new file mode 100644
index 000000000000..43a695ae3cd3
--- /dev/null
+++ b/test/CodeGen/x86_64-mno-sse.c
@@ -0,0 +1,15 @@
+// RUN: %clang_cc1 -triple x86_64-linux -target-feature -sse -target-feature -sse2 -S -o /dev/null -verify %s
+// REQUIRES: x86-registered-target
+
+double f1(void) { // expected-error {{SSE register return with SSE disabled}}
+ return 1.4;
+}
+extern double g;
+void f2(void) { // expected-error {{SSE register return with SSE disabled}}
+ g = f1();
+}
+void take_double(double);
+void pass_double(void) {
+ // FIXME: Still asserts.
+ //take_double(1.5);
+}
diff --git a/test/CodeGen/xray-customevent.cpp b/test/CodeGen/xray-customevent.cpp
new file mode 100644
index 000000000000..359d92df938a
--- /dev/null
+++ b/test/CodeGen/xray-customevent.cpp
@@ -0,0 +1,28 @@
+// RUN: %clang_cc1 -fxray-instrument -x c++ -std=c++11 -triple x86_64-unknown-unknown -emit-llvm -o - %s | FileCheck %s
+
+// CHECK-LABEL: @_Z16alwaysInstrumentv
+[[clang::xray_always_instrument]] void alwaysInstrument() {
+ static constexpr char kPhase[] = "instrument";
+ __xray_customevent(kPhase, 10);
+ // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i32 10)
+}
+
+// CHECK-LABEL: @_Z15neverInstrumentv
+[[clang::xray_never_instrument]] void neverInstrument() {
+ static constexpr char kPhase[] = "never";
+ __xray_customevent(kPhase, 5);
+ // CHECK-NOT: call void @llvm.xray.customevent(i8*{{.*}}, i32 5)
+}
+
+// CHECK-LABEL: @_Z21conditionalInstrumenti
+[[clang::xray_always_instrument]] void conditionalInstrument(int v) {
+ static constexpr char kTrue[] = "true";
+ static constexpr char kUntrue[] = "untrue";
+ if (v % 2)
+ __xray_customevent(kTrue, 4);
+ else
+ __xray_customevent(kUntrue, 6);
+
+ // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i32 4)
+ // CHECK: call void @llvm.xray.customevent(i8*{{.*}}, i32 6)
+}
diff --git a/test/CodeGenCXX/array-default-argument.cpp b/test/CodeGenCXX/array-default-argument.cpp
new file mode 100644
index 000000000000..a07e3908392a
--- /dev/null
+++ b/test/CodeGenCXX/array-default-argument.cpp
@@ -0,0 +1,36 @@
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple %itanium_abi_triple | FileCheck %s
+// RUN: %clang_cc1 -emit-llvm -o - %s -triple %itanium_abi_triple -std=c++98 -fexceptions -fcxx-exceptions | FileCheck %s --check-prefix=CHECK --check-prefix=CHECK-EH
+
+struct A {
+ A();
+ ~A();
+};
+
+struct B {
+ B(A = A());
+ ~B();
+};
+
+void f();
+// CHECK-LABEL: define void @_Z1gv()
+void g() {
+ // CHECK: br label %[[LOOP:.*]]
+
+ // [[LOOP]]:
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1AC1Ev([[TEMPORARY:.*]])
+ // CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD:.*]]
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1BC1E1A({{.*}}, [[TEMPORARY]])
+ // CHECK-EH: unwind label %[[A_AND_PARTIAL_ARRAY_LPAD:.*]]
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1AD1Ev([[TEMPORARY]])
+ // CHECK-EH: unwind label %[[PARTIAL_ARRAY_LPAD]]
+ // CHECK: getelementptr {{.*}}, i{{[0-9]*}} 1
+ // CHECK: icmp eq
+ // CHECK: br i1 {{.*}} label %[[LOOP]]
+ B b[5];
+
+ // CHECK: {{call|invoke}} void @_Z1fv()
+ f();
+
+ // CHECK-NOT: @_ZN1AD1Ev(
+ // CHECK: {{call|invoke}} {{.*}} @_ZN1BD1Ev(
+}
diff --git a/test/CodeGenCXX/linetable-virtual-variadic.cpp b/test/CodeGenCXX/linetable-virtual-variadic.cpp
index 6f966416867a..cd746cdfdfe2 100644
--- a/test/CodeGenCXX/linetable-virtual-variadic.cpp
+++ b/test/CodeGenCXX/linetable-virtual-variadic.cpp
@@ -12,8 +12,10 @@ void Derived::VariadicFunction(...) { }
// CHECK: define void @_ZN7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP:[0-9]+]]
// CHECK: ret void, !dbg ![[LOC:[0-9]+]]
-// CHECK-LABEL: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz(
-// CHECK: ret void, !dbg ![[LOC:[0-9]+]]
+// CHECK: define void @_ZT{{.+}}N7Derived16VariadicFunctionEz({{.*}} !dbg ![[SP_I:[0-9]+]]
+// CHECK: ret void, !dbg ![[LOC_I:[0-9]+]]
//
// CHECK: ![[SP]] = distinct !DISubprogram(name: "VariadicFunction"
// CHECK: ![[LOC]] = !DILocation({{.*}}scope: ![[SP]])
+// CHECK: ![[SP_I]] = distinct !DISubprogram(name: "VariadicFunction"
+// CHECK: ![[LOC_I]] = !DILocation({{.*}}scope: ![[SP_I]])
diff --git a/test/CodeGenCXX/vla.cpp b/test/CodeGenCXX/vla.cpp
index 4e22bba7d719..957a9f9568b3 100644
--- a/test/CodeGenCXX/vla.cpp
+++ b/test/CodeGenCXX/vla.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s
+// RUN: %clang_cc1 -std=c++11 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s
template<typename T>
struct S {
@@ -54,3 +54,60 @@ void test0(void *array, int n) {
// CHECK-NEXT: ret void
}
+
+
+void test2(int b) {
+ // CHECK-LABEL: define void {{.*}}test2{{.*}}(i32 %b)
+ int varr[b];
+ // get the address of %b by checking the first store that stores it
+ //CHECK: store i32 %b, i32* [[PTR_B:%.*]]
+
+ // get the size of the VLA by getting the first load of the PTR_B
+ //CHECK: [[VLA_NUM_ELEMENTS_PREZEXT:%.*]] = load i32, i32* [[PTR_B]]
+ //CHECK-NEXT: [[VLA_NUM_ELEMENTS_PRE:%.*]] = zext i32 [[VLA_NUM_ELEMENTS_PREZEXT]]
+
+ b = 15;
+ //CHECK: store i32 15, i32* [[PTR_B]]
+
+ // Now get the sizeof, and then divide by the element size
+
+
+ //CHECK: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_NUM_ELEMENTS_PRE]]
+ //CHECK-NEXT: [[VLA_NUM_ELEMENTS_POST:%.*]] = udiv i64 [[VLA_SIZEOF]], 4
+ //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_NUM_ELEMENTS_POST]]
+ //CHECK-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+ for (int d : varr) 0;
+}
+
+void test3(int b, int c) {
+ // CHECK-LABEL: define void {{.*}}test3{{.*}}(i32 %b, i32 %c)
+ int varr[b][c];
+ // get the address of %b by checking the first store that stores it
+ //CHECK: store i32 %b, i32* [[PTR_B:%.*]]
+ //CHECK-NEXT: store i32 %c, i32* [[PTR_C:%.*]]
+
+ // get the size of the VLA by getting the first load of the PTR_B
+ //CHECK: [[VLA_DIM1_PREZEXT:%.*]] = load i32, i32* [[PTR_B]]
+ //CHECK-NEXT: [[VLA_DIM1_PRE:%.*]] = zext i32 [[VLA_DIM1_PREZEXT]]
+ //CHECK: [[VLA_DIM2_PREZEXT:%.*]] = load i32, i32* [[PTR_C]]
+ //CHECK-NEXT: [[VLA_DIM2_PRE:%.*]] = zext i32 [[VLA_DIM2_PREZEXT]]
+
+ b = 15;
+ c = 15;
+ //CHECK: store i32 15, i32* [[PTR_B]]
+ //CHECK: store i32 15, i32* [[PTR_C]]
+ // Now get the sizeof, and then divide by the element size
+
+ // multiply the two dimensions, then by the element type and then divide by the sizeof dim2
+ //CHECK: [[VLA_DIM1_X_DIM2:%.*]] = mul nuw i64 [[VLA_DIM1_PRE]], [[VLA_DIM2_PRE]]
+ //CHECK-NEXT: [[VLA_SIZEOF:%.*]] = mul nuw i64 4, [[VLA_DIM1_X_DIM2]]
+ //CHECK-NEXT: [[VLA_SIZEOF_DIM2:%.*]] = mul nuw i64 4, [[VLA_DIM2_PRE]]
+ //CHECK-NEXT: [[VLA_NUM_ELEMENTS:%.*]] = udiv i64 [[VLA_SIZEOF]], [[VLA_SIZEOF_DIM2]]
+ //CHECK-NEXT: [[VLA_END_INDEX:%.*]] = mul nsw i64 [[VLA_NUM_ELEMENTS]], [[VLA_DIM2_PRE]]
+ //CHECK-NEXT: [[VLA_END_PTR:%.*]] = getelementptr inbounds i32, i32* {{%.*}}, i64 [[VLA_END_INDEX]]
+ //CHECK-NEXT: store i32* [[VLA_END_PTR]], i32** %__end
+
+ for (auto &d : varr) 0;
+}
+
+
diff --git a/test/CodeGenObjC/arc-blocks.m b/test/CodeGenObjC/arc-blocks.m
index 69cd7bb297b2..b84d141037e0 100644
--- a/test/CodeGenObjC/arc-blocks.m
+++ b/test/CodeGenObjC/arc-blocks.m
@@ -752,6 +752,16 @@ void test19(void (^b)(void)) {
// CHECK-NEXT: call void @objc_release(i8* [[X]])
// CHECK-NEXT: ret void
+// CHECK-UNOPT-LABEL: define void @test20(
+// CHECK-UNOPT: [[XADDR:%.*]] = alloca i8*
+// CHECK-UNOPT-NEXT: [[BLOCK:%.*]] = alloca <[[BLOCKTY:.*]]>
+// CHECK-UNOPT: [[CAPTUREFIELD:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5
+// CHECK-UNOPT: [[BLOCKCAPTURED:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCK]], i32 0, i32 5
+// CHECK-UNOPT: [[CAPTURED:%.*]] = load i8*, i8** [[XADDR]]
+// CHECK-UNOPT: [[RETAINED:%.*]] = call i8* @objc_retain(i8* [[CAPTURED]])
+// CHECK-UNOPT: store i8* [[RETAINED]], i8** [[BLOCKCAPTURED]]
+// CHECK-UNOPT: call void @objc_storeStrong(i8** [[CAPTUREFIELD]], i8* null)
+
// CHECK-LABEL: define internal void @__copy_helper_block
// CHECK: [[BLOCKSOURCE:%.*]] = bitcast i8* %{{.*}} to <[[BLOCKTY]]>*
// CHECK: [[CAPTUREFIELD:%.*]] = getelementptr inbounds <[[BLOCKTY]]>, <[[BLOCKTY]]>* [[BLOCKSOURCE]], i32 0, i32 5
diff --git a/test/CodeGenObjC/arc-foreach.m b/test/CodeGenObjC/arc-foreach.m
index e3b3f1aa5ce4..77cb068187fa 100644
--- a/test/CodeGenObjC/arc-foreach.m
+++ b/test/CodeGenObjC/arc-foreach.m
@@ -68,7 +68,8 @@ void test0(NSArray *array) {
// CHECK-LP64: [[D0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-LP64: [[T0:%.*]] = getelementptr inbounds [[BLOCK_T]], [[BLOCK_T]]* [[BLOCK]], i32 0, i32 5
// CHECK-LP64-NEXT: [[T1:%.*]] = load i8*, i8** [[X]]
-// CHECK-LP64-NEXT: store i8* [[T1]], i8** [[T0]]
+// CHECK-LP64-NEXT: [[T2:%.*]] = call i8* @objc_retain(i8* [[T1]])
+// CHECK-LP64-NEXT: store i8* [[T2]], i8** [[T0]]
// CHECK-LP64-NEXT: [[BLOCK1:%.*]] = bitcast [[BLOCK_T]]* [[BLOCK]]
// CHECK-LP64-NEXT: call void @use_block(void ()* [[BLOCK1]])
// CHECK-LP64-NEXT: call void @objc_storeStrong(i8** [[D0]], i8* null)
@@ -209,7 +210,8 @@ NSArray *array4;
// CHECK-LP64: [[T0:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>* [[BLOCK]], i32 0, i32 5
// CHECK-LP64: [[BC:%.*]] = getelementptr inbounds <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>, <{ i8*, i32, i32, i8*, %struct.__block_descriptor*, [[TY]]* }>* [[BLOCK]], i32 0, i32 5
// CHECK-LP64: [[T1:%.*]] = load [[TY]]*, [[TY]]** [[SELF_ADDR]]
-// CHECK-LP64: store [[TY]]* [[T1]], [[TY]]** [[BC]], align 8
+// CHECK-LP64: [[T2:%.*]] = bitcast [[TY]]* [[T1]] to i8*
+// CHECK-LP64: call i8* @objc_retain(i8* [[T2]])
// CHECK-LP64-OPT-LABEL: define internal void @"\01-[I1 foo2]"(
// CHECK-LP64-OPT: [[TY:%.*]]* %self
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
index c0b30095a679..7baee5eee391 100644
--- a/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-pointer-address-space.cl
@@ -58,16 +58,16 @@ kernel void kernel1(
// CHECK-DAG: !DILocalVariable(name: "FuncVar4", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
int *FuncVar4 = Tmp1;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
- global int *constant FuncVar5 = KernelArg0;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
- constant int *constant FuncVar6 = KernelArg1;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]])
- local int *constant FuncVar7 = KernelArg2;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]])
- private int *constant FuncVar8 = Tmp0;
- // CHECK-DAG: !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]])
- int *constant FuncVar9 = Tmp1;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+ global int *constant FuncVar5 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+ constant int *constant FuncVar6 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_LOCAL]], isLocal: true, isDefinition: true)
+ local int *constant FuncVar7 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_PRIVATE]], isLocal: true, isDefinition: true)
+ private int *constant FuncVar8 = 0;
+ // CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
+ int *constant FuncVar9 = 0;
// CHECK-DAG: distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: ![[DWARF_ADDRESS_SPACE_NONE]], isLocal: true, isDefinition: true)
global int *local FuncVar10; FuncVar10 = KernelArg0;
diff --git a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
index a962d3c75aaf..c0a4c21ce760 100644
--- a/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
+++ b/test/CodeGenOpenCL/amdgpu-debug-info-variable-expression.cl
@@ -80,21 +80,21 @@ kernel void kernel1(
// CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR4]], metadata ![[PRIVATE]]), !dbg !{{[0-9]+}}
int *FuncVar4 = Tmp1;
- // CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = !DILocalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(1)** {{.*}}, metadata ![[FUNCVAR5]], metadata ![[NONE:[0-9]+]]), !dbg !{{[0-9]+}}
- global int *constant FuncVar5 = KernelArg0;
- // CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = !DILocalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(2)** {{.*}}, metadata ![[FUNCVAR6]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- constant int *constant FuncVar6 = KernelArg1;
- // CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = !DILocalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(3)** {{.*}}, metadata ![[FUNCVAR7]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- local int *constant FuncVar7 = KernelArg2;
- // CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = !DILocalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32** {{.*}}, metadata ![[FUNCVAR8]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- private int *constant FuncVar8 = Tmp0;
- // CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = !DILocalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}})
- // CHECK-DAG: call void @llvm.dbg.declare(metadata i32 addrspace(4)** {{.*}}, metadata ![[FUNCVAR9]], metadata ![[NONE]]), !dbg !{{[0-9]+}}
- int *constant FuncVar9 = Tmp1;
+ // CHECK-DAG: ![[FUNCVAR5:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar5", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR5]])
+ global int *constant FuncVar5 = 0;
+ // CHECK-DAG: ![[FUNCVAR6:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar6", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR6]])
+ constant int *constant FuncVar6 = 0;
+ // CHECK-DAG: ![[FUNCVAR7:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar7", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR7]])
+ local int *constant FuncVar7 = 0;
+ // CHECK-DAG: ![[FUNCVAR8:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar8", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR8]])
+ private int *constant FuncVar8 = 0;
+ // CHECK-DAG: ![[FUNCVAR9:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar9", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
+ // CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR9]])
+ int *constant FuncVar9 = 0;
// CHECK-DAG: ![[FUNCVAR10:[0-9]+]] = distinct !DIGlobalVariable(name: "FuncVar10", scope: !{{[0-9]+}}, file: !{{[0-9]+}}, line: {{[0-9]+}}, type: !{{[0-9]+}}, isLocal: true, isDefinition: true)
// CHECK-DAG: !DIGlobalVariableExpression(var: ![[FUNCVAR10]], expr: ![[LOCAL]])
diff --git a/test/CodeGenOpenCL/constant-addr-space-globals.cl b/test/CodeGenOpenCL/constant-addr-space-globals.cl
index 4f0d1ea23e56..7bb970527c26 100644
--- a/test/CodeGenOpenCL/constant-addr-space-globals.cl
+++ b/test/CodeGenOpenCL/constant-addr-space-globals.cl
@@ -11,10 +11,11 @@ kernel void test(global float *out) {
// but create a copy in the original address space (unless a variable itself is
// in the constant address space).
-void foo(constant const int *p1, const int *p2, const int *p3);
+void foo(constant int* p, constant const int *p1, const int *p2, const int *p3);
// CHECK: @k.arr1 = internal addrspace(2) constant [3 x i32] [i32 1, i32 2, i32 3]
// CHECK: @k.arr2 = private unnamed_addr addrspace(2) constant [3 x i32] [i32 4, i32 5, i32 6]
// CHECK: @k.arr3 = private unnamed_addr addrspace(2) constant [3 x i32] [i32 7, i32 8, i32 9]
+// CHECK: @k.var1 = internal addrspace(2) constant i32 1
kernel void k(void) {
// CHECK-NOT: %arr1 = alloca [3 x i32]
constant const int arr1[] = {1, 2, 3};
@@ -23,5 +24,8 @@ kernel void k(void) {
// CHECK: %arr3 = alloca [3 x i32]
int arr3[] = {7, 8, 9};
- foo(arr1, arr2, arr3);
+ constant int var1 = 1;
+
+ // CHECK: call spir_func void @foo(i32 addrspace(2)* @k.var1, i32 addrspace(2)* getelementptr inbounds ([3 x i32], [3 x i32] addrspace(2)* @k.arr1, i32 0, i32 0)
+ foo(&var1, arr1, arr2, arr3);
}
diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c
index 05e239c74243..41f573aa7316 100644
--- a/test/Driver/fsanitize.c
+++ b/test/Driver/fsanitize.c
@@ -30,7 +30,7 @@
// RUN: %clang -target x86_64-pc-win32 -fsanitize-coverage=bb %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-COVERAGE-WIN64
// CHECK-COVERAGE-WIN64: "--dependent-lib={{[^"]*}}ubsan_standalone-x86_64.lib"
-// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=integer %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-INTEGER -implicit-check-not="-fsanitize-address-use-after-scope"
// CHECK-INTEGER: "-fsanitize={{((signed-integer-overflow|unsigned-integer-overflow|integer-divide-by-zero|shift-base|shift-exponent),?){5}"}}
// RUN: %clang -fsanitize=bounds -### -fsyntax-only %s 2>&1 | FileCheck %s --check-prefix=CHECK-BOUNDS
@@ -126,6 +126,13 @@
// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-WITHOUT-USE-AFTER-SCOPE
// CHECK-ASAN-WITHOUT-USE-AFTER-SCOPE: -cc1{{.*}}address-use-after-scope
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address -fsanitize-address-globals-dead-stripping %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS
+// RUN: %clang -target x86_64-linux-gnu -fsanitize=address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-ASAN-GLOBALS
+// RUN: %clang_cl --target=x86_64-windows-msvc -fsanitize=address -fsanitize-address-globals-dead-stripping -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS
+// RUN: %clang_cl --target=x86_64-windows-msvc -fsanitize=address -### -- %s 2>&1 | FileCheck %s --check-prefix=CHECK-ASAN-GLOBALS
+// CHECK-ASAN-GLOBALS: -cc1{{.*}}-fsanitize-address-globals-dead-stripping
+// CHECK-NO-ASAN-GLOBALS-NOT: -cc1{{.*}}-fsanitize-address-globals-dead-stripping
+
// RUN: %clang -target x86_64-linux-gnu -fsanitize-memory-track-origins -pie %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-ONLY-TRACK-ORIGINS
// CHECK-ONLY-TRACK-ORIGINS: warning: argument unused during compilation: '-fsanitize-memory-track-origins'
diff --git a/test/Driver/myriad-toolchain.c b/test/Driver/myriad-toolchain.c
index 971e5d3e6961..7bd215bf1a48 100644
--- a/test/Driver/myriad-toolchain.c
+++ b/test/Driver/myriad-toolchain.c
@@ -54,9 +54,11 @@
// -fno-split-dwarf-inlining is consumed but not passed to moviCompile.
// RUN: %clang -target shave-myriad -c -### %s -g -fno-inline-functions \
// RUN: -fno-inline-functions-called-once -Os -Wall -MF dep.d -fno-split-dwarf-inlining \
-// RUN: -ffunction-sections 2>&1 | FileCheck %s -check-prefix=PASSTHRU_OPTIONS
+// RUN: -ffunction-sections -Xclang -xclangflag -mllvm -llvm-flag 2>&1 \
+// RUN: | FileCheck %s -check-prefix=PASSTHRU_OPTIONS
// PASSTHRU_OPTIONS: "-g" "-fno-inline-functions" "-fno-inline-functions-called-once"
// PASSTHRU_OPTIONS: "-Os" "-Wall" "-MF" "dep.d" "-ffunction-sections"
+// PASSTHRU_OPTIONS: "-Xclang" "-xclangflag" "-mllvm" "-llvm-flag"
// RUN: %clang -target shave-myriad -c %s -o foo.o -### -MD -MF dep.d 2>&1 \
// RUN: | FileCheck %s -check-prefix=MDMF
diff --git a/test/Driver/wasm-toolchain.c b/test/Driver/wasm-toolchain.c
index d0b029303891..3be60df92672 100644
--- a/test/Driver/wasm-toolchain.c
+++ b/test/Driver/wasm-toolchain.c
@@ -27,18 +27,18 @@
// RUN: %clang -### -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK %s
// LINK: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK: lld{{.*}}" "-flavor" "ld" "-L/foo/lib32" "crt1.o" "crti.o" "[[temp]]" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
+// LINK: lld{{.*}}" "-flavor" "wasm" "-L/foo/lib32" "crt1.o" "crti.o" "[[temp]]" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
// A basic C link command-line with optimization. WebAssembly is somewhat
// special in enabling --gc-sections by default.
// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo %s 2>&1 | FileCheck -check-prefix=LINK_OPT %s
// LINK_OPT: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// LINK_OPT: lld{{.*}}" "-flavor" "ld" "--gc-sections" "-L/foo/lib32" "crt1.o" "crti.o" "[[temp]]" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
+// LINK_OPT: lld{{.*}}" "-flavor" "wasm" "--gc-sections" "-L/foo/lib32" "crt1.o" "crti.o" "[[temp]]" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
// Ditto, but ensure that a user --no-gc-sections comes after the
// default --gc-sections.
// RUN: %clang -### -O2 -no-canonical-prefixes -target wasm32-unknown-unknown --sysroot=/foo -Wl,--no-gc-sections %s 2>&1 | FileCheck -check-prefix=NO_GC_SECTIONS %s
// NO_GC_SECTIONS: clang{{.*}}" "-cc1" {{.*}} "-o" "[[temp:[^"]*]]"
-// NO_GC_SECTIONS: lld{{.*}}" "-flavor" "ld" "--gc-sections" "-L/foo/lib32" "crt1.o" "crti.o" "--no-gc-sections" "[[temp]]" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
+// NO_GC_SECTIONS: lld{{.*}}" "-flavor" "wasm" "--gc-sections" "-L/foo/lib32" "crt1.o" "crti.o" "--no-gc-sections" "[[temp]]" "-lc" "-lcompiler_rt" "crtn.o" "-o" "a.out"
diff --git a/test/FixIt/fixit-availability.c b/test/FixIt/fixit-availability.c
index fa641b4b98c6..038dee08b13c 100644
--- a/test/FixIt/fixit-availability.c
+++ b/test/FixIt/fixit-availability.c
@@ -5,6 +5,6 @@ int function(void);
void use() {
function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (__builtin_available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (__builtin_available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n } else {\n // Fallback on earlier versions\n }"
}
diff --git a/test/FixIt/fixit-availability.mm b/test/FixIt/fixit-availability.mm
index 6bf8f49ddc0d..d044a73efdb9 100644
--- a/test/FixIt/fixit-availability.mm
+++ b/test/FixIt/fixit-availability.mm
@@ -7,58 +7,58 @@ void anotherFunction(int function);
int use() {
function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n } else {\n // Fallback on earlier versions\n }"
int y = function(), x = 0;
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:29-[[@LINE-2]]:29}:"\n } else {\n // Fallback on earlier versions\n }"
x += function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:19-[[@LINE-2]]:19}:"\n } else {\n // Fallback on earlier versions\n }"
if (1) {
x = function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:20-[[@LINE-2]]:20}:"\n } else {\n // Fallback on earlier versions\n }"
}
anotherFunction(function());
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:31-[[@LINE-2]]:31}:"\n } else {\n // Fallback on earlier versions\n }"
if (function()) {
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:4-[[@LINE+1]]:4}:"\n } else {\n // Fallback on earlier versions\n }"
}
while (function())
- // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+ // CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+1]]:6-[[@LINE+1]]:6}:"\n } else {\n // Fallback on earlier versions\n }"
;
do
function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
while (1);
for (int i = 0; i < 10; ++i)
function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
switch (x) {
case 0:
function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
case 2:
anotherFunction(1);
function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
break;
default:
function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
break;
}
return function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:21-[[@LINE-2]]:21}:"\n } else {\n // Fallback on earlier versions\n }"
}
@@ -72,39 +72,39 @@ int use() {
void useInMacros() {
MYFUNCTION();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:16-[[@LINE-2]]:16}:"\n } else {\n // Fallback on earlier versions\n }"
MACRO_ARGUMENT_SEMI(function())
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:34-[[@LINE-2]]:34}:"\n } else {\n // Fallback on earlier versions\n }"
MACRO_ARGUMENT(function());
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:30-[[@LINE-2]]:30}:"\n } else {\n // Fallback on earlier versions\n }"
MACRO_ARGUMENT_2(function());
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:32-[[@LINE-2]]:32}:"\n } else {\n // Fallback on earlier versions\n }"
INNER_MACRO
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:14-[[@LINE-2]]:14}:"\n } else {\n // Fallback on earlier versions\n }"
}
void wrapDeclStmtUses() {
int x = 0, y = function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:3-[[@LINE-1]]:3}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE+13]]:22-[[@LINE+13]]:22}:"\n } else {\n // Fallback on earlier versions\n }"
{
int z = function();
if (z) {
}
-// CHECK: fix-it:{{.*}}:{[[@LINE-4]]:5-[[@LINE-4]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-4]]:5-[[@LINE-4]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:6-[[@LINE-2]]:6}:"\n } else {\n // Fallback on earlier versions\n }"
}
if (y)
int z = function();
-// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macos 10.12, *)) {\n "
+// CHECK: fix-it:{{.*}}:{[[@LINE-1]]:5-[[@LINE-1]]:5}:"if (@available(macOS 10.12, *)) {\n "
// CHECK-NEXT: fix-it:{{.*}}:{[[@LINE-2]]:24-[[@LINE-2]]:24}:"\n } else {\n // Fallback on earlier versions\n }"
anotherFunction(y);
anotherFunction(x);
diff --git a/test/Import/conflicting-struct/Inputs/S1.cpp b/test/Import/conflicting-struct/Inputs/S1.cpp
new file mode 100644
index 000000000000..a99dba8c7821
--- /dev/null
+++ b/test/Import/conflicting-struct/Inputs/S1.cpp
@@ -0,0 +1,6 @@
+class T;
+
+class S {
+ T *t;
+ int a;
+};
diff --git a/test/Import/conflicting-struct/Inputs/S2.cpp b/test/Import/conflicting-struct/Inputs/S2.cpp
new file mode 100644
index 000000000000..de2cb6cd03c7
--- /dev/null
+++ b/test/Import/conflicting-struct/Inputs/S2.cpp
@@ -0,0 +1,7 @@
+class U {
+ int b;
+};
+
+class T {
+ U u;
+};
diff --git a/test/Import/conflicting-struct/test.cpp b/test/Import/conflicting-struct/test.cpp
new file mode 100644
index 000000000000..5aad567cd794
--- /dev/null
+++ b/test/Import/conflicting-struct/test.cpp
@@ -0,0 +1,7 @@
+// RUN: clang-import-test --import %S/Inputs/S1.cpp --import %S/Inputs/S2.cpp -expression %s
+void expr() {
+ S MyS;
+ T MyT;
+ MyS.a = 3;
+ MyT.u.b = 2;
+}
diff --git a/test/Index/Core/index-dependent-source.cpp b/test/Index/Core/index-dependent-source.cpp
new file mode 100644
index 000000000000..8c097b935a37
--- /dev/null
+++ b/test/Index/Core/index-dependent-source.cpp
@@ -0,0 +1,143 @@
+// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
+
+int invalid;
+
+class Base {
+ void baseFunction();
+
+ int baseField;
+
+ static void staticBaseFunction();
+};
+
+template<typename T>
+class BaseTemplate {
+public:
+ T baseTemplateFunction();
+
+ T baseTemplateField;
+
+ static T baseTemplateVariable;
+};
+
+template<typename T, typename S>
+class TemplateClass: public Base , public BaseTemplate<T> {
+public:
+ ~TemplateClass();
+
+ T function() { }
+
+ static void staticFunction() { }
+
+ T field;
+
+ static T variable;
+
+ struct Struct { };
+
+ enum Enum { EnumValue };
+
+ using TypeAlias = S;
+ typedef T Typedef;
+
+ void overload1(const T &);
+ void overload1(const S &);
+};
+
+template<typename T, typename S>
+void indexSimpleDependentDeclarations(const TemplateClass<T, S> &object) {
+ // Valid instance members:
+ object.function();
+// CHECK: [[@LINE-1]]:10 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+ object.field;
+// CHECK: [[@LINE-1]]:10 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+ object.baseFunction();
+// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseFunction | c:@S@Base@F@baseFunction# | __ZN4Base12baseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
+ object.baseField;
+// CHECK: [[@LINE-1]]:10 | field/C++ | baseField | c:@S@Base@FI@baseField | <no-cgname> | Ref,RelCont | rel: 1
+ object.baseTemplateFunction();
+// CHECK: [[@LINE-1]]:10 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+ object.baseTemplateField;
+// CHECK: [[@LINE-1]]:10 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1
+
+ // Invalid instance members:
+ object.variable;
+// CHECK-NOT: [[@LINE-1]]:10
+ object.staticFunction();
+// CHECK-NOT: [[@LINE-1]]:10
+ object.Struct;
+// CHECK-NOT: [[@LINE-1]]:10
+ object.EnumValue;
+// CHECK-NOT: [[@LINE-1]]:10
+
+ // Valid static members:
+ TemplateClass<T, S>::staticFunction();
+// CHECK: [[@LINE-1]]:24 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+ TemplateClass<T, S>::variable;
+// CHECK: [[@LINE-1]]:24 | static-property/C++ | variable | c:@ST>2#T#T@TemplateClass@variable | __ZN13TemplateClass8variableE | Ref,RelCont | rel: 1
+ TemplateClass<T, S>::staticBaseFunction();
+// CHECK: [[@LINE-1]]:24 | static-method/C++ | staticBaseFunction | c:@S@Base@F@staticBaseFunction#S | __ZN4Base18staticBaseFunctionEv | Ref,Call,RelCall,RelCont | rel: 1
+ TemplateClass<T, S>::baseTemplateVariable;
+// CHECK: [[@LINE-1]]:24 | static-property/C++ | baseTemplateVariable | c:@ST>1#T@BaseTemplate@baseTemplateVariable | __ZN12BaseTemplate20baseTemplateVariableE | Ref,RelCont | rel: 1
+ TemplateClass<T, S>::EnumValue;
+// CHECK: [[@LINE-1]]:24 | enumerator/C | EnumValue | c:@ST>2#T#T@TemplateClass@E@Enum@EnumValue | <no-cgname> | Ref,RelCont | rel: 1
+ TemplateClass<T, S>::Struct();
+// CHECK: [[@LINE-1]]:24 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,Call,RelCall,RelCont | rel: 1
+
+ // Invalid static members:
+ TemplateClass<T, S>::field;
+// CHECK-NOT: [[@LINE-1]]:24
+ TemplateClass<T, S>::function();
+// CHECK-NOT: [[@LINE-1]]:24
+
+ // Valid type names:
+ typename TemplateClass<T, S>::Struct Val;
+// CHECK: [[@LINE-1]]:33 | struct/C | Struct | c:@ST>2#T#T@TemplateClass@S@Struct | <no-cgname> | Ref,RelCont | rel: 1
+ typename TemplateClass<T, S>::Enum EnumVal;
+// CHECK: [[@LINE-1]]:33 | enum/C | Enum | c:@ST>2#T#T@TemplateClass@E@Enum | <no-cgname> | Ref,RelCont | rel: 1
+ typename TemplateClass<T, S>::TypeAlias Val2;
+// CHECK: [[@LINE-1]]:33 | type-alias/C++ | TypeAlias | c:@ST>2#T#T@TemplateClass@TypeAlias | <no-cgname> | Ref,RelCont | rel: 1
+ typename TemplateClass<T, S>::Typedef Val3;
+// CHECK: [[@LINE-1]]:33 | type-alias/C | Typedef | c:{{.*}}index-dependent-source.cpp@ST>2#T#T@TemplateClass@T@Typedef | <no-cgname> | Ref,RelCont | rel: 1
+
+ // Invalid type names:
+ typename TemplateClass<T, S>::field Val4;
+// CHECK-NOT: [[@LINE-1]]:33
+ typename TemplateClass<T, S>::staticFunction Val5;
+// CHECK-NOT: [[@LINE-1]]:33
+
+
+ object.invalid;
+// CHECK-NOT: [[@LINE-1]]:10
+ TemplateClass<T, S>::invalid;
+// CHECK-NOT: [[@LINE-1]]:24
+}
+
+template<typename T, typename S, typename Y>
+void indexDependentOverloads(const TemplateClass<T, S> &object) {
+ object.overload1(T());
+// CHECK-NOT: [[@LINE-1]]
+ object.overload1(S());
+// CHECK-NOT: [[@LINE-1]]
+ object.overload1(Y());
+// CHECK-NOT: [[@LINE-1]]
+}
+
+template<typename T> struct UndefinedTemplateClass;
+
+template<typename T>
+void undefinedTemplateLookup(UndefinedTemplateClass<T> &x) {
+// Shouldn't crash!
+ x.lookup;
+ typename UndefinedTemplateClass<T>::Type y;
+}
+
+template<typename T>
+struct UserOfUndefinedTemplateClass: UndefinedTemplateClass<T> { };
+
+template<typename T>
+void undefinedTemplateLookup2(UserOfUndefinedTemplateClass<T> &x) {
+// Shouldn't crash!
+ x.lookup;
+ typename UserOfUndefinedTemplateClass<T>::Type y;
+}
diff --git a/test/Index/Core/index-instantiated-source.cpp b/test/Index/Core/index-instantiated-source.cpp
new file mode 100644
index 000000000000..f61795da540c
--- /dev/null
+++ b/test/Index/Core/index-instantiated-source.cpp
@@ -0,0 +1,39 @@
+// RUN: c-index-test core -print-source-symbols -- %s -std=c++14 -target x86_64-apple-macosx10.7 | FileCheck %s
+// References to declarations in instantiations should be canonicalized:
+
+template<typename T>
+class BaseTemplate {
+public:
+ T baseTemplateFunction();
+// CHECK: [[@LINE-1]]:5 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction#
+
+ T baseTemplateField;
+// CHECK: [[@LINE-1]]:5 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField
+};
+
+template<typename T, typename S>
+class TemplateClass: public BaseTemplate<T> {
+public:
+ T function() { return T(); }
+// CHECK: [[@LINE-1]]:5 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function#
+
+ static void staticFunction() { }
+// CHECK: [[@LINE-1]]:15 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S
+
+ T field;
+// CHECK: [[@LINE-1]]:5 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field
+};
+
+void canonicalizeInstaniationReferences(TemplateClass<int, float> &object) {
+ (void)object.function();
+// CHECK: [[@LINE-1]]:16 | instance-method/C++ | function | c:@ST>2#T#T@TemplateClass@F@function# | <no-cgname>
+ (void)object.field;
+// CHECK: [[@LINE-1]]:16 | field/C++ | field | c:@ST>2#T#T@TemplateClass@FI@field | <no-cgname> | Ref,RelCont | rel: 1
+ (void)object.baseTemplateFunction();
+// CHECK: [[@LINE-1]]:16 | instance-method/C++ | baseTemplateFunction | c:@ST>1#T@BaseTemplate@F@baseTemplateFunction# | <no-cgname>
+ (void)object.baseTemplateField;
+// CHECK: [[@LINE-1]]:16 | field/C++ | baseTemplateField | c:@ST>1#T@BaseTemplate@FI@baseTemplateField | <no-cgname> | Ref,RelCont | rel: 1
+
+ TemplateClass<int, float>::staticFunction();
+// CHECK: [[@LINE-1]]:30 | static-method/C++ | staticFunction | c:@ST>2#T#T@TemplateClass@F@staticFunction#S | <no-cgname
+}
diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp
index 6f902610e673..9248e86ff697 100644
--- a/test/Index/Core/index-source.cpp
+++ b/test/Index/Core/index-source.cpp
@@ -287,3 +287,55 @@ class PartialSpecilizationClass<Cls, Cls> : Cls { };
// CHECK-NEXT: [[@LINE-5]]:7 | class(Gen)/C++ | PartialSpecilizationClass | c:@ST>2#T#T@PartialSpecilizationClass | <no-cgname> | Ref | rel: 0
// CHECK-NEXT: [[@LINE-6]]:33 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
// CHECK-NEXT: [[@LINE-7]]:38 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
+
+template<typename T, int x>
+void functionSp() { }
+
+struct Record {
+ constexpr static int C = 2;
+};
+
+template<>
+void functionSp<SpecializationDecl<Cls>, Record::C>() {
+// CHECK: [[@LINE-1]]:6 | function(Gen,TS)/C++ | functionSp | c:@F@functionSp<#$@S@SpecializationDecl>#$@S@Cls#VI2># | __Z10functionSpI18SpecializationDeclI3ClsELi2EEvv | Def,RelSpecialization | rel: 1
+// CHECK: RelSpecialization | functionSp | c:@FT@>2#T#NIfunctionSp#v#
+// CHECK: [[@LINE-3]]:17 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-4]]:36 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-5]]:50 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-6]]:42 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref,RelCont | rel: 1
+}
+
+template<typename T, int x>
+class ClassWithCorrectSpecialization { };
+
+template<>
+class ClassWithCorrectSpecialization<SpecializationDecl<Cls>, Record::C> { };
+// CHECK: [[@LINE-1]]:38 | class(Gen)/C++ | SpecializationDecl | c:@ST>1#T@SpecializationDecl | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-2]]:57 | class/C++ | Cls | c:@S@Cls | <no-cgname> | Ref | rel: 0
+// CHECK: [[@LINE-3]]:71 | static-property/C++ | C | c:@S@Record@C | __ZN6Record1CE | Ref,Read | rel: 0
+// CHECK: [[@LINE-4]]:63 | struct/C++ | Record | c:@S@Record | <no-cgname> | Ref | rel: 0
+
+namespace ns {
+// CHECK: [[@LINE-1]]:11 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Decl | rel: 0
+namespace inner {
+// CHECK: [[@LINE-1]]:11 | namespace/C++ | inner | c:@N@ns@N@inner | <no-cgname> | Decl,RelChild | rel: 1
+void func();
+
+}
+namespace innerAlias = inner;
+// CHECK: [[@LINE-1]]:11 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Decl,RelChild | rel: 1
+// CHECK: [[@LINE-2]]:24 | namespace/C++ | inner | c:@N@ns@N@inner | <no-cgname> | Ref,RelCont | rel: 1
+}
+
+namespace namespaceAlias = ::ns::innerAlias;
+// CHECK: [[@LINE-1]]:11 | namespace-alias/C++ | namespaceAlias | c:@NA@namespaceAlias | <no-cgname> | Decl | rel: 0
+// CHECK: [[@LINE-2]]:30 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-3]]:34 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Ref,RelCont | rel: 1
+
+void ::ns::inner::func() {
+// CHECK: [[@LINE-1]]:8 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:12 | namespace/C++ | inner | c:@N@ns@N@inner | <no-cgname> | Ref,RelCont | rel: 1
+ ns::innerAlias::func();
+// CHECK: [[@LINE-1]]:3 | namespace/C++ | ns | c:@N@ns | <no-cgname> | Ref,RelCont | rel: 1
+// CHECK: [[@LINE-2]]:7 | namespace-alias/C++ | innerAlias | c:@N@ns@NA@innerAlias | <no-cgname> | Ref,RelCont | rel: 1
+}
diff --git a/test/Index/complete-available.m b/test/Index/complete-available.m
new file mode 100644
index 000000000000..8267dbdddc5c
--- /dev/null
+++ b/test/Index/complete-available.m
@@ -0,0 +1,20 @@
+/* The run lines are below, because this test is line- and
+ column-number sensitive. */
+void atAvailable() {
+ if (@available(macOS 10.10, *)) {
+
+ }
+ if (__builtin_available(iOS 8, *)) {
+ }
+}
+
+// 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
+// CHECK: {TypedText iOS} (40)
+// CHECK: {TypedText iOSApplicationExtension} (40)
+// CHECK: {TypedText macOS} (40)
+// CHECK: {TypedText macOSApplicationExtension} (40)
+// CHECK: {TypedText tvOS} (40)
+// CHECK: {TypedText tvOSApplicationExtension} (40)
+// CHECK: {TypedText watchOS} (40)
+// CHECK: {TypedText watchOSApplicationExtension} (40)
diff --git a/test/Index/get-cursor.m b/test/Index/get-cursor.m
index af277d45fdf4..e85d49fb0c3e 100644
--- a/test/Index/get-cursor.m
+++ b/test/Index/get-cursor.m
@@ -154,6 +154,12 @@ SomeT someVar;
typedef MY_TYPE2(SomeT2) { int x; };
SomeT2 someVar2;
+#define GEN_DECL(mod_name) __attribute__((external_source_symbol(language="Swift", defined_in=mod_name, generated_declaration)))
+
+GEN_DECL("some_module")
+@interface ExtCls
+-(void)method;
+@end
// RUN: c-index-test -cursor-at=%s:4:28 -cursor-at=%s:5:28 %s | FileCheck -check-prefix=CHECK-PROP %s
// CHECK-PROP: ObjCPropertyDecl=foo1:4:26
@@ -226,3 +232,8 @@ SomeT2 someVar2;
// CHECK-TRANSPARENT: 147:1 TypeRef=TokenPaste_t:144:9 Extent=[147:1 - 147:13] Spelling=TokenPaste_t ([147:1 - 147:13])
// CHECK-TRANSPARENT: 151:1 TypeRef=SomeT:150:17 (Transparent: struct SomeT) Extent=[151:1 - 151:6] Spelling=SomeT ([151:1 - 151:6])
// CHECK-TRANSPARENT: 155:1 TypeRef=SomeT2:154:18 Extent=[155:1 - 155:7] Spelling=SomeT2 ([155:1 - 155:7])
+
+// RUN: c-index-test -cursor-at=%s:160:12 -cursor-at=%s:161:8 %s | FileCheck -check-prefix=CHECK-EXTERNAL %s
+// CHECK-EXTERNAL: 160:12 ObjCInterfaceDecl=ExtCls:160:12 (external lang: Swift, defined: some_module, gen: 1)
+// CHECK-EXTERNAL: 161:8 ObjCInstanceMethodDecl=method:161:8 (external lang: Swift, defined: some_module, gen: 1)
+C \ No newline at end of file
diff --git a/test/Misc/warning-flags.c b/test/Misc/warning-flags.c
index be02e12e2cbb..5172d3b15a90 100644
--- a/test/Misc/warning-flags.c
+++ b/test/Misc/warning-flags.c
@@ -6,8 +6,8 @@ This test serves two purposes:
(1) It documents all existing warnings that currently have no associated -W flag,
and ensures that the list never grows.
- If take an existing warning and add a flag, this test will fail. To
- fix this test, simply remove that warning from the list below.
+ If you take an existing warning and add a flag, this test will fail.
+ To fix this test, simply remove that warning from the list below.
(2) It prevents us adding new warnings to Clang that have no -W flag. All
new warnings should have -W flags.
diff --git a/test/Modules/DebugInfoNamespace.cpp b/test/Modules/DebugInfoNamespace.cpp
new file mode 100644
index 000000000000..33add085d8a6
--- /dev/null
+++ b/test/Modules/DebugInfoNamespace.cpp
@@ -0,0 +1,19 @@
+// RUN: rm -rf %t
+// RUN: %clang_cc1 -x objective-c++ -std=c++11 -debug-info-kind=standalone \
+// RUN: -dwarf-ext-refs -fmodules \
+// RUN: -fmodule-format=obj -fimplicit-module-maps \
+// RUN: -triple %itanium_abi_triple -fmodules-cache-path=%t \
+// RUN: %s -I %S/Inputs/DebugInfoNamespace -I %t -emit-llvm -o - \
+// RUN: | FileCheck %s
+
+#include "A.h"
+#include "B.h"
+using namespace N;
+B b;
+
+// Verify that the forward decl of B is in module B.
+//
+// CHECK: !DICompositeType(tag: DW_TAG_structure_type, name: "B",
+// CHECK-SAME: scope: ![[N:[0-9]+]]
+// CHECK: ![[N]] = !DINamespace(name: "N", scope: ![[B:[0-9]+]])
+// CHECK: ![[B]] = !DIModule(scope: null, name: "B",
diff --git a/test/Modules/DebugInfoSubmoduleImport.c b/test/Modules/DebugInfoSubmoduleImport.c
index 1b31aada9c6a..b608d300d5fe 100644
--- a/test/Modules/DebugInfoSubmoduleImport.c
+++ b/test/Modules/DebugInfoSubmoduleImport.c
@@ -2,6 +2,11 @@
// RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \
// RUN: -fimplicit-module-maps -x c -fmodules-cache-path=%t -I %S/Inputs \
// RUN: %s -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s
+//
+// RUN: %clang_cc1 -fmodules -fmodule-format=obj -debug-info-kind=limited -dwarf-ext-refs \
+// RUN: -fimplicit-module-maps -x c -fmodules-cache-path=%t -I %S/Inputs \
+// RUN: -fmodules-local-submodule-visibility \
+// RUN: %s -emit-llvm -debugger-tuning=lldb -o - | FileCheck %s
#include "DebugSubmoduleA.h"
#include "DebugSubmoduleB.h"
diff --git a/test/Modules/Inputs/DebugInfoNamespace/A.h b/test/Modules/Inputs/DebugInfoNamespace/A.h
new file mode 100644
index 000000000000..dc5a1cd26ab6
--- /dev/null
+++ b/test/Modules/Inputs/DebugInfoNamespace/A.h
@@ -0,0 +1,3 @@
+namespace N {
+ struct A {};
+}
diff --git a/test/Modules/Inputs/DebugInfoNamespace/B.h b/test/Modules/Inputs/DebugInfoNamespace/B.h
new file mode 100644
index 000000000000..c9033a54d4e5
--- /dev/null
+++ b/test/Modules/Inputs/DebugInfoNamespace/B.h
@@ -0,0 +1,3 @@
+namespace N {
+ struct B {};
+}
diff --git a/test/Modules/Inputs/DebugInfoNamespace/module.modulemap b/test/Modules/Inputs/DebugInfoNamespace/module.modulemap
new file mode 100644
index 000000000000..9300fcf98c64
--- /dev/null
+++ b/test/Modules/Inputs/DebugInfoNamespace/module.modulemap
@@ -0,0 +1,8 @@
+module A {
+ header "A.h"
+ export *
+}
+module B {
+ header "B.h"
+ export *
+}
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/B.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/B.h
new file mode 100644
index 000000000000..761540b09cb3
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/B.h
@@ -0,0 +1 @@
+// B.h
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/Sub.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/Sub.h
new file mode 100644
index 000000000000..fd86e3cf872f
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/Headers/Sub.h
@@ -0,0 +1,2 @@
+// Sub.h
+#import "B.h"
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h
new file mode 100644
index 000000000000..4ab49b798c63
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/BPriv.h
@@ -0,0 +1 @@
+// BPriv.h
diff --git a/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
new file mode 100644
index 000000000000..f6ac6188d65f
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Frameworks/Sub.framework/PrivateHeaders/SubPriv.h
@@ -0,0 +1 @@
+#import "BPriv.h"
diff --git a/test/Modules/Inputs/MainA.framework/Headers/A.h b/test/Modules/Inputs/MainA.framework/Headers/A.h
new file mode 100644
index 000000000000..975f1f0437bb
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Headers/A.h
@@ -0,0 +1 @@
+// A.h
diff --git a/test/Modules/Inputs/MainA.framework/Headers/Main.h b/test/Modules/Inputs/MainA.framework/Headers/Main.h
new file mode 100644
index 000000000000..cb8cc00a0c45
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Headers/Main.h
@@ -0,0 +1,2 @@
+// Main.h
+#import "A.h"
diff --git a/test/Modules/Inputs/MainA.framework/Modules/module.modulemap b/test/Modules/Inputs/MainA.framework/Modules/module.modulemap
new file mode 100644
index 000000000000..4b0b5e955386
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Modules/module.modulemap
@@ -0,0 +1,12 @@
+framework module MainA {
+ umbrella header "Main.h"
+
+ module * { export * }
+ export *
+
+ framework module Sub {
+ umbrella header "Sub.h"
+ module * { export * }
+ export *
+ }
+}
diff --git a/test/Modules/Inputs/MainA.framework/Modules/module.private.modulemap b/test/Modules/Inputs/MainA.framework/Modules/module.private.modulemap
new file mode 100644
index 000000000000..a8dc5c2be5f0
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/Modules/module.private.modulemap
@@ -0,0 +1,12 @@
+framework module MainA_Private {
+ umbrella header "MainPriv.h"
+
+ module * { export * }
+ export *
+
+ explicit framework module Sub {
+ umbrella header "SubPriv.h"
+ module * { export * }
+ export *
+ }
+}
diff --git a/test/Modules/Inputs/MainA.framework/PrivateHeaders/APriv.h b/test/Modules/Inputs/MainA.framework/PrivateHeaders/APriv.h
new file mode 100644
index 000000000000..6ac683c39c55
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/PrivateHeaders/APriv.h
@@ -0,0 +1 @@
+// APriv.h
diff --git a/test/Modules/Inputs/MainA.framework/PrivateHeaders/MainPriv.h b/test/Modules/Inputs/MainA.framework/PrivateHeaders/MainPriv.h
new file mode 100644
index 000000000000..68103017ad0b
--- /dev/null
+++ b/test/Modules/Inputs/MainA.framework/PrivateHeaders/MainPriv.h
@@ -0,0 +1 @@
+#import "APriv.h"
diff --git a/test/Modules/Inputs/SameHeader/A.h b/test/Modules/Inputs/SameHeader/A.h
new file mode 100644
index 000000000000..bebe9c31c28e
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/A.h
@@ -0,0 +1,3 @@
+#ifndef __A_h__
+#define __A_h__
+#endif
diff --git a/test/Modules/Inputs/SameHeader/B.h b/test/Modules/Inputs/SameHeader/B.h
new file mode 100644
index 000000000000..c3fe49cd854f
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/B.h
@@ -0,0 +1,4 @@
+#ifndef __B_h__
+#define __B_h__
+#include "C.h"
+#endif
diff --git a/test/Modules/Inputs/SameHeader/C.h b/test/Modules/Inputs/SameHeader/C.h
new file mode 100644
index 000000000000..33c3316a6517
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/C.h
@@ -0,0 +1,12 @@
+#ifndef __C_h__
+#define __C_h__
+int c = 1;
+
+struct aaa {
+ int b;
+};
+
+typedef struct fd_set {
+ char c;
+};
+#endif
diff --git a/test/Modules/Inputs/SameHeader/module.modulemap b/test/Modules/Inputs/SameHeader/module.modulemap
new file mode 100644
index 000000000000..d0283a71ac97
--- /dev/null
+++ b/test/Modules/Inputs/SameHeader/module.modulemap
@@ -0,0 +1,11 @@
+module X {
+ module A {
+ header "A.h"
+ export *
+ }
+ module B {
+ header "B.h"
+ export *
+ }
+ export *
+}
diff --git a/test/Modules/find-privateheaders.m b/test/Modules/find-privateheaders.m
index c5e82ac70da2..5720a73f9be8 100644
--- a/test/Modules/find-privateheaders.m
+++ b/test/Modules/find-privateheaders.m
@@ -1,2 +1,13 @@
-// RUN: %clang_cc1 -fmodules -fsyntax-only -F%S/Inputs %s
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules -fsyntax-only -F%S/Inputs -fimplicit-module-maps \
+// RUN: -fmodules-cache-path=%t.cache -Wno-private-module -DBUILD_PUBLIC -verify %s
+// RUN: rm -rf %t.cache
+// RUN: %clang_cc1 -fmodules -fsyntax-only -F%S/Inputs -fimplicit-module-maps \
+// RUN: -fmodules-cache-path=%t.cache -Wno-private-module -verify %s
+//expected-no-diagnostics
+
+#ifdef BUILD_PUBLIC
#import "Main/Main.h"
+#else
+#import "MainA/MainPriv.h"
+#endif
diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp
index 294e925627c6..58814dd6b3fb 100644
--- a/test/Modules/odr_hash.cpp
+++ b/test/Modules/odr_hash.cpp
@@ -1078,6 +1078,39 @@ S<X> s;
#endif
}
+namespace MultipleTypedefs {
+#if defined(FIRST)
+typedef int B1;
+typedef B1 A1;
+struct S1 {
+ A1 x;
+};
+#elif defined(SECOND)
+typedef int A1;
+struct S1 {
+ A1 x;
+};
+#else
+S1 s1;
+#endif
+
+#if defined(FIRST)
+struct T2 { int x; };
+typedef T2 B2;
+typedef B2 A2;
+struct S2 {
+ T2 x;
+};
+#elif defined(SECOND)
+struct T2 { int x; };
+typedef T2 A2;
+struct S2 {
+ T2 x;
+};
+#else
+S2 s2;
+#endif
+}
// Keep macros contained to one file.
#ifdef FIRST
diff --git a/test/Modules/preprocess-module.cpp b/test/Modules/preprocess-module.cpp
index a3b789238388..64af00c471df 100644
--- a/test/Modules/preprocess-module.cpp
+++ b/test/Modules/preprocess-module.cpp
@@ -19,6 +19,11 @@
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -x c++-module-map-cpp-output %t/no-rewrite.ii -emit-module -o %t/no-rewrite.pcm
// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -x c++-module-map-cpp-output %t/rewrite.ii -emit-module -o %t/rewrite.pcm
+// Check that we can load the original module map in the same compilation (this
+// could happen if we had a redundant -fmodule-map-file= in the original
+// build).
+// RUN: %clang_cc1 -fmodules -fmodule-name=file -fmodule-file=%t/fwd.pcm -fmodule-map-file=%S/Inputs/preprocess/module.modulemap -x c++-module-map-cpp-output %t/rewrite.ii -emit-module -o /dev/null
+
// Check the module we built works.
// RUN: %clang_cc1 -fmodules -fmodule-file=%t/no-rewrite.pcm %s -verify
// RUN: %clang_cc1 -fmodules -fmodule-file=%t/rewrite.pcm %s -verify
diff --git a/test/Modules/redefinition-same-header.m b/test/Modules/redefinition-same-header.m
new file mode 100644
index 000000000000..f1c6cbbcaa2e
--- /dev/null
+++ b/test/Modules/redefinition-same-header.m
@@ -0,0 +1,20 @@
+// RUN: rm -rf %t.tmp
+// RUN: %clang_cc1 -fsyntax-only -I %S/Inputs/SameHeader -fmodules \
+// RUN: -fimplicit-module-maps -fmodules-cache-path=%t.tmp %s -verify
+
+// expected-error@Inputs/SameHeader/C.h:3 {{redefinition of 'c'}}
+// expected-note-re@Inputs/SameHeader/B.h:3 {{'{{.*}}C.h' included multiple times, additional include site in header from module 'X.B'}}
+// expected-note@Inputs/SameHeader/module.modulemap:6 {{X.B defined here}}
+// expected-note-re@redefinition-same-header.m:20 {{'{{.*}}C.h' included multiple times, additional include site here}}
+
+// expected-error@Inputs/SameHeader/C.h:5 {{redefinition of 'aaa'}}
+// expected-note-re@Inputs/SameHeader/B.h:3 {{'{{.*}}C.h' included multiple times, additional include site in header from module 'X.B'}}
+// expected-note@Inputs/SameHeader/module.modulemap:6 {{X.B defined here}}
+// expected-note-re@redefinition-same-header.m:20 {{'{{.*}}C.h' included multiple times, additional include site here}}
+
+// expected-error@Inputs/SameHeader/C.h:9 {{redefinition of 'fd_set'}}
+// expected-note-re@Inputs/SameHeader/B.h:3 {{'{{.*}}C.h' included multiple times, additional include site in header from module 'X.B'}}
+// expected-note@Inputs/SameHeader/module.modulemap:6 {{X.B defined here}}
+// expected-note-re@redefinition-same-header.m:20 {{'{{.*}}C.h' included multiple times, additional include site here}}
+#include "A.h" // maps to a modular
+#include "C.h" // textual include
diff --git a/test/OpenMP/report_default_DSA.cpp b/test/OpenMP/report_default_DSA.cpp
new file mode 100644
index 000000000000..d14cd5cbe9a4
--- /dev/null
+++ b/test/OpenMP/report_default_DSA.cpp
@@ -0,0 +1,18 @@
+// RUN: %clang_cc1 -verify -fopenmp -fopenmp-version=45 %s
+
+void foo(int x, int n) {
+ double vec[n];
+ for (int iter = 0; iter < x; iter++) {
+#pragma omp target teams distribute parallel for map( \
+ from \
+ : vec [0:n]) default(none)
+ // expected-error@+1 {{variable 'n' must have explicitly specified data sharing attributes}}
+ for (int ii = 0; ii < n; ii++) {
+ // expected-error@+3 {{variable 'iter' must have explicitly specified data sharing attributes}}
+ // expected-error@+2 {{variable 'vec' must have explicitly specified data sharing attributes}}
+ // expected-error@+1 {{variable 'x' must have explicitly specified data sharing attributes}}
+ vec[ii] = iter + ii + x;
+ }
+ }
+}
+
diff --git a/test/PCH/cxx-templates.cpp b/test/PCH/cxx-templates.cpp
index d50eee0623c5..e241701f50df 100644
--- a/test/PCH/cxx-templates.cpp
+++ b/test/PCH/cxx-templates.cpp
@@ -108,3 +108,11 @@ namespace cyclic_module_load {
template int local_extern::f<int[]>(); // expected-note {{in instantiation of}}
#endif
template int local_extern::g<int[]>();
+
+namespace MemberSpecializationLocation {
+#ifndef NO_ERRORS
+ // expected-note@cxx-templates.h:* {{previous}}
+ template<> float A<int>::n; // expected-error {{redeclaration of 'n' with a different type}}
+#endif
+ int k = A<int>::n;
+}
diff --git a/test/PCH/cxx-templates.h b/test/PCH/cxx-templates.h
index c4a844727691..68b252e7974e 100644
--- a/test/PCH/cxx-templates.h
+++ b/test/PCH/cxx-templates.h
@@ -358,3 +358,6 @@ namespace rdar15468709c {
}
}
+namespace MemberSpecializationLocation {
+ template<typename T> struct A { static int n; };
+}
diff --git a/test/Parser/objc-available.m b/test/Parser/objc-available.m
index a170721240ce..49bc53930655 100644
--- a/test/Parser/objc-available.m
+++ b/test/Parser/objc-available.m
@@ -21,6 +21,12 @@ void f() {
(void)@available; // expected-error{{expected '('}}
}
+void prettyPlatformNames() {
+ (void)@available(iOS 8, tvOS 10, watchOS 3, macOS 10.11, *);
+ (void)__builtin_available(iOSApplicationExtension 8, tvOSApplicationExtension 10,
+ watchOSApplicationExtension 3, macOSApplicationExtension 10.11, *);
+}
+
#if __has_builtin(__builtin_available)
#error expected
// expected-error@-1 {{expected}}
diff --git a/test/Preprocessor/predefined-arch-macros.c b/test/Preprocessor/predefined-arch-macros.c
index a0eb8cbcca9a..08f4d2573f40 100644
--- a/test/Preprocessor/predefined-arch-macros.c
+++ b/test/Preprocessor/predefined-arch-macros.c
@@ -1601,6 +1601,7 @@
// CHECK_BDVER1_M32: #define __AES__ 1
// CHECK_BDVER1_M32: #define __AVX__ 1
// CHECK_BDVER1_M32: #define __FMA4__ 1
+// CHECK_BDVER1_M32: #define __LWP__ 1
// CHECK_BDVER1_M32: #define __LZCNT__ 1
// CHECK_BDVER1_M32: #define __MMX__ 1
// CHECK_BDVER1_M32: #define __PCLMUL__ 1
@@ -1630,6 +1631,7 @@
// CHECK_BDVER1_M64: #define __AES__ 1
// CHECK_BDVER1_M64: #define __AVX__ 1
// CHECK_BDVER1_M64: #define __FMA4__ 1
+// CHECK_BDVER1_M64: #define __LWP__ 1
// CHECK_BDVER1_M64: #define __LZCNT__ 1
// CHECK_BDVER1_M64: #define __MMX__ 1
// CHECK_BDVER1_M64: #define __PCLMUL__ 1
@@ -1664,6 +1666,7 @@
// CHECK_BDVER2_M32: #define __F16C__ 1
// CHECK_BDVER2_M32: #define __FMA4__ 1
// CHECK_BDVER2_M32: #define __FMA__ 1
+// CHECK_BDVER2_M32: #define __LWP__ 1
// CHECK_BDVER2_M32: #define __LZCNT__ 1
// CHECK_BDVER2_M32: #define __MMX__ 1
// CHECK_BDVER2_M32: #define __PCLMUL__ 1
@@ -1697,6 +1700,7 @@
// CHECK_BDVER2_M64: #define __F16C__ 1
// CHECK_BDVER2_M64: #define __FMA4__ 1
// CHECK_BDVER2_M64: #define __FMA__ 1
+// CHECK_BDVER2_M64: #define __LWP__ 1
// CHECK_BDVER2_M64: #define __LZCNT__ 1
// CHECK_BDVER2_M64: #define __MMX__ 1
// CHECK_BDVER2_M64: #define __PCLMUL__ 1
@@ -1733,6 +1737,7 @@
// CHECK_BDVER3_M32: #define __FMA4__ 1
// CHECK_BDVER3_M32: #define __FMA__ 1
// CHECK_BDVER3_M32: #define __FSGSBASE__ 1
+// CHECK_BDVER3_M32: #define __LWP__ 1
// CHECK_BDVER3_M32: #define __LZCNT__ 1
// CHECK_BDVER3_M32: #define __MMX__ 1
// CHECK_BDVER3_M32: #define __PCLMUL__ 1
@@ -1768,6 +1773,7 @@
// CHECK_BDVER3_M64: #define __FMA4__ 1
// CHECK_BDVER3_M64: #define __FMA__ 1
// CHECK_BDVER3_M64: #define __FSGSBASE__ 1
+// CHECK_BDVER3_M64: #define __LWP__ 1
// CHECK_BDVER3_M64: #define __LZCNT__ 1
// CHECK_BDVER3_M64: #define __MMX__ 1
// CHECK_BDVER3_M64: #define __PCLMUL__ 1
@@ -1807,6 +1813,7 @@
// CHECK_BDVER4_M32: #define __FMA4__ 1
// CHECK_BDVER4_M32: #define __FMA__ 1
// CHECK_BDVER4_M32: #define __FSGSBASE__ 1
+// CHECK_BDVER4_M32: #define __LWP__ 1
// CHECK_BDVER4_M32: #define __LZCNT__ 1
// CHECK_BDVER4_M32: #define __MMX__ 1
// CHECK_BDVER4_M32: #define __PCLMUL__ 1
@@ -1843,6 +1850,7 @@
// CHECK_BDVER4_M64: #define __FMA4__ 1
// CHECK_BDVER4_M64: #define __FMA__ 1
// CHECK_BDVER4_M64: #define __FSGSBASE__ 1
+// CHECK_BDVER4_M64: #define __LWP__ 1
// CHECK_BDVER4_M64: #define __LZCNT__ 1
// CHECK_BDVER4_M64: #define __MMX__ 1
// CHECK_BDVER4_M64: #define __PCLMUL__ 1
diff --git a/test/Preprocessor/x86_target_features.c b/test/Preprocessor/x86_target_features.c
index a201900ba762..ce3835f91f42 100644
--- a/test/Preprocessor/x86_target_features.c
+++ b/test/Preprocessor/x86_target_features.c
@@ -272,6 +272,14 @@
// AESNOSSE2-NOT: #define __SSE2__ 1
// AESNOSSE2-NOT: #define __SSE3__ 1
+// RUN: %clang -target i386-unknown-unknown -march=pentiumpro -mlwp -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=LWP %s
+
+// LWP: #define __LWP__ 1
+
+// RUN: %clang -target i386-unknown-unknown -march=bdver1 -mno-lwp -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=NOLWP %s
+
+// NOLWP-NOT: #define __LWP__ 1
+
// RUN: %clang -target i386-unknown-unknown -march=pentiumpro -msha -x c -E -dM -o - %s | FileCheck -match-full-lines --check-prefix=SHA %s
// SHA: #define __SHA__ 1
diff --git a/test/Sema/overloadable.c b/test/Sema/overloadable.c
index f5e17d211910..49d8085651d4 100644
--- a/test/Sema/overloadable.c
+++ b/test/Sema/overloadable.c
@@ -151,3 +151,18 @@ void dropping_qualifiers_is_incompatible() {
foo(ccharbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@148{{candidate function}} expected-note@149{{candidate function}}
foo(vcharbuf); // expected-error{{call to 'foo' is ambiguous}} expected-note@148{{candidate function}} expected-note@149{{candidate function}}
}
+
+// Bug: we used to treat `__typeof__(foo)` as though it was `__typeof__(&foo)`
+// if `foo` was overloaded with only one function that could have its address
+// taken.
+void typeof_function_is_not_a_pointer() {
+ void not_a_pointer(void *) __attribute__((overloadable));
+ void not_a_pointer(char *__attribute__((pass_object_size(1))))
+ __attribute__((overloadable));
+
+ __typeof__(not_a_pointer) *fn;
+
+ void take_fn(void (*)(void *));
+ // if take_fn is passed a void (**)(void *), we'll get a warning.
+ take_fn(fn);
+}
diff --git a/test/Sema/redefinition-same-header.c b/test/Sema/redefinition-same-header.c
new file mode 100644
index 000000000000..be5bd1d71c92
--- /dev/null
+++ b/test/Sema/redefinition-same-header.c
@@ -0,0 +1,14 @@
+// RUN: rm -rf %t
+// RUN: mkdir -p %t
+// RUN: echo 'int yyy = 42;' > %t/a.h
+// RUN: %clang_cc1 -fsyntax-only %s -I%t -verify
+
+// expected-error@a.h:1 {{redefinition of 'yyy'}}
+// expected-note@a.h:1 {{unguarded header; consider using #ifdef guards or #pragma once}}
+// expected-note-re@redefinition-same-header.c:11 {{'{{.*}}a.h' included multiple times, additional include site here}}
+// expected-note-re@redefinition-same-header.c:12 {{'{{.*}}a.h' included multiple times, additional include site here}}
+
+#include "a.h"
+#include "a.h"
+
+int foo() { return yyy; }
diff --git a/test/Sema/typo-correction.c b/test/Sema/typo-correction.c
index 59f022dfe528..78007015dcae 100644
--- a/test/Sema/typo-correction.c
+++ b/test/Sema/typo-correction.c
@@ -80,3 +80,10 @@ int h() {
g(x, 5 ? z : 0); // expected-error 2 {{use of undeclared identifier}}
(x, 5 ? z : 0); // expected-error 2 {{use of undeclared identifier}}
}
+
+__attribute__((overloadable)) void func_overloadable(int);
+__attribute__((overloadable)) void func_overloadable(float);
+
+void overloadable_callexpr(int arg) {
+ func_overloadable(ar); //expected-error{{use of undeclared identifier}}
+}
diff --git a/test/Sema/vector-cast.c b/test/Sema/vector-cast.c
index ea4acfac6a0b..cf23eb2742c4 100644
--- a/test/Sema/vector-cast.c
+++ b/test/Sema/vector-cast.c
@@ -53,9 +53,8 @@ void f4() {
float2 f2;
double d, a, b, c;
float64x2_t v = {0.0, 1.0};
- // FIXME: These diagnostics are inaccurate: should complain that 'double' to vector 'float2' involves truncation
- f2 += d; // expected-error {{cannot convert between vector values of different size ('float2' (vector of 2 'float' values) and 'double')}}
- d += f2; // expected-error {{cannot convert between vector values of different size}}
+ f2 += d; // expected-error {{cannot convert between scalar type 'double' and vector type 'float2' (vector of 2 'float' values) as implicit conversion would cause truncation}}
+ d += f2; // expected-error {{assigning to 'double' from incompatible type 'float2' (vector of 2 'float' values)}}
a = 3.0 + vget_low_f64(v);
b = vget_low_f64(v) + 3.0;
c = vget_low_f64(v);
diff --git a/test/Sema/vector-gcc-compat.c b/test/Sema/vector-gcc-compat.c
new file mode 100644
index 000000000000..9eb0569b25f0
--- /dev/null
+++ b/test/Sema/vector-gcc-compat.c
@@ -0,0 +1,330 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -triple x86_64-apple-darwin10
+
+// Test the compatibility of clang's vector extensions with gcc's vector
+// extensions for C. Notably &&, ||, ?: and ! are not available.
+typedef long long v2i64 __attribute__((vector_size(16)));
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef short v2i16 __attribute__((vector_size(4)));
+typedef char v2i8 __attribute__((vector_size(2)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16)));
+typedef unsigned int v2u32 __attribute__((vector_size(8)));
+typedef unsigned short v2u16 __attribute__((vector_size(4)));
+typedef unsigned char v2u8 __attribute__((vector_size(2)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v2f64 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+typedef int v4i32 __attribute((vector_size(16)));
+
+void arithmeticTest(void);
+void logicTest(void);
+void comparisonTest(void);
+void floatTestSignedType(char a, short b, int c, long long d);
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d);
+void floatTestConstant(void);
+void intTestType(char a, short b, int c, long long d);
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d);
+void uintTestType(char a, short b, int c, long long d);
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d);
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a, v2u8 v2u8_a);
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a);
+
+void arithmeticTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1};
+ v2i64 v2i64_r;
+
+ v2i64_r = v2i64_a + 1;
+ v2i64_r = v2i64_a - 1;
+ v2i64_r = v2i64_a * 1;
+ v2i64_r = v2i64_a / 1;
+ v2i64_r = v2i64_a % 1;
+
+ v2i64_r = 1 + v2i64_a;
+ v2i64_r = 1 - v2i64_a;
+ v2i64_r = 1 * v2i64_a;
+ v2i64_r = 1 / v2i64_a;
+ v2i64_r = 1 % v2i64_a;
+
+ v2i64_a += 1;
+ v2i64_a -= 1;
+ v2i64_a *= 1;
+ v2i64_a /= 1;
+ v2i64_a %= 1;
+}
+
+void comparisonTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1};
+ v2i64 v2i64_r;
+
+ v2i64_r = v2i64_a == 1;
+ v2i64_r = v2i64_a != 1;
+ v2i64_r = v2i64_a < 1;
+ v2i64_r = v2i64_a > 1;
+ v2i64_r = v2i64_a <= 1;
+ v2i64_r = v2i64_a >= 1;
+
+ v2i64_r = 1 == v2i64_a;
+ v2i64_r = 1 != v2i64_a;
+ v2i64_r = 1 < v2i64_a;
+ v2i64_r = 1 > v2i64_a;
+ v2i64_r = 1 <= v2i64_a;
+ v2i64_r = 1 >= v2i64_a;
+}
+
+void logicTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1};
+ v2i64 v2i64_b = (v2i64){2, 1};
+ v2i64 v2i64_c = (v2i64){3, 1};
+ v2i64 v2i64_r;
+
+ v2i64_r = !v2i64_a; // expected-error {{invalid argument type 'v2i64' (vector of 2 'long long' values) to unary expression}}
+ v2i64_r = ~v2i64_a;
+
+ v2i64_r = v2i64_a ? v2i64_b : v2i64_c; // expected-error {{used type 'v2i64' (vector of 2 'long long' values) where arithmetic or pointer type is required}}
+
+ v2i64_r = v2i64_a & 1;
+ v2i64_r = v2i64_a | 1;
+ v2i64_r = v2i64_a ^ 1;
+
+ v2i64_r = 1 & v2i64_a;
+ v2i64_r = 1 | v2i64_a;
+ v2i64_r = 1 ^ v2i64_a;
+
+ v2i64_a &= 1;
+ v2i64_a |= 1;
+ v2i64_a ^= 1;
+
+ v2i64_r = v2i64_a && 1; // expected-error {{logical expression with vector type 'v2i64' (vector of 2 'long long' values) and non-vector type 'int' is only supported in C++}}
+ v2i64_r = v2i64_a || 1; // expected-error {{logical expression with vector type 'v2i64' (vector of 2 'long long' values) and non-vector type 'int' is only supported in C++}}
+
+ v2i64_r = v2i64_a && v2i64_a; // expected-error {{logical expression with vector types 'v2i64' (vector of 2 'long long' values) and 'v2i64' is only supported in C++}}
+ v2i64_r = v2i64_a || v2i64_a; // expected-error {{logical expression with vector types 'v2i64' (vector of 2 'long long' values) and 'v2i64' is only supported in C++}}
+
+ v2i64_r = v2i64_a << 1;
+ v2i64_r = v2i64_a >> 1;
+
+ v2i64_r = 1 << v2i64_a;
+ v2i64_r = 1 >> v2i64_a;
+
+ v2i64_a <<= 1;
+ v2i64_a >>= 1;
+}
+
+// For operations with floating point types, we check that interger constants
+// can be respresented, or failing that checking based on the integer types.
+void floatTestConstant(void) {
+ // Test that constants added to floats must be expressible as floating point
+ // numbers.
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f32_a = v4f32_a + 1;
+ v4f32_a = v4f32_a + 0xFFFFFF;
+ v4f32_a = v4f32_a + (-1567563LL);
+ v4f32_a = v4f32_a + (16777208);
+ v4f32_a = v4f32_a + (16777219); // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+}
+
+void floatTestConstantComparison(void);
+void doubleTestConstantComparison(void);
+
+void floatTestConstantComparison(void) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4i32 v4i32_r;
+ v4i32_r = v4f32_a > 0.4f;
+ v4i32_r = v4f32_a >= 0.4f;
+ v4i32_r = v4f32_a < 0.4f;
+ v4i32_r = v4f32_a <= 0.4f;
+ v4i32_r = v4f32_a == 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v4i32_r = v4f32_a != 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void doubleTestConstantComparison(void) {
+ v2f64 v2f64_a = {0.4, 0.4};
+ v2i64 v2i64_r;
+ v2i64_r = v2f64_a > 0.4;
+ v2i64_r = v2f64_a >= 0.4;
+ v2i64_r = v2f64_a < 0.4;
+ v2i64_r = v2f64_a <= 0.4;
+ v2i64_r = v2f64_a == 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v2i64_r = v2f64_a != 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}
+}
+
+void floatTestSignedType(char a, short b, int c, long long d) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}
+}
+
+void intTestType(char a, short b, int c, long long d) {
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ v2i64_a = v2i64_a + d;
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2i32' (vector of 2 'int' values)}}
+ v2i32_a = v2i32_a + c;
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2i16' (vector of 2 'short' values)}}
+ v2i16_a = v2i16_a + b;
+ v2i16_a = v2i16_a + a;
+
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2i8' (vector of 2 'char' values)}}
+ v2i8_a = v2i8_a + a;
+}
+
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) {
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ v2i64_a = v2i64_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i64' (vector of 2 'long long' values) as implicit conversion would cause truncation}}
+
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2i32' (vector of 2 'int' values)}}
+ v2i32_a = v2i32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i32' (vector of 2 'int' values) as implicit conversion would cause truncation}}
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2i16' (vector of 2 'short' values)}}
+ v2i16_a = v2i16_a + b; // expected-error {{cannot convert between scalar type 'unsigned short' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}
+ v2i16_a = v2i16_a + a;
+
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2i8' (vector of 2 'char' values)}}
+ v2i8_a = v2i8_a + a; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+}
+
+void uintTestType(char a, short b, int c, long long d) {
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d; // expected-warning {{implicit conversion changes signedness: 'long long' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u32' (vector of 2 'unsigned int' values)}}
+
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u16' (vector of 2 'unsigned short' values)}}
+
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u8' (vector of 2 'unsigned char' values)}}
+}
+
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) {
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d;
+ v2u64_a = v2u64_a + c;
+ v2u64_a = v2u64_a + b;
+ v2u64_a = v2u64_a + a;
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c;
+ v2u32_a = v2u32_a + b;
+ v2u32_a = v2u32_a + a;
+
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b;
+ v2u16_a = v2u16_a + a;
+
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a;
+}
+
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a,
+ v2u8 v2u8_a) {
+ v2u64_a = v2u64_a + 0xFFFFFFFFFFFFFFFF;
+ v2u32_a = v2u32_a + 0xFFFFFFFF;
+ v2u16_a = v2u16_a + 0xFFFF;
+ v2u8_a = v2u8_a + 0xFF;
+
+ v2u32_a = v2u32_a + 0x1FFFFFFFF; // expected-warning {{implicit conversion from 'long' to 'v2u32' (vector of 2 'unsigned int' values) changes value from 8589934591 to 4294967295}}
+ v2u16_a = v2u16_a + 0x1FFFF; // expected-warning {{implicit conversion from 'int' to 'v2u16' (vector of 2 'unsigned short' values) changes value from 131071 to 65535}}
+ v2u8_a = v2u8_a + 0x1FF; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+}
+
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a) {
+ // Legal upper bounds.
+ v2i64_a = v2i64_a + (long long)0x7FFFFFFFFFFFFFFF;
+ v2i32_a = v2i32_a + (int)0x7FFFFFFF;
+ v2i16_a = v2i16_a + (short)0x7FFF;
+ v2i8_a = v2i8_a + (char)0x7F;
+
+ // Legal lower bounds.
+ v2i64_a = v2i64_a + (-9223372036854775807);
+ v2i32_a = v2i32_a + (-2147483648);
+ v2i16_a = v2i16_a + (-32768);
+ v2i8_a = v2i8_a + (-128);
+
+ // One increment/decrement more than the type can hold
+ v2i32_a = v2i32_a + 2147483648; // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from 2147483648 to -2147483648}}
+ v2i16_a = v2i16_a + 32768; // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from 32768 to -32768}}
+ v2i8_a = v2i8_a + 128; // expected-warning {{implicit conversion from 'int' to 'v2i8' (vector of 2 'char' values) changes value from 128 to -128}}
+
+ v2i32_a = v2i32_a + (-2147483649); // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from -2147483649 to 2147483647}}
+ v2i16_a = v2i16_a + (-32769); // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from -32769 to 32767}}
+ v2i8_a = v2i8_a + (-129); // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+}
diff --git a/test/Sema/vector-gcc-compat.cpp b/test/Sema/vector-gcc-compat.cpp
new file mode 100644
index 000000000000..12da314c325f
--- /dev/null
+++ b/test/Sema/vector-gcc-compat.cpp
@@ -0,0 +1,328 @@
+// RUN: %clang_cc1 %s -verify -fsyntax-only -Weverything -std=c++11 -triple x86_64-apple-darwin10
+
+// Test the compatibility of clang++'s vector extensions with g++'s vector
+// extensions. In comparison to the extensions available in C, the !, ?:, && and
+// || operators work on vector types.
+
+typedef long long v2i64 __attribute__((vector_size(16))); // expected-warning {{'long long' is incompatible with C++98}}
+typedef int v2i32 __attribute__((vector_size(8)));
+typedef short v2i16 __attribute__((vector_size(4)));
+typedef char v2i8 __attribute__((vector_size(2)));
+
+typedef unsigned long long v2u64 __attribute__((vector_size(16))); // expected-warning {{'long long' is incompatible with C++98}}
+typedef unsigned int v2u32 __attribute__((vector_size(8)));
+typedef unsigned short v2u16 __attribute__((vector_size(4)));
+typedef unsigned char v2u8 __attribute__((vector_size(2)));
+
+typedef float v4f32 __attribute__((vector_size(16)));
+typedef double v2f64 __attribute__((vector_size(16)));
+typedef double v4f64 __attribute__((vector_size(32)));
+typedef int v4i32 __attribute((vector_size(16)));
+
+void arithmeticTest(void);
+void logicTest(void);
+void comparisonTest(void);
+void floatTestSignedType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void floatTestConstant(void);
+void intTestType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void uintTestType(char a, short b, int c, long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d); // expected-warning {{'long long' is incompatible with C++98}}
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a, v2u8 v2u8_a);
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a);
+
+void arithmeticTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_r;
+
+ v2i64_r = v2i64_a + 1;
+ v2i64_r = v2i64_a - 1;
+ v2i64_r = v2i64_a * 1;
+ v2i64_r = v2i64_a / 1;
+ v2i64_r = v2i64_a % 1;
+
+ v2i64_r = 1 + v2i64_a;
+ v2i64_r = 1 - v2i64_a;
+ v2i64_r = 1 * v2i64_a;
+ v2i64_r = 1 / v2i64_a;
+ v2i64_r = 1 % v2i64_a;
+
+ v2i64_a += 1;
+ v2i64_a -= 1;
+ v2i64_a *= 1;
+ v2i64_a /= 1;
+ v2i64_a %= 1;
+}
+
+void comparisonTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_r;
+
+ v2i64_r = v2i64_a == 1;
+ v2i64_r = v2i64_a != 1;
+ v2i64_r = v2i64_a < 1;
+ v2i64_r = v2i64_a > 1;
+ v2i64_r = v2i64_a <= 1;
+ v2i64_r = v2i64_a >= 1;
+
+ v2i64_r = 1 == v2i64_a;
+ v2i64_r = 1 != v2i64_a;
+ v2i64_r = 1 < v2i64_a;
+ v2i64_r = 1 > v2i64_a;
+ v2i64_r = 1 <= v2i64_a;
+ v2i64_r = 1 >= v2i64_a;
+}
+
+void logicTest(void) {
+ v2i64 v2i64_a = (v2i64){0, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_b = (v2i64){2, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_c = (v2i64){3, 1}; // expected-warning {{compound literals are a C99-specific feature}}
+ v2i64 v2i64_r;
+
+ v2i64_r = !v2i64_a; // expected-error {{invalid argument type 'v2i64' (vector of 2 'long long' values) to unary expression}}
+ v2i64_r = ~v2i64_a;
+
+ v2i64_r = v2i64_a ? v2i64_b : v2i64_c; // expected-error {{value of type 'v2i64' (vector of 2 'long long' values) is not contextually convertible to 'bool'}}
+
+ v2i64_r = v2i64_a & 1;
+ v2i64_r = v2i64_a | 1;
+ v2i64_r = v2i64_a ^ 1;
+
+ v2i64_r = 1 & v2i64_a;
+ v2i64_r = 1 | v2i64_a;
+ v2i64_r = 1 ^ v2i64_a;
+ v2i64_a &= 1;
+ v2i64_a |= 1;
+ v2i64_a ^= 1;
+
+ v2i64_r = v2i64_a && 1;
+ v2i64_r = v2i64_a || 1;
+
+ v2i64_r = v2i64_a << 1;
+ v2i64_r = v2i64_a >> 1;
+
+ v2i64_r = 1 << v2i64_a;
+ v2i64_r = 1 >> v2i64_a;
+
+ v2i64_a <<= 1;
+ v2i64_a >>= 1;
+}
+
+// For operations with floating point types, we check that interger constants
+// can be respresented, or failing that checking based on the integer types.
+void floatTestConstant(void) {
+ // Test that constants added to floats must be expressible as floating point
+ // numbers.
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f32_a = v4f32_a + 1;
+ v4f32_a = v4f32_a + 0xFFFFFF;
+ v4f32_a = v4f32_a + (-1567563LL); // expected-warning {{'long long' is incompatible with C++98}}
+ v4f32_a = v4f32_a + (16777208);
+ v4f32_a = v4f32_a + (16777219); // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+}
+
+void floatTestConstantComparison(void);
+void doubleTestConstantComparison(void);
+
+void floatTestConstantComparison(void) {
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4i32 v4i32_r;
+ v4i32_r = v4f32_a > 0.4f;
+ v4i32_r = v4f32_a >= 0.4f;
+ v4i32_r = v4f32_a < 0.4f;
+ v4i32_r = v4f32_a <= 0.4f;
+ v4i32_r = v4f32_a == 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v4i32_r = v4f32_a != 0.4f; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void doubleTestConstantComparison(void) {
+ v2f64 v2f64_a = {0.4, 0.4};
+ v2i64 v2i64_r;
+ v2i64_r = v2f64_a > 0.4;
+ v2i64_r = v2f64_a >= 0.4;
+ v2i64_r = v2f64_a < 0.4;
+ v2i64_r = v2f64_a <= 0.4;
+ v2i64_r = v2f64_a == 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+ v2i64_r = v2f64_a != 0.4; // expected-warning {{comparing floating point with == or != is unsafe}}
+}
+
+void floatTestUnsignedType(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}
+}
+
+void floatTestSignedType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v4f32 v4f32_a = {0.4f, 0.4f, 0.4f, 0.4f};
+ v4f64 v4f64_b = {0.4, 0.4, 0.4, 0.4};
+
+ v4f32_a = v4f32_a + a;
+ v4f32_a = v4f32_a + b;
+ v4f32_a = v4f32_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+ v4f32_a = v4f32_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f32' (vector of 4 'float' values) as implicit conversion would cause truncation}}
+
+ v4f64_b = v4f64_b + a;
+ v4f64_b = v4f64_b + b;
+ v4f64_b = v4f64_b + c;
+ v4f64_b = v4f64_b + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v4f64' (vector of 4 'double' values) as implicit conversion would cause truncation}}
+}
+
+void intTestType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ v2i64_a = v2i64_a + d;
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2i32' (vector of 2 'int' values)}}
+ v2i32_a = v2i32_a + c;
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2i16' (vector of 2 'short' values)}}
+ v2i16_a = v2i16_a + b;
+ v2i16_a = v2i16_a + a;
+
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2i8' (vector of 2 'char' values)}}
+ v2i8_a = v2i8_a + a;
+}
+
+void intTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2i64 v2i64_a = {1, 2};
+ v2i32 v2i32_a = {1, 2};
+ v2i16 v2i16_a = {1, 2};
+ v2i8 v2i8_a = {1, 2};
+
+ v2i64_a = v2i64_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i64' (vector of 2 'long long' values) as implicit conversion would cause truncation}}
+
+ v2i64_a = v2i64_a + c;
+ v2i64_a = v2i64_a + b;
+ v2i64_a = v2i64_a + a;
+
+ v2i32_a = v2i32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2i32' (vector of 2 'int' values)}}
+ v2i32_a = v2i32_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i32' (vector of 2 'int' values) as implicit conversion would cause truncation}}
+ v2i32_a = v2i32_a + b;
+ v2i32_a = v2i32_a + a;
+
+ v2i16_a = v2i16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}
+ v2i16_a = v2i16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2i16' (vector of 2 'short' values)}}
+ v2i16_a = v2i16_a + b; // expected-error {{cannot convert between scalar type 'unsigned short' and vector type 'v2i16' (vector of 2 'short' values) as implicit conversion would cause truncation}}
+ v2i16_a = v2i16_a + a;
+
+ v2i8_a = v2i8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+ v2i8_a = v2i8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2i8' (vector of 2 'char' values)}}
+ v2i8_a = v2i8_a + a; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+}
+
+void uintTestType(char a, short b, int c, long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d; // expected-warning {{implicit conversion changes signedness: 'long long' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+ v2u64_a = v2u64_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u64' (vector of 2 'unsigned long long' values)}}
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c; // expected-warning {{implicit conversion changes signedness: 'int' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u32' (vector of 2 'unsigned int' values)}}
+
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b; // expected-warning {{implicit conversion changes signedness: 'short' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u16' (vector of 2 'unsigned short' values)}}
+
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a; // expected-warning {{implicit conversion changes signedness: 'char' to 'v2u8' (vector of 2 'unsigned char' values)}}
+}
+
+void uintTestTypeUnsigned(unsigned char a, unsigned short b, unsigned int c,
+ unsigned long long d) { // expected-warning {{'long long' is incompatible with C++98}}
+ v2u64 v2u64_a = {1, 2};
+ v2u32 v2u32_a = {1, 2};
+ v2u16 v2u16_a = {1, 2};
+ v2u8 v2u8_a = {1, 2};
+
+ v2u64_a = v2u64_a + d;
+ v2u64_a = v2u64_a + c;
+ v2u64_a = v2u64_a + b;
+ v2u64_a = v2u64_a + a;
+
+ v2u32_a = v2u32_a + d; // expected-warning {{implicit conversion loses integer precision: 'unsigned long long' to 'v2u32' (vector of 2 'unsigned int' values)}}
+ v2u32_a = v2u32_a + c;
+ v2u32_a = v2u32_a + b;
+ v2u32_a = v2u32_a + a;
+
+ v2u16_a = v2u16_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u16' (vector of 2 'unsigned short' values) as implicit conversion would cause truncation}}
+ v2u16_a = v2u16_a + c; // expected-warning {{implicit conversion loses integer precision: 'unsigned int' to 'v2u16' (vector of 2 'unsigned short' values)}}
+ v2u16_a = v2u16_a + b;
+ v2u16_a = v2u16_a + a;
+
+ v2u8_a = v2u8_a + d; // expected-error {{cannot convert between scalar type 'unsigned long long' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + c; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+ v2u8_a = v2u8_a + b; // expected-warning {{implicit conversion loses integer precision: 'unsigned short' to 'v2u8' (vector of 2 'unsigned char' values)}}
+ v2u8_a = v2u8_a + a;
+}
+
+void uintTestConstant(v2u64 v2u64_a, v2u32 v2u32_a, v2u16 v2u16_a,
+ v2u8 v2u8_a) {
+ v2u64_a = v2u64_a + 0xFFFFFFFFFFFFFFFF;
+ v2u32_a = v2u32_a + 0xFFFFFFFF;
+ v2u16_a = v2u16_a + 0xFFFF;
+ v2u8_a = v2u8_a + 0xFF;
+
+ v2u32_a = v2u32_a + 0x1FFFFFFFF; // expected-warning {{implicit conversion from 'long' to 'v2u32' (vector of 2 'unsigned int' values) changes value from 8589934591 to 4294967295}}
+ v2u16_a = v2u16_a + 0x1FFFF; // expected-warning {{implicit conversion from 'int' to 'v2u16' (vector of 2 'unsigned short' values) changes value from 131071 to 65535}}
+ v2u8_a = v2u8_a + 0x1FF; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2u8' (vector of 2 'unsigned char' values) as implicit conversion would cause truncation}}
+}
+
+void intTestConstant(v2i64 v2i64_a, v2i32 v2i32_a, v2i16 v2i16_a, v2i8 v2i8_a) {
+ // Legal upper bounds.
+ v2i64_a = v2i64_a + static_cast<long long>(0x7FFFFFFFFFFFFFFF); // expected-warning {{'long long' is incompatible with C++98}}
+ v2i32_a = v2i32_a + static_cast<int>(0x7FFFFFFF);
+ v2i16_a = v2i16_a + static_cast<short>(0x7FFF);
+ v2i8_a = v2i8_a + static_cast<char>(0x7F);
+
+ // Legal lower bounds.
+ v2i64_a = v2i64_a + (-9223372036854775807);
+ v2i32_a = v2i32_a + (-2147483648);
+ v2i16_a = v2i16_a + (-32768);
+ v2i8_a = v2i8_a + (-128);
+
+ // One increment/decrement more than the type can hold
+ v2i32_a = v2i32_a + 2147483648; // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from 2147483648 to -2147483648}}
+ v2i16_a = v2i16_a + 32768; // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from 32768 to -32768}}
+ v2i8_a = v2i8_a + 128; // expected-warning {{implicit conversion from 'int' to 'v2i8' (vector of 2 'char' values) changes value from 128 to -128}}
+
+ v2i32_a = v2i32_a + (-2147483649); // expected-warning {{implicit conversion from 'long' to 'v2i32' (vector of 2 'int' values) changes value from -2147483649 to 2147483647}}
+ v2i16_a = v2i16_a + (-32769); // expected-warning {{implicit conversion from 'int' to 'v2i16' (vector of 2 'short' values) changes value from -32769 to 32767}}
+ v2i8_a = v2i8_a + (-129); // expected-error {{cannot convert between scalar type 'int' and vector type 'v2i8' (vector of 2 'char' values) as implicit conversion would cause truncation}}
+}
diff --git a/test/Sema/vector-ops.c b/test/Sema/vector-ops.c
index 9cdd9d2f1748..575f38b972f5 100644
--- a/test/Sema/vector-ops.c
+++ b/test/Sema/vector-ops.c
@@ -13,11 +13,11 @@ void test1(v2u v2ua, v2s v2sa, v2f v2fa) {
(void)(~v2fa); // expected-error{{invalid argument type 'v2f' (vector of 2 'float' values) to unary}}
// Comparison operators
- v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2ua = (v2ua==v2sa); // expected-warning{{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values}}
v2sa = (v2ua==v2sa);
// Arrays
- int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values)}}
+ int array1[v2ua]; // expected-error{{size of array has non-integer type 'v2u' (vector of 2 'unsigned int' values}}
int array2[17];
// FIXME: error message below needs type!
(void)(array2[v2ua]); // expected-error{{array subscript is not an integer}}
@@ -28,108 +28,108 @@ void test1(v2u v2ua, v2s v2sa, v2f v2fa) {
}
void testLogicalVecVec(v2u v2ua, v2s v2sa, v2f v2fa) {
-
// Logical operators
- v2ua = v2ua && v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2ua = v2ua || v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2ua = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
+ v2ua = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
- v2ua = v2sa && v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2ua = v2sa || v2ua; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2ua = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
+ v2ua = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
- v2ua = v2ua && v2fa; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2ua = v2ua || v2fa; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2ua = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2ua = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
- v2ua = v2sa && v2fa; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2ua = v2sa || v2fa; // expected-warning {{incompatible vector types assigning to 'v2u' (vector of 2 'unsigned int' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2ua = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2ua = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
- v2sa = v2sa && v2sa;
- v2sa = v2sa || v2sa;
+ v2sa = v2sa && v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
+ v2sa = v2sa || v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
- v2sa = v2ua && v2ua;
- v2sa = v2ua || v2ua;
+ v2sa = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
+ v2sa = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
- v2sa = v2sa && v2ua;
- v2sa = v2sa || v2ua;
+ v2sa = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
+ v2sa = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
- v2sa = v2sa && v2fa;
- v2sa = v2sa || v2fa;
+ v2sa = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2sa = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
- v2sa = v2ua && v2fa;
- v2sa = v2ua || v2fa;
+ v2sa = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2sa = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
- v2fa = v2fa && v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2fa = v2fa || v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2fa = v2fa && v2fa; // expected-error {{logical expression with vector types 'v2f' (vector of 2 'float' values) and 'v2f'}}
+ v2fa = v2fa || v2fa; // expected-error {{logical expression with vector types 'v2f' (vector of 2 'float' values) and 'v2f'}}
- v2fa = v2sa && v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2fa = v2sa || v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2fa = v2sa && v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2fa = v2sa || v2fa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2f' (vector of 2 'float' values)}}
- v2fa = v2ua && v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2fa = v2ua || v2fa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2fa = v2ua && v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
+ v2fa = v2ua || v2fa; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2f' (vector of 2 'float' values)}}
- v2fa = v2ua && v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2fa = v2ua || v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2fa = v2ua && v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
+ v2fa = v2ua || v2ua; // expected-error {{logical expression with vector types 'v2u' (vector of 2 'unsigned int' values) and 'v2u'}}
- v2fa = v2sa && v2sa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2fa = v2sa || v2sa; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2fa = v2sa && v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
+ v2fa = v2sa || v2sa; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2s'}}
- v2fa = v2sa && v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
- v2fa = v2sa || v2ua; // expected-warning {{incompatible vector types assigning to 'v2f' (vector of 2 'float' values) from '__attribute__((__vector_size__(2 * sizeof(int)))) int' (vector of 2 'int' values)}}
+ v2fa = v2sa && v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
+ v2fa = v2sa || v2ua; // expected-error {{logical expression with vector types 'v2s' (vector of 2 'int' values) and 'v2u' (vector of 2 'unsigned int' values)}}
}
void testLogicalVecScalar(v2u v2ua, v2s v2sa, v2f v2fa) {
-
unsigned u1;
- v2ua = v2ua && u1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}}
- v2ua = v2ua || u1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}}
+ v2ua = v2ua && u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
+ v2ua = v2ua || u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
- v2sa = v2sa && u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2sa = v2sa || u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2sa = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2sa = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2ua = v2sa && u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2ua = v2sa || u1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
- v2sa = v2ua && u1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}}
- v2sa = v2ua || u1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'unsigned int')}}
+ v2ua = v2sa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2ua = v2sa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2s' (vector of 2 'int' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'unsigned int')}}
+ v2sa = v2ua && u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
+ v2sa = v2ua || u1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'unsigned int' is only supported in C++}}
- v2ua = v2fa && u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
- v2ua = v2fa || u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2ua = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2ua = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
- v2sa = v2fa && u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
- v2sa = v2fa || u1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'unsigned int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2sa = v2fa && u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
+ v2sa = v2fa || u1; // expected-error {{cannot convert between scalar type 'unsigned int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'unsigned int')}}
int s1;
- v2ua = v2ua && s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
- v2ua = v2ua || s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
+ v2ua = v2ua && s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
+ v2ua = v2ua || s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
- v2sa = v2sa && s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
- v2sa = v2sa || s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
+ v2sa = v2sa && s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
+ v2sa = v2sa || s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
- v2ua = v2sa && s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
- v2ua = v2sa || s1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'int')}}
- v2sa = v2ua && s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
- v2sa = v2ua || s1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'int')}}
+ v2ua = v2sa && s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
+ v2ua = v2sa || s1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'int' is only supported in C++}}
- v2ua = v2fa && s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
- v2ua = v2fa || s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
+ v2sa = v2ua && s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
+ v2sa = v2ua || s1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'int' is only supported in C++}}
- v2sa = v2fa && s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
- v2sa = v2fa || s1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'int')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int')}}
+ v2ua = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
+ v2ua = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
+
+ v2sa = v2fa && s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
+ v2sa = v2fa || s1; // expected-error {{cannot convert between scalar type 'int' and vector type 'v2f' (vector of 2 'float' values) as implicit conversion would cause truncation}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'int'}}
float f1;
- v2ua = v2ua && f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
- v2ua = v2ua || f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
+ v2ua = v2ua && f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
+ v2ua = v2ua || f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
+
+ v2sa = v2sa && f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
+ v2sa = v2sa || f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
- v2sa = v2sa && f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
- v2sa = v2sa || f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
+ v2ua = v2sa && f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
+ v2ua = v2sa || f1; // expected-error {{logical expression with vector type 'v2s' (vector of 2 'int' values) and non-vector type 'float' is only supported in C++}}
- v2ua = v2sa && f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
- v2ua = v2sa || f1; // expected-error {{cannot convert between vector values of different size ('v2s' (vector of 2 'int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2s' (vector of 2 'int' values) and 'float')}}
- v2sa = v2ua && f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
- v2sa = v2ua || f1; // expected-error {{cannot convert between vector values of different size ('v2u' (vector of 2 'unsigned int' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2u' (vector of 2 'unsigned int' values) and 'float')}}
+ v2sa = v2ua && f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
+ v2sa = v2ua || f1; // expected-error {{logical expression with vector type 'v2u' (vector of 2 'unsigned int' values) and non-vector type 'float' is only supported in C++}}
- v2ua = v2fa && f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
- v2ua = v2fa || f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
+ v2ua = v2fa && f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
+ v2ua = v2fa || f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
- v2sa = v2fa && f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
- v2sa = v2fa || f1; // expected-error {{cannot convert between vector values of different size ('v2f' (vector of 2 'float' values) and 'float')}} expected-error {{invalid operands to binary expression ('v2f' (vector of 2 'float' values) and 'float')}}
+ v2sa = v2fa && f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
+ v2sa = v2fa || f1; // expected-error {{logical expression with vector type 'v2f' (vector of 2 'float' values) and non-vector type 'float' is only supported in C++}}
}
diff --git a/test/Sema/zvector.c b/test/Sema/zvector.c
index d1cf1aa01f4b..740163fcd9d5 100644
--- a/test/Sema/zvector.c
+++ b/test/Sema/zvector.c
@@ -326,14 +326,14 @@ void foo(void)
bc = bc + sc2; // expected-error {{incompatible type}}
bc = sc + bc2; // expected-error {{incompatible type}}
- sc = sc + sc_scalar; // expected-error {{cannot convert}}
- sc = sc + uc_scalar; // expected-error {{cannot convert}}
- sc = sc_scalar + sc; // expected-error {{cannot convert}}
- sc = uc_scalar + sc; // expected-error {{cannot convert}}
- uc = uc + sc_scalar; // expected-error {{cannot convert}}
- uc = uc + uc_scalar; // expected-error {{cannot convert}}
- uc = sc_scalar + uc; // expected-error {{cannot convert}}
- uc = uc_scalar + uc; // expected-error {{cannot convert}}
+ sc = sc + sc_scalar;
+ sc = sc + uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+ sc = sc_scalar + sc;
+ sc = uc_scalar + sc; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+ uc = uc + sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ uc = uc + uc_scalar;
+ uc = sc_scalar + uc; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ uc = uc_scalar + uc;
ss = ss + ss2;
us = us + us2;
@@ -368,10 +368,10 @@ void foo(void)
sc += sl2; // expected-error {{cannot convert}}
sc += fd2; // expected-error {{cannot convert}}
- sc += sc_scalar; // expected-error {{cannot convert}}
- sc += uc_scalar; // expected-error {{cannot convert}}
- uc += sc_scalar; // expected-error {{cannot convert}}
- uc += uc_scalar; // expected-error {{cannot convert}}
+ sc += sc_scalar;
+ sc += uc_scalar; // expected-error {{cannot convert between scalar type 'unsigned char' and vector type '__vector signed char' (vector of 16 'signed char' values) as implicit conversion would cause truncation}}
+ uc += sc_scalar; // expected-error {{implicit conversion changes signedness: 'signed char' to '__vector unsigned char' (vector of 16 'unsigned char' values)}}
+ uc += uc_scalar;
ss += ss2;
us += us2;
diff --git a/test/SemaCXX/constructor-initializer.cpp b/test/SemaCXX/constructor-initializer.cpp
index c5de33cedb90..102ff1e80d03 100644
--- a/test/SemaCXX/constructor-initializer.cpp
+++ b/test/SemaCXX/constructor-initializer.cpp
@@ -302,3 +302,22 @@ namespace PR14073 {
struct S2 { union { union { int n; }; char c; }; S2() : n(n) {} }; // expected-warning {{field 'n' is uninitialized when used here}}
struct S3 { struct { int n; }; S3() : n(n) {} }; // expected-warning {{field 'n' is uninitialized when used here}}
}
+
+namespace PR10758 {
+struct A;
+struct B {
+ B (A const &); // expected-note 2 {{candidate constructor not viable: no known conversion from 'const PR10758::B' to 'const PR10758::A &' for 1st argument}}
+ B (B &); // expected-note 2 {{candidate constructor not viable: 1st argument ('const PR10758::B') would lose const qualifier}}
+};
+struct A {
+ A (B); // expected-note 2 {{passing argument to parameter here}}
+};
+
+B f(B const &b) {
+ return b; // expected-error {{no matching constructor for initialization of 'PR10758::B'}}
+}
+
+A f2(const B &b) {
+ return b; // expected-error {{no matching constructor for initialization of 'PR10758::B'}}
+}
+}
diff --git a/test/SemaCXX/cxx1y-generic-lambdas.cpp b/test/SemaCXX/cxx1y-generic-lambdas.cpp
index 1993c6e1853d..9f3c77591a86 100644
--- a/test/SemaCXX/cxx1y-generic-lambdas.cpp
+++ b/test/SemaCXX/cxx1y-generic-lambdas.cpp
@@ -986,3 +986,10 @@ class Enclosing3 {
);
};
}
+
+namespace PR32638 {
+ //https://bugs.llvm.org/show_bug.cgi?id=32638
+ void test() {
+ [](auto x) noexcept(noexcept(x)) { } (0);
+ }
+} \ No newline at end of file
diff --git a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
index b4963646838c..a78548b6f128 100644
--- a/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
+++ b/test/SemaCXX/cxx1y-variable-templates_top_level.cpp
@@ -9,7 +9,7 @@
#endif
template<typename T>
-T pi = T(3.1415926535897932385); // expected-note {{template is declared here}}
+T pi = T(3.1415926535897932385); // expected-note 2{{declared here}}
template<typename T>
CONST T cpi = T(3.1415926535897932385); // expected-note {{template is declared here}}
@@ -58,10 +58,9 @@ namespace use_in_top_level_funcs {
namespace shadow {
void foo() {
int ipi0 = pi<int>;
- int pi;
+ int pi; // expected-note {{found}}
int a = pi;
- int ipi = pi<int>; // expected-error {{expected '(' for function-style cast or type construction}} \
- // expected-error {{expected expression}}
+ int ipi = pi<int>; // expected-error {{'pi' does not name a template but is followed by template arguments; did you mean '::pi'?}}
}
}
diff --git a/test/SemaCXX/enable_if.cpp b/test/SemaCXX/enable_if.cpp
index 9a06d3866110..93014f50d508 100644
--- a/test/SemaCXX/enable_if.cpp
+++ b/test/SemaCXX/enable_if.cpp
@@ -499,3 +499,17 @@ void run() {
}
}
}
+
+namespace TypeOfFn {
+ template <typename T, typename U>
+ struct is_same;
+
+ template <typename T> struct is_same<T, T> {
+ enum { value = 1 };
+ };
+
+ void foo(int a) __attribute__((enable_if(a, "")));
+ void foo(float a) __attribute__((enable_if(1, "")));
+
+ static_assert(is_same<__typeof__(foo)*, decltype(&foo)>::value, "");
+}
diff --git a/test/SemaCXX/for-range-examples.cpp b/test/SemaCXX/for-range-examples.cpp
index 08a9982c6378..d6b527ff8a50 100644
--- a/test/SemaCXX/for-range-examples.cpp
+++ b/test/SemaCXX/for-range-examples.cpp
@@ -241,3 +241,37 @@ namespace pr18587 {
}
}
}
+
+namespace PR32933 {
+// https://bugs.llvm.org/show_bug.cgi?id=32933
+void foo ()
+{
+ int b = 1, a[b];
+ a[0] = 0;
+ [&] { for (int c : a) 0; } ();
+}
+
+
+int foo(int b) {
+ int varr[b][(b+=8)];
+ b = 15;
+ [&] {
+ int i = 0;
+ for (auto &c : varr)
+ {
+ c[0] = ++b;
+ }
+ [&] {
+ int i = 0;
+ for (auto &c : varr) {
+ int j = 0;
+ for(auto &c2 : c) {
+ ++j;
+ }
+ ++i;
+ }
+ }();
+ }();
+ return b;
+}
+} \ No newline at end of file
diff --git a/test/SemaCXX/invalid-member-expr.cpp b/test/SemaCXX/invalid-member-expr.cpp
index 172be6b8266d..fd50d328da67 100644
--- a/test/SemaCXX/invalid-member-expr.cpp
+++ b/test/SemaCXX/invalid-member-expr.cpp
@@ -53,9 +53,7 @@ namespace test3 {
namespace rdar11293995 {
struct Length {
- explicit Length(PassRefPtr<CalculationValue>); // expected-error {{unknown type name}} \
- expected-error {{expected ')'}} \
- expected-note {{to match this '('}}
+ explicit Length(PassRefPtr<CalculationValue>); // expected-error {{no template named 'PassRefPtr}} expected-error {{undeclared identifier 'CalculationValue'}}
};
struct LengthSize {
diff --git a/test/SemaCXX/modules-ts.cppm b/test/SemaCXX/modules-ts.cppm
index 16695f6463a8..d1d7aaa96e6c 100644
--- a/test/SemaCXX/modules-ts.cppm
+++ b/test/SemaCXX/modules-ts.cppm
@@ -17,7 +17,8 @@ static int m; // ok, internal linkage, so no redefinition error
int n;
#if TEST >= 2
// expected-error@-2 {{redefinition of '}}
-// expected-note@-3 {{previous}}
+// expected-note@-3 {{unguarded header; consider using #ifdef guards or #pragma once}}
+// expected-note-re@modules-ts.cppm:1 {{'{{.*}}modules-ts.cppm' included multiple times, additional include site here}}
#endif
#if TEST == 0
diff --git a/test/SemaCXX/type-traits.cpp b/test/SemaCXX/type-traits.cpp
index 9da59b93c503..919122576222 100644
--- a/test/SemaCXX/type-traits.cpp
+++ b/test/SemaCXX/type-traits.cpp
@@ -1256,7 +1256,7 @@ void is_trivially_copyable2()
int t33[F(__is_trivially_copyable(ExtDefaulted))];
int t34[T(__is_trivially_copyable(const int))];
- int t35[F(__is_trivially_copyable(volatile int))];
+ int t35[T(__is_trivially_copyable(volatile int))];
}
struct CStruct {
diff --git a/test/SemaCXX/typo-correction.cpp b/test/SemaCXX/typo-correction.cpp
index c59ee618f929..2d78f06c5d33 100644
--- a/test/SemaCXX/typo-correction.cpp
+++ b/test/SemaCXX/typo-correction.cpp
@@ -524,13 +524,16 @@ namespace shadowed_template {
template <typename T> class Fizbin {}; // expected-note {{'::shadowed_template::Fizbin' declared here}}
class Baz {
int Fizbin();
- // TODO: Teach the parser to recover from the typo correction instead of
- // continuing to treat the template name as an implicit-int declaration.
- Fizbin<int> qux; // expected-error {{unknown type name 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}} \
- // expected-error {{expected member name or ';' after declaration specifiers}}
+ Fizbin<int> qux; // expected-error {{no template named 'Fizbin'; did you mean '::shadowed_template::Fizbin'?}}
};
}
+namespace no_correct_template_id_to_non_template {
+ struct Frobnatz {}; // expected-note {{declared here}}
+ Frobnats fn; // expected-error {{unknown type name 'Frobnats'; did you mean 'Frobnatz'?}}
+ Frobnats<int> fni; // expected-error-re {{no template named 'Frobnats'{{$}}}}
+}
+
namespace PR18852 {
void func() {
struct foo {
diff --git a/test/SemaCXX/vector-no-lax.cpp b/test/SemaCXX/vector-no-lax.cpp
index a85f7f9db060..3cedcb1e8ce5 100644
--- a/test/SemaCXX/vector-no-lax.cpp
+++ b/test/SemaCXX/vector-no-lax.cpp
@@ -4,6 +4,6 @@ typedef int __attribute__((vector_size (16))) vSInt32;
vSInt32 foo (vUInt32 a) {
vSInt32 b = { 0, 0, 0, 0 };
- b += a; // expected-error{{cannot convert between vector values}}
+ b += a; // expected-error{{cannot convert between vector type 'vUInt32' (vector of 4 'unsigned int' values) and vector type 'vSInt32' (vector of 4 'int' values) as implicit conversion would cause truncation}}
return b;
}
diff --git a/test/SemaCXX/warn-unused-filescoped.cpp b/test/SemaCXX/warn-unused-filescoped.cpp
index 18defee7d04a..93c6bbd7edc9 100644
--- a/test/SemaCXX/warn-unused-filescoped.cpp
+++ b/test/SemaCXX/warn-unused-filescoped.cpp
@@ -1,5 +1,5 @@
-// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -Wno-unused-local-typedefs -Wno-c++11-extensions -std=c++98 %s
-// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-member-function -Wno-unused-local-typedefs -std=c++11 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-template -Wunused-member-function -Wno-unused-local-typedefs -Wno-c++11-extensions -std=c++98 %s
+// RUN: %clang_cc1 -fsyntax-only -verify -Wunused -Wunused-template -Wunused-member-function -Wno-unused-local-typedefs -std=c++14 %s
#ifdef HEADER
@@ -65,7 +65,7 @@ namespace {
template <> void TS<int>::m() { } // expected-warning{{unused}}
template <typename T>
- void tf() { }
+ void tf() { } // expected-warning{{unused}}
template <> void tf<int>() { } // expected-warning{{unused}}
struct VS {
@@ -200,6 +200,18 @@ void bar() { void func() __attribute__((used)); }
static void func() {}
}
+namespace test9 {
+template<typename T>
+static void completeRedeclChainForTemplateSpecialization() { } // expected-warning {{unused}}
+}
+
+namespace test10 {
+#if __cplusplus >= 201103L
+template<class T>
+constexpr T pi = T(3.14); // expected-warning {{unused}}
+#endif
+}
+
namespace pr19713 {
#if __cplusplus >= 201103L
// FIXME: We should warn on both of these.
diff --git a/test/SemaObjC/method-bad-param.m b/test/SemaObjC/method-bad-param.m
index ad67a34edb00..a7f0745ddbad 100644
--- a/test/SemaObjC/method-bad-param.m
+++ b/test/SemaObjC/method-bad-param.m
@@ -20,6 +20,12 @@
}
@end
+// Ensure that this function is properly marked as a failure.
+void func_with_bad_call(bar* b, foo* f) {
+ [b cccccc:5]; // expected-warning {{instance method '-cccccc:' not found}}
+ // expected-note@-17 {{receiver is instance of class declared here}}
+}
+
void somefunc(foo x) {} // expected-error {{interface type 'foo' cannot be passed by value; did you forget * in 'foo'}}
foo somefunc2() {} // expected-error {{interface type 'foo' cannot be returned by value; did you forget * in 'foo'}}
diff --git a/test/SemaObjC/unguarded-availability.m b/test/SemaObjC/unguarded-availability.m
index ae921f4a27b3..071a21ea1b3f 100644
--- a/test/SemaObjC/unguarded-availability.m
+++ b/test/SemaObjC/unguarded-availability.m
@@ -8,7 +8,7 @@
int func_10_11() AVAILABLE_10_11; // expected-note 4 {{'func_10_11' has been explicitly marked partial here}}
#ifdef OBJCPP
-// expected-note@+2 2 {{marked partial here}}
+// expected-note@+2 6 {{marked partial here}}
#endif
int func_10_12() AVAILABLE_10_12; // expected-note 6 {{'func_10_12' has been explicitly marked partial here}}
@@ -48,7 +48,7 @@ void star_case() {
} else
func_10_11(); // expected-warning{{'func_10_11' is only available on macOS 10.11 or newer}} expected-note{{enclose 'func_10_11' in an @available check to silence this warning}}
- if (@available(macos 10.11, *)) {
+ if (@available(macOS 10.11, *)) {
if (@available(ios 8, *)) {
func_10_11();
func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{enclose}}
@@ -176,7 +176,7 @@ int instantiate_with_availability_attr() {
}
int instantiate_availability() {
- if (@available(macos 10.12, *))
+ if (@available(macOS 10.12, *))
with_availability_attr<int_10_12>();
else
with_availability_attr<int_10_12>(); // expected-warning{{'with_availability_attr<int>' is only available on macOS 10.11 or newer}} expected-warning{{'int_10_12' is only available on macOS 10.12 or newer}} expected-note 2 {{enclose}}
@@ -188,4 +188,19 @@ auto topLevelLambda = [] () {
func_10_12();
};
+void functionInFunction() {
+ func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+ struct DontWarnTwice {
+ void f() {
+ func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+ }
+ };
+ void([] () {
+ func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+ });
+ (void)(^ {
+ func_10_12(); // expected-warning{{'func_10_12' is only available on macOS 10.12 or newer}} expected-note{{@available}}
+ });
+}
+
#endif
diff --git a/test/SemaObjCXX/interface-return-type.mm b/test/SemaObjCXX/interface-return-type.mm
new file mode 100644
index 000000000000..9fff8610ae0d
--- /dev/null
+++ b/test/SemaObjCXX/interface-return-type.mm
@@ -0,0 +1,7 @@
+// RUN: %clang_cc1 -fsyntax-only -std=c++11 %s -verify
+
+@class NSObject;
+template<typename T> struct C {
+ static T f(); // expected-error {{interface type 'NSObject' cannot be returned by value; did you forget * in 'NSObject'?}}
+};
+int g() { NSObject *x = C<NSObject>::f(); }//expected-error {{no member named 'f' in 'C<NSObject>'}} expected-note {{in instantiation of template class 'C<NSObject>' requested here}}
diff --git a/test/SemaObjCXX/is-base-of.mm b/test/SemaObjCXX/is-base-of.mm
new file mode 100644
index 000000000000..9cf16661b0c5
--- /dev/null
+++ b/test/SemaObjCXX/is-base-of.mm
@@ -0,0 +1,25 @@
+// RUN: %clang_cc1 -std=c++11 -fsyntax-only -verify %s
+
+@interface NSObj
+@end
+
+@interface NSChild : NSObj
+@end
+
+static_assert(__is_base_of(NSObj, NSChild), "");
+static_assert(!__is_base_of(NSChild, NSObj), "");
+
+static_assert(__is_base_of(NSObj, NSObj), "");
+
+static_assert(!__is_base_of(NSObj *, NSChild *), "");
+static_assert(!__is_base_of(NSChild *, NSObj *), "");
+
+static_assert(__is_base_of(const volatile NSObj, NSChild), "");
+static_assert(__is_base_of(NSObj, const volatile NSChild), "");
+
+@class NSForward; // expected-note{{forward declaration of class}}
+
+static_assert(!__is_base_of(NSForward, NSObj), "");
+static_assert(!__is_base_of(NSObj, NSForward), ""); // expected-error{{incomplete type 'NSForward'}}
+
+static_assert(!__is_base_of(id, NSObj), "");
diff --git a/test/SemaOpenCL/array-init.cl b/test/SemaOpenCL/array-init.cl
new file mode 100644
index 000000000000..d9691d86dd81
--- /dev/null
+++ b/test/SemaOpenCL/array-init.cl
@@ -0,0 +1,20 @@
+// RUN: %clang_cc1 %s -verify -pedantic -fsyntax-only -cl-std=CL2.0
+// expected-no-diagnostics
+
+__kernel void k1(queue_t q1, queue_t q2) {
+ queue_t q[] = {q1, q2};
+}
+
+__kernel void k2(read_only pipe int p) {
+ reserve_id_t i1 = reserve_read_pipe(p, 1);
+ reserve_id_t i2 = reserve_read_pipe(p, 1);
+ reserve_id_t i[] = {i1, i2};
+}
+
+event_t create_event();
+__kernel void k3() {
+ event_t e1 = create_event();
+ event_t e2 = create_event();
+ event_t e[] = {e1, e2};
+}
+
diff --git a/test/SemaOpenCL/storageclass.cl b/test/SemaOpenCL/storageclass.cl
index a93f8244dcbd..f457cfd1d3f6 100644
--- a/test/SemaOpenCL/storageclass.cl
+++ b/test/SemaOpenCL/storageclass.cl
@@ -5,7 +5,7 @@ constant int G2 = 0;
int G3 = 0; // expected-error{{program scope variable must reside in constant address space}}
global int G4 = 0; // expected-error{{program scope variable must reside in constant address space}}
-void kernel foo() {
+void kernel foo(int x) {
// static is not allowed at local scope before CL2.0
static int S1 = 5; // expected-error{{variables in function scope cannot be declared static}}
static constant int S2 = 5; // expected-error{{variables in function scope cannot be declared static}}
@@ -15,6 +15,12 @@ void kernel foo() {
auto int L3 = 7; // expected-error{{OpenCL version 1.2 does not support the 'auto' storage class specifier}}
global int L4; // expected-error{{function scope variable cannot be declared in global address space}}
+
+ constant int L5 = x; // expected-error {{initializer element is not a compile-time constant}}
+ global int *constant L6 = &G4;
+ private int *constant L7 = &x; // expected-error {{initializer element is not a compile-time constant}}
+ constant int *constant L8 = &L1;
+ local int *constant L9 = &L2; // expected-error {{initializer element is not a compile-time constant}}
}
static void kernel bar() { // expected-error{{kernel functions cannot be declared static}}
@@ -29,4 +35,7 @@ void f() {
}
global int L3; // expected-error{{function scope variable cannot be declared in global address space}}
extern constant float L4;
+ extern local float L5; // expected-error{{extern variable must reside in constant address space}}
+ static int L6 = 0; // expected-error{{variables in function scope cannot be declared static}}
+ static int L7; // expected-error{{variables in function scope cannot be declared static}}
}
diff --git a/test/SemaTemplate/deduction-crash.cpp b/test/SemaTemplate/deduction-crash.cpp
index ff7421a910bd..c94c9db94e06 100644
--- a/test/SemaTemplate/deduction-crash.cpp
+++ b/test/SemaTemplate/deduction-crash.cpp
@@ -2,7 +2,7 @@
// Note that the error count below doesn't matter. We just want to
// make sure that the parser doesn't crash.
-// CHECK: 16 errors
+// CHECK: 17 errors
// PR7511
template<a>
diff --git a/test/SemaTemplate/default-arguments.cpp b/test/SemaTemplate/default-arguments.cpp
index d3e249db7ee2..b5b042c64a71 100644
--- a/test/SemaTemplate/default-arguments.cpp
+++ b/test/SemaTemplate/default-arguments.cpp
@@ -207,3 +207,19 @@ Y<false> y2;
} // end ns1
} // end ns PR26134
+
+namespace friends {
+ namespace ns {
+ template<typename> struct A {
+ template<typename> friend void f();
+ template<typename> friend struct X;
+ };
+ template<typename = int> void f(); // expected-warning 0-1{{extension}}
+ template<typename = int> struct X;
+ A<int> a;
+ }
+ namespace ns {
+ void g() { f(); }
+ X<int> *p;
+ }
+}
diff --git a/test/SemaTemplate/explicit-instantiation.cpp b/test/SemaTemplate/explicit-instantiation.cpp
index 010716dd1426..42d9f4d332a9 100644
--- a/test/SemaTemplate/explicit-instantiation.cpp
+++ b/test/SemaTemplate/explicit-instantiation.cpp
@@ -95,7 +95,7 @@ namespace PR7622 {
struct basic_streambuf;
template<typename,typename>
- struct basic_streambuf{friend bob<>()}; // expected-error{{unknown type name 'bob'}} \
+ struct basic_streambuf{friend bob<>()}; // expected-error{{no template named 'bob'}} \
// expected-error{{expected member name or ';' after declaration specifiers}}
template struct basic_streambuf<int>;
}
diff --git a/test/SemaTemplate/explicit-specialization-member.cpp b/test/SemaTemplate/explicit-specialization-member.cpp
index f302836c7e4b..c0c36808b492 100644
--- a/test/SemaTemplate/explicit-specialization-member.cpp
+++ b/test/SemaTemplate/explicit-specialization-member.cpp
@@ -1,4 +1,4 @@
-// RUN: %clang_cc1 -fsyntax-only -verify %s
+// RUN: %clang_cc1 -fsyntax-only -verify %s -fcxx-exceptions
template<typename T>
struct X0 {
typedef T* type;
@@ -57,3 +57,12 @@ template<typename T> struct Helper {
template<typename T> void Helper<T>::func<2>() {} // expected-error {{cannot specialize a member}} \
// expected-error {{no function template matches}}
}
+
+namespace SpecLoc {
+ template <typename T> struct A {
+ static int n; // expected-note {{previous}}
+ static void f(); // expected-note {{previous}}
+ };
+ template<> float A<int>::n; // expected-error {{different type}}
+ template<> void A<int>::f() throw(); // expected-error {{does not match}}
+}
diff --git a/test/SemaTemplate/ms-lookup-template-base-classes.cpp b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
index 6afc7091260d..a41248ee1b8e 100644
--- a/test/SemaTemplate/ms-lookup-template-base-classes.cpp
+++ b/test/SemaTemplate/ms-lookup-template-base-classes.cpp
@@ -347,8 +347,7 @@ template <typename T> struct B : A<T> {
};
template <typename T> struct C : A<T> {
// Incorrect form.
- NameFromBase<T> m; // expected-error {{unknown type name 'NameFromBase'}}
- //expected-error@-1 {{expected member name or ';' after declaration specifiers}}
+ NameFromBase<T> m; // expected-error {{no template named 'NameFromBase'}}
};
}
diff --git a/test/SemaTemplate/typo-template-name.cpp b/test/SemaTemplate/typo-template-name.cpp
new file mode 100644
index 000000000000..fe5201a8e26c
--- /dev/null
+++ b/test/SemaTemplate/typo-template-name.cpp
@@ -0,0 +1,43 @@
+// RUN: %clang_cc1 -std=c++1z %s -verify -Wno-unused
+
+namespace InExpr {
+ namespace A {
+ void typo_first_a(); // expected-note {{found}}
+ template<typename T> void typo_first_b(); // expected-note 2{{declared here}}
+ }
+ void testA() { A::typo_first_a<int>(); } // expected-error {{'typo_first_a' does not name a template but is followed by template arguments; did you mean 'typo_first_b'?}}
+
+ namespace B {
+ void typo_first_b(); // expected-note {{found}}
+ }
+ void testB() { B::typo_first_b<int>(); } // expected-error {{'typo_first_b' does not name a template but is followed by template arguments; did you mean 'A::typo_first_b'?}}
+
+ struct Base {
+ template<typename T> static void foo(); // expected-note 4{{declared here}}
+ int n;
+ };
+ struct Derived : Base {
+ void foo(); // expected-note {{found}}
+ };
+ // We probably don't want to suggest correcting to .Base::foo<int>
+ void testMember() { Derived().foo<int>(); } // expected-error-re {{does not name a template but is followed by template arguments{{$}}}}
+
+ struct Derived2 : Base {
+ void goo(); // expected-note {{found}}
+ };
+ void testMember2() { Derived2().goo<int>(); } // expected-error {{member 'goo' of 'InExpr::Derived2' is not a template; did you mean 'foo'?}}
+
+ void no_correction() {
+ int foo; // expected-note 3{{found}}
+
+ foo<int>(); // expected-error {{'foo' does not name a template but is followed by template arguments; did you mean 'Base::foo'?}}
+ foo<>(); // expected-error {{'foo' does not name a template but is followed by template arguments; did you mean 'Base::foo'?}}
+ foo<Base *>(); // expected-error {{'foo' does not name a template but is followed by template arguments; did you mean 'Base::foo'?}}
+
+ // These are valid expressions.
+ foo<foo; // expected-warning {{self-comparison}}
+ foo<int()>(0);
+ foo<int(), true>(false);
+ foo<Base{}.n;
+ }
+}
diff --git a/tools/c-index-test/c-index-test.c b/tools/c-index-test/c-index-test.c
index 1179fbf39113..1f5d60443197 100644
--- a/tools/c-index-test/c-index-test.c
+++ b/tools/c-index-test/c-index-test.c
@@ -809,6 +809,19 @@ static void PrintCursor(CXCursor Cursor, const char *CommentSchemaFile) {
if (clang_Cursor_isObjCOptional(Cursor))
printf(" (@optional)");
+ {
+ CXString language;
+ CXString definedIn;
+ unsigned generated;
+ if (clang_Cursor_isExternalSymbol(Cursor, &language, &definedIn,
+ &generated)) {
+ printf(" (external lang: %s, defined: %s, gen: %d)",
+ clang_getCString(language), clang_getCString(definedIn), generated);
+ clang_disposeString(language);
+ clang_disposeString(definedIn);
+ }
+ }
+
if (Cursor.kind == CXCursor_IBOutletCollectionAttr) {
CXType T =
clang_getCanonicalType(clang_getIBOutletCollectionType(Cursor));
diff --git a/tools/clang-import-test/clang-import-test.cpp b/tools/clang-import-test/clang-import-test.cpp
index d7ab18478c32..567a4bb4f0a2 100644
--- a/tools/clang-import-test/clang-import-test.cpp
+++ b/tools/clang-import-test/clang-import-test.cpp
@@ -42,6 +42,10 @@ static llvm::cl::list<std::string>
Imports("import", llvm::cl::ZeroOrMore,
llvm::cl::desc("Path to a file containing declarations to import"));
+static llvm::cl::opt<bool>
+ Direct("direct", llvm::cl::Optional,
+ llvm::cl::desc("Use the parsed declarations without indirection"));
+
static llvm::cl::list<std::string>
ClangArgs("Xcc", llvm::cl::ZeroOrMore,
llvm::cl::desc("Argument to pass to the CompilerInvocation"),
@@ -172,6 +176,14 @@ BuildCompilerInstance(ArrayRef<const char *> ClangArgv) {
return Ins;
}
+std::unique_ptr<CompilerInstance>
+BuildCompilerInstance(ArrayRef<std::string> ClangArgs) {
+ std::vector<const char *> ClangArgv(ClangArgs.size());
+ std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
+ [](const std::string &s) -> const char * { return s.data(); });
+ return init_convenience::BuildCompilerInstance(ClangArgv);
+}
+
std::unique_ptr<ASTContext>
BuildASTContext(CompilerInstance &CI, SelectorTable &ST, Builtin::Context &BC) {
auto AST = llvm::make_unique<ASTContext>(
@@ -205,6 +217,21 @@ void AddExternalSource(
CI.getASTContext().getTranslationUnitDecl()->setHasExternalVisibleStorage();
}
+std::unique_ptr<CompilerInstance> BuildIndirect(std::unique_ptr<CompilerInstance> &CI) {
+ std::vector<const char *> ClangArgv(ClangArgs.size());
+ std::transform(ClangArgs.begin(), ClangArgs.end(), ClangArgv.begin(),
+ [](const std::string &s) -> const char * { return s.data(); });
+ std::unique_ptr<CompilerInstance> IndirectCI =
+ init_convenience::BuildCompilerInstance(ClangArgv);
+ auto ST = llvm::make_unique<SelectorTable>();
+ auto BC = llvm::make_unique<Builtin::Context>();
+ std::unique_ptr<ASTContext> AST =
+ init_convenience::BuildASTContext(*IndirectCI, *ST, *BC);
+ IndirectCI->setASTContext(AST.release());
+ AddExternalSource(*IndirectCI, CI);
+ return IndirectCI;
+}
+
llvm::Error ParseSource(const std::string &Path, CompilerInstance &CI,
CodeGenerator &CG) {
SourceManager &SM = CI.getSourceManager();
@@ -231,7 +258,8 @@ Parse(const std::string &Path,
std::unique_ptr<ASTContext> AST =
init_convenience::BuildASTContext(*CI, *ST, *BC);
CI->setASTContext(AST.release());
- AddExternalSource(*CI, Imports);
+ if (Imports.size())
+ AddExternalSource(*CI, Imports);
auto LLVMCtx = llvm::make_unique<llvm::LLVMContext>();
std::unique_ptr<CodeGenerator> CG =
@@ -268,8 +296,21 @@ int main(int argc, const char **argv) {
ImportCIs.push_back(std::move(*ImportCI));
}
}
+ std::vector<std::unique_ptr<CompilerInstance>> IndirectCIs;
+ if (!Direct) {
+ for (auto &ImportCI : ImportCIs) {
+ llvm::Expected<std::unique_ptr<CompilerInstance>> IndirectCI =
+ BuildIndirect(ImportCI);
+ if (auto E = IndirectCI.takeError()) {
+ llvm::errs() << llvm::toString(std::move(E));
+ exit(-1);
+ } else {
+ IndirectCIs.push_back(std::move(*IndirectCI));
+ }
+ }
+ }
llvm::Expected<std::unique_ptr<CompilerInstance>> ExpressionCI =
- Parse(Expression, ImportCIs);
+ Parse(Expression, Direct ? ImportCIs : IndirectCIs);
if (auto E = ExpressionCI.takeError()) {
llvm::errs() << llvm::toString(std::move(E));
exit(-1);
@@ -277,3 +318,4 @@ int main(int argc, const char **argv) {
return 0;
}
}
+
diff --git a/tools/libclang/CIndex.cpp b/tools/libclang/CIndex.cpp
index c251d83e2097..9c795ae9c5b7 100644
--- a/tools/libclang/CIndex.cpp
+++ b/tools/libclang/CIndex.cpp
@@ -7479,6 +7479,35 @@ unsigned clang_Cursor_isVariadic(CXCursor C) {
return 0;
}
+unsigned clang_Cursor_isExternalSymbol(CXCursor C,
+ CXString *language, CXString *definedIn,
+ unsigned *isGenerated) {
+ if (!clang_isDeclaration(C.kind))
+ return 0;
+
+ const Decl *D = getCursorDecl(C);
+
+ auto getExternalSymAttr = [](const Decl *D) -> ExternalSourceSymbolAttr* {
+ if (auto *attr = D->getAttr<ExternalSourceSymbolAttr>())
+ return attr;
+ if (auto *dcd = dyn_cast<Decl>(D->getDeclContext())) {
+ if (auto *attr = dcd->getAttr<ExternalSourceSymbolAttr>())
+ return attr;
+ }
+ return nullptr;
+ };
+ if (auto *attr = getExternalSymAttr(D)) {
+ if (language)
+ *language = cxstring::createDup(attr->getLanguage());
+ if (definedIn)
+ *definedIn = cxstring::createDup(attr->getDefinedIn());
+ if (isGenerated)
+ *isGenerated = attr->getGeneratedDeclaration();
+ return 1;
+ }
+ return 0;
+}
+
CXSourceRange clang_Cursor_getCommentRange(CXCursor C) {
if (!clang_isDeclaration(C.kind))
return clang_getNullRange();
diff --git a/tools/libclang/libclang.exports b/tools/libclang/libclang.exports
index 895dd804b008..d9a406e5741b 100644
--- a/tools/libclang/libclang.exports
+++ b/tools/libclang/libclang.exports
@@ -35,6 +35,7 @@ clang_Cursor_getReceiverType
clang_Cursor_isAnonymous
clang_Cursor_isBitField
clang_Cursor_isDynamicCall
+clang_Cursor_isExternalSymbol
clang_Cursor_isNull
clang_Cursor_isObjCOptional
clang_Cursor_isVariadic
diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp
index 9b833a96f16a..076041406c87 100644
--- a/unittests/Format/FormatTest.cpp
+++ b/unittests/Format/FormatTest.cpp
@@ -342,7 +342,7 @@ TEST_F(FormatTest, FormatIfWithoutCompoundStatement) {
verifyFormat("if (a)\n if (b) {\n f();\n }\ng();");
FormatStyle AllowsMergedIf = getLLVMStyle();
- AllowsMergedIf.AlignEscapedNewlinesLeft = true;
+ AllowsMergedIf.AlignEscapedNewlines = FormatStyle::ENAS_Left;
AllowsMergedIf.AllowShortIfStatementsOnASingleLine = true;
verifyFormat("if (a)\n"
" // comment\n"
@@ -2106,7 +2106,7 @@ TEST_F(FormatTest, LayoutStatementsAroundPreprocessorDirectives) {
verifyIncompleteFormat("void f(\n"
"#if A\n"
- " );\n"
+ ");\n"
"#else\n"
"#endif");
}
@@ -2591,6 +2591,60 @@ TEST_F(FormatTest, BreakingBeforeNonAssigmentOperators) {
Style);
}
+TEST_F(FormatTest, AllowBinPackingInsideArguments) {
+ FormatStyle Style = getLLVMStyle();
+ Style.BreakBeforeBinaryOperators = FormatStyle::BOS_NonAssignment;
+ Style.BinPackArguments = false;
+ Style.ColumnLimit = 40;
+ verifyFormat("void test() {\n"
+ " someFunction(\n"
+ " this + argument + is + quite\n"
+ " + long + so + it + gets + wrapped\n"
+ " + but + remains + bin - packed);\n"
+ "}",
+ Style);
+ verifyFormat("void test() {\n"
+ " someFunction(arg1,\n"
+ " this + argument + is\n"
+ " + quite + long + so\n"
+ " + it + gets + wrapped\n"
+ " + but + remains + bin\n"
+ " - packed,\n"
+ " arg3);\n"
+ "}",
+ Style);
+ verifyFormat("void test() {\n"
+ " someFunction(\n"
+ " arg1,\n"
+ " this + argument + has\n"
+ " + anotherFunc(nested,\n"
+ " calls + whose\n"
+ " + arguments\n"
+ " + are + also\n"
+ " + wrapped,\n"
+ " in + addition)\n"
+ " + to + being + bin - packed,\n"
+ " arg3);\n"
+ "}",
+ Style);
+
+ Style.BreakBeforeBinaryOperators = FormatStyle::BOS_None;
+ verifyFormat("void test() {\n"
+ " someFunction(\n"
+ " arg1,\n"
+ " this + argument + has +\n"
+ " anotherFunc(nested,\n"
+ " calls + whose +\n"
+ " arguments +\n"
+ " are + also +\n"
+ " wrapped,\n"
+ " in + addition) +\n"
+ " to + being + bin - packed,\n"
+ " arg3);\n"
+ "}",
+ Style);
+}
+
TEST_F(FormatTest, ConstructorInitializers) {
verifyFormat("Constructor() : Initializer(FitsOnTheLine) {}");
verifyFormat("Constructor() : Inttializer(FitsOnTheLine) {}",
@@ -4421,7 +4475,7 @@ TEST_F(FormatTest, WrapsTemplateDeclarations) {
EXPECT_EQ("static_cast<A< //\n"
" B> *>(\n"
"\n"
- " );",
+ ");",
format("static_cast<A<//\n"
" B>*>(\n"
"\n"
@@ -6423,7 +6477,7 @@ TEST_F(FormatTest, BreaksStringLiterals) {
EXPECT_EQ("\"some text other\";", format("\"some text other\";", Style));
FormatStyle AlignLeft = getLLVMStyleWithColumns(12);
- AlignLeft.AlignEscapedNewlinesLeft = true;
+ AlignLeft.AlignEscapedNewlines = FormatStyle::ENAS_Left;
EXPECT_EQ("#define A \\\n"
" \"some \" \\\n"
" \"text \" \\\n"
@@ -6513,7 +6567,7 @@ TEST_F(FormatTest, BreaksStringLiteralsWithin_TMacro) {
"#if !TEST\n"
" _T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n"
"#endif\n"
- " );",
+ ");",
format("f(\n"
"#if !TEST\n"
"_T(\"XXXXXXXXXXXXXXXXXXXXXXXXXXXXXn\")\n"
@@ -6824,7 +6878,7 @@ TEST_F(FormatTest, ConfigurableUseOfTab) {
FormatStyle Tab = getLLVMStyleWithColumns(42);
Tab.IndentWidth = 8;
Tab.UseTab = FormatStyle::UT_Always;
- Tab.AlignEscapedNewlinesLeft = true;
+ Tab.AlignEscapedNewlines = FormatStyle::ENAS_Left;
EXPECT_EQ("if (aaaaaaaa && // q\n"
" bb)\t\t// w\n"
@@ -7605,14 +7659,21 @@ TEST_F(FormatTest, AlignConsecutiveAssignments) {
"int oneTwoThree = 123;\n"
"int oneTwo = 12;",
Alignment));
- Alignment.AlignEscapedNewlinesLeft = true;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " int b = 23; \\\n"
+ " int ccc = 234; \\\n"
+ " int dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
" int b = 23; \\\n"
" int ccc = 234; \\\n"
" int dddddddddd = 2345;",
Alignment);
- Alignment.AlignEscapedNewlinesLeft = false;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right;
verifyFormat("#define A "
" \\\n"
" int aaaa = 12; "
@@ -7879,14 +7940,21 @@ TEST_F(FormatTest, AlignConsecutiveDeclarations) {
"}",
Alignment));
Alignment.AlignConsecutiveAssignments = false;
- Alignment.AlignEscapedNewlinesLeft = true;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_DontAlign;
+ verifyFormat("#define A \\\n"
+ " int aaaa = 12; \\\n"
+ " float b = 23; \\\n"
+ " const int ccc = 234; \\\n"
+ " unsigned dddddddddd = 2345;",
+ Alignment);
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Left;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
" float b = 23; \\\n"
" const int ccc = 234; \\\n"
" unsigned dddddddddd = 2345;",
Alignment);
- Alignment.AlignEscapedNewlinesLeft = false;
+ Alignment.AlignEscapedNewlines = FormatStyle::ENAS_Right;
Alignment.ColumnLimit = 30;
verifyFormat("#define A \\\n"
" int aaaa = 12; \\\n"
@@ -8671,7 +8739,6 @@ TEST_F(FormatTest, GetsCorrectBasedOnStyle) {
TEST_F(FormatTest, ParsesConfigurationBools) {
FormatStyle Style = {};
Style.Language = FormatStyle::LK_Cpp;
- CHECK_PARSE_BOOL(AlignEscapedNewlinesLeft);
CHECK_PARSE_BOOL(AlignOperands);
CHECK_PARSE_BOOL(AlignTrailingComments);
CHECK_PARSE_BOOL(AlignConsecutiveAssignments);
@@ -8794,6 +8861,19 @@ TEST_F(FormatTest, ParsesConfiguration) {
CHECK_PARSE("AlignAfterOpenBracket: true", AlignAfterOpenBracket,
FormatStyle::BAS_Align);
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
+ CHECK_PARSE("AlignEscapedNewlines: DontAlign", AlignEscapedNewlines,
+ FormatStyle::ENAS_DontAlign);
+ CHECK_PARSE("AlignEscapedNewlines: Left", AlignEscapedNewlines,
+ FormatStyle::ENAS_Left);
+ CHECK_PARSE("AlignEscapedNewlines: Right", AlignEscapedNewlines,
+ FormatStyle::ENAS_Right);
+ // For backward compatibility:
+ CHECK_PARSE("AlignEscapedNewlinesLeft: true", AlignEscapedNewlines,
+ FormatStyle::ENAS_Left);
+ CHECK_PARSE("AlignEscapedNewlinesLeft: false", AlignEscapedNewlines,
+ FormatStyle::ENAS_Right);
+
Style.UseTab = FormatStyle::UT_ForIndentation;
CHECK_PARSE("UseTab: Never", UseTab, FormatStyle::UT_Never);
CHECK_PARSE("UseTab: ForIndentation", UseTab, FormatStyle::UT_ForIndentation);
@@ -9559,7 +9639,7 @@ TEST_F(FormatTest, FormatsLambdas) {
// Other corner cases.
verifyFormat("void f() {\n"
" bar([]() {} // Did not respect SpacesBeforeTrailingComments\n"
- " );\n"
+ " );\n"
"}");
// Lambdas created through weird macros.
diff --git a/unittests/Format/FormatTestJS.cpp b/unittests/Format/FormatTestJS.cpp
index 9144fe17e9ec..ff28f304be99 100644
--- a/unittests/Format/FormatTestJS.cpp
+++ b/unittests/Format/FormatTestJS.cpp
@@ -367,6 +367,25 @@ TEST_F(FormatTestJS, GoogScopes) {
"});");
}
+TEST_F(FormatTestJS, IIFEs) {
+ // Internal calling parens; no semi.
+ verifyFormat("(function() {\n"
+ "var a = 1;\n"
+ "}())");
+ // External calling parens; no semi.
+ verifyFormat("(function() {\n"
+ "var b = 2;\n"
+ "})()");
+ // Internal calling parens; with semi.
+ verifyFormat("(function() {\n"
+ "var c = 3;\n"
+ "}());");
+ // External calling parens; with semi.
+ verifyFormat("(function() {\n"
+ "var d = 4;\n"
+ "})();");
+}
+
TEST_F(FormatTestJS, GoogModules) {
verifyFormat("goog.module('this.is.really.absurdly.long');",
getGoogleJSStyleWithColumns(40));
@@ -451,6 +470,16 @@ TEST_F(FormatTestJS, FormatsFreestandingFunctions) {
" inner2(a, b);\n"
"}");
verifyFormat("function f() {}");
+ verifyFormat("function aFunction() {}\n"
+ "(function f() {\n"
+ " var x = 1;\n"
+ "}());\n");
+ // Known issue: this should wrap after {}, but calculateBraceTypes
+ // misclassifies the first braces as a BK_BracedInit.
+ verifyFormat("function aFunction(){} {\n"
+ " let x = 1;\n"
+ " console.log(x);\n"
+ "}\n");
}
TEST_F(FormatTestJS, GeneratorFunctions) {
@@ -519,6 +548,39 @@ TEST_F(FormatTestJS, AsyncFunctions) {
" // Comment.\n"
" return async.then();\n"
"}\n");
+ verifyFormat("for async (const x of y) {\n"
+ " console.log(x);\n"
+ "}\n");
+ verifyFormat("function asyncLoop() {\n"
+ " for async (const x of y) {\n"
+ " console.log(x);\n"
+ " }\n"
+ "}\n");
+
+}
+
+TEST_F(FormatTestJS, FunctionParametersTrailingComma) {
+ verifyFormat("function trailingComma(\n"
+ " p1,\n"
+ " p2,\n"
+ " p3,\n"
+ ") {\n"
+ " a; //\n"
+ "}\n",
+ "function trailingComma(p1, p2, p3,) {\n"
+ " a; //\n"
+ "}\n");
+ verifyFormat("trailingComma(\n"
+ " p1,\n"
+ " p2,\n"
+ " p3,\n"
+ ");\n",
+ "trailingComma(p1, p2, p3,);\n");
+ verifyFormat("trailingComma(\n"
+ " p1 // hello\n"
+ ");\n",
+ "trailingComma(p1 // hello\n"
+ ");\n");
}
TEST_F(FormatTestJS, ArrayLiterals) {
@@ -662,7 +724,7 @@ TEST_F(FormatTestJS, FunctionLiterals) {
"})\n"
" .doSomethingElse(\n"
" // break\n"
- " );");
+ " );");
Style.ColumnLimit = 33;
verifyFormat("f({a: function() { return 1; }});", Style);
@@ -829,7 +891,7 @@ TEST_F(FormatTestJS, ArrowFunctions) {
"})\n"
" .doSomethingElse(\n"
" // break\n"
- " );");
+ " );");
}
TEST_F(FormatTestJS, ReturnStatements) {
@@ -1770,6 +1832,8 @@ TEST_F(FormatTestJS, NonNullAssertionOperator) {
" .foo()!\n"
" .foo()!;\n",
getGoogleJSStyleWithColumns(20));
+ verifyFormat("let x = namespace!;\n");
+ verifyFormat("return !!x;\n");
}
TEST_F(FormatTestJS, Conditional) {
@@ -1785,6 +1849,7 @@ TEST_F(FormatTestJS, ImportComments) {
verifyFormat("import {x} from 'x'; // from some location",
getGoogleJSStyleWithColumns(25));
verifyFormat("// taze: x from 'location'", getGoogleJSStyleWithColumns(10));
+ verifyFormat("/// <reference path=\"some/location\" />", getGoogleJSStyleWithColumns(10));
}
TEST_F(FormatTestJS, Exponentiation) {
diff --git a/unittests/Format/FormatTestSelective.cpp b/unittests/Format/FormatTestSelective.cpp
index 8046d7fab2dd..9ee87b34c217 100644
--- a/unittests/Format/FormatTestSelective.cpp
+++ b/unittests/Format/FormatTestSelective.cpp
@@ -325,7 +325,7 @@ TEST_F(FormatTestSelective, WrongIndent) {
}
TEST_F(FormatTestSelective, AlwaysFormatsEntireMacroDefinitions) {
- Style.AlignEscapedNewlinesLeft = true;
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
EXPECT_EQ("int i;\n"
"#define A \\\n"
" int i; \\\n"
@@ -467,7 +467,7 @@ TEST_F(FormatTestSelective, ReformatRegionAdjustsIndent) {
TEST_F(FormatTestSelective, UnderstandsTabs) {
Style.IndentWidth = 8;
Style.UseTab = FormatStyle::UT_Always;
- Style.AlignEscapedNewlinesLeft = true;
+ Style.AlignEscapedNewlines = FormatStyle::ENAS_Left;
EXPECT_EQ("void f() {\n"
"\tf();\n"
"\tg();\n"
diff --git a/unittests/Tooling/RecursiveASTVisitorTest.cpp b/unittests/Tooling/RecursiveASTVisitorTest.cpp
index 7e08f9619c1c..269bdbb34ab1 100644
--- a/unittests/Tooling/RecursiveASTVisitorTest.cpp
+++ b/unittests/Tooling/RecursiveASTVisitorTest.cpp
@@ -52,6 +52,14 @@ TEST(RecursiveASTVisitor, TraverseLambdaBodyCanBeOverridden) {
EXPECT_TRUE(Visitor.allBodiesHaveBeenTraversed());
}
+TEST(RecursiveASTVisitor, VisitsAttributedLambdaExpr) {
+ LambdaExprVisitor Visitor;
+ Visitor.ExpectMatch("", 1, 12);
+ EXPECT_TRUE(Visitor.runOver(
+ "void f() { [] () __attribute__ (( fastcall )) { return; }(); }",
+ LambdaExprVisitor::Lang_CXX14));
+}
+
// Matches the (optional) capture-default of a lambda-introducer.
class LambdaDefaultCaptureVisitor
: public ExpectedLocationVisitor<LambdaDefaultCaptureVisitor> {
diff --git a/unittests/Tooling/RefactoringCallbacksTest.cpp b/unittests/Tooling/RefactoringCallbacksTest.cpp
index ad8aa8f98feb..e226522a70f4 100644
--- a/unittests/Tooling/RefactoringCallbacksTest.cpp
+++ b/unittests/Tooling/RefactoringCallbacksTest.cpp
@@ -7,10 +7,10 @@
//
//===----------------------------------------------------------------------===//
-#include "clang/Tooling/RefactoringCallbacks.h"
#include "RewriterTestContext.h"
#include "clang/ASTMatchers/ASTMatchFinder.h"
#include "clang/ASTMatchers/ASTMatchers.h"
+#include "clang/Tooling/RefactoringCallbacks.h"
#include "gtest/gtest.h"
namespace clang {
@@ -19,11 +19,10 @@ namespace tooling {
using namespace ast_matchers;
template <typename T>
-void expectRewritten(const std::string &Code,
- const std::string &Expected,
- const T &AMatcher,
- RefactoringCallback &Callback) {
- MatchFinder Finder;
+void expectRewritten(const std::string &Code, const std::string &Expected,
+ const T &AMatcher, RefactoringCallback &Callback) {
+ std::map<std::string, Replacements> FileToReplace;
+ ASTMatchRefactorer Finder(FileToReplace);
Finder.addMatcher(AMatcher, &Callback);
std::unique_ptr<tooling::FrontendActionFactory> Factory(
tooling::newFrontendActionFactory(&Finder));
@@ -31,7 +30,7 @@ void expectRewritten(const std::string &Code,
<< "Parsing error in \"" << Code << "\"";
RewriterTestContext Context;
FileID ID = Context.createInMemoryFile("input.cc", Code);
- EXPECT_TRUE(tooling::applyAllReplacements(Callback.getReplacements(),
+ EXPECT_TRUE(tooling::applyAllReplacements(FileToReplace["input.cc"],
Context.Rewrite));
EXPECT_EQ(Expected, Context.getRewrittenText(ID));
}
@@ -61,18 +60,18 @@ TEST(RefactoringCallbacksTest, ReplacesInteger) {
std::string Code = "void f() { int i = 1; }";
std::string Expected = "void f() { int i = 2; }";
ReplaceStmtWithText Callback("id", "2");
- expectRewritten(Code, Expected, id("id", expr(integerLiteral())),
- Callback);
+ expectRewritten(Code, Expected, id("id", expr(integerLiteral())), Callback);
}
TEST(RefactoringCallbacksTest, ReplacesStmtWithStmt) {
std::string Code = "void f() { int i = false ? 1 : i * 2; }";
std::string Expected = "void f() { int i = i * 2; }";
ReplaceStmtWithStmt Callback("always-false", "should-be");
- expectRewritten(Code, Expected,
- id("always-false", conditionalOperator(
- hasCondition(cxxBoolLiteral(equals(false))),
- hasFalseExpression(id("should-be", expr())))),
+ expectRewritten(
+ Code, Expected,
+ id("always-false",
+ conditionalOperator(hasCondition(cxxBoolLiteral(equals(false))),
+ hasFalseExpression(id("should-be", expr())))),
Callback);
}
@@ -80,10 +79,10 @@ TEST(RefactoringCallbacksTest, ReplacesIfStmt) {
std::string Code = "bool a; void f() { if (a) f(); else a = true; }";
std::string Expected = "bool a; void f() { f(); }";
ReplaceIfStmtWithItsBody Callback("id", true);
- expectRewritten(Code, Expected,
- id("id", ifStmt(
- hasCondition(implicitCastExpr(hasSourceExpression(
- declRefExpr(to(varDecl(hasName("a"))))))))),
+ expectRewritten(
+ Code, Expected,
+ id("id", ifStmt(hasCondition(implicitCastExpr(hasSourceExpression(
+ declRefExpr(to(varDecl(hasName("a"))))))))),
Callback);
}
@@ -92,9 +91,63 @@ TEST(RefactoringCallbacksTest, RemovesEntireIfOnEmptyElse) {
std::string Expected = "void f() { }";
ReplaceIfStmtWithItsBody Callback("id", false);
expectRewritten(Code, Expected,
- id("id", ifStmt(hasCondition(cxxBoolLiteral(equals(false))))),
- Callback);
+ id("id", ifStmt(hasCondition(cxxBoolLiteral(equals(false))))),
+ Callback);
}
+TEST(RefactoringCallbacksTest, TemplateJustText) {
+ std::string Code = "void f() { int i = 1; }";
+ std::string Expected = "void f() { FOO }";
+ auto Callback = ReplaceNodeWithTemplate::create("id", "FOO");
+ EXPECT_FALSE(Callback.takeError());
+ expectRewritten(Code, Expected, id("id", declStmt()), **Callback);
+}
+
+TEST(RefactoringCallbacksTest, TemplateSimpleSubst) {
+ std::string Code = "void f() { int i = 1; }";
+ std::string Expected = "void f() { long x = 1; }";
+ auto Callback = ReplaceNodeWithTemplate::create("decl", "long x = ${init}");
+ EXPECT_FALSE(Callback.takeError());
+ expectRewritten(Code, Expected,
+ id("decl", varDecl(hasInitializer(id("init", expr())))),
+ **Callback);
+}
+
+TEST(RefactoringCallbacksTest, TemplateLiteral) {
+ std::string Code = "void f() { int i = 1; }";
+ std::string Expected = "void f() { string x = \"$-1\"; }";
+ auto Callback = ReplaceNodeWithTemplate::create("decl",
+ "string x = \"$$-${init}\"");
+ EXPECT_FALSE(Callback.takeError());
+ expectRewritten(Code, Expected,
+ id("decl", varDecl(hasInitializer(id("init", expr())))),
+ **Callback);
+}
+
+static void ExpectStringError(const std::string &Expected,
+ llvm::Error E) {
+ std::string Found;
+ handleAllErrors(std::move(E), [&](const llvm::StringError &SE) {
+ llvm::raw_string_ostream Stream(Found);
+ SE.log(Stream);
+ });
+ EXPECT_EQ(Expected, Found);
+}
+
+TEST(RefactoringCallbacksTest, TemplateUnterminated) {
+ auto Callback = ReplaceNodeWithTemplate::create("decl",
+ "string x = \"$$-${init\"");
+ ExpectStringError("Unterminated ${...} in replacement template near ${init\"",
+ Callback.takeError());
+}
+
+TEST(RefactoringCallbacksTest, TemplateUnknownDollar) {
+ auto Callback = ReplaceNodeWithTemplate::create("decl",
+ "string x = \"$<");
+ ExpectStringError("Invalid $ in replacement template near $<",
+ Callback.takeError());
+}
+
+
} // end namespace ast_matchers
} // end namespace clang
diff --git a/www/cxx_dr_status.html b/www/cxx_dr_status.html
index a01e0dd8dddb..b03b3f0ef9c2 100644
--- a/www/cxx_dr_status.html
+++ b/www/cxx_dr_status.html
@@ -28,7 +28,7 @@
<!--*************************************************************************-->
<h1>C++ Defect Report Support in Clang</h1>
<!--*************************************************************************-->
-<p>Last updated: $Date: 2017-03-17 22:41:20 +0100 (Fri, 17 Mar 2017) $</p>
+<p>Last updated: $Date: 2017-05-10 00:21:24 +0200 (Wed, 10 May 2017) $</p>
<h2 id="cxxdr">C++ defect report implementation status</h2>
@@ -589,7 +589,7 @@
</tr>
<tr id="92">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#92">92</a></td>
- <td>WP</td>
+ <td>CD4</td>
<td>Should <I>exception-specification</I>s be part of the type system?</td>
<td class="svn" align="center">Clang 4 (C++17 onwards)</td>
</tr>
@@ -935,11 +935,11 @@
<td>Accessibility and ambiguity</td>
<td class="na" align="center">N/A</td>
</tr>
- <tr class="open" id="150">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#150">150</a></td>
- <td>open</td>
+ <tr id="150">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#150">150</a></td>
+ <td>DR</td>
<td>Template template parameters and default arguments</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="151">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#151">151</a></td>
@@ -1310,7 +1310,7 @@ accessible?</td>
</tr>
<tr id="212">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#212">212</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Implicit instantiation is not described clearly enough</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -1466,7 +1466,7 @@ accessible?</td>
</tr>
<tr id="238">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#238">238</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Precision and accuracy constraints on floating point</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -1490,7 +1490,7 @@ accessible?</td>
</tr>
<tr id="242">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#242">242</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Interpretation of old-style casts</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -2019,7 +2019,7 @@ of class templates</td>
</tr>
<tr id="330">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#330">330</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Qualification conversions and pointers to arrays of pointers</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -2397,7 +2397,7 @@ of class templates</td>
</tr>
<tr id="393">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#393">393</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Pointer to array of unknown bound in template argument list in parameter</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -3017,7 +3017,7 @@ of class templates</td>
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#496">496</a></td>
<td>CD3</td>
<td>Is a volatile-qualified type really a POD?</td>
- <td class="none" align="center">No</td>
+ <td class="none" align="center">Superseded by <a href="#dr2094">dr2094</a></td>
</tr>
<tr id="497">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#497">497</a></td>
@@ -3587,7 +3587,7 @@ and <I>POD class</I></td>
</tr>
<tr id="591">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#591">591</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>When a dependent base class is the current instantiation</td>
<td class="none" align="center">No</td>
</tr>
@@ -3695,7 +3695,7 @@ and <I>POD class</I></td>
</tr>
<tr id="609">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#609">609</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>What is a &#8220;top-level&#8221; cv-qualifier?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -5735,7 +5735,7 @@ and <I>POD class</I></td>
</tr>
<tr id="987">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#987">987</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Which declarations introduce namespace members?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -5939,7 +5939,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1021">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1021">1021</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Definitions of namespace members</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -6509,7 +6509,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1116">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1116">1116</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Aliasing of union members</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7295,7 +7295,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1247">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1247">1247</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Restriction on alias name appearing in <I>type-id</I></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7457,7 +7457,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1274">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1274">1274</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Common nonterminal for <I>expression</I> and <I>braced-init-list</I></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7517,7 +7517,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1284">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1284">1284</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Should the lifetime of an array be independent of that of its elements?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7565,7 +7565,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1292">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1292">1292</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Dependent calls with <I>braced-init-list</I>s containing a pack expansion</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7667,7 +7667,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1309">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1309">1309</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Incorrect note regarding lookup of a member of the current instantiation</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7703,7 +7703,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1315">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1315">1315</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Restrictions on non-type template arguments in partial specializations</td>
<td class="partial" align="center">Partial</td>
</tr>
@@ -7841,7 +7841,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1338">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1338">1338</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Aliasing and allocation functions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7870,8 +7870,8 @@ and <I>POD class</I></td>
<td align="center">Not resolved</td>
</tr>
<tr id="1343">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1343">1343</a></td>
- <td>tentatively ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1343">1343</a></td>
+ <td>DR</td>
<td>Sequencing of non-class initialization</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7919,7 +7919,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1351">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1351">1351</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Problems with implicitly-declared <I>exception-specification</I>s</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -7949,7 +7949,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1356">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1356">1356</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Exception specifications of copy assignment operators with virtual bases</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8159,7 +8159,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1391">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1391">1391</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Conversions to parameter types with non-deduced template arguments</td>
<td class="partial" align="center">Partial</td>
</tr>
@@ -8182,8 +8182,8 @@ and <I>POD class</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1395">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1395">1395</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1395">1395</a></td>
+ <td>DR</td>
<td>Partial ordering of variadic templates reconsidered</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8195,7 +8195,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1397">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1397">1397</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Class completeness in non-static data member initializers</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8489,7 +8489,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1446">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1446">1446</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Member function with no <I>ref-qualifier</I> and non-member function with rvalue reference</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8603,7 +8603,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1465">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1465">1465</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>noexcept</TT> and <TT>std::bad_array_new_length</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8615,7 +8615,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1467">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1467">1467</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>List-initialization of aggregate from same-type object</td>
<td class="full" align="center">Clang 3.7 (C++11 onwards)</td>
</tr>
@@ -8717,7 +8717,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1484">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1484">1484</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Unused local classes of function templates</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8753,7 +8753,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1490">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1490">1490</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>List-initialization from a string literal</td>
<td class="full" align="center">Clang 3.7 (C++11 onwards)</td>
</tr>
@@ -8765,7 +8765,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1492">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1492">1492</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Exception specifications on template destructors</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8789,7 +8789,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1496">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1496">1496</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Triviality with deleted and missing default constructors</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -8921,7 +8921,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1518">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1518">1518</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Explicit default constructors and copy-list-initialization</td>
<td class="svn" align="center">Clang 4</td>
</tr>
@@ -9125,7 +9125,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1552">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1552">1552</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><I>exception-specification</I>s and defaulted special member functions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9161,7 +9161,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1558">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1558">1558</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Unused arguments in alias template specializations</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9201,11 +9201,11 @@ and <I>POD class</I></td>
<td>Template argument deduction from an initializer list</td>
<td class="none" align="center">Unknown</td>
</tr>
- <tr class="open" id="1565">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1565">1565</a></td>
- <td>drafting</td>
+ <tr id="1565">
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1565">1565</a></td>
+ <td>NAD</td>
<td>Copy elision and lifetime of <TT>initializer_list</TT> underlying array</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1566">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1566">1566</a></td>
@@ -9239,19 +9239,19 @@ and <I>POD class</I></td>
</tr>
<tr id="1571">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1571">1571</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>cv-qualification for indirect reference binding via conversion function</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1572">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1572">1572</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Incorrect example for rvalue reference binding via conversion function</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1573">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1573">1573</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Inherited constructor characteristics</td>
<td class="full" align="center">Clang 3.9</td>
</tr>
@@ -9347,7 +9347,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1589">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1589">1589</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Ambiguous ranking of list-initialization sequences</td>
<td class="full" align="center">Clang 3.7 (C++11 onwards)</td>
</tr>
@@ -9359,7 +9359,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1591">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1591">1591</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Deducing array bound and element type from initializer list</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9389,7 +9389,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1596">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1596">1596</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Non-array objects as <TT>array[1]</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9413,7 +9413,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1600">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1600">1600</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Erroneous reference initialization in example</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9431,7 +9431,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1603">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1603">1603</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Errors resulting from giving unnamed namespaces internal linkage</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9497,13 +9497,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1614">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1614">1614</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Address of pure virtual function vs odr-use</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1615">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1615">1615</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Alignment of types, variables, and members</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9543,11 +9543,11 @@ and <I>POD class</I></td>
<td>Member initializers in anonymous unions</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="1622">
+ <tr id="1622">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1622">1622</a></td>
- <td>drafting</td>
+ <td>ready</td>
<td>Empty aggregate initializer for union</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr class="open" id="1623">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1623">1623</a></td>
@@ -9593,13 +9593,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1630">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1630">1630</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Multiple default constructor templates</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1631">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1631">1631</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Incorrect overload resolution for single-element <I>initializer-list</I></td>
<td class="full" align="center">Clang 3.7</td>
</tr>
@@ -9611,7 +9611,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1633">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1633">1633</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Copy-initialization in member initialization</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9641,13 +9641,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1638">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1638">1638</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Declaring an explicit specialization of a scoped enumeration</td>
<td class="full" align="center">Yes</td>
</tr>
<tr id="1639">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1639">1639</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><I>exception-specification</I>s and pointer/pointer-to-member expressions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9683,7 +9683,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1645">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1645">1645</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Identical inheriting constructors via default arguments</td>
<td class="full" align="center">Clang 3.9</td>
</tr>
@@ -9725,13 +9725,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1652">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1652">1652</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Object addresses in <TT>constexpr</TT> expressions</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1653">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1653">1653</a></td>
- <td>WP</td>
+ <td>CD4</td>
<td>Removing deprecated increment of <TT>bool</TT></td>
<td class="svn" align="center">Clang 4 (C++17 onwards)</td>
</tr>
@@ -9755,7 +9755,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1657">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1657">1657</a></td>
- <td>WP</td>
+ <td>CD4</td>
<td>Attributes for namespaces and enumerators</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9845,7 +9845,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1672">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1672">1672</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Layout compatibility with multiple empty bases</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9873,11 +9873,11 @@ and <I>POD class</I></td>
<td><TT>auto</TT> return type for allocation and deallocation functions</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="1677">
+ <tr id="1677">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1677">1677</a></td>
- <td>drafting</td>
+ <td>ready</td>
<td>Constant initialization via aggregate initialization</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1678">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_closed.html#1678">1678</a></td>
@@ -9911,7 +9911,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1683">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1683">1683</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Incorrect example after <TT>constexpr</TT> changes</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9929,7 +9929,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1686">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1686">1686</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Which variables are &#8220;explicitly declared <TT>const</TT>?&#8221;</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9977,7 +9977,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1694">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1694">1694</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Restriction on reference to temporary as a constant expression</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -9989,7 +9989,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1696">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1696">1696</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Temporary lifetime and non-static data member initializers</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10043,7 +10043,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1705">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1705">1705</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Unclear specification of &#8220;more specialized&#8221;</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10061,7 +10061,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1708">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1708">1708</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>overly-strict requirements for names with C language linkage</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10085,7 +10085,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1712">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1712">1712</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>constexpr</TT> variable template declarations</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10103,7 +10103,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1715">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1715">1715</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Access and inherited constructor templates</td>
<td class="full" align="center">Clang 3.9</td>
</tr>
@@ -10127,7 +10127,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1719">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1719">1719</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Layout compatibility and cv-qualification revisited</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10145,7 +10145,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1722">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1722">1722</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Should lambda to function pointer conversion function be <TT>noexcept</TT>?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10217,7 +10217,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1734">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1734">1734</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Nontrivial deleted copy functions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10229,7 +10229,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1736">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1736">1736</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Inheriting constructor templates in a local class</td>
<td class="full" align="center">Clang 3.9</td>
</tr>
@@ -10277,7 +10277,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1744">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1744">1744</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Unordered initialization for variable template specializations</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10301,7 +10301,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1748">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1748">1748</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Placement new with a null pointer</td>
<td class="full" align="center">Clang 3.7</td>
</tr>
@@ -10313,25 +10313,25 @@ and <I>POD class</I></td>
</tr>
<tr id="1750">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1750">1750</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>&#8220;Argument&#8221; vs &#8220;parameter&#8221;</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1751">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1751">1751</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Non-trivial operations vs non-trivial initialization</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1752">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1752">1752</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Right-recursion in <I>mem-initializer-list</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1753">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1753">1753</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><I>decltype-specifier</I> in <I>nested-name-specifier</I> of destructor</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10349,19 +10349,19 @@ and <I>POD class</I></td>
</tr>
<tr id="1756">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1756">1756</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Direct-list-initialization of a non-class object</td>
<td class="full" align="center">Clang 3.7</td>
</tr>
<tr id="1757">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1757">1757</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Const integral subobjects</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1758">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1758">1758</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Explicit conversion in copy/move list initialization</td>
<td class="full" align="center">Clang 3.7</td>
</tr>
@@ -10409,7 +10409,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1766">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1766">1766</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Values outside the range of the values of an enumeration</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10457,7 +10457,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1774">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1774">1774</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Discrepancy between subobject destruction and stack unwinding</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10469,13 +10469,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1776">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1776">1776</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Replacement of class objects containing reference members</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1777">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1777">1777</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Empty pack expansion in <I>dynamic-exception-specification</I></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10487,13 +10487,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1779">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1779">1779</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Type dependency of <TT>__func__</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1780">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1780">1780</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Explicit instantiation/specialization of generic lambda <TT>operator()</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10505,7 +10505,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1782">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1782">1782</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Form of initialization for <TT>nullptr_t</TT> to <TT>bool</TT> conversion</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10541,7 +10541,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1788">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1788">1788</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Sized deallocation of array of non-class type</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10559,7 +10559,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1791">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1791">1791</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Incorrect restrictions on <I>cv-qualifier-seq</I> and <I>ref-qualifier</I></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10571,7 +10571,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1793">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1793">1793</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>thread_local</TT> in explicit specializations</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10583,19 +10583,19 @@ and <I>POD class</I></td>
</tr>
<tr id="1795">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1795">1795</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Disambiguating <I>original-namespace-definition</I> and <I>extension-namespace-definition</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1796">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1796">1796</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Is all-bits-zero for null characters a meaningful requirement?</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1797">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1797">1797</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Are all bit patterns of <TT>unsigned char</TT> distinct numbers?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10607,13 +10607,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1799">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1799">1799</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>mutable</TT> and non-explicit const qualification</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1800">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1800">1800</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Pointer to member of nested anonymous union</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10625,7 +10625,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1802">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1802">1802</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>char16_t</TT> string literals and surrogate pairs</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10637,25 +10637,25 @@ and <I>POD class</I></td>
</tr>
<tr id="1804">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1804">1804</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Partial specialization and friendship</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1805">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1805">1805</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Conversions of array operands in <I>conditional-expression</I>s</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1806">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1806">1806</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Virtual bases and move-assignment</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1807">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1807">1807</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Order of destruction of array elements after an exception</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10667,19 +10667,19 @@ and <I>POD class</I></td>
</tr>
<tr id="1809">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1809">1809</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Narrowing and template argument deduction</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1810">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1810">1810</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Invalid <I>ud-suffix</I>es</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1811">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1811">1811</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Lookup of deallocation function in a virtual destructor definition</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10691,25 +10691,25 @@ and <I>POD class</I></td>
</tr>
<tr id="1813">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1813">1813</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Direct vs indirect bases in standard-layout classes</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1814">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1814">1814</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Default arguments in <I>lambda-expression</I>s</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1815">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1815">1815</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Lifetime extension in aggregate initialization</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1816">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1816">1816</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Unclear specification of bit-field values</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10727,7 +10727,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1819">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1819">1819</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Acceptable scopes for definition of partial specialization</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10751,19 +10751,19 @@ and <I>POD class</I></td>
</tr>
<tr id="1823">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1823">1823</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>String literal uniqueness in inline functions</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1824">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1824">1824</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Completeness of return type vs point of instantiation</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1825">
- <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1825">1825</a></td>
- <td>ready</td>
+ <td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1825">1825</a></td>
+ <td>DR</td>
<td>Partial ordering between variadic and non-variadic function templates</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10793,7 +10793,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1830">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1830">1830</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Repeated specifiers</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10805,7 +10805,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1832">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1832">1832</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Casting to incomplete enumeration</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10817,7 +10817,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1834">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1834">1834</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Constant initialization binding a reference to an xvalue</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10841,7 +10841,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1838">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1838">1838</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Definition via <I>unqualified-id</I> and <I>using-declaration</I></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10871,7 +10871,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1843">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1843">1843</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Bit-field in conditional operator with <TT>throw</TT> operand</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10889,19 +10889,19 @@ and <I>POD class</I></td>
</tr>
<tr id="1846">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1846">1846</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Declaring explicitly-defaulted implicitly-deleted functions</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1847">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1847">1847</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Clarifying compatibility during partial ordering</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1848">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1848">1848</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Parenthesized constructor and destructor declarators</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10913,19 +10913,19 @@ and <I>POD class</I></td>
</tr>
<tr id="1850">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1850">1850</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Differences between definition context and point of instantiation</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1851">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1851">1851</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>decltype(auto)</TT> in <I>new-expression</I>s</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1852">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1852">1852</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Wording issues regarding <TT>decltype(auto)</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10961,7 +10961,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1858">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1858">1858</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Comparing pointers to union members</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10971,15 +10971,15 @@ and <I>POD class</I></td>
<td>UTF-16 in <TT>char16_t</TT> string literals</td>
<td align="center">Not resolved</td>
</tr>
- <tr class="open" id="1860">
+ <tr id="1860">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_active.html#1860">1860</a></td>
- <td>review</td>
+ <td>ready</td>
<td>What is a &#8220;direct member?&#8221;</td>
- <td align="center">Not resolved</td>
+ <td class="none" align="center">Unknown</td>
</tr>
<tr id="1861">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1861">1861</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Values of a bit-field</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -10991,7 +10991,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1863">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1863">1863</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Requirements on thrown object type to support <TT>std::current_exception()</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11003,13 +11003,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1865">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1865">1865</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Pointer arithmetic and multi-level qualification conversions</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1866">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1866">1866</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Initializing variant members with non-trivial destructors</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11033,7 +11033,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1870">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1870">1870</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Contradictory wording about definitions vs explicit specialization/instantiation</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11045,25 +11045,25 @@ and <I>POD class</I></td>
</tr>
<tr id="1872">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1872">1872</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Instantiations of <TT>constexpr</TT> templates that cannot appear in constant expressions</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1873">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1873">1873</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Protected member access from derived class friends</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1874">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1874">1874</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Type vs non-type template parameters with <TT>class</TT> keyword</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1875">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1875">1875</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Reordering declarations in class scope</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11075,13 +11075,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1877">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1877">1877</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Return type deduction from <TT>return</TT> with no operand</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1878">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1878">1878</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>operator auto</TT> template</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11099,13 +11099,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1881">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1881">1881</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Standard-layout classes and unnamed bit-fields</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1882">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1882">1882</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Reserved names without library use</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11123,25 +11123,25 @@ and <I>POD class</I></td>
</tr>
<tr id="1885">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1885">1885</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Return value of a function is underspecified</td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1886">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1886">1886</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Language linkage for <TT>main()</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1887">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1887">1887</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Problems with <TT>::</TT> as <I>nested-name-specifier</I></td>
<td class="none" align="center">Unknown</td>
</tr>
<tr id="1888">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1888">1888</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Implicitly-declared default constructors and <TT>explicit</TT></td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11159,13 +11159,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1891">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1891">1891</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Move constructor/assignment for closure class</td>
<td class="svn" align="center">Clang 4</td>
</tr>
<tr id="1892">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1892">1892</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Use of <TT>auto</TT> in function type</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11183,7 +11183,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1895">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1895">1895</a></td>
- <td>DR</td>
+ <td>CD4</td>
<td>Deleted conversions in conditional operator operands</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11207,7 +11207,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1899">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1899">1899</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Value-dependent constant expressions</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11225,13 +11225,13 @@ and <I>POD class</I></td>
</tr>
<tr id="1902">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1902">1902</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>What makes a conversion &#8220;otherwise ill-formed&#8221;?</td>
<td class="full" align="center">Clang 3.7</td>
</tr>
<tr id="1903">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1903">1903</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>What declarations are introduced by a non-member <I>using-declaration</I>?</td>
<td class="none" align="center">Unknown</td>
</tr>
@@ -11267,7 +11267,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1909">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1909">1909</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td>Member class template with the same name as the class</td>
<td class="full" align="center">Yes</td>
</tr>
@@ -11279,7 +11279,7 @@ and <I>POD class</I></td>
</tr>
<tr id="1911">
<td><a href="http://www.open-std.org/jtc1/sc22/wg21/docs/cwg_defects.html#1911">1911</a></td>
- <td>DRWP</td>
+ <td>CD4</td>
<td><TT>constexpr</TT> constructor with non-literal base class</td>
<td class="none" align="center">Unknown</td></