Vendor import of clang trunk r303197:
https://llvm.org/svn/llvm-project/cfe/trunk@303197
This commit is contained in:
parent
0a5fb09b59
commit
2410013d93
@ -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)
|
||||
|
@ -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 "")
|
||||
|
@ -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()
|
||||
|
@ -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
|
||||
|
@ -209,23 +209,45 @@ the configuration (without a prefix: ``Auto``).
|
||||
float b = 23;
|
||||
std::string ccc = 23;
|
||||
|
||||
**AlignEscapedNewlinesLeft** (``bool``)
|
||||
If ``true``, aligns escaped newlines as far left as possible.
|
||||
Otherwise puts them into the right-most column.
|
||||
**AlignEscapedNewlines** (``EscapedNewlineAlignmentStyle``)
|
||||
Options for aligning backslashes in escaped newlines.
|
||||
|
||||
.. code-block:: c++
|
||||
Possible values:
|
||||
|
||||
* ``ENAS_DontAlign`` (in configuration: ``DontAlign``)
|
||||
Don't align escaped newlines.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#define A \
|
||||
int aaaa; \
|
||||
int b; \
|
||||
int dddddddddd;
|
||||
|
||||
* ``ENAS_Left`` (in configuration: ``Left``)
|
||||
Align escaped newlines as far left as possible.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
true:
|
||||
#define A \
|
||||
int aaaa; \
|
||||
int b; \
|
||||
int dddddddddd;
|
||||
|
||||
false:
|
||||
|
||||
* ``ENAS_Right`` (in configuration: ``Right``)
|
||||
Align escaped newlines in the right-most column.
|
||||
|
||||
.. code-block:: c++
|
||||
|
||||
#define A \
|
||||
int aaaa; \
|
||||
int b; \
|
||||
int dddddddddd;
|
||||
|
||||
true:
|
||||
#define A \
|
||||
int aaaa; \
|
||||
int b; \
|
||||
int dddddddddd;
|
||||
|
||||
false:
|
||||
#define A \
|
||||
int aaaa; \
|
||||
int b; \
|
||||
int dddddddddd;
|
||||
|
||||
**AlignOperands** (``bool``)
|
||||
If ``true``, horizontally align operands of binary and ternary
|
||||
@ -1525,7 +1547,7 @@ the configuration (without a prefix: ``Auto``).
|
||||
Use C++03-compatible syntax.
|
||||
|
||||
* ``LS_Cpp11`` (in configuration: ``Cpp11``)
|
||||
Use features of C++11, C++14 and C++1z (e.g. ``A<A<int>>`` instead of
|
||||
Use features of C++11, C++14 and C++1z (e.g. ``A<A<int>>`` instead of
|
||||
``A<A<int> >``).
|
||||
|
||||
* ``LS_Auto`` (in configuration: ``Auto``)
|
||||
|
@ -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(...) \
|
||||
|
@ -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
|
||||
|
@ -161,7 +161,8 @@ class CXXBasePaths {
|
||||
void ComputeDeclsFound();
|
||||
|
||||
bool lookupInBases(ASTContext &Context, const CXXRecordDecl *Record,
|
||||
CXXRecordDecl::BaseMatchesCallback BaseMatches);
|
||||
CXXRecordDecl::BaseMatchesCallback BaseMatches,
|
||||
bool LookupInDependent = false);
|
||||
|
||||
public:
|
||||
typedef std::list<CXXBasePath>::iterator paths_iterator;
|
||||
|
@ -966,9 +966,16 @@ class VarDecl : public DeclaratorDecl, public Redeclarable<VarDecl> {
|
||||
/// 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<FieldDecl> {
|
||||
void setCapturedVLAType(const VariableArrayType *VLAType);
|
||||
|
||||
/// getParent - Returns the parent of this field declaration, which
|
||||
/// is the struct in which this method is defined.
|
||||
/// is the struct in which this field is defined.
|
||||
const RecordDecl *getParent() const {
|
||||
return cast<RecordDecl>(getDeclContext());
|
||||
}
|
||||
|
@ -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<const NamedDecl *>
|
||||
lookupDependentName(const DeclarationName &Name,
|
||||
llvm::function_ref<bool(const NamedDecl *ND)> Filter);
|
||||
|
||||
/// Renders and displays an inheritance diagram
|
||||
/// for this C++ class and all of its base classes (transitively) using
|
||||
/// GraphViz.
|
||||
|
@ -44,6 +44,8 @@ class ExternalASTMerger : public ExternalASTSource {
|
||||
FindExternalLexicalDecls(const DeclContext *DC,
|
||||
llvm::function_ref<bool(Decl::Kind)> IsKindWeWant,
|
||||
SmallVectorImpl<Decl *> &Result) override;
|
||||
|
||||
void CompleteType(TagDecl *Tag) override;
|
||||
};
|
||||
|
||||
} // end namespace clang
|
||||
|
@ -2326,7 +2326,7 @@ DEF_TRAVERSE_STMT(LambdaExpr, {
|
||||
}
|
||||
|
||||
TypeLoc TL = S->getCallOperator()->getTypeSourceInfo()->getTypeLoc();
|
||||
FunctionProtoTypeLoc Proto = TL.castAs<FunctionProtoTypeLoc>();
|
||||
FunctionProtoTypeLoc Proto = TL.getAsAdjusted<FunctionProtoTypeLoc>();
|
||||
|
||||
if (S->hasExplicitParameters() && S->hasExplicitResultType()) {
|
||||
// Visit the whole type.
|
||||
|
@ -652,6 +652,30 @@ def Availability : InheritableAttr {
|
||||
.Case("tvos_app_extension", "tvOS (App Extension)")
|
||||
.Case("watchos_app_extension", "watchOS (App Extension)")
|
||||
.Default(llvm::StringRef());
|
||||
}
|
||||
static llvm::StringRef getPlatformNameSourceSpelling(llvm::StringRef Platform) {
|
||||
return llvm::StringSwitch<llvm::StringRef>(Platform)
|
||||
.Case("ios", "iOS")
|
||||
.Case("macos", "macOS")
|
||||
.Case("tvos", "tvOS")
|
||||
.Case("watchos", "watchOS")
|
||||
.Case("ios_app_extension", "iOSApplicationExtension")
|
||||
.Case("macos_app_extension", "macOSApplicationExtension")
|
||||
.Case("tvos_app_extension", "tvOSApplicationExtension")
|
||||
.Case("watchos_app_extension", "watchOSApplicationExtension")
|
||||
.Default(Platform);
|
||||
}
|
||||
static llvm::StringRef canonicalizePlatformName(llvm::StringRef Platform) {
|
||||
return llvm::StringSwitch<llvm::StringRef>(Platform)
|
||||
.Case("iOS", "ios")
|
||||
.Case("macOS", "macos")
|
||||
.Case("tvOS", "tvos")
|
||||
.Case("watchOS", "watchos")
|
||||
.Case("iOSApplicationExtension", "ios_app_extension")
|
||||
.Case("macOSApplicationExtension", "macos_app_extension")
|
||||
.Case("tvOSApplicationExtension", "tvos_app_extension")
|
||||
.Case("watchOSApplicationExtension", "watchos_app_extension")
|
||||
.Default(Platform);
|
||||
} }];
|
||||
let HasCustomParsing = 1;
|
||||
let DuplicatesAllowedWhileMerging = 1;
|
||||
|
@ -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
|
||||
|
@ -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,
|
||||
|
@ -303,6 +303,8 @@ def note_empty_parens_zero_initialize : Note<
|
||||
"replace parentheses with an initializer to declare a variable">;
|
||||
def warn_unused_function : Warning<"unused function %0">,
|
||||
InGroup<UnusedFunction>, DefaultIgnore;
|
||||
def warn_unused_template : Warning<"unused %select{function|variable}0 template %1">,
|
||||
InGroup<UnusedTemplate>, DefaultIgnore;
|
||||
def warn_unused_member_function : Warning<"unused member function %0">,
|
||||
InGroup<UnusedMemberFunction>, DefaultIgnore;
|
||||
def warn_used_but_marked_unused: Warning<"%0 was marked unused but was used">,
|
||||
@ -2463,6 +2465,9 @@ def err_attribute_invalid_size : Error<
|
||||
"vector size not an integral multiple of component size">;
|
||||
def err_attribute_zero_size : Error<"zero vector size">;
|
||||
def err_attribute_size_too_large : Error<"vector size too large">;
|
||||
def err_typecheck_vector_not_convertable_implict_truncation : Error<
|
||||
"cannot convert between %select{scalar|vector}0 type %1 and vector type"
|
||||
" %2 as implicit conversion would cause truncation">;
|
||||
def err_typecheck_vector_not_convertable : Error<
|
||||
"cannot convert between vector values of different size (%0 and %1)">;
|
||||
def err_typecheck_vector_not_convertable_non_scalar : Error<
|
||||
@ -4607,6 +4612,8 @@ def err_abi_tag_on_redeclaration : Error<
|
||||
"cannot add 'abi_tag' attribute in a redeclaration">;
|
||||
def err_new_abi_tag_on_redeclaration : Error<
|
||||
"'abi_tag' %0 missing in original declaration">;
|
||||
def note_use_ifdef_guards : Note<
|
||||
"unguarded header; consider using #ifdef guards or #pragma once">;
|
||||
|
||||
def note_deleted_dtor_no_operator_delete : Note<
|
||||
"virtual destructor requires an unambiguous, accessible 'operator delete'">;
|
||||
@ -5775,6 +5782,9 @@ def err_objc_object_assignment : Error<
|
||||
"cannot assign to class object (%0 invalid)">;
|
||||
def err_typecheck_invalid_operands : Error<
|
||||
"invalid operands to binary expression (%0 and %1)">;
|
||||
def err_typecheck_logical_vector_expr_gnu_cpp_restrict : Error<
|
||||
"logical expression with vector %select{type %1 and non-vector type %2|types"
|
||||
" %1 and %2}0 is only supported in C++">;
|
||||
def err_typecheck_sub_ptr_compatible : Error<
|
||||
"%diff{$ and $ are not pointers to compatible types|"
|
||||
"pointers to incompatible types}0,1">;
|
||||
@ -8186,9 +8196,20 @@ def err_undeclared_use_suggest : Error<
|
||||
"use of undeclared %0; did you mean %1?">;
|
||||
def err_undeclared_var_use_suggest : Error<
|
||||
"use of undeclared identifier %0; did you mean %1?">;
|
||||
def err_no_template : Error<"no template named %0">;
|
||||
def err_no_template_suggest : Error<"no template named %0; did you mean %1?">;
|
||||
def err_no_member_template : Error<"no template named %0 in %1">;
|
||||
def err_no_member_template_suggest : Error<
|
||||
"no template named %0 in %1; did you mean %select{|simply }2%3?">;
|
||||
def err_non_template_in_template_id : Error<
|
||||
"%0 does not name a template but is followed by template arguments">;
|
||||
def err_non_template_in_template_id_suggest : Error<
|
||||
"%0 does not name a template but is followed by template arguments; "
|
||||
"did you mean %1?">;
|
||||
def err_non_template_in_member_template_id_suggest : Error<
|
||||
"member %0 of %1 is not a template; did you mean %select{|simply }2%3?">;
|
||||
def note_non_template_in_template_id_found : Note<
|
||||
"non-template declaration found by name lookup">;
|
||||
def err_mem_init_not_member_or_class_suggest : Error<
|
||||
"initializer %0 does not name a non-static data member or base "
|
||||
"class; did you mean the %select{base class|member}1 %2?">;
|
||||
@ -8875,6 +8896,13 @@ def ext_equivalent_internal_linkage_decl_in_modules : ExtWarn<
|
||||
InGroup<DiagGroup<"modules-ambiguous-internal-linkage">>;
|
||||
def note_equivalent_internal_linkage_decl : Note<
|
||||
"declared here%select{ in module '%1'|}0">;
|
||||
|
||||
def note_redefinition_modules_same_file : Note<
|
||||
"'%0' included multiple times, additional include site in header from module '%1'">;
|
||||
def note_redefinition_modules_same_file_modulemap : Note<
|
||||
"consider adding '%0' as part of '%1' definition">;
|
||||
def note_redefinition_include_same_file : Note<
|
||||
"'%0' included multiple times, additional include site here">;
|
||||
}
|
||||
|
||||
let CategoryName = "Coroutines Issue" in {
|
||||
|
@ -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
|
||||
|
@ -827,6 +827,9 @@ def fno_sanitize_address_use_after_scope : Flag<["-"], "fno-sanitize-address-use
|
||||
Group<f_clang_Group>,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
HelpText<"Disable use-after-scope detection in AddressSanitizer">;
|
||||
def fsanitize_address_globals_dead_stripping : Flag<["-"], "fsanitize-address-globals-dead-stripping">,
|
||||
Group<f_clang_Group>,
|
||||
HelpText<"Enable linker dead stripping of globals in AddressSanitizer">;
|
||||
def fsanitize_recover : Flag<["-"], "fsanitize-recover">, Group<f_clang_Group>;
|
||||
def fno_sanitize_recover : Flag<["-"], "fno-sanitize-recover">,
|
||||
Flags<[CoreOption, DriverOption]>,
|
||||
|
@ -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;
|
||||
|
@ -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 ==
|
||||
|
@ -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
|
||||
|
@ -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;
|
||||
};
|
||||
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -1074,6 +1074,10 @@ class Sema {
|
||||
/// correctly named definition after the renamed definition.
|
||||
llvm::SmallPtrSet<const NamedDecl *, 4> TypoCorrectedFunctionDefinitions;
|
||||
|
||||
/// Stack of types that correspond to the parameter entities that are
|
||||
/// currently being copy-initialized. Can be empty.
|
||||
llvm::SmallVector<QualType, 4> CurrentParameterCopyTypes;
|
||||
|
||||
void ReadMethodPool(Selector Sel);
|
||||
void updateOutOfDateSelector(Selector Sel);
|
||||
|
||||
@ -1456,6 +1460,11 @@ class Sema {
|
||||
/// The modules we're currently parsing.
|
||||
llvm::SmallVector<ModuleScope, 16> ModuleScopes;
|
||||
|
||||
/// Get the module whose scope we are currently within.
|
||||
Module *getCurrentModule() const {
|
||||
return ModuleScopes.empty() ? nullptr : ModuleScopes.back().Module;
|
||||
}
|
||||
|
||||
VisibleModuleSet VisibleModules;
|
||||
|
||||
Module *CachedFakeTopLevelModule;
|
||||
@ -1466,7 +1475,7 @@ 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<DeclRefExpr>(E.get()))
|
||||
return !DRE->hasExplicitTemplateArgs();
|
||||
if (auto *ME = dyn_cast<MemberExpr>(E.get()))
|
||||
return !ME->hasExplicitTemplateArgs();
|
||||
// Any additional cases recognized here should also be handled by
|
||||
// diagnoseExprIntendedAsTemplateName.
|
||||
return false;
|
||||
}
|
||||
void diagnoseExprIntendedAsTemplateName(Scope *S, ExprResult TemplateName,
|
||||
SourceLocation Less,
|
||||
SourceLocation Greater);
|
||||
|
||||
Decl *ActOnDeclarator(Scope *S, Declarator &D);
|
||||
|
||||
NamedDecl *HandleDeclarator(Scope *S, Declarator &D,
|
||||
@ -2336,6 +2362,7 @@ 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<CodeCompletionResult> &Results);
|
||||
|
@ -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<std::string, Replacements> &FileToReplaces);
|
||||
|
||||
template <typename T>
|
||||
void addMatcher(const T &Matcher, RefactoringCallback *Callback) {
|
||||
MatchFinder.addMatcher(Matcher, Callback);
|
||||
Callbacks.push_back(Callback);
|
||||
}
|
||||
|
||||
void addDynamicMatcher(const ast_matchers::internal::DynTypedMatcher &Matcher,
|
||||
RefactoringCallback *Callback);
|
||||
|
||||
std::unique_ptr<ASTConsumer> newASTConsumer();
|
||||
|
||||
private:
|
||||
friend class RefactoringASTConsumer;
|
||||
std::vector<RefactoringCallback *> Callbacks;
|
||||
ast_matchers::MatchFinder MatchFinder;
|
||||
std::map<std::string, Replacements> &FileToReplaces;
|
||||
};
|
||||
|
||||
/// \brief Replace the text of the statement bound to \c FromId with the text in
|
||||
/// \c ToText.
|
||||
class ReplaceStmtWithText : public RefactoringCallback {
|
||||
@ -59,6 +86,29 @@ 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<std::unique_ptr<ReplaceNodeWithTemplate>>
|
||||
create(StringRef FromId, StringRef ToTemplate);
|
||||
void run(const ast_matchers::MatchFinder::MatchResult &Result) override;
|
||||
|
||||
private:
|
||||
struct TemplateElement {
|
||||
enum { Literal, Identifier } Type;
|
||||
std::string Value;
|
||||
};
|
||||
ReplaceNodeWithTemplate(llvm::StringRef FromId,
|
||||
std::vector<TemplateElement> Template);
|
||||
std::string FromId;
|
||||
std::vector<TemplateElement> Template;
|
||||
};
|
||||
|
||||
/// \brief Replace the text of the statement bound to \c FromId with the text of
|
||||
/// the statement bound to \c ToId.
|
||||
class ReplaceStmtWithStmt : public RefactoringCallback {
|
||||
|
@ -1622,10 +1622,18 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
|
||||
|
||||
// We may already have a record of the same name; try to find and match it.
|
||||
RecordDecl *AdoptDecl = nullptr;
|
||||
RecordDecl *PrevDecl = nullptr;
|
||||
if (!DC->isFunctionOrMethod()) {
|
||||
SmallVector<NamedDecl *, 4> ConflictingDecls;
|
||||
SmallVector<NamedDecl *, 2> FoundDecls;
|
||||
DC->getRedeclContext()->localUncachedLookup(SearchName, FoundDecls);
|
||||
|
||||
if (!FoundDecls.empty()) {
|
||||
// We're going to have to compare D against potentially conflicting Decls, so complete it.
|
||||
if (D->hasExternalLexicalStorage() && !D->isCompleteDefinition())
|
||||
D->getASTContext().getExternalSource()->CompleteType(D);
|
||||
}
|
||||
|
||||
for (unsigned I = 0, N = FoundDecls.size(); I != N; ++I) {
|
||||
if (!FoundDecls[I]->isInIdentifierNamespace(IDNS))
|
||||
continue;
|
||||
@ -1652,6 +1660,8 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
|
||||
}
|
||||
}
|
||||
|
||||
PrevDecl = FoundRecord;
|
||||
|
||||
if (RecordDecl *FoundDef = FoundRecord->getDefinition()) {
|
||||
if ((SearchName && !D->isCompleteDefinition())
|
||||
|| (D->isCompleteDefinition() &&
|
||||
@ -1744,6 +1754,10 @@ Decl *ASTNodeImporter::VisitRecordDecl(RecordDecl *D) {
|
||||
LexicalDC->addDeclInternal(D2);
|
||||
if (D->isAnonymousStructOrUnion())
|
||||
D2->setAnonymousStructOrUnion(true);
|
||||
if (PrevDecl) {
|
||||
// FIXME: do this for all Redeclarables, not just RecordDecls.
|
||||
D2->setPreviousDecl(PrevDecl);
|
||||
}
|
||||
}
|
||||
|
||||
Importer.Imported(D, D2);
|
||||
|
@ -855,6 +855,11 @@ static bool IsStructurallyEquivalent(StructuralEquivalenceContext &Context,
|
||||
|
||||
if (CXXRecordDecl *D1CXX = dyn_cast<CXXRecordDecl>(D1)) {
|
||||
if (CXXRecordDecl *D2CXX = dyn_cast<CXXRecordDecl>(D2)) {
|
||||
if (D1CXX->hasExternalLexicalStorage() &&
|
||||
!D1CXX->isCompleteDefinition()) {
|
||||
D1CXX->getASTContext().getExternalSource()->CompleteType(D1CXX);
|
||||
}
|
||||
|
||||
if (D1CXX->getNumBases() != D2CXX->getNumBases()) {
|
||||
if (Context.Complain) {
|
||||
Context.Diag2(D2->getLocation(), diag::warn_odr_tag_type_inconsistent)
|
||||
|
@ -13,6 +13,7 @@
|
||||
#include "clang/AST/CXXInheritance.h"
|
||||
#include "clang/AST/ASTContext.h"
|
||||
#include "clang/AST/DeclCXX.h"
|
||||
#include "clang/AST/DeclTemplate.h"
|
||||
#include "clang/AST/RecordLayout.h"
|
||||
#include "llvm/ADT/SetVector.h"
|
||||
#include <algorithm>
|
||||
@ -174,9 +175,10 @@ bool CXXRecordDecl::forallBases(ForallBasesCallback BaseMatches,
|
||||
return AllMatches;
|
||||
}
|
||||
|
||||
bool CXXBasePaths::lookupInBases(
|
||||
ASTContext &Context, const CXXRecordDecl *Record,
|
||||
CXXRecordDecl::BaseMatchesCallback BaseMatches) {
|
||||
bool CXXBasePaths::lookupInBases(ASTContext &Context,
|
||||
const CXXRecordDecl *Record,
|
||||
CXXRecordDecl::BaseMatchesCallback BaseMatches,
|
||||
bool LookupInDependent) {
|
||||
bool FoundPath = false;
|
||||
|
||||
// The access of the path down to this record.
|
||||
@ -194,7 +196,7 @@ bool CXXBasePaths::lookupInBases(
|
||||
// the base class scope is not examined during unqualified name lookup
|
||||
// either at the point of definition of the class template or member or
|
||||
// during an instantiation of the class tem- plate or member.
|
||||
if (BaseType->isDependentType())
|
||||
if (!LookupInDependent && BaseType->isDependentType())
|
||||
continue;
|
||||
|
||||
// Determine whether we need to visit this base class at all,
|
||||
@ -262,10 +264,28 @@ bool CXXBasePaths::lookupInBases(
|
||||
return FoundPath;
|
||||
}
|
||||
} else if (VisitBase) {
|
||||
CXXRecordDecl *BaseRecord
|
||||
= cast<CXXRecordDecl>(BaseSpec.getType()->castAs<RecordType>()
|
||||
->getDecl());
|
||||
if (lookupInBases(Context, BaseRecord, BaseMatches)) {
|
||||
CXXRecordDecl *BaseRecord;
|
||||
if (LookupInDependent) {
|
||||
BaseRecord = nullptr;
|
||||
const TemplateSpecializationType *TST =
|
||||
BaseSpec.getType()->getAs<TemplateSpecializationType>();
|
||||
if (!TST) {
|
||||
if (auto *RT = BaseSpec.getType()->getAs<RecordType>())
|
||||
BaseRecord = cast<CXXRecordDecl>(RT->getDecl());
|
||||
} else {
|
||||
TemplateName TN = TST->getTemplateName();
|
||||
if (auto *TD =
|
||||
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl()))
|
||||
BaseRecord = TD->getTemplatedDecl();
|
||||
}
|
||||
if (BaseRecord && !BaseRecord->hasDefinition())
|
||||
BaseRecord = nullptr;
|
||||
} else {
|
||||
BaseRecord = cast<CXXRecordDecl>(
|
||||
BaseSpec.getType()->castAs<RecordType>()->getDecl());
|
||||
}
|
||||
if (BaseRecord &&
|
||||
lookupInBases(Context, BaseRecord, BaseMatches, LookupInDependent)) {
|
||||
// C++ [class.member.lookup]p2:
|
||||
// A member name f in one sub-object B hides a member name f in
|
||||
// a sub-object A if A is a base class sub-object of B. Any
|
||||
@ -299,9 +319,11 @@ bool CXXBasePaths::lookupInBases(
|
||||
}
|
||||
|
||||
bool CXXRecordDecl::lookupInBases(BaseMatchesCallback BaseMatches,
|
||||
CXXBasePaths &Paths) const {
|
||||
CXXBasePaths &Paths,
|
||||
bool LookupInDependent) const {
|
||||
// If we didn't find anything, report that.
|
||||
if (!Paths.lookupInBases(getASTContext(), this, BaseMatches))
|
||||
if (!Paths.lookupInBases(getASTContext(), this, BaseMatches,
|
||||
LookupInDependent))
|
||||
return false;
|
||||
|
||||
// If we're not recording paths or we won't ever find ambiguities,
|
||||
@ -387,23 +409,49 @@ bool CXXRecordDecl::FindTagMember(const CXXBaseSpecifier *Specifier,
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
|
||||
CXXBasePath &Path,
|
||||
DeclarationName Name) {
|
||||
RecordDecl *BaseRecord =
|
||||
Specifier->getType()->castAs<RecordType>()->getDecl();
|
||||
|
||||
const unsigned IDNS = IDNS_Ordinary | IDNS_Tag | IDNS_Member;
|
||||
static bool findOrdinaryMember(RecordDecl *BaseRecord, CXXBasePath &Path,
|
||||
DeclarationName Name) {
|
||||
const unsigned IDNS = clang::Decl::IDNS_Ordinary | clang::Decl::IDNS_Tag |
|
||||
clang::Decl::IDNS_Member;
|
||||
for (Path.Decls = BaseRecord->lookup(Name);
|
||||
!Path.Decls.empty();
|
||||
Path.Decls = Path.Decls.slice(1)) {
|
||||
if (Path.Decls.front()->isInIdentifierNamespace(IDNS))
|
||||
return true;
|
||||
}
|
||||
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
bool CXXRecordDecl::FindOrdinaryMember(const CXXBaseSpecifier *Specifier,
|
||||
CXXBasePath &Path,
|
||||
DeclarationName Name) {
|
||||
RecordDecl *BaseRecord =
|
||||
Specifier->getType()->castAs<RecordType>()->getDecl();
|
||||
return findOrdinaryMember(BaseRecord, Path, Name);
|
||||
}
|
||||
|
||||
bool CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
|
||||
const CXXBaseSpecifier *Specifier, CXXBasePath &Path,
|
||||
DeclarationName Name) {
|
||||
const TemplateSpecializationType *TST =
|
||||
Specifier->getType()->getAs<TemplateSpecializationType>();
|
||||
if (!TST) {
|
||||
auto *RT = Specifier->getType()->getAs<RecordType>();
|
||||
if (!RT)
|
||||
return false;
|
||||
return findOrdinaryMember(RT->getDecl(), Path, Name);
|
||||
}
|
||||
TemplateName TN = TST->getTemplateName();
|
||||
const auto *TD = dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
|
||||
if (!TD)
|
||||
return false;
|
||||
CXXRecordDecl *RD = TD->getTemplatedDecl();
|
||||
if (!RD)
|
||||
return false;
|
||||
return findOrdinaryMember(RD, Path, Name);
|
||||
}
|
||||
|
||||
bool CXXRecordDecl::FindOMPReductionMember(const CXXBaseSpecifier *Specifier,
|
||||
CXXBasePath &Path,
|
||||
DeclarationName Name) {
|
||||
@ -438,6 +486,36 @@ FindNestedNameSpecifierMember(const CXXBaseSpecifier *Specifier,
|
||||
return false;
|
||||
}
|
||||
|
||||
std::vector<const NamedDecl *> CXXRecordDecl::lookupDependentName(
|
||||
const DeclarationName &Name,
|
||||
llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
|
||||
std::vector<const NamedDecl *> Results;
|
||||
// Lookup in the class.
|
||||
DeclContext::lookup_result DirectResult = lookup(Name);
|
||||
if (!DirectResult.empty()) {
|
||||
for (const NamedDecl *ND : DirectResult) {
|
||||
if (Filter(ND))
|
||||
Results.push_back(ND);
|
||||
}
|
||||
return Results;
|
||||
}
|
||||
// Perform lookup into our base classes.
|
||||
CXXBasePaths Paths;
|
||||
Paths.setOrigin(this);
|
||||
if (!lookupInBases(
|
||||
[&](const CXXBaseSpecifier *Specifier, CXXBasePath &Path) {
|
||||
return CXXRecordDecl::FindOrdinaryMemberInDependentClasses(
|
||||
Specifier, Path, Name);
|
||||
},
|
||||
Paths, /*LookupInDependent=*/true))
|
||||
return Results;
|
||||
for (const NamedDecl *ND : Paths.front().Decls) {
|
||||
if (Filter(ND))
|
||||
Results.push_back(ND);
|
||||
}
|
||||
return Results;
|
||||
}
|
||||
|
||||
void OverridingMethods::add(unsigned OverriddenSubobject,
|
||||
UniqueVirtualMethod Overriding) {
|
||||
SmallVectorImpl<UniqueVirtualMethod> &SubobjectOverrides
|
||||
|
@ -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())
|
||||
|
@ -178,3 +178,9 @@ void ExternalASTMerger::FindExternalLexicalDecls(
|
||||
}
|
||||
});
|
||||
}
|
||||
|
||||
void ExternalASTMerger::CompleteType(TagDecl *Tag) {
|
||||
SmallVector<Decl *, 0> Result;
|
||||
FindExternalLexicalDecls(Tag, [](Decl::Kind) { return true; }, Result);
|
||||
Tag->setHasExternalLexicalStorage(false);
|
||||
}
|
||||
|
@ -411,7 +411,7 @@ class ODRTypeVisitor : public TypeVisitor<ODRTypeVisitor> {
|
||||
|
||||
void VisitTypedefType(const TypedefType *T) {
|
||||
AddDecl(T->getDecl());
|
||||
Hash.AddQualType(T->getDecl()->getUnderlyingType());
|
||||
AddQualType(T->getDecl()->getUnderlyingType().getCanonicalType());
|
||||
VisitType(T);
|
||||
}
|
||||
};
|
||||
|
@ -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
|
||||
|
@ -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())
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -194,6 +194,8 @@ static void addSanitizerCoveragePass(const PassManagerBuilder &Builder,
|
||||
// where this is not a factor). Also, on ELF this feature requires an assembler
|
||||
// extension that only works with -integrated-as at the moment.
|
||||
static bool asanUseGlobalsGC(const Triple &T, const CodeGenOptions &CGOpts) {
|
||||
if (!CGOpts.SanitizeAddressGlobalsDeadStripping)
|
||||
return false;
|
||||
switch (T.getObjectFormat()) {
|
||||
case Triple::MachO:
|
||||
case Triple::COFF:
|
||||
@ -1071,7 +1073,8 @@ void clang::EmitBackendOutput(DiagnosticsEngine &Diags,
|
||||
// into memory and pass it into runThinLTOBackend, which will run the
|
||||
// function importer and invoke LTO passes.
|
||||
Expected<std::unique_ptr<ModuleSummaryIndex>> IndexOrErr =
|
||||
llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile);
|
||||
llvm::getModuleSummaryIndexForFile(CGOpts.ThinLTOIndexFile,
|
||||
/*IgnoreEmptyThinLTOIndexFile*/true);
|
||||
if (!IndexOrErr) {
|
||||
logAllUnhandledErrors(IndexOrErr.takeError(), errs(),
|
||||
"Error loading index file '" +
|
||||
|
@ -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;
|
||||
}
|
||||
|
@ -2769,6 +2769,32 @@ RValue CodeGenFunction::EmitBuiltinExpr(const FunctionDecl *FD,
|
||||
return RValue::get(ConstantInt::get(ConvertType(E->getType()),
|
||||
Layout.size().getQuantity()));
|
||||
}
|
||||
|
||||
case Builtin::BI__xray_customevent: {
|
||||
if (!ShouldXRayInstrumentFunction())
|
||||
return RValue::getIgnored();
|
||||
if (const auto *XRayAttr = CurFuncDecl->getAttr<XRayInstrumentAttr>()) {
|
||||
if (XRayAttr->neverXRayInstrument())
|
||||
return RValue::getIgnored();
|
||||
}
|
||||
Function *F = CGM.getIntrinsic(Intrinsic::xray_customevent);
|
||||
auto FTy = F->getFunctionType();
|
||||
auto Arg0 = E->getArg(0);
|
||||
auto Arg0Val = EmitScalarExpr(Arg0);
|
||||
auto Arg0Ty = Arg0->getType();
|
||||
auto PTy0 = FTy->getParamType(0);
|
||||
if (PTy0 != Arg0Val->getType()) {
|
||||
if (Arg0Ty->isArrayType())
|
||||
Arg0Val = EmitArrayToPointerDecay(Arg0).getPointer();
|
||||
else
|
||||
Arg0Val = Builder.CreatePointerCast(Arg0Val, PTy0);
|
||||
}
|
||||
auto Arg1 = EmitScalarExpr(E->getArg(1));
|
||||
auto PTy1 = FTy->getParamType(1);
|
||||
if (PTy1 != Arg1->getType())
|
||||
Arg1 = Builder.CreateTruncOrBitCast(Arg1, PTy1);
|
||||
return RValue::get(Builder.CreateCall(F, {Arg0Val, Arg1}));
|
||||
}
|
||||
}
|
||||
|
||||
// If this is an alias for a lib function (e.g. __builtin_sin), emit
|
||||
@ -4545,7 +4571,7 @@ Value *CodeGenFunction::EmitARMBuiltinExpr(unsigned BuiltinID,
|
||||
Function *F = CGM.getIntrinsic(BuiltinID == ARM::BI__builtin_arm_stlex
|
||||
? Intrinsic::arm_stlexd
|
||||
: Intrinsic::arm_strexd);
|
||||
llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, nullptr);
|
||||
llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty);
|
||||
|
||||
Address Tmp = CreateMemTemp(E->getArg(0)->getType());
|
||||
Value *Val = EmitScalarExpr(E->getArg(0));
|
||||
@ -5375,7 +5401,7 @@ Value *CodeGenFunction::EmitAArch64BuiltinExpr(unsigned BuiltinID,
|
||||
Function *F = CGM.getIntrinsic(BuiltinID == AArch64::BI__builtin_arm_stlex
|
||||
? Intrinsic::aarch64_stlxp
|
||||
: Intrinsic::aarch64_stxp);
|
||||
llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty, nullptr);
|
||||
llvm::Type *STy = llvm::StructType::get(Int64Ty, Int64Ty);
|
||||
|
||||
Address Tmp = CreateMemTemp(E->getArg(0)->getType());
|
||||
EmitAnyExprToMem(E->getArg(0), Tmp, Qualifiers(), /*init*/ true);
|
||||
@ -7347,8 +7373,8 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID,
|
||||
// unsigned int __cpu_type;
|
||||
// unsigned int __cpu_subtype;
|
||||
// unsigned int __cpu_features[1];
|
||||
llvm::Type *STy = llvm::StructType::get(
|
||||
Int32Ty, Int32Ty, Int32Ty, llvm::ArrayType::get(Int32Ty, 1), nullptr);
|
||||
llvm::Type *STy = llvm::StructType::get(Int32Ty, Int32Ty, Int32Ty,
|
||||
llvm::ArrayType::get(Int32Ty, 1));
|
||||
|
||||
// Grab the global __cpu_model.
|
||||
llvm::Constant *CpuModel = CGM.CreateRuntimeVariable(STy, "__cpu_model");
|
||||
|
@ -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),
|
||||
|
@ -51,8 +51,7 @@ DominatingValue<RValue>::saved_type::save(CodeGenFunction &CGF, RValue rv) {
|
||||
if (rv.isComplex()) {
|
||||
CodeGenFunction::ComplexPairTy V = rv.getComplexVal();
|
||||
llvm::Type *ComplexTy =
|
||||
llvm::StructType::get(V.first->getType(), V.second->getType(),
|
||||
(void*) nullptr);
|
||||
llvm::StructType::get(V.first->getType(), V.second->getType());
|
||||
Address addr = CGF.CreateDefaultAlignTempAlloca(ComplexTy, "saved-complex");
|
||||
CGF.Builder.CreateStore(V.first,
|
||||
CGF.Builder.CreateStructGEP(addr, 0, CharUnits()));
|
||||
|
@ -209,7 +209,7 @@ llvm::DIScope *CGDebugInfo::getContextDescriptor(const Decl *Context,
|
||||
|
||||
// Check namespace.
|
||||
if (const auto *NSDecl = dyn_cast<NamespaceDecl>(Context))
|
||||
return getOrCreateNameSpace(NSDecl);
|
||||
return getOrCreateNamespace(NSDecl);
|
||||
|
||||
if (const auto *RDecl = dyn_cast<RecordDecl>(Context))
|
||||
if (!RDecl->isDependentType())
|
||||
@ -2860,8 +2860,8 @@ void CGDebugInfo::collectFunctionDeclProps(GlobalDecl GD, llvm::DIFile *Unit,
|
||||
|
||||
if (DebugKind >= codegenoptions::LimitedDebugInfo) {
|
||||
if (const NamespaceDecl *NSDecl =
|
||||
dyn_cast_or_null<NamespaceDecl>(FD->getDeclContext()))
|
||||
FDContext = getOrCreateNameSpace(NSDecl);
|
||||
dyn_cast_or_null<NamespaceDecl>(FD->getLexicalDeclContext()))
|
||||
FDContext = getOrCreateNamespace(NSDecl);
|
||||
else if (const RecordDecl *RDecl =
|
||||
dyn_cast_or_null<RecordDecl>(FD->getDeclContext())) {
|
||||
llvm::DIScope *Mod = getParentModuleOrNull(RDecl);
|
||||
@ -3961,7 +3961,7 @@ void CGDebugInfo::EmitUsingDirective(const UsingDirectiveDecl &UD) {
|
||||
CGM.getCodeGenOpts().DebugExplicitImport) {
|
||||
DBuilder.createImportedModule(
|
||||
getCurrentContextDescriptor(cast<Decl>(UD.getDeclContext())),
|
||||
getOrCreateNameSpace(NSDecl),
|
||||
getOrCreateNamespace(NSDecl),
|
||||
getLineNumber(UD.getLocation()));
|
||||
}
|
||||
}
|
||||
@ -4021,23 +4021,26 @@ CGDebugInfo::EmitNamespaceAlias(const NamespaceAliasDecl &NA) {
|
||||
else
|
||||
R = DBuilder.createImportedDeclaration(
|
||||
getCurrentContextDescriptor(cast<Decl>(NA.getDeclContext())),
|
||||
getOrCreateNameSpace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
|
||||
getOrCreateNamespace(cast<NamespaceDecl>(NA.getAliasedNamespace())),
|
||||
getLineNumber(NA.getLocation()), NA.getName());
|
||||
VH.reset(R);
|
||||
return R;
|
||||
}
|
||||
|
||||
llvm::DINamespace *
|
||||
CGDebugInfo::getOrCreateNameSpace(const NamespaceDecl *NSDecl) {
|
||||
NSDecl = NSDecl->getCanonicalDecl();
|
||||
auto I = NameSpaceCache.find(NSDecl);
|
||||
if (I != NameSpaceCache.end())
|
||||
CGDebugInfo::getOrCreateNamespace(const NamespaceDecl *NSDecl) {
|
||||
// Don't canonicalize the NamespaceDecl here: The DINamespace will be uniqued
|
||||
// if necessary, and this way multiple declarations of the same namespace in
|
||||
// different parent modules stay distinct.
|
||||
auto I = NamespaceCache.find(NSDecl);
|
||||
if (I != NamespaceCache.end())
|
||||
return cast<llvm::DINamespace>(I->second);
|
||||
|
||||
llvm::DIScope *Context = getDeclContextDescriptor(NSDecl);
|
||||
// Don't trust the context if it is a DIModule (see comment above).
|
||||
llvm::DINamespace *NS =
|
||||
DBuilder.createNameSpace(Context, NSDecl->getName(), NSDecl->isInline());
|
||||
NameSpaceCache[NSDecl].reset(NS);
|
||||
NamespaceCache[NSDecl].reset(NS);
|
||||
return NS;
|
||||
}
|
||||
|
||||
|
@ -125,7 +125,7 @@ class CGDebugInfo {
|
||||
/// Cache declarations relevant to DW_TAG_imported_declarations (C++
|
||||
/// using declarations) that aren't covered by other more specific caches.
|
||||
llvm::DenseMap<const Decl *, llvm::TrackingMDRef> DeclCache;
|
||||
llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NameSpaceCache;
|
||||
llvm::DenseMap<const NamespaceDecl *, llvm::TrackingMDRef> NamespaceCache;
|
||||
llvm::DenseMap<const NamespaceAliasDecl *, llvm::TrackingMDRef>
|
||||
NamespaceAliasCache;
|
||||
llvm::DenseMap<const Decl *, llvm::TypedTrackingMDRef<llvm::DIDerivedType>>
|
||||
@ -194,8 +194,9 @@ class CGDebugInfo {
|
||||
getOrCreateFunctionType(const Decl *D, QualType FnType, llvm::DIFile *F);
|
||||
/// \return debug info descriptor for vtable.
|
||||
llvm::DIType *getOrCreateVTablePtrType(llvm::DIFile *F);
|
||||
|
||||
/// \return namespace descriptor for the given namespace decl.
|
||||
llvm::DINamespace *getOrCreateNameSpace(const NamespaceDecl *N);
|
||||
llvm::DINamespace *getOrCreateNamespace(const NamespaceDecl *N);
|
||||
llvm::DIType *CreatePointerLikeType(llvm::dwarf::Tag Tag, const Type *Ty,
|
||||
QualType PointeeTy, llvm::DIFile *F);
|
||||
llvm::DIType *getOrCreateStructPtrType(StringRef Name, llvm::DIType *&Cache);
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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());
|
||||
|
@ -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,
|
||||
|
@ -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 =
|
||||
|
@ -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: {
|
||||
|
@ -89,14 +89,14 @@ struct BinOpInfo {
|
||||
}
|
||||
|
||||
/// Check if the binop computes a division or a remainder.
|
||||
bool isDivisionLikeOperation() const {
|
||||
bool isDivremOp() const {
|
||||
return Opcode == BO_Div || Opcode == BO_Rem || Opcode == BO_DivAssign ||
|
||||
Opcode == BO_RemAssign;
|
||||
}
|
||||
|
||||
/// Check if the binop can result in an integer division by zero.
|
||||
bool mayHaveIntegerDivisionByZero() const {
|
||||
if (isDivisionLikeOperation())
|
||||
if (isDivremOp())
|
||||
if (auto *CI = dyn_cast<llvm::ConstantInt>(RHS))
|
||||
return CI->isZero();
|
||||
return true;
|
||||
@ -104,7 +104,7 @@ struct BinOpInfo {
|
||||
|
||||
/// Check if the binop can result in a float division by zero.
|
||||
bool mayHaveFloatDivisionByZero() const {
|
||||
if (isDivisionLikeOperation())
|
||||
if (isDivremOp())
|
||||
if (auto *CFP = dyn_cast<llvm::ConstantFP>(RHS))
|
||||
return CFP->isZero();
|
||||
return true;
|
||||
@ -2552,6 +2552,7 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
|
||||
if (isSigned)
|
||||
OpID |= 1;
|
||||
|
||||
CodeGenFunction::SanitizerScope SanScope(&CGF);
|
||||
llvm::Type *opTy = CGF.CGM.getTypes().ConvertType(Ops.Ty);
|
||||
|
||||
llvm::Function *intrinsic = CGF.CGM.getIntrinsic(IID, opTy);
|
||||
@ -2567,7 +2568,6 @@ Value *ScalarExprEmitter::EmitOverflowCheckedBinOp(const BinOpInfo &Ops) {
|
||||
// If the signed-integer-overflow sanitizer is enabled, emit a call to its
|
||||
// runtime. Otherwise, this is a -ftrapv check, so just emit a trap.
|
||||
if (!isSigned || CGF.SanOpts.has(SanitizerKind::SignedIntegerOverflow)) {
|
||||
CodeGenFunction::SanitizerScope SanScope(&CGF);
|
||||
llvm::Value *NotOverflow = Builder.CreateNot(overflow);
|
||||
SanitizerMask Kind = isSigned ? SanitizerKind::SignedIntegerOverflow
|
||||
: SanitizerKind::UnsignedIntegerOverflow;
|
||||
|
@ -34,7 +34,6 @@
|
||||
#include "llvm/IR/LLVMContext.h"
|
||||
#include "llvm/IR/Module.h"
|
||||
#include "llvm/Support/Compiler.h"
|
||||
#include <cstdarg>
|
||||
|
||||
using namespace clang;
|
||||
using namespace CodeGen;
|
||||
@ -58,18 +57,19 @@ 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 <typename... Tys>
|
||||
void init(CodeGenModule *Mod, const char *name, llvm::Type *RetTy,
|
||||
Tys *... Types) {
|
||||
CGM = Mod;
|
||||
FunctionName = name;
|
||||
Function = nullptr;
|
||||
std::vector<llvm::Type *> ArgTys;
|
||||
va_list Args;
|
||||
va_start(Args, RetTy);
|
||||
while (llvm::Type *ArgTy = va_arg(Args, llvm::Type *))
|
||||
ArgTys.push_back(ArgTy);
|
||||
va_end(Args);
|
||||
FTy = llvm::FunctionType::get(RetTy, ArgTys, false);
|
||||
if(sizeof...(Tys)) {
|
||||
SmallVector<llvm::Type *, 8> ArgTys({Types...});
|
||||
FTy = llvm::FunctionType::get(RetTy, ArgTys, false);
|
||||
}
|
||||
else {
|
||||
FTy = llvm::FunctionType::get(RetTy, None, false);
|
||||
}
|
||||
}
|
||||
|
||||
llvm::FunctionType *getType() { return FTy; }
|
||||
@ -603,11 +603,10 @@ 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<llvm::Constant *> IvarNames,
|
||||
IvarList.addInt(IntTy, (int)IvarNames.size());
|
||||
|
||||
// Get the ivar structure type.
|
||||
llvm::StructType *ObjCIvarTy = llvm::StructType::get(
|
||||
PtrToInt8Ty,
|
||||
PtrToInt8Ty,
|
||||
IntTy,
|
||||
nullptr);
|
||||
llvm::StructType *ObjCIvarTy =
|
||||
llvm::StructType::get(PtrToInt8Ty, PtrToInt8Ty, IntTy);
|
||||
|
||||
// Array of ivar structures.
|
||||
auto Ivars = IvarList.beginArray(ObjCIvarTy);
|
||||
@ -1611,7 +1603,7 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
|
||||
// anyway; the classes will still work with the GNU runtime, they will just
|
||||
// be ignored.
|
||||
llvm::StructType *ClassTy = llvm::StructType::get(
|
||||
PtrToInt8Ty, // isa
|
||||
PtrToInt8Ty, // isa
|
||||
PtrToInt8Ty, // super_class
|
||||
PtrToInt8Ty, // name
|
||||
LongTy, // version
|
||||
@ -1620,18 +1612,18 @@ llvm::Constant *CGObjCGNU::GenerateClassStructure(
|
||||
IVars->getType(), // ivars
|
||||
Methods->getType(), // methods
|
||||
// These are all filled in by the runtime, so we pretend
|
||||
PtrTy, // dtable
|
||||
PtrTy, // subclass_list
|
||||
PtrTy, // sibling_class
|
||||
PtrTy, // protocols
|
||||
PtrTy, // gc_object_type
|
||||
PtrTy, // dtable
|
||||
PtrTy, // subclass_list
|
||||
PtrTy, // sibling_class
|
||||
PtrTy, // protocols
|
||||
PtrTy, // gc_object_type
|
||||
// New ABI:
|
||||
LongTy, // abi_version
|
||||
IvarOffsets->getType(), // ivar_offsets
|
||||
Properties->getType(), // properties
|
||||
IntPtrTy, // strong_pointers
|
||||
IntPtrTy, // weak_pointers
|
||||
nullptr);
|
||||
IntPtrTy // weak_pointers
|
||||
);
|
||||
|
||||
ConstantInitBuilder Builder(CGM);
|
||||
auto Elements = Builder.beginStruct(ClassTy);
|
||||
|
@ -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);
|
||||
}
|
||||
|
||||
|
@ -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();
|
||||
|
@ -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);
|
||||
|
@ -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);
|
||||
|
@ -490,7 +490,7 @@ llvm::Type *CodeGenTypes::ConvertType(QualType T) {
|
||||
llvm_unreachable("Unexpected undeduced type!");
|
||||
case Type::Complex: {
|
||||
llvm::Type *EltTy = ConvertType(cast<ComplexType>(Ty)->getElementType());
|
||||
ResultType = llvm::StructType::get(EltTy, EltTy, nullptr);
|
||||
ResultType = llvm::StructType::get(EltTy, EltTy);
|
||||
break;
|
||||
}
|
||||
case Type::LValueReference:
|
||||
|
@ -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:
|
||||
|
@ -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);
|
||||
|
@ -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.
|
||||
|
@ -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,
|
||||
|
@ -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.
|
||||
|
||||
|
@ -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"));
|
||||
}
|
||||
|
@ -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
|
||||
|
@ -171,6 +171,18 @@ template <> struct ScalarEnumerationTraits<FormatStyle::BracketAlignmentStyle> {
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<FormatStyle::EscapedNewlineAlignmentStyle> {
|
||||
static void enumeration(IO &IO, FormatStyle::EscapedNewlineAlignmentStyle &Value) {
|
||||
IO.enumCase(Value, "DontAlign", FormatStyle::ENAS_DontAlign);
|
||||
IO.enumCase(Value, "Left", FormatStyle::ENAS_Left);
|
||||
IO.enumCase(Value, "Right", FormatStyle::ENAS_Right);
|
||||
|
||||
// For backward compatibility.
|
||||
IO.enumCase(Value, "true", FormatStyle::ENAS_Left);
|
||||
IO.enumCase(Value, "false", FormatStyle::ENAS_Right);
|
||||
}
|
||||
};
|
||||
|
||||
template <> struct ScalarEnumerationTraits<FormatStyle::PointerAlignmentStyle> {
|
||||
static void enumeration(IO &IO, FormatStyle::PointerAlignmentStyle &Value) {
|
||||
IO.enumCase(Value, "Middle", FormatStyle::PAS_Middle);
|
||||
@ -233,6 +245,7 @@ template <> struct MappingTraits<FormatStyle> {
|
||||
|
||||
// For backward compatibility.
|
||||
if (!IO.outputting()) {
|
||||
IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlines);
|
||||
IO.mapOptional("DerivePointerBinding", Style.DerivePointerAlignment);
|
||||
IO.mapOptional("IndentFunctionDeclarationAfterType",
|
||||
Style.IndentWrappedFunctionNames);
|
||||
@ -247,7 +260,7 @@ template <> struct MappingTraits<FormatStyle> {
|
||||
Style.AlignConsecutiveAssignments);
|
||||
IO.mapOptional("AlignConsecutiveDeclarations",
|
||||
Style.AlignConsecutiveDeclarations);
|
||||
IO.mapOptional("AlignEscapedNewlinesLeft", Style.AlignEscapedNewlinesLeft);
|
||||
IO.mapOptional("AlignEscapedNewlines", Style.AlignEscapedNewlines);
|
||||
IO.mapOptional("AlignOperands", Style.AlignOperands);
|
||||
IO.mapOptional("AlignTrailingComments", Style.AlignTrailingComments);
|
||||
IO.mapOptional("AllowAllParametersOfDeclarationOnNextLine",
|
||||
@ -498,7 +511,7 @@ FormatStyle getLLVMStyle() {
|
||||
FormatStyle LLVMStyle;
|
||||
LLVMStyle.Language = FormatStyle::LK_Cpp;
|
||||
LLVMStyle.AccessModifierOffset = -2;
|
||||
LLVMStyle.AlignEscapedNewlinesLeft = false;
|
||||
LLVMStyle.AlignEscapedNewlines = FormatStyle::ENAS_Right;
|
||||
LLVMStyle.AlignAfterOpenBracket = FormatStyle::BAS_Align;
|
||||
LLVMStyle.AlignOperands = true;
|
||||
LLVMStyle.AlignTrailingComments = true;
|
||||
@ -587,7 +600,7 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
|
||||
GoogleStyle.Language = Language;
|
||||
|
||||
GoogleStyle.AccessModifierOffset = -1;
|
||||
GoogleStyle.AlignEscapedNewlinesLeft = true;
|
||||
GoogleStyle.AlignEscapedNewlines = FormatStyle::ENAS_Left;
|
||||
GoogleStyle.AllowShortIfStatementsOnASingleLine = true;
|
||||
GoogleStyle.AllowShortLoopsOnASingleLine = true;
|
||||
GoogleStyle.AlwaysBreakBeforeMultilineStrings = true;
|
||||
@ -624,9 +637,10 @@ FormatStyle getGoogleStyle(FormatStyle::LanguageKind Language) {
|
||||
GoogleStyle.AllowShortFunctionsOnASingleLine = FormatStyle::SFS_Empty;
|
||||
GoogleStyle.AlwaysBreakBeforeMultilineStrings = false;
|
||||
GoogleStyle.BreakBeforeTernaryOperators = false;
|
||||
// taze:, @tag followed by { for a lot of JSDoc tags, and @see, which is
|
||||
// commonly followed by overlong URLs.
|
||||
GoogleStyle.CommentPragmas = "(taze:|(@[A-Za-z_0-9-]+[ \\t]*{)|@see)";
|
||||
// taze:, triple slash directives (`/// <...`), @tag followed by { for a lot
|
||||
// of JSDoc tags, and @see, which is commonly followed by overlong URLs.
|
||||
GoogleStyle.CommentPragmas =
|
||||
"(taze:|^/[ \t]*<|(@[A-Za-z_0-9-]+[ \\t]*{)|@see)";
|
||||
GoogleStyle.MaxEmptyLinesToKeep = 3;
|
||||
GoogleStyle.NamespaceIndentation = FormatStyle::NI_All;
|
||||
GoogleStyle.SpacesInContainerLiterals = false;
|
||||
|
@ -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()))
|
||||
|
@ -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)) {
|
||||
|
@ -517,8 +517,11 @@ void WhitespaceManager::alignTrailingComments(unsigned Start, unsigned End,
|
||||
}
|
||||
|
||||
void WhitespaceManager::alignEscapedNewlines() {
|
||||
unsigned MaxEndOfLine =
|
||||
Style.AlignEscapedNewlinesLeft ? 0 : Style.ColumnLimit;
|
||||
if (Style.AlignEscapedNewlines == FormatStyle::ENAS_DontAlign)
|
||||
return;
|
||||
|
||||
bool AlignLeft = Style.AlignEscapedNewlines == FormatStyle::ENAS_Left;
|
||||
unsigned MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
|
||||
unsigned StartOfMacro = 0;
|
||||
for (unsigned i = 1, e = Changes.size(); i < e; ++i) {
|
||||
Change &C = Changes[i];
|
||||
@ -527,7 +530,7 @@ void WhitespaceManager::alignEscapedNewlines() {
|
||||
MaxEndOfLine = std::max(C.PreviousEndOfTokenColumn + 2, MaxEndOfLine);
|
||||
} else {
|
||||
alignEscapedNewlines(StartOfMacro + 1, i, MaxEndOfLine);
|
||||
MaxEndOfLine = Style.AlignEscapedNewlinesLeft ? 0 : Style.ColumnLimit;
|
||||
MaxEndOfLine = AlignLeft ? 0 : Style.ColumnLimit;
|
||||
StartOfMacro = i;
|
||||
}
|
||||
}
|
||||
@ -602,7 +605,7 @@ void WhitespaceManager::appendNewlineText(std::string &Text, unsigned Newlines,
|
||||
unsigned EscapedNewlineColumn) {
|
||||
if (Newlines > 0) {
|
||||
unsigned Offset =
|
||||
std::min<int>(EscapedNewlineColumn - 1, PreviousEndOfTokenColumn);
|
||||
std::min<int>(EscapedNewlineColumn - 2, PreviousEndOfTokenColumn);
|
||||
for (unsigned i = 0; i < Newlines; ++i) {
|
||||
Text.append(EscapedNewlineColumn - Offset - 1, ' ');
|
||||
Text.append(UseCRLF ? "\\\r\n" : "\\\n");
|
||||
|
@ -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);
|
||||
|
@ -1458,12 +1458,13 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
/// \brief Computes two dot products in parallel, using the lower and upper
|
||||
/// halves of two [8 x float] vectors as input to the two computations, and
|
||||
/// returning the two dot products in the lower and upper halves of the
|
||||
/// [8 x float] result. The immediate integer operand controls which input
|
||||
/// elements will contribute to the dot product, and where the final results
|
||||
/// are returned. In general, for each dot product, the four corresponding
|
||||
/// elements of the input vectors are multiplied; the first two and second
|
||||
/// two products are summed, then the two sums are added to form the final
|
||||
/// result.
|
||||
/// [8 x float] result.
|
||||
///
|
||||
/// The immediate integer operand controls which input elements will
|
||||
/// contribute to the dot product, and where the final results are returned.
|
||||
/// In general, for each dot product, the four corresponding elements of the
|
||||
/// input vectors are multiplied; the first two and second two products are
|
||||
/// summed, then the two sums are added to form the final result.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1497,15 +1498,16 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
|
||||
/* Vector shuffle */
|
||||
/// \brief Selects 8 float values from the 256-bit operands of [8 x float], as
|
||||
/// specified by the immediate value operand. The four selected elements in
|
||||
/// each operand are copied to the destination according to the bits
|
||||
/// specified in the immediate operand. The selected elements from the first
|
||||
/// 256-bit operand are copied to bits [63:0] and bits [191:128] of the
|
||||
/// destination, and the selected elements from the second 256-bit operand
|
||||
/// are copied to bits [127:64] and bits [255:192] of the destination. For
|
||||
/// example, if bits [7:0] of the immediate operand contain a value of 0xFF,
|
||||
/// the 256-bit destination vector would contain the following values: b[7],
|
||||
/// b[7], a[7], a[7], b[3], b[3], a[3], a[3].
|
||||
/// specified by the immediate value operand.
|
||||
///
|
||||
/// The four selected elements in each operand are copied to the destination
|
||||
/// according to the bits specified in the immediate operand. The selected
|
||||
/// elements from the first 256-bit operand are copied to bits [63:0] and
|
||||
/// bits [191:128] of the destination, and the selected elements from the
|
||||
/// second 256-bit operand are copied to bits [127:64] and bits [255:192] of
|
||||
/// the destination. For example, if bits [7:0] of the immediate operand
|
||||
/// contain a value of 0xFF, the 256-bit destination vector would contain the
|
||||
/// following values: b[7], b[7], a[7], a[7], b[3], b[3], a[3], a[3].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1557,13 +1559,14 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
12 + (((mask) >> 6) & 0x3)); })
|
||||
|
||||
/// \brief Selects four double-precision values from the 256-bit operands of
|
||||
/// [4 x double], as specified by the immediate value operand. The selected
|
||||
/// elements from the first 256-bit operand are copied to bits [63:0] and
|
||||
/// bits [191:128] in the destination, and the selected elements from the
|
||||
/// second 256-bit operand are copied to bits [127:64] and bits [255:192] in
|
||||
/// the destination. For example, if bits [3:0] of the immediate operand
|
||||
/// contain a value of 0xF, the 256-bit destination vector would contain the
|
||||
/// following values: b[3], a[3], b[1], a[1].
|
||||
/// [4 x double], as specified by the immediate value operand.
|
||||
///
|
||||
/// The selected elements from the first 256-bit operand are copied to bits
|
||||
/// [63:0] and bits [191:128] in the destination, and the selected elements
|
||||
/// from the second 256-bit operand are copied to bits [127:64] and bits
|
||||
/// [255:192] in the destination. For example, if bits [3:0] of the immediate
|
||||
/// operand contain a value of 0xF, the 256-bit destination vector would
|
||||
/// contain the following values: b[3], a[3], b[1], a[1].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1641,9 +1644,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of two
|
||||
/// 128-bit vectors of [2 x double], using the operation specified by the
|
||||
/// immediate integer operand. Returns a [2 x double] vector consisting of
|
||||
/// two doubles corresponding to the two comparison results: zero if the
|
||||
/// comparison is false, and all 1's if the comparison is true.
|
||||
/// immediate integer operand.
|
||||
///
|
||||
/// Returns a [2 x double] vector consisting of two doubles corresponding to
|
||||
/// the two comparison results: zero if the comparison is false, and all 1's
|
||||
/// if the comparison is true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1699,9 +1704,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
|
||||
/// \brief Compares each of the corresponding values of two 128-bit vectors of
|
||||
/// [4 x float], using the operation specified by the immediate integer
|
||||
/// operand. Returns a [4 x float] vector consisting of four floats
|
||||
/// corresponding to the four comparison results: zero if the comparison is
|
||||
/// false, and all 1's if the comparison is true.
|
||||
/// operand.
|
||||
///
|
||||
/// Returns a [4 x float] vector consisting of four floats corresponding to
|
||||
/// the four comparison results: zero if the comparison is false, and all 1's
|
||||
/// if the comparison is true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1757,9 +1764,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of two
|
||||
/// 256-bit vectors of [4 x double], using the operation specified by the
|
||||
/// immediate integer operand. Returns a [4 x double] vector consisting of
|
||||
/// four doubles corresponding to the four comparison results: zero if the
|
||||
/// comparison is false, and all 1's if the comparison is true.
|
||||
/// immediate integer operand.
|
||||
///
|
||||
/// Returns a [4 x double] vector consisting of four doubles corresponding to
|
||||
/// the four comparison results: zero if the comparison is false, and all 1's
|
||||
/// if the comparison is true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1815,9 +1824,11 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
|
||||
/// \brief Compares each of the corresponding values of two 256-bit vectors of
|
||||
/// [8 x float], using the operation specified by the immediate integer
|
||||
/// operand. Returns a [8 x float] vector consisting of eight floats
|
||||
/// corresponding to the eight comparison results: zero if the comparison is
|
||||
/// false, and all 1's if the comparison is true.
|
||||
/// operand.
|
||||
///
|
||||
/// Returns a [8 x float] vector consisting of eight floats corresponding to
|
||||
/// the eight comparison results: zero if the comparison is false, and all
|
||||
/// 1's if the comparison is true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1873,8 +1884,10 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
|
||||
/// \brief Compares each of the corresponding scalar double-precision values of
|
||||
/// two 128-bit vectors of [2 x double], using the operation specified by the
|
||||
/// immediate integer operand. If the result is true, all 64 bits of the
|
||||
/// destination vector are set; otherwise they are cleared.
|
||||
/// immediate integer operand.
|
||||
///
|
||||
/// If the result is true, all 64 bits of the destination vector are set;
|
||||
/// otherwise they are cleared.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1930,8 +1943,10 @@ _mm256_blendv_ps(__m256 __a, __m256 __b, __m256 __c)
|
||||
|
||||
/// \brief Compares each of the corresponding scalar values of two 128-bit
|
||||
/// vectors of [4 x float], using the operation specified by the immediate
|
||||
/// integer operand. If the result is true, all 32 bits of the destination
|
||||
/// vector are set; otherwise they are cleared.
|
||||
/// integer operand.
|
||||
///
|
||||
/// If the result is true, all 32 bits of the destination vector are set;
|
||||
/// otherwise they are cleared.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -2536,7 +2551,9 @@ _mm256_unpacklo_ps(__m256 __a, __m256 __b)
|
||||
/// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
|
||||
/// element-by-element comparison of the double-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of double-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2563,7 +2580,9 @@ _mm_testz_pd(__m128d __a, __m128d __b)
|
||||
/// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
|
||||
/// element-by-element comparison of the double-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of double-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2590,7 +2609,9 @@ _mm_testc_pd(__m128d __a, __m128d __b)
|
||||
/// \brief Given two 128-bit floating-point vectors of [2 x double], perform an
|
||||
/// element-by-element comparison of the double-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of double-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2618,7 +2639,9 @@ _mm_testnzc_pd(__m128d __a, __m128d __b)
|
||||
/// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
|
||||
/// element-by-element comparison of the single-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of single-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2645,7 +2668,9 @@ _mm_testz_ps(__m128 __a, __m128 __b)
|
||||
/// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
|
||||
/// element-by-element comparison of the single-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of single-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2672,7 +2697,9 @@ _mm_testc_ps(__m128 __a, __m128 __b)
|
||||
/// \brief Given two 128-bit floating-point vectors of [4 x float], perform an
|
||||
/// element-by-element comparison of the single-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of single-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2700,7 +2727,9 @@ _mm_testnzc_ps(__m128 __a, __m128 __b)
|
||||
/// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
|
||||
/// element-by-element comparison of the double-precision elements in the
|
||||
/// first source vector and the corresponding elements in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of double-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2727,7 +2756,9 @@ _mm256_testz_pd(__m256d __a, __m256d __b)
|
||||
/// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
|
||||
/// element-by-element comparison of the double-precision elements in the
|
||||
/// first source vector and the corresponding elements in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of double-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2754,7 +2785,9 @@ _mm256_testc_pd(__m256d __a, __m256d __b)
|
||||
/// \brief Given two 256-bit floating-point vectors of [4 x double], perform an
|
||||
/// element-by-element comparison of the double-precision elements in the
|
||||
/// first source vector and the corresponding elements in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of double-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2782,7 +2815,9 @@ _mm256_testnzc_pd(__m256d __a, __m256d __b)
|
||||
/// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
|
||||
/// element-by-element comparison of the single-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of single-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2809,7 +2844,9 @@ _mm256_testz_ps(__m256 __a, __m256 __b)
|
||||
/// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
|
||||
/// element-by-element comparison of the single-precision element in the
|
||||
/// first source vector and the corresponding element in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of single-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2836,7 +2873,9 @@ _mm256_testc_ps(__m256 __a, __m256 __b)
|
||||
/// \brief Given two 256-bit floating-point vectors of [8 x float], perform an
|
||||
/// element-by-element comparison of the single-precision elements in the
|
||||
/// first source vector and the corresponding elements in the second source
|
||||
/// vector. The EFLAGS register is updated as follows: \n
|
||||
/// vector.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of single-precision elements where the
|
||||
/// sign-bits of both elements are 1, the ZF flag is set to 0. Otherwise the
|
||||
/// ZF flag is set to 1. \n
|
||||
@ -2862,7 +2901,9 @@ _mm256_testnzc_ps(__m256 __a, __m256 __b)
|
||||
}
|
||||
|
||||
/// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
|
||||
/// of the two source vectors and update the EFLAGS register as follows: \n
|
||||
/// of the two source vectors.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of bits where both bits are 1, the ZF flag
|
||||
/// is set to 0. Otherwise the ZF flag is set to 1. \n
|
||||
/// If there is at least one pair of bits where the bit from the first source
|
||||
@ -2886,7 +2927,9 @@ _mm256_testz_si256(__m256i __a, __m256i __b)
|
||||
}
|
||||
|
||||
/// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
|
||||
/// of the two source vectors and update the EFLAGS register as follows: \n
|
||||
/// of the two source vectors.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of bits where both bits are 1, the ZF flag
|
||||
/// is set to 0. Otherwise the ZF flag is set to 1. \n
|
||||
/// If there is at least one pair of bits where the bit from the first source
|
||||
@ -2910,7 +2953,9 @@ _mm256_testc_si256(__m256i __a, __m256i __b)
|
||||
}
|
||||
|
||||
/// \brief Given two 256-bit integer vectors, perform a bit-by-bit comparison
|
||||
/// of the two source vectors and update the EFLAGS register as follows: \n
|
||||
/// of the two source vectors.
|
||||
///
|
||||
/// The EFLAGS register is updated as follows: \n
|
||||
/// If there is at least one pair of bits where both bits are 1, the ZF flag
|
||||
/// is set to 0. Otherwise the ZF flag is set to 1. \n
|
||||
/// If there is at least one pair of bits where the bit from the first source
|
||||
@ -4466,9 +4511,10 @@ _mm256_castsi256_si128(__m256i __a)
|
||||
}
|
||||
|
||||
/// \brief Constructs a 256-bit floating-point vector of [4 x double] from a
|
||||
/// 128-bit floating-point vector of [2 x double]. The lower 128 bits
|
||||
/// contain the value of the source vector. The contents of the upper 128
|
||||
/// bits are undefined.
|
||||
/// 128-bit floating-point vector of [2 x double].
|
||||
///
|
||||
/// The lower 128 bits contain the value of the source vector. The contents
|
||||
/// of the upper 128 bits are undefined.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -4486,9 +4532,10 @@ _mm256_castpd128_pd256(__m128d __a)
|
||||
}
|
||||
|
||||
/// \brief Constructs a 256-bit floating-point vector of [8 x float] from a
|
||||
/// 128-bit floating-point vector of [4 x float]. The lower 128 bits contain
|
||||
/// the value of the source vector. The contents of the upper 128 bits are
|
||||
/// undefined.
|
||||
/// 128-bit floating-point vector of [4 x float].
|
||||
///
|
||||
/// The lower 128 bits contain the value of the source vector. The contents
|
||||
/// of the upper 128 bits are undefined.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -4506,6 +4553,7 @@ _mm256_castps128_ps256(__m128 __a)
|
||||
}
|
||||
|
||||
/// \brief Constructs a 256-bit integer vector from a 128-bit integer vector.
|
||||
///
|
||||
/// The lower 128 bits contain the value of the source vector. The contents
|
||||
/// of the upper 128 bits are undefined.
|
||||
///
|
||||
@ -4586,8 +4634,10 @@ _mm256_zextsi128_si256(__m128i __a)
|
||||
/// \brief Constructs a new 256-bit vector of [8 x float] by first duplicating
|
||||
/// a 256-bit vector of [8 x float] given in the first parameter, and then
|
||||
/// replacing either the upper or the lower 128 bits with the contents of a
|
||||
/// 128-bit vector of [4 x float] in the second parameter. The immediate
|
||||
/// integer parameter determines between the upper or the lower 128 bits.
|
||||
/// 128-bit vector of [4 x float] in the second parameter.
|
||||
///
|
||||
/// The immediate integer parameter determines between the upper or the lower
|
||||
/// 128 bits.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -4631,8 +4681,10 @@ _mm256_zextsi128_si256(__m128i __a)
|
||||
/// \brief Constructs a new 256-bit vector of [4 x double] by first duplicating
|
||||
/// a 256-bit vector of [4 x double] given in the first parameter, and then
|
||||
/// replacing either the upper or the lower 128 bits with the contents of a
|
||||
/// 128-bit vector of [2 x double] in the second parameter. The immediate
|
||||
/// integer parameter determines between the upper or the lower 128 bits.
|
||||
/// 128-bit vector of [2 x double] in the second parameter.
|
||||
///
|
||||
/// The immediate integer parameter determines between the upper or the lower
|
||||
/// 128 bits.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -4672,8 +4724,10 @@ _mm256_zextsi128_si256(__m128i __a)
|
||||
/// \brief Constructs a new 256-bit integer vector by first duplicating a
|
||||
/// 256-bit integer vector given in the first parameter, and then replacing
|
||||
/// either the upper or the lower 128 bits with the contents of a 128-bit
|
||||
/// integer vector in the second parameter. The immediate integer parameter
|
||||
/// determines between the upper or the lower 128 bits.
|
||||
/// integer vector in the second parameter.
|
||||
///
|
||||
/// The immediate integer parameter determines between the upper or the lower
|
||||
/// 128 bits.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
|
@ -462,8 +462,9 @@ _mm_cmplt_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are less than or equal to those in the second operand. Each
|
||||
/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// operand are less than or equal to those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -482,8 +483,9 @@ _mm_cmple_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are greater than those in the second operand. Each comparison
|
||||
/// yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// operand are greater than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -502,8 +504,9 @@ _mm_cmpgt_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are greater than or equal to those in the second operand. Each
|
||||
/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// operand are greater than or equal to those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -522,9 +525,10 @@ _mm_cmpge_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are ordered with respect to those in the second operand. A pair
|
||||
/// of double-precision values are "ordered" with respect to each other if
|
||||
/// neither value is a NaN. Each comparison yields 0h for false,
|
||||
/// operand are ordered with respect to those in the second operand.
|
||||
///
|
||||
/// A pair of double-precision values are "ordered" with respect to each
|
||||
/// other if neither value is a NaN. Each comparison yields 0h for false,
|
||||
/// FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
@ -544,9 +548,10 @@ _mm_cmpord_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are unordered with respect to those in the second operand. A pair
|
||||
/// of double-precision values are "unordered" with respect to each other if
|
||||
/// one or both values are NaN. Each comparison yields 0h for false,
|
||||
/// operand are unordered with respect to those in the second operand.
|
||||
///
|
||||
/// A pair of double-precision values are "unordered" with respect to each
|
||||
/// other if one or both values are NaN. Each comparison yields 0h for false,
|
||||
/// FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
@ -567,8 +572,9 @@ _mm_cmpunord_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are unequal to those in the second operand. Each comparison
|
||||
/// yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// operand are unequal to those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -587,8 +593,9 @@ _mm_cmpneq_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are not less than those in the second operand. Each comparison
|
||||
/// yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// operand are not less than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -607,8 +614,9 @@ _mm_cmpnlt_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are not less than or equal to those in the second operand. Each
|
||||
/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// operand are not less than or equal to those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -627,8 +635,9 @@ _mm_cmpnle_pd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are not greater than those in the second operand. Each
|
||||
/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// operand are not greater than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -648,6 +657,7 @@ _mm_cmpngt_pd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares each of the corresponding double-precision values of the
|
||||
/// 128-bit vectors of [2 x double] to determine if the values in the first
|
||||
/// operand are not greater than or equal to those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
@ -666,8 +676,9 @@ _mm_cmpnge_pd(__m128d __a, __m128d __b)
|
||||
}
|
||||
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] for equality. The
|
||||
/// comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// the two 128-bit floating-point vectors of [2 x double] for equality.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -690,8 +701,9 @@ _mm_cmpeq_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is less than the corresponding value in
|
||||
/// the second parameter. The comparison yields 0h for false,
|
||||
/// FFFFFFFFFFFFFFFFh for true.
|
||||
/// the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -714,8 +726,9 @@ _mm_cmplt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is less than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0h for
|
||||
/// false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -738,8 +751,9 @@ _mm_cmple_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is greater than the corresponding value
|
||||
/// in the second parameter. The comparison yields 0h for false,
|
||||
/// FFFFFFFFFFFFFFFFh for true.
|
||||
/// in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -763,8 +777,9 @@ _mm_cmpgt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is greater than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0h for
|
||||
/// false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -788,9 +803,11 @@ _mm_cmpge_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is "ordered" with respect to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0h for
|
||||
/// false, FFFFFFFFFFFFFFFFh for true. A pair of double-precision values are
|
||||
/// "ordered" with respect to each other if neither value is a NaN.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true. A pair of
|
||||
/// double-precision values are "ordered" with respect to each other if
|
||||
/// neither value is a NaN.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -813,9 +830,11 @@ _mm_cmpord_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is "unordered" with respect to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0h
|
||||
/// for false, FFFFFFFFFFFFFFFFh for true. A pair of double-precision values
|
||||
/// are "unordered" with respect to each other if one or both values are NaN.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true. A pair of
|
||||
/// double-precision values are "unordered" with respect to each other if one
|
||||
/// or both values are NaN.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -839,8 +858,9 @@ _mm_cmpunord_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is unequal to the corresponding value in
|
||||
/// the second parameter. The comparison yields 0h for false,
|
||||
/// FFFFFFFFFFFFFFFFh for true.
|
||||
/// the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -863,8 +883,9 @@ _mm_cmpneq_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is not less than the corresponding
|
||||
/// value in the second parameter. The comparison yields 0h for false,
|
||||
/// FFFFFFFFFFFFFFFFh for true.
|
||||
/// value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -887,8 +908,9 @@ _mm_cmpnlt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is not less than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0h
|
||||
/// for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -911,8 +933,9 @@ _mm_cmpnle_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is not greater than the corresponding
|
||||
/// value in the second parameter. The comparison yields 0h for false,
|
||||
/// FFFFFFFFFFFFFFFFh for true.
|
||||
/// value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -936,8 +959,9 @@ _mm_cmpngt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is not greater than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0h
|
||||
/// for false, FFFFFFFFFFFFFFFFh for true.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0h for false, FFFFFFFFFFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -982,7 +1006,9 @@ _mm_comieq_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is less than the corresponding value in
|
||||
/// the second parameter. The comparison yields 0 for false, 1 for true.
|
||||
/// the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1004,8 +1030,9 @@ _mm_comilt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is less than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0 for
|
||||
/// false, 1 for true.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1027,7 +1054,9 @@ _mm_comile_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is greater than the corresponding value
|
||||
/// in the second parameter. The comparison yields 0 for false, 1 for true.
|
||||
/// in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1049,8 +1078,9 @@ _mm_comigt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is greater than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0 for
|
||||
/// false, 1 for true.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1072,7 +1102,9 @@ _mm_comige_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is unequal to the corresponding value in
|
||||
/// the second parameter. The comparison yields 0 for false, 1 for true.
|
||||
/// the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1093,8 +1125,9 @@ _mm_comineq_sd(__m128d __a, __m128d __b)
|
||||
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] for equality. The
|
||||
/// comparison yields 0 for false, 1 for true. If either of the two lower
|
||||
/// double-precision values is NaN, 1 is returned.
|
||||
/// comparison yields 0 for false, 1 for true.
|
||||
///
|
||||
/// If either of the two lower double-precision values is NaN, 1 is returned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1117,8 +1150,10 @@ _mm_ucomieq_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is less than the corresponding value in
|
||||
/// the second parameter. The comparison yields 0 for false, 1 for true. If
|
||||
/// either of the two lower double-precision values is NaN, 1 is returned.
|
||||
/// the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true. If either of the two lower
|
||||
/// double-precision values is NaN, 1 is returned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1141,9 +1176,10 @@ _mm_ucomilt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is less than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0 for
|
||||
/// false, 1 for true. If either of the two lower double-precision values is
|
||||
/// NaN, 1 is returned.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true. If either of the two lower
|
||||
/// double-precision values is NaN, 1 is returned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1166,8 +1202,10 @@ _mm_ucomile_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is greater than the corresponding value
|
||||
/// in the second parameter. The comparison yields 0 for false, 1 for true.
|
||||
/// If either of the two lower double-precision values is NaN, 0 is returned.
|
||||
/// in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true. If either of the two lower
|
||||
/// double-precision values is NaN, 0 is returned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1190,9 +1228,10 @@ _mm_ucomigt_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is greater than or equal to the
|
||||
/// corresponding value in the second parameter. The comparison yields 0 for
|
||||
/// false, 1 for true. If either of the two lower double-precision values
|
||||
/// is NaN, 0 is returned.
|
||||
/// corresponding value in the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true. If either of the two
|
||||
/// lower double-precision values is NaN, 0 is returned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1215,8 +1254,10 @@ _mm_ucomige_sd(__m128d __a, __m128d __b)
|
||||
/// \brief Compares the lower double-precision floating-point values in each of
|
||||
/// the two 128-bit floating-point vectors of [2 x double] to determine if
|
||||
/// the value in the first parameter is unequal to the corresponding value in
|
||||
/// the second parameter. The comparison yields 0 for false, 1 for true. If
|
||||
/// either of the two lower double-precision values is NaN, 0 is returned.
|
||||
/// the second parameter.
|
||||
///
|
||||
/// The comparison yields 0 for false, 1 for true. If either of the two lower
|
||||
/// double-precision values is NaN, 0 is returned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1278,8 +1319,9 @@ _mm_cvtps_pd(__m128 __a)
|
||||
|
||||
/// \brief Converts the lower two integer elements of a 128-bit vector of
|
||||
/// [4 x i32] into two double-precision floating-point values, returned in a
|
||||
/// 128-bit vector of [2 x double]. The upper two elements of the input
|
||||
/// vector are unused.
|
||||
/// 128-bit vector of [2 x double].
|
||||
///
|
||||
/// The upper two elements of the input vector are unused.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1287,7 +1329,9 @@ _mm_cvtps_pd(__m128 __a)
|
||||
///
|
||||
/// \param __a
|
||||
/// A 128-bit integer vector of [4 x i32]. The lower two integer elements are
|
||||
/// converted to double-precision values. The upper two elements are unused.
|
||||
/// converted to double-precision values.
|
||||
///
|
||||
/// The upper two elements are unused.
|
||||
/// \returns A 128-bit vector of [2 x double] containing the converted values.
|
||||
static __inline__ __m128d __DEFAULT_FN_ATTRS
|
||||
_mm_cvtepi32_pd(__m128i __a)
|
||||
@ -1409,10 +1453,11 @@ _mm_cvtss_sd(__m128d __a, __m128 __b)
|
||||
|
||||
/// \brief Converts the two double-precision floating-point elements of a
|
||||
/// 128-bit vector of [2 x double] into two signed 32-bit integer values,
|
||||
/// returned in the lower 64 bits of a 128-bit vector of [4 x i32]. If the
|
||||
/// result of either conversion is inexact, the result is truncated (rounded
|
||||
/// towards zero) regardless of the current MXCSR setting. The upper 64 bits
|
||||
/// of the result vector are set to zero.
|
||||
/// returned in the lower 64 bits of a 128-bit vector of [4 x i32].
|
||||
///
|
||||
/// If the result of either conversion is inexact, the result is truncated
|
||||
/// (rounded towards zero) regardless of the current MXCSR setting. The upper
|
||||
/// 64 bits of the result vector are set to zero.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1466,9 +1511,10 @@ _mm_cvtpd_pi32(__m128d __a)
|
||||
|
||||
/// \brief Converts the two double-precision floating-point elements of a
|
||||
/// 128-bit vector of [2 x double] into two signed 32-bit integer values,
|
||||
/// returned in a 64-bit vector of [2 x i32]. If the result of either
|
||||
/// conversion is inexact, the result is truncated (rounded towards zero)
|
||||
/// regardless of the current MXCSR setting.
|
||||
/// returned in a 64-bit vector of [2 x i32].
|
||||
///
|
||||
/// If the result of either conversion is inexact, the result is truncated
|
||||
/// (rounded towards zero) regardless of the current MXCSR setting.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1980,8 +2026,9 @@ _mm_storel_pd(double *__dp, __m128d __a)
|
||||
|
||||
/// \brief Adds the corresponding elements of two 128-bit vectors of [16 x i8],
|
||||
/// saving the lower 8 bits of each sum in the corresponding element of a
|
||||
/// 128-bit result vector of [16 x i8]. The integer elements of both
|
||||
/// parameters can be either signed or unsigned.
|
||||
/// 128-bit result vector of [16 x i8].
|
||||
///
|
||||
/// The integer elements of both parameters can be either signed or unsigned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -2001,8 +2048,9 @@ _mm_add_epi8(__m128i __a, __m128i __b)
|
||||
|
||||
/// \brief Adds the corresponding elements of two 128-bit vectors of [8 x i16],
|
||||
/// saving the lower 16 bits of each sum in the corresponding element of a
|
||||
/// 128-bit result vector of [8 x i16]. The integer elements of both
|
||||
/// parameters can be either signed or unsigned.
|
||||
/// 128-bit result vector of [8 x i16].
|
||||
///
|
||||
/// The integer elements of both parameters can be either signed or unsigned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -2022,8 +2070,9 @@ _mm_add_epi16(__m128i __a, __m128i __b)
|
||||
|
||||
/// \brief Adds the corresponding elements of two 128-bit vectors of [4 x i32],
|
||||
/// saving the lower 32 bits of each sum in the corresponding element of a
|
||||
/// 128-bit result vector of [4 x i32]. The integer elements of both
|
||||
/// parameters can be either signed or unsigned.
|
||||
/// 128-bit result vector of [4 x i32].
|
||||
///
|
||||
/// The integer elements of both parameters can be either signed or unsigned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -2061,8 +2110,9 @@ _mm_add_si64(__m64 __a, __m64 __b)
|
||||
|
||||
/// \brief Adds the corresponding elements of two 128-bit vectors of [2 x i64],
|
||||
/// saving the lower 64 bits of each sum in the corresponding element of a
|
||||
/// 128-bit result vector of [2 x i64]. The integer elements of both
|
||||
/// parameters can be either signed or unsigned.
|
||||
/// 128-bit result vector of [2 x i64].
|
||||
///
|
||||
/// The integer elements of both parameters can be either signed or unsigned.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -2208,10 +2258,12 @@ _mm_avg_epu16(__m128i __a, __m128i __b)
|
||||
/// \brief Multiplies the corresponding elements of two 128-bit signed [8 x i16]
|
||||
/// vectors, producing eight intermediate 32-bit signed integer products, and
|
||||
/// adds the consecutive pairs of 32-bit products to form a 128-bit signed
|
||||
/// [4 x i32] vector. For example, bits [15:0] of both parameters are
|
||||
/// multiplied producing a 32-bit product, bits [31:16] of both parameters
|
||||
/// are multiplied producing a 32-bit product, and the sum of those two
|
||||
/// products becomes bits [31:0] of the result.
|
||||
/// [4 x i32] vector.
|
||||
///
|
||||
/// For example, bits [15:0] of both parameters are multiplied producing a
|
||||
/// 32-bit product, bits [31:16] of both parameters are multiplied producing
|
||||
/// a 32-bit product, and the sum of those two products becomes bits [31:0]
|
||||
/// of the result.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3146,8 +3198,9 @@ _mm_cmpgt_epi8(__m128i __a, __m128i __b)
|
||||
|
||||
/// \brief Compares each of the corresponding signed 16-bit values of the
|
||||
/// 128-bit integer vectors to determine if the values in the first operand
|
||||
/// are greater than those in the second operand. Each comparison yields 0h
|
||||
/// for false, FFFFh for true.
|
||||
/// are greater than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3166,8 +3219,9 @@ _mm_cmpgt_epi16(__m128i __a, __m128i __b)
|
||||
|
||||
/// \brief Compares each of the corresponding signed 32-bit values of the
|
||||
/// 128-bit integer vectors to determine if the values in the first operand
|
||||
/// are greater than those in the second operand. Each comparison yields 0h
|
||||
/// for false, FFFFFFFFh for true.
|
||||
/// are greater than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3186,8 +3240,9 @@ _mm_cmpgt_epi32(__m128i __a, __m128i __b)
|
||||
|
||||
/// \brief Compares each of the corresponding signed 8-bit values of the 128-bit
|
||||
/// integer vectors to determine if the values in the first operand are less
|
||||
/// than those in the second operand. Each comparison yields 0h for false,
|
||||
/// FFh for true.
|
||||
/// than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3206,8 +3261,9 @@ _mm_cmplt_epi8(__m128i __a, __m128i __b)
|
||||
|
||||
/// \brief Compares each of the corresponding signed 16-bit values of the
|
||||
/// 128-bit integer vectors to determine if the values in the first operand
|
||||
/// are less than those in the second operand. Each comparison yields 0h for
|
||||
/// false, FFFFh for true.
|
||||
/// are less than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3226,8 +3282,9 @@ _mm_cmplt_epi16(__m128i __a, __m128i __b)
|
||||
|
||||
/// \brief Compares each of the corresponding signed 32-bit values of the
|
||||
/// 128-bit integer vectors to determine if the values in the first operand
|
||||
/// are less than those in the second operand. Each comparison yields 0h for
|
||||
/// false, FFFFFFFFh for true.
|
||||
/// are less than those in the second operand.
|
||||
///
|
||||
/// Each comparison yields 0h for false, FFFFFFFFh for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3925,10 +3982,11 @@ _mm_storeu_si128(__m128i *__p, __m128i __b)
|
||||
|
||||
/// \brief Moves bytes selected by the mask from the first operand to the
|
||||
/// specified unaligned memory location. When a mask bit is 1, the
|
||||
/// corresponding byte is written, otherwise it is not written. To minimize
|
||||
/// caching, the date is flagged as non-temporal (unlikely to be used again
|
||||
/// soon). Exception and trap behavior for elements not selected for storage
|
||||
/// to memory are implementation dependent.
|
||||
/// corresponding byte is written, otherwise it is not written.
|
||||
///
|
||||
/// To minimize caching, the date is flagged as non-temporal (unlikely to be
|
||||
/// used again soon). Exception and trap behavior for elements not selected
|
||||
/// for storage to memory are implementation dependent.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3972,8 +4030,10 @@ _mm_storel_epi64(__m128i *__p, __m128i __a)
|
||||
}
|
||||
|
||||
/// \brief Stores a 128-bit floating point vector of [2 x double] to a 128-bit
|
||||
/// aligned memory location. To minimize caching, the data is flagged as
|
||||
/// non-temporal (unlikely to be used again soon).
|
||||
/// aligned memory location.
|
||||
///
|
||||
/// To minimize caching, the data is flagged as non-temporal (unlikely to be
|
||||
/// used again soon).
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -3990,6 +4050,7 @@ _mm_stream_pd(double *__p, __m128d __a)
|
||||
}
|
||||
|
||||
/// \brief Stores a 128-bit integer vector to a 128-bit aligned memory location.
|
||||
///
|
||||
/// To minimize caching, the data is flagged as non-temporal (unlikely to be
|
||||
/// used again soon).
|
||||
///
|
||||
@ -4007,8 +4068,9 @@ _mm_stream_si128(__m128i *__p, __m128i __a)
|
||||
__builtin_nontemporal_store((__v2di)__a, (__v2di*)__p);
|
||||
}
|
||||
|
||||
/// \brief Stores a 32-bit integer value in the specified memory location. To
|
||||
/// minimize caching, the data is flagged as non-temporal (unlikely to be
|
||||
/// \brief Stores a 32-bit integer value in the specified memory location.
|
||||
///
|
||||
/// To minimize caching, the data is flagged as non-temporal (unlikely to be
|
||||
/// used again soon).
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
@ -4026,8 +4088,9 @@ _mm_stream_si32(int *__p, int __a)
|
||||
}
|
||||
|
||||
#ifdef __x86_64__
|
||||
/// \brief Stores a 64-bit integer value in the specified memory location. To
|
||||
/// minimize caching, the data is flagged as non-temporal (unlikely to be
|
||||
/// \brief Stores a 64-bit integer value in the specified memory location.
|
||||
///
|
||||
/// To minimize caching, the data is flagged as non-temporal (unlikely to be
|
||||
/// used again soon).
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
|
@ -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);
|
||||
|
@ -608,10 +608,11 @@ _mm_subs_pi16(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Subtracts each 8-bit unsigned integer element of the second 64-bit
|
||||
/// integer vector of [8 x i8] from the corresponding 8-bit unsigned integer
|
||||
/// element of the first 64-bit integer vector of [8 x i8]. If an element of
|
||||
/// the first vector is less than the corresponding element of the second
|
||||
/// vector, the result is saturated to 0. The results are packed into a
|
||||
/// 64-bit integer vector of [8 x i8].
|
||||
/// element of the first 64-bit integer vector of [8 x i8].
|
||||
///
|
||||
/// If an element of the first vector is less than the corresponding element
|
||||
/// of the second vector, the result is saturated to 0. The results are
|
||||
/// packed into a 64-bit integer vector of [8 x i8].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -631,10 +632,11 @@ _mm_subs_pu8(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Subtracts each 16-bit unsigned integer element of the second 64-bit
|
||||
/// integer vector of [4 x i16] from the corresponding 16-bit unsigned
|
||||
/// integer element of the first 64-bit integer vector of [4 x i16]. If an
|
||||
/// element of the first vector is less than the corresponding element of the
|
||||
/// second vector, the result is saturated to 0. The results are packed into
|
||||
/// a 64-bit integer vector of [4 x i16].
|
||||
/// integer element of the first 64-bit integer vector of [4 x i16].
|
||||
///
|
||||
/// If an element of the first vector is less than the corresponding element
|
||||
/// of the second vector, the result is saturated to 0. The results are
|
||||
/// packed into a 64-bit integer vector of [4 x i16].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -657,9 +659,11 @@ _mm_subs_pu16(__m64 __m1, __m64 __m2)
|
||||
/// element of the second 64-bit integer vector of [4 x i16] and get four
|
||||
/// 32-bit products. Adds adjacent pairs of products to get two 32-bit sums.
|
||||
/// The lower 32 bits of these two sums are packed into a 64-bit integer
|
||||
/// vector of [2 x i32]. For example, bits [15:0] of both parameters are
|
||||
/// multiplied, bits [31:16] of both parameters are multiplied, and the sum
|
||||
/// of both results is written to bits [31:0] of the result.
|
||||
/// vector of [2 x i32].
|
||||
///
|
||||
/// For example, bits [15:0] of both parameters are multiplied, bits [31:16]
|
||||
/// of both parameters are multiplied, and the sum of both results is written
|
||||
/// to bits [31:0] of the result.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -851,10 +855,11 @@ _mm_slli_si64(__m64 __m, int __count)
|
||||
|
||||
/// \brief Right-shifts each 16-bit integer element of the first parameter,
|
||||
/// which is a 64-bit integer vector of [4 x i16], by the number of bits
|
||||
/// specified by the second parameter, which is a 64-bit integer. High-order
|
||||
/// bits are filled with the sign bit of the initial value of each 16-bit
|
||||
/// element. The 16-bit results are packed into a 64-bit integer vector of
|
||||
/// [4 x i16].
|
||||
/// specified by the second parameter, which is a 64-bit integer.
|
||||
///
|
||||
/// High-order bits are filled with the sign bit of the initial value of each
|
||||
/// 16-bit element. The 16-bit results are packed into a 64-bit integer
|
||||
/// vector of [4 x i16].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -874,6 +879,7 @@ _mm_sra_pi16(__m64 __m, __m64 __count)
|
||||
|
||||
/// \brief Right-shifts each 16-bit integer element of a 64-bit integer vector
|
||||
/// of [4 x i16] by the number of bits specified by a 32-bit integer.
|
||||
///
|
||||
/// High-order bits are filled with the sign bit of the initial value of each
|
||||
/// 16-bit element. The 16-bit results are packed into a 64-bit integer
|
||||
/// vector of [4 x i16].
|
||||
@ -896,10 +902,11 @@ _mm_srai_pi16(__m64 __m, int __count)
|
||||
|
||||
/// \brief Right-shifts each 32-bit integer element of the first parameter,
|
||||
/// which is a 64-bit integer vector of [2 x i32], by the number of bits
|
||||
/// specified by the second parameter, which is a 64-bit integer. High-order
|
||||
/// bits are filled with the sign bit of the initial value of each 32-bit
|
||||
/// element. The 32-bit results are packed into a 64-bit integer vector of
|
||||
/// [2 x i32].
|
||||
/// specified by the second parameter, which is a 64-bit integer.
|
||||
///
|
||||
/// High-order bits are filled with the sign bit of the initial value of each
|
||||
/// 32-bit element. The 32-bit results are packed into a 64-bit integer
|
||||
/// vector of [2 x i32].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -919,6 +926,7 @@ _mm_sra_pi32(__m64 __m, __m64 __count)
|
||||
|
||||
/// \brief Right-shifts each 32-bit integer element of a 64-bit integer vector
|
||||
/// of [2 x i32] by the number of bits specified by a 32-bit integer.
|
||||
///
|
||||
/// High-order bits are filled with the sign bit of the initial value of each
|
||||
/// 32-bit element. The 32-bit results are packed into a 64-bit integer
|
||||
/// vector of [2 x i32].
|
||||
@ -941,9 +949,10 @@ _mm_srai_pi32(__m64 __m, int __count)
|
||||
|
||||
/// \brief Right-shifts each 16-bit integer element of the first parameter,
|
||||
/// which is a 64-bit integer vector of [4 x i16], by the number of bits
|
||||
/// specified by the second parameter, which is a 64-bit integer. High-order
|
||||
/// bits are cleared. The 16-bit results are packed into a 64-bit integer
|
||||
/// vector of [4 x i16].
|
||||
/// specified by the second parameter, which is a 64-bit integer.
|
||||
///
|
||||
/// High-order bits are cleared. The 16-bit results are packed into a 64-bit
|
||||
/// integer vector of [4 x i16].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -963,6 +972,7 @@ _mm_srl_pi16(__m64 __m, __m64 __count)
|
||||
|
||||
/// \brief Right-shifts each 16-bit integer element of a 64-bit integer vector
|
||||
/// of [4 x i16] by the number of bits specified by a 32-bit integer.
|
||||
///
|
||||
/// High-order bits are cleared. The 16-bit results are packed into a 64-bit
|
||||
/// integer vector of [4 x i16].
|
||||
///
|
||||
@ -984,9 +994,10 @@ _mm_srli_pi16(__m64 __m, int __count)
|
||||
|
||||
/// \brief Right-shifts each 32-bit integer element of the first parameter,
|
||||
/// which is a 64-bit integer vector of [2 x i32], by the number of bits
|
||||
/// specified by the second parameter, which is a 64-bit integer. High-order
|
||||
/// bits are cleared. The 32-bit results are packed into a 64-bit integer
|
||||
/// vector of [2 x i32].
|
||||
/// specified by the second parameter, which is a 64-bit integer.
|
||||
///
|
||||
/// High-order bits are cleared. The 32-bit results are packed into a 64-bit
|
||||
/// integer vector of [2 x i32].
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1006,6 +1017,7 @@ _mm_srl_pi32(__m64 __m, __m64 __count)
|
||||
|
||||
/// \brief Right-shifts each 32-bit integer element of a 64-bit integer vector
|
||||
/// of [2 x i32] by the number of bits specified by a 32-bit integer.
|
||||
///
|
||||
/// High-order bits are cleared. The 32-bit results are packed into a 64-bit
|
||||
/// integer vector of [2 x i32].
|
||||
///
|
||||
@ -1026,8 +1038,9 @@ _mm_srli_pi32(__m64 __m, int __count)
|
||||
}
|
||||
|
||||
/// \brief Right-shifts the first 64-bit integer parameter by the number of bits
|
||||
/// specified by the second 64-bit integer parameter. High-order bits are
|
||||
/// cleared.
|
||||
/// specified by the second 64-bit integer parameter.
|
||||
///
|
||||
/// High-order bits are cleared.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1046,7 +1059,9 @@ _mm_srl_si64(__m64 __m, __m64 __count)
|
||||
|
||||
/// \brief Right-shifts the first parameter, which is a 64-bit integer, by the
|
||||
/// number of bits specified by the second parameter, which is a 32-bit
|
||||
/// integer. High-order bits are cleared.
|
||||
/// integer.
|
||||
///
|
||||
/// High-order bits are cleared.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1140,8 +1155,9 @@ _mm_xor_si64(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Compares the 8-bit integer elements of two 64-bit integer vectors of
|
||||
/// [8 x i8] to determine if the element of the first vector is equal to the
|
||||
/// corresponding element of the second vector. The comparison yields 0 for
|
||||
/// false, 0xFF for true.
|
||||
/// corresponding element of the second vector.
|
||||
///
|
||||
/// The comparison yields 0 for false, 0xFF for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1161,8 +1177,9 @@ _mm_cmpeq_pi8(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Compares the 16-bit integer elements of two 64-bit integer vectors of
|
||||
/// [4 x i16] to determine if the element of the first vector is equal to the
|
||||
/// corresponding element of the second vector. The comparison yields 0 for
|
||||
/// false, 0xFFFF for true.
|
||||
/// corresponding element of the second vector.
|
||||
///
|
||||
/// The comparison yields 0 for false, 0xFFFF for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1182,8 +1199,9 @@ _mm_cmpeq_pi16(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Compares the 32-bit integer elements of two 64-bit integer vectors of
|
||||
/// [2 x i32] to determine if the element of the first vector is equal to the
|
||||
/// corresponding element of the second vector. The comparison yields 0 for
|
||||
/// false, 0xFFFFFFFF for true.
|
||||
/// corresponding element of the second vector.
|
||||
///
|
||||
/// The comparison yields 0 for false, 0xFFFFFFFF for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1203,8 +1221,9 @@ _mm_cmpeq_pi32(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Compares the 8-bit integer elements of two 64-bit integer vectors of
|
||||
/// [8 x i8] to determine if the element of the first vector is greater than
|
||||
/// the corresponding element of the second vector. The comparison yields 0
|
||||
/// for false, 0xFF for true.
|
||||
/// the corresponding element of the second vector.
|
||||
///
|
||||
/// The comparison yields 0 for false, 0xFF for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1224,8 +1243,9 @@ _mm_cmpgt_pi8(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Compares the 16-bit integer elements of two 64-bit integer vectors of
|
||||
/// [4 x i16] to determine if the element of the first vector is greater than
|
||||
/// the corresponding element of the second vector. The comparison yields 0
|
||||
/// for false, 0xFFFF for true.
|
||||
/// the corresponding element of the second vector.
|
||||
///
|
||||
/// The comparison yields 0 for false, 0xFFFF for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -1245,8 +1265,9 @@ _mm_cmpgt_pi16(__m64 __m1, __m64 __m2)
|
||||
|
||||
/// \brief Compares the 32-bit integer elements of two 64-bit integer vectors of
|
||||
/// [2 x i32] to determine if the element of the first vector is greater than
|
||||
/// the corresponding element of the second vector. The comparison yields 0
|
||||
/// for false, 0xFFFFFFFF for true.
|
||||
/// the corresponding element of the second vector.
|
||||
///
|
||||
/// The comparison yields 0 for false, 0xFFFFFFFF for true.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
|
@ -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:
|
||||
|
@ -31,9 +31,11 @@
|
||||
__attribute__((__always_inline__, __nodebug__, __target__("sse3")))
|
||||
|
||||
/// \brief Loads data from an unaligned memory location to elements in a 128-bit
|
||||
/// vector. If the address of the data is not 16-byte aligned, the
|
||||
/// instruction may read two adjacent aligned blocks of memory to retrieve
|
||||
/// the requested data.
|
||||
/// vector.
|
||||
///
|
||||
/// If the address of the data is not 16-byte aligned, the instruction may
|
||||
/// read two adjacent aligned blocks of memory to retrieve the requested
|
||||
/// data.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
|
@ -50,8 +50,10 @@ _m_prefetch(void *__P)
|
||||
/// the L1 data cache and sets the cache-coherency to modified. This
|
||||
/// provides a hint to the processor that the cache line will be modified.
|
||||
/// It is intended for use when the cache line will be written to shortly
|
||||
/// after the prefetch is performed. Note that the effect of this intrinsic
|
||||
/// is dependent on the processor implementation.
|
||||
/// after the prefetch is performed.
|
||||
///
|
||||
/// Note that the effect of this intrinsic is dependent on the processor
|
||||
/// implementation.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
|
@ -586,7 +586,9 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
|
||||
/* SSE4 Floating Point Dot Product Instructions. */
|
||||
/// \brief Computes the dot product of the two 128-bit vectors of [4 x float]
|
||||
/// and returns it in the elements of the 128-bit result vector of
|
||||
/// [4 x float]. The immediate integer operand controls which input elements
|
||||
/// [4 x float].
|
||||
///
|
||||
/// The immediate integer operand controls which input elements
|
||||
/// will contribute to the dot product, and where the final results are
|
||||
/// returned.
|
||||
///
|
||||
@ -620,7 +622,9 @@ _mm_mul_epi32 (__m128i __V1, __m128i __V2)
|
||||
|
||||
/// \brief Computes the dot product of the two 128-bit vectors of [2 x double]
|
||||
/// and returns it in the elements of the 128-bit result vector of
|
||||
/// [2 x double]. The immediate integer operand controls which input
|
||||
/// [2 x double].
|
||||
///
|
||||
/// The immediate integer operand controls which input
|
||||
/// elements will contribute to the dot product, and where the final results
|
||||
/// are returned.
|
||||
///
|
||||
@ -875,7 +879,7 @@ _mm_max_epu32 (__m128i __V1, __m128i __V2)
|
||||
/// int _mm_extract_ps(__m128 X, const int N);
|
||||
/// \endcode
|
||||
///
|
||||
/// This intrinsic corresponds to the <c> VEXTRACTPS / EXTRACTPS </c>
|
||||
/// This intrinsic corresponds to the <c> VEXTRACTPS / EXTRACTPS </c>
|
||||
/// instruction.
|
||||
///
|
||||
/// \param X
|
||||
|
@ -469,10 +469,11 @@ _mm_hsubs_pi16(__m64 __a, __m64 __b)
|
||||
/// values contained in the first source operand and packed 8-bit signed
|
||||
/// integer values contained in the second source operand, adds pairs of
|
||||
/// contiguous products with signed saturation, and writes the 16-bit sums to
|
||||
/// the corresponding bits in the destination. For example, bits [7:0] of
|
||||
/// both operands are multiplied, bits [15:8] of both operands are
|
||||
/// multiplied, and the sum of both results is written to bits [15:0] of the
|
||||
/// destination.
|
||||
/// the corresponding bits in the destination.
|
||||
///
|
||||
/// For example, bits [7:0] of both operands are multiplied, bits [15:8] of
|
||||
/// both operands are multiplied, and the sum of both results is written to
|
||||
/// bits [15:0] of the destination.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -502,10 +503,11 @@ _mm_maddubs_epi16(__m128i __a, __m128i __b)
|
||||
/// values contained in the first source operand and packed 8-bit signed
|
||||
/// integer values contained in the second source operand, adds pairs of
|
||||
/// contiguous products with signed saturation, and writes the 16-bit sums to
|
||||
/// the corresponding bits in the destination. For example, bits [7:0] of
|
||||
/// both operands are multiplied, bits [15:8] of both operands are
|
||||
/// multiplied, and the sum of both results is written to bits [15:0] of the
|
||||
/// destination.
|
||||
/// the corresponding bits in the destination.
|
||||
///
|
||||
/// For example, bits [7:0] of both operands are multiplied, bits [15:8] of
|
||||
/// both operands are multiplied, and the sum of both results is written to
|
||||
/// bits [15:0] of the destination.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -619,13 +621,14 @@ _mm_shuffle_pi8(__m64 __a, __m64 __b)
|
||||
}
|
||||
|
||||
/// \brief For each 8-bit integer in the first source operand, perform one of
|
||||
/// the following actions as specified by the second source operand: If the
|
||||
/// byte in the second source is negative, calculate the two's complement of
|
||||
/// the corresponding byte in the first source, and write that value to the
|
||||
/// destination. If the byte in the second source is positive, copy the
|
||||
/// corresponding byte from the first source to the destination. If the byte
|
||||
/// in the second source is zero, clear the corresponding byte in the
|
||||
/// destination.
|
||||
/// the following actions as specified by the second source operand.
|
||||
///
|
||||
/// If the byte in the second source is negative, calculate the two's
|
||||
/// complement of the corresponding byte in the first source, and write that
|
||||
/// value to the destination. If the byte in the second source is positive,
|
||||
/// copy the corresponding byte from the first source to the destination. If
|
||||
/// the byte in the second source is zero, clear the corresponding byte in
|
||||
/// the destination.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -644,13 +647,14 @@ _mm_sign_epi8(__m128i __a, __m128i __b)
|
||||
}
|
||||
|
||||
/// \brief For each 16-bit integer in the first source operand, perform one of
|
||||
/// the following actions as specified by the second source operand: If the
|
||||
/// word in the second source is negative, calculate the two's complement of
|
||||
/// the corresponding word in the first source, and write that value to the
|
||||
/// destination. If the word in the second source is positive, copy the
|
||||
/// corresponding word from the first source to the destination. If the word
|
||||
/// in the second source is zero, clear the corresponding word in the
|
||||
/// destination.
|
||||
/// the following actions as specified by the second source operand.
|
||||
///
|
||||
/// If the word in the second source is negative, calculate the two's
|
||||
/// complement of the corresponding word in the first source, and write that
|
||||
/// value to the destination. If the word in the second source is positive,
|
||||
/// copy the corresponding word from the first source to the destination. If
|
||||
/// the word in the second source is zero, clear the corresponding word in
|
||||
/// the destination.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -669,8 +673,9 @@ _mm_sign_epi16(__m128i __a, __m128i __b)
|
||||
}
|
||||
|
||||
/// \brief For each 32-bit integer in the first source operand, perform one of
|
||||
/// the following actions as specified by the second source operand: If the
|
||||
/// doubleword in the second source is negative, calculate the two's
|
||||
/// the following actions as specified by the second source operand.
|
||||
///
|
||||
/// If the doubleword in the second source is negative, calculate the two's
|
||||
/// complement of the corresponding word in the first source, and write that
|
||||
/// value to the destination. If the doubleword in the second source is
|
||||
/// positive, copy the corresponding word from the first source to the
|
||||
@ -694,13 +699,14 @@ _mm_sign_epi32(__m128i __a, __m128i __b)
|
||||
}
|
||||
|
||||
/// \brief For each 8-bit integer in the first source operand, perform one of
|
||||
/// the following actions as specified by the second source operand: If the
|
||||
/// byte in the second source is negative, calculate the two's complement of
|
||||
/// the corresponding byte in the first source, and write that value to the
|
||||
/// destination. If the byte in the second source is positive, copy the
|
||||
/// corresponding byte from the first source to the destination. If the byte
|
||||
/// in the second source is zero, clear the corresponding byte in the
|
||||
/// destination.
|
||||
/// the following actions as specified by the second source operand.
|
||||
///
|
||||
/// If the byte in the second source is negative, calculate the two's
|
||||
/// complement of the corresponding byte in the first source, and write that
|
||||
/// value to the destination. If the byte in the second source is positive,
|
||||
/// copy the corresponding byte from the first source to the destination. If
|
||||
/// the byte in the second source is zero, clear the corresponding byte in
|
||||
/// the destination.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -719,13 +725,14 @@ _mm_sign_pi8(__m64 __a, __m64 __b)
|
||||
}
|
||||
|
||||
/// \brief For each 16-bit integer in the first source operand, perform one of
|
||||
/// the following actions as specified by the second source operand: If the
|
||||
/// word in the second source is negative, calculate the two's complement of
|
||||
/// the corresponding word in the first source, and write that value to the
|
||||
/// destination. If the word in the second source is positive, copy the
|
||||
/// corresponding word from the first source to the destination. If the word
|
||||
/// in the second source is zero, clear the corresponding word in the
|
||||
/// destination.
|
||||
/// the following actions as specified by the second source operand.
|
||||
///
|
||||
/// If the word in the second source is negative, calculate the two's
|
||||
/// complement of the corresponding word in the first source, and write that
|
||||
/// value to the destination. If the word in the second source is positive,
|
||||
/// copy the corresponding word from the first source to the destination. If
|
||||
/// the word in the second source is zero, clear the corresponding word in
|
||||
/// the destination.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -744,8 +751,9 @@ _mm_sign_pi16(__m64 __a, __m64 __b)
|
||||
}
|
||||
|
||||
/// \brief For each 32-bit integer in the first source operand, perform one of
|
||||
/// the following actions as specified by the second source operand: If the
|
||||
/// doubleword in the second source is negative, calculate the two's
|
||||
/// the following actions as specified by the second source operand.
|
||||
///
|
||||
/// If the doubleword in the second source is negative, calculate the two's
|
||||
/// complement of the corresponding doubleword in the first source, and
|
||||
/// write that value to the destination. If the doubleword in the second
|
||||
/// source is positive, copy the corresponding doubleword from the first
|
||||
|
@ -88,6 +88,4 @@
|
||||
#include <clzerointrin.h>
|
||||
#endif
|
||||
|
||||
/* FIXME: LWP */
|
||||
|
||||
#endif /* __X86INTRIN_H */
|
||||
|
@ -2331,8 +2331,10 @@ _mm_mulhi_pu16(__m64 __a, __m64 __b)
|
||||
/// \brief Conditionally copies the values from each 8-bit element in the first
|
||||
/// 64-bit integer vector operand to the specified memory location, as
|
||||
/// specified by the most significant bit in the corresponding element in the
|
||||
/// second 64-bit integer vector operand. To minimize caching, the data is
|
||||
/// flagged as non-temporal (unlikely to be used again soon).
|
||||
/// second 64-bit integer vector operand.
|
||||
///
|
||||
/// To minimize caching, the data is flagged as non-temporal
|
||||
/// (unlikely to be used again soon).
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -2815,11 +2817,12 @@ _mm_cvtpi32x2_ps(__m64 __a, __m64 __b)
|
||||
|
||||
/// \brief Converts each single-precision floating-point element of a 128-bit
|
||||
/// floating-point vector of [4 x float] into a 16-bit signed integer, and
|
||||
/// packs the results into a 64-bit integer vector of [4 x i16]. If the
|
||||
/// floating-point element is NaN or infinity, or if the floating-point
|
||||
/// element is greater than 0x7FFFFFFF or less than -0x8000, it is converted
|
||||
/// to 0x8000. Otherwise if the floating-point element is greater than
|
||||
/// 0x7FFF, it is converted to 0x7FFF.
|
||||
/// packs the results into a 64-bit integer vector of [4 x i16].
|
||||
///
|
||||
/// If the floating-point element is NaN or infinity, or if the
|
||||
/// floating-point element is greater than 0x7FFFFFFF or less than -0x8000,
|
||||
/// it is converted to 0x8000. Otherwise if the floating-point element is
|
||||
/// greater than 0x7FFF, it is converted to 0x7FFF.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
@ -2845,11 +2848,12 @@ _mm_cvtps_pi16(__m128 __a)
|
||||
/// \brief Converts each single-precision floating-point element of a 128-bit
|
||||
/// floating-point vector of [4 x float] into an 8-bit signed integer, and
|
||||
/// packs the results into the lower 32 bits of a 64-bit integer vector of
|
||||
/// [8 x i8]. The upper 32 bits of the vector are set to 0. If the
|
||||
/// floating-point element is NaN or infinity, or if the floating-point
|
||||
/// element is greater than 0x7FFFFFFF or less than -0x80, it is converted
|
||||
/// to 0x80. Otherwise if the floating-point element is greater than 0x7F,
|
||||
/// it is converted to 0x7F.
|
||||
/// [8 x i8]. The upper 32 bits of the vector are set to 0.
|
||||
///
|
||||
/// If the floating-point element is NaN or infinity, or if the
|
||||
/// floating-point element is greater than 0x7FFFFFFF or less than -0x80, it
|
||||
/// is converted to 0x80. Otherwise if the floating-point element is greater
|
||||
/// than 0x7F, it is converted to 0x7F.
|
||||
///
|
||||
/// \headerfile <x86intrin.h>
|
||||
///
|
||||
|
@ -150,6 +150,53 @@ class BodyIndexer : public RecursiveASTVisitor<BodyIndexer> {
|
||||
Parent, ParentDC, Roles, Relations, E);
|
||||
}
|
||||
|
||||
bool indexDependentReference(
|
||||
const Expr *E, const Type *T, const DeclarationNameInfo &NameInfo,
|
||||
llvm::function_ref<bool(const NamedDecl *ND)> Filter) {
|
||||
if (!T)
|
||||
return true;
|
||||
const TemplateSpecializationType *TST =
|
||||
T->getAs<TemplateSpecializationType>();
|
||||
if (!TST)
|
||||
return true;
|
||||
TemplateName TN = TST->getTemplateName();
|
||||
const ClassTemplateDecl *TD =
|
||||
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
|
||||
if (!TD)
|
||||
return true;
|
||||
CXXRecordDecl *RD = TD->getTemplatedDecl();
|
||||
if (!RD->hasDefinition())
|
||||
return true;
|
||||
RD = RD->getDefinition();
|
||||
std::vector<const NamedDecl *> Symbols =
|
||||
RD->lookupDependentName(NameInfo.getName(), Filter);
|
||||
// FIXME: Improve overload handling.
|
||||
if (Symbols.size() != 1)
|
||||
return true;
|
||||
SourceLocation Loc = NameInfo.getLoc();
|
||||
if (Loc.isInvalid())
|
||||
Loc = E->getLocStart();
|
||||
SmallVector<SymbolRelation, 4> Relations;
|
||||
SymbolRoleSet Roles = getRolesForRef(E, Relations);
|
||||
return IndexCtx.handleReference(Symbols[0], Loc, Parent, ParentDC, Roles,
|
||||
Relations, E);
|
||||
}
|
||||
|
||||
bool VisitCXXDependentScopeMemberExpr(CXXDependentScopeMemberExpr *E) {
|
||||
const DeclarationNameInfo &Info = E->getMemberNameInfo();
|
||||
return indexDependentReference(
|
||||
E, E->getBaseType().getTypePtrOrNull(), Info,
|
||||
[](const NamedDecl *D) { return D->isCXXInstanceMember(); });
|
||||
}
|
||||
|
||||
bool VisitDependentScopeDeclRefExpr(DependentScopeDeclRefExpr *E) {
|
||||
const DeclarationNameInfo &Info = E->getNameInfo();
|
||||
const NestedNameSpecifier *NNS = E->getQualifier();
|
||||
return indexDependentReference(
|
||||
E, NNS->getAsType(), Info,
|
||||
[](const NamedDecl *D) { return !D->isCXXInstanceMember(); });
|
||||
}
|
||||
|
||||
bool VisitDesignatedInitExpr(DesignatedInitExpr *E) {
|
||||
for (DesignatedInitExpr::Designator &D : llvm::reverse(E->designators())) {
|
||||
if (D.isFieldDesignator() && D.getField())
|
||||
|
@ -52,6 +52,22 @@ class IndexingDeclVisitor : public ConstDeclVisitor<IndexingDeclVisitor, bool> {
|
||||
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<IndexingDeclVisitor, bool> {
|
||||
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<IndexingDeclVisitor, bool> {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitNamespaceAliasDecl(const NamespaceAliasDecl *D) {
|
||||
TRY_DECL(D, IndexCtx.handleDecl(D));
|
||||
IndexCtx.indexNestedNameSpecifierLoc(D->getQualifierLoc(), D);
|
||||
IndexCtx.handleReference(D->getAliasedNamespace(), D->getTargetNameLoc(), D,
|
||||
D->getLexicalDeclContext());
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitUsingDecl(const UsingDecl *D) {
|
||||
const DeclContext *DC = D->getDeclContext()->getRedeclContext();
|
||||
const NamedDecl *Parent = dyn_cast<NamedDecl>(DC);
|
||||
|
@ -141,6 +141,34 @@ class TypeIndexer : public RecursiveASTVisitor<TypeIndexer> {
|
||||
return true;
|
||||
}
|
||||
|
||||
bool VisitDependentNameTypeLoc(DependentNameTypeLoc TL) {
|
||||
const DependentNameType *DNT = TL.getTypePtr();
|
||||
const NestedNameSpecifier *NNS = DNT->getQualifier();
|
||||
const Type *T = NNS->getAsType();
|
||||
if (!T)
|
||||
return true;
|
||||
const TemplateSpecializationType *TST =
|
||||
T->getAs<TemplateSpecializationType>();
|
||||
if (!TST)
|
||||
return true;
|
||||
TemplateName TN = TST->getTemplateName();
|
||||
const ClassTemplateDecl *TD =
|
||||
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl());
|
||||
if (!TD)
|
||||
return true;
|
||||
CXXRecordDecl *RD = TD->getTemplatedDecl();
|
||||
if (!RD->hasDefinition())
|
||||
return true;
|
||||
RD = RD->getDefinition();
|
||||
DeclarationName Name(DNT->getIdentifier());
|
||||
std::vector<const NamedDecl *> Symbols = RD->lookupDependentName(
|
||||
Name, [](const NamedDecl *ND) { return isa<TypeDecl>(ND); });
|
||||
if (Symbols.size() != 1)
|
||||
return true;
|
||||
return IndexCtx.handleReference(Symbols[0], TL.getNameLoc(), Parent,
|
||||
ParentDC, SymbolRoleSet(), Relations);
|
||||
}
|
||||
|
||||
bool TraverseStmt(Stmt *S) {
|
||||
IndexCtx.indexBody(S, Parent, ParentDC);
|
||||
return true;
|
||||
@ -184,7 +212,7 @@ void IndexingContext::indexNestedNameSpecifierLoc(NestedNameSpecifierLoc NNS,
|
||||
|
||||
if (!DC)
|
||||
DC = Parent->getLexicalDeclContext();
|
||||
SourceLocation Loc = NNS.getSourceRange().getBegin();
|
||||
SourceLocation Loc = NNS.getLocalBeginLoc();
|
||||
|
||||
switch (NNS.getNestedNameSpecifier()->getKind()) {
|
||||
case NestedNameSpecifier::Identifier:
|
||||
|
@ -124,6 +124,10 @@ bool IndexingContext::isTemplateImplicitInstantiation(const Decl *D) {
|
||||
TKind = FD->getTemplateSpecializationKind();
|
||||
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
TKind = VD->getTemplateSpecializationKind();
|
||||
} else if (isa<FieldDecl>(D)) {
|
||||
if (const auto *Parent =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext()))
|
||||
TKind = Parent->getSpecializationKind();
|
||||
}
|
||||
switch (TKind) {
|
||||
case TSK_Undeclared:
|
||||
@ -159,6 +163,17 @@ static const Decl *adjustTemplateImplicitInstantiation(const Decl *D) {
|
||||
return FD->getTemplateInstantiationPattern();
|
||||
} else if (auto *VD = dyn_cast<VarDecl>(D)) {
|
||||
return VD->getTemplateInstantiationPattern();
|
||||
} else if (const auto *FD = dyn_cast<FieldDecl>(D)) {
|
||||
if (const auto *Parent =
|
||||
dyn_cast<ClassTemplateSpecializationDecl>(D->getDeclContext())) {
|
||||
const CXXRecordDecl *Pattern = Parent->getTemplateInstantiationPattern();
|
||||
for (const NamedDecl *ND : Pattern->lookup(FD->getDeclName())) {
|
||||
if (ND->isImplicit())
|
||||
continue;
|
||||
if (isa<FieldDecl>(ND))
|
||||
return ND;
|
||||
}
|
||||
}
|
||||
}
|
||||
return nullptr;
|
||||
}
|
||||
|
@ -29,7 +29,6 @@ MacroInfo::MacroInfo(SourceLocation DefLoc)
|
||||
IsUsed(false),
|
||||
IsAllowRedefinitionsWithoutWarning(false),
|
||||
IsWarnIfUnused(false),
|
||||
FromASTFile(false),
|
||||
UsedForHeaderGuard(false) {
|
||||
}
|
||||
|
||||
@ -137,7 +136,6 @@ LLVM_DUMP_METHOD void MacroInfo::dump() const {
|
||||
if (IsAllowRedefinitionsWithoutWarning)
|
||||
Out << " allow_redefinitions_without_warning";
|
||||
if (IsWarnIfUnused) Out << " warn_if_unused";
|
||||
if (FromASTFile) Out << " imported";
|
||||
if (UsedForHeaderGuard) Out << " header_guard";
|
||||
|
||||
Out << "\n #define <macro>";
|
||||
|
@ -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);
|
||||
|
@ -54,35 +54,12 @@ using namespace clang;
|
||||
// Utility Methods for Preprocessor Directive Handling.
|
||||
//===----------------------------------------------------------------------===//
|
||||
|
||||
MacroInfo *Preprocessor::AllocateMacroInfo() {
|
||||
MacroInfoChain *MIChain = BP.Allocate<MacroInfoChain>();
|
||||
MIChain->Next = MIChainHead;
|
||||
MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
|
||||
auto *MIChain = new (BP) MacroInfoChain{L, MIChainHead};
|
||||
MIChainHead = MIChain;
|
||||
return &MIChain->MI;
|
||||
}
|
||||
|
||||
MacroInfo *Preprocessor::AllocateMacroInfo(SourceLocation L) {
|
||||
MacroInfo *MI = AllocateMacroInfo();
|
||||
new (MI) MacroInfo(L);
|
||||
return MI;
|
||||
}
|
||||
|
||||
MacroInfo *Preprocessor::AllocateDeserializedMacroInfo(SourceLocation L,
|
||||
unsigned SubModuleID) {
|
||||
static_assert(alignof(MacroInfo) >= sizeof(SubModuleID),
|
||||
"alignment for MacroInfo is less than the ID");
|
||||
DeserializedMacroInfoChain *MIChain =
|
||||
BP.Allocate<DeserializedMacroInfoChain>();
|
||||
MIChain->Next = DeserialMIChainHead;
|
||||
DeserialMIChainHead = MIChain;
|
||||
|
||||
MacroInfo *MI = &MIChain->MI;
|
||||
new (MI) MacroInfo(L);
|
||||
MI->FromASTFile = true;
|
||||
MI->setOwningModuleID(SubModuleID);
|
||||
return MI;
|
||||
}
|
||||
|
||||
DefMacroDirective *Preprocessor::AllocateDefMacroDirective(MacroInfo *MI,
|
||||
SourceLocation Loc) {
|
||||
return new (BP) DefMacroDirective(MI, Loc);
|
||||
|
@ -88,7 +88,7 @@ Preprocessor::Preprocessor(std::shared_ptr<PreprocessorOptions> PPOpts,
|
||||
CurDirLookup(nullptr), CurLexerKind(CLK_Lexer),
|
||||
CurLexerSubmodule(nullptr), Callbacks(nullptr),
|
||||
CurSubmoduleState(&NullSubmoduleState), MacroArgCache(nullptr),
|
||||
Record(nullptr), MIChainHead(nullptr), DeserialMIChainHead(nullptr) {
|
||||
Record(nullptr), MIChainHead(nullptr) {
|
||||
OwnsHeaderSearch = OwnsHeaders;
|
||||
|
||||
CounterValue = 0; // __COUNTER__ starts at 0.
|
||||
@ -169,11 +169,6 @@ Preprocessor::~Preprocessor() {
|
||||
std::fill(TokenLexerCache, TokenLexerCache + NumCachedTokenLexers, nullptr);
|
||||
CurTokenLexer.reset();
|
||||
|
||||
while (DeserializedMacroInfoChain *I = DeserialMIChainHead) {
|
||||
DeserialMIChainHead = I->Next;
|
||||
I->~DeserializedMacroInfoChain();
|
||||
}
|
||||
|
||||
// Free any cached MacroArgs.
|
||||
for (MacroArgs *ArgList = MacroArgCache; ArgList;)
|
||||
ArgList = ArgList->deallocate();
|
||||
|
@ -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.
|
||||
|
@ -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();
|
||||
|
@ -235,6 +235,30 @@ bool Parser::isNotExpressionStart() {
|
||||
return isKnownToBeDeclarationSpecifier();
|
||||
}
|
||||
|
||||
/// We've parsed something that could plausibly be intended to be a template
|
||||
/// name (\p LHS) followed by a '<' token, and the following code can't possibly
|
||||
/// be an expression. Determine if this is likely to be a template-id and if so,
|
||||
/// diagnose it.
|
||||
bool Parser::diagnoseUnknownTemplateId(ExprResult LHS, SourceLocation Less) {
|
||||
TentativeParsingAction TPA(*this);
|
||||
// FIXME: We could look at the token sequence in a lot more detail here.
|
||||
if (SkipUntil(tok::greater, tok::greatergreater, tok::greatergreatergreater,
|
||||
StopAtSemi | StopBeforeMatch)) {
|
||||
TPA.Commit();
|
||||
|
||||
SourceLocation Greater;
|
||||
ParseGreaterThanInTemplateList(Greater, true, false);
|
||||
Actions.diagnoseExprIntendedAsTemplateName(getCurScope(), LHS,
|
||||
Less, Greater);
|
||||
return true;
|
||||
}
|
||||
|
||||
// There's no matching '>' token, this probably isn't supposed to be
|
||||
// interpreted as a template-id. Parse it as an (ill-formed) comparison.
|
||||
TPA.Revert();
|
||||
return false;
|
||||
}
|
||||
|
||||
static bool isFoldOperator(prec::Level Level) {
|
||||
return Level > prec::Unknown && Level != prec::Conditional;
|
||||
}
|
||||
@ -276,6 +300,16 @@ Parser::ParseRHSOfBinaryExpression(ExprResult LHS, prec::Level MinPrec) {
|
||||
return LHS;
|
||||
}
|
||||
|
||||
// If a '<' token is followed by a type that can be a template argument and
|
||||
// cannot be an expression, then this is ill-formed, but might be intended
|
||||
// to be a template-id.
|
||||
if (OpToken.is(tok::less) && Actions.mightBeIntendedToBeTemplateName(LHS) &&
|
||||
(isKnownToBeDeclarationSpecifier() ||
|
||||
Tok.isOneOf(tok::greater, tok::greatergreater,
|
||||
tok::greatergreatergreater)) &&
|
||||
diagnoseUnknownTemplateId(LHS, OpToken.getLocation()))
|
||||
return ExprError();
|
||||
|
||||
// If the next token is an ellipsis, then this is a fold-expression. Leave
|
||||
// it alone so we can handle it in the paren expression.
|
||||
if (isFoldOperator(NextTokPrec) && Tok.is(tok::ellipsis)) {
|
||||
@ -2989,6 +3023,11 @@ Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
|
||||
return AvailabilitySpec(ConsumeToken());
|
||||
} else {
|
||||
// Parse the platform name.
|
||||
if (Tok.is(tok::code_completion)) {
|
||||
Actions.CodeCompleteAvailabilityPlatformName();
|
||||
cutOffParsing();
|
||||
return None;
|
||||
}
|
||||
if (Tok.isNot(tok::identifier)) {
|
||||
Diag(Tok, diag::err_avail_query_expected_platform_name);
|
||||
return None;
|
||||
@ -3001,12 +3040,14 @@ Optional<AvailabilitySpec> Parser::ParseAvailabilitySpec() {
|
||||
if (Version.empty())
|
||||
return None;
|
||||
|
||||
StringRef Platform = PlatformIdentifier->Ident->getName();
|
||||
StringRef GivenPlatform = PlatformIdentifier->Ident->getName();
|
||||
StringRef Platform =
|
||||
AvailabilityAttr::canonicalizePlatformName(GivenPlatform);
|
||||
|
||||
if (AvailabilityAttr::getPrettyPlatformName(Platform).empty()) {
|
||||
Diag(PlatformIdentifier->Loc,
|
||||
diag::err_avail_query_unrecognized_platform_name)
|
||||
<< Platform;
|
||||
<< GivenPlatform;
|
||||
return None;
|
||||
}
|
||||
|
||||
|
@ -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 ||
|
||||
|
@ -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);
|
||||
|
||||
|
@ -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()
|
||||
|
||||
|
@ -477,6 +477,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
|
||||
return true;
|
||||
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
// If this is a function template and none of its specializations is used,
|
||||
// we should warn.
|
||||
if (FunctionTemplateDecl *Template = FD->getDescribedFunctionTemplate())
|
||||
for (const auto *Spec : Template->specializations())
|
||||
if (ShouldRemoveFromUnused(SemaRef, Spec))
|
||||
return true;
|
||||
|
||||
// UnusedFileScopedDecls stores the first declaration.
|
||||
// The declaration may have become definition so check again.
|
||||
const FunctionDecl *DeclToCheck;
|
||||
@ -500,6 +507,13 @@ static bool ShouldRemoveFromUnused(Sema *SemaRef, const DeclaratorDecl *D) {
|
||||
VD->isUsableInConstantExpressions(SemaRef->Context))
|
||||
return true;
|
||||
|
||||
if (VarTemplateDecl *Template = VD->getDescribedVarTemplate())
|
||||
// If this is a variable template and none of its specializations is used,
|
||||
// we should warn.
|
||||
for (const auto *Spec : Template->specializations())
|
||||
if (ShouldRemoveFromUnused(SemaRef, Spec))
|
||||
return true;
|
||||
|
||||
// UnusedFileScopedDecls stores the first declaration.
|
||||
// The declaration may have become definition so check again.
|
||||
const VarDecl *DeclToCheck = VD->getDefinition();
|
||||
@ -905,10 +919,14 @@ void Sema::ActOnEndOfTranslationUnit() {
|
||||
<< /*function*/0 << DiagD->getDeclName();
|
||||
}
|
||||
} else {
|
||||
Diag(DiagD->getLocation(),
|
||||
isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
|
||||
: diag::warn_unused_function)
|
||||
<< DiagD->getDeclName();
|
||||
if (FD->getDescribedFunctionTemplate())
|
||||
Diag(DiagD->getLocation(), diag::warn_unused_template)
|
||||
<< /*function*/0 << DiagD->getDeclName();
|
||||
else
|
||||
Diag(DiagD->getLocation(),
|
||||
isa<CXXMethodDecl>(DiagD) ? diag::warn_unused_member_function
|
||||
: diag::warn_unused_function)
|
||||
<< DiagD->getDeclName();
|
||||
}
|
||||
} else {
|
||||
const VarDecl *DiagD = cast<VarDecl>(*I)->getDefinition();
|
||||
@ -924,7 +942,11 @@ void Sema::ActOnEndOfTranslationUnit() {
|
||||
Diag(DiagD->getLocation(), diag::warn_unused_const_variable)
|
||||
<< DiagD->getDeclName();
|
||||
} else {
|
||||
Diag(DiagD->getLocation(), diag::warn_unused_variable)
|
||||
if (DiagD->getDescribedVarTemplate())
|
||||
Diag(DiagD->getLocation(), diag::warn_unused_template)
|
||||
<< /*variable*/1 << DiagD->getDeclName();
|
||||
else
|
||||
Diag(DiagD->getLocation(), diag::warn_unused_variable)
|
||||
<< DiagD->getDeclName();
|
||||
}
|
||||
}
|
||||
|
@ -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();
|
||||
}
|
||||
|
@ -3869,6 +3869,41 @@ static void AddObjCProperties(
|
||||
}
|
||||
}
|
||||
|
||||
static void AddRecordMembersCompletionResults(Sema &SemaRef,
|
||||
ResultBuilder &Results, Scope *S,
|
||||
QualType BaseType,
|
||||
RecordDecl *RD) {
|
||||
// Indicate that we are performing a member access, and the cv-qualifiers
|
||||
// for the base object type.
|
||||
Results.setObjectTypeQualifiers(BaseType.getQualifiers());
|
||||
|
||||
// Access to a C/C++ class, struct, or union.
|
||||
Results.allowNestedNameSpecifiers();
|
||||
CodeCompletionDeclConsumer Consumer(Results, SemaRef.CurContext);
|
||||
SemaRef.LookupVisibleDecls(RD, Sema::LookupMemberName, Consumer,
|
||||
SemaRef.CodeCompleter->includeGlobals(),
|
||||
/*IncludeDependentBases=*/true);
|
||||
|
||||
if (SemaRef.getLangOpts().CPlusPlus) {
|
||||
if (!Results.empty()) {
|
||||
// The "template" keyword can follow "->" or "." in the grammar.
|
||||
// However, we only want to suggest the template keyword if something
|
||||
// is dependent.
|
||||
bool IsDependent = BaseType->isDependentType();
|
||||
if (!IsDependent) {
|
||||
for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
|
||||
if (DeclContext *Ctx = DepScope->getEntity()) {
|
||||
IsDependent = Ctx->isDependentContext();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsDependent)
|
||||
Results.AddResult(CodeCompletionResult("template"));
|
||||
}
|
||||
}
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
|
||||
SourceLocation OpLoc, bool IsArrow,
|
||||
bool IsBaseExprStatement) {
|
||||
@ -3879,8 +3914,6 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
|
||||
if (ConvertedBase.isInvalid())
|
||||
return;
|
||||
Base = ConvertedBase.get();
|
||||
|
||||
typedef CodeCompletionResult Result;
|
||||
|
||||
QualType BaseType = Base->getType();
|
||||
|
||||
@ -3915,34 +3948,18 @@ void Sema::CodeCompleteMemberReferenceExpr(Scope *S, Expr *Base,
|
||||
&ResultBuilder::IsMember);
|
||||
Results.EnterNewScope();
|
||||
if (const RecordType *Record = BaseType->getAs<RecordType>()) {
|
||||
// Indicate that we are performing a member access, and the cv-qualifiers
|
||||
// for the base object type.
|
||||
Results.setObjectTypeQualifiers(BaseType.getQualifiers());
|
||||
|
||||
// Access to a C/C++ class, struct, or union.
|
||||
Results.allowNestedNameSpecifiers();
|
||||
CodeCompletionDeclConsumer Consumer(Results, CurContext);
|
||||
LookupVisibleDecls(Record->getDecl(), LookupMemberName, Consumer,
|
||||
CodeCompleter->includeGlobals());
|
||||
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
if (!Results.empty()) {
|
||||
// The "template" keyword can follow "->" or "." in the grammar.
|
||||
// However, we only want to suggest the template keyword if something
|
||||
// is dependent.
|
||||
bool IsDependent = BaseType->isDependentType();
|
||||
if (!IsDependent) {
|
||||
for (Scope *DepScope = S; DepScope; DepScope = DepScope->getParent())
|
||||
if (DeclContext *Ctx = DepScope->getEntity()) {
|
||||
IsDependent = Ctx->isDependentContext();
|
||||
break;
|
||||
}
|
||||
}
|
||||
|
||||
if (IsDependent)
|
||||
Results.AddResult(Result("template"));
|
||||
}
|
||||
AddRecordMembersCompletionResults(*this, Results, S, BaseType,
|
||||
Record->getDecl());
|
||||
} else if (const auto *TST = BaseType->getAs<TemplateSpecializationType>()) {
|
||||
TemplateName TN = TST->getTemplateName();
|
||||
if (const auto *TD =
|
||||
dyn_cast_or_null<ClassTemplateDecl>(TN.getAsTemplateDecl())) {
|
||||
CXXRecordDecl *RD = TD->getTemplatedDecl();
|
||||
AddRecordMembersCompletionResults(*this, Results, S, BaseType, RD);
|
||||
}
|
||||
} else if (const auto *ICNT = BaseType->getAs<InjectedClassNameType>()) {
|
||||
if (auto *RD = ICNT->getDecl())
|
||||
AddRecordMembersCompletionResults(*this, Results, S, BaseType, RD);
|
||||
} else if (!IsArrow && BaseType->isObjCObjectPointerType()) {
|
||||
// Objective-C property reference.
|
||||
AddedPropertiesSet AddedProperties;
|
||||
@ -7811,6 +7828,23 @@ void Sema::CodeCompleteNaturalLanguage() {
|
||||
nullptr, 0);
|
||||
}
|
||||
|
||||
void Sema::CodeCompleteAvailabilityPlatformName() {
|
||||
ResultBuilder Results(*this, CodeCompleter->getAllocator(),
|
||||
CodeCompleter->getCodeCompletionTUInfo(),
|
||||
CodeCompletionContext::CCC_Other);
|
||||
Results.EnterNewScope();
|
||||
static const char *Platforms[] = {"macOS", "iOS", "watchOS", "tvOS"};
|
||||
for (const char *Platform : llvm::makeArrayRef(Platforms)) {
|
||||
Results.AddResult(CodeCompletionResult(Platform));
|
||||
Results.AddResult(CodeCompletionResult(Results.getAllocator().CopyString(
|
||||
Twine(Platform) + "ApplicationExtension")));
|
||||
}
|
||||
Results.ExitScope();
|
||||
HandleCodeCompleteResults(this, CodeCompleter,
|
||||
CodeCompletionContext::CCC_Other, Results.data(),
|
||||
Results.size());
|
||||
}
|
||||
|
||||
void Sema::GatherGlobalCodeCompletions(CodeCompletionAllocator &Allocator,
|
||||
CodeCompletionTUInfo &CCTUInfo,
|
||||
SmallVectorImpl<CodeCompletionResult> &Results) {
|
||||
|
@ -64,22 +64,45 @@ namespace {
|
||||
|
||||
class TypeNameValidatorCCC : public CorrectionCandidateCallback {
|
||||
public:
|
||||
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass=false,
|
||||
bool AllowTemplates=false)
|
||||
: AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
|
||||
AllowTemplates(AllowTemplates) {
|
||||
WantExpressionKeywords = false;
|
||||
WantCXXNamedCasts = false;
|
||||
WantRemainingKeywords = false;
|
||||
TypeNameValidatorCCC(bool AllowInvalid, bool WantClass = false,
|
||||
bool AllowTemplates = false,
|
||||
bool AllowNonTemplates = true)
|
||||
: AllowInvalidDecl(AllowInvalid), WantClassName(WantClass),
|
||||
AllowTemplates(AllowTemplates), AllowNonTemplates(AllowNonTemplates) {
|
||||
WantExpressionKeywords = false;
|
||||
WantCXXNamedCasts = false;
|
||||
WantRemainingKeywords = false;
|
||||
}
|
||||
|
||||
bool ValidateCandidate(const TypoCorrection &candidate) override {
|
||||
if (NamedDecl *ND = candidate.getCorrectionDecl()) {
|
||||
if (!AllowInvalidDecl && ND->isInvalidDecl())
|
||||
return false;
|
||||
|
||||
if (getAsTypeTemplateDecl(ND))
|
||||
return AllowTemplates;
|
||||
|
||||
bool IsType = isa<TypeDecl>(ND) || isa<ObjCInterfaceDecl>(ND);
|
||||
bool AllowedTemplate = AllowTemplates && getAsTypeTemplateDecl(ND);
|
||||
return (IsType || AllowedTemplate) &&
|
||||
(AllowInvalidDecl || !ND->isInvalidDecl());
|
||||
if (!IsType)
|
||||
return false;
|
||||
|
||||
if (AllowNonTemplates)
|
||||
return true;
|
||||
|
||||
// An injected-class-name of a class template (specialization) is valid
|
||||
// as a template or as a non-template.
|
||||
if (AllowTemplates) {
|
||||
auto *RD = dyn_cast<CXXRecordDecl>(ND);
|
||||
if (!RD || !RD->isInjectedClassName())
|
||||
return false;
|
||||
RD = cast<CXXRecordDecl>(RD->getDeclContext());
|
||||
return RD->getDescribedClassTemplate() ||
|
||||
isa<ClassTemplateSpecializationDecl>(RD);
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
return !WantClassName && candidate.isKeyword();
|
||||
}
|
||||
|
||||
@ -87,6 +110,7 @@ class TypeNameValidatorCCC : public CorrectionCandidateCallback {
|
||||
bool AllowInvalidDecl;
|
||||
bool WantClassName;
|
||||
bool AllowTemplates;
|
||||
bool AllowNonTemplates;
|
||||
};
|
||||
|
||||
} // end anonymous namespace
|
||||
@ -627,7 +651,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
||||
Scope *S,
|
||||
CXXScopeSpec *SS,
|
||||
ParsedType &SuggestedType,
|
||||
bool AllowClassTemplates) {
|
||||
bool IsTemplateName) {
|
||||
// Don't report typename errors for editor placeholders.
|
||||
if (II->isEditorPlaceholder())
|
||||
return;
|
||||
@ -639,28 +663,41 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
||||
if (TypoCorrection Corrected =
|
||||
CorrectTypo(DeclarationNameInfo(II, IILoc), LookupOrdinaryName, S, SS,
|
||||
llvm::make_unique<TypeNameValidatorCCC>(
|
||||
false, false, AllowClassTemplates),
|
||||
false, false, IsTemplateName, !IsTemplateName),
|
||||
CTK_ErrorRecovery)) {
|
||||
// FIXME: Support error recovery for the template-name case.
|
||||
bool CanRecover = !IsTemplateName;
|
||||
if (Corrected.isKeyword()) {
|
||||
// We corrected to a keyword.
|
||||
diagnoseTypo(Corrected, PDiag(diag::err_unknown_typename_suggest) << II);
|
||||
diagnoseTypo(Corrected,
|
||||
PDiag(IsTemplateName ? diag::err_no_template_suggest
|
||||
: diag::err_unknown_typename_suggest)
|
||||
<< II);
|
||||
II = Corrected.getCorrectionAsIdentifierInfo();
|
||||
} else {
|
||||
// We found a similarly-named type or interface; suggest that.
|
||||
if (!SS || !SS->isSet()) {
|
||||
diagnoseTypo(Corrected,
|
||||
PDiag(diag::err_unknown_typename_suggest) << II);
|
||||
PDiag(IsTemplateName ? diag::err_no_template_suggest
|
||||
: diag::err_unknown_typename_suggest)
|
||||
<< II, CanRecover);
|
||||
} else if (DeclContext *DC = computeDeclContext(*SS, false)) {
|
||||
std::string CorrectedStr(Corrected.getAsString(getLangOpts()));
|
||||
bool DroppedSpecifier = Corrected.WillReplaceSpecifier() &&
|
||||
II->getName().equals(CorrectedStr);
|
||||
diagnoseTypo(Corrected,
|
||||
PDiag(diag::err_unknown_nested_typename_suggest)
|
||||
<< II << DC << DroppedSpecifier << SS->getRange());
|
||||
PDiag(IsTemplateName
|
||||
? diag::err_no_member_template_suggest
|
||||
: diag::err_unknown_nested_typename_suggest)
|
||||
<< II << DC << DroppedSpecifier << SS->getRange(),
|
||||
CanRecover);
|
||||
} else {
|
||||
llvm_unreachable("could not have corrected a typo here");
|
||||
}
|
||||
|
||||
if (!CanRecover)
|
||||
return;
|
||||
|
||||
CXXScopeSpec tmpSS;
|
||||
if (Corrected.getCorrectionSpecifier())
|
||||
tmpSS.MakeTrivial(Context, Corrected.getCorrectionSpecifier(),
|
||||
@ -675,7 +712,7 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
||||
return;
|
||||
}
|
||||
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
if (getLangOpts().CPlusPlus && !IsTemplateName) {
|
||||
// See if II is a class template that the user forgot to pass arguments to.
|
||||
UnqualifiedId Name;
|
||||
Name.setIdentifier(II, IILoc);
|
||||
@ -700,10 +737,13 @@ void Sema::DiagnoseUnknownTypeName(IdentifierInfo *&II,
|
||||
// (struct, union, enum) from Parser::ParseImplicitInt here, instead?
|
||||
|
||||
if (!SS || (!SS->isSet() && !SS->isInvalid()))
|
||||
Diag(IILoc, diag::err_unknown_typename) << II;
|
||||
Diag(IILoc, IsTemplateName ? diag::err_no_template
|
||||
: diag::err_unknown_typename)
|
||||
<< II;
|
||||
else if (DeclContext *DC = computeDeclContext(*SS, false))
|
||||
Diag(IILoc, diag::err_typename_nested_not_found)
|
||||
<< II << DC << SS->getRange();
|
||||
Diag(IILoc, IsTemplateName ? diag::err_no_member_template
|
||||
: diag::err_typename_nested_not_found)
|
||||
<< II << DC << SS->getRange();
|
||||
else if (isDependentScopeSpecifier(*SS)) {
|
||||
unsigned DiagID = diag::err_typename_missing;
|
||||
if (getLangOpts().MSVCCompat && isMicrosoftMissingTypename(SS, S))
|
||||
@ -1488,6 +1528,11 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
|
||||
if (const FunctionDecl *FD = dyn_cast<FunctionDecl>(D)) {
|
||||
if (FD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
|
||||
return false;
|
||||
// A non-out-of-line declaration of a member specialization was implicitly
|
||||
// instantiated; it's the out-of-line declaration that we're interested in.
|
||||
if (FD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
|
||||
FD->getMemberSpecializationInfo() && !FD->isOutOfLine())
|
||||
return false;
|
||||
|
||||
if (const CXXMethodDecl *MD = dyn_cast<CXXMethodDecl>(FD)) {
|
||||
if (MD->isVirtual() || IsDisallowedCopyOrAssign(MD))
|
||||
@ -1514,6 +1559,10 @@ bool Sema::ShouldWarnIfUnusedFileScopedDecl(const DeclaratorDecl *D) const {
|
||||
if (VD->isStaticDataMember() &&
|
||||
VD->getTemplateSpecializationKind() == TSK_ImplicitInstantiation)
|
||||
return false;
|
||||
if (VD->isStaticDataMember() &&
|
||||
VD->getTemplateSpecializationKind() == TSK_ExplicitSpecialization &&
|
||||
VD->getMemberSpecializationInfo() && !VD->isOutOfLine())
|
||||
return false;
|
||||
|
||||
if (VD->isInline() && !isMainFileLoc(*this, VD->getLocation()))
|
||||
return false;
|
||||
@ -1972,7 +2021,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
|
||||
Diag(New->getLocation(), diag::err_redefinition_variably_modified_typedef)
|
||||
<< Kind << NewType;
|
||||
if (Old->getLocation().isValid())
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
New->setInvalidDecl();
|
||||
return true;
|
||||
}
|
||||
@ -1985,7 +2034,7 @@ bool Sema::isIncompatibleTypedef(TypeDecl *Old, TypedefNameDecl *New) {
|
||||
Diag(New->getLocation(), diag::err_redefinition_different_typedef)
|
||||
<< Kind << NewType << OldType;
|
||||
if (Old->getLocation().isValid())
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
New->setInvalidDecl();
|
||||
return true;
|
||||
}
|
||||
@ -2052,7 +2101,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
|
||||
|
||||
NamedDecl *OldD = OldDecls.getRepresentativeDecl();
|
||||
if (OldD->getLocation().isValid())
|
||||
Diag(OldD->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(OldD->getLocation(), New->getLocation());
|
||||
|
||||
return New->setInvalidDecl();
|
||||
}
|
||||
@ -2078,7 +2127,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
|
||||
New->setTypeSourceInfo(OldTD->getTypeSourceInfo());
|
||||
|
||||
// Make the old tag definition visible.
|
||||
makeMergedDefinitionVisible(Hidden, NewTag->getLocation());
|
||||
makeMergedDefinitionVisible(Hidden);
|
||||
|
||||
// If this was an unscoped enumeration, yank all of its enumerators
|
||||
// out of the scope.
|
||||
@ -2144,7 +2193,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
|
||||
|
||||
Diag(New->getLocation(), diag::err_redefinition)
|
||||
<< New->getDeclName();
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
return New->setInvalidDecl();
|
||||
}
|
||||
|
||||
@ -2165,7 +2214,7 @@ void Sema::MergeTypedefNameDecl(Scope *S, TypedefNameDecl *New,
|
||||
|
||||
Diag(New->getLocation(), diag::ext_redefinition_of_typedef)
|
||||
<< New->getDeclName();
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
}
|
||||
|
||||
/// DeclhasAttr - returns true if decl Declaration already has the target
|
||||
@ -2452,7 +2501,10 @@ static void checkNewAttributesAfterDef(Sema &S, Decl *New, const Decl *Old) {
|
||||
? diag::err_alias_after_tentative
|
||||
: diag::err_redefinition;
|
||||
S.Diag(VD->getLocation(), Diag) << VD->getDeclName();
|
||||
S.Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
if (Diag == diag::err_redefinition)
|
||||
S.notePreviousDefinition(Def->getLocation(), VD->getLocation());
|
||||
else
|
||||
S.Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
VD->setInvalidDecl();
|
||||
}
|
||||
++I;
|
||||
@ -2839,7 +2891,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
|
||||
} else {
|
||||
Diag(New->getLocation(), diag::err_redefinition_different_kind)
|
||||
<< New->getDeclName();
|
||||
Diag(OldD->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(OldD->getLocation(), New->getLocation());
|
||||
return true;
|
||||
}
|
||||
}
|
||||
@ -2876,7 +2928,7 @@ bool Sema::MergeFunctionDecl(FunctionDecl *New, NamedDecl *&OldD,
|
||||
!Old->hasAttr<InternalLinkageAttr>()) {
|
||||
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
|
||||
<< New->getDeclName();
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
New->dropAttr<InternalLinkageAttr>();
|
||||
}
|
||||
|
||||
@ -3604,9 +3656,9 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
||||
}
|
||||
if (!Old) {
|
||||
Diag(New->getLocation(), diag::err_redefinition_different_kind)
|
||||
<< New->getDeclName();
|
||||
Diag(Previous.getRepresentativeDecl()->getLocation(),
|
||||
diag::note_previous_definition);
|
||||
<< New->getDeclName();
|
||||
notePreviousDefinition(Previous.getRepresentativeDecl()->getLocation(),
|
||||
New->getLocation());
|
||||
return New->setInvalidDecl();
|
||||
}
|
||||
|
||||
@ -3635,7 +3687,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
||||
Old->getStorageClass() == SC_None &&
|
||||
!Old->hasAttr<WeakImportAttr>()) {
|
||||
Diag(New->getLocation(), diag::warn_weak_import) << New->getDeclName();
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
// Remove weak_import attribute on new declaration.
|
||||
New->dropAttr<WeakImportAttr>();
|
||||
}
|
||||
@ -3644,7 +3696,7 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
||||
!Old->hasAttr<InternalLinkageAttr>()) {
|
||||
Diag(New->getLocation(), diag::err_internal_linkage_redeclaration)
|
||||
<< New->getDeclName();
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
New->dropAttr<InternalLinkageAttr>();
|
||||
}
|
||||
|
||||
@ -3801,6 +3853,67 @@ void Sema::MergeVarDecl(VarDecl *New, LookupResult &Previous) {
|
||||
New->setImplicitlyInline();
|
||||
}
|
||||
|
||||
void Sema::notePreviousDefinition(SourceLocation Old, SourceLocation New) {
|
||||
SourceManager &SrcMgr = getSourceManager();
|
||||
auto FNewDecLoc = SrcMgr.getDecomposedLoc(New);
|
||||
auto FOldDecLoc = SrcMgr.getDecomposedLoc(Old);
|
||||
auto *FNew = SrcMgr.getFileEntryForID(FNewDecLoc.first);
|
||||
auto *FOld = SrcMgr.getFileEntryForID(FOldDecLoc.first);
|
||||
auto &HSI = PP.getHeaderSearchInfo();
|
||||
StringRef HdrFilename = SrcMgr.getFilename(SrcMgr.getSpellingLoc(Old));
|
||||
|
||||
auto noteFromModuleOrInclude = [&](SourceLocation &Loc,
|
||||
SourceLocation &IncLoc) -> bool {
|
||||
Module *Mod = nullptr;
|
||||
// Redefinition errors with modules are common with non modular mapped
|
||||
// headers, example: a non-modular header H in module A that also gets
|
||||
// included directly in a TU. Pointing twice to the same header/definition
|
||||
// is confusing, try to get better diagnostics when modules is on.
|
||||
if (getLangOpts().Modules) {
|
||||
auto ModLoc = SrcMgr.getModuleImportLoc(Old);
|
||||
if (!ModLoc.first.isInvalid())
|
||||
Mod = HSI.getModuleMap().inferModuleFromLocation(
|
||||
FullSourceLoc(Loc, SrcMgr));
|
||||
}
|
||||
|
||||
if (IncLoc.isValid()) {
|
||||
if (Mod) {
|
||||
Diag(IncLoc, diag::note_redefinition_modules_same_file)
|
||||
<< HdrFilename.str() << Mod->getFullModuleName();
|
||||
if (!Mod->DefinitionLoc.isInvalid())
|
||||
Diag(Mod->DefinitionLoc, diag::note_defined_here)
|
||||
<< Mod->getFullModuleName();
|
||||
} else {
|
||||
Diag(IncLoc, diag::note_redefinition_include_same_file)
|
||||
<< HdrFilename.str();
|
||||
}
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
};
|
||||
|
||||
// Is it the same file and same offset? Provide more information on why
|
||||
// this leads to a redefinition error.
|
||||
bool EmittedDiag = false;
|
||||
if (FNew == FOld && FNewDecLoc.second == FOldDecLoc.second) {
|
||||
SourceLocation OldIncLoc = SrcMgr.getIncludeLoc(FOldDecLoc.first);
|
||||
SourceLocation NewIncLoc = SrcMgr.getIncludeLoc(FNewDecLoc.first);
|
||||
EmittedDiag = noteFromModuleOrInclude(Old, OldIncLoc);
|
||||
EmittedDiag |= noteFromModuleOrInclude(New, NewIncLoc);
|
||||
|
||||
// If the header has no guards, emit a note suggesting one.
|
||||
if (FOld && !HSI.isFileMultipleIncludeGuarded(FOld))
|
||||
Diag(Old, diag::note_use_ifdef_guards);
|
||||
|
||||
if (EmittedDiag)
|
||||
return;
|
||||
}
|
||||
|
||||
// Redefinition coming from different files or couldn't do better above.
|
||||
Diag(Old, diag::note_previous_definition);
|
||||
}
|
||||
|
||||
/// We've just determined that \p Old and \p New both appear to be definitions
|
||||
/// of the same variable. Either diagnose or fix the problem.
|
||||
bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
|
||||
@ -3816,12 +3929,12 @@ bool Sema::checkVarDeclRedefinition(VarDecl *Old, VarDecl *New) {
|
||||
|
||||
// Make the canonical definition visible.
|
||||
if (auto *OldTD = Old->getDescribedVarTemplate())
|
||||
makeMergedDefinitionVisible(OldTD, New->getLocation());
|
||||
makeMergedDefinitionVisible(Old, New->getLocation());
|
||||
makeMergedDefinitionVisible(OldTD);
|
||||
makeMergedDefinitionVisible(Old);
|
||||
return false;
|
||||
} else {
|
||||
Diag(New->getLocation(), diag::err_redefinition) << New;
|
||||
Diag(Old->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Old->getLocation(), New->getLocation());
|
||||
New->setInvalidDecl();
|
||||
return true;
|
||||
}
|
||||
@ -6706,6 +6819,9 @@ NamedDecl *Sema::ActOnVariableDeclarator(
|
||||
return NewTemplate;
|
||||
}
|
||||
|
||||
if (IsMemberSpecialization && !NewVD->isInvalidDecl())
|
||||
CompleteMemberSpecialization(NewVD, Previous);
|
||||
|
||||
return NewVD;
|
||||
}
|
||||
|
||||
@ -8919,12 +9035,17 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
||||
}
|
||||
}
|
||||
|
||||
MarkUnusedFileScopedDecl(NewFD);
|
||||
|
||||
if (getLangOpts().CPlusPlus) {
|
||||
if (FunctionTemplate) {
|
||||
if (NewFD->isInvalidDecl())
|
||||
FunctionTemplate->setInvalidDecl();
|
||||
return FunctionTemplate;
|
||||
}
|
||||
|
||||
if (isMemberSpecialization && !NewFD->isInvalidDecl())
|
||||
CompleteMemberSpecialization(NewFD, Previous);
|
||||
}
|
||||
|
||||
if (NewFD->hasAttr<OpenCLKernelAttr>()) {
|
||||
@ -8964,8 +9085,6 @@ Sema::ActOnFunctionDeclarator(Scope *S, Declarator &D, DeclContext *DC,
|
||||
}
|
||||
}
|
||||
|
||||
MarkUnusedFileScopedDecl(NewFD);
|
||||
|
||||
// Here we have an function template explicit specialization at class scope.
|
||||
// The actually specialization will be postponed to template instatiation
|
||||
// time via the ClassScopeFunctionSpecializationDecl node.
|
||||
@ -9182,7 +9301,9 @@ bool Sema::CheckFunctionDeclaration(Scope *S, FunctionDecl *NewFD,
|
||||
if (OldTemplateDecl->getTemplatedDecl()->isDeleted()) {
|
||||
FunctionDecl *const OldTemplatedDecl =
|
||||
OldTemplateDecl->getTemplatedDecl();
|
||||
// FIXME: This assert will not hold in the presence of modules.
|
||||
assert(OldTemplatedDecl->getCanonicalDecl() == OldTemplatedDecl);
|
||||
// FIXME: We need an update record for this AST mutation.
|
||||
OldTemplatedDecl->setDeletedAsWritten(false);
|
||||
}
|
||||
}
|
||||
@ -10273,23 +10394,36 @@ void Sema::AddInitializerToDecl(Decl *RealDecl, Expr *Init, bool DirectInit) {
|
||||
VDecl->setInit(Init);
|
||||
|
||||
if (VDecl->isLocalVarDecl()) {
|
||||
// Don't check the initializer if the declaration is malformed.
|
||||
if (VDecl->isInvalidDecl()) {
|
||||
// do nothing
|
||||
|
||||
// OpenCL v1.2 s6.5.3: __constant locals must be constant-initialized.
|
||||
// This is true even in OpenCL C++.
|
||||
} else if (VDecl->getType().getAddressSpace() == LangAS::opencl_constant) {
|
||||
CheckForConstantInitializer(Init, DclT);
|
||||
|
||||
// Otherwise, C++ does not restrict the initializer.
|
||||
} else if (getLangOpts().CPlusPlus) {
|
||||
// do nothing
|
||||
|
||||
// C99 6.7.8p4: All the expressions in an initializer for an object that has
|
||||
// static storage duration shall be constant expressions or string literals.
|
||||
// C++ does not have this restriction.
|
||||
if (!getLangOpts().CPlusPlus && !VDecl->isInvalidDecl()) {
|
||||
} else if (VDecl->getStorageClass() == SC_Static) {
|
||||
CheckForConstantInitializer(Init, DclT);
|
||||
|
||||
// C89 is stricter than C99 for aggregate initializers.
|
||||
// C89 6.5.7p3: All the expressions [...] in an initializer list
|
||||
// for an object that has aggregate or union type shall be
|
||||
// constant expressions.
|
||||
} else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
|
||||
isa<InitListExpr>(Init)) {
|
||||
const Expr *Culprit;
|
||||
if (VDecl->getStorageClass() == SC_Static)
|
||||
CheckForConstantInitializer(Init, DclT);
|
||||
// C89 is stricter than C99 for non-static aggregate types.
|
||||
// C89 6.5.7p3: All the expressions [...] in an initializer list
|
||||
// for an object that has aggregate or union type shall be
|
||||
// constant expressions.
|
||||
else if (!getLangOpts().C99 && VDecl->getType()->isAggregateType() &&
|
||||
isa<InitListExpr>(Init) &&
|
||||
!Init->isConstantInitializer(Context, false, &Culprit))
|
||||
if (!Init->isConstantInitializer(Context, false, &Culprit)) {
|
||||
Diag(Culprit->getExprLoc(),
|
||||
diag::ext_aggregate_init_not_constant)
|
||||
<< Culprit->getSourceRange();
|
||||
}
|
||||
}
|
||||
} else if (VDecl->isStaticDataMember() && !VDecl->isInline() &&
|
||||
VDecl->getLexicalDeclContext()->isRecord()) {
|
||||
@ -11023,8 +11157,7 @@ static bool hasDependentAlignment(VarDecl *VD) {
|
||||
|
||||
/// FinalizeDeclaration - called by ParseDeclarationAfterDeclarator to perform
|
||||
/// any semantic actions necessary after any initializer has been attached.
|
||||
void
|
||||
Sema::FinalizeDeclaration(Decl *ThisDecl) {
|
||||
void Sema::FinalizeDeclaration(Decl *ThisDecl) {
|
||||
// Note that we are no longer parsing the initializer for this declaration.
|
||||
ParsingInitForAutoVars.erase(ThisDecl);
|
||||
|
||||
@ -11189,9 +11322,8 @@ Sema::FinalizeDeclaration(Decl *ThisDecl) {
|
||||
if (DC->getRedeclContext()->isFileContext() && VD->isExternallyVisible())
|
||||
AddPushedVisibilityAttribute(VD);
|
||||
|
||||
// FIXME: Warn on unused templates.
|
||||
if (VD->isFileVarDecl() && !VD->getDescribedVarTemplate() &&
|
||||
!isa<VarTemplatePartialSpecializationDecl>(VD))
|
||||
// FIXME: Warn on unused var template partial specializations.
|
||||
if (VD->isFileVarDecl() && !isa<VarTemplatePartialSpecializationDecl>(VD))
|
||||
MarkUnusedFileScopedDecl(VD);
|
||||
|
||||
// Now we have parsed the initializer and can update the table of magic
|
||||
@ -11765,9 +11897,8 @@ Sema::CheckForFunctionRedefinition(FunctionDecl *FD,
|
||||
Definition->getNumTemplateParameterLists())) {
|
||||
SkipBody->ShouldSkip = true;
|
||||
if (auto *TD = Definition->getDescribedFunctionTemplate())
|
||||
makeMergedDefinitionVisible(TD, FD->getLocation());
|
||||
makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition),
|
||||
FD->getLocation());
|
||||
makeMergedDefinitionVisible(TD);
|
||||
makeMergedDefinitionVisible(const_cast<FunctionDecl*>(Definition));
|
||||
return;
|
||||
}
|
||||
|
||||
@ -13421,7 +13552,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
// we already have. Make the existing definition visible and
|
||||
// use it in place of this one.
|
||||
SkipBody->ShouldSkip = true;
|
||||
makeMergedDefinitionVisible(Hidden, KWLoc);
|
||||
makeMergedDefinitionVisible(Hidden);
|
||||
return Def;
|
||||
} else if (!IsExplicitSpecializationAfterInstantiation) {
|
||||
// A redeclaration in function prototype scope in C isn't
|
||||
@ -13430,7 +13561,8 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
Diag(NameLoc, diag::warn_redefinition_in_param_list) << Name;
|
||||
else
|
||||
Diag(NameLoc, diag::err_redefinition) << Name;
|
||||
Diag(Def->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(Def->getLocation(),
|
||||
NameLoc.isValid() ? NameLoc : KWLoc);
|
||||
// If this is a redefinition, recover by making this
|
||||
// struct be anonymous, which will make any later
|
||||
// references get the previous definition.
|
||||
@ -13520,7 +13652,7 @@ Decl *Sema::ActOnTag(Scope *S, unsigned TagSpec, TagUseKind TUK,
|
||||
// The tag name clashes with something else in the target scope,
|
||||
// issue an error and recover by making this tag be anonymous.
|
||||
Diag(NameLoc, diag::err_redefinition_different_kind) << Name;
|
||||
Diag(PrevDecl->getLocation(), diag::note_previous_definition);
|
||||
notePreviousDefinition(PrevDecl->getLocation(), NameLoc);
|
||||
Name = nullptr;
|
||||
Invalid = true;
|
||||
}
|
||||
@ -13753,6 +13885,9 @@ 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;
|
||||
}
|
||||
}
|
||||
|
@ -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<FunctionDecl>(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());
|
||||
|
@ -5277,6 +5277,9 @@ ExprResult Sema::ActOnCallExpr(Scope *Scope, Expr *Fn, SourceLocation LParenLoc,
|
||||
|
||||
// We aren't supposed to apply this logic if there's an '&' involved.
|
||||
if (!find.HasFormOfMemberPointer) {
|
||||
if (Expr::hasAnyTypeDependentArguments(ArgExprs))
|
||||
return new (Context) CallExpr(
|
||||
Context, Fn, ArgExprs, Context.DependentTy, VK_RValue, RParenLoc);
|
||||
OverloadExpr *ovl = find.Expression;
|
||||
if (UnresolvedLookupExpr *ULE = dyn_cast<UnresolvedLookupExpr>(ovl))
|
||||
return BuildOverloadedCallExpr(
|
||||
@ -8028,6 +8031,33 @@ QualType Sema::InvalidOperands(SourceLocation Loc, ExprResult &LHS,
|
||||
return QualType();
|
||||
}
|
||||
|
||||
// Diagnose cases where a scalar was implicitly converted to a vector and
|
||||
// diagnose the underlying types. Otherwise, diagnose the error
|
||||
// as invalid vector logical operands for non-C++ cases.
|
||||
QualType Sema::InvalidLogicalVectorOperands(SourceLocation Loc, ExprResult &LHS,
|
||||
ExprResult &RHS) {
|
||||
QualType LHSType = LHS.get()->IgnoreImpCasts()->getType();
|
||||
QualType RHSType = RHS.get()->IgnoreImpCasts()->getType();
|
||||
|
||||
bool LHSNatVec = LHSType->isVectorType();
|
||||
bool RHSNatVec = RHSType->isVectorType();
|
||||
|
||||
if (!(LHSNatVec && RHSNatVec)) {
|
||||
Expr *Vector = LHSNatVec ? LHS.get() : RHS.get();
|
||||
Expr *NonVector = !LHSNatVec ? LHS.get() : RHS.get();
|
||||
Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)
|
||||
<< 0 << Vector->getType() << NonVector->IgnoreImpCasts()->getType()
|
||||
<< Vector->getSourceRange();
|
||||
return QualType();
|
||||
}
|
||||
|
||||
Diag(Loc, diag::err_typecheck_logical_vector_expr_gnu_cpp_restrict)
|
||||
<< 1 << LHSType << RHSType << LHS.get()->getSourceRange()
|
||||
<< RHS.get()->getSourceRange();
|
||||
|
||||
return QualType();
|
||||
}
|
||||
|
||||
/// Try to convert a value of non-vector type to a vector type by converting
|
||||
/// the type to the element type of the vector and then performing a splat.
|
||||
/// If the language is OpenCL, we only use conversions that promote scalar
|
||||
@ -8075,6 +8105,162 @@ static bool tryVectorConvertAndSplat(Sema &S, ExprResult *scalar,
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Test if a (constant) integer Int can be casted to another integer type
|
||||
/// IntTy without losing precision.
|
||||
static bool canConvertIntToOtherIntTy(Sema &S, ExprResult *Int,
|
||||
QualType OtherIntTy) {
|
||||
QualType IntTy = Int->get()->getType().getUnqualifiedType();
|
||||
|
||||
// Reject cases where the value of the Int is unknown as that would
|
||||
// possibly cause truncation, but accept cases where the scalar can be
|
||||
// demoted without loss of precision.
|
||||
llvm::APSInt Result;
|
||||
bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
|
||||
int Order = S.Context.getIntegerTypeOrder(OtherIntTy, IntTy);
|
||||
bool IntSigned = IntTy->hasSignedIntegerRepresentation();
|
||||
bool OtherIntSigned = OtherIntTy->hasSignedIntegerRepresentation();
|
||||
|
||||
if (CstInt) {
|
||||
// If the scalar is constant and is of a higher order and has more active
|
||||
// bits that the vector element type, reject it.
|
||||
unsigned NumBits = IntSigned
|
||||
? (Result.isNegative() ? Result.getMinSignedBits()
|
||||
: Result.getActiveBits())
|
||||
: Result.getActiveBits();
|
||||
if (Order < 0 && S.Context.getIntWidth(OtherIntTy) < NumBits)
|
||||
return true;
|
||||
|
||||
// If the signedness of the scalar type and the vector element type
|
||||
// differs and the number of bits is greater than that of the vector
|
||||
// element reject it.
|
||||
return (IntSigned != OtherIntSigned &&
|
||||
NumBits > S.Context.getIntWidth(OtherIntTy));
|
||||
}
|
||||
|
||||
// Reject cases where the value of the scalar is not constant and it's
|
||||
// order is greater than that of the vector element type.
|
||||
return (Order < 0);
|
||||
}
|
||||
|
||||
/// Test if a (constant) integer Int can be casted to floating point type
|
||||
/// FloatTy without losing precision.
|
||||
static bool canConvertIntTyToFloatTy(Sema &S, ExprResult *Int,
|
||||
QualType FloatTy) {
|
||||
QualType IntTy = Int->get()->getType().getUnqualifiedType();
|
||||
|
||||
// Determine if the integer constant can be expressed as a floating point
|
||||
// number of the appropiate type.
|
||||
llvm::APSInt Result;
|
||||
bool CstInt = Int->get()->EvaluateAsInt(Result, S.Context);
|
||||
uint64_t Bits = 0;
|
||||
if (CstInt) {
|
||||
// Reject constants that would be truncated if they were converted to
|
||||
// the floating point type. Test by simple to/from conversion.
|
||||
// FIXME: Ideally the conversion to an APFloat and from an APFloat
|
||||
// could be avoided if there was a convertFromAPInt method
|
||||
// which could signal back if implicit truncation occurred.
|
||||
llvm::APFloat Float(S.Context.getFloatTypeSemantics(FloatTy));
|
||||
Float.convertFromAPInt(Result, IntTy->hasSignedIntegerRepresentation(),
|
||||
llvm::APFloat::rmTowardZero);
|
||||
llvm::APSInt ConvertBack(S.Context.getIntWidth(IntTy),
|
||||
!IntTy->hasSignedIntegerRepresentation());
|
||||
bool Ignored = false;
|
||||
Float.convertToInteger(ConvertBack, llvm::APFloat::rmNearestTiesToEven,
|
||||
&Ignored);
|
||||
if (Result != ConvertBack)
|
||||
return true;
|
||||
} else {
|
||||
// Reject types that cannot be fully encoded into the mantissa of
|
||||
// the float.
|
||||
Bits = S.Context.getTypeSize(IntTy);
|
||||
unsigned FloatPrec = llvm::APFloat::semanticsPrecision(
|
||||
S.Context.getFloatTypeSemantics(FloatTy));
|
||||
if (Bits > FloatPrec)
|
||||
return true;
|
||||
}
|
||||
|
||||
return false;
|
||||
}
|
||||
|
||||
/// Attempt to convert and splat Scalar into a vector whose types matches
|
||||
/// Vector following GCC conversion rules. The rule is that implicit
|
||||
/// conversion can occur when Scalar can be casted to match Vector's element
|
||||
/// type without causing truncation of Scalar.
|
||||
static bool tryGCCVectorConvertAndSplat(Sema &S, ExprResult *Scalar,
|
||||
ExprResult *Vector) {
|
||||
QualType ScalarTy = Scalar->get()->getType().getUnqualifiedType();
|
||||
QualType VectorTy = Vector->get()->getType().getUnqualifiedType();
|
||||
const VectorType *VT = VectorTy->getAs<VectorType>();
|
||||
|
||||
assert(!isa<ExtVectorType>(VT) &&
|
||||
"ExtVectorTypes should not be handled here!");
|
||||
|
||||
QualType VectorEltTy = VT->getElementType();
|
||||
|
||||
// Reject cases where the vector element type or the scalar element type are
|
||||
// not integral or floating point types.
|
||||
if (!VectorEltTy->isArithmeticType() || !ScalarTy->isArithmeticType())
|
||||
return true;
|
||||
|
||||
// The conversion to apply to the scalar before splatting it,
|
||||
// if necessary.
|
||||
CastKind ScalarCast = CK_NoOp;
|
||||
|
||||
// Accept cases where the vector elements are integers and the scalar is
|
||||
// an integer.
|
||||
// FIXME: Notionally if the scalar was a floating point value with a precise
|
||||
// integral representation, we could cast it to an appropriate integer
|
||||
// type and then perform the rest of the checks here. GCC will perform
|
||||
// this conversion in some cases as determined by the input language.
|
||||
// We should accept it on a language independent basis.
|
||||
if (VectorEltTy->isIntegralType(S.Context) &&
|
||||
ScalarTy->isIntegralType(S.Context) &&
|
||||
S.Context.getIntegerTypeOrder(VectorEltTy, ScalarTy)) {
|
||||
|
||||
if (canConvertIntToOtherIntTy(S, Scalar, VectorEltTy))
|
||||
return true;
|
||||
|
||||
ScalarCast = CK_IntegralCast;
|
||||
} else if (VectorEltTy->isRealFloatingType()) {
|
||||
if (ScalarTy->isRealFloatingType()) {
|
||||
|
||||
// Reject cases where the scalar type is not a constant and has a higher
|
||||
// Order than the vector element type.
|
||||
llvm::APFloat Result(0.0);
|
||||
bool CstScalar = Scalar->get()->EvaluateAsFloat(Result, S.Context);
|
||||
int Order = S.Context.getFloatingTypeOrder(VectorEltTy, ScalarTy);
|
||||
if (!CstScalar && Order < 0)
|
||||
return true;
|
||||
|
||||
// If the scalar cannot be safely casted to the vector element type,
|
||||
// reject it.
|
||||
if (CstScalar) {
|
||||
bool Truncated = false;
|
||||
Result.convert(S.Context.getFloatTypeSemantics(VectorEltTy),
|
||||
llvm::APFloat::rmNearestTiesToEven, &Truncated);
|
||||
if (Truncated)
|
||||
return true;
|
||||
}
|
||||
|
||||
ScalarCast = CK_FloatingCast;
|
||||
} else if (ScalarTy->isIntegralType(S.Context)) {
|
||||
if (canConvertIntTyToFloatTy(S, Scalar, VectorEltTy))
|
||||
return true;
|
||||
|
||||
ScalarCast = CK_IntegralToFloating;
|
||||
} else
|
||||
return true;
|
||||
}
|
||||
|
||||
// Adjust scalar if desired.
|
||||
if (Scalar) {
|
||||
if (ScalarCast != CK_NoOp)
|
||||
*Scalar = S.ImpCastExprToType(Scalar->get(), VectorEltTy, ScalarCast);
|
||||
*Scalar = S.ImpCastExprToType(Scalar->get(), VectorTy, CK_VectorSplat);
|
||||
}
|
||||
return false;
|
||||
}
|
||||
|
||||
QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
|
||||
SourceLocation Loc, bool IsCompAssign,
|
||||
bool AllowBothBool,
|
||||
@ -8143,19 +8329,29 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
|
||||
}
|
||||
}
|
||||
|
||||
// If there's an ext-vector type and a scalar, try to convert the scalar to
|
||||
// If there's a vector type and a scalar, try to convert the scalar to
|
||||
// the vector element type and splat.
|
||||
// FIXME: this should also work for regular vector types as supported in GCC.
|
||||
if (!RHSVecType && isa<ExtVectorType>(LHSVecType)) {
|
||||
if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
|
||||
LHSVecType->getElementType(), LHSType))
|
||||
return LHSType;
|
||||
if (!RHSVecType) {
|
||||
if (isa<ExtVectorType>(LHSVecType)) {
|
||||
if (!tryVectorConvertAndSplat(*this, &RHS, RHSType,
|
||||
LHSVecType->getElementType(), LHSType))
|
||||
return LHSType;
|
||||
} else {
|
||||
if (!tryGCCVectorConvertAndSplat(*this, &RHS, &LHS))
|
||||
return LHSType;
|
||||
}
|
||||
}
|
||||
if (!LHSVecType && isa<ExtVectorType>(RHSVecType)) {
|
||||
if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
|
||||
LHSType, RHSVecType->getElementType(),
|
||||
RHSType))
|
||||
return RHSType;
|
||||
if (!LHSVecType) {
|
||||
if (isa<ExtVectorType>(RHSVecType)) {
|
||||
if (!tryVectorConvertAndSplat(*this, (IsCompAssign ? nullptr : &LHS),
|
||||
LHSType, RHSVecType->getElementType(),
|
||||
RHSType))
|
||||
return RHSType;
|
||||
} else {
|
||||
if (LHS.get()->getValueKind() == VK_LValue ||
|
||||
!tryGCCVectorConvertAndSplat(*this, &LHS, &RHS))
|
||||
return RHSType;
|
||||
}
|
||||
}
|
||||
|
||||
// FIXME: The code below also handles conversion between vectors and
|
||||
@ -8208,6 +8404,22 @@ QualType Sema::CheckVectorOperands(ExprResult &LHS, ExprResult &RHS,
|
||||
return QualType();
|
||||
}
|
||||
|
||||
|
||||
// If there is a vector type that is not a ExtVector and a scalar, we reach
|
||||
// this point if scalar could not be converted to the vector's element type
|
||||
// without truncation.
|
||||
if ((RHSVecType && !isa<ExtVectorType>(RHSVecType)) ||
|
||||
(LHSVecType && !isa<ExtVectorType>(LHSVecType))) {
|
||||
QualType Scalar = LHSVecType ? RHSType : LHSType;
|
||||
QualType Vector = LHSVecType ? LHSType : RHSType;
|
||||
unsigned ScalarOrVector = LHSVecType && RHSVecType ? 1 : 0;
|
||||
Diag(Loc,
|
||||
diag::err_typecheck_vector_not_convertable_implict_truncation)
|
||||
<< ScalarOrVector << Scalar << Vector;
|
||||
|
||||
return QualType();
|
||||
}
|
||||
|
||||
// Otherwise, use the generic diagnostic.
|
||||
Diag(Loc, diag::err_typecheck_vector_not_convertable)
|
||||
<< LHSType << RHSType
|
||||
@ -9827,6 +10039,12 @@ QualType Sema::CheckVectorLogicalOperands(ExprResult &LHS, ExprResult &RHS,
|
||||
if (getLangOpts().OpenCL && getLangOpts().OpenCLVersion < 120 &&
|
||||
vType->hasFloatingRepresentation())
|
||||
return InvalidOperands(Loc, LHS, RHS);
|
||||
// FIXME: The check for C++ here is for GCC compatibility. GCC rejects the
|
||||
// usage of the logical operators && and || with vectors in C. This
|
||||
// check could be notionally dropped.
|
||||
if (!getLangOpts().CPlusPlus &&
|
||||
!(isa<ExtVectorType>(vType->getAs<VectorType>())))
|
||||
return InvalidLogicalVectorOperands(Loc, LHS, RHS);
|
||||
|
||||
return GetSignedVectorType(LHS.get()->getType());
|
||||
}
|
||||
@ -11770,6 +11988,8 @@ ExprResult Sema::CreateBuiltinUnaryOp(SourceLocation OpLoc,
|
||||
resultType = GetSignedVectorType(resultType);
|
||||
break;
|
||||
} else {
|
||||
// FIXME: GCC's vector extension permits the usage of '!' with a vector
|
||||
// type in C++. We should allow that here too.
|
||||
return ExprError(Diag(OpLoc, diag::err_typecheck_unary_expr)
|
||||
<< resultType << Input.get()->getSourceRange());
|
||||
}
|
||||
|
@ -4720,10 +4720,24 @@ static bool EvaluateBinaryTypeTrait(Sema &Self, TypeTrait BTT, QualType LhsT,
|
||||
// regard to cv-qualifiers.
|
||||
|
||||
const RecordType *lhsRecord = LhsT->getAs<RecordType>();
|
||||
if (!lhsRecord) return false;
|
||||
|
||||
const RecordType *rhsRecord = RhsT->getAs<RecordType>();
|
||||
if (!rhsRecord) return false;
|
||||
if (!rhsRecord || !lhsRecord) {
|
||||
const ObjCObjectType *LHSObjTy = LhsT->getAs<ObjCObjectType>();
|
||||
const ObjCObjectType *RHSObjTy = RhsT->getAs<ObjCObjectType>();
|
||||
if (!LHSObjTy || !RHSObjTy)
|
||||
return false;
|
||||
|
||||
ObjCInterfaceDecl *BaseInterface = LHSObjTy->getInterface();
|
||||
ObjCInterfaceDecl *DerivedInterface = RHSObjTy->getInterface();
|
||||
if (!BaseInterface || !DerivedInterface)
|
||||
return false;
|
||||
|
||||
if (Self.RequireCompleteType(
|
||||
KeyLoc, RhsT, diag::err_incomplete_type_used_in_type_trait_expr))
|
||||
return false;
|
||||
|
||||
return BaseInterface->isSuperClassOf(DerivedInterface);
|
||||
}
|
||||
|
||||
assert(Self.Context.hasSameUnqualifiedType(LhsT, RhsT)
|
||||
== (lhsRecord == rhsRecord));
|
||||
@ -5342,6 +5356,15 @@ QualType Sema::CXXCheckConditionalOperands(ExprResult &Cond, ExprResult &LHS,
|
||||
|
||||
// C++11 [expr.cond]p1
|
||||
// The first expression is contextually converted to bool.
|
||||
//
|
||||
// FIXME; GCC's vector extension permits the use of a?b:c where the type of
|
||||
// a is that of a integer vector with the same number of elements and
|
||||
// size as the vectors of b and c. If one of either b or c is a scalar
|
||||
// it is implicitly converted to match the type of the vector.
|
||||
// Otherwise the expression is ill-formed. If both b and c are scalars,
|
||||
// then b and c are checked and converted to the type of a if possible.
|
||||
// Unlike the OpenCL ?: operator, the expression is evaluated as
|
||||
// (a[0] != 0 ? b[0] : c[0], .. , a[n] != 0 ? b[n] : c[n]).
|
||||
if (!Cond.get()->isTypeDependent()) {
|
||||
ExprResult CondRes = CheckCXXBooleanCondition(Cond.get());
|
||||
if (CondRes.isInvalid())
|
||||
|
@ -4241,8 +4241,7 @@ void Sema::diagnoseARCUnbridgedCast(Expr *e) {
|
||||
castType = cast->getTypeAsWritten();
|
||||
CCK = CCK_OtherCast;
|
||||
} else {
|
||||
castType = cast->getType();
|
||||
CCK = CCK_ImplicitConversion;
|
||||
llvm_unreachable("Unexpected ImplicitCastExpr");
|
||||
}
|
||||
|
||||
ARCConversionTypeClass castACTC =
|
||||
|
@ -1209,7 +1209,7 @@ void InitListChecker::CheckSubElementType(const InitializedEntity &Entity,
|
||||
|
||||
} else {
|
||||
assert((ElemType->isRecordType() || ElemType->isVectorType() ||
|
||||
ElemType->isClkEventT()) && "Unexpected type");
|
||||
ElemType->isOpenCLSpecificType()) && "Unexpected type");
|
||||
|
||||
// C99 6.7.8p13:
|
||||
//
|
||||
@ -8296,8 +8296,46 @@ Sema::PerformCopyInitialization(const InitializedEntity &Entity,
|
||||
AllowExplicit);
|
||||
InitializationSequence Seq(*this, Entity, Kind, InitE, TopLevelOfInitList);
|
||||
|
||||
// Prevent infinite recursion when performing parameter copy-initialization.
|
||||
const bool ShouldTrackCopy =
|
||||
Entity.isParameterKind() && Seq.isConstructorInitialization();
|
||||
if (ShouldTrackCopy) {
|
||||
if (llvm::find(CurrentParameterCopyTypes, Entity.getType()) !=
|
||||
CurrentParameterCopyTypes.end()) {
|
||||
Seq.SetOverloadFailure(
|
||||
InitializationSequence::FK_ConstructorOverloadFailed,
|
||||
OR_No_Viable_Function);
|
||||
|
||||
// Try to give a meaningful diagnostic note for the problematic
|
||||
// constructor.
|
||||
const auto LastStep = Seq.step_end() - 1;
|
||||
assert(LastStep->Kind ==
|
||||
InitializationSequence::SK_ConstructorInitialization);
|
||||
const FunctionDecl *Function = LastStep->Function.Function;
|
||||
auto Candidate =
|
||||
llvm::find_if(Seq.getFailedCandidateSet(),
|
||||
[Function](const OverloadCandidate &Candidate) -> bool {
|
||||
return Candidate.Viable &&
|
||||
Candidate.Function == Function &&
|
||||
Candidate.Conversions.size() > 0;
|
||||
});
|
||||
if (Candidate != Seq.getFailedCandidateSet().end() &&
|
||||
Function->getNumParams() > 0) {
|
||||
Candidate->Viable = false;
|
||||
Candidate->FailureKind = ovl_fail_bad_conversion;
|
||||
Candidate->Conversions[0].setBad(BadConversionSequence::no_conversion,
|
||||
InitE,
|
||||
Function->getParamDecl(0)->getType());
|
||||
}
|
||||
}
|
||||
CurrentParameterCopyTypes.push_back(Entity.getType());
|
||||
}
|
||||
|
||||
ExprResult Result = Seq.Perform(*this, Entity, Kind, InitE);
|
||||
|
||||
if (ShouldTrackCopy)
|
||||
CurrentParameterCopyTypes.pop_back();
|
||||
|
||||
return Result;
|
||||
}
|
||||
|
||||
|
Some files were not shown because too many files have changed in this diff Show More
Loading…
Reference in New Issue
Block a user