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>`` instead of
+ Use features of C++11, C++14 and C++1z (e.g. ``A>`` instead of
``A >``).
* ``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) \
@@ -4080,6 +4080,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
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::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 @@ class VarDecl : public DeclaratorDecl, public Redeclarable {
/// 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 @@ class FieldDecl : public DeclaratorDecl, public Mergeable {
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(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 @@ class CXXRecordDecl : public RecordDecl {
/// \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.
@@ -1607,6 +1610,16 @@ class CXXRecordDecl : public RecordDecl {
static bool FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
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.
///
@@ -1633,6 +1646,14 @@ class CXXRecordDecl : public RecordDecl {
/// \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
+ lookupDependentName(const DeclarationName &Name,
+ llvm::function_ref 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 @@ class ExternalASTMerger : public ExternalASTSource {
FindExternalLexicalDecls(const DeclContext *DC,
llvm::function_ref IsKindWeWant,
SmallVectorImpl &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 Proto = TL.getAsAdjusted();
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(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(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, DefaultIgnore;
+def warn_unused_template : Warning<"unused %select{function|variable}0 template %1">,
+ InGroup, DefaultIgnore;
def warn_unused_member_function : Warning<"unused member function %0">,
InGroup, 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>;
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,
Flags<[CoreOption, DriverOption]>,
HelpText<"Disable use-after-scope detection in AddressSanitizer">;
+def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">,
+ Group,
+ HelpText<"Enable linker dead stripping of globals in AddressSanitizer">;
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, 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 @@ class MacroInfo {
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 @@ class Preprocessor {
/// \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 @@ class Preprocessor {
/// 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 @@ class Parser : public CodeCompletionHandler {
K == tok::plusplus || K == tok::minusminus);
}
+ bool diagnoseUnknownTemplateId(ExprResult TemplateName, SourceLocation Less);
+
ExprResult ParsePostfixExpressionSuffix(ExprResult LHS);
ExprResult ParseUnaryExprOrTypeTraitExpression();
ExprResult ParseBuiltinPrimaryExpression();
@@ -2723,10 +2725,7 @@ class Parser : public CodeCompletionHandler {
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 @@ class Sema {
/// correctly named definition after the renamed definition.
llvm::SmallPtrSet TypoCorrectedFunctionDefinitions;
+ /// Stack of types that correspond to the parameter entities that are
+ /// currently being copy-initialized. Can be empty.
+ llvm::SmallVector CurrentParameterCopyTypes;
+
void ReadMethodPool(Selector Sel);
void updateOutOfDateSelector(Selector Sel);
@@ -1456,6 +1460,11 @@ class Sema {
/// The modules we're currently parsing.
llvm::SmallVector 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 @@ class Sema {
/// \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 @@ class Sema {
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 @@ class Sema {
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(E.get()))
+ return !DRE->hasExplicitTemplateArgs();
+ if (auto *ME = dyn_cast(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 @@ class Sema {
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 @@ class Sema {
resolveAddressOfOnlyViableOverloadCandidate(Expr *E,
DeclAccessPair &FoundResult);
- bool resolveAndFixAddressOfOnlyViableOverloadCandidate(ExprResult &SrcExpr);
+ bool resolveAndFixAddressOfOnlyViableOverloadCandidate(
+ ExprResult &SrcExpr, bool DoFunctionPointerConversion = false);
FunctionDecl *
ResolveSingleFunctionTemplateSpecialization(OverloadExpr *ovl,
@@ -3049,7 +3077,8 @@ class Sema {
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 @@ class Sema {
TemplateArgumentListInfo *ExplicitTemplateArgs,
LookupResult &Previous);
bool CheckMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
+ void CompleteMemberSpecialization(NamedDecl *Member, LookupResult &Previous);
DeclResult
ActOnExplicitInstantiation(Scope *S,
@@ -9259,6 +9289,8 @@ class Sema {
/// 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 @@ class Sema {
MacroInfo *MacroInfo,
unsigned Argument);
void CodeCompleteNaturalLanguage();
+ void CodeCompleteAvailabilityPlatformName();
void GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
CodeCompletionTUInfo &CCTUInfo,
SmallVectorImpl &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 @@ class RefactoringCallback : public ast_matchers::MatchFinder::MatchCallback {
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 &FileToReplaces);
+
+ template
+ 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 newASTConsumer();
+
+private:
+ friend class RefactoringASTConsumer;
+ std::vector Callbacks;
+ ast_matchers::MatchFinder MatchFinder;
+ std::map &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 @@ class ReplaceStmtWithText : public RefactoringCallback {
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>
+ 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 Template);
+ std::string FromId;
+ std::vector 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 ConflictingDecls;
SmallVector 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(D1)) {
if (CXXRecordDecl *D2CXX = dyn_cast(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
@@ -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(BaseSpec.getType()->castAs()
- ->getDecl());
- if (lookupInBases(Context, BaseRecord, BaseMatches)) {
+ CXXRecordDecl *BaseRecord;
+ if (LookupInDependent) {
+ BaseRecord = nullptr;
+ const TemplateSpecializationType *TST =
+ BaseSpec.getType()->getAs();
+ if (!TST) {
+ if (auto *RT = BaseSpec.getType()->getAs())
+ BaseRecord = cast(RT->getDecl());
+ } else {
+ TemplateName TN = TST->getTemplateName();
+ if (auto *TD =
+ dyn_cast_or_null(TN.getAsTemplateDecl()))
+ BaseRecord = TD->getTemplatedDecl();
+ }
+ if (BaseRecord && !BaseRecord->hasDefinition())
+ BaseRecord = nullptr;
+ } else {
+ BaseRecord = cast(
+ BaseSpec.getType()->castAs()->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()->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()->getDecl();
+ return findOrdinaryMember(BaseRecord, Path, Name);
+}
+
+bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
+ const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
+ DeclarationName Name) {
+ const TemplateSpecializationType *TST =
+ Specifier->getType()->getAs();
+ if (!TST) {
+ auto *RT = Specifier->getType()->getAs();
+ if (!RT)
+ return false;
+ return findOrdinaryMember(RT->getDecl(), Path, Name);
+ }
+ TemplateName TN = TST->getTemplateName();
+ const auto *TD = dyn_cast_or_null(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 CXXRecordDecl::lookupDependentName(
+ const DeclarationName &Name,
+ llvm::function_ref Filter) {
+ std::vector 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 &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 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 @@ class ODRTypeVisitor : public TypeVisitor {
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 @@ class SparcTargetInfo : public TargetInfo {
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> 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()) {
+ 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::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(Context))
- return getOrCreateNameSpace(NSDecl);
+ return getOrCreateNamespace(NSDecl);
if (const auto *RDecl = dyn_cast(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(FD->getDeclContext()))
- FDContext = getOrCreateNameSpace(NSDecl);
+ dyn_cast_or_null(FD->getLexicalDeclContext()))
+ FDContext = getOrCreateNamespace(NSDecl);
else if (const RecordDecl *RDecl =
dyn_cast_or_null(FD->getDeclContext())) {
llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
@@ -3961,7 +3961,7 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) {
CGM.getCodeGenOpts().DebugExplicitImport) {
DBuilder.createImportedModule(
getCurrentContextDescriptor(cast(UD.getDeclContext())),
- getOrCreateNameSpace(NSDecl),
+ getOrCreateNamespace(NSDecl),
getLineNumber(UD.getLocation()));
}
}
@@ -4021,23 +4021,26 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
else
R = DBuilder.createImportedDeclaration(
getCurrentContextDescriptor(cast(NA.getDeclContext())),
- getOrCreateNameSpace(cast(NA.getAliasedNamespace())),
+ getOrCreateNamespace(cast(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(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 DeclCache;
- llvm::DenseMap NameSpaceCache;
+ llvm::DenseMap NamespaceCache;
llvm::DenseMap
NamespaceAliasCache;
llvm::DenseMap>
@@ -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(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(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
using namespace clang;
using namespace CodeGen;
@@ -58,18 +57,19 @@ class LazyRuntimeFunction {
/// 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
+ void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy,
+ Tys *... Types) {
CGM = Mod;
FunctionName = name;
Function = nullptr;
- std::vector 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 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 @@ class CGObjCGCC : public CGObjCGNU {
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 @@ class CGObjCObjFW: public CGObjCGNU {
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 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 @@ class ObjCCommonTypesHelper {
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(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 {
}
};
+template <> struct ScalarEnumerationTraits {
+ 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 {
static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
@@ -233,6 +245,7 @@ template <> struct MappingTraits {
// 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 {
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 @@ class AnnotatingParser {
}
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 @@ class AnnotatingParser {
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(EscapedNewlineColumn - 1, PreviousEndOfTokenColumn);
+ std::min(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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
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
///
@@ -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
///
@@ -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
///
@@ -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
@@ -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
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
@@ -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
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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
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
///
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
///
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 VEXTRACTPS / EXTRACTPS
+/// This intrinsic corresponds to the VEXTRACTPS / EXTRACTPS
/// 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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
///
@@ -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
#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
///
@@ -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
///
@@ -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
///
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 @@ class BodyIndexer : public RecursiveASTVisitor {
Parent, ParentDC, Roles, Relations, E);
}
+ bool indexDependentReference(
+ const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
+ llvm::function_ref Filter) {
+ if (!T)
+ return true;
+ const TemplateSpecializationType *TST =
+ T->getAs();
+ if (!TST)
+ return true;
+ TemplateName TN = TST->getTemplateName();
+ const ClassTemplateDecl *TD =
+ dyn_cast_or_null(TN.getAsTemplateDecl());
+ if (!TD)
+ return true;
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ if (!RD->hasDefinition())
+ return true;
+ RD = RD->getDefinition();
+ std::vector 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 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 @@ class IndexingDeclVisitor : public ConstDeclVisitor {
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 @@ class IndexingDeclVisitor : public ConstDeclVisitor {
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 @@ class IndexingDeclVisitor : public ConstDeclVisitor {
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(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 @@ class TypeIndexer : public RecursiveASTVisitor {
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();
+ if (!TST)
+ return true;
+ TemplateName TN = TST->getTemplateName();
+ const ClassTemplateDecl *TD =
+ dyn_cast_or_null(TN.getAsTemplateDecl());
+ if (!TD)
+ return true;
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ if (!RD->hasDefinition())
+ return true;
+ RD = RD->getDefinition();
+ DeclarationName Name(DNT->getIdentifier());
+ std::vector Symbols = RD->lookupDependentName(
+ Name, [](const NamedDecl *ND) { return isa(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(D)) {
TKind = VD->getTemplateSpecializationKind();
+ } else if (isa(D)) {
+ if (const auto *Parent =
+ dyn_cast(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(D)) {
return VD->getTemplateInstantiationPattern();
+ } else if (const auto *FD = dyn_cast(D)) {
+ if (const auto *Parent =
+ dyn_cast(D->getDeclContext())) {
+ const CXXRecordDecl *Pattern = Parent->getTemplateInstantiationPattern();
+ for (const NamedDecl *ND : Pattern->lookup(FD->getDeclName())) {
+ if (ND->isImplicit())
+ continue;
+ if (isa(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 ";
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();
- 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();
- 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 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 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 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(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(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(DiagD) ? diag::warn_unused_member_function
+ : diag::warn_unused_function)
+ << DiagD->getDeclName();
}
} else {
const VarDecl *DiagD = cast(*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()) {
- // 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()) {
+ TemplateName TN = TST->getTemplateName();
+ if (const auto *TD =
+ dyn_cast_or_null(TN.getAsTemplateDecl())) {
+ CXXRecordDecl *RD = TD->getTemplatedDecl();
+ AddRecordMembersCompletionResults(*this, Results, S, BaseType, RD);
}
+ } else if (const auto *ICNT = BaseType->getAs()) {
+ 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 &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(ND) || isa(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(ND);
+ if (!RD || !RD->isInjectedClassName())
+ return false;
+ RD = cast(RD->getDeclContext());
+ return RD->getDescribedClassTemplate() ||
+ isa(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(
- 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(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(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()) {
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
<< New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
New->dropAttr();
}
@@ -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()) {
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();
}
@@ -3644,7 +3696,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
!Old->hasAttr()) {
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
<< New->getDeclName();
- Diag(Old->getLocation(), diag::note_previous_definition);
+ notePreviousDefinition(Old->getLocation(), New->getLocation());
New->dropAttr();
}
@@ -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()) {
@@ -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(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(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(VD))
+ // FIXME: Warn on unused var template partial specializations.
+ if (VD->isFileVarDecl() && !isa(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(Definition),
- FD->getLocation());
+ makeMergedDefinitionVisible(TD);
+ makeMergedDefinitionVisible(const_cast(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 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
// 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 @@ class DiagnoseUnguardedAvailability
SemaRef.Context.getTargetInfo().getPlatformMinVersion());
}
+ bool TraverseDecl(Decl *D) {
+ // Avoid visiting nested functions to prevent duplicate warnings.
+ if (!D || isa(D))
+ return true;
+ return Base::TraverseDecl(D);
+ }
+
bool TraverseStmt(Stmt *S) {
if (!S)
return true;
@@ -7243,6 +7250,8 @@ class DiagnoseUnguardedAvailability
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(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();
+
+ assert(!isa(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(LHSVecType)) {
- if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
- LHSVecType->getElementType(), LHSType))
- return LHSType;
+ if (!RHSVecType) {
+ if (isa(LHSVecType)) {
+ if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
+ LHSVecType->getElementType(), LHSType))
+ return LHSType;
+ } else {
+ if (!tryGCCVectorConvertAndSplat(*this, &RHS, &LHS))
+ return LHSType;
+ }
}
- if (!LHSVecType && isa(RHSVecType)) {
- if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
- LHSType, RHSVecType->getElementType(),
- RHSType))
- return RHSType;
+ if (!LHSVecType) {
+ if (isa(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(RHSVecType)) ||
+ (LHSVecType && !isa(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(vType->getAs())))
+ 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();
- if (!lhsRecord) return false;
-
const RecordType *rhsRecord = RhsT->getAs();
- if (!rhsRecord) return false;
+ if (!rhsRecord || !lhsRecord) {
+ const ObjCObjectType *LHSObjTy = LhsT->getAs