diff options
author | David L. Jones <dlj@google.com> | 2017-11-15 01:40:05 +0000 |
---|---|---|
committer | David L. Jones <dlj@google.com> | 2017-11-15 01:40:05 +0000 |
commit | fdfce82b87b73e18577d493e84bdabe2585b95d0 (patch) | |
tree | e8d9290e273dba03920bf15a8c7742fcf5ed0b87 | |
parent | 41af1698c520ea38edf83e7c91f1e519d34f20c1 (diff) | |
parent | a7540887e8b5cb34ee28c12bef863bad85c65b6f (diff) | |
download | clang-google/testing.tar.gz |
Creating branches/google/testing and tags/google/testing/2017-11-14 from r317716google/testing
git-svn-id: https://llvm.org/svn/llvm-project/cfe/branches/google/testing@318248 91177308-0d34-0410-b5e6-96231b3b80d8
161 files changed, 7156 insertions, 3651 deletions
diff --git a/CMakeLists.txt b/CMakeLists.txt index 42d580077d..563b33eae2 100644 --- a/CMakeLists.txt +++ b/CMakeLists.txt @@ -429,6 +429,7 @@ add_subdirectory(include) # All targets below may depend on all tablegen'd files. get_property(CLANG_TABLEGEN_TARGETS GLOBAL PROPERTY CLANG_TABLEGEN_TARGETS) add_custom_target(clang-tablegen-targets DEPENDS ${CLANG_TABLEGEN_TARGETS}) +set_target_properties(clang-tablegen-targets PROPERTIES FOLDER "Misc") list(APPEND LLVM_COMMON_DEPENDS clang-tablegen-targets) # Force target to be built as soon as possible. Clang modules builds depend diff --git a/bindings/python/tests/cindex/test_tls_kind.py b/bindings/python/tests/cindex/test_tls_kind.py index 6a03c0d5ee..d0ee4587bc 100644 --- a/bindings/python/tests/cindex/test_tls_kind.py +++ b/bindings/python/tests/cindex/test_tls_kind.py @@ -27,11 +27,21 @@ _Thread_local int tls_static; # The following case tests '__declspec(thread)'. Since it is a Microsoft # specific extension, specific flags are required for the parser to pick # these up. - flags = ['-fms-extensions', '-target', 'x86_64-unknown-windows-win32'] + flags = ['-fms-extensions', '-target', 'x86_64-unknown-windows-win32', + '-fms-compatibility-version=18'] tu = get_tu(""" -__declspec(thread) int tls_declspec; +__declspec(thread) int tls_declspec_msvc18; """, lang = 'cpp', flags=flags) - tls_declspec = get_cursor(tu.cursor, 'tls_declspec') - assert tls_declspec.tls_kind == TLSKind.STATIC + tls_declspec_msvc18 = get_cursor(tu.cursor, 'tls_declspec_msvc18') + assert tls_declspec_msvc18.tls_kind == TLSKind.STATIC + + flags = ['-fms-extensions', '-target', 'x86_64-unknown-windows-win32', + '-fms-compatibility-version=19'] + tu = get_tu(""" +__declspec(thread) int tls_declspec_msvc19; +""", lang = 'cpp', flags=flags) + + tls_declspec_msvc19 = get_cursor(tu.cursor, 'tls_declspec_msvc19') + assert tls_declspec_msvc19.tls_kind == TLSKind.DYNAMIC diff --git a/docs/LanguageExtensions.rst b/docs/LanguageExtensions.rst index 652145f66f..9583a51a3b 100644 --- a/docs/LanguageExtensions.rst +++ b/docs/LanguageExtensions.rst @@ -436,6 +436,49 @@ const_cast no no no no See also :ref:`langext-__builtin_shufflevector`, :ref:`langext-__builtin_convertvector`. +Half-Precision Floating Point +============================= + +Clang supports two half-precision (16-bit) floating point types: ``__fp16`` and +``_Float16``. ``__fp16`` is defined in the ARM C Language Extensions (`ACLE +<http://infocenter.arm.com/help/topic/com.arm.doc.ihi0053d/IHI0053D_acle_2_1.pdf>`_) +and ``_Float16`` in ISO/IEC TS 18661-3:2015. + +``__fp16`` is a storage and interchange format only. This means that values of +``__fp16`` promote to (at least) float when used in arithmetic operations. +There are two ``__fp16`` formats. Clang supports the IEEE 754-2008 format and +not the ARM alternative format. + +ISO/IEC TS 18661-3:2015 defines C support for additional floating point types. +``_FloatN`` is defined as a binary floating type, where the N suffix denotes +the number of bits and is 16, 32, 64, or greater and equal to 128 and a +multiple of 32. Clang supports ``_Float16``. The difference from ``__fp16`` is +that arithmetic on ``_Float16`` is performed in half-precision, thus it is not +a storage-only format. ``_Float16`` is available as a source language type in +both C and C++ mode. + +It is recommended that portable code use the ``_Float16`` type because +``__fp16`` is an ARM C-Language Extension (ACLE), whereas ``_Float16`` is +defined by the C standards committee, so using ``_Float16`` will not prevent +code from being ported to architectures other than Arm. Also, ``_Float16`` +arithmetic and operations will directly map on half-precision instructions when +they are available (e.g. Armv8.2-A), avoiding conversions to/from +single-precision, and thus will result in more performant code. If +half-precision instructions are unavailable, values will be promoted to +single-precision, similar to the semantics of ``__fp16`` except that the +results will be stored in single-precision. + +In an arithmetic operation where one operand is of ``__fp16`` type and the +other is of ``_Float16`` type, the ``_Float16`` type is first converted to +``__fp16`` type and then the operation is completed as if both operands were of +``__fp16`` type. + +To define a ``_Float16`` literal, suffix ``f16`` can be appended to the compile-time +constant declaration. There is no default argument promotion for ``_Float16``; this +applies to the standard floating types only. As a consequence, for example, an +explicit cast is required for printing a ``_Float16`` value (there is no string +format specifier for ``_Float16``). + Messages on ``deprecated`` and ``unavailable`` Attributes ========================================================= diff --git a/docs/ReleaseNotes.rst b/docs/ReleaseNotes.rst index 4c8099121e..8699812496 100644 --- a/docs/ReleaseNotes.rst +++ b/docs/ReleaseNotes.rst @@ -82,7 +82,8 @@ Improvements to Clang's diagnostics tautological comparisons between integer variable of the type ``T`` and the largest/smallest possible integer constant of that same type. -- For C code, ``-Wsign-compare``, ``-Wtautological-constant-compare`` and +- For C code, ``-Wsign-compare``, ``-Wsign-conversion``, + ``-Wtautological-constant-compare`` and ``-Wtautological-constant-out-of-range-compare`` were adjusted to use the underlying datatype of ``enum``. diff --git a/include/clang/AST/CanonicalType.h b/include/clang/AST/CanonicalType.h index 023456e2e3..6487613200 100644 --- a/include/clang/AST/CanonicalType.h +++ b/include/clang/AST/CanonicalType.h @@ -1,4 +1,4 @@ -//===-- CanonicalType.h - C Language Family Type Representation -*- C++ -*-===// +//===- CanonicalType.h - C Language Family Type Representation --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,13 +16,29 @@ #define LLVM_CLANG_AST_CANONICALTYPE_H #include "clang/AST/Type.h" +#include "clang/Basic/Diagnostic.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/iterator.h" #include "llvm/Support/Casting.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include <cassert> +#include <iterator> +#include <type_traits> namespace clang { template<typename T> class CanProxy; template<typename T> struct CanProxyAdaptor; +class CXXRecordDecl; +class EnumDecl; +class Expr; +class IdentifierInfo; +class ObjCInterfaceDecl; +class RecordDecl; +class TagDecl; +class TemplateTypeParmDecl; //----------------------------------------------------------------------------// // Canonical, qualified type template @@ -46,8 +62,6 @@ template<typename T> struct CanProxyAdaptor; /// converted to @c CanQual<ReferenceType>. Note that any @c CanQual type can /// be implicitly converted to a QualType, but the reverse operation requires /// a call to ASTContext::getCanonicalType(). -/// -/// template<typename T = Type> class CanQual { /// \brief The actual, canonical type. @@ -55,7 +69,7 @@ class CanQual { public: /// \brief Constructs a NULL canonical type. - CanQual() : Stored() { } + CanQual() = default; /// \brief Converting constructor that permits implicit upcasting of /// canonical type pointers. @@ -66,12 +80,11 @@ public: /// \brief Retrieve the underlying type pointer, which refers to a /// canonical type. /// - /// The underlying pointer must not be NULL. + /// The underlying pointer must not be nullptr. const T *getTypePtr() const { return cast<T>(Stored.getTypePtr()); } /// \brief Retrieve the underlying type pointer, which refers to a - /// canonical type, or NULL. - /// + /// canonical type, or nullptr. const T *getTypePtrOrNull() const { return cast_or_null<T>(Stored.getTypePtrOrNull()); } @@ -125,9 +138,11 @@ public: bool isConstQualified() const { return Stored.isLocalConstQualified(); } + bool isVolatileQualified() const { return Stored.isLocalVolatileQualified(); } + bool isRestrictQualified() const { return Stored.isLocalRestrictQualified(); } @@ -195,7 +210,7 @@ inline bool operator!=(CanQual<T> x, CanQual<U> y) { } /// \brief Represents a canonical, potentially-qualified type. -typedef CanQual<Type> CanQualType; +using CanQualType = CanQual<Type>; inline CanQualType Type::getCanonicalTypeUnqualified() const { return CanQualType::CreateUnsafe(getCanonicalTypeInternal()); @@ -320,7 +335,7 @@ public: /// than the more typical @c QualType, to propagate the notion of "canonical" /// through the system. template<typename T> -struct CanProxyAdaptor : CanProxyBase<T> { }; +struct CanProxyAdaptor : CanProxyBase<T> {}; /// \brief Canonical proxy type returned when retrieving the members of a /// canonical type or as the result of the @c CanQual<T>::getAs member @@ -333,7 +348,7 @@ template<typename T> class CanProxy : public CanProxyAdaptor<T> { public: /// \brief Build a NULL proxy. - CanProxy() { } + CanProxy() = default; /// \brief Build a proxy to the given canonical type. CanProxy(CanQual<T> Stored) { this->Stored = Stored; } @@ -342,7 +357,7 @@ public: operator CanQual<T>() const { return this->Stored; } }; -} // end namespace clang +} // namespace clang namespace llvm { @@ -350,8 +365,9 @@ namespace llvm { /// CanQual<T> to a specific Type class. We're prefer isa/dyn_cast/cast/etc. /// to return smart pointer (proxies?). template<typename T> -struct simplify_type< ::clang::CanQual<T> > { - typedef const T *SimpleType; +struct simplify_type< ::clang::CanQual<T>> { + using SimpleType = const T *; + static SimpleType getSimplifiedValue(::clang::CanQual<T> Val) { return Val.getTypePtr(); } @@ -359,18 +375,20 @@ struct simplify_type< ::clang::CanQual<T> > { // Teach SmallPtrSet that CanQual<T> is "basically a pointer". template<typename T> -struct PointerLikeTypeTraits<clang::CanQual<T> > { - static inline void *getAsVoidPointer(clang::CanQual<T> P) { +struct PointerLikeTypeTraits<clang::CanQual<T>> { + static void *getAsVoidPointer(clang::CanQual<T> P) { return P.getAsOpaquePtr(); } - static inline clang::CanQual<T> getFromVoidPointer(void *P) { + + static clang::CanQual<T> getFromVoidPointer(void *P) { return clang::CanQual<T>::getFromOpaquePtr(P); } + // qualifier information is encoded in the low bits. enum { NumLowBitsAvailable = 0 }; }; -} // end namespace llvm +} // namespace llvm namespace clang { @@ -388,7 +406,7 @@ struct CanTypeIterator CanQualType, typename std::iterator_traits<InputIterator>::difference_type, CanProxy<Type>, CanQualType> { - CanTypeIterator() {} + CanTypeIterator() = default; explicit CanTypeIterator(InputIterator Iter) : CanTypeIterator::iterator_adaptor_base(std::move(Iter)) {} @@ -486,6 +504,7 @@ struct CanProxyAdaptor<FunctionProtoType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, hasExtParameterInfos) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR( ArrayRef<FunctionProtoType::ExtParameterInfo>, getExtParameterInfos) + CanQualType getParamType(unsigned i) const { return CanQualType::CreateUnsafe(this->getTypePtr()->getParamType(i)); } @@ -493,8 +512,8 @@ struct CanProxyAdaptor<FunctionProtoType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isVariadic) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(unsigned, getTypeQuals) - typedef CanTypeIterator<FunctionProtoType::param_type_iterator> - param_type_iterator; + using param_type_iterator = + CanTypeIterator<FunctionProtoType::param_type_iterator>; param_type_iterator param_type_begin() const { return param_type_iterator(this->getTypePtr()->param_type_begin()); @@ -566,7 +585,8 @@ struct CanProxyAdaptor<ObjCObjectType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedId) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClass) - typedef ObjCObjectPointerType::qual_iterator qual_iterator; + using qual_iterator = ObjCObjectPointerType::qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) @@ -584,7 +604,8 @@ struct CanProxyAdaptor<ObjCObjectPointerType> LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedIdType) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, isObjCQualifiedClassType) - typedef ObjCObjectPointerType::qual_iterator qual_iterator; + using qual_iterator = ObjCObjectPointerType::qual_iterator; + LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_begin) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(qual_iterator, qual_end) LLVM_CLANG_CANPROXY_SIMPLE_ACCESSOR(bool, qual_empty) @@ -661,7 +682,6 @@ CanProxy<Type> CanTypeIterator<InputIterator>::operator->() const { return CanProxy<Type>(*this); } -} - +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_CANONICALTYPE_H diff --git a/include/clang/AST/DeclBase.h b/include/clang/AST/DeclBase.h index 47515a848a..f93c9f0b9a 100644 --- a/include/clang/AST/DeclBase.h +++ b/include/clang/AST/DeclBase.h @@ -1,4 +1,4 @@ -//===-- DeclBase.h - Base Classes for representing declarations -*- C++ -*-===// +//===- DeclBase.h - Base Classes for representing declarations --*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -16,33 +16,40 @@ #include "clang/AST/AttrIterator.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/Specifiers.h" #include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/iterator.h" #include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/PrettyStackTrace.h" +#include <algorithm> +#include <cassert> +#include <cstddef> +#include <iterator> +#include <string> +#include <type_traits> +#include <utility> namespace clang { + +class ASTContext; class ASTMutationListener; -class BlockDecl; -class CXXRecordDecl; -class CompoundStmt; +class Attr; class DeclContext; -class DeclarationName; -class DependentDiagnostic; -class EnumDecl; -class ExportDecl; class ExternalSourceSymbolAttr; class FunctionDecl; class FunctionType; +class IdentifierInfo; enum Linkage : unsigned char; -class LinkageComputer; class LinkageSpecDecl; class Module; class NamedDecl; -class NamespaceDecl; class ObjCCategoryDecl; class ObjCCategoryImplDecl; class ObjCContainerDecl; @@ -53,23 +60,21 @@ class ObjCMethodDecl; class ObjCProtocolDecl; struct PrintingPolicy; class RecordDecl; +class SourceManager; class Stmt; class StoredDeclsMap; class TemplateDecl; class TranslationUnitDecl; class UsingDirectiveDecl; -} -namespace clang { - - /// \brief Captures the result of checking the availability of a - /// declaration. - enum AvailabilityResult { - AR_Available = 0, - AR_NotYetIntroduced, - AR_Deprecated, - AR_Unavailable - }; +/// \brief Captures the result of checking the availability of a +/// declaration. +enum AvailabilityResult { + AR_Available = 0, + AR_NotYetIntroduced, + AR_Deprecated, + AR_Unavailable +}; /// Decl - This represents one declaration (or definition), e.g. a variable, /// typedef, function, struct, etc. @@ -94,7 +99,7 @@ public: /// \brief A placeholder type used to construct an empty shell of a /// decl-derived type that will be filled in later (e.g., by some /// deserialization method). - struct EmptyShell { }; + struct EmptyShell {}; /// IdentifierNamespace - The different namespaces in which /// declarations may appear. According to C99 6.2.3, there are @@ -208,15 +213,18 @@ public: enum class ModuleOwnershipKind : unsigned { /// This declaration is not owned by a module. Unowned, + /// This declaration has an owning module, but is globally visible /// (typically because its owning module is visible and we know that /// modules cannot later become hidden in this compilation). /// After serialization and deserialization, this will be converted /// to VisibleWhenImported. Visible, + /// This declaration has an owning module, and is visible when that /// module is imported. VisibleWhenImported, + /// This declaration has an owning module, but is only visible to /// lookups that occur within that module. ModulePrivate @@ -238,7 +246,6 @@ private: DeclContext *LexicalDC; }; - /// DeclCtx - Holds either a DeclContext* or a MultipleDC*. /// For declarations that don't contain C++ scope specifiers, it contains /// the DeclContext where the Decl was declared. @@ -254,12 +261,14 @@ private: /// // LexicalDC == global namespace llvm::PointerUnion<DeclContext*, MultipleDC*> DeclCtx; - inline bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } - inline bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } - inline MultipleDC *getMultipleDC() const { + bool isInSemaDC() const { return DeclCtx.is<DeclContext*>(); } + bool isOutOfSemaDC() const { return DeclCtx.is<MultipleDC*>(); } + + MultipleDC *getMultipleDC() const { return DeclCtx.get<MultipleDC*>(); } - inline DeclContext *getSemanticDC() const { + + DeclContext *getSemanticDC() const { return DeclCtx.get<DeclContext*>(); } @@ -298,10 +307,16 @@ private: static bool StatisticsEnabled; protected: + friend class ASTDeclReader; + friend class ASTDeclWriter; + friend class ASTReader; + friend class CXXClassMemberWrapper; + friend class LinkageComputer; + template<typename decl_type> friend class Redeclarable; + /// Access - Used by C++ decls for the access specifier. // NOTE: VC++ treats enums as signed, avoid using the AccessSpecifier enum unsigned Access : 2; - friend class CXXClassMemberWrapper; /// \brief Whether this declaration was loaded from an AST file. unsigned FromASTFile : 1; @@ -313,13 +328,6 @@ protected: /// Otherwise, it is the linkage + 1. mutable unsigned CacheValidAndLinkage : 3; - friend class ASTDeclWriter; - friend class ASTDeclReader; - friend class ASTReader; - friend class LinkageComputer; - - template<typename decl_type> friend class Redeclarable; - /// \brief Allocate memory for a deserialized declaration. /// /// This routine must be used to allocate memory for any declaration that is @@ -357,7 +365,7 @@ private: protected: Decl(Kind DK, DeclContext *DC, SourceLocation L) : NextInContextAndBits(nullptr, getModuleOwnershipKindForChildOf(DC)), - DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(0), HasAttrs(false), + DeclCtx(DC), Loc(L), DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), @@ -366,9 +374,9 @@ protected: } Decl(Kind DK, EmptyShell Empty) - : NextInContextAndBits(), DeclKind(DK), InvalidDecl(0), HasAttrs(false), - Implicit(false), Used(false), Referenced(false), - TopLevelDeclInObjCContainer(false), Access(AS_none), FromASTFile(0), + : DeclKind(DK), InvalidDecl(false), HasAttrs(false), Implicit(false), + Used(false), Referenced(false), TopLevelDeclInObjCContainer(false), + Access(AS_none), FromASTFile(0), IdentifierNamespace(getIdentifierNamespaceForKind(DK)), CacheValidAndLinkage(0) { if (StatisticsEnabled) add(DK); @@ -392,14 +400,15 @@ protected: } public: - /// \brief Source range that this declaration covers. virtual SourceRange getSourceRange() const LLVM_READONLY { return SourceRange(getLocation(), getLocation()); } + SourceLocation getLocStart() const LLVM_READONLY { return getSourceRange().getBegin(); } + SourceLocation getLocEnd() const LLVM_READONLY { return getSourceRange().getEnd(); } @@ -460,12 +469,15 @@ public: } bool hasAttrs() const { return HasAttrs; } + void setAttrs(const AttrVec& Attrs) { return setAttrsImpl(Attrs, getASTContext()); } + AttrVec &getAttrs() { return const_cast<AttrVec&>(const_cast<const Decl*>(this)->getAttrs()); } + const AttrVec &getAttrs() const; void dropAttrs(); @@ -476,8 +488,8 @@ public: setAttrs(AttrVec(1, A)); } - typedef AttrVec::const_iterator attr_iterator; - typedef llvm::iterator_range<attr_iterator> attr_range; + using attr_iterator = AttrVec::const_iterator; + using attr_range = llvm::iterator_range<attr_iterator>; attr_range attrs() const { return attr_range(attr_begin(), attr_end()); @@ -510,6 +522,7 @@ public: specific_attr_iterator<T> specific_attr_begin() const { return specific_attr_iterator<T>(attr_begin()); } + template <typename T> specific_attr_iterator<T> specific_attr_end() const { return specific_attr_iterator<T>(attr_end()); @@ -518,6 +531,7 @@ public: template<typename T> T *getAttr() const { return hasAttrs() ? getSpecificAttr<T>(getAttrs()) : nullptr; } + template<typename T> bool hasAttr() const { return hasAttrs() && hasSpecificAttr<T>(getAttrs()); } @@ -616,7 +630,6 @@ protected: } public: - /// \brief Determine the availability of the given declaration. /// /// This routine will determine the most restrictive availability of @@ -698,6 +711,7 @@ public: private: Module *getOwningModuleSlow() const; + protected: bool hasLocalOwningModuleStorage() const; @@ -777,14 +791,17 @@ public: unsigned getIdentifierNamespace() const { return IdentifierNamespace; } + bool isInIdentifierNamespace(unsigned NS) const { return getIdentifierNamespace() & NS; } + static unsigned getIdentifierNamespaceForKind(Kind DK); bool hasTagIdentifierNamespace() const { return isTagIdentifierNamespace(getIdentifierNamespace()); } + static bool isTagIdentifierNamespace(unsigned NS) { // TagDecls have Tag and Type set and may also have TagFriend. return (NS & ~IDNS_TagFriend) == (IDNS_Tag | IDNS_Type); @@ -872,18 +889,18 @@ public: /// \brief Iterates through all the redeclarations of the same decl. class redecl_iterator { /// Current - The current declaration. - Decl *Current; + Decl *Current = nullptr; Decl *Starter; public: - typedef Decl *value_type; - typedef const value_type &reference; - typedef const value_type *pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = Decl *; + using reference = const value_type &; + using pointer = const value_type *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - redecl_iterator() : Current(nullptr) { } - explicit redecl_iterator(Decl *C) : Current(C), Starter(C) { } + redecl_iterator() = default; + explicit redecl_iterator(Decl *C) : Current(C), Starter(C) {} reference operator*() const { return Current; } value_type operator->() const { return Current; } @@ -906,12 +923,13 @@ public: friend bool operator==(redecl_iterator x, redecl_iterator y) { return x.Current == y.Current; } + friend bool operator!=(redecl_iterator x, redecl_iterator y) { return x.Current != y.Current; } }; - typedef llvm::iterator_range<redecl_iterator> redecl_range; + using redecl_range = llvm::iterator_range<redecl_iterator>; /// \brief Returns an iterator range for all the redeclarations of the same /// decl. It will iterate at least once (when this decl is the only one). @@ -922,6 +940,7 @@ public: redecl_iterator redecls_begin() const { return redecl_iterator(const_cast<Decl *>(this)); } + redecl_iterator redecls_end() const { return redecl_iterator(); } /// \brief Retrieve the previous declaration that declares the same entity @@ -1103,10 +1122,13 @@ public: static void printGroup(Decl** Begin, unsigned NumDecls, raw_ostream &Out, const PrintingPolicy &Policy, unsigned Indentation = 0); + // Debuggers don't usually respect default arguments. void dump() const; + // Same as dump(), but forces color printing. void dumpColor() const; + void dump(raw_ostream &Out, bool Deserialize = false) const; /// \brief Looks through the Decl's underlying type to extract a FunctionType @@ -1141,10 +1163,11 @@ class PrettyStackTraceDecl : public llvm::PrettyStackTraceEntry { SourceLocation Loc; SourceManager &SM; const char *Message; + public: PrettyStackTraceDecl(const Decl *theDecl, SourceLocation L, SourceManager &sm, const char *Msg) - : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} + : TheDecl(theDecl), Loc(L), SM(sm), Message(Msg) {} void print(raw_ostream &OS) const override; }; @@ -1153,30 +1176,35 @@ public: /// single result (with no stable storage) or a collection of results (with /// stable storage provided by the lookup table). class DeclContextLookupResult { - typedef ArrayRef<NamedDecl *> ResultTy; + using ResultTy = ArrayRef<NamedDecl *>; + ResultTy Result; + // If there is only one lookup result, it would be invalidated by // reallocations of the name table, so store it separately. - NamedDecl *Single; + NamedDecl *Single = nullptr; static NamedDecl *const SingleElementDummyList; public: - DeclContextLookupResult() : Result(), Single() {} + DeclContextLookupResult() = default; DeclContextLookupResult(ArrayRef<NamedDecl *> Result) - : Result(Result), Single() {} + : Result(Result) {} DeclContextLookupResult(NamedDecl *Single) : Result(SingleElementDummyList), Single(Single) {} class iterator; - typedef llvm::iterator_adaptor_base<iterator, ResultTy::iterator, - std::random_access_iterator_tag, - NamedDecl *const> IteratorBase; + + using IteratorBase = + llvm::iterator_adaptor_base<iterator, ResultTy::iterator, + std::random_access_iterator_tag, + NamedDecl *const>; + class iterator : public IteratorBase { value_type SingleElement; public: - iterator() : IteratorBase(), SingleElement() {} + iterator() = default; explicit iterator(pointer Pos, value_type Single = nullptr) : IteratorBase(Pos), SingleElement(Single) {} @@ -1184,9 +1212,10 @@ public: return SingleElement ? SingleElement : IteratorBase::operator*(); } }; - typedef iterator const_iterator; - typedef iterator::pointer pointer; - typedef iterator::reference reference; + + using const_iterator = iterator; + using pointer = iterator::pointer; + using reference = iterator::reference; iterator begin() const { return iterator(Result.begin(), Single); } iterator end() const { return iterator(Result.end(), Single); } @@ -1220,7 +1249,6 @@ public: /// ExportDecl /// BlockDecl /// OMPDeclareReductionDecl -/// class DeclContext { /// DeclKind - This indicates which class this is. unsigned DeclKind : 8; @@ -1260,22 +1288,22 @@ class DeclContext { /// contains an entry for a DeclarationName (and we haven't lazily /// omitted anything), then it contains all relevant entries for that /// name (modulo the hasExternalDecls() flag). - mutable StoredDeclsMap *LookupPtr; + mutable StoredDeclsMap *LookupPtr = nullptr; protected: + friend class ASTDeclReader; + friend class ASTWriter; + friend class ExternalASTSource; + /// FirstDecl - The first declaration stored within this declaration /// context. - mutable Decl *FirstDecl; + mutable Decl *FirstDecl = nullptr; /// LastDecl - The last declaration stored within this declaration /// context. FIXME: We could probably cache this value somewhere /// outside of the DeclContext, to reduce the size of DeclContext by /// another pointer. - mutable Decl *LastDecl; - - friend class ExternalASTSource; - friend class ASTDeclReader; - friend class ASTWriter; + mutable Decl *LastDecl = nullptr; /// \brief Build up a chain of declarations. /// @@ -1288,8 +1316,7 @@ protected: ExternalVisibleStorage(false), NeedToReconcileExternalVisibleStorage(false), HasLazyLocalLexicalLookups(false), HasLazyExternalLexicalLookups(false), - UseQualifiedLookup(false), - LookupPtr(nullptr), FirstDecl(nullptr), LastDecl(nullptr) {} + UseQualifiedLookup(false) {} public: ~DeclContext(); @@ -1297,6 +1324,7 @@ public: Decl::Kind getDeclKind() const { return static_cast<Decl::Kind>(DeclKind); } + const char *getDeclKindName() const; /// getParent - Returns the containing DeclContext. @@ -1504,19 +1532,20 @@ public: /// within this context. class decl_iterator { /// Current - The current declaration. - Decl *Current; + Decl *Current = nullptr; public: - typedef Decl *value_type; - typedef const value_type &reference; - typedef const value_type *pointer; - typedef std::forward_iterator_tag iterator_category; - typedef std::ptrdiff_t difference_type; + using value_type = Decl *; + using reference = const value_type &; + using pointer = const value_type *; + using iterator_category = std::forward_iterator_tag; + using difference_type = std::ptrdiff_t; - decl_iterator() : Current(nullptr) { } - explicit decl_iterator(Decl *C) : Current(C) { } + decl_iterator() = default; + explicit decl_iterator(Decl *C) : Current(C) {} reference operator*() const { return Current; } + // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return Current; } @@ -1534,12 +1563,13 @@ public: friend bool operator==(decl_iterator x, decl_iterator y) { return x.Current == y.Current; } + friend bool operator!=(decl_iterator x, decl_iterator y) { return x.Current != y.Current; } }; - typedef llvm::iterator_range<decl_iterator> decl_range; + using decl_range = llvm::iterator_range<decl_iterator>; /// decls_begin/decls_end - Iterate over the declarations stored in /// this context. @@ -1578,16 +1608,16 @@ public: } public: - typedef SpecificDecl *value_type; - // TODO: Add reference and pointer typedefs (with some appropriate proxy - // type) if we ever have a need for them. - typedef void reference; - typedef void pointer; - typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type - difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = SpecificDecl *; + // TODO: Add reference and pointer types (with some appropriate proxy type) + // if we ever have a need for them. + using reference = void; + using pointer = void; + using difference_type = + std::iterator_traits<DeclContext::decl_iterator>::difference_type; + using iterator_category = std::forward_iterator_tag; - specific_decl_iterator() : Current() { } + specific_decl_iterator() = default; /// specific_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -1602,6 +1632,7 @@ public: } value_type operator*() const { return cast<SpecificDecl>(*Current); } + // This doesn't meet the iterator requirements, but it's convenient value_type operator->() const { return **this; } @@ -1655,16 +1686,16 @@ public: } public: - typedef SpecificDecl *value_type; - // TODO: Add reference and pointer typedefs (with some appropriate proxy - // type) if we ever have a need for them. - typedef void reference; - typedef void pointer; - typedef std::iterator_traits<DeclContext::decl_iterator>::difference_type - difference_type; - typedef std::forward_iterator_tag iterator_category; + using value_type = SpecificDecl *; + // TODO: Add reference and pointer types (with some appropriate proxy type) + // if we ever have a need for them. + using reference = void; + using pointer = void; + using difference_type = + std::iterator_traits<DeclContext::decl_iterator>::difference_type; + using iterator_category = std::forward_iterator_tag; - filtered_decl_iterator() : Current() { } + filtered_decl_iterator() = default; /// filtered_decl_iterator - Construct a new iterator over a /// subset of the declarations the range [C, @@ -1742,8 +1773,8 @@ public: /// @brief Checks whether a declaration is in this context. bool containsDecl(Decl *D) const; - typedef DeclContextLookupResult lookup_result; - typedef lookup_result::iterator lookup_iterator; + using lookup_result = DeclContextLookupResult; + using lookup_iterator = lookup_result::iterator; /// lookup - Find the declarations (if any) with the given Name in /// this context. Returns a range of iterators that contains all of @@ -1789,7 +1820,7 @@ public: /// of looking up every possible name. class all_lookups_iterator; - typedef llvm::iterator_range<all_lookups_iterator> lookups_range; + using lookups_range = llvm::iterator_range<all_lookups_iterator>; lookups_range lookups() const; lookups_range noload_lookups() const; @@ -1805,21 +1836,26 @@ public: all_lookups_iterator noload_lookups_end() const; struct udir_iterator; - typedef llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, - std::random_access_iterator_tag, - UsingDirectiveDecl *> udir_iterator_base; + + using udir_iterator_base = + llvm::iterator_adaptor_base<udir_iterator, lookup_iterator, + std::random_access_iterator_tag, + UsingDirectiveDecl *>; + struct udir_iterator : udir_iterator_base { udir_iterator(lookup_iterator I) : udir_iterator_base(I) {} + UsingDirectiveDecl *operator*() const; }; - typedef llvm::iterator_range<udir_iterator> udir_range; + using udir_range = llvm::iterator_range<udir_iterator>; udir_range using_directives() const; // These are all defined in DependentDiagnostic.h. class ddiag_iterator; - typedef llvm::iterator_range<DeclContext::ddiag_iterator> ddiag_range; + + using ddiag_range = llvm::iterator_range<DeclContext::ddiag_iterator>; inline ddiag_range ddiags() const; @@ -1892,6 +1928,8 @@ public: bool Deserialize = false) const; private: + friend class DependentDiagnostic; + void reconcileExternalVisibleStorage() const; bool LoadLexicalDeclsFromExternalStorage() const; @@ -1903,7 +1941,6 @@ private: /// use of addDeclInternal(). void makeDeclVisibleInContextInternal(NamedDecl *D); - friend class DependentDiagnostic; StoredDeclsMap *CreateStoredDeclsMap(ASTContext &C) const; void buildLookupImpl(DeclContext *DCtx, bool Internal); @@ -1942,8 +1979,7 @@ struct cast_convert_decl_context<ToTy, true> { } }; - -} // end clang. +} // namespace clang namespace llvm { @@ -1963,12 +1999,14 @@ struct cast_convert_val<ToTy, return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, ::clang::DeclContext, ::clang::DeclContext> { static ToTy &doit(::clang::DeclContext &Val) { return *::clang::cast_convert_decl_context<ToTy>::doit(&Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, const ::clang::DeclContext*, const ::clang::DeclContext*> { @@ -1976,6 +2014,7 @@ struct cast_convert_val<ToTy, return ::clang::cast_convert_decl_context<ToTy>::doit(Val); } }; + template<class ToTy> struct cast_convert_val<ToTy, ::clang::DeclContext*, ::clang::DeclContext*> { static ToTy *doit(::clang::DeclContext *Val) { @@ -2012,6 +2051,6 @@ struct cast_convert_val< const ::clang::DeclContext, FromTy*, FromTy*> { } }; -} // end namespace llvm +} // namespace llvm -#endif +#endif // LLVM_CLANG_AST_DECLBASE_H diff --git a/include/clang/AST/ExternalASTSource.h b/include/clang/AST/ExternalASTSource.h index d8dd18ecb8..be013c5d6b 100644 --- a/include/clang/AST/ExternalASTSource.h +++ b/include/clang/AST/ExternalASTSource.h @@ -1,4 +1,4 @@ -//===--- ExternalASTSource.h - Abstract External AST Interface --*- C++ -*-===// +//===- ExternalASTSource.h - Abstract External AST Interface ----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -11,24 +11,44 @@ // construction of AST nodes from some external source. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_AST_EXTERNALASTSOURCE_H #define LLVM_CLANG_AST_EXTERNALASTSOURCE_H #include "clang/AST/CharUnits.h" #include "clang/AST/DeclBase.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/PointerUnion.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <iterator> +#include <string> +#include <utility> namespace clang { class ASTConsumer; +class ASTContext; class CXXBaseSpecifier; class CXXCtorInitializer; +class CXXRecordDecl; class DeclarationName; -class ExternalSemaSource; // layering violation required for downcasting class FieldDecl; -class Module; +class IdentifierInfo; class NamedDecl; +class ObjCInterfaceDecl; class RecordDecl; class Selector; class Stmt; @@ -42,30 +62,31 @@ class TagDecl; /// actual type and declaration nodes, and read parts of declaration /// contexts. class ExternalASTSource : public RefCountedBase<ExternalASTSource> { + friend class ExternalSemaSource; + /// Generation number for this external AST source. Must be increased /// whenever we might have added new redeclarations for existing decls. - uint32_t CurrentGeneration; + uint32_t CurrentGeneration = 0; /// \brief Whether this AST source also provides information for /// semantic analysis. - bool SemaSource; - - friend class ExternalSemaSource; + bool SemaSource = false; public: - ExternalASTSource() : CurrentGeneration(0), SemaSource(false) { } - + ExternalASTSource() = default; virtual ~ExternalASTSource(); /// \brief RAII class for safely pairing a StartedDeserializing call /// with FinishedDeserializing. class Deserializing { ExternalASTSource *Source; + public: explicit Deserializing(ExternalASTSource *source) : Source(source) { assert(Source); Source->StartedDeserializing(); } + ~Deserializing() { Source->FinishedDeserializing(); } @@ -122,7 +143,7 @@ public: virtual CXXBaseSpecifier *GetExternalCXXBaseSpecifiers(uint64_t Offset); /// \brief Update an out-of-date identifier. - virtual void updateOutOfDateIdentifier(IdentifierInfo &II) { } + virtual void updateOutOfDateIdentifier(IdentifierInfo &II) {} /// \brief Find all declarations with the given name in the given context, /// and add them to the context by calling SetExternalVisibleDeclsForName @@ -154,12 +175,13 @@ public: const Module *ClangModule = nullptr; public: - ASTSourceDescriptor(){}; + ASTSourceDescriptor() = default; ASTSourceDescriptor(StringRef Name, StringRef Path, StringRef ASTFile, ASTFileSignature Signature) : PCHModuleName(std::move(Name)), Path(std::move(Path)), - ASTFile(std::move(ASTFile)), Signature(Signature){}; + ASTFile(std::move(ASTFile)), Signature(Signature) {} ASTSourceDescriptor(const Module &M); + std::string getModuleName() const; StringRef getPath() const { return Path; } StringRef getASTFile() const { return ASTFile; } @@ -246,7 +268,6 @@ public: /// The default implementation of this method is a no-op. virtual void PrintStats(); - /// \brief Perform layout on the given record. /// /// This routine allows the external AST source to provide an specific @@ -289,7 +310,7 @@ public: size_t mmap_bytes; MemoryBufferSizes(size_t malloc_bytes, size_t mmap_bytes) - : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} + : malloc_bytes(malloc_bytes), mmap_bytes(mmap_bytes) {} }; /// Return the amount of memory used by memory buffers, breaking down @@ -329,12 +350,12 @@ struct LazyOffsetPtr { /// /// If the low bit is clear, a pointer to the AST node. If the low /// bit is set, the upper 63 bits are the offset. - mutable uint64_t Ptr; + mutable uint64_t Ptr = 0; public: - LazyOffsetPtr() : Ptr(0) { } + LazyOffsetPtr() = default; + explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) {} - explicit LazyOffsetPtr(T *Ptr) : Ptr(reinterpret_cast<uint64_t>(Ptr)) { } explicit LazyOffsetPtr(uint64_t Offset) : Ptr((Offset << 1) | 0x01) { assert((Offset << 1 >> 1) == Offset && "Offsets must require < 63 bits"); if (Offset == 0) @@ -392,15 +413,16 @@ struct LazyGenerationalUpdatePtr { /// A cache of the value of this pointer, in the most recent generation in /// which we queried it. struct LazyData { - LazyData(ExternalASTSource *Source, T Value) - : ExternalSource(Source), LastGeneration(0), LastValue(Value) {} ExternalASTSource *ExternalSource; - uint32_t LastGeneration; + uint32_t LastGeneration = 0; T LastValue; + + LazyData(ExternalASTSource *Source, T Value) + : ExternalSource(Source), LastValue(Value) {} }; // Our value is represented as simply T if there is no external AST source. - typedef llvm::PointerUnion<T, LazyData*> ValueType; + using ValueType = llvm::PointerUnion<T, LazyData*>; ValueType Value; LazyGenerationalUpdatePtr(ValueType V) : Value(V) {} @@ -459,25 +481,31 @@ public: return LazyGenerationalUpdatePtr(ValueType::getFromOpaqueValue(Ptr)); } }; -} // end namespace clang + +} // namespace clang /// Specialize PointerLikeTypeTraits to allow LazyGenerationalUpdatePtr to be /// placed into a PointerUnion. namespace llvm { + template<typename Owner, typename T, void (clang::ExternalASTSource::*Update)(Owner)> struct PointerLikeTypeTraits< clang::LazyGenerationalUpdatePtr<Owner, T, Update>> { - typedef clang::LazyGenerationalUpdatePtr<Owner, T, Update> Ptr; + using Ptr = clang::LazyGenerationalUpdatePtr<Owner, T, Update>; + static void *getAsVoidPointer(Ptr P) { return P.getOpaqueValue(); } static Ptr getFromVoidPointer(void *P) { return Ptr::getFromOpaqueValue(P); } + enum { NumLowBitsAvailable = PointerLikeTypeTraits<T>::NumLowBitsAvailable - 1 }; }; -} + +} // namespace llvm namespace clang { + /// \brief Represents a lazily-loaded vector of data. /// /// The lazily-loaded vector of data contains data that is partially loaded @@ -511,13 +539,14 @@ public: class iterator : public llvm::iterator_adaptor_base< iterator, int, std::random_access_iterator_tag, T, int, T *, T &> { + friend class LazyVector; + LazyVector *Self; iterator(LazyVector *Self, int Position) : iterator::iterator_adaptor_base(Position), Self(Self) {} bool isLoaded() const { return this->I < 0; } - friend class LazyVector; public: iterator() : iterator(nullptr, 0) {} @@ -562,23 +591,23 @@ public: }; /// \brief A lazy pointer to a statement. -typedef LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt> - LazyDeclStmtPtr; +using LazyDeclStmtPtr = + LazyOffsetPtr<Stmt, uint64_t, &ExternalASTSource::GetExternalDeclStmt>; /// \brief A lazy pointer to a declaration. -typedef LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl> - LazyDeclPtr; +using LazyDeclPtr = + LazyOffsetPtr<Decl, uint32_t, &ExternalASTSource::GetExternalDecl>; /// \brief A lazy pointer to a set of CXXCtorInitializers. -typedef LazyOffsetPtr<CXXCtorInitializer *, uint64_t, - &ExternalASTSource::GetExternalCXXCtorInitializers> - LazyCXXCtorInitializersPtr; +using LazyCXXCtorInitializersPtr = + LazyOffsetPtr<CXXCtorInitializer *, uint64_t, + &ExternalASTSource::GetExternalCXXCtorInitializers>; /// \brief A lazy pointer to a set of CXXBaseSpecifiers. -typedef LazyOffsetPtr<CXXBaseSpecifier, uint64_t, - &ExternalASTSource::GetExternalCXXBaseSpecifiers> - LazyCXXBaseSpecifiersPtr; +using LazyCXXBaseSpecifiersPtr = + LazyOffsetPtr<CXXBaseSpecifier, uint64_t, + &ExternalASTSource::GetExternalCXXBaseSpecifiers>; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_AST_EXTERNALASTSOURCE_H diff --git a/include/clang/AST/PrettyPrinter.h b/include/clang/AST/PrettyPrinter.h index 953ecada6c..2c0564335b 100644 --- a/include/clang/AST/PrettyPrinter.h +++ b/include/clang/AST/PrettyPrinter.h @@ -30,8 +30,8 @@ public: virtual bool handledStmt(Stmt* E, raw_ostream& OS) = 0; }; -/// \brief Describes how types, statements, expressions, and -/// declarations should be printed. +/// Describes how types, statements, expressions, and declarations should be +/// printed. /// /// This type is intended to be small and suitable for passing by value. /// It is very frequently copied. @@ -53,20 +53,20 @@ struct PrintingPolicy { IncludeNewlines(true), MSVCFormatting(false), ConstantsAsWritten(false), SuppressImplicitBase(false) { } - /// \brief Adjust this printing policy for cases where it's known that - /// we're printing C++ code (for instance, if AST dumping reaches a - /// C++-only construct). This should not be used if a real LangOptions - /// object is available. + /// Adjust this printing policy for cases where it's known that we're + /// printing C++ code (for instance, if AST dumping reaches a C++-only + /// construct). This should not be used if a real LangOptions object is + /// available. void adjustForCPlusPlus() { SuppressTagKeyword = true; Bool = true; UseVoidForZeroParams = false; } - /// \brief The number of spaces to use to indent each line. + /// The number of spaces to use to indent each line. unsigned Indentation : 8; - /// \brief Whether we should suppress printing of the actual specifiers for + /// Whether we should suppress printing of the actual specifiers for /// the given type or declaration. /// /// This flag is only used when we are printing declarators beyond @@ -82,7 +82,7 @@ struct PrintingPolicy { /// "const int" type specifier and instead only print the "*y". bool SuppressSpecifiers : 1; - /// \brief Whether type printing should skip printing the tag keyword. + /// Whether type printing should skip printing the tag keyword. /// /// This is used when printing the inner type of elaborated types, /// (as the tag keyword is part of the elaborated type): @@ -92,7 +92,7 @@ struct PrintingPolicy { /// \endcode bool SuppressTagKeyword : 1; - /// \brief When true, include the body of a tag definition. + /// When true, include the body of a tag definition. /// /// This is used to place the definition of a struct /// in the middle of another declaration as with: @@ -102,14 +102,14 @@ struct PrintingPolicy { /// \endcode bool IncludeTagDefinition : 1; - /// \brief Suppresses printing of scope specifiers. + /// Suppresses printing of scope specifiers. bool SuppressScope : 1; - /// \brief Suppress printing parts of scope specifiers that don't need + /// Suppress printing parts of scope specifiers that don't need /// to be written, e.g., for inline or anonymous namespaces. bool SuppressUnwrittenScope : 1; - /// \brief Suppress printing of variable initializers. + /// Suppress printing of variable initializers. /// /// This flag is used when printing the loop variable in a for-range /// statement. For example, given: @@ -122,8 +122,8 @@ struct PrintingPolicy { /// internal initializer constructed for x will not be printed. bool SuppressInitializers : 1; - /// \brief Whether we should print the sizes of constant array expressions - /// as written in the sources. + /// Whether we should print the sizes of constant array expressions as written + /// in the sources. /// /// This flag determines whether array types declared as /// @@ -140,69 +140,67 @@ struct PrintingPolicy { /// \endcode bool ConstantArraySizeAsWritten : 1; - /// \brief When printing an anonymous tag name, also print the location of - /// that entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just - /// prints "(anonymous)" for the name. + /// When printing an anonymous tag name, also print the location of that + /// entity (e.g., "enum <anonymous at t.h:10:5>"). Otherwise, just prints + /// "(anonymous)" for the name. bool AnonymousTagLocations : 1; - /// \brief When true, suppress printing of the __strong lifetime qualifier in - /// ARC. + /// When true, suppress printing of the __strong lifetime qualifier in ARC. unsigned SuppressStrongLifetime : 1; - /// \brief When true, suppress printing of lifetime qualifier in - /// ARC. + /// When true, suppress printing of lifetime qualifier in ARC. unsigned SuppressLifetimeQualifiers : 1; /// When true, suppresses printing template arguments in names of C++ /// constructors. unsigned SuppressTemplateArgsInCXXConstructors : 1; - /// \brief Whether we can use 'bool' rather than '_Bool' (even if the language + /// Whether we can use 'bool' rather than '_Bool' (even if the language /// doesn't actually have 'bool', because, e.g., it is defined as a macro). unsigned Bool : 1; - /// \brief Whether we can use 'restrict' rather than '__restrict'. + /// Whether we can use 'restrict' rather than '__restrict'. unsigned Restrict : 1; - /// \brief Whether we can use 'alignof' rather than '__alignof'. + /// Whether we can use 'alignof' rather than '__alignof'. unsigned Alignof : 1; - /// \brief Whether we can use '_Alignof' rather than '__alignof'. + /// Whether we can use '_Alignof' rather than '__alignof'. unsigned UnderscoreAlignof : 1; - /// \brief Whether we should use '(void)' rather than '()' for a function - /// prototype with zero parameters. + /// Whether we should use '(void)' rather than '()' for a function prototype + /// with zero parameters. unsigned UseVoidForZeroParams : 1; - /// \brief Provide a 'terse' output. + /// Provide a 'terse' output. /// /// For example, in this mode we don't print function bodies, class members, /// declarations inside namespaces etc. Effectively, this should print /// only the requested declaration. unsigned TerseOutput : 1; - /// \brief When true, do certain refinement needed for producing proper - /// declaration tag; such as, do not print attributes attached to the declaration. + /// When true, do certain refinement needed for producing proper declaration + /// tag; such as, do not print attributes attached to the declaration. /// unsigned PolishForDeclaration : 1; - /// \brief When true, print the half-precision floating-point type as 'half' + /// When true, print the half-precision floating-point type as 'half' /// instead of '__fp16' unsigned Half : 1; - /// \brief When true, print the built-in wchar_t type as __wchar_t. For use in + /// When true, print the built-in wchar_t type as __wchar_t. For use in /// Microsoft mode when wchar_t is not available. unsigned MSWChar : 1; - /// \brief When true, include newlines after statements like "break", etc. + /// When true, include newlines after statements like "break", etc. unsigned IncludeNewlines : 1; - /// \brief Use whitespace and punctuation like MSVC does. In particular, this - /// prints anonymous namespaces as `anonymous namespace' and does not insert - /// spaces after template arguments. + /// Use whitespace and punctuation like MSVC does. In particular, this prints + /// anonymous namespaces as `anonymous namespace' and does not insert spaces + /// after template arguments. bool MSVCFormatting : 1; - /// \brief Whether we should print the constant expressions as written in the + /// Whether we should print the constant expressions as written in the /// sources. /// /// This flag determines whether constants expressions like @@ -220,7 +218,7 @@ struct PrintingPolicy { /// \endcode bool ConstantsAsWritten : 1; - /// \brief When true, don't print the implicit 'self' or 'this' expressions. + /// When true, don't print the implicit 'self' or 'this' expressions. bool SuppressImplicitBase : 1; }; diff --git a/include/clang/Tooling/Core/QualTypeNames.h b/include/clang/AST/QualTypeNames.h index 7248356e74..86d805feee 100644 --- a/include/clang/Tooling/Core/QualTypeNames.h +++ b/include/clang/AST/QualTypeNames.h @@ -56,8 +56,8 @@ // // ===----------------------------------------------------------------------===// -#ifndef LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H -#define LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H +#ifndef LLVM_CLANG_AST_QUALTYPENAMES_H +#define LLVM_CLANG_AST_QUALTYPENAMES_H #include "clang/AST/ASTContext.h" @@ -71,9 +71,20 @@ namespace TypeName { /// \param[in] Ctx - the ASTContext to be used. /// \param[in] WithGlobalNsPrefix - If true, then the global namespace /// specifier "::" will be prepended to the fully qualified name. -std::string getFullyQualifiedName(QualType QT, - const ASTContext &Ctx, +std::string getFullyQualifiedName(QualType QT, const ASTContext &Ctx, bool WithGlobalNsPrefix = false); -} // end namespace TypeName -} // end namespace clang -#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H + +/// \brief Generates a QualType that can be used to name the same type +/// if used at the end of the current translation unit. This ignores +/// issues such as type shadowing. +/// +/// \param[in] QT - the type for which the fully qualified type will be +/// returned. +/// \param[in] Ctx - the ASTContext to be used. +/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace +/// specifier "::" should be prepended or not. +QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, + bool WithGlobalNsPrefix = false); +} // end namespace TypeName +} // end namespace clang +#endif // LLVM_CLANG_TOOLING_CORE_QUALTYPENAMES_H diff --git a/include/clang/Basic/Builtins.def b/include/clang/Basic/Builtins.def index 8e276e8445..34ffd8d813 100644 --- a/include/clang/Basic/Builtins.def +++ b/include/clang/Basic/Builtins.def @@ -103,9 +103,9 @@ #endif // Standard libc/libm functions: -BUILTIN(__builtin_atan2 , "ddd" , "Fnc") -BUILTIN(__builtin_atan2f, "fff" , "Fnc") -BUILTIN(__builtin_atan2l, "LdLdLd", "Fnc") +BUILTIN(__builtin_atan2 , "ddd" , "Fne") +BUILTIN(__builtin_atan2f, "fff" , "Fne") +BUILTIN(__builtin_atan2l, "LdLdLd", "Fne") BUILTIN(__builtin_abs , "ii" , "ncF") BUILTIN(__builtin_copysign, "ddd", "ncF") BUILTIN(__builtin_copysignf, "fff", "ncF") @@ -113,9 +113,9 @@ BUILTIN(__builtin_copysignl, "LdLdLd", "ncF") BUILTIN(__builtin_fabs , "dd" , "ncF") BUILTIN(__builtin_fabsf, "ff" , "ncF") BUILTIN(__builtin_fabsl, "LdLd", "ncF") -BUILTIN(__builtin_fmod , "ddd" , "Fnc") -BUILTIN(__builtin_fmodf, "fff" , "Fnc") -BUILTIN(__builtin_fmodl, "LdLdLd", "Fnc") +BUILTIN(__builtin_fmod , "ddd" , "Fne") +BUILTIN(__builtin_fmodf, "fff" , "Fne") +BUILTIN(__builtin_fmodl, "LdLdLd", "Fne") BUILTIN(__builtin_frexp , "ddi*" , "Fn") BUILTIN(__builtin_frexpf, "ffi*" , "Fn") BUILTIN(__builtin_frexpl, "LdLdi*", "Fn") @@ -127,9 +127,9 @@ BUILTIN(__builtin_inff , "f" , "nc") BUILTIN(__builtin_infl , "Ld" , "nc") BUILTIN(__builtin_labs , "LiLi" , "Fnc") BUILTIN(__builtin_llabs, "LLiLLi", "Fnc") -BUILTIN(__builtin_ldexp , "ddi" , "Fnc") -BUILTIN(__builtin_ldexpf, "ffi" , "Fnc") -BUILTIN(__builtin_ldexpl, "LdLdi", "Fnc") +BUILTIN(__builtin_ldexp , "ddi" , "Fne") +BUILTIN(__builtin_ldexpf, "ffi" , "Fne") +BUILTIN(__builtin_ldexpl, "LdLdi", "Fne") BUILTIN(__builtin_modf , "ddd*" , "Fn") BUILTIN(__builtin_modff, "fff*" , "Fn") BUILTIN(__builtin_modfl, "LdLdLd*", "Fn") @@ -142,119 +142,119 @@ BUILTIN(__builtin_nansl, "LdcC*", "ncF") BUILTIN(__builtin_powi , "ddi" , "Fnc") BUILTIN(__builtin_powif, "ffi" , "Fnc") BUILTIN(__builtin_powil, "LdLdi", "Fnc") -BUILTIN(__builtin_pow , "ddd" , "Fnc") -BUILTIN(__builtin_powf, "fff" , "Fnc") -BUILTIN(__builtin_powl, "LdLdLd", "Fnc") +BUILTIN(__builtin_pow , "ddd" , "Fne") +BUILTIN(__builtin_powf, "fff" , "Fne") +BUILTIN(__builtin_powl, "LdLdLd", "Fne") // Standard unary libc/libm functions with double/float/long double variants: -BUILTIN(__builtin_acos , "dd" , "Fnc") -BUILTIN(__builtin_acosf, "ff" , "Fnc") -BUILTIN(__builtin_acosl, "LdLd", "Fnc") -BUILTIN(__builtin_acosh , "dd" , "Fnc") -BUILTIN(__builtin_acoshf, "ff" , "Fnc") -BUILTIN(__builtin_acoshl, "LdLd", "Fnc") -BUILTIN(__builtin_asin , "dd" , "Fnc") -BUILTIN(__builtin_asinf, "ff" , "Fnc") -BUILTIN(__builtin_asinl, "LdLd", "Fnc") -BUILTIN(__builtin_asinh , "dd" , "Fnc") -BUILTIN(__builtin_asinhf, "ff" , "Fnc") -BUILTIN(__builtin_asinhl, "LdLd", "Fnc") -BUILTIN(__builtin_atan , "dd" , "Fnc") -BUILTIN(__builtin_atanf, "ff" , "Fnc") -BUILTIN(__builtin_atanl, "LdLd", "Fnc") -BUILTIN(__builtin_atanh , "dd", "Fnc") -BUILTIN(__builtin_atanhf, "ff", "Fnc") -BUILTIN(__builtin_atanhl, "LdLd", "Fnc") -BUILTIN(__builtin_cbrt , "dd", "Fnc") -BUILTIN(__builtin_cbrtf, "ff", "Fnc") -BUILTIN(__builtin_cbrtl, "LdLd", "Fnc") +BUILTIN(__builtin_acos , "dd" , "Fne") +BUILTIN(__builtin_acosf, "ff" , "Fne") +BUILTIN(__builtin_acosl, "LdLd", "Fne") +BUILTIN(__builtin_acosh , "dd" , "Fne") +BUILTIN(__builtin_acoshf, "ff" , "Fne") +BUILTIN(__builtin_acoshl, "LdLd", "Fne") +BUILTIN(__builtin_asin , "dd" , "Fne") +BUILTIN(__builtin_asinf, "ff" , "Fne") +BUILTIN(__builtin_asinl, "LdLd", "Fne") +BUILTIN(__builtin_asinh , "dd" , "Fne") +BUILTIN(__builtin_asinhf, "ff" , "Fne") +BUILTIN(__builtin_asinhl, "LdLd", "Fne") +BUILTIN(__builtin_atan , "dd" , "Fne") +BUILTIN(__builtin_atanf, "ff" , "Fne") +BUILTIN(__builtin_atanl, "LdLd", "Fne") +BUILTIN(__builtin_atanh , "dd", "Fne") +BUILTIN(__builtin_atanhf, "ff", "Fne") +BUILTIN(__builtin_atanhl, "LdLd", "Fne") +BUILTIN(__builtin_cbrt , "dd", "Fne") +BUILTIN(__builtin_cbrtf, "ff", "Fne") +BUILTIN(__builtin_cbrtl, "LdLd", "Fne") BUILTIN(__builtin_ceil , "dd" , "Fnc") BUILTIN(__builtin_ceilf, "ff" , "Fnc") BUILTIN(__builtin_ceill, "LdLd", "Fnc") -BUILTIN(__builtin_cos , "dd" , "Fnc") -BUILTIN(__builtin_cosf, "ff" , "Fnc") -BUILTIN(__builtin_cosh , "dd" , "Fnc") -BUILTIN(__builtin_coshf, "ff" , "Fnc") -BUILTIN(__builtin_coshl, "LdLd", "Fnc") -BUILTIN(__builtin_cosl, "LdLd", "Fnc") -BUILTIN(__builtin_erf , "dd", "Fnc") -BUILTIN(__builtin_erff, "ff", "Fnc") -BUILTIN(__builtin_erfl, "LdLd", "Fnc") -BUILTIN(__builtin_erfc , "dd", "Fnc") -BUILTIN(__builtin_erfcf, "ff", "Fnc") -BUILTIN(__builtin_erfcl, "LdLd", "Fnc") -BUILTIN(__builtin_exp , "dd" , "Fnc") -BUILTIN(__builtin_expf, "ff" , "Fnc") -BUILTIN(__builtin_expl, "LdLd", "Fnc") -BUILTIN(__builtin_exp2 , "dd" , "Fnc") -BUILTIN(__builtin_exp2f, "ff" , "Fnc") -BUILTIN(__builtin_exp2l, "LdLd", "Fnc") -BUILTIN(__builtin_expm1 , "dd", "Fnc") -BUILTIN(__builtin_expm1f, "ff", "Fnc") -BUILTIN(__builtin_expm1l, "LdLd", "Fnc") -BUILTIN(__builtin_fdim, "ddd", "Fnc") -BUILTIN(__builtin_fdimf, "fff", "Fnc") -BUILTIN(__builtin_fdiml, "LdLdLd", "Fnc") +BUILTIN(__builtin_cos , "dd" , "Fne") +BUILTIN(__builtin_cosf, "ff" , "Fne") +BUILTIN(__builtin_cosh , "dd" , "Fne") +BUILTIN(__builtin_coshf, "ff" , "Fne") +BUILTIN(__builtin_coshl, "LdLd", "Fne") +BUILTIN(__builtin_cosl, "LdLd", "Fne") +BUILTIN(__builtin_erf , "dd", "Fne") +BUILTIN(__builtin_erff, "ff", "Fne") +BUILTIN(__builtin_erfl, "LdLd", "Fne") +BUILTIN(__builtin_erfc , "dd", "Fne") +BUILTIN(__builtin_erfcf, "ff", "Fne") +BUILTIN(__builtin_erfcl, "LdLd", "Fne") +BUILTIN(__builtin_exp , "dd" , "Fne") +BUILTIN(__builtin_expf, "ff" , "Fne") +BUILTIN(__builtin_expl, "LdLd", "Fne") +BUILTIN(__builtin_exp2 , "dd" , "Fne") +BUILTIN(__builtin_exp2f, "ff" , "Fne") +BUILTIN(__builtin_exp2l, "LdLd", "Fne") +BUILTIN(__builtin_expm1 , "dd", "Fne") +BUILTIN(__builtin_expm1f, "ff", "Fne") +BUILTIN(__builtin_expm1l, "LdLd", "Fne") +BUILTIN(__builtin_fdim, "ddd", "Fne") +BUILTIN(__builtin_fdimf, "fff", "Fne") +BUILTIN(__builtin_fdiml, "LdLdLd", "Fne") BUILTIN(__builtin_floor , "dd" , "Fnc") BUILTIN(__builtin_floorf, "ff" , "Fnc") BUILTIN(__builtin_floorl, "LdLd", "Fnc") -BUILTIN(__builtin_fma, "dddd", "Fnc") -BUILTIN(__builtin_fmaf, "ffff", "Fnc") -BUILTIN(__builtin_fmal, "LdLdLdLd", "Fnc") +BUILTIN(__builtin_fma, "dddd", "Fne") +BUILTIN(__builtin_fmaf, "ffff", "Fne") +BUILTIN(__builtin_fmal, "LdLdLdLd", "Fne") BUILTIN(__builtin_fmax, "ddd", "Fnc") BUILTIN(__builtin_fmaxf, "fff", "Fnc") BUILTIN(__builtin_fmaxl, "LdLdLd", "Fnc") BUILTIN(__builtin_fmin, "ddd", "Fnc") BUILTIN(__builtin_fminf, "fff", "Fnc") BUILTIN(__builtin_fminl, "LdLdLd", "Fnc") -BUILTIN(__builtin_hypot , "ddd" , "Fnc") -BUILTIN(__builtin_hypotf, "fff" , "Fnc") -BUILTIN(__builtin_hypotl, "LdLdLd", "Fnc") -BUILTIN(__builtin_ilogb , "id", "Fnc") -BUILTIN(__builtin_ilogbf, "if", "Fnc") -BUILTIN(__builtin_ilogbl, "iLd", "Fnc") -BUILTIN(__builtin_lgamma , "dd", "Fnc") -BUILTIN(__builtin_lgammaf, "ff", "Fnc") -BUILTIN(__builtin_lgammal, "LdLd", "Fnc") -BUILTIN(__builtin_llrint, "LLid", "Fnc") -BUILTIN(__builtin_llrintf, "LLif", "Fnc") -BUILTIN(__builtin_llrintl, "LLiLd", "Fnc") -BUILTIN(__builtin_llround , "LLid", "Fnc") -BUILTIN(__builtin_llroundf, "LLif", "Fnc") -BUILTIN(__builtin_llroundl, "LLiLd", "Fnc") -BUILTIN(__builtin_log , "dd" , "Fnc") -BUILTIN(__builtin_log10 , "dd" , "Fnc") -BUILTIN(__builtin_log10f, "ff" , "Fnc") -BUILTIN(__builtin_log10l, "LdLd", "Fnc") -BUILTIN(__builtin_log1p , "dd" , "Fnc") -BUILTIN(__builtin_log1pf, "ff" , "Fnc") -BUILTIN(__builtin_log1pl, "LdLd", "Fnc") -BUILTIN(__builtin_log2, "dd" , "Fnc") -BUILTIN(__builtin_log2f, "ff" , "Fnc") -BUILTIN(__builtin_log2l, "LdLd" , "Fnc") -BUILTIN(__builtin_logb , "dd", "Fnc") -BUILTIN(__builtin_logbf, "ff", "Fnc") -BUILTIN(__builtin_logbl, "LdLd", "Fnc") -BUILTIN(__builtin_logf, "ff" , "Fnc") -BUILTIN(__builtin_logl, "LdLd", "Fnc") -BUILTIN(__builtin_lrint , "Lid", "Fnc") -BUILTIN(__builtin_lrintf, "Lif", "Fnc") -BUILTIN(__builtin_lrintl, "LiLd", "Fnc") -BUILTIN(__builtin_lround , "Lid", "Fnc") -BUILTIN(__builtin_lroundf, "Lif", "Fnc") -BUILTIN(__builtin_lroundl, "LiLd", "Fnc") +BUILTIN(__builtin_hypot , "ddd" , "Fne") +BUILTIN(__builtin_hypotf, "fff" , "Fne") +BUILTIN(__builtin_hypotl, "LdLdLd", "Fne") +BUILTIN(__builtin_ilogb , "id", "Fne") +BUILTIN(__builtin_ilogbf, "if", "Fne") +BUILTIN(__builtin_ilogbl, "iLd", "Fne") +BUILTIN(__builtin_lgamma , "dd", "Fn") +BUILTIN(__builtin_lgammaf, "ff", "Fn") +BUILTIN(__builtin_lgammal, "LdLd", "Fn") +BUILTIN(__builtin_llrint, "LLid", "Fne") +BUILTIN(__builtin_llrintf, "LLif", "Fne") +BUILTIN(__builtin_llrintl, "LLiLd", "Fne") +BUILTIN(__builtin_llround , "LLid", "Fne") +BUILTIN(__builtin_llroundf, "LLif", "Fne") +BUILTIN(__builtin_llroundl, "LLiLd", "Fne") +BUILTIN(__builtin_log , "dd" , "Fne") +BUILTIN(__builtin_log10 , "dd" , "Fne") +BUILTIN(__builtin_log10f, "ff" , "Fne") +BUILTIN(__builtin_log10l, "LdLd", "Fne") +BUILTIN(__builtin_log1p , "dd" , "Fne") +BUILTIN(__builtin_log1pf, "ff" , "Fne") +BUILTIN(__builtin_log1pl, "LdLd", "Fne") +BUILTIN(__builtin_log2, "dd" , "Fne") +BUILTIN(__builtin_log2f, "ff" , "Fne") +BUILTIN(__builtin_log2l, "LdLd" , "Fne") +BUILTIN(__builtin_logb , "dd", "Fne") +BUILTIN(__builtin_logbf, "ff", "Fne") +BUILTIN(__builtin_logbl, "LdLd", "Fne") +BUILTIN(__builtin_logf, "ff" , "Fne") +BUILTIN(__builtin_logl, "LdLd", "Fne") +BUILTIN(__builtin_lrint , "Lid", "Fne") +BUILTIN(__builtin_lrintf, "Lif", "Fne") +BUILTIN(__builtin_lrintl, "LiLd", "Fne") +BUILTIN(__builtin_lround , "Lid", "Fne") +BUILTIN(__builtin_lroundf, "Lif", "Fne") +BUILTIN(__builtin_lroundl, "LiLd", "Fne") BUILTIN(__builtin_nearbyint , "dd", "Fnc") BUILTIN(__builtin_nearbyintf, "ff", "Fnc") BUILTIN(__builtin_nearbyintl, "LdLd", "Fnc") -BUILTIN(__builtin_nextafter , "ddd", "Fnc") -BUILTIN(__builtin_nextafterf, "fff", "Fnc") -BUILTIN(__builtin_nextafterl, "LdLdLd", "Fnc") -BUILTIN(__builtin_nexttoward , "ddLd", "Fnc") -BUILTIN(__builtin_nexttowardf, "ffLd", "Fnc") -BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fnc") -BUILTIN(__builtin_remainder , "ddd", "Fnc") -BUILTIN(__builtin_remainderf, "fff", "Fnc") -BUILTIN(__builtin_remainderl, "LdLdLd", "Fnc") +BUILTIN(__builtin_nextafter , "ddd", "Fne") +BUILTIN(__builtin_nextafterf, "fff", "Fne") +BUILTIN(__builtin_nextafterl, "LdLdLd", "Fne") +BUILTIN(__builtin_nexttoward , "ddLd", "Fne") +BUILTIN(__builtin_nexttowardf, "ffLd", "Fne") +BUILTIN(__builtin_nexttowardl, "LdLdLd", "Fne") +BUILTIN(__builtin_remainder , "ddd", "Fne") +BUILTIN(__builtin_remainderf, "fff", "Fne") +BUILTIN(__builtin_remainderl, "LdLdLd", "Fne") BUILTIN(__builtin_remquo , "dddi*", "Fn") BUILTIN(__builtin_remquof, "fffi*", "Fn") BUILTIN(__builtin_remquol, "LdLdLdi*", "Fn") @@ -264,30 +264,30 @@ BUILTIN(__builtin_rintl, "LdLd", "Fnc") BUILTIN(__builtin_round, "dd" , "Fnc") BUILTIN(__builtin_roundf, "ff" , "Fnc") BUILTIN(__builtin_roundl, "LdLd" , "Fnc") -BUILTIN(__builtin_scalbln , "ddLi", "Fnc") -BUILTIN(__builtin_scalblnf, "ffLi", "Fnc") -BUILTIN(__builtin_scalblnl, "LdLdLi", "Fnc") -BUILTIN(__builtin_scalbn , "ddi", "Fnc") -BUILTIN(__builtin_scalbnf, "ffi", "Fnc") -BUILTIN(__builtin_scalbnl, "LdLdi", "Fnc") -BUILTIN(__builtin_sin , "dd" , "Fnc") -BUILTIN(__builtin_sinf, "ff" , "Fnc") -BUILTIN(__builtin_sinh , "dd" , "Fnc") -BUILTIN(__builtin_sinhf, "ff" , "Fnc") -BUILTIN(__builtin_sinhl, "LdLd", "Fnc") -BUILTIN(__builtin_sinl, "LdLd", "Fnc") -BUILTIN(__builtin_sqrt , "dd" , "Fnc") -BUILTIN(__builtin_sqrtf, "ff" , "Fnc") -BUILTIN(__builtin_sqrtl, "LdLd", "Fnc") -BUILTIN(__builtin_tan , "dd" , "Fnc") -BUILTIN(__builtin_tanf, "ff" , "Fnc") -BUILTIN(__builtin_tanh , "dd" , "Fnc") -BUILTIN(__builtin_tanhf, "ff" , "Fnc") -BUILTIN(__builtin_tanhl, "LdLd", "Fnc") -BUILTIN(__builtin_tanl, "LdLd", "Fnc") -BUILTIN(__builtin_tgamma , "dd", "Fnc") -BUILTIN(__builtin_tgammaf, "ff", "Fnc") -BUILTIN(__builtin_tgammal, "LdLd", "Fnc") +BUILTIN(__builtin_scalbln , "ddLi", "Fne") +BUILTIN(__builtin_scalblnf, "ffLi", "Fne") +BUILTIN(__builtin_scalblnl, "LdLdLi", "Fne") +BUILTIN(__builtin_scalbn , "ddi", "Fne") +BUILTIN(__builtin_scalbnf, "ffi", "Fne") +BUILTIN(__builtin_scalbnl, "LdLdi", "Fne") +BUILTIN(__builtin_sin , "dd" , "Fne") +BUILTIN(__builtin_sinf, "ff" , "Fne") +BUILTIN(__builtin_sinh , "dd" , "Fne") +BUILTIN(__builtin_sinhf, "ff" , "Fne") +BUILTIN(__builtin_sinhl, "LdLd", "Fne") +BUILTIN(__builtin_sinl, "LdLd", "Fne") +BUILTIN(__builtin_sqrt , "dd" , "Fne") +BUILTIN(__builtin_sqrtf, "ff" , "Fne") +BUILTIN(__builtin_sqrtl, "LdLd", "Fne") +BUILTIN(__builtin_tan , "dd" , "Fne") +BUILTIN(__builtin_tanf, "ff" , "Fne") +BUILTIN(__builtin_tanh , "dd" , "Fne") +BUILTIN(__builtin_tanhf, "ff" , "Fne") +BUILTIN(__builtin_tanhl, "LdLd", "Fne") +BUILTIN(__builtin_tanl, "LdLd", "Fne") +BUILTIN(__builtin_tgamma , "dd", "Fne") +BUILTIN(__builtin_tgammaf, "ff", "Fne") +BUILTIN(__builtin_tgammal, "LdLd", "Fne") BUILTIN(__builtin_trunc , "dd", "Fnc") BUILTIN(__builtin_truncf, "ff", "Fnc") BUILTIN(__builtin_truncl, "LdLd", "Fnc") @@ -1162,6 +1162,10 @@ LIBBUILTIN(remainder, "ddd", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(remainderf, "fff", "fne", "math.h", ALL_LANGUAGES) LIBBUILTIN(remainderl, "LdLdLd", "fne", "math.h", ALL_LANGUAGES) +LIBBUILTIN(remquo, "dddi*", "fn", "math.h", ALL_LANGUAGES) +LIBBUILTIN(remquof, "fffi*", "fn", "math.h", ALL_LANGUAGES) +LIBBUILTIN(remquol, "LdLdLdi*", "fn", "math.h", ALL_LANGUAGES) + LIBBUILTIN(rint, "dd", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(rintf, "ff", "fnc", "math.h", ALL_LANGUAGES) LIBBUILTIN(rintl, "LdLd", "fnc", "math.h", ALL_LANGUAGES) diff --git a/include/clang/Basic/BuiltinsNVPTX.def b/include/clang/Basic/BuiltinsNVPTX.def index caa860480f..b596793c9c 100644 --- a/include/clang/Basic/BuiltinsNVPTX.def +++ b/include/clang/Basic/BuiltinsNVPTX.def @@ -481,7 +481,7 @@ TARGET_BUILTIN(__nvvm_atom_cta_add_gen_f, "ffD*f", "n", "satom") TARGET_BUILTIN(__nvvm_atom_sys_add_gen_f, "ffD*f", "n", "satom") BUILTIN(__nvvm_atom_add_g_d, "ddD*1d", "n") BUILTIN(__nvvm_atom_add_s_d, "ddD*3d", "n") -BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n") +TARGET_BUILTIN(__nvvm_atom_add_gen_d, "ddD*d", "n", "satom") TARGET_BUILTIN(__nvvm_atom_cta_add_gen_d, "ddD*d", "n", "satom") TARGET_BUILTIN(__nvvm_atom_sys_add_gen_d, "ddD*d", "n", "satom") diff --git a/include/clang/Basic/BuiltinsX86.def b/include/clang/Basic/BuiltinsX86.def index d57ea8f119..6a897b3942 100644 --- a/include/clang/Basic/BuiltinsX86.def +++ b/include/clang/Basic/BuiltinsX86.def @@ -910,39 +910,10 @@ TARGET_BUILTIN(__builtin_ia32_cvttps2dq512_mask, "V16iV16fV16iUsIi", "", "avx512 TARGET_BUILTIN(__builtin_ia32_cvttps2udq512_mask, "V16iV16fV16iUsIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvttpd2dq512_mask, "V8iV8dV8iUcIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_cvttpd2udq512_mask, "V8iV8dV8iUcIi", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f") +TARGET_BUILTIN(__builtin_ia32_cmpps512_mask, "UsV16fV16fIiUsIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmpps256_mask, "UcV8fV8fIiUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cmpps128_mask, "UcV4fV4fIiUc", "", "avx512vl") - -TARGET_BUILTIN(__builtin_ia32_pcmpeqb512_mask, "LLiV64cV64cLLi", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpeqd512_mask, "sV16iV16is", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pcmpeqq512_mask, "cV8LLiV8LLic", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pcmpeqw512_mask, "iV32sV32si", "", "avx512bw") - -TARGET_BUILTIN(__builtin_ia32_pcmpeqb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpeqd256_mask, "cV8iV8ic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpeqq256_mask, "cV4LLiV4LLic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpeqw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpeqb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpeqd128_mask, "cV4iV4ic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpeqq128_mask, "cV2LLiV2LLic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpeqw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw") - -TARGET_BUILTIN(__builtin_ia32_pcmpgtb512_mask, "LLiV64cV64cLLi", "", "avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpgtd512_mask, "sV16iV16is", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pcmpgtq512_mask, "cV8LLiV8LLic", "", "avx512f") -TARGET_BUILTIN(__builtin_ia32_pcmpgtw512_mask, "iV32sV32si", "", "avx512bw") - -TARGET_BUILTIN(__builtin_ia32_pcmpgtb256_mask, "iV32cV32ci", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpgtd256_mask, "cV8iV8ic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpgtq256_mask, "cV4LLiV4LLic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpgtw256_mask, "sV16sV16ss", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpgtb128_mask, "sV16cV16cs", "", "avx512vl,avx512bw") -TARGET_BUILTIN(__builtin_ia32_pcmpgtd128_mask, "cV4iV4ic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpgtq128_mask, "cV2LLiV2LLic", "", "avx512vl") -TARGET_BUILTIN(__builtin_ia32_pcmpgtw128_mask, "cV8sV8sc", "", "avx512vl,avx512bw") - TARGET_BUILTIN(__builtin_ia32_cmppd512_mask, "UcV8dV8dIiUcIi", "", "avx512f") TARGET_BUILTIN(__builtin_ia32_cmppd256_mask, "UcV4dV4dIiUc", "", "avx512vl") TARGET_BUILTIN(__builtin_ia32_cmppd128_mask, "UcV2dV2dIiUc", "", "avx512vl") @@ -1580,12 +1551,6 @@ TARGET_BUILTIN(__builtin_ia32_cvtmask2q128, "V2LLiUc","","avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtmask2q256, "V4LLiUc","","avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtq2mask128, "UcV2LLi","","avx512dq,avx512vl") TARGET_BUILTIN(__builtin_ia32_cvtq2mask256, "UcV4LLi","","avx512dq,avx512vl") -TARGET_BUILTIN(__builtin_ia32_broadcastmb512, "V8LLiUc","","avx512cd") -TARGET_BUILTIN(__builtin_ia32_broadcastmw512, "V16iUs","","avx512cd") -TARGET_BUILTIN(__builtin_ia32_broadcastmb128, "V2LLiUc","","avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_broadcastmb256, "V4LLiUc","","avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_broadcastmw128, "V4iUs","","avx512cd,avx512vl") -TARGET_BUILTIN(__builtin_ia32_broadcastmw256, "V8iUs","","avx512cd,avx512vl") TARGET_BUILTIN(__builtin_ia32_pmovsdb512_mask, "V16cV16iV16cUs","","avx512f") TARGET_BUILTIN(__builtin_ia32_pmovsdb512mem_mask, "vV16c*V16iUs","","avx512f") TARGET_BUILTIN(__builtin_ia32_pmovswb512mem_mask, "vV32c*V32sUi","","avx512bw") diff --git a/include/clang/Basic/DiagnosticSemaKinds.td b/include/clang/Basic/DiagnosticSemaKinds.td index b8538f92cb..c27b495168 100644 --- a/include/clang/Basic/DiagnosticSemaKinds.td +++ b/include/clang/Basic/DiagnosticSemaKinds.td @@ -2778,7 +2778,7 @@ def err_attribute_weakref_not_global_context : Error< def err_attribute_weakref_without_alias : Error< "weakref declaration of %0 must also have an alias attribute">; def err_alias_not_supported_on_darwin : Error < - "only weak aliases are supported on darwin">; + "aliases are not supported on darwin">; def err_alias_to_undefined : Error< "%select{alias|ifunc}0 must point to a defined %select{variable or |}1function">; def warn_alias_to_weak_alias : Warning< diff --git a/include/clang/Basic/IdentifierTable.h b/include/clang/Basic/IdentifierTable.h index 3938e09890..8e3c15afbf 100644 --- a/include/clang/Basic/IdentifierTable.h +++ b/include/clang/Basic/IdentifierTable.h @@ -1,4 +1,4 @@ -//===--- IdentifierTable.h - Hash table for identifier lookup ---*- C++ -*-===// +//===- IdentifierTable.h - Hash table for identifier lookup -----*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,11 +6,11 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the clang::IdentifierInfo, clang::IdentifierTable, and /// clang::Selector interfaces. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_IDENTIFIERTABLE_H @@ -18,35 +18,29 @@ #include "clang/Basic/LLVM.h" #include "clang/Basic/TokenKinds.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/SmallString.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" #include "llvm/Support/Allocator.h" +#include "llvm/Support/PointerLikeTypeTraits.h" +#include "llvm/Support/type_traits.h" #include <cassert> #include <cstddef> #include <cstdint> #include <cstring> -#include <new> #include <string> #include <utility> -namespace llvm { - - template <typename T> struct DenseMapInfo; - -} // end namespace llvm - namespace clang { - class LangOptions; - class IdentifierInfo; - class IdentifierTable; - class SourceLocation; - class MultiKeywordSelector; // private class used by Selector - class DeclarationName; // AST class that stores declaration names +class IdentifierInfo; +class LangOptions; +class MultiKeywordSelector; +class SourceLocation; - /// \brief A simple pair of identifier info and location. - typedef std::pair<IdentifierInfo*, SourceLocation> IdentifierLocPair; +/// \brief A simple pair of identifier info and location. +using IdentifierLocPair = std::pair<IdentifierInfo *, SourceLocation>; /// One of these records is kept for each identifier that /// is lexed. This contains information about whether the token was \#define'd, @@ -85,8 +79,10 @@ class IdentifierInfo { // keyword. // 29 bit left in 64-bit word. - void *FETokenInfo; // Managed by the language front-end. - llvm::StringMapEntry<IdentifierInfo*> *Entry; + // Managed by the language front-end. + void *FETokenInfo = nullptr; + + llvm::StringMapEntry<IdentifierInfo *> *Entry = nullptr; public: IdentifierInfo(); @@ -104,7 +100,6 @@ public: /// \brief Return the beginning of the actual null-terminated string for this /// identifier. - /// const char *getNameStart() const { if (Entry) return Entry->getKeyData(); // FIXME: This is gross. It would be best not to embed specific details @@ -112,12 +107,12 @@ public: // The 'this' pointer really points to a // std::pair<IdentifierInfo, const char*>, where internal pointer // points to the external string data. - typedef std::pair<IdentifierInfo, const char*> actualtype; + using actualtype = std::pair<IdentifierInfo, const char *>; + return ((const actualtype*) this)->second; } /// \brief Efficiently return the length of this identifier info. - /// unsigned getLength() const { if (Entry) return Entry->getKeyLength(); // FIXME: This is gross. It would be best not to embed specific details @@ -125,7 +120,8 @@ public: // The 'this' pointer really points to a // std::pair<IdentifierInfo, const char*>, where internal pointer // points to the external string data. - typedef std::pair<IdentifierInfo, const char*> actualtype; + using actualtype = std::pair<IdentifierInfo, const char *>; + const char* p = ((const actualtype*) this)->second - 2; return (((unsigned) p[0]) | (((unsigned) p[1]) << 8)) - 1; } @@ -465,7 +461,7 @@ public: class IdentifierTable { // Shark shows that using MallocAllocator is *much* slower than using this // BumpPtrAllocator! - typedef llvm::StringMap<IdentifierInfo*, llvm::BumpPtrAllocator> HashTableTy; + using HashTableTy = llvm::StringMap<IdentifierInfo *, llvm::BumpPtrAllocator>; HashTableTy HashTable; IdentifierInfoLookup* ExternalLookup; @@ -551,8 +547,8 @@ public: return *II; } - typedef HashTableTy::const_iterator iterator; - typedef HashTableTy::const_iterator const_iterator; + using iterator = HashTableTy::const_iterator; + using const_iterator = HashTableTy::const_iterator; iterator begin() const { return HashTable.begin(); } iterator end() const { return HashTable.end(); } @@ -654,7 +650,9 @@ class Selector { MultiArg = 0x3, ArgFlags = ZeroArg|OneArg }; - uintptr_t InfoPtr; // a pointer to the MultiKeywordSelector or IdentifierInfo. + + // a pointer to the MultiKeywordSelector or IdentifierInfo. + uintptr_t InfoPtr = 0; Selector(IdentifierInfo *II, unsigned nArgs) { InfoPtr = reinterpret_cast<uintptr_t>(II); @@ -662,6 +660,7 @@ class Selector { assert(nArgs < 2 && "nArgs not equal to 0/1"); InfoPtr |= nArgs+1; } + Selector(MultiKeywordSelector *SI) { InfoPtr = reinterpret_cast<uintptr_t>(SI); assert((InfoPtr & ArgFlags) == 0 &&"Insufficiently aligned IdentifierInfo"); @@ -692,7 +691,7 @@ public: /// The default ctor should only be used when creating data structures that /// will contain selectors. - Selector() : InfoPtr(0) {} + Selector() = default; Selector(uintptr_t V) : InfoPtr(V) {} /// operator==/!= - Indicate whether the specified selectors are identical. @@ -776,7 +775,8 @@ public: /// \brief This table allows us to fully hide how we implement /// multi-keyword caching. class SelectorTable { - void *Impl; // Actually a SelectorTableImpl + // Actually a SelectorTableImpl + void *Impl; public: SelectorTable(); @@ -793,6 +793,7 @@ public: Selector getUnarySelector(IdentifierInfo *ID) { return Selector(ID, 1); } + Selector getNullarySelector(IdentifierInfo *ID) { return Selector(ID, 0); } @@ -848,7 +849,7 @@ public: unsigned ExtraKindOrNumArgs; }; -} // end namespace clang +} // namespace clang namespace llvm { @@ -856,11 +857,11 @@ namespace llvm { /// DenseSets. template <> struct DenseMapInfo<clang::Selector> { - static inline clang::Selector getEmptyKey() { + static clang::Selector getEmptyKey() { return clang::Selector::getEmptyMarker(); } - static inline clang::Selector getTombstoneKey() { + static clang::Selector getTombstoneKey() { return clang::Selector::getTombstoneMarker(); } @@ -874,15 +875,13 @@ struct DenseMapInfo<clang::Selector> { template <> struct isPodLike<clang::Selector> { static const bool value = true; }; -template <typename T> struct PointerLikeTypeTraits; - template<> struct PointerLikeTypeTraits<clang::Selector> { - static inline const void *getAsVoidPointer(clang::Selector P) { + static const void *getAsVoidPointer(clang::Selector P) { return P.getAsOpaquePtr(); } - static inline clang::Selector getFromVoidPointer(const void *P) { + static clang::Selector getFromVoidPointer(const void *P) { return clang::Selector(reinterpret_cast<uintptr_t>(P)); } @@ -893,11 +892,11 @@ struct PointerLikeTypeTraits<clang::Selector> { // are not guaranteed to be 8-byte aligned. template<> struct PointerLikeTypeTraits<clang::IdentifierInfo*> { - static inline void *getAsVoidPointer(clang::IdentifierInfo* P) { + static void *getAsVoidPointer(clang::IdentifierInfo* P) { return P; } - static inline clang::IdentifierInfo *getFromVoidPointer(void *P) { + static clang::IdentifierInfo *getFromVoidPointer(void *P) { return static_cast<clang::IdentifierInfo*>(P); } @@ -906,17 +905,17 @@ struct PointerLikeTypeTraits<clang::IdentifierInfo*> { template<> struct PointerLikeTypeTraits<const clang::IdentifierInfo*> { - static inline const void *getAsVoidPointer(const clang::IdentifierInfo* P) { + static const void *getAsVoidPointer(const clang::IdentifierInfo* P) { return P; } - static inline const clang::IdentifierInfo *getFromVoidPointer(const void *P) { + static const clang::IdentifierInfo *getFromVoidPointer(const void *P) { return static_cast<const clang::IdentifierInfo*>(P); } enum { NumLowBitsAvailable = 1 }; }; -} // end namespace llvm +} // namespace llvm #endif // LLVM_CLANG_BASIC_IDENTIFIERTABLE_H diff --git a/include/clang/Basic/LangOptions.h b/include/clang/Basic/LangOptions.h index 51fb5ad661..f7a43adefa 100644 --- a/include/clang/Basic/LangOptions.h +++ b/include/clang/Basic/LangOptions.h @@ -77,7 +77,8 @@ public: DCC_CDecl, DCC_FastCall, DCC_StdCall, - DCC_VectorCall + DCC_VectorCall, + DCC_RegCall }; enum AddrSpaceMapMangling { ASMM_Target, ASMM_On, ASMM_Off }; diff --git a/include/clang/Basic/Module.h b/include/clang/Basic/Module.h index 0b2a665f05..6631721e35 100644 --- a/include/clang/Basic/Module.h +++ b/include/clang/Basic/Module.h @@ -1,4 +1,4 @@ -//===--- Module.h - Describe a module ---------------------------*- C++ -*-===// +//===- Module.h - Describe a module -----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,12 +6,13 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the clang::Module class, which describes a module in the /// source code. -/// +// //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_BASIC_MODULE_H #define LLVM_CLANG_BASIC_MODULE_H @@ -19,6 +20,7 @@ #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/Optional.h" #include "llvm/ADT/PointerIntPair.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/SetVector.h" @@ -26,22 +28,28 @@ #include "llvm/ADT/STLExtras.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" +#include "llvm/ADT/iterator_range.h" +#include <array> +#include <cassert> +#include <cstdint> +#include <ctime> #include <string> #include <utility> #include <vector> namespace llvm { - class raw_ostream; -} + +class raw_ostream; + +} // namespace llvm namespace clang { class LangOptions; class TargetInfo; -class IdentifierInfo; - + /// \brief Describes the name of a module. -typedef SmallVector<std::pair<std::string, SourceLocation>, 2> ModuleId; +using ModuleId = SmallVector<std::pair<std::string, SourceLocation>, 2>; /// The signature of a module, which is a hash of the AST content. struct ASTFileSignature : std::array<uint32_t, 5> { @@ -85,7 +93,7 @@ public: /// \brief The build directory of this module. This is the directory in /// which the module is notionally built, and relative to which its headers /// are found. - const DirectoryEntry *Directory; + const DirectoryEntry *Directory = nullptr; /// \brief The presumed file name for the module map defining this module. /// Only non-empty when building from preprocessed source. @@ -114,7 +122,7 @@ private: /// \brief The AST file if this is a top-level module which has a /// corresponding serialized AST file, or null otherwise. - const FileEntry *ASTFile; + const FileEntry *ASTFile = nullptr; /// \brief The top-level headers associated with this module. llvm::SmallSetVector<const FileEntry *, 2> TopHeaders; @@ -181,7 +189,7 @@ public: /// \brief An individual requirement: a feature name and a flag indicating /// the required state of that feature. - typedef std::pair<std::string, bool> Requirement; + using Requirement = std::pair<std::string, bool>; /// \brief The set of language features required to use this module. /// @@ -270,7 +278,7 @@ public: /// /// The pointer is the module being re-exported, while the bit will be true /// to indicate that this is a wildcard export. - typedef llvm::PointerIntPair<Module *, 1, bool> ExportDecl; + using ExportDecl = llvm::PointerIntPair<Module *, 1, bool>; /// \brief The set of export declarations. SmallVector<ExportDecl, 2> Exports; @@ -302,9 +310,9 @@ public: /// \brief A library or framework to link against when an entity from this /// module is used. struct LinkLibrary { - LinkLibrary() : IsFramework(false) { } + LinkLibrary() = default; LinkLibrary(const std::string &Library, bool IsFramework) - : Library(Library), IsFramework(IsFramework) { } + : Library(Library), IsFramework(IsFramework) {} /// \brief The library to link against. /// @@ -313,7 +321,7 @@ public: std::string Library; /// \brief Whether this is a framework rather than a library. - bool IsFramework; + bool IsFramework = false; }; /// \brief The set of libraries or frameworks to link against when @@ -432,7 +440,6 @@ public: const Module *getTopLevelModule() const; /// \brief Retrieve the name of the top-level module. - /// StringRef getTopLevelModuleName() const { return getTopLevelModule()->Name; } @@ -525,8 +532,8 @@ public: unsigned getVisibilityID() const { return VisibilityID; } - typedef std::vector<Module *>::iterator submodule_iterator; - typedef std::vector<Module *>::const_iterator submodule_const_iterator; + using submodule_iterator = std::vector<Module *>::iterator; + using submodule_const_iterator = std::vector<Module *>::const_iterator; submodule_iterator submodule_begin() { return SubModules.begin(); } submodule_const_iterator submodule_begin() const {return SubModules.begin();} @@ -551,7 +558,6 @@ public: } /// \brief Print the module map for this module to the given stream. - /// void print(raw_ostream &OS, unsigned Indent = 0) const; /// \brief Dump the contents of this module to the given output stream. @@ -564,7 +570,7 @@ private: /// \brief A set of visible modules. class VisibleModuleSet { public: - VisibleModuleSet() : Generation(0) {} + VisibleModuleSet() = default; VisibleModuleSet(VisibleModuleSet &&O) : ImportLocs(std::move(O.ImportLocs)), Generation(O.Generation ? 1 : 0) { O.ImportLocs.clear(); @@ -599,13 +605,15 @@ public: /// \brief A callback to call when a module is made visible (directly or /// indirectly) by a call to \ref setVisible. - typedef llvm::function_ref<void(Module *M)> VisibleCallback; + using VisibleCallback = llvm::function_ref<void(Module *M)>; + /// \brief A callback to call when a module conflict is found. \p Path /// consists of a sequence of modules from the conflicting module to the one /// made visible, where each was exported by the next. - typedef llvm::function_ref<void(ArrayRef<Module *> Path, - Module *Conflict, StringRef Message)> - ConflictCallback; + using ConflictCallback = + llvm::function_ref<void(ArrayRef<Module *> Path, Module *Conflict, + StringRef Message)>; + /// \brief Make a specific module visible. void setVisible(Module *M, SourceLocation Loc, VisibleCallback Vis = [](Module *) {}, @@ -616,11 +624,11 @@ private: /// Import locations for each visible module. Indexed by the module's /// VisibilityID. std::vector<SourceLocation> ImportLocs; + /// Visibility generation, bumped every time the visibility state changes. - unsigned Generation; + unsigned Generation = 0; }; -} // end namespace clang - +} // namespace clang #endif // LLVM_CLANG_BASIC_MODULE_H diff --git a/include/clang/Basic/Sanitizers.def b/include/clang/Basic/Sanitizers.def index d6df617172..3586fc228d 100644 --- a/include/clang/Basic/Sanitizers.def +++ b/include/clang/Basic/Sanitizers.def @@ -135,6 +135,9 @@ SANITIZER("efficiency-working-set", EfficiencyWorkingSet) SANITIZER_GROUP("efficiency-all", Efficiency, EfficiencyCacheFrag | EfficiencyWorkingSet) +// Scudo hardened allocator +SANITIZER("scudo", Scudo) + // Magic group, containing all sanitizers. For example, "-fno-sanitize=all" // can be used to disable all the sanitizers. SANITIZER_GROUP("all", All, ~0ULL) diff --git a/include/clang/Basic/SourceManager.h b/include/clang/Basic/SourceManager.h index 16bd5616a6..397ad2e77f 100644 --- a/include/clang/Basic/SourceManager.h +++ b/include/clang/Basic/SourceManager.h @@ -1,4 +1,4 @@ -//===--- SourceManager.h - Track and cache source files ---------*- C++ -*-===// +//===- SourceManager.h - Track and cache source files -----------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,7 +6,7 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines the SourceManager interface. /// @@ -29,14 +29,13 @@ /// location in the source where the macro was originally defined, /// and the presumed location is where the line directive states that /// the line is 17, or any other line. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_SOURCEMANAGER_H #define LLVM_CLANG_BASIC_SOURCEMANAGER_H #include "clang/Basic/FileManager.h" -#include "clang/Basic/LLVM.h" #include "clang/Basic/SourceLocation.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/BitVector.h" @@ -49,10 +48,8 @@ #include "llvm/Support/Allocator.h" #include "llvm/Support/Compiler.h" #include "llvm/Support/MemoryBuffer.h" -#include <algorithm> #include <cassert> #include <cstddef> -#include <cstdint> #include <map> #include <memory> #include <string> @@ -69,7 +66,6 @@ class SourceManager; /// \brief Public enums and private classes that are part of the /// SourceManager implementation. -/// namespace SrcMgr { /// \brief Indicates whether a file or directory holds normal user code, @@ -100,6 +96,7 @@ namespace SrcMgr { enum CCFlags { /// \brief Whether the buffer is invalid. InvalidFlag = 0x01, + /// \brief Whether the buffer should not be freed on destruction. DoNotFreeFlag = 0x02 }; @@ -130,12 +127,12 @@ namespace SrcMgr { /// /// This is lazily computed. This is owned by the SourceManager /// BumpPointerAllocator object. - unsigned *SourceLineCache; + unsigned *SourceLineCache = nullptr; /// \brief The number of lines in this ContentCache. /// /// This is only valid if SourceLineCache is non-null. - unsigned NumLines; + unsigned NumLines = 0; /// \brief Indicates whether the buffer itself was provided to override /// the actual file contents. @@ -157,15 +154,14 @@ namespace SrcMgr { ContentCache(const FileEntry *Ent, const FileEntry *contentEnt) : Buffer(nullptr, false), OrigEntry(Ent), ContentsEntry(contentEnt), - SourceLineCache(nullptr), NumLines(0), BufferOverridden(false), - IsSystemFile(false), IsTransient(false) {} + BufferOverridden(false), IsSystemFile(false), IsTransient(false) {} /// The copy ctor does not allow copies where source object has either /// a non-NULL Buffer or SourceLineCache. Ownership of allocated memory /// is not transferred, so this is a logical error. ContentCache(const ContentCache &RHS) - : Buffer(nullptr, false), SourceLineCache(nullptr), - BufferOverridden(false), IsSystemFile(false), IsTransient(false) { + : Buffer(nullptr, false), BufferOverridden(false), IsSystemFile(false), + IsTransient(false) { OrigEntry = RHS.OrigEntry; ContentsEntry = RHS.ContentsEntry; @@ -246,6 +242,10 @@ namespace SrcMgr { /// FileInfos contain a "ContentCache *", with the contents of the file. /// class FileInfo { + friend class clang::SourceManager; + friend class clang::ASTWriter; + friend class clang::ASTReader; + /// \brief The location of the \#include that brought in this file. /// /// This is an invalid SLOC for the main file (top of the \#include chain). @@ -264,10 +264,6 @@ namespace SrcMgr { llvm::PointerIntPair<const ContentCache*, 3, CharacteristicKind> ContentAndKind; - friend class clang::SourceManager; - friend class clang::ASTWriter; - friend class clang::ASTReader; - public: /// \brief Return a FileInfo object. static FileInfo get(SourceLocation IL, const ContentCache *Con, @@ -448,7 +444,7 @@ namespace SrcMgr { } }; -} // end SrcMgr namespace. +} // namespace SrcMgr /// \brief External source of source location entries. class ExternalSLocEntrySource { @@ -546,7 +542,7 @@ public: /// \brief The stack used when building modules on demand, which is used /// to provide a link between the source managers of the different compiler /// instances. -typedef ArrayRef<std::pair<std::string, FullSourceLoc>> ModuleBuildStack; +using ModuleBuildStack = ArrayRef<std::pair<std::string, FullSourceLoc>>; /// \brief This class handles loading and caching of source files into memory. /// @@ -578,7 +574,7 @@ class SourceManager : public RefCountedBase<SourceManager> { /// \brief True if the ContentCache for files that are overridden by other /// files, should report the original file name. Defaults to true. - bool OverridenFilesKeepOriginalName; + bool OverridenFilesKeepOriginalName = true; /// \brief True if non-system source files should be treated as volatile /// (likely to change while trying to use them). Defaults to false. @@ -587,12 +583,13 @@ class SourceManager : public RefCountedBase<SourceManager> { /// \brief True if all files read during this compilation should be treated /// as transient (may not be present in later compilations using a module /// file created from this compilation). Defaults to false. - bool FilesAreTransient; + bool FilesAreTransient = false; struct OverriddenFilesInfoTy { /// \brief Files that have been overridden with the contents from another /// file. llvm::DenseMap<const FileEntry *, const FileEntry *> OverriddenFiles; + /// \brief Files that were overridden with a memory buffer. llvm::DenseSet<const FileEntry *> OverriddenFilesWithBuffer; }; @@ -647,7 +644,7 @@ class SourceManager : public RefCountedBase<SourceManager> { llvm::BitVector SLocEntryLoaded; /// \brief An external source for source location entries. - ExternalSLocEntrySource *ExternalSLocEntries; + ExternalSLocEntrySource *ExternalSLocEntries = nullptr; /// \brief A one-entry cache to speed up getFileID. /// @@ -658,7 +655,7 @@ class SourceManager : public RefCountedBase<SourceManager> { /// \brief Holds information for \#line directives. /// /// This is referenced by indices from SLocEntryTable. - LineTableInfo *LineTable; + LineTableInfo *LineTable = nullptr; /// \brief These ivars serve as a cache used in the getLineNumber /// method which is used to speedup getLineNumber calls to nearby locations. @@ -674,7 +671,8 @@ class SourceManager : public RefCountedBase<SourceManager> { FileID PreambleFileID; // Statistics for -print-stats. - mutable unsigned NumLinearScans, NumBinaryProbes; + mutable unsigned NumLinearScans = 0; + mutable unsigned NumBinaryProbes = 0; /// \brief Associates a FileID with its "included/expanded in" decomposed /// location. @@ -684,12 +682,12 @@ class SourceManager : public RefCountedBase<SourceManager> { mutable llvm::DenseMap<FileID, std::pair<FileID, unsigned>> IncludedLocMap; /// The key value into the IsBeforeInTUCache table. - typedef std::pair<FileID, FileID> IsBeforeInTUCacheKey; + using IsBeforeInTUCacheKey = std::pair<FileID, FileID>; /// The IsBeforeInTranslationUnitCache is a mapping from FileID pairs /// to cache results. - typedef llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry> - InBeforeInTUCache; + using InBeforeInTUCache = + llvm::DenseMap<IsBeforeInTUCacheKey, InBeforeInTUCacheEntry>; /// Cache results for the isBeforeInTranslationUnit method. mutable InBeforeInTUCache IBTUCache; @@ -706,7 +704,7 @@ class SourceManager : public RefCountedBase<SourceManager> { /// \brief Lazily computed map of macro argument chunks to their expanded /// source location. - typedef std::map<unsigned, SourceLocation> MacroArgsMap; + using MacroArgsMap = std::map<unsigned, SourceLocation>; mutable llvm::DenseMap<FileID, std::unique_ptr<MacroArgsMap>> MacroArgsCacheMap; @@ -1417,7 +1415,6 @@ public: //===--------------------------------------------------------------------===// /// \brief Return the uniqued ID for the specified filename. - /// unsigned getLineTableFilenameID(StringRef Str); /// \brief Add a line note to the line table for the FileID and offset @@ -1538,8 +1535,9 @@ public: } // Iterators over FileInfos. - typedef llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*> - ::const_iterator fileinfo_iterator; + using fileinfo_iterator = + llvm::DenseMap<const FileEntry*, SrcMgr::ContentCache*>::const_iterator; + fileinfo_iterator fileinfo_begin() const { return FileInfos.begin(); } fileinfo_iterator fileinfo_end() const { return FileInfos.end(); } bool hasFileInfo(const FileEntry *File) const { @@ -1547,7 +1545,6 @@ public: } /// \brief Print statistics to stderr. - /// void PrintStats() const; void dump() const; @@ -1638,6 +1635,9 @@ public: } private: + friend class ASTReader; + friend class ASTWriter; + llvm::MemoryBuffer *getFakeBufferForRecovery() const; const SrcMgr::ContentCache *getFakeContentCacheForRecovery() const; @@ -1729,8 +1729,6 @@ private: SourceLocation SpellLoc, SourceLocation ExpansionLoc, unsigned ExpansionLength) const; - friend class ASTReader; - friend class ASTWriter; }; /// \brief Comparison function object. @@ -1743,7 +1741,7 @@ class BeforeThanCompare<SourceLocation> { SourceManager &SM; public: - explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { } + explicit BeforeThanCompare(SourceManager &SM) : SM(SM) {} bool operator()(SourceLocation LHS, SourceLocation RHS) const { return SM.isBeforeInTranslationUnit(LHS, RHS); @@ -1756,13 +1754,13 @@ class BeforeThanCompare<SourceRange> { SourceManager &SM; public: - explicit BeforeThanCompare(SourceManager &SM) : SM(SM) { } + explicit BeforeThanCompare(SourceManager &SM) : SM(SM) {} bool operator()(SourceRange LHS, SourceRange RHS) const { return SM.isBeforeInTranslationUnit(LHS.getBegin(), RHS.getBegin()); } }; -} // end namespace clang +} // namespace clang #endif // LLVM_CLANG_BASIC_SOURCEMANAGER_H diff --git a/include/clang/Basic/SourceManagerInternals.h b/include/clang/Basic/SourceManagerInternals.h index 9403dea888..edd910e704 100644 --- a/include/clang/Basic/SourceManagerInternals.h +++ b/include/clang/Basic/SourceManagerInternals.h @@ -1,4 +1,4 @@ -//===--- SourceManagerInternals.h - SourceManager Internals -----*- C++ -*-===// +//===- SourceManagerInternals.h - SourceManager Internals -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -6,10 +6,10 @@ // License. See LICENSE.TXT for details. // //===----------------------------------------------------------------------===// -/// +// /// \file /// \brief Defines implementation details of the clang::SourceManager class. -/// +// //===----------------------------------------------------------------------===// #ifndef LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H @@ -18,7 +18,11 @@ #include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" +#include <cassert> #include <map> +#include <vector> namespace clang { @@ -86,7 +90,8 @@ class LineTableInfo { /// \brief Map from FileIDs to a list of line entries (sorted by the offset /// at which they occur in the file). - std::map<FileID, std::vector<LineEntry> > LineEntries; + std::map<FileID, std::vector<LineEntry>> LineEntries; + public: void clear() { FilenameIDs.clear(); @@ -95,10 +100,12 @@ public: } unsigned getLineTableFilenameID(StringRef Str); + StringRef getFilename(unsigned ID) const { assert(ID < FilenamesByID.size() && "Invalid FilenameID"); return FilenamesByID[ID]->getKey(); } + unsigned getNumFilenames() const { return FilenamesByID.size(); } void AddLineNote(FileID FID, unsigned Offset, @@ -112,7 +119,8 @@ public: const LineEntry *FindNearestLineEntry(FileID FID, unsigned Offset); // Low-level access - typedef std::map<FileID, std::vector<LineEntry> >::iterator iterator; + using iterator = std::map<FileID, std::vector<LineEntry>>::iterator; + iterator begin() { return LineEntries.begin(); } iterator end() { return LineEntries.end(); } @@ -121,6 +129,6 @@ public: void AddEntry(FileID FID, const std::vector<LineEntry> &Entries); }; -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_BASIC_SOURCEMANAGERINTERNALS_H diff --git a/include/clang/Driver/CC1Options.td b/include/clang/Driver/CC1Options.td index bca51b593a..348a42f4b3 100644 --- a/include/clang/Driver/CC1Options.td +++ b/include/clang/Driver/CC1Options.td @@ -704,7 +704,7 @@ def fnative_half_arguments_and_returns : Flag<["-"], "fnative-half-arguments-and def fallow_half_arguments_and_returns : Flag<["-"], "fallow-half-arguments-and-returns">, HelpText<"Allow function arguments and returns of type half">; def fdefault_calling_conv_EQ : Joined<["-"], "fdefault-calling-conv=">, - HelpText<"Set default MS calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall">; + HelpText<"Set default calling convention">, Values<"cdecl,fastcall,stdcall,vectorcall,regcall">; def finclude_default_header : Flag<["-"], "finclude-default-header">, HelpText<"Include the default header file for OpenCL">; def fpreserve_vec3_type : Flag<["-"], "fpreserve-vec3-type">, diff --git a/include/clang/Driver/CLCompatOptions.td b/include/clang/Driver/CLCompatOptions.td index aebb36ed0e..68a9a8136c 100644 --- a/include/clang/Driver/CLCompatOptions.td +++ b/include/clang/Driver/CLCompatOptions.td @@ -302,6 +302,8 @@ def _SLASH_Gz : CLFlag<"Gz">, HelpText<"Set __stdcall as a default calling convention">; def _SLASH_Gv : CLFlag<"Gv">, HelpText<"Set __vectorcall as a default calling convention">; +def _SLASH_Gregcall : CLFlag<"Gregcall">, + HelpText<"Set __regcall as a default calling convention">; // Ignored: diff --git a/include/clang/Driver/Options.td b/include/clang/Driver/Options.td index e3476c721a..01605619e0 100644 --- a/include/clang/Driver/Options.td +++ b/include/clang/Driver/Options.td @@ -519,7 +519,7 @@ def cl_fp32_correctly_rounded_divide_sqrt : Flag<["-"], "cl-fp32-correctly-round def client__name : JoinedOrSeparate<["-"], "client_name">; def combine : Flag<["-", "--"], "combine">, Flags<[DriverOption, Unsupported]>; def compatibility__version : JoinedOrSeparate<["-"], "compatibility_version">; -def coverage : Flag<["-", "--"], "coverage">; +def coverage : Flag<["-", "--"], "coverage">, Flags<[CoreOption]>; def cpp_precomp : Flag<["-"], "cpp-precomp">, Group<clang_ignored_f_Group>; def current__version : JoinedOrSeparate<["-"], "current_version">; def cxx_isystem : JoinedOrSeparate<["-"], "cxx-isystem">, Group<clang_i_Group>, @@ -1384,6 +1384,10 @@ def fpic : Flag<["-"], "fpic">, Group<f_Group>; def fno_pic : Flag<["-"], "fno-pic">, Group<f_Group>; def fpie : Flag<["-"], "fpie">, Group<f_Group>; def fno_pie : Flag<["-"], "fno-pie">, Group<f_Group>; +def fplt : Flag<["-"], "fplt">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Use the PLT to make function calls">; +def fno_plt : Flag<["-"], "fno-plt">, Group<f_Group>, Flags<[CC1Option]>, + HelpText<"Do not use the PLT to make function calls">; def fropi : Flag<["-"], "fropi">, Group<f_Group>; def fno_ropi : Flag<["-"], "fno-ropi">, Group<f_Group>; def frwpi : Flag<["-"], "frwpi">, Group<f_Group>; diff --git a/include/clang/Driver/SanitizerArgs.h b/include/clang/Driver/SanitizerArgs.h index 19309c3f3b..44083aec16 100644 --- a/include/clang/Driver/SanitizerArgs.h +++ b/include/clang/Driver/SanitizerArgs.h @@ -72,6 +72,7 @@ class SanitizerArgs { bool needsEsanRt() const { return Sanitizers.hasOneOf(SanitizerKind::Efficiency); } + bool needsScudoRt() const { return Sanitizers.has(SanitizerKind::Scudo); } bool requiresPIE() const; bool needsUnwindTables() const; diff --git a/include/clang/Frontend/CodeGenOptions.def b/include/clang/Frontend/CodeGenOptions.def index 8f2aae2f14..b4c68a49bb 100644 --- a/include/clang/Frontend/CodeGenOptions.def +++ b/include/clang/Frontend/CodeGenOptions.def @@ -297,6 +297,8 @@ CODEGENOPT(PreserveVec3Type, 1, 0) /// Whether to emit .debug_gnu_pubnames section instead of .debug_pubnames. CODEGENOPT(GnuPubnames, 1, 0) +CODEGENOPT(NoPLT, 1, 0) + #undef CODEGENOPT #undef ENUM_CODEGENOPT #undef VALUE_CODEGENOPT diff --git a/include/clang/Lex/Lexer.h b/include/clang/Lex/Lexer.h index 603ce10f64..9ad3e21476 100644 --- a/include/clang/Lex/Lexer.h +++ b/include/clang/Lex/Lexer.h @@ -466,6 +466,13 @@ public: const LangOptions &LangOpts, unsigned MaxLines = 0); + /// Finds the token that comes right after the given location. + /// + /// Returns the next token, or none if the location is inside a macro. + static Optional<Token> findNextToken(SourceLocation Loc, + const SourceManager &SM, + const LangOptions &LangOpts); + /// \brief Checks that the given token is the first token that occurs after /// the given location (this excludes comments and whitespace). Returns the /// location immediately after the specified token. If the token is not found diff --git a/include/clang/Lex/Preprocessor.h b/include/clang/Lex/Preprocessor.h index 4f211a3eb6..5e847effdc 100644 --- a/include/clang/Lex/Preprocessor.h +++ b/include/clang/Lex/Preprocessor.h @@ -286,6 +286,23 @@ class Preprocessor { /// This is used when loading a precompiled preamble. std::pair<int, bool> SkipMainFilePreamble; +public: + struct PreambleSkipInfo { + PreambleSkipInfo(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc, + bool FoundNonSkipPortion, bool FoundElse, + SourceLocation ElseLoc) + : HashTokenLoc(HashTokenLoc), IfTokenLoc(IfTokenLoc), + FoundNonSkipPortion(FoundNonSkipPortion), FoundElse(FoundElse), + ElseLoc(ElseLoc) {} + + SourceLocation HashTokenLoc; + SourceLocation IfTokenLoc; + bool FoundNonSkipPortion; + bool FoundElse; + SourceLocation ElseLoc; + }; + +private: class PreambleConditionalStackStore { enum State { Off = 0, @@ -319,6 +336,12 @@ class Preprocessor { bool hasRecordedPreamble() const { return !ConditionalStack.empty(); } + bool reachedEOFWhileSkipping() const { return SkipInfo.hasValue(); } + + void clearSkipInfo() { SkipInfo.reset(); } + + llvm::Optional<PreambleSkipInfo> SkipInfo; + private: SmallVector<PPConditionalInfo, 4> ConditionalStack; State ConditionalStackState; @@ -1839,7 +1862,7 @@ private: /// \p FoundElse is false, then \#else directives are ok, if not, then we have /// already seen one so a \#else directive is a duplicate. When this returns, /// the caller can lex the first valid token. - void SkipExcludedConditionalBlock(const Token &HashToken, + void SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc, bool FoundNonSkipPortion, bool FoundElse, SourceLocation ElseLoc = SourceLocation()); @@ -2019,9 +2042,15 @@ public: PreambleConditionalStack.setStack(s); } - void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s) { + void setReplayablePreambleConditionalStack(ArrayRef<PPConditionalInfo> s, + llvm::Optional<PreambleSkipInfo> SkipInfo) { PreambleConditionalStack.startReplaying(); PreambleConditionalStack.setStack(s); + PreambleConditionalStack.SkipInfo = SkipInfo; + } + + llvm::Optional<PreambleSkipInfo> getPreambleSkipInfo() const { + return PreambleConditionalStack.SkipInfo; } private: diff --git a/include/clang/Serialization/ASTBitCodes.h b/include/clang/Serialization/ASTBitCodes.h index 42c62257ad..34a7bb3301 100644 --- a/include/clang/Serialization/ASTBitCodes.h +++ b/include/clang/Serialization/ASTBitCodes.h @@ -14,17 +14,23 @@ // respective lists. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_SERIALIZATION_ASTBITCODES_H #define LLVM_CLANG_SERIALIZATION_ASTBITCODES_H #include "clang/AST/DeclarationName.h" #include "clang/AST/Type.h" -#include "llvm/ADT/DenseMap.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/SourceLocation.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/Bitcode/BitCodes.h" -#include "llvm/Support/DataTypes.h" +#include <cassert> +#include <cstdint> namespace clang { - namespace serialization { +namespace serialization { + /// \brief AST file major version number supported by this version of /// Clang. /// @@ -52,7 +58,7 @@ namespace clang { /// /// The ID numbers of identifiers are consecutive (in order of discovery) /// and start at 1. 0 is reserved for NULL. - typedef uint32_t IdentifierID; + using IdentifierID = uint32_t; /// \brief An ID number that refers to a declaration in an AST file. /// @@ -60,12 +66,12 @@ namespace clang { /// discovery), with values below NUM_PREDEF_DECL_IDS being reserved. /// At the start of a chain of precompiled headers, declaration ID 1 is /// used for the translation unit declaration. - typedef uint32_t DeclID; + using DeclID = uint32_t; // FIXME: Turn these into classes so we can have some type safety when // we go from local ID to global and vice-versa. - typedef DeclID LocalDeclID; - typedef DeclID GlobalDeclID; + using LocalDeclID = DeclID; + using GlobalDeclID = DeclID; /// \brief An ID number that refers to a type in an AST file. /// @@ -77,22 +83,25 @@ namespace clang { /// IDs (based on the PREDEF_TYPE_*_ID constants), with 0 as a /// placeholder for "no type". Values from NUM_PREDEF_TYPE_IDs are /// other types that have serialized representations. - typedef uint32_t TypeID; + using TypeID = uint32_t; /// \brief A type index; the type ID with the qualifier bits removed. class TypeIdx { - uint32_t Idx; + uint32_t Idx = 0; + public: - TypeIdx() : Idx(0) { } - explicit TypeIdx(uint32_t index) : Idx(index) { } + TypeIdx() = default; + explicit TypeIdx(uint32_t index) : Idx(index) {} uint32_t getIndex() const { return Idx; } + TypeID asTypeID(unsigned FastQuals) const { if (Idx == uint32_t(-1)) return TypeID(-1); return (Idx << Qualifiers::FastWidth) | FastQuals; } + static TypeIdx fromTypeID(TypeID ID) { if (ID == TypeID(-1)) return TypeIdx(-1); @@ -104,14 +113,17 @@ namespace clang { /// A structure for putting "fast"-unqualified QualTypes into a /// DenseMap. This uses the standard pointer hash function. struct UnsafeQualTypeDenseMapInfo { - static inline bool isEqual(QualType A, QualType B) { return A == B; } - static inline QualType getEmptyKey() { + static bool isEqual(QualType A, QualType B) { return A == B; } + + static QualType getEmptyKey() { return QualType::getFromOpaquePtr((void*) 1); } - static inline QualType getTombstoneKey() { + + static QualType getTombstoneKey() { return QualType::getFromOpaquePtr((void*) 2); } - static inline unsigned getHashValue(QualType T) { + + static unsigned getHashValue(QualType T) { assert(!T.getLocalFastQualifiers() && "hash invalid for types with fast quals"); uintptr_t v = reinterpret_cast<uintptr_t>(T.getAsOpaquePtr()); @@ -120,44 +132,44 @@ namespace clang { }; /// \brief An ID number that refers to an identifier in an AST file. - typedef uint32_t IdentID; + using IdentID = uint32_t; /// \brief The number of predefined identifier IDs. const unsigned int NUM_PREDEF_IDENT_IDS = 1; /// \brief An ID number that refers to a macro in an AST file. - typedef uint32_t MacroID; + using MacroID = uint32_t; /// \brief A global ID number that refers to a macro in an AST file. - typedef uint32_t GlobalMacroID; + using GlobalMacroID = uint32_t; /// \brief A local to a module ID number that refers to a macro in an /// AST file. - typedef uint32_t LocalMacroID; + using LocalMacroID = uint32_t; /// \brief The number of predefined macro IDs. const unsigned int NUM_PREDEF_MACRO_IDS = 1; /// \brief An ID number that refers to an ObjC selector in an AST file. - typedef uint32_t SelectorID; + using SelectorID = uint32_t; /// \brief The number of predefined selector IDs. const unsigned int NUM_PREDEF_SELECTOR_IDS = 1; /// \brief An ID number that refers to a set of CXXBaseSpecifiers in an /// AST file. - typedef uint32_t CXXBaseSpecifiersID; + using CXXBaseSpecifiersID = uint32_t; /// \brief An ID number that refers to a list of CXXCtorInitializers in an /// AST file. - typedef uint32_t CXXCtorInitializersID; + using CXXCtorInitializersID = uint32_t; /// \brief An ID number that refers to an entity in the detailed /// preprocessing record. - typedef uint32_t PreprocessedEntityID; + using PreprocessedEntityID = uint32_t; /// \brief An ID number that refers to a submodule in a module file. - typedef uint32_t SubmoduleID; + using SubmoduleID = uint32_t; /// \brief The number of predefined submodule IDs. const unsigned int NUM_PREDEF_SUBMODULE_IDS = 1; @@ -166,18 +178,21 @@ namespace clang { struct PPEntityOffset { /// \brief Raw source location of beginning of range. unsigned Begin; + /// \brief Raw source location of end of range. unsigned End; + /// \brief Offset in the AST file. uint32_t BitOffset; PPEntityOffset(SourceRange R, uint32_t BitOffset) : Begin(R.getBegin().getRawEncoding()), - End(R.getEnd().getRawEncoding()), - BitOffset(BitOffset) { } + End(R.getEnd().getRawEncoding()), BitOffset(BitOffset) {} + SourceLocation getBegin() const { return SourceLocation::getFromRawEncoding(Begin); } + SourceLocation getEnd() const { return SourceLocation::getFromRawEncoding(End); } @@ -186,17 +201,19 @@ namespace clang { /// \brief Source range/offset of a preprocessed entity. struct DeclOffset { /// \brief Raw source location. - unsigned Loc; + unsigned Loc = 0; + /// \brief Offset in the AST file. - uint32_t BitOffset; + uint32_t BitOffset = 0; - DeclOffset() : Loc(0), BitOffset(0) { } + DeclOffset() = default; DeclOffset(SourceLocation Loc, uint32_t BitOffset) - : Loc(Loc.getRawEncoding()), - BitOffset(BitOffset) { } + : Loc(Loc.getRawEncoding()), BitOffset(BitOffset) {} + void setLocation(SourceLocation L) { Loc = L.getRawEncoding(); } + SourceLocation getLocation() const { return SourceLocation::getFromRawEncoding(Loc); } @@ -617,17 +634,21 @@ namespace clang { /// \brief Describes a source location entry (SLocEntry) for a /// file. SM_SLOC_FILE_ENTRY = 1, + /// \brief Describes a source location entry (SLocEntry) for a /// buffer. SM_SLOC_BUFFER_ENTRY = 2, + /// \brief Describes a blob that contains the data for a buffer /// entry. This kind of record always directly follows a /// SM_SLOC_BUFFER_ENTRY record or a SM_SLOC_FILE_ENTRY with an /// overridden buffer. SM_SLOC_BUFFER_BLOB = 3, + /// \brief Describes a zlib-compressed blob that contains the data for /// a buffer entry. SM_SLOC_BUFFER_BLOB_COMPRESSED = 4, + /// \brief Describes a source location entry (SLocEntry) for a /// macro expansion. SM_SLOC_EXPANSION_ENTRY = 5 @@ -676,46 +697,63 @@ namespace clang { enum SubmoduleRecordTypes { /// \brief Metadata for submodules as a whole. SUBMODULE_METADATA = 0, + /// \brief Defines the major attributes of a submodule, including its /// name and parent. SUBMODULE_DEFINITION = 1, + /// \brief Specifies the umbrella header used to create this module, /// if any. SUBMODULE_UMBRELLA_HEADER = 2, + /// \brief Specifies a header that falls into this (sub)module. SUBMODULE_HEADER = 3, + /// \brief Specifies a top-level header that falls into this (sub)module. SUBMODULE_TOPHEADER = 4, + /// \brief Specifies an umbrella directory. SUBMODULE_UMBRELLA_DIR = 5, + /// \brief Specifies the submodules that are imported by this /// submodule. SUBMODULE_IMPORTS = 6, + /// \brief Specifies the submodules that are re-exported from this /// submodule. SUBMODULE_EXPORTS = 7, + /// \brief Specifies a required feature. SUBMODULE_REQUIRES = 8, + /// \brief Specifies a header that has been explicitly excluded /// from this submodule. SUBMODULE_EXCLUDED_HEADER = 9, + /// \brief Specifies a library or framework to link against. SUBMODULE_LINK_LIBRARY = 10, + /// \brief Specifies a configuration macro for this module. SUBMODULE_CONFIG_MACRO = 11, + /// \brief Specifies a conflict with another module. SUBMODULE_CONFLICT = 12, + /// \brief Specifies a header that is private to this submodule. SUBMODULE_PRIVATE_HEADER = 13, + /// \brief Specifies a header that is part of the module but must be /// textually included. SUBMODULE_TEXTUAL_HEADER = 14, + /// \brief Specifies a header that is private to this submodule but /// must be textually included. SUBMODULE_PRIVATE_TEXTUAL_HEADER = 15, + /// \brief Specifies some declarations with initializers that must be /// emitted to initialize the module. SUBMODULE_INITIALIZERS = 16, + /// \brief Specifies the name of the module that will eventually /// re-export the entities in this module. SUBMODULE_EXPORT_AS = 17, @@ -743,94 +781,139 @@ namespace clang { enum PredefinedTypeIDs { /// \brief The NULL type. PREDEF_TYPE_NULL_ID = 0, + /// \brief The void type. PREDEF_TYPE_VOID_ID = 1, + /// \brief The 'bool' or '_Bool' type. PREDEF_TYPE_BOOL_ID = 2, + /// \brief The 'char' type, when it is unsigned. PREDEF_TYPE_CHAR_U_ID = 3, + /// \brief The 'unsigned char' type. PREDEF_TYPE_UCHAR_ID = 4, + /// \brief The 'unsigned short' type. PREDEF_TYPE_USHORT_ID = 5, + /// \brief The 'unsigned int' type. PREDEF_TYPE_UINT_ID = 6, + /// \brief The 'unsigned long' type. PREDEF_TYPE_ULONG_ID = 7, + /// \brief The 'unsigned long long' type. PREDEF_TYPE_ULONGLONG_ID = 8, + /// \brief The 'char' type, when it is signed. PREDEF_TYPE_CHAR_S_ID = 9, + /// \brief The 'signed char' type. PREDEF_TYPE_SCHAR_ID = 10, + /// \brief The C++ 'wchar_t' type. PREDEF_TYPE_WCHAR_ID = 11, + /// \brief The (signed) 'short' type. PREDEF_TYPE_SHORT_ID = 12, + /// \brief The (signed) 'int' type. PREDEF_TYPE_INT_ID = 13, + /// \brief The (signed) 'long' type. PREDEF_TYPE_LONG_ID = 14, + /// \brief The (signed) 'long long' type. PREDEF_TYPE_LONGLONG_ID = 15, + /// \brief The 'float' type. PREDEF_TYPE_FLOAT_ID = 16, + /// \brief The 'double' type. PREDEF_TYPE_DOUBLE_ID = 17, + /// \brief The 'long double' type. PREDEF_TYPE_LONGDOUBLE_ID = 18, + /// \brief The placeholder type for overloaded function sets. PREDEF_TYPE_OVERLOAD_ID = 19, + /// \brief The placeholder type for dependent types. PREDEF_TYPE_DEPENDENT_ID = 20, + /// \brief The '__uint128_t' type. PREDEF_TYPE_UINT128_ID = 21, + /// \brief The '__int128_t' type. PREDEF_TYPE_INT128_ID = 22, + /// \brief The type of 'nullptr'. PREDEF_TYPE_NULLPTR_ID = 23, + /// \brief The C++ 'char16_t' type. PREDEF_TYPE_CHAR16_ID = 24, + /// \brief The C++ 'char32_t' type. PREDEF_TYPE_CHAR32_ID = 25, + /// \brief The ObjC 'id' type. PREDEF_TYPE_OBJC_ID = 26, + /// \brief The ObjC 'Class' type. PREDEF_TYPE_OBJC_CLASS = 27, + /// \brief The ObjC 'SEL' type. PREDEF_TYPE_OBJC_SEL = 28, + /// \brief The 'unknown any' placeholder type. PREDEF_TYPE_UNKNOWN_ANY = 29, + /// \brief The placeholder type for bound member functions. PREDEF_TYPE_BOUND_MEMBER = 30, + /// \brief The "auto" deduction type. PREDEF_TYPE_AUTO_DEDUCT = 31, + /// \brief The "auto &&" deduction type. PREDEF_TYPE_AUTO_RREF_DEDUCT = 32, + /// \brief The OpenCL 'half' / ARM NEON __fp16 type. PREDEF_TYPE_HALF_ID = 33, + /// \brief ARC's unbridged-cast placeholder type. PREDEF_TYPE_ARC_UNBRIDGED_CAST = 34, + /// \brief The pseudo-object placeholder type. PREDEF_TYPE_PSEUDO_OBJECT = 35, + /// \brief The placeholder type for builtin functions. PREDEF_TYPE_BUILTIN_FN = 36, + /// \brief OpenCL event type. PREDEF_TYPE_EVENT_ID = 37, + /// \brief OpenCL clk event type. PREDEF_TYPE_CLK_EVENT_ID = 38, + /// \brief OpenCL sampler type. PREDEF_TYPE_SAMPLER_ID = 39, + /// \brief OpenCL queue type. PREDEF_TYPE_QUEUE_ID = 40, + /// \brief OpenCL reserve_id type. PREDEF_TYPE_RESERVE_ID_ID = 41, + /// \brief The placeholder type for OpenMP array section. PREDEF_TYPE_OMP_ARRAY_SECTION = 42, + /// \brief The '__float128' type PREDEF_TYPE_FLOAT128_ID = 43, + /// \brief The '_Float16' type PREDEF_TYPE_FLOAT16_ID = 44, + /// \brief OpenCL image types with auto numeration #define IMAGE_TYPE(ImgType, Id, SingletonId, Access, Suffix) \ PREDEF_TYPE_##Id##_ID, @@ -853,94 +936,139 @@ namespace clang { enum TypeCode { /// \brief An ExtQualType record. TYPE_EXT_QUAL = 1, + /// \brief A ComplexType record. TYPE_COMPLEX = 3, + /// \brief A PointerType record. TYPE_POINTER = 4, + /// \brief A BlockPointerType record. TYPE_BLOCK_POINTER = 5, + /// \brief An LValueReferenceType record. TYPE_LVALUE_REFERENCE = 6, + /// \brief An RValueReferenceType record. TYPE_RVALUE_REFERENCE = 7, + /// \brief A MemberPointerType record. TYPE_MEMBER_POINTER = 8, + /// \brief A ConstantArrayType record. TYPE_CONSTANT_ARRAY = 9, + /// \brief An IncompleteArrayType record. TYPE_INCOMPLETE_ARRAY = 10, + /// \brief A VariableArrayType record. TYPE_VARIABLE_ARRAY = 11, + /// \brief A VectorType record. TYPE_VECTOR = 12, + /// \brief An ExtVectorType record. TYPE_EXT_VECTOR = 13, + /// \brief A FunctionNoProtoType record. TYPE_FUNCTION_NO_PROTO = 14, + /// \brief A FunctionProtoType record. TYPE_FUNCTION_PROTO = 15, + /// \brief A TypedefType record. TYPE_TYPEDEF = 16, + /// \brief A TypeOfExprType record. TYPE_TYPEOF_EXPR = 17, + /// \brief A TypeOfType record. TYPE_TYPEOF = 18, + /// \brief A RecordType record. TYPE_RECORD = 19, + /// \brief An EnumType record. TYPE_ENUM = 20, + /// \brief An ObjCInterfaceType record. TYPE_OBJC_INTERFACE = 21, + /// \brief An ObjCObjectPointerType record. TYPE_OBJC_OBJECT_POINTER = 22, + /// \brief a DecltypeType record. TYPE_DECLTYPE = 23, + /// \brief An ElaboratedType record. TYPE_ELABORATED = 24, + /// \brief A SubstTemplateTypeParmType record. TYPE_SUBST_TEMPLATE_TYPE_PARM = 25, + /// \brief An UnresolvedUsingType record. TYPE_UNRESOLVED_USING = 26, + /// \brief An InjectedClassNameType record. TYPE_INJECTED_CLASS_NAME = 27, + /// \brief An ObjCObjectType record. TYPE_OBJC_OBJECT = 28, + /// \brief An TemplateTypeParmType record. TYPE_TEMPLATE_TYPE_PARM = 29, + /// \brief An TemplateSpecializationType record. TYPE_TEMPLATE_SPECIALIZATION = 30, + /// \brief A DependentNameType record. TYPE_DEPENDENT_NAME = 31, + /// \brief A DependentTemplateSpecializationType record. TYPE_DEPENDENT_TEMPLATE_SPECIALIZATION = 32, + /// \brief A DependentSizedArrayType record. TYPE_DEPENDENT_SIZED_ARRAY = 33, + /// \brief A ParenType record. TYPE_PAREN = 34, + /// \brief A PackExpansionType record. TYPE_PACK_EXPANSION = 35, + /// \brief An AttributedType record. TYPE_ATTRIBUTED = 36, + /// \brief A SubstTemplateTypeParmPackType record. TYPE_SUBST_TEMPLATE_TYPE_PARM_PACK = 37, + /// \brief A AutoType record. TYPE_AUTO = 38, + /// \brief A UnaryTransformType record. TYPE_UNARY_TRANSFORM = 39, + /// \brief An AtomicType record. TYPE_ATOMIC = 40, + /// \brief A DecayedType record. TYPE_DECAYED = 41, + /// \brief An AdjustedType record. TYPE_ADJUSTED = 42, + /// \brief A PipeType record. TYPE_PIPE = 43, + /// \brief An ObjCTypeParamType record. TYPE_OBJC_TYPE_PARAM = 44, + /// \brief A DeducedTemplateSpecializationType record. TYPE_DEDUCED_TEMPLATE_SPECIALIZATION = 45, + /// \brief A DependentSizedExtVectorType record. TYPE_DEPENDENT_SIZED_EXT_VECTOR = 46, + /// \brief A DependentAddressSpaceType record. TYPE_DEPENDENT_ADDRESS_SPACE = 47 }; @@ -953,18 +1081,25 @@ namespace clang { enum SpecialTypeIDs { /// \brief CFConstantString type SPECIAL_TYPE_CF_CONSTANT_STRING = 0, + /// \brief C FILE typedef type SPECIAL_TYPE_FILE = 1, + /// \brief C jmp_buf typedef type SPECIAL_TYPE_JMP_BUF = 2, + /// \brief C sigjmp_buf typedef type SPECIAL_TYPE_SIGJMP_BUF = 3, + /// \brief Objective-C "id" redefinition type SPECIAL_TYPE_OBJC_ID_REDEFINITION = 4, + /// \brief Objective-C "Class" redefinition type SPECIAL_TYPE_OBJC_CLASS_REDEFINITION = 5, + /// \brief Objective-C "SEL" redefinition type SPECIAL_TYPE_OBJC_SEL_REDEFINITION = 6, + /// \brief C ucontext_t typedef type SPECIAL_TYPE_UCONTEXT_T = 7 }; @@ -1055,57 +1190,84 @@ namespace clang { /// \brief A TypedefDecl record. DECL_TYPEDEF = 51, /// \brief A TypeAliasDecl record. + DECL_TYPEALIAS, + /// \brief An EnumDecl record. DECL_ENUM, + /// \brief A RecordDecl record. DECL_RECORD, + /// \brief An EnumConstantDecl record. DECL_ENUM_CONSTANT, + /// \brief A FunctionDecl record. DECL_FUNCTION, + /// \brief A ObjCMethodDecl record. DECL_OBJC_METHOD, + /// \brief A ObjCInterfaceDecl record. DECL_OBJC_INTERFACE, + /// \brief A ObjCProtocolDecl record. DECL_OBJC_PROTOCOL, + /// \brief A ObjCIvarDecl record. DECL_OBJC_IVAR, + /// \brief A ObjCAtDefsFieldDecl record. DECL_OBJC_AT_DEFS_FIELD, + /// \brief A ObjCCategoryDecl record. DECL_OBJC_CATEGORY, + /// \brief A ObjCCategoryImplDecl record. DECL_OBJC_CATEGORY_IMPL, + /// \brief A ObjCImplementationDecl record. DECL_OBJC_IMPLEMENTATION, + /// \brief A ObjCCompatibleAliasDecl record. DECL_OBJC_COMPATIBLE_ALIAS, + /// \brief A ObjCPropertyDecl record. DECL_OBJC_PROPERTY, + /// \brief A ObjCPropertyImplDecl record. DECL_OBJC_PROPERTY_IMPL, + /// \brief A FieldDecl record. DECL_FIELD, + /// \brief A MSPropertyDecl record. DECL_MS_PROPERTY, + /// \brief A VarDecl record. DECL_VAR, + /// \brief An ImplicitParamDecl record. DECL_IMPLICIT_PARAM, + /// \brief A ParmVarDecl record. DECL_PARM_VAR, + /// \brief A DecompositionDecl record. DECL_DECOMPOSITION, + /// \brief A BindingDecl record. DECL_BINDING, + /// \brief A FileScopeAsmDecl record. DECL_FILE_SCOPE_ASM, + /// \brief A BlockDecl record. DECL_BLOCK, + /// \brief A CapturedDecl record. DECL_CAPTURED, + /// \brief A record that stores the set of declarations that are /// lexically stored within a given DeclContext. /// @@ -1115,6 +1277,7 @@ namespace clang { /// the contents of a DeclContext, e.g., via /// DeclContext::decls_begin() and DeclContext::decls_end(). DECL_CONTEXT_LEXICAL, + /// \brief A record that stores the set of declarations that are /// visible from a given DeclContext. /// @@ -1123,104 +1286,151 @@ namespace clang { /// IDs. This data is used when performing qualified name lookup /// into a DeclContext via DeclContext::lookup. DECL_CONTEXT_VISIBLE, + /// \brief A LabelDecl record. DECL_LABEL, + /// \brief A NamespaceDecl record. DECL_NAMESPACE, + /// \brief A NamespaceAliasDecl record. DECL_NAMESPACE_ALIAS, + /// \brief A UsingDecl record. DECL_USING, + /// \brief A UsingPackDecl record. DECL_USING_PACK, + /// \brief A UsingShadowDecl record. DECL_USING_SHADOW, + /// \brief A ConstructorUsingShadowDecl record. DECL_CONSTRUCTOR_USING_SHADOW, + /// \brief A UsingDirecitveDecl record. DECL_USING_DIRECTIVE, + /// \brief An UnresolvedUsingValueDecl record. DECL_UNRESOLVED_USING_VALUE, + /// \brief An UnresolvedUsingTypenameDecl record. DECL_UNRESOLVED_USING_TYPENAME, + /// \brief A LinkageSpecDecl record. DECL_LINKAGE_SPEC, + /// \brief An ExportDecl record. DECL_EXPORT, + /// \brief A CXXRecordDecl record. DECL_CXX_RECORD, + /// \brief A CXXDeductionGuideDecl record. DECL_CXX_DEDUCTION_GUIDE, + /// \brief A CXXMethodDecl record. DECL_CXX_METHOD, + /// \brief A CXXConstructorDecl record. DECL_CXX_CONSTRUCTOR, + /// \brief A CXXConstructorDecl record for an inherited constructor. DECL_CXX_INHERITED_CONSTRUCTOR, + /// \brief A CXXDestructorDecl record. DECL_CXX_DESTRUCTOR, + /// \brief A CXXConversionDecl record. DECL_CXX_CONVERSION, + /// \brief An AccessSpecDecl record. DECL_ACCESS_SPEC, /// \brief A FriendDecl record. DECL_FRIEND, + /// \brief A FriendTemplateDecl record. DECL_FRIEND_TEMPLATE, + /// \brief A ClassTemplateDecl record. DECL_CLASS_TEMPLATE, + /// \brief A ClassTemplateSpecializationDecl record. DECL_CLASS_TEMPLATE_SPECIALIZATION, + /// \brief A ClassTemplatePartialSpecializationDecl record. DECL_CLASS_TEMPLATE_PARTIAL_SPECIALIZATION, + /// \brief A VarTemplateDecl record. DECL_VAR_TEMPLATE, + /// \brief A VarTemplateSpecializationDecl record. DECL_VAR_TEMPLATE_SPECIALIZATION, + /// \brief A VarTemplatePartialSpecializationDecl record. DECL_VAR_TEMPLATE_PARTIAL_SPECIALIZATION, + /// \brief A FunctionTemplateDecl record. DECL_FUNCTION_TEMPLATE, + /// \brief A TemplateTypeParmDecl record. DECL_TEMPLATE_TYPE_PARM, + /// \brief A NonTypeTemplateParmDecl record. DECL_NON_TYPE_TEMPLATE_PARM, + /// \brief A TemplateTemplateParmDecl record. DECL_TEMPLATE_TEMPLATE_PARM, + /// \brief A TypeAliasTemplateDecl record. DECL_TYPE_ALIAS_TEMPLATE, + /// \brief A StaticAssertDecl record. DECL_STATIC_ASSERT, + /// \brief A record containing CXXBaseSpecifiers. DECL_CXX_BASE_SPECIFIERS, + /// \brief A record containing CXXCtorInitializers. DECL_CXX_CTOR_INITIALIZERS, + /// \brief A IndirectFieldDecl record. DECL_INDIRECTFIELD, + /// \brief A NonTypeTemplateParmDecl record that stores an expanded /// non-type template parameter pack. DECL_EXPANDED_NON_TYPE_TEMPLATE_PARM_PACK, + /// \brief A TemplateTemplateParmDecl record that stores an expanded /// template template parameter pack. DECL_EXPANDED_TEMPLATE_TEMPLATE_PARM_PACK, + /// \brief A ClassScopeFunctionSpecializationDecl record a class scope /// function specialization. (Microsoft extension). DECL_CLASS_SCOPE_FUNCTION_SPECIALIZATION, + /// \brief An ImportDecl recording a module import. DECL_IMPORT, + /// \brief An OMPThreadPrivateDecl record. DECL_OMP_THREADPRIVATE, + /// \brief An EmptyDecl record. DECL_EMPTY, + /// \brief An ObjCTypeParamDecl record. DECL_OBJC_TYPE_PARAM, + /// \brief An OMPCapturedExprDecl record. DECL_OMP_CAPTUREDEXPR, + /// \brief A PragmaCommentDecl record. DECL_PRAGMA_COMMENT, + /// \brief A PragmaDetectMismatchDecl record. DECL_PRAGMA_DETECT_MISMATCH, + /// \brief An OMPDeclareReductionDecl record. DECL_OMP_DECLARE_REDUCTION, }; @@ -1236,128 +1446,190 @@ namespace clang { /// \brief A marker record that indicates that we are at the end /// of an expression. STMT_STOP = 128, + /// \brief A NULL expression. STMT_NULL_PTR, + /// \brief A reference to a previously [de]serialized Stmt record. STMT_REF_PTR, + /// \brief A NullStmt record. STMT_NULL, + /// \brief A CompoundStmt record. STMT_COMPOUND, + /// \brief A CaseStmt record. STMT_CASE, + /// \brief A DefaultStmt record. STMT_DEFAULT, + /// \brief A LabelStmt record. STMT_LABEL, + /// \brief An AttributedStmt record. STMT_ATTRIBUTED, + /// \brief An IfStmt record. STMT_IF, + /// \brief A SwitchStmt record. STMT_SWITCH, + /// \brief A WhileStmt record. STMT_WHILE, + /// \brief A DoStmt record. STMT_DO, + /// \brief A ForStmt record. STMT_FOR, + /// \brief A GotoStmt record. STMT_GOTO, + /// \brief An IndirectGotoStmt record. STMT_INDIRECT_GOTO, + /// \brief A ContinueStmt record. STMT_CONTINUE, + /// \brief A BreakStmt record. STMT_BREAK, + /// \brief A ReturnStmt record. STMT_RETURN, + /// \brief A DeclStmt record. STMT_DECL, + /// \brief A CapturedStmt record. STMT_CAPTURED, + /// \brief A GCC-style AsmStmt record. STMT_GCCASM, + /// \brief A MS-style AsmStmt record. STMT_MSASM, + /// \brief A PredefinedExpr record. EXPR_PREDEFINED, + /// \brief A DeclRefExpr record. EXPR_DECL_REF, + /// \brief An IntegerLiteral record. EXPR_INTEGER_LITERAL, + /// \brief A FloatingLiteral record. EXPR_FLOATING_LITERAL, + /// \brief An ImaginaryLiteral record. EXPR_IMAGINARY_LITERAL, + /// \brief A StringLiteral record. EXPR_STRING_LITERAL, + /// \brief A CharacterLiteral record. EXPR_CHARACTER_LITERAL, + /// \brief A ParenExpr record. EXPR_PAREN, + /// \brief A ParenListExpr record. EXPR_PAREN_LIST, + /// \brief A UnaryOperator record. EXPR_UNARY_OPERATOR, + /// \brief An OffsetOfExpr record. EXPR_OFFSETOF, + /// \brief A SizefAlignOfExpr record. EXPR_SIZEOF_ALIGN_OF, + /// \brief An ArraySubscriptExpr record. EXPR_ARRAY_SUBSCRIPT, + /// \brief A CallExpr record. EXPR_CALL, + /// \brief A MemberExpr record. EXPR_MEMBER, + /// \brief A BinaryOperator record. EXPR_BINARY_OPERATOR, + /// \brief A CompoundAssignOperator record. EXPR_COMPOUND_ASSIGN_OPERATOR, + /// \brief A ConditionOperator record. EXPR_CONDITIONAL_OPERATOR, + /// \brief An ImplicitCastExpr record. EXPR_IMPLICIT_CAST, + /// \brief A CStyleCastExpr record. EXPR_CSTYLE_CAST, + /// \brief A CompoundLiteralExpr record. EXPR_COMPOUND_LITERAL, + /// \brief An ExtVectorElementExpr record. EXPR_EXT_VECTOR_ELEMENT, + /// \brief An InitListExpr record. EXPR_INIT_LIST, + /// \brief A DesignatedInitExpr record. EXPR_DESIGNATED_INIT, + /// \brief A DesignatedInitUpdateExpr record. EXPR_DESIGNATED_INIT_UPDATE, + /// \brief An NoInitExpr record. EXPR_NO_INIT, + /// \brief An ArrayInitLoopExpr record. EXPR_ARRAY_INIT_LOOP, + /// \brief An ArrayInitIndexExpr record. EXPR_ARRAY_INIT_INDEX, + /// \brief An ImplicitValueInitExpr record. EXPR_IMPLICIT_VALUE_INIT, + /// \brief A VAArgExpr record. EXPR_VA_ARG, + /// \brief An AddrLabelExpr record. EXPR_ADDR_LABEL, + /// \brief A StmtExpr record. EXPR_STMT, + /// \brief A ChooseExpr record. EXPR_CHOOSE, + /// \brief A GNUNullExpr record. EXPR_GNU_NULL, + /// \brief A ShuffleVectorExpr record. EXPR_SHUFFLE_VECTOR, + /// \brief A ConvertVectorExpr record. EXPR_CONVERT_VECTOR, + /// \brief BlockExpr EXPR_BLOCK, + /// \brief A GenericSelectionExpr record. EXPR_GENERIC_SELECTION, + /// \brief A PseudoObjectExpr record. EXPR_PSEUDO_OBJECT, + /// \brief An AtomicExpr record. EXPR_ATOMIC, @@ -1369,45 +1641,61 @@ namespace clang { EXPR_OBJC_BOXED_EXPRESSION, EXPR_OBJC_ARRAY_LITERAL, EXPR_OBJC_DICTIONARY_LITERAL, - - + /// \brief An ObjCEncodeExpr record. EXPR_OBJC_ENCODE, + /// \brief An ObjCSelectorExpr record. EXPR_OBJC_SELECTOR_EXPR, + /// \brief An ObjCProtocolExpr record. EXPR_OBJC_PROTOCOL_EXPR, + /// \brief An ObjCIvarRefExpr record. EXPR_OBJC_IVAR_REF_EXPR, + /// \brief An ObjCPropertyRefExpr record. EXPR_OBJC_PROPERTY_REF_EXPR, + /// \brief An ObjCSubscriptRefExpr record. EXPR_OBJC_SUBSCRIPT_REF_EXPR, + /// \brief UNUSED EXPR_OBJC_KVC_REF_EXPR, + /// \brief An ObjCMessageExpr record. EXPR_OBJC_MESSAGE_EXPR, + /// \brief An ObjCIsa Expr record. EXPR_OBJC_ISA, + /// \brief An ObjCIndirectCopyRestoreExpr record. EXPR_OBJC_INDIRECT_COPY_RESTORE, /// \brief An ObjCForCollectionStmt record. STMT_OBJC_FOR_COLLECTION, + /// \brief An ObjCAtCatchStmt record. STMT_OBJC_CATCH, + /// \brief An ObjCAtFinallyStmt record. STMT_OBJC_FINALLY, + /// \brief An ObjCAtTryStmt record. STMT_OBJC_AT_TRY, + /// \brief An ObjCAtSynchronizedStmt record. STMT_OBJC_AT_SYNCHRONIZED, + /// \brief An ObjCAtThrowStmt record. STMT_OBJC_AT_THROW, + /// \brief An ObjCAutoreleasePoolStmt record. STMT_OBJC_AUTORELEASE_POOL, + /// \brief An ObjCBoolLiteralExpr record. EXPR_OBJC_BOOL_LITERAL, + /// \brief An ObjCAvailabilityCheckExpr record. EXPR_OBJC_AVAILABILITY_CHECK, @@ -1415,37 +1703,52 @@ namespace clang { /// \brief A CXXCatchStmt record. STMT_CXX_CATCH, + /// \brief A CXXTryStmt record. STMT_CXX_TRY, /// \brief A CXXForRangeStmt record. + STMT_CXX_FOR_RANGE, /// \brief A CXXOperatorCallExpr record. EXPR_CXX_OPERATOR_CALL, + /// \brief A CXXMemberCallExpr record. EXPR_CXX_MEMBER_CALL, + /// \brief A CXXConstructExpr record. EXPR_CXX_CONSTRUCT, + /// \brief A CXXInheritedCtorInitExpr record. EXPR_CXX_INHERITED_CTOR_INIT, + /// \brief A CXXTemporaryObjectExpr record. EXPR_CXX_TEMPORARY_OBJECT, + /// \brief A CXXStaticCastExpr record. EXPR_CXX_STATIC_CAST, + /// \brief A CXXDynamicCastExpr record. EXPR_CXX_DYNAMIC_CAST, + /// \brief A CXXReinterpretCastExpr record. EXPR_CXX_REINTERPRET_CAST, + /// \brief A CXXConstCastExpr record. EXPR_CXX_CONST_CAST, + /// \brief A CXXFunctionalCastExpr record. EXPR_CXX_FUNCTIONAL_CAST, + /// \brief A UserDefinedLiteral record. EXPR_USER_DEFINED_LITERAL, + /// \brief A CXXStdInitializerListExpr record. EXPR_CXX_STD_INITIALIZER_LIST, + /// \brief A CXXBoolLiteralExpr record. EXPR_CXX_BOOL_LITERAL, + EXPR_CXX_NULL_PTR_LITERAL, // CXXNullPtrLiteralExpr EXPR_CXX_TYPEID_EXPR, // CXXTypeidExpr (of expr). EXPR_CXX_TYPEID_TYPE, // CXXTypeidExpr (of type). @@ -1567,11 +1870,14 @@ namespace clang { enum DesignatorTypes { /// \brief Field designator where only the field name is known. DESIG_FIELD_NAME = 0, + /// \brief Field designator where the field has been resolved to /// a declaration. DESIG_FIELD_DECL = 1, + /// \brief Array designator. DESIG_ARRAY = 2, + /// \brief GNU array range designator. DESIG_ARRAY_RANGE = 3 }; @@ -1587,8 +1893,11 @@ namespace clang { /// \brief Describes the redeclarations of a declaration. struct LocalRedeclarationsInfo { - DeclID FirstID; // The ID of the first declaration - unsigned Offset; // Offset into the array of redeclaration chains. + // The ID of the first declaration + DeclID FirstID; + + // Offset into the array of redeclaration chains. + unsigned Offset; friend bool operator<(const LocalRedeclarationsInfo &X, const LocalRedeclarationsInfo &Y) { @@ -1613,8 +1922,11 @@ namespace clang { /// \brief Describes the categories of an Objective-C class. struct ObjCCategoriesInfo { - DeclID DefinitionID; // The ID of the definition - unsigned Offset; // Offset into the array of category lists. + // The ID of the definition + DeclID DefinitionID; + + // Offset into the array of category lists. + unsigned Offset; friend bool operator<(const ObjCCategoriesInfo &X, const ObjCCategoriesInfo &Y) { @@ -1643,15 +1955,14 @@ namespace clang { /// same key can occasionally represent multiple names (for names that /// contain types, in particular). class DeclarationNameKey { - typedef unsigned NameKind; + using NameKind = unsigned; - NameKind Kind; - uint64_t Data; + NameKind Kind = 0; + uint64_t Data = 0; public: - DeclarationNameKey() : Kind(), Data() {} + DeclarationNameKey() = default; DeclarationNameKey(DeclarationName Name); - DeclarationNameKey(NameKind Kind, uint64_t Data) : Kind(Kind), Data(Data) {} @@ -1663,12 +1974,14 @@ namespace clang { Kind == DeclarationName::CXXDeductionGuideName); return (IdentifierInfo *)Data; } + Selector getSelector() const { assert(Kind == DeclarationName::ObjCZeroArgSelector || Kind == DeclarationName::ObjCOneArgSelector || Kind == DeclarationName::ObjCMultiArgSelector); return Selector(Data); } + OverloadedOperatorKind getOperatorKind() const { assert(Kind == DeclarationName::CXXOperatorName); return (OverloadedOperatorKind)Data; @@ -1684,26 +1997,32 @@ namespace clang { }; /// @} - } -} // end namespace clang + +} // namespace serialization +} // namespace clang namespace llvm { + template <> struct DenseMapInfo<clang::serialization::DeclarationNameKey> { static clang::serialization::DeclarationNameKey getEmptyKey() { return clang::serialization::DeclarationNameKey(-1, 1); } + static clang::serialization::DeclarationNameKey getTombstoneKey() { return clang::serialization::DeclarationNameKey(-1, 2); } + static unsigned getHashValue(const clang::serialization::DeclarationNameKey &Key) { return Key.getHash(); } + static bool isEqual(const clang::serialization::DeclarationNameKey &L, const clang::serialization::DeclarationNameKey &R) { return L == R; } }; -} -#endif +} // namespace llvm + +#endif // LLVM_CLANG_SERIALIZATION_ASTBITCODES_H diff --git a/include/clang/Serialization/ASTReader.h b/include/clang/Serialization/ASTReader.h index 9c5ad00691..7b71fee95d 100644 --- a/include/clang/Serialization/ASTReader.h +++ b/include/clang/Serialization/ASTReader.h @@ -1,4 +1,4 @@ -//===--- ASTReader.h - AST File Reader --------------------------*- C++ -*-===// +//===- ASTReader.h - AST File Reader ----------------------------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -17,13 +17,21 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" +#include "clang/AST/Type.h" #include "clang/Basic/Diagnostic.h" +#include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/FileSystemOptions.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/Module.h" +#include "clang/Basic/OpenCLOptions.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/Version.h" +#include "clang/Basic/VersionTuple.h" #include "clang/Lex/ExternalPreprocessorSource.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/PreprocessingRecord.h" +#include "clang/Lex/Token.h" #include "clang/Sema/ExternalSemaSource.h" #include "clang/Sema/IdentifierResolver.h" #include "clang/Serialization/ASTBitCodes.h" @@ -31,70 +39,86 @@ #include "clang/Serialization/Module.h" #include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/ModuleManager.h" +#include "llvm/ADT/APFloat.h" +#include "llvm/ADT/APInt.h" +#include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/DenseSet.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" #include "llvm/ADT/MapVector.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SetVector.h" #include "llvm/ADT/SmallPtrSet.h" -#include "llvm/ADT/SmallSet.h" #include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringMap.h" #include "llvm/ADT/StringRef.h" -#include "llvm/ADT/TinyPtrVector.h" -#include "llvm/Support/DataTypes.h" +#include "llvm/ADT/iterator.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/Endian.h" +#include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Timer.h" +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <ctime> #include <deque> #include <memory> +#include <set> #include <string> #include <utility> #include <vector> -namespace llvm { - class BitstreamCursor; - class MemoryBuffer; - class APInt; - class APSInt; - class APFloat; -} - namespace clang { -class SourceManager; -class HeaderSearchOptions; -class FileManager; -class AddrLabelExpr; class ASTConsumer; class ASTContext; -class ASTIdentifierIterator; -class ASTUnit; // FIXME: Layering violation and egregious hack. -class Attr; -class Decl; -class DeclContext; -class DefMacroDirective; -class DiagnosticOptions; -class NestedNameSpecifier; +class ASTDeserializationListener; +class ASTReader; +class ASTRecordReader; class CXXBaseSpecifier; class CXXConstructorDecl; class CXXCtorInitializer; +class CXXTemporary; +class Decl; +class DeclaratorDecl; +class DeclContext; +class EnumDecl; +class Expr; +class FieldDecl; +class FileEntry; +class FileManager; +class FileSystemOptions; +class FunctionDecl; class GlobalModuleIndex; -class GotoStmt; -class MacroDefinition; -class MacroDirective; -class ModuleMacro; +struct HeaderFileInfo; +class HeaderSearchOptions; +class LangOptions; +class LazyASTUnresolvedSet; +class MacroInfo; +class MemoryBufferCache; class NamedDecl; -class OpaqueValueExpr; +class NamespaceDecl; +class NestedNameSpecifier; +class ObjCCategoryDecl; +class ObjCInterfaceDecl; +class PCHContainerReader; class Preprocessor; class PreprocessorOptions; +struct QualifierInfo; class Sema; +class SourceManager; +class Stmt; class SwitchCase; -class ASTDeserializationListener; -class ASTWriter; -class ASTReader; -class ASTDeclReader; -class ASTStmtReader; -class ASTRecordReader; -class TypeLocReader; -struct HeaderFileInfo; -class VersionTuple; class TargetOptions; -class LazyASTUnresolvedSet; +class TemplateParameterList; +class TypedefNameDecl; +class TypeSourceInfo; +class ValueDecl; +class VarDecl; /// \brief Abstract interface for callback invocations by the ASTReader. /// @@ -189,9 +213,11 @@ public: /// \brief Returns true if this \c ASTReaderListener wants to receive the /// input files of the AST file via \c visitInputFile, false otherwise. virtual bool needsInputFileVisitation() { return false; } + /// \brief Returns true if this \c ASTReaderListener wants to receive the /// system input files of the AST file via \c visitInputFile, false otherwise. virtual bool needsSystemInputFileVisitation() { return false; } + /// \brief if \c needsInputFileVisitation returns true, this is called for /// each non-system input file of the AST File. If /// \c needsSystemInputFileVisitation is true, then it is called for all @@ -206,6 +232,7 @@ public: /// \brief Returns true if this \c ASTReaderListener wants to receive the /// imports of the AST file via \c visitImport, false otherwise. virtual bool needsImportVisitation() const { return false; } + /// \brief If needsImportVisitation returns \c true, this is called for each /// AST file imported by this AST file. virtual void visitImport(StringRef Filename) {} @@ -306,12 +333,15 @@ namespace serialization { class ReadMethodPoolVisitor; namespace reader { - class ASTIdentifierLookupTrait; - /// \brief The on-disk hash table(s) used for DeclContext name lookup. - struct DeclContextLookupTable; -} -} // end namespace serialization +class ASTIdentifierLookupTrait; + +/// \brief The on-disk hash table(s) used for DeclContext name lookup. +struct DeclContextLookupTable; + +} // namespace reader + +} // namespace serialization /// \brief Reads an AST files chain containing the contents of a translation /// unit. @@ -334,8 +364,20 @@ class ASTReader public ExternalSLocEntrySource { public: - typedef SmallVector<uint64_t, 64> RecordData; - typedef SmallVectorImpl<uint64_t> RecordDataImpl; + /// \brief Types of AST files. + friend class ASTDeclReader; + friend class ASTIdentifierIterator; + friend class ASTRecordReader; + friend class ASTStmtReader; + friend class ASTUnit; // ASTUnit needs to remap source locations. + friend class ASTWriter; + friend class PCHValidator; + friend class serialization::reader::ASTIdentifierLookupTrait; + friend class serialization::ReadMethodPoolVisitor; + friend class TypeLocReader; + + using RecordData = SmallVector<uint64_t, 64>; + using RecordDataImpl = SmallVectorImpl<uint64_t>; /// \brief The result of reading the control block of an AST file, which /// can fail for various reasons. @@ -343,41 +385,34 @@ public: /// \brief The control block was read successfully. Aside from failures, /// the AST file is safe to read into the current context. Success, + /// \brief The AST file itself appears corrupted. Failure, + /// \brief The AST file was missing. Missing, + /// \brief The AST file is out-of-date relative to its input files, /// and needs to be regenerated. OutOfDate, + /// \brief The AST file was written by a different version of Clang. VersionMismatch, + /// \brief The AST file was writtten with a different language/target /// configuration. ConfigurationMismatch, + /// \brief The AST file has errors. HadErrors }; - /// \brief Types of AST files. - friend class PCHValidator; - friend class ASTDeclReader; - friend class ASTStmtReader; - friend class ASTIdentifierIterator; - friend class serialization::reader::ASTIdentifierLookupTrait; - friend class TypeLocReader; - friend class ASTRecordReader; - friend class ASTWriter; - friend class ASTUnit; // ASTUnit needs to remap source locations. - friend class serialization::ReadMethodPoolVisitor; - - typedef serialization::ModuleFile ModuleFile; - typedef serialization::ModuleKind ModuleKind; - typedef serialization::ModuleManager ModuleManager; - - typedef ModuleManager::ModuleIterator ModuleIterator; - typedef ModuleManager::ModuleConstIterator ModuleConstIterator; - typedef ModuleManager::ModuleReverseIterator ModuleReverseIterator; + using ModuleFile = serialization::ModuleFile; + using ModuleKind = serialization::ModuleKind; + using ModuleManager = serialization::ModuleManager; + using ModuleIterator = ModuleManager::ModuleIterator; + using ModuleConstIterator = ModuleManager::ModuleConstIterator; + using ModuleReverseIterator = ModuleManager::ModuleReverseIterator; private: /// \brief The receiver of some callbacks invoked by ASTReader. @@ -385,6 +420,7 @@ private: /// \brief The receiver of deserialization events. ASTDeserializationListener *DeserializationListener = nullptr; + bool OwnsDeserializationListener = false; SourceManager &SourceMgr; @@ -436,7 +472,8 @@ private: /// \brief A map of negated SLocEntryIDs to the modules containing them. ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocEntryMap; - typedef ContinuousRangeMap<unsigned, ModuleFile*, 64> GlobalSLocOffsetMapType; + using GlobalSLocOffsetMapType = + ContinuousRangeMap<unsigned, ModuleFile *, 64>; /// \brief A map of reversed (SourceManager::MaxLoadedOffset - SLocOffset) /// SourceLocation offsets to the modules containing them. @@ -448,8 +485,8 @@ private: /// ID = (I + 1) << FastQual::Width has already been loaded std::vector<QualType> TypesLoaded; - typedef ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4> - GlobalTypeMapType; + using GlobalTypeMapType = + ContinuousRangeMap<serialization::TypeID, ModuleFile *, 4>; /// \brief Mapping from global type IDs to the module in which the /// type resides along with the offset that should be added to the @@ -462,17 +499,17 @@ private: /// = I + 1 has already been loaded. std::vector<Decl *> DeclsLoaded; - typedef ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4> - GlobalDeclMapType; + using GlobalDeclMapType = + ContinuousRangeMap<serialization::DeclID, ModuleFile *, 4>; /// \brief Mapping from global declaration IDs to the module in which the /// declaration resides. GlobalDeclMapType GlobalDeclMap; - typedef std::pair<ModuleFile *, uint64_t> FileOffset; - typedef SmallVector<FileOffset, 2> FileOffsetsTy; - typedef llvm::DenseMap<serialization::DeclID, FileOffsetsTy> - DeclUpdateOffsetsMap; + using FileOffset = std::pair<ModuleFile *, uint64_t>; + using FileOffsetsTy = SmallVector<FileOffset, 2>; + using DeclUpdateOffsetsMap = + llvm::DenseMap<serialization::DeclID, FileOffsetsTy>; /// \brief Declarations that have modifications residing in a later file /// in the chain. @@ -481,12 +518,15 @@ private: struct PendingUpdateRecord { Decl *D; serialization::GlobalDeclID ID; + // Whether the declaration was just deserialized. bool JustLoaded; + PendingUpdateRecord(serialization::GlobalDeclID ID, Decl *D, bool JustLoaded) : D(D), ID(ID), JustLoaded(JustLoaded) {} }; + /// \brief Declaration updates for already-loaded declarations that we need /// to apply once we finish processing an import. llvm::SmallVector<PendingUpdateRecord, 16> PendingUpdateRecords; @@ -505,7 +545,7 @@ private: /// \brief Declarations that have been imported and have typedef names for /// linkage purposes. - llvm::DenseMap<std::pair<DeclContext*, IdentifierInfo*>, NamedDecl*> + llvm::DenseMap<std::pair<DeclContext *, IdentifierInfo *>, NamedDecl *> ImportedTypedefNamesForLinkage; /// \brief Mergeable declaration contexts that have anonymous declarations @@ -514,10 +554,10 @@ private: AnonymousDeclarationsForMerging; struct FileDeclsInfo { - ModuleFile *Mod; + ModuleFile *Mod = nullptr; ArrayRef<serialization::LocalDeclID> Decls; - FileDeclsInfo() : Mod(nullptr) {} + FileDeclsInfo() = default; FileDeclsInfo(ModuleFile *Mod, ArrayRef<serialization::LocalDeclID> Decls) : Mod(Mod), Decls(Decls) {} }; @@ -527,7 +567,7 @@ private: /// \brief An array of lexical contents of a declaration context, as a sequence of /// Decl::Kind, DeclID pairs. - typedef ArrayRef<llvm::support::unaligned_uint32_t> LexicalContents; + using LexicalContents = ArrayRef<llvm::support::unaligned_uint32_t>; /// \brief Map from a DeclContext to its lexical contents. llvm::DenseMap<const DeclContext*, std::pair<ModuleFile*, LexicalContents>> @@ -548,7 +588,7 @@ private: ModuleFile *Mod; const unsigned char *Data; }; - typedef SmallVector<PendingVisibleUpdate, 1> DeclContextVisibleUpdates; + using DeclContextVisibleUpdates = SmallVector<PendingVisibleUpdate, 1>; /// \brief Updates to the visible declarations of declaration contexts that /// haven't been loaded yet. @@ -559,22 +599,23 @@ private: /// declarations that have not yet been linked to their definitions. llvm::SmallPtrSet<Decl *, 4> PendingDefinitions; - typedef llvm::MapVector<Decl *, uint64_t, - llvm::SmallDenseMap<Decl *, unsigned, 4>, - SmallVector<std::pair<Decl *, uint64_t>, 4> > - PendingBodiesMap; + using PendingBodiesMap = + llvm::MapVector<Decl *, uint64_t, + llvm::SmallDenseMap<Decl *, unsigned, 4>, + SmallVector<std::pair<Decl *, uint64_t>, 4>>; /// \brief Functions or methods that have bodies that will be attached. PendingBodiesMap PendingBodies; /// \brief Definitions for which we have added merged definitions but not yet /// performed deduplication. - llvm::SetVector<NamedDecl*> PendingMergedDefinitionsToDeduplicate; + llvm::SetVector<NamedDecl *> PendingMergedDefinitionsToDeduplicate; /// \brief Read the record that describes the lexical contents of a DC. bool ReadLexicalDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, uint64_t Offset, DeclContext *DC); + /// \brief Read the record that describes the visible contents of a DC. bool ReadVisibleDeclContextStorage(ModuleFile &M, llvm::BitstreamCursor &Cursor, @@ -588,8 +629,8 @@ private: /// been loaded. std::vector<IdentifierInfo *> IdentifiersLoaded; - typedef ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4> - GlobalIdentifierMapType; + using GlobalIdentifierMapType = + ContinuousRangeMap<serialization::IdentID, ModuleFile *, 4>; /// \brief Mapping from global identifier IDs to the module in which the /// identifier resides along with the offset that should be added to the @@ -604,16 +645,16 @@ private: /// been loaded. std::vector<MacroInfo *> MacrosLoaded; - typedef std::pair<IdentifierInfo *, serialization::SubmoduleID> - LoadedMacroInfo; + using LoadedMacroInfo = + std::pair<IdentifierInfo *, serialization::SubmoduleID>; /// \brief A set of #undef directives that we have loaded; used to /// deduplicate the same #undef information coming from multiple module /// files. llvm::DenseSet<LoadedMacroInfo> LoadedUndefs; - typedef ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4> - GlobalMacroMapType; + using GlobalMacroMapType = + ContinuousRangeMap<serialization::MacroID, ModuleFile *, 4>; /// \brief Mapping from global macro IDs to the module in which the /// macro resides along with the offset that should be added to the @@ -626,8 +667,8 @@ private: /// indicate that the particular submodule ID has not yet been loaded. SmallVector<Module *, 2> SubmodulesLoaded; - typedef ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4> - GlobalSubmoduleMapType; + using GlobalSubmoduleMapType = + ContinuousRangeMap<serialization::SubmoduleID, ModuleFile *, 4>; /// \brief Mapping from global submodule IDs to the module file in which the /// submodule resides along with the offset that should be added to the @@ -635,14 +676,13 @@ private: GlobalSubmoduleMapType GlobalSubmoduleMap; /// \brief A set of hidden declarations. - typedef SmallVector<Decl*, 2> HiddenNames; - typedef llvm::DenseMap<Module *, HiddenNames> HiddenNamesMapType; + using HiddenNames = SmallVector<Decl *, 2>; + using HiddenNamesMapType = llvm::DenseMap<Module *, HiddenNames>; /// \brief A mapping from each of the hidden submodules to the deserialized /// declarations in that submodule that could be made visible. HiddenNamesMapType HiddenNamesMap; - /// \brief A module import, export, or conflict that hasn't yet been resolved. struct UnresolvedModuleRef { /// \brief The file in which this module resides. @@ -675,11 +715,10 @@ private: /// been loaded. SmallVector<Selector, 16> SelectorsLoaded; - typedef ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4> - GlobalSelectorMapType; + using GlobalSelectorMapType = + ContinuousRangeMap<serialization::SelectorID, ModuleFile *, 4>; /// \brief Mapping from global selector IDs to the module in which the - /// global selector ID to produce a local ID. GlobalSelectorMapType GlobalSelectorMap; @@ -699,15 +738,15 @@ private: : M(M), MacroDirectivesOffset(MacroDirectivesOffset) {} }; - typedef llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2> > - PendingMacroIDsMap; + using PendingMacroIDsMap = + llvm::MapVector<IdentifierInfo *, SmallVector<PendingMacroInfo, 2>>; /// \brief Mapping from identifiers that have a macro history to the global /// IDs have not yet been deserialized to the global IDs of those macros. PendingMacroIDsMap PendingMacroIDs; - typedef ContinuousRangeMap<unsigned, ModuleFile *, 4> - GlobalPreprocessedEntityMapType; + using GlobalPreprocessedEntityMapType = + ContinuousRangeMap<unsigned, ModuleFile *, 4>; /// \brief Mapping from global preprocessing entity IDs to the module in /// which the preprocessed entity resides along with the offset that should be @@ -895,7 +934,8 @@ private: ///\brief Whether we are currently processing update records. bool ProcessingUpdateRecords = false; - typedef llvm::DenseMap<unsigned, SwitchCase *> SwitchCaseMapTy; + using SwitchCaseMapTy = llvm::DenseMap<unsigned, SwitchCase *>; + /// \brief Mapping from switch-case IDs in the chain to switch-case statements /// /// Statements usually don't have IDs, but switch cases need them, so that the @@ -979,7 +1019,7 @@ private: /// /// The declarations on the identifier chain for these identifiers will be /// loaded once the recursive loading has completed. - llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4> > + llvm::MapVector<IdentifierInfo *, SmallVector<uint32_t, 4>> PendingIdentifierInfos; /// \brief The set of lookup results that we have faked in order to support @@ -998,7 +1038,9 @@ private: public: InterestingDecl(Decl *D, bool HasBody) : D(D), DeclHasPendingBody(HasBody) {} + Decl *getDecl() { return D; } + /// Whether the declaration has a pending body. bool hasPendingBody() { return DeclHasPendingBody; } }; @@ -1062,8 +1104,8 @@ private: /// module is loaded. SmallVector<ObjCInterfaceDecl *, 16> ObjCClassesLoaded; - typedef llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2> > - KeyDeclsMap; + using KeyDeclsMap = + llvm::DenseMap<Decl *, SmallVector<serialization::DeclID, 2>>; /// \brief A mapping from canonical declarations to the set of global /// declaration IDs for key declaration that have been merged with that @@ -1097,15 +1139,14 @@ private: ASTReader &Reader; enum ReadingKind PrevKind; - ReadingKindTracker(const ReadingKindTracker &) = delete; - void operator=(const ReadingKindTracker &) = delete; - public: ReadingKindTracker(enum ReadingKind newKind, ASTReader &reader) : Reader(reader), PrevKind(Reader.ReadingKind) { Reader.ReadingKind = newKind; } + ReadingKindTracker(const ReadingKindTracker &) = delete; + ReadingKindTracker &operator=(const ReadingKindTracker &) = delete; ~ReadingKindTracker() { Reader.ReadingKind = PrevKind; } }; @@ -1114,15 +1155,15 @@ private: ASTReader &Reader; bool PrevState; - ProcessingUpdatesRAIIObj(const ProcessingUpdatesRAIIObj &) = delete; - void operator=(const ProcessingUpdatesRAIIObj &) = delete; - public: ProcessingUpdatesRAIIObj(ASTReader &reader) : Reader(reader), PrevState(Reader.ProcessingUpdateRecords) { Reader.ProcessingUpdateRecords = true; } + ProcessingUpdatesRAIIObj(const ProcessingUpdatesRAIIObj &) = delete; + ProcessingUpdatesRAIIObj & + operator=(const ProcessingUpdatesRAIIObj &) = delete; ~ProcessingUpdatesRAIIObj() { Reader.ProcessingUpdateRecords = PrevState; } }; @@ -1205,7 +1246,7 @@ private: ImportedModule(ModuleFile *Mod, ModuleFile *ImportedBy, SourceLocation ImportLoc) - : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) { } + : Mod(Mod), ImportedBy(ImportedBy), ImportLoc(ImportLoc) {} }; ASTReadResult ReadASTCore(StringRef FileName, ModuleKind Type, @@ -1266,10 +1307,11 @@ private: std::string &SuggestedPredefines); struct RecordLocation { - RecordLocation(ModuleFile *M, uint64_t O) - : F(M), Offset(O) {} ModuleFile *F; uint64_t Offset; + + RecordLocation(ModuleFile *M, uint64_t O) + : F(M), Offset(O) {} }; QualType readTypeRecord(unsigned Index); @@ -1328,12 +1370,11 @@ public: ModuleDeclIterator, const serialization::LocalDeclID *, std::random_access_iterator_tag, const Decl *, ptrdiff_t, const Decl *, const Decl *> { - ASTReader *Reader; - ModuleFile *Mod; + ASTReader *Reader = nullptr; + ModuleFile *Mod = nullptr; public: - ModuleDeclIterator() - : iterator_adaptor_base(nullptr), Reader(nullptr), Mod(nullptr) {} + ModuleDeclIterator() : iterator_adaptor_base(nullptr) {} ModuleDeclIterator(ASTReader *Reader, ModuleFile *Mod, const serialization::LocalDeclID *Pos) @@ -1342,6 +1383,7 @@ public: value_type operator*() const { return Reader->GetDecl(Reader->getGlobalDeclID(*Mod, *I)); } + value_type operator->() const { return **this; } bool operator==(const ModuleDeclIterator &RHS) const { @@ -1378,8 +1420,6 @@ private: void Error(unsigned DiagID, StringRef Arg1 = StringRef(), StringRef Arg2 = StringRef()) const; - ASTReader(const ASTReader &) = delete; - void operator=(const ASTReader &) = delete; public: /// \brief Load the AST file and validate its contents against the given /// Preprocessor. @@ -1428,7 +1468,8 @@ public: bool AllowConfigurationMismatch = false, bool ValidateSystemInputs = false, bool UseGlobalIndex = true, std::unique_ptr<llvm::Timer> ReadTimer = {}); - + ASTReader(const ASTReader &) = delete; + ASTReader &operator=(const ASTReader &) = delete; ~ASTReader() override; SourceManager &getSourceManager() const { return SourceMgr; } @@ -1443,15 +1484,19 @@ public: enum LoadFailureCapabilities { /// \brief The client can't handle any AST loading failures. ARR_None = 0, + /// \brief The client can handle an AST file that cannot load because it /// is missing. ARR_Missing = 0x1, + /// \brief The client can handle an AST file that cannot load because it /// is out-of-date relative to its input files. ARR_OutOfDate = 0x2, + /// \brief The client can handle an AST file that cannot load because it /// was built with a different version of Clang. ARR_VersionMismatch = 0x4, + /// \brief The client can handle an AST file that cannot load because it's /// compiled configuration doesn't match that of the context it was /// loaded into. @@ -1522,11 +1567,11 @@ public: /// RAII object to temporarily add an AST callback listener. class ListenerScope { ASTReader &Reader; - bool Chained; + bool Chained = false; public: ListenerScope(ASTReader &Reader, std::unique_ptr<ASTReaderListener> L) - : Reader(Reader), Chained(false) { + : Reader(Reader) { auto Old = Reader.takeListener(); if (Old) { Chained = true; @@ -1535,6 +1580,7 @@ public: } Reader.setListener(std::move(L)); } + ~ListenerScope() { auto New = Reader.takeListener(); if (Chained) @@ -1933,16 +1979,16 @@ public: llvm::SmallSetVector<const TypedefNameDecl *, 4> &Decls) override; void ReadReferencedSelectors( - SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) override; + SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) override; void ReadWeakUndeclaredIdentifiers( - SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WI) override; + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WI) override; void ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) override; void ReadPendingInstantiations( - SmallVectorImpl<std::pair<ValueDecl *, - SourceLocation> > &Pending) override; + SmallVectorImpl<std::pair<ValueDecl *, + SourceLocation>> &Pending) override; void ReadLateParsedTemplates( llvm::MapVector<const FunctionDecl *, std::unique_ptr<LateParsedTemplate>> @@ -2275,20 +2321,19 @@ public: /// \brief An object for streaming information from a record. class ASTRecordReader { - typedef serialization::ModuleFile ModuleFile; + using ModuleFile = serialization::ModuleFile; ASTReader *Reader; ModuleFile *F; unsigned Idx = 0; ASTReader::RecordData Record; - typedef ASTReader::RecordData RecordData; - typedef ASTReader::RecordDataImpl RecordDataImpl; + using RecordData = ASTReader::RecordData; + using RecordDataImpl = ASTReader::RecordDataImpl; public: /// Construct an ASTRecordReader that uses the default encoding scheme. - ASTRecordReader(ASTReader &Reader, ModuleFile &F) - : Reader(&Reader), F(&F) {} + ASTRecordReader(ASTReader &Reader, ModuleFile &F) : Reader(&Reader), F(&F) {} /// \brief Reads a record with id AbbrevID from Cursor, resetting the /// internal state. @@ -2302,17 +2347,20 @@ public: /// \brief The current position in this record. unsigned getIdx() const { return Idx; } + /// \brief The length of this record. size_t size() const { return Record.size(); } /// \brief An arbitrary index in this record. const uint64_t &operator[](size_t N) { return Record[N]; } + /// \brief The last element in this record. const uint64_t &back() const { return Record.back(); } /// \brief Returns the current value in this record, and advances to the /// next value. const uint64_t &readInt() { return Record[Idx++]; } + /// \brief Returns the current value in this record, without advancing. const uint64_t &peekInt() { return Record[Idx]; } @@ -2566,7 +2614,7 @@ public: /// then restores it when destroyed. struct SavedStreamPosition { explicit SavedStreamPosition(llvm::BitstreamCursor &Cursor) - : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) { } + : Cursor(Cursor), Offset(Cursor.GetCurrentBitNo()) {} ~SavedStreamPosition() { Cursor.JumpToBit(Offset); @@ -2581,6 +2629,6 @@ inline void PCHValidator::Error(const char *Msg) { Reader.Error(Msg); } -} // end namespace clang +} // namespace clang -#endif +#endif // LLVM_CLANG_SERIALIZATION_ASTREADER_H diff --git a/include/clang/Serialization/ContinuousRangeMap.h b/include/clang/Serialization/ContinuousRangeMap.h index 244b01b22a..24bfadd0f8 100644 --- a/include/clang/Serialization/ContinuousRangeMap.h +++ b/include/clang/Serialization/ContinuousRangeMap.h @@ -1,4 +1,4 @@ -//===--- ContinuousRangeMap.h - Map with int range as key -------*- C++ -*-===// +//===- ContinuousRangeMap.h - Map with int range as key ---------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -18,6 +18,7 @@ #include "clang/Basic/LLVM.h" #include "llvm/ADT/SmallVector.h" #include <algorithm> +#include <cassert> #include <utility> namespace clang { @@ -35,14 +36,15 @@ namespace clang { template <typename Int, typename V, unsigned InitialCapacity> class ContinuousRangeMap { public: - typedef std::pair<Int, V> value_type; - typedef value_type &reference; - typedef const value_type &const_reference; - typedef value_type *pointer; - typedef const value_type *const_pointer; + using value_type = std::pair<Int, V>; + using reference = value_type &; + using const_reference = const value_type &; + using pointer = value_type *; + using const_pointer = const value_type *; private: - typedef SmallVector<value_type, InitialCapacity> Representation; + using Representation = SmallVector<value_type, InitialCapacity>; + Representation Rep; struct Compare { @@ -52,7 +54,7 @@ private: bool operator ()(Int L, const_reference R) const { return L < R.first; } - bool operator ()(Int L, Int R) const { + bool operator ()(Int L, Int R) const { return L < R; } bool operator ()(const_reference L, const_reference R) const { @@ -80,8 +82,8 @@ public: Rep.insert(I, Val); } - typedef typename Representation::iterator iterator; - typedef typename Representation::const_iterator const_iterator; + using iterator = typename Representation::iterator; + using const_iterator = typename Representation::const_iterator; iterator begin() { return Rep.begin(); } iterator end() { return Rep.end(); } @@ -108,13 +110,12 @@ public: /// from a set of values. class Builder { ContinuousRangeMap &Self; - + + public: + explicit Builder(ContinuousRangeMap &Self) : Self(Self) {} Builder(const Builder&) = delete; Builder &operator=(const Builder&) = delete; - public: - explicit Builder(ContinuousRangeMap &Self) : Self(Self) { } - ~Builder() { std::sort(Self.Rep.begin(), Self.Rep.end(), Compare()); std::unique(Self.Rep.begin(), Self.Rep.end(), @@ -131,9 +132,10 @@ public: Self.Rep.push_back(Val); } }; + friend class Builder; }; -} +} // namespace clang -#endif +#endif // LLVM_CLANG_SERIALIZATION_CONTINUOUSRANGEMAP_H diff --git a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h index af1af4590d..06132587b4 100644 --- a/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h +++ b/include/clang/StaticAnalyzer/Core/PathSensitive/SVals.h @@ -103,9 +103,6 @@ public: return *static_cast<const T *>(this); } - /// BufferTy - A temporary buffer to hold a set of SVals. - typedef SmallVector<SVal,5> BufferTy; - inline unsigned getRawKind() const { return Kind; } inline BaseKind getBaseKind() const { return (BaseKind) (Kind & BaseMask); } inline unsigned getSubKind() const { return (Kind & ~BaseMask) >> BaseBits; } diff --git a/include/clang/Tooling/Execution.h b/include/clang/Tooling/Execution.h index 9d07c5659e..1a44c4788c 100644 --- a/include/clang/Tooling/Execution.h +++ b/include/clang/Tooling/Execution.h @@ -162,6 +162,13 @@ createExecutorFromCommandLineArgs(int &argc, const char **argv, llvm::cl::OptionCategory &Category, const char *Overview = nullptr); +namespace internal { +llvm::Expected<std::unique_ptr<ToolExecutor>> +createExecutorFromCommandLineArgsImpl(int &argc, const char **argv, + llvm::cl::OptionCategory &Category, + const char *Overview = nullptr); +} // end namespace internal + } // end namespace tooling } // end namespace clang diff --git a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h index 8b01a61256..d96ad78ad8 100644 --- a/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h +++ b/include/clang/Tooling/Refactoring/RecursiveSymbolVisitor.h @@ -70,6 +70,18 @@ public: return visit(Expr->getFoundDecl().getDecl(), Expr->getMemberLoc()); } + bool VisitOffsetOfExpr(const OffsetOfExpr *S) { + for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) { + const OffsetOfNode &Component = S->getComponent(I); + if (Component.getKind() == OffsetOfNode::Field) { + if (!visit(Component.getField(), Component.getLocEnd())) + return false; + } + // FIXME: Try to resolve dependent field references. + } + return true; + } + // Other visitors: bool VisitTypeLoc(const TypeLoc Loc) { diff --git a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h index d9ed7d3a1f..734b624d77 100644 --- a/include/clang/Tooling/Refactoring/Rename/RenamingAction.h +++ b/include/clang/Tooling/Refactoring/Rename/RenamingAction.h @@ -66,6 +66,28 @@ private: std::string NewName; }; +class QualifiedRenameRule final : public SourceChangeRefactoringRule { +public: + static Expected<QualifiedRenameRule> initiate(RefactoringRuleContext &Context, + std::string OldQualifiedName, + std::string NewQualifiedName); + + static const RefactoringDescriptor &describe(); + +private: + QualifiedRenameRule(const NamedDecl *ND, + std::string NewQualifiedName) + : ND(ND), NewQualifiedName(std::move(NewQualifiedName)) {} + + Expected<AtomicChanges> + createSourceReplacements(RefactoringRuleContext &Context) override; + + // A NamedDecl which indentifies the the symbol being renamed. + const NamedDecl *ND; + // The new qualified name to change the symbol to. + std::string NewQualifiedName; +}; + /// Returns source replacements that correspond to the rename of the given /// symbol occurrences. llvm::Expected<std::vector<AtomicChange>> diff --git a/lib/AST/ASTContext.cpp b/lib/AST/ASTContext.cpp index 87d096dab0..8247d1a23e 100644 --- a/lib/AST/ASTContext.cpp +++ b/lib/AST/ASTContext.cpp @@ -9281,6 +9281,11 @@ CallingConv ASTContext::getDefaultCallingConvention(bool IsVariadic, if (!IsVariadic) return CC_X86VectorCall; break; + case LangOptions::DCC_RegCall: + // __regcall cannot be applied to variadic functions. + if (!IsVariadic) + return CC_X86RegCall; + break; } return Target->getDefaultCallingConv(TargetInfo::CCMT_Unknown); } diff --git a/lib/AST/CMakeLists.txt b/lib/AST/CMakeLists.txt index db771b5eb7..a6f1027856 100644 --- a/lib/AST/CMakeLists.txt +++ b/lib/AST/CMakeLists.txt @@ -49,6 +49,7 @@ add_clang_library(clangAST ODRHash.cpp OpenMPClause.cpp ParentMap.cpp + QualTypeNames.cpp RawCommentList.cpp RecordLayout.cpp RecordLayoutBuilder.cpp diff --git a/lib/AST/DeclBase.cpp b/lib/AST/DeclBase.cpp index 1e15ee98bb..29ce7ae034 100644 --- a/lib/AST/DeclBase.cpp +++ b/lib/AST/DeclBase.cpp @@ -1,4 +1,4 @@ -//===--- DeclBase.cpp - Declaration AST Node Implementation ---------------===// +//===- DeclBase.cpp - Declaration AST Node Implementation -----------------===// // // The LLVM Compiler Infrastructure // @@ -15,6 +15,7 @@ #include "clang/AST/ASTContext.h" #include "clang/AST/ASTMutationListener.h" #include "clang/AST/Attr.h" +#include "clang/AST/AttrIterator.h" #include "clang/AST/Decl.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/DeclContextInternals.h" @@ -25,11 +26,30 @@ #include "clang/AST/DependentDiagnostic.h" #include "clang/AST/ExternalASTSource.h" #include "clang/AST/Stmt.h" -#include "clang/AST/StmtCXX.h" #include "clang/AST/Type.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/LangOptions.h" +#include "clang/Basic/ObjCRuntime.h" +#include "clang/Basic/PartialDiagnostic.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetInfo.h" +#include "clang/Basic/VersionTuple.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/PointerIntPair.h" +#include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Casting.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> +#include <cassert> +#include <cstddef> +#include <string> +#include <tuple> +#include <utility> + using namespace clang; //===----------------------------------------------------------------------===// @@ -230,7 +250,6 @@ const DeclContext *Decl::getParentFunctionOrMethod() const { return nullptr; } - //===----------------------------------------------------------------------===// // PrettyStackTraceDecl Implementation //===----------------------------------------------------------------------===// @@ -260,7 +279,7 @@ void PrettyStackTraceDecl::print(raw_ostream &OS) const { //===----------------------------------------------------------------------===// // Out-of-line virtual method providing a home for Decl. -Decl::~Decl() { } +Decl::~Decl() = default; void Decl::setDeclContext(DeclContext *DC) { DeclCtx = DC; @@ -913,7 +932,6 @@ const FunctionType *Decl::getFunctionType(bool BlocksToo) const { return Ty->getAs<FunctionType>(); } - /// Starting at a given context (a Decl or DeclContext), look for a /// code context that is not a closure (a lambda, block, etc.). template <class T> static Decl *getNonClosureContext(T *D) { @@ -966,7 +984,7 @@ bool DeclContext::classof(const Decl *D) { } } -DeclContext::~DeclContext() { } +DeclContext::~DeclContext() = default; /// \brief Find the parent context of this context that will be /// used for unqualified name lookup. @@ -1057,15 +1075,14 @@ static bool isLinkageSpecContext(const DeclContext *DC, } bool DeclContext::isExternCContext() const { - return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_c); + return isLinkageSpecContext(this, LinkageSpecDecl::lang_c); } const LinkageSpecDecl *DeclContext::getExternCContext() const { const DeclContext *DC = this; while (DC->getDeclKind() != Decl::TranslationUnit) { if (DC->getDeclKind() == Decl::LinkageSpec && - cast<LinkageSpecDecl>(DC)->getLanguage() == - clang::LinkageSpecDecl::lang_c) + cast<LinkageSpecDecl>(DC)->getLanguage() == LinkageSpecDecl::lang_c) return cast<LinkageSpecDecl>(DC); DC = DC->getLexicalParent(); } @@ -1073,7 +1090,7 @@ const LinkageSpecDecl *DeclContext::getExternCContext() const { } bool DeclContext::isExternCXXContext() const { - return isLinkageSpecContext(this, clang::LinkageSpecDecl::lang_cxx); + return isLinkageSpecContext(this, LinkageSpecDecl::lang_cxx); } bool DeclContext::Encloses(const DeclContext *DC) const { @@ -1108,13 +1125,11 @@ DeclContext *DeclContext::getPrimaryContext() { case Decl::ObjCInterface: if (ObjCInterfaceDecl *Def = cast<ObjCInterfaceDecl>(this)->getDefinition()) return Def; - return this; case Decl::ObjCProtocol: if (ObjCProtocolDecl *Def = cast<ObjCProtocolDecl>(this)->getDefinition()) return Def; - return this; case Decl::ObjCCategory: diff --git a/lib/AST/ExternalASTSource.cpp b/lib/AST/ExternalASTSource.cpp index 182d38242f..198ba9d4fb 100644 --- a/lib/AST/ExternalASTSource.cpp +++ b/lib/AST/ExternalASTSource.cpp @@ -1,4 +1,4 @@ -//===- ExternalASTSource.cpp - Abstract External AST Interface --*- C++ -*-===// +//===- ExternalASTSource.cpp - Abstract External AST Interface ------------===// // // The LLVM Compiler Infrastructure // @@ -16,12 +16,16 @@ #include "clang/AST/ExternalASTSource.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclarationName.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/Module.h" +#include "llvm/ADT/None.h" #include "llvm/Support/ErrorHandling.h" +#include <cstdint> using namespace clang; -ExternalASTSource::~ExternalASTSource() { } +ExternalASTSource::~ExternalASTSource() = default; llvm::Optional<ExternalASTSource::ASTSourceDescriptor> ExternalASTSource::getSourceDescriptor(unsigned ID) { @@ -66,7 +70,7 @@ void ExternalASTSource::FinishedDeserializing() {} void ExternalASTSource::StartTranslationUnit(ASTConsumer *Consumer) {} -void ExternalASTSource::PrintStats() { } +void ExternalASTSource::PrintStats() {} bool ExternalASTSource::layoutRecordType( const RecordDecl *Record, uint64_t &Size, uint64_t &Alignment, diff --git a/lib/Tooling/Core/QualTypeNames.cpp b/lib/AST/QualTypeNames.cpp index 721c2c92fc..86c0eff9f7 100644 --- a/lib/Tooling/Core/QualTypeNames.cpp +++ b/lib/AST/QualTypeNames.cpp @@ -9,11 +9,11 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/Core/QualTypeNames.h" #include "clang/AST/DeclTemplate.h" #include "clang/AST/DeclarationName.h" #include "clang/AST/GlobalDecl.h" #include "clang/AST/Mangle.h" +#include "clang/AST/QualTypeNames.h" #include <stdio.h> #include <memory> @@ -21,17 +21,6 @@ namespace clang { namespace TypeName { -/// \brief Generates a QualType that can be used to name the same type -/// if used at the end of the current translation unit. This ignores -/// issues such as type shadowing. -/// -/// \param[in] QT - the type for which the fully qualified type will be -/// returned. -/// \param[in] Ctx - the ASTContext to be used. -/// \param[in] WithGlobalNsPrefix - Indicate whether the global namespace -/// specifier "::" should be prepended or not. -static QualType getFullyQualifiedType(QualType QT, const ASTContext &Ctx, - bool WithGlobalNsPrefix); /// \brief Create a NestedNameSpecifier for Namesp and its enclosing /// scopes. diff --git a/lib/Analysis/BodyFarm.cpp b/lib/Analysis/BodyFarm.cpp index 58a129c411..e5d3c5ce5b 100644 --- a/lib/Analysis/BodyFarm.cpp +++ b/lib/Analysis/BodyFarm.cpp @@ -96,8 +96,8 @@ public: /// Create a Return statement. ReturnStmt *makeReturn(const Expr *RetVal); - /// Create an integer literal. - IntegerLiteral *makeIntegerLiteral(uint64_t value); + /// Create an integer literal expression of the given type. + IntegerLiteral *makeIntegerLiteral(uint64_t Value, QualType Ty); /// Create a member expression. MemberExpr *makeMemberExpression(Expr *base, ValueDecl *MemberDecl, @@ -206,11 +206,9 @@ ReturnStmt *ASTMaker::makeReturn(const Expr *RetVal) { nullptr); } -IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t value) { - return IntegerLiteral::Create(C, - llvm::APInt( - /*numBits=*/C.getTypeSize(C.IntTy), value), - /*QualType=*/C.IntTy, SourceLocation()); +IntegerLiteral *ASTMaker::makeIntegerLiteral(uint64_t Value, QualType Ty) { + llvm::APInt APValue = llvm::APInt(C.getTypeSize(Ty), Value); + return IntegerLiteral::Create(C, APValue, Ty, SourceLocation()); } MemberExpr *ASTMaker::makeMemberExpression(Expr *base, ValueDecl *MemberDecl, @@ -325,6 +323,16 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { const ParmVarDecl *Flag = D->getParamDecl(0); const ParmVarDecl *Callback = D->getParamDecl(1); + + if (!Callback->getType()->isReferenceType()) { + llvm::dbgs() << "libcxx03 std::call_once implementation, skipping.\n"; + return nullptr; + } + if (!Flag->getType()->isReferenceType()) { + llvm::dbgs() << "unknown std::call_once implementation, skipping.\n"; + return nullptr; + } + QualType CallbackType = Callback->getType().getNonReferenceType(); // Nullable pointer, non-null iff function is a CXXRecordDecl. @@ -346,15 +354,13 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { // Otherwise, try libstdc++ implementation, with a field // `_M_once` if (!FlagFieldDecl) { - DEBUG(llvm::dbgs() << "No field __state_ found on std::once_flag struct, " - << "assuming libstdc++ implementation\n"); FlagFieldDecl = M.findMemberField(FlagRecordDecl, "_M_once"); } if (!FlagFieldDecl) { - DEBUG(llvm::dbgs() << "No field _M_once found on std::once flag struct: " - << "unknown std::call_once implementation, " - << "ignoring the call"); + DEBUG(llvm::dbgs() << "No field _M_once or __state_ found on " + << "std::once_flag struct: unknown std::call_once " + << "implementation, ignoring the call."); return nullptr; } @@ -388,9 +394,9 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { // First two arguments are used for the flag and for the callback. if (D->getNumParams() != CallbackFunctionType->getNumParams() + 2) { - DEBUG(llvm::dbgs() << "Number of params of the callback does not match " - << "the number of params passed to std::call_once, " - << "ignoring the call"); + DEBUG(llvm::dbgs() << "Types of params of the callback do not match " + << "params passed to std::call_once, " + << "ignoring the call\n"); return nullptr; } @@ -439,7 +445,8 @@ static Stmt *create_call_once(ASTContext &C, const FunctionDecl *D) { // Create assignment. BinaryOperator *FlagAssignment = M.makeAssignment( - Deref, M.makeIntegralCast(M.makeIntegerLiteral(1), DerefType), DerefType); + Deref, M.makeIntegralCast(M.makeIntegerLiteral(1, C.IntTy), DerefType), + DerefType); IfStmt *Out = new (C) IfStmt(C, SourceLocation(), @@ -478,8 +485,8 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { // sets it, and calls the block. Basically, an AST dump of: // // void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) { - // if (!*predicate) { - // *predicate = 1; + // if (*predicate != ~0l) { + // *predicate = ~0l; // block(); // } // } @@ -496,7 +503,9 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { /*SourceLocation=*/SourceLocation()); // (2) Create the assignment to the predicate. - IntegerLiteral *IL = M.makeIntegerLiteral(1); + Expr *DoneValue = + new (C) UnaryOperator(M.makeIntegerLiteral(0, C.LongTy), UO_Not, C.LongTy, + VK_RValue, OK_Ordinary, SourceLocation()); BinaryOperator *B = M.makeAssignment( @@ -504,7 +513,7 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { M.makeLvalueToRvalue( M.makeDeclRefExpr(Predicate), PredicateQPtrTy), PredicateTy), - M.makeIntegralCast(IL, PredicateTy), + M.makeIntegralCast(DoneValue, PredicateTy), PredicateTy); // (3) Create the compound statement. @@ -520,20 +529,14 @@ static Stmt *create_dispatch_once(ASTContext &C, const FunctionDecl *D) { PredicateQPtrTy), PredicateTy), PredicateTy); - - UnaryOperator *UO = new (C) UnaryOperator( - /* input=*/ LValToRval, - /* opc=*/ UO_LNot, - /* QualType=*/ C.IntTy, - /* ExprValueKind=*/ VK_RValue, - /* ExprObjectKind=*/ OK_Ordinary, SourceLocation()); - + + Expr *GuardCondition = M.makeComparison(LValToRval, DoneValue, BO_NE); // (5) Create the 'if' statement. IfStmt *If = new (C) IfStmt(C, SourceLocation(), /* IsConstexpr=*/ false, /* init=*/ nullptr, /* var=*/ nullptr, - /* cond=*/ UO, + /* cond=*/ GuardCondition, /* then=*/ CS); return If; } diff --git a/lib/Basic/IdentifierTable.cpp b/lib/Basic/IdentifierTable.cpp index fe7829ec50..2bed531ae3 100644 --- a/lib/Basic/IdentifierTable.cpp +++ b/lib/Basic/IdentifierTable.cpp @@ -1,4 +1,4 @@ -//===--- IdentifierTable.cpp - Hash table for identifier lookup -----------===// +//===- IdentifierTable.cpp - Hash table for identifier lookup -------------===// // // The LLVM Compiler Infrastructure // @@ -12,17 +12,24 @@ // //===----------------------------------------------------------------------===// -#include "clang/Basic/CharInfo.h" #include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/CharInfo.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/OperatorKinds.h" #include "clang/Basic/Specifiers.h" -#include "llvm/ADT/DenseMap.h" +#include "clang/Basic/TokenKinds.h" +#include "llvm/ADT/DenseMapInfo.h" #include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include <cassert> #include <cstdio> +#include <cstring> +#include <string> using namespace clang; @@ -46,27 +53,27 @@ IdentifierInfo::IdentifierInfo() { RevertedTokenID = false; OutOfDate = false; IsModulesImport = false; - FETokenInfo = nullptr; - Entry = nullptr; } //===----------------------------------------------------------------------===// // IdentifierTable Implementation //===----------------------------------------------------------------------===// -IdentifierIterator::~IdentifierIterator() { } +IdentifierIterator::~IdentifierIterator() = default; -IdentifierInfoLookup::~IdentifierInfoLookup() {} +IdentifierInfoLookup::~IdentifierInfoLookup() = default; namespace { - /// \brief A simple identifier lookup iterator that represents an - /// empty sequence of identifiers. - class EmptyLookupIterator : public IdentifierIterator - { - public: - StringRef Next() override { return StringRef(); } - }; -} + +/// \brief A simple identifier lookup iterator that represents an +/// empty sequence of identifiers. +class EmptyLookupIterator : public IdentifierIterator +{ +public: + StringRef Next() override { return StringRef(); } +}; + +} // namespace IdentifierIterator *IdentifierInfoLookup::getIdentifiers() { return new EmptyLookupIterator(); @@ -76,11 +83,9 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts, IdentifierInfoLookup* externalLookup) : HashTable(8192), // Start with space for 8K identifiers. ExternalLookup(externalLookup) { - // Populate the identifier table with info about keywords for the current // language. AddKeywords(LangOpts); - // Add the '_experimental_modules_import' contextual keyword. get("import").setModulesImport(true); @@ -92,6 +97,7 @@ IdentifierTable::IdentifierTable(const LangOptions &LangOpts, // Constants for TokenKinds.def namespace { + enum { KEYC99 = 0x1, KEYCXX = 0x2, @@ -127,7 +133,8 @@ namespace { KS_Enabled, // Enabled KS_Future // Is a keyword in future standard }; -} + +} // namespace /// \brief Translates flags as specified in TokenKinds.def into keyword status /// in the given language standard. @@ -366,6 +373,7 @@ unsigned llvm::DenseMapInfo<clang::Selector>::getHashValue(clang::Selector S) { } namespace clang { + /// MultiKeywordSelector - One of these variable length records is kept for each /// selector containing more than one keyword. We use a folding set /// to unique aggregate names (keyword selectors in ObjC parlance). Access to @@ -375,6 +383,7 @@ class MultiKeywordSelector MultiKeywordSelector(unsigned nKeys) { ExtraKindOrNumArgs = NUM_EXTRA_KINDS + nKeys; } + public: // Constructor for keyword selectors. MultiKeywordSelector(unsigned nKeys, IdentifierInfo **IIV) { @@ -392,28 +401,34 @@ public: unsigned getNumArgs() const { return ExtraKindOrNumArgs - NUM_EXTRA_KINDS; } - typedef IdentifierInfo *const *keyword_iterator; + using keyword_iterator = IdentifierInfo *const *; + keyword_iterator keyword_begin() const { return reinterpret_cast<keyword_iterator>(this+1); } + keyword_iterator keyword_end() const { return keyword_begin()+getNumArgs(); } + IdentifierInfo *getIdentifierInfoForSlot(unsigned i) const { assert(i < getNumArgs() && "getIdentifierInfoForSlot(): illegal index"); return keyword_begin()[i]; } + static void Profile(llvm::FoldingSetNodeID &ID, keyword_iterator ArgTys, unsigned NumArgs) { ID.AddInteger(NumArgs); for (unsigned i = 0; i != NumArgs; ++i) ID.AddPointer(ArgTys[i]); } + void Profile(llvm::FoldingSetNodeID &ID) { Profile(ID, keyword_begin(), getNumArgs()); } }; -} // end namespace clang. + +} // namespace clang. unsigned Selector::getNumArgs() const { unsigned IIF = getIdentifierInfoFlag(); @@ -431,6 +446,7 @@ IdentifierInfo *Selector::getIdentifierInfoForSlot(unsigned argIndex) const { assert(argIndex == 0 && "illegal keyword index"); return getAsIdentifierInfo(); } + // We point to a MultiKeywordSelector. MultiKeywordSelector *SI = getMultiKeywordSelector(); return SI->getIdentifierInfoForSlot(argIndex); @@ -592,11 +608,13 @@ ObjCStringFormatFamily Selector::getStringFormatFamilyImpl(Selector sel) { } namespace { - struct SelectorTableImpl { - llvm::FoldingSet<MultiKeywordSelector> Table; - llvm::BumpPtrAllocator Allocator; - }; -} // end anonymous namespace. + +struct SelectorTableImpl { + llvm::FoldingSet<MultiKeywordSelector> Table; + llvm::BumpPtrAllocator Allocator; +}; + +} // namespace static SelectorTableImpl &getSelectorTableImpl(void *P) { return *static_cast<SelectorTableImpl*>(P); diff --git a/lib/Basic/Module.cpp b/lib/Basic/Module.cpp index 621b1b23d7..7124184865 100644 --- a/lib/Basic/Module.cpp +++ b/lib/Basic/Module.cpp @@ -1,4 +1,4 @@ -//===--- Module.cpp - Describe a module -----------------------------------===// +//===- Module.cpp - Describe a module -------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -16,23 +16,33 @@ #include "clang/Basic/CharInfo.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/LangOptions.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/TargetInfo.h" #include "llvm/ADT/ArrayRef.h" #include "llvm/ADT/SmallVector.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/Support/Compiler.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cassert> +#include <functional> +#include <string> +#include <utility> +#include <vector> using namespace clang; Module::Module(StringRef Name, SourceLocation DefinitionLoc, Module *Parent, bool IsFramework, bool IsExplicit, unsigned VisibilityID) - : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), Directory(), - Umbrella(), ASTFile(nullptr), VisibilityID(VisibilityID), - IsMissingRequirement(false), HasIncompatibleModuleFile(false), - IsAvailable(true), IsFromModuleFile(false), IsFramework(IsFramework), - IsExplicit(IsExplicit), IsSystem(false), IsExternC(false), - IsInferred(false), InferSubmodules(false), InferExplicitSubmodules(false), + : Name(Name), DefinitionLoc(DefinitionLoc), Parent(Parent), + VisibilityID(VisibilityID), IsMissingRequirement(false), + HasIncompatibleModuleFile(false), IsAvailable(true), + IsFromModuleFile(false), IsFramework(IsFramework), IsExplicit(IsExplicit), + IsSystem(false), IsExternC(false), IsInferred(false), + InferSubmodules(false), InferExplicitSubmodules(false), InferExportWildcard(false), ConfigMacrosExhaustive(false), NoUndeclaredIncludes(false), NameVisibility(Hidden) { if (Parent) { @@ -130,6 +140,7 @@ static StringRef getModuleNameFromComponent( const std::pair<std::string, SourceLocation> &IdComponent) { return IdComponent.first; } + static StringRef getModuleNameFromComponent(StringRef R) { return R; } template<typename InputIter> diff --git a/lib/Basic/SanitizerSpecialCaseList.cpp b/lib/Basic/SanitizerSpecialCaseList.cpp index 4dd52ee870..ee8feecbce 100644 --- a/lib/Basic/SanitizerSpecialCaseList.cpp +++ b/lib/Basic/SanitizerSpecialCaseList.cpp @@ -57,7 +57,7 @@ bool SanitizerSpecialCaseList::inSection(SanitizerMask Mask, StringRef Prefix, StringRef Category) const { for (auto &S : SanitizerSections) if ((S.Mask & Mask) && - SpecialCaseList::inSection(S.Entries, Prefix, Query, Category)) + SpecialCaseList::inSectionBlame(S.Entries, Prefix, Query, Category)) return true; return false; diff --git a/lib/Basic/SourceManager.cpp b/lib/Basic/SourceManager.cpp index 620f05c637..e664879639 100644 --- a/lib/Basic/SourceManager.cpp +++ b/lib/Basic/SourceManager.cpp @@ -1,4 +1,4 @@ -//===--- SourceManager.cpp - Track and cache source files -----------------===// +//===- SourceManager.cpp - Track and cache source files -------------------===// // // The LLVM Compiler Infrastructure // @@ -14,17 +14,33 @@ #include "clang/Basic/SourceManager.h" #include "clang/Basic/Diagnostic.h" #include "clang/Basic/FileManager.h" +#include "clang/Basic/LLVM.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManagerInternals.h" +#include "llvm/ADT/DenseMap.h" #include "llvm/ADT/Optional.h" +#include "llvm/ADT/None.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringSwitch.h" +#include "llvm/ADT/StringRef.h" +#include "llvm/Support/Allocator.h" #include "llvm/Support/Capacity.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/ErrorHandling.h" +#include "llvm/Support/FileSystem.h" +#include "llvm/Support/MathExtras.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> -#include <cstring> +#include <cassert> +#include <cstddef> +#include <cstdint> +#include <memory> +#include <tuple> +#include <utility> +#include <vector> using namespace clang; using namespace SrcMgr; @@ -222,7 +238,6 @@ void LineTableInfo::AddLineNote(FileID FID, unsigned Offset, unsigned LineNo, IncludeOffset)); } - /// FindNearestLineEntry - Find the line entry nearest to FID that is before /// it. If there is no line entry before Offset in FID, return null. const LineEntry *LineTableInfo::FindNearestLineEntry(FileID FID, @@ -250,7 +265,6 @@ void LineTableInfo::AddEntry(FileID FID, } /// getLineTableFilenameID - Return the uniqued ID for the specified filename. -/// unsigned SourceManager::getLineTableFilenameID(StringRef Name) { return getLineTable().getLineTableFilenameID(Name); } @@ -298,10 +312,7 @@ LineTableInfo &SourceManager::getLineTable() { SourceManager::SourceManager(DiagnosticsEngine &Diag, FileManager &FileMgr, bool UserFilesAreVolatile) - : Diag(Diag), FileMgr(FileMgr), OverridenFilesKeepOriginalName(true), - UserFilesAreVolatile(UserFilesAreVolatile), FilesAreTransient(false), - ExternalSLocEntries(nullptr), LineTable(nullptr), NumLinearScans(0), - NumBinaryProbes(0) { + : Diag(Diag), FileMgr(FileMgr), UserFilesAreVolatile(UserFilesAreVolatile) { clearIDTables(); Diag.setSourceManager(this); } @@ -342,7 +353,7 @@ void SourceManager::clearIDTables() { // Use up FileID #0 as an invalid expansion. NextLocalOffset = 0; CurrentLoadedOffset = MaxLoadedOffset; - createExpansionLoc(SourceLocation(),SourceLocation(),SourceLocation(), 1); + createExpansionLoc(SourceLocation(), SourceLocation(), SourceLocation(), 1); } void SourceManager::initializeForReplay(const SourceManager &Old) { @@ -408,7 +419,6 @@ SourceManager::getOrCreateContentCache(const FileEntry *FileEnt, return Entry; } - /// Create a new ContentCache for the specified memory buffer. /// This does no caching. const ContentCache * @@ -716,7 +726,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { // Find the FileID that contains this. "I" is an iterator that points to a // FileID whose offset is known to be larger than SLocOffset. unsigned NumProbes = 0; - while (1) { + while (true) { --I; if (I->getOffset() <= SLocOffset) { FileID Res = FileID::get(int(I - LocalSLocEntryTable.begin())); @@ -740,7 +750,7 @@ FileID SourceManager::getFileIDLocal(unsigned SLocOffset) const { // SLocOffset. unsigned LessIndex = 0; NumProbes = 0; - while (1) { + while (true) { bool Invalid = false; unsigned MiddleIndex = (GreaterIndex-LessIndex)/2+LessIndex; unsigned MidOffset = getLocalSLocEntry(MiddleIndex, &Invalid).getOffset(); @@ -817,7 +827,7 @@ FileID SourceManager::getFileIDLoaded(unsigned SLocOffset) const { unsigned GreaterIndex = I; unsigned LessIndex = LoadedSLocEntryTable.size(); NumProbes = 0; - while (1) { + while (true) { ++NumProbes; unsigned MiddleIndex = (LessIndex - GreaterIndex) / 2 + GreaterIndex; const SrcMgr::SLocEntry &E = getLoadedSLocEntry(MiddleIndex); @@ -935,7 +945,6 @@ SourceLocation SourceManager::getImmediateSpellingLoc(SourceLocation Loc) const{ return Loc.getLocWithOffset(LocInfo.second); } - /// getImmediateExpansionRange - Loc is required to be an expansion location. /// Return the start/end of the expansion information. std::pair<SourceLocation,SourceLocation> @@ -1055,7 +1064,6 @@ bool SourceManager::isAtEndOfImmediateMacroExpansion(SourceLocation Loc, return true; } - //===----------------------------------------------------------------------===// // Queries about the code at a SourceLocation. //===----------------------------------------------------------------------===// @@ -1084,7 +1092,6 @@ const char *SourceManager::getCharacterData(SourceLocation SL, return Buffer->getBufferStart() + (CharDataInvalid? 0 : LocInfo.second); } - /// getColumnNumber - Return the column # for the specified file position. /// this is significantly cheaper to compute than the line number. unsigned SourceManager::getColumnNumber(FileID FID, unsigned FilePos, @@ -1189,7 +1196,7 @@ static void ComputeLineNumbers(DiagnosticsEngine &Diag, ContentCache *FI, const unsigned char *Buf = (const unsigned char *)Buffer->getBufferStart(); const unsigned char *End = (const unsigned char *)Buffer->getBufferEnd(); unsigned Offs = 0; - while (1) { + while (true) { // Skip over the contents of the line. const unsigned char *NextBuf = (const unsigned char *)Buf; @@ -1419,7 +1426,6 @@ StringRef SourceManager::getBufferName(SourceLocation Loc, return getBuffer(getFileID(Loc), Invalid)->getBufferIdentifier(); } - /// getPresumedLoc - This method returns the "presumed" location of a /// SourceLocation specifies. A "presumed location" can be modified by \#line /// or GNU line marker directives. This provides a view on the data that a @@ -1767,7 +1773,7 @@ void SourceManager::computeMacroArgsCache(MacroArgsMap &MacroArgsCache, MacroArgsCache.insert(std::make_pair(0, SourceLocation())); int ID = FID.ID; - while (1) { + while (true) { ++ID; // Stop if there are no more FileIDs to check. if (ID > 0) { @@ -1830,7 +1836,7 @@ void SourceManager::associateFileChunkWithMacroArgExp( FileID SpellFID; // Current FileID in the spelling range. unsigned SpellRelativeOffs; std::tie(SpellFID, SpellRelativeOffs) = getDecomposedLoc(SpellLoc); - while (1) { + while (true) { const SLocEntry &Entry = getSLocEntry(SpellFID); unsigned SpellFIDBeginOffs = Entry.getOffset(); unsigned SpellFIDSize = getFileIDSize(SpellFID); @@ -1857,7 +1863,6 @@ void SourceManager::associateFileChunkWithMacroArgExp( ++SpellFID.ID; SpellRelativeOffs = 0; } - } assert(SpellLoc.isFileID()); @@ -1937,8 +1942,8 @@ SourceManager::getDecomposedIncludedLoc(FileID FID) const { // Uses IncludedLocMap to retrieve/cache the decomposed loc. - typedef std::pair<FileID, unsigned> DecompTy; - typedef llvm::DenseMap<FileID, DecompTy> MapTy; + using DecompTy = std::pair<FileID, unsigned>; + using MapTy = llvm::DenseMap<FileID, DecompTy>; std::pair<MapTy::iterator, bool> InsertOp = IncludedLocMap.insert(std::make_pair(FID, DecompTy())); DecompTy &DecompLoc = InsertOp.first->second; @@ -2085,7 +2090,7 @@ std::pair<bool, bool> SourceManager::isInTheSameTranslationUnit( // of the other looking for a match. // We use a map from FileID to Offset to store the chain. Easier than writing // a custom set hash info that only depends on the first part of a pair. - typedef llvm::SmallDenseMap<FileID, unsigned, 16> LocSet; + using LocSet = llvm::SmallDenseMap<FileID, unsigned, 16>; LocSet LChain; do { LChain.insert(LOffs); @@ -2197,7 +2202,7 @@ LLVM_DUMP_METHOD void SourceManager::dump() const { } } -ExternalSLocEntrySource::~ExternalSLocEntrySource() { } +ExternalSLocEntrySource::~ExternalSLocEntrySource() = default; /// Return the amount of memory used by memory buffers, breaking down /// by heap-backed versus mmap'ed memory. diff --git a/lib/Basic/Targets/X86.cpp b/lib/Basic/Targets/X86.cpp index ee70c14e1d..a08ba478a0 100644 --- a/lib/Basic/Targets/X86.cpp +++ b/lib/Basic/Targets/X86.cpp @@ -1121,6 +1121,8 @@ void X86TargetInfo::getTargetDefines(const LangOptions &Opts, bool X86TargetInfo::isValidFeatureName(StringRef Name) const { return llvm::StringSwitch<bool>(Name) + .Case("3dnow", true) + .Case("3dnowa", true) .Case("aes", true) .Case("avx", true) .Case("avx2", true) diff --git a/lib/CodeGen/CGBuiltin.cpp b/lib/CodeGen/CGBuiltin.cpp index bc37afa284..369240f316 100644 --- a/lib/CodeGen/CGBuiltin.cpp +++ b/lib/CodeGen/CGBuiltin.cpp @@ -8142,32 +8142,6 @@ Value *CodeGenFunction::EmitX86BuiltinExpr(unsigned BuiltinID, case X86::BI__builtin_ia32_selectpd_256: case X86::BI__builtin_ia32_selectpd_512: return EmitX86Select(*this, Ops[0], Ops[1], Ops[2]); - case X86::BI__builtin_ia32_pcmpeqb128_mask: - case X86::BI__builtin_ia32_pcmpeqb256_mask: - case X86::BI__builtin_ia32_pcmpeqb512_mask: - case X86::BI__builtin_ia32_pcmpeqw128_mask: - case X86::BI__builtin_ia32_pcmpeqw256_mask: - case X86::BI__builtin_ia32_pcmpeqw512_mask: - case X86::BI__builtin_ia32_pcmpeqd128_mask: - case X86::BI__builtin_ia32_pcmpeqd256_mask: - case X86::BI__builtin_ia32_pcmpeqd512_mask: - case X86::BI__builtin_ia32_pcmpeqq128_mask: - case X86::BI__builtin_ia32_pcmpeqq256_mask: - case X86::BI__builtin_ia32_pcmpeqq512_mask: - return EmitX86MaskedCompare(*this, 0, false, Ops); - case X86::BI__builtin_ia32_pcmpgtb128_mask: - case X86::BI__builtin_ia32_pcmpgtb256_mask: - case X86::BI__builtin_ia32_pcmpgtb512_mask: - case X86::BI__builtin_ia32_pcmpgtw128_mask: - case X86::BI__builtin_ia32_pcmpgtw256_mask: - case X86::BI__builtin_ia32_pcmpgtw512_mask: - case X86::BI__builtin_ia32_pcmpgtd128_mask: - case X86::BI__builtin_ia32_pcmpgtd256_mask: - case X86::BI__builtin_ia32_pcmpgtd512_mask: - case X86::BI__builtin_ia32_pcmpgtq128_mask: - case X86::BI__builtin_ia32_pcmpgtq256_mask: - case X86::BI__builtin_ia32_pcmpgtq512_mask: - return EmitX86MaskedCompare(*this, 6, true, Ops); case X86::BI__builtin_ia32_cmpb128_mask: case X86::BI__builtin_ia32_cmpb256_mask: case X86::BI__builtin_ia32_cmpb512_mask: @@ -9580,6 +9554,16 @@ Value *CodeGenFunction::EmitNVPTXBuiltinExpr(unsigned BuiltinID, return Builder.CreateCall(FnALAF32, {Ptr, Val}); } + case NVPTX::BI__nvvm_atom_add_gen_d: { + Value *Ptr = EmitScalarExpr(E->getArg(0)); + Value *Val = EmitScalarExpr(E->getArg(1)); + // atomicrmw only deals with integer arguments, so we need to use + // LLVM's nvvm_atomic_load_add_f64 intrinsic. + Value *FnALAF64 = + CGM.getIntrinsic(Intrinsic::nvvm_atomic_load_add_f64, Ptr->getType()); + return Builder.CreateCall(FnALAF64, {Ptr, Val}); + } + case NVPTX::BI__nvvm_atom_inc_gen_ui: { Value *Ptr = EmitScalarExpr(E->getArg(0)); Value *Val = EmitScalarExpr(E->getArg(1)); diff --git a/lib/CodeGen/CGCall.cpp b/lib/CodeGen/CGCall.cpp index 971455a873..cefd73be27 100644 --- a/lib/CodeGen/CGCall.cpp +++ b/lib/CodeGen/CGCall.cpp @@ -1855,6 +1855,16 @@ void CodeGenModule::ConstructAttributeList( !(TargetDecl && TargetDecl->hasAttr<NoSplitStackAttr>())) FuncAttrs.addAttribute("split-stack"); + // Add NonLazyBind attribute to function declarations when -fno-plt + // is used. + if (TargetDecl && CodeGenOpts.NoPLT) { + if (auto *Fn = dyn_cast<FunctionDecl>(TargetDecl)) { + if (!Fn->isDefined() && !AttrOnCallSite) { + FuncAttrs.addAttribute(llvm::Attribute::NonLazyBind); + } + } + } + if (!AttrOnCallSite) { bool DisableTailCalls = CodeGenOpts.DisableTailCalls || diff --git a/lib/CodeGen/CGOpenMPRuntime.cpp b/lib/CodeGen/CGOpenMPRuntime.cpp index 35929af95e..0846c6a041 100644 --- a/lib/CodeGen/CGOpenMPRuntime.cpp +++ b/lib/CodeGen/CGOpenMPRuntime.cpp @@ -1451,7 +1451,9 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, return ThreadID; } // If exceptions are enabled, do not use parameter to avoid possible crash. - if (!CGF.getInvokeDest()) { + if (!CGF.EHStack.requiresLandingPad() || !CGF.getLangOpts().Exceptions || + !CGF.getLangOpts().CXXExceptions || + CGF.Builder.GetInsertBlock() == CGF.AllocaInsertPt->getParent()) { if (auto *OMPRegionInfo = dyn_cast_or_null<CGOpenMPRegionInfo>(CGF.CapturedStmtInfo)) { if (OMPRegionInfo->getThreadIDVariable()) { @@ -1475,12 +1477,13 @@ llvm::Value *CGOpenMPRuntime::getThreadID(CodeGenFunction &CGF, // function. CGBuilderTy::InsertPointGuard IPG(CGF.Builder); CGF.Builder.SetInsertPoint(CGF.AllocaInsertPt); - ThreadID = - CGF.EmitRuntimeCall(createRuntimeFunction(OMPRTL__kmpc_global_thread_num), - emitUpdateLocation(CGF, Loc)); + auto *Call = CGF.Builder.CreateCall( + createRuntimeFunction(OMPRTL__kmpc_global_thread_num), + emitUpdateLocation(CGF, Loc)); + Call->setCallingConv(CGF.getRuntimeCC()); auto &Elem = OpenMPLocThreadIDMap.FindAndConstruct(CGF.CurFn); - Elem.second.ThreadID = ThreadID; - return ThreadID; + Elem.second.ThreadID = Call; + return Call; } void CGOpenMPRuntime::functionFinished(CodeGenFunction &CGF) { @@ -5975,22 +5978,21 @@ public: /// \brief Delete the element from the device environment, ignoring the /// current reference count associated with the element. OMP_MAP_DELETE = 0x08, - /// \brief The element being mapped is a pointer, therefore the pointee - /// should be mapped as well. - OMP_MAP_IS_PTR = 0x10, - /// \brief This flags signals that an argument is the first one relating to - /// a map/private clause expression. For some cases a single - /// map/privatization results in multiple arguments passed to the runtime - /// library. - OMP_MAP_FIRST_REF = 0x20, + /// \brief The element being mapped is a pointer-pointee pair; both the + /// pointer and the pointee should be mapped. + OMP_MAP_PTR_AND_OBJ = 0x10, + /// \brief This flags signals that the base address of an entry should be + /// passed to the target kernel as an argument. + OMP_MAP_TARGET_PARAM = 0x20, /// \brief Signal that the runtime library has to return the device pointer - /// in the current position for the data being mapped. - OMP_MAP_RETURN_PTR = 0x40, + /// in the current position for the data being mapped. Used when we have the + /// use_device_ptr clause. + OMP_MAP_RETURN_PARAM = 0x40, /// \brief This flag signals that the reference being passed is a pointer to /// private data. - OMP_MAP_PRIVATE_PTR = 0x80, + OMP_MAP_PRIVATE = 0x80, /// \brief Pass the element to the device by value. - OMP_MAP_PRIVATE_VAL = 0x100, + OMP_MAP_LITERAL = 0x100, /// Implicit map OMP_MAP_IMPLICIT = 0x200, }; @@ -6081,7 +6083,7 @@ private: /// expression. unsigned getMapTypeBits(OpenMPMapClauseKind MapType, OpenMPMapClauseKind MapTypeModifier, bool AddPtrFlag, - bool AddIsFirstFlag) const { + bool AddIsTargetParamFlag) const { unsigned Bits = 0u; switch (MapType) { case OMPC_MAP_alloc: @@ -6108,9 +6110,9 @@ private: break; } if (AddPtrFlag) - Bits |= OMP_MAP_IS_PTR; - if (AddIsFirstFlag) - Bits |= OMP_MAP_FIRST_REF; + Bits |= OMP_MAP_PTR_AND_OBJ; + if (AddIsTargetParamFlag) + Bits |= OMP_MAP_TARGET_PARAM; if (MapTypeModifier == OMPC_MAP_always) Bits |= OMP_MAP_ALWAYS; return Bits; @@ -6217,28 +6219,28 @@ private: // // map(s.p[:22], s.a s.b) // &s, &(s.p), sizeof(double*), noflags - // &(s.p), &(s.p[0]), 22*sizeof(double), ptr_flag + extra_flag + // &(s.p), &(s.p[0]), 22*sizeof(double), ptr_flag // // map(s.ps) // &s, &(s.ps), sizeof(S2*), noflags // // map(s.ps->s.i) // &s, &(s.ps), sizeof(S2*), noflags - // &(s.ps), &(s.ps->s.i), sizeof(int), ptr_flag + extra_flag + // &(s.ps), &(s.ps->s.i), sizeof(int), ptr_flag // // map(s.ps->ps) // &s, &(s.ps), sizeof(S2*), noflags - // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + extra_flag + // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag // // map(s.ps->ps->ps) // &s, &(s.ps), sizeof(S2*), noflags - // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + extra_flag - // &(s.ps->ps), &(s.ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag + // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + // &(s.ps->ps), &(s.ps->ps->ps), sizeof(S2*), ptr_flag // // map(s.ps->ps->s.f[:22]) // &s, &(s.ps), sizeof(S2*), noflags - // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + extra_flag - // &(s.ps->ps), &(s.ps->ps->s.f[0]), 22*sizeof(float), ptr_flag + extra_flag + // &(s.ps), &(s.ps->ps), sizeof(S2*), ptr_flag + // &(s.ps->ps), &(s.ps->ps->s.f[0]), 22*sizeof(float), ptr_flag // // map(ps) // &ps, &ps, sizeof(S2*), noflags @@ -6254,29 +6256,28 @@ private: // // map(ps->p[:22]) // ps, &(ps->p), sizeof(double*), noflags - // &(ps->p), &(ps->p[0]), 22*sizeof(double), ptr_flag + extra_flag + // &(ps->p), &(ps->p[0]), 22*sizeof(double), ptr_flag // // map(ps->ps) // ps, &(ps->ps), sizeof(S2*), noflags // // map(ps->ps->s.i) // ps, &(ps->ps), sizeof(S2*), noflags - // &(ps->ps), &(ps->ps->s.i), sizeof(int), ptr_flag + extra_flag + // &(ps->ps), &(ps->ps->s.i), sizeof(int), ptr_flag // // map(ps->ps->ps) // ps, &(ps->ps), sizeof(S2*), noflags - // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag + // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag // // map(ps->ps->ps->ps) // ps, &(ps->ps), sizeof(S2*), noflags - // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag - // &(ps->ps->ps), &(ps->ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag + // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + // &(ps->ps->ps), &(ps->ps->ps->ps), sizeof(S2*), ptr_flag // // map(ps->ps->ps->s.f[:22]) // ps, &(ps->ps), sizeof(S2*), noflags - // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + extra_flag - // &(ps->ps->ps), &(ps->ps->ps->s.f[0]), 22*sizeof(float), ptr_flag + - // extra_flag + // &(ps->ps), &(ps->ps->ps), sizeof(S2*), ptr_flag + // &(ps->ps->ps), &(ps->ps->ps->s.f[0]), 22*sizeof(float), ptr_flag // Track if the map information being generated is the first for a capture. bool IsCaptureFirstInfo = IsFirstComponentList; @@ -6416,7 +6417,7 @@ private: // 'private ptr' and 'map to' flag. Return the right flags if the captured // declaration is known as first-private in this handler. if (FirstPrivateDecls.count(Cap.getCapturedVar())) - return MappableExprsHandler::OMP_MAP_PRIVATE_PTR | + return MappableExprsHandler::OMP_MAP_PRIVATE | MappableExprsHandler::OMP_MAP_TO; // We didn't modify anything. @@ -6557,7 +6558,7 @@ public: BasePointers.push_back({Ptr, VD}); Pointers.push_back(Ptr); Sizes.push_back(llvm::Constant::getNullValue(this->CGF.SizeTy)); - Types.push_back(OMP_MAP_RETURN_PTR | OMP_MAP_FIRST_REF); + Types.push_back(OMP_MAP_RETURN_PARAM | OMP_MAP_TARGET_PARAM); } for (auto &M : Info) { @@ -6595,7 +6596,7 @@ public: "No relevant declaration related with device pointer??"); BasePointers[CurrentBasePointersIdx].setDevicePtrDecl(RelevantVD); - Types[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PTR; + Types[CurrentBasePointersIdx] |= OMP_MAP_RETURN_PARAM; } IsFirstComponentList = false; } @@ -6647,7 +6648,7 @@ public: BasePointers.push_back({Arg, VD}); Pointers.push_back(Arg); Sizes.push_back(CGF.getTypeSize(CGF.getContext().VoidPtrTy)); - Types.push_back(OMP_MAP_PRIVATE_VAL | OMP_MAP_FIRST_REF); + Types.push_back(OMP_MAP_LITERAL | OMP_MAP_TARGET_PARAM); return; } @@ -6690,7 +6691,7 @@ public: if (!RI.getType()->isAnyPointerType()) { // We have to signal to the runtime captures passed by value that are // not pointers. - CurMapTypes.push_back(OMP_MAP_PRIVATE_VAL); + CurMapTypes.push_back(OMP_MAP_LITERAL); CurSizes.push_back(CGF.getTypeSize(RI.getType())); } else { // Pointers are implicitly mapped with a zero size and no flags @@ -6720,9 +6721,8 @@ public: CurMapTypes.back() = adjustMapModifiersForPrivateClauses(CI, CurMapTypes.back()); } - // Every default map produces a single argument, so, it is always the - // first one. - CurMapTypes.back() |= OMP_MAP_FIRST_REF; + // Every default map produces a single argument which is a target parameter. + CurMapTypes.back() |= OMP_MAP_TARGET_PARAM; } }; @@ -6922,8 +6922,8 @@ void CGOpenMPRuntime::emitTargetCall(CodeGenFunction &CGF, CurPointers.push_back(*CV); CurSizes.push_back(CGF.getTypeSize(RI->getType())); // Copy to the device as an argument. No need to retrieve it. - CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_PRIVATE_VAL | - MappableExprsHandler::OMP_MAP_FIRST_REF); + CurMapTypes.push_back(MappableExprsHandler::OMP_MAP_LITERAL | + MappableExprsHandler::OMP_MAP_TARGET_PARAM); } else { // If we have any information in the map clause, we use it, otherwise we // just do a default mapping. diff --git a/lib/CodeGen/CodeGenFunction.cpp b/lib/CodeGen/CodeGenFunction.cpp index 234d1a2849..3b60b996ca 100644 --- a/lib/CodeGen/CodeGenFunction.cpp +++ b/lib/CodeGen/CodeGenFunction.cpp @@ -87,7 +87,7 @@ CodeGenFunction::CodeGenFunction(CodeGenModule &cgm, bool suppressNewContext) llvm::FastMathFlags FMF; if (CGM.getLangOpts().FastMath) - FMF.setUnsafeAlgebra(); + FMF.setFast(); if (CGM.getLangOpts().FiniteMathOnly) { FMF.setNoNaNs(); FMF.setNoInfs(); diff --git a/lib/CodeGen/CodeGenModule.cpp b/lib/CodeGen/CodeGenModule.cpp index b2a18a03f2..61a1ed2393 100644 --- a/lib/CodeGen/CodeGenModule.cpp +++ b/lib/CodeGen/CodeGenModule.cpp @@ -2284,7 +2284,8 @@ CodeGenModule::CreateRuntimeFunction(llvm::FunctionType *FTy, StringRef Name, F->setCallingConv(getRuntimeCC()); if (!Local && getTriple().isOSBinFormatCOFF() && - !getCodeGenOpts().LTOVisibilityPublicStd) { + !getCodeGenOpts().LTOVisibilityPublicStd && + !getTriple().isWindowsGNUEnvironment()) { const FunctionDecl *FD = GetRuntimeFunctionDecl(Context, Name); if (!FD || FD->hasAttr<DLLImportAttr>()) { F->setDLLStorageClass(llvm::GlobalValue::DLLImportStorageClass); @@ -4030,6 +4031,13 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { case Decl::Namespace: EmitDeclContext(cast<NamespaceDecl>(D)); break; + case Decl::ClassTemplateSpecialization: { + const auto *Spec = cast<ClassTemplateSpecializationDecl>(D); + if (DebugInfo && + Spec->getSpecializationKind() == TSK_ExplicitInstantiationDefinition && + Spec->hasDefinition()) + DebugInfo->completeTemplateDefinition(*Spec); + } LLVM_FALLTHROUGH; case Decl::CXXRecord: if (DebugInfo) { if (auto *ES = D->getASTContext().getExternalSource()) @@ -4216,15 +4224,6 @@ void CodeGenModule::EmitTopLevelDecl(Decl *D) { EmitOMPThreadPrivateDecl(cast<OMPThreadPrivateDecl>(D)); break; - case Decl::ClassTemplateSpecialization: { - const auto *Spec = cast<ClassTemplateSpecializationDecl>(D); - if (DebugInfo && - Spec->getSpecializationKind() == TSK_ExplicitInstantiationDefinition && - Spec->hasDefinition()) - DebugInfo->completeTemplateDefinition(*Spec); - break; - } - case Decl::OMPDeclareReduction: EmitOMPDeclareReduction(cast<OMPDeclareReductionDecl>(D)); break; diff --git a/lib/CodeGen/TargetInfo.cpp b/lib/CodeGen/TargetInfo.cpp index b1773b7090..4b8006428f 100644 --- a/lib/CodeGen/TargetInfo.cpp +++ b/lib/CodeGen/TargetInfo.cpp @@ -6319,7 +6319,7 @@ public: return occupiesMoreThan(CGT, scalars, /*total*/ 4); } bool isSwiftErrorInRegister() const override { - return true; + return false; } }; diff --git a/lib/Driver/Driver.cpp b/lib/Driver/Driver.cpp index 765b006e90..e14a596d98 100644 --- a/lib/Driver/Driver.cpp +++ b/lib/Driver/Driver.cpp @@ -3880,7 +3880,13 @@ const ToolChain &Driver::getToolChain(const ArgList &Args, break; case llvm::Triple::MSVC: case llvm::Triple::UnknownEnvironment: - TC = llvm::make_unique<toolchains::MSVCToolChain>(*this, Target, Args); + if (Args.getLastArgValue(options::OPT_fuse_ld_EQ) + .startswith_lower("bfd")) + TC = llvm::make_unique<toolchains::CrossWindowsToolChain>( + *this, Target, Args); + else + TC = + llvm::make_unique<toolchains::MSVCToolChain>(*this, Target, Args); break; } break; diff --git a/lib/Driver/SanitizerArgs.cpp b/lib/Driver/SanitizerArgs.cpp index 32c1c43a5b..8d9f32f848 100644 --- a/lib/Driver/SanitizerArgs.cpp +++ b/lib/Driver/SanitizerArgs.cpp @@ -30,7 +30,7 @@ enum : SanitizerMask { NeedsUbsanCxxRt = Vptr | CFI, NotAllowedWithTrap = Vptr, NotAllowedWithMinimalRuntime = Vptr, - RequiresPIE = DataFlow, + RequiresPIE = DataFlow | Scudo, NeedsUnwindTables = Address | Thread | Memory | DataFlow, SupportsCoverage = Address | KernelAddress | Memory | Leak | Undefined | Integer | Nullability | DataFlow | Fuzzer | FuzzerNoLink, @@ -173,7 +173,7 @@ static SanitizerMask parseSanitizeTrapArgs(const Driver &D, bool SanitizerArgs::needsUbsanRt() const { // All of these include ubsan. if (needsAsanRt() || needsMsanRt() || needsTsanRt() || needsDfsanRt() || - needsLsanRt() || needsCfiDiagRt()) + needsLsanRt() || needsCfiDiagRt() || needsScudoRt()) return false; return (Sanitizers.Mask & NeedsUbsanRt & ~TrapSanitizers.Mask) || @@ -370,17 +370,14 @@ SanitizerArgs::SanitizerArgs(const ToolChain &TC, // Warn about incompatible groups of sanitizers. std::pair<SanitizerMask, SanitizerMask> IncompatibleGroups[] = { - std::make_pair(Address, Thread), std::make_pair(Address, Memory), - std::make_pair(Thread, Memory), std::make_pair(Leak, Thread), - std::make_pair(Leak, Memory), std::make_pair(KernelAddress, Address), - std::make_pair(KernelAddress, Leak), - std::make_pair(KernelAddress, Thread), - std::make_pair(KernelAddress, Memory), - std::make_pair(Efficiency, Address), - std::make_pair(Efficiency, Leak), - std::make_pair(Efficiency, Thread), - std::make_pair(Efficiency, Memory), - std::make_pair(Efficiency, KernelAddress)}; + std::make_pair(Address, Thread | Memory), + std::make_pair(Thread, Memory), + std::make_pair(Leak, Thread | Memory), + std::make_pair(KernelAddress, Address| Leak | Thread | Memory), + std::make_pair(Efficiency, Address | Leak | Thread | Memory | + KernelAddress), + std::make_pair(Scudo, Address | Leak | Thread | Memory | KernelAddress | + Efficiency) }; for (auto G : IncompatibleGroups) { SanitizerMask Group = G.first; if (Kinds & Group) { diff --git a/lib/Driver/ToolChains/Clang.cpp b/lib/Driver/ToolChains/Clang.cpp index c1c8813cc4..758ece19e1 100644 --- a/lib/Driver/ToolChains/Clang.cpp +++ b/lib/Driver/ToolChains/Clang.cpp @@ -3423,6 +3423,10 @@ void Clang::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back("-mpie-copy-relocations"); } + if (Args.hasFlag(options::OPT_fno_plt, options::OPT_fplt, false)) { + CmdArgs.push_back("-fno-plt"); + } + // -fhosted is default. // TODO: Audit uses of KernelOrKext and see where it'd be more appropriate to // use Freestanding. @@ -4972,7 +4976,8 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, // Parse the default calling convention options. if (Arg *CCArg = Args.getLastArg(options::OPT__SLASH_Gd, options::OPT__SLASH_Gr, - options::OPT__SLASH_Gz, options::OPT__SLASH_Gv)) { + options::OPT__SLASH_Gz, options::OPT__SLASH_Gv, + options::OPT__SLASH_Gregcall)) { unsigned DCCOptId = CCArg->getOption().getID(); const char *DCCFlag = nullptr; bool ArchSupported = true; @@ -4993,6 +4998,10 @@ void Clang::AddClangCLArgs(const ArgList &Args, types::ID InputType, ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64; DCCFlag = "-fdefault-calling-conv=vectorcall"; break; + case options::OPT__SLASH_Gregcall: + ArchSupported = Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64; + DCCFlag = "-fdefault-calling-conv=regcall"; + break; } // MSVC doesn't warn if /Gr or /Gz is used on x64, so we don't either. diff --git a/lib/Driver/ToolChains/CommonArgs.cpp b/lib/Driver/ToolChains/CommonArgs.cpp index b359cbb77e..91f653a53e 100644 --- a/lib/Driver/ToolChains/CommonArgs.cpp +++ b/lib/Driver/ToolChains/CommonArgs.cpp @@ -566,7 +566,6 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, if (!Args.hasArg(options::OPT_shared) && !TC.getTriple().isAndroid()) HelperStaticRuntimes.push_back("asan-preinit"); } - if (SanArgs.needsUbsanRt()) { if (SanArgs.requiresMinimalRuntime()) { SharedRuntimes.push_back("ubsan_minimal"); @@ -574,6 +573,8 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, SharedRuntimes.push_back("ubsan_standalone"); } } + if (SanArgs.needsScudoRt()) + SharedRuntimes.push_back("scudo"); } // The stats_client library is also statically linked into DSOs. @@ -630,6 +631,11 @@ collectSanitizerRuntimes(const ToolChain &TC, const ArgList &Args, } if (SanArgs.needsEsanRt()) StaticRuntimes.push_back("esan"); + if (SanArgs.needsScudoRt()) { + StaticRuntimes.push_back("scudo"); + if (SanArgs.linkCXXRuntimes()) + StaticRuntimes.push_back("scudo_cxx"); + } } // Should be called before we add system libraries (C++ ABI, libstdc++/libc++, diff --git a/lib/Driver/ToolChains/Cuda.h b/lib/Driver/ToolChains/Cuda.h index 414c9445c7..3101cb3ab7 100644 --- a/lib/Driver/ToolChains/Cuda.h +++ b/lib/Driver/ToolChains/Cuda.h @@ -157,6 +157,7 @@ public: bool isPICDefaultForced() const override { return false; } bool SupportsProfiling() const override { return false; } bool SupportsObjCGC() const override { return false; } + bool IsMathErrnoDefault() const override { return false; } void AddCudaIncludeArgs(const llvm::opt::ArgList &DriverArgs, llvm::opt::ArgStringList &CC1Args) const override; diff --git a/lib/Driver/ToolChains/Linux.cpp b/lib/Driver/ToolChains/Linux.cpp index 613a9f3c88..9b722166c5 100644 --- a/lib/Driver/ToolChains/Linux.cpp +++ b/lib/Driver/ToolChains/Linux.cpp @@ -845,9 +845,10 @@ SanitizerMask Linux::getSupportedSanitizers() const { Res |= SanitizerKind::Memory; if (IsX86_64 || IsMIPS64) Res |= SanitizerKind::Efficiency; - if (IsX86 || IsX86_64) { + if (IsX86 || IsX86_64) Res |= SanitizerKind::Function; - } + if (IsX86_64 || IsMIPS64 || IsAArch64 || IsX86 || IsArmArch) + Res |= SanitizerKind::Scudo; return Res; } diff --git a/lib/Driver/ToolChains/MinGW.cpp b/lib/Driver/ToolChains/MinGW.cpp index 660b0c798e..79864eab83 100644 --- a/lib/Driver/ToolChains/MinGW.cpp +++ b/lib/Driver/ToolChains/MinGW.cpp @@ -107,14 +107,6 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, // handled somewhere else. Args.ClaimAllArgs(options::OPT_w); - StringRef LinkerName = Args.getLastArgValue(options::OPT_fuse_ld_EQ, "ld"); - if (LinkerName.equals_lower("lld")) { - CmdArgs.push_back("-flavor"); - CmdArgs.push_back("gnu"); - } else if (!LinkerName.equals_lower("ld")) { - D.Diag(diag::err_drv_unsupported_linker) << LinkerName; - } - if (!D.SysRoot.empty()) CmdArgs.push_back(Args.MakeArgString("--sysroot=" + D.SysRoot)); @@ -244,7 +236,7 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, if (Args.hasArg(options::OPT_static)) CmdArgs.push_back("--end-group"); - else if (!LinkerName.equals_lower("lld")) + else AddLibGCC(Args, CmdArgs); } @@ -255,7 +247,7 @@ void tools::MinGW::Linker::ConstructJob(Compilation &C, const JobAction &JA, CmdArgs.push_back(Args.MakeArgString(TC.GetFilePath("crtend.o"))); } } - const char *Exec = Args.MakeArgString(TC.GetProgramPath(LinkerName.data())); + const char *Exec = Args.MakeArgString(TC.GetLinkerPath()); C.addCommand(llvm::make_unique<Command>(JA, *this, Exec, CmdArgs, Inputs)); } diff --git a/lib/Format/TokenAnnotator.cpp b/lib/Format/TokenAnnotator.cpp index bc8fef8bda..aa5990e8c0 100644 --- a/lib/Format/TokenAnnotator.cpp +++ b/lib/Format/TokenAnnotator.cpp @@ -696,7 +696,8 @@ private: CurrentToken->Type = TT_PointerOrReference; consumeToken(); if (CurrentToken && - CurrentToken->Previous->isOneOf(TT_BinaryOperator, tok::comma)) + CurrentToken->Previous->isOneOf(TT_BinaryOperator, TT_UnaryOperator, + tok::comma)) CurrentToken->Previous->Type = TT_OverloadedOperator; } if (CurrentToken) { diff --git a/lib/Format/UsingDeclarationsSorter.cpp b/lib/Format/UsingDeclarationsSorter.cpp index d6753b545e..e9c535da92 100644 --- a/lib/Format/UsingDeclarationsSorter.cpp +++ b/lib/Format/UsingDeclarationsSorter.cpp @@ -33,8 +33,27 @@ struct UsingDeclaration { UsingDeclaration(const AnnotatedLine *Line, const std::string &Label) : Line(Line), Label(Label) {} + // Compares lexicographically with the exception that '_' is just before 'A'. bool operator<(const UsingDeclaration &Other) const { - return StringRef(Label).compare_lower(Other.Label) < 0; + size_t Size = Label.size(); + size_t OtherSize = Other.Label.size(); + for (size_t I = 0, E = std::min(Size, OtherSize); I < E; ++I) { + char Rank = rank(Label[I]); + char OtherRank = rank(Other.Label[I]); + if (Rank != OtherRank) + return Rank < OtherRank; + } + return Size < OtherSize; + } + + // Returns the position of c in a lexicographic ordering with the exception + // that '_' is just before 'A'. + static char rank(char c) { + if (c == '_') + return 'A'; + if ('A' <= c && c < '_') + return c + 1; + return c; } }; @@ -77,7 +96,7 @@ void endUsingDeclarationBlock( SmallVectorImpl<UsingDeclaration> *UsingDeclarations, const SourceManager &SourceMgr, tooling::Replacements *Fixes) { bool BlockAffected = false; - for (const UsingDeclaration& Declaration : *UsingDeclarations) { + for (const UsingDeclaration &Declaration : *UsingDeclarations) { if (Declaration.Line->Affected) { BlockAffected = true; break; diff --git a/lib/Frontend/CompilerInvocation.cpp b/lib/Frontend/CompilerInvocation.cpp index 2c0d99b4be..ca1c65e95a 100644 --- a/lib/Frontend/CompilerInvocation.cpp +++ b/lib/Frontend/CompilerInvocation.cpp @@ -653,6 +653,7 @@ static bool ParseCodeGenArgs(CodeGenOptions &Opts, ArgList &Args, InputKind IK, Args.hasArg(OPT_mincremental_linker_compatible); Opts.PIECopyRelocations = Args.hasArg(OPT_mpie_copy_relocations); + Opts.NoPLT = Args.hasArg(OPT_fno_plt); Opts.OmitLeafFramePointer = Args.hasArg(OPT_momit_leaf_frame_pointer); Opts.SaveTempLabels = Args.hasArg(OPT_msave_temp_labels); Opts.NoDwarfDirectoryAsm = Args.hasArg(OPT_fno_dwarf_directory_asm); @@ -2310,12 +2311,12 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, // Check for MS default calling conventions being specified. if (Arg *A = Args.getLastArg(OPT_fdefault_calling_conv_EQ)) { LangOptions::DefaultCallingConvention DefaultCC = - llvm::StringSwitch<LangOptions::DefaultCallingConvention>( - A->getValue()) + llvm::StringSwitch<LangOptions::DefaultCallingConvention>(A->getValue()) .Case("cdecl", LangOptions::DCC_CDecl) .Case("fastcall", LangOptions::DCC_FastCall) .Case("stdcall", LangOptions::DCC_StdCall) .Case("vectorcall", LangOptions::DCC_VectorCall) + .Case("regcall", LangOptions::DCC_RegCall) .Default(LangOptions::DCC_None); if (DefaultCC == LangOptions::DCC_None) Diags.Report(diag::err_drv_invalid_value) @@ -2326,7 +2327,8 @@ static void ParseLangArgs(LangOptions &Opts, ArgList &Args, InputKind IK, bool emitError = (DefaultCC == LangOptions::DCC_FastCall || DefaultCC == LangOptions::DCC_StdCall) && Arch != llvm::Triple::x86; - emitError |= DefaultCC == LangOptions::DCC_VectorCall && + emitError |= (DefaultCC == LangOptions::DCC_VectorCall || + DefaultCC == LangOptions::DCC_RegCall) && !(Arch == llvm::Triple::x86 || Arch == llvm::Triple::x86_64); if (emitError) Diags.Report(diag::err_drv_argument_not_allowed_with) diff --git a/lib/Headers/avx512bwintrin.h b/lib/Headers/avx512bwintrin.h index 53da5869d3..905d67b163 100644 --- a/lib/Headers/avx512bwintrin.h +++ b/lib/Headers/avx512bwintrin.h @@ -56,293 +56,145 @@ _mm512_setzero_hi(void) { /* Integer compare */ -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epi8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_pcmpeqb512_mask((__v64qi)__a, (__v64qi)__b, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_pcmpeqb512_mask((__v64qi)__a, (__v64qi)__b, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epu8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 0, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 0, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epi16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_pcmpeqw512_mask((__v32hi)__a, (__v32hi)__b, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_pcmpeqw512_mask((__v32hi)__a, (__v32hi)__b, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epu16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 0, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 0, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpge_epi8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpge_epu8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 5, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpge_epi16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpge_epu16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 5, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epi8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_pcmpgtb512_mask((__v64qi)__a, (__v64qi)__b, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_pcmpgtb512_mask((__v64qi)__a, (__v64qi)__b, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epu8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 6, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 6, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epi16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_pcmpgtw512_mask((__v32hi)__a, (__v32hi)__b, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_pcmpgtw512_mask((__v32hi)__a, (__v32hi)__b, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epu16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 6, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 6, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmple_epi8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmple_epu8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 2, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmple_epi16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmple_epu16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 2, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmplt_epi8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, - __u); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmplt_epu8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, - (__mmask64)-1); -} - -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 1, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmplt_epi16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmplt_epu16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 1, - __u); -} +#define _mm512_cmp_epi8_mask(a, b, p) __extension__ ({ \ + (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), (int)(p), \ + (__mmask64)-1); }) -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epi8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, - (__mmask64)-1); -} +#define _mm512_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ + (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), (int)(p), \ + (__mmask64)(m)); }) -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epi8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, - __u); -} +#define _mm512_cmp_epu8_mask(a, b, p) __extension__ ({ \ + (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), (int)(p), \ + (__mmask64)-1); }) -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epu8_mask(__m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, - (__mmask64)-1); -} +#define _mm512_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ + (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ + (__v64qi)(__m512i)(b), (int)(p), \ + (__mmask64)(m)); }) -static __inline__ __mmask64 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epu8_mask(__mmask64 __u, __m512i __a, __m512i __b) { - return (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)__a, (__v64qi)__b, 4, - __u); -} +#define _mm512_cmp_epi16_mask(a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), (int)(p), \ + (__mmask32)-1); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epi16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, - (__mmask32)-1); -} +#define _mm512_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), (int)(p), \ + (__mmask32)(m)); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epi16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, - __u); -} +#define _mm512_cmp_epu16_mask(a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), (int)(p), \ + (__mmask32)-1); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epu16_mask(__m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, - (__mmask32)-1); -} +#define _mm512_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ + (__v32hi)(__m512i)(b), (int)(p), \ + (__mmask32)(m)); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epu16_mask(__mmask32 __u, __m512i __a, __m512i __b) { - return (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)__a, (__v32hi)__b, 4, - __u); -} +#define _mm512_cmpeq_epi8_mask(A, B) \ + _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epi8_mask(k, A, B) \ + _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epi8_mask(A, B) \ + _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epi8_mask(k, A, B) \ + _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epi8_mask(A, B) \ + _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epi8_mask(k, A, B) \ + _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epi8_mask(A, B) \ + _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epi8_mask(k, A, B) \ + _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epi8_mask(A, B) \ + _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epi8_mask(k, A, B) \ + _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epi8_mask(A, B) \ + _mm512_cmp_epi8_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epi8_mask(k, A, B) \ + _mm512_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm512_cmpeq_epu8_mask(A, B) \ + _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epu8_mask(k, A, B) \ + _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epu8_mask(A, B) \ + _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epu8_mask(k, A, B) \ + _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epu8_mask(A, B) \ + _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epu8_mask(k, A, B) \ + _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epu8_mask(A, B) \ + _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epu8_mask(k, A, B) \ + _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epu8_mask(A, B) \ + _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epu8_mask(k, A, B) \ + _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epu8_mask(A, B) \ + _mm512_cmp_epu8_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epu8_mask(k, A, B) \ + _mm512_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm512_cmpeq_epi16_mask(A, B) \ + _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epi16_mask(k, A, B) \ + _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epi16_mask(A, B) \ + _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epi16_mask(k, A, B) \ + _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epi16_mask(A, B) \ + _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epi16_mask(k, A, B) \ + _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epi16_mask(A, B) \ + _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epi16_mask(k, A, B) \ + _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epi16_mask(A, B) \ + _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epi16_mask(k, A, B) \ + _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epi16_mask(A, B) \ + _mm512_cmp_epi16_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epi16_mask(k, A, B) \ + _mm512_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm512_cmpeq_epu16_mask(A, B) \ + _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epu16_mask(k, A, B) \ + _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epu16_mask(A, B) \ + _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epu16_mask(k, A, B) \ + _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epu16_mask(A, B) \ + _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epu16_mask(k, A, B) \ + _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epu16_mask(A, B) \ + _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epu16_mask(k, A, B) \ + _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epu16_mask(A, B) \ + _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epu16_mask(k, A, B) \ + _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epu16_mask(A, B) \ + _mm512_cmp_epu16_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epu16_mask(k, A, B) \ + _mm512_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_NE) static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_add_epi8 (__m512i __A, __m512i __B) { @@ -1541,46 +1393,6 @@ _mm512_maskz_cvtepu8_epi16(__mmask32 __U, __m256i __A) } -#define _mm512_cmp_epi8_mask(a, b, p) __extension__ ({ \ - (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ - (__v64qi)(__m512i)(b), (int)(p), \ - (__mmask64)-1); }) - -#define _mm512_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ - (__mmask64)__builtin_ia32_cmpb512_mask((__v64qi)(__m512i)(a), \ - (__v64qi)(__m512i)(b), (int)(p), \ - (__mmask64)(m)); }) - -#define _mm512_cmp_epu8_mask(a, b, p) __extension__ ({ \ - (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ - (__v64qi)(__m512i)(b), (int)(p), \ - (__mmask64)-1); }) - -#define _mm512_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ - (__mmask64)__builtin_ia32_ucmpb512_mask((__v64qi)(__m512i)(a), \ - (__v64qi)(__m512i)(b), (int)(p), \ - (__mmask64)(m)); }) - -#define _mm512_cmp_epi16_mask(a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ - (__v32hi)(__m512i)(b), (int)(p), \ - (__mmask32)-1); }) - -#define _mm512_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_cmpw512_mask((__v32hi)(__m512i)(a), \ - (__v32hi)(__m512i)(b), (int)(p), \ - (__mmask32)(m)); }) - -#define _mm512_cmp_epu16_mask(a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ - (__v32hi)(__m512i)(b), (int)(p), \ - (__mmask32)-1); }) - -#define _mm512_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_ucmpw512_mask((__v32hi)(__m512i)(a), \ - (__v32hi)(__m512i)(b), (int)(p), \ - (__mmask32)(m)); }) - #define _mm512_shufflehi_epi16(A, imm) __extension__ ({ \ (__m512i)__builtin_shufflevector((__v32hi)(__m512i)(A), \ (__v32hi)_mm512_undefined_epi32(), \ diff --git a/lib/Headers/avx512cdintrin.h b/lib/Headers/avx512cdintrin.h index 23c423584a..ec7e0cd443 100644 --- a/lib/Headers/avx512cdintrin.h +++ b/lib/Headers/avx512cdintrin.h @@ -130,13 +130,14 @@ _mm512_maskz_lzcnt_epi64 (__mmask8 __U, __m512i __A) static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_broadcastmb_epi64 (__mmask8 __A) { - return (__m512i) __builtin_ia32_broadcastmb512 (__A); + return (__m512i) _mm512_set1_epi64((long long) __A); } static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_broadcastmw_epi32 (__mmask16 __A) { - return (__m512i) __builtin_ia32_broadcastmw512 (__A); + return (__m512i) _mm512_set1_epi32((int) __A); + } #undef __DEFAULT_FN_ATTRS diff --git a/lib/Headers/avx512fintrin.h b/lib/Headers/avx512fintrin.h index 247ac879ea..50e0429e19 100644 --- a/lib/Headers/avx512fintrin.h +++ b/lib/Headers/avx512fintrin.h @@ -4844,293 +4844,105 @@ _mm512_knot(__mmask16 __M) /* Integer compare */ -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epi32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_pcmpeqd512_mask((__v16si)__a, (__v16si)__b, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epu32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 0, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epi64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_pcmpeqq512_mask((__v8di)__a, (__v8di)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpeq_epu64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpeq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 0, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpge_epi32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 5, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpge_epu32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpge_epi64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpge_epu64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpge_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 5, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epi32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_pcmpgtd512_mask((__v16si)__a, (__v16si)__b, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epu32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 6, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epi64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_pcmpgtq512_mask((__v8di)__a, (__v8di)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpgt_epu64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpgt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 6, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmple_epi32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 2, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmple_epu32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmple_epi64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmple_epu64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmple_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 2, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmplt_epi32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 1, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmplt_epu32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmplt_epi64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmplt_epu64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmplt_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 1, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epi32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epi32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_cmpd512_mask((__v16si)__a, (__v16si)__b, 4, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epu32_mask(__m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epu32_mask(__mmask16 __u, __m512i __a, __m512i __b) { - return (__mmask16)__builtin_ia32_ucmpd512_mask((__v16si)__a, (__v16si)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epi64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epi64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_cmpq512_mask((__v8di)__a, (__v8di)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_cmpneq_epu64_mask(__m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm512_mask_cmpneq_epu64_mask(__mmask8 __u, __m512i __a, __m512i __b) { - return (__mmask8)__builtin_ia32_ucmpq512_mask((__v8di)__a, (__v8di)__b, 4, - __u); -} +#define _mm512_cmpeq_epi32_mask(A, B) \ + _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epi32_mask(k, A, B) \ + _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epi32_mask(A, B) \ + _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epi32_mask(k, A, B) \ + _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epi32_mask(A, B) \ + _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epi32_mask(k, A, B) \ + _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epi32_mask(A, B) \ + _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epi32_mask(k, A, B) \ + _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epi32_mask(A, B) \ + _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epi32_mask(k, A, B) \ + _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epi32_mask(A, B) \ + _mm512_cmp_epi32_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epi32_mask(k, A, B) \ + _mm512_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm512_cmpeq_epu32_mask(A, B) \ + _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epu32_mask(k, A, B) \ + _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epu32_mask(A, B) \ + _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epu32_mask(k, A, B) \ + _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epu32_mask(A, B) \ + _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epu32_mask(k, A, B) \ + _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epu32_mask(A, B) \ + _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epu32_mask(k, A, B) \ + _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epu32_mask(A, B) \ + _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epu32_mask(k, A, B) \ + _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epu32_mask(A, B) \ + _mm512_cmp_epu32_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epu32_mask(k, A, B) \ + _mm512_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm512_cmpeq_epi64_mask(A, B) \ + _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epi64_mask(k, A, B) \ + _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epi64_mask(A, B) \ + _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epi64_mask(k, A, B) \ + _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epi64_mask(A, B) \ + _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epi64_mask(k, A, B) \ + _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epi64_mask(A, B) \ + _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epi64_mask(k, A, B) \ + _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epi64_mask(A, B) \ + _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epi64_mask(k, A, B) \ + _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epi64_mask(A, B) \ + _mm512_cmp_epi64_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epi64_mask(k, A, B) \ + _mm512_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm512_cmpeq_epu64_mask(A, B) \ + _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_EQ) +#define _mm512_mask_cmpeq_epu64_mask(k, A, B) \ + _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm512_cmpge_epu64_mask(A, B) \ + _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_GE) +#define _mm512_mask_cmpge_epu64_mask(k, A, B) \ + _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm512_cmpgt_epu64_mask(A, B) \ + _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_GT) +#define _mm512_mask_cmpgt_epu64_mask(k, A, B) \ + _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm512_cmple_epu64_mask(A, B) \ + _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_LE) +#define _mm512_mask_cmple_epu64_mask(k, A, B) \ + _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm512_cmplt_epu64_mask(A, B) \ + _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_LT) +#define _mm512_mask_cmplt_epu64_mask(k, A, B) \ + _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm512_cmpneq_epu64_mask(A, B) \ + _mm512_cmp_epu64_mask((A), (B), _MM_CMPINT_NE) +#define _mm512_mask_cmpneq_epu64_mask(k, A, B) \ + _mm512_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_NE) static __inline__ __m512i __DEFAULT_FN_ATTRS _mm512_cvtepi8_epi32(__m128i __A) diff --git a/lib/Headers/avx512vlbwintrin.h b/lib/Headers/avx512vlbwintrin.h index 4ab785bdbb..2196a45a26 100644 --- a/lib/Headers/avx512vlbwintrin.h +++ b/lib/Headers/avx512vlbwintrin.h @@ -38,581 +38,285 @@ _mm_setzero_hi(void){ /* Integer compare */ -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpeq_epi8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_pcmpeqb128_mask((__v16qi)__a, (__v16qi)__b, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_pcmpeqb128_mask((__v16qi)__a, (__v16qi)__b, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpeq_epu8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 0, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 0, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epi8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_pcmpeqb256_mask((__v32qi)__a, (__v32qi)__b, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_pcmpeqb256_mask((__v32qi)__a, (__v32qi)__b, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epu8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 0, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 0, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpeq_epi16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpeqw128_mask((__v8hi)__a, (__v8hi)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpeqw128_mask((__v8hi)__a, (__v8hi)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpeq_epu16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 0, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 0, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epi16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_pcmpeqw256_mask((__v16hi)__a, (__v16hi)__b, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_pcmpeqw256_mask((__v16hi)__a, (__v16hi)__b, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epu16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 0, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 0, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpge_epi8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpge_epu8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 5, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpge_epi8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpge_epu8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpge_epi16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpge_epu16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 5, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpge_epi16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpge_epu16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 5, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpgt_epi8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_pcmpgtb128_mask((__v16qi)__a, (__v16qi)__b, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_pcmpgtb128_mask((__v16qi)__a, (__v16qi)__b, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpgt_epu8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 6, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 6, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epi8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_pcmpgtb256_mask((__v32qi)__a, (__v32qi)__b, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_pcmpgtb256_mask((__v32qi)__a, (__v32qi)__b, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epu8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 6, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 6, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpgt_epi16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpgtw128_mask((__v8hi)__a, (__v8hi)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpgtw128_mask((__v8hi)__a, (__v8hi)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpgt_epu16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 6, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 6, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epi16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_pcmpgtw256_mask((__v16hi)__a, (__v16hi)__b, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_pcmpgtw256_mask((__v16hi)__a, (__v16hi)__b, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epu16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 6, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 6, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmple_epi8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmple_epu8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 2, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmple_epi8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmple_epu8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmple_epi16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmple_epu16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 2, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmple_epi16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmple_epu16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 2, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmplt_epi8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmplt_epu8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 1, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmplt_epi8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, - __u); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmplt_epu8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, - (__mmask32)-1); -} - -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmplt_epi16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmplt_epu16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 1, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmplt_epi16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, - __u); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmplt_epu16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, - (__mmask16)-1); -} - -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 1, - __u); -} +#define _mm_cmp_epi8_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), (int)(p), \ + (__mmask16)-1); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpneq_epi8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, - (__mmask16)-1); -} +#define _mm_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), (int)(p), \ + (__mmask16)(m)); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epi8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, - __u); -} +#define _mm_cmp_epu8_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), (int)(p), \ + (__mmask16)-1); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_cmpneq_epu8_mask(__m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, - (__mmask16)-1); -} +#define _mm_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ + (__v16qi)(__m128i)(b), (int)(p), \ + (__mmask16)(m)); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epu8_mask(__mmask16 __u, __m128i __a, __m128i __b) { - return (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)__a, (__v16qi)__b, 4, - __u); -} +#define _mm256_cmp_epi8_mask(a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), (int)(p), \ + (__mmask32)-1); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epi8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, - (__mmask32)-1); -} +#define _mm256_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), (int)(p), \ + (__mmask32)(m)); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epi8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, - __u); -} +#define _mm256_cmp_epu8_mask(a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), (int)(p), \ + (__mmask32)-1); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epu8_mask(__m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, - (__mmask32)-1); -} +#define _mm256_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ + (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ + (__v32qi)(__m256i)(b), (int)(p), \ + (__mmask32)(m)); }) -static __inline__ __mmask32 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epu8_mask(__mmask32 __u, __m256i __a, __m256i __b) { - return (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)__a, (__v32qi)__b, 4, - __u); -} +#define _mm_cmp_epi16_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), (int)(p), \ + (__mmask8)-1); }) -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpneq_epi16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, - (__mmask8)-1); -} +#define _mm_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), (int)(p), \ + (__mmask8)(m)); }) -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epi16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, - __u); -} +#define _mm_cmp_epu16_mask(a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), (int)(p), \ + (__mmask8)-1); }) -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpneq_epu16_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, - (__mmask8)-1); -} +#define _mm_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ + (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ + (__v8hi)(__m128i)(b), (int)(p), \ + (__mmask8)(m)); }) -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epu16_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)__a, (__v8hi)__b, 4, - __u); -} +#define _mm256_cmp_epi16_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), (int)(p), \ + (__mmask16)-1); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epi16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, - (__mmask16)-1); -} +#define _mm256_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), (int)(p), \ + (__mmask16)(m)); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epi16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, - __u); -} +#define _mm256_cmp_epu16_mask(a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), (int)(p), \ + (__mmask16)-1); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epu16_mask(__m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, - (__mmask16)-1); -} +#define _mm256_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ + (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ + (__v16hi)(__m256i)(b), (int)(p), \ + (__mmask16)(m)); }) -static __inline__ __mmask16 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epu16_mask(__mmask16 __u, __m256i __a, __m256i __b) { - return (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)__a, (__v16hi)__b, 4, - __u); -} +#define _mm_cmpeq_epi8_mask(A, B) \ + _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epi8_mask(k, A, B) \ + _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epi8_mask(A, B) \ + _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epi8_mask(k, A, B) \ + _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epi8_mask(A, B) \ + _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epi8_mask(k, A, B) \ + _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epi8_mask(A, B) \ + _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epi8_mask(k, A, B) \ + _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epi8_mask(A, B) \ + _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epi8_mask(k, A, B) \ + _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epi8_mask(A, B) \ + _mm_cmp_epi8_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epi8_mask(k, A, B) \ + _mm_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epi8_mask(A, B) \ + _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epi8_mask(k, A, B) \ + _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epi8_mask(A, B) \ + _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epi8_mask(k, A, B) \ + _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epi8_mask(A, B) \ + _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epi8_mask(k, A, B) \ + _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epi8_mask(A, B) \ + _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epi8_mask(k, A, B) \ + _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epi8_mask(A, B) \ + _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epi8_mask(k, A, B) \ + _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epi8_mask(A, B) \ + _mm256_cmp_epi8_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epi8_mask(k, A, B) \ + _mm256_mask_cmp_epi8_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm_cmpeq_epu8_mask(A, B) \ + _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epu8_mask(k, A, B) \ + _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epu8_mask(A, B) \ + _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epu8_mask(k, A, B) \ + _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epu8_mask(A, B) \ + _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epu8_mask(k, A, B) \ + _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epu8_mask(A, B) \ + _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epu8_mask(k, A, B) \ + _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epu8_mask(A, B) \ + _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epu8_mask(k, A, B) \ + _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epu8_mask(A, B) \ + _mm_cmp_epu8_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epu8_mask(k, A, B) \ + _mm_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epu8_mask(A, B) \ + _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epu8_mask(k, A, B) \ + _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epu8_mask(A, B) \ + _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epu8_mask(k, A, B) \ + _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epu8_mask(A, B) \ + _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epu8_mask(k, A, B) \ + _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epu8_mask(A, B) \ + _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epu8_mask(k, A, B) \ + _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epu8_mask(A, B) \ + _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epu8_mask(k, A, B) \ + _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epu8_mask(A, B) \ + _mm256_cmp_epu8_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epu8_mask(k, A, B) \ + _mm256_mask_cmp_epu8_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm_cmpeq_epi16_mask(A, B) \ + _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epi16_mask(k, A, B) \ + _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epi16_mask(A, B) \ + _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epi16_mask(k, A, B) \ + _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epi16_mask(A, B) \ + _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epi16_mask(k, A, B) \ + _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epi16_mask(A, B) \ + _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epi16_mask(k, A, B) \ + _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epi16_mask(A, B) \ + _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epi16_mask(k, A, B) \ + _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epi16_mask(A, B) \ + _mm_cmp_epi16_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epi16_mask(k, A, B) \ + _mm_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epi16_mask(A, B) \ + _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epi16_mask(k, A, B) \ + _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epi16_mask(A, B) \ + _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epi16_mask(k, A, B) \ + _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epi16_mask(A, B) \ + _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epi16_mask(k, A, B) \ + _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epi16_mask(A, B) \ + _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epi16_mask(k, A, B) \ + _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epi16_mask(A, B) \ + _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epi16_mask(k, A, B) \ + _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epi16_mask(A, B) \ + _mm256_cmp_epi16_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epi16_mask(k, A, B) \ + _mm256_mask_cmp_epi16_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm_cmpeq_epu16_mask(A, B) \ + _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epu16_mask(k, A, B) \ + _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epu16_mask(A, B) \ + _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epu16_mask(k, A, B) \ + _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epu16_mask(A, B) \ + _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epu16_mask(k, A, B) \ + _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epu16_mask(A, B) \ + _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epu16_mask(k, A, B) \ + _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epu16_mask(A, B) \ + _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epu16_mask(k, A, B) \ + _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epu16_mask(A, B) \ + _mm_cmp_epu16_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epu16_mask(k, A, B) \ + _mm_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epu16_mask(A, B) \ + _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epu16_mask(k, A, B) \ + _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epu16_mask(A, B) \ + _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epu16_mask(k, A, B) \ + _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epu16_mask(A, B) \ + _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epu16_mask(k, A, B) \ + _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epu16_mask(A, B) \ + _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epu16_mask(k, A, B) \ + _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epu16_mask(A, B) \ + _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epu16_mask(k, A, B) \ + _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epu16_mask(A, B) \ + _mm256_cmp_epu16_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epu16_mask(k, A, B) \ + _mm256_mask_cmp_epu16_mask((k), (A), (B), _MM_CMPINT_NE) static __inline__ __m256i __DEFAULT_FN_ATTRS _mm256_mask_add_epi8(__m256i __W, __mmask32 __U, __m256i __A, __m256i __B){ @@ -2146,86 +1850,6 @@ _mm256_maskz_cvtepu8_epi16 (__mmask16 __U, __m128i __A) } -#define _mm_cmp_epi8_mask(a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ - (__v16qi)(__m128i)(b), (int)(p), \ - (__mmask16)-1); }) - -#define _mm_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_cmpb128_mask((__v16qi)(__m128i)(a), \ - (__v16qi)(__m128i)(b), (int)(p), \ - (__mmask16)(m)); }) - -#define _mm_cmp_epu8_mask(a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ - (__v16qi)(__m128i)(b), (int)(p), \ - (__mmask16)-1); }) - -#define _mm_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_ucmpb128_mask((__v16qi)(__m128i)(a), \ - (__v16qi)(__m128i)(b), (int)(p), \ - (__mmask16)(m)); }) - -#define _mm256_cmp_epi8_mask(a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ - (__v32qi)(__m256i)(b), (int)(p), \ - (__mmask32)-1); }) - -#define _mm256_mask_cmp_epi8_mask(m, a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_cmpb256_mask((__v32qi)(__m256i)(a), \ - (__v32qi)(__m256i)(b), (int)(p), \ - (__mmask32)(m)); }) - -#define _mm256_cmp_epu8_mask(a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ - (__v32qi)(__m256i)(b), (int)(p), \ - (__mmask32)-1); }) - -#define _mm256_mask_cmp_epu8_mask(m, a, b, p) __extension__ ({ \ - (__mmask32)__builtin_ia32_ucmpb256_mask((__v32qi)(__m256i)(a), \ - (__v32qi)(__m256i)(b), (int)(p), \ - (__mmask32)(m)); }) - -#define _mm_cmp_epi16_mask(a, b, p) __extension__ ({ \ - (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ - (__v8hi)(__m128i)(b), (int)(p), \ - (__mmask8)-1); }) - -#define _mm_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ - (__mmask8)__builtin_ia32_cmpw128_mask((__v8hi)(__m128i)(a), \ - (__v8hi)(__m128i)(b), (int)(p), \ - (__mmask8)(m)); }) - -#define _mm_cmp_epu16_mask(a, b, p) __extension__ ({ \ - (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ - (__v8hi)(__m128i)(b), (int)(p), \ - (__mmask8)-1); }) - -#define _mm_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ - (__mmask8)__builtin_ia32_ucmpw128_mask((__v8hi)(__m128i)(a), \ - (__v8hi)(__m128i)(b), (int)(p), \ - (__mmask8)(m)); }) - -#define _mm256_cmp_epi16_mask(a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ - (__v16hi)(__m256i)(b), (int)(p), \ - (__mmask16)-1); }) - -#define _mm256_mask_cmp_epi16_mask(m, a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_cmpw256_mask((__v16hi)(__m256i)(a), \ - (__v16hi)(__m256i)(b), (int)(p), \ - (__mmask16)(m)); }) - -#define _mm256_cmp_epu16_mask(a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ - (__v16hi)(__m256i)(b), (int)(p), \ - (__mmask16)-1); }) - -#define _mm256_mask_cmp_epu16_mask(m, a, b, p) __extension__ ({ \ - (__mmask16)__builtin_ia32_ucmpw256_mask((__v16hi)(__m256i)(a), \ - (__v16hi)(__m256i)(b), (int)(p), \ - (__mmask16)(m)); }) - #define _mm_mask_shufflehi_epi16(W, U, A, imm) __extension__ ({ \ (__m128i)__builtin_ia32_selectw_128((__mmask8)(U), \ (__v8hi)_mm_shufflehi_epi16((A), (imm)), \ diff --git a/lib/Headers/avx512vlcdintrin.h b/lib/Headers/avx512vlcdintrin.h index 7b02e2e1f9..8f1cd25f0b 100644 --- a/lib/Headers/avx512vlcdintrin.h +++ b/lib/Headers/avx512vlcdintrin.h @@ -33,26 +33,26 @@ static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_broadcastmb_epi64 (__mmask8 __A) -{ - return (__m128i) __builtin_ia32_broadcastmb128 (__A); +{ + return (__m128i) _mm_set1_epi64x((long long) __A); } static __inline__ __m256i __DEFAULT_FN_ATTRS _mm256_broadcastmb_epi64 (__mmask8 __A) { - return (__m256i) __builtin_ia32_broadcastmb256 (__A); + return (__m256i) _mm256_set1_epi64x((long long)__A); } static __inline__ __m128i __DEFAULT_FN_ATTRS _mm_broadcastmw_epi32 (__mmask16 __A) { - return (__m128i) __builtin_ia32_broadcastmw128 (__A); + return (__m128i) _mm_set1_epi32((int)__A); } static __inline__ __m256i __DEFAULT_FN_ATTRS _mm256_broadcastmw_epi32 (__mmask16 __A) { - return (__m256i) __builtin_ia32_broadcastmw256 (__A); + return (__m256i) _mm256_set1_epi32((int)__A); } diff --git a/lib/Headers/avx512vlintrin.h b/lib/Headers/avx512vlintrin.h index 7e17cff05f..457ff0c46b 100644 --- a/lib/Headers/avx512vlintrin.h +++ b/lib/Headers/avx512vlintrin.h @@ -38,582 +38,205 @@ _mm_setzero_di(void) { /* Integer compare */ -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpeq_epi32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpeqd128_mask((__v4si)__a, (__v4si)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpeqd128_mask((__v4si)__a, (__v4si)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpeq_epu32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 0, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 0, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epi32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpeqd256_mask((__v8si)__a, (__v8si)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpeqd256_mask((__v8si)__a, (__v8si)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epu32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 0, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 0, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpeq_epi64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpeqq128_mask((__v2di)__a, (__v2di)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpeqq128_mask((__v2di)__a, (__v2di)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpeq_epu64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 0, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpeq_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 0, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epi64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpeqq256_mask((__v4di)__a, (__v4di)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpeqq256_mask((__v4di)__a, (__v4di)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpeq_epu64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 0, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpeq_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 0, - __u); -} - - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpge_epi32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpge_epu32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpge_epi32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpge_epu32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpge_epi64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpge_epu64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpge_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpge_epi64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpge_epu64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 5, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpge_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 5, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpgt_epi32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpgtd128_mask((__v4si)__a, (__v4si)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpgtd128_mask((__v4si)__a, (__v4si)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpgt_epu32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 6, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 6, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epi32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpgtd256_mask((__v8si)__a, (__v8si)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpgtd256_mask((__v8si)__a, (__v8si)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epu32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 6, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 6, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpgt_epi64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpgtq128_mask((__v2di)__a, (__v2di)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_pcmpgtq128_mask((__v2di)__a, (__v2di)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpgt_epu64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 6, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpgt_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 6, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epi64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpgtq256_mask((__v4di)__a, (__v4di)__b, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_pcmpgtq256_mask((__v4di)__a, (__v4di)__b, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpgt_epu64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 6, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpgt_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 6, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmple_epi32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmple_epu32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmple_epi32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmple_epu32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmple_epi64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmple_epu64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmple_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmple_epi64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmple_epu64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 2, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmple_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 2, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmplt_epi32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmplt_epu32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmplt_epi32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmplt_epu32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmplt_epi64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmplt_epu64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmplt_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmplt_epi64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmplt_epu64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 1, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmplt_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 1, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpneq_epi32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epi32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpd128_mask((__v4si)__a, (__v4si)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpneq_epu32_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epu32_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpd128_mask((__v4si)__a, (__v4si)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epi32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epi32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpd256_mask((__v8si)__a, (__v8si)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epu32_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epu32_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpd256_mask((__v8si)__a, (__v8si)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpneq_epi64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epi64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_cmpq128_mask((__v2di)__a, (__v2di)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_cmpneq_epu64_mask(__m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm_mask_cmpneq_epu64_mask(__mmask8 __u, __m128i __a, __m128i __b) { - return (__mmask8)__builtin_ia32_ucmpq128_mask((__v2di)__a, (__v2di)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epi64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epi64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_cmpq256_mask((__v4di)__a, (__v4di)__b, 4, - __u); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_cmpneq_epu64_mask(__m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 4, - (__mmask8)-1); -} - -static __inline__ __mmask8 __DEFAULT_FN_ATTRS -_mm256_mask_cmpneq_epu64_mask(__mmask8 __u, __m256i __a, __m256i __b) { - return (__mmask8)__builtin_ia32_ucmpq256_mask((__v4di)__a, (__v4di)__b, 4, - __u); -} +#define _mm_cmpeq_epi32_mask(A, B) \ + _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epi32_mask(k, A, B) \ + _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epi32_mask(A, B) \ + _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epi32_mask(k, A, B) \ + _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epi32_mask(A, B) \ + _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epi32_mask(k, A, B) \ + _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epi32_mask(A, B) \ + _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epi32_mask(k, A, B) \ + _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epi32_mask(A, B) \ + _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epi32_mask(k, A, B) \ + _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epi32_mask(A, B) \ + _mm_cmp_epi32_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epi32_mask(k, A, B) \ + _mm_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epi32_mask(A, B) \ + _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epi32_mask(k, A, B) \ + _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epi32_mask(A, B) \ + _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epi32_mask(k, A, B) \ + _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epi32_mask(A, B) \ + _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epi32_mask(k, A, B) \ + _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epi32_mask(A, B) \ + _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epi32_mask(k, A, B) \ + _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epi32_mask(A, B) \ + _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epi32_mask(k, A, B) \ + _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epi32_mask(A, B) \ + _mm256_cmp_epi32_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epi32_mask(k, A, B) \ + _mm256_mask_cmp_epi32_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm_cmpeq_epu32_mask(A, B) \ + _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epu32_mask(k, A, B) \ + _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epu32_mask(A, B) \ + _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epu32_mask(k, A, B) \ + _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epu32_mask(A, B) \ + _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epu32_mask(k, A, B) \ + _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epu32_mask(A, B) \ + _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epu32_mask(k, A, B) \ + _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epu32_mask(A, B) \ + _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epu32_mask(k, A, B) \ + _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epu32_mask(A, B) \ + _mm_cmp_epu32_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epu32_mask(k, A, B) \ + _mm_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epu32_mask(A, B) \ + _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epu32_mask(k, A, B) \ + _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epu32_mask(A, B) \ + _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epu32_mask(k, A, B) \ + _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epu32_mask(A, B) \ + _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epu32_mask(k, A, B) \ + _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epu32_mask(A, B) \ + _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epu32_mask(k, A, B) \ + _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epu32_mask(A, B) \ + _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epu32_mask(k, A, B) \ + _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epu32_mask(A, B) \ + _mm256_cmp_epu32_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epu32_mask(k, A, B) \ + _mm256_mask_cmp_epu32_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm_cmpeq_epi64_mask(A, B) \ + _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epi64_mask(k, A, B) \ + _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epi64_mask(A, B) \ + _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epi64_mask(k, A, B) \ + _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epi64_mask(A, B) \ + _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epi64_mask(k, A, B) \ + _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epi64_mask(A, B) \ + _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epi64_mask(k, A, B) \ + _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epi64_mask(A, B) \ + _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epi64_mask(k, A, B) \ + _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epi64_mask(A, B) \ + _mm_cmp_epi64_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epi64_mask(k, A, B) \ + _mm_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epi64_mask(A, B) \ + _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epi64_mask(k, A, B) \ + _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epi64_mask(A, B) \ + _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epi64_mask(k, A, B) \ + _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epi64_mask(A, B) \ + _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epi64_mask(k, A, B) \ + _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epi64_mask(A, B) \ + _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epi64_mask(k, A, B) \ + _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epi64_mask(A, B) \ + _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epi64_mask(k, A, B) \ + _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epi64_mask(A, B) \ + _mm256_cmp_epi64_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epi64_mask(k, A, B) \ + _mm256_mask_cmp_epi64_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm_cmpeq_epu64_mask(A, B) \ + _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_EQ) +#define _mm_mask_cmpeq_epu64_mask(k, A, B) \ + _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm_cmpge_epu64_mask(A, B) \ + _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_GE) +#define _mm_mask_cmpge_epu64_mask(k, A, B) \ + _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm_cmpgt_epu64_mask(A, B) \ + _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_GT) +#define _mm_mask_cmpgt_epu64_mask(k, A, B) \ + _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm_cmple_epu64_mask(A, B) \ + _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_LE) +#define _mm_mask_cmple_epu64_mask(k, A, B) \ + _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm_cmplt_epu64_mask(A, B) \ + _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_LT) +#define _mm_mask_cmplt_epu64_mask(k, A, B) \ + _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm_cmpneq_epu64_mask(A, B) \ + _mm_cmp_epu64_mask((A), (B), _MM_CMPINT_NE) +#define _mm_mask_cmpneq_epu64_mask(k, A, B) \ + _mm_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_NE) + +#define _mm256_cmpeq_epu64_mask(A, B) \ + _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_EQ) +#define _mm256_mask_cmpeq_epu64_mask(k, A, B) \ + _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_EQ) +#define _mm256_cmpge_epu64_mask(A, B) \ + _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_GE) +#define _mm256_mask_cmpge_epu64_mask(k, A, B) \ + _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GE) +#define _mm256_cmpgt_epu64_mask(A, B) \ + _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_GT) +#define _mm256_mask_cmpgt_epu64_mask(k, A, B) \ + _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_GT) +#define _mm256_cmple_epu64_mask(A, B) \ + _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_LE) +#define _mm256_mask_cmple_epu64_mask(k, A, B) \ + _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LE) +#define _mm256_cmplt_epu64_mask(A, B) \ + _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_LT) +#define _mm256_mask_cmplt_epu64_mask(k, A, B) \ + _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_LT) +#define _mm256_cmpneq_epu64_mask(A, B) \ + _mm256_cmp_epu64_mask((A), (B), _MM_CMPINT_NE) +#define _mm256_mask_cmpneq_epu64_mask(k, A, B) \ + _mm256_mask_cmp_epu64_mask((k), (A), (B), _MM_CMPINT_NE) static __inline__ __m256i __DEFAULT_FN_ATTRS _mm256_mask_add_epi32(__m256i __W, __mmask8 __U, __m256i __A, __m256i __B) diff --git a/lib/Index/IndexBody.cpp b/lib/Index/IndexBody.cpp index 6bbd381025..ac34956b24 100644 --- a/lib/Index/IndexBody.cpp +++ b/lib/Index/IndexBody.cpp @@ -427,6 +427,17 @@ public: return true; } + + bool VisitOffsetOfExpr(OffsetOfExpr *S) { + for (unsigned I = 0, E = S->getNumComponents(); I != E; ++I) { + const OffsetOfNode &Component = S->getComponent(I); + if (Component.getKind() == OffsetOfNode::Field) + IndexCtx.handleReference(Component.getField(), Component.getLocEnd(), + Parent, ParentDC, SymbolRoleSet(), {}); + // FIXME: Try to resolve dependent field references. + } + return true; + } }; } // anonymous namespace diff --git a/lib/Lex/Lexer.cpp b/lib/Lex/Lexer.cpp index 5132d0e62c..67dcff6b71 100644 --- a/lib/Lex/Lexer.cpp +++ b/lib/Lex/Lexer.cpp @@ -1212,18 +1212,12 @@ const char *Lexer::SkipEscapedNewLines(const char *P) { } } -/// \brief Checks that the given token is the first token that occurs after the -/// given location (this excludes comments and whitespace). Returns the location -/// immediately after the specified token. If the token is not found or the -/// location is inside a macro, the returned source location will be invalid. -SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc, - tok::TokenKind TKind, - const SourceManager &SM, - const LangOptions &LangOpts, - bool SkipTrailingWhitespaceAndNewLine) { +Optional<Token> Lexer::findNextToken(SourceLocation Loc, + const SourceManager &SM, + const LangOptions &LangOpts) { if (Loc.isMacroID()) { if (!Lexer::isAtEndOfMacroExpansion(Loc, SM, LangOpts, &Loc)) - return SourceLocation(); + return None; } Loc = Lexer::getLocForEndOfToken(Loc, 0, SM, LangOpts); @@ -1234,7 +1228,7 @@ SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc, bool InvalidTemp = false; StringRef File = SM.getBufferData(LocInfo.first, &InvalidTemp); if (InvalidTemp) - return SourceLocation(); + return None; const char *TokenBegin = File.data() + LocInfo.second; @@ -1244,15 +1238,25 @@ SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc, // Find the token. Token Tok; lexer.LexFromRawLexer(Tok); - if (Tok.isNot(TKind)) + return Tok; +} + +/// \brief Checks that the given token is the first token that occurs after the +/// given location (this excludes comments and whitespace). Returns the location +/// immediately after the specified token. If the token is not found or the +/// location is inside a macro, the returned source location will be invalid. +SourceLocation Lexer::findLocationAfterToken( + SourceLocation Loc, tok::TokenKind TKind, const SourceManager &SM, + const LangOptions &LangOpts, bool SkipTrailingWhitespaceAndNewLine) { + Optional<Token> Tok = findNextToken(Loc, SM, LangOpts); + if (!Tok || Tok->isNot(TKind)) return SourceLocation(); - SourceLocation TokenLoc = Tok.getLocation(); + SourceLocation TokenLoc = Tok->getLocation(); // Calculate how much whitespace needs to be skipped if any. unsigned NumWhitespaceChars = 0; if (SkipTrailingWhitespaceAndNewLine) { - const char *TokenEnd = SM.getCharacterData(TokenLoc) + - Tok.getLength(); + const char *TokenEnd = SM.getCharacterData(TokenLoc) + Tok->getLength(); unsigned char C = *TokenEnd; while (isHorizontalWhitespace(C)) { C = *(++TokenEnd); @@ -1269,7 +1273,7 @@ SourceLocation Lexer::findLocationAfterToken(SourceLocation Loc, } } - return TokenLoc.getLocWithOffset(Tok.getLength() + NumWhitespaceChars); + return TokenLoc.getLocWithOffset(Tok->getLength() + NumWhitespaceChars); } /// getCharAndSizeSlow - Peek a single 'character' from the specified buffer, diff --git a/lib/Lex/PPDirectives.cpp b/lib/Lex/PPDirectives.cpp index f9a97505bf..ca3e70fd10 100644 --- a/lib/Lex/PPDirectives.cpp +++ b/lib/Lex/PPDirectives.cpp @@ -350,7 +350,7 @@ void Preprocessor::CheckEndOfDirective(const char *DirType, bool EnableMacros) { /// If ElseOk is true, then \#else directives are ok, if not, then we have /// already seen one so a \#else directive is a duplicate. When this returns, /// the caller can lex the first valid token. -void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, +void Preprocessor::SkipExcludedConditionalBlock(SourceLocation HashTokenLoc, SourceLocation IfTokenLoc, bool FoundNonSkipPortion, bool FoundElse, @@ -358,8 +358,11 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, ++NumSkipped; assert(!CurTokenLexer && CurPPLexer && "Lexing a macro, not a file?"); - CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/false, - FoundNonSkipPortion, FoundElse); + if (PreambleConditionalStack.reachedEOFWhileSkipping()) + PreambleConditionalStack.clearSkipInfo(); + else + CurPPLexer->pushConditionalLevel(IfTokenLoc, /*isSkipping*/ false, + FoundNonSkipPortion, FoundElse); if (CurPTHLexer) { PTHSkipExcludedConditionalBlock(); @@ -385,6 +388,9 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, // We don't emit errors for unterminated conditionals here, // Lexer::LexEndOfFile can do that propertly. // Just return and let the caller lex after this #include. + if (PreambleConditionalStack.isRecording()) + PreambleConditionalStack.SkipInfo.emplace( + HashTokenLoc, IfTokenLoc, FoundNonSkipPortion, FoundElse, ElseLoc); break; } @@ -554,7 +560,7 @@ void Preprocessor::SkipExcludedConditionalBlock(const Token &HashToken, if (Callbacks) Callbacks->SourceRangeSkipped( - SourceRange(HashToken.getLocation(), CurPPLexer->getSourceLocation()), + SourceRange(HashTokenLoc, CurPPLexer->getSourceLocation()), Tok.getLocation()); } @@ -2676,7 +2682,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, if (MacroNameTok.is(tok::eod)) { // Skip code until we get to #endif. This helps with recovery by not // emitting an error when the #endif is reached. - SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(), + SkipExcludedConditionalBlock(HashToken.getLocation(), + DirectiveTok.getLocation(), /*Foundnonskip*/ false, /*FoundElse*/ false); return; } @@ -2725,7 +2732,8 @@ void Preprocessor::HandleIfdefDirective(Token &Result, /*foundelse*/false); } else { // No, skip the contents of this block. - SkipExcludedConditionalBlock(HashToken, DirectiveTok.getLocation(), + SkipExcludedConditionalBlock(HashToken.getLocation(), + DirectiveTok.getLocation(), /*Foundnonskip*/ false, /*FoundElse*/ false); } @@ -2772,7 +2780,7 @@ void Preprocessor::HandleIfDirective(Token &IfToken, /*foundnonskip*/true, /*foundelse*/false); } else { // No, skip the contents of this block. - SkipExcludedConditionalBlock(HashToken, IfToken.getLocation(), + SkipExcludedConditionalBlock(HashToken.getLocation(), IfToken.getLocation(), /*Foundnonskip*/ false, /*FoundElse*/ false); } @@ -2837,7 +2845,8 @@ void Preprocessor::HandleElseDirective(Token &Result, const Token &HashToken) { } // Finally, skip the rest of the contents of this block. - SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true, + SkipExcludedConditionalBlock(HashToken.getLocation(), CI.IfLoc, + /*Foundnonskip*/ true, /*FoundElse*/ true, Result.getLocation()); } @@ -2881,7 +2890,7 @@ void Preprocessor::HandleElifDirective(Token &ElifToken, } // Finally, skip the rest of the contents of this block. - SkipExcludedConditionalBlock(HashToken, CI.IfLoc, /*Foundnonskip*/ true, - /*FoundElse*/ CI.FoundElse, - ElifToken.getLocation()); + SkipExcludedConditionalBlock( + HashToken.getLocation(), CI.IfLoc, /*Foundnonskip*/ true, + /*FoundElse*/ CI.FoundElse, ElifToken.getLocation()); } diff --git a/lib/Lex/PPMacroExpansion.cpp b/lib/Lex/PPMacroExpansion.cpp index b0330f2881..9f0c88dd97 100644 --- a/lib/Lex/PPMacroExpansion.cpp +++ b/lib/Lex/PPMacroExpansion.cpp @@ -1138,6 +1138,7 @@ static bool HasFeature(const Preprocessor &PP, StringRef Feature) { .Case("dataflow_sanitizer", LangOpts.Sanitize.has(SanitizerKind::DataFlow)) .Case("efficiency_sanitizer", LangOpts.Sanitize.hasOneOf(SanitizerKind::Efficiency)) + .Case("scudo", LangOpts.Sanitize.hasOneOf(SanitizerKind::Scudo)) // Objective-C features .Case("objc_arr", LangOpts.ObjCAutoRefCount) // FIXME: REMOVE? .Case("objc_arc", LangOpts.ObjCAutoRefCount) diff --git a/lib/Lex/Preprocessor.cpp b/lib/Lex/Preprocessor.cpp index 65df6a57f1..d80899de8f 100644 --- a/lib/Lex/Preprocessor.cpp +++ b/lib/Lex/Preprocessor.cpp @@ -550,6 +550,13 @@ void Preprocessor::replayPreambleConditionalStack() { "CurPPLexer is null when calling replayPreambleConditionalStack."); CurPPLexer->setConditionalLevels(PreambleConditionalStack.getStack()); PreambleConditionalStack.doneReplaying(); + if (PreambleConditionalStack.reachedEOFWhileSkipping()) + SkipExcludedConditionalBlock( + PreambleConditionalStack.SkipInfo->HashTokenLoc, + PreambleConditionalStack.SkipInfo->IfTokenLoc, + PreambleConditionalStack.SkipInfo->FoundNonSkipPortion, + PreambleConditionalStack.SkipInfo->FoundElse, + PreambleConditionalStack.SkipInfo->ElseLoc); } } diff --git a/lib/Parse/ParseExprCXX.cpp b/lib/Parse/ParseExprCXX.cpp index a640439b8f..ad4801971a 100644 --- a/lib/Parse/ParseExprCXX.cpp +++ b/lib/Parse/ParseExprCXX.cpp @@ -249,7 +249,7 @@ bool Parser::ParseOptionalCXXScopeSpecifier(CXXScopeSpec &SS, if (Tok.is(tok::code_completion)) { // Code completion for a nested-name-specifier, where the code - // code completion token follows the '::'. + // completion token follows the '::'. Actions.CodeCompleteQualifiedId(getCurScope(), SS, EnteringContext); // Include code completion token into the range of the scope otherwise // when we try to annotate the scope tokens the dangling code completion @@ -991,27 +991,34 @@ Optional<unsigned> Parser::ParseLambdaIntroducer(LambdaIntroducer &Intro, /// /// Returns true if it hit something unexpected. bool Parser::TryParseLambdaIntroducer(LambdaIntroducer &Intro) { - TentativeParsingAction PA(*this); + { + bool SkippedInits = false; + TentativeParsingAction PA1(*this); - bool SkippedInits = false; - Optional<unsigned> DiagID(ParseLambdaIntroducer(Intro, &SkippedInits)); + if (ParseLambdaIntroducer(Intro, &SkippedInits)) { + PA1.Revert(); + return true; + } - if (DiagID) { - PA.Revert(); - return true; + if (!SkippedInits) { + PA1.Commit(); + return false; + } + + PA1.Revert(); } - if (SkippedInits) { - // Parse it again, but this time parse the init-captures too. - PA.Revert(); - Intro = LambdaIntroducer(); - DiagID = ParseLambdaIntroducer(Intro); - assert(!DiagID && "parsing lambda-introducer failed on reparse"); + // Try to parse it again, but this time parse the init-captures too. + Intro = LambdaIntroducer(); + TentativeParsingAction PA2(*this); + + if (!ParseLambdaIntroducer(Intro)) { + PA2.Commit(); return false; } - PA.Commit(); - return false; + PA2.Revert(); + return true; } static void diff --git a/lib/Sema/SemaChecking.cpp b/lib/Sema/SemaChecking.cpp index 53e710d7b7..ca07f7429e 100644 --- a/lib/Sema/SemaChecking.cpp +++ b/lib/Sema/SemaChecking.cpp @@ -2312,7 +2312,10 @@ bool Sema::CheckX86BuiltinFunctionCall(unsigned BuiltinID, CallExpr *TheCall) { i = 1; l = -128; u = 255; break; case X86::BI__builtin_ia32_vcvtps2ph: + case X86::BI__builtin_ia32_vcvtps2ph_mask: case X86::BI__builtin_ia32_vcvtps2ph256: + case X86::BI__builtin_ia32_vcvtps2ph256_mask: + case X86::BI__builtin_ia32_vcvtps2ph512_mask: case X86::BI__builtin_ia32_rndscaleps_128_mask: case X86::BI__builtin_ia32_rndscalepd_128_mask: case X86::BI__builtin_ia32_rndscaleps_256_mask: diff --git a/lib/Sema/SemaCodeComplete.cpp b/lib/Sema/SemaCodeComplete.cpp index 72ab65fc58..26004cf3c3 100644 --- a/lib/Sema/SemaCodeComplete.cpp +++ b/lib/Sema/SemaCodeComplete.cpp @@ -14,6 +14,7 @@ #include "clang/AST/DeclObjC.h" #include "clang/AST/ExprCXX.h" #include "clang/AST/ExprObjC.h" +#include "clang/AST/QualTypeNames.h" #include "clang/Basic/CharInfo.h" #include "clang/Lex/HeaderSearch.h" #include "clang/Lex/MacroInfo.h" @@ -1495,6 +1496,7 @@ static PrintingPolicy getCompletionPrintingPolicy(const ASTContext &Context, Policy.AnonymousTagLocations = false; Policy.SuppressStrongLifetime = true; Policy.SuppressUnwrittenScope = true; + Policy.SuppressScope = true; return Policy; } @@ -2139,9 +2141,10 @@ static void AddResultTypeChunk(ASTContext &Context, T = Method->getSendResultType(BaseType); else T = Method->getReturnType(); - } else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) + } else if (const EnumConstantDecl *Enumerator = dyn_cast<EnumConstantDecl>(ND)) { T = Context.getTypeDeclType(cast<TypeDecl>(Enumerator->getDeclContext())); - else if (isa<UnresolvedUsingValueDecl>(ND)) { + T = clang::TypeName::getFullyQualifiedType(T, Context); + } else if (isa<UnresolvedUsingValueDecl>(ND)) { /* Do nothing: ignore unresolved using declarations*/ } else if (const ObjCIvarDecl *Ivar = dyn_cast<ObjCIvarDecl>(ND)) { if (!BaseType.isNull()) diff --git a/lib/Sema/SemaDecl.cpp b/lib/Sema/SemaDecl.cpp index 0c00ef7e26..ab1a66ad8f 100644 --- a/lib/Sema/SemaDecl.cpp +++ b/lib/Sema/SemaDecl.cpp @@ -9673,6 +9673,13 @@ void Sema::CheckMain(FunctionDecl* FD, const DeclSpec& DS) { assert(T->isFunctionType() && "function decl is not of function type"); const FunctionType* FT = T->castAs<FunctionType>(); + // Set default calling convention for main() + if (FT->getCallConv() != CC_C) { + FT = Context.adjustFunctionType(FT, FT->getExtInfo().withCallingConv(CC_C)); + FD->setType(QualType(FT, 0)); + T = Context.getCanonicalType(FD->getType()); + } + if (getLangOpts().GNUMode && !getLangOpts().CPlusPlus) { // In C with GNU extensions we allow main() to have non-integer return // type, but we should warn about the extension, and we disable the diff --git a/lib/Sema/SemaInit.cpp b/lib/Sema/SemaInit.cpp index dc7fe1d92b..5ece958ee6 100644 --- a/lib/Sema/SemaInit.cpp +++ b/lib/Sema/SemaInit.cpp @@ -6422,6 +6422,10 @@ static void CheckMoveOnConstruction(Sema &S, const Expr *InitExpr, if (!VD || !VD->hasLocalStorage()) return; + // __block variables are not moved implicitly. + if (VD->hasAttr<BlocksAttr>()) + return; + QualType SourceType = VD->getType(); if (!SourceType->isRecordType()) return; diff --git a/lib/Sema/SemaOpenMP.cpp b/lib/Sema/SemaOpenMP.cpp index 941ac75fa6..243c6ed5f4 100644 --- a/lib/Sema/SemaOpenMP.cpp +++ b/lib/Sema/SemaOpenMP.cpp @@ -9711,7 +9711,7 @@ static bool ActOnOMPReductionKindClause( } if ((OASE && !ConstantLengthOASE) || - (!ASE && + (!OASE && !ASE && D->getType().getNonReferenceType()->isVariablyModifiedType())) { // For arrays/array sections only: // Create pseudo array type for private copy. The size for this array will diff --git a/lib/Sema/SemaPseudoObject.cpp b/lib/Sema/SemaPseudoObject.cpp index d159172a69..58980be64a 100644 --- a/lib/Sema/SemaPseudoObject.cpp +++ b/lib/Sema/SemaPseudoObject.cpp @@ -1442,8 +1442,7 @@ MSPropertyOpBuilder::getBaseMSProperty(MSPropertySubscriptExpr *E) { Expr *MSPropertyOpBuilder::rebuildAndCaptureObject(Expr *syntacticBase) { InstanceBase = capture(RefExpr->getBaseExpr()); - std::for_each(CallArgs.begin(), CallArgs.end(), - [this](Expr *&Arg) { Arg = capture(Arg); }); + llvm::for_each(CallArgs, [this](Expr *&Arg) { Arg = capture(Arg); }); syntacticBase = Rebuilder(S, [=](Expr *, unsigned Idx) -> Expr * { switch (Idx) { case 0: diff --git a/lib/Serialization/ASTReader.cpp b/lib/Serialization/ASTReader.cpp index 5a3423a3ec..944eeee6b4 100644 --- a/lib/Serialization/ASTReader.cpp +++ b/lib/Serialization/ASTReader.cpp @@ -1,4 +1,4 @@ -//===-- ASTReader.cpp - AST File Reader -----------------------------------===// +//===- ASTReader.cpp - AST File Reader ------------------------------------===// // // The LLVM Compiler Infrastructure // @@ -19,28 +19,41 @@ #include "clang/AST/ASTMutationListener.h" #include "clang/AST/ASTUnresolvedSet.h" #include "clang/AST/Decl.h" +#include "clang/AST/DeclBase.h" #include "clang/AST/DeclCXX.h" +#include "clang/AST/DeclFriend.h" #include "clang/AST/DeclGroup.h" #include "clang/AST/DeclObjC.h" #include "clang/AST/DeclTemplate.h" +#include "clang/AST/DeclarationName.h" #include "clang/AST/Expr.h" #include "clang/AST/ExprCXX.h" +#include "clang/AST/ExternalASTSource.h" #include "clang/AST/NestedNameSpecifier.h" #include "clang/AST/ODRHash.h" #include "clang/AST/RawCommentList.h" +#include "clang/AST/TemplateBase.h" +#include "clang/AST/TemplateName.h" #include "clang/AST/Type.h" +#include "clang/AST/TypeLoc.h" #include "clang/AST/TypeLocVisitor.h" #include "clang/AST/UnresolvedSet.h" #include "clang/Basic/CommentOptions.h" +#include "clang/Basic/Diagnostic.h" #include "clang/Basic/DiagnosticOptions.h" #include "clang/Basic/ExceptionSpecificationType.h" #include "clang/Basic/FileManager.h" #include "clang/Basic/FileSystemOptions.h" +#include "clang/Basic/IdentifierTable.h" +#include "clang/Basic/LLVM.h" #include "clang/Basic/LangOptions.h" #include "clang/Basic/MemoryBufferCache.h" +#include "clang/Basic/Module.h" #include "clang/Basic/ObjCRuntime.h" #include "clang/Basic/OperatorKinds.h" +#include "clang/Basic/PragmaKinds.h" #include "clang/Basic/Sanitizers.h" +#include "clang/Basic/SourceLocation.h" #include "clang/Basic/SourceManager.h" #include "clang/Basic/SourceManagerInternals.h" #include "clang/Basic/Specifiers.h" @@ -57,41 +70,61 @@ #include "clang/Lex/PreprocessingRecord.h" #include "clang/Lex/Preprocessor.h" #include "clang/Lex/PreprocessorOptions.h" +#include "clang/Lex/Token.h" +#include "clang/Sema/ObjCMethodList.h" #include "clang/Sema/Scope.h" #include "clang/Sema/Sema.h" #include "clang/Sema/Weak.h" +#include "clang/Serialization/ASTBitCodes.h" #include "clang/Serialization/ASTDeserializationListener.h" +#include "clang/Serialization/ContinuousRangeMap.h" #include "clang/Serialization/GlobalModuleIndex.h" +#include "clang/Serialization/Module.h" +#include "clang/Serialization/ModuleFileExtension.h" #include "clang/Serialization/ModuleManager.h" #include "clang/Serialization/SerializationDiagnostic.h" #include "llvm/ADT/APFloat.h" #include "llvm/ADT/APInt.h" #include "llvm/ADT/APSInt.h" +#include "llvm/ADT/ArrayRef.h" +#include "llvm/ADT/DenseMap.h" +#include "llvm/ADT/FoldingSet.h" #include "llvm/ADT/Hashing.h" +#include "llvm/ADT/IntrusiveRefCntPtr.h" +#include "llvm/ADT/None.h" +#include "llvm/ADT/Optional.h" +#include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallPtrSet.h" #include "llvm/ADT/SmallString.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/StringExtras.h" +#include "llvm/ADT/StringMap.h" +#include "llvm/ADT/StringRef.h" #include "llvm/ADT/Triple.h" +#include "llvm/ADT/iterator_range.h" #include "llvm/Bitcode/BitstreamReader.h" +#include "llvm/Support/Casting.h" #include "llvm/Support/Compression.h" #include "llvm/Support/Compiler.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/Error.h" #include "llvm/Support/ErrorHandling.h" #include "llvm/Support/FileSystem.h" #include "llvm/Support/MemoryBuffer.h" #include "llvm/Support/Path.h" #include "llvm/Support/SaveAndRestore.h" +#include "llvm/Support/Timer.h" #include "llvm/Support/raw_ostream.h" #include <algorithm> #include <cassert> +#include <cstddef> #include <cstdint> #include <cstdio> -#include <cstring> #include <ctime> #include <iterator> #include <limits> #include <map> #include <memory> -#include <new> #include <string> #include <system_error> #include <tuple> @@ -171,19 +204,23 @@ bool ChainedASTReaderListener::ReadPreprocessorOptions( SuggestedPredefines) || Second->ReadPreprocessorOptions(PPOpts, Complain, SuggestedPredefines); } + void ChainedASTReaderListener::ReadCounter(const serialization::ModuleFile &M, unsigned Value) { First->ReadCounter(M, Value); Second->ReadCounter(M, Value); } + bool ChainedASTReaderListener::needsInputFileVisitation() { return First->needsInputFileVisitation() || Second->needsInputFileVisitation(); } + bool ChainedASTReaderListener::needsSystemInputFileVisitation() { return First->needsSystemInputFileVisitation() || Second->needsSystemInputFileVisitation(); } + void ChainedASTReaderListener::visitModuleFile(StringRef Filename, ModuleKind Kind) { First->visitModuleFile(Filename, Kind); @@ -216,7 +253,7 @@ void ChainedASTReaderListener::readModuleFileExtension( // PCH validator implementation //===----------------------------------------------------------------------===// -ASTReaderListener::~ASTReaderListener() {} +ASTReaderListener::~ASTReaderListener() = default; /// \brief Compare the given set of language options against an existing set of /// language options. @@ -409,17 +446,16 @@ bool PCHValidator::ReadTargetOptions(const TargetOptions &TargetOpts, namespace { - typedef llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> > - MacroDefinitionsMap; - typedef llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8> > - DeclsMap; +using MacroDefinitionsMap = + llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>; +using DeclsMap = llvm::DenseMap<DeclarationName, SmallVector<NamedDecl *, 8>>; -} // end anonymous namespace +} // namespace static bool checkDiagnosticGroupMappings(DiagnosticsEngine &StoredDiags, DiagnosticsEngine &Diags, bool Complain) { - typedef DiagnosticsEngine::Level Level; + using Level = DiagnosticsEngine::Level; // Check current mappings for new -Werror mappings, and the stored mappings // for cases that were explicitly mapped to *not* be errors that are now @@ -603,8 +639,8 @@ static bool checkPreprocessorOptions(const PreprocessorOptions &PPOpts, std::pair<StringRef, bool> Existing = ExistingMacros[MacroName]; // Check whether we know anything about this macro name or not. - llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/> >::iterator Known - = ASTFileMacros.find(MacroName); + llvm::StringMap<std::pair<StringRef, bool /*IsUndef*/>>::iterator Known = + ASTFileMacros.find(MacroName); if (!Validate || Known == ASTFileMacros.end()) { // FIXME: Check whether this identifier was referenced anywhere in the // AST file. If so, we should reject the AST file. Unfortunately, this @@ -770,6 +806,7 @@ unsigned ASTSelectorLookupTrait::ComputeHash(Selector Sel) { std::pair<unsigned, unsigned> ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) { using namespace llvm::support; + unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d); unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d); return std::make_pair(KeyLen, DataLen); @@ -778,6 +815,7 @@ ASTSelectorLookupTrait::ReadKeyDataLength(const unsigned char*& d) { ASTSelectorLookupTrait::internal_key_type ASTSelectorLookupTrait::ReadKey(const unsigned char* d, unsigned) { using namespace llvm::support; + SelectorTable &SelTable = Reader.getContext().Selectors; unsigned N = endian::readNext<uint16_t, little, unaligned>(d); IdentifierInfo *FirstII = Reader.getLocalIdentifier( @@ -838,6 +876,7 @@ unsigned ASTIdentifierLookupTraitBase::ComputeHash(const internal_key_type& a) { std::pair<unsigned, unsigned> ASTIdentifierLookupTraitBase::ReadKeyDataLength(const unsigned char*& d) { using namespace llvm::support; + unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d); unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d); return std::make_pair(KeyLen, DataLen); @@ -868,6 +907,7 @@ static bool readBit(unsigned &Bits) { IdentID ASTIdentifierLookupTrait::ReadIdentifierID(const unsigned char *d) { using namespace llvm::support; + unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d); return Reader.getGlobalIdentifierID(F, RawID >> 1); } @@ -885,6 +925,7 @@ IdentifierInfo *ASTIdentifierLookupTrait::ReadData(const internal_key_type& k, const unsigned char* d, unsigned DataLen) { using namespace llvm::support; + unsigned RawID = endian::readNext<uint32_t, little, unaligned>(d); bool IsInteresting = RawID & 0x01; @@ -1027,6 +1068,7 @@ unsigned DeclarationNameKey::getHash() const { ModuleFile * ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) { using namespace llvm::support; + uint32_t ModuleFileID = endian::readNext<uint32_t, little, unaligned>(d); return Reader.getLocalModuleFile(F, ModuleFileID); } @@ -1034,6 +1076,7 @@ ASTDeclContextNameLookupTrait::ReadFileRef(const unsigned char *&d) { std::pair<unsigned, unsigned> ASTDeclContextNameLookupTrait::ReadKeyDataLength(const unsigned char *&d) { using namespace llvm::support; + unsigned KeyLen = endian::readNext<uint16_t, little, unaligned>(d); unsigned DataLen = endian::readNext<uint16_t, little, unaligned>(d); return std::make_pair(KeyLen, DataLen); @@ -1079,6 +1122,7 @@ void ASTDeclContextNameLookupTrait::ReadDataInto(internal_key_type, unsigned DataLen, data_type_builder &Val) { using namespace llvm::support; + for (unsigned NumDecls = DataLen / 4; NumDecls; --NumDecls) { uint32_t LocalID = endian::readNext<uint32_t, little, unaligned>(d); Val.insert(Reader.getGlobalDeclID(F, LocalID)); @@ -1278,7 +1322,9 @@ resolveFileRelativeToOriginalDir(const std::string &Filename, const std::string &CurrDir) { assert(OriginalDir != CurrDir && "No point trying to resolve the file if the PCH dir didn't change"); + using namespace llvm::sys; + SmallString<128> filePath(Filename); fs::make_absolute(filePath); assert(path::is_absolute(OriginalDir)); @@ -1672,6 +1718,7 @@ bool HeaderFileInfoTrait::EqualKey(internal_key_ref a, internal_key_ref b) { std::pair<unsigned, unsigned> HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) { using namespace llvm::support; + unsigned KeyLen = (unsigned) endian::readNext<uint16_t, little, unaligned>(d); unsigned DataLen = (unsigned) *d++; return std::make_pair(KeyLen, DataLen); @@ -1680,6 +1727,7 @@ HeaderFileInfoTrait::ReadKeyDataLength(const unsigned char*& d) { HeaderFileInfoTrait::internal_key_type HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { using namespace llvm::support; + internal_key_type ikey; ikey.Size = off_t(endian::readNext<uint64_t, little, unaligned>(d)); ikey.ModTime = time_t(endian::readNext<uint64_t, little, unaligned>(d)); @@ -1691,8 +1739,9 @@ HeaderFileInfoTrait::ReadKey(const unsigned char *d, unsigned) { HeaderFileInfoTrait::data_type HeaderFileInfoTrait::ReadData(internal_key_ref key, const unsigned char *d, unsigned DataLen) { - const unsigned char *End = d + DataLen; using namespace llvm::support; + + const unsigned char *End = d + DataLen; HeaderFileInfo HFI; unsigned Flags = *d++; // FIXME: Refactor with mergeHeaderFileInfo in HeaderSearch.cpp. @@ -1813,7 +1862,7 @@ namespace { unsigned PriorGeneration; unsigned &NumIdentifierLookups; unsigned &NumIdentifierLookupHits; - IdentifierInfo *Found; + IdentifierInfo *Found = nullptr; public: IdentifierLookupVisitor(StringRef Name, unsigned PriorGeneration, @@ -1822,10 +1871,7 @@ namespace { : Name(Name), NameHash(ASTIdentifierLookupTrait::ComputeHash(Name)), PriorGeneration(PriorGeneration), NumIdentifierLookups(NumIdentifierLookups), - NumIdentifierLookupHits(NumIdentifierLookupHits), - Found() - { - } + NumIdentifierLookupHits(NumIdentifierLookupHits) {} bool operator()(ModuleFile &M) { // If we've already searched this module file, skip it now. @@ -1858,7 +1904,7 @@ namespace { IdentifierInfo *getIdentifierInfo() const { return Found; } }; -} // end anonymous namespace +} // namespace void ASTReader::updateOutOfDateIdentifier(IdentifierInfo &II) { // Note that we are loading an identifier. @@ -1985,10 +2031,9 @@ void ASTReader::resolvePendingMacro(IdentifierInfo *II, MD = PP.AllocateDefMacroDirective(MI, Loc); break; } - case MacroDirective::MD_Undefine: { + case MacroDirective::MD_Undefine: MD = PP.AllocateUndefMacroDirective(Loc); break; - } case MacroDirective::MD_Visibility: bool isPublic = Record[Idx++]; MD = PP.AllocateVisibilityMacroDirective(Loc, isPublic); @@ -2124,7 +2169,7 @@ InputFile ASTReader::getInputFile(ModuleFile &F, unsigned ID, bool Complain) { if (Complain) { // Build a list of the PCH imports that got us here (in reverse). SmallVector<ModuleFile *, 4> ImportStack(1, &F); - while (ImportStack.back()->ImportedBy.size() > 0) + while (!ImportStack.back()->ImportedBy.empty()) ImportStack.push_back(ImportStack.back()->ImportedBy[0]); // The top-level PCH is stale. @@ -2622,7 +2667,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case llvm::BitstreamEntry::Error: Error("error at end of module block in AST file"); return Failure; - case llvm::BitstreamEntry::EndBlock: { + case llvm::BitstreamEntry::EndBlock: // Outside of C++, we do not store a lookup map for the translation unit. // Instead, mark it as needing a lookup map to be built if this module // contains any declarations lexically within it (which it always does!). @@ -2635,7 +2680,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } return Success; - } case llvm::BitstreamEntry::SubBlock: switch (Entry.ID) { case DECLTYPES_BLOCK_ID: @@ -2995,8 +3039,20 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { case PP_CONDITIONAL_STACK: if (!Record.empty()) { + unsigned Idx = 0, End = Record.size() - 1; + bool ReachedEOFWhileSkipping = Record[Idx++]; + llvm::Optional<Preprocessor::PreambleSkipInfo> SkipInfo; + if (ReachedEOFWhileSkipping) { + SourceLocation HashToken = ReadSourceLocation(F, Record, Idx); + SourceLocation IfTokenLoc = ReadSourceLocation(F, Record, Idx); + bool FoundNonSkipPortion = Record[Idx++]; + bool FoundElse = Record[Idx++]; + SourceLocation ElseLoc = ReadSourceLocation(F, Record, Idx); + SkipInfo.emplace(HashToken, IfTokenLoc, FoundNonSkipPortion, + FoundElse, ElseLoc); + } SmallVector<PPConditionalInfo, 4> ConditionalStack; - for (unsigned Idx = 0, N = Record.size() - 1; Idx < N; /* in loop */) { + while (Idx < End) { auto Loc = ReadSourceLocation(F, Record, Idx); bool WasSkipping = Record[Idx++]; bool FoundNonSkip = Record[Idx++]; @@ -3004,7 +3060,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { ConditionalStack.push_back( {Loc, WasSkipping, FoundNonSkip, FoundElse}); } - PP.setReplayablePreambleConditionalStack(ConditionalStack); + PP.setReplayablePreambleConditionalStack(ConditionalStack, SkipInfo); } break; @@ -3158,7 +3214,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case DECL_UPDATE_OFFSETS: { + case DECL_UPDATE_OFFSETS: if (Record.size() % 2 != 0) { Error("invalid DECL_UPDATE_OFFSETS block in AST file"); return Failure; @@ -3174,9 +3230,8 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { PendingUpdateRecord(ID, D, /*JustLoaded=*/false)); } break; - } - case OBJC_CATEGORIES_MAP: { + case OBJC_CATEGORIES_MAP: if (F.LocalNumObjCCategoriesInMap != 0) { Error("duplicate OBJC_CATEGORIES_MAP record in AST file"); return Failure; @@ -3185,7 +3240,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { F.LocalNumObjCCategoriesInMap = Record[0]; F.ObjCCategoriesMap = (const ObjCCategoriesInfo *)Blob.data(); break; - } case OBJC_CATEGORIES: F.ObjCCategories.swap(Record); @@ -3199,7 +3253,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { CUDASpecialDeclRefs.push_back(getGlobalDeclID(F, Record[I])); break; - case HEADER_SEARCH_TABLE: { + case HEADER_SEARCH_TABLE: F.HeaderFileInfoTableData = Blob.data(); F.LocalNumHeaderFileInfos = Record[1]; if (Record[0]) { @@ -3216,7 +3270,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { PP.getHeaderSearchInfo().SetExternalLookup(this); } break; - } case FP_PRAGMA_OPTIONS: // Later tables overwrite earlier ones. @@ -3284,6 +3337,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { ReadSourceLocation(F, Record, I).getRawEncoding()); } break; + case DELETE_EXPRS_TO_ANALYZE: for (unsigned I = 0, N = Record.size(); I != N;) { DelayedDeleteExprs.push_back(getGlobalDeclID(F, Record[I++])); @@ -3297,7 +3351,7 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } break; - case IMPORTED_MODULES: { + case IMPORTED_MODULES: if (!F.isModule()) { // If we aren't loading a module (which has its own exports), make // all of the imported modules visible. @@ -3313,7 +3367,6 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { } } break; - } case MACRO_OFFSET: { if (F.LocalNumMacros != 0) { @@ -3339,10 +3392,9 @@ ASTReader::ReadASTBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case LATE_PARSED_TEMPLATE: { + case LATE_PARSED_TEMPLATE: LateParsedTemplates.append(Record.begin(), Record.end()); break; - } case OPTIMIZE_PRAGMA_OPTIONS: if (Record.size() != 1) { @@ -3424,8 +3476,7 @@ void ASTReader::ReadModuleOffsetMap(ModuleFile &F) const { } // Continuous range maps we may be updating in our module. - typedef ContinuousRangeMap<uint32_t, int, 2>::Builder - RemapBuilder; + using RemapBuilder = ContinuousRangeMap<uint32_t, int, 2>::Builder; RemapBuilder SLocRemap(F.SLocRemap); RemapBuilder IdentifierRemap(F.IdentifierRemap); RemapBuilder MacroRemap(F.MacroRemap); @@ -3589,7 +3640,6 @@ ASTReader::ReadModuleMapFileBlock(RecordData &Record, ModuleFile &F, return Success; } - /// \brief Move the given method to the back of the global list of methods. static void moveMethodToBackOfGlobalList(Sema &S, ObjCMethodDecl *Method) { // Find the entry for this selector in the method pool. @@ -4242,7 +4292,7 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( // Read all of the records in the options block. RecordData Record; ASTReadResult Result = Success; - while (1) { + while (true) { llvm::BitstreamEntry Entry = Stream.advance(); switch (Entry.Kind) { @@ -4262,11 +4312,10 @@ ASTReader::ASTReadResult ASTReader::readUnhashedControlBlockImpl( Record.clear(); switch ( (UnhashedControlBlockRecordTypes)Stream.readRecord(Entry.ID, Record)) { - case SIGNATURE: { + case SIGNATURE: if (F) std::copy(Record.begin(), Record.end(), F->Signature.data()); break; - } case DIAGNOSTIC_OPTIONS: { bool Complain = (ClientLoadCapabilities & ARR_OutOfDate) == 0; if (Listener && ValidateDiagnosticOptions && @@ -4595,9 +4644,7 @@ namespace { ExistingTargetOpts(ExistingTargetOpts), ExistingPPOpts(ExistingPPOpts), ExistingModuleCachePath(ExistingModuleCachePath), - FileMgr(FileMgr) - { - } + FileMgr(FileMgr) {} bool ReadLanguageOptions(const LangOptions &LangOpts, bool Complain, bool AllowCompatibleDifferences) override { @@ -4627,7 +4674,7 @@ namespace { } }; -} // end anonymous namespace +} // namespace bool ASTReader::readASTFileControlBlock( StringRef Filename, FileManager &FileMgr, @@ -4711,15 +4758,12 @@ bool ASTReader::readASTFileControlBlock( StringRef Blob; unsigned RecCode = Stream.readRecord(Entry.ID, Record, &Blob); switch ((ControlRecordTypes)RecCode) { - case METADATA: { + case METADATA: if (Record[0] != VERSION_MAJOR) return true; - if (Listener.ReadFullVersionInformation(Blob)) return true; - break; - } case MODULE_NAME: Listener.ReadModuleName(Blob); break; @@ -5027,10 +5071,9 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // them here. break; - case SUBMODULE_TOPHEADER: { + case SUBMODULE_TOPHEADER: CurrentModule->addTopHeaderFilename(Blob); break; - } case SUBMODULE_UMBRELLA_DIR: { std::string Dirname = Blob; @@ -5067,7 +5110,7 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { break; } - case SUBMODULE_IMPORTS: { + case SUBMODULE_IMPORTS: for (unsigned Idx = 0; Idx != Record.size(); ++Idx) { UnresolvedModuleRef Unresolved; Unresolved.File = &F; @@ -5078,9 +5121,8 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { UnresolvedModuleRefs.push_back(Unresolved); } break; - } - case SUBMODULE_EXPORTS: { + case SUBMODULE_EXPORTS: for (unsigned Idx = 0; Idx + 1 < Record.size(); Idx += 2) { UnresolvedModuleRef Unresolved; Unresolved.File = &F; @@ -5095,12 +5137,11 @@ ASTReader::ReadSubmoduleBlock(ModuleFile &F, unsigned ClientLoadCapabilities) { // the parsed, unresolved exports around. CurrentModule->UnresolvedExports.clear(); break; - } - case SUBMODULE_REQUIRES: { + + case SUBMODULE_REQUIRES: CurrentModule->addRequirement(Blob, Record[0], PP.getLangOpts(), PP.getTargetInfo()); break; - } case SUBMODULE_LINK_LIBRARY: CurrentModule->LinkLibraries.push_back( @@ -5450,7 +5491,7 @@ struct PPEntityComp { const ASTReader &Reader; ModuleFile &M; - PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) { } + PPEntityComp(const ASTReader &Reader, ModuleFile &M) : Reader(Reader), M(M) {} bool operator()(const PPEntityOffset &L, const PPEntityOffset &R) const { SourceLocation LHS = getLoc(L); @@ -5473,7 +5514,7 @@ struct PPEntityComp { } }; -} // end anonymous namespace +} // namespace PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc, bool EndsAfter) const { @@ -5489,7 +5530,9 @@ PreprocessedEntityID ASTReader::findPreprocessedEntity(SourceLocation Loc, return findNextPreprocessedEntity(SLocMapI); ModuleFile &M = *SLocMapI->second; - typedef const PPEntityOffset *pp_iterator; + + using pp_iterator = const PPEntityOffset *; + pp_iterator pp_begin = M.PreprocessedEntityOffsets; pp_iterator pp_end = pp_begin + M.NumPreprocessedEntities; @@ -5567,12 +5610,10 @@ namespace { /// \brief Visitor used to search for information about a header file. class HeaderFileInfoVisitor { const FileEntry *FE; - Optional<HeaderFileInfo> HFI; public: - explicit HeaderFileInfoVisitor(const FileEntry *FE) - : FE(FE) { } + explicit HeaderFileInfoVisitor(const FileEntry *FE) : FE(FE) {} bool operator()(ModuleFile &M) { HeaderFileInfoLookupTable *Table @@ -5592,7 +5633,7 @@ namespace { Optional<HeaderFileInfo> getHeaderFileInfo() const { return HFI; } }; -} // end anonymous namespace +} // namespace HeaderFileInfo ASTReader::GetHeaderFileInfo(const FileEntry *FE) { HeaderFileInfoVisitor Visitor(FE); @@ -6113,6 +6154,7 @@ QualType ASTReader::readTypeRecord(unsigned Index) { Protos.push_back(ReadDeclAs<ObjCProtocolDecl>(*Loc.F, Record, Idx)); return Context.getObjCTypeParamType(Decl, Protos); } + case TYPE_OBJC_OBJECT: { unsigned Idx = 0; QualType Base = readType(*Loc.F, Record, Idx); @@ -6309,7 +6351,9 @@ void ASTReader::readExceptionSpec(ModuleFile &ModuleFile, } } -class clang::TypeLocReader : public TypeLocVisitor<TypeLocReader> { +namespace clang { + +class TypeLocReader : public TypeLocVisitor<TypeLocReader> { ModuleFile *F; ASTReader *Reader; const ASTReader::RecordData &Record; @@ -6344,6 +6388,8 @@ public: void VisitArrayTypeLoc(ArrayTypeLoc); }; +} // namespace clang + void TypeLocReader::VisitQualifiedTypeLoc(QualifiedTypeLoc TL) { // nothing to do } @@ -6460,23 +6506,28 @@ void TypeLocReader::VisitFunctionProtoTypeLoc(FunctionProtoTypeLoc TL) { void TypeLocReader::VisitFunctionNoProtoTypeLoc(FunctionNoProtoTypeLoc TL) { VisitFunctionTypeLoc(TL); } + void TypeLocReader::VisitUnresolvedUsingTypeLoc(UnresolvedUsingTypeLoc TL) { TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitTypedefTypeLoc(TypedefTypeLoc TL) { TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitTypeOfExprTypeLoc(TypeOfExprTypeLoc TL) { TL.setTypeofLoc(ReadSourceLocation()); TL.setLParenLoc(ReadSourceLocation()); TL.setRParenLoc(ReadSourceLocation()); } + void TypeLocReader::VisitTypeOfTypeLoc(TypeOfTypeLoc TL) { TL.setTypeofLoc(ReadSourceLocation()); TL.setLParenLoc(ReadSourceLocation()); TL.setRParenLoc(ReadSourceLocation()); TL.setUnderlyingTInfo(GetTypeSourceInfo()); } + void TypeLocReader::VisitDecltypeTypeLoc(DecltypeTypeLoc TL) { TL.setNameLoc(ReadSourceLocation()); } @@ -6530,10 +6581,12 @@ void TypeLocReader::VisitSubstTemplateTypeParmTypeLoc( SubstTemplateTypeParmTypeLoc TL) { TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitSubstTemplateTypeParmPackTypeLoc( SubstTemplateTypeParmPackTypeLoc TL) { TL.setNameLoc(ReadSourceLocation()); } + void TypeLocReader::VisitTemplateSpecializationTypeLoc( TemplateSpecializationTypeLoc TL) { TL.setTemplateKeywordLoc(ReadSourceLocation()); @@ -6546,6 +6599,7 @@ void TypeLocReader::VisitTemplateSpecializationTypeLoc( Reader->GetTemplateArgumentLocInfo( *F, TL.getTypePtr()->getArg(i).getKind(), Record, Idx)); } + void TypeLocReader::VisitParenTypeLoc(ParenTypeLoc TL) { TL.setLParenLoc(ReadSourceLocation()); TL.setRParenLoc(ReadSourceLocation()); @@ -6656,13 +6710,11 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_BOOL_ID: T = Context.BoolTy; break; - case PREDEF_TYPE_CHAR_U_ID: case PREDEF_TYPE_CHAR_S_ID: // FIXME: Check that the signedness of CharTy is correct! T = Context.CharTy; break; - case PREDEF_TYPE_UCHAR_ID: T = Context.UnsignedCharTy; break; @@ -6776,19 +6828,15 @@ QualType ASTReader::GetType(TypeID ID) { case PREDEF_TYPE_AUTO_DEDUCT: T = Context.getAutoDeductType(); break; - case PREDEF_TYPE_AUTO_RREF_DEDUCT: T = Context.getAutoRRefDeductType(); break; - case PREDEF_TYPE_ARC_UNBRIDGED_CAST: T = Context.ARCUnbridgedCastTy; break; - case PREDEF_TYPE_BUILTIN_FN: T = Context.BuiltinFnTy; break; - case PREDEF_TYPE_OMP_ARRAY_SECTION: T = Context.OMPArraySectionTy; break; @@ -7275,7 +7323,7 @@ public: } }; -} // end anonymous namespace +} // namespace void ASTReader::FindFileRegionDecls(FileID File, unsigned Offset, unsigned Length, @@ -7471,30 +7519,25 @@ void ASTReader::PrintStats() { NumVisibleDeclContextsRead, TotalVisibleDeclContexts, ((float)NumVisibleDeclContextsRead/TotalVisibleDeclContexts * 100)); - if (TotalNumMethodPoolEntries) { + if (TotalNumMethodPoolEntries) std::fprintf(stderr, " %u/%u method pool entries read (%f%%)\n", NumMethodPoolEntriesRead, TotalNumMethodPoolEntries, ((float)NumMethodPoolEntriesRead/TotalNumMethodPoolEntries * 100)); - } - if (NumMethodPoolLookups) { + if (NumMethodPoolLookups) std::fprintf(stderr, " %u/%u method pool lookups succeeded (%f%%)\n", NumMethodPoolHits, NumMethodPoolLookups, ((float)NumMethodPoolHits/NumMethodPoolLookups * 100.0)); - } - if (NumMethodPoolTableLookups) { + if (NumMethodPoolTableLookups) std::fprintf(stderr, " %u/%u method pool table lookups succeeded (%f%%)\n", NumMethodPoolTableHits, NumMethodPoolTableLookups, ((float)NumMethodPoolTableHits/NumMethodPoolTableLookups * 100.0)); - } - - if (NumIdentifierLookupHits) { + if (NumIdentifierLookupHits) std::fprintf(stderr, " %u / %u identifier table lookups succeeded (%f%%)\n", NumIdentifierLookupHits, NumIdentifierLookups, (double)NumIdentifierLookupHits*100.0/NumIdentifierLookups); - } if (GlobalIndex) { std::fprintf(stderr, "\n"); @@ -7514,7 +7557,8 @@ dumpModuleIDMap(StringRef Name, if (Map.begin() == Map.end()) return; - typedef ContinuousRangeMap<Key, ModuleFile *, InitialCapacity> MapType; + using MapType = ContinuousRangeMap<Key, ModuleFile *, InitialCapacity>; + llvm::errs() << Name << ":\n"; for (typename MapType::const_iterator I = Map.begin(), IEnd = Map.end(); I != IEnd; ++I) { @@ -7711,7 +7755,7 @@ namespace clang { StringRef Next() override; }; -} // end namespace clang +} // namespace clang ASTIdentifierIterator::ASTIdentifierIterator(const ASTReader &Reader, bool SkipModules) @@ -7769,7 +7813,7 @@ public: } }; -} // end anonymous namespace. +} // namespace IdentifierIterator *ASTReader::getIdentifiers() { if (!loadGlobalIndex()) { @@ -7791,19 +7835,17 @@ namespace serialization { ASTReader &Reader; Selector Sel; unsigned PriorGeneration; - unsigned InstanceBits; - unsigned FactoryBits; - bool InstanceHasMoreThanOneDecl; - bool FactoryHasMoreThanOneDecl; + unsigned InstanceBits = 0; + unsigned FactoryBits = 0; + bool InstanceHasMoreThanOneDecl = false; + bool FactoryHasMoreThanOneDecl = false; SmallVector<ObjCMethodDecl *, 4> InstanceMethods; SmallVector<ObjCMethodDecl *, 4> FactoryMethods; public: ReadMethodPoolVisitor(ASTReader &Reader, Selector Sel, unsigned PriorGeneration) - : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration), - InstanceBits(0), FactoryBits(0), InstanceHasMoreThanOneDecl(false), - FactoryHasMoreThanOneDecl(false) {} + : Reader(Reader), Sel(Sel), PriorGeneration(PriorGeneration) {} bool operator()(ModuleFile &M) { if (!M.SelectorLookupTable) @@ -7851,14 +7893,16 @@ namespace serialization { unsigned getInstanceBits() const { return InstanceBits; } unsigned getFactoryBits() const { return FactoryBits; } + bool instanceHasMoreThanOneDecl() const { return InstanceHasMoreThanOneDecl; } + bool factoryHasMoreThanOneDecl() const { return FactoryHasMoreThanOneDecl; } }; -} // end namespace serialization -} // end namespace clang +} // namespace serialization +} // namespace clang /// \brief Add the given set of methods to the method list. static void addMethodsToPool(Sema &S, ArrayRef<ObjCMethodDecl *> Methods, @@ -8001,7 +8045,7 @@ void ASTReader::ReadUnusedLocalTypedefNameCandidates( } void ASTReader::ReadReferencedSelectors( - SmallVectorImpl<std::pair<Selector, SourceLocation> > &Sels) { + SmallVectorImpl<std::pair<Selector, SourceLocation>> &Sels) { if (ReferencedSelectorsData.empty()) return; @@ -8019,7 +8063,7 @@ void ASTReader::ReadReferencedSelectors( } void ASTReader::ReadWeakUndeclaredIdentifiers( - SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo> > &WeakIDs) { + SmallVectorImpl<std::pair<IdentifierInfo *, WeakInfo>> &WeakIDs) { if (WeakUndeclaredIdentifiers.empty()) return; @@ -8051,7 +8095,7 @@ void ASTReader::ReadUsedVTables(SmallVectorImpl<ExternalVTableUse> &VTables) { } void ASTReader::ReadPendingInstantiations( - SmallVectorImpl<std::pair<ValueDecl *, SourceLocation> > &Pending) { + SmallVectorImpl<std::pair<ValueDecl *, SourceLocation>> &Pending) { for (unsigned Idx = 0, N = PendingInstantiations.size(); Idx < N;) { ValueDecl *D = cast<ValueDecl>(GetDecl(PendingInstantiations[Idx++])); SourceLocation Loc @@ -8763,11 +8807,10 @@ ASTReader::ReadNestedNameSpecifier(ModuleFile &F, break; } - case NestedNameSpecifier::Global: { + case NestedNameSpecifier::Global: NNS = NestedNameSpecifier::GlobalSpecifier(Context); // No associated value, and there can't be a prefix. break; - } case NestedNameSpecifier::Super: { CXXRecordDecl *RD = ReadDeclAs<CXXRecordDecl>(F, Record, Idx); @@ -8944,7 +8987,7 @@ void ASTReader::ReadComments() { ASTContext &Context = getContext(); std::vector<RawComment *> Comments; for (SmallVectorImpl<std::pair<BitstreamCursor, - serialization::ModuleFile *> >::iterator + serialization::ModuleFile *>>::iterator I = CommentsCursors.begin(), E = CommentsCursors.end(); I != E; ++I) { @@ -9034,7 +9077,7 @@ std::string ASTReader::getOwningModuleNameForDiagnostic(const Decl *D) { return M->ModuleName; // Not from a module. - return ""; + return {}; } void ASTReader::finishPendingActions() { @@ -9044,8 +9087,8 @@ void ASTReader::finishPendingActions() { !PendingUpdateRecords.empty()) { // If any identifiers with corresponding top-level declarations have // been loaded, load those declarations now. - typedef llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2> > - TopLevelDeclsMap; + using TopLevelDeclsMap = + llvm::DenseMap<IdentifierInfo *, SmallVector<Decl *, 2>>; TopLevelDeclsMap TopLevelDecls; while (!PendingIdentifierInfos.empty()) { @@ -10412,7 +10455,7 @@ void ASTReader::diagnoseOdrViolations() { } } - if (Diagnosed == true) + if (Diagnosed) continue; Diag(FirstDecl->getLocation(), diff --git a/lib/Serialization/ASTWriter.cpp b/lib/Serialization/ASTWriter.cpp index dec8d8f7d7..3834314109 100644 --- a/lib/Serialization/ASTWriter.cpp +++ b/lib/Serialization/ASTWriter.cpp @@ -2407,6 +2407,17 @@ void ASTWriter::WritePreprocessor(const Preprocessor &PP, bool IsModule) { if (PP.isRecordingPreamble() && PP.hasRecordedPreamble()) { assert(!IsModule); + auto SkipInfo = PP.getPreambleSkipInfo(); + if (SkipInfo.hasValue()) { + Record.push_back(true); + AddSourceLocation(SkipInfo->HashTokenLoc, Record); + AddSourceLocation(SkipInfo->IfTokenLoc, Record); + Record.push_back(SkipInfo->FoundNonSkipPortion); + Record.push_back(SkipInfo->FoundElse); + AddSourceLocation(SkipInfo->ElseLoc, Record); + } else { + Record.push_back(false); + } for (const auto &Cond : PP.getPreambleConditionalStack()) { AddSourceLocation(Cond.IfLoc, Record); Record.push_back(Cond.WasSkipping); diff --git a/lib/Serialization/ASTWriterDecl.cpp b/lib/Serialization/ASTWriterDecl.cpp index 803795887c..e940806094 100644 --- a/lib/Serialization/ASTWriterDecl.cpp +++ b/lib/Serialization/ASTWriterDecl.cpp @@ -2258,15 +2258,24 @@ void ASTRecordWriter::AddFunctionDefinition(const FunctionDecl *FD) { assert(FD->doesThisDeclarationHaveABody()); bool ModulesCodegen = false; if (Writer->WritingModule && !FD->isDependentContext()) { - // Under -fmodules-codegen, codegen is performed for all defined functions. - // When building a C++ Modules TS module interface unit, a strong definition - // in the module interface is provided by the compilation of that module - // interface unit, not by its users. (Inline functions are still emitted - // in module users.) - ModulesCodegen = - Writer->Context->getLangOpts().ModulesCodegen || - (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit && - Writer->Context->GetGVALinkageForFunction(FD) == GVA_StrongExternal); + Optional<GVALinkage> Linkage; + if (Writer->WritingModule->Kind == Module::ModuleInterfaceUnit) { + // When building a C++ Modules TS module interface unit, a strong + // definition in the module interface is provided by the compilation of + // that module interface unit, not by its users. (Inline functions are + // still emitted in module users.) + Linkage = Writer->Context->GetGVALinkageForFunction(FD); + ModulesCodegen = *Linkage == GVA_StrongExternal; + } + if (Writer->Context->getLangOpts().ModulesCodegen) { + // Under -fmodules-codegen, codegen is performed for all non-internal, + // non-always_inline functions. + if (!FD->hasAttr<AlwaysInlineAttr>()) { + if (!Linkage) + Linkage = Writer->Context->GetGVALinkageForFunction(FD); + ModulesCodegen = *Linkage != GVA_Internal; + } + } } Record->push_back(ModulesCodegen); if (ModulesCodegen) diff --git a/lib/Serialization/MultiOnDiskHashTable.h b/lib/Serialization/MultiOnDiskHashTable.h index fdbbb602b5..44d1616a01 100644 --- a/lib/Serialization/MultiOnDiskHashTable.h +++ b/lib/Serialization/MultiOnDiskHashTable.h @@ -1,4 +1,4 @@ -//===--- MultiOnDiskHashTable.h - Merged set of hash tables -----*- C++ -*-===// +//===- MultiOnDiskHashTable.h - Merged set of hash tables -------*- C++ -*-===// // // The LLVM Compiler Infrastructure // @@ -15,6 +15,7 @@ // files. // //===----------------------------------------------------------------------===// + #ifndef LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H #define LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H @@ -22,33 +23,43 @@ #include "llvm/ADT/DenseSet.h" #include "llvm/ADT/PointerUnion.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/ADT/SmallVector.h" #include "llvm/ADT/TinyPtrVector.h" +#include "llvm/ADT/iterator_range.h" +#include "llvm/Support/Endian.h" #include "llvm/Support/EndianStream.h" #include "llvm/Support/OnDiskHashTable.h" +#include "llvm/Support/raw_ostream.h" +#include <algorithm> +#include <cstdint> +#include <vector> namespace clang { namespace serialization { -class ModuleFile; - /// \brief A collection of on-disk hash tables, merged when relevant for performance. template<typename Info> class MultiOnDiskHashTable { public: /// A handle to a file, used when overriding tables. - typedef typename Info::file_type file_type; + using file_type = typename Info::file_type; + /// A pointer to an on-disk representation of the hash table. - typedef const unsigned char *storage_type; + using storage_type = const unsigned char *; - typedef typename Info::external_key_type external_key_type; - typedef typename Info::internal_key_type internal_key_type; - typedef typename Info::data_type data_type; - typedef typename Info::data_type_builder data_type_builder; - typedef unsigned hash_value_type; + using external_key_type = typename Info::external_key_type; + using internal_key_type = typename Info::internal_key_type; + using data_type = typename Info::data_type; + using data_type_builder = typename Info::data_type_builder; + using hash_value_type = unsigned; private: + /// The generator is permitted to read our merged table. + template<typename ReaderInfo, typename WriterInfo> + friend class MultiOnDiskHashTableGenerator; + /// \brief A hash table stored on disk. struct OnDiskTable { - typedef llvm::OnDiskIterableChainedHashTable<Info> HashTable; + using HashTable = llvm::OnDiskIterableChainedHashTable<Info>; file_type File; HashTable Table; @@ -65,8 +76,8 @@ private: llvm::DenseMap<internal_key_type, data_type> Data; }; - typedef llvm::PointerUnion<OnDiskTable*, MergedTable*> Table; - typedef llvm::TinyPtrVector<void*> TableVector; + using Table = llvm::PointerUnion<OnDiskTable *, MergedTable *>; + using TableVector = llvm::TinyPtrVector<void *>; /// \brief The current set of on-disk and merged tables. /// We manually store the opaque value of the Table because TinyPtrVector @@ -80,14 +91,16 @@ private: llvm::TinyPtrVector<file_type> PendingOverrides; struct AsOnDiskTable { - typedef OnDiskTable *result_type; + using result_type = OnDiskTable *; + result_type operator()(void *P) const { return Table::getFromOpaqueValue(P).template get<OnDiskTable *>(); } }; - typedef llvm::mapped_iterator<TableVector::iterator, AsOnDiskTable> - table_iterator; - typedef llvm::iterator_range<table_iterator> table_range; + + using table_iterator = + llvm::mapped_iterator<TableVector::iterator, AsOnDiskTable>; + using table_range = llvm::iterator_range<table_iterator>; /// \brief The current set of on-disk tables. table_range tables() { @@ -160,17 +173,15 @@ private: Tables.push_back(Table(Merged).getOpaqueValue()); } - /// The generator is permitted to read our merged table. - template<typename ReaderInfo, typename WriterInfo> - friend class MultiOnDiskHashTableGenerator; - public: - MultiOnDiskHashTable() {} + MultiOnDiskHashTable() = default; + MultiOnDiskHashTable(MultiOnDiskHashTable &&O) : Tables(std::move(O.Tables)), PendingOverrides(std::move(O.PendingOverrides)) { O.Tables.clear(); } + MultiOnDiskHashTable &operator=(MultiOnDiskHashTable &&O) { if (&O == this) return *this; @@ -180,11 +191,13 @@ public: PendingOverrides = std::move(O.PendingOverrides); return *this; } + ~MultiOnDiskHashTable() { clear(); } /// \brief Add the table \p Data loaded from file \p File. void add(file_type File, storage_type Data, Info InfoObj = Info()) { using namespace llvm::support; + storage_type Ptr = Data; uint32_t BucketOffset = endian::readNext<uint32_t, little, unaligned>(Ptr); @@ -278,8 +291,8 @@ public: /// \brief Writer for the on-disk hash table. template<typename ReaderInfo, typename WriterInfo> class MultiOnDiskHashTableGenerator { - typedef MultiOnDiskHashTable<ReaderInfo> BaseTable; - typedef llvm::OnDiskChainedHashTableGenerator<WriterInfo> Generator; + using BaseTable = MultiOnDiskHashTable<ReaderInfo>; + using Generator = llvm::OnDiskChainedHashTableGenerator<WriterInfo>; Generator Gen; @@ -294,6 +307,7 @@ public: void emit(llvm::SmallVectorImpl<char> &Out, WriterInfo &Info, const BaseTable *Base) { using namespace llvm::support; + llvm::raw_svector_ostream OutStream(Out); // Write our header information. @@ -327,8 +341,7 @@ public: } }; -} // end namespace clang::serialization -} // end namespace clang - +} // namespace serialization +} // namespace clang -#endif +#endif // LLVM_CLANG_LIB_SERIALIZATION_MULTIONDISKHASHTABLE_H diff --git a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp index 58218df238..28ad7e9e50 100644 --- a/lib/StaticAnalyzer/Checkers/CStringChecker.cpp +++ b/lib/StaticAnalyzer/Checkers/CStringChecker.cpp @@ -289,8 +289,8 @@ ProgramStateRef CStringChecker::CheckLocation(CheckerContext &C, if (!ER) return state; - assert(ER->getValueType() == C.getASTContext().CharTy && - "CheckLocation should only be called with char* ElementRegions"); + if (ER->getValueType() != C.getASTContext().CharTy) + return state; // Get the size of the array. const SubRegion *superReg = cast<SubRegion>(ER->getSuperRegion()); @@ -874,6 +874,8 @@ bool CStringChecker::IsFirstBufInBound(CheckerContext &C, if (!ER) return true; // cf top comment. + // FIXME: Does this crash when a non-standard definition + // of a library function is encountered? assert(ER->getValueType() == C.getASTContext().CharTy && "IsFirstBufInBound should only be called with char* ElementRegions"); diff --git a/lib/StaticAnalyzer/Core/ExprEngineC.cpp b/lib/StaticAnalyzer/Core/ExprEngineC.cpp index 6f1e8391e6..01c6af7ffa 100644 --- a/lib/StaticAnalyzer/Core/ExprEngineC.cpp +++ b/lib/StaticAnalyzer/Core/ExprEngineC.cpp @@ -92,12 +92,10 @@ void ExprEngine::VisitBinaryOperator(const BinaryOperator* B, // Process non-assignments except commas or short-circuited // logical expressions (LAnd and LOr). SVal Result = evalBinOp(state, Op, LeftV, RightV, B->getType()); - if (Result.isUnknown()) { - Bldr.generateNode(B, *it, state); - continue; + if (!Result.isUnknown()) { + state = state->BindExpr(B, LCtx, Result); } - state = state->BindExpr(B, LCtx, Result); Bldr.generateNode(B, *it, state); continue; } @@ -628,6 +626,16 @@ void ExprEngine::VisitLogicalExpr(const BinaryOperator* B, ExplodedNode *Pred, StmtNodeBuilder Bldr(Pred, Dst, *currBldrCtx); ProgramStateRef state = Pred->getState(); + if (B->getType()->isVectorType()) { + // FIXME: We do not model vector arithmetic yet. When adding support for + // that, note that the CFG-based reasoning below does not apply, because + // logical operators on vectors are not short-circuit. Currently they are + // modeled as short-circuit in Clang CFG but this is incorrect. + // Do not set the value for the expression. It'd be UnknownVal by default. + Bldr.generateNode(B, Pred, state); + return; + } + ExplodedNode *N = Pred; while (!N->getLocation().getAs<BlockEntrance>()) { ProgramPoint P = N->getLocation(); diff --git a/lib/Tooling/Core/CMakeLists.txt b/lib/Tooling/Core/CMakeLists.txt index e2b0dd424d..b302479358 100644 --- a/lib/Tooling/Core/CMakeLists.txt +++ b/lib/Tooling/Core/CMakeLists.txt @@ -3,7 +3,6 @@ set(LLVM_LINK_COMPONENTS support) add_clang_library(clangToolingCore Lookup.cpp Replacement.cpp - QualTypeNames.cpp Diagnostic.cpp LINK_LIBS diff --git a/lib/Tooling/Execution.cpp b/lib/Tooling/Execution.cpp index 1a078ef7e1..498d683f89 100644 --- a/lib/Tooling/Execution.cpp +++ b/lib/Tooling/Execution.cpp @@ -54,13 +54,14 @@ llvm::Error ToolExecutor::execute(std::unique_ptr<FrontendActionFactory> Action, return execute(Actions); } +namespace internal { llvm::Expected<std::unique_ptr<ToolExecutor>> -createExecutorFromCommandLineArgs(int &argc, const char **argv, - llvm::cl::OptionCategory &Category, - const char *Overview) { +createExecutorFromCommandLineArgsImpl(int &argc, const char **argv, + llvm::cl::OptionCategory &Category, + const char *Overview) { auto OptionsParser = CommonOptionsParser::create(argc, argv, Category, llvm::cl::ZeroOrMore, - /*Overview=*/nullptr); + /*Overview=*/Overview); if (!OptionsParser) return OptionsParser.takeError(); for (auto I = ToolExecutorPluginRegistry::begin(), @@ -84,6 +85,21 @@ createExecutorFromCommandLineArgs(int &argc, const char **argv, llvm::Twine("Executor \"") + ExecutorName + "\" is not registered.", llvm::inconvertibleErrorCode()); } +} // end namespace internal + +llvm::Expected<std::unique_ptr<ToolExecutor>> +createExecutorFromCommandLineArgs(int &argc, const char **argv, + llvm::cl::OptionCategory &Category, + const char *Overview) { + return internal::createExecutorFromCommandLineArgsImpl(argc, argv, Category, + Overview); +} + +// This anchor is used to force the linker to link in the generated object file +// and thus register the StandaloneToolExecutorPlugin. +extern volatile int StandaloneToolExecutorAnchorSource; +static int LLVM_ATTRIBUTE_UNUSED StandaloneToolExecutorAnchorDest = + StandaloneToolExecutorAnchorSource; } // end namespace tooling } // end namespace clang diff --git a/lib/Tooling/Refactoring/ASTSelection.cpp b/lib/Tooling/Refactoring/ASTSelection.cpp index 71a0d44be1..ab2be15512 100644 --- a/lib/Tooling/Refactoring/ASTSelection.cpp +++ b/lib/Tooling/Refactoring/ASTSelection.cpp @@ -249,9 +249,30 @@ struct SelectedNodeWithParents { SelectedNodeWithParents &operator=(SelectedNodeWithParents &&) = default; SelectedASTNode::ReferenceType Node; llvm::SmallVector<SelectedASTNode::ReferenceType, 8> Parents; + + /// Canonicalizes the given selection by selecting different related AST nodes + /// when it makes sense to do so. + void canonicalize(); }; } // end anonymous namespace +void SelectedNodeWithParents::canonicalize() { + const Stmt *S = Node.get().Node.get<Stmt>(); + assert(S && "non statement selection!"); + const Stmt *Parent = Parents[Parents.size() - 1].get().Node.get<Stmt>(); + if (!Parent) + return; + // Select the parent expression when: + // - The string literal in ObjC string literal is selected, e.g.: + // @"test" becomes @"test" + // ~~~~~~ ~~~~~~~ + if (isa<StringLiteral>(S) && isa<ObjCStringLiteral>(Parent)) + Node = Parents.pop_back_val(); + // FIXME: Syntactic form -> Entire pseudo-object expr. + // FIXME: Callee -> Call. + // FIXME: Callee member expr -> Call. +} + /// Finds the set of bottom-most selected AST nodes that are in the selection /// tree with the specified selection kind. /// @@ -330,7 +351,7 @@ CodeRangeASTSelection::create(SourceRange SelectionRange, return None; const Stmt *CodeRangeStmt = Selected.Node.get().Node.get<Stmt>(); if (!isa<CompoundStmt>(CodeRangeStmt)) { - // FIXME (Alex L): Canonicalize. + Selected.canonicalize(); return CodeRangeASTSelection(Selected.Node, Selected.Parents, /*AreChildrenSelected=*/false); } diff --git a/lib/Tooling/Refactoring/CMakeLists.txt b/lib/Tooling/Refactoring/CMakeLists.txt index 5d3ddd45b6..402b5d3c6a 100644 --- a/lib/Tooling/Refactoring/CMakeLists.txt +++ b/lib/Tooling/Refactoring/CMakeLists.txt @@ -4,7 +4,8 @@ add_clang_library(clangToolingRefactor ASTSelection.cpp ASTSelectionRequirements.cpp AtomicChange.cpp - Extract.cpp + Extract/Extract.cpp + Extract/SourceExtraction.cpp RefactoringActions.cpp Rename/RenamingAction.cpp Rename/SymbolOccurrences.cpp diff --git a/lib/Tooling/Refactoring/Extract.cpp b/lib/Tooling/Refactoring/Extract/Extract.cpp index 3f5a839318..b0847a7400 100644 --- a/lib/Tooling/Refactoring/Extract.cpp +++ b/lib/Tooling/Refactoring/Extract/Extract.cpp @@ -14,6 +14,7 @@ //===----------------------------------------------------------------------===// #include "clang/Tooling/Refactoring/Extract/Extract.h" +#include "SourceExtraction.h" #include "clang/AST/ASTContext.h" #include "clang/AST/DeclCXX.h" #include "clang/AST/Expr.h" @@ -145,6 +146,8 @@ ExtractFunction::createSourceReplacements(RefactoringRuleContext &Context) { PP.SuppressLifetimeQualifiers = true; PP.SuppressUnwrittenScope = true; + ExtractionSemicolonPolicy Semicolons = ExtractionSemicolonPolicy::compute( + Code[Code.size() - 1], ExtractedRange, SM, LangOpts); AtomicChange Change(SM, ExtractedDeclLocation); // Create the replacement for the extracted declaration. { @@ -162,8 +165,8 @@ ExtractFunction::createSourceReplacements(RefactoringRuleContext &Context) { if (IsExpr && !ReturnType->isVoidType()) OS << "return "; OS << ExtractedCodeRewriter.getRewrittenText(ExtractedRange); - // FIXME: Compute the correct semicolon policy. - OS << ';'; + if (Semicolons.isNeededInExtractedFunction()) + OS << ';'; OS << "\n}\n\n"; auto Err = Change.insert(SM, ExtractedDeclLocation, OS.str()); if (Err) @@ -178,7 +181,8 @@ ExtractFunction::createSourceReplacements(RefactoringRuleContext &Context) { OS << DeclName << '('; // FIXME: Forward arguments. OS << ')'; - // FIXME: Add semicolon if needed. + if (Semicolons.isNeededInOriginalFunction()) + OS << ';'; auto Err = Change.replace( SM, CharSourceRange::getTokenRange(ExtractedRange), OS.str()); diff --git a/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp b/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp new file mode 100644 index 0000000000..7fd8cc2d3c --- /dev/null +++ b/lib/Tooling/Refactoring/Extract/SourceExtraction.cpp @@ -0,0 +1,112 @@ +//===--- SourceExtraction.cpp - Clang refactoring library -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#include "SourceExtraction.h" +#include "clang/AST/Stmt.h" +#include "clang/AST/StmtCXX.h" +#include "clang/AST/StmtObjC.h" +#include "clang/Basic/SourceManager.h" +#include "clang/Lex/Lexer.h" + +using namespace clang; + +namespace { + +/// Returns true if the token at the given location is a semicolon. +bool isSemicolonAtLocation(SourceLocation TokenLoc, const SourceManager &SM, + const LangOptions &LangOpts) { + return Lexer::getSourceText( + CharSourceRange::getTokenRange(TokenLoc, TokenLoc), SM, + LangOpts) == ";"; +} + +/// Returns true if there should be a semicolon after the given statement. +bool isSemicolonRequiredAfter(const Stmt *S) { + if (isa<CompoundStmt>(S)) + return false; + if (const auto *If = dyn_cast<IfStmt>(S)) + return isSemicolonRequiredAfter(If->getElse() ? If->getElse() + : If->getThen()); + if (const auto *While = dyn_cast<WhileStmt>(S)) + return isSemicolonRequiredAfter(While->getBody()); + if (const auto *For = dyn_cast<ForStmt>(S)) + return isSemicolonRequiredAfter(For->getBody()); + if (const auto *CXXFor = dyn_cast<CXXForRangeStmt>(S)) + return isSemicolonRequiredAfter(CXXFor->getBody()); + if (const auto *ObjCFor = dyn_cast<ObjCForCollectionStmt>(S)) + return isSemicolonRequiredAfter(ObjCFor->getBody()); + switch (S->getStmtClass()) { + case Stmt::SwitchStmtClass: + case Stmt::CXXTryStmtClass: + case Stmt::ObjCAtSynchronizedStmtClass: + case Stmt::ObjCAutoreleasePoolStmtClass: + case Stmt::ObjCAtTryStmtClass: + return false; + default: + return true; + } +} + +/// Returns true if the two source locations are on the same line. +bool areOnSameLine(SourceLocation Loc1, SourceLocation Loc2, + const SourceManager &SM) { + return !Loc1.isMacroID() && !Loc2.isMacroID() && + SM.getSpellingLineNumber(Loc1) == SM.getSpellingLineNumber(Loc2); +} + +} // end anonymous namespace + +namespace clang { +namespace tooling { + +ExtractionSemicolonPolicy +ExtractionSemicolonPolicy::compute(const Stmt *S, SourceRange &ExtractedRange, + const SourceManager &SM, + const LangOptions &LangOpts) { + auto neededInExtractedFunction = []() { + return ExtractionSemicolonPolicy(true, false); + }; + auto neededInOriginalFunction = []() { + return ExtractionSemicolonPolicy(false, true); + }; + + /// The extracted expression should be terminated with a ';'. The call to + /// the extracted function will replace this expression, so it won't need + /// a terminating ';'. + if (isa<Expr>(S)) + return neededInExtractedFunction(); + + /// Some statements don't need to be terminated with ';'. The call to the + /// extracted function will be a standalone statement, so it should be + /// terminated with a ';'. + bool NeedsSemi = isSemicolonRequiredAfter(S); + if (!NeedsSemi) + return neededInOriginalFunction(); + + /// Some statements might end at ';'. The extraction will move that ';', so + /// the call to the extracted function should be terminated with a ';'. + SourceLocation End = ExtractedRange.getEnd(); + if (isSemicolonAtLocation(End, SM, LangOpts)) + return neededInOriginalFunction(); + + /// Other statements should generally have a trailing ';'. We can try to find + /// it and move it together it with the extracted code. + Optional<Token> NextToken = Lexer::findNextToken(End, SM, LangOpts); + if (NextToken && NextToken->is(tok::semi) && + areOnSameLine(NextToken->getLocation(), End, SM)) { + ExtractedRange.setEnd(NextToken->getLocation()); + return neededInOriginalFunction(); + } + + /// Otherwise insert semicolons in both places. + return ExtractionSemicolonPolicy(true, true); +} + +} // end namespace tooling +} // end namespace clang diff --git a/lib/Tooling/Refactoring/Extract/SourceExtraction.h b/lib/Tooling/Refactoring/Extract/SourceExtraction.h new file mode 100644 index 0000000000..4b4bd8b477 --- /dev/null +++ b/lib/Tooling/Refactoring/Extract/SourceExtraction.h @@ -0,0 +1,52 @@ +//===--- SourceExtraction.cpp - Clang refactoring library -----------------===// +// +// The LLVM Compiler Infrastructure +// +// This file is distributed under the University of Illinois Open Source +// License. See LICENSE.TXT for details. +// +//===----------------------------------------------------------------------===// + +#ifndef LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H +#define LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H + +#include "clang/Basic/LLVM.h" + +namespace clang { + +class LangOptions; +class SourceManager; +class SourceRange; +class Stmt; + +namespace tooling { + +/// Determines which semicolons should be inserted during extraction. +class ExtractionSemicolonPolicy { +public: + bool isNeededInExtractedFunction() const { + return IsNeededInExtractedFunction; + } + + bool isNeededInOriginalFunction() const { return IsNeededInOriginalFunction; } + + /// Returns the semicolon insertion policy that is needed for extraction of + /// the given statement from the given source range. + static ExtractionSemicolonPolicy compute(const Stmt *S, + SourceRange &ExtractedRange, + const SourceManager &SM, + const LangOptions &LangOpts); + +private: + ExtractionSemicolonPolicy(bool IsNeededInExtractedFunction, + bool IsNeededInOriginalFunction) + : IsNeededInExtractedFunction(IsNeededInExtractedFunction), + IsNeededInOriginalFunction(IsNeededInOriginalFunction) {} + bool IsNeededInExtractedFunction; + bool IsNeededInOriginalFunction; +}; + +} // end namespace tooling +} // end namespace clang + +#endif // LLVM_CLANG_LIB_TOOLING_REFACTORING_EXTRACT_SOURCE_EXTRACTION_H diff --git a/lib/Tooling/Refactoring/RefactoringActions.cpp b/lib/Tooling/Refactoring/RefactoringActions.cpp index 73a3118396..37a1639cb4 100644 --- a/lib/Tooling/Refactoring/RefactoringActions.cpp +++ b/lib/Tooling/Refactoring/RefactoringActions.cpp @@ -46,6 +46,22 @@ public: } }; +class OldQualifiedNameOption : public RequiredRefactoringOption<std::string> { +public: + StringRef getName() const override { return "old-qualified-name"; } + StringRef getDescription() const override { + return "The old qualified name to be renamed"; + } +}; + +class NewQualifiedNameOption : public RequiredRefactoringOption<std::string> { +public: + StringRef getName() const override { return "new-qualified-name"; } + StringRef getDescription() const override { + return "The new qualified name to change the symbol to"; + } +}; + class NewNameOption : public RequiredRefactoringOption<std::string> { public: StringRef getName() const override { return "new-name"; } @@ -70,6 +86,10 @@ public: RefactoringActionRules Rules; Rules.push_back(createRefactoringActionRule<RenameOccurrences>( SourceRangeSelectionRequirement(), OptionRequirement<NewNameOption>())); + // FIXME: Use NewNameOption. + Rules.push_back(createRefactoringActionRule<QualifiedRenameRule>( + OptionRequirement<OldQualifiedNameOption>(), + OptionRequirement<NewQualifiedNameOption>())); return Rules; } }; diff --git a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp index 695fa553b4..c8ed9dd19a 100644 --- a/lib/Tooling/Refactoring/Rename/RenamingAction.cpp +++ b/lib/Tooling/Refactoring/Rename/RenamingAction.cpp @@ -31,6 +31,8 @@ #include "clang/Tooling/Refactoring/Rename/USRLocFinder.h" #include "clang/Tooling/Tooling.h" #include "llvm/ADT/STLExtras.h" +#include "llvm/Support/Errc.h" +#include "llvm/Support/Error.h" #include <string> #include <vector> @@ -41,22 +43,14 @@ namespace tooling { namespace { -class OccurrenceFinder final : public FindSymbolOccurrencesRefactoringRule { -public: - OccurrenceFinder(const NamedDecl *ND) : ND(ND) {} - - Expected<SymbolOccurrences> - findSymbolOccurrences(RefactoringRuleContext &Context) override { - std::vector<std::string> USRs = - getUSRsForDeclaration(ND, Context.getASTContext()); - std::string PrevName = ND->getNameAsString(); - return getOccurrencesOfUSRs( - USRs, PrevName, Context.getASTContext().getTranslationUnitDecl()); - } - -private: - const NamedDecl *ND; -}; +Expected<SymbolOccurrences> +findSymbolOccurrences(const NamedDecl *ND, RefactoringRuleContext &Context) { + std::vector<std::string> USRs = + getUSRsForDeclaration(ND, Context.getASTContext()); + std::string PrevName = ND->getNameAsString(); + return getOccurrencesOfUSRs(USRs, PrevName, + Context.getASTContext().getTranslationUnitDecl()); +} } // end anonymous namespace @@ -83,8 +77,7 @@ RenameOccurrences::initiate(RefactoringRuleContext &Context, Expected<AtomicChanges> RenameOccurrences::createSourceReplacements(RefactoringRuleContext &Context) { - Expected<SymbolOccurrences> Occurrences = - OccurrenceFinder(ND).findSymbolOccurrences(Context); + Expected<SymbolOccurrences> Occurrences = findSymbolOccurrences(ND, Context); if (!Occurrences) return Occurrences.takeError(); // FIXME: Verify that the new name is valid. @@ -93,6 +86,60 @@ RenameOccurrences::createSourceReplacements(RefactoringRuleContext &Context) { *Occurrences, Context.getASTContext().getSourceManager(), Name); } +Expected<QualifiedRenameRule> +QualifiedRenameRule::initiate(RefactoringRuleContext &Context, + std::string OldQualifiedName, + std::string NewQualifiedName) { + const NamedDecl *ND = + getNamedDeclFor(Context.getASTContext(), OldQualifiedName); + if (!ND) + return llvm::make_error<llvm::StringError>("Could not find symbol " + + OldQualifiedName, + llvm::errc::invalid_argument); + return QualifiedRenameRule(ND, std::move(NewQualifiedName)); +} + +const RefactoringDescriptor &QualifiedRenameRule::describe() { + static const RefactoringDescriptor Descriptor = { + /*Name=*/"local-qualified-rename", + /*Title=*/"Qualified Rename", + /*Description=*/ + R"(Finds and renames qualified symbols in code within a translation unit. +It is used to move/rename a symbol to a new namespace/name: + * Supported symbols: classes, class members, functions, enums, and type alias. + * Renames all symbol occurrences from the old qualified name to the new + qualified name. All symbol references will be correctly qualified; For + symbol definitions, only name will be changed. +For example, rename "A::Foo" to "B::Bar": + Old code: + namespace foo { + class A {}; + } + + namespace bar { + void f(foo::A a) {} + } + + New code after rename: + namespace foo { + class B {}; + } + + namespace bar { + void f(B b) {} + })" + }; + return Descriptor; +} + +Expected<AtomicChanges> +QualifiedRenameRule::createSourceReplacements(RefactoringRuleContext &Context) { + auto USRs = getUSRsForDeclaration(ND, Context.getASTContext()); + assert(!USRs.empty()); + return tooling::createRenameAtomicChanges( + USRs, NewQualifiedName, Context.getASTContext().getTranslationUnitDecl()); +} + Expected<std::vector<AtomicChange>> createRenameReplacements(const SymbolOccurrences &Occurrences, const SourceManager &SM, const SymbolName &NewName) { diff --git a/lib/Tooling/StandaloneExecution.cpp b/lib/Tooling/StandaloneExecution.cpp index e52e4a611f..eea8e39d13 100644 --- a/lib/Tooling/StandaloneExecution.cpp +++ b/lib/Tooling/StandaloneExecution.cpp @@ -79,13 +79,13 @@ public: } }; -// This anchor is used to force the linker to link in the generated object file -// and thus register the plugin. -volatile int ToolExecutorPluginAnchorSource = 0; - static ToolExecutorPluginRegistry::Add<StandaloneToolExecutorPlugin> X("standalone", "Runs FrontendActions on a set of files provided " "via positional arguments."); +// This anchor is used to force the linker to link in the generated object file +// and thus register the plugin. +volatile int StandaloneToolExecutorAnchorSource = 0; + } // end namespace tooling } // end namespace clang diff --git a/test/Analysis/call_once.cpp b/test/Analysis/call_once.cpp index 5013cd423e..db9e5cc7ca 100644 --- a/test/Analysis/call_once.cpp +++ b/test/Analysis/call_once.cpp @@ -1,6 +1,11 @@ // RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -verify %s // RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBSTDCPP -verify %s +// We do NOT model libcxx03 implementation, but the analyzer should still +// not crash. +// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -verify %s +// RUN: %clang_analyze_cc1 -std=c++11 -fblocks -analyzer-checker=core,debug.ExprInspection -DEMULATE_LIBCXX03 -DEMULATE_LIBSTDCPP -verify %s + void clang_analyzer_eval(bool); // Faking std::std::call_once implementation. @@ -16,8 +21,13 @@ typedef struct once_flag_s { } once_flag; #endif +#ifndef EMULATE_LIBCXX03 template <class Callable, class... Args> void call_once(once_flag &o, Callable&& func, Args&&... args) {}; +#else +template <class Callable, class... Args> // libcxx03 call_once +void call_once(once_flag &o, Callable func, Args&&... args) {}; +#endif } // namespace std @@ -28,7 +38,9 @@ void test_called_warning() { std::call_once(g_initialize, [&] { int *x = nullptr; +#ifndef EMULATE_LIBCXX03 int y = *x; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} +#endif z = 200; }); } @@ -45,8 +57,10 @@ void test_called_on_path_inside_no_warning() { x = &z; }); +#ifndef EMULATE_LIBCXX03 *x = 100; // no-warning clang_analyzer_eval(z == 100); // expected-warning{{TRUE}} +#endif } void test_called_on_path_no_warning() { @@ -59,7 +73,11 @@ void test_called_on_path_no_warning() { x = &y; }); +#ifndef EMULATE_LIBCXX03 *x = 100; // no-warning +#else + *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} +#endif } void test_called_on_path_warning() { @@ -72,7 +90,9 @@ void test_called_on_path_warning() { x = nullptr; }); +#ifndef EMULATE_LIBCXX03 *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} +#endif } void test_called_once_warning() { @@ -89,7 +109,9 @@ void test_called_once_warning() { x = &y; }); +#ifndef EMULATE_LIBCXX03 *x = 100; // expected-warning{{Dereference of null pointer (loaded from variable 'x')}} +#endif } void test_called_once_no_warning() { @@ -106,7 +128,9 @@ void test_called_once_no_warning() { x = nullptr; }); +#ifndef EMULATE_LIBCXX03 *x = 100; // no-warning +#endif } static int global = 0; @@ -117,7 +141,9 @@ void funcPointer() { void test_func_pointers() { static std::once_flag flag; std::call_once(flag, &funcPointer); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(global == 1); // expected-warning{{TRUE}} +#endif } template <class _Fp> @@ -157,7 +183,9 @@ void test_param_passing_lambda() { }, x); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(y == 120); // expected-warning{{TRUE}} +#endif } void test_param_passing_lambda_false() { @@ -169,7 +197,9 @@ void test_param_passing_lambda_false() { }, x); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(x == 120); // expected-warning{{FALSE}} +#endif } void test_param_passing_stored_lambda() { @@ -182,7 +212,9 @@ void test_param_passing_stored_lambda() { }; std::call_once(flag, lambda, x); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(y == 120); // expected-warning{{TRUE}} +#endif } void test_multiparam_passing_lambda() { @@ -194,8 +226,10 @@ void test_multiparam_passing_lambda() { }, 1, 2, 3); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(x == 120); // expected-warning{{FALSE}} clang_analyzer_eval(x == 6); // expected-warning{{TRUE}} +#endif } static int global2 = 0; @@ -206,7 +240,9 @@ void test_param_passing_lambda_global() { global2 = a + b + c; }, 1, 2, 3); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(global2 == 6); // expected-warning{{TRUE}} +#endif } static int global3 = 0; @@ -220,7 +256,9 @@ void test_param_passing_funcptr() { std::call_once(flag, &funcptr, 1, 2, 3); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(global3 == 6); // expected-warning{{TRUE}} +#endif } void test_blocks() { @@ -229,7 +267,9 @@ void test_blocks() { std::call_once(flag, ^{ global3 = 120; }); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(global3 == 120); // expected-warning{{TRUE}} +#endif } int call_once() { @@ -238,7 +278,9 @@ int call_once() { void test_non_std_call_once() { int x = call_once(); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(x == 5); // expected-warning{{TRUE}} +#endif } namespace std { @@ -247,28 +289,36 @@ void call_once(d, e); } void g(); void test_no_segfault_on_different_impl() { +#ifndef EMULATE_LIBCXX03 std::call_once(g, false); // no-warning +#endif } void test_lambda_refcapture() { static std::once_flag flag; int a = 6; std::call_once(flag, [&](int &a) { a = 42; }, a); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(a == 42); // expected-warning{{TRUE}} +#endif } void test_lambda_refcapture2() { static std::once_flag flag; int a = 6; std::call_once(flag, [=](int &a) { a = 42; }, a); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(a == 42); // expected-warning{{TRUE}} +#endif } void test_lambda_fail_refcapture() { static std::once_flag flag; int a = 6; std::call_once(flag, [=](int a) { a = 42; }, a); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(a == 42); // expected-warning{{FALSE}} +#endif } void mutator(int ¶m) { @@ -278,7 +328,9 @@ void test_reftypes_funcptr() { static std::once_flag flag; int a = 6; std::call_once(flag, &mutator, a); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(a == 42); // expected-warning{{TRUE}} +#endif } void fail_mutator(int param) { @@ -288,7 +340,9 @@ void test_mutator_noref() { static std::once_flag flag; int a = 6; std::call_once(flag, &fail_mutator, a); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(a == 42); // expected-warning{{FALSE}} +#endif } // Function is implicitly treated as a function pointer @@ -301,5 +355,7 @@ void test_implicit_funcptr() { static std::once_flag flagn; std::call_once(flagn, callbackn, x); +#ifndef EMULATE_LIBCXX03 clang_analyzer_eval(x == 42); // expected-warning{{TRUE}} +#endif } diff --git a/test/Analysis/string-with-signedness.c b/test/Analysis/string-with-signedness.c new file mode 100644 index 0000000000..1b00971a83 --- /dev/null +++ b/test/Analysis/string-with-signedness.c @@ -0,0 +1,10 @@ +// RUN: %clang_analyze_cc1 -Wno-incompatible-library-redeclaration -analyzer-checker=core,unix.cstring,alpha.unix.cstring -verify %s + +// expected-no-diagnostics + +void *strcpy(unsigned char *, unsigned char *); + +unsigned char a, b; +void testUnsignedStrcpy() { + strcpy(&a, &b); +} diff --git a/test/Analysis/unix-fns.c b/test/Analysis/unix-fns.c index 481f545e28..9126e1bb39 100644 --- a/test/Analysis/unix-fns.c +++ b/test/Analysis/unix-fns.c @@ -34,11 +34,40 @@ typedef union { struct dispatch_disk_s *_ddisk; } dispatch_object_t __attribute__((__transparent_union__)); typedef void (^dispatch_block_t)(void); -typedef long dispatch_once_t; typedef struct dispatch_queue_s *dispatch_queue_t; -void dispatch_once(dispatch_once_t *predicate, dispatch_block_t block); void dispatch_sync(dispatch_queue_t queue, dispatch_block_t block); +typedef long dispatch_once_t; + +extern +__attribute__((__nonnull__)) +__attribute__((__nothrow__)) +void dispatch_once(dispatch_once_t *predicate, + __attribute__((__noescape__)) dispatch_block_t block); + +// Inlined fast-path dispatch_once defers to the real dispatch_once +// on the slow path. +static +__inline__ +__attribute__((__always_inline__)) +__attribute__((__nonnull__)) +__attribute__((__nothrow__)) +void _dispatch_once(dispatch_once_t *predicate, + __attribute__((__noescape__)) dispatch_block_t block) +{ + if (__builtin_expect((*predicate), (~0l)) != ~0l) { + dispatch_once(predicate, block); + } else { + __asm__ __volatile__("" ::: "memory"); + } + __builtin_assume(*predicate == ~0l); +} + +// Macro so that user calls to dispatch_once() call the inlined fast-path +// variant. +#undef dispatch_once +#define dispatch_once _dispatch_once + #ifndef O_CREAT #define O_CREAT 0x0200 #define O_RDONLY 0x0000 @@ -181,16 +210,6 @@ void test_valloc_nowarn(size_t sz) { } } -// Test dispatch_once being a macro that wraps a call to _dispatch_once, which in turn -// calls the real dispatch_once. - -static inline void _dispatch_once(dispatch_once_t *predicate, dispatch_block_t block) -{ - dispatch_once(predicate, block); -} - -#define dispatch_once _dispatch_once - void test_dispatch_once_in_macro() { dispatch_once_t pred = 0; dispatch_once(&pred, ^(){}); // expected-warning {{Call to 'dispatch_once' uses the local variable 'pred' for the predicate value}} @@ -206,7 +225,7 @@ void test_dispatch_sync(dispatch_queue_t queue, int *q) { }); } -// Test inlining if dispatch_once. +// Test inlining of dispatch_once. void test_inline_dispatch_once() { static dispatch_once_t pred; int *p = 0; @@ -215,6 +234,17 @@ void test_inline_dispatch_once() { }); } +// Make sure code after call to dispatch once is reached. +void test_inline_dispatch_once_reachable() { + static dispatch_once_t pred; + __block int *p; + dispatch_once(&pred, ^(void) { + p = 0; + }); + + *p = 7; // expected-warning {{Dereference of null pointer (loaded from variable 'p')}} +} + // CHECK: <key>diagnostics</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> @@ -228,12 +258,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>51</integer> +// CHECK-NEXT: <key>line</key><integer>80</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>51</integer> +// CHECK-NEXT: <key>line</key><integer>80</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -241,12 +271,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -262,12 +292,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -275,12 +305,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -292,7 +322,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -300,12 +330,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -325,12 +355,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>53</integer> +// CHECK-NEXT: <key>line</key><integer>82</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -338,12 +368,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -359,12 +389,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -372,12 +402,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>11</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -389,7 +419,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -397,12 +427,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>19</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>25</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -426,7 +456,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>6</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>56</integer> +// CHECK-NEXT: <key>line</key><integer>85</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -442,12 +472,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>62</integer> +// CHECK-NEXT: <key>line</key><integer>91</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>62</integer> +// CHECK-NEXT: <key>line</key><integer>91</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -455,12 +485,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -476,12 +506,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -489,12 +519,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -506,7 +536,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -514,12 +544,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -539,12 +569,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>64</integer> +// CHECK-NEXT: <key>line</key><integer>93</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -552,12 +582,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -573,12 +603,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -586,12 +616,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>13</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -603,7 +633,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -611,12 +641,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>44</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>50</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -640,7 +670,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>6</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>67</integer> +// CHECK-NEXT: <key>line</key><integer>96</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -656,12 +686,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>73</integer> +// CHECK-NEXT: <key>line</key><integer>102</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>73</integer> +// CHECK-NEXT: <key>line</key><integer>102</integer> // CHECK-NEXT: <key>col</key><integer>17</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -669,12 +699,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -690,12 +720,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -703,12 +733,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -724,12 +754,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>9</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -737,12 +767,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>52</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>64</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -754,7 +784,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>52</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -762,12 +792,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>66</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>72</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -791,7 +821,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>74</integer> +// CHECK-NEXT: <key>line</key><integer>103</integer> // CHECK-NEXT: <key>col</key><integer>52</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -807,12 +837,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>84</integer> +// CHECK-NEXT: <key>line</key><integer>113</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>84</integer> +// CHECK-NEXT: <key>line</key><integer>113</integer> // CHECK-NEXT: <key>col</key><integer>16</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -820,12 +850,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>85</integer> +// CHECK-NEXT: <key>line</key><integer>114</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>85</integer> +// CHECK-NEXT: <key>line</key><integer>114</integer> // CHECK-NEXT: <key>col</key><integer>14</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -837,7 +867,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>85</integer> +// CHECK-NEXT: <key>line</key><integer>114</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -845,12 +875,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>85</integer> +// CHECK-NEXT: <key>line</key><integer>114</integer> // CHECK-NEXT: <key>col</key><integer>16</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>85</integer> +// CHECK-NEXT: <key>line</key><integer>114</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -874,7 +904,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>85</integer> +// CHECK-NEXT: <key>line</key><integer>114</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -890,12 +920,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -903,12 +933,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -920,7 +950,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -928,12 +958,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -957,7 +987,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>94</integer> +// CHECK-NEXT: <key>line</key><integer>123</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -973,12 +1003,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -986,12 +1016,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1003,7 +1033,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1011,12 +1041,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1040,7 +1070,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>106</integer> +// CHECK-NEXT: <key>line</key><integer>135</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1056,12 +1086,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1069,12 +1099,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1086,7 +1116,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1094,12 +1124,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>26</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>26</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1123,7 +1153,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>112</integer> +// CHECK-NEXT: <key>line</key><integer>141</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1139,12 +1169,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1152,12 +1182,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1169,7 +1199,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1177,12 +1207,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>28</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>28</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1206,7 +1236,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>124</integer> +// CHECK-NEXT: <key>line</key><integer>153</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1222,12 +1252,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1235,12 +1265,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1252,7 +1282,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1260,12 +1290,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>29</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>29</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1289,7 +1319,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>130</integer> +// CHECK-NEXT: <key>line</key><integer>159</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1305,12 +1335,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1318,12 +1348,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1335,7 +1365,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1343,12 +1373,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1372,7 +1402,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>148</integer> +// CHECK-NEXT: <key>line</key><integer>177</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1388,12 +1418,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1401,12 +1431,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>16</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>31</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1418,7 +1448,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>16</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1426,12 +1456,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>33</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>33</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1455,7 +1485,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>160</integer> +// CHECK-NEXT: <key>line</key><integer>189</integer> // CHECK-NEXT: <key>col</key><integer>16</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1471,12 +1501,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1484,12 +1514,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>20</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1501,7 +1531,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1509,12 +1539,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>22</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1538,7 +1568,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>1</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>172</integer> +// CHECK-NEXT: <key>line</key><integer>201</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1554,12 +1584,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>195</integer> +// CHECK-NEXT: <key>line</key><integer>214</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>195</integer> +// CHECK-NEXT: <key>line</key><integer>214</integer> // CHECK-NEXT: <key>col</key><integer>17</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1567,12 +1597,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>line</key><integer>215</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>line</key><integer>215</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1584,7 +1614,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>line</key><integer>215</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1592,12 +1622,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>line</key><integer>215</integer> // CHECK-NEXT: <key>col</key><integer>17</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>line</key><integer>215</integer> // CHECK-NEXT: <key>col</key><integer>21</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1621,7 +1651,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_function_offset</key><string>2</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>196</integer> +// CHECK-NEXT: <key>line</key><integer>215</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1633,7 +1663,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>201</integer> +// CHECK-NEXT: <key>line</key><integer>220</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1641,12 +1671,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>201</integer> +// CHECK-NEXT: <key>line</key><integer>220</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>201</integer> +// CHECK-NEXT: <key>line</key><integer>220</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1666,12 +1696,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>201</integer> +// CHECK-NEXT: <key>line</key><integer>220</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>201</integer> +// CHECK-NEXT: <key>line</key><integer>220</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1679,12 +1709,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1700,12 +1730,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1713,12 +1743,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1730,7 +1760,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1738,12 +1768,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>line</key><integer>225</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1759,7 +1789,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1767,12 +1797,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>line</key><integer>225</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1788,7 +1818,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1796,12 +1826,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>206</integer> +// CHECK-NEXT: <key>line</key><integer>225</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1817,7 +1847,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1835,12 +1865,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>202</integer> +// CHECK-NEXT: <key>line</key><integer>221</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1848,12 +1878,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1869,12 +1899,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1882,12 +1912,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1899,7 +1929,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1907,12 +1937,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1932,12 +1962,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>203</integer> +// CHECK-NEXT: <key>line</key><integer>222</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1945,12 +1975,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1966,12 +1996,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1979,12 +2009,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -1996,7 +2026,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2004,12 +2034,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2030,7 +2060,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>5d3f4c433004c7a6d4a06aa30cc3ea85</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>204</integer> +// CHECK-NEXT: <key>line</key><integer>223</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2046,12 +2076,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>line</key><integer>230</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>211</integer> +// CHECK-NEXT: <key>line</key><integer>230</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2059,12 +2089,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>line</key><integer>231</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>line</key><integer>231</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2076,7 +2106,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>line</key><integer>231</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2084,12 +2114,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>line</key><integer>231</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>line</key><integer>231</integer> // CHECK-NEXT: <key>col</key><integer>8</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2109,12 +2139,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>line</key><integer>231</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>212</integer> +// CHECK-NEXT: <key>line</key><integer>231</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2122,12 +2152,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2139,7 +2169,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2147,12 +2177,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>215</integer> +// CHECK-NEXT: <key>line</key><integer>234</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2168,7 +2198,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2176,12 +2206,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>215</integer> +// CHECK-NEXT: <key>line</key><integer>234</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2197,7 +2227,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>line</key><integer>50</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2215,12 +2245,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>line</key><integer>50</integer> // CHECK-NEXT: <key>col</key><integer>1</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>187</integer> +// CHECK-NEXT: <key>line</key><integer>50</integer> // CHECK-NEXT: <key>col</key><integer>6</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2228,12 +2258,46 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>58</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>15</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2245,7 +2309,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2253,12 +2317,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>33</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2274,7 +2338,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2282,12 +2346,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>3</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>189</integer> +// CHECK-NEXT: <key>line</key><integer>59</integer> // CHECK-NEXT: <key>col</key><integer>33</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2303,7 +2367,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2321,12 +2385,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>213</integer> +// CHECK-NEXT: <key>line</key><integer>232</integer> // CHECK-NEXT: <key>col</key><integer>24</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2334,12 +2398,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2355,12 +2419,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>start</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>4</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2368,12 +2432,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>end</key> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2385,7 +2449,7 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>kind</key><string>event</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2393,12 +2457,12 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <array> // CHECK-NEXT: <array> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>5</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> @@ -2419,9 +2483,459 @@ void test_inline_dispatch_once() { // CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>265c4fd608dafee211bfa93d21c28866</string> // CHECK-NEXT: <key>location</key> // CHECK-NEXT: <dict> -// CHECK-NEXT: <key>line</key><integer>214</integer> +// CHECK-NEXT: <key>line</key><integer>233</integer> // CHECK-NEXT: <key>col</key><integer>7</integer> // CHECK-NEXT: <key>file</key><integer>0</integer> // CHECK-NEXT: </dict> // CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>path</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling '_dispatch_once'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling '_dispatch_once'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>50</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'test_inline_dispatch_once_reachable'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'test_inline_dispatch_once_reachable'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>50</integer> +// CHECK-NEXT: <key>col</key><integer>1</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>50</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>58</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>15</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>33</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling 'dispatch_once'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling 'dispatch_once'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>33</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>2</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Calling anonymous block</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Calling anonymous block</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>24</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>depth</key><integer>3</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Entered call from 'dispatch_once'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Entered call from 'dispatch_once'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>24</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>24</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>7</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>242</integer> +// CHECK-NEXT: <key>col</key><integer>11</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>3</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Null pointer value stored to 'p'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Null pointer value stored to 'p'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>33</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>2</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returning to caller</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning to caller</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>33</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>1</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returning from 'dispatch_once'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning from 'dispatch_once'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>59</integer> +// CHECK-NEXT: <key>col</key><integer>15</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>63</integer> +// CHECK-NEXT: <key>col</key><integer>2</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>63</integer> +// CHECK-NEXT: <key>col</key><integer>17</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>243</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Returning from '_dispatch_once'</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Returning from '_dispatch_once'</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>control</string> +// CHECK-NEXT: <key>edges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>start</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>3</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>241</integer> +// CHECK-NEXT: <key>col</key><integer>15</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>end</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>245</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>245</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>kind</key><string>event</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>245</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <key>ranges</key> +// CHECK-NEXT: <array> +// CHECK-NEXT: <array> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>245</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>245</integer> +// CHECK-NEXT: <key>col</key><integer>4</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>depth</key><integer>0</integer> +// CHECK-NEXT: <key>extended_message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: <key>message</key> +// CHECK-NEXT: <string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </array> +// CHECK-NEXT: <key>description</key><string>Dereference of null pointer (loaded from variable 'p')</string> +// CHECK-NEXT: <key>category</key><string>Logic error</string> +// CHECK-NEXT: <key>type</key><string>Dereference of null pointer</string> +// CHECK-NEXT: <key>check_name</key><string>core.NullDereference</string> +// CHECK-NEXT: <!-- This hash is experimental and going to change! --> +// CHECK-NEXT: <key>issue_hash_content_of_line_in_context</key><string>1e83bd4361a2351df0b4e77eb3a9109b</string> +// CHECK-NEXT: <key>issue_context_kind</key><string>function</string> +// CHECK-NEXT: <key>issue_context</key><string>test_inline_dispatch_once_reachable</string> +// CHECK-NEXT: <key>issue_hash_function_offset</key><string>7</string> +// CHECK-NEXT: <key>location</key> +// CHECK-NEXT: <dict> +// CHECK-NEXT: <key>line</key><integer>245</integer> +// CHECK-NEXT: <key>col</key><integer>6</integer> +// CHECK-NEXT: <key>file</key><integer>0</integer> +// CHECK-NEXT: </dict> +// CHECK-NEXT: </dict> // CHECK-NEXT: </array> diff --git a/test/Analysis/vector.c b/test/Analysis/vector.c new file mode 100644 index 0000000000..32b568f6b0 --- /dev/null +++ b/test/Analysis/vector.c @@ -0,0 +1,28 @@ +// RUN: %clang_analyze_cc1 -analyzer-checker=core,debug.ExprInspection -verify %s + +typedef int __attribute__((ext_vector_type(2))) V; + +void clang_analyzer_numTimesReached(); +void clang_analyzer_eval(int); + +int flag; + +V pass_through_and_set_flag(V v) { + flag = 1; + return v; +} + +V dont_crash_and_dont_split_state(V x, V y) { + flag = 0; + V z = x && pass_through_and_set_flag(y); + clang_analyzer_eval(flag); // expected-warning{{TRUE}} + // FIXME: For now we treat vector operator && as short-circuit, + // but in fact it is not. It should always evaluate + // pass_through_and_set_flag(). It should not split state. + // Now we also get FALSE on the other path. + // expected-warning@-5{{FALSE}} + + // FIXME: Should be 1 since we should not split state. + clang_analyzer_numTimesReached(); // expected-warning{{2}} + return z; +} diff --git a/test/CodeCompletion/call.cpp b/test/CodeCompletion/call.cpp index 40a72ba836..3e062109a9 100644 --- a/test/CodeCompletion/call.cpp +++ b/test/CodeCompletion/call.cpp @@ -19,10 +19,10 @@ void test() { f(Y(), 0, 0); // RUN: %clang_cc1 -fsyntax-only -code-completion-patterns -code-completion-at=%s:19:9 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s // CHECK-CC1: COMPLETION: Pattern : dynamic_cast<<#type#>>(<#expression#>) - // CHECK-CC1: f(N::Y y, <#int ZZ#>) + // CHECK-CC1: f(Y y, <#int ZZ#>) // CHECK-CC1-NEXT: f(int i, <#int j#>, int k) // CHECK-CC1-NEXT: f(float x, <#float y#>) // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:19:13 %s -o - | FileCheck -check-prefix=CHECK-CC2 %s - // CHECK-CC2-NOT: f(N::Y y, int ZZ) + // CHECK-CC2-NOT: f(Y y, int ZZ) // CHECK-CC2: f(int i, int j, <#int k#>) } diff --git a/test/CodeCompletion/qualifiers-as-written.cpp b/test/CodeCompletion/qualifiers-as-written.cpp new file mode 100644 index 0000000000..90530ec65c --- /dev/null +++ b/test/CodeCompletion/qualifiers-as-written.cpp @@ -0,0 +1,31 @@ +struct foo { + typedef int type; + + type method(type, foo::type, ::foo::type, ::foo::foo::type); +}; + +namespace ns { + struct bar { + }; + + struct baz { + }; + + int func(foo::type a, bar b, baz c); +} + +typedef ns::bar bar; + +int func(foo a, bar b, ns::bar c, ns::baz d); +using ns::func; + +void test() { + foo().method(0, 0, 0, 0); + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:23:9 %s -o - | FileCheck %s --check-prefix=CHECK-1 + // CHECK-1: COMPLETION: method : [#type#]method(<#type#>, <#foo::type#>, <#::foo::type#>, <#::foo::foo::type#>) + f + // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:26:3 %s -o - | FileCheck %s --check-prefix=CHECK-2 + // FIXME(ibiryukov): We should get rid of CHECK-DAGs here when completion output is made deterministic (see PR35244). + // CHECK-2-DAG: COMPLETION: func : [#int#]func(<#foo a#>, <#bar b#>, <#ns::bar c#>, <#ns::baz d#> + // CHECK-2-DAG: COMPLETION: func : [#int#]func(<#foo::type a#>, <#bar b#>, <#baz c#> +} diff --git a/test/CodeCompletion/uninstantiated_params.cpp b/test/CodeCompletion/uninstantiated_params.cpp index 57a520dd57..643f2f7255 100644 --- a/test/CodeCompletion/uninstantiated_params.cpp +++ b/test/CodeCompletion/uninstantiated_params.cpp @@ -9,5 +9,5 @@ void test() { unique_ptr<int> x; x. // RUN: %clang_cc1 -fsyntax-only -code-completion-at=%s:10:5 %s -o - | FileCheck -check-prefix=CHECK-CC1 %s - // CHECK-CC1: [#void#]reset({#<#unique_ptr<int>::pointer ptr = pointer()#>#}) + // CHECK-CC1: [#void#]reset({#<#pointer ptr = pointer()#>#}) } diff --git a/test/CodeGen/avx512cdintrin.c b/test/CodeGen/avx512cdintrin.c index a28601895b..e01d277be9 100644 --- a/test/CodeGen/avx512cdintrin.c +++ b/test/CodeGen/avx512cdintrin.c @@ -68,14 +68,40 @@ __m512i test_mm512_maskz_lzcnt_epi64(__mmask8 __U, __m512i __A) { return _mm512_maskz_lzcnt_epi64(__U,__A); } -__m512i test_mm512_broadcastmb_epi64(__mmask8 __A) { +__m512i test_mm512_broadcastmb_epi64(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm512_broadcastmb_epi64 - // CHECK: @llvm.x86.avx512.broadcastmb.512 - return _mm512_broadcastmb_epi64(__A); + // CHECK: icmp eq <8 x i64> %{{.*}}, %{{.*}} + // CHECK: zext i8 %{{.*}} to i64 + // CHECK: insertelement <8 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 1 + // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 2 + // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 3 + // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 4 + // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 5 + // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 6 + // CHECK: insertelement <8 x i64> %{{.*}}, i64 %{{.*}}, i32 7 + return _mm512_broadcastmb_epi64(_mm512_cmpeq_epu64_mask ( a, b)); } -__m512i test_mm512_broadcastmw_epi32(__mmask16 __A) { +__m512i test_mm512_broadcastmw_epi32(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm512_broadcastmw_epi32 - // CHECK: @llvm.x86.avx512.broadcastmw.512 - return _mm512_broadcastmw_epi32(__A); + // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}} + // CHECK: zext i16 %{{.*}} to i32 + // CHECK: insertelement <16 x i32> undef, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + // CHECK: insertelement <16 x i32> %{{.*}}, i32 %{{.*}} + return _mm512_broadcastmw_epi32(_mm512_cmpeq_epi32_mask ( a, b)); } diff --git a/test/CodeGen/avx512vlcd-builtins.c b/test/CodeGen/avx512vlcd-builtins.c index 643f24f1d2..376a342f76 100644 --- a/test/CodeGen/avx512vlcd-builtins.c +++ b/test/CodeGen/avx512vlcd-builtins.c @@ -3,28 +3,56 @@ #include <immintrin.h> -__m128i test_mm_broadcastmb_epi64(__mmask8 __A) { +__m128i test_mm_broadcastmb_epi64(__m128i a,__m128i b) { // CHECK-LABEL: @test_mm_broadcastmb_epi64 - // CHECK: @llvm.x86.avx512.broadcastmb.128 - return _mm_broadcastmb_epi64(__A); + // CHECK: icmp eq <4 x i32> %{{.*}}, %{{.*}} + // CHECK: shufflevector <4 x i1> %{{.*}}, <4 x i1> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> + // CHECK: bitcast <8 x i1> %{{.*}} to i8 + // CHECK: zext i8 %{{.*}} to i64 + // CHECK: insertelement <2 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <2 x i64> %{{.*}}, i64 %{{.*}}, i32 1 + return _mm_broadcastmb_epi64(_mm_cmpeq_epi32_mask (a, b)); } -__m256i test_mm256_broadcastmb_epi64(__mmask8 __A) { +__m256i test_mm256_broadcastmb_epi64(__m256i a, __m256i b) { // CHECK-LABEL: @test_mm256_broadcastmb_epi64 - // CHECK: @llvm.x86.avx512.broadcastmb.256 - return _mm256_broadcastmb_epi64(__A); -} - -__m128i test_mm_broadcastmw_epi32(__mmask16 __A) { + // CHECK: icmp eq <4 x i64> %{{.*}}, %{{.*}} + // CHECK: shufflevector <4 x i1> %{{.*}}, <4 x i1> zeroinitializer, <8 x i32> <i32 0, i32 1, i32 2, i32 3, i32 4, i32 5, i32 6, i32 7> + // CHECK: bitcast <8 x i1> %{{.*}} to i8 + // CHECK: zext i8 %{{.*}} to i64 + // CHECK: insertelement <4 x i64> undef, i64 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 1 + // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 2 + // CHECK: insertelement <4 x i64> %{{.*}}, i64 %{{.*}}, i32 3 + return _mm256_broadcastmb_epi64(_mm256_cmpeq_epi64_mask ( a, b)); +} + +__m128i test_mm_broadcastmw_epi32(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm_broadcastmw_epi32 - // CHECK: @llvm.x86.avx512.broadcastmw.128 - return _mm_broadcastmw_epi32(__A); + // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}} + // CHECK: bitcast <16 x i1> %{{.*}} to i16 + // CHECK: zext i16 %{{.*}} to i32 + // CHECK: insertelement <4 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 1 + // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 2 + // CHECK: insertelement <4 x i32> %{{.*}}, i32 %{{.*}}, i32 3 + return _mm_broadcastmw_epi32(_mm512_cmpeq_epi32_mask ( a, b)); } -__m256i test_mm256_broadcastmw_epi32(__mmask16 __A) { +__m256i test_mm256_broadcastmw_epi32(__m512i a, __m512i b) { // CHECK-LABEL: @test_mm256_broadcastmw_epi32 - // CHECK: @llvm.x86.avx512.broadcastmw.256 - return _mm256_broadcastmw_epi32(__A); + // CHECK: icmp eq <16 x i32> %{{.*}}, %{{.*}} + // CHECK: bitcast <16 x i1> %{{.*}} to i16 + // CHECK: zext i16 %{{.*}} to i32 + // CHECK: insertelement <8 x i32> undef, i32 %{{.*}}, i32 0 + // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 1 + // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 2 + // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 3 + // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 4 + // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 5 + // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 6 + // CHECK: insertelement <8 x i32> %{{.*}}, i32 %{{.*}}, i32 7 + return _mm256_broadcastmw_epi32(_mm512_cmpeq_epi32_mask ( a, b)); } __m128i test_mm_conflict_epi64(__m128i __A) { diff --git a/test/CodeGen/builtin-sqrt.c b/test/CodeGen/builtin-sqrt.c index f93c5926d5..528ad09517 100644 --- a/test/CodeGen/builtin-sqrt.c +++ b/test/CodeGen/builtin-sqrt.c @@ -1,9 +1,7 @@ // RUN: %clang_cc1 -fmath-errno -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=HAS_ERRNO // RUN: %clang_cc1 -triple x86_64-apple-darwin %s -emit-llvm -o - | FileCheck %s --check-prefix=NO_ERRNO -// FIXME: If a builtin is supposed to have identical semantics to its libm twin, then it -// should not be marked "constant" in Builtins.def because that means it can't set errno. -// Note that both runs have 'readnone' on the libcall here. +// FIXME: If the builtin does not set errno, it should be converted to an LLVM intrinsic. float foo(float X) { // HAS_ERRNO: call float @sqrtf(float @@ -12,7 +10,7 @@ float foo(float X) { } // HAS_ERRNO: declare float @sqrtf(float) [[ATTR:#[0-9]+]] -// HAS_ERRNO: attributes [[ATTR]] = { nounwind readnone {{.*}}} +// HAS_ERRNO-NOT: attributes [[ATTR]] = {{{.*}} readnone // NO_ERRNO: declare float @sqrtf(float) [[ATTR:#[0-9]+]] // NO_ERRNO: attributes [[ATTR]] = { nounwind readnone {{.*}}} diff --git a/test/CodeGen/builtins-nvptx-ptx50.cu b/test/CodeGen/builtins-nvptx-ptx50.cu new file mode 100644 index 0000000000..e85be442eb --- /dev/null +++ b/test/CodeGen/builtins-nvptx-ptx50.cu @@ -0,0 +1,23 @@ +// RUN: %clang_cc1 -triple nvptx64-unknown-unknown -target-cpu sm_60 \ +// RUN: -fcuda-is-device -S -emit-llvm -o - -x cuda %s \ +// RUN: | FileCheck -check-prefix=CHECK %s +// +// RUN: %clang_cc1 -triple nvptx-unknown-unknown -target-cpu sm_50 \ +// RUN: -fcuda-is-device -S -o /dev/null -x cuda -verify %s + +#define __device__ __attribute__((device)) +#define __global__ __attribute__((global)) +#define __shared__ __attribute__((shared)) +#define __constant__ __attribute__((constant)) + +// We have to keep all builtins that depend on particular target feature in the +// same function, because the codegen will stop after the very first function +// that encounters an error, so -verify will not be able to find errors in +// subsequent functions. + +// CHECK-LABEL: test_fn +__device__ void test_fn(double d, double* double_ptr) { + // CHECK: call double @llvm.nvvm.atomic.load.add.f64.p0f64 + // expected-error@+1 {{'__nvvm_atom_add_gen_d' needs target feature satom}} + __nvvm_atom_add_gen_d(double_ptr, d); +} diff --git a/test/CodeGen/complex-builtins.c b/test/CodeGen/complex-builtins.c new file mode 100644 index 0000000000..687a294250 --- /dev/null +++ b/test/CodeGen/complex-builtins.c @@ -0,0 +1,206 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO + +// Test attributes and codegen of complex builtins. + +void foo(float f) { + __builtin_cabs(f); __builtin_cabsf(f); __builtin_cabsl(f); + +// NO__ERRNO: declare double @cabs(double, double) [[READNONE:#[0-9]+]] +// NO__ERRNO: declare float @cabsf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE:#[0-9]+]] +// HAS_ERRNO: declare double @cabs(double, double) [[READNONE:#[0-9]+]] +// HAS_ERRNO: declare float @cabsf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE:#[0-9]+]] + + __builtin_cacos(f); __builtin_cacosf(f); __builtin_cacosl(f); + +// NO__ERRNO: declare { double, double } @cacos(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cacosf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cacos(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cacosf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_cacosh(f); __builtin_cacoshf(f); __builtin_cacoshl(f); + +// NO__ERRNO: declare { double, double } @cacosh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cacosh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_carg(f); __builtin_cargf(f); __builtin_cargl(f); + +// NO__ERRNO: declare double @carg(double, double) [[READNONE]] +// NO__ERRNO: declare float @cargf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare double @carg(double, double) [[READNONE]] +// HAS_ERRNO: declare float @cargf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_casin(f); __builtin_casinf(f); __builtin_casinl(f); + +// NO__ERRNO: declare { double, double } @casin(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @casinf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @casin(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @casinf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_casinh(f); __builtin_casinhf(f); __builtin_casinhl(f); + +// NO__ERRNO: declare { double, double } @casinh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @casinhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @casinh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @casinhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_catan(f); __builtin_catanf(f); __builtin_catanl(f); + +// NO__ERRNO: declare { double, double } @catan(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @catanf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @catan(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @catanf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_catanh(f); __builtin_catanhf(f); __builtin_catanhl(f); + +// NO__ERRNO: declare { double, double } @catanh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @catanhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @catanh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @catanhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_ccos(f); __builtin_ccosf(f); __builtin_ccosl(f); + +// NO__ERRNO: declare { double, double } @ccos(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ccosf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ccos(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ccosf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_ccosh(f); __builtin_ccoshf(f); __builtin_ccoshl(f); + +// NO__ERRNO: declare { double, double } @ccosh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ccosh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_cexp(f); __builtin_cexpf(f); __builtin_cexpl(f); + +// NO__ERRNO: declare { double, double } @cexp(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cexpf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cexp(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cexpf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_cimag(f); __builtin_cimagf(f); __builtin_cimagl(f); + +// NO__ERRNO-NOT: .cimag +// NO__ERRNO-NOT: @cimag +// HAS_ERRNO-NOT: .cimag +// HAS_ERRNO-NOT: @cimag + + __builtin_conj(f); __builtin_conjf(f); __builtin_conjl(f); + +// NO__ERRNO-NOT: .conj +// NO__ERRNO-NOT: @conj +// HAS_ERRNO-NOT: .conj +// HAS_ERRNO-NOT: @conj + + __builtin_clog(f); __builtin_clogf(f); __builtin_clogl(f); + +// NO__ERRNO: declare { double, double } @clog(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @clogf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @clog(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @clogf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_cproj(f); __builtin_cprojf(f); __builtin_cprojl(f); + +// NO__ERRNO: declare { double, double } @cproj(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cproj(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_cpow(f,f); __builtin_cpowf(f,f); __builtin_cpowl(f,f); + +// NO__ERRNO: declare { double, double } @cpow(double, double, double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cpow(double, double, double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_creal(f); __builtin_crealf(f); __builtin_creall(f); + +// NO__ERRNO-NOT: .creal +// NO__ERRNO-NOT: @creal +// HAS_ERRNO-NOT: .creal +// HAS_ERRNO-NOT: @creal + + __builtin_csin(f); __builtin_csinf(f); __builtin_csinl(f); + +// NO__ERRNO: declare { double, double } @csin(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @csinf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @csin(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @csinf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_csinh(f); __builtin_csinhf(f); __builtin_csinhl(f); + +// NO__ERRNO: declare { double, double } @csinh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @csinhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @csinh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @csinhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_csqrt(f); __builtin_csqrtf(f); __builtin_csqrtl(f); + +// NO__ERRNO: declare { double, double } @csqrt(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @csqrt(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_ctan(f); __builtin_ctanf(f); __builtin_ctanl(f); + +// NO__ERRNO: declare { double, double } @ctan(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ctanf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ctan(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ctanf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + __builtin_ctanh(f); __builtin_ctanhf(f); __builtin_ctanhl(f); + +// NO__ERRNO: declare { double, double } @ctanh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ctanh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +}; + + +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } + +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } + diff --git a/test/CodeGen/complex-libcalls.c b/test/CodeGen/complex-libcalls.c new file mode 100644 index 0000000000..72aa74d170 --- /dev/null +++ b/test/CodeGen/complex-libcalls.c @@ -0,0 +1,208 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO + +// Test attributes and builtin codegen of complex library calls. + +void foo(float f) { + cabs(f); cabsf(f); cabsl(f); + +// NO__ERRNO: declare double @cabs(double, double) [[READNONE:#[0-9]+]] +// NO__ERRNO: declare float @cabsf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE:#[0-9+]]] +// HAS_ERRNO: declare double @cabs(double, double) [[READNONE:#[0-9]+]] +// HAS_ERRNO: declare float @cabsf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @cabsl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE:#[0-9]+]] + + cacos(f); cacosf(f); cacosl(f); + +// NO__ERRNO: declare { double, double } @cacos(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cacosf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cacos(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cacosf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + cacosh(f); cacoshf(f); cacoshl(f); + +// NO__ERRNO: declare { double, double } @cacosh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cacosh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cacoshf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cacoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + carg(f); cargf(f); cargl(f); + +// NO__ERRNO: declare double @carg(double, double) [[READNONE]] +// NO__ERRNO: declare float @cargf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare double @carg(double, double) [[READNONE]] +// HAS_ERRNO: declare float @cargf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @cargl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + casin(f); casinf(f); casinl(f); + +// NO__ERRNO: declare { double, double } @casin(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @casinf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @casin(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @casinf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + casinh(f); casinhf(f); casinhl(f); + +// NO__ERRNO: declare { double, double } @casinh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @casinhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @casinh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @casinhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @casinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + catan(f); catanf(f); catanl(f); + +// NO__ERRNO: declare { double, double } @catan(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @catanf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @catan(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @catanf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + catanh(f); catanhf(f); catanhl(f); + +// NO__ERRNO: declare { double, double } @catanh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @catanhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @catanh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @catanhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @catanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + ccos(f); ccosf(f); ccosl(f); + +// NO__ERRNO: declare { double, double } @ccos(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ccosf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ccos(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ccosf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccosl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + ccosh(f); ccoshf(f); ccoshl(f); + +// NO__ERRNO: declare { double, double } @ccosh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ccosh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ccoshf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ccoshl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + cexp(f); cexpf(f); cexpl(f); + +// NO__ERRNO: declare { double, double } @cexp(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cexpf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cexp(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cexpf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cexpl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + cimag(f); cimagf(f); cimagl(f); + +// NO__ERRNO-NOT: .cimag +// NO__ERRNO-NOT: @cimag +// HAS_ERRNO-NOT: .cimag +// HAS_ERRNO-NOT: @cimag + + conj(f); conjf(f); conjl(f); + +// NO__ERRNO: declare { double, double } @conj(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @conjf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @conjl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @conj(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @conjf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @conjl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + clog(f); clogf(f); clogl(f); + +// NO__ERRNO: declare { double, double } @clog(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @clogf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @clog(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @clogf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @clogl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + cproj(f); cprojf(f); cprojl(f); + +// NO__ERRNO: declare { double, double } @cproj(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cproj(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cprojf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cprojl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + cpow(f,f); cpowf(f,f); cpowl(f,f); + +// NO__ERRNO: declare { double, double } @cpow(double, double, double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @cpow(double, double, double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @cpowf(<2 x float>, <2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @cpowl({ x86_fp80, x86_fp80 }* byval align 16, { x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + creal(f); crealf(f); creall(f); + +// NO__ERRNO-NOT: .creal +// NO__ERRNO-NOT: @creal +// HAS_ERRNO-NOT: .creal +// HAS_ERRNO-NOT: @creal + + csin(f); csinf(f); csinl(f); + +// NO__ERRNO: declare { double, double } @csin(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @csinf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @csin(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @csinf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + csinh(f); csinhf(f); csinhl(f); + +// NO__ERRNO: declare { double, double } @csinh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @csinhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @csinh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @csinhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csinhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + csqrt(f); csqrtf(f); csqrtl(f); + +// NO__ERRNO: declare { double, double } @csqrt(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @csqrt(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @csqrtf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @csqrtl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + ctan(f); ctanf(f); ctanl(f); + +// NO__ERRNO: declare { double, double } @ctan(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ctanf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ctan(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ctanf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] + + ctanh(f); ctanhf(f); ctanhl(f); + +// NO__ERRNO: declare { double, double } @ctanh(double, double) [[READNONE]] +// NO__ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[READNONE]] +// NO__ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +// HAS_ERRNO: declare { double, double } @ctanh(double, double) [[READNONE]] +// HAS_ERRNO: declare <2 x float> @ctanhf(<2 x float>) [[READNONE]] +// HAS_ERRNO: declare { x86_fp80, x86_fp80 } @ctanhl({ x86_fp80, x86_fp80 }* byval align 16) [[NOT_READNONE]] +}; + + +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } + +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } + diff --git a/test/CodeGen/math-builtins.c b/test/CodeGen/math-builtins.c new file mode 100644 index 0000000000..cb9b597458 --- /dev/null +++ b/test/CodeGen/math-builtins.c @@ -0,0 +1,560 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO + +// Test attributes and codegen of math builtins. + +void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { + __builtin_atan2(f,f); __builtin_atan2f(f,f) ; __builtin_atan2l(f, f); + +// NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]] +// NO__ERRNO: declare float @atan2f(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE:#[0-9]+]] +// HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]] + + __builtin_copysign(f,f); __builtin_copysignf(f,f);__builtin_copysignl(f,f); + +// NO__ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] +// NO__ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.copysign.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] +// HAS_ERRNO: declare float @llvm.copysign.f32(float, float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.copysign.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_fabs(f); __builtin_fabsf(f); __builtin_fabsl(f); + +// NO__ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.fabs.f64(double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.fabs.f32(float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.fabs.f80(x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_fmod(f,f); __builtin_fmodf(f,f); __builtin_fmodl(f,f); + +// NO__ERRNO-NOT: .fmod +// NO__ERRNO-NOT: @fmod +// HAS_ERRNO-NOT: .fmod +// HAS_ERRNO-NOT: @fmod + + __builtin_frexp(f,i); __builtin_frexpf(f,i); __builtin_frexpl(f,i); + +// NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]] +// NO__ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]] + + __builtin_huge_val(); __builtin_huge_valf(); __builtin_huge_vall(); + +// NO__ERRNO-NOT: .huge +// NO__ERRNO-NOT: @huge +// HAS_ERRNO-NOT: .huge +// HAS_ERRNO-NOT: @huge + + __builtin_inf(); __builtin_inff(); __builtin_infl(); + +// NO__ERRNO-NOT: .inf +// NO__ERRNO-NOT: @inf +// HAS_ERRNO-NOT: .inf +// HAS_ERRNO-NOT: @inf + + __builtin_ldexp(f,f); __builtin_ldexpf(f,f); __builtin_ldexpl(f,f); + +// NO__ERRNO: declare double @ldexp(double, i32) [[READNONE]] +// NO__ERRNO: declare float @ldexpf(float, i32) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[READNONE]] +// HAS_ERRNO: declare double @ldexp(double, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare float @ldexpf(float, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[NOT_READNONE]] + + __builtin_modf(f,d); __builtin_modff(f,fp); __builtin_modfl(f,l); + +// NO__ERRNO: declare double @modf(double, double*) [[NOT_READNONE]] +// NO__ERRNO: declare float @modff(float, float*) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]] +// HAS_ERRNO: declare double @modf(double, double*) [[NOT_READNONE]] +// HAS_ERRNO: declare float @modff(float, float*) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]] + + __builtin_nan(c); __builtin_nanf(c); __builtin_nanl(c); + +// NO__ERRNO: declare double @nan(i8*) [[READNONE]] +// NO__ERRNO: declare float @nanf(i8*) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]] +// HAS_ERRNO: declare double @nan(i8*) [[READNONE:#[0-9]+]] +// HAS_ERRNO: declare float @nanf(i8*) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READNONE]] + + __builtin_nans(c); __builtin_nansf(c); __builtin_nansl(c); + +// NO__ERRNO: declare double @nans(i8*) [[READNONE]] +// NO__ERRNO: declare float @nansf(i8*) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]] +// HAS_ERRNO: declare double @nans(i8*) [[READNONE]] +// HAS_ERRNO: declare float @nansf(i8*) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @nansl(i8*) [[READNONE]] + + __builtin_pow(f,f); __builtin_powf(f,f); __builtin_powl(f,f); + +// NO__ERRNO: declare double @llvm.pow.f64(double, double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.pow.f32(float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @pow(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @powf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + __builtin_powi(f,f); __builtin_powif(f,f); __builtin_powil(f,f); + +// NO__ERRNO: declare double @llvm.powi.f64(double, i32) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.powi.f32(float, i32) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.powi.f80(x86_fp80, i32) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.powi.f64(double, i32) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.powi.f32(float, i32) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.powi.f80(x86_fp80, i32) [[READNONE_INTRINSIC]] + + /* math */ + __builtin_acos(f); __builtin_acosf(f); __builtin_acosl(f); + +// NO__ERRNO: declare double @acos(double) [[READNONE]] +// NO__ERRNO: declare float @acosf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @acosl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @acos(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @acosf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @acosl(x86_fp80) [[NOT_READNONE]] + + __builtin_acosh(f); __builtin_acoshf(f); __builtin_acoshl(f); + +// NO__ERRNO: declare double @acosh(double) [[READNONE]] +// NO__ERRNO: declare float @acoshf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @acosh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @acoshf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[NOT_READNONE]] + + __builtin_asin(f); __builtin_asinf(f); __builtin_asinl(f); + +// NO__ERRNO: declare double @asin(double) [[READNONE]] +// NO__ERRNO: declare float @asinf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @asinl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @asin(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @asinf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @asinl(x86_fp80) [[NOT_READNONE]] + + __builtin_asinh(f); __builtin_asinhf(f); __builtin_asinhl(f); + +// NO__ERRNO: declare double @asinh(double) [[READNONE]] +// NO__ERRNO: declare float @asinhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @asinh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @asinhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[NOT_READNONE]] + + __builtin_atan(f); __builtin_atanf(f); __builtin_atanl(f); + +// NO__ERRNO: declare double @atan(double) [[READNONE]] +// NO__ERRNO: declare float @atanf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @atanl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @atan(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @atanf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @atanl(x86_fp80) [[NOT_READNONE]] + + __builtin_atanh(f); __builtin_atanhf(f); __builtin_atanhl(f); + +// NO__ERRNO: declare double @atanh(double) [[READNONE]] +// NO__ERRNO: declare float @atanhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @atanh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @atanhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[NOT_READNONE]] + + __builtin_cbrt(f); __builtin_cbrtf(f); __builtin_cbrtl(f); + +// NO__ERRNO: declare double @cbrt(double) [[READNONE]] +// NO__ERRNO: declare float @cbrtf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @cbrt(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @cbrtf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[NOT_READNONE]] + + __builtin_ceil(f); __builtin_ceilf(f); __builtin_ceill(f); + +// NO__ERRNO: declare double @llvm.ceil.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.ceil.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.ceil.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.ceil.f64(double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.ceil.f32(float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.ceil.f80(x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_cos(f); __builtin_cosf(f); __builtin_cosl(f); + +// NO__ERRNO: declare double @cos(double) [[READNONE]] +// NO__ERRNO: declare float @cosf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cosl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @cos(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @cosf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @cosl(x86_fp80) [[NOT_READNONE]] + + __builtin_cosh(f); __builtin_coshf(f); __builtin_coshl(f); + +// NO__ERRNO: declare double @cosh(double) [[READNONE]] +// NO__ERRNO: declare float @coshf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @coshl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @cosh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @coshf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @coshl(x86_fp80) [[NOT_READNONE]] + + __builtin_erf(f); __builtin_erff(f); __builtin_erfl(f); + +// NO__ERRNO: declare double @erf(double) [[READNONE]] +// NO__ERRNO: declare float @erff(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @erfl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @erf(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @erff(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @erfl(x86_fp80) [[NOT_READNONE]] + + __builtin_erfc(f); __builtin_erfcf(f); __builtin_erfcl(f); + +// NO__ERRNO: declare double @erfc(double) [[READNONE]] +// NO__ERRNO: declare float @erfcf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @erfc(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @erfcf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[NOT_READNONE]] + + __builtin_exp(f); __builtin_expf(f); __builtin_expl(f); + +// NO__ERRNO: declare double @exp(double) [[READNONE]] +// NO__ERRNO: declare float @expf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @expl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @exp(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @expf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @expl(x86_fp80) [[NOT_READNONE]] + + __builtin_exp2(f); __builtin_exp2f(f); __builtin_exp2l(f); + +// NO__ERRNO: declare double @exp2(double) [[READNONE]] +// NO__ERRNO: declare float @exp2f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @exp2l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @exp2(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @exp2f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @exp2l(x86_fp80) [[NOT_READNONE]] + + __builtin_expm1(f); __builtin_expm1f(f); __builtin_expm1l(f); + +// NO__ERRNO: declare double @expm1(double) [[READNONE]] +// NO__ERRNO: declare float @expm1f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @expm1(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @expm1f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[NOT_READNONE]] + + __builtin_fdim(f,f); __builtin_fdimf(f,f); __builtin_fdiml(f,f); + +// NO__ERRNO: declare double @fdim(double, double) [[READNONE]] +// NO__ERRNO: declare float @fdimf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @fdim(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @fdimf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[NOT_READNONE]] + + __builtin_floor(f); __builtin_floorf(f); __builtin_floorl(f); + +// NO__ERRNO: declare double @llvm.floor.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.floor.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.floor.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.floor.f64(double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.floor.f32(float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.floor.f80(x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_fma(f,f,f); __builtin_fmaf(f,f,f); __builtin_fmal(f,f,f); + +// NO__ERRNO: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_fmax(f,f); __builtin_fmaxf(f,f); __builtin_fmaxl(f,f); + +// NO__ERRNO: declare double @llvm.maxnum.f64(double, double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.maxnum.f32(float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.maxnum.f64(double, double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.maxnum.f32(float, float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.maxnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_fmin(f,f); __builtin_fminf(f,f); __builtin_fminl(f,f); + +// NO__ERRNO: declare double @llvm.minnum.f64(double, double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.minnum.f32(float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.minnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.minnum.f64(double, double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.minnum.f32(float, float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.minnum.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_hypot(f,f); __builtin_hypotf(f,f); __builtin_hypotl(f,f); + +// NO__ERRNO: declare double @hypot(double, double) [[READNONE]] +// NO__ERRNO: declare float @hypotf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @hypot(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @hypotf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + __builtin_ilogb(f); __builtin_ilogbf(f); __builtin_ilogbl(f); + +// NO__ERRNO: declare i32 @ilogb(double) [[READNONE]] +// NO__ERRNO: declare i32 @ilogbf(float) [[READNONE]] +// NO__ERRNO: declare i32 @ilogbl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i32 @ilogb(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i32 @ilogbf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i32 @ilogbl(x86_fp80) [[NOT_READNONE]] + + __builtin_lgamma(f); __builtin_lgammaf(f); __builtin_lgammal(f); + +// NO__ERRNO: declare double @lgamma(double) [[NOT_READNONE]] +// NO__ERRNO: declare float @lgammaf(float) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare double @lgamma(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @lgammaf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]] + + __builtin_llrint(f); __builtin_llrintf(f); __builtin_llrintl(f); + +// NO__ERRNO: declare i64 @llrint(double) [[READNONE]] +// NO__ERRNO: declare i64 @llrintf(float) [[READNONE]] +// NO__ERRNO: declare i64 @llrintl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @llrint(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llrintf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llrintl(x86_fp80) [[NOT_READNONE]] + + __builtin_llround(f); __builtin_llroundf(f); __builtin_llroundl(f); + +// NO__ERRNO: declare i64 @llround(double) [[READNONE]] +// NO__ERRNO: declare i64 @llroundf(float) [[READNONE]] +// NO__ERRNO: declare i64 @llroundl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @llround(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llroundf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llroundl(x86_fp80) [[NOT_READNONE]] + + __builtin_log(f); __builtin_logf(f); __builtin_logl(f); + +// NO__ERRNO: declare double @log(double) [[READNONE]] +// NO__ERRNO: declare float @logf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @logl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @logf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @logl(x86_fp80) [[NOT_READNONE]] + + __builtin_log10(f); __builtin_log10f(f); __builtin_log10l(f); + +// NO__ERRNO: declare double @log10(double) [[READNONE]] +// NO__ERRNO: declare float @log10f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @log10l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log10(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @log10f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @log10l(x86_fp80) [[NOT_READNONE]] + + __builtin_log1p(f); __builtin_log1pf(f); __builtin_log1pl(f); + +// NO__ERRNO: declare double @log1p(double) [[READNONE]] +// NO__ERRNO: declare float @log1pf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log1p(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @log1pf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[NOT_READNONE]] + + __builtin_log2(f); __builtin_log2f(f); __builtin_log2l(f); + +// NO__ERRNO: declare double @log2(double) [[READNONE]] +// NO__ERRNO: declare float @log2f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @log2l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log2(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @log2f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @log2l(x86_fp80) [[NOT_READNONE]] + + __builtin_logb(f); __builtin_logbf(f); __builtin_logbl(f); + +// NO__ERRNO: declare double @logb(double) [[READNONE]] +// NO__ERRNO: declare float @logbf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @logbl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @logb(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @logbf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @logbl(x86_fp80) [[NOT_READNONE]] + + __builtin_lrint(f); __builtin_lrintf(f); __builtin_lrintl(f); + +// NO__ERRNO: declare i64 @lrint(double) [[READNONE]] +// NO__ERRNO: declare i64 @lrintf(float) [[READNONE]] +// NO__ERRNO: declare i64 @lrintl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @lrint(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lrintf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lrintl(x86_fp80) [[NOT_READNONE]] + + __builtin_lround(f); __builtin_lroundf(f); __builtin_lroundl(f); + +// NO__ERRNO: declare i64 @lround(double) [[READNONE]] +// NO__ERRNO: declare i64 @lroundf(float) [[READNONE]] +// NO__ERRNO: declare i64 @lroundl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @lround(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lroundf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lroundl(x86_fp80) [[NOT_READNONE]] + + __builtin_nearbyint(f); __builtin_nearbyintf(f); __builtin_nearbyintl(f); + +// NO__ERRNO: declare double @llvm.nearbyint.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.nearbyint.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.nearbyint.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.nearbyint.f64(double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.nearbyint.f32(float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.nearbyint.f80(x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_nextafter(f,f); __builtin_nextafterf(f,f); __builtin_nextafterl(f,f); + +// NO__ERRNO: declare double @nextafter(double, double) [[READNONE]] +// NO__ERRNO: declare float @nextafterf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @nextafter(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @nextafterf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + __builtin_nexttoward(f,f); __builtin_nexttowardf(f,f);__builtin_nexttowardl(f,f); + +// NO__ERRNO: declare double @nexttoward(double, x86_fp80) [[READNONE]] +// NO__ERRNO: declare float @nexttowardf(float, x86_fp80) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @nexttoward(double, x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare float @nexttowardf(float, x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + __builtin_remainder(f,f); __builtin_remainderf(f,f); __builtin_remainderl(f,f); + +// NO__ERRNO: declare double @remainder(double, double) [[READNONE]] +// NO__ERRNO: declare float @remainderf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @remainder(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @remainderf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + __builtin_remquo(f,f,i); __builtin_remquof(f,f,i); __builtin_remquol(f,f,i); + +// NO__ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]] +// NO__ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]] + + __builtin_rint(f); __builtin_rintf(f); __builtin_rintl(f); + +// NO__ERRNO: declare double @llvm.rint.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.rint.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.rint.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.rint.f64(double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.rint.f32(float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.rint.f80(x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_round(f); __builtin_roundf(f); __builtin_roundl(f); + +// NO__ERRNO: declare double @llvm.round.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.round.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.round.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.round.f64(double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.round.f32(float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.round.f80(x86_fp80) [[READNONE_INTRINSIC]] + + __builtin_scalbln(f,f); __builtin_scalblnf(f,f); __builtin_scalblnl(f,f); + +// NO__ERRNO: declare double @scalbln(double, i64) [[READNONE]] +// NO__ERRNO: declare float @scalblnf(float, i64) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[READNONE]] +// HAS_ERRNO: declare double @scalbln(double, i64) [[NOT_READNONE]] +// HAS_ERRNO: declare float @scalblnf(float, i64) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[NOT_READNONE]] + + __builtin_scalbn(f,f); __builtin_scalbnf(f,f); __builtin_scalbnl(f,f); + +// NO__ERRNO: declare double @scalbn(double, i32) [[READNONE]] +// NO__ERRNO: declare float @scalbnf(float, i32) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[READNONE]] +// HAS_ERRNO: declare double @scalbn(double, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare float @scalbnf(float, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[NOT_READNONE]] + + __builtin_sin(f); __builtin_sinf(f); __builtin_sinl(f); + +// NO__ERRNO: declare double @sin(double) [[READNONE]] +// NO__ERRNO: declare float @sinf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @sinl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @sin(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @sinf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @sinl(x86_fp80) [[NOT_READNONE]] + + __builtin_sinh(f); __builtin_sinhf(f); __builtin_sinhl(f); + +// NO__ERRNO: declare double @sinh(double) [[READNONE]] +// NO__ERRNO: declare float @sinhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @sinh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @sinhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[NOT_READNONE]] + + __builtin_sqrt(f); __builtin_sqrtf(f); __builtin_sqrtl(f); + +// NO__ERRNO: declare double @sqrt(double) [[READNONE]] +// NO__ERRNO: declare float @sqrtf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @sqrt(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @sqrtf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[NOT_READNONE]] + + __builtin_tan(f); __builtin_tanf(f); __builtin_tanl(f); + +// NO__ERRNO: declare double @tan(double) [[READNONE]] +// NO__ERRNO: declare float @tanf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @tanl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @tan(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @tanf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @tanl(x86_fp80) [[NOT_READNONE]] + + __builtin_tanh(f); __builtin_tanhf(f); __builtin_tanhl(f); + +// NO__ERRNO: declare double @tanh(double) [[READNONE]] +// NO__ERRNO: declare float @tanhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @tanh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @tanhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[NOT_READNONE]] + + __builtin_tgamma(f); __builtin_tgammaf(f); __builtin_tgammal(f); + +// NO__ERRNO: declare double @tgamma(double) [[READNONE]] +// NO__ERRNO: declare float @tgammaf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @tgamma(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @tgammaf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[NOT_READNONE]] + + __builtin_trunc(f); __builtin_truncf(f); __builtin_truncl(f); + +// NO__ERRNO: declare double @llvm.trunc.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.trunc.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.trunc.f64(double) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare float @llvm.trunc.f32(float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.trunc.f80(x86_fp80) [[READNONE_INTRINSIC]] +}; + + +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } + +// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } +// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } + diff --git a/test/CodeGen/math-libcalls.c b/test/CodeGen/math-libcalls.c new file mode 100644 index 0000000000..fcb54ed8d9 --- /dev/null +++ b/test/CodeGen/math-libcalls.c @@ -0,0 +1,532 @@ +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm %s | FileCheck %s -check-prefix=NO__ERRNO +// RUN: %clang_cc1 -triple x86_64-unknown-unknown -w -S -o - -emit-llvm -fmath-errno %s | FileCheck %s -check-prefix=HAS_ERRNO + +// Test attributes and builtin codegen of math library calls. + +void foo(double *d, float f, float *fp, long double *l, int *i, const char *c) { + atan2(f,f); atan2f(f,f) ; atan2l(f, f); + +// NO__ERRNO: declare double @atan2(double, double) [[READNONE:#[0-9]+]] +// NO__ERRNO: declare float @atan2f(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @atan2(double, double) [[NOT_READNONE:#[0-9]+]] +// HAS_ERRNO: declare float @atan2f(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @atan2l(x86_fp80, x86_fp80) [[NOT_READNONE]] + + copysign(f,f); copysignf(f,f);copysignl(f,f); + +// NO__ERRNO: declare double @copysign(double, double) [[READNONE]] +// NO__ERRNO: declare float @copysignf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @copysign(double, double) [[READNONE:#[0-9]+]] +// HAS_ERRNO: declare float @copysignf(float, float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @copysignl(x86_fp80, x86_fp80) [[READNONE]] + + fabs(f); fabsf(f); fabsl(f); + +// NO__ERRNO: declare double @fabs(double) [[READNONE]] +// NO__ERRNO: declare float @fabsf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @fabsl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @fabs(double) [[READNONE]] +// HAS_ERRNO: declare float @fabsf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @fabsl(x86_fp80) [[READNONE]] + + fmod(f,f); fmodf(f,f); fmodl(f,f); + +// NO__ERRNO: declare double @fmod(double, double) [[READNONE]] +// NO__ERRNO: declare float @fmodf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @fmod(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @fmodf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @fmodl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + frexp(f,i); frexpf(f,i); frexpl(f,i); + +// NO__ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE:#[0-9]+]] +// NO__ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare double @frexp(double, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare float @frexpf(float, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @frexpl(x86_fp80, i32*) [[NOT_READNONE]] + + ldexp(f,f); ldexpf(f,f); ldexpl(f,f); + +// NO__ERRNO: declare double @ldexp(double, i32) [[READNONE]] +// NO__ERRNO: declare float @ldexpf(float, i32) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[READNONE]] +// HAS_ERRNO: declare double @ldexp(double, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare float @ldexpf(float, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @ldexpl(x86_fp80, i32) [[NOT_READNONE]] + + modf(f,d); modff(f,fp); modfl(f,l); + +// NO__ERRNO: declare double @modf(double, double*) [[NOT_READNONE]] +// NO__ERRNO: declare float @modff(float, float*) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]] +// HAS_ERRNO: declare double @modf(double, double*) [[NOT_READNONE]] +// HAS_ERRNO: declare float @modff(float, float*) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @modfl(x86_fp80, x86_fp80*) [[NOT_READNONE]] + + nan(c); nanf(c); nanl(c); + +// NO__ERRNO: declare double @nan(i8*) [[READONLY:#[0-9]+]] +// NO__ERRNO: declare float @nanf(i8*) [[READONLY]] +// NO__ERRNO: declare x86_fp80 @nanl(i8*) [[READONLY]] +// HAS_ERRNO: declare double @nan(i8*) [[READONLY:#[0-9]+]] +// HAS_ERRNO: declare float @nanf(i8*) [[READONLY]] +// HAS_ERRNO: declare x86_fp80 @nanl(i8*) [[READONLY]] + + pow(f,f); powf(f,f); powl(f,f); + +// NO__ERRNO: declare double @llvm.pow.f64(double, double) [[READNONE_INTRINSIC:#[0-9]+]] +// NO__ERRNO: declare float @llvm.pow.f32(float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.pow.f80(x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @pow(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @powf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @powl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + /* math */ + acos(f); acosf(f); acosl(f); + +// NO__ERRNO: declare double @acos(double) [[READNONE]] +// NO__ERRNO: declare float @acosf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @acosl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @acos(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @acosf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @acosl(x86_fp80) [[NOT_READNONE]] + + acosh(f); acoshf(f); acoshl(f); + +// NO__ERRNO: declare double @acosh(double) [[READNONE]] +// NO__ERRNO: declare float @acoshf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @acosh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @acoshf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @acoshl(x86_fp80) [[NOT_READNONE]] + + asin(f); asinf(f); asinl(f); + +// NO__ERRNO: declare double @asin(double) [[READNONE]] +// NO__ERRNO: declare float @asinf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @asinl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @asin(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @asinf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @asinl(x86_fp80) [[NOT_READNONE]] + + asinh(f); asinhf(f); asinhl(f); + +// NO__ERRNO: declare double @asinh(double) [[READNONE]] +// NO__ERRNO: declare float @asinhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @asinh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @asinhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @asinhl(x86_fp80) [[NOT_READNONE]] + + atan(f); atanf(f); atanl(f); + +// NO__ERRNO: declare double @atan(double) [[READNONE]] +// NO__ERRNO: declare float @atanf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @atanl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @atan(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @atanf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @atanl(x86_fp80) [[NOT_READNONE]] + + atanh(f); atanhf(f); atanhl(f); + +// NO__ERRNO: declare double @atanh(double) [[READNONE]] +// NO__ERRNO: declare float @atanhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @atanh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @atanhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @atanhl(x86_fp80) [[NOT_READNONE]] + + cbrt(f); cbrtf(f); cbrtl(f); + +// NO__ERRNO: declare double @cbrt(double) [[READNONE]] +// NO__ERRNO: declare float @cbrtf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @cbrt(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @cbrtf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @cbrtl(x86_fp80) [[NOT_READNONE]] + + ceil(f); ceilf(f); ceill(f); + +// NO__ERRNO: declare double @ceil(double) [[READNONE]] +// NO__ERRNO: declare float @ceilf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @ceill(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @ceil(double) [[READNONE]] +// HAS_ERRNO: declare float @ceilf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @ceill(x86_fp80) [[READNONE]] + + cos(f); cosf(f); cosl(f); + +// NO__ERRNO: declare double @cos(double) [[READNONE]] +// NO__ERRNO: declare float @cosf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @cosl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @cos(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @cosf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @cosl(x86_fp80) [[NOT_READNONE]] + + cosh(f); coshf(f); coshl(f); + +// NO__ERRNO: declare double @cosh(double) [[READNONE]] +// NO__ERRNO: declare float @coshf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @coshl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @cosh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @coshf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @coshl(x86_fp80) [[NOT_READNONE]] + + erf(f); erff(f); erfl(f); + +// NO__ERRNO: declare double @erf(double) [[READNONE]] +// NO__ERRNO: declare float @erff(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @erfl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @erf(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @erff(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @erfl(x86_fp80) [[NOT_READNONE]] + + erfc(f); erfcf(f); erfcl(f); + +// NO__ERRNO: declare double @erfc(double) [[READNONE]] +// NO__ERRNO: declare float @erfcf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @erfc(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @erfcf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @erfcl(x86_fp80) [[NOT_READNONE]] + + exp(f); expf(f); expl(f); + +// NO__ERRNO: declare double @exp(double) [[READNONE]] +// NO__ERRNO: declare float @expf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @expl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @exp(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @expf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @expl(x86_fp80) [[NOT_READNONE]] + + exp2(f); exp2f(f); exp2l(f); + +// NO__ERRNO: declare double @exp2(double) [[READNONE]] +// NO__ERRNO: declare float @exp2f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @exp2l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @exp2(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @exp2f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @exp2l(x86_fp80) [[NOT_READNONE]] + + expm1(f); expm1f(f); expm1l(f); + +// NO__ERRNO: declare double @expm1(double) [[READNONE]] +// NO__ERRNO: declare float @expm1f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @expm1(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @expm1f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @expm1l(x86_fp80) [[NOT_READNONE]] + + fdim(f,f); fdimf(f,f); fdiml(f,f); + +// NO__ERRNO: declare double @fdim(double, double) [[READNONE]] +// NO__ERRNO: declare float @fdimf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @fdim(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @fdimf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @fdiml(x86_fp80, x86_fp80) [[NOT_READNONE]] + + floor(f); floorf(f); floorl(f); + +// NO__ERRNO: declare double @floor(double) [[READNONE]] +// NO__ERRNO: declare float @floorf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @floorl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @floor(double) [[READNONE]] +// HAS_ERRNO: declare float @floorf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @floorl(x86_fp80) [[READNONE]] + + fma(f,f,f); fmaf(f,f,f); fmal(f,f,f); + +// NO__ERRNO: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @llvm.fma.f64(double, double, double) [[READNONE_INTRINSIC:#[0-9]+]] +// HAS_ERRNO: declare float @llvm.fma.f32(float, float, float) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare x86_fp80 @llvm.fma.f80(x86_fp80, x86_fp80, x86_fp80) [[READNONE_INTRINSIC]] + + fmax(f,f); fmaxf(f,f); fmaxl(f,f); + +// NO__ERRNO: declare double @fmax(double, double) [[READNONE]] +// NO__ERRNO: declare float @fmaxf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @fmax(double, double) [[READNONE]] +// HAS_ERRNO: declare float @fmaxf(float, float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @fmaxl(x86_fp80, x86_fp80) [[READNONE]] + + fmin(f,f); fminf(f,f); fminl(f,f); + +// NO__ERRNO: declare double @fmin(double, double) [[READNONE]] +// NO__ERRNO: declare float @fminf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @fmin(double, double) [[READNONE]] +// HAS_ERRNO: declare float @fminf(float, float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @fminl(x86_fp80, x86_fp80) [[READNONE]] + + hypot(f,f); hypotf(f,f); hypotl(f,f); + +// NO__ERRNO: declare double @hypot(double, double) [[READNONE]] +// NO__ERRNO: declare float @hypotf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @hypot(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @hypotf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @hypotl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + ilogb(f); ilogbf(f); ilogbl(f); + +// NO__ERRNO: declare i32 @ilogb(double) [[READNONE]] +// NO__ERRNO: declare i32 @ilogbf(float) [[READNONE]] +// NO__ERRNO: declare i32 @ilogbl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i32 @ilogb(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i32 @ilogbf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i32 @ilogbl(x86_fp80) [[NOT_READNONE]] + + lgamma(f); lgammaf(f); lgammal(f); + +// NO__ERRNO: declare double @lgamma(double) [[NOT_READNONE]] +// NO__ERRNO: declare float @lgammaf(float) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare double @lgamma(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @lgammaf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @lgammal(x86_fp80) [[NOT_READNONE]] + + llrint(f); llrintf(f); llrintl(f); + +// NO__ERRNO: declare i64 @llrint(double) [[READNONE]] +// NO__ERRNO: declare i64 @llrintf(float) [[READNONE]] +// NO__ERRNO: declare i64 @llrintl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @llrint(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llrintf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llrintl(x86_fp80) [[NOT_READNONE]] + + llround(f); llroundf(f); llroundl(f); + +// NO__ERRNO: declare i64 @llround(double) [[READNONE]] +// NO__ERRNO: declare i64 @llroundf(float) [[READNONE]] +// NO__ERRNO: declare i64 @llroundl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @llround(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llroundf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @llroundl(x86_fp80) [[NOT_READNONE]] + + log(f); logf(f); logl(f); + +// NO__ERRNO: declare double @log(double) [[READNONE]] +// NO__ERRNO: declare float @logf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @logl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @logf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @logl(x86_fp80) [[NOT_READNONE]] + + log10(f); log10f(f); log10l(f); + +// NO__ERRNO: declare double @log10(double) [[READNONE]] +// NO__ERRNO: declare float @log10f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @log10l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log10(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @log10f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @log10l(x86_fp80) [[NOT_READNONE]] + + log1p(f); log1pf(f); log1pl(f); + +// NO__ERRNO: declare double @log1p(double) [[READNONE]] +// NO__ERRNO: declare float @log1pf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log1p(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @log1pf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @log1pl(x86_fp80) [[NOT_READNONE]] + + log2(f); log2f(f); log2l(f); + +// NO__ERRNO: declare double @log2(double) [[READNONE]] +// NO__ERRNO: declare float @log2f(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @log2l(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @log2(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @log2f(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @log2l(x86_fp80) [[NOT_READNONE]] + + logb(f); logbf(f); logbl(f); + +// NO__ERRNO: declare double @logb(double) [[READNONE]] +// NO__ERRNO: declare float @logbf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @logbl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @logb(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @logbf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @logbl(x86_fp80) [[NOT_READNONE]] + + lrint(f); lrintf(f); lrintl(f); + +// NO__ERRNO: declare i64 @lrint(double) [[READNONE]] +// NO__ERRNO: declare i64 @lrintf(float) [[READNONE]] +// NO__ERRNO: declare i64 @lrintl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @lrint(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lrintf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lrintl(x86_fp80) [[NOT_READNONE]] + + lround(f); lroundf(f); lroundl(f); + +// NO__ERRNO: declare i64 @lround(double) [[READNONE]] +// NO__ERRNO: declare i64 @lroundf(float) [[READNONE]] +// NO__ERRNO: declare i64 @lroundl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare i64 @lround(double) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lroundf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare i64 @lroundl(x86_fp80) [[NOT_READNONE]] + + nearbyint(f); nearbyintf(f); nearbyintl(f); + +// NO__ERRNO: declare double @nearbyint(double) [[READNONE]] +// NO__ERRNO: declare float @nearbyintf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @nearbyint(double) [[READNONE]] +// HAS_ERRNO: declare float @nearbyintf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @nearbyintl(x86_fp80) [[READNONE]] + + nextafter(f,f); nextafterf(f,f); nextafterl(f,f); + +// NO__ERRNO: declare double @nextafter(double, double) [[READNONE]] +// NO__ERRNO: declare float @nextafterf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @nextafter(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @nextafterf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @nextafterl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + nexttoward(f,f); nexttowardf(f,f);nexttowardl(f,f); + +// NO__ERRNO: declare double @nexttoward(double, x86_fp80) [[READNONE]] +// NO__ERRNO: declare float @nexttowardf(float, x86_fp80) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @nexttoward(double, x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare float @nexttowardf(float, x86_fp80) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @nexttowardl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + remainder(f,f); remainderf(f,f); remainderl(f,f); + +// NO__ERRNO: declare double @remainder(double, double) [[READNONE]] +// NO__ERRNO: declare float @remainderf(float, float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @remainder(double, double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @remainderf(float, float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @remainderl(x86_fp80, x86_fp80) [[NOT_READNONE]] + + remquo(f,f,i); remquof(f,f,i); remquol(f,f,i); + +// NO__ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]] +// NO__ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]] +// NO__ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare double @remquo(double, double, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare float @remquof(float, float, i32*) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @remquol(x86_fp80, x86_fp80, i32*) [[NOT_READNONE]] + + rint(f); rintf(f); rintl(f); + +// NO__ERRNO: declare double @rint(double) [[READNONE]] +// NO__ERRNO: declare float @rintf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @rintl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @rint(double) [[READNONE]] +// HAS_ERRNO: declare float @rintf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @rintl(x86_fp80) [[READNONE]] + + round(f); roundf(f); roundl(f); + +// NO__ERRNO: declare double @round(double) [[READNONE]] +// NO__ERRNO: declare float @roundf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @roundl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @round(double) [[READNONE]] +// HAS_ERRNO: declare float @roundf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @roundl(x86_fp80) [[READNONE]] + + scalbln(f,f); scalblnf(f,f); scalblnl(f,f); + +// NO__ERRNO: declare double @scalbln(double, i64) [[READNONE]] +// NO__ERRNO: declare float @scalblnf(float, i64) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[READNONE]] +// HAS_ERRNO: declare double @scalbln(double, i64) [[NOT_READNONE]] +// HAS_ERRNO: declare float @scalblnf(float, i64) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @scalblnl(x86_fp80, i64) [[NOT_READNONE]] + + scalbn(f,f); scalbnf(f,f); scalbnl(f,f); + +// NO__ERRNO: declare double @scalbn(double, i32) [[READNONE]] +// NO__ERRNO: declare float @scalbnf(float, i32) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[READNONE]] +// HAS_ERRNO: declare double @scalbn(double, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare float @scalbnf(float, i32) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @scalbnl(x86_fp80, i32) [[NOT_READNONE]] + + sin(f); sinf(f); sinl(f); + +// NO__ERRNO: declare double @sin(double) [[READNONE]] +// NO__ERRNO: declare float @sinf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @sinl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @sin(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @sinf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @sinl(x86_fp80) [[NOT_READNONE]] + + sinh(f); sinhf(f); sinhl(f); + +// NO__ERRNO: declare double @sinh(double) [[READNONE]] +// NO__ERRNO: declare float @sinhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @sinh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @sinhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @sinhl(x86_fp80) [[NOT_READNONE]] + + sqrt(f); sqrtf(f); sqrtl(f); + +// NO__ERRNO: declare double @llvm.sqrt.f64(double) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare float @llvm.sqrt.f32(float) [[READNONE_INTRINSIC]] +// NO__ERRNO: declare x86_fp80 @llvm.sqrt.f80(x86_fp80) [[READNONE_INTRINSIC]] +// HAS_ERRNO: declare double @sqrt(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @sqrtf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @sqrtl(x86_fp80) [[NOT_READNONE]] + + tan(f); tanf(f); tanl(f); + +// NO__ERRNO: declare double @tan(double) [[READNONE]] +// NO__ERRNO: declare float @tanf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @tanl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @tan(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @tanf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @tanl(x86_fp80) [[NOT_READNONE]] + + tanh(f); tanhf(f); tanhl(f); + +// NO__ERRNO: declare double @tanh(double) [[READNONE]] +// NO__ERRNO: declare float @tanhf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @tanh(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @tanhf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @tanhl(x86_fp80) [[NOT_READNONE]] + + tgamma(f); tgammaf(f); tgammal(f); + +// NO__ERRNO: declare double @tgamma(double) [[READNONE]] +// NO__ERRNO: declare float @tgammaf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @tgamma(double) [[NOT_READNONE]] +// HAS_ERRNO: declare float @tgammaf(float) [[NOT_READNONE]] +// HAS_ERRNO: declare x86_fp80 @tgammal(x86_fp80) [[NOT_READNONE]] + + trunc(f); truncf(f); truncl(f); + +// NO__ERRNO: declare double @trunc(double) [[READNONE]] +// NO__ERRNO: declare float @truncf(float) [[READNONE]] +// NO__ERRNO: declare x86_fp80 @truncl(x86_fp80) [[READNONE]] +// HAS_ERRNO: declare double @trunc(double) [[READNONE]] +// HAS_ERRNO: declare float @truncf(float) [[READNONE]] +// HAS_ERRNO: declare x86_fp80 @truncl(x86_fp80) [[READNONE]] +}; + + +// NO__ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// NO__ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } +// NO__ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} } +// NO__ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } + +// HAS_ERRNO: attributes [[NOT_READNONE]] = { nounwind "correctly{{.*}} } +// HAS_ERRNO: attributes [[READNONE]] = { {{.*}}readnone{{.*}} } +// HAS_ERRNO: attributes [[READONLY]] = { {{.*}}readonly{{.*}} } +// HAS_ERRNO: attributes [[READNONE_INTRINSIC]] = { {{.*}}readnone{{.*}} } + diff --git a/test/CodeGen/noplt.c b/test/CodeGen/noplt.c new file mode 100644 index 0000000000..f467199efa --- /dev/null +++ b/test/CodeGen/noplt.c @@ -0,0 +1,9 @@ +// RUN: %clang_cc1 -emit-llvm -fno-plt %s -o - | FileCheck %s -check-prefix=CHECK-NOPLT + +// CHECK-NOPLT: Function Attrs: nonlazybind +// CHECK-NOPLT-NEXT: declare {{.*}}i32 @foo +int foo(); + +int bar() { + return foo(); +} diff --git a/test/CodeGenCXX/cxx1z-inline-variables.cpp b/test/CodeGenCXX/cxx1z-inline-variables.cpp index 0d2ec92a7a..2d16acd8a8 100644 --- a/test/CodeGenCXX/cxx1z-inline-variables.cpp +++ b/test/CodeGenCXX/cxx1z-inline-variables.cpp @@ -67,6 +67,18 @@ int &use3 = X<int>::a; template<> int X<int>::b = 20; template<> inline int X<int>::c = 30; +template<typename T> struct Y; +template<> struct Y<int> { + static constexpr int a = 123; + static constexpr int b = 456; + static constexpr int c = 789; +}; +// CHECK: @_ZN1YIiE1aE = weak_odr constant i32 123 +constexpr int Y<int>::a; +// CHECK: @_ZN1YIiE1bE = linkonce_odr constant i32 456 +const int &yib = Y<int>::b; +// CHECK-NOT: @_ZN1YIiE1cE + // CHECK-LABEL: define {{.*}}global_var_init // CHECK: call i32 @_Z1fv diff --git a/test/CodeGenCXX/default_calling_conv.cpp b/test/CodeGenCXX/default_calling_conv.cpp index 15eedc8e31..b5b0f47ceb 100644 --- a/test/CodeGenCXX/default_calling_conv.cpp +++ b/test/CodeGenCXX/default_calling_conv.cpp @@ -3,18 +3,21 @@ // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -fdefault-calling-conv=stdcall -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL // RUN: %clang_cc1 -triple i486-unknown-linux-gnu -mrtd -emit-llvm -o - %s | FileCheck %s --check-prefix=STDCALL --check-prefix=ALL // RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=vectorcall -emit-llvm -o - %s | FileCheck %s --check-prefix=VECTORCALL --check-prefix=ALL +// RUN: %clang_cc1 -triple i986-unknown-linux-gnu -fdefault-calling-conv=regcall -emit-llvm -o - %s | FileCheck %s --check-prefix=REGCALL --check-prefix=ALL // CDECL: define void @_Z5test1v // FASTCALL: define x86_fastcallcc void @_Z5test1v // STDCALL: define x86_stdcallcc void @_Z5test1v // VECTORCALL: define x86_vectorcallcc void @_Z5test1v +// REGCALL: define x86_regcallcc void @_Z17__regcall3__test1v void test1() {} -// fastcall, stdcall, and vectorcall all do not support variadic functions. +// fastcall, stdcall, vectorcall and regcall do not support variadic functions. // CDECL: define void @_Z12testVariadicz // FASTCALL: define void @_Z12testVariadicz // STDCALL: define void @_Z12testVariadicz // VECTORCALL: define void @_Z12testVariadicz +// REGCALL: define void @_Z12testVariadicz void testVariadic(...){} // ALL: define void @_Z5test2v @@ -29,6 +32,9 @@ void __attribute__((stdcall)) test4() {} // ALL: define x86_vectorcallcc void @_Z5test5v void __attribute__((vectorcall)) test5() {} +// ALL: define x86_regcallcc void @_Z17__regcall3__test6v +void __attribute__((regcall)) test6() {} + // ALL: define linkonce_odr void @_ZN1A11test_memberEv class A { public: @@ -39,3 +45,8 @@ void test() { A a; a.test_member(); } + +// ALL: define i32 @main +int main() { + return 1; +} diff --git a/test/CodeGenCXX/runtime-dllstorage.cpp b/test/CodeGenCXX/runtime-dllstorage.cpp index 76c002c0e4..8ccf029168 100644 --- a/test/CodeGenCXX/runtime-dllstorage.cpp +++ b/test/CodeGenCXX/runtime-dllstorage.cpp @@ -12,7 +12,7 @@ // %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA -check-prefix CHECK-DYNAMIC-IA-ATEXIT // %clang_cc1 -triple i686-windows-itanium -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -fno-use-cxa-atexit -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA -check-prefix CHECK-STATIC-IA-ATEXIT -// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA +// RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA // RUN: %clang_cc1 -triple i686-windows-gnu -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA // RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-DYNAMIC-IA // RUN: %clang_cc1 -triple i686-windows-cygnus -std=c++11 -fdeclspec -fms-compatibility -fexceptions -fcxx-exceptions -flto-visibility-public-std -emit-llvm -o - %s | FileCheck %s -check-prefix CHECK-IA -check-prefix CHECK-STATIC-IA diff --git a/test/Driver/Inputs/Windows/usr/bin/ld.bfd b/test/Driver/Inputs/Windows/usr/bin/ld.bfd new file mode 100755 index 0000000000..e69de29bb2 --- /dev/null +++ b/test/Driver/Inputs/Windows/usr/bin/ld.bfd diff --git a/test/Driver/cl-cc-flags.c b/test/Driver/cl-cc-flags.c index 76f116e199..d74062a656 100644 --- a/test/Driver/cl-cc-flags.c +++ b/test/Driver/cl-cc-flags.c @@ -13,6 +13,9 @@ // RUN: %clang_cl --target=i686-windows-msvc /Gv -### -- %s 2>&1 | FileCheck --check-prefix=VECTORCALL %s // VECTORCALL: -fdefault-calling-conv=vectorcall +// RUN: %clang_cl --target=i686-windows-msvc /Gregcall -### -- %s 2>&1 | FileCheck --check-prefix=REGCALL %s +// REGCALL: -fdefault-calling-conv=regcall + // Last one should win: // RUN: %clang_cl --target=i686-windows-msvc /Gd /Gv -### -- %s 2>&1 | FileCheck --check-prefix=LASTWINS_VECTOR %s diff --git a/test/Driver/coverage.c b/test/Driver/coverage.c new file mode 100644 index 0000000000..9cfba81f07 --- /dev/null +++ b/test/Driver/coverage.c @@ -0,0 +1,8 @@ +// Test coverage flag. +// REQUIRES: system-windows +// +// RUN: %clang_cl -### -coverage %s -o foo/bar.o 2>&1 | FileCheck -check-prefix=CLANG-CL-COVERAGE %s +// CLANG-CL-COVERAGE-NOT: error: +// CLANG-CL-COVERAGE-NOT: warning: +// CLANG-CL-COVERAGE-NOT: argument unused +// CLANG-CL-COVERAGE-NOT: unknown argument diff --git a/test/Driver/fsanitize.c b/test/Driver/fsanitize.c index dcca96ff3a..3de6fa0b35 100644 --- a/test/Driver/fsanitize.c +++ b/test/Driver/fsanitize.c @@ -608,3 +608,29 @@ // CHECK-CFI-NOICALL-MINIMAL: "-fsanitize=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall" // CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-trap=cfi-derived-cast,cfi-unrelated-cast,cfi-nvcall,cfi-vcall" // CHECK-CFI-NOICALL-MINIMAL: "-fsanitize-minimal-runtime" + +// RUN: %clang -target aarch64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO +// RUN: %clang -target arm-linux-androideabi -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO +// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO +// RUN: %clang -target i386-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO +// CHECK-SCUDO: "-fsanitize=scudo" + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-PIE +// RUN: %clang -target arm-linux-androideabi -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-PIE +// CHECK-SCUDO-PIE: "-mrelocation-model" "pic" "-pic-level" "2" "-pic-is-pie" +// CHECK-SCUDO-PIE: "-pie" + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,undefined %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-UBSAN +// CHECK-SCUDO-UBSAN: "-fsanitize={{.*}}scudo" + +// RUN: %clang -target powerpc-unknown-linux -fsanitize=scudo %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-NO-SCUDO +// CHECK-NO-SCUDO: unsupported option + +// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,address %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-ASAN +// CHECK-SCUDO-ASAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=address' +// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,leak %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-LSAN +// CHECK-SCUDO-LSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=leak' +// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,memory %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-MSAN +// CHECK-SCUDO-MSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=memory' +// RUN: %clang -target x86_64-linux-gnu -fsanitize=scudo,thread %s -### 2>&1 | FileCheck %s --check-prefix=CHECK-SCUDO-TSAN +// CHECK-SCUDO-TSAN: error: invalid argument '-fsanitize=scudo' not allowed with '-fsanitize=thread' diff --git a/test/Driver/fuse-ld.c b/test/Driver/fuse-ld.c index bd8c9a5386..b043ce624e 100644 --- a/test/Driver/fuse-ld.c +++ b/test/Driver/fuse-ld.c @@ -67,3 +67,29 @@ // RUN: -gcc-toolchain %S/Inputs/basic_android_tree 2>&1 \ // RUN: | FileCheck %s -check-prefix=CHECK-ANDROID-ARM-GOLD-TC // CHECK-ANDROID-ARM-GOLD-TC: Inputs/basic_android_tree/lib/gcc/arm-linux-androideabi/4.4.3/../../../../arm-linux-androideabi/bin{{/|\\+}}ld.gold + + +// RUN: %clang %s -### -fuse-ld=link \ +// RUN: -target i686-unknown-windows-msvc 2>&1 \ +// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LINK +// CHECK-WINDOWS-MSVC-LINK: "{{.*}}link.exe" +// CHECK-WINDOWS-MSVC-LINK-SAME: "-out:{{.*}}" + +// RUN: %clang %s -### -fuse-ld=lld \ +// RUN: -target i686-unknown-windows-msvc 2>&1 \ +// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LLD +// CHECK-WINDOWS-MSVC-LLD: "{{.*}}lld-link" +// CHECK-WINDOWS-MSVC-LLD-SAME: "-out:{{.*}}" + +// RUN: %clang %s -### -fuse-ld=lld-link \ +// RUN: -target i686-unknown-windows-msvc 2>&1 \ +// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-LLD-LINK +// CHECK-WINDOWS-MSVC-LLD-LINK: "{{.*}}lld-link" +// CHECK-WINDOWS-MSVC-LLD-LINK-SAME: "-out:{{.*}}" + +// RUN: %clang %s -### -fuse-ld=bfd \ +// RUN: -target i686-unknown-windows-msvc \ +// RUN: -B %S/Inputs/Windows/usr/bin 2>&1 \ +// RUN: | FileCheck %s --check-prefix CHECK-WINDOWS-MSVC-BFD +// CHECK-WINDOWS-MSVC-BFD: "{{.*}}ld.bfd" +// CHECK-WINDOWS-MSVC-BFD-SAME: "-o" diff --git a/test/Driver/mingw-useld.c b/test/Driver/mingw-useld.c deleted file mode 100644 index a0ab5a9338..0000000000 --- a/test/Driver/mingw-useld.c +++ /dev/null @@ -1,19 +0,0 @@ -// RUN: %clang -### -target i686-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s 2>&1 | FileCheck -check-prefix=CHECK_LD_32 %s -// CHECK_LD_32: ld{{(.exe)?}}" -// CHECK_LD_32: "i386pe" -// CHECK_LD_32-NOT: "-flavor" "gnu" - -// RUN: %clang -### -target i686-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s -fuse-ld=lld 2>&1 | FileCheck -check-prefix=CHECK_LLD_32 %s -// CHECK_LLD_32-NOT: invalid linker name in argument -// CHECK_LLD_32: lld{{(.exe)?}}" "-flavor" "gnu" -// CHECK_LLD_32: "i386pe" - -// RUN: %clang -### -target x86_64-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s -fuse-ld=lld 2>&1 | FileCheck -check-prefix=CHECK_LLD_64 %s -// CHECK_LLD_64-NOT: invalid linker name in argument -// CHECK_LLD_64: lld{{(.exe)?}}" "-flavor" "gnu" -// CHECK_LLD_64: "i386pep" - -// RUN: %clang -### -target arm-pc-windows-gnu --sysroot=%S/Inputs/mingw_clang_tree/mingw32 %s -fuse-ld=lld 2>&1 | FileCheck -check-prefix=CHECK_LLD_ARM %s -// CHECK_LLD_ARM-NOT: invalid linker name in argument -// CHECK_LLD_ARM: lld{{(.exe)?}}" "-flavor" "gnu" -// CHECK_LLD_ARM: "thumb2pe" diff --git a/test/Driver/sanitizer-ld.c b/test/Driver/sanitizer-ld.c index f03714c4b5..8fc31fe37a 100644 --- a/test/Driver/sanitizer-ld.c +++ b/test/Driver/sanitizer-ld.c @@ -644,3 +644,53 @@ // // CHECK-ESAN-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" // CHECK-ESAN-LINUX: libclang_rt.esan-x86_64.a + +// RUN: %clang -fsanitize=scudo %s -### -o %t.o 2>&1 \ +// RUN: -target i386-unknown-linux -fuse-ld=ld \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-SCUDO-LINUX %s +// CHECK-SCUDO-LINUX: "{{.*}}ld{{(.exe)?}}" +// CHECK-SCUDO-LINUX: "-pie" +// CHECK-SCUDO-LINUX: "-whole-archive" "{{.*}}libclang_rt.scudo-i386.a" "-no-whole-archive" +// CHECK-SCUDO-LINUX-NOT: "-lstdc++" +// CHECK-SCUDO-LINUX: "-lpthread" +// CHECK-SCUDO-LINUX: "-ldl" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.so -shared 2>&1 \ +// RUN: -target i386-unknown-linux -fuse-ld=ld -fsanitize=scudo -shared-libsan \ +// RUN: -resource-dir=%S/Inputs/resource_dir \ +// RUN: --sysroot=%S/Inputs/basic_linux_tree \ +// RUN: | FileCheck --check-prefix=CHECK-SCUDO-SHARED-LINUX %s +// +// CHECK-SCUDO-SHARED-LINUX: "{{(.*[^-.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-SCUDO-SHARED-LINUX-NOT: "-lc" +// CHECK-SCUDO-SHARED-LINUX-NOT: libclang_rt.scudo-i386.a" +// CHECK-SCUDO-SHARED-LINUX: libclang_rt.scudo-i386.so" +// CHECK-SCUDO-SHARED-LINUX-NOT: "-lpthread" +// CHECK-SCUDO-SHARED-LINUX-NOT: "-lrt" +// CHECK-SCUDO-SHARED-LINUX-NOT: "-ldl" +// CHECK-SCUDO-SHARED-LINUX-NOT: "-export-dynamic" +// CHECK-SCUDO-SHARED-LINUX-NOT: "--dynamic-list" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=scudo \ +// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ +// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID %s +// +// CHECK-SCUDO-ANDROID: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-SCUDO-ANDROID-NOT: "-lc" +// CHECK-SCUDO-ANDROID: "-pie" +// CHECK-SCUDO-ANDROID-NOT: "-lpthread" +// CHECK-SCUDO-ANDROID: libclang_rt.scudo-arm-android.so" +// CHECK-SCUDO-ANDROID-NOT: "-lpthread" + +// RUN: %clang -no-canonical-prefixes %s -### -o %t.o 2>&1 \ +// RUN: -target arm-linux-androideabi -fuse-ld=ld -fsanitize=scudo \ +// RUN: --sysroot=%S/Inputs/basic_android_tree/sysroot \ +// RUN: -static-libsan \ +// RUN: | FileCheck --check-prefix=CHECK-SCUDO-ANDROID-STATIC %s +// CHECK-SCUDO-ANDROID-STATIC: "{{(.*[^.0-9A-Z_a-z])?}}ld{{(.exe)?}}" +// CHECK-SCUDO-ANDROID-STATIC: "-pie" +// CHECK-SCUDO-ANDROID-STATIC: "-whole-archive" "{{.*}}libclang_rt.scudo-arm-android.a" "-no-whole-archive" +// CHECK-SCUDO-ANDROID-STATIC-NOT: "-lstdc++" +// CHECK-SCUDO-ANDROID-STATIC: "-lpthread" diff --git a/test/Headers/mm3dnow.c b/test/Headers/mm3dnow.c new file mode 100644 index 0000000000..255483cb9b --- /dev/null +++ b/test/Headers/mm3dnow.c @@ -0,0 +1,16 @@ +// RUN: %clang_cc1 -fsyntax-only -ffreestanding %s -verify +// RUN: %clang_cc1 -fsyntax-only -ffreestanding -x c++ %s -verify +// expected-no-diagnostics + +#if defined(i386) || defined(__x86_64__) +#include <mm3dnow.h> + +int __attribute__((__target__(("3dnow")))) foo(int a) { + _m_femms(); + return 4; +} + +__m64 __attribute__((__target__(("3dnowa")))) bar(__m64 a) { + return _m_pf2iw(a); +} +#endif diff --git a/test/Index/Core/index-source.cpp b/test/Index/Core/index-source.cpp index f9c88d5ea6..6ad600b351 100644 --- a/test/Index/Core/index-source.cpp +++ b/test/Index/Core/index-source.cpp @@ -525,3 +525,36 @@ struct rd33122110::Outer::Nested<int>; // CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I // CHECK: [[@LINE-3]]:20 | struct/C++ | Outer | c:@N@rd33122110@S@Outer | <no-cgname> | Ref,RelCont | rel: 1 // CHECK-NEXT: RelCont | Nested | c:@N@rd33122110@S@Outer@S@Nested>#I + +namespace index_offsetof { + +struct Struct { + int field; +}; + +struct Struct2 { + Struct array[4][2]; +}; + +void foo() { + __builtin_offsetof(Struct, field); +// CHECK: [[@LINE-1]]:30 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1 +// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo# + __builtin_offsetof(Struct2, array[1][0].field); +// CHECK: [[@LINE-1]]:31 | field/C | array | c:@N@index_offsetof@S@Struct2@FI@array | <no-cgname> | Ref,RelCont | rel: 1 +// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo# +// CHECK: [[@LINE-3]]:43 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1 +// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@F@foo# +} + +#define OFFSET_OF_(X, Y) __builtin_offsetof(X, Y) + +class SubclassOffsetof : public Struct { + void foo() { + OFFSET_OF_(SubclassOffsetof, field); +// CHECK: [[@LINE-1]]:34 | field/C | field | c:@N@index_offsetof@S@Struct@FI@field | <no-cgname> | Ref,RelCont | rel: 1 +// CHECK-NEXT: RelCont | foo | c:@N@index_offsetof@S@SubclassOffsetof@F@foo# + } +}; + +} diff --git a/test/Index/complete-cxx-inline-methods.cpp b/test/Index/complete-cxx-inline-methods.cpp index c0a4a8d75c..0f78e8caa7 100644 --- a/test/Index/complete-cxx-inline-methods.cpp +++ b/test/Index/complete-cxx-inline-methods.cpp @@ -25,7 +25,7 @@ private: // RUN: c-index-test -code-completion-at=%s:4:9 -std=c++98 %s | FileCheck %s // RUN: c-index-test -code-completion-at=%s:13:7 -std=c++98 %s | FileCheck %s -// CHECK: CXXMethod:{ResultType MyCls::Vec &}{TypedText operator=}{LeftParen (}{Placeholder const MyCls::Vec &}{RightParen )} (79) +// CHECK: CXXMethod:{ResultType Vec &}{TypedText operator=}{LeftParen (}{Placeholder const Vec &}{RightParen )} (79) // CHECK-NEXT: StructDecl:{TypedText Vec}{Text ::} (75) // CHECK-NEXT: FieldDecl:{ResultType int}{TypedText x} (35) // CHECK-NEXT: FieldDecl:{ResultType int}{TypedText y} (35) diff --git a/test/Index/preamble-conditionals-inverted.cpp b/test/Index/preamble-conditionals-inverted.cpp index 1d67ccb61a..f5cf1205e3 100644 --- a/test/Index/preamble-conditionals-inverted.cpp +++ b/test/Index/preamble-conditionals-inverted.cpp @@ -3,6 +3,8 @@ // RUN: | FileCheck %s --implicit-check-not "error:" #ifdef FOO_H -void foo(); +void foo() {} #endif + +int foo() { return 0; } diff --git a/test/Index/preamble-conditionals-skipping.cpp b/test/Index/preamble-conditionals-skipping.cpp new file mode 100644 index 0000000000..fa5764cd5d --- /dev/null +++ b/test/Index/preamble-conditionals-skipping.cpp @@ -0,0 +1,16 @@ +// RUN: env CINDEXTEST_EDITING=1 c-index-test -test-load-source-reparse 5 \ +// RUN: local -std=c++14 %s 2>&1 \ +// RUN: | FileCheck %s --implicit-check-not "error:" + +#ifdef MYCPLUSPLUS +extern "C" { +#endif + +#ifdef MYCPLUSPLUS +} +#endif + +int main() +{ + return 0; +} diff --git a/test/Modules/Inputs/codegen/foo.h b/test/Modules/Inputs/codegen/foo.h index bd3b6489e7..76ad6559cc 100644 --- a/test/Modules/Inputs/codegen/foo.h +++ b/test/Modules/Inputs/codegen/foo.h @@ -29,4 +29,7 @@ inline void inst_decl() { inst<float>(); } +__attribute__((always_inline)) inline void always_inl() { +} + asm("narf"); diff --git a/test/Modules/Inputs/codegen/use.cpp b/test/Modules/Inputs/codegen/use.cpp index cd1a4a642d..3e551881f6 100644 --- a/test/Modules/Inputs/codegen/use.cpp +++ b/test/Modules/Inputs/codegen/use.cpp @@ -6,3 +6,6 @@ void non_modular_use_of_implicit_dtor() { void use_of_instantiated_declaration_without_definition() { inst<int>(); } +void call_always_inline() { + always_inl(); +} diff --git a/test/Modules/codegen-opt.test b/test/Modules/codegen-opt.test index 2f4997a7c7..f62cf38a53 100644 --- a/test/Modules/codegen-opt.test +++ b/test/Modules/codegen-opt.test @@ -25,7 +25,13 @@ FOO-NOT: {{define|declare}} FOO: declare void @_Z2f1Ri(i32* FOO-NOT: {{define|declare}} -FIXME: this internal function should be weak_odr, comdat, and with a new mangling +Internal functions are not modularly code generated - they are +internal wherever they're used. This might not be ideal, but +continues to workaround/support some oddities that backwards +compatible modules have seen and supported in the wild. To remove +the duplication here, the internal functions would need to be +promoted to weak_odr, placed in comdat and given a new mangling - +this would be needed for the C++ Modules TS anyway. FOO: define internal void @_ZL2f2v() #{{[0-9]+}} FOO-NOT: {{define|declare}} @@ -45,7 +51,7 @@ BAR-OPT: define available_externally void @_Z3foov() BAR-CMN-NOT: {{define|declare}} BAR-OPT: declare void @_Z2f1Ri(i32* BAR-OPT-NOT: {{define|declare}} -BAR-OPT: define available_externally void @_ZL2f2v() +BAR-OPT: define internal void @_ZL2f2v() BAR-OPT-NOT: {{define|declare}} @@ -61,5 +67,5 @@ USE-OPT: define available_externally void @_Z3foov() USE-OPT-NOT: {{define|declare}} USE-OPT: declare void @_Z2f1Ri(i32* USE-OPT-NOT: {{define|declare}} -USE-OPT: define available_externally void @_ZL2f2v() +USE-OPT: define internal void @_ZL2f2v() USE-OPT-NOT: {{define|declare}} diff --git a/test/Modules/codegen.test b/test/Modules/codegen.test index 1bdea5df43..a919933da2 100644 --- a/test/Modules/codegen.test +++ b/test/Modules/codegen.test @@ -4,7 +4,7 @@ REQUIRES: x86-registered-target RUN: %clang_cc1 -triple=x86_64-linux-gnu -fmodules-codegen -fmodules-debuginfo -x c++ -fmodules -emit-module -fmodule-name=foo %S/Inputs/codegen/foo.modulemap -o %t/foo.pcm RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - %t/foo.pcm | FileCheck --check-prefix=FOO --check-prefix=BOTH %s -RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s +RUN: %clang_cc1 -triple x86_64-linux-gnu -emit-llvm -debug-info-kind=limited -o - -fmodules -disable-llvm-passes -fmodule-file=%t/foo.pcm %S/Inputs/codegen/use.cpp | FileCheck --check-prefix=BOTH --check-prefix=USE %s For want of any better definition, inline asm goes "everywhere" the same as it if it were in a header (with the disadvantage that the inline asm will be @@ -23,6 +23,7 @@ USE: module asm "narf" FOO: $_Z2f1PKcz = comdat any FOO: $_ZN13implicit_dtorD1Ev = comdat any USE: $_Z4instIiEvv = comdat any +USE: $_Z10always_inlv = comdat any FOO: $_ZN13implicit_dtorD2Ev = comdat any FOO: define weak_odr void @_Z2f1PKcz(i8* %fmt, ...) #{{[0-9]+}} comdat FOO: call void @llvm.va_start(i8* %{{[a-zA-Z0-9]*}}) @@ -38,6 +39,7 @@ FOO: define weak_odr void @_ZN13implicit_dtorD2Ev USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD1Ev USE: define linkonce_odr void @_Z4instIiEvv +USE: define linkonce_odr void @_Z10always_inlv USE: define linkonce_odr void @_ZN20uninst_implicit_dtorD2Ev Modular debug info puts the definition of a class defined in a module in that diff --git a/test/Modules/odr_hash.cpp b/test/Modules/odr_hash.cpp index 8ff95d2566..b672695dce 100644 --- a/test/Modules/odr_hash.cpp +++ b/test/Modules/odr_hash.cpp @@ -12,6 +12,10 @@ // RUN: echo "#define SECOND" >> %t/Inputs/second.h // RUN: cat %s >> %t/Inputs/second.h +// Test that each header can compile +// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/first.h +// RUN: %clang_cc1 -fsyntax-only -x c++ -std=c++1z %t/Inputs/second.h + // Build module map file // RUN: echo "module FirstModule {" >> %t/Inputs/module.map // RUN: echo " header \"first.h\"" >> %t/Inputs/module.map @@ -28,6 +32,13 @@ #include "second.h" #endif +// Used for testing +#if defined(FIRST) +#define ACCESS public: +#elif defined(SECOND) +#define ACCESS private: +#endif + namespace AccessSpecifiers { #if defined(FIRST) struct S1 { @@ -55,6 +66,32 @@ S2 s2; // expected-error@second.h:* {{'AccessSpecifiers::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found protected access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} #endif + +#define DECLS \ +public: \ +private: \ +protected: + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'AccessSpecifiers::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif + +#undef DECLS } // namespace AccessSpecifiers namespace StaticAssert { @@ -113,7 +150,31 @@ S4 s4; // expected-error@second.h:* {{'StaticAssert::S4' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found static assert}} #endif -} + +#define DECLS \ + static_assert(4 == 4, "Message"); \ + static_assert(5 == 5); + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'StaticAssert::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace StaticAssert namespace Field { #if defined(FIRST) @@ -302,6 +363,38 @@ S13 s13; // expected-error@first.h:* {{'Field::S13::x' from module 'FirstModule' is not present in definition of 'Field::S13' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif + +#define DECLS \ + int a; \ + int b : 3; \ + unsigned c : 1 + 2; \ + s d; \ + double e = 1.0; \ + long f[5]; + +#if defined(FIRST) || defined(SECOND) +typedef short s; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'Field::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace Field namespace Method { @@ -531,6 +624,40 @@ S15 s15; // expected-error@first.h:* {{'Method::S15::A' from module 'FirstModule' is not present in definition of 'Method::S15' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'A' does not match}} #endif + +#define DECLS \ + void A(); \ + static void B(); \ + virtual void C(); \ + virtual void D() = 0; \ + inline void E(); \ + void F() const; \ + void G() volatile; \ + void H(int x); \ + void I(int x = 5 + 5); \ + void J(int); \ + void K(int x[2]); \ + int L(); + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1* v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1* i1; +// expected-error@second.h:* {{'Method::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace Method namespace Constructor { @@ -565,6 +692,31 @@ S2* s2; // expected-error@second.h:* {{'Constructor::S2' has different definitions in different modules; first difference is definition in module 'SecondModule' found constructor that has 2 parameters}} // expected-note@first.h:* {{but in 'FirstModule' found constructor that has 1 parameter}} #endif + +#define DECLS(CLASS) \ + CLASS(int); \ + CLASS(double); \ + CLASS(int, int); + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS(Valid1) +}; +#else +Valid1* v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS(Invalid1) + ACCESS +}; +#else +Invalid1* i1; +// expected-error@second.h:* {{'Constructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace Constructor namespace Destructor { @@ -600,32 +752,44 @@ S2 s2; // expected-note@first.h:* {{but in 'FirstModule' found destructor is virtual}} #endif -} // namespace Destructor - -// Naive parsing of AST can lead to cycles in processing. Ensure -// self-references don't trigger an endless cycles of AST node processing. -namespace SelfReference { -#if defined(FIRST) -template <template <int> class T> class Wrapper {}; - -template <int N> class S { - S(Wrapper<::SelfReference::S> &Ref) {} +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + ~Valid1(); }; +#else +Valid1 v1; +#endif -struct Xx { - struct Yy { - }; +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + ~Invalid1(); + ACCESS }; +#else +Invalid1 i1; +// expected-error@second.h:* {{'Destructor::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif -Xx::Xx::Xx::Yy yy; +#if defined(FIRST) || defined(SECOND) +struct Valid2 { + virtual ~Valid2(); +}; +#else +Valid2 v2; +#endif -namespace NNS { -template <typename> struct Foo; -template <template <class> class T = NNS::Foo> -struct NestedNamespaceSpecifier {}; -} +#if defined(FIRST) || defined(SECOND) +struct Invalid2 { + virtual ~Invalid2(); + ACCESS +}; +#else +Invalid2 i2; +// expected-error@second.h:* {{'Destructor::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} #endif -} // namespace SelfReference +} // namespace Destructor namespace TypeDef { #if defined(FIRST) @@ -722,6 +886,35 @@ S6 s6; // expected-error@second.h:* {{'TypeDef::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found typedef 'b' with underlying type 'float'}} // expected-note@first.h:* {{but in 'FirstModule' found typedef 'b' with different underlying type 'TypeDef::F' (aka 'float')}} #endif + +#define DECLS \ + typedef int A; \ + typedef double B; \ + typedef I C; + +#if defined(FIRST) || defined(SECOND) +typedef int I; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'TypeDef::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace TypeDef namespace Using { @@ -819,6 +1012,35 @@ S6 s6; // expected-error@second.h:* {{'Using::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found type alias 'b' with underlying type 'float'}} // expected-note@first.h:* {{but in 'FirstModule' found type alias 'b' with different underlying type 'Using::F' (aka 'float')}} #endif + +#if defined(FIRST) || defined(SECOND) +using I = int; +#endif + +#define DECLS \ + using A = int; \ + using B = double; \ + using C = I; + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'Using::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace Using namespace RecordType { @@ -837,7 +1059,34 @@ S1 s1; // expected-error@first.h:* {{'RecordType::S1::x' from module 'FirstModule' is not present in definition of 'RecordType::S1' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif -} + +#define DECLS \ + Foo F; + +#if defined(FIRST) || defined(SECOND) +struct Foo {}; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'RecordType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace RecordType namespace DependentType { #if defined(FIRST) @@ -856,7 +1105,34 @@ using U1 = S1<T>; // expected-error@first.h:* {{'DependentType::S1::x' from module 'FirstModule' is not present in definition of 'S1<T>' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif -} + +#define DECLS \ + typename T::typeA x; + +#if defined(FIRST) || defined(SECOND) +template <class T> +struct Valid1 { + DECLS +}; +#else +template <class T> +using V1 = Valid1<T>; +#endif + +#if defined(FIRST) || defined(SECOND) +template <class T> +struct Invalid1 { + DECLS + ACCESS +}; +#else +template <class T> +using I1 = Invalid1<T>; +// expected-error@second.h:* {{'DependentType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace DependentType namespace ElaboratedType { #if defined(FIRST) @@ -874,7 +1150,34 @@ S1 s1; // expected-error@first.h:* {{'ElaboratedType::S1::x' from module 'FirstModule' is not present in definition of 'ElaboratedType::S1' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif -} + +#define DECLS \ + NS::type x; + +#if defined(FIRST) || defined(SECOND) +namespace NS { using type = float; } +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'ElaboratedType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace ElaboratedType namespace Enum { #if defined(FIRST) @@ -892,6 +1195,33 @@ S1 s1; // expected-error@first.h:* {{'Enum::S1::x' from module 'FirstModule' is not present in definition of 'Enum::S1' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'x' does not match}} #endif + +#define DECLS \ + E e = E1; + +#if defined(FIRST) || defined(SECOND) +enum E { E1, E2 }; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'Enum::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } namespace NestedNamespaceSpecifier { @@ -1069,7 +1399,73 @@ S10 s10; // expected-note@first.h:* {{declaration of 'x' does not match}} #endif } + +#define DECLS \ + NS1::Type a; \ + NS1::NS2::Type b; \ + NS1::S c; \ + NS3::Type d; + +#if defined(FIRST) || defined(SECOND) +namespace NS1 { + using Type = int; + namespace NS2 { + using Type = double; + } + struct S {}; } +namespace NS3 = NS1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS + +#define DECLS \ + typename T::type *x = {}; \ + int y = x->T::foo(); \ + int z = U::template X<int>::value; + +#if defined(FIRST) || defined(SECOND) +template <class T, class U> +struct Valid2 { + DECLS +}; +#else +template <class T, class U> +using V2 = Valid2<T, U>; +#endif + +#if defined(FIRST) || defined(SECOND) +template <class T, class U> +struct Invalid2 { + DECLS + ACCESS +}; +#else +template <class T, class U> +using I2 = Invalid2<T, U>; +// expected-error@second.h:* {{'NestedNamespaceSpecifier::Invalid2' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace NestedNamespaceSpecifier namespace TemplateSpecializationType { #if defined(FIRST) @@ -1103,7 +1499,40 @@ S2 s2; // expected-error@first.h:* {{'TemplateSpecializationType::S2::u' from module 'FirstModule' is not present in definition of 'TemplateSpecializationType::S2' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'u' does not match}} #endif -} + +#define DECLS \ + OneTemplateArg<int> x; \ + OneTemplateArg<double> y; \ + OneTemplateArg<char *> z; \ + TwoTemplateArgs<int, int> a; \ + TwoTemplateArgs<double, float> b; \ + TwoTemplateArgs<short *, char> c; + +#if defined(FIRST) || defined(SECOND) +template <class T> struct OneTemplateArg {}; +template <class T, class U> struct TwoTemplateArgs {}; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { +DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { +DECLS +ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'TemplateSpecializationType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace TemplateSpecializationType namespace TemplateArgument { #if defined(FIRST) @@ -1205,7 +1634,43 @@ S6 s6; // expected-error@second.h:* {{'TemplateArgument::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found field 'y'}} // expected-note@first.h:* {{but in 'FirstModule' found field 'x'}} #endif -} + +#define DECLS \ + OneClass<int> a; \ + OneInt<1> b; \ + using c = OneClass<float>; \ + using d = OneInt<2>; \ + using e = OneInt<2 + 2>; \ + OneTemplateClass<OneClass> f; \ + OneTemplateInt<OneInt> g; + +#if defined(FIRST) || defined(SECOND) +template <class> struct OneClass{}; +template <int> struct OneInt{}; +template <template <class> class> struct OneTemplateClass{}; +template <template <int> class> struct OneTemplateInt{}; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { +DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { +DECLS +ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'TemplateArgument::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace TemplateArgument namespace TemplateTypeParmType { #if defined(FIRST) @@ -1247,7 +1712,41 @@ using TemplateTypeParmType::S2; // expected-error@first.h:* {{'TemplateTypeParmType::S2::type' from module 'FirstModule' is not present in definition of 'S2<T, U>' in module 'SecondModule'}} // expected-note@second.h:* {{declaration of 'type' does not match}} #endif -} + +#define DECLS \ + T t; \ + U u; \ + ParameterPack<T> a; \ + ParameterPack<T, U> b; \ + ParameterPack<U> c; \ + ParameterPack<U, T> d; + +#if defined(FIRST) || defined(SECOND) +template <class ...Ts> struct ParameterPack {}; +#endif + +#if defined(FIRST) || defined(SECOND) +template <class T, class U> +struct Valid1 { + DECLS +}; +#else +using TemplateTypeParmType::Valid1; +#endif + +#if defined(FIRST) || defined(SECOND) +template <class T, class U> +struct Invalid1 { + DECLS + ACCESS +}; +#else +using TemplateTypeParmType::Invalid1; +// expected-error@second.h:* {{'TemplateTypeParmType::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace TemplateTypeParmType namespace VarDecl { #if defined(FIRST) @@ -1381,46 +1880,36 @@ S9 s9; // expected-note@second.h:* {{declaration of 'x' does not match}} #endif -#if defined(FIRST) -template <typename T> -struct S { - struct R { - void foo(T x = 0) {} - }; -}; -#elif defined(SECOND) -template <typename T> -struct S { - struct R { - void foo(T x = 1) {} - }; +#define DECLS \ + static int a; \ + static I b; \ + static const int c = 1; \ + static constexpr int d = 5; + +#if defined(FIRST) || defined(SECOND) +using I = int; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS }; #else -void run() { - S<int>::R().foo(); -} -// expected-error@second.h:* {{'VarDecl::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}} -// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}} +Valid1 v1; #endif -#if defined(FIRST) -template <typename alpha> struct Bravo { - void charlie(bool delta = false) {} -}; -typedef Bravo<char> echo; -echo foxtrot; -#elif defined(SECOND) -template <typename alpha> struct Bravo { - void charlie(bool delta = (false)) {} +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS }; -typedef Bravo<char> echo; -echo foxtrot; #else -Bravo<char> golf; -// expected-error@second.h:* {{'VarDecl::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}} -// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}} +Invalid1 i1; +// expected-error@second.h:* {{'VarDecl::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} #endif -} +#undef DECLS +} // namespace VarDecl namespace Friend { #if defined(FIRST) @@ -1499,7 +1988,41 @@ S5 s5; // expected-error@second.h:* {{'Friend::S5' has different definitions in different modules; first difference is definition in module 'SecondModule' found friend function 'T5b'}} // expected-note@first.h:* {{but in 'FirstModule' found friend function 'T5a'}} #endif -} + +#define DECLS \ + friend class FriendA; \ + friend struct FriendB; \ + friend FriendC; \ + friend const FriendD; \ + friend void Function(); + +#if defined(FIRST) || defined(SECOND) +class FriendA {}; +class FriendB {}; +class FriendC {}; +class FriendD {}; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 { + DECLS +}; +#else +Valid1 v1; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Invalid1 { + DECLS + ACCESS +}; +#else +Invalid1 i1; +// expected-error@second.h:* {{'Friend::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS +} // namespace Friend namespace TemplateParameters { #if defined(FIRST) @@ -1575,6 +2098,38 @@ using TemplateParameters::S6; // expected-error@second.h:* {{'TemplateParameters::S6' has different definitions in different modules; first difference is definition in module 'SecondModule' found unnamed template parameter}} // expected-note@first.h:* {{but in 'FirstModule' found template parameter 'A'}} #endif + +#define DECLS + +#if defined(FIRST) || defined(SECOND) +template <class> class DefaultArg; +#endif + +#if defined(FIRST) || defined(SECOND) +template <int, class, template <class> class, + int A, class B, template <int> class C, + int D = 1, class E = int, template <class F> class = DefaultArg> +struct Valid1 { + DECLS +}; +#else +using TemplateParameters::Valid1; +#endif + +#if defined(FIRST) || defined(SECOND) +template <int, class, template <class> class, + int A, class B, template <int> class C, + int D = 1, class E = int, template <class F> class = DefaultArg> +struct Invalid1 { + DECLS + ACCESS +}; +#else +using TemplateParameters::Invalid1; +// expected-error@second.h:* {{'TemplateParameters::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} +#endif +#undef DECLS } // namespace TemplateParameters namespace BaseClass { @@ -1695,68 +2250,69 @@ S10 s10; // expected-error@second.h:* {{'BaseClass::S10' has different definitions in different modules; first difference is definition in module 'SecondModule' found 1st base class 'BaseClass::B10a' with protected access specifier}} // expected-note@first.h:* {{but in 'FirstModule' found 1st base class 'BaseClass::B10a' with no access specifier}} #endif -} // namespace BaseClass -// Interesting cases that should not cause errors. struct S should not error -// while struct T should error at the access specifier mismatch at the end. -namespace AllDecls { -#define CREATE_ALL_DECL_STRUCT(NAME, ACCESS) \ - typedef int INT; \ - struct NAME { \ - public: \ - private: \ - protected: \ - static_assert(1 == 1, "Message"); \ - static_assert(2 == 2); \ - \ - int x; \ - double y; \ - \ - INT z; \ - \ - unsigned a : 1; \ - unsigned b : 2 * 2 + 5 / 2; \ - \ - mutable int c = sizeof(x + y); \ - \ - void method() {} \ - static void static_method() {} \ - virtual void virtual_method() {} \ - virtual void pure_virtual_method() = 0; \ - inline void inline_method() {} \ - void volatile_method() volatile {} \ - void const_method() const {} \ - \ - typedef int typedef_int; \ - using using_int = int; \ - \ - void method_one_arg(int x) {} \ - void method_one_arg_default_argument(int x = 5 + 5) {} \ - void method_decayed_type(int x[5]) {} \ - \ - int constant_arr[5]; \ - \ - ACCESS: \ - }; +#define DECLS -#if defined(FIRST) -CREATE_ALL_DECL_STRUCT(S, public) -#elif defined(SECOND) -CREATE_ALL_DECL_STRUCT(S, public) +#if defined(FIRST) || defined(SECOND) +struct Base1 {}; +struct Base2 {}; +struct Base3 {}; +struct Base4 {}; +struct Base5 {}; +#endif + +#if defined(FIRST) || defined(SECOND) +struct Valid1 : + Base1, virtual Base2, protected Base3, public Base4, private Base5 { + + DECLS +}; #else -S *s; +Valid1 v1; #endif -#if defined(FIRST) -CREATE_ALL_DECL_STRUCT(T, private) -#elif defined(SECOND) -CREATE_ALL_DECL_STRUCT(T, public) +#if defined(FIRST) || defined(SECOND) +struct Invalid1 : + Base1, virtual Base2, protected Base3, public Base4, private Base5 { + + DECLS + ACCESS +}; #else -T *t; -// expected-error@second.h:* {{'AllDecls::T' has different definitions in different modules; first difference is definition in module 'SecondModule' found public access specifier}} -// expected-note@first.h:* {{but in 'FirstModule' found private access specifier}} +Invalid1 i1; +// expected-error@second.h:* {{'BaseClass::Invalid1' has different definitions in different modules; first difference is definition in module 'SecondModule' found private access specifier}} +// expected-note@first.h:* {{but in 'FirstModule' found public access specifier}} #endif +#undef DECLS +} // namespace BaseClass + + +// Collection of interesting cases below. + +// Naive parsing of AST can lead to cycles in processing. Ensure +// self-references don't trigger an endless cycles of AST node processing. +namespace SelfReference { +#if defined(FIRST) +template <template <int> class T> class Wrapper {}; + +template <int N> class S { + S(Wrapper<::SelfReference::S> &Ref) {} +}; + +struct Xx { + struct Yy { + }; +}; + +Xx::Xx::Xx::Yy yy; + +namespace NNS { +template <typename> struct Foo; +template <template <class> class T = NNS::Foo> +struct NestedNamespaceSpecifier {}; } +#endif +} // namespace SelfReference namespace FriendFunction { #if defined(FIRST) @@ -1825,7 +2381,7 @@ T t; // expected-note@second.h:* {{but in 'SecondModule' found public access specifier}} #endif -} // namespace ImplicitDelc +} // namespace ImplicitDecl namespace TemplatedClass { #if defined(FIRST) @@ -2051,7 +2607,7 @@ void run() { S<int>::R().foo(); } #endif -} +} // namespace LateParsedDefaultArgument namespace LateParsedDefaultArgument { #if defined(FIRST) @@ -2065,7 +2621,7 @@ Bravo<char> golf; #elif defined(SECOND) #else #endif -} +} // LateParsedDefaultArgument namespace DifferentParameterNameInTemplate { #if defined(FIRST) || defined(SECOND) @@ -2111,7 +2667,7 @@ struct BetaHelper { #else Alpha::Alpha() {} #endif -} +} // DifferentParameterNameInTemplate namespace ParameterTest { #if defined(FIRST) @@ -2138,7 +2694,7 @@ G* S<G>::Foo(const G* asdf, int*) {} #else S<X> s; #endif -} +} // ParameterTest namespace MultipleTypedefs { #if defined(FIRST) @@ -2188,12 +2744,59 @@ struct S3 { #else S3 s3; #endif +} // MultipleTypedefs + +namespace DefaultArguments { +#if defined(FIRST) +template <typename T> +struct S { + struct R { + void foo(T x = 0) {} + }; +}; +#elif defined(SECOND) +template <typename T> +struct S { + struct R { + void foo(T x = 1) {} + }; +}; +#else +void run() { + S<int>::R().foo(); } +// expected-error@second.h:* {{'DefaultArguments::S::R' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'foo' with 1st parameter with a default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'foo' with 1st parameter with a different default argument}} +#endif + +#if defined(FIRST) +template <typename alpha> struct Bravo { + void charlie(bool delta = false) {} +}; +typedef Bravo<char> echo; +echo foxtrot; +#elif defined(SECOND) +template <typename alpha> struct Bravo { + void charlie(bool delta = (false)) {} +}; +typedef Bravo<char> echo; +echo foxtrot; +#else +Bravo<char> golf; +// expected-error@second.h:* {{'DefaultArguments::Bravo' has different definitions in different modules; first difference is definition in module 'SecondModule' found method 'charlie' with 1st parameter with a default argument}} +// expected-note@first.h:* {{but in 'FirstModule' found method 'charlie' with 1st parameter with a different default argument}} +#endif +} // namespace DefaultArguments // Keep macros contained to one file. #ifdef FIRST #undef FIRST #endif + #ifdef SECOND #undef SECOND #endif + +#ifdef ACCESS +#undef ACCESS +#endif diff --git a/test/OpenMP/critical_codegen.cpp b/test/OpenMP/critical_codegen.cpp index 964c91f45a..f4e449a223 100644 --- a/test/OpenMP/critical_codegen.cpp +++ b/test/OpenMP/critical_codegen.cpp @@ -78,7 +78,7 @@ void critical_ref(S &s) { void parallel_critical() { #pragma omp parallel #pragma omp critical - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call void @__kmpc_critical({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] // TERM_DEBUG: invoke void {{.*}}foo{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], diff --git a/test/OpenMP/for_codegen.cpp b/test/OpenMP/for_codegen.cpp index 0d5972f7d0..9ea167fb1f 100644 --- a/test/OpenMP/for_codegen.cpp +++ b/test/OpenMP/for_codegen.cpp @@ -355,7 +355,7 @@ int foo() {return 0;}; void parallel_for(float *a) { #pragma omp parallel #pragma omp for schedule(static, 5) - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call void @__kmpc_for_static_init_4u({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] // TERM_DEBUG: invoke i32 {{.*}}foo{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], diff --git a/test/OpenMP/for_reduction_codegen.cpp b/test/OpenMP/for_reduction_codegen.cpp index ac4c6ffcac..3f014a4530 100644 --- a/test/OpenMP/for_reduction_codegen.cpp +++ b/test/OpenMP/for_reduction_codegen.cpp @@ -207,6 +207,11 @@ int main() { #pragma omp for reduction(+:arr) reduction(&:arrs) for (int i = 0; i < 10; ++i) ++arr[1][i]; + // arr is a VLA, but the array section has constant length so we can generate a constant sized array! +#pragma omp parallel +#pragma omp for reduction(+:arr[1][0:2]) + for (int i = 0; i < 10; ++i) + ++arr[1][i]; #pragma omp parallel #pragma omp for reduction(& : var2[0 : 5][1 : 6]) for (int i = 0; i < 10; ++i) @@ -254,15 +259,16 @@ int main() { // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 6, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, float*, [[S_FLOAT_TY]]*, [[S_FLOAT_TY]]*, float*, [2 x i32]*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 5, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [2 x i32]*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK1:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 4, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*, [10 x [4 x [[S_FLOAT_TY]]]]*)* [[MAIN_MICROTASK2:@.+]] to void -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK3:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 3, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, i64, i64, i32*)* [[MAIN_MICROTASK3:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK4:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK5:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK6:@.+]] to void -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [5 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK7:@.+]] to void -// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK8:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [[S_FLOAT_TY]]***)* [[MAIN_MICROTASK7:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [5 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK8:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK9:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK10:@.+]] to void // CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK11:@.+]] to void +// CHECK: call void (%{{.+}}*, i{{[0-9]+}}, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)*, ...) @__kmpc_fork_call(%{{.+}}* @{{.+}}, i{{[0-9]+}} 1, void (i{{[0-9]+}}*, i{{[0-9]+}}*, ...)* bitcast (void (i{{[0-9]+}}*, i{{[0-9]+}}*, [4 x [[S_FLOAT_TY]]]*)* [[MAIN_MICROTASK12:@.+]] to void // CHECK: = call {{.*}}i{{.+}} [[TMAIN_INT_42:@.+]]() // CHECK: call {{.*}} [[S_FLOAT_TY_DESTR:@.+]]([[S_FLOAT_TY]]* // CHECK: ret @@ -915,7 +921,35 @@ int main() { // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK3]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, i32* {{.*}} %{{.+}}) + +// CHECK: [[VLA1_ORIG_ADDR:%.+]] = alloca i64 +// CHECK: [[VLA2_ORIG_ADDR:%.+]] = alloca i64 +// CHECK: [[ARR_ORIG_ADDR:%.+]] = alloca i32*, +// CHECK: [[ARR_PRIV:%.+]] = alloca [1 x [2 x i32]], + +// Reduction list for runtime. +// CHECK: [[RED_LIST:%.+]] = alloca [1 x i8*], + +// CHECK: store i{{[0-9]+}}* [[GTID_ADDR]], i{{[0-9]+}}** [[GTID_ADDR_ADDR:%.+]], +// CHECK: [[VLA1:%.+]] = load i64, i64* [[VLA1_ORIG_ADDR]] +// CHECK: [[VLA2:%.+]] = load i64, i64* [[VLA2_ORIG_ADDR]] +// CHECK: [[ARR_ORIG:%.+]] = load i32*, i32** [[ARR_ORIG_ADDR]], + +// CHECK: [[LOW_OFFSET:%.+]] = mul nsw i64 1, [[VLA2]] +// CHECK: [[ARRIDX:%.+]] = getelementptr inbounds i32, i32* [[ARR_ORIG]], i64 [[LOW_OFFSET]] +// CHECK: [[LOW:%.+]] = getelementptr inbounds i32, i32* [[ARRIDX]], i64 0 + +// CHECK: [[START:%.+]] = ptrtoint i32* [[ARR_ORIG]] to i64 +// CHECK: [[LOW_BOUND:%.+]] = ptrtoint i32* [[LOW]] to i64 +// CHECK: [[OFFSET_BYTES:%.+]] = sub i64 [[START]], [[LOW_BOUND]] +// CHECK: [[OFFSET:%.+]] = sdiv exact i64 [[OFFSET_BYTES]], ptrtoint (i32* getelementptr (i32, i32* null, i32 1) to i64) +// CHECK: [[PSEUDO_ARR_PRIV:%.+]] = getelementptr [1 x [2 x i32]], [1 x [2 x i32]]* [[ARR_PRIV]], i64 [[OFFSET]] +// CHECK: [[ARR_PRIV:%.+]] = bitcast [1 x [2 x i32]]* [[PSEUDO_ARR_PRIV]] to i32* + +// CHECK: ret void + +// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) // CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***, @@ -943,7 +977,7 @@ int main() { // CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]] // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK4]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) // CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***, // CHECK: [[VAR2_PRIV:%.+]] = alloca [1 x [6 x [[S_FLOAT_TY]]]], @@ -972,7 +1006,7 @@ int main() { // CHECK: store [[S_FLOAT_TY]]* [[VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]] // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK5]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) // CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***, // CHECK: [[VAR2_PRIV:%.+]] = alloca [1 x [6 x [[S_FLOAT_TY]]]], @@ -1001,7 +1035,7 @@ int main() { // CHECK: store [[S_FLOAT_TY]]* [[VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]] // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK6]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK7]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [[S_FLOAT_TY]]*** dereferenceable(8) %{{.+}}) // CHECK: [[VAR2_ORIG_ADDR:%.+]] = alloca [[S_FLOAT_TY]]***, // CHECK: [[VAR2_PRIV:%.+]] = alloca [[S_FLOAT_TY]], @@ -1029,7 +1063,7 @@ int main() { // CHECK: store [[S_FLOAT_TY]]* [[PSEUDO_VAR2_PRIV]], [[S_FLOAT_TY]]** [[REF]] // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK7]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [5 x [[S_FLOAT_TY]]]* dereferenceable(20) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK8]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [5 x [[S_FLOAT_TY]]]* dereferenceable(20) %{{.+}}) // CHECK: [[VVAR2_ORIG_ADDR:%.+]] = alloca [5 x [[S_FLOAT_TY]]]*, // CHECK: [[VVAR2_PRIV:%.+]] = alloca [5 x [[S_FLOAT_TY]]], @@ -1049,7 +1083,7 @@ int main() { // CHECK: [[PSEUDO_VVAR2_PRIV:%.+]] = getelementptr [5 x [[S_FLOAT_TY]]], [5 x [[S_FLOAT_TY]]]* [[VVAR2_PRIV]], i64 [[OFFSET]] // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK8]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK9]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) // CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*, // CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], @@ -1079,7 +1113,7 @@ int main() { // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK9]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK10]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) // CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*, // CHECK: [[VAR3_PRIV:%.+]] = alloca [2 x [[S_FLOAT_TY]]], @@ -1109,7 +1143,7 @@ int main() { // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK10]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK11]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) // CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*, @@ -1140,7 +1174,7 @@ int main() { // CHECK: ret void -// CHECK: define internal void [[MAIN_MICROTASK11]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) +// CHECK: define internal void [[MAIN_MICROTASK12]](i{{[0-9]+}}* noalias [[GTID_ADDR:%.+]], i{{[0-9]+}}* noalias %{{.+}}, [4 x [[S_FLOAT_TY]]]* dereferenceable(16) %{{.+}}) // CHECK: [[VAR3_ORIG_ADDR:%.+]] = alloca [4 x [[S_FLOAT_TY]]]*, // CHECK: [[VAR3_PRIV:%.+]] = alloca [4 x [[S_FLOAT_TY]]], diff --git a/test/OpenMP/for_simd_codegen.cpp b/test/OpenMP/for_simd_codegen.cpp index e33bfe4a57..89f779db33 100644 --- a/test/OpenMP/for_simd_codegen.cpp +++ b/test/OpenMP/for_simd_codegen.cpp @@ -673,7 +673,7 @@ int bar() {return 0;}; void parallel_simd(float *a) { #pragma omp parallel #pragma omp for simd - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: invoke i32 {{.*}}bar{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], // TERM_DEBUG-NOT: __kmpc_global_thread_num diff --git a/test/OpenMP/master_codegen.cpp b/test/OpenMP/master_codegen.cpp index d61b476756..ad92a13e14 100644 --- a/test/OpenMP/master_codegen.cpp +++ b/test/OpenMP/master_codegen.cpp @@ -49,7 +49,7 @@ int main() { void parallel_master() { #pragma omp parallel #pragma omp master - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call i32 @__kmpc_master({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] // TERM_DEBUG: invoke void {{.*}}foo{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], diff --git a/test/OpenMP/openmp_win_codegen.cpp b/test/OpenMP/openmp_win_codegen.cpp new file mode 100644 index 0000000000..45b2c185cb --- /dev/null +++ b/test/OpenMP/openmp_win_codegen.cpp @@ -0,0 +1,61 @@ +// RUN: %clang_cc1 -verify -fopenmp -x c++ -triple x86_64-pc-windows-msvc18.0.0 -std=c++11 -fms-compatibility-version=18 -fms-extensions -emit-llvm %s -fexceptions -fcxx-exceptions -o - -O1 | FileCheck %s +// REQUIRES: x86-registered-target +// expected-no-diagnostics + +void foo(); +void bar(); + +struct Test { + static void main() { + int failed = 0; + int j = 2; + +#pragma omp parallel + { + int local_j = 3; +#pragma omp single copyprivate(local_j) + { + local_j = 4; + } + + // Assure reports a data race, but value written to "j" + // should always be the same. + j = local_j; + } + + } +}; + +// CHECK-LABEL: @main +int main() { + // CHECK: call void @{{.+}}main + Test::main(); + // CHECK: call void (%ident_t*, i32, void (i32*, i32*, ...)*, ...) @__kmpc_fork_call(%ident_t* {{.*}}@0, i32 0, void (i32*, i32*, ...)* bitcast (void (i32*, i32*)* [[OUTLINED:@.+]] to void (i32*, i32*, ...)*)) +#pragma omp parallel + { + try { + foo(); + } catch (int t) { +#pragma omp critical + { + bar(); + }; + } + }; + // CHECK: ret i32 0 + return 0; +} + +// CHECK: define internal void [[OUTLINED]]( +// CHECK: [[GID:%.+]] = {{.*}}call i32 @__kmpc_global_thread_num(%ident_t* {{.*}}@0) +// CHECK: invoke void @{{.+}}foo +// CHECK: catchswitch within +// CHECK: catchpad within +// CHECK: call void @__kmpc_critical(%ident_t* {{.*}}@0, i32 [[GID]], +// CHECK: invoke void @{{.+}}bar +// CHECK: call void @__kmpc_end_critical(%ident_t* {{.*}}@0, i32 [[GID]], +// CHECK: catchret from +// CHECK: cleanuppad within +// CHECK: call void @__kmpc_end_critical(%ident_t* {{.*}}@0, i32 [[GID]], +// CHECK: cleanupret from + diff --git a/test/OpenMP/parallel_for_codegen.cpp b/test/OpenMP/parallel_for_codegen.cpp index bc04532bd1..1773619bce 100644 --- a/test/OpenMP/parallel_for_codegen.cpp +++ b/test/OpenMP/parallel_for_codegen.cpp @@ -348,7 +348,7 @@ int foo() {return 0;}; void parallel_for(float *a, int n) { float arr[n]; #pragma omp parallel for schedule(static, 5) private(arr) - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call void @__kmpc_for_static_init_4u({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] // TERM_DEBUG: invoke i32 {{.*}}foo{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], diff --git a/test/OpenMP/parallel_for_simd_codegen.cpp b/test/OpenMP/parallel_for_simd_codegen.cpp index 9112635855..369ea17844 100644 --- a/test/OpenMP/parallel_for_simd_codegen.cpp +++ b/test/OpenMP/parallel_for_simd_codegen.cpp @@ -668,7 +668,7 @@ int bar() {return 0;}; // TERM_DEBUG-LABEL: parallel_simd void parallel_simd(float *a) { #pragma omp parallel for simd - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: invoke i32 {{.*}}bar{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], // TERM_DEBUG-NOT: __kmpc_global_thread_num diff --git a/test/OpenMP/parallel_sections_codegen.cpp b/test/OpenMP/parallel_sections_codegen.cpp index afbc6e4d5e..a261473036 100644 --- a/test/OpenMP/parallel_sections_codegen.cpp +++ b/test/OpenMP/parallel_sections_codegen.cpp @@ -74,7 +74,7 @@ int main() { // CHECK-LABEL: tmain // CHECK: call void {{.*}} @__kmpc_fork_call( -// CHECK: __kmpc_global_thread_num +// CHECK-NOT: __kmpc_global_thread_num // CHECK: call void @__kmpc_for_static_init_4( // CHECK: invoke void @{{.*}}foo{{.*}}() // CHECK-NEXT: unwind label %[[TERM_LPAD:.+]] diff --git a/test/OpenMP/sections_codegen.cpp b/test/OpenMP/sections_codegen.cpp index 0ed87e4035..94ded37db9 100644 --- a/test/OpenMP/sections_codegen.cpp +++ b/test/OpenMP/sections_codegen.cpp @@ -84,7 +84,7 @@ int main() { // CHECK-LABEL: tmain // CHECK: call void {{.*}} @__kmpc_fork_call( -// CHECK: __kmpc_global_thread_num +// CHECK-NOT: __kmpc_global_thread_num // CHECK: call void @__kmpc_for_static_init_4( // CHECK: invoke void @{{.*}}foo{{.*}}() // CHECK-NEXT: unwind label %[[TERM_LPAD:.+]] diff --git a/test/OpenMP/single_codegen.cpp b/test/OpenMP/single_codegen.cpp index 4feb3bdac3..892e160324 100644 --- a/test/OpenMP/single_codegen.cpp +++ b/test/OpenMP/single_codegen.cpp @@ -190,7 +190,7 @@ int main() { void parallel_single() { #pragma omp parallel #pragma omp single - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call i32 @__kmpc_single({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] // TERM_DEBUG: invoke void {{.*}}foo{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], diff --git a/test/OpenMP/taskgroup_codegen.cpp b/test/OpenMP/taskgroup_codegen.cpp index 3dd41a1f82..4b7d89e703 100644 --- a/test/OpenMP/taskgroup_codegen.cpp +++ b/test/OpenMP/taskgroup_codegen.cpp @@ -40,7 +40,7 @@ int main() { void parallel_taskgroup() { #pragma omp parallel #pragma omp taskgroup - // TERM_DEBUG: __kmpc_global_thread_num + // TERM_DEBUG-NOT: __kmpc_global_thread_num // TERM_DEBUG: call void @__kmpc_taskgroup({{.+}}), !dbg [[DBG_LOC_START:![0-9]+]] // TERM_DEBUG: invoke void {{.*}}foo{{.*}}() // TERM_DEBUG: unwind label %[[TERM_LPAD:.+]], diff --git a/test/Parser/objcxx11-invalid-lambda.cpp b/test/Parser/objcxx11-invalid-lambda.cpp new file mode 100644 index 0000000000..74c5636b6a --- /dev/null +++ b/test/Parser/objcxx11-invalid-lambda.cpp @@ -0,0 +1,10 @@ +// RUN: %clang_cc1 -fsyntax-only -verify -x objective-c++ -std=c++11 %s + +void foo() { // expected-note {{to match this '{'}} + int bar; + auto baz = [ + bar( // expected-note {{to match this '('}} expected-note {{to match this '('}} + foo_undeclared() // expected-error{{use of undeclared identifier 'foo_undeclared'}} expected-error{{use of undeclared identifier 'foo_undeclared'}} + /* ) */ + ] () { }; // expected-error{{expected ')'}} +} // expected-error{{expected ')'}} expected-error{{expected ';' at end of declaration}} expected-error{{expected '}'}} diff --git a/test/Refactor/Extract/ExtractExprIntoFunction.cpp b/test/Refactor/Extract/ExtractExprIntoFunction.cpp index be610fc303..b4f0b59543 100644 --- a/test/Refactor/Extract/ExtractExprIntoFunction.cpp +++ b/test/Refactor/Extract/ExtractExprIntoFunction.cpp @@ -20,10 +20,10 @@ void simpleExtractStmtNoCaptures() { // CHECK: 1 'astatement' results: // CHECK: static void extracted() { // CHECK-NEXT: int a = 1; -// CHECK-NEXT: int b = 2;;{{$}} +// CHECK-NEXT: int b = 2;{{$}} // CHECK-NEXT: }{{[[:space:]].*}} // CHECK-NEXT: void simpleExtractStmtNoCaptures() { -// CHECK-NEXT: /*range astatement=->+1:13*/extracted(){{$}} +// CHECK-NEXT: /*range astatement=->+1:13*/extracted();{{$}} // CHECK-NEXT: } diff --git a/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp b/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp new file mode 100644 index 0000000000..5caf9d4526 --- /dev/null +++ b/test/Refactor/Extract/ExtractionSemicolonPolicy.cpp @@ -0,0 +1,192 @@ +// RUN: clang-refactor extract -selection=test:%s %s -- -std=c++11 -fcxx-exceptions | grep -v CHECK | FileCheck %s + +struct Rectangle { int width, height; }; + +void extractStatement(const Rectangle &r) { + /*range adeclstmt=->+0:59*/int area = r.width * r.height; +} +// CHECK: 1 'adeclstmt' results: +// CHECK: static void extracted() { +// CHECK-NEXT: int area = r.width * r.height;{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatement(const Rectangle &r) { +// CHECK-NEXT: /*range adeclstmt=->+0:59*/extracted();{{$}} +// CHECK-NEXT: } + +void extractStatementNoSemiIf(const Rectangle &r) { + /*range bextractif=->+2:4*/if (r.width) { + int x = r.height; + } +} +// CHECK: 1 'bextractif' results: +// CHECK: static void extracted() { +// CHECK-NEXT: if (r.width) { +// CHECK-NEXT: int x = r.height; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatementNoSemiIf(const Rectangle &r) { +// CHECK-NEXT: /*range bextractif=->+2:4*/extracted();{{$}} +// CHECK-NEXT: } + +void extractStatementDontExtraneousSemi(const Rectangle &r) { + /*range cextractif=->+2:4*/if (r.width) { + int x = r.height; + } ; +} //^ This semicolon shouldn't be extracted. +// CHECK: 1 'cextractif' results: +// CHECK: static void extracted() { +// CHECK-NEXT: if (r.width) { +// CHECK-NEXT: int x = r.height; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatementDontExtraneousSemi(const Rectangle &r) { +// CHECK-NEXT: extracted(); ;{{$}} +// CHECK-NEXT: } + +void extractStatementNotSemiSwitch() { + /*range dextract=->+5:4*/switch (2) { + case 1: + break; + case 2: + break; + } +} +// CHECK: 1 'dextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: switch (2) { +// CHECK-NEXT: case 1: +// CHECK-NEXT: break; +// CHECK-NEXT: case 2: +// CHECK-NEXT: break; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatementNotSemiSwitch() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: } + +void extractStatementNotSemiWhile() { + /*range eextract=->+2:4*/while (true) { + int x = 0; + } +} +// CHECK: 1 'eextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: while (true) { +// CHECK-NEXT: int x = 0; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatementNotSemiWhile() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: } + +void extractStatementNotSemiFor() { + /*range fextract=->+1:4*/for (int i = 0; i < 10; ++i) { + } +} +// CHECK: 1 'fextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: for (int i = 0; i < 10; ++i) { +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatementNotSemiFor() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: } + +struct XS { + int *begin() { return 0; } + int *end() { return 0; } +}; + +void extractStatementNotSemiRangedFor(XS xs) { + /*range gextract=->+1:4*/for (int i : xs) { + } +} +// CHECK: 1 'gextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: for (int i : xs) { +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatementNotSemiRangedFor(XS xs) { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: } + +void extractStatementNotSemiRangedTryCatch() { + /*range hextract=->+3:4*/try { int x = 0; } + catch (const int &i) { + int y = i; + } +} +// CHECK: 1 'hextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: try { int x = 0; } +// CHECK-NEXT: catch (const int &i) { +// CHECK-NEXT: int y = i; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractStatementNotSemiRangedTryCatch() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: } + +void extractCantFindSemicolon() { + /*range iextract=->+1:17*/do { + } while (true) + // Add a semicolon in both the extracted and original function as we don't + // want to extract the semicolon below. + ; +} +// CHECK: 1 'iextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: do { +// CHECK-NEXT: } while (true);{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractCantFindSemicolon() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: // +// CHECK-NEXT: // +// CHECK-NEXT: ; +// CHECK-NEXT: } + +void extractFindSemicolon() { + /*range jextract=->+1:17*/do { + } while (true) /*grab*/ ; +} +// CHECK: 1 'jextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: do { +// CHECK-NEXT: } while (true) /*grab*/ ;{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void extractFindSemicolon() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: } + +void call(); + +void careForNonCompoundSemicolons1() { + /*range kextract=->+1:11*/if (true) + call(); +} +// CHECK: 1 'kextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: if (true) +// CHECK-NEXT: call();{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void careForNonCompoundSemicolons1() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: } + +void careForNonCompoundSemicolons2() { + /*range lextract=->+3:1*/for (int i = 0; i < 10; ++i) + while (i != 0) + ; + // end right here111! +} +// CHECK: 1 'lextract' results: +// CHECK: static void extracted() { +// CHECK-NEXT: for (int i = 0; i < 10; ++i) +// CHECK-NEXT: while (i != 0) +// CHECK-NEXT: ;{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} +// CHECK-NEXT: void careForNonCompoundSemicolons2() { +// CHECK-NEXT: extracted();{{$}} +// CHECK-NEXT: // +// CHECK-NEXT: } diff --git a/test/Refactor/Extract/ExtractionSemicolonPolicy.m b/test/Refactor/Extract/ExtractionSemicolonPolicy.m new file mode 100644 index 0000000000..10e6a164f2 --- /dev/null +++ b/test/Refactor/Extract/ExtractionSemicolonPolicy.m @@ -0,0 +1,56 @@ +// RUN: clang-refactor extract -selection=test:%s %s -- 2>&1 | grep -v CHECK | FileCheck %s + +@interface NSArray ++ (id)arrayWithObjects:(const id [])objects count:(unsigned long)cnt; +@end + +void extractStatementNoSemiObjCFor(NSArray *array) { + /*range astmt=->+2:4*/for (id i in array) { + int x = 0; + } +} +// CHECK: 1 'astmt' results: +// CHECK: static void extracted() { +// CHECK-NEXT: for (id i in array) { +// CHECK-NEXT: int x = 0; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} + +void extractStatementNoSemiSync() { + id lock; + /*range bstmt=->+2:4*/@synchronized(lock) { + int x = 0; + } +} +// CHECK: 1 'bstmt' results: +// CHECK: static void extracted() { +// CHECK-NEXT: @synchronized(lock) { +// CHECK-NEXT: int x = 0; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} + +void extractStatementNoSemiAutorel() { + /*range cstmt=->+2:4*/@autoreleasepool { + int x = 0; + } +} +// CHECK: 1 'cstmt' results: +// CHECK: static void extracted() { +// CHECK-NEXT: @autoreleasepool { +// CHECK-NEXT: int x = 0; +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} + +void extractStatementNoSemiTryFinalllllly() { + /*range dstmt=->+3:4*/@try { + int x = 0; + } @finally { + } +} +// CHECK: 1 'dstmt' results: +// CHECK: static void extracted() { +// CHECK-NEXT: @try { +// CHECK-NEXT: int x = 0; +// CHECK-NEXT: } @finally { +// CHECK-NEXT: }{{$}} +// CHECK-NEXT: }{{[[:space:]].*}} diff --git a/test/Refactor/LocalRename/BuiltinOffsetof.cpp b/test/Refactor/LocalRename/BuiltinOffsetof.cpp new file mode 100644 index 0000000000..3119eeb7e5 --- /dev/null +++ b/test/Refactor/LocalRename/BuiltinOffsetof.cpp @@ -0,0 +1,32 @@ +// RUN: clang-refactor local-rename -selection=test:%s -new-name=bar %s -- | grep -v CHECK | FileCheck %s + +struct Struct { + int /*range f=*/field; +}; + +struct Struct2 { + Struct /*range array=*/array[4][2]; +}; + +void foo() { + (void)__builtin_offsetof(Struct, /*range f=*/field); + (void)__builtin_offsetof(Struct2, /*range array=*/array[1][0]./*range f=*/field); +} + +#define OFFSET_OF_(X, Y) __builtin_offsetof(X, Y) + +class SubclassOffsetof : public Struct { + void foo() { + (void)OFFSET_OF_(SubclassOffsetof, field); + } +}; + +// CHECK: 2 'array' results: +// CHECK: Struct /*range array=*/bar[4][2]; +// CHECK: __builtin_offsetof(Struct2, /*range array=*/bar[1][0]./*range f=*/field); + +// CHECK: 3 'f' results: +// CHECK: int /*range f=*/bar; +// CHECK: __builtin_offsetof(Struct, /*range f=*/bar); +// CHECK-NEXT: __builtin_offsetof(Struct2, /*range array=*/array[1][0]./*range f=*/bar); +// CHECK: OFFSET_OF_(SubclassOffsetof, bar); diff --git a/test/Refactor/LocalRename/QualifiedRename.cpp b/test/Refactor/LocalRename/QualifiedRename.cpp new file mode 100644 index 0000000000..d9eb138e5c --- /dev/null +++ b/test/Refactor/LocalRename/QualifiedRename.cpp @@ -0,0 +1,24 @@ +// RUN: clang-refactor local-rename -old-qualified-name="foo::A" -new-qualified-name="bar::B" %s -- -std=c++11 2>&1 | grep -v CHECK | FileCheck %s + +namespace foo { +class A {}; +} +// CHECK: namespace foo { +// CHECK-NEXT: class B {}; +// CHECK-NEXT: } + +namespace bar { +void f(foo::A* a) { + foo::A b; +} +// CHECK: void f(B* a) { +// CHECK-NEXT: B b; +// CHECK-NEXT: } +} + +void f(foo::A* a) { + foo::A b; +} +// CHECK: void f(bar::B* a) { +// CHECK-NEXT: bar::B b; +// CHECK-NEXT: } diff --git a/test/Sema/attr-alias.c b/test/Sema/attr-alias.c index 151052f89e..93136706a7 100644 --- a/test/Sema/attr-alias.c +++ b/test/Sema/attr-alias.c @@ -2,7 +2,4 @@ void g() {} -// It is important that the following string be in the error message. The gcc -// testsuite looks for it to decide if a target supports aliases. - -void f() __attribute__((alias("g"))); //expected-error {{only weak aliases are supported}} +void f() __attribute__((alias("g"))); //expected-error {{aliases are not supported on darwin}} diff --git a/test/Sema/enum-sign-conversion.c b/test/Sema/enum-sign-conversion.c new file mode 100644 index 0000000000..518fc670d3 --- /dev/null +++ b/test/Sema/enum-sign-conversion.c @@ -0,0 +1,13 @@ +// RUN: %clang_cc1 -triple=x86_64-pc-linux-gnu -fsyntax-only -verify -DUNSIGNED -Wsign-conversion %s +// RUN: %clang_cc1 -triple=x86_64-pc-win32 -fsyntax-only -verify -Wsign-conversion %s + +// PR35200 +enum X { A,B,C}; +int f(enum X x) { +#ifdef UNSIGNED + return x; // expected-warning {{implicit conversion changes signedness: 'enum X' to 'int'}} +#else + // expected-no-diagnostics + return x; +#endif +} diff --git a/test/SemaObjCXX/block-variable-move.mm b/test/SemaObjCXX/block-variable-move.mm new file mode 100644 index 0000000000..e26dffc5d0 --- /dev/null +++ b/test/SemaObjCXX/block-variable-move.mm @@ -0,0 +1,43 @@ +// RUN: %clang_cc1 -std=c++11 -fsyntax-only -fobjc-arc -verify -fblocks -Wpessimizing-move -Wredundant-move %s + +// definitions for std::move +namespace std { +inline namespace foo { +template <class T> struct remove_reference { typedef T type; }; +template <class T> struct remove_reference<T&> { typedef T type; }; +template <class T> struct remove_reference<T&&> { typedef T type; }; + +template <class T> typename remove_reference<T>::type &&move(T &&t); +} +} + +class MoveOnly { +public: + MoveOnly() { } + MoveOnly(MoveOnly &&) = default; // expected-note 2 {{copy constructor is implicitly deleted}} + MoveOnly &operator=(MoveOnly &&) = default; + ~MoveOnly(); +}; + +void copyInit() { + __block MoveOnly temp; + MoveOnly temp2 = temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}} + MoveOnly temp3 = std::move(temp); // ok +} + +MoveOnly errorOnCopy() { + __block MoveOnly temp; + return temp; // expected-error {{call to implicitly-deleted copy constructor of 'MoveOnly'}} +} + +MoveOnly dontWarnOnMove() { + __block MoveOnly temp; + return std::move(temp); // ok +} + +class MoveOnlySub : public MoveOnly {}; + +MoveOnly dontWarnOnMoveSubclass() { + __block MoveOnlySub temp; + return std::move(temp); // ok +} diff --git a/tools/clang-diff/ClangDiff.cpp b/tools/clang-diff/ClangDiff.cpp index 55cef91170..4e2150aa45 100644 --- a/tools/clang-diff/ClangDiff.cpp +++ b/tools/clang-diff/ClangDiff.cpp @@ -33,9 +33,9 @@ static cl::opt<bool> ASTDumpJson( cl::desc("Print the internal representation of the AST as JSON."), cl::init(false), cl::cat(ClangDiffCategory)); -static cl::opt<bool> - PrintMatches("dump-matches", cl::desc("Print the matched nodes."), - cl::init(false), cl::cat(ClangDiffCategory)); +static cl::opt<bool> PrintMatches("dump-matches", + cl::desc("Print the matched nodes."), + cl::init(false), cl::cat(ClangDiffCategory)); static cl::opt<bool> HtmlDiff("html", cl::desc("Output a side-by-side diff in HTML."), diff --git a/tools/clang-format/ClangFormat.cpp b/tools/clang-format/ClangFormat.cpp index e169b9e585..b7179ffd64 100644 --- a/tools/clang-format/ClangFormat.cpp +++ b/tools/clang-format/ClangFormat.cpp @@ -289,7 +289,7 @@ static bool format(StringRef FileName) { "xml:space='preserve' incomplete_format='" << (Status.FormatComplete ? "false" : "true") << "'"; if (!Status.FormatComplete) - outs() << " line=" << Status.Line; + outs() << " line='" << Status.Line << "'"; outs() << ">\n"; if (Cursor.getNumOccurrences() != 0) outs() << "<cursor>" diff --git a/tools/clang-refactor/ClangRefactor.cpp b/tools/clang-refactor/ClangRefactor.cpp index 523c3a6220..950b80062c 100644 --- a/tools/clang-refactor/ClangRefactor.cpp +++ b/tools/clang-refactor/ClangRefactor.cpp @@ -25,6 +25,7 @@ #include "clang/Tooling/Tooling.h" #include "llvm/Support/CommandLine.h" #include "llvm/Support/FileSystem.h" +#include "llvm/Support/Signals.h" #include "llvm/Support/raw_ostream.h" #include <string> @@ -258,18 +259,17 @@ public: : SubCommand(Action->getCommand(), Action->getDescription()), Action(std::move(Action)), ActionRules(std::move(ActionRules)) { // Check if the selection option is supported. - bool HasSelection = false; for (const auto &Rule : this->ActionRules) { - if ((HasSelection = Rule->hasSelectionRequirement())) + if (Rule->hasSelectionRequirement()) { + Selection = llvm::make_unique<cl::opt<std::string>>( + "selection", + cl::desc( + "The selected source range in which the refactoring should " + "be initiated (<file>:<line>:<column>-<line>:<column> or " + "<file>:<line>:<column>)"), + cl::cat(Category), cl::sub(*this)); break; - } - if (HasSelection) { - Selection = llvm::make_unique<cl::opt<std::string>>( - "selection", - cl::desc("The selected source range in which the refactoring should " - "be initiated (<file>:<line>:<column>-<line>:<column> or " - "<file>:<line>:<column>)"), - cl::cat(Category), cl::sub(*this)); + } } // Create the refactoring options. for (const auto &Rule : this->ActionRules) { @@ -283,10 +283,10 @@ public: const RefactoringActionRules &getActionRules() const { return ActionRules; } - /// Parses the command-line arguments that are specific to this rule. + /// Parses the "-selection" command-line argument. /// /// \returns true on error, false otherwise. - bool parseArguments() { + bool parseSelectionArgument() { if (Selection) { ParsedSelection = SourceSelectionArgument::fromString(*Selection); if (!ParsedSelection) @@ -314,7 +314,7 @@ private: class ClangRefactorConsumer final : public ClangRefactorToolConsumerInterface { public: - ClangRefactorConsumer() {} + ClangRefactorConsumer(AtomicChanges &Changes) : SourceChanges(&Changes) {} void handleError(llvm::Error Err) override { Optional<PartialDiagnosticAt> Diag = DiagnosticError::take(Err); @@ -329,24 +329,23 @@ public: } void handle(AtomicChanges Changes) override { - SourceChanges.insert(SourceChanges.begin(), Changes.begin(), Changes.end()); + SourceChanges->insert(SourceChanges->begin(), Changes.begin(), + Changes.end()); } void handle(SymbolOccurrences Occurrences) override { llvm_unreachable("symbol occurrence results are not handled yet"); } - const AtomicChanges &getSourceChanges() const { return SourceChanges; } - private: - AtomicChanges SourceChanges; + AtomicChanges *SourceChanges; }; class ClangRefactorTool { public: - std::vector<std::unique_ptr<RefactoringActionSubcommand>> SubCommands; - - ClangRefactorTool() { + ClangRefactorTool() + : SelectedSubcommand(nullptr), MatchingRule(nullptr), + Consumer(new ClangRefactorConsumer(Changes)), HasFailed(false) { std::vector<std::unique_ptr<RefactoringAction>> Actions = createRefactoringActions(); @@ -369,59 +368,115 @@ public: } } - using TUCallbackType = llvm::function_ref<void(ASTContext &)>; + // Initializes the selected subcommand and refactoring rule based on the + // command line options. + llvm::Error Init() { + auto Subcommand = getSelectedSubcommand(); + if (!Subcommand) + return Subcommand.takeError(); + auto Rule = getMatchingRule(**Subcommand); + if (!Rule) + return Rule.takeError(); + + SelectedSubcommand = *Subcommand; + MatchingRule = *Rule; + + return llvm::Error::success(); + } - /// Parses the translation units that were given to the subcommand using - /// the 'sources' option and invokes the callback for each parsed - /// translation unit. - bool foreachTranslationUnit(const CompilationDatabase &DB, - ArrayRef<std::string> Sources, - TUCallbackType Callback) { + bool hasFailed() const { return HasFailed; } + + using TUCallbackType = std::function<void(ASTContext &)>; + + // Callback of an AST action. This invokes the matching rule on the given AST. + void callback(ASTContext &AST) { + assert(SelectedSubcommand && MatchingRule && Consumer); + RefactoringRuleContext Context(AST.getSourceManager()); + Context.setASTContext(AST); + + // If the selection option is test specific, we use a test-specific + // consumer. + std::unique_ptr<ClangRefactorToolConsumerInterface> TestConsumer; + bool HasSelection = MatchingRule->hasSelectionRequirement(); + if (HasSelection) + TestConsumer = SelectedSubcommand->getSelection()->createCustomConsumer(); + ClangRefactorToolConsumerInterface *ActiveConsumer = + TestConsumer ? TestConsumer.get() : Consumer.get(); + ActiveConsumer->beginTU(AST); + + auto InvokeRule = [&](RefactoringResultConsumer &Consumer) { + if (opts::Verbose) + logInvocation(*SelectedSubcommand, Context); + MatchingRule->invoke(*ActiveConsumer, Context); + }; + if (HasSelection) { + assert(SelectedSubcommand->getSelection() && + "Missing selection argument?"); + if (opts::Verbose) + SelectedSubcommand->getSelection()->print(llvm::outs()); + if (SelectedSubcommand->getSelection()->forAllRanges( + Context.getSources(), [&](SourceRange R) { + Context.setSelectionRange(R); + InvokeRule(*ActiveConsumer); + })) + HasFailed = true; + ActiveConsumer->endTU(); + return; + } + InvokeRule(*ActiveConsumer); + ActiveConsumer->endTU(); + } + + llvm::Expected<std::unique_ptr<FrontendActionFactory>> + getFrontendActionFactory() { class ToolASTConsumer : public ASTConsumer { public: TUCallbackType Callback; - ToolASTConsumer(TUCallbackType Callback) : Callback(Callback) {} + ToolASTConsumer(TUCallbackType Callback) + : Callback(std::move(Callback)) {} void HandleTranslationUnit(ASTContext &Context) override { Callback(Context); } }; - class ActionWrapper { + class ToolASTAction : public ASTFrontendAction { public: - TUCallbackType Callback; - ActionWrapper(TUCallbackType Callback) : Callback(Callback) {} - - std::unique_ptr<ASTConsumer> newASTConsumer() { - return llvm::make_unique<ToolASTConsumer>(Callback); + explicit ToolASTAction(TUCallbackType Callback) + : Callback(std::move(Callback)) {} + + protected: + std::unique_ptr<clang::ASTConsumer> + CreateASTConsumer(clang::CompilerInstance &compiler, + StringRef /* dummy */) override { + std::unique_ptr<clang::ASTConsumer> Consumer{ + new ToolASTConsumer(Callback)}; + return Consumer; } + + private: + TUCallbackType Callback; }; - ClangTool Tool(DB, Sources); - ActionWrapper ToolAction(Callback); - std::unique_ptr<tooling::FrontendActionFactory> Factory = - tooling::newFrontendActionFactory(&ToolAction); - return Tool.run(Factory.get()); - } + class ToolActionFactory : public FrontendActionFactory { + public: + ToolActionFactory(TUCallbackType Callback) + : Callback(std::move(Callback)) {} - /// Logs an individual refactoring action invocation to STDOUT. - void logInvocation(RefactoringActionSubcommand &Subcommand, - const RefactoringRuleContext &Context) { - if (!opts::Verbose) - return; - llvm::outs() << "invoking action '" << Subcommand.getName() << "':\n"; - if (Context.getSelectionRange().isValid()) { - SourceRange R = Context.getSelectionRange(); - llvm::outs() << " -selection="; - R.getBegin().print(llvm::outs(), Context.getSources()); - llvm::outs() << " -> "; - R.getEnd().print(llvm::outs(), Context.getSources()); - llvm::outs() << "\n"; - } + FrontendAction *create() override { return new ToolASTAction(Callback); } + + private: + TUCallbackType Callback; + }; + + return llvm::make_unique<ToolActionFactory>( + [this](ASTContext &AST) { return callback(AST); }); } - bool applySourceChanges(const AtomicChanges &Replacements) { + // FIXME(ioeric): this seems to only works for changes in a single file at + // this point. + bool applySourceChanges() { std::set<std::string> Files; - for (const auto &Change : Replacements) + for (const auto &Change : Changes) Files.insert(Change.getFilePath()); // FIXME: Add automatic formatting support as well. tooling::ApplyChangesSpec Spec; @@ -435,7 +490,7 @@ public: return true; } auto Result = tooling::applyAtomicChanges(File, (*BufferErr)->getBuffer(), - Replacements, Spec); + Changes, Spec); if (!Result) { llvm::errs() << toString(Result.takeError()); return true; @@ -457,121 +512,127 @@ public: return false; } - bool invokeAction(RefactoringActionSubcommand &Subcommand, - const CompilationDatabase &DB, - ArrayRef<std::string> Sources) { - // Find a set of matching rules. +private: + /// Logs an individual refactoring action invocation to STDOUT. + void logInvocation(RefactoringActionSubcommand &Subcommand, + const RefactoringRuleContext &Context) { + llvm::outs() << "invoking action '" << Subcommand.getName() << "':\n"; + if (Context.getSelectionRange().isValid()) { + SourceRange R = Context.getSelectionRange(); + llvm::outs() << " -selection="; + R.getBegin().print(llvm::outs(), Context.getSources()); + llvm::outs() << " -> "; + R.getEnd().print(llvm::outs(), Context.getSources()); + llvm::outs() << "\n"; + } + } + + llvm::Expected<RefactoringActionRule *> + getMatchingRule(RefactoringActionSubcommand &Subcommand) { SmallVector<RefactoringActionRule *, 4> MatchingRules; llvm::StringSet<> MissingOptions; - bool HasSelection = false; for (const auto &Rule : Subcommand.getActionRules()) { - bool SelectionMatches = true; - if (Rule->hasSelectionRequirement()) { - HasSelection = true; - if (!Subcommand.getSelection()) { - MissingOptions.insert("selection"); - SelectionMatches = false; - } - } CommandLineRefactoringOptionVisitor Visitor(Subcommand.getOptions()); Rule->visitRefactoringOptions(Visitor); - if (SelectionMatches && Visitor.getMissingRequiredOptions().empty()) { - MatchingRules.push_back(Rule.get()); - continue; + if (Visitor.getMissingRequiredOptions().empty()) { + if (!Rule->hasSelectionRequirement()) { + MatchingRules.push_back(Rule.get()); + } else { + Subcommand.parseSelectionArgument(); + if (Subcommand.getSelection()) { + MatchingRules.push_back(Rule.get()); + } else { + MissingOptions.insert("selection"); + } + } } for (const RefactoringOption *Opt : Visitor.getMissingRequiredOptions()) MissingOptions.insert(Opt->getName()); } if (MatchingRules.empty()) { - llvm::errs() << "error: '" << Subcommand.getName() - << "' can't be invoked with the given arguments:\n"; + std::string Error; + llvm::raw_string_ostream OS(Error); + OS << "ERROR: '" << Subcommand.getName() + << "' can't be invoked with the given arguments:\n"; for (const auto &Opt : MissingOptions) - llvm::errs() << " missing '-" << Opt.getKey() << "' option\n"; - return true; + OS << " missing '-" << Opt.getKey() << "' option\n"; + OS.flush(); + return llvm::make_error<llvm::StringError>( + Error, llvm::inconvertibleErrorCode()); } - - ClangRefactorConsumer Consumer; - bool HasFailed = false; - if (foreachTranslationUnit(DB, Sources, [&](ASTContext &AST) { - RefactoringRuleContext Context(AST.getSourceManager()); - Context.setASTContext(AST); - - auto InvokeRule = [&](RefactoringResultConsumer &Consumer) { - logInvocation(Subcommand, Context); - for (RefactoringActionRule *Rule : MatchingRules) { - if (!Rule->hasSelectionRequirement()) - continue; - Rule->invoke(Consumer, Context); - return; - } - // FIXME (Alex L): If more than one initiation succeeded, then the - // rules are ambiguous. - llvm_unreachable( - "The action must have at least one selection rule"); - }; - - std::unique_ptr<ClangRefactorToolConsumerInterface> CustomConsumer; - if (HasSelection) - CustomConsumer = Subcommand.getSelection()->createCustomConsumer(); - ClangRefactorToolConsumerInterface &ActiveConsumer = - CustomConsumer ? *CustomConsumer : Consumer; - ActiveConsumer.beginTU(AST); - if (HasSelection) { - assert(Subcommand.getSelection() && "Missing selection argument?"); - if (opts::Verbose) - Subcommand.getSelection()->print(llvm::outs()); - if (Subcommand.getSelection()->forAllRanges( - Context.getSources(), [&](SourceRange R) { - Context.setSelectionRange(R); - InvokeRule(ActiveConsumer); - })) - HasFailed = true; - ActiveConsumer.endTU(); - return; - } - // FIXME (Alex L): Implement non-selection based invocation path. - ActiveConsumer.endTU(); - })) - return true; - return HasFailed || applySourceChanges(Consumer.getSourceChanges()); + if (MatchingRules.size() != 1) { + return llvm::make_error<llvm::StringError>( + llvm::Twine("ERROR: more than one matching rule of action") + + Subcommand.getName() + "was found with given options.", + llvm::inconvertibleErrorCode()); + } + return MatchingRules.front(); } + // Figure out which action is specified by the user. The user must specify the + // action using a command-line subcommand, e.g. the invocation `clang-refactor + // local-rename` corresponds to the `LocalRename` refactoring action. All + // subcommands must have a unique names. This allows us to figure out which + // refactoring action should be invoked by looking at the first subcommand + // that's enabled by LLVM's command-line parser. + llvm::Expected<RefactoringActionSubcommand *> getSelectedSubcommand() { + auto It = llvm::find_if( + SubCommands, + [](const std::unique_ptr<RefactoringActionSubcommand> &SubCommand) { + return !!(*SubCommand); + }); + if (It == SubCommands.end()) { + std::string Error; + llvm::raw_string_ostream OS(Error); + OS << "error: no refactoring action given\n"; + OS << "note: the following actions are supported:\n"; + for (const auto &Subcommand : SubCommands) + OS.indent(2) << Subcommand->getName() << "\n"; + OS.flush(); + return llvm::make_error<llvm::StringError>( + Error, llvm::inconvertibleErrorCode()); + } + RefactoringActionSubcommand *Subcommand = &(**It); + return Subcommand; + } + + std::vector<std::unique_ptr<RefactoringActionSubcommand>> SubCommands; + RefactoringActionSubcommand *SelectedSubcommand; + RefactoringActionRule *MatchingRule; + std::unique_ptr<ClangRefactorToolConsumerInterface> Consumer; + AtomicChanges Changes; + bool HasFailed; }; } // end anonymous namespace int main(int argc, const char **argv) { - ClangRefactorTool Tool; + llvm::sys::PrintStackTraceOnErrorSignal(argv[0]); + + ClangRefactorTool RefactorTool; CommonOptionsParser Options( argc, argv, cl::GeneralCategory, cl::ZeroOrMore, "Clang-based refactoring tool for C, C++ and Objective-C"); - // Figure out which action is specified by the user. The user must specify - // the action using a command-line subcommand, e.g. the invocation - // `clang-refactor local-rename` corresponds to the `LocalRename` refactoring - // action. All subcommands must have a unique names. This allows us to figure - // out which refactoring action should be invoked by looking at the first - // subcommand that's enabled by LLVM's command-line parser. - auto It = llvm::find_if( - Tool.SubCommands, - [](const std::unique_ptr<RefactoringActionSubcommand> &SubCommand) { - return !!(*SubCommand); - }); - if (It == Tool.SubCommands.end()) { - llvm::errs() << "error: no refactoring action given\n"; - llvm::errs() << "note: the following actions are supported:\n"; - for (const auto &Subcommand : Tool.SubCommands) - llvm::errs().indent(2) << Subcommand->getName() << "\n"; + if (auto Err = RefactorTool.Init()) { + llvm::errs() << llvm::toString(std::move(Err)) << "\n"; return 1; } - RefactoringActionSubcommand &ActionCommand = **It; - if (ActionCommand.parseArguments()) + auto ActionFactory = RefactorTool.getFrontendActionFactory(); + if (!ActionFactory) { + llvm::errs() << llvm::toString(ActionFactory.takeError()) << "\n"; return 1; - if (Tool.invokeAction(ActionCommand, Options.getCompilations(), - Options.getSourcePathList())) - return 1; - - return 0; + } + ClangTool Tool(Options.getCompilations(), Options.getSourcePathList()); + bool Failed = false; + if (Tool.run(ActionFactory->get()) != 0) { + llvm::errs() << "Failed to run refactoring action on files\n"; + // It is possible that TUs are broken while changes are generated correctly, + // so we still try applying changes. + Failed = true; + } + return RefactorTool.applySourceChanges() || Failed || + RefactorTool.hasFailed(); } diff --git a/tools/libclang/CMakeLists.txt b/tools/libclang/CMakeLists.txt index da2beca2ac..3a51c6a5f2 100644 --- a/tools/libclang/CMakeLists.txt +++ b/tools/libclang/CMakeLists.txt @@ -145,6 +145,7 @@ install(DIRECTORY ../../include/clang-c # component and an install-component target, so add a dummy libclang-headers # target to allow using it in LLVM_DISTRIBUTION_COMPONENTS. add_custom_target(libclang-headers) +set_target_properties(libclang-headers PROPERTIES FOLDER "Misc") if (NOT CMAKE_CONFIGURATION_TYPES) # don't add this for IDE's. add_custom_target(install-libclang-headers diff --git a/unittests/Format/FormatTest.cpp b/unittests/Format/FormatTest.cpp index 82530c0376..c61a56921a 100644 --- a/unittests/Format/FormatTest.cpp +++ b/unittests/Format/FormatTest.cpp @@ -5591,6 +5591,7 @@ TEST_F(FormatTest, UnderstandsOverloadedOperators) { verifyFormat("bool operator!=();"); verifyFormat("int operator+();"); verifyFormat("int operator++();"); + verifyFormat("int operator++(int) volatile noexcept;"); verifyFormat("bool operator,();"); verifyFormat("bool operator();"); verifyFormat("bool operator()();"); diff --git a/unittests/Format/UsingDeclarationsSorterTest.cpp b/unittests/Format/UsingDeclarationsSorterTest.cpp index caa2f4380b..6ce96ed962 100644 --- a/unittests/Format/UsingDeclarationsSorterTest.cpp +++ b/unittests/Format/UsingDeclarationsSorterTest.cpp @@ -86,19 +86,25 @@ TEST_F(UsingDeclarationsSorterTest, SwapsTwoConsecutiveUsingDeclarations) { "using a, b;")); } -TEST_F(UsingDeclarationsSorterTest, SortsCaseInsensitively) { +TEST_F(UsingDeclarationsSorterTest, SortsCaseSensitively) { EXPECT_EQ("using A;\n" "using a;", sortUsingDeclarations("using A;\n" "using a;")); - EXPECT_EQ("using a;\n" - "using A;", + EXPECT_EQ("using A;\n" + "using a;", sortUsingDeclarations("using a;\n" "using A;")); - EXPECT_EQ("using a;\n" - "using B;", + EXPECT_EQ("using B;\n" + "using a;", sortUsingDeclarations("using B;\n" "using a;")); + + // Sorts '_' right before 'A'. + EXPECT_EQ("using _;\n" + "using A;", + sortUsingDeclarations("using A;\n" + "using _;")); EXPECT_EQ("using _;\n" "using a;", sortUsingDeclarations("using a;\n" @@ -110,8 +116,8 @@ TEST_F(UsingDeclarationsSorterTest, SortsCaseInsensitively) { EXPECT_EQ("using ::testing::_;\n" "using ::testing::Aardvark;\n" - "using ::testing::apple::Honeycrisp;\n" "using ::testing::Xylophone;\n" + "using ::testing::apple::Honeycrisp;\n" "using ::testing::zebra::Stripes;", sortUsingDeclarations("using ::testing::Aardvark;\n" "using ::testing::Xylophone;\n" @@ -120,43 +126,6 @@ TEST_F(UsingDeclarationsSorterTest, SortsCaseInsensitively) { "using ::testing::zebra::Stripes;")); } -TEST_F(UsingDeclarationsSorterTest, SortsStably) { - EXPECT_EQ("using a;\n" - "using a;\n" - "using A;\n" - "using a;\n" - "using A;\n" - "using a;\n" - "using A;\n" - "using a;\n" - "using B;\n" - "using b;\n" - "using b;\n" - "using B;\n" - "using b;\n" - "using b;\n" - "using b;\n" - "using B;\n" - "using b;", - sortUsingDeclarations("using a;\n" - "using B;\n" - "using a;\n" - "using b;\n" - "using A;\n" - "using a;\n" - "using b;\n" - "using B;\n" - "using b;\n" - "using A;\n" - "using a;\n" - "using b;\n" - "using b;\n" - "using B;\n" - "using b;\n" - "using A;\n" - "using a;")); -} - TEST_F(UsingDeclarationsSorterTest, SortsMultipleTopLevelDeclarations) { EXPECT_EQ("using a;\n" "using b;\n" diff --git a/unittests/Tooling/ASTSelectionTest.cpp b/unittests/Tooling/ASTSelectionTest.cpp index 1435334d6c..f10d899a0a 100644 --- a/unittests/Tooling/ASTSelectionTest.cpp +++ b/unittests/Tooling/ASTSelectionTest.cpp @@ -972,4 +972,36 @@ TEST(ASTSelectionFinder, SimpleCodeRangeASTSelectionInObjCMethod) { SelectionFinderVisitor::Lang_OBJC); } +TEST(ASTSelectionFinder, CanonicalizeObjCStringLiteral) { + StringRef Source = R"( +void foo() { + (void)@"test"; +} + )"; + // Just '"test"': + findSelectedASTNodesWithRange( + Source, {3, 10}, FileRange{{3, 10}, {3, 16}}, + [](SourceRange SelectionRange, Optional<SelectedASTNode> Node) { + EXPECT_TRUE(Node); + Optional<CodeRangeASTSelection> SelectedCode = + CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); + EXPECT_TRUE(SelectedCode); + EXPECT_EQ(SelectedCode->size(), 1u); + EXPECT_TRUE(isa<ObjCStringLiteral>((*SelectedCode)[0])); + }, + SelectionFinderVisitor::Lang_OBJC); + // Just 'test': + findSelectedASTNodesWithRange( + Source, {3, 11}, FileRange{{3, 11}, {3, 15}}, + [](SourceRange SelectionRange, Optional<SelectedASTNode> Node) { + EXPECT_TRUE(Node); + Optional<CodeRangeASTSelection> SelectedCode = + CodeRangeASTSelection::create(SelectionRange, std::move(*Node)); + EXPECT_TRUE(SelectedCode); + EXPECT_EQ(SelectedCode->size(), 1u); + EXPECT_TRUE(isa<ObjCStringLiteral>((*SelectedCode)[0])); + }, + SelectionFinderVisitor::Lang_OBJC); +} + } // end anonymous namespace diff --git a/unittests/Tooling/ExecutionTest.cpp b/unittests/Tooling/ExecutionTest.cpp index 44e37b4009..b0c16d6cc5 100644 --- a/unittests/Tooling/ExecutionTest.cpp +++ b/unittests/Tooling/ExecutionTest.cpp @@ -125,13 +125,6 @@ public: } }; -// This anchor is used to force the linker to link in the generated object file -// and thus register the plugin. -extern volatile int ToolExecutorPluginAnchorSource; - -static int LLVM_ATTRIBUTE_UNUSED TestToolExecutorPluginAnchorDest = - ToolExecutorPluginAnchorSource; - static ToolExecutorPluginRegistry::Add<TestToolExecutorPlugin> X("test-executor", "Plugin for TestToolExecutor."); @@ -140,8 +133,8 @@ llvm::cl::OptionCategory TestCategory("execution-test options"); TEST(CreateToolExecutorTest, FailedCreateExecutorUndefinedFlag) { std::vector<const char *> argv = {"prog", "--fake_flag_no_no_no", "f"}; int argc = argv.size(); - auto Executor = - createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory); + auto Executor = internal::createExecutorFromCommandLineArgsImpl( + argc, &argv[0], TestCategory); ASSERT_FALSE((bool)Executor); llvm::consumeError(Executor.takeError()); } @@ -155,8 +148,8 @@ TEST(CreateToolExecutorTest, RegisterFlagsBeforeReset) { std::vector<const char *> argv = {"prog", "--before_reset=set", "f"}; int argc = argv.size(); - auto Executor = - createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory); + auto Executor = internal::createExecutorFromCommandLineArgsImpl( + argc, &argv[0], TestCategory); ASSERT_TRUE((bool)Executor); EXPECT_EQ(BeforeReset, "set"); BeforeReset.removeArgument(); @@ -165,8 +158,8 @@ TEST(CreateToolExecutorTest, RegisterFlagsBeforeReset) { TEST(CreateToolExecutorTest, CreateStandaloneToolExecutor) { std::vector<const char *> argv = {"prog", "standalone.cpp"}; int argc = argv.size(); - auto Executor = - createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory); + auto Executor = internal::createExecutorFromCommandLineArgsImpl( + argc, &argv[0], TestCategory); ASSERT_TRUE((bool)Executor); EXPECT_EQ(Executor->get()->getExecutorName(), StandaloneToolExecutor::ExecutorName); @@ -176,8 +169,8 @@ TEST(CreateToolExecutorTest, CreateTestToolExecutor) { std::vector<const char *> argv = {"prog", "test.cpp", "--executor=test-executor"}; int argc = argv.size(); - auto Executor = - createExecutorFromCommandLineArgs(argc, &argv[0], TestCategory); + auto Executor = internal::createExecutorFromCommandLineArgsImpl( + argc, &argv[0], TestCategory); ASSERT_TRUE((bool)Executor); EXPECT_EQ(Executor->get()->getExecutorName(), TestToolExecutor::ExecutorName); } diff --git a/unittests/Tooling/QualTypeNamesTest.cpp b/unittests/Tooling/QualTypeNamesTest.cpp index edd5060ba0..dd48f3bf45 100644 --- a/unittests/Tooling/QualTypeNamesTest.cpp +++ b/unittests/Tooling/QualTypeNamesTest.cpp @@ -7,7 +7,7 @@ // //===----------------------------------------------------------------------===// -#include "clang/Tooling/Core/QualTypeNames.h" +#include "clang/AST/QualTypeNames.h" #include "TestVisitor.h" using namespace clang; diff --git a/utils/TableGen/CMakeLists.txt b/utils/TableGen/CMakeLists.txt index 435529cdfd..dba0c94ac0 100644 --- a/utils/TableGen/CMakeLists.txt +++ b/utils/TableGen/CMakeLists.txt @@ -13,3 +13,4 @@ add_tablegen(clang-tblgen CLANG NeonEmitter.cpp TableGen.cpp ) +set_target_properties(clang-tblgen PROPERTIES FOLDER "Clang tablegenning") |